From 7e9caa8f7462811c2de08fde2fbbc3983d75b195 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 20 Apr 2024 00:03:27 +0000 Subject: [PATCH] Rebuild pages at 018db8238bc256c1dba73747ae3988ce8fa29843 --- CATcher-org_WATcher_main/authorship.json | 2 +- CATcher-org_WATcher_main/commits.json | 2 +- TEAMMATES_teammates_master/authorship.json | 2 +- TEAMMATES_teammates_master/commits.json | 2 +- archive.zip | Bin 2469774 -> 2470471 bytes markbind_markbind_master/commits.json | 2 +- reposense-logs/reposense.log.0 | 1674 ++++++++++---------- summary.json | 2 +- 8 files changed, 843 insertions(+), 843 deletions(-) diff --git a/CATcher-org_WATcher_main/authorship.json b/CATcher-org_WATcher_main/authorship.json index 17ca730..eb1dc8e 100644 --- a/CATcher-org_WATcher_main/authorship.json +++ b/CATcher-org_WATcher_main/authorship.json @@ -1 +1 @@ -[{"path":"src/app/activity-dashboard/activity-dashboard.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":".event-tables-wrapper {"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" display: flex;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" overflow-x: auto;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":4}},{"path":"src/app/activity-dashboard/activity-dashboard.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cdiv\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" \u003cmat-grid-list cols\u003d\"4\" rowHeight\u003d\"80px\"\u003e"},{"lineNumber":3,"author":{"gitId":"-"},"content":" \u003cmat-grid-tile\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"grid-flush-left\"\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":" \u003ch1 class\u003d\"mat-headline\" style\u003d\"margin: 0px\"\u003eActivity\u003c/h1\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":7,"author":{"gitId":"-"},"content":" \u003c/mat-grid-tile\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":" \u003cmat-grid-tile\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003cmat-form-field appearance\u003d\"fill\"\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003cmat-label\u003eStart Date\u003c/mat-label\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003cinput matInput [min]\u003d\"startMinDate\" [max]\u003d\"startMaxDate\" [matDatepicker]\u003d\"startPicker\" (dateChange)\u003d\"pickStartDate($event)\" /\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003cmat-hint\u003eMM/DD/YYYY\u003c/mat-hint\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":" \u003cmat-datepicker-toggle matSuffix [for]\u003d\"startPicker\"\u003e\u003c/mat-datepicker-toggle\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":" \u003cmat-datepicker startView\u003d\"year\" #startPicker\u003e\u003c/mat-datepicker\u003e"},{"lineNumber":16,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":" \u003c/mat-grid-tile\u003e"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":" \u003cmat-grid-tile\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003cmat-form-field appearance\u003d\"fill\"\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003cmat-label\u003eEnd Date\u003c/mat-label\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u003cinput matInput [min]\u003d\"endMinDate\" [max]\u003d\"endMaxDate\" [matDatepicker]\u003d\"endPicker\" (dateChange)\u003d\"pickEndDate($event)\" /\u003e"},{"lineNumber":23,"author":{"gitId":"-"},"content":" \u003cmat-hint\u003eMM/DD/YYYY\u003c/mat-hint\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":" \u003cmat-datepicker-toggle matSuffix [for]\u003d\"endPicker\"\u003e\u003c/mat-datepicker-toggle\u003e"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u003cmat-datepicker startView\u003d\"year\" #endPicker\u003e\u003c/mat-datepicker\u003e"},{"lineNumber":26,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003c/mat-grid-tile\u003e"},{"lineNumber":28,"author":{"gitId":"-"},"content":" \u003c/mat-grid-list\u003e"},{"lineNumber":29,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":"\u003cdiv class\u003d\"event-tables-wrapper\"\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003capp-event-tables"},{"lineNumber":33,"author":{"gitId":"-"},"content":" *ngFor\u003d\"let assignee of assignees\""},{"lineNumber":34,"author":{"gitId":"-"},"content":" class\u003d\"issue-table\""},{"lineNumber":35,"author":{"gitId":"-"},"content":" [actor]\u003d\"assignee\""},{"lineNumber":36,"author":{"gitId":"-"},"content":" [columnsToDisplay]\u003d\"this.displayedColumns\""},{"lineNumber":37,"author":{"gitId":"-"},"content":" [expandedColumnsToDisplay]\u003d\"this.expandedColumns\""},{"lineNumber":38,"author":{"gitId":"-"},"content":" [actions]\u003d\"this.actionButtons\""},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003e\u003c/app-event-tables\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"NereusWB922":1,"-":39}},{"path":"src/app/activity-dashboard/activity-dashboard.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component, OnInit, QueryList, ViewChildren } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { MatDatepickerInputEvent } from \u0027@angular/material/datepicker\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import * as moment from \u0027moment\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { GithubUser } from \u0027../core/models/github-user.model\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027../core/services/github.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { GithubEventService } from \u0027../core/services/githubevent.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { EXPANDED_TABLE_COLUMNS, TABLE_COLUMNS } from \u0027./event-tables/event-tables-columns\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { ACTION_BUTTONS, EventTablesComponent } from \u0027./event-tables/event-tables.component\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":11,"author":{"gitId":"-"},"content":" selector: \u0027app-activity-dashboard\u0027,"},{"lineNumber":12,"author":{"gitId":"-"},"content":" templateUrl: \u0027./activity-dashboard.component.html\u0027,"},{"lineNumber":13,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./activity-dashboard.component.css\u0027]"},{"lineNumber":14,"author":{"gitId":"-"},"content":"})"},{"lineNumber":15,"author":{"gitId":"-"},"content":"export class ActivityDashboardComponent implements OnInit {"},{"lineNumber":16,"author":{"gitId":"-"},"content":" readonly displayedColumns \u003d [TABLE_COLUMNS.DATE_START, TABLE_COLUMNS.ISSUE_COUNT, TABLE_COLUMNS.PR_COUNT, TABLE_COLUMNS.COMMENT_COUNT];"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" readonly expandedColumns \u003d [EXPANDED_TABLE_COLUMNS.TITLE, EXPANDED_TABLE_COLUMNS.DATE];"},{"lineNumber":18,"author":{"gitId":"-"},"content":" readonly actionButtons: ACTION_BUTTONS[] \u003d [ACTION_BUTTONS.VIEW_IN_WEB];"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" startMinDate: Date;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" startMaxDate \u003d moment().endOf(\u0027day\u0027).toDate();"},{"lineNumber":22,"author":{"gitId":"-"},"content":" endMinDate: Date;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" endMaxDate \u003d moment().endOf(\u0027day\u0027).toDate();"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" assignees: GithubUser[];"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @ViewChildren(EventTablesComponent) tables: QueryList\u003cEventTablesComponent\u003e;"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" constructor(private githubService: GithubService, private githubEventService: GithubEventService) {}"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" ngOnInit() {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" this.githubEventService.getEvents();"},{"lineNumber":33,"author":{"gitId":"-"},"content":" this.githubService.getUsersAssignable().subscribe((x) \u003d\u003e (this.assignees \u003d x));"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" pickStartDate(event: MatDatepickerInputEvent\u003cDate\u003e) {"},{"lineNumber":37,"author":{"gitId":"-"},"content":" this.endMinDate \u003d event.value;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" this.tables.forEach((t) \u003d\u003e (t.githubEvents.start \u003d `${event.value}`));"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" pickEndDate(event: MatDatepickerInputEvent\u003cDate\u003e) {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" this.startMaxDate \u003d event.value;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" this.tables.forEach((t) \u003d\u003e (t.githubEvents.end \u003d `${event.value}`));"},{"lineNumber":44,"author":{"gitId":"-"},"content":" }"},{"lineNumber":45,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"NereusWB922":1,"-":44}},{"path":"src/app/activity-dashboard/activity-dashboard.module.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { CommonModule } from \u0027@angular/common\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { NgModule } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { SharedModule } from \u0027../shared/shared.module\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { ActivityDashboardRoutingModule } from \u0027./activity-dashboard-routing.module\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { ActivityDashboardComponent } from \u0027./activity-dashboard.component\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { EventTablesModule } from \u0027./event-tables/event-tables.module\u0027;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"import { EventWeekDetailsComponent } from \u0027./event-week-details/event-week-details.component\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"@NgModule({"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" declarations: [ActivityDashboardComponent, EventWeekDetailsComponent],"},{"lineNumber":11,"author":{"gitId":"-"},"content":" imports: [CommonModule, SharedModule, ActivityDashboardRoutingModule, EventTablesModule]"},{"lineNumber":12,"author":{"gitId":"-"},"content":"})"},{"lineNumber":13,"author":{"gitId":"-"},"content":"export class ActivityDashboardModule {}"}],"authorContributionMap":{"NereusWB922":2,"-":11}},{"path":"src/app/activity-dashboard/event-tables/event-tables.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":".table-container {"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" margin: 10px;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" min-width: 400px;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":".actor-card {"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" display: flex;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" align-items: center;"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" padding: 10px;"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" margin-bottom: 1px;"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":".actor-username {"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" flex-grow: 1;"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" font-size: 15px;"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" margin: 0;"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" text-align: center;"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" word-break: break-word;"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":".avatar-container {"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" margin-right: 10px;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"}"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":".mat-table {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" /* flex-wrap: wrap; */"},{"lineNumber":27,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"}"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":".mat-cell {"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" display: flex;"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" align-items: center;"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" justify-content: center;"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" text-align: center;"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" padding: 0;"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":".mat-header-cell {"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" display: flex;"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" align-items: center;"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" justify-content: center;"},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":" text-align: center;"},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":" padding: 0;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"}"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":".mat-header-row {"},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" white-space: nowrap;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"}"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":".example-element-row:hover {"},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":" border: 3px solid rgba(0, 0, 0, 0.514);"},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" border-radius: 3px;"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" color: #210749;"},{"lineNumber":54,"author":{"gitId":"-"},"content":"}"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":".example-element-row td {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" border-bottom-width: 0;"},{"lineNumber":58,"author":{"gitId":"-"},"content":"}"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":".example-element-detail {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" overflow: hidden;"},{"lineNumber":62,"author":{"gitId":"-"},"content":" display: flex;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":64,"author":{"gitId":"-"},"content":"}"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":"/* Colour cells */"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":".white {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" background-color: white;"},{"lineNumber":70,"author":{"gitId":"-"},"content":"}"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":".pale-green {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" background-color: palegreen;"},{"lineNumber":74,"author":{"gitId":"-"},"content":"}"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":".green {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" background-color: green;"},{"lineNumber":78,"author":{"gitId":"-"},"content":"}"},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":".scrollable-container {"},{"lineNumber":81,"author":{"gitId":"NereusWB922"},"content":" height: 53vh;"},{"lineNumber":82,"author":{"gitId":"NereusWB922"},"content":" overflow: auto;"},{"lineNumber":83,"author":{"gitId":"NereusWB922"},"content":" margin-bottom: 2px;"},{"lineNumber":84,"author":{"gitId":"NereusWB922"},"content":" scrollbar-width: none;"},{"lineNumber":85,"author":{"gitId":"NereusWB922"},"content":" position: relative;"},{"lineNumber":86,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":87,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":88,"author":{"gitId":"NereusWB922"},"content":".scrollable-container::-webkit-scrollbar {"},{"lineNumber":89,"author":{"gitId":"NereusWB922"},"content":" display: none;"},{"lineNumber":90,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":91,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":92,"author":{"gitId":"NereusWB922"},"content":"/* Ref: https://css-scroll-shadows.vercel.app */"},{"lineNumber":93,"author":{"gitId":"NereusWB922"},"content":".scrollable-container::before {"},{"lineNumber":94,"author":{"gitId":"NereusWB922"},"content":" pointer-events: none;"},{"lineNumber":95,"author":{"gitId":"NereusWB922"},"content":" content: \u0027\u0027;"},{"lineNumber":96,"author":{"gitId":"NereusWB922"},"content":" position: absolute;"},{"lineNumber":97,"author":{"gitId":"NereusWB922"},"content":" z-index: 2;"},{"lineNumber":98,"author":{"gitId":"NereusWB922"},"content":" height: 6px;"},{"lineNumber":99,"author":{"gitId":"NereusWB922"},"content":" width: 100%;"},{"lineNumber":100,"author":{"gitId":"NereusWB922"},"content":" display: block;"},{"lineNumber":101,"author":{"gitId":"NereusWB922"},"content":" background-image: linear-gradient(to bottom, white 66%, transparent);"},{"lineNumber":102,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":103,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":104,"author":{"gitId":"NereusWB922"},"content":".scrollable-container::after {"},{"lineNumber":105,"author":{"gitId":"NereusWB922"},"content":" pointer-events: none;"},{"lineNumber":106,"author":{"gitId":"NereusWB922"},"content":" content: \u0027\u0027;"},{"lineNumber":107,"author":{"gitId":"NereusWB922"},"content":" position: sticky;"},{"lineNumber":108,"author":{"gitId":"NereusWB922"},"content":" z-index: 2;"},{"lineNumber":109,"author":{"gitId":"NereusWB922"},"content":" top: 100%;"},{"lineNumber":110,"author":{"gitId":"NereusWB922"},"content":" height: 6px;"},{"lineNumber":111,"author":{"gitId":"NereusWB922"},"content":" width: 100%;"},{"lineNumber":112,"author":{"gitId":"NereusWB922"},"content":" display: block;"},{"lineNumber":113,"author":{"gitId":"NereusWB922"},"content":" background-image: linear-gradient(to top, white 66%, transparent);"},{"lineNumber":114,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":115,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":116,"author":{"gitId":"NereusWB922"},"content":".scrollable-container-wrapper {"},{"lineNumber":117,"author":{"gitId":"NereusWB922"},"content":" position: relative;"},{"lineNumber":118,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":119,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":120,"author":{"gitId":"NereusWB922"},"content":".scrollable-container-wrapper::before {"},{"lineNumber":121,"author":{"gitId":"NereusWB922"},"content":" pointer-events: none;"},{"lineNumber":122,"author":{"gitId":"NereusWB922"},"content":" content: \u0027\u0027;"},{"lineNumber":123,"author":{"gitId":"NereusWB922"},"content":" position: absolute;"},{"lineNumber":124,"author":{"gitId":"NereusWB922"},"content":" z-index: 1;"},{"lineNumber":125,"author":{"gitId":"NereusWB922"},"content":" top: 0;"},{"lineNumber":126,"author":{"gitId":"NereusWB922"},"content":" left: 0;"},{"lineNumber":127,"author":{"gitId":"NereusWB922"},"content":" right: 0;"},{"lineNumber":128,"author":{"gitId":"NereusWB922"},"content":" height: 5px;"},{"lineNumber":129,"author":{"gitId":"NereusWB922"},"content":" background-image: radial-gradient(farthest-side at 50% 0, rgba(0, 0, 0, 0.5), transparent);"},{"lineNumber":130,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":131,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":132,"author":{"gitId":"NereusWB922"},"content":".scrollable-container-wrapper::after {"},{"lineNumber":133,"author":{"gitId":"NereusWB922"},"content":" pointer-events: none;"},{"lineNumber":134,"author":{"gitId":"NereusWB922"},"content":" content: \u0027\u0027;"},{"lineNumber":135,"author":{"gitId":"NereusWB922"},"content":" position: absolute;"},{"lineNumber":136,"author":{"gitId":"NereusWB922"},"content":" z-index: 1;"},{"lineNumber":137,"author":{"gitId":"NereusWB922"},"content":" bottom: 0;"},{"lineNumber":138,"author":{"gitId":"NereusWB922"},"content":" left: 0;"},{"lineNumber":139,"author":{"gitId":"NereusWB922"},"content":" right: 0;"},{"lineNumber":140,"author":{"gitId":"NereusWB922"},"content":" height: 5px;"},{"lineNumber":141,"author":{"gitId":"NereusWB922"},"content":" background-image: radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, 0.5), transparent);"},{"lineNumber":142,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":105,"-":37}},{"path":"src/app/activity-dashboard/event-tables/event-tables.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"table-container\"\u003e"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card class\u003d\"actor-card\"\u003e"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" mat-card-avatar"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" *ngIf\u003d\"this.actor\""},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" class\u003d\"avatar-container\""},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" [ngStyle]\u003d\"{"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" background: \u0027url(\u0027 + this.actor.avatar_url + \u0027)\u0027,"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" \u0027background-size\u0027: \u002740px\u0027"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" }\""},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" \u003e\u003c/div\u003e"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card-title class\u003d\"actor-username\"\u003e"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" {{ this.actor !\u003d\u003d undefined ? this.actor.login : \u0027Unknown\u0027 }}"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card-title\u003e"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card\u003e"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv class\u003d\"scrollable-container-wrapper\"\u003e"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv class\u003d\"scrollable-container\"\u003e"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-table [dataSource]\u003d\"this.githubEvents\" matSort multiTemplateDataRows\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003cng-container matColumnDef\u003d\"date_start\"\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003cmat-header-cell *matHeaderCellDef mat-sort-header\u003e Date \u003c/mat-header-cell\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u003cmat-cell *matCellDef\u003d\"let element\"\u003e"},{"lineNumber":23,"author":{"gitId":"-"},"content":" \u003cspan (click)\u003d\"$event.stopPropagation()\" style\u003d\"cursor: default\"\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":" {{ element.date_start }}"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":26,"author":{"gitId":"-"},"content":" \u003c/mat-cell\u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" \u003cng-container matColumnDef\u003d\"issue_count\"\u003e"},{"lineNumber":30,"author":{"gitId":"-"},"content":" \u003cmat-header-cell *matHeaderCellDef mat-sort-header\u003e Issue # \u003c/mat-header-cell\u003e"},{"lineNumber":31,"author":{"gitId":"-"},"content":" \u003cmat-cell *matCellDef\u003d\"let element\" [ngClass]\u003d\"colorCell(element.issue_count)\"\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003cspan (click)\u003d\"$event.stopPropagation()\" style\u003d\"cursor: default\"\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" {{ element.issue_count }}"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":" \u003c/mat-cell\u003e"},{"lineNumber":36,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" \u003cng-container matColumnDef\u003d\"pr_count\"\u003e"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003cmat-header-cell *matHeaderCellDef mat-sort-header\u003e PR # \u003c/mat-header-cell\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003cmat-cell *matCellDef\u003d\"let element\" [ngClass]\u003d\"colorCell(element.pr_count)\"\u003e"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003cspan (click)\u003d\"$event.stopPropagation()\" style\u003d\"cursor: default\"\u003e"},{"lineNumber":42,"author":{"gitId":"-"},"content":" {{ element.pr_count }}"},{"lineNumber":43,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u003c/mat-cell\u003e"},{"lineNumber":45,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" \u003cng-container matColumnDef\u003d\"comment_count\"\u003e"},{"lineNumber":48,"author":{"gitId":"-"},"content":" \u003cmat-header-cell *matHeaderCellDef mat-sort-header\u003e Comment # \u003c/mat-header-cell\u003e"},{"lineNumber":49,"author":{"gitId":"-"},"content":" \u003cmat-cell *matCellDef\u003d\"let element\" [ngClass]\u003d\"colorCell(element.comment_count)\"\u003e"},{"lineNumber":50,"author":{"gitId":"-"},"content":" \u003cspan (click)\u003d\"$event.stopPropagation()\" style\u003d\"cursor: default\"\u003e"},{"lineNumber":51,"author":{"gitId":"-"},"content":" {{ element.comment_count }}"},{"lineNumber":52,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":53,"author":{"gitId":"-"},"content":" \u003c/mat-cell\u003e"},{"lineNumber":54,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-header-row *matHeaderRowDef\u003d\"this.columnsToDisplay\"\u003e\u003c/mat-header-row\u003e"},{"lineNumber":57,"author":{"gitId":"-"},"content":" \u003cmat-row"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" *matRowDef\u003d\"let eventWeek; columns: this.columnsToDisplay\""},{"lineNumber":59,"author":{"gitId":"-"},"content":" class\u003d\"example-element-row\""},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":" (click)\u003d\"openDialog(eventWeek)\""},{"lineNumber":61,"author":{"gitId":"-"},"content":" \u003e\u003c/mat-row\u003e"},{"lineNumber":62,"author":{"gitId":"-"},"content":" \u003c/mat-table\u003e"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" \u003c/div\u003e"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" \u003c/div\u003e"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" \u003cmat-card *ngIf\u003d\"this.githubEvents.isLoading$ | async\" style\u003d\"display: flex; justify-content: center; align-items: center\"\u003e"},{"lineNumber":67,"author":{"gitId":"-"},"content":" \u003cmat-progress-spinner color\u003d\"primary\" mode\u003d\"indeterminate\" diameter\u003d\"50\" strokeWidth\u003d\"5\"\u003e\u003c/mat-progress-spinner\u003e"},{"lineNumber":68,"author":{"gitId":"-"},"content":" \u003c/mat-card\u003e"},{"lineNumber":69,"author":{"gitId":"-"},"content":" \u003cmat-paginator [pageSize]\u003d\"20\" [pageSizeOptions]\u003d\"[10, 20, 50]\"\u003e\u003c/mat-paginator\u003e"},{"lineNumber":70,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"NereusWB922":22,"-":48}},{"path":"src/app/activity-dashboard/event-tables/event-tables.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { animate, state, style, transition, trigger } from \u0027@angular/animations\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { AfterViewInit, Component, Input, OnInit, ViewChild } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { MatDialog } from \u0027@angular/material/dialog\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { MatPaginator } from \u0027@angular/material/paginator\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { MatSort } from \u0027@angular/material/sort\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { GithubUser } from \u0027../../core/models/github-user.model\u0027;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"import { ErrorHandlingService } from \u0027../../core/services/error-handling.service\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { GithubEventService } from \u0027../../core/services/githubevent.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027../../core/services/logging.service\u0027;"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"import { EventWeekDetailsComponent } from \u0027../event-week-details/event-week-details.component\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { EventWeek } from \u0027../event-week.model\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { GithubEventDataTable } from \u0027./GithubEventDataTable\u0027;"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":"import { NoEventsError } from \u0027./no-events-error.model\u0027;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"export enum ACTION_BUTTONS {"},{"lineNumber":16,"author":{"gitId":"-"},"content":" VIEW_IN_WEB,"},{"lineNumber":17,"author":{"gitId":"-"},"content":" COLLAPSE"},{"lineNumber":18,"author":{"gitId":"-"},"content":"}"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":21,"author":{"gitId":"-"},"content":" selector: \u0027app-event-tables\u0027,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" templateUrl: \u0027./event-tables.component.html\u0027,"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" styleUrls: [\u0027./event-tables.component.css\u0027]"},{"lineNumber":24,"author":{"gitId":"-"},"content":"})"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":27,"author":{"gitId":"-"},"content":" * Angular Table Expandable Rows"},{"lineNumber":28,"author":{"gitId":"-"},"content":" * ref: https://material.angular.io/components/table/examples#table-expandable-rows"},{"lineNumber":29,"author":{"gitId":"-"},"content":" */"},{"lineNumber":30,"author":{"gitId":"-"},"content":"export class EventTablesComponent implements OnInit, AfterViewInit {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" @Input() columnsToDisplay: string[];"},{"lineNumber":32,"author":{"gitId":"-"},"content":" @Input() expandedColumnsToDisplay: string[];"},{"lineNumber":33,"author":{"gitId":"-"},"content":" @Input() actions: ACTION_BUTTONS[];"},{"lineNumber":34,"author":{"gitId":"-"},"content":" @Input() actor?: GithubUser \u003d undefined;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" @Input() filters?: any \u003d undefined;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" @ViewChild(MatSort, { static: true }) sort: MatSort;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" githubEvents: GithubEventDataTable;"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" public readonly action_buttons \u003d ACTION_BUTTONS;"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" constructor("},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" public githubEventService: GithubEventService,"},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":" public dialog: MatDialog,"},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" private logger: LoggingService,"},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" private errorHandling: ErrorHandlingService"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":" ) {}"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" ngOnInit() {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" this.githubEvents \u003d new GithubEventDataTable(this.githubEventService, this.logger, this.sort, this.paginator, this.actor, this.filters);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" ngAfterViewInit(): void {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" setTimeout(() \u003d\u003e {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" this.githubEvents.loadEvents();"},{"lineNumber":58,"author":{"gitId":"-"},"content":" });"},{"lineNumber":59,"author":{"gitId":"-"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" reload() {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" this.githubEvents.loadEvents();"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":66,"author":{"gitId":"-"},"content":" * Formats the title text to account for those that contain long words."},{"lineNumber":67,"author":{"gitId":"-"},"content":" * @param title - Title of Event that is to be displayed in the Table Row."},{"lineNumber":68,"author":{"gitId":"-"},"content":" */"},{"lineNumber":69,"author":{"gitId":"-"},"content":" fitTitleText(title: string): string {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" // Arbitrary Length of Characters beyond which an overflow occurs."},{"lineNumber":71,"author":{"gitId":"-"},"content":" const MAX_WORD_LENGTH \u003d 43;"},{"lineNumber":72,"author":{"gitId":"-"},"content":" const SPLITTER_TEXT \u003d \u0027 \u0027;"},{"lineNumber":73,"author":{"gitId":"-"},"content":" const ELLIPSES \u003d \u0027...\u0027;"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" return title"},{"lineNumber":76,"author":{"gitId":"-"},"content":" .split(SPLITTER_TEXT)"},{"lineNumber":77,"author":{"gitId":"-"},"content":" .map((word) \u003d\u003e {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" if (word.length \u003e MAX_WORD_LENGTH) {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" return word.substring(0, MAX_WORD_LENGTH - 5).concat(ELLIPSES);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" }"},{"lineNumber":81,"author":{"gitId":"-"},"content":" return word;"},{"lineNumber":82,"author":{"gitId":"-"},"content":" })"},{"lineNumber":83,"author":{"gitId":"-"},"content":" .join(SPLITTER_TEXT);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" /** Not implemented yet. */"},{"lineNumber":87,"author":{"gitId":"-"},"content":" viewEventInBrowser(id: number, event: Event) {"},{"lineNumber":88,"author":{"gitId":"-"},"content":" this.logger.info(`EventTablesComponent: Opening Event ${id} on Github`);"},{"lineNumber":89,"author":{"gitId":"-"},"content":" // window.open(\u0027https://github.com/\u0027, \u0027_blank\u0027);"},{"lineNumber":90,"author":{"gitId":"-"},"content":" }"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"NereusWB922"},"content":" /** Opens dialog to show the event details of the selected week. */"},{"lineNumber":93,"author":{"gitId":"NereusWB922"},"content":" openDialog(eventWeek: EventWeek) {"},{"lineNumber":94,"author":{"gitId":"NereusWB922"},"content":" if (eventWeek.events.length \u003c\u003d 0) {"},{"lineNumber":95,"author":{"gitId":"NereusWB922"},"content":" this.errorHandling.handleError(new NoEventsError());"},{"lineNumber":96,"author":{"gitId":"NereusWB922"},"content":" return;"},{"lineNumber":97,"author":{"gitId":"-"},"content":" }"},{"lineNumber":98,"author":{"gitId":"NereusWB922"},"content":" this.dialog.open(EventWeekDetailsComponent, {"},{"lineNumber":99,"author":{"gitId":"NereusWB922"},"content":" data: {"},{"lineNumber":100,"author":{"gitId":"NereusWB922"},"content":" eventWeek,"},{"lineNumber":101,"author":{"gitId":"NereusWB922"},"content":" expandedColumnsToDisplay: this.expandedColumnsToDisplay"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" /** Returns color string of cell. Shade darkens with magnitude of number. */"},{"lineNumber":107,"author":{"gitId":"-"},"content":" colorCell(count: number) {"},{"lineNumber":108,"author":{"gitId":"-"},"content":" if (count \u003d\u003d\u003d 0) {"},{"lineNumber":109,"author":{"gitId":"-"},"content":" return \u0027white\u0027;"},{"lineNumber":110,"author":{"gitId":"-"},"content":" } else if (count \u003e 0 \u0026\u0026 count \u003c\u003d 5) {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" return \u0027pale-green\u0027;"},{"lineNumber":112,"author":{"gitId":"-"},"content":" } else if (count \u003e 6) {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" return \u0027green\u0027;"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":" }"},{"lineNumber":116,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"NereusWB922":21,"-":95}},{"path":"src/app/activity-dashboard/event-tables/no-events-error.model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"export class NoEventsError extends Error {"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" constructor() {"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" super(\u0027No events found for this week.\u0027);"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" Object.setPrototypeOf(this, NoEventsError.prototype);"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":6}},{"path":"src/app/activity-dashboard/event-week-details/event-week-details.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":".mat-cell {"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" white-space: nowrap;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" display: flex;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" align-items: center;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" justify-content: center;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" text-align: center;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" padding: 0;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":".mat-header-cell {"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" display: flex;"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" align-items: center;"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" justify-content: center;"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" text-align: center;"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" padding: 0;"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":".mat-dialog-content {"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" min-width: 500px;"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":20}},{"path":"src/app/activity-dashboard/event-week-details/event-week-details.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"\u003ch2 mat-dialog-title\u003eEvent Week Details\u003c/h2\u003e"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"\u003cmat-dialog-content class\u003d\"mat-typography\"\u003e"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-table [dataSource]\u003d\"data.eventWeek.events\"\u003e"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" \u003cng-container matColumnDef\u003d\"{{ expandableColumn }}\" *ngFor\u003d\"let expandableColumn of data.expandedColumnsToDisplay\"\u003e"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-header-cell *matHeaderCellDef\u003e{{ expandableColumn }}\u003c/mat-header-cell\u003e"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-cell *matCellDef\u003d\"let property\"\u003e"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" {{ property[expandableColumn] }}"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-cell\u003e"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" \u003c/ng-container\u003e"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-header-row *matHeaderRowDef\u003d\"data.expandedColumnsToDisplay\"\u003e\u003c/mat-header-row\u003e"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-row *matRowDef\u003d\"let property; columns: data.expandedColumnsToDisplay\"\u003e\u003c/mat-row\u003e"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-table\u003e"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":"\u003c/mat-dialog-content\u003e"}],"authorContributionMap":{"NereusWB922":13}},{"path":"src/app/activity-dashboard/event-week-details/event-week-details.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Component, Inject } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { MAT_DIALOG_DATA } from \u0027@angular/material/dialog\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { EventWeek } from \u0027../event-week.model\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"export interface DialogData {"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" eventWeek: EventWeek;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" expandedColumnsToDisplay: string[];"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"@Component({"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" selector: \u0027app-event-week-detail\u0027,"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" templateUrl: \u0027./event-week-details.component.html\u0027,"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" styleUrls: [\u0027./event-week-details.component.css\u0027]"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"})"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":"export class EventWeekDetailsComponent {"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" constructor(@Inject(MAT_DIALOG_DATA) public data: DialogData) {}"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":17}},{"path":"src/app/app-routing.module.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { NgModule } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { RouterModule, Routes } from \u0027@angular/router\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { ActivityDashboardModule } from \u0027./activity-dashboard/activity-dashboard.module\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { AuthModule } from \u0027./auth/auth.module\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { AuthGuard } from \u0027./core/guards/auth.guard\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { ParseUrlParamsGuard } from \u0027./core/guards/parse-url-params.guard\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { IssuesViewerModule } from \u0027./issues-viewer/issues-viewer.module\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"const routes: Routes \u003d ["},{"lineNumber":10,"author":{"gitId":"-"},"content":" { path: \u0027\u0027, loadChildren: () \u003d\u003e AuthModule },"},{"lineNumber":11,"author":{"gitId":"-"},"content":" { path: \u0027issuesViewer/:org/:repo\u0027, canActivate: [ParseUrlParamsGuard], children: [] },"},{"lineNumber":12,"author":{"gitId":"-"},"content":" { path: \u0027issuesViewer\u0027, loadChildren: () \u003d\u003e IssuesViewerModule, canLoad: [AuthGuard] },"},{"lineNumber":13,"author":{"gitId":"-"},"content":" { path: \u0027activityDashboard\u0027, loadChildren: () \u003d\u003e ActivityDashboardModule, canLoad: [AuthGuard] }"},{"lineNumber":14,"author":{"gitId":"-"},"content":"];"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"@NgModule({"},{"lineNumber":17,"author":{"gitId":"MadLamprey"},"content":" imports: [RouterModule.forRoot(routes, { relativeLinkResolution: \u0027legacy\u0027 })],"},{"lineNumber":18,"author":{"gitId":"-"},"content":" exports: [RouterModule]"},{"lineNumber":19,"author":{"gitId":"-"},"content":"})"},{"lineNumber":20,"author":{"gitId":"-"},"content":"export class AppRoutingModule {}"}],"authorContributionMap":{"MadLamprey":1,"-":19}},{"path":"src/app/app.module.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { HttpClientModule } from \u0027@angular/common/http\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { ErrorHandler, NgModule, NgZone } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { BrowserModule, Title } from \u0027@angular/platform-browser\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { BrowserAnimationsModule } from \u0027@angular/platform-browser/animations\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { Router } from \u0027@angular/router\u0027;"},{"lineNumber":6,"author":{"gitId":"MadLamprey"},"content":"import { ApolloLink, InMemoryCache, PossibleTypesMap } from \u0027@apollo/client/core\u0027;"},{"lineNumber":7,"author":{"gitId":"MadLamprey"},"content":"import { setContext } from \u0027@apollo/client/link/context\u0027;"},{"lineNumber":8,"author":{"gitId":"MadLamprey"},"content":"import { Apollo } from \u0027apollo-angular\u0027;"},{"lineNumber":9,"author":{"gitId":"MadLamprey"},"content":"import { HttpLink } from \u0027apollo-angular/http\u0027;"},{"lineNumber":10,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import \u0027reflect-metadata\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import graphqlTypes from \u0027../../graphql/graphql-types\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import \u0027../polyfills\u0027;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import { ActivityDashboardModule } from \u0027./activity-dashboard/activity-dashboard.module\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import { AppRoutingModule } from \u0027./app-routing.module\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import { AppComponent } from \u0027./app.component\u0027;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import { AuthModule } from \u0027./auth/auth.module\u0027;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import { UserConfirmationComponent } from \u0027./core/guards/user-confirmation/user-confirmation.component\u0027;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import { AuthService } from \u0027./core/services/auth.service\u0027;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import { ErrorHandlingService } from \u0027./core/services/error-handling.service\u0027;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import { ErrorMessageService } from \u0027./core/services/error-message.service\u0027;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import { AuthServiceFactory } from \u0027./core/services/factories/factory.auth.service\u0027;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import { GithubServiceFactory } from \u0027./core/services/factories/factory.github.service\u0027;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import { IssueServiceFactory } from \u0027./core/services/factories/factory.issue.service\u0027;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027./core/services/github.service\u0027;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import { GithubEventService } from \u0027./core/services/githubevent.service\u0027;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import { IssueService } from \u0027./core/services/issue.service\u0027;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import { LabelService } from \u0027./core/services/label.service\u0027;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027./core/services/logging.service\u0027;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import { RepoSessionStorageService } from \u0027./core/services/repo-session-storage.service\u0027;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import { UserService } from \u0027./core/services/user.service\u0027;"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":"import { ViewService } from \u0027./core/services/view.service\u0027;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import { IssuesViewerModule } from \u0027./issues-viewer/issues-viewer.module\u0027;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import { LabelDefinitionPopupComponent } from \u0027./shared/label-definition-popup/label-definition-popup.component\u0027;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import { HeaderComponent } from \u0027./shared/layout\u0027;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import { RepoChangeFormComponent } from \u0027./shared/repo-change-form/repo-change-form.component\u0027;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import { SharedModule } from \u0027./shared/shared.module\u0027;"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":"@NgModule({"},{"lineNumber":40,"author":{"gitId":"Arif-Khalid"},"content":" declarations: [AppComponent, HeaderComponent, UserConfirmationComponent, LabelDefinitionPopupComponent, RepoChangeFormComponent],"},{"lineNumber":41,"author":{"gitId":"-"},"content":" imports: ["},{"lineNumber":42,"author":{"gitId":"-"},"content":" BrowserModule,"},{"lineNumber":43,"author":{"gitId":"-"},"content":" BrowserAnimationsModule,"},{"lineNumber":44,"author":{"gitId":"-"},"content":" AuthModule,"},{"lineNumber":45,"author":{"gitId":"-"},"content":" IssuesViewerModule,"},{"lineNumber":46,"author":{"gitId":"-"},"content":" ActivityDashboardModule,"},{"lineNumber":47,"author":{"gitId":"-"},"content":" SharedModule,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" HttpClientModule,"},{"lineNumber":49,"author":{"gitId":"MadLamprey"},"content":" AppRoutingModule"},{"lineNumber":50,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":51,"author":{"gitId":"-"},"content":" providers: ["},{"lineNumber":52,"author":{"gitId":"-"},"content":" {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" provide: GithubService,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" useFactory: GithubServiceFactory,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" deps: [ErrorHandlingService, Apollo, LoggingService]"},{"lineNumber":56,"author":{"gitId":"-"},"content":" },"},{"lineNumber":57,"author":{"gitId":"-"},"content":" {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" provide: AuthService,"},{"lineNumber":59,"author":{"gitId":"-"},"content":" useFactory: AuthServiceFactory,"},{"lineNumber":60,"author":{"gitId":"-"},"content":" deps: ["},{"lineNumber":61,"author":{"gitId":"-"},"content":" Router,"},{"lineNumber":62,"author":{"gitId":"-"},"content":" NgZone,"},{"lineNumber":63,"author":{"gitId":"-"},"content":" GithubService,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" UserService,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" IssueService,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" LabelService,"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":" ViewService,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" GithubEventService,"},{"lineNumber":69,"author":{"gitId":"-"},"content":" Title,"},{"lineNumber":70,"author":{"gitId":"-"},"content":" ErrorHandlingService,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" LoggingService"},{"lineNumber":72,"author":{"gitId":"-"},"content":" ]"},{"lineNumber":73,"author":{"gitId":"-"},"content":" },"},{"lineNumber":74,"author":{"gitId":"-"},"content":" {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" provide: IssueService,"},{"lineNumber":76,"author":{"gitId":"-"},"content":" useFactory: IssueServiceFactory,"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" deps: [GithubService, UserService, ViewService]"},{"lineNumber":78,"author":{"gitId":"-"},"content":" },"},{"lineNumber":79,"author":{"gitId":"-"},"content":" {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" provide: ErrorHandler,"},{"lineNumber":81,"author":{"gitId":"-"},"content":" useClass: ErrorHandlingService"},{"lineNumber":82,"author":{"gitId":"-"},"content":" },"},{"lineNumber":83,"author":{"gitId":"-"},"content":" ErrorMessageService,"},{"lineNumber":84,"author":{"gitId":"-"},"content":" RepoSessionStorageService"},{"lineNumber":85,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":86,"author":{"gitId":"-"},"content":" bootstrap: [AppComponent]"},{"lineNumber":87,"author":{"gitId":"-"},"content":"})"},{"lineNumber":88,"author":{"gitId":"-"},"content":"export class AppModule {"},{"lineNumber":89,"author":{"gitId":"-"},"content":" constructor(private apollo: Apollo, private httpLink: HttpLink, private authService: AuthService, private logger: LoggingService) {"},{"lineNumber":90,"author":{"gitId":"-"},"content":" const URI \u003d \u0027https://api.github.com/graphql\u0027;"},{"lineNumber":91,"author":{"gitId":"-"},"content":" const log \u003d new ApolloLink((operation, forward) \u003d\u003e {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" operation.setContext({ start: performance.now() });"},{"lineNumber":93,"author":{"gitId":"-"},"content":" this.logger.info(\u0027AppModule: GraphQL request\u0027, operation.getContext());"},{"lineNumber":94,"author":{"gitId":"-"},"content":" return forward(operation).map((result) \u003d\u003e {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" const time \u003d performance.now() - operation.getContext().start;"},{"lineNumber":96,"author":{"gitId":"-"},"content":" this.logger.info(\u0027AppModule: GraphQL response\u0027, operation.getContext(), `in ${Math.round(time)}ms`);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" const repo \u003d operation.getContext().response.body.data.repository;"},{"lineNumber":98,"author":{"gitId":"-"},"content":" const item \u003d Object.keys(repo)[0];"},{"lineNumber":99,"author":{"gitId":"-"},"content":" this.logger.debug(\u0027AppModule: GraphQL response body\u0027, item, repo[item].edges.length, repo[item].edges);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" return result;"},{"lineNumber":101,"author":{"gitId":"-"},"content":" });"},{"lineNumber":102,"author":{"gitId":"-"},"content":" });"},{"lineNumber":103,"author":{"gitId":"-"},"content":" const basic \u003d setContext(() \u003d\u003e {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" return { headers: { Accept: \u0027charset\u003dutf-8\u0027 } };"},{"lineNumber":105,"author":{"gitId":"-"},"content":" });"},{"lineNumber":106,"author":{"gitId":"-"},"content":" const auth \u003d setContext(() \u003d\u003e {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" return { headers: { Authorization: `Token ${this.authService.accessToken.getValue()}` } };"},{"lineNumber":108,"author":{"gitId":"-"},"content":" });"},{"lineNumber":109,"author":{"gitId":"-"},"content":" const link \u003d ApolloLink.from([log, basic, auth, this.httpLink.create({ uri: URI })]);"},{"lineNumber":110,"author":{"gitId":"MadLamprey"},"content":" const possibleTypes: PossibleTypesMap \u003d {};"},{"lineNumber":111,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":112,"author":{"gitId":"MadLamprey"},"content":" graphqlTypes.__schema.types.forEach((type: any) \u003d\u003e {"},{"lineNumber":113,"author":{"gitId":"MadLamprey"},"content":" if (type.kind \u003d\u003d\u003d \u0027UNION\u0027 || type.kind \u003d\u003d\u003d \u0027INTERFACE\u0027) {"},{"lineNumber":114,"author":{"gitId":"MadLamprey"},"content":" possibleTypes[type.name] \u003d type.possibleTypes.map((possibleType: any) \u003d\u003e possibleType.name);"},{"lineNumber":115,"author":{"gitId":"MadLamprey"},"content":" }"},{"lineNumber":116,"author":{"gitId":"-"},"content":" });"},{"lineNumber":117,"author":{"gitId":"MadLamprey"},"content":" const cache \u003d new InMemoryCache({ possibleTypes });"},{"lineNumber":118,"author":{"gitId":"-"},"content":" this.apollo.create({"},{"lineNumber":119,"author":{"gitId":"-"},"content":" link: link,"},{"lineNumber":120,"author":{"gitId":"-"},"content":" cache: cache"},{"lineNumber":121,"author":{"gitId":"-"},"content":" });"},{"lineNumber":122,"author":{"gitId":"-"},"content":" }"},{"lineNumber":123,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"NereusWB922":3,"Arif-Khalid":1,"MadLamprey":13,"-":106}},{"path":"src/app/auth/auth.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component, NgZone, OnDestroy, OnInit } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { ActivatedRoute, Router } from \u0027@angular/router\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { Observable, Subscription } from \u0027rxjs\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { filter, flatMap, map } from \u0027rxjs/operators\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { AppConfig } from \u0027../../environments/environment\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { STORAGE_KEYS } from \u0027../core/constants/storage-keys.constants\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { GithubUser } from \u0027../core/models/github-user.model\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { ApplicationService } from \u0027../core/services/application.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { AuthService, AuthState } from \u0027../core/services/auth.service\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { ErrorHandlingService } from \u0027../core/services/error-handling.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { ErrorMessageService } from \u0027../core/services/error-message.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027../core/services/logging.service\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { UserService } from \u0027../core/services/user.service\u0027;"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"import { ViewService } from \u0027../core/services/view.service\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":17,"author":{"gitId":"-"},"content":" selector: \u0027app-auth\u0027,"},{"lineNumber":18,"author":{"gitId":"-"},"content":" templateUrl: \u0027./auth.component.html\u0027,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./auth.component.css\u0027]"},{"lineNumber":20,"author":{"gitId":"-"},"content":"})"},{"lineNumber":21,"author":{"gitId":"-"},"content":"export class AuthComponent implements OnInit, OnDestroy {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" authState: AuthState;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" accessTokenSubscription: Subscription;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" authStateSubscription: Subscription;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" currentUserName: string;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" urlEncodedSessionName: string;"},{"lineNumber":27,"author":{"gitId":"-"},"content":" urlEncodedRepo: string;"},{"lineNumber":28,"author":{"gitId":"-"},"content":" sessionInformation: string;"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" constructor("},{"lineNumber":31,"author":{"gitId":"-"},"content":" public appService: ApplicationService,"},{"lineNumber":32,"author":{"gitId":"-"},"content":" private authService: AuthService,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" private userService: UserService,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" private errorHandlingService: ErrorHandlingService,"},{"lineNumber":35,"author":{"gitId":"-"},"content":" private router: Router,"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" private viewService: ViewService,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" private ngZone: NgZone,"},{"lineNumber":38,"author":{"gitId":"-"},"content":" private activatedRoute: ActivatedRoute,"},{"lineNumber":39,"author":{"gitId":"-"},"content":" private logger: LoggingService"},{"lineNumber":40,"author":{"gitId":"-"},"content":" ) {}"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" ngOnInit() {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" this.logger.startSession();"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" const oauthCode \u003d this.activatedRoute.snapshot.queryParamMap.get(\u0027code\u0027);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" const state \u003d this.activatedRoute.snapshot.queryParamMap.get(\u0027state\u0027);"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" if (this.authService.isAuthenticated()) {"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":" this.router.navigate([this.viewService.currentView]);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" }"},{"lineNumber":52,"author":{"gitId":"-"},"content":" this.initAccessTokenSubscription();"},{"lineNumber":53,"author":{"gitId":"-"},"content":" this.initAuthStateSubscription();"},{"lineNumber":54,"author":{"gitId":"-"},"content":" this.createProfileFromUrlQueryParams();"},{"lineNumber":55,"author":{"gitId":"-"},"content":" this.getRepoFromUrlQueryParams();"},{"lineNumber":56,"author":{"gitId":"-"},"content":" if (oauthCode) {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" // runs upon receiving oauthCode from the redirect"},{"lineNumber":58,"author":{"gitId":"-"},"content":" this.authService.changeAuthState(AuthState.AwaitingAuthentication);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" // this.restoreOrgDetailsFromLocalStorage();"},{"lineNumber":60,"author":{"gitId":"-"},"content":" this.logger.info(\u0027AuthComponent: Obtained authorisation code from Github\u0027);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" this.fetchAccessToken(oauthCode, state);"},{"lineNumber":62,"author":{"gitId":"nknguyenhc"},"content":" return;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"nknguyenhc"},"content":" this.authService.startOAuthIfHasNext();"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":68,"author":{"gitId":"-"},"content":" * Will fetch the access token from GitHub."},{"lineNumber":69,"author":{"gitId":"-"},"content":" * @param oauthCode - The authorisation code obtained from GitHub."},{"lineNumber":70,"author":{"gitId":"-"},"content":" * @param state - The state returned from GitHub."},{"lineNumber":71,"author":{"gitId":"-"},"content":" */"},{"lineNumber":72,"author":{"gitId":"-"},"content":" fetchAccessToken(oauthCode: string, state: string) {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" if (!this.authService.isReturnedStateSame(state)) {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" this.logger.info(`AuthComponent: Received incorrect state ${state}, continue waiting for correct state`);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" this.logger.info(`AuthComponent: Retrieving access token from Github`);"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" const accessTokenUrl \u003d `${AppConfig.accessTokenUrl}/${oauthCode}/client_id/${AppConfig.clientId}`;"},{"lineNumber":81,"author":{"gitId":"-"},"content":" fetch(accessTokenUrl)"},{"lineNumber":82,"author":{"gitId":"-"},"content":" .then((res) \u003d\u003e res.json())"},{"lineNumber":83,"author":{"gitId":"-"},"content":" .then((data) \u003d\u003e {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" if (data.error) {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" throw new Error(data.error);"},{"lineNumber":86,"author":{"gitId":"-"},"content":" }"},{"lineNumber":87,"author":{"gitId":"-"},"content":" this.authService.storeOAuthAccessToken(data.token);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" this.logger.info(`AuthComponent: Sucessfully obtained access token`);"},{"lineNumber":89,"author":{"gitId":"-"},"content":" })"},{"lineNumber":90,"author":{"gitId":"-"},"content":" .catch((err) \u003d\u003e {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" this.logger.info(`AuthComponent: Error in data fetched from access token URL: ${err}`);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" this.errorHandlingService.handleError(err);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" this.authService.changeAuthState(AuthState.NotAuthenticated);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" });"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" ngOnDestroy() {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" if (this.authStateSubscription) {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" this.authStateSubscription.unsubscribe();"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":" if (this.accessTokenSubscription) {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" this.accessTokenSubscription.unsubscribe();"},{"lineNumber":103,"author":{"gitId":"-"},"content":" }"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":107,"author":{"gitId":"-"},"content":" * Checks whether the current version of WATcher is outdated."},{"lineNumber":108,"author":{"gitId":"-"},"content":" */"},{"lineNumber":109,"author":{"gitId":"-"},"content":" checkAppIsOutdated(): Observable\u003cany\u003e {"},{"lineNumber":110,"author":{"gitId":"-"},"content":" return this.appService.isApplicationOutdated().pipe("},{"lineNumber":111,"author":{"gitId":"-"},"content":" map((isOutdated: boolean) \u003d\u003e {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" if (isOutdated) {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" throw new Error(ErrorMessageService.applicationVersionOutdatedMessage());"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":" })"},{"lineNumber":116,"author":{"gitId":"-"},"content":" );"},{"lineNumber":117,"author":{"gitId":"-"},"content":" }"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" updateSession(sessionEvent: string) {"},{"lineNumber":120,"author":{"gitId":"-"},"content":" this.sessionInformation \u003d sessionEvent;"},{"lineNumber":121,"author":{"gitId":"-"},"content":" }"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" goToSessionSelect() {"},{"lineNumber":124,"author":{"gitId":"-"},"content":" this.authService.changeAuthState(AuthState.NotAuthenticated);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" }"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" isUserNotAuthenticated(): boolean {"},{"lineNumber":128,"author":{"gitId":"-"},"content":" return this.authState \u003d\u003d\u003d AuthState.NotAuthenticated;"},{"lineNumber":129,"author":{"gitId":"-"},"content":" }"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" isUserAuthenticating(): boolean {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" return this.authState \u003d\u003d\u003d AuthState.AwaitingAuthentication;"},{"lineNumber":133,"author":{"gitId":"-"},"content":" }"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" isAwaitingOAuthUserConfirm(): boolean {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" return this.authState \u003d\u003d\u003d AuthState.ConfirmOAuthUser;"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" isUserAuthenticated(): boolean {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" return this.authState \u003d\u003d\u003d AuthState.Authenticated;"},{"lineNumber":141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" isRepoSet(): boolean {"},{"lineNumber":144,"author":{"gitId":"NereusWB922"},"content":" return this.viewService.isRepoSet();"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" get currentSessionOrg(): string {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" if (!this.sessionInformation) {"},{"lineNumber":149,"author":{"gitId":"-"},"content":" // Retrieve org details of session information from local storage"},{"lineNumber":150,"author":{"gitId":"-"},"content":" return window.localStorage.getItem(STORAGE_KEYS.ORG);"},{"lineNumber":151,"author":{"gitId":"-"},"content":" }"},{"lineNumber":152,"author":{"gitId":"-"},"content":" return this.getOrgDetails(this.sessionInformation);"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":156,"author":{"gitId":"-"},"content":" * Extracts the Organization Details from the input sessionInformation."},{"lineNumber":157,"author":{"gitId":"-"},"content":" * @param sessionInformation - string in the format of \u0027orgName/dataRepo\u0027"},{"lineNumber":158,"author":{"gitId":"-"},"content":" */"},{"lineNumber":159,"author":{"gitId":"-"},"content":" private getOrgDetails(sessionInformation: string) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" return sessionInformation.split(\u0027/\u0027)[0];"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" private initAuthStateSubscription() {"},{"lineNumber":164,"author":{"gitId":"-"},"content":" this.authStateSubscription \u003d this.authService.currentAuthState.subscribe((state) \u003d\u003e {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" this.ngZone.run(() \u003d\u003e {"},{"lineNumber":166,"author":{"gitId":"-"},"content":" this.authState \u003d state;"},{"lineNumber":167,"author":{"gitId":"-"},"content":" });"},{"lineNumber":168,"author":{"gitId":"-"},"content":" });"},{"lineNumber":169,"author":{"gitId":"-"},"content":" }"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" private initAccessTokenSubscription() {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" this.accessTokenSubscription \u003d this.authService.accessToken"},{"lineNumber":173,"author":{"gitId":"-"},"content":" .pipe("},{"lineNumber":174,"author":{"gitId":"-"},"content":" filter((token: string) \u003d\u003e !!token),"},{"lineNumber":175,"author":{"gitId":"-"},"content":" flatMap(() \u003d\u003e this.userService.getAuthenticatedUser())"},{"lineNumber":176,"author":{"gitId":"-"},"content":" )"},{"lineNumber":177,"author":{"gitId":"-"},"content":" .subscribe((user: GithubUser) \u003d\u003e {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" this.ngZone.run(() \u003d\u003e {"},{"lineNumber":179,"author":{"gitId":"-"},"content":" this.currentUserName \u003d user.login;"},{"lineNumber":180,"author":{"gitId":"nknguyenhc"},"content":" if (this.authService.hasNext()) {"},{"lineNumber":181,"author":{"gitId":"nknguyenhc"},"content":" this.authService.completeLoginIfHasNext(this.currentUserName);"},{"lineNumber":182,"author":{"gitId":"nknguyenhc"},"content":" } else {"},{"lineNumber":183,"author":{"gitId":"-"},"content":" this.authService.changeAuthState(AuthState.ConfirmOAuthUser);"},{"lineNumber":184,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":185,"author":{"gitId":"-"},"content":" });"},{"lineNumber":186,"author":{"gitId":"-"},"content":" });"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":" private createProfileFromUrlQueryParams() {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" const urlParams \u003d this.activatedRoute.snapshot.queryParamMap;"},{"lineNumber":191,"author":{"gitId":"-"},"content":" if (urlParams.has(\u0027session\u0027)) {"},{"lineNumber":192,"author":{"gitId":"-"},"content":" this.urlEncodedSessionName \u003d urlParams.get(\u0027session\u0027);"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":" }"},{"lineNumber":195,"author":{"gitId":"-"},"content":""},{"lineNumber":196,"author":{"gitId":"-"},"content":" private getRepoFromUrlQueryParams() {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" const urlParams \u003d this.activatedRoute.snapshot.queryParamMap;"},{"lineNumber":198,"author":{"gitId":"-"},"content":" if (urlParams.has(\u0027repo\u0027)) {"},{"lineNumber":199,"author":{"gitId":"-"},"content":" this.urlEncodedRepo \u003d urlParams.get(\u0027repo\u0027);"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }"},{"lineNumber":201,"author":{"gitId":"-"},"content":" }"},{"lineNumber":202,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":6,"NereusWB922":4,"-":192}},{"path":"src/app/core/guards/auth.guard.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { ActivatedRouteSnapshot, CanActivate, CanLoad, Route, Router, RouterStateSnapshot, UrlSegment } from \u0027@angular/router\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { AuthService } from \u0027../services/auth.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":7,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":8,"author":{"gitId":"-"},"content":"})"},{"lineNumber":9,"author":{"gitId":"-"},"content":"export class AuthGuard implements CanActivate, CanLoad {"},{"lineNumber":10,"author":{"gitId":"-"},"content":" constructor(private auth: AuthService, private router: Router) {}"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":" canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable\u003cboolean\u003e | Promise\u003cboolean\u003e | boolean {"},{"lineNumber":13,"author":{"gitId":"-"},"content":" if (this.auth.isAuthenticated()) {"},{"lineNumber":14,"author":{"gitId":"nknguyenhc"},"content":" this.auth.clearNext();"},{"lineNumber":15,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":16,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":17,"author":{"gitId":"nknguyenhc"},"content":" this.auth.storeNext(state);"},{"lineNumber":18,"author":{"gitId":"-"},"content":" this.router.navigate([\u0027\u0027]);"},{"lineNumber":19,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" }"},{"lineNumber":21,"author":{"gitId":"-"},"content":" }"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" canLoad(route: Route, segments: UrlSegment[]): Observable\u003cboolean\u003e | Promise\u003cboolean\u003e | boolean {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" if (this.auth.isAuthenticated()) {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" this.router.navigate([\u0027\u0027]);"},{"lineNumber":28,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":2,"-":29}},{"path":"src/app/core/models/github-user.model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Group } from \u0027./github/group.interface\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"/**"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" * Represents raw data returned from the GitHub API about a user."},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"export interface RawGithubUser {"},{"lineNumber":7,"author":{"gitId":"-"},"content":" avatar_url: string;"},{"lineNumber":8,"author":{"gitId":"-"},"content":" created_at: string;"},{"lineNumber":9,"author":{"gitId":"-"},"content":" html_url: string;"},{"lineNumber":10,"author":{"gitId":"-"},"content":" login: string;"},{"lineNumber":11,"author":{"gitId":"-"},"content":" name: string;"},{"lineNumber":12,"author":{"gitId":"-"},"content":" node_id: string;"},{"lineNumber":13,"author":{"gitId":"-"},"content":" two_factor_authentication: boolean;"},{"lineNumber":14,"author":{"gitId":"-"},"content":" site_admin: false;"},{"lineNumber":15,"author":{"gitId":"-"},"content":" type: string;"},{"lineNumber":16,"author":{"gitId":"-"},"content":" updated_at: string;"},{"lineNumber":17,"author":{"gitId":"-"},"content":" url: string;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"}"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":"/**"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" * Represents a GitHub user in WATcher"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":"export class GithubUser implements RawGithubUser, Group {"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" static NO_ASSIGNEE: GithubUser \u003d new GithubUser({"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" avatar_url: \u0027\u0027,"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" created_at: \u0027\u0027,"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" html_url: \u0027\u0027,"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" login: \u0027Unassigned\u0027,"},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" name: \u0027\u0027,"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" node_id: \u0027\u0027,"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" two_factor_authentication: false,"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" site_admin: false,"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" type: \u0027\u0027,"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" updated_at: \u0027\u0027,"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" url: \u0027\u0027"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" avatar_url: string;"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" created_at: string;"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" html_url: string;"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" login: string;"},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":" name: string;"},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":" node_id: string;"},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" two_factor_authentication: boolean;"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" site_admin: false;"},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":" type: string;"},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" updated_at: string;"},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" url: string;"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" constructor(rawData: RawGithubUser) {"},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":" Object.assign(this, rawData);"},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":" equals(other: any) {"},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" if (!(other instanceof GithubUser)) {"},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" return false;"},{"lineNumber":57,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" return this.login \u003d\u003d\u003d other.login;"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":48,"-":12}},{"path":"src/app/core/models/github/group.interface.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"/**"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" * Represents a group used for grouping purposes."},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" * Groups can be used to organize issues/prs based on certain criteria,"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" * such as milestones, assignees, or other properties."},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"export interface Group {"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" equals(other: any): boolean;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":8}},{"path":"src/app/core/models/issue.model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import * as moment from \u0027moment\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { GithubComment } from \u0027./github/github-comment.model\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { GithubIssue } from \u0027./github/github-issue.model\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { GithubLabel } from \u0027./github/github-label.model\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { HiddenData } from \u0027./hidden-data.model\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { Milestone } from \u0027./milestone.model\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"export class Issue {"},{"lineNumber":9,"author":{"gitId":"-"},"content":" /** Basic Fields */"},{"lineNumber":10,"author":{"gitId":"-"},"content":" readonly globalId: string;"},{"lineNumber":11,"author":{"gitId":"-"},"content":" readonly id: number;"},{"lineNumber":12,"author":{"gitId":"-"},"content":" readonly created_at: string;"},{"lineNumber":13,"author":{"gitId":"-"},"content":" readonly githubIssue: GithubIssue;"},{"lineNumber":14,"author":{"gitId":"-"},"content":" githubComments: GithubComment[];"},{"lineNumber":15,"author":{"gitId":"-"},"content":" title: string;"},{"lineNumber":16,"author":{"gitId":"-"},"content":" description: string;"},{"lineNumber":17,"author":{"gitId":"-"},"content":" hiddenDataInDescription: HiddenData;"},{"lineNumber":18,"author":{"gitId":"-"},"content":" updated_at: string;"},{"lineNumber":19,"author":{"gitId":"-"},"content":" closed_at: string;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" milestone: Milestone;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" state: string;"},{"lineNumber":22,"author":{"gitId":"-"},"content":" stateReason: string;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" issueOrPr: string;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" author: string;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" isDraft: boolean;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" /** Depending on the view, assignees attribute can be derived from Github\u0027s assignee feature OR from the Github\u0027s issue description */"},{"lineNumber":28,"author":{"gitId":"-"},"content":" assignees?: string[];"},{"lineNumber":29,"author":{"gitId":"-"},"content":" labels?: string[];"},{"lineNumber":30,"author":{"gitId":"-"},"content":" githubLabels?: GithubLabel[];"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":33,"author":{"gitId":"-"},"content":" * Formats the text to create space at the end of the user input to prevent any issues with"},{"lineNumber":34,"author":{"gitId":"-"},"content":" * the markdown interpretation."},{"lineNumber":35,"author":{"gitId":"-"},"content":" *"},{"lineNumber":36,"author":{"gitId":"-"},"content":" * Brought over from comment-editor.component.ts"},{"lineNumber":37,"author":{"gitId":"-"},"content":" */"},{"lineNumber":38,"author":{"gitId":"-"},"content":" static formatText(text: string): string {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" if (text \u003d\u003d\u003d null) {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" if (text \u003d\u003d\u003d undefined) {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return undefined;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" const newLinesRegex \u003d /[\\n\\r]/gi;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" const textSplitArray \u003d text.split(newLinesRegex);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" if (textSplitArray.filter((split) \u003d\u003e split.trim() !\u003d\u003d \u0027\u0027).length \u003e 0) {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" return `${text}\\n\\n`;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" return text;"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":" }"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":57,"author":{"gitId":"-"},"content":" * Processes and cleans a raw issue description obtained from user input."},{"lineNumber":58,"author":{"gitId":"-"},"content":" */"},{"lineNumber":59,"author":{"gitId":"-"},"content":" static updateDescription(description: string): string {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" const defaultString \u003d \u0027No details provided by bug reporter.\u0027;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" return Issue.orDefaultString(Issue.formatText(description), defaultString);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" }"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":65,"author":{"gitId":"-"},"content":" * Given two strings, returns the first if it is not an empty string or a false value such as null/undefined."},{"lineNumber":66,"author":{"gitId":"-"},"content":" * Returns the second string if the first is an empty string."},{"lineNumber":67,"author":{"gitId":"-"},"content":" */"},{"lineNumber":68,"author":{"gitId":"-"},"content":" private static orDefaultString(stringA: string, def: string): string {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" if (!stringA) {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" return def;"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":" return stringA.length !\u003d\u003d 0 ? stringA : def;"},{"lineNumber":73,"author":{"gitId":"-"},"content":" }"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" protected constructor(githubIssue: GithubIssue) {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" /** Basic Fields */"},{"lineNumber":77,"author":{"gitId":"-"},"content":" this.globalId \u003d githubIssue.id;"},{"lineNumber":78,"author":{"gitId":"-"},"content":" this.id \u003d +githubIssue.number;"},{"lineNumber":79,"author":{"gitId":"-"},"content":" this.created_at \u003d moment(githubIssue.created_at).format(\u0027lll\u0027);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" this.updated_at \u003d moment(githubIssue.updated_at).format(\u0027lll\u0027);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" this.closed_at \u003d moment(githubIssue.closed_at).format(\u0027lll\u0027);"},{"lineNumber":82,"author":{"gitId":"-"},"content":" this.title \u003d githubIssue.title;"},{"lineNumber":83,"author":{"gitId":"-"},"content":" this.hiddenDataInDescription \u003d new HiddenData(githubIssue.body);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" this.description \u003d Issue.updateDescription(this.hiddenDataInDescription.originalStringWithoutHiddenData);"},{"lineNumber":85,"author":{"gitId":"-"},"content":" this.state \u003d githubIssue.state;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" this.stateReason \u003d githubIssue.stateReason;"},{"lineNumber":87,"author":{"gitId":"-"},"content":" this.issueOrPr \u003d githubIssue.issueOrPr;"},{"lineNumber":88,"author":{"gitId":"-"},"content":" this.author \u003d githubIssue.user.login;"},{"lineNumber":89,"author":{"gitId":"-"},"content":" // this.githubIssue \u003d githubIssue;"},{"lineNumber":90,"author":{"gitId":"-"},"content":" this.isDraft \u003d githubIssue.isDraft;"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" this.assignees \u003d githubIssue.assignees.map((assignee) \u003d\u003e assignee.login);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" this.githubLabels \u003d githubIssue.labels;"},{"lineNumber":94,"author":{"gitId":"-"},"content":" this.labels \u003d githubIssue.labels.map((label) \u003d\u003e label.name);"},{"lineNumber":95,"author":{"gitId":"MadLamprey"},"content":" this.milestone \u003d githubIssue.milestone"},{"lineNumber":96,"author":{"gitId":"MadLamprey"},"content":" ? new Milestone(githubIssue.milestone)"},{"lineNumber":97,"author":{"gitId":"MadLamprey"},"content":" : this.issueOrPr \u003d\u003d\u003d \u0027Issue\u0027"},{"lineNumber":98,"author":{"gitId":"MadLamprey"},"content":" ? Milestone.IssueWithoutMilestone"},{"lineNumber":99,"author":{"gitId":"MadLamprey"},"content":" : Milestone.PRWithoutMilestone;"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" public static createPhaseBugReportingIssue(githubIssue: GithubIssue): Issue {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" return new Issue(githubIssue);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" createGithubIssueDescription(): string {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" return `${this.description}\\n${this.hiddenDataInDescription.toString()}`;"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":"}"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":"export interface Issues {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" [id: number]: Issue;"},{"lineNumber":113,"author":{"gitId":"-"},"content":"}"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":"export const IssuesFilter \u003d {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" issuesViewer: {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" Student: \u0027NO_FILTER\u0027,"},{"lineNumber":118,"author":{"gitId":"-"},"content":" Tutor: \u0027NO_FILTER\u0027,"},{"lineNumber":119,"author":{"gitId":"-"},"content":" Admin: \u0027NO_FILTER\u0027"},{"lineNumber":120,"author":{"gitId":"-"},"content":" }"},{"lineNumber":121,"author":{"gitId":"-"},"content":"};"}],"authorContributionMap":{"NereusWB922":1,"MadLamprey":5,"-":115}},{"path":"src/app/core/models/label.model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":2,"author":{"gitId":"-"},"content":" * Represents a label and its attributes."},{"lineNumber":3,"author":{"gitId":"-"},"content":" */"},{"lineNumber":4,"author":{"gitId":"-"},"content":"export class Label implements SimpleLabel {"},{"lineNumber":5,"author":{"gitId":"-"},"content":" readonly name: string;"},{"lineNumber":6,"author":{"gitId":"-"},"content":" color: string;"},{"lineNumber":7,"author":{"gitId":"-"},"content":" definition?: string;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":" constructor(label: { name: string; color: string; definition?: string }) {"},{"lineNumber":10,"author":{"gitId":"nknguyenhc"},"content":" this.name \u003d label.name;"},{"lineNumber":11,"author":{"gitId":"-"},"content":" this.color \u003d label.color;"},{"lineNumber":12,"author":{"gitId":"-"},"content":" this.definition \u003d label.definition;"},{"lineNumber":13,"author":{"gitId":"-"},"content":" }"},{"lineNumber":14,"author":{"gitId":"-"},"content":"}"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * Represents a simplified label with name and color"},{"lineNumber":18,"author":{"gitId":"-"},"content":" */"},{"lineNumber":19,"author":{"gitId":"-"},"content":"export type SimpleLabel \u003d {"},{"lineNumber":20,"author":{"gitId":"nknguyenhc"},"content":" name: string;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" color: string;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"};"}],"authorContributionMap":{"nknguyenhc":2,"-":20}},{"path":"src/app/core/models/milestone.model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Group } from \u0027./github/group.interface\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":4,"author":{"gitId":"-"},"content":" * Represents a milestone and its attributes fetched from Github."},{"lineNumber":5,"author":{"gitId":"-"},"content":" */"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"export class Milestone implements Group {"},{"lineNumber":7,"author":{"gitId":"MadLamprey"},"content":" static IssueWithoutMilestone: Milestone \u003d new Milestone({ title: \u0027Issue without a milestone\u0027, state: null });"},{"lineNumber":8,"author":{"gitId":"MadLamprey"},"content":" static PRWithoutMilestone: Milestone \u003d new Milestone({ title: \u0027PR without a milestone\u0027, state: null });"},{"lineNumber":9,"author":{"gitId":"-"},"content":" title: string;"},{"lineNumber":10,"author":{"gitId":"-"},"content":" state: string;"},{"lineNumber":11,"author":{"gitId":"nknguyenhc"},"content":" deadline?: Date;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"nknguyenhc"},"content":" constructor(milestone: { title: string; state: string; due_on?: string }) {"},{"lineNumber":14,"author":{"gitId":"-"},"content":" this.title \u003d milestone.title;"},{"lineNumber":15,"author":{"gitId":"-"},"content":" this.state \u003d milestone.state;"},{"lineNumber":16,"author":{"gitId":"nknguyenhc"},"content":" this.deadline \u003d milestone.due_on ? new Date(milestone.due_on) : undefined;"},{"lineNumber":17,"author":{"gitId":"-"},"content":" }"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" public equals(other: any) {"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" if (!(other instanceof Milestone)) {"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" return false;"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" return this.title \u003d\u003d\u003d other.title;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" }"},{"lineNumber":25,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":3,"NereusWB922":8,"MadLamprey":2,"-":12}},{"path":"src/app/core/models/repo-change-response.model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"Arif-Khalid"},"content":"/**"},{"lineNumber":2,"author":{"gitId":"Arif-Khalid"},"content":" * Represents the response of the repo-change-form component"},{"lineNumber":3,"author":{"gitId":"Arif-Khalid"},"content":" */"},{"lineNumber":4,"author":{"gitId":"Arif-Khalid"},"content":"export type RepoChangeResponse \u003d {"},{"lineNumber":5,"author":{"gitId":"Arif-Khalid"},"content":" repo: string;"},{"lineNumber":6,"author":{"gitId":"Arif-Khalid"},"content":" keepFilters: boolean;"},{"lineNumber":7,"author":{"gitId":"Arif-Khalid"},"content":"};"}],"authorContributionMap":{"Arif-Khalid":7}},{"path":"src/app/core/models/session.model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { pipe } from \u0027rxjs\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { throwIfFalse } from \u0027../../shared/lib/custom-ops\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { Repo } from \u0027./repo.model\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { View } from \u0027./view.model\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" * Session repository comprises the view and its corresponding repository array."},{"lineNumber":8,"author":{"gitId":"-"},"content":" */"},{"lineNumber":9,"author":{"gitId":"-"},"content":"export interface SessionRepo {"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" view: View;"},{"lineNumber":11,"author":{"gitId":"-"},"content":" repos: Repo[];"},{"lineNumber":12,"author":{"gitId":"-"},"content":"}"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":15,"author":{"gitId":"-"},"content":" * Session data comprises an array of session repositories."},{"lineNumber":16,"author":{"gitId":"-"},"content":" */"},{"lineNumber":17,"author":{"gitId":"-"},"content":"export interface SessionData {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" sessionRepo: SessionRepo[];"},{"lineNumber":19,"author":{"gitId":"-"},"content":"}"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"export const SESSION_DATA_UNAVAILABLE \u003d \u0027Session data does not exist.\u0027;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"export const SESSION_DATA_MISSING_FIELDS \u003d \u0027Session data does not contain any repositories.\u0027;"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":"export const NO_VALID_OPEN_VIEWS \u003d \u0027Invalid views in Session data.\u0027;"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":"export const OPENED_VIEW_REPO_UNDEFINED \u003d \u0027View has no repo defined.\u0027;"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":"export function assertSessionDataIntegrity() {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" return pipe("},{"lineNumber":28,"author":{"gitId":"-"},"content":" throwIfFalse("},{"lineNumber":29,"author":{"gitId":"-"},"content":" (sessionData) \u003d\u003e sessionData !\u003d\u003d undefined,"},{"lineNumber":30,"author":{"gitId":"-"},"content":" () \u003d\u003e new Error(SESSION_DATA_UNAVAILABLE)"},{"lineNumber":31,"author":{"gitId":"-"},"content":" ),"},{"lineNumber":32,"author":{"gitId":"-"},"content":" throwIfFalse(hasSessionRepo, () \u003d\u003e new Error(SESSION_DATA_MISSING_FIELDS)),"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" throwIfFalse(areViewsValid, () \u003d\u003e new Error(NO_VALID_OPEN_VIEWS)),"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" throwIfFalse(areReposDefined, () \u003d\u003e new Error(OPENED_VIEW_REPO_UNDEFINED))"},{"lineNumber":35,"author":{"gitId":"-"},"content":" );"},{"lineNumber":36,"author":{"gitId":"-"},"content":"}"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":39,"author":{"gitId":"-"},"content":" * Checks if Session Data has all its crucial fields present."},{"lineNumber":40,"author":{"gitId":"-"},"content":" * @param sessionData"},{"lineNumber":41,"author":{"gitId":"-"},"content":" */"},{"lineNumber":42,"author":{"gitId":"-"},"content":"function hasSessionRepo(sessionData: SessionData): boolean {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" return sessionData.sessionRepo !\u003d null \u0026\u0026 Array.isArray(sessionData.sessionRepo) \u0026\u0026 sessionData.sessionRepo.length \u003e 0;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"}"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" * Checks if Views belong to a pre-defined View."},{"lineNumber":48,"author":{"gitId":"-"},"content":" * @param sessionData"},{"lineNumber":49,"author":{"gitId":"-"},"content":" */"},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":"function areViewsValid(sessionData: SessionData): boolean {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" return sessionData.sessionRepo.reduce("},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" (isViewValidSoFar: boolean, currentViewRepo: SessionRepo) \u003d\u003e isViewValidSoFar \u0026\u0026 currentViewRepo.view in View,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" true"},{"lineNumber":54,"author":{"gitId":"-"},"content":" );"},{"lineNumber":55,"author":{"gitId":"-"},"content":"}"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" * Checks if each View has an associated repo defined as well."},{"lineNumber":59,"author":{"gitId":"-"},"content":" * @param sessionData"},{"lineNumber":60,"author":{"gitId":"-"},"content":" */"},{"lineNumber":61,"author":{"gitId":"-"},"content":"function areReposDefined(sessionData: SessionData): boolean {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" return sessionData.sessionRepo.reduce("},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" (isViewRepoDefinedSoFar: boolean, currentViewRepo: SessionRepo) \u003d\u003e"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" isViewRepoDefinedSoFar \u0026\u0026 !!currentViewRepo.repos \u0026\u0026 Array.isArray(currentViewRepo.repos) \u0026\u0026 currentViewRepo.repos.length \u003e 0,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" true"},{"lineNumber":66,"author":{"gitId":"-"},"content":" );"},{"lineNumber":67,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"NereusWB922":13,"-":54}},{"path":"src/app/core/models/view.model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"export enum View {"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" issuesViewer \u003d \u0027issuesViewer\u0027,"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" activityDashboard \u003d \u0027activityDashboard\u0027"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":4}},{"path":"src/app/core/services/auth.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Injectable, NgZone } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Title } from \u0027@angular/platform-browser\u0027;"},{"lineNumber":3,"author":{"gitId":"nknguyenhc"},"content":"import { Router, RouterStateSnapshot } from \u0027@angular/router\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { BehaviorSubject, from, Observable, of } from \u0027rxjs\u0027;"},{"lineNumber":5,"author":{"gitId":"nknguyenhc"},"content":"import { catchError, map, mergeMap } from \u0027rxjs/operators\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { AppConfig } from \u0027../../../environments/environment\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { generateSessionId } from \u0027../../shared/lib/session\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { uuid } from \u0027../../shared/lib/uuid\u0027;"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"import { View } from \u0027../models/view.model\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { ErrorHandlingService } from \u0027./error-handling.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027./github.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { GithubEventService } from \u0027./githubevent.service\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { IssueService } from \u0027./issue.service\u0027;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import { LabelService } from \u0027./label.service\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027./logging.service\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import { UserService } from \u0027./user.service\u0027;"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":"import { ViewService } from \u0027./view.service\u0027;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"export enum AuthState {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u0027NotAuthenticated\u0027,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u0027AwaitingAuthentication\u0027,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u0027ConfirmOAuthUser\u0027,"},{"lineNumber":23,"author":{"gitId":"-"},"content":" \u0027Authenticated\u0027"},{"lineNumber":24,"author":{"gitId":"-"},"content":"}"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":27,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":28,"author":{"gitId":"-"},"content":"})"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":31,"author":{"gitId":"-"},"content":" * Responsible for initiating the authentication process and querying or"},{"lineNumber":32,"author":{"gitId":"-"},"content":" * updating the application state with regards to authentication."},{"lineNumber":33,"author":{"gitId":"-"},"content":" */"},{"lineNumber":34,"author":{"gitId":"-"},"content":"export class AuthService {"},{"lineNumber":35,"author":{"gitId":"nknguyenhc"},"content":" private static readonly DEFAULT_NO_PERMISSION_TO_PRIVATE_REPOS \u003d false;"},{"lineNumber":36,"author":{"gitId":"nknguyenhc"},"content":" private static readonly SESSION_NEXT_KEY \u003d \u0027next\u0027;"},{"lineNumber":37,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" authStateSource \u003d new BehaviorSubject(AuthState.NotAuthenticated);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" currentAuthState \u003d this.authStateSource.asObservable();"},{"lineNumber":40,"author":{"gitId":"-"},"content":" accessToken \u003d new BehaviorSubject(undefined);"},{"lineNumber":41,"author":{"gitId":"-"},"content":" private state: string;"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" ENABLE_POPUP_MESSAGE \u003d \u0027Please enable pop-ups in your browser\u0027;"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" constructor("},{"lineNumber":46,"author":{"gitId":"-"},"content":" private router: Router,"},{"lineNumber":47,"author":{"gitId":"-"},"content":" private ngZone: NgZone,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" private githubService: GithubService,"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private userService: UserService,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" private issueService: IssueService,"},{"lineNumber":51,"author":{"gitId":"-"},"content":" private labelService: LabelService,"},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" private viewService: ViewService,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" private githubEventService: GithubEventService,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" private titleService: Title,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" private errorHandlingService: ErrorHandlingService,"},{"lineNumber":56,"author":{"gitId":"-"},"content":" private logger: LoggingService"},{"lineNumber":57,"author":{"gitId":"-"},"content":" ) {}"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":60,"author":{"gitId":"nknguyenhc"},"content":" * Stores the data about the next route in the session storage."},{"lineNumber":61,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":62,"author":{"gitId":"nknguyenhc"},"content":" storeNext(next: RouterStateSnapshot) {"},{"lineNumber":63,"author":{"gitId":"nknguyenhc"},"content":" sessionStorage.setItem(AuthService.SESSION_NEXT_KEY, next.url);"},{"lineNumber":64,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":65,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":66,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":67,"author":{"gitId":"nknguyenhc"},"content":" * Checks if there is a next route to be redirected to after login,"},{"lineNumber":68,"author":{"gitId":"nknguyenhc"},"content":" * by checking the session storage."},{"lineNumber":69,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":70,"author":{"gitId":"nknguyenhc"},"content":" hasNext(): boolean {"},{"lineNumber":71,"author":{"gitId":"nknguyenhc"},"content":" return sessionStorage.getItem(AuthService.SESSION_NEXT_KEY) !\u003d\u003d null;"},{"lineNumber":72,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":73,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":74,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":75,"author":{"gitId":"nknguyenhc"},"content":" * Checks if there is a next route to be redirected to after login,"},{"lineNumber":76,"author":{"gitId":"nknguyenhc"},"content":" * and start OAuth process automatically if there is."},{"lineNumber":77,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":78,"author":{"gitId":"nknguyenhc"},"content":" startOAuthIfHasNext() {"},{"lineNumber":79,"author":{"gitId":"nknguyenhc"},"content":" if (this.hasNext()) {"},{"lineNumber":80,"author":{"gitId":"nknguyenhc"},"content":" this.logger.info(`AuthService: Start OAuth because there is a next route`);"},{"lineNumber":81,"author":{"gitId":"nknguyenhc"},"content":" this.startOAuthProcess(AuthService.DEFAULT_NO_PERMISSION_TO_PRIVATE_REPOS);"},{"lineNumber":82,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":83,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":84,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":85,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":86,"author":{"gitId":"nknguyenhc"},"content":" * Checks if there is a next route to be redirected to after login,"},{"lineNumber":87,"author":{"gitId":"nknguyenhc"},"content":" * and complete the login process if there is."},{"lineNumber":88,"author":{"gitId":"nknguyenhc"},"content":" * Assuming that user has authenticated on Github, and the app is awaiting confirmation."},{"lineNumber":89,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":90,"author":{"gitId":"nknguyenhc"},"content":" completeLoginIfHasNext(username: string) {"},{"lineNumber":91,"author":{"gitId":"nknguyenhc"},"content":" if (!this.hasNext()) {"},{"lineNumber":92,"author":{"gitId":"nknguyenhc"},"content":" return;"},{"lineNumber":93,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":94,"author":{"gitId":"nknguyenhc"},"content":" this.logger.info(`AuthService: Automatically complete login because there is a next route`);"},{"lineNumber":95,"author":{"gitId":"nknguyenhc"},"content":" this.changeAuthState(AuthState.AwaitingAuthentication);"},{"lineNumber":96,"author":{"gitId":"nknguyenhc"},"content":" this.userService.createUserModel(username).subscribe("},{"lineNumber":97,"author":{"gitId":"nknguyenhc"},"content":" () \u003d\u003e {"},{"lineNumber":98,"author":{"gitId":"nknguyenhc"},"content":" this.changeAuthState(AuthState.Authenticated);"},{"lineNumber":99,"author":{"gitId":"nknguyenhc"},"content":" },"},{"lineNumber":100,"author":{"gitId":"nknguyenhc"},"content":" (err) \u003d\u003e {"},{"lineNumber":101,"author":{"gitId":"nknguyenhc"},"content":" this.changeAuthState(AuthState.NotAuthenticated);"},{"lineNumber":102,"author":{"gitId":"nknguyenhc"},"content":" this.errorHandlingService.handleError(err);"},{"lineNumber":103,"author":{"gitId":"nknguyenhc"},"content":" this.logger.info(`AuthService: Automatic completion of login failed with an error: ${err}`);"},{"lineNumber":104,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":105,"author":{"gitId":"nknguyenhc"},"content":" );"},{"lineNumber":106,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":107,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":108,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":109,"author":{"gitId":"nknguyenhc"},"content":" * Clears the next route from the session storage."},{"lineNumber":110,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":111,"author":{"gitId":"nknguyenhc"},"content":" clearNext() {"},{"lineNumber":112,"author":{"gitId":"nknguyenhc"},"content":" sessionStorage.removeItem(AuthService.SESSION_NEXT_KEY);"},{"lineNumber":113,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":114,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":115,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":116,"author":{"gitId":"nknguyenhc"},"content":" * Redirect to the URL indicating the next route."},{"lineNumber":117,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":118,"author":{"gitId":"nknguyenhc"},"content":" redirectToNext() {"},{"lineNumber":119,"author":{"gitId":"nknguyenhc"},"content":" const next \u003d sessionStorage.getItem(AuthService.SESSION_NEXT_KEY);"},{"lineNumber":120,"author":{"gitId":"NereusWB922"},"content":" this.viewService"},{"lineNumber":121,"author":{"gitId":"nknguyenhc"},"content":" .setupFromUrl(next)"},{"lineNumber":122,"author":{"gitId":"nknguyenhc"},"content":" .pipe("},{"lineNumber":123,"author":{"gitId":"nknguyenhc"},"content":" mergeMap(() \u003d\u003e this.setRepo()),"},{"lineNumber":124,"author":{"gitId":"nknguyenhc"},"content":" catchError((err) \u003d\u003e {"},{"lineNumber":125,"author":{"gitId":"nknguyenhc"},"content":" this.logger.info(`AuthService: Failed to redirect to next URL with error: ${err}`);"},{"lineNumber":126,"author":{"gitId":"nknguyenhc"},"content":" this.errorHandlingService.handleError(err);"},{"lineNumber":127,"author":{"gitId":"nknguyenhc"},"content":" this.clearNext();"},{"lineNumber":128,"author":{"gitId":"nknguyenhc"},"content":" return of(false);"},{"lineNumber":129,"author":{"gitId":"nknguyenhc"},"content":" })"},{"lineNumber":130,"author":{"gitId":"nknguyenhc"},"content":" )"},{"lineNumber":131,"author":{"gitId":"nknguyenhc"},"content":" .subscribe((isSetupSuccesssful) \u003d\u003e {"},{"lineNumber":132,"author":{"gitId":"nknguyenhc"},"content":" if (isSetupSuccesssful) {"},{"lineNumber":133,"author":{"gitId":"nknguyenhc"},"content":" this.router.navigateByUrl(next);"},{"lineNumber":134,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":135,"author":{"gitId":"nknguyenhc"},"content":" });"},{"lineNumber":136,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":137,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":139,"author":{"gitId":"-"},"content":" * Will store the OAuth token."},{"lineNumber":140,"author":{"gitId":"-"},"content":" */"},{"lineNumber":141,"author":{"gitId":"-"},"content":" storeOAuthAccessToken(token: string) {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" this.githubService.storeOAuthAccessToken(token);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" this.accessToken.next(token);"},{"lineNumber":144,"author":{"gitId":"-"},"content":" }"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" reset(): void {"},{"lineNumber":147,"author":{"gitId":"-"},"content":" this.logger.info(\u0027AuthService: Clearing access token and setting AuthState to NotAuthenticated.\u0027);"},{"lineNumber":148,"author":{"gitId":"-"},"content":" this.accessToken.next(undefined);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" this.changeAuthState(AuthState.NotAuthenticated);"},{"lineNumber":150,"author":{"gitId":"-"},"content":" this.ngZone.run(() \u003d\u003e this.router.navigate([\u0027\u0027]));"},{"lineNumber":151,"author":{"gitId":"-"},"content":" }"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":" logOut(): void {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" this.githubService.reset();"},{"lineNumber":155,"author":{"gitId":"-"},"content":" this.userService.reset();"},{"lineNumber":156,"author":{"gitId":"-"},"content":" this.issueService.reset(true);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" this.labelService.reset();"},{"lineNumber":158,"author":{"gitId":"NereusWB922"},"content":" this.viewService.reset();"},{"lineNumber":159,"author":{"gitId":"-"},"content":" this.githubEventService.reset();"},{"lineNumber":160,"author":{"gitId":"-"},"content":" this.logger.reset();"},{"lineNumber":161,"author":{"gitId":"-"},"content":" this.setLandingPageTitle();"},{"lineNumber":162,"author":{"gitId":"-"},"content":" this.issueService.setIssueTeamFilter(\u0027All Teams\u0027);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" this.reset();"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"NereusWB922"},"content":" setTitleWithViewDetail(): void {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" const appSetting \u003d require(\u0027../../../../package.json\u0027);"},{"lineNumber":168,"author":{"gitId":"NereusWB922"},"content":" const title \u003d `${appSetting.name} ${appSetting.version} - ${this.viewService.getCurrentRepositoryURL()}`;"},{"lineNumber":169,"author":{"gitId":"-"},"content":" this.logger.info(`AuthService: Setting Title as ${title}`);"},{"lineNumber":170,"author":{"gitId":"-"},"content":" this.titleService.setTitle(title);"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" setLandingPageTitle(): void {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" const appSetting \u003d require(\u0027../../../../package.json\u0027);"},{"lineNumber":175,"author":{"gitId":"-"},"content":" const title \u003d `${appSetting.name} ${appSetting.version}`;"},{"lineNumber":176,"author":{"gitId":"-"},"content":" this.logger.info(`AuthService: Setting Title as ${title}`);"},{"lineNumber":177,"author":{"gitId":"-"},"content":" this.titleService.setTitle(title);"},{"lineNumber":178,"author":{"gitId":"-"},"content":" }"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" isAuthenticated(): boolean {"},{"lineNumber":181,"author":{"gitId":"-"},"content":" return this.authStateSource.getValue() \u003d\u003d\u003d AuthState.Authenticated;"},{"lineNumber":182,"author":{"gitId":"-"},"content":" }"},{"lineNumber":183,"author":{"gitId":"-"},"content":""},{"lineNumber":184,"author":{"gitId":"-"},"content":" changeAuthState(newAuthState: AuthState) {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" if (newAuthState \u003d\u003d\u003d AuthState.Authenticated) {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" const sessionId \u003d generateSessionId();"},{"lineNumber":187,"author":{"gitId":"-"},"content":" this.issueService.setSessionId(sessionId);"},{"lineNumber":188,"author":{"gitId":"-"},"content":" this.logger.info(`AuthService: Successfully authenticated with session: ${sessionId}`);"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":" this.authStateSource.next(newAuthState);"},{"lineNumber":191,"author":{"gitId":"-"},"content":" }"},{"lineNumber":192,"author":{"gitId":"-"},"content":""},{"lineNumber":193,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":194,"author":{"gitId":"-"},"content":" * Generates and assigns an unguessable random \u0027state\u0027 string to pass to Github for protection against cross-site request forgery attacks"},{"lineNumber":195,"author":{"gitId":"-"},"content":" */"},{"lineNumber":196,"author":{"gitId":"-"},"content":" generateStateString() {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" this.state \u003d uuid();"},{"lineNumber":198,"author":{"gitId":"-"},"content":" sessionStorage.setItem(\u0027state\u0027, this.state);"},{"lineNumber":199,"author":{"gitId":"-"},"content":" }"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":" isReturnedStateSame(returnedState: string): boolean {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" const state \u003d sessionStorage.getItem(\u0027state\u0027);"},{"lineNumber":203,"author":{"gitId":"-"},"content":" return returnedState \u003d\u003d\u003d state;"},{"lineNumber":204,"author":{"gitId":"-"},"content":" }"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":207,"author":{"gitId":"-"},"content":" * Will start the Github OAuth web flow process."},{"lineNumber":208,"author":{"gitId":"-"},"content":" */"},{"lineNumber":209,"author":{"gitId":"-"},"content":" startOAuthProcess(hasPrivateConsent: boolean) {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" this.logger.info(\u0027AuthService: Starting authentication\u0027);"},{"lineNumber":211,"author":{"gitId":"-"},"content":" // Available OAuth scopes https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps#available-scopes"},{"lineNumber":212,"author":{"gitId":"-"},"content":" let permissionLevel \u003d \u0027public-repo\u0027;"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" if (hasPrivateConsent) {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" // grants WATcher access to private repos if user allows"},{"lineNumber":216,"author":{"gitId":"-"},"content":" permissionLevel \u003d \u0027repo\u0027;"},{"lineNumber":217,"author":{"gitId":"-"},"content":" }"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":" const githubRepoPermission \u003d permissionLevel; // don\u0027t allow changes after logging ins"},{"lineNumber":220,"author":{"gitId":"-"},"content":""},{"lineNumber":221,"author":{"gitId":"-"},"content":" this.changeAuthState(AuthState.AwaitingAuthentication);"},{"lineNumber":222,"author":{"gitId":"-"},"content":""},{"lineNumber":223,"author":{"gitId":"-"},"content":" this.generateStateString();"},{"lineNumber":224,"author":{"gitId":"-"},"content":" this.redirectToOAuthPage("},{"lineNumber":225,"author":{"gitId":"-"},"content":" encodeURI("},{"lineNumber":226,"author":{"gitId":"-"},"content":" `${AppConfig.githubUrl}/login/oauth/authorize?client_id\u003d${AppConfig.clientId}\u0026scope\u003d${githubRepoPermission},read:user\u0026state\u003d${this.state}`"},{"lineNumber":227,"author":{"gitId":"-"},"content":" )"},{"lineNumber":228,"author":{"gitId":"-"},"content":" );"},{"lineNumber":229,"author":{"gitId":"-"},"content":" this.logger.info(`AuthService: Redirecting for Github authentication`);"},{"lineNumber":230,"author":{"gitId":"-"},"content":" }"},{"lineNumber":231,"author":{"gitId":"-"},"content":""},{"lineNumber":232,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":233,"author":{"gitId":"-"},"content":" * Handles the clean up required after authentication and setting up of repository is completed."},{"lineNumber":234,"author":{"gitId":"-"},"content":" */"},{"lineNumber":235,"author":{"gitId":"nknguyenhc"},"content":" handleSetRepoSuccess(repoName: string) {"},{"lineNumber":236,"author":{"gitId":"NereusWB922"},"content":" this.setTitleWithViewDetail();"},{"lineNumber":237,"author":{"gitId":"NereusWB922"},"content":" this.router.navigate([View.issuesViewer], {"},{"lineNumber":238,"author":{"gitId":"nknguyenhc"},"content":" queryParams: {"},{"lineNumber":239,"author":{"gitId":"NereusWB922"},"content":" [ViewService.REPO_QUERY_PARAM_KEY]: repoName"},{"lineNumber":240,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":241,"author":{"gitId":"nknguyenhc"},"content":" });"},{"lineNumber":242,"author":{"gitId":"-"},"content":" }"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":245,"author":{"gitId":"-"},"content":" * Setup repository after authentication."},{"lineNumber":246,"author":{"gitId":"-"},"content":" */"},{"lineNumber":247,"author":{"gitId":"-"},"content":" setRepo(): Observable\u003cboolean\u003e {"},{"lineNumber":248,"author":{"gitId":"NereusWB922"},"content":" return from(this.viewService.initializeCurrentRepository()).pipe("},{"lineNumber":249,"author":{"gitId":"-"},"content":" map(() \u003d\u003e {"},{"lineNumber":250,"author":{"gitId":"NereusWB922"},"content":" if (!this.viewService.currentRepo) {"},{"lineNumber":251,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":252,"author":{"gitId":"-"},"content":" }"},{"lineNumber":253,"author":{"gitId":"-"},"content":" this.githubEventService.setLatestChangeEvent();"},{"lineNumber":254,"author":{"gitId":"NereusWB922"},"content":" this.handleSetRepoSuccess(this.viewService.currentRepo.toString());"},{"lineNumber":255,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":256,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":257,"author":{"gitId":"-"},"content":" catchError((error) \u003d\u003e {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" this.errorHandlingService.handleError(error);"},{"lineNumber":259,"author":{"gitId":"nknguyenhc"},"content":" this.clearNext();"},{"lineNumber":260,"author":{"gitId":"-"},"content":" return of(false);"},{"lineNumber":261,"author":{"gitId":"-"},"content":" })"},{"lineNumber":262,"author":{"gitId":"-"},"content":" );"},{"lineNumber":263,"author":{"gitId":"-"},"content":" }"},{"lineNumber":264,"author":{"gitId":"-"},"content":""},{"lineNumber":265,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":266,"author":{"gitId":"-"},"content":" * Will redirect to GitHub OAuth page"},{"lineNumber":267,"author":{"gitId":"-"},"content":" */"},{"lineNumber":268,"author":{"gitId":"-"},"content":" private redirectToOAuthPage(url: string): void {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" if (url \u003d\u003d null) {"},{"lineNumber":270,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":271,"author":{"gitId":"-"},"content":" }"},{"lineNumber":272,"author":{"gitId":"-"},"content":" window.location.href \u003d url;"},{"lineNumber":273,"author":{"gitId":"-"},"content":" }"},{"lineNumber":274,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":88,"NereusWB922":14,"-":172}},{"path":"src/app/core/services/error-message.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":4,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":5,"author":{"gitId":"-"},"content":"})"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":8,"author":{"gitId":"-"},"content":" * Contains all error message prompts to user."},{"lineNumber":9,"author":{"gitId":"-"},"content":" */"},{"lineNumber":10,"author":{"gitId":"-"},"content":"export class ErrorMessageService {"},{"lineNumber":11,"author":{"gitId":"-"},"content":" public static repositoryNotPresentMessage() {"},{"lineNumber":12,"author":{"gitId":"-"},"content":" return \u0027Invalid repository name. Please provide Github repository URL or the repository name in the format Org/Repository Name.\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":" }"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"nknguyenhc"},"content":" public static invalidUrlMessage() {"},{"lineNumber":16,"author":{"gitId":"nknguyenhc"},"content":" return \u0027URL is invalid, or repository does not exist, please indicate the repository you wish to view to continue.\u0027;"},{"lineNumber":17,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":18,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":" public static unableToFetchIssuesMessage() {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch issue.\u0027;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" }"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" public static unableToFetchMilestoneMessage() {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch milestones.\u0027;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" public static unableToFetchLabelsMessage() {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch labels.\u0027;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" public static usersUnassignableMessage(assignee: string) {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" return `Cannot assign ${assignee} to the issue. Please check if ${assignee} is authorized.`;"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" public static unableToFetchUsersMessage() {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch assignable users for repository\u0027;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" }"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" public static unableToFetchEventsMessage() {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch issue events for repository\u0027;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" public static unableToFetchActivityEventsMessage() {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch activity events for repository\u0027;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" public static unableToFetchDataFileMessage() {"},{"lineNumber":48,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch data file.\u0027;"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" public static unableToFetchLatestReleaseMessage() {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch latest release.\u0027;"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" public static unableToFetchSettingsFileMessage() {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch settings file.\u0027;"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" public static unableToFetchAuthenticatedUsersMessage() {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch authenticated user.\u0027;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" public static unableToOpenInBrowserMessage() {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" return \u0027Unable to open this issue in Browser\u0027;"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" public static applicationVersionOutdatedMessage() {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" return \u0027Please update to the latest version of WATcher.\u0027;"},{"lineNumber":69,"author":{"gitId":"-"},"content":" }"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" public static multipleDropdownOptionsErrorMessage() {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" return \u0027Supply either Dropdown option number or text, not both.\u0027;"},{"lineNumber":73,"author":{"gitId":"-"},"content":" }"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" public static noDropdownOptionsErrorMessage() {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" return \u0027No Dropdown identification parameters supplied.\u0027;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":4,"-":74}},{"path":"src/app/core/services/factories/factory.auth.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { NgZone } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Title } from \u0027@angular/platform-browser\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { Router } from \u0027@angular/router\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"// import { AppConfig } from \u0027../../../../environments/environment\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { AuthService } from \u0027../auth.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { ErrorHandlingService } from \u0027../error-handling.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027../github.service\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { GithubEventService } from \u0027../githubevent.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { IssueService } from \u0027../issue.service\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { LabelService } from \u0027../label.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027../logging.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"// import { MockAuthService } from \u0027../mocks/mock.auth.service\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { UserService } from \u0027../user.service\u0027;"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"import { ViewService } from \u0027../view.service\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"export function AuthServiceFactory("},{"lineNumber":17,"author":{"gitId":"-"},"content":" router: Router,"},{"lineNumber":18,"author":{"gitId":"-"},"content":" ngZone: NgZone,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" githubService: GithubService,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" userService: UserService,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" issueService: IssueService,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" labelService: LabelService,"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" viewService: ViewService,"},{"lineNumber":24,"author":{"gitId":"-"},"content":" githubEventService: GithubEventService,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" titleService: Title,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" errorHandlingService: ErrorHandlingService,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" logger: LoggingService"},{"lineNumber":28,"author":{"gitId":"-"},"content":") {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" // TODO: Write Mocks"},{"lineNumber":30,"author":{"gitId":"-"},"content":" // if (AppConfig.test) {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" // return new MockAuthService("},{"lineNumber":32,"author":{"gitId":"-"},"content":" // router,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" // ngZone,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" // githubService,"},{"lineNumber":35,"author":{"gitId":"-"},"content":" // userService,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" // issueService,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" // labelService,"},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" // viewService,"},{"lineNumber":39,"author":{"gitId":"-"},"content":" // githubEventService,"},{"lineNumber":40,"author":{"gitId":"-"},"content":" // titleService,"},{"lineNumber":41,"author":{"gitId":"-"},"content":" // logger"},{"lineNumber":42,"author":{"gitId":"-"},"content":" // );"},{"lineNumber":43,"author":{"gitId":"-"},"content":" // }"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return new AuthService("},{"lineNumber":45,"author":{"gitId":"-"},"content":" router,"},{"lineNumber":46,"author":{"gitId":"-"},"content":" ngZone,"},{"lineNumber":47,"author":{"gitId":"-"},"content":" githubService,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" userService,"},{"lineNumber":49,"author":{"gitId":"-"},"content":" issueService,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" labelService,"},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":" viewService,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" githubEventService,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" titleService,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" errorHandlingService,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" logger"},{"lineNumber":56,"author":{"gitId":"-"},"content":" );"},{"lineNumber":57,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"NereusWB922":4,"-":53}},{"path":"src/app/core/services/factories/factory.github.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Apollo } from \u0027apollo-angular\u0027;"},{"lineNumber":2,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"// import { AppConfig } from \u0027../../../../environments/environment\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { ErrorHandlingService } from \u0027../error-handling.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027../github.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027../logging.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"// import { MockGithubService } from \u0027../mocks/mock.github.service\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"export function GithubServiceFactory(handling: ErrorHandlingService, apollo: Apollo, logger: LoggingService) {"},{"lineNumber":10,"author":{"gitId":"-"},"content":" // TODO: Write Mocks"},{"lineNumber":11,"author":{"gitId":"-"},"content":" // if (AppConfig.test) {"},{"lineNumber":12,"author":{"gitId":"-"},"content":" // return new MockGithubService();"},{"lineNumber":13,"author":{"gitId":"-"},"content":" // }"},{"lineNumber":14,"author":{"gitId":"-"},"content":" return new GithubService(handling, apollo, logger);"},{"lineNumber":15,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"MadLamprey":1,"-":14}},{"path":"src/app/core/services/factories/factory.issue.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"// import { AppConfig } from \u0027../../../../environments/environment\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027../github.service\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { IssueService } from \u0027../issue.service\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"// import { MockIssueService } from \u0027../mocks/mock.issue.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { UserService } from \u0027../user.service\u0027;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"import { ViewService } from \u0027../view.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"export function IssueServiceFactory(githubService: GithubService, userService: UserService, viewService: ViewService) {"},{"lineNumber":9,"author":{"gitId":"-"},"content":" // TODO: Write Mocks"},{"lineNumber":10,"author":{"gitId":"-"},"content":" // if (AppConfig.test) {"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" // return new MockIssueService(githubService, viewService, dataService);"},{"lineNumber":12,"author":{"gitId":"-"},"content":" // }"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" return new IssueService(githubService, userService, viewService);"},{"lineNumber":14,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"NereusWB922":4,"-":10}},{"path":"src/app/core/services/filters.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"Arif-Khalid"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"Arif-Khalid"},"content":"import { Sort } from \u0027@angular/material/sort\u0027;"},{"lineNumber":3,"author":{"gitId":"Arif-Khalid"},"content":"import { ActivatedRoute, Router } from \u0027@angular/router\u0027;"},{"lineNumber":4,"author":{"gitId":"Arif-Khalid"},"content":"import { BehaviorSubject, pipe } from \u0027rxjs\u0027;"},{"lineNumber":5,"author":{"gitId":"Arif-Khalid"},"content":"import { SimpleLabel } from \u0027../models/label.model\u0027;"},{"lineNumber":6,"author":{"gitId":"Arif-Khalid"},"content":"import { Milestone } from \u0027../models/milestone.model\u0027;"},{"lineNumber":7,"author":{"gitId":"Arif-Khalid"},"content":"import { LoggingService } from \u0027./logging.service\u0027;"},{"lineNumber":8,"author":{"gitId":"nknguyenhc"},"content":"import { MilestoneService } from \u0027./milestone.service\u0027;"},{"lineNumber":9,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":10,"author":{"gitId":"Arif-Khalid"},"content":"export type Filter \u003d {"},{"lineNumber":11,"author":{"gitId":"Arif-Khalid"},"content":" title: string;"},{"lineNumber":12,"author":{"gitId":"nknguyenhc"},"content":" status: string[];"},{"lineNumber":13,"author":{"gitId":"Arif-Khalid"},"content":" type: string;"},{"lineNumber":14,"author":{"gitId":"Arif-Khalid"},"content":" sort: Sort;"},{"lineNumber":15,"author":{"gitId":"Arif-Khalid"},"content":" labels: string[];"},{"lineNumber":16,"author":{"gitId":"Arif-Khalid"},"content":" milestones: string[];"},{"lineNumber":17,"author":{"gitId":"Arif-Khalid"},"content":" hiddenLabels: Set\u003cstring\u003e;"},{"lineNumber":18,"author":{"gitId":"nknguyenhc"},"content":" deselectedLabels: Set\u003cstring\u003e;"},{"lineNumber":19,"author":{"gitId":"MadLamprey"},"content":" itemsPerPage: number;"},{"lineNumber":20,"author":{"gitId":"Arif-Khalid"},"content":"};"},{"lineNumber":21,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":22,"author":{"gitId":"Arif-Khalid"},"content":"@Injectable({"},{"lineNumber":23,"author":{"gitId":"Arif-Khalid"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":24,"author":{"gitId":"Arif-Khalid"},"content":"})"},{"lineNumber":25,"author":{"gitId":"Arif-Khalid"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"Arif-Khalid"},"content":" * Responsible for centralising filters"},{"lineNumber":27,"author":{"gitId":"Arif-Khalid"},"content":" * Filters are subscribed to and emitted from this service"},{"lineNumber":28,"author":{"gitId":"Arif-Khalid"},"content":" */"},{"lineNumber":29,"author":{"gitId":"Arif-Khalid"},"content":"export class FiltersService {"},{"lineNumber":30,"author":{"gitId":"Arif-Khalid"},"content":" public static readonly PRESET_VIEW_QUERY_PARAM_KEY \u003d \u0027presetview\u0027;"},{"lineNumber":31,"author":{"gitId":"MadLamprey"},"content":" private itemsPerPage \u003d 20;"},{"lineNumber":32,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":33,"author":{"gitId":"nknguyenhc"},"content":" readonly presetViews: {"},{"lineNumber":34,"author":{"gitId":"nknguyenhc"},"content":" [key: string]: () \u003d\u003e Filter;"},{"lineNumber":35,"author":{"gitId":"nknguyenhc"},"content":" } \u003d {"},{"lineNumber":36,"author":{"gitId":"nknguyenhc"},"content":" currentlyActive: () \u003d\u003e ({"},{"lineNumber":37,"author":{"gitId":"nknguyenhc"},"content":" title: \u0027\u0027,"},{"lineNumber":38,"author":{"gitId":"nknguyenhc"},"content":" status: [\u0027open pullrequest\u0027, \u0027merged pullrequest\u0027, \u0027open issue\u0027, \u0027closed issue\u0027],"},{"lineNumber":39,"author":{"gitId":"nknguyenhc"},"content":" type: \u0027all\u0027,"},{"lineNumber":40,"author":{"gitId":"nknguyenhc"},"content":" sort: { active: \u0027status\u0027, direction: \u0027asc\u0027 },"},{"lineNumber":41,"author":{"gitId":"nknguyenhc"},"content":" labels: [],"},{"lineNumber":42,"author":{"gitId":"nknguyenhc"},"content":" milestones: this.getMilestonesForCurrentlyActive().map((milestone) \u003d\u003e milestone.title),"},{"lineNumber":43,"author":{"gitId":"nknguyenhc"},"content":" hiddenLabels: new Set\u003cstring\u003e(),"},{"lineNumber":44,"author":{"gitId":"MadLamprey"},"content":" deselectedLabels: new Set\u003cstring\u003e(),"},{"lineNumber":45,"author":{"gitId":"MadLamprey"},"content":" itemsPerPage: this.itemsPerPage"},{"lineNumber":46,"author":{"gitId":"nknguyenhc"},"content":" }),"},{"lineNumber":47,"author":{"gitId":"nknguyenhc"},"content":" contributions: () \u003d\u003e ({"},{"lineNumber":48,"author":{"gitId":"nknguyenhc"},"content":" title: \u0027\u0027,"},{"lineNumber":49,"author":{"gitId":"nknguyenhc"},"content":" status: [\u0027open pullrequest\u0027, \u0027merged pullrequest\u0027, \u0027open issue\u0027, \u0027closed issue\u0027],"},{"lineNumber":50,"author":{"gitId":"nknguyenhc"},"content":" type: \u0027all\u0027,"},{"lineNumber":51,"author":{"gitId":"nknguyenhc"},"content":" sort: { active: \u0027id\u0027, direction: \u0027desc\u0027 },"},{"lineNumber":52,"author":{"gitId":"nknguyenhc"},"content":" labels: [],"},{"lineNumber":53,"author":{"gitId":"nknguyenhc"},"content":" milestones: this.milestoneService.milestones.map((milestone) \u003d\u003e milestone.title),"},{"lineNumber":54,"author":{"gitId":"nknguyenhc"},"content":" hiddenLabels: new Set\u003cstring\u003e(),"},{"lineNumber":55,"author":{"gitId":"MadLamprey"},"content":" deselectedLabels: new Set\u003cstring\u003e(),"},{"lineNumber":56,"author":{"gitId":"MadLamprey"},"content":" itemsPerPage: this.itemsPerPage"},{"lineNumber":57,"author":{"gitId":"nknguyenhc"},"content":" }),"},{"lineNumber":58,"author":{"gitId":"nknguyenhc"},"content":" custom: () \u003d\u003e this.filter$.value"},{"lineNumber":59,"author":{"gitId":"nknguyenhc"},"content":" };"},{"lineNumber":60,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":61,"author":{"gitId":"nknguyenhc"},"content":" // List of keys in the new filter change that causes current filter to not qualify to be a preset view."},{"lineNumber":62,"author":{"gitId":"nknguyenhc"},"content":" readonly presetChangingKeys \u003d new Set\u003cstring\u003e([\u0027status\u0027, \u0027type\u0027, \u0027milestones\u0027, \u0027labels\u0027, \u0027deselectedLabels\u0027]);"},{"lineNumber":63,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":64,"author":{"gitId":"nknguyenhc"},"content":" readonly defaultFilter \u003d this.presetViews.currentlyActive;"},{"lineNumber":65,"author":{"gitId":"nknguyenhc"},"content":" public filter$ \u003d new BehaviorSubject\u003cFilter\u003e(this.defaultFilter());"},{"lineNumber":66,"author":{"gitId":"nknguyenhc"},"content":" // Either \u0027currentlyActive\u0027, \u0027contributions\u0027, or \u0027custom\u0027."},{"lineNumber":67,"author":{"gitId":"nknguyenhc"},"content":" public presetView$ \u003d new BehaviorSubject\u003cstring\u003e(\u0027currentlyActive\u0027);"},{"lineNumber":68,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":69,"author":{"gitId":"Arif-Khalid"},"content":" // Helps in determining whether all milestones were selected from previous repo during sanitization of milestones"},{"lineNumber":70,"author":{"gitId":"Arif-Khalid"},"content":" private previousMilestonesLength \u003d 0;"},{"lineNumber":71,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":72,"author":{"gitId":"Arif-Khalid"},"content":" constructor("},{"lineNumber":73,"author":{"gitId":"Arif-Khalid"},"content":" private logger: LoggingService,"},{"lineNumber":74,"author":{"gitId":"Arif-Khalid"},"content":" private router: Router,"},{"lineNumber":75,"author":{"gitId":"Arif-Khalid"},"content":" private route: ActivatedRoute,"},{"lineNumber":76,"author":{"gitId":"Arif-Khalid"},"content":" private milestoneService: MilestoneService"},{"lineNumber":77,"author":{"gitId":"MadLamprey"},"content":" ) {"},{"lineNumber":78,"author":{"gitId":"MadLamprey"},"content":" this.filter$.subscribe((filter: Filter) \u003d\u003e {"},{"lineNumber":79,"author":{"gitId":"MadLamprey"},"content":" this.itemsPerPage \u003d filter.itemsPerPage;"},{"lineNumber":80,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":81,"author":{"gitId":"MadLamprey"},"content":" }"},{"lineNumber":82,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":83,"author":{"gitId":"Arif-Khalid"},"content":" private pushFiltersToUrl(): void {"},{"lineNumber":84,"author":{"gitId":"Arif-Khalid"},"content":" const queryParams \u003d { ...this.route.snapshot.queryParams };"},{"lineNumber":85,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":86,"author":{"gitId":"Arif-Khalid"},"content":" for (const filterName of Object.keys(this.filter$.value)) {"},{"lineNumber":87,"author":{"gitId":"Arif-Khalid"},"content":" const filterValue \u003d this.filter$.value[filterName];"},{"lineNumber":88,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":89,"author":{"gitId":"Arif-Khalid"},"content":" // Don\u0027t include empty or null filters"},{"lineNumber":90,"author":{"gitId":"Arif-Khalid"},"content":" // Intended behaviour to reset to default if 0 of a certain filter are selected"},{"lineNumber":91,"author":{"gitId":"Arif-Khalid"},"content":" switch (filterName) {"},{"lineNumber":92,"author":{"gitId":"Arif-Khalid"},"content":" // Strings"},{"lineNumber":93,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027title\u0027:"},{"lineNumber":94,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027type\u0027:"},{"lineNumber":95,"author":{"gitId":"Arif-Khalid"},"content":" if (!filterValue) {"},{"lineNumber":96,"author":{"gitId":"Arif-Khalid"},"content":" delete queryParams[filterName];"},{"lineNumber":97,"author":{"gitId":"Arif-Khalid"},"content":" continue;"},{"lineNumber":98,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":99,"author":{"gitId":"Arif-Khalid"},"content":" queryParams[filterName] \u003d filterValue;"},{"lineNumber":100,"author":{"gitId":"Arif-Khalid"},"content":" break;"},{"lineNumber":101,"author":{"gitId":"Arif-Khalid"},"content":" // Arrays"},{"lineNumber":102,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027status\u0027:"},{"lineNumber":103,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027labels\u0027:"},{"lineNumber":104,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027milestones\u0027:"},{"lineNumber":105,"author":{"gitId":"Arif-Khalid"},"content":" if (filterValue.length \u003d\u003d\u003d 0) {"},{"lineNumber":106,"author":{"gitId":"Arif-Khalid"},"content":" delete queryParams[filterName];"},{"lineNumber":107,"author":{"gitId":"Arif-Khalid"},"content":" continue;"},{"lineNumber":108,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":109,"author":{"gitId":"Arif-Khalid"},"content":" queryParams[filterName] \u003d filterValue;"},{"lineNumber":110,"author":{"gitId":"Arif-Khalid"},"content":" break;"},{"lineNumber":111,"author":{"gitId":"Arif-Khalid"},"content":" // Sets"},{"lineNumber":112,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027selectedLabels\u0027:"},{"lineNumber":113,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027deselectedLabels\u0027:"},{"lineNumber":114,"author":{"gitId":"Arif-Khalid"},"content":" if (filterValue.size \u003d\u003d\u003d 0) {"},{"lineNumber":115,"author":{"gitId":"Arif-Khalid"},"content":" delete queryParams[filterName];"},{"lineNumber":116,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":117,"author":{"gitId":"Arif-Khalid"},"content":" queryParams[filterName] \u003d [...filterValue];"},{"lineNumber":118,"author":{"gitId":"Arif-Khalid"},"content":" break;"},{"lineNumber":119,"author":{"gitId":"Arif-Khalid"},"content":" // Objects"},{"lineNumber":120,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027sort\u0027:"},{"lineNumber":121,"author":{"gitId":"Arif-Khalid"},"content":" queryParams[filterName] \u003d JSON.stringify(filterValue);"},{"lineNumber":122,"author":{"gitId":"Arif-Khalid"},"content":" break;"},{"lineNumber":123,"author":{"gitId":"MadLamprey"},"content":" case \u0027itemsPerPage\u0027:"},{"lineNumber":124,"author":{"gitId":"MadLamprey"},"content":" queryParams[filterName] \u003d filterValue.toString();"},{"lineNumber":125,"author":{"gitId":"MadLamprey"},"content":" break;"},{"lineNumber":126,"author":{"gitId":"Arif-Khalid"},"content":" default:"},{"lineNumber":127,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":128,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":129,"author":{"gitId":"Arif-Khalid"},"content":" queryParams[FiltersService.PRESET_VIEW_QUERY_PARAM_KEY] \u003d this.presetView$.value;"},{"lineNumber":130,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":131,"author":{"gitId":"Arif-Khalid"},"content":" this.router.navigate([], {"},{"lineNumber":132,"author":{"gitId":"Arif-Khalid"},"content":" relativeTo: this.route,"},{"lineNumber":133,"author":{"gitId":"Arif-Khalid"},"content":" queryParams,"},{"lineNumber":134,"author":{"gitId":"Arif-Khalid"},"content":" replaceUrl: true"},{"lineNumber":135,"author":{"gitId":"Arif-Khalid"},"content":" });"},{"lineNumber":136,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":137,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":138,"author":{"gitId":"Arif-Khalid"},"content":" clearFilters(): void {"},{"lineNumber":139,"author":{"gitId":"Arif-Khalid"},"content":" this.updatePresetView(\u0027currentlyActive\u0027);"},{"lineNumber":140,"author":{"gitId":"Arif-Khalid"},"content":" this.previousMilestonesLength \u003d 0;"},{"lineNumber":141,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":142,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":143,"author":{"gitId":"Arif-Khalid"},"content":" initializeFromURLParams() {"},{"lineNumber":144,"author":{"gitId":"Arif-Khalid"},"content":" const nextFilter: Filter \u003d this.defaultFilter();"},{"lineNumber":145,"author":{"gitId":"Arif-Khalid"},"content":" const queryParams \u003d this.route.snapshot.queryParamMap;"},{"lineNumber":146,"author":{"gitId":"Arif-Khalid"},"content":" try {"},{"lineNumber":147,"author":{"gitId":"Arif-Khalid"},"content":" const presetView \u003d queryParams.get(FiltersService.PRESET_VIEW_QUERY_PARAM_KEY);"},{"lineNumber":148,"author":{"gitId":"Arif-Khalid"},"content":" // Use preset view if set in url"},{"lineNumber":149,"author":{"gitId":"Arif-Khalid"},"content":" if (presetView \u0026\u0026 this.presetViews.hasOwnProperty(presetView) \u0026\u0026 presetView !\u003d\u003d \u0027custom\u0027) {"},{"lineNumber":150,"author":{"gitId":"Arif-Khalid"},"content":" this.updatePresetView(presetView);"},{"lineNumber":151,"author":{"gitId":"Arif-Khalid"},"content":" return;"},{"lineNumber":152,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":153,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":154,"author":{"gitId":"Arif-Khalid"},"content":" // No preset view and no other filters in params, use default view"},{"lineNumber":155,"author":{"gitId":"Arif-Khalid"},"content":" if (!presetView \u0026\u0026 Object.keys(nextFilter).every((filterName) \u003d\u003e queryParams.get(filterName) \u003d\u003d\u003d null)) {"},{"lineNumber":156,"author":{"gitId":"Arif-Khalid"},"content":" this.updatePresetView(\u0027currentlyActive\u0027);"},{"lineNumber":157,"author":{"gitId":"Arif-Khalid"},"content":" return;"},{"lineNumber":158,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":159,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":160,"author":{"gitId":"Arif-Khalid"},"content":" for (const filterName of Object.keys(nextFilter)) {"},{"lineNumber":161,"author":{"gitId":"Arif-Khalid"},"content":" // Check if there is no such param in url"},{"lineNumber":162,"author":{"gitId":"Arif-Khalid"},"content":" if (queryParams.get(filterName) \u003d\u003d\u003d null) {"},{"lineNumber":163,"author":{"gitId":"Arif-Khalid"},"content":" continue;"},{"lineNumber":164,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":165,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":166,"author":{"gitId":"Arif-Khalid"},"content":" const filterData \u003d queryParams.getAll(filterName);"},{"lineNumber":167,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":168,"author":{"gitId":"Arif-Khalid"},"content":" switch (filterName) {"},{"lineNumber":169,"author":{"gitId":"Arif-Khalid"},"content":" // Strings"},{"lineNumber":170,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027title\u0027:"},{"lineNumber":171,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027type\u0027:"},{"lineNumber":172,"author":{"gitId":"Arif-Khalid"},"content":" nextFilter[filterName] \u003d filterData[0];"},{"lineNumber":173,"author":{"gitId":"Arif-Khalid"},"content":" break;"},{"lineNumber":174,"author":{"gitId":"Arif-Khalid"},"content":" // Arrays"},{"lineNumber":175,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027status\u0027:"},{"lineNumber":176,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027labels\u0027:"},{"lineNumber":177,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027milestones\u0027:"},{"lineNumber":178,"author":{"gitId":"Arif-Khalid"},"content":" nextFilter[filterName] \u003d filterData;"},{"lineNumber":179,"author":{"gitId":"Arif-Khalid"},"content":" break;"},{"lineNumber":180,"author":{"gitId":"Arif-Khalid"},"content":" // Sets"},{"lineNumber":181,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027selectedLabels\u0027:"},{"lineNumber":182,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027deselectedLabels\u0027:"},{"lineNumber":183,"author":{"gitId":"Arif-Khalid"},"content":" nextFilter[filterName] \u003d new Set(filterData);"},{"lineNumber":184,"author":{"gitId":"Arif-Khalid"},"content":" break;"},{"lineNumber":185,"author":{"gitId":"Arif-Khalid"},"content":" // Objects"},{"lineNumber":186,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027sort\u0027:"},{"lineNumber":187,"author":{"gitId":"Arif-Khalid"},"content":" nextFilter[filterName] \u003d JSON.parse(filterData[0]);"},{"lineNumber":188,"author":{"gitId":"Arif-Khalid"},"content":" break;"},{"lineNumber":189,"author":{"gitId":"MadLamprey"},"content":" case \u0027itemsPerPage\u0027:"},{"lineNumber":190,"author":{"gitId":"MadLamprey"},"content":" nextFilter[filterName] \u003d Number(filterData[0]);"},{"lineNumber":191,"author":{"gitId":"MadLamprey"},"content":" break;"},{"lineNumber":192,"author":{"gitId":"Arif-Khalid"},"content":" default:"},{"lineNumber":193,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":194,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":195,"author":{"gitId":"Arif-Khalid"},"content":" this.updateFilters(nextFilter);"},{"lineNumber":196,"author":{"gitId":"Arif-Khalid"},"content":" } catch (err) {"},{"lineNumber":197,"author":{"gitId":"Arif-Khalid"},"content":" this.logger.info(`FiltersService: Update filters from URL failed with an error: ${err}`);"},{"lineNumber":198,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":199,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":200,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":201,"author":{"gitId":"Arif-Khalid"},"content":" updateFilters(newFilters: Partial\u003cFilter\u003e): void {"},{"lineNumber":202,"author":{"gitId":"nknguyenhc"},"content":" const nextDropdownFilter: Filter \u003d {"},{"lineNumber":203,"author":{"gitId":"Arif-Khalid"},"content":" ...this.filter$.value,"},{"lineNumber":204,"author":{"gitId":"Arif-Khalid"},"content":" ...newFilters"},{"lineNumber":205,"author":{"gitId":"Arif-Khalid"},"content":" };"},{"lineNumber":206,"author":{"gitId":"nknguyenhc"},"content":" this.filter$.next(nextDropdownFilter);"},{"lineNumber":207,"author":{"gitId":"nknguyenhc"},"content":" this.updatePresetViewFromFilters(newFilters);"},{"lineNumber":208,"author":{"gitId":"Arif-Khalid"},"content":" this.pushFiltersToUrl();"},{"lineNumber":209,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":210,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":211,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":212,"author":{"gitId":"nknguyenhc"},"content":" * Updates the filters without updating the preset view."},{"lineNumber":213,"author":{"gitId":"nknguyenhc"},"content":" * This should only be called when there are new labels/milestones."},{"lineNumber":214,"author":{"gitId":"nknguyenhc"},"content":" * The preset view will be reapplied."},{"lineNumber":215,"author":{"gitId":"nknguyenhc"},"content":" * @param newFilters The filters with new values"},{"lineNumber":216,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":217,"author":{"gitId":"nknguyenhc"},"content":" private updateFiltersWithoutUpdatingPresetView(newFilters: Partial\u003cFilter\u003e): void {"},{"lineNumber":218,"author":{"gitId":"nknguyenhc"},"content":" const nextDropdownFilter: Filter \u003d {"},{"lineNumber":219,"author":{"gitId":"nknguyenhc"},"content":" ...this.filter$.value,"},{"lineNumber":220,"author":{"gitId":"nknguyenhc"},"content":" ...newFilters"},{"lineNumber":221,"author":{"gitId":"nknguyenhc"},"content":" };"},{"lineNumber":222,"author":{"gitId":"nknguyenhc"},"content":" this.filter$.next(nextDropdownFilter);"},{"lineNumber":223,"author":{"gitId":"nknguyenhc"},"content":" this.filter$.next(this.presetViews[this.presetView$.value]());"},{"lineNumber":224,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":225,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":226,"author":{"gitId":"nknguyenhc"},"content":" private updatePresetViewFromFilters(newFilter: Partial\u003cFilter\u003e): void {"},{"lineNumber":227,"author":{"gitId":"nknguyenhc"},"content":" for (const key of Object.keys(newFilter)) {"},{"lineNumber":228,"author":{"gitId":"nknguyenhc"},"content":" if (this.presetChangingKeys.has(key)) {"},{"lineNumber":229,"author":{"gitId":"nknguyenhc"},"content":" this.presetView$.next(\u0027custom\u0027);"},{"lineNumber":230,"author":{"gitId":"nknguyenhc"},"content":" return;"},{"lineNumber":231,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":232,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":233,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":234,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":235,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":236,"author":{"gitId":"nknguyenhc"},"content":" * Updates the filter based on a preset view."},{"lineNumber":237,"author":{"gitId":"nknguyenhc"},"content":" * @param presetViewName The name of the preset view, either \u0027currentlyActive\u0027, \u0027contributions\u0027, or \u0027custom\u0027."},{"lineNumber":238,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":239,"author":{"gitId":"nknguyenhc"},"content":" updatePresetView(presetViewName: string) {"},{"lineNumber":240,"author":{"gitId":"nknguyenhc"},"content":" this.filter$.next(this.presetViews[presetViewName]());"},{"lineNumber":241,"author":{"gitId":"nknguyenhc"},"content":" this.presetView$.next(presetViewName);"},{"lineNumber":242,"author":{"gitId":"Arif-Khalid"},"content":" this.pushFiltersToUrl();"},{"lineNumber":243,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":244,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":245,"author":{"gitId":"Arif-Khalid"},"content":" sanitizeLabels(allLabels: SimpleLabel[]): void {"},{"lineNumber":246,"author":{"gitId":"Arif-Khalid"},"content":" const allLabelsSet \u003d new Set(allLabels.map((label) \u003d\u003e label.name));"},{"lineNumber":247,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":248,"author":{"gitId":"Arif-Khalid"},"content":" const newHiddenLabels: Set\u003cstring\u003e \u003d new Set();"},{"lineNumber":249,"author":{"gitId":"Arif-Khalid"},"content":" for (const hiddenLabel of this.filter$.value.hiddenLabels) {"},{"lineNumber":250,"author":{"gitId":"Arif-Khalid"},"content":" if (allLabelsSet.has(hiddenLabel)) {"},{"lineNumber":251,"author":{"gitId":"Arif-Khalid"},"content":" newHiddenLabels.add(hiddenLabel);"},{"lineNumber":252,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":253,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":254,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":255,"author":{"gitId":"nknguyenhc"},"content":" const newDeselectedLabels: Set\u003cstring\u003e \u003d new Set();"},{"lineNumber":256,"author":{"gitId":"nknguyenhc"},"content":" for (const deselectedLabel of this.filter$.value.deselectedLabels) {"},{"lineNumber":257,"author":{"gitId":"nknguyenhc"},"content":" if (allLabelsSet.has(deselectedLabel)) {"},{"lineNumber":258,"author":{"gitId":"nknguyenhc"},"content":" newDeselectedLabels.add(deselectedLabel);"},{"lineNumber":259,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":260,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":261,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":262,"author":{"gitId":"nknguyenhc"},"content":" const newLabels \u003d this.filter$.value.labels.filter((label) \u003d\u003e allLabelsSet.has(label));"},{"lineNumber":263,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":264,"author":{"gitId":"nknguyenhc"},"content":" this.updateFiltersWithoutUpdatingPresetView({"},{"lineNumber":265,"author":{"gitId":"nknguyenhc"},"content":" labels: newLabels,"},{"lineNumber":266,"author":{"gitId":"nknguyenhc"},"content":" hiddenLabels: newHiddenLabels,"},{"lineNumber":267,"author":{"gitId":"nknguyenhc"},"content":" deselectedLabels: newDeselectedLabels"},{"lineNumber":268,"author":{"gitId":"nknguyenhc"},"content":" });"},{"lineNumber":269,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":270,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":271,"author":{"gitId":"Arif-Khalid"},"content":" sanitizeMilestones(allMilestones: Milestone[]) {"},{"lineNumber":272,"author":{"gitId":"MadLamprey"},"content":" const milestones \u003d allMilestones.map((milestone) \u003d\u003e milestone.title);"},{"lineNumber":273,"author":{"gitId":"MadLamprey"},"content":" milestones.push(Milestone.IssueWithoutMilestone.title, Milestone.PRWithoutMilestone.title);"},{"lineNumber":274,"author":{"gitId":"MadLamprey"},"content":" const allMilestonesSet \u003d new Set(milestones);"},{"lineNumber":275,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":276,"author":{"gitId":"Arif-Khalid"},"content":" // All previous milestones were selected, reset to all new milestones selected"},{"lineNumber":277,"author":{"gitId":"Arif-Khalid"},"content":" if (this.filter$.value.milestones.length \u003d\u003d\u003d this.previousMilestonesLength) {"},{"lineNumber":278,"author":{"gitId":"nknguyenhc"},"content":" this.updateFiltersWithoutUpdatingPresetView({ milestones: [...allMilestonesSet] });"},{"lineNumber":279,"author":{"gitId":"MadLamprey"},"content":" this.previousMilestonesLength \u003d allMilestonesSet.size;"},{"lineNumber":280,"author":{"gitId":"Arif-Khalid"},"content":" return;"},{"lineNumber":281,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":282,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":283,"author":{"gitId":"Arif-Khalid"},"content":" const newMilestones: string[] \u003d [];"},{"lineNumber":284,"author":{"gitId":"Arif-Khalid"},"content":" for (const milestone of this.filter$.value.milestones) {"},{"lineNumber":285,"author":{"gitId":"Arif-Khalid"},"content":" if (allMilestonesSet.has(milestone)) {"},{"lineNumber":286,"author":{"gitId":"Arif-Khalid"},"content":" newMilestones.push(milestone);"},{"lineNumber":287,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":288,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":289,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":290,"author":{"gitId":"Arif-Khalid"},"content":" // No applicable milestones, reset to all milestones selected"},{"lineNumber":291,"author":{"gitId":"Arif-Khalid"},"content":" if (newMilestones.length \u003d\u003d\u003d 0) {"},{"lineNumber":292,"author":{"gitId":"Arif-Khalid"},"content":" newMilestones.push(...allMilestonesSet);"},{"lineNumber":293,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":294,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":295,"author":{"gitId":"nknguyenhc"},"content":" this.updateFiltersWithoutUpdatingPresetView({ milestones: newMilestones });"},{"lineNumber":296,"author":{"gitId":"MadLamprey"},"content":" this.previousMilestonesLength \u003d allMilestonesSet.size;"},{"lineNumber":297,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":298,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":299,"author":{"gitId":"nknguyenhc"},"content":" getMilestonesForCurrentlyActive(): Milestone[] {"},{"lineNumber":300,"author":{"gitId":"nknguyenhc"},"content":" const earliestOpenMilestone \u003d this.milestoneService.getEarliestOpenMilestone();"},{"lineNumber":301,"author":{"gitId":"nknguyenhc"},"content":" if (earliestOpenMilestone) {"},{"lineNumber":302,"author":{"gitId":"NereusWB922"},"content":" return [earliestOpenMilestone, Milestone.PRWithoutMilestone];"},{"lineNumber":303,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":304,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":305,"author":{"gitId":"nknguyenhc"},"content":" const latestClosedMilestone \u003d this.milestoneService.getLatestClosedMilestone();"},{"lineNumber":306,"author":{"gitId":"nknguyenhc"},"content":" if (latestClosedMilestone) {"},{"lineNumber":307,"author":{"gitId":"NereusWB922"},"content":" return [latestClosedMilestone, Milestone.PRWithoutMilestone];"},{"lineNumber":308,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":309,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":310,"author":{"gitId":"NereusWB922"},"content":" return [...this.milestoneService.milestones, Milestone.PRWithoutMilestone];"},{"lineNumber":311,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":312,"author":{"gitId":"Arif-Khalid"},"content":"}"}],"authorContributionMap":{"nknguyenhc":95,"Arif-Khalid":191,"NereusWB922":3,"MadLamprey":23}},{"path":"src/app/core/services/github.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { HttpErrorResponse } from \u0027@angular/common/http\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"MadLamprey"},"content":"import { ApolloQueryResult } from \u0027@apollo/client/core\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { Apollo, QueryRef } from \u0027apollo-angular\u0027;"},{"lineNumber":5,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { DocumentNode } from \u0027graphql\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { BehaviorSubject, forkJoin, from, merge, Observable, of, throwError } from \u0027rxjs\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { catchError, filter, flatMap, map, throwIfEmpty } from \u0027rxjs/operators\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":10,"author":{"gitId":"-"},"content":" FetchIssue,"},{"lineNumber":11,"author":{"gitId":"-"},"content":" FetchIssueQuery,"},{"lineNumber":12,"author":{"gitId":"-"},"content":" FetchIssues,"},{"lineNumber":13,"author":{"gitId":"-"},"content":" FetchIssuesQuery,"},{"lineNumber":14,"author":{"gitId":"-"},"content":" FetchPullRequests,"},{"lineNumber":15,"author":{"gitId":"-"},"content":" FetchPullRequestsQuery"},{"lineNumber":16,"author":{"gitId":"-"},"content":"} from \u0027../../../../graphql/graphql-types\u0027;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import { AppConfig } from \u0027../../../environments/environment\u0027;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import { getNumberOfPages } from \u0027../../shared/lib/github-paginator-parser\u0027;"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":"import { GithubUser, RawGithubUser } from \u0027../models/github-user.model\u0027;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import { IssueLastModifiedManagerModel } from \u0027../models/github/cache-manager/issue-last-modified-manager.model\u0027;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import { IssuesCacheManager } from \u0027../models/github/cache-manager/issues-cache-manager.model\u0027;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import { GithubEvent } from \u0027../models/github/github-event.model\u0027;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import { GithubGraphqlIssue } from \u0027../models/github/github-graphql.issue\u0027;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import { GithubGraphqlIssueOrPr } from \u0027../models/github/github-graphql.issue-or-pr\u0027;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import RestGithubIssueFilter from \u0027../models/github/github-issue-filter.model\u0027;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import { GithubIssue } from \u0027../models/github/github-issue.model\u0027;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import { GithubResponse } from \u0027../models/github/github-response.model\u0027;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import { GithubRelease } from \u0027../models/github/github.release\u0027;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import { SessionData } from \u0027../models/session.model\u0027;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import { ERRORCODE_NOT_FOUND, ErrorHandlingService } from \u0027./error-handling.service\u0027;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import { ErrorMessageService } from \u0027./error-message.service\u0027;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027./logging.service\u0027;"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":"const { Octokit } \u003d require(\u0027@octokit/rest\u0027);"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":"const WATCHER_ORG \u003d \u0027WATcher-org\u0027;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"const WATCHER_REPO \u003d \u0027WATcher\u0027;"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":"/** Owner of Repository to watch */"},{"lineNumber":40,"author":{"gitId":"-"},"content":"let ORG_NAME \u003d \u0027\u0027; // repoOrg"},{"lineNumber":41,"author":{"gitId":"-"},"content":"/** Name of Repository to watch */"},{"lineNumber":42,"author":{"gitId":"-"},"content":"let REPO \u003d \u0027\u0027; // repoName"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":"/** Owner of Settings repository, currently not used */"},{"lineNumber":45,"author":{"gitId":"-"},"content":"let MOD_ORG \u003d \u0027\u0027;"},{"lineNumber":46,"author":{"gitId":"-"},"content":"/** Name of Settings repository, currently not used */"},{"lineNumber":47,"author":{"gitId":"-"},"content":"let DATA_REPO \u003d \u0027\u0027;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"const MAX_ITEMS_PER_PAGE \u003d 100;"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":"let octokit \u003d new Octokit();"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":53,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":54,"author":{"gitId":"-"},"content":"})"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":57,"author":{"gitId":"-"},"content":" * Responsible for communicating with GitHub to create, update, read and delete"},{"lineNumber":58,"author":{"gitId":"-"},"content":" * features related to Github using GitHub API Requests."},{"lineNumber":59,"author":{"gitId":"-"},"content":" * For example, issues, issue labels and repositories."},{"lineNumber":60,"author":{"gitId":"-"},"content":" */"},{"lineNumber":61,"author":{"gitId":"-"},"content":"export class GithubService {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" private static readonly IF_NONE_MATCH_EMPTY \u003d { \u0027If-None-Match\u0027: \u0027\u0027 };"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" private issuesCacheManager \u003d new IssuesCacheManager();"},{"lineNumber":65,"author":{"gitId":"-"},"content":" private issuesLastModifiedManager \u003d new IssueLastModifiedManagerModel();"},{"lineNumber":66,"author":{"gitId":"-"},"content":" private issueQueryRefs \u003d new Map\u003cnumber, QueryRef\u003cFetchIssueQuery\u003e\u003e();"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" constructor(private errorHandlingService: ErrorHandlingService, private apollo: Apollo, private logger: LoggingService) {}"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" storeOAuthAccessToken(accessToken: string) {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" octokit \u003d new Octokit({"},{"lineNumber":72,"author":{"gitId":"-"},"content":" auth() {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" return `Token ${accessToken}`;"},{"lineNumber":74,"author":{"gitId":"-"},"content":" },"},{"lineNumber":75,"author":{"gitId":"-"},"content":" log: {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" debug: (message, ...otherInfo) \u003d\u003e this.logger.debug(\u0027GithubService: \u0027 + message, ...otherInfo),"},{"lineNumber":77,"author":{"gitId":"-"},"content":" // Do not log info for HTTP response 304 due to repeated polling"},{"lineNumber":78,"author":{"gitId":"-"},"content":" info: (message, ...otherInfo) \u003d\u003e"},{"lineNumber":79,"author":{"gitId":"-"},"content":" /304 in \\d+ms$/.test(message) ? undefined : this.logger.info(\u0027GithubService: \u0027 + message, ...otherInfo),"},{"lineNumber":80,"author":{"gitId":"-"},"content":" warn: (message, ...otherInfo) \u003d\u003e this.logger.warn(\u0027GithubService: \u0027 + message, ...otherInfo),"},{"lineNumber":81,"author":{"gitId":"-"},"content":" error: (message, ...otherInfo) \u003d\u003e this.logger.error(\u0027GithubService: \u0027 + message, ...otherInfo)"},{"lineNumber":82,"author":{"gitId":"-"},"content":" }"},{"lineNumber":83,"author":{"gitId":"-"},"content":" });"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":87,"author":{"gitId":"-"},"content":" * Sets settings repository. Not used."},{"lineNumber":88,"author":{"gitId":"-"},"content":" * @param orgName WATcher organisation"},{"lineNumber":89,"author":{"gitId":"-"},"content":" * @param dataRepo WATcher repository"},{"lineNumber":90,"author":{"gitId":"-"},"content":" */"},{"lineNumber":91,"author":{"gitId":"-"},"content":" storeOrganizationDetails(orgName: string, dataRepo: string) {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" MOD_ORG \u003d orgName;"},{"lineNumber":93,"author":{"gitId":"-"},"content":" DATA_REPO \u003d dataRepo;"},{"lineNumber":94,"author":{"gitId":"-"},"content":" }"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":97,"author":{"gitId":"-"},"content":" * Sets repository to watch. This repository is used for fetching from Github."},{"lineNumber":98,"author":{"gitId":"NereusWB922"},"content":" * @param viewRepoOwner Repository owner"},{"lineNumber":99,"author":{"gitId":"-"},"content":" * @param repoName Repository name"},{"lineNumber":100,"author":{"gitId":"-"},"content":" */"},{"lineNumber":101,"author":{"gitId":"NereusWB922"},"content":" storeViewDetails(viewRepoOwner: string, repoName: string) {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" REPO \u003d repoName;"},{"lineNumber":103,"author":{"gitId":"NereusWB922"},"content":" ORG_NAME \u003d viewRepoOwner;"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":107,"author":{"gitId":"-"},"content":" * Fetches an array of filtered GitHubIssues using GraphQL query."},{"lineNumber":108,"author":{"gitId":"-"},"content":" * In WATcher, this includes pull requests."},{"lineNumber":109,"author":{"gitId":"-"},"content":" *"},{"lineNumber":110,"author":{"gitId":"-"},"content":" * @param issuesFilter - The issue filter."},{"lineNumber":111,"author":{"gitId":"-"},"content":" * @returns An observable array of filtered GithubIssues"},{"lineNumber":112,"author":{"gitId":"-"},"content":" */"},{"lineNumber":113,"author":{"gitId":"-"},"content":" fetchIssuesGraphql(issuesFilter: RestGithubIssueFilter): Observable\u003cArray\u003cGithubIssue\u003e\u003e {"},{"lineNumber":114,"author":{"gitId":"-"},"content":" const graphqlFilter \u003d issuesFilter.convertToGraphqlFilter();"},{"lineNumber":115,"author":{"gitId":"-"},"content":" /*"},{"lineNumber":116,"author":{"gitId":"-"},"content":" * Github Issues consists of issues and pull requests in WATcher."},{"lineNumber":117,"author":{"gitId":"-"},"content":" */"},{"lineNumber":118,"author":{"gitId":"nknguyenhc"},"content":" return this.toFetchIssues(issuesFilter).pipe("},{"lineNumber":119,"author":{"gitId":"-"},"content":" filter((toFetch) \u003d\u003e toFetch),"},{"lineNumber":120,"author":{"gitId":"-"},"content":" flatMap(() \u003d\u003e {"},{"lineNumber":121,"author":{"gitId":"nknguyenhc"},"content":" return merge("},{"lineNumber":122,"author":{"gitId":"nknguyenhc"},"content":" this.fetchGraphqlList\u003cFetchIssuesQuery, GithubGraphqlIssueOrPr\u003e("},{"lineNumber":123,"author":{"gitId":"-"},"content":" FetchIssues,"},{"lineNumber":124,"author":{"gitId":"-"},"content":" { owner: ORG_NAME, name: REPO, filter: graphqlFilter },"},{"lineNumber":125,"author":{"gitId":"-"},"content":" (result) \u003d\u003e result.data.repository.issues.edges,"},{"lineNumber":126,"author":{"gitId":"-"},"content":" GithubGraphqlIssueOrPr"},{"lineNumber":127,"author":{"gitId":"nknguyenhc"},"content":" ),"},{"lineNumber":128,"author":{"gitId":"nknguyenhc"},"content":" this.fetchGraphqlList\u003cFetchPullRequestsQuery, GithubGraphqlIssueOrPr\u003e("},{"lineNumber":129,"author":{"gitId":"-"},"content":" FetchPullRequests,"},{"lineNumber":130,"author":{"gitId":"-"},"content":" { owner: ORG_NAME, name: REPO },"},{"lineNumber":131,"author":{"gitId":"-"},"content":" (result) \u003d\u003e result.data.repository.pullRequests.edges,"},{"lineNumber":132,"author":{"gitId":"-"},"content":" GithubGraphqlIssueOrPr"},{"lineNumber":133,"author":{"gitId":"nknguyenhc"},"content":" )"},{"lineNumber":134,"author":{"gitId":"-"},"content":" );"},{"lineNumber":135,"author":{"gitId":"-"},"content":" })"},{"lineNumber":136,"author":{"gitId":"-"},"content":" );"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":140,"author":{"gitId":"-"},"content":" * Checks if there are pages of filtered issues that are not cached in the cache model,"},{"lineNumber":141,"author":{"gitId":"-"},"content":" * and updates the model to cache these new pages."},{"lineNumber":142,"author":{"gitId":"-"},"content":" * @param filter - The issue filter."},{"lineNumber":143,"author":{"gitId":"-"},"content":" * @returns Observable\u003cboolean\u003e that returns true if there are pages that do not exist in the cache model."},{"lineNumber":144,"author":{"gitId":"-"},"content":" */"},{"lineNumber":145,"author":{"gitId":"-"},"content":" private toFetchIssues(filter: RestGithubIssueFilter): Observable\u003cboolean\u003e {"},{"lineNumber":146,"author":{"gitId":"-"},"content":" const pageFetchLimit \u003d 100;"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" let responseInFirstPage: GithubResponse\u003cGithubIssue[]\u003e;"},{"lineNumber":149,"author":{"gitId":"-"},"content":" return this.getIssuesAPICall(filter, 1).pipe("},{"lineNumber":150,"author":{"gitId":"-"},"content":" map((response: GithubResponse\u003cGithubIssue[]\u003e) \u003d\u003e {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" responseInFirstPage \u003d response;"},{"lineNumber":152,"author":{"gitId":"-"},"content":" return getNumberOfPages(response);"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":154,"author":{"gitId":"-"},"content":" flatMap((numOfPages: number) \u003d\u003e {"},{"lineNumber":155,"author":{"gitId":"-"},"content":" const apiCalls: Observable\u003cGithubResponse\u003cGithubIssue[]\u003e\u003e[] \u003d [];"},{"lineNumber":156,"author":{"gitId":"-"},"content":" if (numOfPages \u003e pageFetchLimit) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" throw new Error(`Repository has too many pages (${numOfPages}), not supported.`);"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":" for (let i \u003d 2; i \u003c\u003d numOfPages; i++) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" apiCalls.push(this.getIssuesAPICall(filter, i));"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":" return apiCalls.length \u003d\u003d\u003d 0 ? of([]) : forkJoin(apiCalls);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":164,"author":{"gitId":"-"},"content":" map((resultArray: GithubResponse\u003cGithubIssue[]\u003e[]) \u003d\u003e {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" const responses \u003d [responseInFirstPage, ...resultArray];"},{"lineNumber":166,"author":{"gitId":"-"},"content":" const isCached \u003d responses.reduce((result, response) \u003d\u003e {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" return result \u0026\u0026 response.isCached;"},{"lineNumber":168,"author":{"gitId":"-"},"content":" }, true);"},{"lineNumber":169,"author":{"gitId":"-"},"content":" responses.forEach((resp, index) \u003d\u003e this.issuesCacheManager.set(index + 1, resp));"},{"lineNumber":170,"author":{"gitId":"-"},"content":" return !isCached;"},{"lineNumber":171,"author":{"gitId":"-"},"content":" })"},{"lineNumber":172,"author":{"gitId":"-"},"content":" );"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":176,"author":{"gitId":"-"},"content":" * Checks if the specified repository exists."},{"lineNumber":177,"author":{"gitId":"-"},"content":" * @param owner - Owner of Specified Repository."},{"lineNumber":178,"author":{"gitId":"-"},"content":" * @param repo - Name of Repository."},{"lineNumber":179,"author":{"gitId":"-"},"content":" */"},{"lineNumber":180,"author":{"gitId":"-"},"content":" isRepositoryPresent(owner: string, repo: string): Observable\u003cboolean\u003e {"},{"lineNumber":181,"author":{"gitId":"-"},"content":" return from(octokit.repos.get({ owner: owner, repo: repo, headers: GithubService.IF_NONE_MATCH_EMPTY })).pipe("},{"lineNumber":182,"author":{"gitId":"-"},"content":" map((rawData: { status: number }) \u003d\u003e {"},{"lineNumber":183,"author":{"gitId":"-"},"content":" return rawData.status !\u003d\u003d ERRORCODE_NOT_FOUND;"},{"lineNumber":184,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":185,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" return of(false);"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":188,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.repositoryNotPresentMessage()))"},{"lineNumber":189,"author":{"gitId":"-"},"content":" );"},{"lineNumber":190,"author":{"gitId":"-"},"content":" }"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":193,"author":{"gitId":"-"},"content":" * Fetches information about an issue using GraphQL."},{"lineNumber":194,"author":{"gitId":"-"},"content":" *"},{"lineNumber":195,"author":{"gitId":"-"},"content":" * If the issue is not modified, return a `304 - Not Modified` response."},{"lineNumber":196,"author":{"gitId":"-"},"content":" *"},{"lineNumber":197,"author":{"gitId":"-"},"content":" * @param id - The issue id."},{"lineNumber":198,"author":{"gitId":"-"},"content":" * @returns Observable\u003cGithubGraphqlIssue\u003e that represents the response object."},{"lineNumber":199,"author":{"gitId":"-"},"content":" */"},{"lineNumber":200,"author":{"gitId":"-"},"content":" fetchIssueGraphql(id: number): Observable\u003cGithubGraphqlIssue\u003e {"},{"lineNumber":201,"author":{"gitId":"-"},"content":" if (this.issueQueryRefs.get(id) \u003d\u003d\u003d undefined) {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" const newQueryRef \u003d this.apollo.watchQuery\u003cFetchIssueQuery\u003e({"},{"lineNumber":203,"author":{"gitId":"-"},"content":" query: FetchIssue,"},{"lineNumber":204,"author":{"gitId":"-"},"content":" variables: {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" owner: ORG_NAME,"},{"lineNumber":206,"author":{"gitId":"-"},"content":" name: REPO,"},{"lineNumber":207,"author":{"gitId":"-"},"content":" issueId: id"},{"lineNumber":208,"author":{"gitId":"-"},"content":" }"},{"lineNumber":209,"author":{"gitId":"-"},"content":" });"},{"lineNumber":210,"author":{"gitId":"-"},"content":" this.issueQueryRefs.set(id, newQueryRef);"},{"lineNumber":211,"author":{"gitId":"-"},"content":" }"},{"lineNumber":212,"author":{"gitId":"-"},"content":""},{"lineNumber":213,"author":{"gitId":"-"},"content":" const queryRef \u003d this.issueQueryRefs.get(id);"},{"lineNumber":214,"author":{"gitId":"-"},"content":" return this.toFetchIssue(id).pipe("},{"lineNumber":215,"author":{"gitId":"-"},"content":" filter((toFetch) \u003d\u003e toFetch),"},{"lineNumber":216,"author":{"gitId":"-"},"content":" flatMap(() \u003d\u003e from(queryRef.refetch())),"},{"lineNumber":217,"author":{"gitId":"-"},"content":" map((value: ApolloQueryResult\u003cFetchIssueQuery\u003e) \u003d\u003e {"},{"lineNumber":218,"author":{"gitId":"-"},"content":" return new GithubGraphqlIssue(value.data.repository.issue);"},{"lineNumber":219,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":220,"author":{"gitId":"-"},"content":" throwIfEmpty(() \u003d\u003e new HttpErrorResponse({ status: 304 }))"},{"lineNumber":221,"author":{"gitId":"-"},"content":" );"},{"lineNumber":222,"author":{"gitId":"-"},"content":" }"},{"lineNumber":223,"author":{"gitId":"-"},"content":""},{"lineNumber":224,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":225,"author":{"gitId":"-"},"content":" * Checks if the issue has been modified since the last query, and"},{"lineNumber":226,"author":{"gitId":"-"},"content":" * updates the model to reflect the last modified time."},{"lineNumber":227,"author":{"gitId":"-"},"content":" *"},{"lineNumber":228,"author":{"gitId":"-"},"content":" * @param id - The issue id."},{"lineNumber":229,"author":{"gitId":"-"},"content":" * @returns Observable\u003cboolean\u003e that returns true if the issue has been modified."},{"lineNumber":230,"author":{"gitId":"-"},"content":" */"},{"lineNumber":231,"author":{"gitId":"-"},"content":" toFetchIssue(id: number): Observable\u003cboolean\u003e {"},{"lineNumber":232,"author":{"gitId":"-"},"content":" return from("},{"lineNumber":233,"author":{"gitId":"-"},"content":" octokit.issues.get({"},{"lineNumber":234,"author":{"gitId":"-"},"content":" owner: ORG_NAME,"},{"lineNumber":235,"author":{"gitId":"-"},"content":" repo: REPO,"},{"lineNumber":236,"author":{"gitId":"-"},"content":" issue_number: id,"},{"lineNumber":237,"author":{"gitId":"-"},"content":" headers: { \u0027If-Modified-Since\u0027: this.issuesLastModifiedManager.get(id) }"},{"lineNumber":238,"author":{"gitId":"-"},"content":" })"},{"lineNumber":239,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":240,"author":{"gitId":"-"},"content":" map((response: GithubResponse\u003cGithubIssue\u003e) \u003d\u003e {"},{"lineNumber":241,"author":{"gitId":"-"},"content":" this.issuesLastModifiedManager.set(id, response.headers[\u0027last-modified\u0027]);"},{"lineNumber":242,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":243,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":244,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchIssuesMessage()))"},{"lineNumber":245,"author":{"gitId":"-"},"content":" );"},{"lineNumber":246,"author":{"gitId":"-"},"content":" }"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" fetchAllMilestones(): Observable\u003cArray\u003c{}\u003e\u003e {"},{"lineNumber":249,"author":{"gitId":"-"},"content":" return from("},{"lineNumber":250,"author":{"gitId":"-"},"content":" octokit.issues.listMilestonesForRepo({"},{"lineNumber":251,"author":{"gitId":"-"},"content":" owner: ORG_NAME,"},{"lineNumber":252,"author":{"gitId":"-"},"content":" repo: REPO,"},{"lineNumber":253,"author":{"gitId":"-"},"content":" state: \u0027all\u0027,"},{"lineNumber":254,"author":{"gitId":"-"},"content":" per_page: MAX_ITEMS_PER_PAGE,"},{"lineNumber":255,"author":{"gitId":"-"},"content":" headers: GithubService.IF_NONE_MATCH_EMPTY"},{"lineNumber":256,"author":{"gitId":"-"},"content":" })"},{"lineNumber":257,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":258,"author":{"gitId":"-"},"content":" map((response) \u003d\u003e {"},{"lineNumber":259,"author":{"gitId":"-"},"content":" return response[\u0027data\u0027];"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":261,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchMilestoneMessage()))"},{"lineNumber":262,"author":{"gitId":"-"},"content":" );"},{"lineNumber":263,"author":{"gitId":"-"},"content":" }"},{"lineNumber":264,"author":{"gitId":"-"},"content":""},{"lineNumber":265,"author":{"gitId":"-"},"content":" fetchAllLabels(): Observable\u003cArray\u003c{}\u003e\u003e {"},{"lineNumber":266,"author":{"gitId":"-"},"content":" return from("},{"lineNumber":267,"author":{"gitId":"-"},"content":" octokit.issues.listLabelsForRepo({"},{"lineNumber":268,"author":{"gitId":"-"},"content":" owner: ORG_NAME,"},{"lineNumber":269,"author":{"gitId":"-"},"content":" repo: REPO,"},{"lineNumber":270,"author":{"gitId":"-"},"content":" per_page: MAX_ITEMS_PER_PAGE,"},{"lineNumber":271,"author":{"gitId":"-"},"content":" headers: GithubService.IF_NONE_MATCH_EMPTY"},{"lineNumber":272,"author":{"gitId":"-"},"content":" })"},{"lineNumber":273,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":274,"author":{"gitId":"-"},"content":" map((response) \u003d\u003e {"},{"lineNumber":275,"author":{"gitId":"-"},"content":" return response[\u0027data\u0027];"},{"lineNumber":276,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":277,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchLabelsMessage()))"},{"lineNumber":278,"author":{"gitId":"-"},"content":" );"},{"lineNumber":279,"author":{"gitId":"-"},"content":" }"},{"lineNumber":280,"author":{"gitId":"-"},"content":""},{"lineNumber":281,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":282,"author":{"gitId":"-"},"content":" * Checks if the given list of users are allowed to be assigned to an issue."},{"lineNumber":283,"author":{"gitId":"-"},"content":" * @param assignees - GitHub usernames to be checked"},{"lineNumber":284,"author":{"gitId":"-"},"content":" */"},{"lineNumber":285,"author":{"gitId":"-"},"content":" areUsersAssignable(assignees: string[]): Observable\u003cvoid\u003e {"},{"lineNumber":286,"author":{"gitId":"-"},"content":" return from("},{"lineNumber":287,"author":{"gitId":"-"},"content":" octokit.issues.listAssignees({"},{"lineNumber":288,"author":{"gitId":"-"},"content":" owner: ORG_NAME,"},{"lineNumber":289,"author":{"gitId":"-"},"content":" repo: REPO"},{"lineNumber":290,"author":{"gitId":"-"},"content":" })"},{"lineNumber":291,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":292,"author":{"gitId":"-"},"content":" map(({ data }: { data: { login: string }[] }) \u003d\u003e data.map(({ login }) \u003d\u003e login)),"},{"lineNumber":293,"author":{"gitId":"-"},"content":" map((assignables: string[]) \u003d\u003e"},{"lineNumber":294,"author":{"gitId":"-"},"content":" assignees.forEach((assignee) \u003d\u003e {"},{"lineNumber":295,"author":{"gitId":"-"},"content":" if (!assignables.includes(assignee)) {"},{"lineNumber":296,"author":{"gitId":"-"},"content":" throw new Error(ErrorMessageService.usersUnassignableMessage(assignee));"},{"lineNumber":297,"author":{"gitId":"-"},"content":" }"},{"lineNumber":298,"author":{"gitId":"-"},"content":" })"},{"lineNumber":299,"author":{"gitId":"-"},"content":" )"},{"lineNumber":300,"author":{"gitId":"-"},"content":" );"},{"lineNumber":301,"author":{"gitId":"-"},"content":" }"},{"lineNumber":302,"author":{"gitId":"-"},"content":""},{"lineNumber":303,"author":{"gitId":"-"},"content":" getUsersAssignable(): Observable\u003cGithubUser[]\u003e {"},{"lineNumber":304,"author":{"gitId":"-"},"content":" return from("},{"lineNumber":305,"author":{"gitId":"-"},"content":" octokit.issues.listAssignees({"},{"lineNumber":306,"author":{"gitId":"-"},"content":" owner: ORG_NAME,"},{"lineNumber":307,"author":{"gitId":"-"},"content":" repo: REPO"},{"lineNumber":308,"author":{"gitId":"-"},"content":" })"},{"lineNumber":309,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":310,"author":{"gitId":"-"},"content":" map((response) \u003d\u003e {"},{"lineNumber":311,"author":{"gitId":"NereusWB922"},"content":" const data: RawGithubUser[] \u003d response[\u0027data\u0027];"},{"lineNumber":312,"author":{"gitId":"NereusWB922"},"content":" return data.map((rawGithubUser) \u003d\u003e {"},{"lineNumber":313,"author":{"gitId":"NereusWB922"},"content":" return new GithubUser(rawGithubUser);"},{"lineNumber":314,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":315,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":316,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchUsersMessage()))"},{"lineNumber":317,"author":{"gitId":"-"},"content":" );"},{"lineNumber":318,"author":{"gitId":"-"},"content":" }"},{"lineNumber":319,"author":{"gitId":"-"},"content":""},{"lineNumber":320,"author":{"gitId":"-"},"content":" fetchEventsForRepo(): Observable\u003cany[]\u003e {"},{"lineNumber":321,"author":{"gitId":"-"},"content":" return from(octokit.issues.listEventsForRepo({ owner: ORG_NAME, repo: REPO, headers: GithubService.IF_NONE_MATCH_EMPTY })).pipe("},{"lineNumber":322,"author":{"gitId":"-"},"content":" map((response) \u003d\u003e {"},{"lineNumber":323,"author":{"gitId":"-"},"content":" return response[\u0027data\u0027];"},{"lineNumber":324,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":325,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchEventsMessage()))"},{"lineNumber":326,"author":{"gitId":"-"},"content":" );"},{"lineNumber":327,"author":{"gitId":"-"},"content":" }"},{"lineNumber":328,"author":{"gitId":"-"},"content":""},{"lineNumber":329,"author":{"gitId":"-"},"content":" fetchEventsForRepoCall(pageNumber: number): Observable\u003cGithubResponse\u003cany[]\u003e\u003e {"},{"lineNumber":330,"author":{"gitId":"-"},"content":" return \u003cObservable\u003cGithubResponse\u003cany[]\u003e\u003e\u003efrom("},{"lineNumber":331,"author":{"gitId":"-"},"content":" octokit.activity.listRepoEvents({"},{"lineNumber":332,"author":{"gitId":"-"},"content":" owner: ORG_NAME,"},{"lineNumber":333,"author":{"gitId":"-"},"content":" repo: REPO,"},{"lineNumber":334,"author":{"gitId":"-"},"content":" page: pageNumber"},{"lineNumber":335,"author":{"gitId":"-"},"content":" })"},{"lineNumber":336,"author":{"gitId":"-"},"content":" ).pipe(catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchActivityEventsMessage())));"},{"lineNumber":337,"author":{"gitId":"-"},"content":" }"},{"lineNumber":338,"author":{"gitId":"-"},"content":""},{"lineNumber":339,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":340,"author":{"gitId":"-"},"content":" * Fetches all events of current repository for Activity Dashboard."},{"lineNumber":341,"author":{"gitId":"-"},"content":" * Adapted from getIssueApiCalls()."},{"lineNumber":342,"author":{"gitId":"-"},"content":" *"},{"lineNumber":343,"author":{"gitId":"-"},"content":" * @returns GithubEvents observable"},{"lineNumber":344,"author":{"gitId":"-"},"content":" */"},{"lineNumber":345,"author":{"gitId":"-"},"content":" fetchAllEventsForRepo(): Observable\u003cGithubEvent[]\u003e {"},{"lineNumber":346,"author":{"gitId":"-"},"content":" let responseInFirstPage: GithubResponse\u003cGithubEvent[]\u003e;"},{"lineNumber":347,"author":{"gitId":"-"},"content":" return this.fetchEventsForRepoCall(1).pipe("},{"lineNumber":348,"author":{"gitId":"-"},"content":" map((response: GithubResponse\u003cGithubEvent[]\u003e) \u003d\u003e {"},{"lineNumber":349,"author":{"gitId":"-"},"content":" responseInFirstPage \u003d response;"},{"lineNumber":350,"author":{"gitId":"-"},"content":" return getNumberOfPages(response);"},{"lineNumber":351,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":352,"author":{"gitId":"-"},"content":" flatMap((numOfPages: number) \u003d\u003e {"},{"lineNumber":353,"author":{"gitId":"-"},"content":" const apiCalls: Observable\u003cGithubResponse\u003cGithubEvent[]\u003e\u003e[] \u003d [];"},{"lineNumber":354,"author":{"gitId":"-"},"content":" for (let i \u003d 1; i \u003c\u003d numOfPages; i++) {"},{"lineNumber":355,"author":{"gitId":"-"},"content":" apiCalls.push(this.fetchEventsForRepoCall(i));"},{"lineNumber":356,"author":{"gitId":"-"},"content":" }"},{"lineNumber":357,"author":{"gitId":"-"},"content":" return apiCalls.length \u003d\u003d\u003d 0 ? of([]) : forkJoin(apiCalls);"},{"lineNumber":358,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":359,"author":{"gitId":"-"},"content":" map((responseArray) \u003d\u003e responseArray.map((x) \u003d\u003e x[\u0027data\u0027]))"},{"lineNumber":360,"author":{"gitId":"-"},"content":" );"},{"lineNumber":361,"author":{"gitId":"-"},"content":" }"},{"lineNumber":362,"author":{"gitId":"-"},"content":""},{"lineNumber":363,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":364,"author":{"gitId":"-"},"content":" * Not in use. Fetches data csv file from Organization repository."},{"lineNumber":365,"author":{"gitId":"-"},"content":" */"},{"lineNumber":366,"author":{"gitId":"-"},"content":" fetchDataFile(): Observable\u003c{}\u003e {"},{"lineNumber":367,"author":{"gitId":"-"},"content":" return from("},{"lineNumber":368,"author":{"gitId":"-"},"content":" octokit.repos.getContents({ owner: MOD_ORG, repo: DATA_REPO, path: \u0027data.csv\u0027, headers: GithubService.IF_NONE_MATCH_EMPTY })"},{"lineNumber":369,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":370,"author":{"gitId":"-"},"content":" map((rawData) \u003d\u003e {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" return { data: atob(rawData[\u0027data\u0027][\u0027content\u0027]) };"},{"lineNumber":372,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":373,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchDataFileMessage()))"},{"lineNumber":374,"author":{"gitId":"-"},"content":" );"},{"lineNumber":375,"author":{"gitId":"-"},"content":" }"},{"lineNumber":376,"author":{"gitId":"-"},"content":""},{"lineNumber":377,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":378,"author":{"gitId":"-"},"content":" * Gets information of latest release of WATcher."},{"lineNumber":379,"author":{"gitId":"-"},"content":" * @returns GithubRelease observable"},{"lineNumber":380,"author":{"gitId":"-"},"content":" */"},{"lineNumber":381,"author":{"gitId":"-"},"content":" fetchLatestRelease(): Observable\u003cGithubRelease\u003e {"},{"lineNumber":382,"author":{"gitId":"-"},"content":" return from("},{"lineNumber":383,"author":{"gitId":"-"},"content":" octokit.repos.getLatestRelease({ owner: WATCHER_ORG, repo: WATCHER_REPO, headers: GithubService.IF_NONE_MATCH_EMPTY })"},{"lineNumber":384,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":385,"author":{"gitId":"-"},"content":" map((res) \u003d\u003e res[\u0027data\u0027]),"},{"lineNumber":386,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchLatestReleaseMessage()))"},{"lineNumber":387,"author":{"gitId":"-"},"content":" );"},{"lineNumber":388,"author":{"gitId":"-"},"content":" }"},{"lineNumber":389,"author":{"gitId":"-"},"content":""},{"lineNumber":390,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":391,"author":{"gitId":"-"},"content":" * Fetches the data file that is regulates session information."},{"lineNumber":392,"author":{"gitId":"-"},"content":" * @return Observable\u003cSessionData\u003e representing session information."},{"lineNumber":393,"author":{"gitId":"-"},"content":" */"},{"lineNumber":394,"author":{"gitId":"-"},"content":" fetchSettingsFile(): Observable\u003cSessionData\u003e {"},{"lineNumber":395,"author":{"gitId":"-"},"content":" return from("},{"lineNumber":396,"author":{"gitId":"-"},"content":" octokit.repos.getContents({ owner: MOD_ORG, repo: DATA_REPO, path: \u0027settings.json\u0027, headers: GithubService.IF_NONE_MATCH_EMPTY })"},{"lineNumber":397,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":398,"author":{"gitId":"-"},"content":" map((rawData) \u003d\u003e JSON.parse(atob(rawData[\u0027data\u0027][\u0027content\u0027]))),"},{"lineNumber":399,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchSettingsFileMessage()))"},{"lineNumber":400,"author":{"gitId":"-"},"content":" );"},{"lineNumber":401,"author":{"gitId":"-"},"content":" }"},{"lineNumber":402,"author":{"gitId":"-"},"content":""},{"lineNumber":403,"author":{"gitId":"-"},"content":" fetchAuthenticatedUser(): Observable\u003cGithubUser\u003e {"},{"lineNumber":404,"author":{"gitId":"-"},"content":" return from(octokit.users.getAuthenticated()).pipe("},{"lineNumber":405,"author":{"gitId":"-"},"content":" map((response) \u003d\u003e {"},{"lineNumber":406,"author":{"gitId":"NereusWB922"},"content":" const data: RawGithubUser \u003d response[\u0027data\u0027];"},{"lineNumber":407,"author":{"gitId":"NereusWB922"},"content":" return new GithubUser(data);"},{"lineNumber":408,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":409,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchAuthenticatedUsersMessage()))"},{"lineNumber":410,"author":{"gitId":"-"},"content":" );"},{"lineNumber":411,"author":{"gitId":"-"},"content":" }"},{"lineNumber":412,"author":{"gitId":"-"},"content":""},{"lineNumber":413,"author":{"gitId":"-"},"content":" getRepoURL(): string {"},{"lineNumber":414,"author":{"gitId":"-"},"content":" return ORG_NAME.concat(\u0027/\u0027).concat(REPO);"},{"lineNumber":415,"author":{"gitId":"-"},"content":" }"},{"lineNumber":416,"author":{"gitId":"-"},"content":""},{"lineNumber":417,"author":{"gitId":"-"},"content":" viewIssueInBrowser(id: number, event: Event) {"},{"lineNumber":418,"author":{"gitId":"-"},"content":" if (id) {"},{"lineNumber":419,"author":{"gitId":"-"},"content":" window.open(\u0027https://github.com/\u0027.concat(this.getRepoURL()).concat(\u0027/issues/\u0027).concat(String(id)));"},{"lineNumber":420,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":421,"author":{"gitId":"-"},"content":" this.errorHandlingService.handleError(new Error(ErrorMessageService.unableToOpenInBrowserMessage()));"},{"lineNumber":422,"author":{"gitId":"-"},"content":" }"},{"lineNumber":423,"author":{"gitId":"-"},"content":" event.stopPropagation();"},{"lineNumber":424,"author":{"gitId":"-"},"content":" }"},{"lineNumber":425,"author":{"gitId":"-"},"content":""},{"lineNumber":426,"author":{"gitId":"-"},"content":" reset(): void {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" this.logger.info(`GithubService: Resetting issues cache`);"},{"lineNumber":428,"author":{"gitId":"-"},"content":" this.issuesCacheManager.clear();"},{"lineNumber":429,"author":{"gitId":"-"},"content":" this.issuesLastModifiedManager.clear();"},{"lineNumber":430,"author":{"gitId":"-"},"content":" this.issueQueryRefs.clear();"},{"lineNumber":431,"author":{"gitId":"-"},"content":" }"},{"lineNumber":432,"author":{"gitId":"-"},"content":""},{"lineNumber":433,"author":{"gitId":"-"},"content":" getProfilesData(): Promise\u003cResponse\u003e {"},{"lineNumber":434,"author":{"gitId":"-"},"content":" return fetch(AppConfig.clientDataUrl);"},{"lineNumber":435,"author":{"gitId":"-"},"content":" }"},{"lineNumber":436,"author":{"gitId":"-"},"content":""},{"lineNumber":437,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":438,"author":{"gitId":"-"},"content":" * Performs an API call to fetch a page of filtered issues with a given pageNumber."},{"lineNumber":439,"author":{"gitId":"-"},"content":" *"},{"lineNumber":440,"author":{"gitId":"-"},"content":" * The request is sent with the ETag of the latest cached HTTP response."},{"lineNumber":441,"author":{"gitId":"-"},"content":" * If page requested has the same ETag, or the request results in an error,"},{"lineNumber":442,"author":{"gitId":"-"},"content":" * then the cached page is returned instead."},{"lineNumber":443,"author":{"gitId":"-"},"content":" *"},{"lineNumber":444,"author":{"gitId":"-"},"content":" * @param filter - The issue filter"},{"lineNumber":445,"author":{"gitId":"-"},"content":" * @param pageNumber - The page to be fetched"},{"lineNumber":446,"author":{"gitId":"-"},"content":" * @returns An observable representing the response containing a single page of filtered issues"},{"lineNumber":447,"author":{"gitId":"-"},"content":" */"},{"lineNumber":448,"author":{"gitId":"-"},"content":" private getIssuesAPICall(filter: RestGithubIssueFilter, pageNumber: number): Observable\u003cGithubResponse\u003cGithubIssue[]\u003e\u003e {"},{"lineNumber":449,"author":{"gitId":"-"},"content":" const apiCall: Promise\u003cGithubResponse\u003cGithubIssue[]\u003e\u003e \u003d octokit.issues.listForRepo({"},{"lineNumber":450,"author":{"gitId":"-"},"content":" ...filter,"},{"lineNumber":451,"author":{"gitId":"-"},"content":" owner: ORG_NAME,"},{"lineNumber":452,"author":{"gitId":"-"},"content":" repo: REPO,"},{"lineNumber":453,"author":{"gitId":"-"},"content":" sort: \u0027created\u0027,"},{"lineNumber":454,"author":{"gitId":"-"},"content":" direction: \u0027desc\u0027,"},{"lineNumber":455,"author":{"gitId":"-"},"content":" per_page: 100,"},{"lineNumber":456,"author":{"gitId":"-"},"content":" page: pageNumber,"},{"lineNumber":457,"author":{"gitId":"-"},"content":" headers: { \u0027If-None-Match\u0027: this.issuesCacheManager.getEtagFor(pageNumber) },"},{"lineNumber":458,"author":{"gitId":"-"},"content":" state: \u0027all\u0027"},{"lineNumber":459,"author":{"gitId":"-"},"content":" });"},{"lineNumber":460,"author":{"gitId":"-"},"content":" const apiCall$ \u003d from("},{"lineNumber":461,"author":{"gitId":"-"},"content":" apiCall.catch((err) \u003d\u003e {"},{"lineNumber":462,"author":{"gitId":"-"},"content":" return this.issuesCacheManager.get(pageNumber);"},{"lineNumber":463,"author":{"gitId":"-"},"content":" })"},{"lineNumber":464,"author":{"gitId":"-"},"content":" );"},{"lineNumber":465,"author":{"gitId":"-"},"content":""},{"lineNumber":466,"author":{"gitId":"-"},"content":" return apiCall$.pipe("},{"lineNumber":467,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e {"},{"lineNumber":468,"author":{"gitId":"-"},"content":" // catchError does not appear to catch an error on an observable created from a promise..."},{"lineNumber":469,"author":{"gitId":"-"},"content":" this.logger.info(`GithubService: Error caught in getIssuesAPICall`);"},{"lineNumber":470,"author":{"gitId":"-"},"content":" return of(this.issuesCacheManager.get(pageNumber));"},{"lineNumber":471,"author":{"gitId":"-"},"content":" })"},{"lineNumber":472,"author":{"gitId":"-"},"content":" );"},{"lineNumber":473,"author":{"gitId":"-"},"content":" }"},{"lineNumber":474,"author":{"gitId":"-"},"content":""},{"lineNumber":475,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":476,"author":{"gitId":"-"},"content":" * Fetches a list of items using a GraphQL query that queries for paginated data."},{"lineNumber":477,"author":{"gitId":"-"},"content":" *"},{"lineNumber":478,"author":{"gitId":"-"},"content":" * @param query - The GraphQL query that queries for paginated data."},{"lineNumber":479,"author":{"gitId":"-"},"content":" * @param variables - Additional variables for the GraphQL query."},{"lineNumber":480,"author":{"gitId":"-"},"content":" * @callback pluckEdges A function that returns a list of edges in a ApolloQueryResult."},{"lineNumber":481,"author":{"gitId":"-"},"content":" * @callback Model Constructor for the item model."},{"lineNumber":482,"author":{"gitId":"-"},"content":" * @returns A list of items from the query."},{"lineNumber":483,"author":{"gitId":"-"},"content":" */"},{"lineNumber":484,"author":{"gitId":"-"},"content":" private fetchGraphqlList\u003cT, M\u003e("},{"lineNumber":485,"author":{"gitId":"-"},"content":" query: DocumentNode,"},{"lineNumber":486,"author":{"gitId":"-"},"content":" variables: {},"},{"lineNumber":487,"author":{"gitId":"-"},"content":" pluckEdges: (results: ApolloQueryResult\u003cT\u003e) \u003d\u003e Array\u003cany\u003e,"},{"lineNumber":488,"author":{"gitId":"-"},"content":" Model: new (data) \u003d\u003e M"},{"lineNumber":489,"author":{"gitId":"-"},"content":" ): Observable\u003cArray\u003cM\u003e\u003e {"},{"lineNumber":490,"author":{"gitId":"-"},"content":" return this.withPagination\u003cT\u003e(pluckEdges, query, variables, false).pipe("},{"lineNumber":491,"author":{"gitId":"-"},"content":" map((results: ApolloQueryResult\u003cT\u003e[]) \u003d\u003e {"},{"lineNumber":492,"author":{"gitId":"-"},"content":" const issues \u003d results.reduce((accumulated, current) \u003d\u003e accumulated.concat(pluckEdges(current)), []);"},{"lineNumber":493,"author":{"gitId":"-"},"content":" return issues.map((issue) \u003d\u003e new Model(issue.node));"},{"lineNumber":494,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":495,"author":{"gitId":"-"},"content":" throwIfEmpty(() \u003d\u003e {"},{"lineNumber":496,"author":{"gitId":"-"},"content":" return new HttpErrorResponse({ status: 304 });"},{"lineNumber":497,"author":{"gitId":"-"},"content":" })"},{"lineNumber":498,"author":{"gitId":"-"},"content":" );"},{"lineNumber":499,"author":{"gitId":"-"},"content":" }"},{"lineNumber":500,"author":{"gitId":"-"},"content":""},{"lineNumber":501,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":502,"author":{"gitId":"-"},"content":" * Returns an observable that will continually emit the currently accumulated results, until a page that has less"},{"lineNumber":503,"author":{"gitId":"-"},"content":" * than 100 items is found, after which it performs a final emit with the full results array, and completes."},{"lineNumber":504,"author":{"gitId":"-"},"content":" *"},{"lineNumber":505,"author":{"gitId":"-"},"content":" * If `shouldAccumulate` is false, the observable will emit only the latest result, it will still complete on the"},{"lineNumber":506,"author":{"gitId":"-"},"content":" * same condition."},{"lineNumber":507,"author":{"gitId":"-"},"content":" *"},{"lineNumber":508,"author":{"gitId":"-"},"content":" * @callback pluckEdges - A function that returns a list of edges in a ApolloQueryResult."},{"lineNumber":509,"author":{"gitId":"-"},"content":" * @params query - The query to be performed."},{"lineNumber":510,"author":{"gitId":"-"},"content":" * @params variables - The variables for the query."},{"lineNumber":511,"author":{"gitId":"-"},"content":" * @params shouldAccumulate - Whether the observable should accumulate the results."},{"lineNumber":512,"author":{"gitId":"-"},"content":" * @returns an observable"},{"lineNumber":513,"author":{"gitId":"-"},"content":" */"},{"lineNumber":514,"author":{"gitId":"-"},"content":" private withPagination\u003cT\u003e("},{"lineNumber":515,"author":{"gitId":"-"},"content":" pluckEdges: (results: ApolloQueryResult\u003cT\u003e) \u003d\u003e Array\u003cany\u003e,"},{"lineNumber":516,"author":{"gitId":"-"},"content":" query: DocumentNode,"},{"lineNumber":517,"author":{"gitId":"-"},"content":" variables: { [key: string]: any } \u003d {},"},{"lineNumber":518,"author":{"gitId":"-"},"content":" shouldAccumulate: boolean \u003d true"},{"lineNumber":519,"author":{"gitId":"-"},"content":" ): Observable\u003cApolloQueryResult\u003cT\u003e[]\u003e {"},{"lineNumber":520,"author":{"gitId":"-"},"content":" const maxResultsCount \u003d 100;"},{"lineNumber":521,"author":{"gitId":"-"},"content":" const apollo \u003d this.apollo;"},{"lineNumber":522,"author":{"gitId":"-"},"content":""},{"lineNumber":523,"author":{"gitId":"-"},"content":" let accumulatedResults: ApolloQueryResult\u003cT\u003e[] \u003d [];"},{"lineNumber":524,"author":{"gitId":"-"},"content":" const behaviorSubject: BehaviorSubject\u003cApolloQueryResult\u003cT\u003e[]\u003e \u003d new BehaviorSubject(accumulatedResults);"},{"lineNumber":525,"author":{"gitId":"-"},"content":""},{"lineNumber":526,"author":{"gitId":"-"},"content":" async function queryWith(cursor: string): Promise\u003cvoid\u003e {"},{"lineNumber":527,"author":{"gitId":"-"},"content":" const graphqlQuery \u003d apollo.watchQuery\u003cT\u003e({ query, variables: { ...variables, cursor } });"},{"lineNumber":528,"author":{"gitId":"-"},"content":""},{"lineNumber":529,"author":{"gitId":"-"},"content":" await graphqlQuery.refetch().then(async (results: ApolloQueryResult\u003cT\u003e) \u003d\u003e {"},{"lineNumber":530,"author":{"gitId":"-"},"content":" const intermediate \u003d Array.isArray(results) ? results : [results];"},{"lineNumber":531,"author":{"gitId":"-"},"content":" const edges \u003d pluckEdges(results);"},{"lineNumber":532,"author":{"gitId":"-"},"content":" const nextCursor \u003d edges.length \u003d\u003d\u003d 0 ? null : edges[edges.length - 1].cursor;"},{"lineNumber":533,"author":{"gitId":"-"},"content":""},{"lineNumber":534,"author":{"gitId":"-"},"content":" if (shouldAccumulate) {"},{"lineNumber":535,"author":{"gitId":"-"},"content":" accumulatedResults \u003d accumulatedResults.concat(intermediate);"},{"lineNumber":536,"author":{"gitId":"-"},"content":" behaviorSubject.next(accumulatedResults);"},{"lineNumber":537,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":538,"author":{"gitId":"-"},"content":" behaviorSubject.next(intermediate);"},{"lineNumber":539,"author":{"gitId":"-"},"content":" }"},{"lineNumber":540,"author":{"gitId":"-"},"content":" if (edges.length \u003c maxResultsCount || !nextCursor) {"},{"lineNumber":541,"author":{"gitId":"-"},"content":" // No more queries to perform."},{"lineNumber":542,"author":{"gitId":"-"},"content":" behaviorSubject.complete();"},{"lineNumber":543,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":544,"author":{"gitId":"-"},"content":" }"},{"lineNumber":545,"author":{"gitId":"-"},"content":""},{"lineNumber":546,"author":{"gitId":"-"},"content":" // Use a chain of await to ensure that all recursive queries are completed before `complete` is called."},{"lineNumber":547,"author":{"gitId":"-"},"content":" await queryWith(nextCursor);"},{"lineNumber":548,"author":{"gitId":"-"},"content":" });"},{"lineNumber":549,"author":{"gitId":"-"},"content":" }"},{"lineNumber":550,"author":{"gitId":"-"},"content":""},{"lineNumber":551,"author":{"gitId":"-"},"content":" queryWith(null);"},{"lineNumber":552,"author":{"gitId":"-"},"content":""},{"lineNumber":553,"author":{"gitId":"-"},"content":" return behaviorSubject.asObservable();"},{"lineNumber":554,"author":{"gitId":"-"},"content":" }"},{"lineNumber":555,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":6,"NereusWB922":10,"MadLamprey":2,"-":537}},{"path":"src/app/core/services/grouping/assignee-grouping-strategy.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { map } from \u0027rxjs/operators\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { GithubUser } from \u0027../../models/github-user.model\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import { Issue } from \u0027../../models/issue.model\u0027;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"import { GithubService } from \u0027../github.service\u0027;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"import { GroupingStrategy } from \u0027./grouping-strategy.interface\u0027;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"/**"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" * A GroupingStrategy that groups issues/prs based on their assignees."},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":"@Injectable({"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"})"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":"export class AssigneeGroupingStrategy implements GroupingStrategy {"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" constructor(private githubService: GithubService) {}"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" * Retrieves data for a specific assignee."},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" * If it is the\"No Assignee\" group, unassigned issues are returned."},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" * Otherwise, issues assigned to the specified user are returned."},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" getDataForGroup(issues: Issue[], key: GithubUser): Issue[] {"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" if (key \u003d\u003d\u003d GithubUser.NO_ASSIGNEE) {"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" return this.getUnassignedData(issues);"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" return this.getDataAssignedToUser(issues, key);"},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" * Retrieves an Observable emitting users who can be assigned to issues,"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" * including a special \"No Assignee\" option."},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" getGroups(): Observable\u003cGithubUser[]\u003e {"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" return this.githubService.getUsersAssignable().pipe("},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":" map((users) \u003d\u003e {"},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" users.push(GithubUser.NO_ASSIGNEE);"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" return users;"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" })"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" );"},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" * Groups other than \"No Assignee\" need to be shown on the"},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":" * hidden group list if empty."},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" isInHiddenList(group: GithubUser): boolean {"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":" return group !\u003d\u003d GithubUser.NO_ASSIGNEE;"},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" private getDataAssignedToUser(issues: Issue[], user: GithubUser): Issue[] {"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" const filteredIssues \u003d issues.filter((issue) \u003d\u003e {"},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":" if (this.isPullRequest(issue)) {"},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" return this.isPullRequestCreatedByTarget(issue, user);"},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":57,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" return this.isIssueAssignedToTarget(issue, user);"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":61,"author":{"gitId":"NereusWB922"},"content":" return filteredIssues;"},{"lineNumber":62,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" private getUnassignedData(issues: Issue[]): Issue[] {"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":" return issues.filter((issue) \u003d\u003e !this.isPullRequest(issue) \u0026\u0026 issue.assignees.length \u003d\u003d\u003d 0);"},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":" private isPullRequest(issue: Issue): boolean {"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":" return issue.issueOrPr \u003d\u003d\u003d \u0027PullRequest\u0027;"},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":71,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" private isPullRequestCreatedByTarget(issue: Issue, target: GithubUser): boolean {"},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" return issue.author \u003d\u003d\u003d target.login;"},{"lineNumber":74,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" private isIssueAssignedToTarget(issue: Issue, target: GithubUser): boolean {"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" const isAssigneesFieldDefined \u003d !!issue.assignees;"},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":" return isAssigneesFieldDefined \u0026\u0026 issue.assignees.includes(target.login);"},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":81,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":81}},{"path":"src/app/core/services/grouping/grouping-context.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Injectable, Injector } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { ActivatedRoute, Router } from \u0027@angular/router\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { BehaviorSubject, Observable } from \u0027rxjs\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { Group } from \u0027../../models/github/group.interface\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import { Issue } from \u0027../../models/issue.model\u0027;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"import { AssigneeGroupingStrategy } from \u0027./assignee-grouping-strategy.service\u0027;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"import { GroupingStrategy } from \u0027./grouping-strategy.interface\u0027;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"import { MilestoneGroupingStrategy } from \u0027./milestone-grouping-strategy.service\u0027;"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"export enum GroupBy {"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" Assignee \u003d \u0027assignee\u0027,"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" Milestone \u003d \u0027milestone\u0027"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":"export const DEFAULT_GROUPBY \u003d GroupBy.Assignee;"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" * A service responsible for managing the current grouping strategy and providing grouped data."},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":"@Injectable({"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":"})"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":"export class GroupingContextService {"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" public static readonly GROUP_BY_QUERY_PARAM_KEY \u003d \u0027groupby\u0027;"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" private currGroupBySubject: BehaviorSubject\u003cGroupBy\u003e;"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" currGroupBy: GroupBy;"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" currGroupBy$: Observable\u003cGroupBy\u003e;"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" private groupingStrategyMap: Map\u003cstring, GroupingStrategy\u003e;"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" constructor(private injector: Injector, private route: ActivatedRoute, private router: Router) {"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" this.currGroupBy \u003d DEFAULT_GROUPBY;"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" this.currGroupBySubject \u003d new BehaviorSubject\u003cGroupBy\u003e(this.currGroupBy);"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" this.currGroupBy$ \u003d this.currGroupBySubject.asObservable();"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" this.groupingStrategyMap \u003d new Map\u003cstring, GroupingStrategy\u003e();"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" // Initialize the grouping strategy map with available strategies"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" this.groupingStrategyMap.set(GroupBy.Assignee, this.injector.get(AssigneeGroupingStrategy));"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" this.groupingStrategyMap.set(GroupBy.Milestone, this.injector.get(MilestoneGroupingStrategy));"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" * Initializes the service from URL parameters."},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":" initializeFromUrlParams() {"},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" const groupByParam \u003d this.route.snapshot.queryParamMap.get(GroupingContextService.GROUP_BY_QUERY_PARAM_KEY);"},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":" if (groupByParam \u0026\u0026 Object.values(GroupBy).includes(groupByParam as GroupBy)) {"},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" this.setCurrentGroupingType(groupByParam as GroupBy);"},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":" } else {"},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" this.setCurrentGroupingType(DEFAULT_GROUPBY);"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":57,"author":{"gitId":"NereusWB922"},"content":" * Sets the current grouping type and updates the corresponding query parameter in the URL."},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" * @param groupBy The grouping type to set."},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":" setCurrentGroupingType(groupBy: GroupBy): void {"},{"lineNumber":61,"author":{"gitId":"nknguyenhc"},"content":" if (groupBy !\u003d\u003d this.currGroupBy) {"},{"lineNumber":62,"author":{"gitId":"NereusWB922"},"content":" this.currGroupBy \u003d groupBy;"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" this.currGroupBySubject.next(this.currGroupBy);"},{"lineNumber":64,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" this.router.navigate([], {"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":" relativeTo: this.route,"},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":" queryParams: {"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":" [GroupingContextService.GROUP_BY_QUERY_PARAM_KEY]: groupBy"},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":" },"},{"lineNumber":71,"author":{"gitId":"NereusWB922"},"content":" queryParamsHandling: \u0027merge\u0027,"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" replaceUrl: true"},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":74,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" * Retrieves data for a specific group."},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":" * @param issues - An array of issues to be grouped."},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":" * @param group - The group by which issues are to be grouped."},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":" * @returns An array of issues belonging to the specified group."},{"lineNumber":81,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":82,"author":{"gitId":"NereusWB922"},"content":" getDataForGroup(issues: Issue[], group: Group): Issue[] {"},{"lineNumber":83,"author":{"gitId":"NereusWB922"},"content":" const strategy \u003d this.groupingStrategyMap.get(this.currGroupBy);"},{"lineNumber":84,"author":{"gitId":"NereusWB922"},"content":" return strategy.getDataForGroup(issues, group);"},{"lineNumber":85,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":86,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":87,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":88,"author":{"gitId":"NereusWB922"},"content":" * Retrieves all groups available for current grouping strategy."},{"lineNumber":89,"author":{"gitId":"NereusWB922"},"content":" * @returns An Observable emitting an array of groups."},{"lineNumber":90,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":91,"author":{"gitId":"NereusWB922"},"content":" getGroups(): Observable\u003cGroup[]\u003e {"},{"lineNumber":92,"author":{"gitId":"NereusWB922"},"content":" const strategy \u003d this.groupingStrategyMap.get(this.currGroupBy);"},{"lineNumber":93,"author":{"gitId":"NereusWB922"},"content":" return strategy.getGroups();"},{"lineNumber":94,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":95,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":96,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":97,"author":{"gitId":"NereusWB922"},"content":" * Determines whether a group should be shown on hidden list if it contains no issues."},{"lineNumber":98,"author":{"gitId":"NereusWB922"},"content":" * @param group - The group to check."},{"lineNumber":99,"author":{"gitId":"NereusWB922"},"content":" * @returns A boolean indicating whether the group should be shown on hidden list if empty."},{"lineNumber":100,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":101,"author":{"gitId":"NereusWB922"},"content":" isInHiddenList(group: Group): boolean {"},{"lineNumber":102,"author":{"gitId":"NereusWB922"},"content":" const strategy \u003d this.groupingStrategyMap.get(this.currGroupBy);"},{"lineNumber":103,"author":{"gitId":"NereusWB922"},"content":" return strategy.isInHiddenList(group);"},{"lineNumber":104,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":105,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":106,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":107,"author":{"gitId":"NereusWB922"},"content":" * Resets the current grouping type to the default."},{"lineNumber":108,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":109,"author":{"gitId":"NereusWB922"},"content":" reset(): void {"},{"lineNumber":110,"author":{"gitId":"NereusWB922"},"content":" this.setCurrentGroupingType(DEFAULT_GROUPBY);"},{"lineNumber":111,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":112,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"nknguyenhc":2,"NereusWB922":110}},{"path":"src/app/core/services/grouping/grouping-strategy.interface.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { Group } from \u0027../../models/github/group.interface\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { Issue } from \u0027../../models/issue.model\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"/**"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" * Represent a strategy for grouping issues/prs."},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" * This interface follows the Strategy Pattern, allowing for different"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" * strategies to be implemented for grouping issues/prs based on different criteria."},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"export interface GroupingStrategy {"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" * Retrieves data for a specific group."},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" * @param issues - An array of issues to be grouped."},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" * @param key - The group by which issues are to be grouped."},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" * @returns An array of issues belonging to the specified group."},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" getDataForGroup(issues: Issue[], key: Group): Issue[];"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" * Retrieves observable emitting groups available for the grouping strategy."},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" * @returns An Observable emitting an array of groups."},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" getGroups(): Observable\u003cGroup[]\u003e;"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" * Determines whether a group should be shown on hidden list if it contains no issues."},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" * @param group - The group to check."},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" * @returns A boolean indicating whether the group should be shown on hidden list if empty."},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" isInHiddenList(group: Group): boolean;"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":31}},{"path":"src/app/core/services/grouping/milestone-grouping-strategy.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { map } from \u0027rxjs/operators\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { Issue } from \u0027../../models/issue.model\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import { Milestone } from \u0027../../models/milestone.model\u0027;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"import { MilestoneService } from \u0027../milestone.service\u0027;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"import { GroupingStrategy } from \u0027./grouping-strategy.interface\u0027;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"/**"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" * A GroupingStrategy that groups issues/prs based on their milestones."},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":"@Injectable({"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"})"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":"export class MilestoneGroupingStrategy implements GroupingStrategy {"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" constructor(private milestoneService: MilestoneService) {}"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" * Retrieves data for a milestone."},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" getDataForGroup(issues: Issue[], key: Milestone): Issue[] {"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" return issues.filter((issue) \u003d\u003e issue.milestone.equals(key));"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" * Retrieves an Observable emitting milestones available for grouping issues."},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" getGroups(): Observable\u003cMilestone[]\u003e {"},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" return this.milestoneService.fetchMilestones().pipe("},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" map((milestones) \u003d\u003e {"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" const parseMilestone \u003d this.milestoneService.parseMilestoneData(milestones);"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" parseMilestone.push(Milestone.IssueWithoutMilestone);"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" parseMilestone.push(Milestone.PRWithoutMilestone);"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" return parseMilestone;"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" })"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" );"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" * Groups other than Default Milestone need to be shown on the"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" * hidden group list if empty."},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":" isInHiddenList(group: Milestone): boolean {"},{"lineNumber":44,"author":{"gitId":"MadLamprey"},"content":" return group !\u003d\u003d Milestone.IssueWithoutMilestone \u0026\u0026 group !\u003d\u003d Milestone.PRWithoutMilestone;"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":45,"MadLamprey":1}},{"path":"src/app/core/services/issue.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { BehaviorSubject, Observable, of, Subscription, throwError, timer } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { catchError, exhaustMap, finalize, map } from \u0027rxjs/operators\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import RestGithubIssueFilter from \u0027../models/github/github-issue-filter.model\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { GithubIssue } from \u0027../models/github/github-issue.model\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { Issue, Issues, IssuesFilter } from \u0027../models/issue.model\u0027;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"import { View } from \u0027../models/view.model\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027./github.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { UserService } from \u0027./user.service\u0027;"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"import { ViewService } from \u0027./view.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":13,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":14,"author":{"gitId":"-"},"content":"})"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * Responsible for creating and updating issues, and periodically fetching issues"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * using GitHub."},{"lineNumber":19,"author":{"gitId":"-"},"content":" */"},{"lineNumber":20,"author":{"gitId":"-"},"content":"export class IssueService {"},{"lineNumber":21,"author":{"gitId":"nknguyenhc"},"content":" static readonly POLL_INTERVAL \u003d 20000; // 20 seconds"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" issues: Issues;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" issues$: BehaviorSubject\u003cIssue[]\u003e;"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" private sessionId: string;"},{"lineNumber":27,"author":{"gitId":"-"},"content":" private issueTeamFilter \u003d \u0027All Teams\u0027;"},{"lineNumber":28,"author":{"gitId":"-"},"content":" private issuesPollSubscription: Subscription;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" /** Whether the IssueService is downloading the data from Github*/"},{"lineNumber":30,"author":{"gitId":"-"},"content":" public isLoading \u003d new BehaviorSubject\u003cboolean\u003e(false);"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" constructor(private githubService: GithubService, private userService: UserService, private viewService: ViewService) {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" this.issues$ \u003d new BehaviorSubject(new Array\u003cIssue\u003e());"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" startPollIssues() {"},{"lineNumber":37,"author":{"gitId":"-"},"content":" if (this.issuesPollSubscription \u003d\u003d\u003d undefined) {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" if (this.issues$.getValue().length \u003d\u003d\u003d 0) {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.isLoading.next(true);"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" this.issuesPollSubscription \u003d timer(0, IssueService.POLL_INTERVAL)"},{"lineNumber":43,"author":{"gitId":"-"},"content":" .pipe("},{"lineNumber":44,"author":{"gitId":"-"},"content":" exhaustMap(() \u003d\u003e {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" return this.reloadAllIssues().pipe("},{"lineNumber":46,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(err)),"},{"lineNumber":47,"author":{"gitId":"-"},"content":" finalize(() \u003d\u003e this.isLoading.next(false))"},{"lineNumber":48,"author":{"gitId":"-"},"content":" );"},{"lineNumber":49,"author":{"gitId":"-"},"content":" })"},{"lineNumber":50,"author":{"gitId":"-"},"content":" )"},{"lineNumber":51,"author":{"gitId":"-"},"content":" .subscribe();"},{"lineNumber":52,"author":{"gitId":"-"},"content":" }"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" stopPollIssues() {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" if (this.issuesPollSubscription) {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" this.issuesPollSubscription.unsubscribe();"},{"lineNumber":58,"author":{"gitId":"-"},"content":" this.issuesPollSubscription \u003d undefined;"},{"lineNumber":59,"author":{"gitId":"-"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" reloadAllIssues() {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" return this.initializeData();"},{"lineNumber":64,"author":{"gitId":"-"},"content":" }"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" getIssue(id: number): Observable\u003cIssue\u003e {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" if (this.issues \u003d\u003d\u003d undefined) {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" return this.getLatestIssue(id);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" return of(this.issues[id]);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" getLatestIssue(id: number): Observable\u003cIssue\u003e {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" return this.githubService.fetchIssueGraphql(id).pipe("},{"lineNumber":76,"author":{"gitId":"-"},"content":" map((response: GithubIssue) \u003d\u003e {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" this.createAndSaveIssueModels([response]);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" return this.issues[id];"},{"lineNumber":79,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":80,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e {"},{"lineNumber":81,"author":{"gitId":"-"},"content":" return of(this.issues[id]);"},{"lineNumber":82,"author":{"gitId":"-"},"content":" })"},{"lineNumber":83,"author":{"gitId":"-"},"content":" );"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":87,"author":{"gitId":"-"},"content":" * This function will update the issue\u0027s state of the application. This function needs to be called whenever a issue is added/updated."},{"lineNumber":88,"author":{"gitId":"-"},"content":" *"},{"lineNumber":89,"author":{"gitId":"-"},"content":" * @params issuesToUpdate - An array of issues to update the state of the application with."},{"lineNumber":90,"author":{"gitId":"-"},"content":" */"},{"lineNumber":91,"author":{"gitId":"-"},"content":" private updateLocalStore(issuesToUpdate: Issue[]) {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" const newIssues \u003d { ...this.issues };"},{"lineNumber":93,"author":{"gitId":"-"},"content":" issuesToUpdate.forEach((issue) \u003d\u003e {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" newIssues[issue.id] \u003d issue;"},{"lineNumber":95,"author":{"gitId":"-"},"content":" });"},{"lineNumber":96,"author":{"gitId":"-"},"content":" this.issues \u003d newIssues;"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" this.issues$.next(Object.values(this.issues));"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" reset(resetSessionId: boolean) {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" if (resetSessionId) {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" this.sessionId \u003d undefined;"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" this.issues \u003d undefined;"},{"lineNumber":107,"author":{"gitId":"-"},"content":" this.issues$.next(new Array\u003cIssue\u003e());"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" this.stopPollIssues();"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" private initializeData(): Observable\u003cIssue[]\u003e {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" let issuesAPICallsByFilter: Observable\u003cArray\u003cGithubIssue\u003e\u003e;"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"NereusWB922"},"content":" switch (IssuesFilter[this.viewService.currentView][this.userService.currentUser.role]) {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" case \u0027FILTER_BY_CREATOR\u0027:"},{"lineNumber":117,"author":{"gitId":"-"},"content":" issuesAPICallsByFilter \u003d this.githubService.fetchIssuesGraphql("},{"lineNumber":118,"author":{"gitId":"-"},"content":" new RestGithubIssueFilter({ creator: this.userService.currentUser.loginId })"},{"lineNumber":119,"author":{"gitId":"-"},"content":" );"},{"lineNumber":120,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":121,"author":{"gitId":"-"},"content":" case \u0027NO_FILTER\u0027:"},{"lineNumber":122,"author":{"gitId":"-"},"content":" issuesAPICallsByFilter \u003d this.githubService.fetchIssuesGraphql(new RestGithubIssueFilter({}));"},{"lineNumber":123,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":124,"author":{"gitId":"-"},"content":" case \u0027NO_ACCESS\u0027:"},{"lineNumber":125,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":126,"author":{"gitId":"-"},"content":" return of([]);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" const fetchedIssueIds: number[] \u003d [];"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" return issuesAPICallsByFilter.pipe("},{"lineNumber":132,"author":{"gitId":"-"},"content":" map((githubIssues: GithubIssue[]) \u003d\u003e {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" const issues \u003d this.createAndSaveIssueModels(githubIssues);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" for (const issue of issues) {"},{"lineNumber":135,"author":{"gitId":"-"},"content":" fetchedIssueIds.push(issue.id);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" }"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" const outdatedIssueIds: number[] \u003d this.getOutdatedIssueIds(fetchedIssueIds);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" this.deleteIssuesFromLocalStore(outdatedIssueIds);"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" if (this.issues \u003d\u003d\u003d undefined) {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" return [];"},{"lineNumber":143,"author":{"gitId":"-"},"content":" }"},{"lineNumber":144,"author":{"gitId":"-"},"content":" return Object.values(this.issues);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" })"},{"lineNumber":146,"author":{"gitId":"-"},"content":" );"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" private createAndSaveIssueModels(githubIssues: GithubIssue[]): Issue[] {"},{"lineNumber":150,"author":{"gitId":"-"},"content":" const issues: Issue[] \u003d [];"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" for (const githubIssue of githubIssues) {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" const issue \u003d this.createIssueModel(githubIssue);"},{"lineNumber":154,"author":{"gitId":"-"},"content":" issues.push(issue);"},{"lineNumber":155,"author":{"gitId":"-"},"content":" }"},{"lineNumber":156,"author":{"gitId":"-"},"content":" this.updateLocalStore(issues);"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"-"},"content":" return issues;"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" private deleteIssuesFromLocalStore(ids: number[]): void {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" const withoutIssuesToRemove \u003d { ...this.issues };"},{"lineNumber":163,"author":{"gitId":"-"},"content":" for (const id of ids) {"},{"lineNumber":164,"author":{"gitId":"-"},"content":" delete withoutIssuesToRemove[id];"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" this.issues \u003d withoutIssuesToRemove;"},{"lineNumber":168,"author":{"gitId":"-"},"content":""},{"lineNumber":169,"author":{"gitId":"-"},"content":" this.issues$.next(Object.values(this.issues));"},{"lineNumber":170,"author":{"gitId":"-"},"content":" }"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":173,"author":{"gitId":"-"},"content":" * Returns an array of outdated issue ids by comparing the ids of the recently"},{"lineNumber":174,"author":{"gitId":"-"},"content":" * fetched issues with the current issue ids in the local store"},{"lineNumber":175,"author":{"gitId":"-"},"content":" */"},{"lineNumber":176,"author":{"gitId":"-"},"content":" private getOutdatedIssueIds(fetchedIssueIds: number[]): number[] {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" /*"},{"lineNumber":178,"author":{"gitId":"-"},"content":" Ignore for first fetch or ignore if there is no fetch result"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" We also have to ignore for no fetch result as the cache might return a"},{"lineNumber":181,"author":{"gitId":"-"},"content":" 304 reponse with no differences in issues, resulting in the fetchIssueIds"},{"lineNumber":182,"author":{"gitId":"-"},"content":" to be empty"},{"lineNumber":183,"author":{"gitId":"-"},"content":" */"},{"lineNumber":184,"author":{"gitId":"-"},"content":" if (this.issues \u003d\u003d\u003d undefined || !fetchedIssueIds.length) {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" return [];"},{"lineNumber":186,"author":{"gitId":"-"},"content":" }"},{"lineNumber":187,"author":{"gitId":"-"},"content":""},{"lineNumber":188,"author":{"gitId":"-"},"content":" const fetchedIssueIdsSet \u003d new Set\u003cnumber\u003e(fetchedIssueIds);"},{"lineNumber":189,"author":{"gitId":"-"},"content":""},{"lineNumber":190,"author":{"gitId":"-"},"content":" const result \u003d Object.keys(this.issues)"},{"lineNumber":191,"author":{"gitId":"-"},"content":" .map((x) \u003d\u003e +x)"},{"lineNumber":192,"author":{"gitId":"-"},"content":" .filter((issueId) \u003d\u003e !fetchedIssueIdsSet.has(issueId));"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"-"},"content":" return result;"},{"lineNumber":195,"author":{"gitId":"-"},"content":" }"},{"lineNumber":196,"author":{"gitId":"-"},"content":""},{"lineNumber":197,"author":{"gitId":"-"},"content":" private createIssueModel(githubIssue: GithubIssue): Issue {"},{"lineNumber":198,"author":{"gitId":"NereusWB922"},"content":" switch (this.viewService.currentView) {"},{"lineNumber":199,"author":{"gitId":"NereusWB922"},"content":" case View.issuesViewer:"},{"lineNumber":200,"author":{"gitId":"-"},"content":" return Issue.createPhaseBugReportingIssue(githubIssue);"},{"lineNumber":201,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":202,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":203,"author":{"gitId":"-"},"content":" }"},{"lineNumber":204,"author":{"gitId":"-"},"content":" }"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" setIssueTeamFilter(filterValue: string) {"},{"lineNumber":207,"author":{"gitId":"-"},"content":" if (filterValue) {"},{"lineNumber":208,"author":{"gitId":"-"},"content":" this.issueTeamFilter \u003d filterValue;"},{"lineNumber":209,"author":{"gitId":"-"},"content":" }"},{"lineNumber":210,"author":{"gitId":"-"},"content":" }"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" setSessionId(sessionId: string) {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" this.sessionId \u003d sessionId;"},{"lineNumber":214,"author":{"gitId":"-"},"content":" }"},{"lineNumber":215,"author":{"gitId":"-"},"content":""},{"lineNumber":216,"author":{"gitId":"-"},"content":" getIssueTeamFilter(): string {"},{"lineNumber":217,"author":{"gitId":"-"},"content":" return this.issueTeamFilter;"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":1,"NereusWB922":6,"-":212}},{"path":"src/app/core/services/label.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"Arif-Khalid"},"content":"import { BehaviorSubject, EMPTY, Observable, of, Subject, Subscription, timer } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { catchError, exhaustMap, finalize, map } from \u0027rxjs/operators\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { Label, SimpleLabel } from \u0027../models/label.model\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027./github.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"/* The threshold to decide if color is dark or light."},{"lineNumber":8,"author":{"gitId":"-"},"content":"A higher threshold value will result in more colors determined to be \"dark\"."},{"lineNumber":9,"author":{"gitId":"-"},"content":"W3C recommendation is 0.179, but 0.184 is chosen so that some colors (like bright red)"},{"lineNumber":10,"author":{"gitId":"-"},"content":"are considered dark (Github too consider them dark) */"},{"lineNumber":11,"author":{"gitId":"-"},"content":"const COLOR_DARKNESS_THRESHOLD \u003d 0.184;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"const COLOR_BLACK \u003d \u0027000000\u0027; // Dark color for text with light background"},{"lineNumber":14,"author":{"gitId":"-"},"content":"const COLOR_WHITE \u003d \u0027ffffff\u0027; // Light color for text with dark background"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":17,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":18,"author":{"gitId":"-"},"content":"})"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":21,"author":{"gitId":"-"},"content":" * Responsible for retrieval and parsing of label data"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * from the GitHub repository for the WATcher application."},{"lineNumber":23,"author":{"gitId":"-"},"content":" */"},{"lineNumber":24,"author":{"gitId":"-"},"content":"export class LabelService {"},{"lineNumber":25,"author":{"gitId":"nknguyenhc"},"content":" static readonly POLL_INTERVAL \u003d 20000; // 20 seconds"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" labels: Label[];"},{"lineNumber":28,"author":{"gitId":"-"},"content":" simpleLabels: SimpleLabel[];"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" private labelsPollSubscription: Subscription;"},{"lineNumber":31,"author":{"gitId":"Arif-Khalid"},"content":" private labelsSubject \u003d new Subject\u003cSimpleLabel[]\u003e();"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" constructor(private githubService: GithubService) {}"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" startPollLabels() {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" if (this.labelsPollSubscription) {"},{"lineNumber":37,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" }"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.labelsPollSubscription \u003d timer(0, LabelService.POLL_INTERVAL)"},{"lineNumber":40,"author":{"gitId":"-"},"content":" .pipe("},{"lineNumber":41,"author":{"gitId":"-"},"content":" exhaustMap(() \u003d\u003e {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" return this.fetchLabels().pipe("},{"lineNumber":43,"author":{"gitId":"-"},"content":" catchError(() \u003d\u003e {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return EMPTY;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" })"},{"lineNumber":46,"author":{"gitId":"-"},"content":" );"},{"lineNumber":47,"author":{"gitId":"-"},"content":" })"},{"lineNumber":48,"author":{"gitId":"-"},"content":" )"},{"lineNumber":49,"author":{"gitId":"-"},"content":" .subscribe(() \u003d\u003e {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" this.labelsSubject.next(this.simpleLabels);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" });"},{"lineNumber":52,"author":{"gitId":"-"},"content":" }"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" stopPollLabels() {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" if (this.labelsPollSubscription) {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" this.labelsPollSubscription.unsubscribe();"},{"lineNumber":57,"author":{"gitId":"-"},"content":" this.labelsPollSubscription \u003d undefined;"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" connect(): Observable\u003cSimpleLabel[]\u003e {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" return this.labelsSubject.asObservable();"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":66,"author":{"gitId":"-"},"content":" * Fetch labels from Github."},{"lineNumber":67,"author":{"gitId":"-"},"content":" */"},{"lineNumber":68,"author":{"gitId":"-"},"content":" public fetchLabels(): Observable\u003cany\u003e {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" return this.githubService.fetchAllLabels().pipe("},{"lineNumber":70,"author":{"gitId":"-"},"content":" map((response) \u003d\u003e {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" this.labels \u003d this.parseLabelData(response);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" this.simpleLabels \u003d this.labels;"},{"lineNumber":73,"author":{"gitId":"-"},"content":" this.labelsSubject.next(this.simpleLabels);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" return response;"},{"lineNumber":75,"author":{"gitId":"-"},"content":" })"},{"lineNumber":76,"author":{"gitId":"-"},"content":" );"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":80,"author":{"gitId":"-"},"content":" * Parses label information and returns an array of Label objects."},{"lineNumber":81,"author":{"gitId":"-"},"content":" * @param labels - Label Information from API."},{"lineNumber":82,"author":{"gitId":"-"},"content":" */"},{"lineNumber":83,"author":{"gitId":"-"},"content":" parseLabelData(labels: Array\u003cany\u003e): Label[] {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" const labelData: Label[] \u003d [];"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" for (const label of labels) {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" labelData.push(new Label(label));"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":" return labelData;"},{"lineNumber":90,"author":{"gitId":"-"},"content":" }"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":93,"author":{"gitId":"-"},"content":" * Returns true if the given color is considered \"dark\""},{"lineNumber":94,"author":{"gitId":"-"},"content":" * The color is considered \"dark\" if its luminance is less than COLOR_DARKNESS_THRESHOLD"},{"lineNumber":95,"author":{"gitId":"-"},"content":" * @param inputColor: the color"},{"lineNumber":96,"author":{"gitId":"-"},"content":" */"},{"lineNumber":97,"author":{"gitId":"-"},"content":" isDarkColor(inputColor: string): boolean {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" const COLOR \u003d inputColor.charAt(0) \u003d\u003d\u003d \u0027#\u0027 ? inputColor.substring(1, 7) : inputColor;"},{"lineNumber":99,"author":{"gitId":"-"},"content":" const R \u003d parseInt(COLOR.substring(0, 2), 16);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" const G \u003d parseInt(COLOR.substring(2, 4), 16);"},{"lineNumber":101,"author":{"gitId":"-"},"content":" const B \u003d parseInt(COLOR.substring(4, 6), 16);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" const RGB \u003d [R / 255, G / 255, B / 255];"},{"lineNumber":103,"author":{"gitId":"-"},"content":" const LINEAR_RGB \u003d RGB.map((col) \u003d\u003e {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" if (col \u003c\u003d 0.03928) {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" return col / 12.92;"},{"lineNumber":106,"author":{"gitId":"-"},"content":" }"},{"lineNumber":107,"author":{"gitId":"-"},"content":" return Math.pow((col + 0.055) / 1.055, 2.4);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" });"},{"lineNumber":109,"author":{"gitId":"-"},"content":" // Calculate the luminance of the color"},{"lineNumber":110,"author":{"gitId":"-"},"content":" const LUMINANCE \u003d 0.2126 * LINEAR_RGB[0] + 0.7152 * LINEAR_RGB[1] + 0.0722 * LINEAR_RGB[2];"},{"lineNumber":111,"author":{"gitId":"-"},"content":" // The color is \"dark\" if the luminance is lower than the threshold"},{"lineNumber":112,"author":{"gitId":"-"},"content":" return LUMINANCE \u003c COLOR_DARKNESS_THRESHOLD;"},{"lineNumber":113,"author":{"gitId":"-"},"content":" }"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":116,"author":{"gitId":"-"},"content":" * Returns a css style for the background and text color of the label"},{"lineNumber":117,"author":{"gitId":"-"},"content":" * @param color: the color of the label"},{"lineNumber":118,"author":{"gitId":"-"},"content":" * @return the style with background-color in rgb"},{"lineNumber":119,"author":{"gitId":"-"},"content":" * @throws exception if input is an invalid color code"},{"lineNumber":120,"author":{"gitId":"-"},"content":" */"},{"lineNumber":121,"author":{"gitId":"-"},"content":" setLabelStyle(color: string) {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" let textColor: string;"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" textColor \u003d this.isDarkColor(color) ? COLOR_WHITE : COLOR_BLACK;"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" const styles \u003d {"},{"lineNumber":127,"author":{"gitId":"-"},"content":" \u0027background-color\u0027: `#${color}`,"},{"lineNumber":128,"author":{"gitId":"-"},"content":" color: `#${textColor}`"},{"lineNumber":129,"author":{"gitId":"-"},"content":" };"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" return styles;"},{"lineNumber":132,"author":{"gitId":"-"},"content":" }"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" reset() {"},{"lineNumber":135,"author":{"gitId":"-"},"content":" this.labels \u003d undefined;"},{"lineNumber":136,"author":{"gitId":"-"},"content":" this.simpleLabels \u003d undefined;"},{"lineNumber":137,"author":{"gitId":"-"},"content":" this.stopPollLabels();"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":1,"Arif-Khalid":2,"-":136}},{"path":"src/app/core/services/milestone.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { map } from \u0027rxjs/operators\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { Milestone } from \u0027../models/milestone.model\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027./github.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":8,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":9,"author":{"gitId":"-"},"content":"})"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":12,"author":{"gitId":"-"},"content":" * Responsible for retrieval and parsing and syncing of milestone data"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * from the GitHub repository for the WATcher application."},{"lineNumber":14,"author":{"gitId":"-"},"content":" */"},{"lineNumber":15,"author":{"gitId":"-"},"content":"export class MilestoneService {"},{"lineNumber":16,"author":{"gitId":"nknguyenhc"},"content":" milestones: Milestone[] \u003d [];"},{"lineNumber":17,"author":{"gitId":"-"},"content":" hasNoMilestones: boolean;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":" constructor(private githubService: GithubService) {}"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * Fetch all milestones from github."},{"lineNumber":23,"author":{"gitId":"-"},"content":" */"},{"lineNumber":24,"author":{"gitId":"-"},"content":" public fetchMilestones(): Observable\u003cany\u003e {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" return this.githubService.fetchAllMilestones().pipe("},{"lineNumber":26,"author":{"gitId":"-"},"content":" map((response) \u003d\u003e {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" this.milestones \u003d this.parseMilestoneData(response);"},{"lineNumber":28,"author":{"gitId":"-"},"content":" this.hasNoMilestones \u003d response.length \u003d\u003d\u003d 0;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" return response;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" })"},{"lineNumber":31,"author":{"gitId":"-"},"content":" );"},{"lineNumber":32,"author":{"gitId":"-"},"content":" }"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":35,"author":{"gitId":"-"},"content":" * Parses milestone information and returns an array of Milestone objects."},{"lineNumber":36,"author":{"gitId":"-"},"content":" * @param milestones - Milestone Information from API."},{"lineNumber":37,"author":{"gitId":"-"},"content":" */"},{"lineNumber":38,"author":{"gitId":"-"},"content":" parseMilestoneData(milestones: Array\u003cany\u003e): Milestone[] {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" const milestoneData: Milestone[] \u003d [];"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" for (const milestone of milestones) {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" milestoneData.push(new Milestone(milestone));"},{"lineNumber":43,"author":{"gitId":"-"},"content":" }"},{"lineNumber":44,"author":{"gitId":"-"},"content":" milestoneData.sort((a: Milestone, b: Milestone) \u003d\u003e a.title.localeCompare(b.title));"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" return milestoneData;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" }"},{"lineNumber":48,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":49,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" * Returns the open milestone with earliest deadline."},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":" * If no deadline exists, returns milestone with alphabetically smallest title."},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" * Returns null if there are no open milestones."},{"lineNumber":53,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":54,"author":{"gitId":"nknguyenhc"},"content":" getEarliestOpenMilestone(): Milestone {"},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" const openMilestones: Milestone[] \u003d this.milestones.filter((milestone: Milestone) \u003d\u003e milestone.state \u003d\u003d\u003d \u0027open\u0027);"},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":57,"author":{"gitId":"NereusWB922"},"content":" if (openMilestones.length \u003d\u003d\u003d 0) {"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" return null;"},{"lineNumber":59,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":61,"author":{"gitId":"NereusWB922"},"content":" const target \u003d openMilestones.reduce((prev, curr) \u003d\u003e {"},{"lineNumber":62,"author":{"gitId":"NereusWB922"},"content":" if (prev \u003d\u003d\u003d null) {"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" return curr;"},{"lineNumber":64,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" if (prev.deadline !\u003d\u003d curr.deadline) {"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":" if (!prev.deadline) {"},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":" return curr;"},{"lineNumber":69,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":" if (!curr.deadline) {"},{"lineNumber":71,"author":{"gitId":"NereusWB922"},"content":" return prev;"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" return prev.deadline \u003c curr.deadline ? prev : curr;"},{"lineNumber":74,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" // Both without due date or with the same due date"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" return prev.title.localeCompare(curr.title) \u003c 0 ? prev : curr;"},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":" }, null);"},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":" return target;"},{"lineNumber":81,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":82,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":83,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":84,"author":{"gitId":"nknguyenhc"},"content":" * Gets the closed milestone with the latest deadline."},{"lineNumber":85,"author":{"gitId":"nknguyenhc"},"content":" * Returns null if there is no closed milestone with deadline."},{"lineNumber":86,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":87,"author":{"gitId":"nknguyenhc"},"content":" getLatestClosedMilestone(): Milestone {"},{"lineNumber":88,"author":{"gitId":"nknguyenhc"},"content":" let latestClosedMilestone: Milestone \u003d null;"},{"lineNumber":89,"author":{"gitId":"nknguyenhc"},"content":" for (const milestone of this.milestones) {"},{"lineNumber":90,"author":{"gitId":"nknguyenhc"},"content":" if (!milestone.deadline || milestone.state !\u003d\u003d \u0027closed\u0027) {"},{"lineNumber":91,"author":{"gitId":"nknguyenhc"},"content":" continue;"},{"lineNumber":92,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":93,"author":{"gitId":"nknguyenhc"},"content":" if (latestClosedMilestone \u003d\u003d\u003d null) {"},{"lineNumber":94,"author":{"gitId":"nknguyenhc"},"content":" latestClosedMilestone \u003d milestone;"},{"lineNumber":95,"author":{"gitId":"nknguyenhc"},"content":" } else if (milestone.deadline \u003e latestClosedMilestone.deadline) {"},{"lineNumber":96,"author":{"gitId":"nknguyenhc"},"content":" latestClosedMilestone \u003d milestone;"},{"lineNumber":97,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":98,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":99,"author":{"gitId":"nknguyenhc"},"content":" return latestClosedMilestone;"},{"lineNumber":100,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":28,"NereusWB922":26,"-":47}},{"path":"src/app/core/services/view.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { ActivatedRoute, Router } from \u0027@angular/router\u0027;"},{"lineNumber":3,"author":{"gitId":"nknguyenhc"},"content":"import { BehaviorSubject, Observable, of, Subject } from \u0027rxjs\u0027;"},{"lineNumber":4,"author":{"gitId":"nknguyenhc"},"content":"import { map } from \u0027rxjs/operators\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { STORAGE_KEYS } from \u0027../constants/storage-keys.constants\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { Repo } from \u0027../models/repo.model\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { SessionData } from \u0027../models/session.model\u0027;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"import { View } from \u0027../models/view.model\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { ErrorMessageService } from \u0027./error-message.service\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027./github.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027./logging.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { RepoUrlCacheService } from \u0027./repo-url-cache.service\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"export const SESSION_AVALIABILITY_FIX_FAILED \u003d \u0027Session Availability Fix failed.\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" * The title of each view that appears in the header bar."},{"lineNumber":18,"author":{"gitId":"-"},"content":" */"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":"export const ViewDescription \u003d {"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" [View.issuesViewer]: \u0027Issues Dashboard\u0027,"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" [View.activityDashboard]: \u0027Activity Dashboard\u0027"},{"lineNumber":22,"author":{"gitId":"-"},"content":"};"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * All data of the session."},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" * Add accessible views here."},{"lineNumber":27,"author":{"gitId":"-"},"content":" */"},{"lineNumber":28,"author":{"gitId":"-"},"content":"export const STARTING_SESSION_DATA: SessionData \u003d {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" sessionRepo: ["},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" { view: View.issuesViewer, repos: [] }"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" // { view: View.activityDashboard, repos: [] }"},{"lineNumber":32,"author":{"gitId":"-"},"content":" ]"},{"lineNumber":33,"author":{"gitId":"-"},"content":"};"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":"export const STARTING_VIEW \u003d View.issuesViewer;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":38,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":39,"author":{"gitId":"-"},"content":"})"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":42,"author":{"gitId":"-"},"content":" * Responsible for managing the current selected feature of WATcher as well as the"},{"lineNumber":43,"author":{"gitId":"-"},"content":" * current session data and repository details related to the session."},{"lineNumber":44,"author":{"gitId":"-"},"content":" */"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":"export class ViewService {"},{"lineNumber":46,"author":{"gitId":"nknguyenhc"},"content":" public static readonly REPO_QUERY_PARAM_KEY \u003d \u0027repo\u0027;"},{"lineNumber":47,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" public currentView: View \u003d STARTING_VIEW;"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":" public currentRepo: Repo; // current or main repository of current view"},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" public otherRepos: Repo[]; // more repositories relevant to this view"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" repoSetSource \u003d new BehaviorSubject(false);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" repoSetState \u003d this.repoSetSource.asObservable();"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":56,"author":{"gitId":"-"},"content":" * Expose an observable to track changes to currentRepo"},{"lineNumber":57,"author":{"gitId":"-"},"content":" *"},{"lineNumber":58,"author":{"gitId":"-"},"content":" * TODO - replace all references to currentRepo to have"},{"lineNumber":59,"author":{"gitId":"-"},"content":" * dependencies subscribe to this observable?"},{"lineNumber":60,"author":{"gitId":"-"},"content":" */"},{"lineNumber":61,"author":{"gitId":"-"},"content":" public repoChanged$: Subject\u003cRepo | null\u003e \u003d new Subject();"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" /** Whether the ViewService is changing the repository */"},{"lineNumber":64,"author":{"gitId":"-"},"content":" public isChangingRepo \u003d new BehaviorSubject\u003cboolean\u003e(false);"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" public sessionData \u003d STARTING_SESSION_DATA; // stores session data for the session"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"nknguyenhc"},"content":" constructor("},{"lineNumber":69,"author":{"gitId":"nknguyenhc"},"content":" private githubService: GithubService,"},{"lineNumber":70,"author":{"gitId":"nknguyenhc"},"content":" private repoUrlCacheService: RepoUrlCacheService,"},{"lineNumber":71,"author":{"gitId":"nknguyenhc"},"content":" public logger: LoggingService,"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" private route: ActivatedRoute,"},{"lineNumber":73,"author":{"gitId":"nknguyenhc"},"content":" private router: Router"},{"lineNumber":74,"author":{"gitId":"nknguyenhc"},"content":" ) {}"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":77,"author":{"gitId":"-"},"content":" * Sets the current main repository and additional repos if any."},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":" * Updates session data in View Service and local storage."},{"lineNumber":79,"author":{"gitId":"-"},"content":" * Updates Github Service with current repository."},{"lineNumber":80,"author":{"gitId":"-"},"content":" * @param repo Main current repository"},{"lineNumber":81,"author":{"gitId":"-"},"content":" * @param repos Additional repositories"},{"lineNumber":82,"author":{"gitId":"-"},"content":" */"},{"lineNumber":83,"author":{"gitId":"-"},"content":" setRepository(repo: Repo, repos?: Repo[]): void {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" this.currentRepo \u003d repo;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" this.otherRepos \u003d repos ? repos : [];"},{"lineNumber":86,"author":{"gitId":"NereusWB922"},"content":" this.sessionData.sessionRepo.find((x) \u003d\u003e x.view \u003d\u003d\u003d this.currentView).repos \u003d this.getRepository();"},{"lineNumber":87,"author":{"gitId":"NereusWB922"},"content":" this.githubService.storeViewDetails(this.currentRepo.owner, this.currentRepo.name);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" localStorage.setItem(\u0027sessionData\u0027, JSON.stringify(this.sessionData));"},{"lineNumber":89,"author":{"gitId":"nknguyenhc"},"content":" this.router.navigate([\u0027issuesViewer\u0027], {"},{"lineNumber":90,"author":{"gitId":"nknguyenhc"},"content":" queryParams: {"},{"lineNumber":91,"author":{"gitId":"NereusWB922"},"content":" [ViewService.REPO_QUERY_PARAM_KEY]: repo.toString()"},{"lineNumber":92,"author":{"gitId":"NereusWB922"},"content":" },"},{"lineNumber":93,"author":{"gitId":"NereusWB922"},"content":" queryParamsHandling: \u0027merge\u0027"},{"lineNumber":94,"author":{"gitId":"nknguyenhc"},"content":" });"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":98,"author":{"gitId":"-"},"content":" * Changes current respository to a new repository."},{"lineNumber":99,"author":{"gitId":"-"},"content":" * @param repo New current repository"},{"lineNumber":100,"author":{"gitId":"-"},"content":" */"},{"lineNumber":101,"author":{"gitId":"-"},"content":" private changeCurrentRepository(repo: Repo): void {"},{"lineNumber":102,"author":{"gitId":"NereusWB922"},"content":" this.logger.info(`ViewService: Changing current repository to \u0027${repo}\u0027`);"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"NereusWB922"},"content":" if (this.currentView \u003d\u003d\u003d View.issuesViewer) {"},{"lineNumber":105,"author":{"gitId":"NereusWB922"},"content":" /** Adds past repositories to view */"},{"lineNumber":106,"author":{"gitId":"-"},"content":" (this.otherRepos || []).push(this.currentRepo);"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"nknguyenhc"},"content":" if (!repo.equals(this.currentRepo)) {"},{"lineNumber":109,"author":{"gitId":"-"},"content":" this.setRepository(repo, this.otherRepos);"},{"lineNumber":110,"author":{"gitId":"nknguyenhc"},"content":" this.repoChanged$.next(repo);"},{"lineNumber":111,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" this.repoUrlCacheService.cache(repo.toString());"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":117,"author":{"gitId":"-"},"content":" * Change repository if a valid repository is provided"},{"lineNumber":118,"author":{"gitId":"-"},"content":" * @param repo New repository"},{"lineNumber":119,"author":{"gitId":"-"},"content":" */"},{"lineNumber":120,"author":{"gitId":"-"},"content":" async changeRepositoryIfValid(repo: Repo) {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" this.isChangingRepo.next(true);"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" const isValidRepository \u003d await this.githubService.isRepositoryPresent(repo.owner, repo.name).toPromise();"},{"lineNumber":124,"author":{"gitId":"-"},"content":" if (!isValidRepository) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" this.isChangingRepo.next(false);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" throw new Error(ErrorMessageService.repositoryNotPresentMessage());"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" this.changeCurrentRepository(repo);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" this.isChangingRepo.next(false);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" }"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":134,"author":{"gitId":"-"},"content":" * Returns the full repository array of the current feature."},{"lineNumber":135,"author":{"gitId":"-"},"content":" */"},{"lineNumber":136,"author":{"gitId":"-"},"content":" getRepository(): Repo[] {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" return [this.currentRepo].concat(this.otherRepos);"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":141,"author":{"gitId":"-"},"content":" * Retrieves the repository url from local storage and sets to current repository."},{"lineNumber":142,"author":{"gitId":"-"},"content":" */"},{"lineNumber":143,"author":{"gitId":"-"},"content":" async initializeCurrentRepository() {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" const org \u003d window.localStorage.getItem(STORAGE_KEYS.ORG);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" const repoName \u003d window.localStorage.getItem(STORAGE_KEYS.DATA_REPO);"},{"lineNumber":146,"author":{"gitId":"NereusWB922"},"content":" this.logger.info(`ViewService: received initial org (${org}) and initial name (${repoName})`);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" let repo: Repo;"},{"lineNumber":148,"author":{"gitId":"-"},"content":" if (!org || !repoName) {"},{"lineNumber":149,"author":{"gitId":"-"},"content":" repo \u003d Repo.ofEmptyRepo();"},{"lineNumber":150,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" repo \u003d new Repo(org, repoName);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" }"},{"lineNumber":153,"author":{"gitId":"-"},"content":" const isValidRepository \u003d await this.githubService.isRepositoryPresent(repo.owner, repo.name).toPromise();"},{"lineNumber":154,"author":{"gitId":"-"},"content":" if (!isValidRepository) {"},{"lineNumber":155,"author":{"gitId":"-"},"content":" throw new Error(ErrorMessageService.repositoryNotPresentMessage());"},{"lineNumber":156,"author":{"gitId":"-"},"content":" }"},{"lineNumber":157,"author":{"gitId":"NereusWB922"},"content":" this.logger.info(`ViewService: Repo is ${repo}`);"},{"lineNumber":158,"author":{"gitId":"-"},"content":" this.setRepository(repo);"},{"lineNumber":159,"author":{"gitId":"-"},"content":" this.repoSetSource.next(true);"},{"lineNumber":160,"author":{"gitId":"-"},"content":" }"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":163,"author":{"gitId":"nknguyenhc"},"content":" * Set items in the local storage corresponding to the next URL."},{"lineNumber":164,"author":{"gitId":"NereusWB922"},"content":" * This includes checking if the view is valid, and if the repo is of the correct format."},{"lineNumber":165,"author":{"gitId":"nknguyenhc"},"content":" * @param url The partial URL without the host, e.g. `/issuesViewer?repo\u003dCATcher%2FWATcher."},{"lineNumber":166,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":167,"author":{"gitId":"nknguyenhc"},"content":" setupFromUrl(url: string): Observable\u003cvoid\u003e {"},{"lineNumber":168,"author":{"gitId":"NereusWB922"},"content":" return of(this.getViewAndRepoFromUrl(url)).pipe("},{"lineNumber":169,"author":{"gitId":"NereusWB922"},"content":" map(([viewName, repoName]) \u003d\u003e {"},{"lineNumber":170,"author":{"gitId":"NereusWB922"},"content":" if (!this.isViewAllowed(viewName)) {"},{"lineNumber":171,"author":{"gitId":"nknguyenhc"},"content":" throw new Error(ErrorMessageService.invalidUrlMessage());"},{"lineNumber":172,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":173,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":174,"author":{"gitId":"nknguyenhc"},"content":" if (repoName \u003d\u003d\u003d null) {"},{"lineNumber":175,"author":{"gitId":"nknguyenhc"},"content":" throw new Error(ErrorMessageService.invalidUrlMessage());"},{"lineNumber":176,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":177,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":178,"author":{"gitId":"nknguyenhc"},"content":" const newRepo \u003d Repo.of(repoName);"},{"lineNumber":179,"author":{"gitId":"nknguyenhc"},"content":" if (newRepo) {"},{"lineNumber":180,"author":{"gitId":"nknguyenhc"},"content":" window.localStorage.setItem(STORAGE_KEYS.ORG, newRepo.owner);"},{"lineNumber":181,"author":{"gitId":"nknguyenhc"},"content":" window.localStorage.setItem(STORAGE_KEYS.DATA_REPO, newRepo.name);"},{"lineNumber":182,"author":{"gitId":"nknguyenhc"},"content":" this.repoUrlCacheService.cache(newRepo.toString());"},{"lineNumber":183,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":184,"author":{"gitId":"nknguyenhc"},"content":" })"},{"lineNumber":185,"author":{"gitId":"nknguyenhc"},"content":" );"},{"lineNumber":186,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":187,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":188,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":189,"author":{"gitId":"NereusWB922"},"content":" * Initializes a repo based on the URL parameters and changes the repo if valid."},{"lineNumber":190,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":191,"author":{"gitId":"NereusWB922"},"content":" initializeRepoFromUrlParams(): void {"},{"lineNumber":192,"author":{"gitId":"NereusWB922"},"content":" const repoParams \u003d this.route.snapshot.queryParamMap.get(ViewService.REPO_QUERY_PARAM_KEY);"},{"lineNumber":193,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":194,"author":{"gitId":"NereusWB922"},"content":" const newRepo \u003d Repo.of(repoParams);"},{"lineNumber":195,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":196,"author":{"gitId":"NereusWB922"},"content":" this.changeRepositoryIfValid(newRepo);"},{"lineNumber":197,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":198,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":199,"author":{"gitId":"NereusWB922"},"content":" getViewAndRepoFromUrl(url: string): [string, string] {"},{"lineNumber":200,"author":{"gitId":"nknguyenhc"},"content":" const urlObject \u003d new URL(`${location.protocol}//${location.host}${url}`);"},{"lineNumber":201,"author":{"gitId":"nknguyenhc"},"content":" const pathname \u003d urlObject.pathname;"},{"lineNumber":202,"author":{"gitId":"NereusWB922"},"content":" const reponame \u003d urlObject.searchParams.get(ViewService.REPO_QUERY_PARAM_KEY);"},{"lineNumber":203,"author":{"gitId":"nknguyenhc"},"content":" return [pathname, reponame];"},{"lineNumber":204,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":205,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":206,"author":{"gitId":"NereusWB922"},"content":" isViewAllowed(viewName: string) {"},{"lineNumber":207,"author":{"gitId":"NereusWB922"},"content":" return viewName \u003d\u003d\u003d \u0027/\u0027 + View.issuesViewer;"},{"lineNumber":208,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":209,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":210,"author":{"gitId":"-"},"content":" isRepoSet(): boolean {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" return this.repoSetSource.getValue();"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":215,"author":{"gitId":"NereusWB922"},"content":" * Changes view and updates View Service\u0027s properties."},{"lineNumber":216,"author":{"gitId":"NereusWB922"},"content":" * @param view New view"},{"lineNumber":217,"author":{"gitId":"-"},"content":" */"},{"lineNumber":218,"author":{"gitId":"NereusWB922"},"content":" changeView(view: View) {"},{"lineNumber":219,"author":{"gitId":"NereusWB922"},"content":" this.currentView \u003d view;"},{"lineNumber":220,"author":{"gitId":"-"},"content":""},{"lineNumber":221,"author":{"gitId":"-"},"content":" // For now, assumes repository stays the same"},{"lineNumber":222,"author":{"gitId":"NereusWB922"},"content":" this.githubService.storeViewDetails(this.currentRepo.owner, this.currentRepo.name);"},{"lineNumber":223,"author":{"gitId":"-"},"content":" }"},{"lineNumber":224,"author":{"gitId":"-"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":" public getCurrentRepositoryURL() {"},{"lineNumber":226,"author":{"gitId":"-"},"content":" return this.currentRepo.owner.concat(\u0027/\u0027).concat(this.currentRepo.name);"},{"lineNumber":227,"author":{"gitId":"-"},"content":" }"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" reset() {"},{"lineNumber":230,"author":{"gitId":"NereusWB922"},"content":" this.currentView \u003d STARTING_VIEW;"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":45,"NereusWB922":52,"-":135}},{"path":"src/app/issues-viewer/card-view/card-view.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":".card-column {"},{"lineNumber":2,"author":{"gitId":"-"},"content":" margin: 8px;"},{"lineNumber":3,"author":{"gitId":"nknguyenhc"},"content":" height: 77vh;"},{"lineNumber":4,"author":{"gitId":"nknguyenhc"},"content":" display: flex;"},{"lineNumber":5,"author":{"gitId":"nknguyenhc"},"content":" flex-direction: column;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"}"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":".card {"},{"lineNumber":9,"author":{"gitId":"-"},"content":" margin: 8px 0px 8px 0px;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"}"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":".mat-card-title {"},{"lineNumber":13,"author":{"gitId":"-"},"content":" display: flex;"},{"lineNumber":14,"author":{"gitId":"-"},"content":" align-items: center;"},{"lineNumber":15,"author":{"gitId":"-"},"content":" font-size: 12px;"},{"lineNumber":16,"author":{"gitId":"-"},"content":" text-align: center;"},{"lineNumber":17,"author":{"gitId":"-"},"content":" overflow: auto;"},{"lineNumber":18,"author":{"gitId":"-"},"content":" word-break: break-word;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"}"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":".column-header .mat-card-title {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" font-size: 14px;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"}"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":".mat-card {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" padding: 10px;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"}"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":":host ::ng-deep div.mat-card-header-text {"},{"lineNumber":30,"author":{"gitId":"-"},"content":" margin: 2px;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"}"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":"div.column-header .mat-card-title {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" justify-content: center;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" margin: 0;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"}"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":"div.column-header {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" justify-content: center;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" position: relative;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" z-index: 5;"},{"lineNumber":42,"author":{"gitId":"-"},"content":"}"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":"div.column-header .mat-card-header {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" display: flex;"},{"lineNumber":46,"author":{"gitId":"-"},"content":" align-items: center;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" justify-content: center;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"}"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":".scrollable-container {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" margin-bottom: 2px;"},{"lineNumber":52,"author":{"gitId":"-"},"content":" position: relative;"},{"lineNumber":53,"author":{"gitId":"-"},"content":"}"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"Arif-Khalid"},"content":"/* Ref: https://lea.verou.me/blog/2012/04/background-attachment-local/ */"},{"lineNumber":56,"author":{"gitId":"Arif-Khalid"},"content":".scroll-shadow {"},{"lineNumber":57,"author":{"gitId":"Arif-Khalid"},"content":" background:"},{"lineNumber":58,"author":{"gitId":"Arif-Khalid"},"content":" /* Shadow covers */ linear-gradient(white 30%, rgba(255, 255, 255, 0)),"},{"lineNumber":59,"author":{"gitId":"Arif-Khalid"},"content":" linear-gradient(rgba(255, 255, 255, 0), white 70%) 0 100%,"},{"lineNumber":60,"author":{"gitId":"Arif-Khalid"},"content":" /* Shadows */ radial-gradient(50% 0, farthest-side, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0)),"},{"lineNumber":61,"author":{"gitId":"Arif-Khalid"},"content":" radial-gradient(50% 100%, farthest-side, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0)) 0 100%;"},{"lineNumber":62,"author":{"gitId":"Arif-Khalid"},"content":" background:"},{"lineNumber":63,"author":{"gitId":"Arif-Khalid"},"content":" /* Shadow covers */ linear-gradient(white 30%, rgba(255, 255, 255, 0)),"},{"lineNumber":64,"author":{"gitId":"Arif-Khalid"},"content":" linear-gradient(rgba(255, 255, 255, 0), white 70%) 0 100%,"},{"lineNumber":65,"author":{"gitId":"Arif-Khalid"},"content":" /* Shadows */ radial-gradient(farthest-side at 50% 0, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0)),"},{"lineNumber":66,"author":{"gitId":"Arif-Khalid"},"content":" radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0)) 0 100%;"},{"lineNumber":67,"author":{"gitId":"Arif-Khalid"},"content":" background-repeat: no-repeat;"},{"lineNumber":68,"author":{"gitId":"Arif-Khalid"},"content":" background-color: white;"},{"lineNumber":69,"author":{"gitId":"Arif-Khalid"},"content":" background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px;"},{"lineNumber":70,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":71,"author":{"gitId":"Arif-Khalid"},"content":" /* Opera doesn\u0027t support this in the shorthand */"},{"lineNumber":72,"author":{"gitId":"Arif-Khalid"},"content":" background-attachment: local, local, scroll, scroll;"},{"lineNumber":73,"author":{"gitId":"-"},"content":"}"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":".scrollable-container::before {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" pointer-events: none;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" content: \u0027\u0027;"},{"lineNumber":78,"author":{"gitId":"-"},"content":" position: absolute;"},{"lineNumber":79,"author":{"gitId":"-"},"content":" z-index: 2;"},{"lineNumber":80,"author":{"gitId":"-"},"content":" height: 6px;"},{"lineNumber":81,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":82,"author":{"gitId":"-"},"content":" display: block;"},{"lineNumber":83,"author":{"gitId":"-"},"content":" background-image: linear-gradient(to bottom, white 66%, transparent);"},{"lineNumber":84,"author":{"gitId":"-"},"content":"}"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":".scrollable-container::after {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" pointer-events: none;"},{"lineNumber":88,"author":{"gitId":"-"},"content":" content: \u0027\u0027;"},{"lineNumber":89,"author":{"gitId":"-"},"content":" position: sticky;"},{"lineNumber":90,"author":{"gitId":"-"},"content":" z-index: 2;"},{"lineNumber":91,"author":{"gitId":"-"},"content":" top: 100%;"},{"lineNumber":92,"author":{"gitId":"-"},"content":" height: 6px;"},{"lineNumber":93,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":94,"author":{"gitId":"-"},"content":" display: block;"},{"lineNumber":95,"author":{"gitId":"-"},"content":" background-image: linear-gradient(to top, white 66%, transparent);"},{"lineNumber":96,"author":{"gitId":"-"},"content":"}"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":".scrollable-container-wrapper {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" position: relative;"},{"lineNumber":100,"author":{"gitId":"nknguyenhc"},"content":" scrollbar-width: none;"},{"lineNumber":101,"author":{"gitId":"nknguyenhc"},"content":" overflow: auto;"},{"lineNumber":102,"author":{"gitId":"nknguyenhc"},"content":" flex-grow: 1;"},{"lineNumber":103,"author":{"gitId":"-"},"content":"}"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"nknguyenhc"},"content":".scrollable-container-wrapper::-webkit-scrollbar {"},{"lineNumber":106,"author":{"gitId":"nknguyenhc"},"content":" display: none;"},{"lineNumber":107,"author":{"gitId":"-"},"content":"}"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":".loading-spinner {"},{"lineNumber":110,"author":{"gitId":"-"},"content":" display: flex;"},{"lineNumber":111,"author":{"gitId":"-"},"content":" justify-content: center;"},{"lineNumber":112,"author":{"gitId":"-"},"content":" align-items: center;"},{"lineNumber":113,"author":{"gitId":"-"},"content":"}"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":".mat-card-subtitle {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" display: flex;"},{"lineNumber":117,"author":{"gitId":"-"},"content":" align-items: center;"},{"lineNumber":118,"author":{"gitId":"-"},"content":" font-size: 11px;"},{"lineNumber":119,"author":{"gitId":"-"},"content":" text-align: left;"},{"lineNumber":120,"author":{"gitId":"-"},"content":" overflow: auto;"},{"lineNumber":121,"author":{"gitId":"-"},"content":" margin: 6px 0;"},{"lineNumber":122,"author":{"gitId":"-"},"content":"}"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":".row-count {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" background-color: rgb(222, 222, 222);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" border-radius: 3px;"},{"lineNumber":127,"author":{"gitId":"-"},"content":" cursor: default;"},{"lineNumber":128,"author":{"gitId":"-"},"content":" padding: 6px;"},{"lineNumber":129,"author":{"gitId":"-"},"content":" color: rgb(0, 0, 0);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" font-weight: 410;"},{"lineNumber":131,"author":{"gitId":"-"},"content":" display: inline-flex;"},{"lineNumber":132,"author":{"gitId":"-"},"content":" font-size: 14px;"},{"lineNumber":133,"author":{"gitId":"-"},"content":"}"},{"lineNumber":134,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":135,"author":{"gitId":"nknguyenhc"},"content":":host ::ng-deep .pagination-hide-arrow .mat-paginator-navigation-previous {"},{"lineNumber":136,"author":{"gitId":"nknguyenhc"},"content":" display: none !important;"},{"lineNumber":137,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":138,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":139,"author":{"gitId":"nknguyenhc"},"content":":host ::ng-deep .pagination-hide-arrow .mat-paginator-navigation-next {"},{"lineNumber":140,"author":{"gitId":"nknguyenhc"},"content":" display: none !important;"},{"lineNumber":141,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":142,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":143,"author":{"gitId":"nknguyenhc"},"content":":host ::ng-deep .pagination-hide-arrow .mat-paginator-range-actions {"},{"lineNumber":144,"author":{"gitId":"nknguyenhc"},"content":" display: none !important;"},{"lineNumber":145,"author":{"gitId":"nknguyenhc"},"content":"}"}],"authorContributionMap":{"nknguyenhc":20,"Arif-Khalid":18,"-":107}},{"path":"src/app/issues-viewer/card-view/card-view.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"card-column\"\u003e"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" \u003cng-container"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" [ngTemplateOutlet]\u003d\"getHeaderTemplate() || defaultHeader\""},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" [ngTemplateOutletContext]\u003d\"{ $implicit: this.group }\""},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" \u003e\u003c/ng-container\u003e"},{"lineNumber":6,"author":{"gitId":"Arif-Khalid"},"content":" \u003cdiv class\u003d\"scrollable-container-wrapper scroll-shadow\"\u003e"},{"lineNumber":7,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"scrollable-container\"\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"issue-pr-cards\" *ngFor\u003d\"let issue of this.issues$ | async; index as i\"\u003e"},{"lineNumber":9,"author":{"gitId":"MadLamprey"},"content":" \u003capp-issue-pr-card [issue]\u003d\"issue\" [filter]\u003d\"issues.filter\" [milestoneService]\u003d\"milestoneService\"\u003e\u003c/app-issue-pr-card\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003cmat-card class\u003d\"loading-spinner\" *ngIf\u003d\"this.issues.isLoading$ | async\"\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003cmat-progress-spinner color\u003d\"primary\" mode\u003d\"indeterminate\" diameter\u003d\"50\" strokeWidth\u003d\"5\"\u003e\u003c/mat-progress-spinner\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003c/mat-card\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":16,"author":{"gitId":"nknguyenhc"},"content":" \u003cmat-paginator"},{"lineNumber":17,"author":{"gitId":"nknguyenhc"},"content":" [pageSize]\u003d\"pageSize\""},{"lineNumber":18,"author":{"gitId":"MadLamprey"},"content":" [hidePageSize]\u003d\"true\""},{"lineNumber":19,"author":{"gitId":"nknguyenhc"},"content":" [pageSizeOptions]\u003d\"[10, 20, 50]\""},{"lineNumber":20,"author":{"gitId":"nknguyenhc"},"content":" [class]\u003d\"pageSize \u003e\u003d issueLength ? \u0027pagination-hide-arrow\u0027 : \u0027\u0027\""},{"lineNumber":21,"author":{"gitId":"nknguyenhc"},"content":" \u003e\u003c/mat-paginator\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":"\u003c!-- Template --\u003e"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":"\u003cng-template #defaultHeader\u003e"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card class\u003d\"loading-spinner\"\u003e"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-progress-spinner color\u003d\"primary\" mode\u003d\"indeterminate\" diameter\u003d\"50\" strokeWidth\u003d\"5\"\u003e\u003c/mat-progress-spinner\u003e"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card\u003e"},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":"\u003c/ng-template\u003e"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":"\u003cng-template #assigneeHeader let-assignee\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"column-header\"\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003cmat-card\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003cmat-card-header [ngStyle]\u003d\"{ height: \u002740px\u0027 }\"\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":" \u003cdiv"},{"lineNumber":36,"author":{"gitId":"-"},"content":" mat-card-avatar"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":" *ngIf\u003d\"assignee\""},{"lineNumber":38,"author":{"gitId":"-"},"content":" [ngStyle]\u003d\"{"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" background: \u0027url(\u0027 + assignee.avatar_url + \u0027)\u0027,"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u0027background-size\u0027: \u002740px\u0027"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }\""},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u003e\u003c/div\u003e"},{"lineNumber":43,"author":{"gitId":"-"},"content":" \u003cmat-card-title\u003e"},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" {{ assignee.login }}"},{"lineNumber":45,"author":{"gitId":"-"},"content":" \u003c/mat-card-title\u003e"},{"lineNumber":46,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row-count\"\u003e{{ this.issues.count }}\u003c/div\u003e"},{"lineNumber":47,"author":{"gitId":"-"},"content":" \u003c/mat-card-header\u003e"},{"lineNumber":48,"author":{"gitId":"-"},"content":" \u003c/mat-card\u003e"},{"lineNumber":49,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":"\u003c/ng-template\u003e"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":"\u003cng-template #milestoneHeader let-milestone\u003e"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv class\u003d\"column-header\"\u003e"},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card\u003e"},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card-header [ngStyle]\u003d\"{ height: \u002740px\u0027 }\"\u003e"},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card-title\u003e"},{"lineNumber":57,"author":{"gitId":"NereusWB922"},"content":" {{ milestone.title }}"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card-title\u003e"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv class\u003d\"row-count\"\u003e{{ this.issues.count }}\u003c/div\u003e"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card-header\u003e"},{"lineNumber":61,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card\u003e"},{"lineNumber":62,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":"\u003c/ng-template\u003e"}],"authorContributionMap":{"nknguyenhc":5,"NereusWB922":28,"Arif-Khalid":1,"MadLamprey":2,"-":27}},{"path":"src/app/issues-viewer/card-view/card-view.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import {"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" AfterViewInit,"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" Component,"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" ElementRef,"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" EventEmitter,"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" Input,"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" OnDestroy,"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" OnInit,"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" Output,"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" TemplateRef,"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" ViewChild"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":"} from \u0027@angular/core\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { MatPaginator } from \u0027@angular/material/paginator\u0027;"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"import { Observable, Subscription } from \u0027rxjs\u0027;"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":"import { Group } from \u0027../../core/models/github/group.interface\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import { Issue } from \u0027../../core/models/issue.model\u0027;"},{"lineNumber":17,"author":{"gitId":"nknguyenhc"},"content":"import { FiltersService } from \u0027../../core/services/filters.service\u0027;"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":"import { GroupBy, GroupingContextService } from \u0027../../core/services/grouping/grouping-context.service\u0027;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import { IssueService } from \u0027../../core/services/issue.service\u0027;"},{"lineNumber":20,"author":{"gitId":"nknguyenhc"},"content":"import { MilestoneService } from \u0027../../core/services/milestone.service\u0027;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import { FilterableComponent, FilterableSource } from \u0027../../shared/issue-tables/filterableTypes\u0027;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import { IssuesDataTable } from \u0027../../shared/issue-tables/IssuesDataTable\u0027;"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":25,"author":{"gitId":"-"},"content":" selector: \u0027app-card-view\u0027,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" templateUrl: \u0027./card-view.component.html\u0027,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./card-view.component.css\u0027]"},{"lineNumber":28,"author":{"gitId":"-"},"content":"})"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":31,"author":{"gitId":"-"},"content":" * Displays issues as Cards."},{"lineNumber":32,"author":{"gitId":"-"},"content":" */"},{"lineNumber":33,"author":{"gitId":"-"},"content":"export class CardViewComponent implements OnInit, AfterViewInit, OnDestroy, FilterableComponent {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" @Input() headers: string[];"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" @Input() group?: Group \u003d undefined;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" @Input() filters?: any \u003d undefined;"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" @ViewChild(\u0027defaultHeader\u0027) defaultHeaderTemplate: TemplateRef\u003cany\u003e;"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" @ViewChild(\u0027assigneeHeader\u0027) assigneeHeaderTemplate: TemplateRef\u003cany\u003e;"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" @ViewChild(\u0027milestoneHeader\u0027) milestoneHeaderTemplate: TemplateRef\u003cany\u003e;"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" issues: IssuesDataTable;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" issues$: Observable\u003cIssue[]\u003e;"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":" private timeoutId: NodeJS.Timeout | null \u003d null;"},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" private issuesLengthSubscription: Subscription;"},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" private issuesLoadingStateSubscription: Subscription;"},{"lineNumber":49,"author":{"gitId":"MadLamprey"},"content":" private filterSubscription: Subscription;"},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":51,"author":{"gitId":"Arif-Khalid"},"content":" isLoading \u003d true;"},{"lineNumber":52,"author":{"gitId":"Arif-Khalid"},"content":" issueLength \u003d 0;"},{"lineNumber":53,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":54,"author":{"gitId":"nknguyenhc"},"content":" pageSize \u003d 20;"},{"lineNumber":55,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":56,"author":{"gitId":"nknguyenhc"},"content":" @Output() issueLengthChange: EventEmitter\u003cNumber\u003e \u003d new EventEmitter\u003cNumber\u003e();"},{"lineNumber":57,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":58,"author":{"gitId":"nknguyenhc"},"content":" constructor("},{"lineNumber":59,"author":{"gitId":"nknguyenhc"},"content":" public element: ElementRef,"},{"lineNumber":60,"author":{"gitId":"nknguyenhc"},"content":" public issueService: IssueService,"},{"lineNumber":61,"author":{"gitId":"nknguyenhc"},"content":" public groupingContextService: GroupingContextService,"},{"lineNumber":62,"author":{"gitId":"nknguyenhc"},"content":" private filtersService: FiltersService,"},{"lineNumber":63,"author":{"gitId":"nknguyenhc"},"content":" private milestoneService: MilestoneService"},{"lineNumber":64,"author":{"gitId":"nknguyenhc"},"content":" ) {}"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" ngOnInit() {"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":" this.issues \u003d new IssuesDataTable("},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":" this.issueService,"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":" this.groupingContextService,"},{"lineNumber":70,"author":{"gitId":"nknguyenhc"},"content":" this.filtersService,"},{"lineNumber":71,"author":{"gitId":"nknguyenhc"},"content":" this.milestoneService,"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" this.paginator,"},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" this.headers,"},{"lineNumber":74,"author":{"gitId":"NereusWB922"},"content":" this.group,"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":" this.filters"},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" );"},{"lineNumber":77,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":78,"author":{"gitId":"MadLamprey"},"content":" this.filterSubscription \u003d this.filtersService.filter$.subscribe((filter: any) \u003d\u003e {"},{"lineNumber":79,"author":{"gitId":"MadLamprey"},"content":" this.pageSize \u003d filter.itemsPerPage;"},{"lineNumber":80,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" ngAfterViewInit(): void {"},{"lineNumber":84,"author":{"gitId":"NereusWB922"},"content":" this.timeoutId \u003d setTimeout(() \u003d\u003e {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" this.issues.loadIssues();"},{"lineNumber":86,"author":{"gitId":"-"},"content":" this.issues$ \u003d this.issues.connect();"},{"lineNumber":87,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":88,"author":{"gitId":"Arif-Khalid"},"content":" // Emit event when issues change"},{"lineNumber":89,"author":{"gitId":"NereusWB922"},"content":" this.issuesLengthSubscription \u003d this.issues$.subscribe(() \u003d\u003e {"},{"lineNumber":90,"author":{"gitId":"nknguyenhc"},"content":" this.issueLength \u003d this.issues.count;"},{"lineNumber":91,"author":{"gitId":"nknguyenhc"},"content":" this.issueLengthChange.emit(this.issueLength);"},{"lineNumber":92,"author":{"gitId":"Arif-Khalid"},"content":" });"},{"lineNumber":93,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":94,"author":{"gitId":"Arif-Khalid"},"content":" // Emit event when loading state changes"},{"lineNumber":95,"author":{"gitId":"NereusWB922"},"content":" this.issuesLoadingStateSubscription \u003d this.issues.isLoading$.subscribe((isLoadingUpdate) \u003d\u003e {"},{"lineNumber":96,"author":{"gitId":"Arif-Khalid"},"content":" this.isLoading \u003d isLoadingUpdate;"},{"lineNumber":97,"author":{"gitId":"Arif-Khalid"},"content":" });"},{"lineNumber":98,"author":{"gitId":"-"},"content":" });"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"NereusWB922"},"content":" getHeaderTemplate(): TemplateRef\u003cany\u003e {"},{"lineNumber":102,"author":{"gitId":"NereusWB922"},"content":" switch (this.groupingContextService.currGroupBy) {"},{"lineNumber":103,"author":{"gitId":"NereusWB922"},"content":" case GroupBy.Assignee:"},{"lineNumber":104,"author":{"gitId":"NereusWB922"},"content":" return this.assigneeHeaderTemplate;"},{"lineNumber":105,"author":{"gitId":"NereusWB922"},"content":" case GroupBy.Milestone:"},{"lineNumber":106,"author":{"gitId":"NereusWB922"},"content":" return this.milestoneHeaderTemplate;"},{"lineNumber":107,"author":{"gitId":"NereusWB922"},"content":" default:"},{"lineNumber":108,"author":{"gitId":"NereusWB922"},"content":" return this.defaultHeaderTemplate;"},{"lineNumber":109,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":110,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":111,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" ngOnDestroy(): void {"},{"lineNumber":113,"author":{"gitId":"NereusWB922"},"content":" if (this.timeoutId) {"},{"lineNumber":114,"author":{"gitId":"NereusWB922"},"content":" clearTimeout(this.timeoutId);"},{"lineNumber":115,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":116,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":117,"author":{"gitId":"NereusWB922"},"content":" if (this.issues) {"},{"lineNumber":118,"author":{"gitId":"-"},"content":" this.issues.disconnect();"},{"lineNumber":119,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":120,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":121,"author":{"gitId":"NereusWB922"},"content":" if (this.issuesLengthSubscription) {"},{"lineNumber":122,"author":{"gitId":"NereusWB922"},"content":" this.issuesLengthSubscription.unsubscribe();"},{"lineNumber":123,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":124,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":125,"author":{"gitId":"NereusWB922"},"content":" if (this.issuesLoadingStateSubscription) {"},{"lineNumber":126,"author":{"gitId":"NereusWB922"},"content":" this.issuesLoadingStateSubscription.unsubscribe();"},{"lineNumber":127,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" retrieveFilterable(): FilterableSource {"},{"lineNumber":131,"author":{"gitId":"-"},"content":" return this.issues;"},{"lineNumber":132,"author":{"gitId":"-"},"content":" }"},{"lineNumber":133,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":17,"NereusWB922":59,"Arif-Khalid":10,"MadLamprey":5,"-":42}},{"path":"src/app/issues-viewer/hidden-groups/hidden-groups.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":".hidden-groups {"},{"lineNumber":2,"author":{"gitId":"nknguyenhc"},"content":" margin: 8px;"},{"lineNumber":3,"author":{"gitId":"nknguyenhc"},"content":" min-width: 150px;"},{"lineNumber":4,"author":{"gitId":"nknguyenhc"},"content":" max-width: 300px;"},{"lineNumber":5,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":6,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":7,"author":{"gitId":"nknguyenhc"},"content":".row-count {"},{"lineNumber":8,"author":{"gitId":"nknguyenhc"},"content":" background-color: rgb(222, 222, 222);"},{"lineNumber":9,"author":{"gitId":"nknguyenhc"},"content":" border-radius: 3px;"},{"lineNumber":10,"author":{"gitId":"nknguyenhc"},"content":" cursor: default;"},{"lineNumber":11,"author":{"gitId":"nknguyenhc"},"content":" padding: 6px;"},{"lineNumber":12,"author":{"gitId":"nknguyenhc"},"content":" color: rgb(0, 0, 0);"},{"lineNumber":13,"author":{"gitId":"nknguyenhc"},"content":" font-weight: 410;"},{"lineNumber":14,"author":{"gitId":"nknguyenhc"},"content":" display: inline-flex;"},{"lineNumber":15,"author":{"gitId":"nknguyenhc"},"content":" font-size: 14px;"},{"lineNumber":16,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":17,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":18,"author":{"gitId":"nknguyenhc"},"content":".mat-card-header {"},{"lineNumber":19,"author":{"gitId":"nknguyenhc"},"content":" display: flex;"},{"lineNumber":20,"author":{"gitId":"nknguyenhc"},"content":" flex-direction: row;"},{"lineNumber":21,"author":{"gitId":"nknguyenhc"},"content":" align-items: center;"},{"lineNumber":22,"author":{"gitId":"nknguyenhc"},"content":" width: 100%;"},{"lineNumber":23,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":24,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":25,"author":{"gitId":"nknguyenhc"},"content":".mat-card {"},{"lineNumber":26,"author":{"gitId":"nknguyenhc"},"content":" margin: 8px 0px;"},{"lineNumber":27,"author":{"gitId":"nknguyenhc"},"content":" height: 40px;"},{"lineNumber":28,"author":{"gitId":"nknguyenhc"},"content":" padding: 10px;"},{"lineNumber":29,"author":{"gitId":"nknguyenhc"},"content":" display: flex;"},{"lineNumber":30,"author":{"gitId":"nknguyenhc"},"content":" align-items: center;"},{"lineNumber":31,"author":{"gitId":"nknguyenhc"},"content":" justify-content: center;"},{"lineNumber":32,"author":{"gitId":"nknguyenhc"},"content":" flex-direction: row;"},{"lineNumber":33,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":34,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":35,"author":{"gitId":"nknguyenhc"},"content":".mat-card-title {"},{"lineNumber":36,"author":{"gitId":"nknguyenhc"},"content":" font-size: 14px;"},{"lineNumber":37,"author":{"gitId":"nknguyenhc"},"content":" text-align: center;"},{"lineNumber":38,"author":{"gitId":"nknguyenhc"},"content":" margin: 0;"},{"lineNumber":39,"author":{"gitId":"nknguyenhc"},"content":" flex-grow: 1;"},{"lineNumber":40,"author":{"gitId":"nknguyenhc"},"content":" margin: 2px;"},{"lineNumber":41,"author":{"gitId":"nknguyenhc"},"content":" word-break: break-word;"},{"lineNumber":42,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":43,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":44,"author":{"gitId":"nknguyenhc"},"content":".mat-card-avatar {"},{"lineNumber":45,"author":{"gitId":"nknguyenhc"},"content":" height: 30px;"},{"lineNumber":46,"author":{"gitId":"nknguyenhc"},"content":" width: 30px;"},{"lineNumber":47,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":48,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":49,"author":{"gitId":"nknguyenhc"},"content":".mat-card-header .mat-card-title {"},{"lineNumber":50,"author":{"gitId":"nknguyenhc"},"content":" font-size: 12px;"},{"lineNumber":51,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":52,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":53,"author":{"gitId":"nknguyenhc"},"content":".scrollable-container {"},{"lineNumber":54,"author":{"gitId":"nknguyenhc"},"content":" height: 67vh;"},{"lineNumber":55,"author":{"gitId":"nknguyenhc"},"content":" overflow: auto;"},{"lineNumber":56,"author":{"gitId":"nknguyenhc"},"content":" scrollbar-width: none;"},{"lineNumber":57,"author":{"gitId":"nknguyenhc"},"content":" -ms-overflow-style: none;"},{"lineNumber":58,"author":{"gitId":"nknguyenhc"},"content":" position: relative;"},{"lineNumber":59,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":60,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":61,"author":{"gitId":"nknguyenhc"},"content":".scrollable-containers::-webkit-scrollbar {"},{"lineNumber":62,"author":{"gitId":"nknguyenhc"},"content":" display: none;"},{"lineNumber":63,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":64,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":65,"author":{"gitId":"nknguyenhc"},"content":".scrollable-container::before,"},{"lineNumber":66,"author":{"gitId":"nknguyenhc"},"content":".scrollable-container::after {"},{"lineNumber":67,"author":{"gitId":"nknguyenhc"},"content":" pointer-events: none;"},{"lineNumber":68,"author":{"gitId":"nknguyenhc"},"content":" content: \u0027\u0027;"},{"lineNumber":69,"author":{"gitId":"nknguyenhc"},"content":" z-index: 2;"},{"lineNumber":70,"author":{"gitId":"nknguyenhc"},"content":" height: 6px;"},{"lineNumber":71,"author":{"gitId":"nknguyenhc"},"content":" width: 100%;"},{"lineNumber":72,"author":{"gitId":"nknguyenhc"},"content":" display: block;"},{"lineNumber":73,"author":{"gitId":"nknguyenhc"},"content":" background-image: linear-gradient(to bottom, white 66%, transparent);"},{"lineNumber":74,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":75,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":76,"author":{"gitId":"nknguyenhc"},"content":".scrollable-container::before {"},{"lineNumber":77,"author":{"gitId":"nknguyenhc"},"content":" position: absolute;"},{"lineNumber":78,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":79,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":80,"author":{"gitId":"nknguyenhc"},"content":".scrollable-container::after {"},{"lineNumber":81,"author":{"gitId":"nknguyenhc"},"content":" position: sticky;"},{"lineNumber":82,"author":{"gitId":"nknguyenhc"},"content":"}"}],"authorContributionMap":{"nknguyenhc":81,"NereusWB922":1}},{"path":"src/app/issues-viewer/hidden-groups/hidden-groups.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"\u003cdiv *ngIf\u003d\"groups.length \u003e 0\" class\u003d\"hidden-groups\"\u003e"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card matTooltip\u003d\"Users that have no Issues/PRs pertaining to the current filter\" matTooltipShowDelay\u003d\"0\" matTooltipHideDelay\u003d\"0\"\u003e"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card-title\u003eHidden {{ this.groupingContextService.currGroupBy }}s\u003c/mat-card-title\u003e"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv class\u003d\"row-count\"\u003e{{ groups.length }}\u003c/div\u003e"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card\u003e"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv class\u003d\"scrollable-container\"\u003e"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv *ngFor\u003d\"let group of groups\"\u003e"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" \u003cng-container [ngTemplateOutlet]\u003d\"getCardTemplate()\" [ngTemplateOutletContext]\u003d\"{ $implicit: group }\"\u003e\u003c/ng-container\u003e"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" \u003c/div\u003e"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" \u003c/div\u003e"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":"\u003c/div\u003e"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":"\u003c!-- Templates --\u003e"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"\u003cng-template #defaultCard let-group\u003e"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card class\u003d\"loading-spinner\"\u003e"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-progress-spinner color\u003d\"primary\" mode\u003d\"indeterminate\" diameter\u003d\"50\" strokeWidth\u003d\"5\"\u003e\u003c/mat-progress-spinner\u003e"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card\u003e"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":"\u003c/ng-template\u003e"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":"\u003cng-template #assigneeCard let-assignee\u003e"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card\u003e"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" \u003cmar-card-header class\u003d\"mat-card-header\"\u003e"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" mat-card-avatar"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" [ngStyle]\u003d\"{"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" background: \u0027url(\u0027 + assignee.avatar_url + \u0027)\u0027,"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" \u0027background-size\u0027: \u002730px\u0027"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" }\""},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" \u003e\u003c/div\u003e"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card-title\u003e{{ assignee.login }}\u003c/mat-card-title\u003e"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" \u003c/mar-card-header\u003e"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card\u003e"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":"\u003c/ng-template\u003e"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":"\u003cng-template #milestoneCard let-milestone\u003e"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card\u003e"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":" \u003cmar-card-header class\u003d\"mat-card-header\"\u003e"},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card-title\u003e{{ milestone.title }}\u003c/mat-card-title\u003e"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" \u003c/mar-card-header\u003e"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card\u003e"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":"\u003c/ng-template\u003e"}],"authorContributionMap":{"NereusWB922":41}},{"path":"src/app/issues-viewer/hidden-groups/hidden-groups.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Component, Input, TemplateRef, ViewChild } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { Group } from \u0027../../core/models/github/group.interface\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { GroupBy, GroupingContextService } from \u0027../../core/services/grouping/grouping-context.service\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"@Component({"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" selector: \u0027app-hidden-groups\u0027,"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" templateUrl: \u0027./hidden-groups.component.html\u0027,"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" styleUrls: [\u0027./hidden-groups.component.css\u0027]"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"})"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"export class HiddenGroupsComponent {"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" @Input() groups: Group[] \u003d [];"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" @ViewChild(\u0027defaultCard\u0027) defaultCardTemplate: TemplateRef\u003cany\u003e;"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" @ViewChild(\u0027assigneeCard\u0027) assigneeCardTemplate: TemplateRef\u003cany\u003e;"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" @ViewChild(\u0027milestoneCard\u0027) milestoneCardTemplate: TemplateRef\u003cany\u003e;"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" constructor(public groupingContextService: GroupingContextService) {}"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" getCardTemplate(): TemplateRef\u003cany\u003e {"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" switch (this.groupingContextService.currGroupBy) {"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" case GroupBy.Assignee:"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" return this.assigneeCardTemplate;"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" case GroupBy.Milestone:"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" return this.milestoneCardTemplate;"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" default:"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" return this.defaultCardTemplate;"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":29}},{"path":"src/app/issues-viewer/issues-viewer.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cdiv\u003e"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv class\u003d\"loading-spinner\" *ngIf\u003d\"(this.viewService.isChangingRepo | async) || this.groups.length \u003d\u003d\u003d 0; else elseBlock\"\u003e"},{"lineNumber":3,"author":{"gitId":"-"},"content":" \u003cmat-progress-spinner color\u003d\"primary\" mode\u003d\"indeterminate\" diameter\u003d\"50\" strokeWidth\u003d\"5\"\u003e \u003c/mat-progress-spinner\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003cng-template #elseBlock\u003e"},{"lineNumber":7,"author":{"gitId":"Arif-Khalid"},"content":" \u003capp-filter-bar [views$]\u003d\"views\"\u003e\u003c/app-filter-bar\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"wrapper\"\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003capp-card-view"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" *ngFor\u003d\"let group of groups\""},{"lineNumber":12,"author":{"gitId":"-"},"content":" class\u003d\"issue-table\""},{"lineNumber":13,"author":{"gitId":"Arif-Khalid"},"content":" #card"},{"lineNumber":14,"author":{"gitId":"Arif-Khalid"},"content":" [ngStyle]\u003d\"{ display: card.isLoading || card.issueLength \u003e 0 ? \u0027initial\u0027 : \u0027none\u0027 }\""},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" [group]\u003d\"group\""},{"lineNumber":16,"author":{"gitId":"-"},"content":" [headers]\u003d\"this.displayedColumns\""},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" (issueLengthChange)\u003d\"updateHiddenGroups($event, group)\""},{"lineNumber":18,"author":{"gitId":"-"},"content":" \u003e\u003c/app-card-view\u003e"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" \u003capp-hidden-groups [groups]\u003d\"this.hiddenGroups\"\u003e\u003c/app-hidden-groups\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003c/ng-template\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"NereusWB922":5,"Arif-Khalid":3,"-":14}},{"path":"src/app/issues-viewer/issues-viewer.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { AfterViewInit, Component, OnDestroy, OnInit, QueryList, ViewChildren } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { NavigationEnd, NavigationStart, Router } from \u0027@angular/router\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { BehaviorSubject, of, Subscription } from \u0027rxjs\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { filter } from \u0027rxjs/operators\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import { Group } from \u0027../core/models/github/group.interface\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { Repo } from \u0027../core/models/repo.model\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { ErrorMessageService } from \u0027../core/services/error-message.service\u0027;"},{"lineNumber":8,"author":{"gitId":"Arif-Khalid"},"content":"import { FiltersService } from \u0027../core/services/filters.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027../core/services/github.service\u0027;"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"import { GroupingContextService } from \u0027../core/services/grouping/grouping-context.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { IssueService } from \u0027../core/services/issue.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { LabelService } from \u0027../core/services/label.service\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { MilestoneService } from \u0027../core/services/milestone.service\u0027;"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"import { ViewService } from \u0027../core/services/view.service\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import { TABLE_COLUMNS } from \u0027../shared/issue-tables/issue-tables-columns\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import { CardViewComponent } from \u0027./card-view/card-view.component\u0027;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":19,"author":{"gitId":"-"},"content":" selector: \u0027app-issues-viewer\u0027,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" templateUrl: \u0027./issues-viewer.component.html\u0027,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./issues-viewer.component.css\u0027]"},{"lineNumber":22,"author":{"gitId":"-"},"content":"})"},{"lineNumber":23,"author":{"gitId":"-"},"content":"export class IssuesViewerComponent implements OnInit, AfterViewInit, OnDestroy {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" readonly displayedColumns \u003d [TABLE_COLUMNS.ID, TABLE_COLUMNS.TITLE, TABLE_COLUMNS.ASSIGNEE, TABLE_COLUMNS.LABEL];"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" /** Observes for any change in repo*/"},{"lineNumber":27,"author":{"gitId":"-"},"content":" repoChangeSubscription: Subscription;"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" groupByChangeSubscription: Subscription;"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" /** Observes for any change in the cardviews */"},{"lineNumber":32,"author":{"gitId":"-"},"content":" viewChange: Subscription;"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" popStateEventSubscription: Subscription;"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" availableGroupsSubscription: Subscription;"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" popStateNavigationId: number;"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" /** Users to show as columns */"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" groups: Group[] \u003d [];"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"nknguyenhc"},"content":" /** The list of users with 0 issues (hidden) */"},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" hiddenGroups: Group[] \u003d [];"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" @ViewChildren(CardViewComponent) cardViews: QueryList\u003cCardViewComponent\u003e;"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" views \u003d new BehaviorSubject\u003cQueryList\u003cCardViewComponent\u003e\u003e(undefined);"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" constructor("},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":" public viewService: ViewService,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" public githubService: GithubService,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" public issueService: IssueService,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" public labelService: LabelService,"},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" public milestoneService: MilestoneService,"},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" public groupingContextService: GroupingContextService,"},{"lineNumber":57,"author":{"gitId":"Arif-Khalid"},"content":" private router: Router,"},{"lineNumber":58,"author":{"gitId":"Arif-Khalid"},"content":" private filtersService: FiltersService"},{"lineNumber":59,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":" this.repoChangeSubscription \u003d this.viewService.repoChanged$.subscribe((newRepo) \u003d\u003e {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" this.issueService.reset(false);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" this.labelService.reset();"},{"lineNumber":63,"author":{"gitId":"-"},"content":" this.initialize();"},{"lineNumber":64,"author":{"gitId":"-"},"content":" });"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" this.groupByChangeSubscription \u003d this.groupingContextService.currGroupBy$.subscribe((newGroupBy) \u003d\u003e {"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":" this.initialize();"},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":" this.popStateEventSubscription \u003d this.router.events"},{"lineNumber":71,"author":{"gitId":"NereusWB922"},"content":" .pipe(filter((event) \u003d\u003e event instanceof NavigationEnd || event instanceof NavigationStart))"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" .subscribe((event) \u003d\u003e {"},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" if (event instanceof NavigationStart \u0026\u0026 event.navigationTrigger \u003d\u003d\u003d \u0027popstate\u0027) {"},{"lineNumber":74,"author":{"gitId":"NereusWB922"},"content":" this.popStateNavigationId \u003d event.id;"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" if (event instanceof NavigationEnd \u0026\u0026 event.id \u003d\u003d\u003d this.popStateNavigationId) {"},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":" this.viewService.initializeRepoFromUrlParams();"},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":" this.groupingContextService.initializeFromUrlParams();"},{"lineNumber":80,"author":{"gitId":"Arif-Khalid"},"content":" this.filtersService.initializeFromURLParams();"},{"lineNumber":81,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":82,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":83,"author":{"gitId":"-"},"content":" }"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" ngOnInit() {"},{"lineNumber":86,"author":{"gitId":"-"},"content":" this.initialize();"},{"lineNumber":87,"author":{"gitId":"NereusWB922"},"content":" this.groupingContextService.initializeFromUrlParams();"},{"lineNumber":88,"author":{"gitId":"Arif-Khalid"},"content":" this.filtersService.initializeFromURLParams();"},{"lineNumber":89,"author":{"gitId":"-"},"content":" }"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" ngAfterViewInit(): void {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" this.viewChange \u003d this.cardViews.changes.subscribe((x) \u003d\u003e this.views.next(x));"},{"lineNumber":93,"author":{"gitId":"-"},"content":" }"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" ngOnDestroy(): void {"},{"lineNumber":96,"author":{"gitId":"-"},"content":" this.repoChangeSubscription.unsubscribe();"},{"lineNumber":97,"author":{"gitId":"-"},"content":" this.viewChange.unsubscribe();"},{"lineNumber":98,"author":{"gitId":"NereusWB922"},"content":" this.popStateEventSubscription.unsubscribe();"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":102,"author":{"gitId":"-"},"content":" * Fetch and initialize all information from repository to populate Issue Dashboard."},{"lineNumber":103,"author":{"gitId":"-"},"content":" */"},{"lineNumber":104,"author":{"gitId":"-"},"content":" private initialize() {"},{"lineNumber":105,"author":{"gitId":"NereusWB922"},"content":" if (this.availableGroupsSubscription) {"},{"lineNumber":106,"author":{"gitId":"NereusWB922"},"content":" this.availableGroupsSubscription.unsubscribe();"},{"lineNumber":107,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" // Fetch assignees"},{"lineNumber":110,"author":{"gitId":"NereusWB922"},"content":" this.groups \u003d [];"},{"lineNumber":111,"author":{"gitId":"NereusWB922"},"content":" this.hiddenGroups \u003d [];"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"NereusWB922"},"content":" this.availableGroupsSubscription \u003d this.groupingContextService.getGroups().subscribe((x) \u003d\u003e (this.groups \u003d x));"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":117,"author":{"gitId":"NereusWB922"},"content":" * Checks if our current repository available on view service is indeed a valid repository"},{"lineNumber":118,"author":{"gitId":"-"},"content":" */"},{"lineNumber":119,"author":{"gitId":"-"},"content":" private checkIfValidRepository() {"},{"lineNumber":120,"author":{"gitId":"NereusWB922"},"content":" const currentRepo \u003d this.viewService.currentRepo;"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" if (Repo.isInvalidRepoName(currentRepo)) {"},{"lineNumber":123,"author":{"gitId":"-"},"content":" return of(false);"},{"lineNumber":124,"author":{"gitId":"-"},"content":" }"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" return this.githubService.isRepositoryPresent(currentRepo.owner, currentRepo.name);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":129,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":130,"author":{"gitId":"NereusWB922"},"content":" * Update the list of hidden group based on the new info."},{"lineNumber":131,"author":{"gitId":"NereusWB922"},"content":" * @param issueLength The number of issues under this group."},{"lineNumber":132,"author":{"gitId":"NereusWB922"},"content":" * @param group The group."},{"lineNumber":133,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":134,"author":{"gitId":"NereusWB922"},"content":" updateHiddenGroups(issueLength: number, target: Group) {"},{"lineNumber":135,"author":{"gitId":"NereusWB922"},"content":" if (issueLength \u003d\u003d\u003d 0 \u0026\u0026 this.groupingContextService.isInHiddenList(target)) {"},{"lineNumber":136,"author":{"gitId":"NereusWB922"},"content":" this.addToHiddenGroups(target);"},{"lineNumber":137,"author":{"gitId":"nknguyenhc"},"content":" } else {"},{"lineNumber":138,"author":{"gitId":"NereusWB922"},"content":" this.removeFromHiddenGroups(target);"},{"lineNumber":139,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":140,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":141,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":142,"author":{"gitId":"NereusWB922"},"content":" private addToHiddenGroups(target: Group) {"},{"lineNumber":143,"author":{"gitId":"NereusWB922"},"content":" const isGroupPresent \u003d this.hiddenGroups.some((group) \u003d\u003e group.equals(target));"},{"lineNumber":144,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":145,"author":{"gitId":"NereusWB922"},"content":" if (!isGroupPresent) {"},{"lineNumber":146,"author":{"gitId":"NereusWB922"},"content":" this.hiddenGroups.push(target);"},{"lineNumber":147,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":148,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":149,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":150,"author":{"gitId":"NereusWB922"},"content":" private removeFromHiddenGroups(target: Group) {"},{"lineNumber":151,"author":{"gitId":"NereusWB922"},"content":" this.hiddenGroups \u003d this.hiddenGroups.filter((group) \u003d\u003e !group.equals(target));"},{"lineNumber":152,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":153,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":12,"NereusWB922":61,"Arif-Khalid":5,"-":75}},{"path":"src/app/issues-viewer/issues-viewer.module.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { NgModule } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { FilterBarModule } from \u0027../shared/filter-bar/filter-bar.module\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { IssuesPrCardModule } from \u0027../shared/issue-pr-card/issue-pr-card.module\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { SharedModule } from \u0027../shared/shared.module\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { CardViewComponent } from \u0027./card-view/card-view.component\u0027;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"import { HiddenGroupsComponent } from \u0027./hidden-groups/hidden-groups.component\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { IssuesViewerRoutingModule } from \u0027./issues-viewer-routing.module\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { IssuesViewerComponent } from \u0027./issues-viewer.component\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"@NgModule({"},{"lineNumber":11,"author":{"gitId":"-"},"content":" imports: [FilterBarModule, IssuesViewerRoutingModule, IssuesPrCardModule, SharedModule],"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" declarations: [IssuesViewerComponent, CardViewComponent, HiddenGroupsComponent],"},{"lineNumber":13,"author":{"gitId":"-"},"content":" exports: [IssuesViewerComponent, CardViewComponent]"},{"lineNumber":14,"author":{"gitId":"-"},"content":"})"},{"lineNumber":15,"author":{"gitId":"-"},"content":"export class IssuesViewerModule {}"}],"authorContributionMap":{"NereusWB922":2,"-":13}},{"path":"src/app/shared/filter-bar/filter-bar.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":".dropdown-filters .mat-form-field {"},{"lineNumber":2,"author":{"gitId":"-"},"content":" margin: 8px;"},{"lineNumber":3,"author":{"gitId":"-"},"content":" font-size: 14px;"},{"lineNumber":4,"author":{"gitId":"-"},"content":" max-width: 20%;"},{"lineNumber":5,"author":{"gitId":"MadLamprey"},"content":" width: 14%; /* depends on number of filters*/"},{"lineNumber":6,"author":{"gitId":"-"},"content":"}"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":".search-bar {"},{"lineNumber":9,"author":{"gitId":"MadLamprey"},"content":" width: 80%;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"}"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":".dropdown-filters {"},{"lineNumber":13,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"}"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":".label-filter-grid-tile {"},{"lineNumber":17,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"}"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":".submit-button {"},{"lineNumber":21,"author":{"gitId":"-"},"content":" margin-left: 8px;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"MadLamprey":2,"-":20}},{"path":"src/app/shared/filter-bar/filter-bar.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cmat-grid-list cols\u003d\"7\" rowHeight\u003d\"80px\"\u003e"},{"lineNumber":2,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-grid-tile colspan\u003d\"2\"\u003e"},{"lineNumber":3,"author":{"gitId":"-"},"content":" \u003cmat-form-field class\u003d\"search-bar\"\u003e"},{"lineNumber":4,"author":{"gitId":"Arif-Khalid"},"content":" \u003cinput"},{"lineNumber":5,"author":{"gitId":"Arif-Khalid"},"content":" matInput"},{"lineNumber":6,"author":{"gitId":"Arif-Khalid"},"content":" value\u003d\"{{ this.filtersService.filter$.value.title }}\""},{"lineNumber":7,"author":{"gitId":"Arif-Khalid"},"content":" (keyup)\u003d\"this.filtersService.updateFilters({ title: $event.target.value })\""},{"lineNumber":8,"author":{"gitId":"Arif-Khalid"},"content":" placeholder\u003d\"Search\""},{"lineNumber":9,"author":{"gitId":"Arif-Khalid"},"content":" /\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003c/mat-grid-tile\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-grid-tile colspan\u003d\"4\"\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"dropdown-filters\"\u003e"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-form-field appearance\u003d\"standard\"\u003e"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-label\u003eGroup by\u003c/mat-label\u003e"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-select"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" [value]\u003d\"this.groupingContextService.currGroupBy$ | async\""},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" (selectionChange)\u003d\"this.groupingContextService.setCurrentGroupingType($event.value)\""},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" \u003e"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-option *ngFor\u003d\"let option of this.groupByEnum | keyvalue\" [value]\u003d\"option.value\"\u003e{{ option.key }}\u003c/mat-option\u003e"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-select\u003e"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":" \u003cmat-form-field appearance\u003d\"standard\"\u003e"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u003cmat-label\u003eStatus\u003c/mat-label\u003e"},{"lineNumber":26,"author":{"gitId":"nknguyenhc"},"content":" \u003cmat-select [value]\u003d\"this.filter.status\" (selectionChange)\u003d\"this.filtersService.updateFilters({ status: $event.value })\" multiple\u003e"},{"lineNumber":27,"author":{"gitId":"nknguyenhc"},"content":" \u003cmat-option *ngIf\u003d\"isFilterPullRequest()\" value\u003d\"open pullrequest\"\u003eOpen Pull Requests\u003c/mat-option\u003e"},{"lineNumber":28,"author":{"gitId":"nknguyenhc"},"content":" \u003cmat-option *ngIf\u003d\"isFilterPullRequest()\" value\u003d\"merged pullrequest\"\u003eMerged Pull Requests\u003c/mat-option\u003e"},{"lineNumber":29,"author":{"gitId":"nknguyenhc"},"content":" \u003cmat-option *ngIf\u003d\"isFilterPullRequest()\" value\u003d\"closed pullrequest\"\u003eClosed Pull Request\u003c/mat-option\u003e"},{"lineNumber":30,"author":{"gitId":"nknguyenhc"},"content":" \u003cmat-option *ngIf\u003d\"isFilterIssue()\" value\u003d\"open issue\"\u003eOpen Issues\u003c/mat-option\u003e"},{"lineNumber":31,"author":{"gitId":"nknguyenhc"},"content":" \u003cmat-option *ngIf\u003d\"isFilterIssue()\" value\u003d\"closed issue\"\u003eClosed Issues\u003c/mat-option\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003c/mat-select\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003cmat-form-field appearance\u003d\"standard\"\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":" \u003cmat-label\u003eType\u003c/mat-label\u003e"},{"lineNumber":36,"author":{"gitId":"Arif-Khalid"},"content":" \u003cmat-select [value]\u003d\"this.filter.type\" (selectionChange)\u003d\"this.filtersService.updateFilters({ type: $event.value })\"\u003e"},{"lineNumber":37,"author":{"gitId":"-"},"content":" \u003cmat-option value\u003d\"all\"\u003eAll\u003c/mat-option\u003e"},{"lineNumber":38,"author":{"gitId":"-"},"content":" \u003cmat-option value\u003d\"issue\"\u003eIssue\u003c/mat-option\u003e"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003cmat-option value\u003d\"pullrequest\"\u003ePull Request\u003c/mat-option\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003c/mat-select\u003e"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":42,"author":{"gitId":"Arif-Khalid"},"content":" \u003cmat-form-field"},{"lineNumber":43,"author":{"gitId":"Arif-Khalid"},"content":" appearance\u003d\"standard\""},{"lineNumber":44,"author":{"gitId":"Arif-Khalid"},"content":" matSort"},{"lineNumber":45,"author":{"gitId":"Arif-Khalid"},"content":" [matSortDisableClear]\u003d\"true\""},{"lineNumber":46,"author":{"gitId":"Arif-Khalid"},"content":" (matSortChange)\u003d\"this.filtersService.updateFilters({ sort: $event })\""},{"lineNumber":47,"author":{"gitId":"Arif-Khalid"},"content":" \u003e"},{"lineNumber":48,"author":{"gitId":"-"},"content":" \u003cmat-label\u003eSort\u003c/mat-label\u003e"},{"lineNumber":49,"author":{"gitId":"Arif-Khalid"},"content":" \u003cmat-select [value]\u003d\"this.filter.sort.active\"\u003e"},{"lineNumber":50,"author":{"gitId":"-"},"content":" \u003cmat-option value\u003d\"id\"\u003e"},{"lineNumber":51,"author":{"gitId":"-"},"content":" \u003cspan mat-sort-header\u003d\"id\"\u003eID\u003c/span\u003e"},{"lineNumber":52,"author":{"gitId":"-"},"content":" \u003c/mat-option\u003e"},{"lineNumber":53,"author":{"gitId":"-"},"content":" \u003cmat-option value\u003d\"title\"\u003e"},{"lineNumber":54,"author":{"gitId":"-"},"content":" \u003cspan mat-sort-header\u003d\"title\"\u003eTitle\u003c/span\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":" \u003c/mat-option\u003e"},{"lineNumber":56,"author":{"gitId":"-"},"content":" \u003cmat-option value\u003d\"date\"\u003e"},{"lineNumber":57,"author":{"gitId":"-"},"content":" \u003cspan mat-sort-header\u003d\"date\"\u003eDate Updated\u003c/span\u003e"},{"lineNumber":58,"author":{"gitId":"-"},"content":" \u003c/mat-option\u003e"},{"lineNumber":59,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-option value\u003d\"status\"\u003e"},{"lineNumber":60,"author":{"gitId":"MadLamprey"},"content":" \u003cspan mat-sort-header\u003d\"status\"\u003eStatus\u003c/span\u003e"},{"lineNumber":61,"author":{"gitId":"MadLamprey"},"content":" \u003c/mat-option\u003e"},{"lineNumber":62,"author":{"gitId":"-"},"content":" \u003c/mat-select\u003e"},{"lineNumber":63,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":64,"author":{"gitId":"-"},"content":" \u003cmat-form-field appearance\u003d\"standard\"\u003e"},{"lineNumber":65,"author":{"gitId":"-"},"content":" \u003cmat-label\u003eMilestone\u003c/mat-label\u003e"},{"lineNumber":66,"author":{"gitId":"-"},"content":" \u003cmat-select"},{"lineNumber":67,"author":{"gitId":"-"},"content":" #milestoneSelectorRef"},{"lineNumber":68,"author":{"gitId":"Arif-Khalid"},"content":" [value]\u003d\"this.filter.milestones\""},{"lineNumber":69,"author":{"gitId":"Arif-Khalid"},"content":" (selectionChange)\u003d\"this.filtersService.updateFilters({ milestones: $event.value })\""},{"lineNumber":70,"author":{"gitId":"-"},"content":" [disabled]\u003d\"this.milestoneService.hasNoMilestones\""},{"lineNumber":71,"author":{"gitId":"-"},"content":" multiple"},{"lineNumber":72,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":73,"author":{"gitId":"-"},"content":" \u003cmat-select-trigger *ngIf\u003d\"this.milestoneService.hasNoMilestones\"\u003e"},{"lineNumber":74,"author":{"gitId":"-"},"content":" \u003cspan\u003eNo Milestones\u003c/span\u003e"},{"lineNumber":75,"author":{"gitId":"-"},"content":" \u003c/mat-select-trigger\u003e"},{"lineNumber":76,"author":{"gitId":"Arif-Khalid"},"content":" \u003cmat-option *ngFor\u003d\"let milestone of this.milestoneService.milestones\" [value]\u003d\"milestone.title\"\u003e"},{"lineNumber":77,"author":{"gitId":"-"},"content":" {{ milestone.title }}"},{"lineNumber":78,"author":{"gitId":"-"},"content":" \u003c/mat-option\u003e"},{"lineNumber":79,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-option *ngIf\u003d\"isFilterIssue()\" [value]\u003d\"\u0027Issue without a milestone\u0027\"\u003eIssues without a milestone\u003c/mat-option\u003e"},{"lineNumber":80,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-option *ngIf\u003d\"isFilterPullRequest()\" [value]\u003d\"\u0027PR without a milestone\u0027\"\u003ePRs without a milestone\u003c/mat-option\u003e"},{"lineNumber":81,"author":{"gitId":"-"},"content":" \u003c/mat-select\u003e"},{"lineNumber":82,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":83,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-form-field appearance\u003d\"standard\"\u003e"},{"lineNumber":84,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-label\u003eItems per page\u003c/mat-label\u003e"},{"lineNumber":85,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-select"},{"lineNumber":86,"author":{"gitId":"MadLamprey"},"content":" [value]\u003d\"this.filter.itemsPerPage\""},{"lineNumber":87,"author":{"gitId":"MadLamprey"},"content":" (selectionChange)\u003d\"this.filtersService.updateFilters({ itemsPerPage: $event.value })\""},{"lineNumber":88,"author":{"gitId":"MadLamprey"},"content":" \u003e"},{"lineNumber":89,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-option [value]\u003d\"10\"\u003e10\u003c/mat-option\u003e"},{"lineNumber":90,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-option [value]\u003d\"20\"\u003e20\u003c/mat-option\u003e"},{"lineNumber":91,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-option [value]\u003d\"50\"\u003e50\u003c/mat-option\u003e"},{"lineNumber":92,"author":{"gitId":"-"},"content":" \u003c/mat-select\u003e"},{"lineNumber":93,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":94,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":95,"author":{"gitId":"-"},"content":" \u003c/mat-grid-tile\u003e"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" \u003cmat-grid-tile class\u003d\"label-filter-grid-tile\" colspan\u003d\"1\"\u003e"},{"lineNumber":98,"author":{"gitId":"Arif-Khalid"},"content":" \u003capp-label-filter-bar\u003e\u003c/app-label-filter-bar\u003e"},{"lineNumber":99,"author":{"gitId":"-"},"content":" \u003c/mat-grid-tile\u003e"},{"lineNumber":100,"author":{"gitId":"-"},"content":"\u003c/mat-grid-list\u003e"}],"authorContributionMap":{"nknguyenhc":6,"Arif-Khalid":18,"NereusWB922":9,"MadLamprey":16,"-":51}},{"path":"src/app/shared/filter-bar/filter-bar.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { AfterViewInit, Component, Input, OnDestroy, OnInit, QueryList, ViewChild } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { MatSelect } from \u0027@angular/material/select\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { BehaviorSubject, Subscription } from \u0027rxjs\u0027;"},{"lineNumber":4,"author":{"gitId":"nknguyenhc"},"content":"import { Filter, FiltersService } from \u0027../../core/services/filters.service\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import { GroupBy, GroupingContextService } from \u0027../../core/services/grouping/grouping-context.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027../../core/services/logging.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { MilestoneService } from \u0027../../core/services/milestone.service\u0027;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"import { ViewService } from \u0027../../core/services/view.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { FilterableComponent } from \u0027../issue-tables/filterableTypes\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { LabelFilterBarComponent } from \u0027./label-filter-bar/label-filter-bar.component\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * This component is abstracted out filterbar used by both detailed-viewer page"},{"lineNumber":14,"author":{"gitId":"-"},"content":" * and Issues-viewer"},{"lineNumber":15,"author":{"gitId":"-"},"content":" */"},{"lineNumber":16,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":17,"author":{"gitId":"-"},"content":" selector: \u0027app-filter-bar\u0027,"},{"lineNumber":18,"author":{"gitId":"-"},"content":" templateUrl: \u0027./filter-bar.component.html\u0027,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./filter-bar.component.css\u0027]"},{"lineNumber":20,"author":{"gitId":"-"},"content":"})"},{"lineNumber":21,"author":{"gitId":"Arif-Khalid"},"content":"export class FilterBarComponent implements OnInit, OnDestroy {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Input() views$: BehaviorSubject\u003cQueryList\u003cFilterableComponent\u003e\u003e;"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" repoChangeSubscription: Subscription;"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" /** Selected dropdown filter value */"},{"lineNumber":27,"author":{"gitId":"nknguyenhc"},"content":" filter: Filter \u003d this.filtersService.defaultFilter();"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" groupByEnum: typeof GroupBy \u003d GroupBy;"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" /** Milestone subscription */"},{"lineNumber":32,"author":{"gitId":"-"},"content":" milestoneSubscription: Subscription;"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" @ViewChild(LabelFilterBarComponent, { static: true }) labelFilterBar: LabelFilterBarComponent;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" @ViewChild(\u0027milestoneSelectorRef\u0027, { static: false }) milestoneSelectorRef: MatSelect;"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"Arif-Khalid"},"content":" constructor("},{"lineNumber":39,"author":{"gitId":"Arif-Khalid"},"content":" public milestoneService: MilestoneService,"},{"lineNumber":40,"author":{"gitId":"Arif-Khalid"},"content":" public filtersService: FiltersService,"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" private viewService: ViewService,"},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":" public groupingContextService: GroupingContextService,"},{"lineNumber":43,"author":{"gitId":"Arif-Khalid"},"content":" private logger: LoggingService"},{"lineNumber":44,"author":{"gitId":"Arif-Khalid"},"content":" ) {"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" this.repoChangeSubscription \u003d this.viewService.repoChanged$.subscribe((newRepo) \u003d\u003e this.newRepoInitialize());"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" ngOnInit() {"},{"lineNumber":49,"author":{"gitId":"Arif-Khalid"},"content":" this.newRepoInitialize();"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"Arif-Khalid"},"content":" // One-time initializations"},{"lineNumber":52,"author":{"gitId":"Arif-Khalid"},"content":" this.filtersService.filter$.subscribe((filter) \u003d\u003e {"},{"lineNumber":53,"author":{"gitId":"Arif-Khalid"},"content":" this.filter \u003d filter;"},{"lineNumber":54,"author":{"gitId":"Arif-Khalid"},"content":" this.applyFilter();"},{"lineNumber":55,"author":{"gitId":"-"},"content":" });"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"Arif-Khalid"},"content":" this.views$.subscribe(() \u003d\u003e this.applyFilter());"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" ngOnDestroy(): void {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" this.milestoneSubscription.unsubscribe();"},{"lineNumber":62,"author":{"gitId":"-"},"content":" this.repoChangeSubscription.unsubscribe();"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":66,"author":{"gitId":"-"},"content":" * Signals to IssuesDataTable that a change has occurred in filter."},{"lineNumber":67,"author":{"gitId":"-"},"content":" */"},{"lineNumber":68,"author":{"gitId":"Arif-Khalid"},"content":" applyFilter() {"},{"lineNumber":69,"author":{"gitId":"Arif-Khalid"},"content":" this.views$?.value?.forEach((v) \u003d\u003e (v.retrieveFilterable().filter \u003d this.filter));"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":73,"author":{"gitId":"-"},"content":" * Checks if program is filtering by type issue."},{"lineNumber":74,"author":{"gitId":"-"},"content":" */"},{"lineNumber":75,"author":{"gitId":"nknguyenhc"},"content":" isFilterIssue() {"},{"lineNumber":76,"author":{"gitId":"nknguyenhc"},"content":" return this.filter.type \u003d\u003d\u003d \u0027issue\u0027 || this.filter.type \u003d\u003d\u003d \u0027all\u0027;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"nknguyenhc"},"content":" isFilterPullRequest() {"},{"lineNumber":80,"author":{"gitId":"nknguyenhc"},"content":" return this.filter.type \u003d\u003d\u003d \u0027pullrequest\u0027 || this.filter.type \u003d\u003d\u003d \u0027all\u0027;"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":84,"author":{"gitId":"-"},"content":" * Fetch and initialize all information from repository to populate Issue Dashboard."},{"lineNumber":85,"author":{"gitId":"Arif-Khalid"},"content":" * Re-called when repo has changed"},{"lineNumber":86,"author":{"gitId":"-"},"content":" */"},{"lineNumber":87,"author":{"gitId":"Arif-Khalid"},"content":" private newRepoInitialize() {"},{"lineNumber":88,"author":{"gitId":"-"},"content":" // Fetch milestones and update dropdown filter"},{"lineNumber":89,"author":{"gitId":"-"},"content":" this.milestoneSubscription \u003d this.milestoneService.fetchMilestones().subscribe("},{"lineNumber":90,"author":{"gitId":"-"},"content":" (response) \u003d\u003e {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" this.logger.debug(\u0027IssuesViewerComponent: Fetched milestones from Github\u0027);"},{"lineNumber":92,"author":{"gitId":"Arif-Khalid"},"content":" this.filtersService.sanitizeMilestones(this.milestoneService.milestones);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" },"},{"lineNumber":94,"author":{"gitId":"-"},"content":" (err) \u003d\u003e {},"},{"lineNumber":95,"author":{"gitId":"-"},"content":" () \u003d\u003e {}"},{"lineNumber":96,"author":{"gitId":"-"},"content":" );"},{"lineNumber":97,"author":{"gitId":"-"},"content":" }"},{"lineNumber":98,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":6,"NereusWB922":6,"Arif-Khalid":17,"-":69}},{"path":"src/app/shared/filter-bar/label-filter-bar/label-filter-bar.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"::ng-deep.mat-menu-content:not(:empty) {"},{"lineNumber":2,"author":{"gitId":"-"},"content":" /* Override mat-menu-content\u0027s non-empty default CSS. */"},{"lineNumber":3,"author":{"gitId":"-"},"content":" padding-top: 0px !important;"},{"lineNumber":4,"author":{"gitId":"-"},"content":" padding-bottom: 0px !important;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"}"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"::ng-deep.mat-menu-panel {"},{"lineNumber":8,"author":{"gitId":"-"},"content":" /* Override mat-menu-panel\u0027s default CSS. */"},{"lineNumber":9,"author":{"gitId":"-"},"content":" width: 280px;"},{"lineNumber":10,"author":{"gitId":"-"},"content":" max-width: none !important;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"}"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":".popup-container {"},{"lineNumber":14,"author":{"gitId":"-"},"content":" flex-direction: column;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"}"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":".popupmenu {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" width: max-content;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"}"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":".scroll-container {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" max-height: 400px;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" overflow-y: auto;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" position: relative;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" -ms-overflow-style: none; /* IE and Edge */"},{"lineNumber":27,"author":{"gitId":"-"},"content":" scrollbar-width: none; /* Firefox */"},{"lineNumber":28,"author":{"gitId":"-"},"content":"}"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":"/* Ref: https://css-scroll-shadows.vercel.app */"},{"lineNumber":31,"author":{"gitId":"-"},"content":".scroll-container::before {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" pointer-events: none;"},{"lineNumber":33,"author":{"gitId":"-"},"content":" content: \u0027\u0027;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" position: absolute;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" z-index: 2;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" height: 7px;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" display: block;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" background-image: linear-gradient(to bottom, white 66%, transparent);"},{"lineNumber":40,"author":{"gitId":"-"},"content":"}"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":".scroll-container::after {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" pointer-events: none;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" content: \u0027\u0027;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" position: sticky;"},{"lineNumber":46,"author":{"gitId":"-"},"content":" z-index: 2;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" top: 100%;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" height: 7px;"},{"lineNumber":49,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":50,"author":{"gitId":"-"},"content":" display: block;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" background-image: linear-gradient(to top, white 66%, transparent);"},{"lineNumber":52,"author":{"gitId":"-"},"content":"}"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":".scroll-container-wrapper {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" position: relative;"},{"lineNumber":56,"author":{"gitId":"-"},"content":"}"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":".scroll-container-wrapper::before {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" pointer-events: none;"},{"lineNumber":60,"author":{"gitId":"-"},"content":" content: \u0027\u0027;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" position: absolute;"},{"lineNumber":62,"author":{"gitId":"-"},"content":" z-index: 1;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" top: 0;"},{"lineNumber":64,"author":{"gitId":"-"},"content":" left: 0;"},{"lineNumber":65,"author":{"gitId":"-"},"content":" right: 0;"},{"lineNumber":66,"author":{"gitId":"-"},"content":" height: 5px;"},{"lineNumber":67,"author":{"gitId":"-"},"content":" background-image: radial-gradient(farthest-side at 50% 0, rgba(0, 0, 0, 0.7), transparent);"},{"lineNumber":68,"author":{"gitId":"-"},"content":"}"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":".scroll-container-wrapper::after {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" pointer-events: none;"},{"lineNumber":72,"author":{"gitId":"-"},"content":" content: \u0027\u0027;"},{"lineNumber":73,"author":{"gitId":"-"},"content":" position: absolute;"},{"lineNumber":74,"author":{"gitId":"-"},"content":" z-index: 1;"},{"lineNumber":75,"author":{"gitId":"-"},"content":" bottom: 0;"},{"lineNumber":76,"author":{"gitId":"-"},"content":" left: 0;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" right: 0;"},{"lineNumber":78,"author":{"gitId":"-"},"content":" height: 5px;"},{"lineNumber":79,"author":{"gitId":"-"},"content":" background-image: radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, 0.7), transparent);"},{"lineNumber":80,"author":{"gitId":"-"},"content":"}"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":".scroll-container::-webkit-scrollbar {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" display: none; /* Hide scrollbar for Chrome, Safari and Opera */"},{"lineNumber":84,"author":{"gitId":"-"},"content":"}"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":".flexbox-container {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" display: flex;"},{"lineNumber":88,"author":{"gitId":"-"},"content":" flex-direction: row;"},{"lineNumber":89,"author":{"gitId":"-"},"content":" justify-content: flex-start;"},{"lineNumber":90,"author":{"gitId":"-"},"content":" align-items: center;"},{"lineNumber":91,"author":{"gitId":"nknguyenhc"},"content":" border-radius: 10px;"},{"lineNumber":92,"author":{"gitId":"nknguyenhc"},"content":" height: 40px;"},{"lineNumber":93,"author":{"gitId":"nknguyenhc"},"content":" padding: 0px 12px;"},{"lineNumber":94,"author":{"gitId":"nknguyenhc"},"content":" margin: 8px 4px;"},{"lineNumber":95,"author":{"gitId":"nknguyenhc"},"content":" box-sizing: border-box;"},{"lineNumber":96,"author":{"gitId":"nknguyenhc"},"content":" position: relative;"},{"lineNumber":97,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":98,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":99,"author":{"gitId":"nknguyenhc"},"content":".flexbox-container:hover {"},{"lineNumber":100,"author":{"gitId":"nknguyenhc"},"content":" background-color: rgba(0, 0, 0, 0.04);"},{"lineNumber":101,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":102,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":103,"author":{"gitId":"nknguyenhc"},"content":".flexbox-container-strikethrough {"},{"lineNumber":104,"author":{"gitId":"nknguyenhc"},"content":" position: absolute;"},{"lineNumber":105,"author":{"gitId":"nknguyenhc"},"content":" top: 50%;"},{"lineNumber":106,"author":{"gitId":"nknguyenhc"},"content":" width: 90%;"},{"lineNumber":107,"author":{"gitId":"nknguyenhc"},"content":" left: 50%;"},{"lineNumber":108,"author":{"gitId":"nknguyenhc"},"content":" transform: translate(-50%, -50%);"},{"lineNumber":109,"author":{"gitId":"nknguyenhc"},"content":" height: 2px;"},{"lineNumber":110,"author":{"gitId":"nknguyenhc"},"content":" background-color: black;"},{"lineNumber":111,"author":{"gitId":"-"},"content":"}"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":".input-field {"},{"lineNumber":114,"author":{"gitId":"-"},"content":" width: calc(100% - (2 * 15px)); /* To account for left and right padding. */"},{"lineNumber":115,"author":{"gitId":"-"},"content":" padding: 0 15px;"},{"lineNumber":116,"author":{"gitId":"-"},"content":"}"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":".mat-chip {"},{"lineNumber":119,"author":{"gitId":"-"},"content":" height: auto;"},{"lineNumber":120,"author":{"gitId":"-"},"content":" padding: 5.5px 7px;"},{"lineNumber":121,"author":{"gitId":"-"},"content":" line-height: 1.1em;"},{"lineNumber":122,"author":{"gitId":"-"},"content":" position: inherit;"},{"lineNumber":123,"author":{"gitId":"-"},"content":" border-radius: 6px;"},{"lineNumber":124,"author":{"gitId":"-"},"content":" font-size: 12px;"},{"lineNumber":125,"author":{"gitId":"-"},"content":" min-height: 16px;"},{"lineNumber":126,"author":{"gitId":"-"},"content":" max-height: 42px;"},{"lineNumber":127,"author":{"gitId":"-"},"content":" margin: 0px;"},{"lineNumber":128,"author":{"gitId":"-"},"content":"}"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":".mat-stroked-button {"},{"lineNumber":131,"author":{"gitId":"-"},"content":" font-weight: normal;"},{"lineNumber":132,"author":{"gitId":"-"},"content":"}"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":".hidden {"},{"lineNumber":135,"author":{"gitId":"-"},"content":" display: none !important;"},{"lineNumber":136,"author":{"gitId":"-"},"content":"}"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":"mat-list-option {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" width: max-content;"},{"lineNumber":140,"author":{"gitId":"-"},"content":"}"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":".no-labels {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" /* Chosen to look similar to button above. */"},{"lineNumber":144,"author":{"gitId":"-"},"content":" padding: 0 16px;"},{"lineNumber":145,"author":{"gitId":"-"},"content":" font-size: 14px;"},{"lineNumber":146,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":20,"-":126}},{"path":"src/app/shared/filter-bar/label-filter-bar/label-filter-bar.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cbutton mat-stroked-button *ngIf\u003d\"loaded\" [matMenuTriggerFor]\u003d\"menu\"\u003e"},{"lineNumber":2,"author":{"gitId":"nknguyenhc"},"content":" {{ selectedLabelNames.size \u003d\u003d\u003d 0 ? \u0027All\u0027 : selectedLabelNames.size }} Selected | {{ hiddenLabelNames?.size || 0 }} Hidden ▾"},{"lineNumber":3,"author":{"gitId":"-"},"content":"\u003c/button\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"\u003cbutton mat-stroked-button disabled *ngIf\u003d\"!loaded\" color\u003d\"accent\"\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003cmat-progress-bar mode\u003d\"query\"\u003e\u003c/mat-progress-bar\u003e"},{"lineNumber":7,"author":{"gitId":"-"},"content":"\u003c/button\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"\u003cmat-menu #menu\u003d\"matMenu\" class\u003d\"popupmenu\"\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003cdiv (click)\u003d\"$event.stopPropagation()\" class\u003d\"popup-container\"\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003cmat-form-field appearance\u003d\"standard\" class\u003d\"input-field\"\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003cmat-label\u003eLabels\u003c/mat-label\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003cinput #input matInput placeholder\u003d\"Find labels\" /\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":" \u003cbutton mat-button (click)\u003d\"removeAllSelection()\"\u003eRemove all\u003c/button\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"!hasLabels(input.value)\" class\u003d\"no-labels\"\u003eNo Labels Found!\u003c/div\u003e"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"scroll-container-wrapper\"\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"scroll-container\"\u003e"},{"lineNumber":22,"author":{"gitId":"nknguyenhc"},"content":" \u003cdiv"},{"lineNumber":23,"author":{"gitId":"nknguyenhc"},"content":" *ngFor\u003d\"let label of this.allLabels\""},{"lineNumber":24,"author":{"gitId":"nknguyenhc"},"content":" class\u003d\"flexbox-container\""},{"lineNumber":25,"author":{"gitId":"nknguyenhc"},"content":" (click)\u003d\"changeLabelState(label)\""},{"lineNumber":26,"author":{"gitId":"-"},"content":" [class.hidden]\u003d\"filter(input.value, label.name)\""},{"lineNumber":27,"author":{"gitId":"nknguyenhc"},"content":" [style]\u003d\"{ border: \u00272px solid \u0027 + getColor(label) }\""},{"lineNumber":28,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":29,"author":{"gitId":"nknguyenhc"},"content":" \u003cbutton mat-icon-button *ngIf\u003d\"!hiddenLabelNames.has(label.name)\" (click)\u003d\"hide(label.name); $event.stopPropagation()\"\u003e"},{"lineNumber":30,"author":{"gitId":"-"},"content":" \u003cmat-icon\u003evisibility\u003c/mat-icon\u003e"},{"lineNumber":31,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":32,"author":{"gitId":"nknguyenhc"},"content":" \u003cbutton mat-icon-button *ngIf\u003d\"hiddenLabelNames.has(label.name)\" (click)\u003d\"show(label.name); $event.stopPropagation()\"\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003cmat-icon\u003evisibility_off\u003c/mat-icon\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":" \u003cmat-chip"},{"lineNumber":36,"author":{"gitId":"-"},"content":" [ngStyle]\u003d\"labelService.setLabelStyle(label.color)\""},{"lineNumber":37,"author":{"gitId":"nknguyenhc"},"content":" [disabled]\u003d\"hiddenLabelNames.has(label.name)\""},{"lineNumber":38,"author":{"gitId":"nknguyenhc"},"content":" (click)\u003d\"changeLabelState(label)\""},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":40,"author":{"gitId":"nknguyenhc"},"content":" {{ label.name }}"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003c/mat-chip\u003e"},{"lineNumber":42,"author":{"gitId":"nknguyenhc"},"content":" \u003cdiv *ngIf\u003d\"deselectedLabelNames.has(label.name)\" class\u003d\"flexbox-container-strikethrough\"\u003e\u003c/div\u003e"},{"lineNumber":43,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":45,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":46,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":47,"author":{"gitId":"-"},"content":"\u003c/mat-menu\u003e"}],"authorContributionMap":{"nknguyenhc":12,"-":35}},{"path":"src/app/shared/filter-bar/label-filter-bar/label-filter-bar.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"Arif-Khalid"},"content":"import { AfterViewInit, Component, OnDestroy, OnInit, ViewChild } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"Arif-Khalid"},"content":"import { Observable, Subscription } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { SimpleLabel } from \u0027../../../core/models/label.model\u0027;"},{"lineNumber":4,"author":{"gitId":"Arif-Khalid"},"content":"import { FiltersService } from \u0027../../../core/services/filters.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { LabelService } from \u0027../../../core/services/label.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027../../../core/services/logging.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":9,"author":{"gitId":"-"},"content":" selector: \u0027app-label-filter-bar\u0027,"},{"lineNumber":10,"author":{"gitId":"-"},"content":" templateUrl: \u0027./label-filter-bar.component.html\u0027,"},{"lineNumber":11,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./label-filter-bar.component.css\u0027]"},{"lineNumber":12,"author":{"gitId":"-"},"content":"})"},{"lineNumber":13,"author":{"gitId":"-"},"content":"export class LabelFilterBarComponent implements OnInit, AfterViewInit, OnDestroy {"},{"lineNumber":14,"author":{"gitId":"nknguyenhc"},"content":" private static readonly DEFAULT_LABEL_COLOR: string \u003d \u0027transparent\u0027;"},{"lineNumber":15,"author":{"gitId":"nknguyenhc"},"content":" private static readonly DESELECTED_LABEL_COLOR: string \u003d \u0027#b00020\u0027;"},{"lineNumber":16,"author":{"gitId":"nknguyenhc"},"content":" private static readonly SELECTED_LABEL_COLOR: string \u003d \u0027#41c300\u0027;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":" labels$: Observable\u003cSimpleLabel[]\u003e;"},{"lineNumber":19,"author":{"gitId":"-"},"content":" allLabels: SimpleLabel[];"},{"lineNumber":20,"author":{"gitId":"nknguyenhc"},"content":" selectedLabelNames: Set\u003cstring\u003e \u003d new Set\u003cstring\u003e();"},{"lineNumber":21,"author":{"gitId":"nknguyenhc"},"content":" deselectedLabelNames: Set\u003cstring\u003e \u003d new Set\u003cstring\u003e();"},{"lineNumber":22,"author":{"gitId":"-"},"content":" hiddenLabelNames: Set\u003cstring\u003e \u003d new Set();"},{"lineNumber":23,"author":{"gitId":"-"},"content":" loaded \u003d false;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" labelSubscription: Subscription;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"Arif-Khalid"},"content":" constructor(private labelService: LabelService, private logger: LoggingService, private filtersService: FiltersService) {}"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" ngOnInit() {"},{"lineNumber":30,"author":{"gitId":"-"},"content":" this.loaded \u003d false;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" }"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" ngAfterViewInit(): void {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" setTimeout(() \u003d\u003e {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" this.load();"},{"lineNumber":36,"author":{"gitId":"-"},"content":" this.labels$ \u003d this.labelService.connect();"},{"lineNumber":37,"author":{"gitId":"-"},"content":" this.labels$.subscribe((labels) \u003d\u003e {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" this.allLabels \u003d labels;"},{"lineNumber":39,"author":{"gitId":"Arif-Khalid"},"content":" this.filtersService.sanitizeLabels(this.allLabels);"},{"lineNumber":40,"author":{"gitId":"nknguyenhc"},"content":" this.selectedLabelNames \u003d new Set\u003cstring\u003e(this.filtersService.filter$.value.labels);"},{"lineNumber":41,"author":{"gitId":"nknguyenhc"},"content":" this.deselectedLabelNames \u003d this.filtersService.filter$.value.deselectedLabels;"},{"lineNumber":42,"author":{"gitId":"Arif-Khalid"},"content":" this.hiddenLabelNames \u003d this.filtersService.filter$.value.hiddenLabels;"},{"lineNumber":43,"author":{"gitId":"nknguyenhc"},"content":" this.loaded \u003d true;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" });"},{"lineNumber":45,"author":{"gitId":"-"},"content":" });"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" ngOnDestroy(): void {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" this.labelSubscription?.unsubscribe();"},{"lineNumber":50,"author":{"gitId":"-"},"content":" }"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" hide(label: string): void {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" if (this.hiddenLabelNames.has(label)) {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" this.hiddenLabelNames.add(label);"},{"lineNumber":58,"author":{"gitId":"Arif-Khalid"},"content":" this.filtersService.updateFilters({ hiddenLabels: this.hiddenLabelNames });"},{"lineNumber":59,"author":{"gitId":"-"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" /** Show labels that were hidden */"},{"lineNumber":62,"author":{"gitId":"-"},"content":" show(label: string): void {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" if (!this.hiddenLabelNames.has(label)) {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":" this.hiddenLabelNames.delete(label);"},{"lineNumber":67,"author":{"gitId":"Arif-Khalid"},"content":" this.filtersService.updateFilters({ hiddenLabels: this.hiddenLabelNames });"},{"lineNumber":68,"author":{"gitId":"-"},"content":" }"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":71,"author":{"gitId":"nknguyenhc"},"content":" * Change label to the next state."},{"lineNumber":72,"author":{"gitId":"nknguyenhc"},"content":" * Label has the following state rotation: default -\u003e selected -\u003e deselected."},{"lineNumber":73,"author":{"gitId":"nknguyenhc"},"content":" * @param label The label to change state"},{"lineNumber":74,"author":{"gitId":"-"},"content":" */"},{"lineNumber":75,"author":{"gitId":"nknguyenhc"},"content":" changeLabelState(label: SimpleLabel) {"},{"lineNumber":76,"author":{"gitId":"nknguyenhc"},"content":" if (this.selectedLabelNames.has(label.name)) {"},{"lineNumber":77,"author":{"gitId":"nknguyenhc"},"content":" this.selectedLabelNames.delete(label.name);"},{"lineNumber":78,"author":{"gitId":"nknguyenhc"},"content":" this.deselectedLabelNames.add(label.name);"},{"lineNumber":79,"author":{"gitId":"nknguyenhc"},"content":" } else if (this.deselectedLabelNames.has(label.name)) {"},{"lineNumber":80,"author":{"gitId":"nknguyenhc"},"content":" this.deselectedLabelNames.delete(label.name);"},{"lineNumber":81,"author":{"gitId":"nknguyenhc"},"content":" } else {"},{"lineNumber":82,"author":{"gitId":"nknguyenhc"},"content":" this.selectedLabelNames.add(label.name);"},{"lineNumber":83,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":84,"author":{"gitId":"nknguyenhc"},"content":" this.updateSelection();"},{"lineNumber":85,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":86,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":87,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":88,"author":{"gitId":"nknguyenhc"},"content":" * Returns the border color of the label."},{"lineNumber":89,"author":{"gitId":"nknguyenhc"},"content":" * The border color represents the state of the label."},{"lineNumber":90,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":91,"author":{"gitId":"nknguyenhc"},"content":" getColor(label: SimpleLabel): string {"},{"lineNumber":92,"author":{"gitId":"nknguyenhc"},"content":" if (this.selectedLabelNames.has(label.name)) {"},{"lineNumber":93,"author":{"gitId":"nknguyenhc"},"content":" return LabelFilterBarComponent.SELECTED_LABEL_COLOR;"},{"lineNumber":94,"author":{"gitId":"nknguyenhc"},"content":" } else if (this.deselectedLabelNames.has(label.name)) {"},{"lineNumber":95,"author":{"gitId":"nknguyenhc"},"content":" return LabelFilterBarComponent.DESELECTED_LABEL_COLOR;"},{"lineNumber":96,"author":{"gitId":"nknguyenhc"},"content":" } else {"},{"lineNumber":97,"author":{"gitId":"nknguyenhc"},"content":" return LabelFilterBarComponent.DEFAULT_LABEL_COLOR;"},{"lineNumber":98,"author":{"gitId":"-"},"content":" }"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" /** loads in the labels in the repository */"},{"lineNumber":102,"author":{"gitId":"-"},"content":" public load() {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" this.labelService.startPollLabels();"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" filter(filter: string, target: string): boolean {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" return !target.toLowerCase().includes(filter.toLowerCase());"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" hasLabels(filter: string): boolean {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" if (this.allLabels \u003d\u003d\u003d undefined || this.allLabels.length \u003d\u003d\u003d 0) {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":113,"author":{"gitId":"-"},"content":" }"},{"lineNumber":114,"author":{"gitId":"nknguyenhc"},"content":" return this.allLabels.some((label) \u003d\u003e !this.filter(filter, label.name));"},{"lineNumber":115,"author":{"gitId":"-"},"content":" }"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" updateSelection(): void {"},{"lineNumber":118,"author":{"gitId":"nknguyenhc"},"content":" this.filtersService.updateFilters({"},{"lineNumber":119,"author":{"gitId":"nknguyenhc"},"content":" labels: Array.from(this.selectedLabelNames),"},{"lineNumber":120,"author":{"gitId":"nknguyenhc"},"content":" deselectedLabels: this.deselectedLabelNames"},{"lineNumber":121,"author":{"gitId":"Arif-Khalid"},"content":" });"},{"lineNumber":122,"author":{"gitId":"-"},"content":" }"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" removeAllSelection(): void {"},{"lineNumber":125,"author":{"gitId":"nknguyenhc"},"content":" this.selectedLabelNames \u003d new Set\u003cstring\u003e();"},{"lineNumber":126,"author":{"gitId":"nknguyenhc"},"content":" this.deselectedLabelNames \u003d new Set\u003cstring\u003e();"},{"lineNumber":127,"author":{"gitId":"-"},"content":" this.updateSelection();"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":40,"Arif-Khalid":9,"-":80}},{"path":"src/app/shared/issue-pr-card/issue-pr-card-labels/issue-pr-card-labels.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component, Input } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"nknguyenhc"},"content":"import { GithubLabel } from \u0027../../../core/models/github/github-label.model\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { LabelService } from \u0027../../../core/services/label.service\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":6,"author":{"gitId":"-"},"content":" selector: \u0027app-issue-pr-card-labels\u0027,"},{"lineNumber":7,"author":{"gitId":"-"},"content":" templateUrl: \u0027./issue-pr-card-labels.component.html\u0027,"},{"lineNumber":8,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./issue-pr-card-labels.component.css\u0027]"},{"lineNumber":9,"author":{"gitId":"-"},"content":"})"},{"lineNumber":10,"author":{"gitId":"-"},"content":"export class IssuePrCardLabelsComponent {"},{"lineNumber":11,"author":{"gitId":"nknguyenhc"},"content":" @Input() labels: GithubLabel[];"},{"lineNumber":12,"author":{"gitId":"nknguyenhc"},"content":" @Input() labelSet: Set\u003cstring\u003e;"},{"lineNumber":13,"author":{"gitId":"-"},"content":" constructor(public labelService: LabelService) {}"},{"lineNumber":14,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":3,"-":11}},{"path":"src/app/shared/issue-pr-card/issue-pr-card-milestone/issue-pr-card-milestone.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"MadLamprey"},"content":"\u003cdiv *ngIf\u003d\"repoHasMilestones\" class\u003d\"milestone\" [ngStyle]\u003d\"{ color: milestone.state ? \u0027grey\u0027 : \u0027red\u0027 }\"\u003e"},{"lineNumber":2,"author":{"gitId":"MadLamprey"},"content":" \u003cspan class\u003d\"octicon-milestone\" octicon\u003d\"milestone\" [color]\u003d\"milestone.state ? \u0027grey\u0027 : \u0027red\u0027\" size\u003d\"8\"\u003e \u003c/span\u003e"},{"lineNumber":3,"author":{"gitId":"MadLamprey"},"content":" {{ milestone.state ? milestone.title : \u0027???\u0027 }}"},{"lineNumber":4,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"MadLamprey":3,"-":1}},{"path":"src/app/shared/issue-pr-card/issue-pr-card-milestone/issue-pr-card-milestone.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component, Input } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Milestone } from \u0027../../../core/models/milestone.model\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":""},{"lineNumber":4,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":5,"author":{"gitId":"-"},"content":" selector: \u0027app-issue-pr-card-milestone\u0027,"},{"lineNumber":6,"author":{"gitId":"-"},"content":" templateUrl: \u0027./issue-pr-card-milestone.component.html\u0027,"},{"lineNumber":7,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./issue-pr-card-milestone.component.css\u0027]"},{"lineNumber":8,"author":{"gitId":"-"},"content":"})"},{"lineNumber":9,"author":{"gitId":"-"},"content":"export class IssuePrCardMilestoneComponent {"},{"lineNumber":10,"author":{"gitId":"-"},"content":" @Input() milestone: Milestone;"},{"lineNumber":11,"author":{"gitId":"MadLamprey"},"content":" @Input() repoHasMilestones: boolean;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":" constructor() {}"},{"lineNumber":14,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"MadLamprey":1,"-":13}},{"path":"src/app/shared/issue-pr-card/issue-pr-card.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":".card {"},{"lineNumber":2,"author":{"gitId":"-"},"content":" margin: 8px 0px 8px 0px;"},{"lineNumber":3,"author":{"gitId":"Arif-Khalid"},"content":" background-color: transparent;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"}"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":".mat-card {"},{"lineNumber":7,"author":{"gitId":"-"},"content":" padding: 10px;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"}"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":".column-header {"},{"lineNumber":11,"author":{"gitId":"-"},"content":" justify-content: center;"},{"lineNumber":12,"author":{"gitId":"-"},"content":" margin: 0;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"}"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":".border-green {"},{"lineNumber":16,"author":{"gitId":"-"},"content":" border-left: 2.4px solid green;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"}"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":".border-purple {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" border-left: 2.4px solid purple;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"}"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":".border-red {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" border-left: 2.4px solid red;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"}"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":".border-gray {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" border-left: 2.4px solid gray;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"}"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":".mat-card-content {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" display: flex;"},{"lineNumber":33,"author":{"gitId":"-"},"content":" align-items: center;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" font-size: 11px;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" text-align: left;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" margin: 0px;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" padding: 0px;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"}"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":".mat-card-subtitle {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" display: flex;"},{"lineNumber":42,"author":{"gitId":"-"},"content":" align-items: center;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" font-size: 11px;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" text-align: left;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" overflow: auto;"},{"lineNumber":46,"author":{"gitId":"-"},"content":" margin: 6px 0;"},{"lineNumber":47,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"Arif-Khalid":1,"-":46}},{"path":"src/app/shared/issue-pr-card/issue-pr-card.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cmat-card class\u003d\"card\" [ngClass]\u003d\"getIssueOpenOrCloseColorCSSClass()\"\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"no-underline link-grey-dark\" (click)\u003d\"viewIssueInBrowser($event)\"\u003e"},{"lineNumber":3,"author":{"gitId":"-"},"content":" \u003cspan [matTooltip]\u003d\"this.issue.updated_at\"\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003capp-issue-pr-card-header [issue]\u003d\"issue\"\u003e\u003c/app-issue-pr-card-header\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":" \u003cmat-card-content\u003e"},{"lineNumber":6,"author":{"gitId":"MadLamprey"},"content":" \u003capp-issue-pr-card-milestone"},{"lineNumber":7,"author":{"gitId":"MadLamprey"},"content":" [milestone]\u003d\"issue.milestone\""},{"lineNumber":8,"author":{"gitId":"MadLamprey"},"content":" [repoHasMilestones]\u003d\"!milestoneService.hasNoMilestones\""},{"lineNumber":9,"author":{"gitId":"MadLamprey"},"content":" \u003e\u003c/app-issue-pr-card-milestone\u003e"},{"lineNumber":10,"author":{"gitId":"Arif-Khalid"},"content":" \u003capp-issue-pr-card-labels [labels]\u003d\"issue.githubLabels\" [labelSet]\u003d\"filter?.hiddenLabels\"\u003e\u003c/app-issue-pr-card-labels\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003c/mat-card-content\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":"\u003c/mat-card\u003e"}],"authorContributionMap":{"Arif-Khalid":1,"MadLamprey":4,"-":9}},{"path":"src/app/shared/issue-pr-card/issue-pr-card.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component, Input } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Issue } from \u0027../../core/models/issue.model\u0027;"},{"lineNumber":3,"author":{"gitId":"Arif-Khalid"},"content":"import { Filter } from \u0027../../core/services/filters.service\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027../../core/services/github.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { LabelService } from \u0027../../core/services/label.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027../../core/services/logging.service\u0027;"},{"lineNumber":7,"author":{"gitId":"MadLamprey"},"content":"import { MilestoneService } from \u0027../../core/services/milestone.service\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":10,"author":{"gitId":"-"},"content":" selector: \u0027app-issue-pr-card\u0027,"},{"lineNumber":11,"author":{"gitId":"-"},"content":" templateUrl: \u0027./issue-pr-card.component.html\u0027,"},{"lineNumber":12,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./issue-pr-card.component.css\u0027]"},{"lineNumber":13,"author":{"gitId":"-"},"content":"})"},{"lineNumber":14,"author":{"gitId":"-"},"content":"export class IssuePrCardComponent {"},{"lineNumber":15,"author":{"gitId":"-"},"content":" @Input() issue: Issue;"},{"lineNumber":16,"author":{"gitId":"Arif-Khalid"},"content":" @Input() filter?: Filter;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"MadLamprey"},"content":" constructor("},{"lineNumber":19,"author":{"gitId":"MadLamprey"},"content":" private logger: LoggingService,"},{"lineNumber":20,"author":{"gitId":"MadLamprey"},"content":" private githubService: GithubService,"},{"lineNumber":21,"author":{"gitId":"MadLamprey"},"content":" public labelService: LabelService,"},{"lineNumber":22,"author":{"gitId":"MadLamprey"},"content":" public milestoneService: MilestoneService"},{"lineNumber":23,"author":{"gitId":"MadLamprey"},"content":" ) {}"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" /** Opens issue in new window */"},{"lineNumber":26,"author":{"gitId":"-"},"content":" viewIssueInBrowser(event: Event) {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" this.logger.info(`CardViewComponent: Opening Issue ${this.issue.id} on Github`);"},{"lineNumber":28,"author":{"gitId":"-"},"content":" this.githubService.viewIssueInBrowser(this.issue.id, event);"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" /** Returns CSS class for border color */"},{"lineNumber":32,"author":{"gitId":"-"},"content":" getIssueOpenOrCloseColorCSSClass() {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" if (this.issue.state \u003d\u003d\u003d \u0027OPEN\u0027) {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" if (this.issue.isDraft) {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" return \u0027grey\u0027;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":37,"author":{"gitId":"-"},"content":" return \u0027border-green\u0027;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" }"},{"lineNumber":39,"author":{"gitId":"-"},"content":" } else if (this.issue.issueOrPr \u003d\u003d\u003d \u0027PullRequest\u0027 \u0026\u0026 this.issue.state \u003d\u003d\u003d \u0027CLOSED\u0027) {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" return \u0027border-red\u0027;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" } else if (this.issue.issueOrPr \u003d\u003d\u003d \u0027Issue\u0027 \u0026\u0026 this.issue.stateReason \u003d\u003d\u003d \u0027NOT_PLANNED\u0027) {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" return \u0027border-gray\u0027;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return \u0027border-purple\u0027;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":49,"author":{"gitId":"-"},"content":" * Truncates description to fit in card content."},{"lineNumber":50,"author":{"gitId":"-"},"content":" * @param description - Description of Issue that is to be displayed."},{"lineNumber":51,"author":{"gitId":"-"},"content":" */"},{"lineNumber":52,"author":{"gitId":"-"},"content":" fitDescriptionText(): string {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" // Arbitrary Length of Characters beyond which an overflow occurs."},{"lineNumber":54,"author":{"gitId":"-"},"content":" const MAX_CHARACTER_LENGTH \u003d 72;"},{"lineNumber":55,"author":{"gitId":"-"},"content":" const ELLIPSES \u003d \u0027...\u0027;"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" return this.issue.description.slice(0, MAX_CHARACTER_LENGTH) + ELLIPSES;"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"Arif-Khalid":2,"MadLamprey":7,"-":50}},{"path":"src/app/shared/issue-tables/IssuesDataTable.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { DataSource } from \u0027@angular/cdk/table\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { MatPaginator } from \u0027@angular/material/paginator\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { BehaviorSubject, merge, Observable, Subscription } from \u0027rxjs\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { map } from \u0027rxjs/operators\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import { Group } from \u0027../../core/models/github/group.interface\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { Issue } from \u0027../../core/models/issue.model\u0027;"},{"lineNumber":7,"author":{"gitId":"nknguyenhc"},"content":"import { Filter, FiltersService } from \u0027../../core/services/filters.service\u0027;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"import { GroupingContextService } from \u0027../../core/services/grouping/grouping-context.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { IssueService } from \u0027../../core/services/issue.service\u0027;"},{"lineNumber":10,"author":{"gitId":"nknguyenhc"},"content":"import { MilestoneService } from \u0027../../core/services/milestone.service\u0027;"},{"lineNumber":11,"author":{"gitId":"Arif-Khalid"},"content":"import { applyDropdownFilter } from \u0027./dropdownfilter\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { FilterableSource } from \u0027./filterableTypes\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { paginateData } from \u0027./issue-paginator\u0027;"},{"lineNumber":14,"author":{"gitId":"Arif-Khalid"},"content":"import { applySort } from \u0027./issue-sorter\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import { applySearchFilter } from \u0027./search-filter\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"export class IssuesDataTable extends DataSource\u003cIssue\u003e implements FilterableSource {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" public count \u003d 0;"},{"lineNumber":19,"author":{"gitId":"nknguyenhc"},"content":" private filterChange \u003d new BehaviorSubject(this.filtersService.defaultFilter());"},{"lineNumber":20,"author":{"gitId":"-"},"content":" private issuesSubject \u003d new BehaviorSubject\u003cIssue[]\u003e([]);"},{"lineNumber":21,"author":{"gitId":"-"},"content":" private issueSubscription: Subscription;"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" public isLoading$ \u003d this.issueService.isLoading.asObservable();"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" constructor("},{"lineNumber":26,"author":{"gitId":"-"},"content":" private issueService: IssueService,"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" private groupingContextService: GroupingContextService,"},{"lineNumber":28,"author":{"gitId":"nknguyenhc"},"content":" private filtersService: FiltersService,"},{"lineNumber":29,"author":{"gitId":"nknguyenhc"},"content":" private milestoneService: MilestoneService,"},{"lineNumber":30,"author":{"gitId":"-"},"content":" private paginator: MatPaginator,"},{"lineNumber":31,"author":{"gitId":"-"},"content":" private displayedColumn: string[],"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" private group?: Group,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" private defaultFilter?: (issue: Issue) \u003d\u003e boolean"},{"lineNumber":34,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" super();"},{"lineNumber":36,"author":{"gitId":"-"},"content":" }"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" connect(): Observable\u003cIssue[]\u003e {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" return this.issuesSubject.asObservable();"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" disconnect() {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" this.filterChange.complete();"},{"lineNumber":44,"author":{"gitId":"-"},"content":" this.issuesSubject.complete();"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" if (this.issueSubscription) {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" this.issueSubscription.unsubscribe();"},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":48,"author":{"gitId":"-"},"content":" this.issueService.stopPollIssues();"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" loadIssues() {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" let page;"},{"lineNumber":53,"author":{"gitId":"-"},"content":" if (this.paginator !\u003d\u003d undefined) {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" page \u003d this.paginator.page;"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"Arif-Khalid"},"content":" const displayDataChanges \u003d [this.issueService.issues$, page, this.filterChange].filter((x) \u003d\u003e x !\u003d\u003d undefined);"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" this.issueService.startPollIssues();"},{"lineNumber":60,"author":{"gitId":"-"},"content":" this.issueSubscription \u003d merge(...displayDataChanges)"},{"lineNumber":61,"author":{"gitId":"-"},"content":" .pipe("},{"lineNumber":62,"author":{"gitId":"-"},"content":" // maps each change in display value to new issue ordering or filtering"},{"lineNumber":63,"author":{"gitId":"-"},"content":" map(() \u003d\u003e {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" let data \u003d \u003cIssue[]\u003eObject.values(this.issueService.issues$.getValue()).reverse();"},{"lineNumber":65,"author":{"gitId":"-"},"content":" if (this.defaultFilter) {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" data \u003d data.filter(this.defaultFilter);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":" // Filter by assignee of issue"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":" data \u003d this.groupingContextService.getDataForGroup(data, this.group);"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"Arif-Khalid"},"content":" // Apply Filters"},{"lineNumber":72,"author":{"gitId":"nknguyenhc"},"content":" data \u003d applyDropdownFilter(this.filter, data, !this.milestoneService.hasNoMilestones);"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"Arif-Khalid"},"content":" data \u003d applySearchFilter(this.filter.title, this.displayedColumn, this.issueService, data);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" this.count \u003d data.length;"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"Arif-Khalid"},"content":" data \u003d applySort(this.filter.sort, data);"},{"lineNumber":78,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" if (this.paginator !\u003d\u003d undefined) {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" data \u003d paginateData(this.paginator, data);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":" return data;"},{"lineNumber":83,"author":{"gitId":"-"},"content":" })"},{"lineNumber":84,"author":{"gitId":"-"},"content":" )"},{"lineNumber":85,"author":{"gitId":"-"},"content":" .subscribe((issues) \u003d\u003e {"},{"lineNumber":86,"author":{"gitId":"-"},"content":" this.issuesSubject.next(issues);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" });"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"Arif-Khalid"},"content":" get filter(): Filter {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" return this.filterChange.value;"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"Arif-Khalid"},"content":" set filter(filter: Filter) {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" this.filterChange.next(filter);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" }"},{"lineNumber":97,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":6,"NereusWB922":7,"Arif-Khalid":9,"-":75}},{"path":"src/app/shared/issue-tables/dropdownfilter.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Issue } from \u0027../../core/models/issue.model\u0027;"},{"lineNumber":2,"author":{"gitId":"Arif-Khalid"},"content":"import { Filter } from \u0027../../core/services/filters.service\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":""},{"lineNumber":4,"author":{"gitId":"nknguyenhc"},"content":"type StatusInfo \u003d {"},{"lineNumber":5,"author":{"gitId":"-"},"content":" type: string;"},{"lineNumber":6,"author":{"gitId":"nknguyenhc"},"content":" status: string;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"};"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"nknguyenhc"},"content":"/**"},{"lineNumber":10,"author":{"gitId":"nknguyenhc"},"content":" * Converts a status string into an info object"},{"lineNumber":11,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":12,"author":{"gitId":"nknguyenhc"},"content":"const infoFromStatus \u003d (statusString: string): StatusInfo \u003d\u003e {"},{"lineNumber":13,"author":{"gitId":"nknguyenhc"},"content":" const [status, type] \u003d statusString.split(\u0027 \u0027);"},{"lineNumber":14,"author":{"gitId":"nknguyenhc"},"content":" return { status, type };"},{"lineNumber":15,"author":{"gitId":"-"},"content":"};"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * This module serves to improve separation of concerns in IssuesDataTable.ts and IssueList.ts module by containing the logic for"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * applying dropdownFilter to the issues data table in this module."},{"lineNumber":20,"author":{"gitId":"-"},"content":" * This module exports a single function applyDropDownFilter which is called by IssueList."},{"lineNumber":21,"author":{"gitId":"Arif-Khalid"},"content":" * This functions returns the data passed in after all the filters of dropdownFilters are applied"},{"lineNumber":22,"author":{"gitId":"-"},"content":" */"},{"lineNumber":23,"author":{"gitId":"nknguyenhc"},"content":"export function applyDropdownFilter(filter: Filter, data: Issue[], isFilteringByMilestone: boolean): Issue[] {"},{"lineNumber":24,"author":{"gitId":"Arif-Khalid"},"content":" const filteredData: Issue[] \u003d data.filter((issue) \u003d\u003e {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" let ret \u003d true;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"nknguyenhc"},"content":" // status can either be \u0027open\u0027, \u0027closed\u0027, or \u0027merged\u0027"},{"lineNumber":28,"author":{"gitId":"nknguyenhc"},"content":" ret \u003d"},{"lineNumber":29,"author":{"gitId":"nknguyenhc"},"content":" ret \u0026\u0026"},{"lineNumber":30,"author":{"gitId":"nknguyenhc"},"content":" filter.status.some((item) \u003d\u003e {"},{"lineNumber":31,"author":{"gitId":"nknguyenhc"},"content":" const statusInfo \u003d infoFromStatus(item);"},{"lineNumber":32,"author":{"gitId":"nknguyenhc"},"content":" return statusInfo.status \u003d\u003d\u003d issue.state.toLowerCase() \u0026\u0026 statusInfo.type \u003d\u003d\u003d issue.issueOrPr.toLowerCase();"},{"lineNumber":33,"author":{"gitId":"nknguyenhc"},"content":" });"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"Arif-Khalid"},"content":" if (filter.type \u003d\u003d\u003d \u0027issue\u0027) {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" ret \u003d ret \u0026\u0026 issue.issueOrPr \u003d\u003d\u003d \u0027Issue\u0027;"},{"lineNumber":37,"author":{"gitId":"Arif-Khalid"},"content":" } else if (filter.type \u003d\u003d\u003d \u0027pullrequest\u0027) {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" ret \u003d ret \u0026\u0026 issue.issueOrPr \u003d\u003d\u003d \u0027PullRequest\u0027;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"nknguyenhc"},"content":" ret \u003d ret \u0026\u0026 (!isFilteringByMilestone || filter.milestones.some((milestone) \u003d\u003e issue.milestone.title \u003d\u003d\u003d milestone));"},{"lineNumber":42,"author":{"gitId":"nknguyenhc"},"content":" ret \u003d ret \u0026\u0026 issue.labels.every((label) \u003d\u003e !filter.deselectedLabels.has(label));"},{"lineNumber":43,"author":{"gitId":"Arif-Khalid"},"content":" return ret \u0026\u0026 filter.labels.every((label) \u003d\u003e issue.labels.includes(label));"},{"lineNumber":44,"author":{"gitId":"Arif-Khalid"},"content":" });"},{"lineNumber":45,"author":{"gitId":"Arif-Khalid"},"content":" return filteredData;"},{"lineNumber":46,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":18,"Arif-Khalid":8,"-":20}},{"path":"src/app/shared/issue-tables/filterableTypes.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":2,"author":{"gitId":"-"},"content":" * This module aims to abstract out classes that can be filtered"},{"lineNumber":3,"author":{"gitId":"-"},"content":" */"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"Arif-Khalid"},"content":"import { Filter } from \u0027../../core/services/filters.service\u0027;"},{"lineNumber":6,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":8,"author":{"gitId":"-"},"content":" * FilterableSource is an interface that contains a source that can be filtered"},{"lineNumber":9,"author":{"gitId":"-"},"content":" * by a string filter or dropdownFilter."},{"lineNumber":10,"author":{"gitId":"-"},"content":" * The source should set filter and dropdownFilter as a getter and setter"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * and applies the filter when these variables are changed."},{"lineNumber":12,"author":{"gitId":"-"},"content":" */"},{"lineNumber":13,"author":{"gitId":"-"},"content":"export interface FilterableSource {"},{"lineNumber":14,"author":{"gitId":"Arif-Khalid"},"content":" filter: Filter;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"}"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * FilterComponent is a component that contains a FilterableSource"},{"lineNumber":19,"author":{"gitId":"-"},"content":" */"},{"lineNumber":20,"author":{"gitId":"-"},"content":"export interface FilterableComponent {"},{"lineNumber":21,"author":{"gitId":"-"},"content":" retrieveFilterable: () \u003d\u003e FilterableSource;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"Arif-Khalid":3,"-":19}},{"path":"src/app/shared/issue-tables/issue-sorter.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"Arif-Khalid"},"content":"import { Sort } from \u0027@angular/material/sort\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import * as moment from \u0027moment\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { Issue } from \u0027../../core/models/issue.model\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"Arif-Khalid"},"content":"export function applySort(sort: Sort, data: Issue[]): Issue[] {"},{"lineNumber":6,"author":{"gitId":"-"},"content":" if (!sort.active) {"},{"lineNumber":7,"author":{"gitId":"-"},"content":" return data;"},{"lineNumber":8,"author":{"gitId":"-"},"content":" }"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":" const direction: number \u003d sort.direction \u003d\u003d\u003d \u0027asc\u0027 ? 1 : -1;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":" switch (sort.active) {"},{"lineNumber":13,"author":{"gitId":"-"},"content":" case \u0027id\u0027:"},{"lineNumber":14,"author":{"gitId":"MadLamprey"},"content":" return data.sort((a, b) \u003d\u003e direction * compareByIntegerValue(a.id, b.id));"},{"lineNumber":15,"author":{"gitId":"-"},"content":" case \u0027date\u0027:"},{"lineNumber":16,"author":{"gitId":"MadLamprey"},"content":" return data.sort((a, b) \u003d\u003e direction * compareByDateValue(a.updated_at, b.updated_at));"},{"lineNumber":17,"author":{"gitId":"MadLamprey"},"content":" case \u0027status\u0027:"},{"lineNumber":18,"author":{"gitId":"MadLamprey"},"content":" return data.sort((a, b) \u003d\u003e direction * compareByIssueType(a, b));"},{"lineNumber":19,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":20,"author":{"gitId":"-"},"content":" // title, responseTag are string values"},{"lineNumber":21,"author":{"gitId":"MadLamprey"},"content":" return data.sort((a, b) \u003d\u003e direction * compareByStringValue(a[sort.active], b[sort.active]));"},{"lineNumber":22,"author":{"gitId":"-"},"content":" }"},{"lineNumber":23,"author":{"gitId":"-"},"content":"}"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":"function compareByStringValue(valueA: string, valueB: string): number {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" const orderA \u003d String(valueA || \u0027\u0027).toUpperCase();"},{"lineNumber":27,"author":{"gitId":"-"},"content":" const orderB \u003d String(valueB || \u0027\u0027).toUpperCase();"},{"lineNumber":28,"author":{"gitId":"-"},"content":" return orderA \u003c orderB ? -1 : 1;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"}"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":"function compareByIntegerValue(valueA: number, valueB: number): number {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" return valueA \u003c valueB ? -1 : 1;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"}"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":"function compareByDateValue(valueA: string, valueB: string): number {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" return moment(valueA).isBefore(valueB) ? -1 : 1;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"}"},{"lineNumber":38,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":39,"author":{"gitId":"MadLamprey"},"content":"function compareByIssueType(valueA: Issue, valueB: Issue): number {"},{"lineNumber":40,"author":{"gitId":"MadLamprey"},"content":" const sortOrder \u003d {"},{"lineNumber":41,"author":{"gitId":"MadLamprey"},"content":" \u0027OPEN PullRequest\u0027: 0,"},{"lineNumber":42,"author":{"gitId":"MadLamprey"},"content":" \u0027OPEN Issue\u0027: 1,"},{"lineNumber":43,"author":{"gitId":"MadLamprey"},"content":" \u0027MERGED PullRequest\u0027: 2,"},{"lineNumber":44,"author":{"gitId":"MadLamprey"},"content":" \u0027CLOSED Issue\u0027: 3,"},{"lineNumber":45,"author":{"gitId":"MadLamprey"},"content":" \u0027CLOSED PullRequest\u0027: 4"},{"lineNumber":46,"author":{"gitId":"MadLamprey"},"content":" };"},{"lineNumber":47,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":48,"author":{"gitId":"MadLamprey"},"content":" const aOrder \u003d sortOrder[valueA.state + \u0027 \u0027 + valueA.issueOrPr] || -1;"},{"lineNumber":49,"author":{"gitId":"MadLamprey"},"content":" const bOrder \u003d sortOrder[valueB.state + \u0027 \u0027 + valueB.issueOrPr] || -1;"},{"lineNumber":50,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":51,"author":{"gitId":"MadLamprey"},"content":" if (aOrder \u003d\u003d\u003d bOrder) {"},{"lineNumber":52,"author":{"gitId":"MadLamprey"},"content":" return compareByStringValue(valueA.title, valueB.title);"},{"lineNumber":53,"author":{"gitId":"MadLamprey"},"content":" } else if (aOrder \u003e bOrder) {"},{"lineNumber":54,"author":{"gitId":"MadLamprey"},"content":" return 1;"},{"lineNumber":55,"author":{"gitId":"MadLamprey"},"content":" } else {"},{"lineNumber":56,"author":{"gitId":"MadLamprey"},"content":" return -1;"},{"lineNumber":57,"author":{"gitId":"MadLamprey"},"content":" }"},{"lineNumber":58,"author":{"gitId":"MadLamprey"},"content":"}"}],"authorContributionMap":{"Arif-Khalid":2,"MadLamprey":26,"-":30}},{"path":"src/app/shared/layout/header.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":".repo-menu-footer {"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" display: flex;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" justify-content: space-between;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" align-items: center;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" position: sticky;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" bottom: 0;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" z-index: 1;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" padding: 10px;"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":".new-repo-button {"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" flex-grow: 1;"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":".keep-filter-button {"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" margin-left: 2px;"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":".repo-options {"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" max-height: 300px;"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" overflow-y: auto;"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":".repo-options button {"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" font-size: 17px;"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":"/* Overwrite the width of the menu */"},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":"::ng-deep .repo-menu {"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" width: fit-content !important;"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" min-width: 320px !important;"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":32}},{"path":"src/app/shared/layout/header.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cmat-toolbar color\u003d\"primary\" style\u003d\"position: sticky; position: -webkit-sticky; top: 0; z-index: 1000\"\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" \u003cbutton"},{"lineNumber":3,"author":{"gitId":"-"},"content":" *ngIf\u003d\"isBackButtonShown()\""},{"lineNumber":4,"author":{"gitId":"-"},"content":" mat-icon-button"},{"lineNumber":5,"author":{"gitId":"-"},"content":" class\u003d\"mat-toolbar mat-primary back-button\""},{"lineNumber":6,"author":{"gitId":"-"},"content":" style\u003d\"transform: scale(0.9)\""},{"lineNumber":7,"author":{"gitId":"-"},"content":" (click)\u003d\"goBack()\""},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":9,"author":{"gitId":"-"},"content":" \u003cmat-icon\u003earrow_back_ios\u003c/mat-icon\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" \u003ca class\u003d\"mat-toolbar mat-primary\" style\u003d\"text-decoration: none\" [routerLink]\u003d\"viewService.isRepoSet() ? viewService.currentView : null\""},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003eWATcher v{{ this.getVersion() }}\u003c/a"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":14,"author":{"gitId":"Arif-Khalid"},"content":" \u003cspan id\u003d\"view-descriptor\" *ngIf\u003d\"viewService.isRepoSet()\" style\u003d\"margin-left: 70px\"\u003e"},{"lineNumber":15,"author":{"gitId":"nknguyenhc"},"content":" {{ this.presetViews[this.filtersService.presetView$.value] }}"},{"lineNumber":16,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"nknguyenhc"},"content":" \u003c!-- Gateway to activity dashboard, do not delete --\u003e"},{"lineNumber":19,"author":{"gitId":"nknguyenhc"},"content":" \u003c!--div *ngIf\u003d\"auth.isAuthenticated() \u0026\u0026 this.viewService.sessionData.sessionRepo.length \u003e 1\"\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003cbutton mat-button [matMenuTriggerFor]\u003d\"menu\"\u003e\u003cmat-icon style\u003d\"color: white\"\u003eexpand_more\u003c/mat-icon\u003e\u003c/button\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003cmat-menu #menu\u003d\"matMenu\"\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u003cbutton"},{"lineNumber":23,"author":{"gitId":"-"},"content":" mat-menu-item"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" *ngFor\u003d\"let sessionRepo of this.viewService.sessionData.sessionRepo\""},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" (click)\u003d\"this.routeToSelectedView(sessionRepo.view)\""},{"lineNumber":26,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003cspan\u003e"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-icon [ngStyle]\u003d\"{ color: \u0027green\u0027, visibility: this.viewService.currentView \u003d\u003d\u003d sessionRepo.view ? \u0027visible\u0027 : \u0027hidden\u0027 }\""},{"lineNumber":29,"author":{"gitId":"-"},"content":" \u003edone\u003c/mat-icon"},{"lineNumber":30,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" {{ this.getViewDescription(sessionRepo.view) }}"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003c/mat-menu\u003e"},{"lineNumber":35,"author":{"gitId":"nknguyenhc"},"content":" \u003c/div--\u003e"},{"lineNumber":36,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":37,"author":{"gitId":"Arif-Khalid"},"content":" \u003cdiv *ngIf\u003d\"viewService.isRepoSet()\"\u003e"},{"lineNumber":38,"author":{"gitId":"nknguyenhc"},"content":" \u003cbutton mat-button [matMenuTriggerFor]\u003d\"menu\"\u003e\u003cmat-icon style\u003d\"color: white\"\u003eexpand_more\u003c/mat-icon\u003e\u003c/button\u003e"},{"lineNumber":39,"author":{"gitId":"nknguyenhc"},"content":" \u003cmat-menu #menu\u003d\"matMenu\"\u003e"},{"lineNumber":40,"author":{"gitId":"nknguyenhc"},"content":" \u003cdiv *ngFor\u003d\"let presetView of this.presetViews | keyvalue\"\u003e"},{"lineNumber":41,"author":{"gitId":"nknguyenhc"},"content":" \u003cbutton mat-menu-item *ngIf\u003d\"presetView.key !\u003d\u003d \u0027custom\u0027\" (click)\u003d\"this.filtersService.updatePresetView(presetView.key)\"\u003e"},{"lineNumber":42,"author":{"gitId":"nknguyenhc"},"content":" \u003cspan\u003e"},{"lineNumber":43,"author":{"gitId":"nknguyenhc"},"content":" \u003cmat-icon"},{"lineNumber":44,"author":{"gitId":"nknguyenhc"},"content":" [ngStyle]\u003d\"{ color: \u0027green\u0027, visibility: this.filtersService.presetView$.value \u003d\u003d\u003d presetView.key ? \u0027visible\u0027 : \u0027hidden\u0027 }\""},{"lineNumber":45,"author":{"gitId":"nknguyenhc"},"content":" \u003edone\u003c/mat-icon"},{"lineNumber":46,"author":{"gitId":"nknguyenhc"},"content":" \u003e"},{"lineNumber":47,"author":{"gitId":"nknguyenhc"},"content":" {{ presetView.value }}"},{"lineNumber":48,"author":{"gitId":"nknguyenhc"},"content":" \u003c/span\u003e"},{"lineNumber":49,"author":{"gitId":"nknguyenhc"},"content":" \u003c/button\u003e"},{"lineNumber":50,"author":{"gitId":"nknguyenhc"},"content":" \u003c/div\u003e"},{"lineNumber":51,"author":{"gitId":"nknguyenhc"},"content":" \u003c/mat-menu\u003e"},{"lineNumber":52,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" \u003c!-- everything else --\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" \u003cspan style\u003d\"flex: 1 1 auto\"\u003e\u003c/span\u003e"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv *ngIf\u003d\"auth.isAuthenticated() \u0026\u0026 viewService.isRepoSet()\"\u003e"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" \u003cspan id\u003d\"view-descriptor\" style\u003d\"margin-left: 10px\"\u003e"},{"lineNumber":60,"author":{"gitId":"-"},"content":" {{ this.currentRepo || \u0027No Repository Set\u0027 }}"},{"lineNumber":61,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":62,"author":{"gitId":"-"},"content":" \u003cbutton"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" mat-icon-button"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" matTooltip\u003d\"{{ viewService.isRepoSet() ? \u0027Change Repository\u0027 : \u0027Select Repository\u0027 }}\""},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":" [matMenuTriggerFor]\u003d\"repoMenu\""},{"lineNumber":66,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":67,"author":{"gitId":"-"},"content":" \u003cmat-icon\u003eedit\u003c/mat-icon\u003e"},{"lineNumber":68,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":69,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-menu #repoMenu xPosition\u003d\"before\" class\u003d\"repo-menu\"\u003e"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv class\u003d\"repo-options\"\u003e"},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv *ngFor\u003d\"let repo of this.repoUrlCacheService.suggestions\"\u003e"},{"lineNumber":74,"author":{"gitId":"NereusWB922"},"content":" \u003cbutton mat-menu-item *ngIf\u003d\"repo !\u003d\u003d this.currentRepo\" (click)\u003d\"this.applyRepoDropdown(repo, true)\"\u003e"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":" {{ repo }}"},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" \u003c/button\u003e"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" \u003c/div\u003e"},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":" \u003c/div\u003e"},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv class\u003d\"repo-menu-footer\"\u003e"},{"lineNumber":81,"author":{"gitId":"NereusWB922"},"content":" \u003cbutton mat-flat-button color\u003d\"primary\" class\u003d\"new-repo-button\" (click)\u003d\"this.openChangeRepoDialog()\" matTooltip\u003d\"Add new repository\"\u003e"},{"lineNumber":82,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-icon\u003eadd\u003c/mat-icon\u003e"},{"lineNumber":83,"author":{"gitId":"NereusWB922"},"content":" \u003c/button\u003e"},{"lineNumber":84,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":85,"author":{"gitId":"NereusWB922"},"content":" \u003cbutton"},{"lineNumber":86,"author":{"gitId":"NereusWB922"},"content":" mat-icon-button"},{"lineNumber":87,"author":{"gitId":"NereusWB922"},"content":" (click)\u003d\"toggleKeepFilters($event)\""},{"lineNumber":88,"author":{"gitId":"NereusWB922"},"content":" class\u003d\"keep-filter-button\""},{"lineNumber":89,"author":{"gitId":"NereusWB922"},"content":" matTooltip\u003d\"{{ keepFilters ? \u0027Keep filter on\u0027 : \u0027Keep filter off\u0027 }}\""},{"lineNumber":90,"author":{"gitId":"NereusWB922"},"content":" color\u003d\"{{ keepFilters ? \u0027primary\u0027 : \u0027warn\u0027 }}\""},{"lineNumber":91,"author":{"gitId":"NereusWB922"},"content":" \u003e"},{"lineNumber":92,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-icon\u003e{{ keepFilters ? \u0027filter_alt\u0027 : \u0027filter_alt_off\u0027 }}\u003c/mat-icon\u003e"},{"lineNumber":93,"author":{"gitId":"NereusWB922"},"content":" \u003c/button\u003e"},{"lineNumber":94,"author":{"gitId":"NereusWB922"},"content":" \u003c/div\u003e"},{"lineNumber":95,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-menu\u003e"},{"lineNumber":96,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" \u003cspan style\u003d\"flex: 1 1 auto\"\u003e\u003c/span\u003e"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" \u003cbutton mat-button matTooltip\u003d\"Download WATcher Log\" (click)\u003d\"this.exportLogFile()\"\u003e"},{"lineNumber":100,"author":{"gitId":"-"},"content":" \u003cmat-icon\u003ereceipt\u003c/mat-icon\u003e"},{"lineNumber":101,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":102,"author":{"gitId":"-"},"content":" \u003cbutton mat-button matTooltip\u003d\"Give feedback about WATcher\" (click)\u003d\"openIssueTracker()\"\u003e"},{"lineNumber":103,"author":{"gitId":"-"},"content":" \u003cmat-icon\u003email\u003c/mat-icon\u003e"},{"lineNumber":104,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" \u003cbutton"},{"lineNumber":107,"author":{"gitId":"NereusWB922"},"content":" *ngIf\u003d\"auth.isAuthenticated() \u0026\u0026 viewService.isRepoSet() \u0026\u0026 isOpenUrlButtonShown()\""},{"lineNumber":108,"author":{"gitId":"-"},"content":" mat-button"},{"lineNumber":109,"author":{"gitId":"-"},"content":" matTooltip\u003d\"View current page on GitHub\""},{"lineNumber":110,"author":{"gitId":"-"},"content":" (click)\u003d\"viewBrowser()\""},{"lineNumber":111,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":112,"author":{"gitId":"-"},"content":" \u003cmat-icon\u003eopen_in_new\u003c/mat-icon\u003e"},{"lineNumber":113,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"sync-spinner\" *ngIf\u003d\"auth.isAuthenticated() \u0026\u0026 (this.isLoading$ | async); else notLoading\"\u003e"},{"lineNumber":116,"author":{"gitId":"-"},"content":" \u003cmat-spinner class\u003d\"white-spinner\" [diameter]\u003d\"20\"\u003e\u003c/mat-spinner\u003e"},{"lineNumber":117,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" \u003cng-template #notLoading\u003e"},{"lineNumber":120,"author":{"gitId":"-"},"content":" \u003cbutton"},{"lineNumber":121,"author":{"gitId":"NereusWB922"},"content":" *ngIf\u003d\"auth.isAuthenticated() \u0026\u0026 viewService.isRepoSet() \u0026\u0026 isReloadButtonShown() \u0026\u0026 !this.isReloadButtonDisabled\""},{"lineNumber":122,"author":{"gitId":"-"},"content":" mat-button"},{"lineNumber":123,"author":{"gitId":"-"},"content":" matTooltip\u003d\"Synchronize with Github data\""},{"lineNumber":124,"author":{"gitId":"-"},"content":" (click)\u003d\"reload()\""},{"lineNumber":125,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":126,"author":{"gitId":"-"},"content":" Sync"},{"lineNumber":127,"author":{"gitId":"-"},"content":" \u003cmat-icon\u003erefresh\u003c/mat-icon\u003e"},{"lineNumber":128,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":129,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"sync-spinner\" *ngIf\u003d\"auth.isAuthenticated() \u0026\u0026 isReloadButtonShown() \u0026\u0026 this.isReloadButtonDisabled\"\u003e"},{"lineNumber":130,"author":{"gitId":"-"},"content":" \u003cspan style\u003d\"font-size: 14px; margin-right: 7px\"\u003eSync\u003c/span\u003e"},{"lineNumber":131,"author":{"gitId":"-"},"content":" \u003cmat-spinner class\u003d\"white-spinner\" [diameter]\u003d\"20\"\u003e\u003c/mat-spinner\u003e"},{"lineNumber":132,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":133,"author":{"gitId":"-"},"content":" \u003c/ng-template\u003e"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" \u003cbutton *ngIf\u003d\"auth.isAuthenticated()\" mat-button matTooltip\u003d\"Log out\" (click)\u003d\"openLogOutDialog(); $event.stopPropagation()\"\u003e"},{"lineNumber":136,"author":{"gitId":"-"},"content":" ({{ userService.currentUser.loginId }})"},{"lineNumber":137,"author":{"gitId":"-"},"content":" \u003cmat-icon style\u003d\"margin-left: 2px\"\u003eexit_to_app\u003c/mat-icon\u003e"},{"lineNumber":138,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":139,"author":{"gitId":"-"},"content":"\u003c/mat-toolbar\u003e"}],"authorContributionMap":{"nknguyenhc":19,"NereusWB922":38,"Arif-Khalid":2,"-":80}},{"path":"src/app/shared/layout/header.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Location } from \u0027@angular/common\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Component, OnInit } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { Router, RoutesRecognized } from \u0027@angular/router\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { filter, pairwise, switchMap } from \u0027rxjs/operators\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { AppConfig } from \u0027../../../environments/environment\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { STORAGE_KEYS } from \u0027../../core/constants/storage-keys.constants\u0027;"},{"lineNumber":8,"author":{"gitId":"Arif-Khalid"},"content":"import { RepoChangeResponse } from \u0027../../core/models/repo-change-response.model\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { Repo } from \u0027../../core/models/repo.model\u0027;"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"import { View } from \u0027../../core/models/view.model\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { AuthService } from \u0027../../core/services/auth.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { DialogService } from \u0027../../core/services/dialog.service\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { ErrorHandlingService } from \u0027../../core/services/error-handling.service\u0027;"},{"lineNumber":14,"author":{"gitId":"Arif-Khalid"},"content":"import { FiltersService } from \u0027../../core/services/filters.service\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027../../core/services/github.service\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import { GithubEventService } from \u0027../../core/services/githubevent.service\u0027;"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":"import { GroupingContextService } from \u0027../../core/services/grouping/grouping-context.service\u0027;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import { IssueService } from \u0027../../core/services/issue.service\u0027;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import { LabelService } from \u0027../../core/services/label.service\u0027;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027../../core/services/logging.service\u0027;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import { RepoSessionStorageService } from \u0027../../core/services/repo-session-storage.service\u0027;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import { RepoUrlCacheService } from \u0027../../core/services/repo-url-cache.service\u0027;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import { UserService } from \u0027../../core/services/user.service\u0027;"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":"import { ViewDescription, ViewService } from \u0027../../core/services/view.service\u0027;"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":"const ISSUE_TRACKER_URL \u003d \u0027https://github.com/CATcher-org/WATcher/issues\u0027;"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":29,"author":{"gitId":"-"},"content":" selector: \u0027app-layout-header\u0027,"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" templateUrl: \u0027./header.component.html\u0027,"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" styleUrls: [\u0027./header.component.css\u0027]"},{"lineNumber":32,"author":{"gitId":"-"},"content":"})"},{"lineNumber":33,"author":{"gitId":"-"},"content":"export class HeaderComponent implements OnInit {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" private prevUrl;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" isReloadButtonDisabled \u003d false;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" ISSUE_FILTER \u003d \u0027/issues?q\u003dis:issue+is:all\u0027; // the filtered list must be an issue and must be open"},{"lineNumber":37,"author":{"gitId":"-"},"content":" TUTORIAL_LABEL \u003d \u0027+label:tutorial.\u0027;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" TEAM_LABEL \u003d \u0027+label:team.\u0027;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" EXCLUDE_DUPLICATE \u003d \u0027+-label:duplicate\u0027; // exclude duplicate issues"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" public isLoading$: Observable\u003cboolean\u003e;"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" // Messages for the modal popup window upon logging out"},{"lineNumber":44,"author":{"gitId":"-"},"content":" private readonly logOutDialogMessages \u003d [\u0027Do you wish to log out?\u0027];"},{"lineNumber":45,"author":{"gitId":"-"},"content":" private readonly yesButtonDialogMessage \u003d \u0027Yes, I wish to log out\u0027;"},{"lineNumber":46,"author":{"gitId":"-"},"content":" private readonly noButtonDialogMessage \u003d \"No, I don\u0027t wish to log out\";"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"nknguyenhc"},"content":" readonly presetViews: {"},{"lineNumber":49,"author":{"gitId":"nknguyenhc"},"content":" [key: string]: string;"},{"lineNumber":50,"author":{"gitId":"nknguyenhc"},"content":" } \u003d {"},{"lineNumber":51,"author":{"gitId":"nknguyenhc"},"content":" currentlyActive: \u0027Currently active\u0027,"},{"lineNumber":52,"author":{"gitId":"nknguyenhc"},"content":" contributions: \u0027Contributions\u0027,"},{"lineNumber":53,"author":{"gitId":"nknguyenhc"},"content":" custom: \u0027Custom\u0027"},{"lineNumber":54,"author":{"gitId":"nknguyenhc"},"content":" };"},{"lineNumber":55,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" /** Model for the displayed repository name */"},{"lineNumber":57,"author":{"gitId":"-"},"content":" currentRepo \u003d \u0027\u0027;"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" keepFilters \u003d false;"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" constructor("},{"lineNumber":62,"author":{"gitId":"-"},"content":" private router: Router,"},{"lineNumber":63,"author":{"gitId":"-"},"content":" public auth: AuthService,"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" public viewService: ViewService,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" public userService: UserService,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" public logger: LoggingService,"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":" public repoUrlCacheService: RepoUrlCacheService,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" private location: Location,"},{"lineNumber":69,"author":{"gitId":"-"},"content":" private githubEventService: GithubEventService,"},{"lineNumber":70,"author":{"gitId":"-"},"content":" private issueService: IssueService,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" private labelService: LabelService,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" private errorHandlingService: ErrorHandlingService,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" private githubService: GithubService,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" private dialogService: DialogService,"},{"lineNumber":75,"author":{"gitId":"Arif-Khalid"},"content":" private repoSessionStorageService: RepoSessionStorageService,"},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" private filtersService: FiltersService,"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" private groupingContextService: GroupingContextService"},{"lineNumber":78,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" router.events"},{"lineNumber":80,"author":{"gitId":"-"},"content":" .pipe("},{"lineNumber":81,"author":{"gitId":"-"},"content":" filter((e: any) \u003d\u003e e instanceof RoutesRecognized),"},{"lineNumber":82,"author":{"gitId":"-"},"content":" pairwise()"},{"lineNumber":83,"author":{"gitId":"-"},"content":" )"},{"lineNumber":84,"author":{"gitId":"-"},"content":" .subscribe((e) \u003d\u003e {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" this.prevUrl \u003d e[0].urlAfterRedirects;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" });"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" this.auth.currentAuthState.subscribe(() \u003d\u003e {"},{"lineNumber":89,"author":{"gitId":"-"},"content":" if (auth.isAuthenticated() \u0026\u0026 !repoSessionStorageService.hasRepoLocation()) {"},{"lineNumber":90,"author":{"gitId":"nknguyenhc"},"content":" if (!this.auth.hasNext()) {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" this.openChangeRepoDialog();"},{"lineNumber":92,"author":{"gitId":"nknguyenhc"},"content":" } else {"},{"lineNumber":93,"author":{"gitId":"nknguyenhc"},"content":" this.auth.redirectToNext();"},{"lineNumber":94,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":" });"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"NereusWB922"},"content":" this.viewService.repoSetState.subscribe((state) \u003d\u003e {"},{"lineNumber":99,"author":{"gitId":"NereusWB922"},"content":" if (auth.isAuthenticated() \u0026\u0026 viewService.isRepoSet()) {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" this.initializeRepoNameInTitle();"},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":" });"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"NereusWB922"},"content":" this.viewService.repoChanged$.subscribe((repo) \u003d\u003e {"},{"lineNumber":105,"author":{"gitId":"NereusWB922"},"content":" this.initializeRepoNameInTitle();"},{"lineNumber":106,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":107,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" this.isLoading$ \u003d this.issueService.isLoading.asObservable();"},{"lineNumber":109,"author":{"gitId":"-"},"content":" }"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" ngOnInit() {}"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":114,"author":{"gitId":"NereusWB922"},"content":" * Replaces and resets the current view data and routes the app to the"},{"lineNumber":115,"author":{"gitId":"NereusWB922"},"content":" * newly selected view."},{"lineNumber":116,"author":{"gitId":"NereusWB922"},"content":" * @param selectedView - Selected View that is selected by the user."},{"lineNumber":117,"author":{"gitId":"-"},"content":" */"},{"lineNumber":118,"author":{"gitId":"NereusWB922"},"content":" routeToSelectedView(selectedView: string): void {"},{"lineNumber":119,"author":{"gitId":"NereusWB922"},"content":" // Do nothing if the selected view is the current view."},{"lineNumber":120,"author":{"gitId":"NereusWB922"},"content":" if (this.viewService.currentView \u003d\u003d\u003d View[selectedView]) {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":122,"author":{"gitId":"-"},"content":" }"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"NereusWB922"},"content":" // Replace Current View Data."},{"lineNumber":125,"author":{"gitId":"NereusWB922"},"content":" this.viewService.changeView(View[selectedView]);"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"NereusWB922"},"content":" // Remove current view issues and load selected view issues."},{"lineNumber":128,"author":{"gitId":"-"},"content":" this.githubService.reset();"},{"lineNumber":129,"author":{"gitId":"-"},"content":" this.issueService.reset(false);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" this.labelService.reset();"},{"lineNumber":131,"author":{"gitId":"-"},"content":" this.reload();"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"NereusWB922"},"content":" // Route app to new view."},{"lineNumber":134,"author":{"gitId":"NereusWB922"},"content":" this.router.navigateByUrl(this.viewService.currentView);"},{"lineNumber":135,"author":{"gitId":"-"},"content":" }"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" isBackButtonShown(): boolean {"},{"lineNumber":138,"author":{"gitId":"NereusWB922"},"content":" return `/${this.viewService.currentView}` !\u003d\u003d this.router.url \u0026\u0026 this.router.url !\u003d\u003d \u0027/\u0027 \u0026\u0026 !this.router.url.startsWith(\u0027/?code\u0027);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" }"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" isReloadButtonShown(): boolean {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" return this.router.url !\u003d\u003d \u0027/phaseBugReporting/issues/new\u0027;"},{"lineNumber":143,"author":{"gitId":"-"},"content":" }"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" isOpenUrlButtonShown(): boolean {"},{"lineNumber":146,"author":{"gitId":"NereusWB922"},"content":" return this.viewService.currentView \u003d\u003d\u003d View.issuesViewer || this.viewService.currentView \u003d\u003d\u003d View.activityDashboard;"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" getVersion(): string {"},{"lineNumber":150,"author":{"gitId":"-"},"content":" return AppConfig.version;"},{"lineNumber":151,"author":{"gitId":"-"},"content":" }"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"NereusWB922"},"content":" getViewDescription(openView: string): string {"},{"lineNumber":154,"author":{"gitId":"NereusWB922"},"content":" return ViewDescription[openView];"},{"lineNumber":155,"author":{"gitId":"-"},"content":" }"},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"-"},"content":" goBack() {"},{"lineNumber":158,"author":{"gitId":"NereusWB922"},"content":" if (this.prevUrl \u003d\u003d\u003d `/${this.viewService.currentView}/issues/new`) {"},{"lineNumber":159,"author":{"gitId":"NereusWB922"},"content":" this.router.navigateByUrl(this.viewService.currentView);"},{"lineNumber":160,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":161,"author":{"gitId":"-"},"content":" this.location.back();"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" viewBrowser() {"},{"lineNumber":166,"author":{"gitId":"NereusWB922"},"content":" if (this.viewService.currentView \u003d\u003d\u003d View.activityDashboard) {"},{"lineNumber":167,"author":{"gitId":"NereusWB922"},"content":" window.open(`https://github.com/${this.viewService.currentRepo.owner}/${this.viewService.currentRepo.name}/pulse`);"},{"lineNumber":168,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":169,"author":{"gitId":"-"},"content":" }"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" const routerUrl \u003d this.router.url.substring(1); // remove the first \u0027/\u0027 from string"},{"lineNumber":172,"author":{"gitId":"-"},"content":" const issueUrlIndex \u003d routerUrl.indexOf(\u0027/\u0027); // find the index of second \u0027/\u0027"},{"lineNumber":173,"author":{"gitId":"-"},"content":" let issueUrl: string;"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" // If can\u0027t find the index of second \u0027/\u0027, then router is at the /issues (table list) page"},{"lineNumber":176,"author":{"gitId":"-"},"content":" if (issueUrlIndex \u003c 0) {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" // Apply filters to the issueUrl"},{"lineNumber":178,"author":{"gitId":"-"},"content":" issueUrl \u003d this.ISSUE_FILTER;"},{"lineNumber":179,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" // issueUrl will be from the second \u0027/\u0027"},{"lineNumber":181,"author":{"gitId":"-"},"content":" issueUrl \u003d routerUrl.substring(issueUrlIndex);"},{"lineNumber":182,"author":{"gitId":"-"},"content":" }"},{"lineNumber":183,"author":{"gitId":"-"},"content":" // Open the url in user\u0027s preferred browser"},{"lineNumber":184,"author":{"gitId":"-"},"content":" window.open(\u0027https://github.com/\u0027.concat(this.githubService.getRepoURL()).concat(issueUrl));"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" openIssueTracker() {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" window.open(ISSUE_TRACKER_URL);"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" reload() {"},{"lineNumber":192,"author":{"gitId":"-"},"content":" this.isReloadButtonDisabled \u003d true;"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"-"},"content":" this.githubEventService.reloadPage().subscribe("},{"lineNumber":195,"author":{"gitId":"-"},"content":" (success) \u003d\u003e success,"},{"lineNumber":196,"author":{"gitId":"-"},"content":" (error) \u003d\u003e {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" this.errorHandlingService.handleError(error, () \u003d\u003e this.githubEventService.reloadPage());"},{"lineNumber":198,"author":{"gitId":"-"},"content":" }"},{"lineNumber":199,"author":{"gitId":"-"},"content":" );"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":" this.labelService.fetchLabels().subscribe("},{"lineNumber":202,"author":{"gitId":"-"},"content":" (success) \u003d\u003e success,"},{"lineNumber":203,"author":{"gitId":"-"},"content":" (error) \u003d\u003e {"},{"lineNumber":204,"author":{"gitId":"-"},"content":" this.errorHandlingService.handleError(error, () \u003d\u003e this.labelService.fetchLabels());"},{"lineNumber":205,"author":{"gitId":"-"},"content":" }"},{"lineNumber":206,"author":{"gitId":"-"},"content":" );"},{"lineNumber":207,"author":{"gitId":"-"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" // Prevent user from spamming the reload button"},{"lineNumber":209,"author":{"gitId":"-"},"content":" setTimeout(() \u003d\u003e {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" this.isReloadButtonDisabled \u003d false;"},{"lineNumber":211,"author":{"gitId":"-"},"content":" }, 3000);"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" logOut() {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" this.auth.logOut();"},{"lineNumber":216,"author":{"gitId":"-"},"content":" }"},{"lineNumber":217,"author":{"gitId":"-"},"content":""},{"lineNumber":218,"author":{"gitId":"-"},"content":" openLogOutDialog() {"},{"lineNumber":219,"author":{"gitId":"-"},"content":" const dialogRef \u003d this.dialogService.openUserConfirmationModal("},{"lineNumber":220,"author":{"gitId":"-"},"content":" this.logOutDialogMessages,"},{"lineNumber":221,"author":{"gitId":"-"},"content":" this.yesButtonDialogMessage,"},{"lineNumber":222,"author":{"gitId":"-"},"content":" this.noButtonDialogMessage"},{"lineNumber":223,"author":{"gitId":"-"},"content":" );"},{"lineNumber":224,"author":{"gitId":"-"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":" dialogRef.afterClosed().subscribe((res) \u003d\u003e {"},{"lineNumber":226,"author":{"gitId":"-"},"content":" if (res) {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" this.logger.info(`HeaderComponent: Logging out from ${this.userService.currentUser.loginId}`);"},{"lineNumber":228,"author":{"gitId":"-"},"content":" this.logOut();"},{"lineNumber":229,"author":{"gitId":"-"},"content":" }"},{"lineNumber":230,"author":{"gitId":"-"},"content":" });"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" exportLogFile() {"},{"lineNumber":234,"author":{"gitId":"-"},"content":" this.logger.exportLogFile();"},{"lineNumber":235,"author":{"gitId":"-"},"content":" }"},{"lineNumber":236,"author":{"gitId":"-"},"content":""},{"lineNumber":237,"author":{"gitId":"-"},"content":" initializeRepoNameInTitle() {"},{"lineNumber":238,"author":{"gitId":"NereusWB922"},"content":" if (Repo.isInvalidRepoName(this.viewService.currentRepo)) {"},{"lineNumber":239,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":240,"author":{"gitId":"-"},"content":" }"},{"lineNumber":241,"author":{"gitId":"NereusWB922"},"content":" const currentRepoString \u003d this.viewService.currentRepo.toString();"},{"lineNumber":242,"author":{"gitId":"-"},"content":" this.logger.info(`HeaderComponent: initializing current repository name as ${currentRepoString}`);"},{"lineNumber":243,"author":{"gitId":"-"},"content":" this.currentRepo \u003d currentRepoString;"},{"lineNumber":244,"author":{"gitId":"-"},"content":" }"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":247,"author":{"gitId":"-"},"content":" * Change repository viewed on Issue Dashboard, if a valid repository is provided."},{"lineNumber":248,"author":{"gitId":"-"},"content":" * Re-open dialog to prompt for another repository if an invalid one is provided."},{"lineNumber":249,"author":{"gitId":"-"},"content":" */"},{"lineNumber":250,"author":{"gitId":"Arif-Khalid"},"content":" changeRepositoryIfValid(repo: Repo, newRepoString: string, keepFilters: boolean) {"},{"lineNumber":251,"author":{"gitId":"-"},"content":" if (newRepoString \u003d\u003d\u003d this.currentRepo) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":253,"author":{"gitId":"-"},"content":" }"},{"lineNumber":254,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":255,"author":{"gitId":"NereusWB922"},"content":" this.viewService"},{"lineNumber":256,"author":{"gitId":"-"},"content":" .changeRepositoryIfValid(repo)"},{"lineNumber":257,"author":{"gitId":"-"},"content":" .then(() \u003d\u003e {"},{"lineNumber":258,"author":{"gitId":"NereusWB922"},"content":" this.auth.setTitleWithViewDetail();"},{"lineNumber":259,"author":{"gitId":"-"},"content":" this.currentRepo \u003d newRepoString;"},{"lineNumber":260,"author":{"gitId":"NereusWB922"},"content":" if (!keepFilters) {"},{"lineNumber":261,"author":{"gitId":"NereusWB922"},"content":" this.groupingContextService.reset();"},{"lineNumber":262,"author":{"gitId":"Arif-Khalid"},"content":" this.filtersService.clearFilters();"},{"lineNumber":263,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":264,"author":{"gitId":"-"},"content":" })"},{"lineNumber":265,"author":{"gitId":"-"},"content":" .catch((error) \u003d\u003e {"},{"lineNumber":266,"author":{"gitId":"-"},"content":" this.openChangeRepoDialog();"},{"lineNumber":267,"author":{"gitId":"-"},"content":" this.errorHandlingService.handleError(error);"},{"lineNumber":268,"author":{"gitId":"-"},"content":" });"},{"lineNumber":269,"author":{"gitId":"-"},"content":" }"},{"lineNumber":270,"author":{"gitId":"-"},"content":""},{"lineNumber":271,"author":{"gitId":"NereusWB922"},"content":" applyRepoDropdown(repoString: string) {"},{"lineNumber":272,"author":{"gitId":"NereusWB922"},"content":" const newRepo \u003d Repo.of(repoString);"},{"lineNumber":273,"author":{"gitId":"NereusWB922"},"content":" this.changeRepositoryIfValid(newRepo, newRepo.toString(), this.keepFilters);"},{"lineNumber":274,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":275,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":276,"author":{"gitId":"NereusWB922"},"content":" toggleKeepFilters(event: MouseEvent) {"},{"lineNumber":277,"author":{"gitId":"NereusWB922"},"content":" event.stopPropagation();"},{"lineNumber":278,"author":{"gitId":"NereusWB922"},"content":" this.keepFilters \u003d !this.keepFilters;"},{"lineNumber":279,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":280,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":281,"author":{"gitId":"-"},"content":" openChangeRepoDialog() {"},{"lineNumber":282,"author":{"gitId":"-"},"content":" const dialogRef \u003d this.dialogService.openChangeRepoDialog(this.currentRepo);"},{"lineNumber":283,"author":{"gitId":"-"},"content":""},{"lineNumber":284,"author":{"gitId":"Arif-Khalid"},"content":" dialogRef.afterClosed().subscribe((res: RepoChangeResponse | null) \u003d\u003e {"},{"lineNumber":285,"author":{"gitId":"-"},"content":" if (!res) {"},{"lineNumber":286,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":287,"author":{"gitId":"-"},"content":" }"},{"lineNumber":288,"author":{"gitId":"Arif-Khalid"},"content":" const newRepo \u003d Repo.of(res.repo);"},{"lineNumber":289,"author":{"gitId":"-"},"content":""},{"lineNumber":290,"author":{"gitId":"NereusWB922"},"content":" if (this.viewService.isRepoSet()) {"},{"lineNumber":291,"author":{"gitId":"Arif-Khalid"},"content":" this.changeRepositoryIfValid(newRepo, newRepo.toString(), res.keepFilters);"},{"lineNumber":292,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":293,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":294,"author":{"gitId":"-"},"content":" * From session-selection.component.ts"},{"lineNumber":295,"author":{"gitId":"-"},"content":" *"},{"lineNumber":296,"author":{"gitId":"-"},"content":" * Persist repo information in local browser storage"},{"lineNumber":297,"author":{"gitId":"-"},"content":" * To retrieve after authentication redirects back to WATcher"},{"lineNumber":298,"author":{"gitId":"-"},"content":" *"},{"lineNumber":299,"author":{"gitId":"-"},"content":" * Since localStorage::setItem with an undefined value can result in"},{"lineNumber":300,"author":{"gitId":"-"},"content":" * the subsequent value being stored as a string being \u0027undefined\u0027, check"},{"lineNumber":301,"author":{"gitId":"-"},"content":" * if undefined before storing it. Let\u0027s reset the items before setting them."},{"lineNumber":302,"author":{"gitId":"-"},"content":" */"},{"lineNumber":303,"author":{"gitId":"-"},"content":" window.localStorage.removeItem(STORAGE_KEYS.ORG);"},{"lineNumber":304,"author":{"gitId":"-"},"content":" window.localStorage.removeItem(STORAGE_KEYS.DATA_REPO);"},{"lineNumber":305,"author":{"gitId":"-"},"content":""},{"lineNumber":306,"author":{"gitId":"-"},"content":" if (newRepo) {"},{"lineNumber":307,"author":{"gitId":"-"},"content":" window.localStorage.setItem(STORAGE_KEYS.ORG, newRepo.owner);"},{"lineNumber":308,"author":{"gitId":"-"},"content":" window.localStorage.setItem(STORAGE_KEYS.DATA_REPO, newRepo.name);"},{"lineNumber":309,"author":{"gitId":"-"},"content":""},{"lineNumber":310,"author":{"gitId":"-"},"content":" this.repoUrlCacheService.cache(newRepo.toString());"},{"lineNumber":311,"author":{"gitId":"-"},"content":" }"},{"lineNumber":312,"author":{"gitId":"-"},"content":" this.auth.setRepo().subscribe();"},{"lineNumber":313,"author":{"gitId":"-"},"content":" }"},{"lineNumber":314,"author":{"gitId":"-"},"content":" });"},{"lineNumber":315,"author":{"gitId":"-"},"content":" }"},{"lineNumber":316,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":12,"Arif-Khalid":9,"NereusWB922":54,"-":241}},{"path":"src/app/shared/repo-change-form/repo-change-form.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":".change-repo-form-title {"},{"lineNumber":2,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"}"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":".mat-dialog-content {"},{"lineNumber":6,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"}"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":".mat-form-field {"},{"lineNumber":10,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"}"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":".mat-dialog-actions {"},{"lineNumber":14,"author":{"gitId":"-"},"content":" justify-content: flex-end;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"}"},{"lineNumber":16,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":17,"author":{"gitId":"Arif-Khalid"},"content":".change-repo-form-header {"},{"lineNumber":18,"author":{"gitId":"Arif-Khalid"},"content":" display: flex;"},{"lineNumber":19,"author":{"gitId":"Arif-Khalid"},"content":" justify-content: space-between;"},{"lineNumber":20,"author":{"gitId":"Arif-Khalid"},"content":"}"}],"authorContributionMap":{"Arif-Khalid":5,"-":15}},{"path":"src/app/shared/repo-change-form/repo-change-form.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"Arif-Khalid"},"content":"\u003cdiv class\u003d\"change-repo-form-header\"\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" \u003ch1 mat-dialog-title class\u003d\"change-repo-form-title\"\u003e{{ data.repoName ? \u0027Change repository\u0027 : \u0027Select repository\u0027 }}\u003c/h1\u003e"},{"lineNumber":3,"author":{"gitId":"Arif-Khalid"},"content":" \u003cmat-checkbox *ngIf\u003d\"data.repoName\" [(ngModel)]\u003d\"this.keepFilters\"\u003eKeep Filters\u003c/mat-checkbox\u003e"},{"lineNumber":4,"author":{"gitId":"Arif-Khalid"},"content":"\u003c/div\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":"\u003cdiv mat-dialog-content\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003cform (ngSubmit)\u003d\"onYesClick()\"\u003e"},{"lineNumber":7,"author":{"gitId":"-"},"content":" \u003cmat-form-field appearance\u003d\"fill\"\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003cmat-label\u003eRepository Location (Github Link or Org/Repo)\u003c/mat-label\u003e"},{"lineNumber":9,"author":{"gitId":"-"},"content":" \u003cinput matInput [(ngModel)]\u003d\"this.repoName\" [formControl]\u003d\"repoChangeForm\" [matAutocomplete]\u003d\"auto\" /\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003cmat-autocomplete #auto\u003d\"matAutocomplete\"\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003cmat-option *ngFor\u003d\"let suggestion of filteredSuggestions | async\" [value]\u003d\"suggestion\"\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" {{ suggestion }}"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003c/mat-option\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":" \u003c/mat-autocomplete\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":16,"author":{"gitId":"-"},"content":" \u003c/form\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":18,"author":{"gitId":"-"},"content":"\u003cdiv mat-dialog-actions\u003e"},{"lineNumber":19,"author":{"gitId":"-"},"content":" \u003cbutton mat-button (click)\u003d\"onNoClick()\" color\u003d\"warn\"\u003eCancel\u003c/button\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003cbutton mat-button (click)\u003d\"onYesClick()\" color\u003d\"primary\"\u003e{{ data.repoName ? \u0027Change Repo\u0027 : \u0027Select Repo\u0027 }}\u003c/button\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"Arif-Khalid":3,"-":18}},{"path":"src/app/shared/repo-change-form/repo-change-form.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component, Inject, OnInit } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { FormControl } from \u0027@angular/forms\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { MatDialogRef, MAT_DIALOG_DATA } from \u0027@angular/material/dialog\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":5,"author":{"gitId":"Arif-Khalid"},"content":"import { RepoChangeResponse } from \u0027../../core/models/repo-change-response.model\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { RepoUrlCacheService } from \u0027../../core/services/repo-url-cache.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":9,"author":{"gitId":"-"},"content":" selector: \u0027app-repo-change-form\u0027,"},{"lineNumber":10,"author":{"gitId":"-"},"content":" templateUrl: \u0027./repo-change-form.component.html\u0027,"},{"lineNumber":11,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./repo-change-form.component.css\u0027]"},{"lineNumber":12,"author":{"gitId":"-"},"content":"})"},{"lineNumber":13,"author":{"gitId":"-"},"content":"export class RepoChangeFormComponent implements OnInit {"},{"lineNumber":14,"author":{"gitId":"Arif-Khalid"},"content":" public repoName: string;"},{"lineNumber":15,"author":{"gitId":"Arif-Khalid"},"content":" public keepFilters: boolean;"},{"lineNumber":16,"author":{"gitId":"-"},"content":" filteredSuggestions: Observable\u003cstring[]\u003e;"},{"lineNumber":17,"author":{"gitId":"-"},"content":" repoChangeForm \u003d new FormControl();"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":" constructor("},{"lineNumber":20,"author":{"gitId":"-"},"content":" public dialogRef: MatDialogRef\u003cRepoChangeFormComponent\u003e,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" private repoUrlCacheService: RepoUrlCacheService,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Inject(MAT_DIALOG_DATA) public data"},{"lineNumber":23,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" this.repoName \u003d data.repoName;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" ngOnInit() {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" this.initRepoChangeForm();"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" private initRepoChangeForm() {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" this.filteredSuggestions \u003d this.repoUrlCacheService.getFilteredSuggestions(this.repoChangeForm);"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" onYesClick(): void {"},{"lineNumber":36,"author":{"gitId":"Arif-Khalid"},"content":" const response: RepoChangeResponse \u003d {"},{"lineNumber":37,"author":{"gitId":"Arif-Khalid"},"content":" repo: this.repoName,"},{"lineNumber":38,"author":{"gitId":"Arif-Khalid"},"content":" keepFilters: this.keepFilters"},{"lineNumber":39,"author":{"gitId":"Arif-Khalid"},"content":" };"},{"lineNumber":40,"author":{"gitId":"Arif-Khalid"},"content":" this.dialogRef.close(response);"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" onNoClick(): void {"},{"lineNumber":44,"author":{"gitId":"Arif-Khalid"},"content":" this.dialogRef.close(null);"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"Arif-Khalid":9,"-":37}},{"path":"src/test.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"// This file is required by karma.conf.js and loads recursively all the .spec and framework files"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"// tslint:disable:ordered-imports"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"// Ordered-imports rule is disabled here because the import statement for \u0027zone-testing\u0027 must be"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"// at the top to prevent test setup breakage in \u0027npm run test\u0027."},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"import \u0027zone.js/dist/zone-testing\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { getTestBed } from \u0027@angular/core/testing\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from \u0027@angular/platform-browser-dynamic/testing\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"declare const require: any;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"// First, initialize the Angular testing environment."},{"lineNumber":13,"author":{"gitId":"-"},"content":"getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());"},{"lineNumber":14,"author":{"gitId":"-"},"content":"// Then we find all the tests."},{"lineNumber":15,"author":{"gitId":"-"},"content":"const context \u003d require.context(\u0027../tests\u0027, true, /\\.spec\\.ts$/);"},{"lineNumber":16,"author":{"gitId":"-"},"content":"// And load the modules."},{"lineNumber":17,"author":{"gitId":"-"},"content":"context.keys().map(context);"}],"authorContributionMap":{"NereusWB922":4,"-":13}},{"path":"tests/app/auth/login/login.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { ComponentFixture, TestBed, waitForAsync } from \u0027@angular/core/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { LoginComponent } from \u0027../../../../src/app/auth/login/login.component\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { AuthService, AuthState } from \u0027../../../../src/app/core/services/auth.service\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { ErrorHandlingService } from \u0027../../../../src/app/core/services/error-handling.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027../../../../src/app/core/services/logging.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"describe(\u0027LoginComponent\u0027, () \u003d\u003e {"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" let authServiceSpy: jasmine.SpyObj\u003cAuthService\u003e;"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" let errorHandlingServiceSpy: jasmine.SpyObj\u003cErrorHandlingService\u003e;"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" let loggingServiceSpy: jasmine.SpyObj\u003cLoggingService\u003e;"},{"lineNumber":11,"author":{"gitId":"-"},"content":" let component: LoginComponent;"},{"lineNumber":12,"author":{"gitId":"-"},"content":" let fixture: ComponentFixture\u003cLoginComponent\u003e;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":" beforeEach("},{"lineNumber":15,"author":{"gitId":"-"},"content":" waitForAsync(() \u003d\u003e {"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" authServiceSpy \u003d jasmine.createSpyObj\u003cAuthService\u003e(\u0027AuthService\u0027, [\u0027startOAuthProcess\u0027, \u0027changeAuthState\u0027]);"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" loggingServiceSpy \u003d jasmine.createSpyObj\u003cLoggingService\u003e(\u0027LoggingService\u0027, [\u0027info\u0027]);"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" errorHandlingServiceSpy \u003d jasmine.createSpyObj\u003cErrorHandlingService\u003e(\u0027ErrorHandlingService\u0027, [\u0027handleError\u0027]);"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" TestBed.configureTestingModule({"},{"lineNumber":21,"author":{"gitId":"-"},"content":" providers: ["},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" { provide: AuthService, useValue: authServiceSpy },"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" { provide: LoggingService, useValue: loggingServiceSpy },"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" { provide: ErrorHandlingService, useValue: errorHandlingServiceSpy }"},{"lineNumber":25,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":26,"author":{"gitId":"-"},"content":" declarations: [LoginComponent]"},{"lineNumber":27,"author":{"gitId":"-"},"content":" }).compileComponents();"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" fixture \u003d TestBed.createComponent(LoginComponent);"},{"lineNumber":30,"author":{"gitId":"-"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":32,"author":{"gitId":"-"},"content":" })"},{"lineNumber":33,"author":{"gitId":"-"},"content":" );"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" expect(component).toBeTruthy();"},{"lineNumber":37,"author":{"gitId":"-"},"content":" });"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" it(\u0027startPublicOnlyLoginProcess should call startLoginProcess with false\u0027, () \u003d\u003e {"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" spyOn(component, \u0027startLoginProcess\u0027);"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":" component.startPublicOnlyLoginProcess();"},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" expect(component.startLoginProcess).toHaveBeenCalledWith(false);"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" it(\u0027startIncludePrivateLoginProcess should call startLoginProcess with true\u0027, () \u003d\u003e {"},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" spyOn(component, \u0027startLoginProcess\u0027);"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" component.startIncludePrivateLoginProcess();"},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" expect(component.startLoginProcess).toHaveBeenCalledWith(true);"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should call authService.startOAuthProcess on startLoginProcess\u0027, () \u003d\u003e {"},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" const hasPrivateConsent \u003d false;"},{"lineNumber":57,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" component.startLoginProcess(hasPrivateConsent);"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":" expect(authServiceSpy.startOAuthProcess).toHaveBeenCalledWith(hasPrivateConsent);"},{"lineNumber":61,"author":{"gitId":"NereusWB922"},"content":" expect(loggingServiceSpy.info).toHaveBeenCalledWith(\u0027LoginComponent: Beginning login process\u0027);"},{"lineNumber":62,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should call error handling methods when error is thrown\u0027, () \u003d\u003e {"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":" const hasPrivateConsent \u003d false;"},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" const errorMessage \u003d \u0027Error!\u0027;"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":" const error: Error \u003d new Error(errorMessage);"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":" authServiceSpy.startOAuthProcess.and.throwError(error);"},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":71,"author":{"gitId":"NereusWB922"},"content":" component.startLoginProcess(hasPrivateConsent);"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" expect(authServiceSpy.changeAuthState).toHaveBeenCalledWith(AuthState.NotAuthenticated);"},{"lineNumber":74,"author":{"gitId":"NereusWB922"},"content":" expect(errorHandlingServiceSpy.handleError).toHaveBeenCalledWith(error);"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":" expect(loggingServiceSpy.info.calls.allArgs()).toEqual(["},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" [\u0027LoginComponent: Beginning login process\u0027],"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" [`LoginComponent: Login process failed with an error: ${error}`]"},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":" ]);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" });"},{"lineNumber":80,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"NereusWB922":49,"-":31}},{"path":"tests/app/core/models/session-model.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { of } from \u0027rxjs\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":3,"author":{"gitId":"-"},"content":" assertSessionDataIntegrity,"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" NO_VALID_OPEN_VIEWS,"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" OPENED_VIEW_REPO_UNDEFINED,"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" SESSION_DATA_MISSING_FIELDS,"},{"lineNumber":7,"author":{"gitId":"-"},"content":" SESSION_DATA_UNAVAILABLE"},{"lineNumber":8,"author":{"gitId":"-"},"content":"} from \u0027../../../../src/app/core/models/session.model\u0027;"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"import { View } from \u0027../../../../src/app/core/models/view.model\u0027;"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"import { VALID_SESSION_DATA, WATCHER_REPO } from \u0027../../../constants/session.constants\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"describe(\u0027Session Model\u0027, () \u003d\u003e {"},{"lineNumber":13,"author":{"gitId":"-"},"content":" describe(\u0027assertSessionDataIntegrity()\u0027, () \u003d\u003e {"},{"lineNumber":14,"author":{"gitId":"-"},"content":" it(\u0027should throw error on unavailable session\u0027, () \u003d\u003e {"},{"lineNumber":15,"author":{"gitId":"-"},"content":" of(undefined)"},{"lineNumber":16,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":17,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":18,"author":{"gitId":"-"},"content":" next: () \u003d\u003e fail(),"},{"lineNumber":19,"author":{"gitId":"-"},"content":" error: (err) \u003d\u003e expect(err).toEqual(new Error(SESSION_DATA_UNAVAILABLE))"},{"lineNumber":20,"author":{"gitId":"-"},"content":" });"},{"lineNumber":21,"author":{"gitId":"-"},"content":" });"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should throw error on session data with invalid session\u0027, () \u003d\u003e {"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" of({ sessionRepo: null })"},{"lineNumber":25,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":26,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":27,"author":{"gitId":"-"},"content":" next: () \u003d\u003e fail(),"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e expect(err).toEqual(new Error(SESSION_DATA_MISSING_FIELDS))"},{"lineNumber":29,"author":{"gitId":"-"},"content":" });"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" of({ sessionRepo: [] })"},{"lineNumber":31,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":32,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":33,"author":{"gitId":"-"},"content":" next: () \u003d\u003e fail(),"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e expect(err).toEqual(new Error(SESSION_DATA_MISSING_FIELDS))"},{"lineNumber":35,"author":{"gitId":"-"},"content":" });"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" of({ sessionRepo: \u0027repo\u0027 })"},{"lineNumber":37,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":38,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":39,"author":{"gitId":"-"},"content":" next: () \u003d\u003e fail(),"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e expect(err).toEqual(new Error(SESSION_DATA_MISSING_FIELDS))"},{"lineNumber":41,"author":{"gitId":"-"},"content":" });"},{"lineNumber":42,"author":{"gitId":"-"},"content":" });"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should throw error on session with invalid views\u0027, () \u003d\u003e {"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" of({ sessionRepo: [{ view: \u0027invalidView\u0027 as View, repos: [WATCHER_REPO] }] })"},{"lineNumber":46,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":47,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":48,"author":{"gitId":"-"},"content":" next: () \u003d\u003e fail(),"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e expect(err).toEqual(new Error(NO_VALID_OPEN_VIEWS))"},{"lineNumber":50,"author":{"gitId":"-"},"content":" });"},{"lineNumber":51,"author":{"gitId":"-"},"content":" });"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should throw error on session data with invalid repo\u0027, () \u003d\u003e {"},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":" of({ sessionRepo: [{ view: View.issuesViewer, repo: undefined }] })"},{"lineNumber":55,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":56,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":57,"author":{"gitId":"-"},"content":" next: () \u003d\u003e fail(),"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e expect(err).toEqual(new Error(OPENED_VIEW_REPO_UNDEFINED))"},{"lineNumber":59,"author":{"gitId":"-"},"content":" });"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":" of({ sessionRepo: [{ view: View.issuesViewer, repo: null }] })"},{"lineNumber":61,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":62,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":63,"author":{"gitId":"-"},"content":" next: () \u003d\u003e fail(),"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e expect(err).toEqual(new Error(OPENED_VIEW_REPO_UNDEFINED))"},{"lineNumber":65,"author":{"gitId":"-"},"content":" });"},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" of({ sessionRepo: [{ view: View.issuesViewer, repo: \u0027\u0027 }] })"},{"lineNumber":67,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":68,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":69,"author":{"gitId":"-"},"content":" next: () \u003d\u003e fail(),"},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e expect(err).toEqual(new Error(OPENED_VIEW_REPO_UNDEFINED))"},{"lineNumber":71,"author":{"gitId":"-"},"content":" });"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" of({ sessionRepo: [{ view: View.issuesViewer, repo: [] }] })"},{"lineNumber":73,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":74,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":" next: () \u003d\u003e fail(),"},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e expect(err).toEqual(new Error(OPENED_VIEW_REPO_UNDEFINED))"},{"lineNumber":77,"author":{"gitId":"-"},"content":" });"},{"lineNumber":78,"author":{"gitId":"-"},"content":" });"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should pass for valid session data\u0027, () \u003d\u003e {"},{"lineNumber":81,"author":{"gitId":"NereusWB922"},"content":" of(VALID_SESSION_DATA)"},{"lineNumber":82,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":83,"author":{"gitId":"NereusWB922"},"content":" .subscribe((el) \u003d\u003e expect(el).toEqual(VALID_SESSION_DATA));"},{"lineNumber":84,"author":{"gitId":"-"},"content":" });"},{"lineNumber":85,"author":{"gitId":"-"},"content":" });"},{"lineNumber":86,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"NereusWB922":28,"-":58}},{"path":"tests/app/shared/filter-bar/label-filter-bar/label-filter-bar.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { NO_ERRORS_SCHEMA } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { ComponentFixture, fakeAsync, TestBed, tick } from \u0027@angular/core/testing\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { MatSelectionList } from \u0027@angular/material/list\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { MatMenuModule } from \u0027@angular/material/menu\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import { BehaviorSubject, of } from \u0027rxjs\u0027;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"import { SimpleLabel } from \u0027../../../../../src/app/core/models/label.model\u0027;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"import { FiltersService } from \u0027../../../../../src/app/core/services/filters.service\u0027;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"import { LabelService } from \u0027../../../../../src/app/core/services/label.service\u0027;"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"import { LoggingService } from \u0027../../../../../src/app/core/services/logging.service\u0027;"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"import { LabelFilterBarComponent } from \u0027../../../../../src/app/shared/filter-bar/label-filter-bar/label-filter-bar.component\u0027;"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":"import { LABEL_NAME_SEVERITY_HIGH, LABEL_NAME_SEVERITY_LOW, SEVERITY_SIMPLE_LABELS } from \u0027../../../../constants/label.constants\u0027;"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":"describe(\u0027LabelFilterBarComponent\u0027, () \u003d\u003e {"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" let component: LabelFilterBarComponent;"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" let fixture: ComponentFixture\u003cLabelFilterBarComponent\u003e;"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" let labelServiceSpy: jasmine.SpyObj\u003cLabelService\u003e;"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" let loggingServiceSpy: jasmine.SpyObj\u003cLoggingService\u003e;"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" let filtersServiceSpy: jasmine.SpyObj\u003cFiltersService\u003e;"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" let labelsSubject: BehaviorSubject\u003cSimpleLabel[]\u003e;"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" beforeEach(async () \u003d\u003e {"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" labelServiceSpy \u003d jasmine.createSpyObj(\u0027LabelService\u0027, [\u0027connect\u0027, \u0027startPollLabels\u0027, \u0027fetchLabels\u0027]);"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" loggingServiceSpy \u003d jasmine.createSpyObj(\u0027LoggingService\u0027, [\u0027info\u0027, \u0027debug\u0027]);"},{"lineNumber":24,"author":{"gitId":"Arif-Khalid"},"content":" filtersServiceSpy \u003d jasmine.createSpyObj(\u0027FiltersService\u0027, [\u0027updateFilters\u0027, \u0027sanitizeLabels\u0027]);"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" TestBed.configureTestingModule({"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" providers: ["},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" { provide: LabelService, useValue: labelServiceSpy },"},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" { provide: LoggingService, useValue: loggingServiceSpy },"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" { provide: FiltersService, useValue: filtersServiceSpy }"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" ],"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" imports: [MatMenuModule],"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" declarations: [LabelFilterBarComponent],"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" schemas: [NO_ERRORS_SCHEMA]"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" }).compileComponents();"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":" fixture \u003d TestBed.createComponent(LabelFilterBarComponent);"},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" fixture.detectChanges();"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":" expect(component).toBeTruthy();"},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027ngAfterViewInit\u0027, () \u003d\u003e {"},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" // Setup labels observable"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":" labelsSubject \u003d new BehaviorSubject\u003cSimpleLabel[]\u003e([]);"},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" labelServiceSpy.fetchLabels.and.returnValue(of([]));"},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":" labelServiceSpy.connect.and.returnValue(labelsSubject.asObservable());"},{"lineNumber":52,"author":{"gitId":"Arif-Khalid"},"content":" filtersServiceSpy.sanitizeLabels.and.callThrough();"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":55,"author":{"gitId":"Arif-Khalid"},"content":" // it(\u0027should update allLabels with latest emmitted value after ngAfterViewInit\u0027, fakeAsync(() \u003d\u003e {"},{"lineNumber":56,"author":{"gitId":"Arif-Khalid"},"content":" // component.ngAfterViewInit();"},{"lineNumber":57,"author":{"gitId":"Arif-Khalid"},"content":" // tick();"},{"lineNumber":58,"author":{"gitId":"Arif-Khalid"},"content":" // labelsSubject.next(SEVERITY_SIMPLE_LABELS);"},{"lineNumber":59,"author":{"gitId":"Arif-Khalid"},"content":" // expect(component.allLabels).toEqual(SEVERITY_SIMPLE_LABELS);"},{"lineNumber":60,"author":{"gitId":"Arif-Khalid"},"content":" // }));"},{"lineNumber":61,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":62,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027hide(label)\u0027, () \u003d\u003e {"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should add label to hidden labels set and update filter\u0027, () \u003d\u003e {"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":" const label \u003d LABEL_NAME_SEVERITY_HIGH;"},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" expect(component.hiddenLabelNames).not.toContain(label);"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":" component.hide(label);"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":" expect(component.hiddenLabelNames).toContain(label);"},{"lineNumber":71,"author":{"gitId":"NereusWB922"},"content":" expect(filtersServiceSpy.updateFilters).toHaveBeenCalledWith({ hiddenLabels: component.hiddenLabelNames });"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":74,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027show(label)\u0027, () \u003d\u003e {"},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should remove label from hidden labels set and update filter\u0027, () \u003d\u003e {"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" const label \u003d LABEL_NAME_SEVERITY_HIGH;"},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":" component.hide(label);"},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":" expect(component.hiddenLabelNames).toContain(label);"},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":81,"author":{"gitId":"NereusWB922"},"content":" component.show(label);"},{"lineNumber":82,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":83,"author":{"gitId":"NereusWB922"},"content":" expect(component.hiddenLabelNames).not.toContain(label);"},{"lineNumber":84,"author":{"gitId":"NereusWB922"},"content":" expect(filtersServiceSpy.updateFilters).toHaveBeenCalledWith({ hiddenLabels: component.hiddenLabelNames });"},{"lineNumber":85,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":86,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":87,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":88,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027hasLabels\u0027, () \u003d\u003e {"},{"lineNumber":89,"author":{"gitId":"NereusWB922"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":90,"author":{"gitId":"NereusWB922"},"content":" component.allLabels \u003d SEVERITY_SIMPLE_LABELS;"},{"lineNumber":91,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":92,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":93,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should return true if any label match the filter\u0027, () \u003d\u003e {"},{"lineNumber":94,"author":{"gitId":"NereusWB922"},"content":" const filter \u003d \u0027low\u0027;"},{"lineNumber":95,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":96,"author":{"gitId":"NereusWB922"},"content":" const result \u003d component.hasLabels(filter);"},{"lineNumber":97,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":98,"author":{"gitId":"NereusWB922"},"content":" expect(result).toBeTrue();"},{"lineNumber":99,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":100,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":101,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should return false if no label match the filter\u0027, () \u003d\u003e {"},{"lineNumber":102,"author":{"gitId":"NereusWB922"},"content":" const filter \u003d \u0027priority\u0027;"},{"lineNumber":103,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":104,"author":{"gitId":"NereusWB922"},"content":" const result \u003d component.hasLabels(filter);"},{"lineNumber":105,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":106,"author":{"gitId":"NereusWB922"},"content":" expect(result).toBeFalse();"},{"lineNumber":107,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":108,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":109,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should return false if no label exists\u0027, () \u003d\u003e {"},{"lineNumber":110,"author":{"gitId":"NereusWB922"},"content":" const filter \u003d \u0027low\u0027;"},{"lineNumber":111,"author":{"gitId":"NereusWB922"},"content":" component.allLabels \u003d [];"},{"lineNumber":112,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":113,"author":{"gitId":"NereusWB922"},"content":" const result \u003d component.hasLabels(filter);"},{"lineNumber":114,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":115,"author":{"gitId":"NereusWB922"},"content":" expect(result).toBeFalse();"},{"lineNumber":116,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":117,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":118,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":119,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027updateSelection\u0027, () \u003d\u003e {"},{"lineNumber":120,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should update filters service with selected labels\u0027, () \u003d\u003e {"},{"lineNumber":121,"author":{"gitId":"NereusWB922"},"content":" const selectedLabels \u003d [LABEL_NAME_SEVERITY_HIGH, LABEL_NAME_SEVERITY_LOW];"},{"lineNumber":122,"author":{"gitId":"nknguyenhc"},"content":" component.selectedLabelNames \u003d new Set\u003cstring\u003e(selectedLabels);"},{"lineNumber":123,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":124,"author":{"gitId":"nknguyenhc"},"content":" component.updateSelection();"},{"lineNumber":125,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":126,"author":{"gitId":"nknguyenhc"},"content":" expect(filtersServiceSpy.updateFilters).toHaveBeenCalledWith({ labels: selectedLabels, deselectedLabels: new Set\u003cstring\u003e() });"},{"lineNumber":127,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":128,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":129,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":130,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027removeAllSelection\u0027, () \u003d\u003e {"},{"lineNumber":131,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should deselect all labels and update the filter\u0027, () \u003d\u003e {"},{"lineNumber":132,"author":{"gitId":"NereusWB922"},"content":" component.removeAllSelection();"},{"lineNumber":133,"author":{"gitId":"nknguyenhc"},"content":" expect(component.selectedLabelNames).toEqual(new Set\u003cstring\u003e());"},{"lineNumber":134,"author":{"gitId":"nknguyenhc"},"content":" expect(component.deselectedLabelNames).toEqual(new Set\u003cstring\u003e());"},{"lineNumber":135,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":136,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":137,"author":{"gitId":"NereusWB922"},"content":"});"}],"authorContributionMap":{"nknguyenhc":5,"NereusWB922":124,"Arif-Khalid":8}},{"path":"tests/app/shared/issue-tables/issue-paginator.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { MatPaginator } from \u0027@angular/material/paginator\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Issue } from \u0027../../../../src/app/core/models/issue.model\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { paginateData } from \u0027../../../../src/app/shared/issue-tables/issue-paginator\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":5,"author":{"gitId":"-"},"content":" ISSUE_WITH_ASSIGNEES,"},{"lineNumber":6,"author":{"gitId":"-"},"content":" ISSUE_WITH_EMPTY_DESCRIPTION,"},{"lineNumber":7,"author":{"gitId":"-"},"content":" ISSUE_WITH_EMPTY_DESCRIPTION_HIGH_SEVERITY,"},{"lineNumber":8,"author":{"gitId":"-"},"content":" ISSUE_WITH_EMPTY_DESCRIPTION_LOW_SEVERITY"},{"lineNumber":9,"author":{"gitId":"-"},"content":"} from \u0027../../../constants/githubissue.constants\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"describe(\u0027issue-paginator\u0027, () \u003d\u003e {"},{"lineNumber":12,"author":{"gitId":"-"},"content":" describe(\u0027paginateData()\u0027, () \u003d\u003e {"},{"lineNumber":13,"author":{"gitId":"-"},"content":" let dataSet_7: Issue[];"},{"lineNumber":14,"author":{"gitId":"-"},"content":" let paginator: MatPaginator;"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" const mediumSeverityIssueWithResponse: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_EMPTY_DESCRIPTION);"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" const mediumSeverityIssueWithAssigneee: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_ASSIGNEES);"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" const lowSeverityFeatureFlawIssue: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_EMPTY_DESCRIPTION_LOW_SEVERITY);"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" const highSeverityDocumentationBugIssue: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_EMPTY_DESCRIPTION_HIGH_SEVERITY);"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":21,"author":{"gitId":"-"},"content":" dataSet_7 \u003d ["},{"lineNumber":22,"author":{"gitId":"-"},"content":" mediumSeverityIssueWithResponse,"},{"lineNumber":23,"author":{"gitId":"-"},"content":" mediumSeverityIssueWithAssigneee,"},{"lineNumber":24,"author":{"gitId":"-"},"content":" lowSeverityFeatureFlawIssue,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" mediumSeverityIssueWithResponse,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" mediumSeverityIssueWithAssigneee,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" lowSeverityFeatureFlawIssue,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" highSeverityDocumentationBugIssue"},{"lineNumber":29,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":30,"author":{"gitId":"-"},"content":" paginator \u003d { pageSize: 3 } as MatPaginator;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" });"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" it(\u0027should set the length of paginator to the length of data\u0027, () \u003d\u003e {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" paginateData(paginator, dataSet_7);"},{"lineNumber":35,"author":{"gitId":"-"},"content":" expect(paginator.length).toEqual(7);"},{"lineNumber":36,"author":{"gitId":"-"},"content":" });"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" it(\u0027should return list of issues according to page index\u0027, () \u003d\u003e {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" paginator.pageIndex \u003d 0;"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" // Returns issues index 0 to 2"},{"lineNumber":42,"author":{"gitId":"-"},"content":" const returnedList \u003d paginateData(paginator, dataSet_7);"},{"lineNumber":43,"author":{"gitId":"-"},"content":" expect(returnedList).toEqual([mediumSeverityIssueWithResponse, mediumSeverityIssueWithAssigneee, lowSeverityFeatureFlawIssue]);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" });"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" it(\u0027should return list of issues in the previous page if there are no issues on the current page\u0027, () \u003d\u003e {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" paginator.pageIndex \u003d 3;"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" // Returns issues index 6 on page 2"},{"lineNumber":50,"author":{"gitId":"-"},"content":" const returnedList \u003d paginateData(paginator, dataSet_7);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" expect(returnedList).toEqual([highSeverityDocumentationBugIssue]);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" });"},{"lineNumber":53,"author":{"gitId":"-"},"content":" });"},{"lineNumber":54,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"NereusWB922":4,"-":50}},{"path":"tests/app/shared/issue-tables/issue-sorter.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { MatSort } from \u0027@angular/material/sort\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Issue } from \u0027../../../../src/app/core/models/issue.model\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { applySort } from \u0027../../../../src/app/shared/issue-tables/issue-sorter\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import {"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" ISSUE_UPDATED_EARLIER,"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" ISSUE_UPDATED_LATER,"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" ISSUE_WITH_ASSIGNEES,"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" ISSUE_WITH_EMPTY_DESCRIPTION"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"} from \u0027../../../constants/githubissue.constants\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"describe(\u0027issuer-sorter\u0027, () \u003d\u003e {"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027applySort()\u0027, () \u003d\u003e {"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" const dummyIssue: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_EMPTY_DESCRIPTION);"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" const otherDummyIssue: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_ASSIGNEES);"},{"lineNumber":15,"author":{"gitId":"-"},"content":" const issuesList: Issue[] \u003d [dummyIssue, otherDummyIssue];"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" const issueUpdatedEarlier: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_UPDATED_EARLIER);"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" const issueUpdatedLater: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_UPDATED_LATER);"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" const issuesWithDifferentUpdatedDate: Issue[] \u003d [issueUpdatedEarlier, issueUpdatedLater];"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" const matSort: MatSort \u003d new MatSort();"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should return the same data if sort.active is not set\u0027, () \u003d\u003e {"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" const sortedData \u003d applySort(matSort, issuesList);"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" expect(sortedData).toEqual(issuesList);"},{"lineNumber":26,"author":{"gitId":"-"},"content":" });"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" it(\u0027sorts issues based on their string fields correctly\u0027, () \u003d\u003e {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" matSort.active \u003d \u0027title\u0027;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" matSort.direction \u003d \u0027asc\u0027;"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" const sortedIssuesByTitleAsc \u003d applySort(matSort, issuesList);"},{"lineNumber":32,"author":{"gitId":"-"},"content":" assertOrder(sortedIssuesByTitleAsc, dummyIssue, otherDummyIssue);"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" matSort.direction \u003d \u0027desc\u0027;"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" const sortedIssuesByTitleDesc \u003d applySort(matSort, issuesList);"},{"lineNumber":36,"author":{"gitId":"-"},"content":" assertOrder(sortedIssuesByTitleDesc, otherDummyIssue, dummyIssue);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" });"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" it(\u0027sorts issues based on their id fields correctly\u0027, () \u003d\u003e {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" matSort.active \u003d \u0027id\u0027;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" matSort.direction \u003d \u0027asc\u0027;"},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":" const sortedIssuedByIdAsc \u003d applySort(matSort, issuesList);"},{"lineNumber":43,"author":{"gitId":"-"},"content":" assertOrder(sortedIssuedByIdAsc, otherDummyIssue, dummyIssue);"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" matSort.direction \u003d \u0027desc\u0027;"},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":" const sortedIssuedByIdDesc \u003d applySort(matSort, issuesList);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" assertOrder(sortedIssuedByIdDesc, dummyIssue, otherDummyIssue);"},{"lineNumber":48,"author":{"gitId":"-"},"content":" });"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" it(\u0027sorts issues based on their updated date fields correctly\u0027, () \u003d\u003e {"},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":" matSort.active \u003d \u0027date\u0027;"},{"lineNumber":52,"author":{"gitId":"-"},"content":" matSort.direction \u003d \u0027asc\u0027;"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":" const sortedIssuedByDateAsc \u003d applySort(matSort, issuesWithDifferentUpdatedDate);"},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" assertOrder(sortedIssuedByDateAsc, issueUpdatedEarlier, issueUpdatedLater);"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" matSort.direction \u003d \u0027desc\u0027;"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" const sortedIssuedByDateDesc \u003d applySort(matSort, issuesWithDifferentUpdatedDate);"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" assertOrder(sortedIssuedByDateDesc, issueUpdatedLater, issueUpdatedEarlier);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" });"},{"lineNumber":61,"author":{"gitId":"-"},"content":" });"},{"lineNumber":62,"author":{"gitId":"-"},"content":"});"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":65,"author":{"gitId":"-"},"content":" * This helper method helps to check if the sorted issues are in their"},{"lineNumber":66,"author":{"gitId":"-"},"content":" * correct order based on the variable arguments provided."},{"lineNumber":67,"author":{"gitId":"-"},"content":" */"},{"lineNumber":68,"author":{"gitId":"-"},"content":"function assertOrder(sortedIssues: Issue[], ...expectedSortedIssues: Issue[]) {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" for (let i \u003d 0; i \u003c sortedIssues.length; i++) {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" expect(sortedIssues[i].id).toBe(expectedSortedIssues[i].id);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"NereusWB922":28,"-":44}},{"path":"tests/app/shared/issue-tables/search-filter.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Issue } from \u0027../../../../src/app/core/models/issue.model\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { IssueService } from \u0027../../../../src/app/core/services/issue.service\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { TABLE_COLUMNS } from \u0027../../../../src/app/shared/issue-tables/issue-tables-columns\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { applySearchFilter } from \u0027../../../../src/app/shared/issue-tables/search-filter\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { USER_ANUBHAV } from \u0027../../../constants/data.constants\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":7,"author":{"gitId":"-"},"content":" ISSUE_WITH_ASSIGNEES,"},{"lineNumber":8,"author":{"gitId":"-"},"content":" ISSUE_WITH_EMPTY_DESCRIPTION,"},{"lineNumber":9,"author":{"gitId":"-"},"content":" ISSUE_WITH_EMPTY_DESCRIPTION_HIGH_SEVERITY,"},{"lineNumber":10,"author":{"gitId":"-"},"content":" ISSUE_WITH_EMPTY_DESCRIPTION_LOW_SEVERITY"},{"lineNumber":11,"author":{"gitId":"-"},"content":"} from \u0027../../../constants/githubissue.constants\u0027;"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":"import { GITHUB_LABEL_FEATURE_FLAW } from \u0027../../../constants/githublabel.constants\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"describe(\u0027search-filter\u0027, () \u003d\u003e {"},{"lineNumber":15,"author":{"gitId":"-"},"content":" describe(\u0027applySearchFilter()\u0027, () \u003d\u003e {"},{"lineNumber":16,"author":{"gitId":"-"},"content":" let searchKey: string;"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" const mediumSeverityIssueWithResponse: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_EMPTY_DESCRIPTION);"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" const mediumSeverityIssueWithAssigneee: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_ASSIGNEES);"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" const lowSeverityFeatureFlawIssue: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_EMPTY_DESCRIPTION_LOW_SEVERITY);"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" const highSeverityDocumentationBugIssue: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_EMPTY_DESCRIPTION_HIGH_SEVERITY);"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" const issuesList: Issue[] \u003d ["},{"lineNumber":23,"author":{"gitId":"-"},"content":" mediumSeverityIssueWithResponse,"},{"lineNumber":24,"author":{"gitId":"-"},"content":" mediumSeverityIssueWithAssigneee,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" lowSeverityFeatureFlawIssue,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" highSeverityDocumentationBugIssue"},{"lineNumber":27,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" const displayedColumns: string[] \u003d [TABLE_COLUMNS.ID, TABLE_COLUMNS.TITLE, TABLE_COLUMNS.ASSIGNEE, TABLE_COLUMNS.LABEL];"},{"lineNumber":29,"author":{"gitId":"-"},"content":" const issueService: IssueService \u003d new IssueService(null, null, null);"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" it(\u0027can filter for issues which are assigned to a specific user\u0027, () \u003d\u003e {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" searchKey \u003d USER_ANUBHAV.loginId;"},{"lineNumber":33,"author":{"gitId":"-"},"content":" expect(applySearchFilter(searchKey, displayedColumns, issueService, issuesList)).toEqual([mediumSeverityIssueWithAssigneee]);"},{"lineNumber":34,"author":{"gitId":"-"},"content":" });"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" it(\u0027can filter for issues using label\u0027, () \u003d\u003e {"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":" searchKey \u003d GITHUB_LABEL_FEATURE_FLAW.name;"},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" expect(applySearchFilter(searchKey, displayedColumns, issueService, issuesList)).toEqual([lowSeverityFeatureFlawIssue]);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" });"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" it(\u0027can filter for issues that contain the search key in any other column\u0027, () \u003d\u003e {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" // Search by id of issue"},{"lineNumber":43,"author":{"gitId":"-"},"content":" searchKey \u003d mediumSeverityIssueWithResponse.id.toString();"},{"lineNumber":44,"author":{"gitId":"-"},"content":" expect(applySearchFilter(searchKey, displayedColumns, issueService, issuesList)).toEqual([mediumSeverityIssueWithResponse]);"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" // Search by title of issue"},{"lineNumber":47,"author":{"gitId":"-"},"content":" searchKey \u003d mediumSeverityIssueWithAssigneee.title;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" expect(applySearchFilter(searchKey, displayedColumns, issueService, issuesList)).toEqual([mediumSeverityIssueWithAssigneee]);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" });"},{"lineNumber":50,"author":{"gitId":"-"},"content":" });"},{"lineNumber":51,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"NereusWB922":9,"-":42}},{"path":"tests/constants/data.constants.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { UserRole } from \u0027../../src/app/core/models/user.model\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"export const csvString \u003d"},{"lineNumber":4,"author":{"gitId":"-"},"content":" `"},{"lineNumber":5,"author":{"gitId":"-"},"content":"role,name,team"},{"lineNumber":6,"author":{"gitId":"-"},"content":"student,JunWei96,CS2103T-W12-3"},{"lineNumber":7,"author":{"gitId":"-"},"content":"admin,damithc,"},{"lineNumber":8,"author":{"gitId":"-"},"content":"tutor,anubh-v,CS2103T-W12-3"},{"lineNumber":9,"author":{"gitId":"-"},"content":"admin,geshuming,"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"tutor,jj-lim,CS2103T-W12-3"},{"lineNumber":12,"author":{"gitId":"-"},"content":"tutor,jj-lim,CS2103T-W12-3"},{"lineNumber":13,"author":{"gitId":"-"},"content":"tutor,jj-lim,CS2103T-W12-4"},{"lineNumber":14,"author":{"gitId":"-"},"content":"tutor,q ,CS2103T-W12-4"},{"lineNumber":15,"author":{"gitId":"-"},"content":"student,003-samuel,CS2103T-W12-3"},{"lineNumber":16,"author":{"gitId":"-"},"content":"student,damithc,CS2103T-W12-3"},{"lineNumber":17,"author":{"gitId":"-"},"content":"student,RonakLakhotia,CS2103T-W12-4"},{"lineNumber":18,"author":{"gitId":"-"},"content":"student,ptvrajsk,CS2103T-W12-3` + ` `;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"// jsonData is a json representation of csvString"},{"lineNumber":21,"author":{"gitId":"-"},"content":"export const jsonData \u003d {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" roles: {"},{"lineNumber":23,"author":{"gitId":"-"},"content":" students: {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" junwei96: \u0027true\u0027,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u0027003-samuel\u0027: \u0027true\u0027,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" damithc: \u0027true\u0027,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" ronaklakhotia: \u0027true\u0027,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" ptvrajsk: \u0027true\u0027"},{"lineNumber":29,"author":{"gitId":"-"},"content":" },"},{"lineNumber":30,"author":{"gitId":"-"},"content":" tutors: { \u0027anubh-v\u0027: \u0027true\u0027, \u0027jj-lim\u0027: \u0027true\u0027, q: \u0027true\u0027 },"},{"lineNumber":31,"author":{"gitId":"-"},"content":" admins: { damithc: \u0027true\u0027, geshuming: \u0027true\u0027 }"},{"lineNumber":32,"author":{"gitId":"-"},"content":" },"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u0027team-structure\u0027: {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u0027CS2103T-W12-3\u0027: {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" junwei96: \u0027JunWei96\u0027,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" \u0027003-samuel\u0027: \u0027003-samuel\u0027,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" damithc: \u0027damithc\u0027,"},{"lineNumber":38,"author":{"gitId":"-"},"content":" ptvrajsk: \u0027ptvrajsk\u0027"},{"lineNumber":39,"author":{"gitId":"-"},"content":" },"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u0027CS2103T-W12-4\u0027: { ronaklakhotia: \u0027RonakLakhotia\u0027 }"},{"lineNumber":41,"author":{"gitId":"-"},"content":" },"},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u0027students-allocation\u0027: {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" junwei96: { teamId: \u0027CS2103T-W12-3\u0027 },"},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u0027003-samuel\u0027: { teamId: \u0027CS2103T-W12-3\u0027 },"},{"lineNumber":45,"author":{"gitId":"-"},"content":" damithc: { teamId: \u0027CS2103T-W12-3\u0027 },"},{"lineNumber":46,"author":{"gitId":"-"},"content":" ronaklakhotia: { teamId: \u0027CS2103T-W12-4\u0027 },"},{"lineNumber":47,"author":{"gitId":"-"},"content":" ptvrajsk: { teamId: \u0027CS2103T-W12-3\u0027 }"},{"lineNumber":48,"author":{"gitId":"-"},"content":" },"},{"lineNumber":49,"author":{"gitId":"-"},"content":" \u0027tutors-allocation\u0027: {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" \u0027anubh-v\u0027: { \u0027CS2103T-W12-3\u0027: \u0027true\u0027 },"},{"lineNumber":51,"author":{"gitId":"-"},"content":" \u0027jj-lim\u0027: { \u0027CS2103T-W12-3\u0027: \u0027true\u0027, \u0027CS2103T-W12-4\u0027: \u0027true\u0027 },"},{"lineNumber":52,"author":{"gitId":"-"},"content":" q: { \u0027CS2103T-W12-4\u0027: \u0027true\u0027 }"},{"lineNumber":53,"author":{"gitId":"-"},"content":" },"},{"lineNumber":54,"author":{"gitId":"-"},"content":" \u0027admins-allocation\u0027: { damithc: {}, geshuming: {} }"},{"lineNumber":55,"author":{"gitId":"-"},"content":"};"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":"export const USER_JUNWEI \u003d {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" loginId: \u0027JunWei96\u0027,"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" role: UserRole.Student"},{"lineNumber":60,"author":{"gitId":"-"},"content":"};"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":"export const USER_ANUBHAV \u003d {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" loginId: \u0027anubh-v\u0027,"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" role: UserRole.Student"},{"lineNumber":65,"author":{"gitId":"-"},"content":"};"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":"export const USER_Q \u003d {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" loginId: \u0027q\u0027,"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":" role: UserRole.Tutor"},{"lineNumber":70,"author":{"gitId":"-"},"content":"};"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":"export const USER_SHUMING \u003d {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" loginId: \u0027geshuming\u0027,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" role: UserRole.Admin,"},{"lineNumber":75,"author":{"gitId":"-"},"content":" allocatedTeams: []"},{"lineNumber":76,"author":{"gitId":"-"},"content":"};"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":"export const USER_WITH_TWO_ROLES \u003d {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" loginId: \u0027damithc\u0027,"},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":" role: UserRole.Admin"},{"lineNumber":81,"author":{"gitId":"-"},"content":"};"}],"authorContributionMap":{"NereusWB922":4,"-":77}},{"path":"tests/constants/error.constants.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"MadLamprey"},"content":"import { HttpErrorResponse } from \u0027@angular/common/http\u0027;"},{"lineNumber":2,"author":{"gitId":"MadLamprey"},"content":"import { RequestError } from \u0027@octokit/request-error\u0027;"},{"lineNumber":3,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":4,"author":{"gitId":"MadLamprey"},"content":"export const STANDARD_ERROR \u003d new Error(\u0027This is a normal error\u0027);"},{"lineNumber":5,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":6,"author":{"gitId":"MadLamprey"},"content":"export const ERROR_WITH_NO_MESSAGE \u003d new Error();"},{"lineNumber":7,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":8,"author":{"gitId":"MadLamprey"},"content":"export const HTTP_304_ERROR \u003d new HttpErrorResponse({ status: 304 });"},{"lineNumber":9,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":10,"author":{"gitId":"MadLamprey"},"content":"export const HTTP_422_ERROR \u003d new HttpErrorResponse({ status: 422 });"},{"lineNumber":11,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":12,"author":{"gitId":"MadLamprey"},"content":"export const HTTP_500_ERROR \u003d new HttpErrorResponse({ status: 500 });"},{"lineNumber":13,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":14,"author":{"gitId":"MadLamprey"},"content":"export const HTTP_400_ERROR \u003d new HttpErrorResponse({ status: 400 });"},{"lineNumber":15,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":16,"author":{"gitId":"MadLamprey"},"content":"export const HTTP_401_ERROR \u003d new HttpErrorResponse({ status: 401 });"},{"lineNumber":17,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":18,"author":{"gitId":"MadLamprey"},"content":"export const HTTP_404_ERROR \u003d new HttpErrorResponse({ status: 404 });"},{"lineNumber":19,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":20,"author":{"gitId":"MadLamprey"},"content":"export const HTTP_UNKNOWN_ERROR \u003d new HttpErrorResponse({ status: 999 });"},{"lineNumber":21,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":22,"author":{"gitId":"MadLamprey"},"content":"export const OCTOKIT_REQUEST_ERROR \u003d new RequestError(\u0027This is an octokit request error\u0027, 400, {"},{"lineNumber":23,"author":{"gitId":"MadLamprey"},"content":" request: { method: \u0027GET\u0027, url: \u0027\u0027, headers: {} }"},{"lineNumber":24,"author":{"gitId":"MadLamprey"},"content":"});"}],"authorContributionMap":{"MadLamprey":24}},{"path":"tests/constants/githubissue.constants.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { IssueState, IssueStateReason } from \u0027../../graphql/graphql-types\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { GithubIssue } from \u0027../../src/app/core/models/github/github-issue.model\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { GithubLabel } from \u0027../../src/app/core/models/github/github-label.model\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { USER_ANUBHAV } from \u0027./data.constants\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import { EMPTY_TEAM_RESPONSE } from \u0027./githubcomment.constants\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":7,"author":{"gitId":"-"},"content":" GITHUB_LABEL_DOCUMENTATION_BUG,"},{"lineNumber":8,"author":{"gitId":"-"},"content":" GITHUB_LABEL_FEATURE_FLAW,"},{"lineNumber":9,"author":{"gitId":"-"},"content":" GITHUB_LABEL_FUNCTIONALITY_BUG,"},{"lineNumber":10,"author":{"gitId":"-"},"content":" GITHUB_LABEL_HIGH_SEVERITY,"},{"lineNumber":11,"author":{"gitId":"-"},"content":" GITHUB_LABEL_LOW_SEVERITY,"},{"lineNumber":12,"author":{"gitId":"-"},"content":" GITHUB_LABEL_MEDIUM_SEVERITY,"},{"lineNumber":13,"author":{"gitId":"-"},"content":" GITHUB_LABEL_TEAM_LABEL,"},{"lineNumber":14,"author":{"gitId":"-"},"content":" GITHUB_LABEL_TUTORIAL_LABEL"},{"lineNumber":15,"author":{"gitId":"-"},"content":"} from \u0027./githublabel.constants\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"const randomId: () \u003d\u003e string \u003d () \u003d\u003e {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" return Math.floor(Math.random() * 1000000000).toString();"},{"lineNumber":19,"author":{"gitId":"-"},"content":"};"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"const randomIssueNumber: () \u003d\u003e number \u003d () \u003d\u003e {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" return Math.round(Math.random() * 1000);"},{"lineNumber":23,"author":{"gitId":"-"},"content":"};"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":"const randomISODate: (startDate?: Date, endDate?: Date) \u003d\u003e string \u003d ("},{"lineNumber":26,"author":{"gitId":"-"},"content":" startDate: Date \u003d new Date(2020, 1, 1),"},{"lineNumber":27,"author":{"gitId":"-"},"content":" endDate: Date \u003d new Date()"},{"lineNumber":28,"author":{"gitId":"-"},"content":") \u003d\u003e {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" return new Date(startDate.getTime() + Math.random() * (startDate.getTime() - endDate.getTime())).toISOString();"},{"lineNumber":30,"author":{"gitId":"-"},"content":"};"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":"const USER_ANUBHAV_DETAILS \u003d {"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" login: USER_ANUBHAV.loginId"},{"lineNumber":34,"author":{"gitId":"-"},"content":"};"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":"export const MILESTONE_ONE \u003d {"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":" number: \u00271\u0027,"},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" title: \u0027Milestone 1\u0027,"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" state: \u0027Open\u0027"},{"lineNumber":40,"author":{"gitId":"-"},"content":"};"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":"export const ISSUE_WITH_EMPTY_DESCRIPTION \u003d new GithubIssue({"},{"lineNumber":43,"author":{"gitId":"-"},"content":" id: \u0027574085971\u0027,"},{"lineNumber":44,"author":{"gitId":"-"},"content":" number: 92,"},{"lineNumber":45,"author":{"gitId":"-"},"content":" assignees: [],"},{"lineNumber":46,"author":{"gitId":"-"},"content":" body: \u0027\u0027,"},{"lineNumber":47,"author":{"gitId":"-"},"content":" created_at: \u00272020-03-02T16:19:02Z\u0027,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" labels: [GITHUB_LABEL_TEAM_LABEL, GITHUB_LABEL_TUTORIAL_LABEL, GITHUB_LABEL_FUNCTIONALITY_BUG, GITHUB_LABEL_MEDIUM_SEVERITY],"},{"lineNumber":49,"author":{"gitId":"-"},"content":" state: IssueState.Open,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" stateReason: IssueStateReason.Reopened,"},{"lineNumber":51,"author":{"gitId":"-"},"content":" title: \u0027App starts to lag when given large amount of input\u0027,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" updated_at: \u00272020-03-13T13:37:32Z\u0027,"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" closed_at: \u0027\u0027,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" url: \u0027https://api.github.com/repos/CATcher-org/pe-results/issues/92\u0027,"},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" user: USER_ANUBHAV_DETAILS,"},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" milestone: MILESTONE_ONE,"},{"lineNumber":57,"author":{"gitId":"NereusWB922"},"content":" comments: [],"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" issueOrPr: \u0027Issue\u0027,"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" isDraft: false"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":"});"},{"lineNumber":61,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":62,"author":{"gitId":"NereusWB922"},"content":"export const CLOSED_ISSUE_WITH_EMPTY_DESCRIPTION \u003d new GithubIssue({"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" id: \u0027574085971\u0027,"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" number: 92,"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":" assignees: [],"},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" body: \u0027\u0027,"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":" created_at: \u00272020-03-02T16:19:02Z\u0027,"},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":" labels: [GITHUB_LABEL_TEAM_LABEL, GITHUB_LABEL_TUTORIAL_LABEL, GITHUB_LABEL_FUNCTIONALITY_BUG, GITHUB_LABEL_MEDIUM_SEVERITY],"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":" state: IssueState.Closed,"},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":" stateReason: IssueStateReason.Completed,"},{"lineNumber":71,"author":{"gitId":"NereusWB922"},"content":" title: \u0027App starts to lag when given large amount of input\u0027,"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" updated_at: \u00272020-03-13T13:37:32Z\u0027,"},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" closed_at: \u00272020-03-22T15:37:32Z\u0027,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" url: \u0027https://api.github.com/repos/CATcher-org/pe-results/issues/92\u0027,"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":" user: USER_ANUBHAV_DETAILS,"},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" milestone: MILESTONE_ONE,"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" comments: [],"},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":" issueOrPr: \u0027Issue\u0027,"},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":" isDraft: false"},{"lineNumber":80,"author":{"gitId":"-"},"content":"});"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"NereusWB922"},"content":"export const ISSUE_UPDATED_EARLIER \u003d new GithubIssue({"},{"lineNumber":83,"author":{"gitId":"NereusWB922"},"content":" id: \u0027000000001\u0027,"},{"lineNumber":84,"author":{"gitId":"NereusWB922"},"content":" number: 1,"},{"lineNumber":85,"author":{"gitId":"NereusWB922"},"content":" assignees: [],"},{"lineNumber":86,"author":{"gitId":"NereusWB922"},"content":" body: \u0027\u0027,"},{"lineNumber":87,"author":{"gitId":"NereusWB922"},"content":" created_at: \u00272020-09-02T16:19:02Z\u0027,"},{"lineNumber":88,"author":{"gitId":"NereusWB922"},"content":" labels: [GITHUB_LABEL_TEAM_LABEL, GITHUB_LABEL_TUTORIAL_LABEL, GITHUB_LABEL_FUNCTIONALITY_BUG, GITHUB_LABEL_MEDIUM_SEVERITY],"},{"lineNumber":89,"author":{"gitId":"NereusWB922"},"content":" state: IssueState.Open,"},{"lineNumber":90,"author":{"gitId":"NereusWB922"},"content":" stateReason: IssueStateReason.Reopened,"},{"lineNumber":91,"author":{"gitId":"NereusWB922"},"content":" title: \u0027App starts to lag when given large amount of input\u0027,"},{"lineNumber":92,"author":{"gitId":"NereusWB922"},"content":" updated_at: \u00272020-09-03T13:37:32Z\u0027,"},{"lineNumber":93,"author":{"gitId":"NereusWB922"},"content":" closed_at: \u0027\u0027,"},{"lineNumber":94,"author":{"gitId":"NereusWB922"},"content":" url: \u0027https://api.github.com/repos/CATcher-org/pe-results/issues/93\u0027,"},{"lineNumber":95,"author":{"gitId":"NereusWB922"},"content":" user: USER_ANUBHAV_DETAILS,"},{"lineNumber":96,"author":{"gitId":"NereusWB922"},"content":" milestone: MILESTONE_ONE,"},{"lineNumber":97,"author":{"gitId":"NereusWB922"},"content":" comments: [],"},{"lineNumber":98,"author":{"gitId":"NereusWB922"},"content":" issueOrPr: \u0027Issue\u0027,"},{"lineNumber":99,"author":{"gitId":"NereusWB922"},"content":" isDraft: false"},{"lineNumber":100,"author":{"gitId":"NereusWB922"},"content":"});"},{"lineNumber":101,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":102,"author":{"gitId":"NereusWB922"},"content":"export const ISSUE_UPDATED_LATER \u003d new GithubIssue({"},{"lineNumber":103,"author":{"gitId":"NereusWB922"},"content":" id: \u0027000000002\u0027,"},{"lineNumber":104,"author":{"gitId":"NereusWB922"},"content":" number: 2,"},{"lineNumber":105,"author":{"gitId":"NereusWB922"},"content":" assignees: [],"},{"lineNumber":106,"author":{"gitId":"NereusWB922"},"content":" body: \u0027\u0027,"},{"lineNumber":107,"author":{"gitId":"NereusWB922"},"content":" created_at: \u00272020-10-02T16:19:02Z\u0027,"},{"lineNumber":108,"author":{"gitId":"NereusWB922"},"content":" labels: [GITHUB_LABEL_TEAM_LABEL, GITHUB_LABEL_TUTORIAL_LABEL, GITHUB_LABEL_FUNCTIONALITY_BUG, GITHUB_LABEL_MEDIUM_SEVERITY],"},{"lineNumber":109,"author":{"gitId":"NereusWB922"},"content":" state: IssueState.Open,"},{"lineNumber":110,"author":{"gitId":"NereusWB922"},"content":" stateReason: IssueStateReason.Reopened,"},{"lineNumber":111,"author":{"gitId":"NereusWB922"},"content":" title: \u0027App starts to lag when given large amount of input\u0027,"},{"lineNumber":112,"author":{"gitId":"NereusWB922"},"content":" updated_at: \u00272020-10-22T13:37:32Z\u0027,"},{"lineNumber":113,"author":{"gitId":"NereusWB922"},"content":" closed_at: \u0027\u0027,"},{"lineNumber":114,"author":{"gitId":"NereusWB922"},"content":" url: \u0027https://api.github.com/repos/CATcher-org/pe-results/issues/94\u0027,"},{"lineNumber":115,"author":{"gitId":"NereusWB922"},"content":" user: USER_ANUBHAV_DETAILS,"},{"lineNumber":116,"author":{"gitId":"NereusWB922"},"content":" milestone: MILESTONE_ONE,"},{"lineNumber":117,"author":{"gitId":"NereusWB922"},"content":" comments: [],"},{"lineNumber":118,"author":{"gitId":"NereusWB922"},"content":" issueOrPr: \u0027Issue\u0027,"},{"lineNumber":119,"author":{"gitId":"NereusWB922"},"content":" isDraft: false"},{"lineNumber":120,"author":{"gitId":"-"},"content":"});"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":"export const ISSUE_WITH_EMPTY_DESCRIPTION_LOW_SEVERITY \u003d new GithubIssue({"},{"lineNumber":123,"author":{"gitId":"-"},"content":" id: \u0027384830567\u0027,"},{"lineNumber":124,"author":{"gitId":"-"},"content":" number: 130,"},{"lineNumber":125,"author":{"gitId":"-"},"content":" assignees: [],"},{"lineNumber":126,"author":{"gitId":"-"},"content":" body: \u0027\u0027,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" created_at: \u00272020-03-02T16:19:02Z\u0027,"},{"lineNumber":128,"author":{"gitId":"-"},"content":" labels: [GITHUB_LABEL_TEAM_LABEL, GITHUB_LABEL_TUTORIAL_LABEL, GITHUB_LABEL_FEATURE_FLAW, GITHUB_LABEL_LOW_SEVERITY],"},{"lineNumber":129,"author":{"gitId":"-"},"content":" state: IssueState.Open,"},{"lineNumber":130,"author":{"gitId":"-"},"content":" stateReason: IssueStateReason.Reopened,"},{"lineNumber":131,"author":{"gitId":"-"},"content":" title: \u0027App is sometimes slow\u0027,"},{"lineNumber":132,"author":{"gitId":"-"},"content":" updated_at: \u00272020-03-13T13:37:32Z\u0027,"},{"lineNumber":133,"author":{"gitId":"NereusWB922"},"content":" closed_at: \u0027\u0027,"},{"lineNumber":134,"author":{"gitId":"-"},"content":" url: \u0027https://api.github.com/repos/CATcher-org/pe-results/issues/130\u0027,"},{"lineNumber":135,"author":{"gitId":"NereusWB922"},"content":" user: USER_ANUBHAV_DETAILS,"},{"lineNumber":136,"author":{"gitId":"NereusWB922"},"content":" milestone: MILESTONE_ONE,"},{"lineNumber":137,"author":{"gitId":"NereusWB922"},"content":" comments: [],"},{"lineNumber":138,"author":{"gitId":"NereusWB922"},"content":" issueOrPr: \u0027Issue\u0027,"},{"lineNumber":139,"author":{"gitId":"NereusWB922"},"content":" isDraft: false"},{"lineNumber":140,"author":{"gitId":"-"},"content":"});"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":"export const ISSUE_WITH_EMPTY_DESCRIPTION_HIGH_SEVERITY \u003d new GithubIssue({"},{"lineNumber":143,"author":{"gitId":"-"},"content":" id: \u0027573957398\u0027,"},{"lineNumber":144,"author":{"gitId":"-"},"content":" number: 32,"},{"lineNumber":145,"author":{"gitId":"-"},"content":" assignees: [],"},{"lineNumber":146,"author":{"gitId":"-"},"content":" body: \u0027\u0027,"},{"lineNumber":147,"author":{"gitId":"-"},"content":" created_at: \u00272010-03-12T19:12:02Z\u0027,"},{"lineNumber":148,"author":{"gitId":"-"},"content":" labels: [GITHUB_LABEL_TEAM_LABEL, GITHUB_LABEL_TUTORIAL_LABEL, GITHUB_LABEL_DOCUMENTATION_BUG, GITHUB_LABEL_HIGH_SEVERITY],"},{"lineNumber":149,"author":{"gitId":"-"},"content":" state: IssueState.Open,"},{"lineNumber":150,"author":{"gitId":"-"},"content":" stateReason: IssueStateReason.Reopened,"},{"lineNumber":151,"author":{"gitId":"-"},"content":" title: \u0027Too many typos\u0027,"},{"lineNumber":152,"author":{"gitId":"-"},"content":" updated_at: \u00272012-03-12T19:12:02Z\u0027,"},{"lineNumber":153,"author":{"gitId":"NereusWB922"},"content":" closed_at: \u0027\u0027,"},{"lineNumber":154,"author":{"gitId":"-"},"content":" url: \u0027https://api.github.com/repos/CATcher-org/pe-results/issues/130\u0027,"},{"lineNumber":155,"author":{"gitId":"NereusWB922"},"content":" user: USER_ANUBHAV_DETAILS,"},{"lineNumber":156,"author":{"gitId":"NereusWB922"},"content":" milestone: MILESTONE_ONE,"},{"lineNumber":157,"author":{"gitId":"NereusWB922"},"content":" comments: [],"},{"lineNumber":158,"author":{"gitId":"NereusWB922"},"content":" issueOrPr: \u0027Issue\u0027,"},{"lineNumber":159,"author":{"gitId":"NereusWB922"},"content":" isDraft: false"},{"lineNumber":160,"author":{"gitId":"-"},"content":"});"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"NereusWB922"},"content":"export const ISSUE_WITHOUT_MILESTONE \u003d new GithubIssue({"},{"lineNumber":163,"author":{"gitId":"NereusWB922"},"content":" id: \u0027573957398\u0027,"},{"lineNumber":164,"author":{"gitId":"NereusWB922"},"content":" number: 32,"},{"lineNumber":165,"author":{"gitId":"-"},"content":" assignees: [],"},{"lineNumber":166,"author":{"gitId":"-"},"content":" body: \u0027\u0027,"},{"lineNumber":167,"author":{"gitId":"NereusWB922"},"content":" created_at: \u00272010-03-12T19:12:02Z\u0027,"},{"lineNumber":168,"author":{"gitId":"-"},"content":" labels: [GITHUB_LABEL_TEAM_LABEL, GITHUB_LABEL_TUTORIAL_LABEL, GITHUB_LABEL_DOCUMENTATION_BUG, GITHUB_LABEL_HIGH_SEVERITY],"},{"lineNumber":169,"author":{"gitId":"-"},"content":" state: IssueState.Open,"},{"lineNumber":170,"author":{"gitId":"-"},"content":" stateReason: IssueStateReason.Reopened,"},{"lineNumber":171,"author":{"gitId":"NereusWB922"},"content":" title: \u0027Too many typos\u0027,"},{"lineNumber":172,"author":{"gitId":"NereusWB922"},"content":" updated_at: \u00272012-03-12T19:12:02Z\u0027,"},{"lineNumber":173,"author":{"gitId":"NereusWB922"},"content":" closed_at: \u0027\u0027,"},{"lineNumber":174,"author":{"gitId":"-"},"content":" url: \u0027https://api.github.com/repos/CATcher-org/pe-results/issues/130\u0027,"},{"lineNumber":175,"author":{"gitId":"NereusWB922"},"content":" user: USER_ANUBHAV_DETAILS,"},{"lineNumber":176,"author":{"gitId":"NereusWB922"},"content":" comments: [],"},{"lineNumber":177,"author":{"gitId":"NereusWB922"},"content":" issueOrPr: \u0027Issue\u0027,"},{"lineNumber":178,"author":{"gitId":"NereusWB922"},"content":" isDraft: false"},{"lineNumber":179,"author":{"gitId":"-"},"content":"});"},{"lineNumber":180,"author":{"gitId":"-"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":"export const ISSUE_WITH_ASSIGNEES \u003d new GithubIssue({"},{"lineNumber":182,"author":{"gitId":"-"},"content":" id: \u0027551732011\u0027,"},{"lineNumber":183,"author":{"gitId":"-"},"content":" number: 91,"},{"lineNumber":184,"author":{"gitId":"NereusWB922"},"content":" assignees: [USER_ANUBHAV_DETAILS],"},{"lineNumber":185,"author":{"gitId":"-"},"content":" body: \u0027Screen freezes every few minutes\u0027,"},{"lineNumber":186,"author":{"gitId":"-"},"content":" created_at: \u00272020-01-18T07:01:45Z\u0027,"},{"lineNumber":187,"author":{"gitId":"-"},"content":" labels: [GITHUB_LABEL_TEAM_LABEL, GITHUB_LABEL_TUTORIAL_LABEL, GITHUB_LABEL_FUNCTIONALITY_BUG, GITHUB_LABEL_MEDIUM_SEVERITY],"},{"lineNumber":188,"author":{"gitId":"-"},"content":" state: IssueState.Open,"},{"lineNumber":189,"author":{"gitId":"-"},"content":" stateReason: IssueStateReason.Reopened,"},{"lineNumber":190,"author":{"gitId":"-"},"content":" title: \u0027Screen freezes\u0027,"},{"lineNumber":191,"author":{"gitId":"-"},"content":" updated_at: \u00272020-03-02T12:50:02Z\u0027,"},{"lineNumber":192,"author":{"gitId":"NereusWB922"},"content":" closed_at: \u0027\u0027,"},{"lineNumber":193,"author":{"gitId":"-"},"content":" url: \u0027https://api.github.com/repos/CATcher-org/pe-results/issues/91\u0027,"},{"lineNumber":194,"author":{"gitId":"-"},"content":" user: USER_ANUBHAV_DETAILS,"},{"lineNumber":195,"author":{"gitId":"NereusWB922"},"content":" milestone: MILESTONE_ONE,"},{"lineNumber":196,"author":{"gitId":"NereusWB922"},"content":" comments: [EMPTY_TEAM_RESPONSE],"},{"lineNumber":197,"author":{"gitId":"NereusWB922"},"content":" issueOrPr: \u0027Issue\u0027,"},{"lineNumber":198,"author":{"gitId":"NereusWB922"},"content":" isDraft: false"},{"lineNumber":199,"author":{"gitId":"-"},"content":"});"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":"export const generateIssueWithRandomData: () \u003d\u003e GithubIssue \u003d () \u003d\u003e {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" const created_and_updated_date: string \u003d randomISODate();"},{"lineNumber":203,"author":{"gitId":"-"},"content":" const issueNumber: number \u003d randomIssueNumber();"},{"lineNumber":204,"author":{"gitId":"-"},"content":" const severityLabels: GithubLabel[] \u003d [GITHUB_LABEL_LOW_SEVERITY, GITHUB_LABEL_MEDIUM_SEVERITY, GITHUB_LABEL_HIGH_SEVERITY];"},{"lineNumber":205,"author":{"gitId":"-"},"content":" const typeLabels: GithubLabel[] \u003d [GITHUB_LABEL_FUNCTIONALITY_BUG, GITHUB_LABEL_FEATURE_FLAW, GITHUB_LABEL_DOCUMENTATION_BUG];"},{"lineNumber":206,"author":{"gitId":"-"},"content":" return new GithubIssue({"},{"lineNumber":207,"author":{"gitId":"-"},"content":" id: randomId(),"},{"lineNumber":208,"author":{"gitId":"-"},"content":" number: issueNumber,"},{"lineNumber":209,"author":{"gitId":"-"},"content":" assignees: [],"},{"lineNumber":210,"author":{"gitId":"-"},"content":" comments: [],"},{"lineNumber":211,"author":{"gitId":"-"},"content":" body: `Issue No.: ${issueNumber}\\nSample Content.`,"},{"lineNumber":212,"author":{"gitId":"-"},"content":" created_at: created_and_updated_date,"},{"lineNumber":213,"author":{"gitId":"-"},"content":" labels: [GITHUB_LABEL_TEAM_LABEL, GITHUB_LABEL_TUTORIAL_LABEL, typeLabels[issueNumber % 3], severityLabels[issueNumber % 3]],"},{"lineNumber":214,"author":{"gitId":"-"},"content":" state: IssueState.Open,"},{"lineNumber":215,"author":{"gitId":"-"},"content":" stateReason: IssueStateReason.Reopened,"},{"lineNumber":216,"author":{"gitId":"-"},"content":" title: `Random Issue: ${issueNumber}`,"},{"lineNumber":217,"author":{"gitId":"-"},"content":" updated_at: created_and_updated_date,"},{"lineNumber":218,"author":{"gitId":"-"},"content":" url: `https://api.github.com/repos/CATcher-org/pe-results/issues/${issueNumber}`,"},{"lineNumber":219,"author":{"gitId":"-"},"content":" user: USER_ANUBHAV_DETAILS"},{"lineNumber":220,"author":{"gitId":"-"},"content":" });"},{"lineNumber":221,"author":{"gitId":"-"},"content":"};"}],"authorContributionMap":{"NereusWB922":99,"-":122}},{"path":"tests/constants/githublabel.constants.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { GithubLabel } from \u0027../../src/app/core/models/github/github-label.model\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"export const GITHUB_LABEL_FUNCTIONALITY_BUG \u003d {"},{"lineNumber":4,"author":{"gitId":"-"},"content":" color: \u00279900cc\u0027,"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" name: \u0027type.FunctionalityBug\u0027"},{"lineNumber":6,"author":{"gitId":"-"},"content":"} as GithubLabel;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"export const GITHUB_LABEL_FEATURE_FLAW \u003d {"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" color: \u0027d966ff\u0027,"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" name: \u0027type.FeatureFlaw\u0027"},{"lineNumber":11,"author":{"gitId":"-"},"content":"} as GithubLabel;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"export const GITHUB_LABEL_DOCUMENTATION_BUG \u003d {"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" color: \u0027d966ff\u0027,"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" name: \u0027type.DocumentationBug\u0027"},{"lineNumber":16,"author":{"gitId":"-"},"content":"} as GithubLabel;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"export const GITHUB_LABEL_LOW_SEVERITY \u003d {"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" color: \u0027ffcccc\u0027,"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" name: \u0027severity.Low\u0027"},{"lineNumber":21,"author":{"gitId":"-"},"content":"} as GithubLabel;"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":"export const GITHUB_LABEL_HIGH_SEVERITY \u003d {"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" color: \u0027ff6666\u0027,"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" name: \u0027severity.High\u0027"},{"lineNumber":26,"author":{"gitId":"-"},"content":"} as GithubLabel;"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":"export const GITHUB_LABEL_MEDIUM_SEVERITY \u003d {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" color: \u0027ff9999\u0027,"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" name: \u0027severity.Medium\u0027"},{"lineNumber":31,"author":{"gitId":"-"},"content":"} as GithubLabel;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":"export const GITHUB_LABEL_TUTORIAL_LABEL \u003d {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" color: \u0027c2e0c6\u0027,"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" name: \u0027tutorial.CS2103T-W12\u0027"},{"lineNumber":36,"author":{"gitId":"-"},"content":"} as GithubLabel;"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":"export const GITHUB_LABEL_TEAM_LABEL \u003d {"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" color: \u0027d4c5f9\u0027,"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" name: \u0027team.3\u0027"},{"lineNumber":41,"author":{"gitId":"-"},"content":"} as GithubLabel;"}],"authorContributionMap":{"NereusWB922":13,"-":28}},{"path":"tests/constants/label.constants.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { SimpleLabel } from \u0027../../src/app/core/models/label.model\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"// Label name constants"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"export const SEVERITY_VERY_LOW \u003d \u0027veryLow\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"export const SEVERITY_LOW \u003d \u0027low\u0027;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"export const SEVERITY_MEDIUM \u003d \u0027medium\u0027;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"export const SEVERITY_HIGH \u003d \u0027high\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"// Label category constants"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"export const CATEGORY_SEVERITY \u003d \u0027severity\u0027;"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":"// Label name constants"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":"export const LABEL_NAME_SEVERITY_VERY_LOW \u003d CATEGORY_SEVERITY + \u0027.\u0027 + SEVERITY_VERY_LOW;"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"export const LABEL_NAME_SEVERITY_LOW \u003d CATEGORY_SEVERITY + \u0027.\u0027 + SEVERITY_LOW;"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":"export const LABEL_NAME_SEVERITY_MEDIUM \u003d CATEGORY_SEVERITY + \u0027.\u0027 + SEVERITY_MEDIUM;"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":"export const LABEL_NAME_SEVERITY_HIGH \u003d CATEGORY_SEVERITY + \u0027.\u0027 + SEVERITY_HIGH;"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":"// Label definition constants"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":"export const DEFINITION_SEVERITY_VERY_LOW \u003d"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cp\u003eA flaw that is \u003cmark\u003epurely cosmetic\u003c/mark\u003e and \u003cmark\u003edoes not affect usage\u003c/mark\u003e. For example, \u0027 +"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cul\u003e\u0027 +"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cli\u003etypo issues\u003c/li\u003e\u0027 +"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cli\u003espacing issues\u003c/li\u003e\u0027 +"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cli\u003elayout issues\u003c/li\u003e\u0027 +"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cli\u003ecolor issues\u003c/li\u003e\u0027 +"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cli\u003efont issues\u003c/li\u003e\u0027 +"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003c/ul\u003e\u0027 +"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" \"in the docs or the UI that doesn\u0027t affect usage.\u003c/p\u003e\";"},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":"export const DEFINITION_SEVERITY_LOW \u003d"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cp\u003eA flaw that is unlikely to affect normal operations of the product. \u0027 +"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" \u0027Appears only in very rare situations and causes a minor inconvenience only.\u003c/p\u003e\u0027;"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":"export const DEFINITION_SEVERITY_MEDIUM \u003d"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cp\u003eA flaw that causes occasional inconvenience to some users but they can \u0027 + \u0027continue to use the product.\u003c/p\u003e\u0027;"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":"export const DEFINITION_SEVERITY_HIGH \u003d"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cp\u003eA flaw that affects most users and causes major problems for users.\u0027 + \u0027i.e., makes the product almost unusable for most users.\u003c/p\u003e\u0027;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":"// Label color constants"},{"lineNumber":38,"author":{"gitId":"-"},"content":"export const COLOR_BLACK \u003d \u0027000000\u0027;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"export const COLOR_WHITE \u003d \u0027ffffff\u0027;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"export const COLOR_SEVERITY_VERY_LOW \u003d \u0027ffe0e0\u0027;"},{"lineNumber":41,"author":{"gitId":"-"},"content":"export const COLOR_SEVERITY_LOW \u003d \u0027ffcccc\u0027;"},{"lineNumber":42,"author":{"gitId":"-"},"content":"export const COLOR_SEVERITY_MEDIUM \u003d \u0027ff9999\u0027;"},{"lineNumber":43,"author":{"gitId":"-"},"content":"export const COLOR_SEVERITY_HIGH \u003d \u0027ff6666\u0027;"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":"// CSS style constants"},{"lineNumber":46,"author":{"gitId":"-"},"content":"export const DARK_BG_LIGHT_TEXT \u003d {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" \u0027background-color\u0027: `#${COLOR_BLACK}`,"},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" color: `#${COLOR_WHITE}`"},{"lineNumber":49,"author":{"gitId":"-"},"content":"};"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":"export const LIGHT_BG_DARK_TEXT \u003d {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" \u0027background-color\u0027: `#${COLOR_WHITE}`,"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" color: `#${COLOR_BLACK}`"},{"lineNumber":54,"author":{"gitId":"-"},"content":"};"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":"export const SEVERITY_LABELS \u003d ["},{"lineNumber":57,"author":{"gitId":"-"},"content":" {"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" name: LABEL_NAME_SEVERITY_VERY_LOW,"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" color: COLOR_SEVERITY_VERY_LOW,"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":" definition: DEFINITION_SEVERITY_VERY_LOW"},{"lineNumber":61,"author":{"gitId":"-"},"content":" },"},{"lineNumber":62,"author":{"gitId":"-"},"content":" {"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" name: LABEL_NAME_SEVERITY_LOW,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" color: COLOR_SEVERITY_LOW,"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":" definition: DEFINITION_SEVERITY_LOW"},{"lineNumber":66,"author":{"gitId":"-"},"content":" },"},{"lineNumber":67,"author":{"gitId":"-"},"content":" {"},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":" name: LABEL_NAME_SEVERITY_MEDIUM,"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":" color: COLOR_SEVERITY_MEDIUM,"},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":" definition: DEFINITION_SEVERITY_MEDIUM"},{"lineNumber":71,"author":{"gitId":"-"},"content":" },"},{"lineNumber":72,"author":{"gitId":"-"},"content":" {"},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" name: LABEL_NAME_SEVERITY_HIGH,"},{"lineNumber":74,"author":{"gitId":"NereusWB922"},"content":" color: COLOR_SEVERITY_HIGH,"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":" definition: DEFINITION_SEVERITY_HIGH"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":"];"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":"export const SEVERITY_SIMPLE_LABELS: SimpleLabel[] \u003d SEVERITY_LABELS.map((label) \u003d\u003e ({"},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":" name: label.name,"},{"lineNumber":81,"author":{"gitId":"NereusWB922"},"content":" color: label.color"},{"lineNumber":82,"author":{"gitId":"NereusWB922"},"content":"}));"}],"authorContributionMap":{"NereusWB922":49,"-":33}},{"path":"tests/constants/session.constants.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Repo } from \u0027../../src/app/core/models/repo.model\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { SessionData, SessionRepo } from \u0027../../src/app/core/models/session.model\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { View } from \u0027../../src/app/core/models/view.model\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"export const WATCHER_REPO: Repo \u003d Repo.of(\u0027CATcher-org/WATcher\u0027);"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"export const CATCHER_REPO: Repo \u003d Repo.of(\u0027CATcher-org/CATcher\u0027);"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"const ISSUES_VIEWER_SESSION_REPO: SessionRepo \u003d {"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" view: View.issuesViewer,"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" repos: [WATCHER_REPO]"},{"lineNumber":11,"author":{"gitId":"-"},"content":"};"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":"const ACTIVITY_DASHBOARD_SESSION_REPO: SessionRepo \u003d {"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" view: View.activityDashboard,"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" repos: [WATCHER_REPO]"},{"lineNumber":16,"author":{"gitId":"-"},"content":"};"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":"export const VALID_SESSION_DATA: SessionData \u003d {"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" sessionRepo: [ISSUES_VIEWER_SESSION_REPO, ACTIVITY_DASHBOARD_SESSION_REPO]"},{"lineNumber":20,"author":{"gitId":"-"},"content":"};"}],"authorContributionMap":{"NereusWB922":13,"-":7}},{"path":"tests/model/issue.model.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import * as moment from \u0027moment\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Issue } from \u0027../../src/app/core/models/issue.model\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { Milestone } from \u0027../../src/app/core/models/milestone.model\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { USER_ANUBHAV } from \u0027../constants/data.constants\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import {"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" CLOSED_ISSUE_WITH_EMPTY_DESCRIPTION,"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" ISSUE_WITHOUT_MILESTONE,"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" ISSUE_WITH_ASSIGNEES,"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" ISSUE_WITH_EMPTY_DESCRIPTION,"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" MILESTONE_ONE"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":"} from \u0027../constants/githubissue.constants\u0027;"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":"import {"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" GITHUB_LABEL_FUNCTIONALITY_BUG,"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" GITHUB_LABEL_MEDIUM_SEVERITY,"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" GITHUB_LABEL_TEAM_LABEL,"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" GITHUB_LABEL_TUTORIAL_LABEL"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":"} from \u0027../constants/githublabel.constants\u0027;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"describe(\u0027Issue model class\u0027, () \u003d\u003e {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" describe(\u0027.createPhaseBugReportIssue(githubIssue)\u0027, () \u003d\u003e {"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should correctly create a issue that has an empty description\u0027, async () \u003d\u003e {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" const issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_EMPTY_DESCRIPTION);"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" expect(issue.globalId).toEqual(ISSUE_WITH_EMPTY_DESCRIPTION.id);"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" expect(issue.id).toEqual(ISSUE_WITH_EMPTY_DESCRIPTION.number);"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" expect(issue.created_at).toEqual(moment(ISSUE_WITH_EMPTY_DESCRIPTION.created_at).format(\u0027lll\u0027));"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" expect(issue.title).toEqual(ISSUE_WITH_EMPTY_DESCRIPTION.title);"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" expect(issue.description).toEqual(\u0027No details provided by bug reporter.\u0027);"},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" expect(issue.updated_at).toEqual(moment(ISSUE_WITH_EMPTY_DESCRIPTION.updated_at).format(\u0027lll\u0027));"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" expect(issue.closed_at).toEqual(\u0027Invalid date\u0027);"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" expect(issue.milestone).toEqual(new Milestone(MILESTONE_ONE));"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" expect(issue.state).toEqual(ISSUE_WITH_EMPTY_DESCRIPTION.state);"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" expect(issue.stateReason).toEqual(ISSUE_WITH_EMPTY_DESCRIPTION.stateReason);"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" expect(issue.issueOrPr).toEqual(\u0027Issue\u0027);"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" expect(issue.author).toEqual(ISSUE_WITH_EMPTY_DESCRIPTION.user.login);"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" expect(issue.isDraft).toEqual(ISSUE_WITH_EMPTY_DESCRIPTION.isDraft);"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":" expect(issue.assignees).toEqual([]);"},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" expect(issue.labels).toEqual(["},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" GITHUB_LABEL_TEAM_LABEL.name,"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" GITHUB_LABEL_TUTORIAL_LABEL.name,"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" GITHUB_LABEL_FUNCTIONALITY_BUG.name,"},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":" GITHUB_LABEL_MEDIUM_SEVERITY.name"},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":" ]);"},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" expect(issue.githubLabels).toEqual(ISSUE_WITH_EMPTY_DESCRIPTION.labels);"},{"lineNumber":45,"author":{"gitId":"-"},"content":" });"},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set close date correctly for closed issue\u0027, () \u003d\u003e {"},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" const issue \u003d Issue.createPhaseBugReportingIssue(CLOSED_ISSUE_WITH_EMPTY_DESCRIPTION);"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" expect(issue.closed_at).toEqual(moment(CLOSED_ISSUE_WITH_EMPTY_DESCRIPTION.closed_at).format(\u0027lll\u0027));"},{"lineNumber":51,"author":{"gitId":"-"},"content":" });"},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set milestone to default milestone for issue without milestone\u0027, () \u003d\u003e {"},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":" const issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITHOUT_MILESTONE);"},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":56,"author":{"gitId":"MadLamprey"},"content":" expect(issue.milestone).toEqual(Milestone.IssueWithoutMilestone);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" });"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set assignees correctly for issue with assignees\u0027, () \u003d\u003e {"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":" const issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_ASSIGNEES);"},{"lineNumber":61,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":62,"author":{"gitId":"NereusWB922"},"content":" expect(issue.assignees).toEqual([USER_ANUBHAV.loginId]);"},{"lineNumber":63,"author":{"gitId":"-"},"content":" });"},{"lineNumber":64,"author":{"gitId":"-"},"content":" });"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027.updateDescription(description)\u0027, () \u003d\u003e {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" it(\u0027correctly clean strings obtained from users\u0027, () \u003d\u003e {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" const noDetailsFromBugReporter \u003d \u0027No details provided by bug reporter.\u0027;"},{"lineNumber":69,"author":{"gitId":"-"},"content":" expect(Issue.updateDescription(\u0027\u0027)).toBe(noDetailsFromBugReporter);"},{"lineNumber":70,"author":{"gitId":"-"},"content":" expect(Issue.updateDescription(null)).toBe(noDetailsFromBugReporter);"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" const typicalDescription \u003d \u0027The app crashes after parsing config files.\u0027;"},{"lineNumber":73,"author":{"gitId":"-"},"content":" expect(Issue.updateDescription(typicalDescription)).toBe(typicalDescription + \u0027\\n\\n\u0027);"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" const inputWithSpecialChars \u003d \u0027$%^!@\u0026-_test\u0027;"},{"lineNumber":76,"author":{"gitId":"-"},"content":" expect(Issue.updateDescription(inputWithSpecialChars)).toBe(inputWithSpecialChars + \u0027\\n\\n\u0027);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" });"},{"lineNumber":78,"author":{"gitId":"-"},"content":" });"},{"lineNumber":79,"author":{"gitId":"-"},"content":"});"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":"describe(\u0027Issue\u0027, () \u003d\u003e {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" const dummyIssue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_EMPTY_DESCRIPTION);"},{"lineNumber":83,"author":{"gitId":"-"},"content":" const otherDummyIssue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_ASSIGNEES);"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" const noReportedDescriptionString \u003d \u0027No details provided by bug reporter.\\n\u0027;"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" it(\u0027.createGithubIssueDescription() forms the correct GitHub Issue description for the issue\u0027, () \u003d\u003e {"},{"lineNumber":88,"author":{"gitId":"NereusWB922"},"content":" expect(dummyIssue.createGithubIssueDescription()).toEqual(noReportedDescriptionString);"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"NereusWB922"},"content":" expect(otherDummyIssue.createGithubIssueDescription()).toEqual(`${otherDummyIssue.description}\\n`);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" });"},{"lineNumber":92,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"NereusWB922":57,"MadLamprey":1,"-":34}},{"path":"tests/services/error-handling.service.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"MadLamprey"},"content":"import { ErrorHandlingService } from \u0027../../src/app/core/services/error-handling.service\u0027;"},{"lineNumber":2,"author":{"gitId":"MadLamprey"},"content":"import { FormErrorComponent } from \u0027../../src/app/shared/error-toasters/form-error/form-error.component\u0027;"},{"lineNumber":3,"author":{"gitId":"MadLamprey"},"content":"import { GeneralMessageErrorComponent } from \u0027../../src/app/shared/error-toasters/general-message-error/general-message-error.component\u0027;"},{"lineNumber":4,"author":{"gitId":"MadLamprey"},"content":"import {"},{"lineNumber":5,"author":{"gitId":"MadLamprey"},"content":" ERROR_WITH_NO_MESSAGE,"},{"lineNumber":6,"author":{"gitId":"MadLamprey"},"content":" HTTP_304_ERROR,"},{"lineNumber":7,"author":{"gitId":"MadLamprey"},"content":" HTTP_400_ERROR,"},{"lineNumber":8,"author":{"gitId":"MadLamprey"},"content":" HTTP_401_ERROR,"},{"lineNumber":9,"author":{"gitId":"MadLamprey"},"content":" HTTP_404_ERROR,"},{"lineNumber":10,"author":{"gitId":"MadLamprey"},"content":" HTTP_422_ERROR,"},{"lineNumber":11,"author":{"gitId":"MadLamprey"},"content":" HTTP_500_ERROR,"},{"lineNumber":12,"author":{"gitId":"MadLamprey"},"content":" HTTP_UNKNOWN_ERROR,"},{"lineNumber":13,"author":{"gitId":"MadLamprey"},"content":" OCTOKIT_REQUEST_ERROR,"},{"lineNumber":14,"author":{"gitId":"MadLamprey"},"content":" STANDARD_ERROR"},{"lineNumber":15,"author":{"gitId":"MadLamprey"},"content":"} from \u0027../constants/error.constants\u0027;"},{"lineNumber":16,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":17,"author":{"gitId":"MadLamprey"},"content":"let errorHandlingService: ErrorHandlingService;"},{"lineNumber":18,"author":{"gitId":"MadLamprey"},"content":"let mockLoggingService;"},{"lineNumber":19,"author":{"gitId":"MadLamprey"},"content":"let mockSnackBar;"},{"lineNumber":20,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":21,"author":{"gitId":"MadLamprey"},"content":"describe(\u0027ErrorHandlingService\u0027, () \u003d\u003e {"},{"lineNumber":22,"author":{"gitId":"MadLamprey"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":23,"author":{"gitId":"MadLamprey"},"content":" mockLoggingService \u003d jasmine.createSpyObj(\u0027LoggingService\u0027, [\u0027error\u0027, \u0027debug\u0027]);"},{"lineNumber":24,"author":{"gitId":"MadLamprey"},"content":" mockSnackBar \u003d jasmine.createSpyObj(\u0027MatSnackBar\u0027, [\u0027openFromComponent\u0027]);"},{"lineNumber":25,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService \u003d new ErrorHandlingService(mockSnackBar, mockLoggingService);"},{"lineNumber":26,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":27,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":28,"author":{"gitId":"MadLamprey"},"content":" describe(\u0027ErrorHandlingService: handleError()\u0027, () \u003d\u003e {"},{"lineNumber":29,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should log errors when handling errors\u0027, () \u003d\u003e {"},{"lineNumber":30,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(STANDARD_ERROR);"},{"lineNumber":31,"author":{"gitId":"MadLamprey"},"content":" expect(mockLoggingService.error).toHaveBeenCalledWith(STANDARD_ERROR);"},{"lineNumber":32,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":33,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":34,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should use the GeneralMessageErrorComponent when handling Errors\u0027, () \u003d\u003e {"},{"lineNumber":35,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(STANDARD_ERROR);"},{"lineNumber":36,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledWith(GeneralMessageErrorComponent, {"},{"lineNumber":37,"author":{"gitId":"MadLamprey"},"content":" data: { message: STANDARD_ERROR.message }"},{"lineNumber":38,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":39,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":40,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":41,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should stringify Errors if there is no message before displaying\u0027, () \u003d\u003e {"},{"lineNumber":42,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(ERROR_WITH_NO_MESSAGE);"},{"lineNumber":43,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledWith(GeneralMessageErrorComponent, {"},{"lineNumber":44,"author":{"gitId":"MadLamprey"},"content":" data: { message: JSON.stringify(ERROR_WITH_NO_MESSAGE) }"},{"lineNumber":45,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":46,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":47,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":48,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should not open the snackbar when handling http status 304 errors\u0027, () \u003d\u003e {"},{"lineNumber":49,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(HTTP_304_ERROR);"},{"lineNumber":50,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).not.toHaveBeenCalled();"},{"lineNumber":51,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":52,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":53,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should use the FormErrorComponent when handling http status 422 errors\u0027, () \u003d\u003e {"},{"lineNumber":54,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(HTTP_422_ERROR);"},{"lineNumber":55,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledWith(FormErrorComponent, { data: HTTP_422_ERROR });"},{"lineNumber":56,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":57,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":58,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should use the GeneralMessageErrorComponent when handling other http errors\u0027, () \u003d\u003e {"},{"lineNumber":59,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(HTTP_500_ERROR);"},{"lineNumber":60,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledWith(GeneralMessageErrorComponent, { data: HTTP_500_ERROR });"},{"lineNumber":61,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(HTTP_400_ERROR);"},{"lineNumber":62,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledWith(GeneralMessageErrorComponent, { data: HTTP_400_ERROR });"},{"lineNumber":63,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(HTTP_401_ERROR);"},{"lineNumber":64,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledWith(GeneralMessageErrorComponent, { data: HTTP_401_ERROR });"},{"lineNumber":65,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(HTTP_404_ERROR);"},{"lineNumber":66,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledWith(GeneralMessageErrorComponent, { data: HTTP_404_ERROR });"},{"lineNumber":67,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(HTTP_UNKNOWN_ERROR);"},{"lineNumber":68,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledWith(GeneralMessageErrorComponent, { data: HTTP_UNKNOWN_ERROR });"},{"lineNumber":69,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledTimes(5);"},{"lineNumber":70,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":71,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":72,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should treat octokit request errors as http errors\u0027, () \u003d\u003e {"},{"lineNumber":73,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(OCTOKIT_REQUEST_ERROR);"},{"lineNumber":74,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledWith(GeneralMessageErrorComponent, { data: OCTOKIT_REQUEST_ERROR });"},{"lineNumber":75,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":76,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":77,"author":{"gitId":"MadLamprey"},"content":"});"}],"authorContributionMap":{"MadLamprey":77}},{"path":"tests/services/label.service.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { of } from \u0027rxjs\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Label } from \u0027../../src/app/core/models/label.model\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { GithubService } from \u0027../../src/app/core/services/github.service\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { LabelService } from \u0027../../src/app/core/services/label.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import * as LabelConstant from \u0027../constants/label.constants\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"let labelService: LabelService;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"let labelList: Label[];"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"let githubServiceSpy: jasmine.SpyObj\u003cGithubService\u003e;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":"describe(\u0027LabelService: fetchLabels()\u0027, () \u003d\u003e {"},{"lineNumber":12,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" githubServiceSpy \u003d jasmine.createSpyObj(\u0027GithubService\u0027, [\u0027fetchAllLabels\u0027]);"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" labelService \u003d new LabelService(githubServiceSpy);"},{"lineNumber":15,"author":{"gitId":"-"},"content":" });"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should fetch labels successfully\u0027, () \u003d\u003e {"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" const mockLabels \u003d LabelConstant.SEVERITY_LABELS;"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" const parsedLabels \u003d labelService.parseLabelData(mockLabels);"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" githubServiceSpy.fetchAllLabels.and.returnValue(of(mockLabels));"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" labelService.fetchLabels().subscribe((response) \u003d\u003e {"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" expect(response).toEqual(mockLabels);"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" expect(labelService.labels).toEqual(parsedLabels);"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" expect(labelService.simpleLabels).toEqual(parsedLabels);"},{"lineNumber":27,"author":{"gitId":"-"},"content":" });"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" expect(githubServiceSpy.fetchAllLabels).toHaveBeenCalled();"},{"lineNumber":30,"author":{"gitId":"-"},"content":" });"},{"lineNumber":31,"author":{"gitId":"-"},"content":"});"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":"describe(\u0027LabelService: parseLabelData()\u0027, () \u003d\u003e {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" beforeAll(() \u003d\u003e {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" labelService \u003d new LabelService(null);"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" labelList \u003d labelService.parseLabelData(LabelConstant.SEVERITY_LABELS);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" });"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" afterAll(() \u003d\u003e {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" labelService \u003d null;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" });"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should be severity very low label\u0027, () \u003d\u003e {"},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[0].name).toBe(LabelConstant.LABEL_NAME_SEVERITY_VERY_LOW);"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[0].color).toBe(LabelConstant.COLOR_SEVERITY_VERY_LOW);"},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[0].definition).toBe(LabelConstant.DEFINITION_SEVERITY_VERY_LOW);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" });"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should be severity low label\u0027, () \u003d\u003e {"},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[1].name).toBe(LabelConstant.LABEL_NAME_SEVERITY_LOW);"},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[1].color).toBe(LabelConstant.COLOR_SEVERITY_LOW);"},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[1].definition).toBe(LabelConstant.DEFINITION_SEVERITY_LOW);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" });"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should be severity medium label\u0027, () \u003d\u003e {"},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[2].name).toBe(LabelConstant.LABEL_NAME_SEVERITY_MEDIUM);"},{"lineNumber":57,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[2].color).toBe(LabelConstant.COLOR_SEVERITY_MEDIUM);"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[2].definition).toBe(LabelConstant.DEFINITION_SEVERITY_MEDIUM);"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":61,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should be severity high label\u0027, () \u003d\u003e {"},{"lineNumber":62,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[3].name).toBe(LabelConstant.LABEL_NAME_SEVERITY_HIGH);"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[3].color).toBe(LabelConstant.COLOR_SEVERITY_HIGH);"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[3].definition).toBe(LabelConstant.DEFINITION_SEVERITY_HIGH);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" });"},{"lineNumber":66,"author":{"gitId":"-"},"content":"});"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":"describe(\u0027LabelService: isDarkColor()\u0027, () \u003d\u003e {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" labelService \u003d new LabelService(null);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" });"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" afterEach(() \u003d\u003e {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" labelService \u003d null;"},{"lineNumber":75,"author":{"gitId":"-"},"content":" });"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" it(\u0027should be true for dark color\u0027, () \u003d\u003e {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" expect(labelService.isDarkColor(LabelConstant.COLOR_BLACK)).toBeTruthy();"},{"lineNumber":79,"author":{"gitId":"-"},"content":" });"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" it(\u0027should be false for light color\u0027, () \u003d\u003e {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" expect(labelService.isDarkColor(LabelConstant.COLOR_WHITE)).toBeFalsy();"},{"lineNumber":83,"author":{"gitId":"-"},"content":" });"},{"lineNumber":84,"author":{"gitId":"-"},"content":"});"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":"describe(\u0027LabelService: setLabelStyle()\u0027, () \u003d\u003e {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":88,"author":{"gitId":"-"},"content":" labelService \u003d new LabelService(null);"},{"lineNumber":89,"author":{"gitId":"-"},"content":" });"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" afterEach(() \u003d\u003e {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" labelService \u003d null;"},{"lineNumber":93,"author":{"gitId":"-"},"content":" });"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" it(\u0027should be dark color background with light color text\u0027, () \u003d\u003e {"},{"lineNumber":96,"author":{"gitId":"-"},"content":" expect(labelService.setLabelStyle(LabelConstant.COLOR_BLACK)).toEqual(LabelConstant.DARK_BG_LIGHT_TEXT);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" });"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" it(\u0027should be light color background with dark color text\u0027, () \u003d\u003e {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" expect(labelService.setLabelStyle(LabelConstant.COLOR_WHITE)).toEqual(LabelConstant.LIGHT_BG_DARK_TEXT);"},{"lineNumber":101,"author":{"gitId":"-"},"content":" });"},{"lineNumber":102,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"NereusWB922":34,"-":68}},{"path":"tests/services/milestone.service.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"MadLamprey"},"content":"import { of } from \u0027rxjs\u0027;"},{"lineNumber":2,"author":{"gitId":"MadLamprey"},"content":"import { Milestone } from \u0027../../src/app/core/models/milestone.model\u0027;"},{"lineNumber":3,"author":{"gitId":"MadLamprey"},"content":"import { GithubService } from \u0027../../src/app/core/services/github.service\u0027;"},{"lineNumber":4,"author":{"gitId":"MadLamprey"},"content":"import { MilestoneService } from \u0027../../src/app/core/services/milestone.service\u0027;"},{"lineNumber":5,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":6,"author":{"gitId":"MadLamprey"},"content":"let milestoneService: MilestoneService;"},{"lineNumber":7,"author":{"gitId":"MadLamprey"},"content":"let githubServiceSpy: jasmine.SpyObj\u003cGithubService\u003e;"},{"lineNumber":8,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":9,"author":{"gitId":"MadLamprey"},"content":"describe(\u0027MilestoneService\u0027, () \u003d\u003e {"},{"lineNumber":10,"author":{"gitId":"MadLamprey"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":11,"author":{"gitId":"MadLamprey"},"content":" githubServiceSpy \u003d jasmine.createSpyObj(\u0027GithubService\u0027, [\u0027fetchAllMilestones\u0027]);"},{"lineNumber":12,"author":{"gitId":"MadLamprey"},"content":" milestoneService \u003d new MilestoneService(githubServiceSpy);"},{"lineNumber":13,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":14,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":15,"author":{"gitId":"MadLamprey"},"content":" describe(\u0027MilestoneService: fetchMilestones()\u0027, () \u003d\u003e {"},{"lineNumber":16,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should fetch all milestones\u0027, (done) \u003d\u003e {"},{"lineNumber":17,"author":{"gitId":"MadLamprey"},"content":" const mockMilestones \u003d [{ title: \u0027Milestone 1\u0027 }, { title: \u0027Milestone 2\u0027 }];"},{"lineNumber":18,"author":{"gitId":"MadLamprey"},"content":" githubServiceSpy.fetchAllMilestones.and.returnValue(of(mockMilestones));"},{"lineNumber":19,"author":{"gitId":"MadLamprey"},"content":" milestoneService.fetchMilestones().subscribe((response) \u003d\u003e {"},{"lineNumber":20,"author":{"gitId":"MadLamprey"},"content":" expect(githubServiceSpy.fetchAllMilestones).toHaveBeenCalled();"},{"lineNumber":21,"author":{"gitId":"MadLamprey"},"content":" expect(milestoneService.milestones.length).toBe(2);"},{"lineNumber":22,"author":{"gitId":"MadLamprey"},"content":" expect(milestoneService.milestones[0].title).toBe(\u0027Milestone 1\u0027);"},{"lineNumber":23,"author":{"gitId":"MadLamprey"},"content":" expect(milestoneService.hasNoMilestones).toBeFalse();"},{"lineNumber":24,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":25,"author":{"gitId":"MadLamprey"},"content":" done();"},{"lineNumber":26,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":27,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":28,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":29,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should handle no milestones\u0027, (done) \u003d\u003e {"},{"lineNumber":30,"author":{"gitId":"MadLamprey"},"content":" githubServiceSpy.fetchAllMilestones.and.returnValue(of([]));"},{"lineNumber":31,"author":{"gitId":"MadLamprey"},"content":" milestoneService.fetchMilestones().subscribe((response) \u003d\u003e {"},{"lineNumber":32,"author":{"gitId":"MadLamprey"},"content":" expect(githubServiceSpy.fetchAllMilestones).toHaveBeenCalled();"},{"lineNumber":33,"author":{"gitId":"MadLamprey"},"content":" expect(milestoneService.milestones.length).toBe(0);"},{"lineNumber":34,"author":{"gitId":"MadLamprey"},"content":" expect(milestoneService.hasNoMilestones).toBeTrue();"},{"lineNumber":35,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":36,"author":{"gitId":"MadLamprey"},"content":" done();"},{"lineNumber":37,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":38,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":39,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":40,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":41,"author":{"gitId":"MadLamprey"},"content":" describe(\u0027MilestoneService: parseMilestoneData()\u0027, () \u003d\u003e {"},{"lineNumber":42,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should parse milestone data correctly\u0027, () \u003d\u003e {"},{"lineNumber":43,"author":{"gitId":"MadLamprey"},"content":" const mockMilestones \u003d [{ title: \u0027Milestone 2\u0027 }, { title: \u0027Milestone 1\u0027 }];"},{"lineNumber":44,"author":{"gitId":"MadLamprey"},"content":" const parsedMilestones \u003d milestoneService.parseMilestoneData(mockMilestones);"},{"lineNumber":45,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":46,"author":{"gitId":"MadLamprey"},"content":" for (const milestone of parsedMilestones) {"},{"lineNumber":47,"author":{"gitId":"MadLamprey"},"content":" expect(milestone).toBeInstanceOf(Milestone);"},{"lineNumber":48,"author":{"gitId":"MadLamprey"},"content":" }"},{"lineNumber":49,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":50,"author":{"gitId":"MadLamprey"},"content":" expect(parsedMilestones.length).toBe(2);"},{"lineNumber":51,"author":{"gitId":"MadLamprey"},"content":" expect(parsedMilestones[0].title).toBe(\u0027Milestone 1\u0027);"},{"lineNumber":52,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":53,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":54,"author":{"gitId":"MadLamprey"},"content":"});"}],"authorContributionMap":{"MadLamprey":54}},{"path":"tests/services/user.service.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { GithubService } from \u0027../../src/app/core/services/github.service\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { LoggingService } from \u0027../../src/app/core/services/logging.service\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { UserService } from \u0027../../src/app/core/services/user.service\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { USER_JUNWEI } from \u0027../constants/data.constants\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"let githubServiceSpy: jasmine.SpyObj\u003cGithubService\u003e;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"let loggingServiceSpy: jasmine.SpyObj\u003cLoggingService\u003e;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"let userService: UserService;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"describe(\u0027UserService\u0027, () \u003d\u003e {"},{"lineNumber":11,"author":{"gitId":"-"},"content":" beforeAll(() \u003d\u003e {"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" githubServiceSpy \u003d jasmine.createSpyObj(\u0027GithubService\u0027, [\u0027fetchAuthenticatedUser\u0027]);"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" loggingServiceSpy \u003d jasmine.createSpyObj(\u0027LoggingService\u0027, [\u0027info\u0027]);"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" userService \u003d new UserService(githubServiceSpy, loggingServiceSpy);"},{"lineNumber":15,"author":{"gitId":"-"},"content":" });"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027createUserModel(loginId)\u0027, () \u003d\u003e {"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should create a user correctly\u0027, async () \u003d\u003e {"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" const createdUser \u003d await userService.createUserModel(USER_JUNWEI.loginId).toPromise();"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" expect(createdUser).toEqual(USER_JUNWEI);"},{"lineNumber":21,"author":{"gitId":"-"},"content":" });"},{"lineNumber":22,"author":{"gitId":"-"},"content":" });"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027reset()\u0027, () \u003d\u003e {"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set current user as undefined\u0027, async () \u003d\u003e {"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" await userService.createUserModel(USER_JUNWEI.loginId).toPromise();"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" expect(userService.currentUser).toEqual(USER_JUNWEI);"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" userService.reset();"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" expect(loggingServiceSpy.info).toHaveBeenCalledWith(\u0027UserService: Clearing current user\u0027);"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" expect(userService.currentUser).toEqual(undefined);"},{"lineNumber":33,"author":{"gitId":"-"},"content":" });"},{"lineNumber":34,"author":{"gitId":"-"},"content":" });"},{"lineNumber":35,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"NereusWB922":20,"-":15}},{"path":"tests/services/view.service.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { ActivatedRoute, Router } from \u0027@angular/router\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { of } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { STORAGE_KEYS } from \u0027../../src/app/core/constants/storage-keys.constants\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { Repo } from \u0027../../src/app/core/models/repo.model\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import { View } from \u0027../../src/app/core/models/view.model\u0027;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"import { ErrorMessageService } from \u0027../../src/app/core/services/error-message.service\u0027;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"import { GithubService } from \u0027../../src/app/core/services/github.service\u0027;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"import { LoggingService } from \u0027../../src/app/core/services/logging.service\u0027;"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"import { RepoUrlCacheService } from \u0027../../src/app/core/services/repo-url-cache.service\u0027;"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"import { ViewService } from \u0027../../src/app/core/services/view.service\u0027;"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":"import { CATCHER_REPO, WATCHER_REPO } from \u0027../constants/session.constants\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":"let viewService: ViewService;"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"let githubServiceSpy: jasmine.SpyObj\u003cGithubService\u003e;"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":"let repoUrlCacheServiceSpy: jasmine.SpyObj\u003cRepoUrlCacheService\u003e;"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":"let loggingServiceSpy: jasmine.SpyObj\u003cLoggingService\u003e;"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":"let routerSpy: jasmine.SpyObj\u003cRouter\u003e;"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":"let activatedRouteSpy: jasmine.SpyObj\u003cActivatedRoute\u003e;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":"describe(\u0027ViewService\u0027, () \u003d\u003e {"},{"lineNumber":21,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" githubServiceSpy \u003d jasmine.createSpyObj(\u0027GithubService\u0027, [\u0027isRepositoryPresent\u0027, \u0027storeViewDetails\u0027]);"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" activatedRouteSpy \u003d jasmine.createSpyObj(\u0027ActivatedRoute\u0027, [\u0027snapshot\u0027]);"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" routerSpy \u003d jasmine.createSpyObj(\u0027Router\u0027, [\u0027navigate\u0027]);"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" repoUrlCacheServiceSpy \u003d jasmine.createSpyObj(\u0027RepoUrlCacheService\u0027, [\u0027cache\u0027]);"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" loggingServiceSpy \u003d jasmine.createSpyObj(\u0027LoggingService\u0027, [\u0027info\u0027]);"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" viewService \u003d new ViewService(githubServiceSpy, repoUrlCacheServiceSpy, loggingServiceSpy, activatedRouteSpy, routerSpy);"},{"lineNumber":28,"author":{"gitId":"-"},"content":" });"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027setRepository(Repo, Repo[])\u0027, () \u003d\u003e {"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set the current repositories and update session data\u0027, () \u003d\u003e {"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" const repos: Repo[] \u003d [CATCHER_REPO];"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" viewService.setRepository(WATCHER_REPO, repos);"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" expect(viewService.currentRepo).toEqual(WATCHER_REPO);"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":" expect(viewService.otherRepos).toEqual(repos);"},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" const currentSessionRepo \u003d viewService.sessionData.sessionRepo.find((x) \u003d\u003e x.view \u003d\u003d\u003d viewService.currentView);"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" expect(currentSessionRepo?.repos).toEqual([WATCHER_REPO, CATCHER_REPO]);"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should store view details via githubService and update localStorage\u0027, () \u003d\u003e {"},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" const localStorageSetItem \u003d spyOn(localStorage, \u0027setItem\u0027);"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":" viewService.setRepository(WATCHER_REPO);"},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" expect(githubServiceSpy.storeViewDetails).toHaveBeenCalledWith(WATCHER_REPO.owner, WATCHER_REPO.name);"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":" expect(localStorageSetItem).toHaveBeenCalledWith(\u0027sessionData\u0027, JSON.stringify(viewService.sessionData));"},{"lineNumber":50,"author":{"gitId":"-"},"content":" });"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should navigate to the new repository\u0027, () \u003d\u003e {"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" viewService.setRepository(WATCHER_REPO);"},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" expect(routerSpy.navigate).toHaveBeenCalledWith([\u0027issuesViewer\u0027], {"},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" queryParams: { repo: WATCHER_REPO.toString() },"},{"lineNumber":57,"author":{"gitId":"NereusWB922"},"content":" queryParamsHandling: \u0027merge\u0027"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":60,"author":{"gitId":"-"},"content":" });"},{"lineNumber":61,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":62,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027changeRepositoryIfValid(Repo)\u0027, () \u003d\u003e {"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set isChangingRepo to true at the start and false at the end\u0027, async () \u003d\u003e {"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" githubServiceSpy.isRepositoryPresent.and.returnValue(of(true));"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" const isChangingRepoNextSpy \u003d spyOn(viewService.isChangingRepo, \u0027next\u0027);"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":" spyOn(viewService, \u0027setRepository\u0027);"},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":" await viewService.changeRepositoryIfValid(WATCHER_REPO);"},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":71,"author":{"gitId":"NereusWB922"},"content":" expect(isChangingRepoNextSpy.calls.first().args[0]).toBe(true);"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" expect(isChangingRepoNextSpy.calls.mostRecent().args[0]).toBe(false);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" });"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should throw error if repository is not valid\u0027, async () \u003d\u003e {"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" githubServiceSpy.isRepositoryPresent.and.returnValue(of(false));"},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":" await expectAsync(viewService.changeRepositoryIfValid(WATCHER_REPO)).toBeRejectedWithError("},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":" ErrorMessageService.repositoryNotPresentMessage()"},{"lineNumber":81,"author":{"gitId":"NereusWB922"},"content":" );"},{"lineNumber":82,"author":{"gitId":"-"},"content":" });"},{"lineNumber":83,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":84,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set and navigate to new repo if repo is valid\u0027, async () \u003d\u003e {"},{"lineNumber":85,"author":{"gitId":"NereusWB922"},"content":" githubServiceSpy.isRepositoryPresent.and.returnValue(of(true));"},{"lineNumber":86,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":87,"author":{"gitId":"NereusWB922"},"content":" const repoChanged$Spy \u003d spyOn(viewService.repoChanged$, \u0027next\u0027);"},{"lineNumber":88,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":89,"author":{"gitId":"NereusWB922"},"content":" await viewService.changeRepositoryIfValid(WATCHER_REPO);"},{"lineNumber":90,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":91,"author":{"gitId":"NereusWB922"},"content":" expect(loggingServiceSpy.info).toHaveBeenCalledWith(`ViewService: Changing current repository to \u0027${WATCHER_REPO}\u0027`);"},{"lineNumber":92,"author":{"gitId":"NereusWB922"},"content":" expect(viewService.currentRepo).toEqual(WATCHER_REPO);"},{"lineNumber":93,"author":{"gitId":"NereusWB922"},"content":" expect(routerSpy.navigate).toHaveBeenCalledWith([\u0027issuesViewer\u0027], {"},{"lineNumber":94,"author":{"gitId":"NereusWB922"},"content":" queryParams: { repo: WATCHER_REPO.toString() },"},{"lineNumber":95,"author":{"gitId":"NereusWB922"},"content":" queryParamsHandling: \u0027merge\u0027"},{"lineNumber":96,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":97,"author":{"gitId":"NereusWB922"},"content":" expect(repoUrlCacheServiceSpy.cache).toHaveBeenCalledWith(WATCHER_REPO.toString());"},{"lineNumber":98,"author":{"gitId":"NereusWB922"},"content":" expect(repoChanged$Spy).toHaveBeenCalledWith(WATCHER_REPO);"},{"lineNumber":99,"author":{"gitId":"-"},"content":" });"},{"lineNumber":100,"author":{"gitId":"-"},"content":" });"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027initializeCurrentRepository()\u0027, () \u003d\u003e {"},{"lineNumber":103,"author":{"gitId":"NereusWB922"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":104,"author":{"gitId":"NereusWB922"},"content":" const org \u003d WATCHER_REPO.owner;"},{"lineNumber":105,"author":{"gitId":"NereusWB922"},"content":" const repoName \u003d WATCHER_REPO.name;"},{"lineNumber":106,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":107,"author":{"gitId":"NereusWB922"},"content":" const localStorageGetItemSpy \u003d spyOn(window.localStorage, \u0027getItem\u0027);"},{"lineNumber":108,"author":{"gitId":"NereusWB922"},"content":" localStorageGetItemSpy.withArgs(STORAGE_KEYS.ORG).and.returnValue(org);"},{"lineNumber":109,"author":{"gitId":"NereusWB922"},"content":" localStorageGetItemSpy.withArgs(STORAGE_KEYS.DATA_REPO).and.returnValue(repoName);"},{"lineNumber":110,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":111,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":112,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set and navigate to new repo if repo is valid\u0027, async () \u003d\u003e {"},{"lineNumber":113,"author":{"gitId":"NereusWB922"},"content":" githubServiceSpy.isRepositoryPresent.and.returnValue(of(true));"},{"lineNumber":114,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":115,"author":{"gitId":"NereusWB922"},"content":" const repoSetSourceNext \u003d spyOn(viewService.repoSetSource, \u0027next\u0027);"},{"lineNumber":116,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":117,"author":{"gitId":"NereusWB922"},"content":" await viewService.initializeCurrentRepository();"},{"lineNumber":118,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":119,"author":{"gitId":"NereusWB922"},"content":" expect(loggingServiceSpy.info).toHaveBeenCalledWith(`ViewService: Repo is ${WATCHER_REPO}`);"},{"lineNumber":120,"author":{"gitId":"NereusWB922"},"content":" expect(viewService.currentRepo).toEqual(WATCHER_REPO);"},{"lineNumber":121,"author":{"gitId":"NereusWB922"},"content":" expect(routerSpy.navigate).toHaveBeenCalledWith([\u0027issuesViewer\u0027], {"},{"lineNumber":122,"author":{"gitId":"NereusWB922"},"content":" queryParams: { repo: WATCHER_REPO.toString() },"},{"lineNumber":123,"author":{"gitId":"NereusWB922"},"content":" queryParamsHandling: \u0027merge\u0027"},{"lineNumber":124,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":125,"author":{"gitId":"NereusWB922"},"content":" expect(repoSetSourceNext).toHaveBeenCalledWith(true);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" });"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should throw error if repository is invalid\u0027, async () \u003d\u003e {"},{"lineNumber":129,"author":{"gitId":"NereusWB922"},"content":" githubServiceSpy.isRepositoryPresent.and.returnValue(of(false));"},{"lineNumber":130,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":131,"author":{"gitId":"NereusWB922"},"content":" await expectAsync(viewService.initializeCurrentRepository()).toBeRejectedWithError(ErrorMessageService.repositoryNotPresentMessage());"},{"lineNumber":132,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":133,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":134,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":135,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027changeView(View)\u0027, () \u003d\u003e {"},{"lineNumber":136,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set current view\u0027, () \u003d\u003e {"},{"lineNumber":137,"author":{"gitId":"NereusWB922"},"content":" viewService.setRepository(WATCHER_REPO);"},{"lineNumber":138,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":139,"author":{"gitId":"NereusWB922"},"content":" expect(viewService.currentView).toEqual(View.issuesViewer);"},{"lineNumber":140,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":141,"author":{"gitId":"NereusWB922"},"content":" viewService.changeView(View.activityDashboard);"},{"lineNumber":142,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":143,"author":{"gitId":"NereusWB922"},"content":" expect(viewService.currentView).toEqual(View.activityDashboard);"},{"lineNumber":144,"author":{"gitId":"-"},"content":" });"},{"lineNumber":145,"author":{"gitId":"-"},"content":" });"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" describe(\u0027.reset()\u0027, () \u003d\u003e {"},{"lineNumber":148,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should reset the currentView of the ViewService\u0027, () \u003d\u003e {"},{"lineNumber":149,"author":{"gitId":"NereusWB922"},"content":" viewService.currentView \u003d View.activityDashboard;"},{"lineNumber":150,"author":{"gitId":"NereusWB922"},"content":" viewService.reset();"},{"lineNumber":151,"author":{"gitId":"NereusWB922"},"content":" expect(viewService.currentView).toBe(View.issuesViewer);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" });"},{"lineNumber":153,"author":{"gitId":"-"},"content":" });"},{"lineNumber":154,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":155,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027setupFromUrl(url)\u0027, () \u003d\u003e {"},{"lineNumber":156,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set items in local storage if url is valid\u0027, async () \u003d\u003e {"},{"lineNumber":157,"author":{"gitId":"NereusWB922"},"content":" const validUrl \u003d `/issuesViewer?repo\u003d${WATCHER_REPO.owner}%2F${WATCHER_REPO.name}`;"},{"lineNumber":158,"author":{"gitId":"NereusWB922"},"content":" const localStorageSetItemSpy \u003d spyOn(window.localStorage, \u0027setItem\u0027);"},{"lineNumber":159,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":160,"author":{"gitId":"NereusWB922"},"content":" await viewService.setupFromUrl(validUrl).toPromise();"},{"lineNumber":161,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":162,"author":{"gitId":"NereusWB922"},"content":" expect(localStorageSetItemSpy).toHaveBeenCalledWith(STORAGE_KEYS.ORG, WATCHER_REPO.owner);"},{"lineNumber":163,"author":{"gitId":"NereusWB922"},"content":" expect(localStorageSetItemSpy).toHaveBeenCalledWith(STORAGE_KEYS.DATA_REPO, WATCHER_REPO.name);"},{"lineNumber":164,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":165,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":166,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should throw error for url without repo paramater\u0027, (done) \u003d\u003e {"},{"lineNumber":167,"author":{"gitId":"NereusWB922"},"content":" const urlWithoutRepo \u003d \u0027/issuesViewer\u0027;"},{"lineNumber":168,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":169,"author":{"gitId":"NereusWB922"},"content":" viewService.setupFromUrl(urlWithoutRepo).subscribe({"},{"lineNumber":170,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e {"},{"lineNumber":171,"author":{"gitId":"NereusWB922"},"content":" expect(err).toEqual(new Error(ErrorMessageService.invalidUrlMessage()));"},{"lineNumber":172,"author":{"gitId":"NereusWB922"},"content":" done();"},{"lineNumber":173,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":174,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":175,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":176,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":177,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should throw error for empty url\u0027, (done) \u003d\u003e {"},{"lineNumber":178,"author":{"gitId":"NereusWB922"},"content":" const emptyUrl \u003d \u0027\u0027;"},{"lineNumber":179,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":180,"author":{"gitId":"NereusWB922"},"content":" viewService.setupFromUrl(emptyUrl).subscribe({"},{"lineNumber":181,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e {"},{"lineNumber":182,"author":{"gitId":"NereusWB922"},"content":" expect(err).toEqual(new Error(ErrorMessageService.invalidUrlMessage()));"},{"lineNumber":183,"author":{"gitId":"NereusWB922"},"content":" done();"},{"lineNumber":184,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":185,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":186,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":187,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":188,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should throw error for url with invalid repo format\u0027, (done) \u003d\u003e {"},{"lineNumber":189,"author":{"gitId":"NereusWB922"},"content":" const urlWithInvalidRepoFormat \u003d \u0027/issuesViewer?repo\u003dInvalidRepo\u0027;"},{"lineNumber":190,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":191,"author":{"gitId":"NereusWB922"},"content":" viewService.setupFromUrl(urlWithInvalidRepoFormat).subscribe({"},{"lineNumber":192,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e {"},{"lineNumber":193,"author":{"gitId":"NereusWB922"},"content":" expect(err).toEqual(new Error(ErrorMessageService.repositoryNotPresentMessage()));"},{"lineNumber":194,"author":{"gitId":"NereusWB922"},"content":" done();"},{"lineNumber":195,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":196,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":197,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":198,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":199,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"NereusWB922":175,"-":24}}] +[{"path":"src/app/activity-dashboard/activity-dashboard.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":".event-tables-wrapper {"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" display: flex;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" overflow-x: auto;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":4}},{"path":"src/app/activity-dashboard/activity-dashboard.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cdiv\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" \u003cmat-grid-list cols\u003d\"4\" rowHeight\u003d\"80px\"\u003e"},{"lineNumber":3,"author":{"gitId":"-"},"content":" \u003cmat-grid-tile\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"grid-flush-left\"\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":" \u003ch1 class\u003d\"mat-headline\" style\u003d\"margin: 0px\"\u003eActivity\u003c/h1\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":7,"author":{"gitId":"-"},"content":" \u003c/mat-grid-tile\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":" \u003cmat-grid-tile\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003cmat-form-field appearance\u003d\"fill\"\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003cmat-label\u003eStart Date\u003c/mat-label\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003cinput matInput [min]\u003d\"startMinDate\" [max]\u003d\"startMaxDate\" [matDatepicker]\u003d\"startPicker\" (dateChange)\u003d\"pickStartDate($event)\" /\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003cmat-hint\u003eMM/DD/YYYY\u003c/mat-hint\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":" \u003cmat-datepicker-toggle matSuffix [for]\u003d\"startPicker\"\u003e\u003c/mat-datepicker-toggle\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":" \u003cmat-datepicker startView\u003d\"year\" #startPicker\u003e\u003c/mat-datepicker\u003e"},{"lineNumber":16,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":" \u003c/mat-grid-tile\u003e"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":" \u003cmat-grid-tile\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003cmat-form-field appearance\u003d\"fill\"\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003cmat-label\u003eEnd Date\u003c/mat-label\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u003cinput matInput [min]\u003d\"endMinDate\" [max]\u003d\"endMaxDate\" [matDatepicker]\u003d\"endPicker\" (dateChange)\u003d\"pickEndDate($event)\" /\u003e"},{"lineNumber":23,"author":{"gitId":"-"},"content":" \u003cmat-hint\u003eMM/DD/YYYY\u003c/mat-hint\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":" \u003cmat-datepicker-toggle matSuffix [for]\u003d\"endPicker\"\u003e\u003c/mat-datepicker-toggle\u003e"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u003cmat-datepicker startView\u003d\"year\" #endPicker\u003e\u003c/mat-datepicker\u003e"},{"lineNumber":26,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003c/mat-grid-tile\u003e"},{"lineNumber":28,"author":{"gitId":"-"},"content":" \u003c/mat-grid-list\u003e"},{"lineNumber":29,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":"\u003cdiv class\u003d\"event-tables-wrapper\"\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003capp-event-tables"},{"lineNumber":33,"author":{"gitId":"-"},"content":" *ngFor\u003d\"let assignee of assignees\""},{"lineNumber":34,"author":{"gitId":"-"},"content":" class\u003d\"issue-table\""},{"lineNumber":35,"author":{"gitId":"-"},"content":" [actor]\u003d\"assignee\""},{"lineNumber":36,"author":{"gitId":"-"},"content":" [columnsToDisplay]\u003d\"this.displayedColumns\""},{"lineNumber":37,"author":{"gitId":"-"},"content":" [expandedColumnsToDisplay]\u003d\"this.expandedColumns\""},{"lineNumber":38,"author":{"gitId":"-"},"content":" [actions]\u003d\"this.actionButtons\""},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003e\u003c/app-event-tables\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"NereusWB922":1,"-":39}},{"path":"src/app/activity-dashboard/activity-dashboard.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component, OnInit, QueryList, ViewChildren } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { MatDatepickerInputEvent } from \u0027@angular/material/datepicker\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import * as moment from \u0027moment\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { GithubUser } from \u0027../core/models/github-user.model\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027../core/services/github.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { GithubEventService } from \u0027../core/services/githubevent.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { EXPANDED_TABLE_COLUMNS, TABLE_COLUMNS } from \u0027./event-tables/event-tables-columns\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { ACTION_BUTTONS, EventTablesComponent } from \u0027./event-tables/event-tables.component\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":11,"author":{"gitId":"-"},"content":" selector: \u0027app-activity-dashboard\u0027,"},{"lineNumber":12,"author":{"gitId":"-"},"content":" templateUrl: \u0027./activity-dashboard.component.html\u0027,"},{"lineNumber":13,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./activity-dashboard.component.css\u0027]"},{"lineNumber":14,"author":{"gitId":"-"},"content":"})"},{"lineNumber":15,"author":{"gitId":"-"},"content":"export class ActivityDashboardComponent implements OnInit {"},{"lineNumber":16,"author":{"gitId":"-"},"content":" readonly displayedColumns \u003d [TABLE_COLUMNS.DATE_START, TABLE_COLUMNS.ISSUE_COUNT, TABLE_COLUMNS.PR_COUNT, TABLE_COLUMNS.COMMENT_COUNT];"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" readonly expandedColumns \u003d [EXPANDED_TABLE_COLUMNS.TITLE, EXPANDED_TABLE_COLUMNS.DATE];"},{"lineNumber":18,"author":{"gitId":"-"},"content":" readonly actionButtons: ACTION_BUTTONS[] \u003d [ACTION_BUTTONS.VIEW_IN_WEB];"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" startMinDate: Date;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" startMaxDate \u003d moment().endOf(\u0027day\u0027).toDate();"},{"lineNumber":22,"author":{"gitId":"-"},"content":" endMinDate: Date;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" endMaxDate \u003d moment().endOf(\u0027day\u0027).toDate();"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" assignees: GithubUser[];"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @ViewChildren(EventTablesComponent) tables: QueryList\u003cEventTablesComponent\u003e;"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" constructor(private githubService: GithubService, private githubEventService: GithubEventService) {}"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" ngOnInit() {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" this.githubEventService.getEvents();"},{"lineNumber":33,"author":{"gitId":"-"},"content":" this.githubService.getUsersAssignable().subscribe((x) \u003d\u003e (this.assignees \u003d x));"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" pickStartDate(event: MatDatepickerInputEvent\u003cDate\u003e) {"},{"lineNumber":37,"author":{"gitId":"-"},"content":" this.endMinDate \u003d event.value;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" this.tables.forEach((t) \u003d\u003e (t.githubEvents.start \u003d `${event.value}`));"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" pickEndDate(event: MatDatepickerInputEvent\u003cDate\u003e) {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" this.startMaxDate \u003d event.value;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" this.tables.forEach((t) \u003d\u003e (t.githubEvents.end \u003d `${event.value}`));"},{"lineNumber":44,"author":{"gitId":"-"},"content":" }"},{"lineNumber":45,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"NereusWB922":1,"-":44}},{"path":"src/app/activity-dashboard/activity-dashboard.module.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { CommonModule } from \u0027@angular/common\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { NgModule } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { SharedModule } from \u0027../shared/shared.module\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { ActivityDashboardRoutingModule } from \u0027./activity-dashboard-routing.module\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { ActivityDashboardComponent } from \u0027./activity-dashboard.component\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { EventTablesModule } from \u0027./event-tables/event-tables.module\u0027;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"import { EventWeekDetailsComponent } from \u0027./event-week-details/event-week-details.component\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"@NgModule({"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" declarations: [ActivityDashboardComponent, EventWeekDetailsComponent],"},{"lineNumber":11,"author":{"gitId":"-"},"content":" imports: [CommonModule, SharedModule, ActivityDashboardRoutingModule, EventTablesModule]"},{"lineNumber":12,"author":{"gitId":"-"},"content":"})"},{"lineNumber":13,"author":{"gitId":"-"},"content":"export class ActivityDashboardModule {}"}],"authorContributionMap":{"NereusWB922":2,"-":11}},{"path":"src/app/activity-dashboard/event-tables/event-tables.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":".table-container {"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" margin: 10px;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" min-width: 400px;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":".actor-card {"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" display: flex;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" align-items: center;"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" padding: 10px;"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" margin-bottom: 1px;"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":".actor-username {"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" flex-grow: 1;"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" font-size: 15px;"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" margin: 0;"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" text-align: center;"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" word-break: break-word;"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":".avatar-container {"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" margin-right: 10px;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"}"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":".mat-table {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" /* flex-wrap: wrap; */"},{"lineNumber":27,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"}"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":".mat-cell {"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" display: flex;"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" align-items: center;"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" justify-content: center;"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" text-align: center;"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" padding: 0;"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":".mat-header-cell {"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" display: flex;"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" align-items: center;"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" justify-content: center;"},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":" text-align: center;"},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":" padding: 0;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"}"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":".mat-header-row {"},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" white-space: nowrap;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"}"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":".example-element-row:hover {"},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":" border: 3px solid rgba(0, 0, 0, 0.514);"},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" border-radius: 3px;"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" color: #210749;"},{"lineNumber":54,"author":{"gitId":"-"},"content":"}"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":".example-element-row td {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" border-bottom-width: 0;"},{"lineNumber":58,"author":{"gitId":"-"},"content":"}"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":".example-element-detail {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" overflow: hidden;"},{"lineNumber":62,"author":{"gitId":"-"},"content":" display: flex;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":64,"author":{"gitId":"-"},"content":"}"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":"/* Colour cells */"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":".white {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" background-color: white;"},{"lineNumber":70,"author":{"gitId":"-"},"content":"}"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":".pale-green {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" background-color: palegreen;"},{"lineNumber":74,"author":{"gitId":"-"},"content":"}"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":".green {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" background-color: green;"},{"lineNumber":78,"author":{"gitId":"-"},"content":"}"},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":".scrollable-container {"},{"lineNumber":81,"author":{"gitId":"NereusWB922"},"content":" height: 53vh;"},{"lineNumber":82,"author":{"gitId":"NereusWB922"},"content":" overflow: auto;"},{"lineNumber":83,"author":{"gitId":"NereusWB922"},"content":" margin-bottom: 2px;"},{"lineNumber":84,"author":{"gitId":"NereusWB922"},"content":" scrollbar-width: none;"},{"lineNumber":85,"author":{"gitId":"NereusWB922"},"content":" position: relative;"},{"lineNumber":86,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":87,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":88,"author":{"gitId":"NereusWB922"},"content":".scrollable-container::-webkit-scrollbar {"},{"lineNumber":89,"author":{"gitId":"NereusWB922"},"content":" display: none;"},{"lineNumber":90,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":91,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":92,"author":{"gitId":"NereusWB922"},"content":"/* Ref: https://css-scroll-shadows.vercel.app */"},{"lineNumber":93,"author":{"gitId":"NereusWB922"},"content":".scrollable-container::before {"},{"lineNumber":94,"author":{"gitId":"NereusWB922"},"content":" pointer-events: none;"},{"lineNumber":95,"author":{"gitId":"NereusWB922"},"content":" content: \u0027\u0027;"},{"lineNumber":96,"author":{"gitId":"NereusWB922"},"content":" position: absolute;"},{"lineNumber":97,"author":{"gitId":"NereusWB922"},"content":" z-index: 2;"},{"lineNumber":98,"author":{"gitId":"NereusWB922"},"content":" height: 6px;"},{"lineNumber":99,"author":{"gitId":"NereusWB922"},"content":" width: 100%;"},{"lineNumber":100,"author":{"gitId":"NereusWB922"},"content":" display: block;"},{"lineNumber":101,"author":{"gitId":"NereusWB922"},"content":" background-image: linear-gradient(to bottom, white 66%, transparent);"},{"lineNumber":102,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":103,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":104,"author":{"gitId":"NereusWB922"},"content":".scrollable-container::after {"},{"lineNumber":105,"author":{"gitId":"NereusWB922"},"content":" pointer-events: none;"},{"lineNumber":106,"author":{"gitId":"NereusWB922"},"content":" content: \u0027\u0027;"},{"lineNumber":107,"author":{"gitId":"NereusWB922"},"content":" position: sticky;"},{"lineNumber":108,"author":{"gitId":"NereusWB922"},"content":" z-index: 2;"},{"lineNumber":109,"author":{"gitId":"NereusWB922"},"content":" top: 100%;"},{"lineNumber":110,"author":{"gitId":"NereusWB922"},"content":" height: 6px;"},{"lineNumber":111,"author":{"gitId":"NereusWB922"},"content":" width: 100%;"},{"lineNumber":112,"author":{"gitId":"NereusWB922"},"content":" display: block;"},{"lineNumber":113,"author":{"gitId":"NereusWB922"},"content":" background-image: linear-gradient(to top, white 66%, transparent);"},{"lineNumber":114,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":115,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":116,"author":{"gitId":"NereusWB922"},"content":".scrollable-container-wrapper {"},{"lineNumber":117,"author":{"gitId":"NereusWB922"},"content":" position: relative;"},{"lineNumber":118,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":119,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":120,"author":{"gitId":"NereusWB922"},"content":".scrollable-container-wrapper::before {"},{"lineNumber":121,"author":{"gitId":"NereusWB922"},"content":" pointer-events: none;"},{"lineNumber":122,"author":{"gitId":"NereusWB922"},"content":" content: \u0027\u0027;"},{"lineNumber":123,"author":{"gitId":"NereusWB922"},"content":" position: absolute;"},{"lineNumber":124,"author":{"gitId":"NereusWB922"},"content":" z-index: 1;"},{"lineNumber":125,"author":{"gitId":"NereusWB922"},"content":" top: 0;"},{"lineNumber":126,"author":{"gitId":"NereusWB922"},"content":" left: 0;"},{"lineNumber":127,"author":{"gitId":"NereusWB922"},"content":" right: 0;"},{"lineNumber":128,"author":{"gitId":"NereusWB922"},"content":" height: 5px;"},{"lineNumber":129,"author":{"gitId":"NereusWB922"},"content":" background-image: radial-gradient(farthest-side at 50% 0, rgba(0, 0, 0, 0.5), transparent);"},{"lineNumber":130,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":131,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":132,"author":{"gitId":"NereusWB922"},"content":".scrollable-container-wrapper::after {"},{"lineNumber":133,"author":{"gitId":"NereusWB922"},"content":" pointer-events: none;"},{"lineNumber":134,"author":{"gitId":"NereusWB922"},"content":" content: \u0027\u0027;"},{"lineNumber":135,"author":{"gitId":"NereusWB922"},"content":" position: absolute;"},{"lineNumber":136,"author":{"gitId":"NereusWB922"},"content":" z-index: 1;"},{"lineNumber":137,"author":{"gitId":"NereusWB922"},"content":" bottom: 0;"},{"lineNumber":138,"author":{"gitId":"NereusWB922"},"content":" left: 0;"},{"lineNumber":139,"author":{"gitId":"NereusWB922"},"content":" right: 0;"},{"lineNumber":140,"author":{"gitId":"NereusWB922"},"content":" height: 5px;"},{"lineNumber":141,"author":{"gitId":"NereusWB922"},"content":" background-image: radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, 0.5), transparent);"},{"lineNumber":142,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":105,"-":37}},{"path":"src/app/activity-dashboard/event-tables/event-tables.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"table-container\"\u003e"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card class\u003d\"actor-card\"\u003e"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" mat-card-avatar"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" *ngIf\u003d\"this.actor\""},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" class\u003d\"avatar-container\""},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" [ngStyle]\u003d\"{"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" background: \u0027url(\u0027 + this.actor.avatar_url + \u0027)\u0027,"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" \u0027background-size\u0027: \u002740px\u0027"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" }\""},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" \u003e\u003c/div\u003e"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card-title class\u003d\"actor-username\"\u003e"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" {{ this.actor !\u003d\u003d undefined ? this.actor.login : \u0027Unknown\u0027 }}"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card-title\u003e"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card\u003e"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv class\u003d\"scrollable-container-wrapper\"\u003e"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv class\u003d\"scrollable-container\"\u003e"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-table [dataSource]\u003d\"this.githubEvents\" matSort multiTemplateDataRows\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003cng-container matColumnDef\u003d\"date_start\"\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003cmat-header-cell *matHeaderCellDef mat-sort-header\u003e Date \u003c/mat-header-cell\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u003cmat-cell *matCellDef\u003d\"let element\"\u003e"},{"lineNumber":23,"author":{"gitId":"-"},"content":" \u003cspan (click)\u003d\"$event.stopPropagation()\" style\u003d\"cursor: default\"\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":" {{ element.date_start }}"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":26,"author":{"gitId":"-"},"content":" \u003c/mat-cell\u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" \u003cng-container matColumnDef\u003d\"issue_count\"\u003e"},{"lineNumber":30,"author":{"gitId":"-"},"content":" \u003cmat-header-cell *matHeaderCellDef mat-sort-header\u003e Issue # \u003c/mat-header-cell\u003e"},{"lineNumber":31,"author":{"gitId":"-"},"content":" \u003cmat-cell *matCellDef\u003d\"let element\" [ngClass]\u003d\"colorCell(element.issue_count)\"\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003cspan (click)\u003d\"$event.stopPropagation()\" style\u003d\"cursor: default\"\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" {{ element.issue_count }}"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":" \u003c/mat-cell\u003e"},{"lineNumber":36,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" \u003cng-container matColumnDef\u003d\"pr_count\"\u003e"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003cmat-header-cell *matHeaderCellDef mat-sort-header\u003e PR # \u003c/mat-header-cell\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003cmat-cell *matCellDef\u003d\"let element\" [ngClass]\u003d\"colorCell(element.pr_count)\"\u003e"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003cspan (click)\u003d\"$event.stopPropagation()\" style\u003d\"cursor: default\"\u003e"},{"lineNumber":42,"author":{"gitId":"-"},"content":" {{ element.pr_count }}"},{"lineNumber":43,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u003c/mat-cell\u003e"},{"lineNumber":45,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" \u003cng-container matColumnDef\u003d\"comment_count\"\u003e"},{"lineNumber":48,"author":{"gitId":"-"},"content":" \u003cmat-header-cell *matHeaderCellDef mat-sort-header\u003e Comment # \u003c/mat-header-cell\u003e"},{"lineNumber":49,"author":{"gitId":"-"},"content":" \u003cmat-cell *matCellDef\u003d\"let element\" [ngClass]\u003d\"colorCell(element.comment_count)\"\u003e"},{"lineNumber":50,"author":{"gitId":"-"},"content":" \u003cspan (click)\u003d\"$event.stopPropagation()\" style\u003d\"cursor: default\"\u003e"},{"lineNumber":51,"author":{"gitId":"-"},"content":" {{ element.comment_count }}"},{"lineNumber":52,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":53,"author":{"gitId":"-"},"content":" \u003c/mat-cell\u003e"},{"lineNumber":54,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-header-row *matHeaderRowDef\u003d\"this.columnsToDisplay\"\u003e\u003c/mat-header-row\u003e"},{"lineNumber":57,"author":{"gitId":"-"},"content":" \u003cmat-row"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" *matRowDef\u003d\"let eventWeek; columns: this.columnsToDisplay\""},{"lineNumber":59,"author":{"gitId":"-"},"content":" class\u003d\"example-element-row\""},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":" (click)\u003d\"openDialog(eventWeek)\""},{"lineNumber":61,"author":{"gitId":"-"},"content":" \u003e\u003c/mat-row\u003e"},{"lineNumber":62,"author":{"gitId":"-"},"content":" \u003c/mat-table\u003e"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" \u003c/div\u003e"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" \u003c/div\u003e"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" \u003cmat-card *ngIf\u003d\"this.githubEvents.isLoading$ | async\" style\u003d\"display: flex; justify-content: center; align-items: center\"\u003e"},{"lineNumber":67,"author":{"gitId":"-"},"content":" \u003cmat-progress-spinner color\u003d\"primary\" mode\u003d\"indeterminate\" diameter\u003d\"50\" strokeWidth\u003d\"5\"\u003e\u003c/mat-progress-spinner\u003e"},{"lineNumber":68,"author":{"gitId":"-"},"content":" \u003c/mat-card\u003e"},{"lineNumber":69,"author":{"gitId":"-"},"content":" \u003cmat-paginator [pageSize]\u003d\"20\" [pageSizeOptions]\u003d\"[10, 20, 50]\"\u003e\u003c/mat-paginator\u003e"},{"lineNumber":70,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"NereusWB922":22,"-":48}},{"path":"src/app/activity-dashboard/event-tables/event-tables.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { animate, state, style, transition, trigger } from \u0027@angular/animations\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { AfterViewInit, Component, Input, OnInit, ViewChild } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { MatDialog } from \u0027@angular/material/dialog\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { MatPaginator } from \u0027@angular/material/paginator\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { MatSort } from \u0027@angular/material/sort\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { GithubUser } from \u0027../../core/models/github-user.model\u0027;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"import { ErrorHandlingService } from \u0027../../core/services/error-handling.service\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { GithubEventService } from \u0027../../core/services/githubevent.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027../../core/services/logging.service\u0027;"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"import { EventWeekDetailsComponent } from \u0027../event-week-details/event-week-details.component\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { EventWeek } from \u0027../event-week.model\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { GithubEventDataTable } from \u0027./GithubEventDataTable\u0027;"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":"import { NoEventsError } from \u0027./no-events-error.model\u0027;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"export enum ACTION_BUTTONS {"},{"lineNumber":16,"author":{"gitId":"-"},"content":" VIEW_IN_WEB,"},{"lineNumber":17,"author":{"gitId":"-"},"content":" COLLAPSE"},{"lineNumber":18,"author":{"gitId":"-"},"content":"}"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":21,"author":{"gitId":"-"},"content":" selector: \u0027app-event-tables\u0027,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" templateUrl: \u0027./event-tables.component.html\u0027,"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" styleUrls: [\u0027./event-tables.component.css\u0027]"},{"lineNumber":24,"author":{"gitId":"-"},"content":"})"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":27,"author":{"gitId":"-"},"content":" * Angular Table Expandable Rows"},{"lineNumber":28,"author":{"gitId":"-"},"content":" * ref: https://material.angular.io/components/table/examples#table-expandable-rows"},{"lineNumber":29,"author":{"gitId":"-"},"content":" */"},{"lineNumber":30,"author":{"gitId":"-"},"content":"export class EventTablesComponent implements OnInit, AfterViewInit {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" @Input() columnsToDisplay: string[];"},{"lineNumber":32,"author":{"gitId":"-"},"content":" @Input() expandedColumnsToDisplay: string[];"},{"lineNumber":33,"author":{"gitId":"-"},"content":" @Input() actions: ACTION_BUTTONS[];"},{"lineNumber":34,"author":{"gitId":"-"},"content":" @Input() actor?: GithubUser \u003d undefined;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" @Input() filters?: any \u003d undefined;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" @ViewChild(MatSort, { static: true }) sort: MatSort;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" githubEvents: GithubEventDataTable;"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" public readonly action_buttons \u003d ACTION_BUTTONS;"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" constructor("},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" public githubEventService: GithubEventService,"},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":" public dialog: MatDialog,"},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" private logger: LoggingService,"},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" private errorHandling: ErrorHandlingService"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":" ) {}"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" ngOnInit() {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" this.githubEvents \u003d new GithubEventDataTable(this.githubEventService, this.logger, this.sort, this.paginator, this.actor, this.filters);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" ngAfterViewInit(): void {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" setTimeout(() \u003d\u003e {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" this.githubEvents.loadEvents();"},{"lineNumber":58,"author":{"gitId":"-"},"content":" });"},{"lineNumber":59,"author":{"gitId":"-"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" reload() {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" this.githubEvents.loadEvents();"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":66,"author":{"gitId":"-"},"content":" * Formats the title text to account for those that contain long words."},{"lineNumber":67,"author":{"gitId":"-"},"content":" * @param title - Title of Event that is to be displayed in the Table Row."},{"lineNumber":68,"author":{"gitId":"-"},"content":" */"},{"lineNumber":69,"author":{"gitId":"-"},"content":" fitTitleText(title: string): string {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" // Arbitrary Length of Characters beyond which an overflow occurs."},{"lineNumber":71,"author":{"gitId":"-"},"content":" const MAX_WORD_LENGTH \u003d 43;"},{"lineNumber":72,"author":{"gitId":"-"},"content":" const SPLITTER_TEXT \u003d \u0027 \u0027;"},{"lineNumber":73,"author":{"gitId":"-"},"content":" const ELLIPSES \u003d \u0027...\u0027;"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" return title"},{"lineNumber":76,"author":{"gitId":"-"},"content":" .split(SPLITTER_TEXT)"},{"lineNumber":77,"author":{"gitId":"-"},"content":" .map((word) \u003d\u003e {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" if (word.length \u003e MAX_WORD_LENGTH) {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" return word.substring(0, MAX_WORD_LENGTH - 5).concat(ELLIPSES);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" }"},{"lineNumber":81,"author":{"gitId":"-"},"content":" return word;"},{"lineNumber":82,"author":{"gitId":"-"},"content":" })"},{"lineNumber":83,"author":{"gitId":"-"},"content":" .join(SPLITTER_TEXT);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" /** Not implemented yet. */"},{"lineNumber":87,"author":{"gitId":"-"},"content":" viewEventInBrowser(id: number, event: Event) {"},{"lineNumber":88,"author":{"gitId":"-"},"content":" this.logger.info(`EventTablesComponent: Opening Event ${id} on Github`);"},{"lineNumber":89,"author":{"gitId":"-"},"content":" // window.open(\u0027https://github.com/\u0027, \u0027_blank\u0027);"},{"lineNumber":90,"author":{"gitId":"-"},"content":" }"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"NereusWB922"},"content":" /** Opens dialog to show the event details of the selected week. */"},{"lineNumber":93,"author":{"gitId":"NereusWB922"},"content":" openDialog(eventWeek: EventWeek) {"},{"lineNumber":94,"author":{"gitId":"NereusWB922"},"content":" if (eventWeek.events.length \u003c\u003d 0) {"},{"lineNumber":95,"author":{"gitId":"NereusWB922"},"content":" this.errorHandling.handleError(new NoEventsError());"},{"lineNumber":96,"author":{"gitId":"NereusWB922"},"content":" return;"},{"lineNumber":97,"author":{"gitId":"-"},"content":" }"},{"lineNumber":98,"author":{"gitId":"NereusWB922"},"content":" this.dialog.open(EventWeekDetailsComponent, {"},{"lineNumber":99,"author":{"gitId":"NereusWB922"},"content":" data: {"},{"lineNumber":100,"author":{"gitId":"NereusWB922"},"content":" eventWeek,"},{"lineNumber":101,"author":{"gitId":"NereusWB922"},"content":" expandedColumnsToDisplay: this.expandedColumnsToDisplay"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" /** Returns color string of cell. Shade darkens with magnitude of number. */"},{"lineNumber":107,"author":{"gitId":"-"},"content":" colorCell(count: number) {"},{"lineNumber":108,"author":{"gitId":"-"},"content":" if (count \u003d\u003d\u003d 0) {"},{"lineNumber":109,"author":{"gitId":"-"},"content":" return \u0027white\u0027;"},{"lineNumber":110,"author":{"gitId":"-"},"content":" } else if (count \u003e 0 \u0026\u0026 count \u003c\u003d 5) {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" return \u0027pale-green\u0027;"},{"lineNumber":112,"author":{"gitId":"-"},"content":" } else if (count \u003e 6) {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" return \u0027green\u0027;"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":" }"},{"lineNumber":116,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"NereusWB922":21,"-":95}},{"path":"src/app/activity-dashboard/event-tables/no-events-error.model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"export class NoEventsError extends Error {"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" constructor() {"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" super(\u0027No events found for this week.\u0027);"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" Object.setPrototypeOf(this, NoEventsError.prototype);"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":6}},{"path":"src/app/activity-dashboard/event-week-details/event-week-details.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":".mat-cell {"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" white-space: nowrap;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" display: flex;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" align-items: center;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" justify-content: center;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" text-align: center;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" padding: 0;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":".mat-header-cell {"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" display: flex;"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" align-items: center;"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" justify-content: center;"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" text-align: center;"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" padding: 0;"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":".mat-dialog-content {"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" min-width: 500px;"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":20}},{"path":"src/app/activity-dashboard/event-week-details/event-week-details.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"\u003ch2 mat-dialog-title\u003eEvent Week Details\u003c/h2\u003e"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"\u003cmat-dialog-content class\u003d\"mat-typography\"\u003e"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-table [dataSource]\u003d\"data.eventWeek.events\"\u003e"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" \u003cng-container matColumnDef\u003d\"{{ expandableColumn }}\" *ngFor\u003d\"let expandableColumn of data.expandedColumnsToDisplay\"\u003e"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-header-cell *matHeaderCellDef\u003e{{ expandableColumn }}\u003c/mat-header-cell\u003e"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-cell *matCellDef\u003d\"let property\"\u003e"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" {{ property[expandableColumn] }}"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-cell\u003e"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" \u003c/ng-container\u003e"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-header-row *matHeaderRowDef\u003d\"data.expandedColumnsToDisplay\"\u003e\u003c/mat-header-row\u003e"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-row *matRowDef\u003d\"let property; columns: data.expandedColumnsToDisplay\"\u003e\u003c/mat-row\u003e"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-table\u003e"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":"\u003c/mat-dialog-content\u003e"}],"authorContributionMap":{"NereusWB922":13}},{"path":"src/app/activity-dashboard/event-week-details/event-week-details.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Component, Inject } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { MAT_DIALOG_DATA } from \u0027@angular/material/dialog\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { EventWeek } from \u0027../event-week.model\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"export interface DialogData {"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" eventWeek: EventWeek;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" expandedColumnsToDisplay: string[];"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"@Component({"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" selector: \u0027app-event-week-detail\u0027,"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" templateUrl: \u0027./event-week-details.component.html\u0027,"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" styleUrls: [\u0027./event-week-details.component.css\u0027]"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"})"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":"export class EventWeekDetailsComponent {"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" constructor(@Inject(MAT_DIALOG_DATA) public data: DialogData) {}"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":17}},{"path":"src/app/app-routing.module.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { NgModule } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { RouterModule, Routes } from \u0027@angular/router\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { ActivityDashboardModule } from \u0027./activity-dashboard/activity-dashboard.module\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { AuthModule } from \u0027./auth/auth.module\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { AuthGuard } from \u0027./core/guards/auth.guard\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { ParseUrlParamsGuard } from \u0027./core/guards/parse-url-params.guard\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { IssuesViewerModule } from \u0027./issues-viewer/issues-viewer.module\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"const routes: Routes \u003d ["},{"lineNumber":10,"author":{"gitId":"-"},"content":" { path: \u0027\u0027, loadChildren: () \u003d\u003e AuthModule },"},{"lineNumber":11,"author":{"gitId":"-"},"content":" { path: \u0027issuesViewer/:org/:repo\u0027, canActivate: [ParseUrlParamsGuard], children: [] },"},{"lineNumber":12,"author":{"gitId":"-"},"content":" { path: \u0027issuesViewer\u0027, loadChildren: () \u003d\u003e IssuesViewerModule, canLoad: [AuthGuard] },"},{"lineNumber":13,"author":{"gitId":"-"},"content":" { path: \u0027activityDashboard\u0027, loadChildren: () \u003d\u003e ActivityDashboardModule, canLoad: [AuthGuard] }"},{"lineNumber":14,"author":{"gitId":"-"},"content":"];"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"@NgModule({"},{"lineNumber":17,"author":{"gitId":"MadLamprey"},"content":" imports: [RouterModule.forRoot(routes, { relativeLinkResolution: \u0027legacy\u0027 })],"},{"lineNumber":18,"author":{"gitId":"-"},"content":" exports: [RouterModule]"},{"lineNumber":19,"author":{"gitId":"-"},"content":"})"},{"lineNumber":20,"author":{"gitId":"-"},"content":"export class AppRoutingModule {}"}],"authorContributionMap":{"MadLamprey":1,"-":19}},{"path":"src/app/app.module.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { HttpClientModule } from \u0027@angular/common/http\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { ErrorHandler, NgModule, NgZone } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { BrowserModule, Title } from \u0027@angular/platform-browser\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { BrowserAnimationsModule } from \u0027@angular/platform-browser/animations\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { Router } from \u0027@angular/router\u0027;"},{"lineNumber":6,"author":{"gitId":"MadLamprey"},"content":"import { ApolloLink, InMemoryCache, PossibleTypesMap } from \u0027@apollo/client/core\u0027;"},{"lineNumber":7,"author":{"gitId":"MadLamprey"},"content":"import { setContext } from \u0027@apollo/client/link/context\u0027;"},{"lineNumber":8,"author":{"gitId":"MadLamprey"},"content":"import { Apollo } from \u0027apollo-angular\u0027;"},{"lineNumber":9,"author":{"gitId":"MadLamprey"},"content":"import { HttpLink } from \u0027apollo-angular/http\u0027;"},{"lineNumber":10,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import \u0027reflect-metadata\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import graphqlTypes from \u0027../../graphql/graphql-types\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import \u0027../polyfills\u0027;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import { ActivityDashboardModule } from \u0027./activity-dashboard/activity-dashboard.module\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import { AppRoutingModule } from \u0027./app-routing.module\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import { AppComponent } from \u0027./app.component\u0027;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import { AuthModule } from \u0027./auth/auth.module\u0027;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import { UserConfirmationComponent } from \u0027./core/guards/user-confirmation/user-confirmation.component\u0027;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import { AuthService } from \u0027./core/services/auth.service\u0027;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import { ErrorHandlingService } from \u0027./core/services/error-handling.service\u0027;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import { ErrorMessageService } from \u0027./core/services/error-message.service\u0027;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import { AuthServiceFactory } from \u0027./core/services/factories/factory.auth.service\u0027;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import { GithubServiceFactory } from \u0027./core/services/factories/factory.github.service\u0027;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import { IssueServiceFactory } from \u0027./core/services/factories/factory.issue.service\u0027;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027./core/services/github.service\u0027;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import { GithubEventService } from \u0027./core/services/githubevent.service\u0027;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import { IssueService } from \u0027./core/services/issue.service\u0027;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import { LabelService } from \u0027./core/services/label.service\u0027;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027./core/services/logging.service\u0027;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import { RepoSessionStorageService } from \u0027./core/services/repo-session-storage.service\u0027;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import { UserService } from \u0027./core/services/user.service\u0027;"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":"import { ViewService } from \u0027./core/services/view.service\u0027;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import { IssuesViewerModule } from \u0027./issues-viewer/issues-viewer.module\u0027;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import { LabelDefinitionPopupComponent } from \u0027./shared/label-definition-popup/label-definition-popup.component\u0027;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import { HeaderComponent } from \u0027./shared/layout\u0027;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import { RepoChangeFormComponent } from \u0027./shared/repo-change-form/repo-change-form.component\u0027;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import { SharedModule } from \u0027./shared/shared.module\u0027;"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":"@NgModule({"},{"lineNumber":40,"author":{"gitId":"Arif-Khalid"},"content":" declarations: [AppComponent, HeaderComponent, UserConfirmationComponent, LabelDefinitionPopupComponent, RepoChangeFormComponent],"},{"lineNumber":41,"author":{"gitId":"-"},"content":" imports: ["},{"lineNumber":42,"author":{"gitId":"-"},"content":" BrowserModule,"},{"lineNumber":43,"author":{"gitId":"-"},"content":" BrowserAnimationsModule,"},{"lineNumber":44,"author":{"gitId":"-"},"content":" AuthModule,"},{"lineNumber":45,"author":{"gitId":"-"},"content":" IssuesViewerModule,"},{"lineNumber":46,"author":{"gitId":"-"},"content":" ActivityDashboardModule,"},{"lineNumber":47,"author":{"gitId":"-"},"content":" SharedModule,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" HttpClientModule,"},{"lineNumber":49,"author":{"gitId":"MadLamprey"},"content":" AppRoutingModule"},{"lineNumber":50,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":51,"author":{"gitId":"-"},"content":" providers: ["},{"lineNumber":52,"author":{"gitId":"-"},"content":" {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" provide: GithubService,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" useFactory: GithubServiceFactory,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" deps: [ErrorHandlingService, Apollo, LoggingService]"},{"lineNumber":56,"author":{"gitId":"-"},"content":" },"},{"lineNumber":57,"author":{"gitId":"-"},"content":" {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" provide: AuthService,"},{"lineNumber":59,"author":{"gitId":"-"},"content":" useFactory: AuthServiceFactory,"},{"lineNumber":60,"author":{"gitId":"-"},"content":" deps: ["},{"lineNumber":61,"author":{"gitId":"-"},"content":" Router,"},{"lineNumber":62,"author":{"gitId":"-"},"content":" NgZone,"},{"lineNumber":63,"author":{"gitId":"-"},"content":" GithubService,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" UserService,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" IssueService,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" LabelService,"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":" ViewService,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" GithubEventService,"},{"lineNumber":69,"author":{"gitId":"-"},"content":" Title,"},{"lineNumber":70,"author":{"gitId":"-"},"content":" ErrorHandlingService,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" LoggingService"},{"lineNumber":72,"author":{"gitId":"-"},"content":" ]"},{"lineNumber":73,"author":{"gitId":"-"},"content":" },"},{"lineNumber":74,"author":{"gitId":"-"},"content":" {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" provide: IssueService,"},{"lineNumber":76,"author":{"gitId":"-"},"content":" useFactory: IssueServiceFactory,"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" deps: [GithubService, UserService, ViewService]"},{"lineNumber":78,"author":{"gitId":"-"},"content":" },"},{"lineNumber":79,"author":{"gitId":"-"},"content":" {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" provide: ErrorHandler,"},{"lineNumber":81,"author":{"gitId":"-"},"content":" useClass: ErrorHandlingService"},{"lineNumber":82,"author":{"gitId":"-"},"content":" },"},{"lineNumber":83,"author":{"gitId":"-"},"content":" ErrorMessageService,"},{"lineNumber":84,"author":{"gitId":"-"},"content":" RepoSessionStorageService"},{"lineNumber":85,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":86,"author":{"gitId":"-"},"content":" bootstrap: [AppComponent]"},{"lineNumber":87,"author":{"gitId":"-"},"content":"})"},{"lineNumber":88,"author":{"gitId":"-"},"content":"export class AppModule {"},{"lineNumber":89,"author":{"gitId":"-"},"content":" constructor(private apollo: Apollo, private httpLink: HttpLink, private authService: AuthService, private logger: LoggingService) {"},{"lineNumber":90,"author":{"gitId":"-"},"content":" const URI \u003d \u0027https://api.github.com/graphql\u0027;"},{"lineNumber":91,"author":{"gitId":"-"},"content":" const log \u003d new ApolloLink((operation, forward) \u003d\u003e {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" operation.setContext({ start: performance.now() });"},{"lineNumber":93,"author":{"gitId":"-"},"content":" this.logger.info(\u0027AppModule: GraphQL request\u0027, operation.getContext());"},{"lineNumber":94,"author":{"gitId":"-"},"content":" return forward(operation).map((result) \u003d\u003e {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" const time \u003d performance.now() - operation.getContext().start;"},{"lineNumber":96,"author":{"gitId":"-"},"content":" this.logger.info(\u0027AppModule: GraphQL response\u0027, operation.getContext(), `in ${Math.round(time)}ms`);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" const repo \u003d operation.getContext().response.body.data.repository;"},{"lineNumber":98,"author":{"gitId":"-"},"content":" const item \u003d Object.keys(repo)[0];"},{"lineNumber":99,"author":{"gitId":"-"},"content":" this.logger.debug(\u0027AppModule: GraphQL response body\u0027, item, repo[item].edges.length, repo[item].edges);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" return result;"},{"lineNumber":101,"author":{"gitId":"-"},"content":" });"},{"lineNumber":102,"author":{"gitId":"-"},"content":" });"},{"lineNumber":103,"author":{"gitId":"-"},"content":" const basic \u003d setContext(() \u003d\u003e {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" return { headers: { Accept: \u0027charset\u003dutf-8\u0027 } };"},{"lineNumber":105,"author":{"gitId":"-"},"content":" });"},{"lineNumber":106,"author":{"gitId":"-"},"content":" const auth \u003d setContext(() \u003d\u003e {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" return { headers: { Authorization: `Token ${this.authService.accessToken.getValue()}` } };"},{"lineNumber":108,"author":{"gitId":"-"},"content":" });"},{"lineNumber":109,"author":{"gitId":"-"},"content":" const link \u003d ApolloLink.from([log, basic, auth, this.httpLink.create({ uri: URI })]);"},{"lineNumber":110,"author":{"gitId":"MadLamprey"},"content":" const possibleTypes: PossibleTypesMap \u003d {};"},{"lineNumber":111,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":112,"author":{"gitId":"MadLamprey"},"content":" graphqlTypes.__schema.types.forEach((type: any) \u003d\u003e {"},{"lineNumber":113,"author":{"gitId":"MadLamprey"},"content":" if (type.kind \u003d\u003d\u003d \u0027UNION\u0027 || type.kind \u003d\u003d\u003d \u0027INTERFACE\u0027) {"},{"lineNumber":114,"author":{"gitId":"MadLamprey"},"content":" possibleTypes[type.name] \u003d type.possibleTypes.map((possibleType: any) \u003d\u003e possibleType.name);"},{"lineNumber":115,"author":{"gitId":"MadLamprey"},"content":" }"},{"lineNumber":116,"author":{"gitId":"-"},"content":" });"},{"lineNumber":117,"author":{"gitId":"MadLamprey"},"content":" const cache \u003d new InMemoryCache({ possibleTypes });"},{"lineNumber":118,"author":{"gitId":"-"},"content":" this.apollo.create({"},{"lineNumber":119,"author":{"gitId":"-"},"content":" link: link,"},{"lineNumber":120,"author":{"gitId":"-"},"content":" cache: cache"},{"lineNumber":121,"author":{"gitId":"-"},"content":" });"},{"lineNumber":122,"author":{"gitId":"-"},"content":" }"},{"lineNumber":123,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"NereusWB922":3,"Arif-Khalid":1,"MadLamprey":13,"-":106}},{"path":"src/app/auth/auth.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component, NgZone, OnDestroy, OnInit } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { ActivatedRoute, Router } from \u0027@angular/router\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { Observable, Subscription } from \u0027rxjs\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { filter, flatMap, map } from \u0027rxjs/operators\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { AppConfig } from \u0027../../environments/environment\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { STORAGE_KEYS } from \u0027../core/constants/storage-keys.constants\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { GithubUser } from \u0027../core/models/github-user.model\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { ApplicationService } from \u0027../core/services/application.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { AuthService, AuthState } from \u0027../core/services/auth.service\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { ErrorHandlingService } from \u0027../core/services/error-handling.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { ErrorMessageService } from \u0027../core/services/error-message.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027../core/services/logging.service\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { UserService } from \u0027../core/services/user.service\u0027;"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"import { ViewService } from \u0027../core/services/view.service\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":17,"author":{"gitId":"-"},"content":" selector: \u0027app-auth\u0027,"},{"lineNumber":18,"author":{"gitId":"-"},"content":" templateUrl: \u0027./auth.component.html\u0027,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./auth.component.css\u0027]"},{"lineNumber":20,"author":{"gitId":"-"},"content":"})"},{"lineNumber":21,"author":{"gitId":"-"},"content":"export class AuthComponent implements OnInit, OnDestroy {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" authState: AuthState;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" accessTokenSubscription: Subscription;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" authStateSubscription: Subscription;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" currentUserName: string;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" urlEncodedSessionName: string;"},{"lineNumber":27,"author":{"gitId":"-"},"content":" urlEncodedRepo: string;"},{"lineNumber":28,"author":{"gitId":"-"},"content":" sessionInformation: string;"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" constructor("},{"lineNumber":31,"author":{"gitId":"-"},"content":" public appService: ApplicationService,"},{"lineNumber":32,"author":{"gitId":"-"},"content":" private authService: AuthService,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" private userService: UserService,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" private errorHandlingService: ErrorHandlingService,"},{"lineNumber":35,"author":{"gitId":"-"},"content":" private router: Router,"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" private viewService: ViewService,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" private ngZone: NgZone,"},{"lineNumber":38,"author":{"gitId":"-"},"content":" private activatedRoute: ActivatedRoute,"},{"lineNumber":39,"author":{"gitId":"-"},"content":" private logger: LoggingService"},{"lineNumber":40,"author":{"gitId":"-"},"content":" ) {}"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" ngOnInit() {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" this.logger.startSession();"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" const oauthCode \u003d this.activatedRoute.snapshot.queryParamMap.get(\u0027code\u0027);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" const state \u003d this.activatedRoute.snapshot.queryParamMap.get(\u0027state\u0027);"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" if (this.authService.isAuthenticated()) {"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":" this.router.navigate([this.viewService.currentView]);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" }"},{"lineNumber":52,"author":{"gitId":"-"},"content":" this.initAccessTokenSubscription();"},{"lineNumber":53,"author":{"gitId":"-"},"content":" this.initAuthStateSubscription();"},{"lineNumber":54,"author":{"gitId":"-"},"content":" this.createProfileFromUrlQueryParams();"},{"lineNumber":55,"author":{"gitId":"-"},"content":" this.getRepoFromUrlQueryParams();"},{"lineNumber":56,"author":{"gitId":"-"},"content":" if (oauthCode) {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" // runs upon receiving oauthCode from the redirect"},{"lineNumber":58,"author":{"gitId":"-"},"content":" this.authService.changeAuthState(AuthState.AwaitingAuthentication);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" // this.restoreOrgDetailsFromLocalStorage();"},{"lineNumber":60,"author":{"gitId":"-"},"content":" this.logger.info(\u0027AuthComponent: Obtained authorisation code from Github\u0027);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" this.fetchAccessToken(oauthCode, state);"},{"lineNumber":62,"author":{"gitId":"nknguyenhc"},"content":" return;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"nknguyenhc"},"content":" this.authService.startOAuthIfHasNext();"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":68,"author":{"gitId":"-"},"content":" * Will fetch the access token from GitHub."},{"lineNumber":69,"author":{"gitId":"-"},"content":" * @param oauthCode - The authorisation code obtained from GitHub."},{"lineNumber":70,"author":{"gitId":"-"},"content":" * @param state - The state returned from GitHub."},{"lineNumber":71,"author":{"gitId":"-"},"content":" */"},{"lineNumber":72,"author":{"gitId":"-"},"content":" fetchAccessToken(oauthCode: string, state: string) {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" if (!this.authService.isReturnedStateSame(state)) {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" this.logger.info(`AuthComponent: Received incorrect state ${state}, continue waiting for correct state`);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" this.logger.info(`AuthComponent: Retrieving access token from Github`);"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" const accessTokenUrl \u003d `${AppConfig.accessTokenUrl}/${oauthCode}/client_id/${AppConfig.clientId}`;"},{"lineNumber":81,"author":{"gitId":"-"},"content":" fetch(accessTokenUrl)"},{"lineNumber":82,"author":{"gitId":"-"},"content":" .then((res) \u003d\u003e res.json())"},{"lineNumber":83,"author":{"gitId":"-"},"content":" .then((data) \u003d\u003e {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" if (data.error) {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" throw new Error(data.error);"},{"lineNumber":86,"author":{"gitId":"-"},"content":" }"},{"lineNumber":87,"author":{"gitId":"-"},"content":" this.authService.storeOAuthAccessToken(data.token);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" this.logger.info(`AuthComponent: Sucessfully obtained access token`);"},{"lineNumber":89,"author":{"gitId":"-"},"content":" })"},{"lineNumber":90,"author":{"gitId":"-"},"content":" .catch((err) \u003d\u003e {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" this.logger.info(`AuthComponent: Error in data fetched from access token URL: ${err}`);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" this.errorHandlingService.handleError(err);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" this.authService.changeAuthState(AuthState.NotAuthenticated);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" });"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" ngOnDestroy() {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" if (this.authStateSubscription) {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" this.authStateSubscription.unsubscribe();"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":" if (this.accessTokenSubscription) {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" this.accessTokenSubscription.unsubscribe();"},{"lineNumber":103,"author":{"gitId":"-"},"content":" }"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":107,"author":{"gitId":"-"},"content":" * Checks whether the current version of WATcher is outdated."},{"lineNumber":108,"author":{"gitId":"-"},"content":" */"},{"lineNumber":109,"author":{"gitId":"-"},"content":" checkAppIsOutdated(): Observable\u003cany\u003e {"},{"lineNumber":110,"author":{"gitId":"-"},"content":" return this.appService.isApplicationOutdated().pipe("},{"lineNumber":111,"author":{"gitId":"-"},"content":" map((isOutdated: boolean) \u003d\u003e {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" if (isOutdated) {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" throw new Error(ErrorMessageService.applicationVersionOutdatedMessage());"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":" })"},{"lineNumber":116,"author":{"gitId":"-"},"content":" );"},{"lineNumber":117,"author":{"gitId":"-"},"content":" }"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" updateSession(sessionEvent: string) {"},{"lineNumber":120,"author":{"gitId":"-"},"content":" this.sessionInformation \u003d sessionEvent;"},{"lineNumber":121,"author":{"gitId":"-"},"content":" }"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" goToSessionSelect() {"},{"lineNumber":124,"author":{"gitId":"-"},"content":" this.authService.changeAuthState(AuthState.NotAuthenticated);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" }"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" isUserNotAuthenticated(): boolean {"},{"lineNumber":128,"author":{"gitId":"-"},"content":" return this.authState \u003d\u003d\u003d AuthState.NotAuthenticated;"},{"lineNumber":129,"author":{"gitId":"-"},"content":" }"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" isUserAuthenticating(): boolean {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" return this.authState \u003d\u003d\u003d AuthState.AwaitingAuthentication;"},{"lineNumber":133,"author":{"gitId":"-"},"content":" }"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" isAwaitingOAuthUserConfirm(): boolean {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" return this.authState \u003d\u003d\u003d AuthState.ConfirmOAuthUser;"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" isUserAuthenticated(): boolean {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" return this.authState \u003d\u003d\u003d AuthState.Authenticated;"},{"lineNumber":141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" isRepoSet(): boolean {"},{"lineNumber":144,"author":{"gitId":"NereusWB922"},"content":" return this.viewService.isRepoSet();"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" get currentSessionOrg(): string {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" if (!this.sessionInformation) {"},{"lineNumber":149,"author":{"gitId":"-"},"content":" // Retrieve org details of session information from local storage"},{"lineNumber":150,"author":{"gitId":"-"},"content":" return window.localStorage.getItem(STORAGE_KEYS.ORG);"},{"lineNumber":151,"author":{"gitId":"-"},"content":" }"},{"lineNumber":152,"author":{"gitId":"-"},"content":" return this.getOrgDetails(this.sessionInformation);"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":156,"author":{"gitId":"-"},"content":" * Extracts the Organization Details from the input sessionInformation."},{"lineNumber":157,"author":{"gitId":"-"},"content":" * @param sessionInformation - string in the format of \u0027orgName/dataRepo\u0027"},{"lineNumber":158,"author":{"gitId":"-"},"content":" */"},{"lineNumber":159,"author":{"gitId":"-"},"content":" private getOrgDetails(sessionInformation: string) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" return sessionInformation.split(\u0027/\u0027)[0];"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" private initAuthStateSubscription() {"},{"lineNumber":164,"author":{"gitId":"-"},"content":" this.authStateSubscription \u003d this.authService.currentAuthState.subscribe((state) \u003d\u003e {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" this.ngZone.run(() \u003d\u003e {"},{"lineNumber":166,"author":{"gitId":"-"},"content":" this.authState \u003d state;"},{"lineNumber":167,"author":{"gitId":"-"},"content":" });"},{"lineNumber":168,"author":{"gitId":"-"},"content":" });"},{"lineNumber":169,"author":{"gitId":"-"},"content":" }"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" private initAccessTokenSubscription() {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" this.accessTokenSubscription \u003d this.authService.accessToken"},{"lineNumber":173,"author":{"gitId":"-"},"content":" .pipe("},{"lineNumber":174,"author":{"gitId":"-"},"content":" filter((token: string) \u003d\u003e !!token),"},{"lineNumber":175,"author":{"gitId":"-"},"content":" flatMap(() \u003d\u003e this.userService.getAuthenticatedUser())"},{"lineNumber":176,"author":{"gitId":"-"},"content":" )"},{"lineNumber":177,"author":{"gitId":"-"},"content":" .subscribe((user: GithubUser) \u003d\u003e {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" this.ngZone.run(() \u003d\u003e {"},{"lineNumber":179,"author":{"gitId":"-"},"content":" this.currentUserName \u003d user.login;"},{"lineNumber":180,"author":{"gitId":"nknguyenhc"},"content":" if (this.authService.hasNext()) {"},{"lineNumber":181,"author":{"gitId":"nknguyenhc"},"content":" this.authService.completeLoginIfHasNext(this.currentUserName);"},{"lineNumber":182,"author":{"gitId":"nknguyenhc"},"content":" } else {"},{"lineNumber":183,"author":{"gitId":"-"},"content":" this.authService.changeAuthState(AuthState.ConfirmOAuthUser);"},{"lineNumber":184,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":185,"author":{"gitId":"-"},"content":" });"},{"lineNumber":186,"author":{"gitId":"-"},"content":" });"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":" private createProfileFromUrlQueryParams() {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" const urlParams \u003d this.activatedRoute.snapshot.queryParamMap;"},{"lineNumber":191,"author":{"gitId":"-"},"content":" if (urlParams.has(\u0027session\u0027)) {"},{"lineNumber":192,"author":{"gitId":"-"},"content":" this.urlEncodedSessionName \u003d urlParams.get(\u0027session\u0027);"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":" }"},{"lineNumber":195,"author":{"gitId":"-"},"content":""},{"lineNumber":196,"author":{"gitId":"-"},"content":" private getRepoFromUrlQueryParams() {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" const urlParams \u003d this.activatedRoute.snapshot.queryParamMap;"},{"lineNumber":198,"author":{"gitId":"-"},"content":" if (urlParams.has(\u0027repo\u0027)) {"},{"lineNumber":199,"author":{"gitId":"-"},"content":" this.urlEncodedRepo \u003d urlParams.get(\u0027repo\u0027);"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }"},{"lineNumber":201,"author":{"gitId":"-"},"content":" }"},{"lineNumber":202,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":6,"NereusWB922":4,"-":192}},{"path":"src/app/core/guards/auth.guard.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { ActivatedRouteSnapshot, CanActivate, CanLoad, Route, Router, RouterStateSnapshot, UrlSegment } from \u0027@angular/router\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { AuthService } from \u0027../services/auth.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":7,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":8,"author":{"gitId":"-"},"content":"})"},{"lineNumber":9,"author":{"gitId":"-"},"content":"export class AuthGuard implements CanActivate, CanLoad {"},{"lineNumber":10,"author":{"gitId":"-"},"content":" constructor(private auth: AuthService, private router: Router) {}"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":" canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable\u003cboolean\u003e | Promise\u003cboolean\u003e | boolean {"},{"lineNumber":13,"author":{"gitId":"-"},"content":" if (this.auth.isAuthenticated()) {"},{"lineNumber":14,"author":{"gitId":"nknguyenhc"},"content":" this.auth.clearNext();"},{"lineNumber":15,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":16,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":17,"author":{"gitId":"nknguyenhc"},"content":" this.auth.storeNext(state);"},{"lineNumber":18,"author":{"gitId":"-"},"content":" this.router.navigate([\u0027\u0027]);"},{"lineNumber":19,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" }"},{"lineNumber":21,"author":{"gitId":"-"},"content":" }"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" canLoad(route: Route, segments: UrlSegment[]): Observable\u003cboolean\u003e | Promise\u003cboolean\u003e | boolean {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" if (this.auth.isAuthenticated()) {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" this.router.navigate([\u0027\u0027]);"},{"lineNumber":28,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":2,"-":29}},{"path":"src/app/core/models/github-user.model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Group } from \u0027./github/group.interface\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"/**"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" * Represents raw data returned from the GitHub API about a user."},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"export interface RawGithubUser {"},{"lineNumber":7,"author":{"gitId":"-"},"content":" avatar_url: string;"},{"lineNumber":8,"author":{"gitId":"-"},"content":" created_at: string;"},{"lineNumber":9,"author":{"gitId":"-"},"content":" html_url: string;"},{"lineNumber":10,"author":{"gitId":"-"},"content":" login: string;"},{"lineNumber":11,"author":{"gitId":"-"},"content":" name: string;"},{"lineNumber":12,"author":{"gitId":"-"},"content":" node_id: string;"},{"lineNumber":13,"author":{"gitId":"-"},"content":" two_factor_authentication: boolean;"},{"lineNumber":14,"author":{"gitId":"-"},"content":" site_admin: false;"},{"lineNumber":15,"author":{"gitId":"-"},"content":" type: string;"},{"lineNumber":16,"author":{"gitId":"-"},"content":" updated_at: string;"},{"lineNumber":17,"author":{"gitId":"-"},"content":" url: string;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"}"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":"/**"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" * Represents a GitHub user in WATcher"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":"export class GithubUser implements RawGithubUser, Group {"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" static NO_ASSIGNEE: GithubUser \u003d new GithubUser({"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" avatar_url: \u0027\u0027,"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" created_at: \u0027\u0027,"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" html_url: \u0027\u0027,"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" login: \u0027Unassigned\u0027,"},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" name: \u0027\u0027,"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" node_id: \u0027\u0027,"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" two_factor_authentication: false,"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" site_admin: false,"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" type: \u0027\u0027,"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" updated_at: \u0027\u0027,"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" url: \u0027\u0027"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" avatar_url: string;"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" created_at: string;"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" html_url: string;"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" login: string;"},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":" name: string;"},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":" node_id: string;"},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" two_factor_authentication: boolean;"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" site_admin: false;"},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":" type: string;"},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" updated_at: string;"},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" url: string;"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" constructor(rawData: RawGithubUser) {"},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":" Object.assign(this, rawData);"},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":" equals(other: any) {"},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" if (!(other instanceof GithubUser)) {"},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" return false;"},{"lineNumber":57,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" return this.login \u003d\u003d\u003d other.login;"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":48,"-":12}},{"path":"src/app/core/models/github/group.interface.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"/**"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" * Represents a group used for grouping purposes."},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" * Groups can be used to organize issues/prs based on certain criteria,"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" * such as milestones, assignees, or other properties."},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"export interface Group {"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" equals(other: any): boolean;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":8}},{"path":"src/app/core/models/issue.model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import * as moment from \u0027moment\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { GithubComment } from \u0027./github/github-comment.model\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { GithubIssue } from \u0027./github/github-issue.model\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { GithubLabel } from \u0027./github/github-label.model\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { HiddenData } from \u0027./hidden-data.model\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { Milestone } from \u0027./milestone.model\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"export class Issue {"},{"lineNumber":9,"author":{"gitId":"-"},"content":" /** Basic Fields */"},{"lineNumber":10,"author":{"gitId":"-"},"content":" readonly globalId: string;"},{"lineNumber":11,"author":{"gitId":"-"},"content":" readonly id: number;"},{"lineNumber":12,"author":{"gitId":"-"},"content":" readonly created_at: string;"},{"lineNumber":13,"author":{"gitId":"-"},"content":" readonly githubIssue: GithubIssue;"},{"lineNumber":14,"author":{"gitId":"-"},"content":" githubComments: GithubComment[];"},{"lineNumber":15,"author":{"gitId":"-"},"content":" title: string;"},{"lineNumber":16,"author":{"gitId":"-"},"content":" description: string;"},{"lineNumber":17,"author":{"gitId":"-"},"content":" hiddenDataInDescription: HiddenData;"},{"lineNumber":18,"author":{"gitId":"-"},"content":" updated_at: string;"},{"lineNumber":19,"author":{"gitId":"-"},"content":" closed_at: string;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" milestone: Milestone;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" state: string;"},{"lineNumber":22,"author":{"gitId":"-"},"content":" stateReason: string;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" issueOrPr: string;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" author: string;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" isDraft: boolean;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" /** Depending on the view, assignees attribute can be derived from Github\u0027s assignee feature OR from the Github\u0027s issue description */"},{"lineNumber":28,"author":{"gitId":"-"},"content":" assignees?: string[];"},{"lineNumber":29,"author":{"gitId":"-"},"content":" labels?: string[];"},{"lineNumber":30,"author":{"gitId":"-"},"content":" githubLabels?: GithubLabel[];"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":33,"author":{"gitId":"-"},"content":" * Formats the text to create space at the end of the user input to prevent any issues with"},{"lineNumber":34,"author":{"gitId":"-"},"content":" * the markdown interpretation."},{"lineNumber":35,"author":{"gitId":"-"},"content":" *"},{"lineNumber":36,"author":{"gitId":"-"},"content":" * Brought over from comment-editor.component.ts"},{"lineNumber":37,"author":{"gitId":"-"},"content":" */"},{"lineNumber":38,"author":{"gitId":"-"},"content":" static formatText(text: string): string {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" if (text \u003d\u003d\u003d null) {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" if (text \u003d\u003d\u003d undefined) {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return undefined;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" const newLinesRegex \u003d /[\\n\\r]/gi;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" const textSplitArray \u003d text.split(newLinesRegex);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" if (textSplitArray.filter((split) \u003d\u003e split.trim() !\u003d\u003d \u0027\u0027).length \u003e 0) {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" return `${text}\\n\\n`;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" return text;"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":" }"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":57,"author":{"gitId":"-"},"content":" * Processes and cleans a raw issue description obtained from user input."},{"lineNumber":58,"author":{"gitId":"-"},"content":" */"},{"lineNumber":59,"author":{"gitId":"-"},"content":" static updateDescription(description: string): string {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" const defaultString \u003d \u0027No details provided by bug reporter.\u0027;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" return Issue.orDefaultString(Issue.formatText(description), defaultString);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" }"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":65,"author":{"gitId":"-"},"content":" * Given two strings, returns the first if it is not an empty string or a false value such as null/undefined."},{"lineNumber":66,"author":{"gitId":"-"},"content":" * Returns the second string if the first is an empty string."},{"lineNumber":67,"author":{"gitId":"-"},"content":" */"},{"lineNumber":68,"author":{"gitId":"-"},"content":" private static orDefaultString(stringA: string, def: string): string {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" if (!stringA) {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" return def;"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":" return stringA.length !\u003d\u003d 0 ? stringA : def;"},{"lineNumber":73,"author":{"gitId":"-"},"content":" }"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" protected constructor(githubIssue: GithubIssue) {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" /** Basic Fields */"},{"lineNumber":77,"author":{"gitId":"-"},"content":" this.globalId \u003d githubIssue.id;"},{"lineNumber":78,"author":{"gitId":"-"},"content":" this.id \u003d +githubIssue.number;"},{"lineNumber":79,"author":{"gitId":"-"},"content":" this.created_at \u003d moment(githubIssue.created_at).format(\u0027lll\u0027);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" this.updated_at \u003d moment(githubIssue.updated_at).format(\u0027lll\u0027);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" this.closed_at \u003d moment(githubIssue.closed_at).format(\u0027lll\u0027);"},{"lineNumber":82,"author":{"gitId":"-"},"content":" this.title \u003d githubIssue.title;"},{"lineNumber":83,"author":{"gitId":"-"},"content":" this.hiddenDataInDescription \u003d new HiddenData(githubIssue.body);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" this.description \u003d Issue.updateDescription(this.hiddenDataInDescription.originalStringWithoutHiddenData);"},{"lineNumber":85,"author":{"gitId":"-"},"content":" this.state \u003d githubIssue.state;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" this.stateReason \u003d githubIssue.stateReason;"},{"lineNumber":87,"author":{"gitId":"-"},"content":" this.issueOrPr \u003d githubIssue.issueOrPr;"},{"lineNumber":88,"author":{"gitId":"-"},"content":" this.author \u003d githubIssue.user.login;"},{"lineNumber":89,"author":{"gitId":"-"},"content":" // this.githubIssue \u003d githubIssue;"},{"lineNumber":90,"author":{"gitId":"-"},"content":" this.isDraft \u003d githubIssue.isDraft;"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" this.assignees \u003d githubIssue.assignees.map((assignee) \u003d\u003e assignee.login);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" this.githubLabels \u003d githubIssue.labels;"},{"lineNumber":94,"author":{"gitId":"-"},"content":" this.labels \u003d githubIssue.labels.map((label) \u003d\u003e label.name);"},{"lineNumber":95,"author":{"gitId":"MadLamprey"},"content":" this.milestone \u003d githubIssue.milestone"},{"lineNumber":96,"author":{"gitId":"MadLamprey"},"content":" ? new Milestone(githubIssue.milestone)"},{"lineNumber":97,"author":{"gitId":"MadLamprey"},"content":" : this.issueOrPr \u003d\u003d\u003d \u0027Issue\u0027"},{"lineNumber":98,"author":{"gitId":"MadLamprey"},"content":" ? Milestone.IssueWithoutMilestone"},{"lineNumber":99,"author":{"gitId":"MadLamprey"},"content":" : Milestone.PRWithoutMilestone;"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" public static createPhaseBugReportingIssue(githubIssue: GithubIssue): Issue {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" return new Issue(githubIssue);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" createGithubIssueDescription(): string {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" return `${this.description}\\n${this.hiddenDataInDescription.toString()}`;"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":"}"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":"export interface Issues {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" [id: number]: Issue;"},{"lineNumber":113,"author":{"gitId":"-"},"content":"}"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":"export const IssuesFilter \u003d {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" issuesViewer: {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" Student: \u0027NO_FILTER\u0027,"},{"lineNumber":118,"author":{"gitId":"-"},"content":" Tutor: \u0027NO_FILTER\u0027,"},{"lineNumber":119,"author":{"gitId":"-"},"content":" Admin: \u0027NO_FILTER\u0027"},{"lineNumber":120,"author":{"gitId":"-"},"content":" }"},{"lineNumber":121,"author":{"gitId":"-"},"content":"};"}],"authorContributionMap":{"NereusWB922":1,"MadLamprey":5,"-":115}},{"path":"src/app/core/models/label.model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":2,"author":{"gitId":"-"},"content":" * Represents a label and its attributes."},{"lineNumber":3,"author":{"gitId":"-"},"content":" */"},{"lineNumber":4,"author":{"gitId":"-"},"content":"export class Label implements SimpleLabel {"},{"lineNumber":5,"author":{"gitId":"-"},"content":" readonly name: string;"},{"lineNumber":6,"author":{"gitId":"-"},"content":" color: string;"},{"lineNumber":7,"author":{"gitId":"-"},"content":" definition?: string;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":" constructor(label: { name: string; color: string; definition?: string }) {"},{"lineNumber":10,"author":{"gitId":"nknguyenhc"},"content":" this.name \u003d label.name;"},{"lineNumber":11,"author":{"gitId":"-"},"content":" this.color \u003d label.color;"},{"lineNumber":12,"author":{"gitId":"-"},"content":" this.definition \u003d label.definition;"},{"lineNumber":13,"author":{"gitId":"-"},"content":" }"},{"lineNumber":14,"author":{"gitId":"-"},"content":"}"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * Represents a simplified label with name and color"},{"lineNumber":18,"author":{"gitId":"-"},"content":" */"},{"lineNumber":19,"author":{"gitId":"-"},"content":"export type SimpleLabel \u003d {"},{"lineNumber":20,"author":{"gitId":"nknguyenhc"},"content":" name: string;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" color: string;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"};"}],"authorContributionMap":{"nknguyenhc":2,"-":20}},{"path":"src/app/core/models/milestone.model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Group } from \u0027./github/group.interface\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":4,"author":{"gitId":"-"},"content":" * Represents a milestone and its attributes fetched from Github."},{"lineNumber":5,"author":{"gitId":"-"},"content":" */"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"export class Milestone implements Group {"},{"lineNumber":7,"author":{"gitId":"MadLamprey"},"content":" static IssueWithoutMilestone: Milestone \u003d new Milestone({ title: \u0027Issue without a milestone\u0027, state: null });"},{"lineNumber":8,"author":{"gitId":"MadLamprey"},"content":" static PRWithoutMilestone: Milestone \u003d new Milestone({ title: \u0027PR without a milestone\u0027, state: null });"},{"lineNumber":9,"author":{"gitId":"-"},"content":" title: string;"},{"lineNumber":10,"author":{"gitId":"-"},"content":" state: string;"},{"lineNumber":11,"author":{"gitId":"nknguyenhc"},"content":" deadline?: Date;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"nknguyenhc"},"content":" constructor(milestone: { title: string; state: string; due_on?: string }) {"},{"lineNumber":14,"author":{"gitId":"-"},"content":" this.title \u003d milestone.title;"},{"lineNumber":15,"author":{"gitId":"-"},"content":" this.state \u003d milestone.state;"},{"lineNumber":16,"author":{"gitId":"nknguyenhc"},"content":" this.deadline \u003d milestone.due_on ? new Date(milestone.due_on) : undefined;"},{"lineNumber":17,"author":{"gitId":"-"},"content":" }"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" public equals(other: any) {"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" if (!(other instanceof Milestone)) {"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" return false;"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" return this.title \u003d\u003d\u003d other.title;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" }"},{"lineNumber":25,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":3,"NereusWB922":8,"MadLamprey":2,"-":12}},{"path":"src/app/core/models/repo-change-response.model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"Arif-Khalid"},"content":"/**"},{"lineNumber":2,"author":{"gitId":"Arif-Khalid"},"content":" * Represents the response of the repo-change-form component"},{"lineNumber":3,"author":{"gitId":"Arif-Khalid"},"content":" */"},{"lineNumber":4,"author":{"gitId":"Arif-Khalid"},"content":"export type RepoChangeResponse \u003d {"},{"lineNumber":5,"author":{"gitId":"Arif-Khalid"},"content":" repo: string;"},{"lineNumber":6,"author":{"gitId":"Arif-Khalid"},"content":" keepFilters: boolean;"},{"lineNumber":7,"author":{"gitId":"Arif-Khalid"},"content":"};"}],"authorContributionMap":{"Arif-Khalid":7}},{"path":"src/app/core/models/session.model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { pipe } from \u0027rxjs\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { throwIfFalse } from \u0027../../shared/lib/custom-ops\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { Repo } from \u0027./repo.model\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { View } from \u0027./view.model\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" * Session repository comprises the view and its corresponding repository array."},{"lineNumber":8,"author":{"gitId":"-"},"content":" */"},{"lineNumber":9,"author":{"gitId":"-"},"content":"export interface SessionRepo {"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" view: View;"},{"lineNumber":11,"author":{"gitId":"-"},"content":" repos: Repo[];"},{"lineNumber":12,"author":{"gitId":"-"},"content":"}"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":15,"author":{"gitId":"-"},"content":" * Session data comprises an array of session repositories."},{"lineNumber":16,"author":{"gitId":"-"},"content":" */"},{"lineNumber":17,"author":{"gitId":"-"},"content":"export interface SessionData {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" sessionRepo: SessionRepo[];"},{"lineNumber":19,"author":{"gitId":"-"},"content":"}"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"export const SESSION_DATA_UNAVAILABLE \u003d \u0027Session data does not exist.\u0027;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"export const SESSION_DATA_MISSING_FIELDS \u003d \u0027Session data does not contain any repositories.\u0027;"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":"export const NO_VALID_OPEN_VIEWS \u003d \u0027Invalid views in Session data.\u0027;"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":"export const OPENED_VIEW_REPO_UNDEFINED \u003d \u0027View has no repo defined.\u0027;"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":"export function assertSessionDataIntegrity() {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" return pipe("},{"lineNumber":28,"author":{"gitId":"-"},"content":" throwIfFalse("},{"lineNumber":29,"author":{"gitId":"-"},"content":" (sessionData) \u003d\u003e sessionData !\u003d\u003d undefined,"},{"lineNumber":30,"author":{"gitId":"-"},"content":" () \u003d\u003e new Error(SESSION_DATA_UNAVAILABLE)"},{"lineNumber":31,"author":{"gitId":"-"},"content":" ),"},{"lineNumber":32,"author":{"gitId":"-"},"content":" throwIfFalse(hasSessionRepo, () \u003d\u003e new Error(SESSION_DATA_MISSING_FIELDS)),"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" throwIfFalse(areViewsValid, () \u003d\u003e new Error(NO_VALID_OPEN_VIEWS)),"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" throwIfFalse(areReposDefined, () \u003d\u003e new Error(OPENED_VIEW_REPO_UNDEFINED))"},{"lineNumber":35,"author":{"gitId":"-"},"content":" );"},{"lineNumber":36,"author":{"gitId":"-"},"content":"}"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":39,"author":{"gitId":"-"},"content":" * Checks if Session Data has all its crucial fields present."},{"lineNumber":40,"author":{"gitId":"-"},"content":" * @param sessionData"},{"lineNumber":41,"author":{"gitId":"-"},"content":" */"},{"lineNumber":42,"author":{"gitId":"-"},"content":"function hasSessionRepo(sessionData: SessionData): boolean {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" return sessionData.sessionRepo !\u003d null \u0026\u0026 Array.isArray(sessionData.sessionRepo) \u0026\u0026 sessionData.sessionRepo.length \u003e 0;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"}"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" * Checks if Views belong to a pre-defined View."},{"lineNumber":48,"author":{"gitId":"-"},"content":" * @param sessionData"},{"lineNumber":49,"author":{"gitId":"-"},"content":" */"},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":"function areViewsValid(sessionData: SessionData): boolean {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" return sessionData.sessionRepo.reduce("},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" (isViewValidSoFar: boolean, currentViewRepo: SessionRepo) \u003d\u003e isViewValidSoFar \u0026\u0026 currentViewRepo.view in View,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" true"},{"lineNumber":54,"author":{"gitId":"-"},"content":" );"},{"lineNumber":55,"author":{"gitId":"-"},"content":"}"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" * Checks if each View has an associated repo defined as well."},{"lineNumber":59,"author":{"gitId":"-"},"content":" * @param sessionData"},{"lineNumber":60,"author":{"gitId":"-"},"content":" */"},{"lineNumber":61,"author":{"gitId":"-"},"content":"function areReposDefined(sessionData: SessionData): boolean {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" return sessionData.sessionRepo.reduce("},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" (isViewRepoDefinedSoFar: boolean, currentViewRepo: SessionRepo) \u003d\u003e"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" isViewRepoDefinedSoFar \u0026\u0026 !!currentViewRepo.repos \u0026\u0026 Array.isArray(currentViewRepo.repos) \u0026\u0026 currentViewRepo.repos.length \u003e 0,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" true"},{"lineNumber":66,"author":{"gitId":"-"},"content":" );"},{"lineNumber":67,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"NereusWB922":13,"-":54}},{"path":"src/app/core/models/view.model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"export enum View {"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" issuesViewer \u003d \u0027issuesViewer\u0027,"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" activityDashboard \u003d \u0027activityDashboard\u0027"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":4}},{"path":"src/app/core/services/auth.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Injectable, NgZone } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Title } from \u0027@angular/platform-browser\u0027;"},{"lineNumber":3,"author":{"gitId":"nknguyenhc"},"content":"import { Router, RouterStateSnapshot } from \u0027@angular/router\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { BehaviorSubject, from, Observable, of } from \u0027rxjs\u0027;"},{"lineNumber":5,"author":{"gitId":"nknguyenhc"},"content":"import { catchError, map, mergeMap } from \u0027rxjs/operators\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { AppConfig } from \u0027../../../environments/environment\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { generateSessionId } from \u0027../../shared/lib/session\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { uuid } from \u0027../../shared/lib/uuid\u0027;"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"import { View } from \u0027../models/view.model\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { ErrorHandlingService } from \u0027./error-handling.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027./github.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { GithubEventService } from \u0027./githubevent.service\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { IssueService } from \u0027./issue.service\u0027;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import { LabelService } from \u0027./label.service\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027./logging.service\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import { UserService } from \u0027./user.service\u0027;"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":"import { ViewService } from \u0027./view.service\u0027;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"export enum AuthState {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u0027NotAuthenticated\u0027,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u0027AwaitingAuthentication\u0027,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u0027ConfirmOAuthUser\u0027,"},{"lineNumber":23,"author":{"gitId":"-"},"content":" \u0027Authenticated\u0027"},{"lineNumber":24,"author":{"gitId":"-"},"content":"}"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":27,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":28,"author":{"gitId":"-"},"content":"})"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":31,"author":{"gitId":"-"},"content":" * Responsible for initiating the authentication process and querying or"},{"lineNumber":32,"author":{"gitId":"-"},"content":" * updating the application state with regards to authentication."},{"lineNumber":33,"author":{"gitId":"-"},"content":" */"},{"lineNumber":34,"author":{"gitId":"-"},"content":"export class AuthService {"},{"lineNumber":35,"author":{"gitId":"nknguyenhc"},"content":" private static readonly DEFAULT_NO_PERMISSION_TO_PRIVATE_REPOS \u003d false;"},{"lineNumber":36,"author":{"gitId":"nknguyenhc"},"content":" private static readonly SESSION_NEXT_KEY \u003d \u0027next\u0027;"},{"lineNumber":37,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" authStateSource \u003d new BehaviorSubject(AuthState.NotAuthenticated);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" currentAuthState \u003d this.authStateSource.asObservable();"},{"lineNumber":40,"author":{"gitId":"-"},"content":" accessToken \u003d new BehaviorSubject(undefined);"},{"lineNumber":41,"author":{"gitId":"-"},"content":" private state: string;"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" ENABLE_POPUP_MESSAGE \u003d \u0027Please enable pop-ups in your browser\u0027;"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" constructor("},{"lineNumber":46,"author":{"gitId":"-"},"content":" private router: Router,"},{"lineNumber":47,"author":{"gitId":"-"},"content":" private ngZone: NgZone,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" private githubService: GithubService,"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private userService: UserService,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" private issueService: IssueService,"},{"lineNumber":51,"author":{"gitId":"-"},"content":" private labelService: LabelService,"},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" private viewService: ViewService,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" private githubEventService: GithubEventService,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" private titleService: Title,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" private errorHandlingService: ErrorHandlingService,"},{"lineNumber":56,"author":{"gitId":"-"},"content":" private logger: LoggingService"},{"lineNumber":57,"author":{"gitId":"-"},"content":" ) {}"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":60,"author":{"gitId":"nknguyenhc"},"content":" * Stores the data about the next route in the session storage."},{"lineNumber":61,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":62,"author":{"gitId":"nknguyenhc"},"content":" storeNext(next: RouterStateSnapshot) {"},{"lineNumber":63,"author":{"gitId":"nknguyenhc"},"content":" sessionStorage.setItem(AuthService.SESSION_NEXT_KEY, next.url);"},{"lineNumber":64,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":65,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":66,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":67,"author":{"gitId":"nknguyenhc"},"content":" * Checks if there is a next route to be redirected to after login,"},{"lineNumber":68,"author":{"gitId":"nknguyenhc"},"content":" * by checking the session storage."},{"lineNumber":69,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":70,"author":{"gitId":"nknguyenhc"},"content":" hasNext(): boolean {"},{"lineNumber":71,"author":{"gitId":"nknguyenhc"},"content":" return sessionStorage.getItem(AuthService.SESSION_NEXT_KEY) !\u003d\u003d null;"},{"lineNumber":72,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":73,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":74,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":75,"author":{"gitId":"nknguyenhc"},"content":" * Checks if there is a next route to be redirected to after login,"},{"lineNumber":76,"author":{"gitId":"nknguyenhc"},"content":" * and start OAuth process automatically if there is."},{"lineNumber":77,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":78,"author":{"gitId":"nknguyenhc"},"content":" startOAuthIfHasNext() {"},{"lineNumber":79,"author":{"gitId":"nknguyenhc"},"content":" if (this.hasNext()) {"},{"lineNumber":80,"author":{"gitId":"nknguyenhc"},"content":" this.logger.info(`AuthService: Start OAuth because there is a next route`);"},{"lineNumber":81,"author":{"gitId":"nknguyenhc"},"content":" this.startOAuthProcess(AuthService.DEFAULT_NO_PERMISSION_TO_PRIVATE_REPOS);"},{"lineNumber":82,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":83,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":84,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":85,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":86,"author":{"gitId":"nknguyenhc"},"content":" * Checks if there is a next route to be redirected to after login,"},{"lineNumber":87,"author":{"gitId":"nknguyenhc"},"content":" * and complete the login process if there is."},{"lineNumber":88,"author":{"gitId":"nknguyenhc"},"content":" * Assuming that user has authenticated on Github, and the app is awaiting confirmation."},{"lineNumber":89,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":90,"author":{"gitId":"nknguyenhc"},"content":" completeLoginIfHasNext(username: string) {"},{"lineNumber":91,"author":{"gitId":"nknguyenhc"},"content":" if (!this.hasNext()) {"},{"lineNumber":92,"author":{"gitId":"nknguyenhc"},"content":" return;"},{"lineNumber":93,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":94,"author":{"gitId":"nknguyenhc"},"content":" this.logger.info(`AuthService: Automatically complete login because there is a next route`);"},{"lineNumber":95,"author":{"gitId":"nknguyenhc"},"content":" this.changeAuthState(AuthState.AwaitingAuthentication);"},{"lineNumber":96,"author":{"gitId":"nknguyenhc"},"content":" this.userService.createUserModel(username).subscribe("},{"lineNumber":97,"author":{"gitId":"nknguyenhc"},"content":" () \u003d\u003e {"},{"lineNumber":98,"author":{"gitId":"nknguyenhc"},"content":" this.changeAuthState(AuthState.Authenticated);"},{"lineNumber":99,"author":{"gitId":"nknguyenhc"},"content":" },"},{"lineNumber":100,"author":{"gitId":"nknguyenhc"},"content":" (err) \u003d\u003e {"},{"lineNumber":101,"author":{"gitId":"nknguyenhc"},"content":" this.changeAuthState(AuthState.NotAuthenticated);"},{"lineNumber":102,"author":{"gitId":"nknguyenhc"},"content":" this.errorHandlingService.handleError(err);"},{"lineNumber":103,"author":{"gitId":"nknguyenhc"},"content":" this.logger.info(`AuthService: Automatic completion of login failed with an error: ${err}`);"},{"lineNumber":104,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":105,"author":{"gitId":"nknguyenhc"},"content":" );"},{"lineNumber":106,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":107,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":108,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":109,"author":{"gitId":"nknguyenhc"},"content":" * Clears the next route from the session storage."},{"lineNumber":110,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":111,"author":{"gitId":"nknguyenhc"},"content":" clearNext() {"},{"lineNumber":112,"author":{"gitId":"nknguyenhc"},"content":" sessionStorage.removeItem(AuthService.SESSION_NEXT_KEY);"},{"lineNumber":113,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":114,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":115,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":116,"author":{"gitId":"nknguyenhc"},"content":" * Redirect to the URL indicating the next route."},{"lineNumber":117,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":118,"author":{"gitId":"nknguyenhc"},"content":" redirectToNext() {"},{"lineNumber":119,"author":{"gitId":"nknguyenhc"},"content":" const next \u003d sessionStorage.getItem(AuthService.SESSION_NEXT_KEY);"},{"lineNumber":120,"author":{"gitId":"NereusWB922"},"content":" this.viewService"},{"lineNumber":121,"author":{"gitId":"nknguyenhc"},"content":" .setupFromUrl(next)"},{"lineNumber":122,"author":{"gitId":"nknguyenhc"},"content":" .pipe("},{"lineNumber":123,"author":{"gitId":"nknguyenhc"},"content":" mergeMap(() \u003d\u003e this.setRepo()),"},{"lineNumber":124,"author":{"gitId":"nknguyenhc"},"content":" catchError((err) \u003d\u003e {"},{"lineNumber":125,"author":{"gitId":"nknguyenhc"},"content":" this.logger.info(`AuthService: Failed to redirect to next URL with error: ${err}`);"},{"lineNumber":126,"author":{"gitId":"nknguyenhc"},"content":" this.errorHandlingService.handleError(err);"},{"lineNumber":127,"author":{"gitId":"nknguyenhc"},"content":" this.clearNext();"},{"lineNumber":128,"author":{"gitId":"nknguyenhc"},"content":" return of(false);"},{"lineNumber":129,"author":{"gitId":"nknguyenhc"},"content":" })"},{"lineNumber":130,"author":{"gitId":"nknguyenhc"},"content":" )"},{"lineNumber":131,"author":{"gitId":"nknguyenhc"},"content":" .subscribe((isSetupSuccesssful) \u003d\u003e {"},{"lineNumber":132,"author":{"gitId":"nknguyenhc"},"content":" if (isSetupSuccesssful) {"},{"lineNumber":133,"author":{"gitId":"nknguyenhc"},"content":" this.router.navigateByUrl(next);"},{"lineNumber":134,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":135,"author":{"gitId":"nknguyenhc"},"content":" });"},{"lineNumber":136,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":137,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":139,"author":{"gitId":"-"},"content":" * Will store the OAuth token."},{"lineNumber":140,"author":{"gitId":"-"},"content":" */"},{"lineNumber":141,"author":{"gitId":"-"},"content":" storeOAuthAccessToken(token: string) {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" this.githubService.storeOAuthAccessToken(token);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" this.accessToken.next(token);"},{"lineNumber":144,"author":{"gitId":"-"},"content":" }"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" reset(): void {"},{"lineNumber":147,"author":{"gitId":"-"},"content":" this.logger.info(\u0027AuthService: Clearing access token and setting AuthState to NotAuthenticated.\u0027);"},{"lineNumber":148,"author":{"gitId":"-"},"content":" this.accessToken.next(undefined);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" this.changeAuthState(AuthState.NotAuthenticated);"},{"lineNumber":150,"author":{"gitId":"-"},"content":" this.ngZone.run(() \u003d\u003e this.router.navigate([\u0027\u0027]));"},{"lineNumber":151,"author":{"gitId":"-"},"content":" }"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":" logOut(): void {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" this.githubService.reset();"},{"lineNumber":155,"author":{"gitId":"-"},"content":" this.userService.reset();"},{"lineNumber":156,"author":{"gitId":"-"},"content":" this.issueService.reset(true);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" this.labelService.reset();"},{"lineNumber":158,"author":{"gitId":"NereusWB922"},"content":" this.viewService.reset();"},{"lineNumber":159,"author":{"gitId":"-"},"content":" this.githubEventService.reset();"},{"lineNumber":160,"author":{"gitId":"-"},"content":" this.logger.reset();"},{"lineNumber":161,"author":{"gitId":"-"},"content":" this.setLandingPageTitle();"},{"lineNumber":162,"author":{"gitId":"-"},"content":" this.issueService.setIssueTeamFilter(\u0027All Teams\u0027);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" this.reset();"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"NereusWB922"},"content":" setTitleWithViewDetail(): void {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" const appSetting \u003d require(\u0027../../../../package.json\u0027);"},{"lineNumber":168,"author":{"gitId":"NereusWB922"},"content":" const title \u003d `${appSetting.name} ${appSetting.version} - ${this.viewService.getCurrentRepositoryURL()}`;"},{"lineNumber":169,"author":{"gitId":"-"},"content":" this.logger.info(`AuthService: Setting Title as ${title}`);"},{"lineNumber":170,"author":{"gitId":"-"},"content":" this.titleService.setTitle(title);"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" setLandingPageTitle(): void {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" const appSetting \u003d require(\u0027../../../../package.json\u0027);"},{"lineNumber":175,"author":{"gitId":"-"},"content":" const title \u003d `${appSetting.name} ${appSetting.version}`;"},{"lineNumber":176,"author":{"gitId":"-"},"content":" this.logger.info(`AuthService: Setting Title as ${title}`);"},{"lineNumber":177,"author":{"gitId":"-"},"content":" this.titleService.setTitle(title);"},{"lineNumber":178,"author":{"gitId":"-"},"content":" }"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" isAuthenticated(): boolean {"},{"lineNumber":181,"author":{"gitId":"-"},"content":" return this.authStateSource.getValue() \u003d\u003d\u003d AuthState.Authenticated;"},{"lineNumber":182,"author":{"gitId":"-"},"content":" }"},{"lineNumber":183,"author":{"gitId":"-"},"content":""},{"lineNumber":184,"author":{"gitId":"-"},"content":" changeAuthState(newAuthState: AuthState) {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" if (newAuthState \u003d\u003d\u003d AuthState.Authenticated) {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" const sessionId \u003d generateSessionId();"},{"lineNumber":187,"author":{"gitId":"-"},"content":" this.issueService.setSessionId(sessionId);"},{"lineNumber":188,"author":{"gitId":"-"},"content":" this.logger.info(`AuthService: Successfully authenticated with session: ${sessionId}`);"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":" this.authStateSource.next(newAuthState);"},{"lineNumber":191,"author":{"gitId":"-"},"content":" }"},{"lineNumber":192,"author":{"gitId":"-"},"content":""},{"lineNumber":193,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":194,"author":{"gitId":"-"},"content":" * Generates and assigns an unguessable random \u0027state\u0027 string to pass to Github for protection against cross-site request forgery attacks"},{"lineNumber":195,"author":{"gitId":"-"},"content":" */"},{"lineNumber":196,"author":{"gitId":"-"},"content":" generateStateString() {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" this.state \u003d uuid();"},{"lineNumber":198,"author":{"gitId":"-"},"content":" sessionStorage.setItem(\u0027state\u0027, this.state);"},{"lineNumber":199,"author":{"gitId":"-"},"content":" }"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":" isReturnedStateSame(returnedState: string): boolean {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" const state \u003d sessionStorage.getItem(\u0027state\u0027);"},{"lineNumber":203,"author":{"gitId":"-"},"content":" return returnedState \u003d\u003d\u003d state;"},{"lineNumber":204,"author":{"gitId":"-"},"content":" }"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":207,"author":{"gitId":"-"},"content":" * Will start the Github OAuth web flow process."},{"lineNumber":208,"author":{"gitId":"-"},"content":" */"},{"lineNumber":209,"author":{"gitId":"-"},"content":" startOAuthProcess(hasPrivateConsent: boolean) {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" this.logger.info(\u0027AuthService: Starting authentication\u0027);"},{"lineNumber":211,"author":{"gitId":"-"},"content":" // Available OAuth scopes https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps#available-scopes"},{"lineNumber":212,"author":{"gitId":"-"},"content":" let permissionLevel \u003d \u0027public-repo\u0027;"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" if (hasPrivateConsent) {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" // grants WATcher access to private repos if user allows"},{"lineNumber":216,"author":{"gitId":"-"},"content":" permissionLevel \u003d \u0027repo\u0027;"},{"lineNumber":217,"author":{"gitId":"-"},"content":" }"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":" const githubRepoPermission \u003d permissionLevel; // don\u0027t allow changes after logging ins"},{"lineNumber":220,"author":{"gitId":"-"},"content":""},{"lineNumber":221,"author":{"gitId":"-"},"content":" this.changeAuthState(AuthState.AwaitingAuthentication);"},{"lineNumber":222,"author":{"gitId":"-"},"content":""},{"lineNumber":223,"author":{"gitId":"-"},"content":" this.generateStateString();"},{"lineNumber":224,"author":{"gitId":"-"},"content":" this.redirectToOAuthPage("},{"lineNumber":225,"author":{"gitId":"-"},"content":" encodeURI("},{"lineNumber":226,"author":{"gitId":"-"},"content":" `${AppConfig.githubUrl}/login/oauth/authorize?client_id\u003d${AppConfig.clientId}\u0026scope\u003d${githubRepoPermission},read:user\u0026state\u003d${this.state}`"},{"lineNumber":227,"author":{"gitId":"-"},"content":" )"},{"lineNumber":228,"author":{"gitId":"-"},"content":" );"},{"lineNumber":229,"author":{"gitId":"-"},"content":" this.logger.info(`AuthService: Redirecting for Github authentication`);"},{"lineNumber":230,"author":{"gitId":"-"},"content":" }"},{"lineNumber":231,"author":{"gitId":"-"},"content":""},{"lineNumber":232,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":233,"author":{"gitId":"-"},"content":" * Handles the clean up required after authentication and setting up of repository is completed."},{"lineNumber":234,"author":{"gitId":"-"},"content":" */"},{"lineNumber":235,"author":{"gitId":"nknguyenhc"},"content":" handleSetRepoSuccess(repoName: string) {"},{"lineNumber":236,"author":{"gitId":"NereusWB922"},"content":" this.setTitleWithViewDetail();"},{"lineNumber":237,"author":{"gitId":"NereusWB922"},"content":" this.router.navigate([View.issuesViewer], {"},{"lineNumber":238,"author":{"gitId":"nknguyenhc"},"content":" queryParams: {"},{"lineNumber":239,"author":{"gitId":"NereusWB922"},"content":" [ViewService.REPO_QUERY_PARAM_KEY]: repoName"},{"lineNumber":240,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":241,"author":{"gitId":"nknguyenhc"},"content":" });"},{"lineNumber":242,"author":{"gitId":"-"},"content":" }"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":245,"author":{"gitId":"-"},"content":" * Setup repository after authentication."},{"lineNumber":246,"author":{"gitId":"-"},"content":" */"},{"lineNumber":247,"author":{"gitId":"-"},"content":" setRepo(): Observable\u003cboolean\u003e {"},{"lineNumber":248,"author":{"gitId":"NereusWB922"},"content":" return from(this.viewService.initializeCurrentRepository()).pipe("},{"lineNumber":249,"author":{"gitId":"-"},"content":" map(() \u003d\u003e {"},{"lineNumber":250,"author":{"gitId":"NereusWB922"},"content":" if (!this.viewService.currentRepo) {"},{"lineNumber":251,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":252,"author":{"gitId":"-"},"content":" }"},{"lineNumber":253,"author":{"gitId":"-"},"content":" this.githubEventService.setLatestChangeEvent();"},{"lineNumber":254,"author":{"gitId":"NereusWB922"},"content":" this.handleSetRepoSuccess(this.viewService.currentRepo.toString());"},{"lineNumber":255,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":256,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":257,"author":{"gitId":"-"},"content":" catchError((error) \u003d\u003e {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" this.errorHandlingService.handleError(error);"},{"lineNumber":259,"author":{"gitId":"nknguyenhc"},"content":" this.clearNext();"},{"lineNumber":260,"author":{"gitId":"-"},"content":" return of(false);"},{"lineNumber":261,"author":{"gitId":"-"},"content":" })"},{"lineNumber":262,"author":{"gitId":"-"},"content":" );"},{"lineNumber":263,"author":{"gitId":"-"},"content":" }"},{"lineNumber":264,"author":{"gitId":"-"},"content":""},{"lineNumber":265,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":266,"author":{"gitId":"-"},"content":" * Will redirect to GitHub OAuth page"},{"lineNumber":267,"author":{"gitId":"-"},"content":" */"},{"lineNumber":268,"author":{"gitId":"-"},"content":" private redirectToOAuthPage(url: string): void {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" if (url \u003d\u003d null) {"},{"lineNumber":270,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":271,"author":{"gitId":"-"},"content":" }"},{"lineNumber":272,"author":{"gitId":"-"},"content":" window.location.href \u003d url;"},{"lineNumber":273,"author":{"gitId":"-"},"content":" }"},{"lineNumber":274,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":88,"NereusWB922":14,"-":172}},{"path":"src/app/core/services/error-message.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":4,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":5,"author":{"gitId":"-"},"content":"})"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":8,"author":{"gitId":"-"},"content":" * Contains all error message prompts to user."},{"lineNumber":9,"author":{"gitId":"-"},"content":" */"},{"lineNumber":10,"author":{"gitId":"-"},"content":"export class ErrorMessageService {"},{"lineNumber":11,"author":{"gitId":"-"},"content":" public static repositoryNotPresentMessage() {"},{"lineNumber":12,"author":{"gitId":"-"},"content":" return \u0027Invalid repository name. Please provide Github repository URL or the repository name in the format Org/Repository Name.\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":" }"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"nknguyenhc"},"content":" public static invalidUrlMessage() {"},{"lineNumber":16,"author":{"gitId":"nknguyenhc"},"content":" return \u0027URL is invalid, or repository does not exist, please indicate the repository you wish to view to continue.\u0027;"},{"lineNumber":17,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":18,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":" public static unableToFetchIssuesMessage() {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch issue.\u0027;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" }"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" public static unableToFetchMilestoneMessage() {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch milestones.\u0027;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" public static unableToFetchLabelsMessage() {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch labels.\u0027;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" public static usersUnassignableMessage(assignee: string) {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" return `Cannot assign ${assignee} to the issue. Please check if ${assignee} is authorized.`;"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" public static unableToFetchUsersMessage() {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch assignable users for repository\u0027;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" }"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" public static unableToFetchEventsMessage() {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch issue events for repository\u0027;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" public static unableToFetchActivityEventsMessage() {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch activity events for repository\u0027;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" public static unableToFetchDataFileMessage() {"},{"lineNumber":48,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch data file.\u0027;"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" public static unableToFetchLatestReleaseMessage() {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch latest release.\u0027;"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" public static unableToFetchSettingsFileMessage() {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch settings file.\u0027;"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" public static unableToFetchAuthenticatedUsersMessage() {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" return \u0027Failed to fetch authenticated user.\u0027;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" public static unableToOpenInBrowserMessage() {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" return \u0027Unable to open this issue in Browser\u0027;"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" public static applicationVersionOutdatedMessage() {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" return \u0027Please update to the latest version of WATcher.\u0027;"},{"lineNumber":69,"author":{"gitId":"-"},"content":" }"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" public static multipleDropdownOptionsErrorMessage() {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" return \u0027Supply either Dropdown option number or text, not both.\u0027;"},{"lineNumber":73,"author":{"gitId":"-"},"content":" }"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" public static noDropdownOptionsErrorMessage() {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" return \u0027No Dropdown identification parameters supplied.\u0027;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":4,"-":74}},{"path":"src/app/core/services/factories/factory.auth.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { NgZone } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Title } from \u0027@angular/platform-browser\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { Router } from \u0027@angular/router\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"// import { AppConfig } from \u0027../../../../environments/environment\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { AuthService } from \u0027../auth.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { ErrorHandlingService } from \u0027../error-handling.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027../github.service\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { GithubEventService } from \u0027../githubevent.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { IssueService } from \u0027../issue.service\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { LabelService } from \u0027../label.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027../logging.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"// import { MockAuthService } from \u0027../mocks/mock.auth.service\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { UserService } from \u0027../user.service\u0027;"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"import { ViewService } from \u0027../view.service\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"export function AuthServiceFactory("},{"lineNumber":17,"author":{"gitId":"-"},"content":" router: Router,"},{"lineNumber":18,"author":{"gitId":"-"},"content":" ngZone: NgZone,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" githubService: GithubService,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" userService: UserService,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" issueService: IssueService,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" labelService: LabelService,"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" viewService: ViewService,"},{"lineNumber":24,"author":{"gitId":"-"},"content":" githubEventService: GithubEventService,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" titleService: Title,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" errorHandlingService: ErrorHandlingService,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" logger: LoggingService"},{"lineNumber":28,"author":{"gitId":"-"},"content":") {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" // TODO: Write Mocks"},{"lineNumber":30,"author":{"gitId":"-"},"content":" // if (AppConfig.test) {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" // return new MockAuthService("},{"lineNumber":32,"author":{"gitId":"-"},"content":" // router,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" // ngZone,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" // githubService,"},{"lineNumber":35,"author":{"gitId":"-"},"content":" // userService,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" // issueService,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" // labelService,"},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" // viewService,"},{"lineNumber":39,"author":{"gitId":"-"},"content":" // githubEventService,"},{"lineNumber":40,"author":{"gitId":"-"},"content":" // titleService,"},{"lineNumber":41,"author":{"gitId":"-"},"content":" // logger"},{"lineNumber":42,"author":{"gitId":"-"},"content":" // );"},{"lineNumber":43,"author":{"gitId":"-"},"content":" // }"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return new AuthService("},{"lineNumber":45,"author":{"gitId":"-"},"content":" router,"},{"lineNumber":46,"author":{"gitId":"-"},"content":" ngZone,"},{"lineNumber":47,"author":{"gitId":"-"},"content":" githubService,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" userService,"},{"lineNumber":49,"author":{"gitId":"-"},"content":" issueService,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" labelService,"},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":" viewService,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" githubEventService,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" titleService,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" errorHandlingService,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" logger"},{"lineNumber":56,"author":{"gitId":"-"},"content":" );"},{"lineNumber":57,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"NereusWB922":4,"-":53}},{"path":"src/app/core/services/factories/factory.github.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Apollo } from \u0027apollo-angular\u0027;"},{"lineNumber":2,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"// import { AppConfig } from \u0027../../../../environments/environment\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { ErrorHandlingService } from \u0027../error-handling.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027../github.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027../logging.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"// import { MockGithubService } from \u0027../mocks/mock.github.service\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"export function GithubServiceFactory(handling: ErrorHandlingService, apollo: Apollo, logger: LoggingService) {"},{"lineNumber":10,"author":{"gitId":"-"},"content":" // TODO: Write Mocks"},{"lineNumber":11,"author":{"gitId":"-"},"content":" // if (AppConfig.test) {"},{"lineNumber":12,"author":{"gitId":"-"},"content":" // return new MockGithubService();"},{"lineNumber":13,"author":{"gitId":"-"},"content":" // }"},{"lineNumber":14,"author":{"gitId":"-"},"content":" return new GithubService(handling, apollo, logger);"},{"lineNumber":15,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"MadLamprey":1,"-":14}},{"path":"src/app/core/services/factories/factory.issue.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"// import { AppConfig } from \u0027../../../../environments/environment\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027../github.service\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { IssueService } from \u0027../issue.service\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"// import { MockIssueService } from \u0027../mocks/mock.issue.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { UserService } from \u0027../user.service\u0027;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"import { ViewService } from \u0027../view.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"export function IssueServiceFactory(githubService: GithubService, userService: UserService, viewService: ViewService) {"},{"lineNumber":9,"author":{"gitId":"-"},"content":" // TODO: Write Mocks"},{"lineNumber":10,"author":{"gitId":"-"},"content":" // if (AppConfig.test) {"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" // return new MockIssueService(githubService, viewService, dataService);"},{"lineNumber":12,"author":{"gitId":"-"},"content":" // }"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" return new IssueService(githubService, userService, viewService);"},{"lineNumber":14,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"NereusWB922":4,"-":10}},{"path":"src/app/core/services/filters.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"Arif-Khalid"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"Arif-Khalid"},"content":"import { Sort } from \u0027@angular/material/sort\u0027;"},{"lineNumber":3,"author":{"gitId":"Arif-Khalid"},"content":"import { ActivatedRoute, Router } from \u0027@angular/router\u0027;"},{"lineNumber":4,"author":{"gitId":"Arif-Khalid"},"content":"import { BehaviorSubject, pipe } from \u0027rxjs\u0027;"},{"lineNumber":5,"author":{"gitId":"Arif-Khalid"},"content":"import { SimpleLabel } from \u0027../models/label.model\u0027;"},{"lineNumber":6,"author":{"gitId":"Arif-Khalid"},"content":"import { Milestone } from \u0027../models/milestone.model\u0027;"},{"lineNumber":7,"author":{"gitId":"Arif-Khalid"},"content":"import { LoggingService } from \u0027./logging.service\u0027;"},{"lineNumber":8,"author":{"gitId":"nknguyenhc"},"content":"import { MilestoneService } from \u0027./milestone.service\u0027;"},{"lineNumber":9,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":10,"author":{"gitId":"Arif-Khalid"},"content":"export type Filter \u003d {"},{"lineNumber":11,"author":{"gitId":"Arif-Khalid"},"content":" title: string;"},{"lineNumber":12,"author":{"gitId":"nknguyenhc"},"content":" status: string[];"},{"lineNumber":13,"author":{"gitId":"Arif-Khalid"},"content":" type: string;"},{"lineNumber":14,"author":{"gitId":"Arif-Khalid"},"content":" sort: Sort;"},{"lineNumber":15,"author":{"gitId":"Arif-Khalid"},"content":" labels: string[];"},{"lineNumber":16,"author":{"gitId":"Arif-Khalid"},"content":" milestones: string[];"},{"lineNumber":17,"author":{"gitId":"Arif-Khalid"},"content":" hiddenLabels: Set\u003cstring\u003e;"},{"lineNumber":18,"author":{"gitId":"nknguyenhc"},"content":" deselectedLabels: Set\u003cstring\u003e;"},{"lineNumber":19,"author":{"gitId":"MadLamprey"},"content":" itemsPerPage: number;"},{"lineNumber":20,"author":{"gitId":"Arif-Khalid"},"content":"};"},{"lineNumber":21,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":22,"author":{"gitId":"Arif-Khalid"},"content":"@Injectable({"},{"lineNumber":23,"author":{"gitId":"Arif-Khalid"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":24,"author":{"gitId":"Arif-Khalid"},"content":"})"},{"lineNumber":25,"author":{"gitId":"Arif-Khalid"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"Arif-Khalid"},"content":" * Responsible for centralising filters"},{"lineNumber":27,"author":{"gitId":"Arif-Khalid"},"content":" * Filters are subscribed to and emitted from this service"},{"lineNumber":28,"author":{"gitId":"Arif-Khalid"},"content":" */"},{"lineNumber":29,"author":{"gitId":"Arif-Khalid"},"content":"export class FiltersService {"},{"lineNumber":30,"author":{"gitId":"Arif-Khalid"},"content":" public static readonly PRESET_VIEW_QUERY_PARAM_KEY \u003d \u0027presetview\u0027;"},{"lineNumber":31,"author":{"gitId":"MadLamprey"},"content":" private itemsPerPage \u003d 20;"},{"lineNumber":32,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":33,"author":{"gitId":"Arif-Khalid"},"content":" readonly defaultFilter: Filter \u003d {"},{"lineNumber":34,"author":{"gitId":"Arif-Khalid"},"content":" title: \u0027\u0027,"},{"lineNumber":35,"author":{"gitId":"Arif-Khalid"},"content":" status: [\u0027open pullrequest\u0027, \u0027merged pullrequest\u0027, \u0027open issue\u0027, \u0027closed issue\u0027],"},{"lineNumber":36,"author":{"gitId":"Arif-Khalid"},"content":" type: \u0027all\u0027,"},{"lineNumber":37,"author":{"gitId":"Arif-Khalid"},"content":" sort: { active: \u0027status\u0027, direction: \u0027asc\u0027 },"},{"lineNumber":38,"author":{"gitId":"Arif-Khalid"},"content":" labels: [],"},{"lineNumber":39,"author":{"gitId":"Arif-Khalid"},"content":" milestones: [],"},{"lineNumber":40,"author":{"gitId":"Arif-Khalid"},"content":" hiddenLabels: new Set\u003cstring\u003e(),"},{"lineNumber":41,"author":{"gitId":"Arif-Khalid"},"content":" deselectedLabels: new Set\u003cstring\u003e(),"},{"lineNumber":42,"author":{"gitId":"Arif-Khalid"},"content":" itemsPerPage: this.itemsPerPage"},{"lineNumber":43,"author":{"gitId":"Arif-Khalid"},"content":" };"},{"lineNumber":44,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":45,"author":{"gitId":"nknguyenhc"},"content":" readonly presetViews: {"},{"lineNumber":46,"author":{"gitId":"Arif-Khalid"},"content":" [key: string]: () \u003d\u003e Partial\u003cFilter\u003e;"},{"lineNumber":47,"author":{"gitId":"nknguyenhc"},"content":" } \u003d {"},{"lineNumber":48,"author":{"gitId":"nknguyenhc"},"content":" currentlyActive: () \u003d\u003e ({"},{"lineNumber":49,"author":{"gitId":"nknguyenhc"},"content":" title: \u0027\u0027,"},{"lineNumber":50,"author":{"gitId":"nknguyenhc"},"content":" status: [\u0027open pullrequest\u0027, \u0027merged pullrequest\u0027, \u0027open issue\u0027, \u0027closed issue\u0027],"},{"lineNumber":51,"author":{"gitId":"nknguyenhc"},"content":" type: \u0027all\u0027,"},{"lineNumber":52,"author":{"gitId":"nknguyenhc"},"content":" sort: { active: \u0027status\u0027, direction: \u0027asc\u0027 },"},{"lineNumber":53,"author":{"gitId":"nknguyenhc"},"content":" labels: [],"},{"lineNumber":54,"author":{"gitId":"nknguyenhc"},"content":" milestones: this.getMilestonesForCurrentlyActive().map((milestone) \u003d\u003e milestone.title),"},{"lineNumber":55,"author":{"gitId":"MadLamprey"},"content":" deselectedLabels: new Set\u003cstring\u003e(),"},{"lineNumber":56,"author":{"gitId":"Arif-Khalid"},"content":" itemsPerPage: 20"},{"lineNumber":57,"author":{"gitId":"nknguyenhc"},"content":" }),"},{"lineNumber":58,"author":{"gitId":"nknguyenhc"},"content":" contributions: () \u003d\u003e ({"},{"lineNumber":59,"author":{"gitId":"nknguyenhc"},"content":" title: \u0027\u0027,"},{"lineNumber":60,"author":{"gitId":"nknguyenhc"},"content":" status: [\u0027open pullrequest\u0027, \u0027merged pullrequest\u0027, \u0027open issue\u0027, \u0027closed issue\u0027],"},{"lineNumber":61,"author":{"gitId":"nknguyenhc"},"content":" type: \u0027all\u0027,"},{"lineNumber":62,"author":{"gitId":"nknguyenhc"},"content":" sort: { active: \u0027id\u0027, direction: \u0027desc\u0027 },"},{"lineNumber":63,"author":{"gitId":"nknguyenhc"},"content":" labels: [],"},{"lineNumber":64,"author":{"gitId":"nknguyenhc"},"content":" milestones: this.milestoneService.milestones.map((milestone) \u003d\u003e milestone.title),"},{"lineNumber":65,"author":{"gitId":"MadLamprey"},"content":" deselectedLabels: new Set\u003cstring\u003e(),"},{"lineNumber":66,"author":{"gitId":"Arif-Khalid"},"content":" itemsPerPage: 20"},{"lineNumber":67,"author":{"gitId":"nknguyenhc"},"content":" }),"},{"lineNumber":68,"author":{"gitId":"Arif-Khalid"},"content":" custom: () \u003d\u003e ({})"},{"lineNumber":69,"author":{"gitId":"nknguyenhc"},"content":" };"},{"lineNumber":70,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":71,"author":{"gitId":"nknguyenhc"},"content":" // List of keys in the new filter change that causes current filter to not qualify to be a preset view."},{"lineNumber":72,"author":{"gitId":"Arif-Khalid"},"content":" readonly presetChangingKeys \u003d new Set\u003cstring\u003e([\u0027status\u0027, \u0027type\u0027, \u0027sort\u0027, \u0027milestones\u0027, \u0027labels\u0027, \u0027deselectedLabels\u0027]);"},{"lineNumber":73,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":74,"author":{"gitId":"Arif-Khalid"},"content":" public filter$ \u003d new BehaviorSubject\u003cFilter\u003e(this.defaultFilter);"},{"lineNumber":75,"author":{"gitId":"nknguyenhc"},"content":" // Either \u0027currentlyActive\u0027, \u0027contributions\u0027, or \u0027custom\u0027."},{"lineNumber":76,"author":{"gitId":"nknguyenhc"},"content":" public presetView$ \u003d new BehaviorSubject\u003cstring\u003e(\u0027currentlyActive\u0027);"},{"lineNumber":77,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":78,"author":{"gitId":"Arif-Khalid"},"content":" // Helps in determining whether all milestones were selected from previous repo during sanitization of milestones"},{"lineNumber":79,"author":{"gitId":"Arif-Khalid"},"content":" private previousMilestonesLength \u003d 0;"},{"lineNumber":80,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":81,"author":{"gitId":"Arif-Khalid"},"content":" constructor("},{"lineNumber":82,"author":{"gitId":"Arif-Khalid"},"content":" private logger: LoggingService,"},{"lineNumber":83,"author":{"gitId":"Arif-Khalid"},"content":" private router: Router,"},{"lineNumber":84,"author":{"gitId":"Arif-Khalid"},"content":" private route: ActivatedRoute,"},{"lineNumber":85,"author":{"gitId":"Arif-Khalid"},"content":" private milestoneService: MilestoneService"},{"lineNumber":86,"author":{"gitId":"MadLamprey"},"content":" ) {"},{"lineNumber":87,"author":{"gitId":"MadLamprey"},"content":" this.filter$.subscribe((filter: Filter) \u003d\u003e {"},{"lineNumber":88,"author":{"gitId":"MadLamprey"},"content":" this.itemsPerPage \u003d filter.itemsPerPage;"},{"lineNumber":89,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":90,"author":{"gitId":"MadLamprey"},"content":" }"},{"lineNumber":91,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":92,"author":{"gitId":"Arif-Khalid"},"content":" private pushFiltersToUrl(): void {"},{"lineNumber":93,"author":{"gitId":"Arif-Khalid"},"content":" const queryParams \u003d { ...this.route.snapshot.queryParams };"},{"lineNumber":94,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":95,"author":{"gitId":"Arif-Khalid"},"content":" for (const filterName of Object.keys(this.filter$.value)) {"},{"lineNumber":96,"author":{"gitId":"Arif-Khalid"},"content":" const filterValue \u003d this.filter$.value[filterName];"},{"lineNumber":97,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":98,"author":{"gitId":"Arif-Khalid"},"content":" // Don\u0027t include empty or null filters"},{"lineNumber":99,"author":{"gitId":"Arif-Khalid"},"content":" // Intended behaviour to reset to default if 0 of a certain filter are selected"},{"lineNumber":100,"author":{"gitId":"Arif-Khalid"},"content":" switch (filterName) {"},{"lineNumber":101,"author":{"gitId":"Arif-Khalid"},"content":" // Strings"},{"lineNumber":102,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027title\u0027:"},{"lineNumber":103,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027type\u0027:"},{"lineNumber":104,"author":{"gitId":"Arif-Khalid"},"content":" if (!filterValue) {"},{"lineNumber":105,"author":{"gitId":"Arif-Khalid"},"content":" delete queryParams[filterName];"},{"lineNumber":106,"author":{"gitId":"Arif-Khalid"},"content":" continue;"},{"lineNumber":107,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":108,"author":{"gitId":"Arif-Khalid"},"content":" queryParams[filterName] \u003d filterValue;"},{"lineNumber":109,"author":{"gitId":"Arif-Khalid"},"content":" break;"},{"lineNumber":110,"author":{"gitId":"Arif-Khalid"},"content":" // Arrays"},{"lineNumber":111,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027status\u0027:"},{"lineNumber":112,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027labels\u0027:"},{"lineNumber":113,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027milestones\u0027:"},{"lineNumber":114,"author":{"gitId":"Arif-Khalid"},"content":" if (filterValue.length \u003d\u003d\u003d 0) {"},{"lineNumber":115,"author":{"gitId":"Arif-Khalid"},"content":" delete queryParams[filterName];"},{"lineNumber":116,"author":{"gitId":"Arif-Khalid"},"content":" continue;"},{"lineNumber":117,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":118,"author":{"gitId":"Arif-Khalid"},"content":" queryParams[filterName] \u003d filterValue;"},{"lineNumber":119,"author":{"gitId":"Arif-Khalid"},"content":" break;"},{"lineNumber":120,"author":{"gitId":"Arif-Khalid"},"content":" // Sets"},{"lineNumber":121,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027selectedLabels\u0027:"},{"lineNumber":122,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027deselectedLabels\u0027:"},{"lineNumber":123,"author":{"gitId":"Arif-Khalid"},"content":" if (filterValue.size \u003d\u003d\u003d 0) {"},{"lineNumber":124,"author":{"gitId":"Arif-Khalid"},"content":" delete queryParams[filterName];"},{"lineNumber":125,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":126,"author":{"gitId":"Arif-Khalid"},"content":" queryParams[filterName] \u003d [...filterValue];"},{"lineNumber":127,"author":{"gitId":"Arif-Khalid"},"content":" break;"},{"lineNumber":128,"author":{"gitId":"Arif-Khalid"},"content":" // Objects"},{"lineNumber":129,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027sort\u0027:"},{"lineNumber":130,"author":{"gitId":"Arif-Khalid"},"content":" queryParams[filterName] \u003d JSON.stringify(filterValue);"},{"lineNumber":131,"author":{"gitId":"Arif-Khalid"},"content":" break;"},{"lineNumber":132,"author":{"gitId":"MadLamprey"},"content":" case \u0027itemsPerPage\u0027:"},{"lineNumber":133,"author":{"gitId":"MadLamprey"},"content":" queryParams[filterName] \u003d filterValue.toString();"},{"lineNumber":134,"author":{"gitId":"MadLamprey"},"content":" break;"},{"lineNumber":135,"author":{"gitId":"Arif-Khalid"},"content":" default:"},{"lineNumber":136,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":137,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":138,"author":{"gitId":"Arif-Khalid"},"content":" queryParams[FiltersService.PRESET_VIEW_QUERY_PARAM_KEY] \u003d this.presetView$.value;"},{"lineNumber":139,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":140,"author":{"gitId":"Arif-Khalid"},"content":" this.router.navigate([], {"},{"lineNumber":141,"author":{"gitId":"Arif-Khalid"},"content":" relativeTo: this.route,"},{"lineNumber":142,"author":{"gitId":"Arif-Khalid"},"content":" queryParams,"},{"lineNumber":143,"author":{"gitId":"Arif-Khalid"},"content":" replaceUrl: true"},{"lineNumber":144,"author":{"gitId":"Arif-Khalid"},"content":" });"},{"lineNumber":145,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":146,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":147,"author":{"gitId":"Arif-Khalid"},"content":" clearFilters(): void {"},{"lineNumber":148,"author":{"gitId":"Arif-Khalid"},"content":" this.updatePresetView(\u0027currentlyActive\u0027);"},{"lineNumber":149,"author":{"gitId":"Arif-Khalid"},"content":" this.previousMilestonesLength \u003d 0;"},{"lineNumber":150,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":151,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":152,"author":{"gitId":"Arif-Khalid"},"content":" initializeFromURLParams() {"},{"lineNumber":153,"author":{"gitId":"Arif-Khalid"},"content":" const nextFilter: Filter \u003d this.defaultFilter;"},{"lineNumber":154,"author":{"gitId":"Arif-Khalid"},"content":" const queryParams \u003d this.route.snapshot.queryParamMap;"},{"lineNumber":155,"author":{"gitId":"Arif-Khalid"},"content":" try {"},{"lineNumber":156,"author":{"gitId":"Arif-Khalid"},"content":" for (const filterName of Object.keys(nextFilter)) {"},{"lineNumber":157,"author":{"gitId":"Arif-Khalid"},"content":" // Check if there is no such param in url"},{"lineNumber":158,"author":{"gitId":"Arif-Khalid"},"content":" if (queryParams.get(filterName) \u003d\u003d\u003d null) {"},{"lineNumber":159,"author":{"gitId":"Arif-Khalid"},"content":" continue;"},{"lineNumber":160,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":161,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":162,"author":{"gitId":"Arif-Khalid"},"content":" const filterData \u003d queryParams.getAll(filterName);"},{"lineNumber":163,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":164,"author":{"gitId":"Arif-Khalid"},"content":" switch (filterName) {"},{"lineNumber":165,"author":{"gitId":"Arif-Khalid"},"content":" // Strings"},{"lineNumber":166,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027title\u0027:"},{"lineNumber":167,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027type\u0027:"},{"lineNumber":168,"author":{"gitId":"Arif-Khalid"},"content":" nextFilter[filterName] \u003d filterData[0];"},{"lineNumber":169,"author":{"gitId":"Arif-Khalid"},"content":" break;"},{"lineNumber":170,"author":{"gitId":"Arif-Khalid"},"content":" // Arrays"},{"lineNumber":171,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027status\u0027:"},{"lineNumber":172,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027labels\u0027:"},{"lineNumber":173,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027milestones\u0027:"},{"lineNumber":174,"author":{"gitId":"Arif-Khalid"},"content":" nextFilter[filterName] \u003d filterData;"},{"lineNumber":175,"author":{"gitId":"Arif-Khalid"},"content":" break;"},{"lineNumber":176,"author":{"gitId":"Arif-Khalid"},"content":" // Sets"},{"lineNumber":177,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027selectedLabels\u0027:"},{"lineNumber":178,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027deselectedLabels\u0027:"},{"lineNumber":179,"author":{"gitId":"Arif-Khalid"},"content":" nextFilter[filterName] \u003d new Set(filterData);"},{"lineNumber":180,"author":{"gitId":"Arif-Khalid"},"content":" break;"},{"lineNumber":181,"author":{"gitId":"Arif-Khalid"},"content":" // Objects"},{"lineNumber":182,"author":{"gitId":"Arif-Khalid"},"content":" case \u0027sort\u0027:"},{"lineNumber":183,"author":{"gitId":"Arif-Khalid"},"content":" nextFilter[filterName] \u003d JSON.parse(filterData[0]);"},{"lineNumber":184,"author":{"gitId":"Arif-Khalid"},"content":" break;"},{"lineNumber":185,"author":{"gitId":"MadLamprey"},"content":" case \u0027itemsPerPage\u0027:"},{"lineNumber":186,"author":{"gitId":"MadLamprey"},"content":" nextFilter[filterName] \u003d Number(filterData[0]);"},{"lineNumber":187,"author":{"gitId":"MadLamprey"},"content":" break;"},{"lineNumber":188,"author":{"gitId":"Arif-Khalid"},"content":" default:"},{"lineNumber":189,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":190,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":191,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":192,"author":{"gitId":"Arif-Khalid"},"content":" this.updateFilters(nextFilter);"},{"lineNumber":193,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":194,"author":{"gitId":"Arif-Khalid"},"content":" // Use preset view if set in url"},{"lineNumber":195,"author":{"gitId":"Arif-Khalid"},"content":" const presetView \u003d queryParams.get(FiltersService.PRESET_VIEW_QUERY_PARAM_KEY);"},{"lineNumber":196,"author":{"gitId":"Arif-Khalid"},"content":" if (presetView \u0026\u0026 this.presetViews.hasOwnProperty(presetView)) {"},{"lineNumber":197,"author":{"gitId":"Arif-Khalid"},"content":" this.updatePresetView(presetView);"},{"lineNumber":198,"author":{"gitId":"Arif-Khalid"},"content":" } else {"},{"lineNumber":199,"author":{"gitId":"Arif-Khalid"},"content":" this.updatePresetView(\u0027currentlyActive\u0027);"},{"lineNumber":200,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":201,"author":{"gitId":"Arif-Khalid"},"content":" } catch (err) {"},{"lineNumber":202,"author":{"gitId":"Arif-Khalid"},"content":" this.logger.info(`FiltersService: Update filters from URL failed with an error: ${err}`);"},{"lineNumber":203,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":204,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":205,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":206,"author":{"gitId":"Arif-Khalid"},"content":" updateFilters(newFilters: Partial\u003cFilter\u003e): void {"},{"lineNumber":207,"author":{"gitId":"nknguyenhc"},"content":" const nextDropdownFilter: Filter \u003d {"},{"lineNumber":208,"author":{"gitId":"Arif-Khalid"},"content":" ...this.filter$.value,"},{"lineNumber":209,"author":{"gitId":"Arif-Khalid"},"content":" ...newFilters"},{"lineNumber":210,"author":{"gitId":"Arif-Khalid"},"content":" };"},{"lineNumber":211,"author":{"gitId":"nknguyenhc"},"content":" this.filter$.next(nextDropdownFilter);"},{"lineNumber":212,"author":{"gitId":"nknguyenhc"},"content":" this.updatePresetViewFromFilters(newFilters);"},{"lineNumber":213,"author":{"gitId":"Arif-Khalid"},"content":" this.pushFiltersToUrl();"},{"lineNumber":214,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":215,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":216,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":217,"author":{"gitId":"nknguyenhc"},"content":" * Updates the filters without updating the preset view."},{"lineNumber":218,"author":{"gitId":"Arif-Khalid"},"content":" * This should only be called when there are new labels/milestones fetched."},{"lineNumber":219,"author":{"gitId":"Arif-Khalid"},"content":" * The preset view will be reapplied in order to account for changes in milestone categories on upstream"},{"lineNumber":220,"author":{"gitId":"nknguyenhc"},"content":" * @param newFilters The filters with new values"},{"lineNumber":221,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":222,"author":{"gitId":"nknguyenhc"},"content":" private updateFiltersWithoutUpdatingPresetView(newFilters: Partial\u003cFilter\u003e): void {"},{"lineNumber":223,"author":{"gitId":"Arif-Khalid"},"content":" const presetFilters \u003d this.presetViews[this.presetView$.value]();"},{"lineNumber":224,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":225,"author":{"gitId":"Arif-Khalid"},"content":" // Remove filters that should not be reset when labels/milestones are fetched"},{"lineNumber":226,"author":{"gitId":"Arif-Khalid"},"content":" delete presetFilters.title;"},{"lineNumber":227,"author":{"gitId":"Arif-Khalid"},"content":" delete presetFilters.itemsPerPage;"},{"lineNumber":228,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":229,"author":{"gitId":"nknguyenhc"},"content":" const nextDropdownFilter: Filter \u003d {"},{"lineNumber":230,"author":{"gitId":"nknguyenhc"},"content":" ...this.filter$.value,"},{"lineNumber":231,"author":{"gitId":"Arif-Khalid"},"content":" ...newFilters,"},{"lineNumber":232,"author":{"gitId":"Arif-Khalid"},"content":" ...presetFilters"},{"lineNumber":233,"author":{"gitId":"nknguyenhc"},"content":" };"},{"lineNumber":234,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":235,"author":{"gitId":"nknguyenhc"},"content":" this.filter$.next(nextDropdownFilter);"},{"lineNumber":236,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":237,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":238,"author":{"gitId":"nknguyenhc"},"content":" private updatePresetViewFromFilters(newFilter: Partial\u003cFilter\u003e): void {"},{"lineNumber":239,"author":{"gitId":"nknguyenhc"},"content":" for (const key of Object.keys(newFilter)) {"},{"lineNumber":240,"author":{"gitId":"nknguyenhc"},"content":" if (this.presetChangingKeys.has(key)) {"},{"lineNumber":241,"author":{"gitId":"nknguyenhc"},"content":" this.presetView$.next(\u0027custom\u0027);"},{"lineNumber":242,"author":{"gitId":"nknguyenhc"},"content":" return;"},{"lineNumber":243,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":244,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":245,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":246,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":247,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":248,"author":{"gitId":"nknguyenhc"},"content":" * Updates the filter based on a preset view."},{"lineNumber":249,"author":{"gitId":"nknguyenhc"},"content":" * @param presetViewName The name of the preset view, either \u0027currentlyActive\u0027, \u0027contributions\u0027, or \u0027custom\u0027."},{"lineNumber":250,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":251,"author":{"gitId":"nknguyenhc"},"content":" updatePresetView(presetViewName: string) {"},{"lineNumber":252,"author":{"gitId":"Arif-Khalid"},"content":" this.filter$.next({ ...this.filter$.value, ...this.presetViews[presetViewName]() });"},{"lineNumber":253,"author":{"gitId":"nknguyenhc"},"content":" this.presetView$.next(presetViewName);"},{"lineNumber":254,"author":{"gitId":"Arif-Khalid"},"content":" this.pushFiltersToUrl();"},{"lineNumber":255,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":256,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":257,"author":{"gitId":"Arif-Khalid"},"content":" sanitizeLabels(allLabels: SimpleLabel[]): void {"},{"lineNumber":258,"author":{"gitId":"Arif-Khalid"},"content":" const allLabelsSet \u003d new Set(allLabels.map((label) \u003d\u003e label.name));"},{"lineNumber":259,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":260,"author":{"gitId":"Arif-Khalid"},"content":" const newHiddenLabels: Set\u003cstring\u003e \u003d new Set();"},{"lineNumber":261,"author":{"gitId":"Arif-Khalid"},"content":" for (const hiddenLabel of this.filter$.value.hiddenLabels) {"},{"lineNumber":262,"author":{"gitId":"Arif-Khalid"},"content":" if (allLabelsSet.has(hiddenLabel)) {"},{"lineNumber":263,"author":{"gitId":"Arif-Khalid"},"content":" newHiddenLabels.add(hiddenLabel);"},{"lineNumber":264,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":265,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":266,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":267,"author":{"gitId":"nknguyenhc"},"content":" const newDeselectedLabels: Set\u003cstring\u003e \u003d new Set();"},{"lineNumber":268,"author":{"gitId":"nknguyenhc"},"content":" for (const deselectedLabel of this.filter$.value.deselectedLabels) {"},{"lineNumber":269,"author":{"gitId":"nknguyenhc"},"content":" if (allLabelsSet.has(deselectedLabel)) {"},{"lineNumber":270,"author":{"gitId":"nknguyenhc"},"content":" newDeselectedLabels.add(deselectedLabel);"},{"lineNumber":271,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":272,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":273,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":274,"author":{"gitId":"nknguyenhc"},"content":" const newLabels \u003d this.filter$.value.labels.filter((label) \u003d\u003e allLabelsSet.has(label));"},{"lineNumber":275,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":276,"author":{"gitId":"nknguyenhc"},"content":" this.updateFiltersWithoutUpdatingPresetView({"},{"lineNumber":277,"author":{"gitId":"nknguyenhc"},"content":" labels: newLabels,"},{"lineNumber":278,"author":{"gitId":"nknguyenhc"},"content":" hiddenLabels: newHiddenLabels,"},{"lineNumber":279,"author":{"gitId":"nknguyenhc"},"content":" deselectedLabels: newDeselectedLabels"},{"lineNumber":280,"author":{"gitId":"nknguyenhc"},"content":" });"},{"lineNumber":281,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":282,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":283,"author":{"gitId":"Arif-Khalid"},"content":" sanitizeMilestones(allMilestones: Milestone[]) {"},{"lineNumber":284,"author":{"gitId":"MadLamprey"},"content":" const milestones \u003d allMilestones.map((milestone) \u003d\u003e milestone.title);"},{"lineNumber":285,"author":{"gitId":"MadLamprey"},"content":" milestones.push(Milestone.IssueWithoutMilestone.title, Milestone.PRWithoutMilestone.title);"},{"lineNumber":286,"author":{"gitId":"MadLamprey"},"content":" const allMilestonesSet \u003d new Set(milestones);"},{"lineNumber":287,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":288,"author":{"gitId":"Arif-Khalid"},"content":" // All previous milestones were selected, reset to all new milestones selected"},{"lineNumber":289,"author":{"gitId":"Arif-Khalid"},"content":" if (this.filter$.value.milestones.length \u003d\u003d\u003d this.previousMilestonesLength) {"},{"lineNumber":290,"author":{"gitId":"nknguyenhc"},"content":" this.updateFiltersWithoutUpdatingPresetView({ milestones: [...allMilestonesSet] });"},{"lineNumber":291,"author":{"gitId":"MadLamprey"},"content":" this.previousMilestonesLength \u003d allMilestonesSet.size;"},{"lineNumber":292,"author":{"gitId":"Arif-Khalid"},"content":" return;"},{"lineNumber":293,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":294,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":295,"author":{"gitId":"Arif-Khalid"},"content":" const newMilestones: string[] \u003d [];"},{"lineNumber":296,"author":{"gitId":"Arif-Khalid"},"content":" for (const milestone of this.filter$.value.milestones) {"},{"lineNumber":297,"author":{"gitId":"Arif-Khalid"},"content":" if (allMilestonesSet.has(milestone)) {"},{"lineNumber":298,"author":{"gitId":"Arif-Khalid"},"content":" newMilestones.push(milestone);"},{"lineNumber":299,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":300,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":301,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":302,"author":{"gitId":"Arif-Khalid"},"content":" // No applicable milestones, reset to all milestones selected"},{"lineNumber":303,"author":{"gitId":"Arif-Khalid"},"content":" if (newMilestones.length \u003d\u003d\u003d 0) {"},{"lineNumber":304,"author":{"gitId":"Arif-Khalid"},"content":" newMilestones.push(...allMilestonesSet);"},{"lineNumber":305,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":306,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":307,"author":{"gitId":"nknguyenhc"},"content":" this.updateFiltersWithoutUpdatingPresetView({ milestones: newMilestones });"},{"lineNumber":308,"author":{"gitId":"MadLamprey"},"content":" this.previousMilestonesLength \u003d allMilestonesSet.size;"},{"lineNumber":309,"author":{"gitId":"Arif-Khalid"},"content":" }"},{"lineNumber":310,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":311,"author":{"gitId":"nknguyenhc"},"content":" getMilestonesForCurrentlyActive(): Milestone[] {"},{"lineNumber":312,"author":{"gitId":"nknguyenhc"},"content":" const earliestOpenMilestone \u003d this.milestoneService.getEarliestOpenMilestone();"},{"lineNumber":313,"author":{"gitId":"nknguyenhc"},"content":" if (earliestOpenMilestone) {"},{"lineNumber":314,"author":{"gitId":"NereusWB922"},"content":" return [earliestOpenMilestone, Milestone.PRWithoutMilestone];"},{"lineNumber":315,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":316,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":317,"author":{"gitId":"nknguyenhc"},"content":" const latestClosedMilestone \u003d this.milestoneService.getLatestClosedMilestone();"},{"lineNumber":318,"author":{"gitId":"nknguyenhc"},"content":" if (latestClosedMilestone) {"},{"lineNumber":319,"author":{"gitId":"NereusWB922"},"content":" return [latestClosedMilestone, Milestone.PRWithoutMilestone];"},{"lineNumber":320,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":321,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":322,"author":{"gitId":"NereusWB922"},"content":" return [...this.milestoneService.milestones, Milestone.PRWithoutMilestone];"},{"lineNumber":323,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":324,"author":{"gitId":"Arif-Khalid"},"content":"}"}],"authorContributionMap":{"nknguyenhc":83,"Arif-Khalid":217,"NereusWB922":3,"MadLamprey":21}},{"path":"src/app/core/services/github.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { HttpErrorResponse } from \u0027@angular/common/http\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"MadLamprey"},"content":"import { ApolloQueryResult } from \u0027@apollo/client/core\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { Apollo, QueryRef } from \u0027apollo-angular\u0027;"},{"lineNumber":5,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { DocumentNode } from \u0027graphql\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { BehaviorSubject, forkJoin, from, merge, Observable, of, throwError } from \u0027rxjs\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { catchError, filter, flatMap, map, throwIfEmpty } from \u0027rxjs/operators\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":10,"author":{"gitId":"-"},"content":" FetchIssue,"},{"lineNumber":11,"author":{"gitId":"-"},"content":" FetchIssueQuery,"},{"lineNumber":12,"author":{"gitId":"-"},"content":" FetchIssues,"},{"lineNumber":13,"author":{"gitId":"-"},"content":" FetchIssuesQuery,"},{"lineNumber":14,"author":{"gitId":"-"},"content":" FetchPullRequests,"},{"lineNumber":15,"author":{"gitId":"-"},"content":" FetchPullRequestsQuery"},{"lineNumber":16,"author":{"gitId":"-"},"content":"} from \u0027../../../../graphql/graphql-types\u0027;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import { AppConfig } from \u0027../../../environments/environment\u0027;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import { getNumberOfPages } from \u0027../../shared/lib/github-paginator-parser\u0027;"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":"import { GithubUser, RawGithubUser } from \u0027../models/github-user.model\u0027;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import { IssueLastModifiedManagerModel } from \u0027../models/github/cache-manager/issue-last-modified-manager.model\u0027;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import { IssuesCacheManager } from \u0027../models/github/cache-manager/issues-cache-manager.model\u0027;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import { GithubEvent } from \u0027../models/github/github-event.model\u0027;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import { GithubGraphqlIssue } from \u0027../models/github/github-graphql.issue\u0027;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import { GithubGraphqlIssueOrPr } from \u0027../models/github/github-graphql.issue-or-pr\u0027;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import RestGithubIssueFilter from \u0027../models/github/github-issue-filter.model\u0027;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import { GithubIssue } from \u0027../models/github/github-issue.model\u0027;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import { GithubResponse } from \u0027../models/github/github-response.model\u0027;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import { GithubRelease } from \u0027../models/github/github.release\u0027;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import { SessionData } from \u0027../models/session.model\u0027;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import { ERRORCODE_NOT_FOUND, ErrorHandlingService } from \u0027./error-handling.service\u0027;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import { ErrorMessageService } from \u0027./error-message.service\u0027;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027./logging.service\u0027;"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":"const { Octokit } \u003d require(\u0027@octokit/rest\u0027);"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":"const WATCHER_ORG \u003d \u0027WATcher-org\u0027;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"const WATCHER_REPO \u003d \u0027WATcher\u0027;"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":"/** Owner of Repository to watch */"},{"lineNumber":40,"author":{"gitId":"-"},"content":"let ORG_NAME \u003d \u0027\u0027; // repoOrg"},{"lineNumber":41,"author":{"gitId":"-"},"content":"/** Name of Repository to watch */"},{"lineNumber":42,"author":{"gitId":"-"},"content":"let REPO \u003d \u0027\u0027; // repoName"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":"/** Owner of Settings repository, currently not used */"},{"lineNumber":45,"author":{"gitId":"-"},"content":"let MOD_ORG \u003d \u0027\u0027;"},{"lineNumber":46,"author":{"gitId":"-"},"content":"/** Name of Settings repository, currently not used */"},{"lineNumber":47,"author":{"gitId":"-"},"content":"let DATA_REPO \u003d \u0027\u0027;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"const MAX_ITEMS_PER_PAGE \u003d 100;"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":"let octokit \u003d new Octokit();"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":53,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":54,"author":{"gitId":"-"},"content":"})"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":57,"author":{"gitId":"-"},"content":" * Responsible for communicating with GitHub to create, update, read and delete"},{"lineNumber":58,"author":{"gitId":"-"},"content":" * features related to Github using GitHub API Requests."},{"lineNumber":59,"author":{"gitId":"-"},"content":" * For example, issues, issue labels and repositories."},{"lineNumber":60,"author":{"gitId":"-"},"content":" */"},{"lineNumber":61,"author":{"gitId":"-"},"content":"export class GithubService {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" private static readonly IF_NONE_MATCH_EMPTY \u003d { \u0027If-None-Match\u0027: \u0027\u0027 };"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" private issuesCacheManager \u003d new IssuesCacheManager();"},{"lineNumber":65,"author":{"gitId":"-"},"content":" private issuesLastModifiedManager \u003d new IssueLastModifiedManagerModel();"},{"lineNumber":66,"author":{"gitId":"-"},"content":" private issueQueryRefs \u003d new Map\u003cnumber, QueryRef\u003cFetchIssueQuery\u003e\u003e();"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" constructor(private errorHandlingService: ErrorHandlingService, private apollo: Apollo, private logger: LoggingService) {}"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" storeOAuthAccessToken(accessToken: string) {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" octokit \u003d new Octokit({"},{"lineNumber":72,"author":{"gitId":"-"},"content":" auth() {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" return `Token ${accessToken}`;"},{"lineNumber":74,"author":{"gitId":"-"},"content":" },"},{"lineNumber":75,"author":{"gitId":"-"},"content":" log: {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" debug: (message, ...otherInfo) \u003d\u003e this.logger.debug(\u0027GithubService: \u0027 + message, ...otherInfo),"},{"lineNumber":77,"author":{"gitId":"-"},"content":" // Do not log info for HTTP response 304 due to repeated polling"},{"lineNumber":78,"author":{"gitId":"-"},"content":" info: (message, ...otherInfo) \u003d\u003e"},{"lineNumber":79,"author":{"gitId":"-"},"content":" /304 in \\d+ms$/.test(message) ? undefined : this.logger.info(\u0027GithubService: \u0027 + message, ...otherInfo),"},{"lineNumber":80,"author":{"gitId":"-"},"content":" warn: (message, ...otherInfo) \u003d\u003e this.logger.warn(\u0027GithubService: \u0027 + message, ...otherInfo),"},{"lineNumber":81,"author":{"gitId":"-"},"content":" error: (message, ...otherInfo) \u003d\u003e this.logger.error(\u0027GithubService: \u0027 + message, ...otherInfo)"},{"lineNumber":82,"author":{"gitId":"-"},"content":" }"},{"lineNumber":83,"author":{"gitId":"-"},"content":" });"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":87,"author":{"gitId":"-"},"content":" * Sets settings repository. Not used."},{"lineNumber":88,"author":{"gitId":"-"},"content":" * @param orgName WATcher organisation"},{"lineNumber":89,"author":{"gitId":"-"},"content":" * @param dataRepo WATcher repository"},{"lineNumber":90,"author":{"gitId":"-"},"content":" */"},{"lineNumber":91,"author":{"gitId":"-"},"content":" storeOrganizationDetails(orgName: string, dataRepo: string) {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" MOD_ORG \u003d orgName;"},{"lineNumber":93,"author":{"gitId":"-"},"content":" DATA_REPO \u003d dataRepo;"},{"lineNumber":94,"author":{"gitId":"-"},"content":" }"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":97,"author":{"gitId":"-"},"content":" * Sets repository to watch. This repository is used for fetching from Github."},{"lineNumber":98,"author":{"gitId":"NereusWB922"},"content":" * @param viewRepoOwner Repository owner"},{"lineNumber":99,"author":{"gitId":"-"},"content":" * @param repoName Repository name"},{"lineNumber":100,"author":{"gitId":"-"},"content":" */"},{"lineNumber":101,"author":{"gitId":"NereusWB922"},"content":" storeViewDetails(viewRepoOwner: string, repoName: string) {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" REPO \u003d repoName;"},{"lineNumber":103,"author":{"gitId":"NereusWB922"},"content":" ORG_NAME \u003d viewRepoOwner;"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":107,"author":{"gitId":"-"},"content":" * Fetches an array of filtered GitHubIssues using GraphQL query."},{"lineNumber":108,"author":{"gitId":"-"},"content":" * In WATcher, this includes pull requests."},{"lineNumber":109,"author":{"gitId":"-"},"content":" *"},{"lineNumber":110,"author":{"gitId":"-"},"content":" * @param issuesFilter - The issue filter."},{"lineNumber":111,"author":{"gitId":"-"},"content":" * @returns An observable array of filtered GithubIssues"},{"lineNumber":112,"author":{"gitId":"-"},"content":" */"},{"lineNumber":113,"author":{"gitId":"-"},"content":" fetchIssuesGraphql(issuesFilter: RestGithubIssueFilter): Observable\u003cArray\u003cGithubIssue\u003e\u003e {"},{"lineNumber":114,"author":{"gitId":"-"},"content":" const graphqlFilter \u003d issuesFilter.convertToGraphqlFilter();"},{"lineNumber":115,"author":{"gitId":"-"},"content":" /*"},{"lineNumber":116,"author":{"gitId":"-"},"content":" * Github Issues consists of issues and pull requests in WATcher."},{"lineNumber":117,"author":{"gitId":"-"},"content":" */"},{"lineNumber":118,"author":{"gitId":"nknguyenhc"},"content":" return this.toFetchIssues(issuesFilter).pipe("},{"lineNumber":119,"author":{"gitId":"-"},"content":" filter((toFetch) \u003d\u003e toFetch),"},{"lineNumber":120,"author":{"gitId":"-"},"content":" flatMap(() \u003d\u003e {"},{"lineNumber":121,"author":{"gitId":"nknguyenhc"},"content":" return merge("},{"lineNumber":122,"author":{"gitId":"nknguyenhc"},"content":" this.fetchGraphqlList\u003cFetchIssuesQuery, GithubGraphqlIssueOrPr\u003e("},{"lineNumber":123,"author":{"gitId":"-"},"content":" FetchIssues,"},{"lineNumber":124,"author":{"gitId":"-"},"content":" { owner: ORG_NAME, name: REPO, filter: graphqlFilter },"},{"lineNumber":125,"author":{"gitId":"-"},"content":" (result) \u003d\u003e result.data.repository.issues.edges,"},{"lineNumber":126,"author":{"gitId":"-"},"content":" GithubGraphqlIssueOrPr"},{"lineNumber":127,"author":{"gitId":"nknguyenhc"},"content":" ),"},{"lineNumber":128,"author":{"gitId":"nknguyenhc"},"content":" this.fetchGraphqlList\u003cFetchPullRequestsQuery, GithubGraphqlIssueOrPr\u003e("},{"lineNumber":129,"author":{"gitId":"-"},"content":" FetchPullRequests,"},{"lineNumber":130,"author":{"gitId":"-"},"content":" { owner: ORG_NAME, name: REPO },"},{"lineNumber":131,"author":{"gitId":"-"},"content":" (result) \u003d\u003e result.data.repository.pullRequests.edges,"},{"lineNumber":132,"author":{"gitId":"-"},"content":" GithubGraphqlIssueOrPr"},{"lineNumber":133,"author":{"gitId":"nknguyenhc"},"content":" )"},{"lineNumber":134,"author":{"gitId":"-"},"content":" );"},{"lineNumber":135,"author":{"gitId":"-"},"content":" })"},{"lineNumber":136,"author":{"gitId":"-"},"content":" );"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":140,"author":{"gitId":"-"},"content":" * Checks if there are pages of filtered issues that are not cached in the cache model,"},{"lineNumber":141,"author":{"gitId":"-"},"content":" * and updates the model to cache these new pages."},{"lineNumber":142,"author":{"gitId":"-"},"content":" * @param filter - The issue filter."},{"lineNumber":143,"author":{"gitId":"-"},"content":" * @returns Observable\u003cboolean\u003e that returns true if there are pages that do not exist in the cache model."},{"lineNumber":144,"author":{"gitId":"-"},"content":" */"},{"lineNumber":145,"author":{"gitId":"-"},"content":" private toFetchIssues(filter: RestGithubIssueFilter): Observable\u003cboolean\u003e {"},{"lineNumber":146,"author":{"gitId":"-"},"content":" const pageFetchLimit \u003d 100;"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" let responseInFirstPage: GithubResponse\u003cGithubIssue[]\u003e;"},{"lineNumber":149,"author":{"gitId":"-"},"content":" return this.getIssuesAPICall(filter, 1).pipe("},{"lineNumber":150,"author":{"gitId":"-"},"content":" map((response: GithubResponse\u003cGithubIssue[]\u003e) \u003d\u003e {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" responseInFirstPage \u003d response;"},{"lineNumber":152,"author":{"gitId":"-"},"content":" return getNumberOfPages(response);"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":154,"author":{"gitId":"-"},"content":" flatMap((numOfPages: number) \u003d\u003e {"},{"lineNumber":155,"author":{"gitId":"-"},"content":" const apiCalls: Observable\u003cGithubResponse\u003cGithubIssue[]\u003e\u003e[] \u003d [];"},{"lineNumber":156,"author":{"gitId":"-"},"content":" if (numOfPages \u003e pageFetchLimit) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" throw new Error(`Repository has too many pages (${numOfPages}), not supported.`);"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":" for (let i \u003d 2; i \u003c\u003d numOfPages; i++) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" apiCalls.push(this.getIssuesAPICall(filter, i));"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":" return apiCalls.length \u003d\u003d\u003d 0 ? of([]) : forkJoin(apiCalls);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":164,"author":{"gitId":"-"},"content":" map((resultArray: GithubResponse\u003cGithubIssue[]\u003e[]) \u003d\u003e {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" const responses \u003d [responseInFirstPage, ...resultArray];"},{"lineNumber":166,"author":{"gitId":"-"},"content":" const isCached \u003d responses.reduce((result, response) \u003d\u003e {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" return result \u0026\u0026 response.isCached;"},{"lineNumber":168,"author":{"gitId":"-"},"content":" }, true);"},{"lineNumber":169,"author":{"gitId":"-"},"content":" responses.forEach((resp, index) \u003d\u003e this.issuesCacheManager.set(index + 1, resp));"},{"lineNumber":170,"author":{"gitId":"-"},"content":" return !isCached;"},{"lineNumber":171,"author":{"gitId":"-"},"content":" })"},{"lineNumber":172,"author":{"gitId":"-"},"content":" );"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":176,"author":{"gitId":"-"},"content":" * Checks if the specified repository exists."},{"lineNumber":177,"author":{"gitId":"-"},"content":" * @param owner - Owner of Specified Repository."},{"lineNumber":178,"author":{"gitId":"-"},"content":" * @param repo - Name of Repository."},{"lineNumber":179,"author":{"gitId":"-"},"content":" */"},{"lineNumber":180,"author":{"gitId":"-"},"content":" isRepositoryPresent(owner: string, repo: string): Observable\u003cboolean\u003e {"},{"lineNumber":181,"author":{"gitId":"-"},"content":" return from(octokit.repos.get({ owner: owner, repo: repo, headers: GithubService.IF_NONE_MATCH_EMPTY })).pipe("},{"lineNumber":182,"author":{"gitId":"-"},"content":" map((rawData: { status: number }) \u003d\u003e {"},{"lineNumber":183,"author":{"gitId":"-"},"content":" return rawData.status !\u003d\u003d ERRORCODE_NOT_FOUND;"},{"lineNumber":184,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":185,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" return of(false);"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":188,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.repositoryNotPresentMessage()))"},{"lineNumber":189,"author":{"gitId":"-"},"content":" );"},{"lineNumber":190,"author":{"gitId":"-"},"content":" }"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":193,"author":{"gitId":"-"},"content":" * Fetches information about an issue using GraphQL."},{"lineNumber":194,"author":{"gitId":"-"},"content":" *"},{"lineNumber":195,"author":{"gitId":"-"},"content":" * If the issue is not modified, return a `304 - Not Modified` response."},{"lineNumber":196,"author":{"gitId":"-"},"content":" *"},{"lineNumber":197,"author":{"gitId":"-"},"content":" * @param id - The issue id."},{"lineNumber":198,"author":{"gitId":"-"},"content":" * @returns Observable\u003cGithubGraphqlIssue\u003e that represents the response object."},{"lineNumber":199,"author":{"gitId":"-"},"content":" */"},{"lineNumber":200,"author":{"gitId":"-"},"content":" fetchIssueGraphql(id: number): Observable\u003cGithubGraphqlIssue\u003e {"},{"lineNumber":201,"author":{"gitId":"-"},"content":" if (this.issueQueryRefs.get(id) \u003d\u003d\u003d undefined) {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" const newQueryRef \u003d this.apollo.watchQuery\u003cFetchIssueQuery\u003e({"},{"lineNumber":203,"author":{"gitId":"-"},"content":" query: FetchIssue,"},{"lineNumber":204,"author":{"gitId":"-"},"content":" variables: {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" owner: ORG_NAME,"},{"lineNumber":206,"author":{"gitId":"-"},"content":" name: REPO,"},{"lineNumber":207,"author":{"gitId":"-"},"content":" issueId: id"},{"lineNumber":208,"author":{"gitId":"-"},"content":" }"},{"lineNumber":209,"author":{"gitId":"-"},"content":" });"},{"lineNumber":210,"author":{"gitId":"-"},"content":" this.issueQueryRefs.set(id, newQueryRef);"},{"lineNumber":211,"author":{"gitId":"-"},"content":" }"},{"lineNumber":212,"author":{"gitId":"-"},"content":""},{"lineNumber":213,"author":{"gitId":"-"},"content":" const queryRef \u003d this.issueQueryRefs.get(id);"},{"lineNumber":214,"author":{"gitId":"-"},"content":" return this.toFetchIssue(id).pipe("},{"lineNumber":215,"author":{"gitId":"-"},"content":" filter((toFetch) \u003d\u003e toFetch),"},{"lineNumber":216,"author":{"gitId":"-"},"content":" flatMap(() \u003d\u003e from(queryRef.refetch())),"},{"lineNumber":217,"author":{"gitId":"-"},"content":" map((value: ApolloQueryResult\u003cFetchIssueQuery\u003e) \u003d\u003e {"},{"lineNumber":218,"author":{"gitId":"-"},"content":" return new GithubGraphqlIssue(value.data.repository.issue);"},{"lineNumber":219,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":220,"author":{"gitId":"-"},"content":" throwIfEmpty(() \u003d\u003e new HttpErrorResponse({ status: 304 }))"},{"lineNumber":221,"author":{"gitId":"-"},"content":" );"},{"lineNumber":222,"author":{"gitId":"-"},"content":" }"},{"lineNumber":223,"author":{"gitId":"-"},"content":""},{"lineNumber":224,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":225,"author":{"gitId":"-"},"content":" * Checks if the issue has been modified since the last query, and"},{"lineNumber":226,"author":{"gitId":"-"},"content":" * updates the model to reflect the last modified time."},{"lineNumber":227,"author":{"gitId":"-"},"content":" *"},{"lineNumber":228,"author":{"gitId":"-"},"content":" * @param id - The issue id."},{"lineNumber":229,"author":{"gitId":"-"},"content":" * @returns Observable\u003cboolean\u003e that returns true if the issue has been modified."},{"lineNumber":230,"author":{"gitId":"-"},"content":" */"},{"lineNumber":231,"author":{"gitId":"-"},"content":" toFetchIssue(id: number): Observable\u003cboolean\u003e {"},{"lineNumber":232,"author":{"gitId":"-"},"content":" return from("},{"lineNumber":233,"author":{"gitId":"-"},"content":" octokit.issues.get({"},{"lineNumber":234,"author":{"gitId":"-"},"content":" owner: ORG_NAME,"},{"lineNumber":235,"author":{"gitId":"-"},"content":" repo: REPO,"},{"lineNumber":236,"author":{"gitId":"-"},"content":" issue_number: id,"},{"lineNumber":237,"author":{"gitId":"-"},"content":" headers: { \u0027If-Modified-Since\u0027: this.issuesLastModifiedManager.get(id) }"},{"lineNumber":238,"author":{"gitId":"-"},"content":" })"},{"lineNumber":239,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":240,"author":{"gitId":"-"},"content":" map((response: GithubResponse\u003cGithubIssue\u003e) \u003d\u003e {"},{"lineNumber":241,"author":{"gitId":"-"},"content":" this.issuesLastModifiedManager.set(id, response.headers[\u0027last-modified\u0027]);"},{"lineNumber":242,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":243,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":244,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchIssuesMessage()))"},{"lineNumber":245,"author":{"gitId":"-"},"content":" );"},{"lineNumber":246,"author":{"gitId":"-"},"content":" }"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" fetchAllMilestones(): Observable\u003cArray\u003c{}\u003e\u003e {"},{"lineNumber":249,"author":{"gitId":"-"},"content":" return from("},{"lineNumber":250,"author":{"gitId":"-"},"content":" octokit.issues.listMilestonesForRepo({"},{"lineNumber":251,"author":{"gitId":"-"},"content":" owner: ORG_NAME,"},{"lineNumber":252,"author":{"gitId":"-"},"content":" repo: REPO,"},{"lineNumber":253,"author":{"gitId":"-"},"content":" state: \u0027all\u0027,"},{"lineNumber":254,"author":{"gitId":"-"},"content":" per_page: MAX_ITEMS_PER_PAGE,"},{"lineNumber":255,"author":{"gitId":"-"},"content":" headers: GithubService.IF_NONE_MATCH_EMPTY"},{"lineNumber":256,"author":{"gitId":"-"},"content":" })"},{"lineNumber":257,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":258,"author":{"gitId":"-"},"content":" map((response) \u003d\u003e {"},{"lineNumber":259,"author":{"gitId":"-"},"content":" return response[\u0027data\u0027];"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":261,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchMilestoneMessage()))"},{"lineNumber":262,"author":{"gitId":"-"},"content":" );"},{"lineNumber":263,"author":{"gitId":"-"},"content":" }"},{"lineNumber":264,"author":{"gitId":"-"},"content":""},{"lineNumber":265,"author":{"gitId":"-"},"content":" fetchAllLabels(): Observable\u003cArray\u003c{}\u003e\u003e {"},{"lineNumber":266,"author":{"gitId":"-"},"content":" return from("},{"lineNumber":267,"author":{"gitId":"-"},"content":" octokit.issues.listLabelsForRepo({"},{"lineNumber":268,"author":{"gitId":"-"},"content":" owner: ORG_NAME,"},{"lineNumber":269,"author":{"gitId":"-"},"content":" repo: REPO,"},{"lineNumber":270,"author":{"gitId":"-"},"content":" per_page: MAX_ITEMS_PER_PAGE,"},{"lineNumber":271,"author":{"gitId":"-"},"content":" headers: GithubService.IF_NONE_MATCH_EMPTY"},{"lineNumber":272,"author":{"gitId":"-"},"content":" })"},{"lineNumber":273,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":274,"author":{"gitId":"-"},"content":" map((response) \u003d\u003e {"},{"lineNumber":275,"author":{"gitId":"-"},"content":" return response[\u0027data\u0027];"},{"lineNumber":276,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":277,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchLabelsMessage()))"},{"lineNumber":278,"author":{"gitId":"-"},"content":" );"},{"lineNumber":279,"author":{"gitId":"-"},"content":" }"},{"lineNumber":280,"author":{"gitId":"-"},"content":""},{"lineNumber":281,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":282,"author":{"gitId":"-"},"content":" * Checks if the given list of users are allowed to be assigned to an issue."},{"lineNumber":283,"author":{"gitId":"-"},"content":" * @param assignees - GitHub usernames to be checked"},{"lineNumber":284,"author":{"gitId":"-"},"content":" */"},{"lineNumber":285,"author":{"gitId":"-"},"content":" areUsersAssignable(assignees: string[]): Observable\u003cvoid\u003e {"},{"lineNumber":286,"author":{"gitId":"-"},"content":" return from("},{"lineNumber":287,"author":{"gitId":"-"},"content":" octokit.issues.listAssignees({"},{"lineNumber":288,"author":{"gitId":"-"},"content":" owner: ORG_NAME,"},{"lineNumber":289,"author":{"gitId":"-"},"content":" repo: REPO"},{"lineNumber":290,"author":{"gitId":"-"},"content":" })"},{"lineNumber":291,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":292,"author":{"gitId":"-"},"content":" map(({ data }: { data: { login: string }[] }) \u003d\u003e data.map(({ login }) \u003d\u003e login)),"},{"lineNumber":293,"author":{"gitId":"-"},"content":" map((assignables: string[]) \u003d\u003e"},{"lineNumber":294,"author":{"gitId":"-"},"content":" assignees.forEach((assignee) \u003d\u003e {"},{"lineNumber":295,"author":{"gitId":"-"},"content":" if (!assignables.includes(assignee)) {"},{"lineNumber":296,"author":{"gitId":"-"},"content":" throw new Error(ErrorMessageService.usersUnassignableMessage(assignee));"},{"lineNumber":297,"author":{"gitId":"-"},"content":" }"},{"lineNumber":298,"author":{"gitId":"-"},"content":" })"},{"lineNumber":299,"author":{"gitId":"-"},"content":" )"},{"lineNumber":300,"author":{"gitId":"-"},"content":" );"},{"lineNumber":301,"author":{"gitId":"-"},"content":" }"},{"lineNumber":302,"author":{"gitId":"-"},"content":""},{"lineNumber":303,"author":{"gitId":"-"},"content":" getUsersAssignable(): Observable\u003cGithubUser[]\u003e {"},{"lineNumber":304,"author":{"gitId":"-"},"content":" return from("},{"lineNumber":305,"author":{"gitId":"-"},"content":" octokit.issues.listAssignees({"},{"lineNumber":306,"author":{"gitId":"-"},"content":" owner: ORG_NAME,"},{"lineNumber":307,"author":{"gitId":"-"},"content":" repo: REPO"},{"lineNumber":308,"author":{"gitId":"-"},"content":" })"},{"lineNumber":309,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":310,"author":{"gitId":"-"},"content":" map((response) \u003d\u003e {"},{"lineNumber":311,"author":{"gitId":"NereusWB922"},"content":" const data: RawGithubUser[] \u003d response[\u0027data\u0027];"},{"lineNumber":312,"author":{"gitId":"NereusWB922"},"content":" return data.map((rawGithubUser) \u003d\u003e {"},{"lineNumber":313,"author":{"gitId":"NereusWB922"},"content":" return new GithubUser(rawGithubUser);"},{"lineNumber":314,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":315,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":316,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchUsersMessage()))"},{"lineNumber":317,"author":{"gitId":"-"},"content":" );"},{"lineNumber":318,"author":{"gitId":"-"},"content":" }"},{"lineNumber":319,"author":{"gitId":"-"},"content":""},{"lineNumber":320,"author":{"gitId":"-"},"content":" fetchEventsForRepo(): Observable\u003cany[]\u003e {"},{"lineNumber":321,"author":{"gitId":"-"},"content":" return from(octokit.issues.listEventsForRepo({ owner: ORG_NAME, repo: REPO, headers: GithubService.IF_NONE_MATCH_EMPTY })).pipe("},{"lineNumber":322,"author":{"gitId":"-"},"content":" map((response) \u003d\u003e {"},{"lineNumber":323,"author":{"gitId":"-"},"content":" return response[\u0027data\u0027];"},{"lineNumber":324,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":325,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchEventsMessage()))"},{"lineNumber":326,"author":{"gitId":"-"},"content":" );"},{"lineNumber":327,"author":{"gitId":"-"},"content":" }"},{"lineNumber":328,"author":{"gitId":"-"},"content":""},{"lineNumber":329,"author":{"gitId":"-"},"content":" fetchEventsForRepoCall(pageNumber: number): Observable\u003cGithubResponse\u003cany[]\u003e\u003e {"},{"lineNumber":330,"author":{"gitId":"-"},"content":" return \u003cObservable\u003cGithubResponse\u003cany[]\u003e\u003e\u003efrom("},{"lineNumber":331,"author":{"gitId":"-"},"content":" octokit.activity.listRepoEvents({"},{"lineNumber":332,"author":{"gitId":"-"},"content":" owner: ORG_NAME,"},{"lineNumber":333,"author":{"gitId":"-"},"content":" repo: REPO,"},{"lineNumber":334,"author":{"gitId":"-"},"content":" page: pageNumber"},{"lineNumber":335,"author":{"gitId":"-"},"content":" })"},{"lineNumber":336,"author":{"gitId":"-"},"content":" ).pipe(catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchActivityEventsMessage())));"},{"lineNumber":337,"author":{"gitId":"-"},"content":" }"},{"lineNumber":338,"author":{"gitId":"-"},"content":""},{"lineNumber":339,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":340,"author":{"gitId":"-"},"content":" * Fetches all events of current repository for Activity Dashboard."},{"lineNumber":341,"author":{"gitId":"-"},"content":" * Adapted from getIssueApiCalls()."},{"lineNumber":342,"author":{"gitId":"-"},"content":" *"},{"lineNumber":343,"author":{"gitId":"-"},"content":" * @returns GithubEvents observable"},{"lineNumber":344,"author":{"gitId":"-"},"content":" */"},{"lineNumber":345,"author":{"gitId":"-"},"content":" fetchAllEventsForRepo(): Observable\u003cGithubEvent[]\u003e {"},{"lineNumber":346,"author":{"gitId":"-"},"content":" let responseInFirstPage: GithubResponse\u003cGithubEvent[]\u003e;"},{"lineNumber":347,"author":{"gitId":"-"},"content":" return this.fetchEventsForRepoCall(1).pipe("},{"lineNumber":348,"author":{"gitId":"-"},"content":" map((response: GithubResponse\u003cGithubEvent[]\u003e) \u003d\u003e {"},{"lineNumber":349,"author":{"gitId":"-"},"content":" responseInFirstPage \u003d response;"},{"lineNumber":350,"author":{"gitId":"-"},"content":" return getNumberOfPages(response);"},{"lineNumber":351,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":352,"author":{"gitId":"-"},"content":" flatMap((numOfPages: number) \u003d\u003e {"},{"lineNumber":353,"author":{"gitId":"-"},"content":" const apiCalls: Observable\u003cGithubResponse\u003cGithubEvent[]\u003e\u003e[] \u003d [];"},{"lineNumber":354,"author":{"gitId":"-"},"content":" for (let i \u003d 1; i \u003c\u003d numOfPages; i++) {"},{"lineNumber":355,"author":{"gitId":"-"},"content":" apiCalls.push(this.fetchEventsForRepoCall(i));"},{"lineNumber":356,"author":{"gitId":"-"},"content":" }"},{"lineNumber":357,"author":{"gitId":"-"},"content":" return apiCalls.length \u003d\u003d\u003d 0 ? of([]) : forkJoin(apiCalls);"},{"lineNumber":358,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":359,"author":{"gitId":"-"},"content":" map((responseArray) \u003d\u003e responseArray.map((x) \u003d\u003e x[\u0027data\u0027]))"},{"lineNumber":360,"author":{"gitId":"-"},"content":" );"},{"lineNumber":361,"author":{"gitId":"-"},"content":" }"},{"lineNumber":362,"author":{"gitId":"-"},"content":""},{"lineNumber":363,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":364,"author":{"gitId":"-"},"content":" * Not in use. Fetches data csv file from Organization repository."},{"lineNumber":365,"author":{"gitId":"-"},"content":" */"},{"lineNumber":366,"author":{"gitId":"-"},"content":" fetchDataFile(): Observable\u003c{}\u003e {"},{"lineNumber":367,"author":{"gitId":"-"},"content":" return from("},{"lineNumber":368,"author":{"gitId":"-"},"content":" octokit.repos.getContents({ owner: MOD_ORG, repo: DATA_REPO, path: \u0027data.csv\u0027, headers: GithubService.IF_NONE_MATCH_EMPTY })"},{"lineNumber":369,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":370,"author":{"gitId":"-"},"content":" map((rawData) \u003d\u003e {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" return { data: atob(rawData[\u0027data\u0027][\u0027content\u0027]) };"},{"lineNumber":372,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":373,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchDataFileMessage()))"},{"lineNumber":374,"author":{"gitId":"-"},"content":" );"},{"lineNumber":375,"author":{"gitId":"-"},"content":" }"},{"lineNumber":376,"author":{"gitId":"-"},"content":""},{"lineNumber":377,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":378,"author":{"gitId":"-"},"content":" * Gets information of latest release of WATcher."},{"lineNumber":379,"author":{"gitId":"-"},"content":" * @returns GithubRelease observable"},{"lineNumber":380,"author":{"gitId":"-"},"content":" */"},{"lineNumber":381,"author":{"gitId":"-"},"content":" fetchLatestRelease(): Observable\u003cGithubRelease\u003e {"},{"lineNumber":382,"author":{"gitId":"-"},"content":" return from("},{"lineNumber":383,"author":{"gitId":"-"},"content":" octokit.repos.getLatestRelease({ owner: WATCHER_ORG, repo: WATCHER_REPO, headers: GithubService.IF_NONE_MATCH_EMPTY })"},{"lineNumber":384,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":385,"author":{"gitId":"-"},"content":" map((res) \u003d\u003e res[\u0027data\u0027]),"},{"lineNumber":386,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchLatestReleaseMessage()))"},{"lineNumber":387,"author":{"gitId":"-"},"content":" );"},{"lineNumber":388,"author":{"gitId":"-"},"content":" }"},{"lineNumber":389,"author":{"gitId":"-"},"content":""},{"lineNumber":390,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":391,"author":{"gitId":"-"},"content":" * Fetches the data file that is regulates session information."},{"lineNumber":392,"author":{"gitId":"-"},"content":" * @return Observable\u003cSessionData\u003e representing session information."},{"lineNumber":393,"author":{"gitId":"-"},"content":" */"},{"lineNumber":394,"author":{"gitId":"-"},"content":" fetchSettingsFile(): Observable\u003cSessionData\u003e {"},{"lineNumber":395,"author":{"gitId":"-"},"content":" return from("},{"lineNumber":396,"author":{"gitId":"-"},"content":" octokit.repos.getContents({ owner: MOD_ORG, repo: DATA_REPO, path: \u0027settings.json\u0027, headers: GithubService.IF_NONE_MATCH_EMPTY })"},{"lineNumber":397,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":398,"author":{"gitId":"-"},"content":" map((rawData) \u003d\u003e JSON.parse(atob(rawData[\u0027data\u0027][\u0027content\u0027]))),"},{"lineNumber":399,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchSettingsFileMessage()))"},{"lineNumber":400,"author":{"gitId":"-"},"content":" );"},{"lineNumber":401,"author":{"gitId":"-"},"content":" }"},{"lineNumber":402,"author":{"gitId":"-"},"content":""},{"lineNumber":403,"author":{"gitId":"-"},"content":" fetchAuthenticatedUser(): Observable\u003cGithubUser\u003e {"},{"lineNumber":404,"author":{"gitId":"-"},"content":" return from(octokit.users.getAuthenticated()).pipe("},{"lineNumber":405,"author":{"gitId":"-"},"content":" map((response) \u003d\u003e {"},{"lineNumber":406,"author":{"gitId":"NereusWB922"},"content":" const data: RawGithubUser \u003d response[\u0027data\u0027];"},{"lineNumber":407,"author":{"gitId":"NereusWB922"},"content":" return new GithubUser(data);"},{"lineNumber":408,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":409,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(ErrorMessageService.unableToFetchAuthenticatedUsersMessage()))"},{"lineNumber":410,"author":{"gitId":"-"},"content":" );"},{"lineNumber":411,"author":{"gitId":"-"},"content":" }"},{"lineNumber":412,"author":{"gitId":"-"},"content":""},{"lineNumber":413,"author":{"gitId":"-"},"content":" getRepoURL(): string {"},{"lineNumber":414,"author":{"gitId":"-"},"content":" return ORG_NAME.concat(\u0027/\u0027).concat(REPO);"},{"lineNumber":415,"author":{"gitId":"-"},"content":" }"},{"lineNumber":416,"author":{"gitId":"-"},"content":""},{"lineNumber":417,"author":{"gitId":"-"},"content":" viewIssueInBrowser(id: number, event: Event) {"},{"lineNumber":418,"author":{"gitId":"-"},"content":" if (id) {"},{"lineNumber":419,"author":{"gitId":"-"},"content":" window.open(\u0027https://github.com/\u0027.concat(this.getRepoURL()).concat(\u0027/issues/\u0027).concat(String(id)));"},{"lineNumber":420,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":421,"author":{"gitId":"-"},"content":" this.errorHandlingService.handleError(new Error(ErrorMessageService.unableToOpenInBrowserMessage()));"},{"lineNumber":422,"author":{"gitId":"-"},"content":" }"},{"lineNumber":423,"author":{"gitId":"-"},"content":" event.stopPropagation();"},{"lineNumber":424,"author":{"gitId":"-"},"content":" }"},{"lineNumber":425,"author":{"gitId":"-"},"content":""},{"lineNumber":426,"author":{"gitId":"-"},"content":" reset(): void {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" this.logger.info(`GithubService: Resetting issues cache`);"},{"lineNumber":428,"author":{"gitId":"-"},"content":" this.issuesCacheManager.clear();"},{"lineNumber":429,"author":{"gitId":"-"},"content":" this.issuesLastModifiedManager.clear();"},{"lineNumber":430,"author":{"gitId":"-"},"content":" this.issueQueryRefs.clear();"},{"lineNumber":431,"author":{"gitId":"-"},"content":" }"},{"lineNumber":432,"author":{"gitId":"-"},"content":""},{"lineNumber":433,"author":{"gitId":"-"},"content":" getProfilesData(): Promise\u003cResponse\u003e {"},{"lineNumber":434,"author":{"gitId":"-"},"content":" return fetch(AppConfig.clientDataUrl);"},{"lineNumber":435,"author":{"gitId":"-"},"content":" }"},{"lineNumber":436,"author":{"gitId":"-"},"content":""},{"lineNumber":437,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":438,"author":{"gitId":"-"},"content":" * Performs an API call to fetch a page of filtered issues with a given pageNumber."},{"lineNumber":439,"author":{"gitId":"-"},"content":" *"},{"lineNumber":440,"author":{"gitId":"-"},"content":" * The request is sent with the ETag of the latest cached HTTP response."},{"lineNumber":441,"author":{"gitId":"-"},"content":" * If page requested has the same ETag, or the request results in an error,"},{"lineNumber":442,"author":{"gitId":"-"},"content":" * then the cached page is returned instead."},{"lineNumber":443,"author":{"gitId":"-"},"content":" *"},{"lineNumber":444,"author":{"gitId":"-"},"content":" * @param filter - The issue filter"},{"lineNumber":445,"author":{"gitId":"-"},"content":" * @param pageNumber - The page to be fetched"},{"lineNumber":446,"author":{"gitId":"-"},"content":" * @returns An observable representing the response containing a single page of filtered issues"},{"lineNumber":447,"author":{"gitId":"-"},"content":" */"},{"lineNumber":448,"author":{"gitId":"-"},"content":" private getIssuesAPICall(filter: RestGithubIssueFilter, pageNumber: number): Observable\u003cGithubResponse\u003cGithubIssue[]\u003e\u003e {"},{"lineNumber":449,"author":{"gitId":"-"},"content":" const apiCall: Promise\u003cGithubResponse\u003cGithubIssue[]\u003e\u003e \u003d octokit.issues.listForRepo({"},{"lineNumber":450,"author":{"gitId":"-"},"content":" ...filter,"},{"lineNumber":451,"author":{"gitId":"-"},"content":" owner: ORG_NAME,"},{"lineNumber":452,"author":{"gitId":"-"},"content":" repo: REPO,"},{"lineNumber":453,"author":{"gitId":"-"},"content":" sort: \u0027created\u0027,"},{"lineNumber":454,"author":{"gitId":"-"},"content":" direction: \u0027desc\u0027,"},{"lineNumber":455,"author":{"gitId":"-"},"content":" per_page: 100,"},{"lineNumber":456,"author":{"gitId":"-"},"content":" page: pageNumber,"},{"lineNumber":457,"author":{"gitId":"-"},"content":" headers: { \u0027If-None-Match\u0027: this.issuesCacheManager.getEtagFor(pageNumber) },"},{"lineNumber":458,"author":{"gitId":"-"},"content":" state: \u0027all\u0027"},{"lineNumber":459,"author":{"gitId":"-"},"content":" });"},{"lineNumber":460,"author":{"gitId":"-"},"content":" const apiCall$ \u003d from("},{"lineNumber":461,"author":{"gitId":"-"},"content":" apiCall.catch((err) \u003d\u003e {"},{"lineNumber":462,"author":{"gitId":"-"},"content":" return this.issuesCacheManager.get(pageNumber);"},{"lineNumber":463,"author":{"gitId":"-"},"content":" })"},{"lineNumber":464,"author":{"gitId":"-"},"content":" );"},{"lineNumber":465,"author":{"gitId":"-"},"content":""},{"lineNumber":466,"author":{"gitId":"-"},"content":" return apiCall$.pipe("},{"lineNumber":467,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e {"},{"lineNumber":468,"author":{"gitId":"-"},"content":" // catchError does not appear to catch an error on an observable created from a promise..."},{"lineNumber":469,"author":{"gitId":"-"},"content":" this.logger.info(`GithubService: Error caught in getIssuesAPICall`);"},{"lineNumber":470,"author":{"gitId":"-"},"content":" return of(this.issuesCacheManager.get(pageNumber));"},{"lineNumber":471,"author":{"gitId":"-"},"content":" })"},{"lineNumber":472,"author":{"gitId":"-"},"content":" );"},{"lineNumber":473,"author":{"gitId":"-"},"content":" }"},{"lineNumber":474,"author":{"gitId":"-"},"content":""},{"lineNumber":475,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":476,"author":{"gitId":"-"},"content":" * Fetches a list of items using a GraphQL query that queries for paginated data."},{"lineNumber":477,"author":{"gitId":"-"},"content":" *"},{"lineNumber":478,"author":{"gitId":"-"},"content":" * @param query - The GraphQL query that queries for paginated data."},{"lineNumber":479,"author":{"gitId":"-"},"content":" * @param variables - Additional variables for the GraphQL query."},{"lineNumber":480,"author":{"gitId":"-"},"content":" * @callback pluckEdges A function that returns a list of edges in a ApolloQueryResult."},{"lineNumber":481,"author":{"gitId":"-"},"content":" * @callback Model Constructor for the item model."},{"lineNumber":482,"author":{"gitId":"-"},"content":" * @returns A list of items from the query."},{"lineNumber":483,"author":{"gitId":"-"},"content":" */"},{"lineNumber":484,"author":{"gitId":"-"},"content":" private fetchGraphqlList\u003cT, M\u003e("},{"lineNumber":485,"author":{"gitId":"-"},"content":" query: DocumentNode,"},{"lineNumber":486,"author":{"gitId":"-"},"content":" variables: {},"},{"lineNumber":487,"author":{"gitId":"-"},"content":" pluckEdges: (results: ApolloQueryResult\u003cT\u003e) \u003d\u003e Array\u003cany\u003e,"},{"lineNumber":488,"author":{"gitId":"-"},"content":" Model: new (data) \u003d\u003e M"},{"lineNumber":489,"author":{"gitId":"-"},"content":" ): Observable\u003cArray\u003cM\u003e\u003e {"},{"lineNumber":490,"author":{"gitId":"-"},"content":" return this.withPagination\u003cT\u003e(pluckEdges, query, variables, false).pipe("},{"lineNumber":491,"author":{"gitId":"-"},"content":" map((results: ApolloQueryResult\u003cT\u003e[]) \u003d\u003e {"},{"lineNumber":492,"author":{"gitId":"-"},"content":" const issues \u003d results.reduce((accumulated, current) \u003d\u003e accumulated.concat(pluckEdges(current)), []);"},{"lineNumber":493,"author":{"gitId":"-"},"content":" return issues.map((issue) \u003d\u003e new Model(issue.node));"},{"lineNumber":494,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":495,"author":{"gitId":"-"},"content":" throwIfEmpty(() \u003d\u003e {"},{"lineNumber":496,"author":{"gitId":"-"},"content":" return new HttpErrorResponse({ status: 304 });"},{"lineNumber":497,"author":{"gitId":"-"},"content":" })"},{"lineNumber":498,"author":{"gitId":"-"},"content":" );"},{"lineNumber":499,"author":{"gitId":"-"},"content":" }"},{"lineNumber":500,"author":{"gitId":"-"},"content":""},{"lineNumber":501,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":502,"author":{"gitId":"-"},"content":" * Returns an observable that will continually emit the currently accumulated results, until a page that has less"},{"lineNumber":503,"author":{"gitId":"-"},"content":" * than 100 items is found, after which it performs a final emit with the full results array, and completes."},{"lineNumber":504,"author":{"gitId":"-"},"content":" *"},{"lineNumber":505,"author":{"gitId":"-"},"content":" * If `shouldAccumulate` is false, the observable will emit only the latest result, it will still complete on the"},{"lineNumber":506,"author":{"gitId":"-"},"content":" * same condition."},{"lineNumber":507,"author":{"gitId":"-"},"content":" *"},{"lineNumber":508,"author":{"gitId":"-"},"content":" * @callback pluckEdges - A function that returns a list of edges in a ApolloQueryResult."},{"lineNumber":509,"author":{"gitId":"-"},"content":" * @params query - The query to be performed."},{"lineNumber":510,"author":{"gitId":"-"},"content":" * @params variables - The variables for the query."},{"lineNumber":511,"author":{"gitId":"-"},"content":" * @params shouldAccumulate - Whether the observable should accumulate the results."},{"lineNumber":512,"author":{"gitId":"-"},"content":" * @returns an observable"},{"lineNumber":513,"author":{"gitId":"-"},"content":" */"},{"lineNumber":514,"author":{"gitId":"-"},"content":" private withPagination\u003cT\u003e("},{"lineNumber":515,"author":{"gitId":"-"},"content":" pluckEdges: (results: ApolloQueryResult\u003cT\u003e) \u003d\u003e Array\u003cany\u003e,"},{"lineNumber":516,"author":{"gitId":"-"},"content":" query: DocumentNode,"},{"lineNumber":517,"author":{"gitId":"-"},"content":" variables: { [key: string]: any } \u003d {},"},{"lineNumber":518,"author":{"gitId":"-"},"content":" shouldAccumulate: boolean \u003d true"},{"lineNumber":519,"author":{"gitId":"-"},"content":" ): Observable\u003cApolloQueryResult\u003cT\u003e[]\u003e {"},{"lineNumber":520,"author":{"gitId":"-"},"content":" const maxResultsCount \u003d 100;"},{"lineNumber":521,"author":{"gitId":"-"},"content":" const apollo \u003d this.apollo;"},{"lineNumber":522,"author":{"gitId":"-"},"content":""},{"lineNumber":523,"author":{"gitId":"-"},"content":" let accumulatedResults: ApolloQueryResult\u003cT\u003e[] \u003d [];"},{"lineNumber":524,"author":{"gitId":"-"},"content":" const behaviorSubject: BehaviorSubject\u003cApolloQueryResult\u003cT\u003e[]\u003e \u003d new BehaviorSubject(accumulatedResults);"},{"lineNumber":525,"author":{"gitId":"-"},"content":""},{"lineNumber":526,"author":{"gitId":"-"},"content":" async function queryWith(cursor: string): Promise\u003cvoid\u003e {"},{"lineNumber":527,"author":{"gitId":"-"},"content":" const graphqlQuery \u003d apollo.watchQuery\u003cT\u003e({ query, variables: { ...variables, cursor } });"},{"lineNumber":528,"author":{"gitId":"-"},"content":""},{"lineNumber":529,"author":{"gitId":"-"},"content":" await graphqlQuery.refetch().then(async (results: ApolloQueryResult\u003cT\u003e) \u003d\u003e {"},{"lineNumber":530,"author":{"gitId":"-"},"content":" const intermediate \u003d Array.isArray(results) ? results : [results];"},{"lineNumber":531,"author":{"gitId":"-"},"content":" const edges \u003d pluckEdges(results);"},{"lineNumber":532,"author":{"gitId":"-"},"content":" const nextCursor \u003d edges.length \u003d\u003d\u003d 0 ? null : edges[edges.length - 1].cursor;"},{"lineNumber":533,"author":{"gitId":"-"},"content":""},{"lineNumber":534,"author":{"gitId":"-"},"content":" if (shouldAccumulate) {"},{"lineNumber":535,"author":{"gitId":"-"},"content":" accumulatedResults \u003d accumulatedResults.concat(intermediate);"},{"lineNumber":536,"author":{"gitId":"-"},"content":" behaviorSubject.next(accumulatedResults);"},{"lineNumber":537,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":538,"author":{"gitId":"-"},"content":" behaviorSubject.next(intermediate);"},{"lineNumber":539,"author":{"gitId":"-"},"content":" }"},{"lineNumber":540,"author":{"gitId":"-"},"content":" if (edges.length \u003c maxResultsCount || !nextCursor) {"},{"lineNumber":541,"author":{"gitId":"-"},"content":" // No more queries to perform."},{"lineNumber":542,"author":{"gitId":"-"},"content":" behaviorSubject.complete();"},{"lineNumber":543,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":544,"author":{"gitId":"-"},"content":" }"},{"lineNumber":545,"author":{"gitId":"-"},"content":""},{"lineNumber":546,"author":{"gitId":"-"},"content":" // Use a chain of await to ensure that all recursive queries are completed before `complete` is called."},{"lineNumber":547,"author":{"gitId":"-"},"content":" await queryWith(nextCursor);"},{"lineNumber":548,"author":{"gitId":"-"},"content":" });"},{"lineNumber":549,"author":{"gitId":"-"},"content":" }"},{"lineNumber":550,"author":{"gitId":"-"},"content":""},{"lineNumber":551,"author":{"gitId":"-"},"content":" queryWith(null);"},{"lineNumber":552,"author":{"gitId":"-"},"content":""},{"lineNumber":553,"author":{"gitId":"-"},"content":" return behaviorSubject.asObservable();"},{"lineNumber":554,"author":{"gitId":"-"},"content":" }"},{"lineNumber":555,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":6,"NereusWB922":10,"MadLamprey":2,"-":537}},{"path":"src/app/core/services/grouping/assignee-grouping-strategy.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { map } from \u0027rxjs/operators\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { GithubUser } from \u0027../../models/github-user.model\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import { Issue } from \u0027../../models/issue.model\u0027;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"import { GithubService } from \u0027../github.service\u0027;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"import { GroupingStrategy } from \u0027./grouping-strategy.interface\u0027;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"/**"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" * A GroupingStrategy that groups issues/prs based on their assignees."},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":"@Injectable({"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"})"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":"export class AssigneeGroupingStrategy implements GroupingStrategy {"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" constructor(private githubService: GithubService) {}"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" * Retrieves data for a specific assignee."},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" * If it is the\"No Assignee\" group, unassigned issues are returned."},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" * Otherwise, issues assigned to the specified user are returned."},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" getDataForGroup(issues: Issue[], key: GithubUser): Issue[] {"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" if (key \u003d\u003d\u003d GithubUser.NO_ASSIGNEE) {"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" return this.getUnassignedData(issues);"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" return this.getDataAssignedToUser(issues, key);"},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" * Retrieves an Observable emitting users who can be assigned to issues,"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" * including a special \"No Assignee\" option."},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" getGroups(): Observable\u003cGithubUser[]\u003e {"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" return this.githubService.getUsersAssignable().pipe("},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":" map((users) \u003d\u003e {"},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" users.push(GithubUser.NO_ASSIGNEE);"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" return users;"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" })"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" );"},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" * Groups other than \"No Assignee\" need to be shown on the"},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":" * hidden group list if empty."},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" isInHiddenList(group: GithubUser): boolean {"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":" return group !\u003d\u003d GithubUser.NO_ASSIGNEE;"},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" private getDataAssignedToUser(issues: Issue[], user: GithubUser): Issue[] {"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" const filteredIssues \u003d issues.filter((issue) \u003d\u003e {"},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":" if (this.isPullRequest(issue)) {"},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" return this.isPullRequestCreatedByTarget(issue, user);"},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":57,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" return this.isIssueAssignedToTarget(issue, user);"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":61,"author":{"gitId":"NereusWB922"},"content":" return filteredIssues;"},{"lineNumber":62,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" private getUnassignedData(issues: Issue[]): Issue[] {"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":" return issues.filter((issue) \u003d\u003e !this.isPullRequest(issue) \u0026\u0026 issue.assignees.length \u003d\u003d\u003d 0);"},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":" private isPullRequest(issue: Issue): boolean {"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":" return issue.issueOrPr \u003d\u003d\u003d \u0027PullRequest\u0027;"},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":71,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" private isPullRequestCreatedByTarget(issue: Issue, target: GithubUser): boolean {"},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" return issue.author \u003d\u003d\u003d target.login;"},{"lineNumber":74,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" private isIssueAssignedToTarget(issue: Issue, target: GithubUser): boolean {"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" const isAssigneesFieldDefined \u003d !!issue.assignees;"},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":" return isAssigneesFieldDefined \u0026\u0026 issue.assignees.includes(target.login);"},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":81,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":81}},{"path":"src/app/core/services/grouping/grouping-context.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Injectable, Injector } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { ActivatedRoute, Router } from \u0027@angular/router\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { BehaviorSubject, Observable } from \u0027rxjs\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { Group } from \u0027../../models/github/group.interface\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import { Issue } from \u0027../../models/issue.model\u0027;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"import { AssigneeGroupingStrategy } from \u0027./assignee-grouping-strategy.service\u0027;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"import { GroupingStrategy } from \u0027./grouping-strategy.interface\u0027;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"import { MilestoneGroupingStrategy } from \u0027./milestone-grouping-strategy.service\u0027;"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"export enum GroupBy {"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" Assignee \u003d \u0027assignee\u0027,"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" Milestone \u003d \u0027milestone\u0027"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":"export const DEFAULT_GROUPBY \u003d GroupBy.Assignee;"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" * A service responsible for managing the current grouping strategy and providing grouped data."},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":"@Injectable({"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":"})"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":"export class GroupingContextService {"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" public static readonly GROUP_BY_QUERY_PARAM_KEY \u003d \u0027groupby\u0027;"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" private currGroupBySubject: BehaviorSubject\u003cGroupBy\u003e;"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" currGroupBy: GroupBy;"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" currGroupBy$: Observable\u003cGroupBy\u003e;"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" private groupingStrategyMap: Map\u003cstring, GroupingStrategy\u003e;"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" constructor(private injector: Injector, private route: ActivatedRoute, private router: Router) {"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" this.currGroupBy \u003d DEFAULT_GROUPBY;"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" this.currGroupBySubject \u003d new BehaviorSubject\u003cGroupBy\u003e(this.currGroupBy);"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" this.currGroupBy$ \u003d this.currGroupBySubject.asObservable();"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" this.groupingStrategyMap \u003d new Map\u003cstring, GroupingStrategy\u003e();"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" // Initialize the grouping strategy map with available strategies"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" this.groupingStrategyMap.set(GroupBy.Assignee, this.injector.get(AssigneeGroupingStrategy));"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" this.groupingStrategyMap.set(GroupBy.Milestone, this.injector.get(MilestoneGroupingStrategy));"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" * Initializes the service from URL parameters."},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":" initializeFromUrlParams() {"},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" const groupByParam \u003d this.route.snapshot.queryParamMap.get(GroupingContextService.GROUP_BY_QUERY_PARAM_KEY);"},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":" if (groupByParam \u0026\u0026 Object.values(GroupBy).includes(groupByParam as GroupBy)) {"},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" this.setCurrentGroupingType(groupByParam as GroupBy);"},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":" } else {"},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" this.setCurrentGroupingType(DEFAULT_GROUPBY);"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":57,"author":{"gitId":"NereusWB922"},"content":" * Sets the current grouping type and updates the corresponding query parameter in the URL."},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" * @param groupBy The grouping type to set."},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":" setCurrentGroupingType(groupBy: GroupBy): void {"},{"lineNumber":61,"author":{"gitId":"nknguyenhc"},"content":" if (groupBy !\u003d\u003d this.currGroupBy) {"},{"lineNumber":62,"author":{"gitId":"NereusWB922"},"content":" this.currGroupBy \u003d groupBy;"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" this.currGroupBySubject.next(this.currGroupBy);"},{"lineNumber":64,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" this.router.navigate([], {"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":" relativeTo: this.route,"},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":" queryParams: {"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":" [GroupingContextService.GROUP_BY_QUERY_PARAM_KEY]: groupBy"},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":" },"},{"lineNumber":71,"author":{"gitId":"NereusWB922"},"content":" queryParamsHandling: \u0027merge\u0027,"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" replaceUrl: true"},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":74,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" * Retrieves data for a specific group."},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":" * @param issues - An array of issues to be grouped."},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":" * @param group - The group by which issues are to be grouped."},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":" * @returns An array of issues belonging to the specified group."},{"lineNumber":81,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":82,"author":{"gitId":"NereusWB922"},"content":" getDataForGroup(issues: Issue[], group: Group): Issue[] {"},{"lineNumber":83,"author":{"gitId":"NereusWB922"},"content":" const strategy \u003d this.groupingStrategyMap.get(this.currGroupBy);"},{"lineNumber":84,"author":{"gitId":"NereusWB922"},"content":" return strategy.getDataForGroup(issues, group);"},{"lineNumber":85,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":86,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":87,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":88,"author":{"gitId":"NereusWB922"},"content":" * Retrieves all groups available for current grouping strategy."},{"lineNumber":89,"author":{"gitId":"NereusWB922"},"content":" * @returns An Observable emitting an array of groups."},{"lineNumber":90,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":91,"author":{"gitId":"NereusWB922"},"content":" getGroups(): Observable\u003cGroup[]\u003e {"},{"lineNumber":92,"author":{"gitId":"NereusWB922"},"content":" const strategy \u003d this.groupingStrategyMap.get(this.currGroupBy);"},{"lineNumber":93,"author":{"gitId":"NereusWB922"},"content":" return strategy.getGroups();"},{"lineNumber":94,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":95,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":96,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":97,"author":{"gitId":"NereusWB922"},"content":" * Determines whether a group should be shown on hidden list if it contains no issues."},{"lineNumber":98,"author":{"gitId":"NereusWB922"},"content":" * @param group - The group to check."},{"lineNumber":99,"author":{"gitId":"NereusWB922"},"content":" * @returns A boolean indicating whether the group should be shown on hidden list if empty."},{"lineNumber":100,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":101,"author":{"gitId":"NereusWB922"},"content":" isInHiddenList(group: Group): boolean {"},{"lineNumber":102,"author":{"gitId":"NereusWB922"},"content":" const strategy \u003d this.groupingStrategyMap.get(this.currGroupBy);"},{"lineNumber":103,"author":{"gitId":"NereusWB922"},"content":" return strategy.isInHiddenList(group);"},{"lineNumber":104,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":105,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":106,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":107,"author":{"gitId":"NereusWB922"},"content":" * Resets the current grouping type to the default."},{"lineNumber":108,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":109,"author":{"gitId":"NereusWB922"},"content":" reset(): void {"},{"lineNumber":110,"author":{"gitId":"NereusWB922"},"content":" this.setCurrentGroupingType(DEFAULT_GROUPBY);"},{"lineNumber":111,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":112,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"nknguyenhc":2,"NereusWB922":110}},{"path":"src/app/core/services/grouping/grouping-strategy.interface.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { Group } from \u0027../../models/github/group.interface\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { Issue } from \u0027../../models/issue.model\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"/**"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" * Represent a strategy for grouping issues/prs."},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" * This interface follows the Strategy Pattern, allowing for different"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" * strategies to be implemented for grouping issues/prs based on different criteria."},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"export interface GroupingStrategy {"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" * Retrieves data for a specific group."},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" * @param issues - An array of issues to be grouped."},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" * @param key - The group by which issues are to be grouped."},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" * @returns An array of issues belonging to the specified group."},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" getDataForGroup(issues: Issue[], key: Group): Issue[];"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" * Retrieves observable emitting groups available for the grouping strategy."},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" * @returns An Observable emitting an array of groups."},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" getGroups(): Observable\u003cGroup[]\u003e;"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" * Determines whether a group should be shown on hidden list if it contains no issues."},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" * @param group - The group to check."},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" * @returns A boolean indicating whether the group should be shown on hidden list if empty."},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" isInHiddenList(group: Group): boolean;"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":31}},{"path":"src/app/core/services/grouping/milestone-grouping-strategy.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { map } from \u0027rxjs/operators\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { Issue } from \u0027../../models/issue.model\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import { Milestone } from \u0027../../models/milestone.model\u0027;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"import { MilestoneService } from \u0027../milestone.service\u0027;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"import { GroupingStrategy } from \u0027./grouping-strategy.interface\u0027;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"/**"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" * A GroupingStrategy that groups issues/prs based on their milestones."},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":"@Injectable({"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"})"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":"export class MilestoneGroupingStrategy implements GroupingStrategy {"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" constructor(private milestoneService: MilestoneService) {}"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" * Retrieves data for a milestone."},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" getDataForGroup(issues: Issue[], key: Milestone): Issue[] {"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" return issues.filter((issue) \u003d\u003e issue.milestone.equals(key));"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" * Retrieves an Observable emitting milestones available for grouping issues."},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" getGroups(): Observable\u003cMilestone[]\u003e {"},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" return this.milestoneService.fetchMilestones().pipe("},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" map((milestones) \u003d\u003e {"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" const parseMilestone \u003d this.milestoneService.parseMilestoneData(milestones);"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" parseMilestone.push(Milestone.IssueWithoutMilestone);"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" parseMilestone.push(Milestone.PRWithoutMilestone);"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" return parseMilestone;"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" })"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" );"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" * Groups other than Default Milestone need to be shown on the"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" * hidden group list if empty."},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":" isInHiddenList(group: Milestone): boolean {"},{"lineNumber":44,"author":{"gitId":"MadLamprey"},"content":" return group !\u003d\u003d Milestone.IssueWithoutMilestone \u0026\u0026 group !\u003d\u003d Milestone.PRWithoutMilestone;"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":45,"MadLamprey":1}},{"path":"src/app/core/services/issue.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { BehaviorSubject, Observable, of, Subscription, throwError, timer } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { catchError, exhaustMap, finalize, map } from \u0027rxjs/operators\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import RestGithubIssueFilter from \u0027../models/github/github-issue-filter.model\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { GithubIssue } from \u0027../models/github/github-issue.model\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { Issue, Issues, IssuesFilter } from \u0027../models/issue.model\u0027;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"import { View } from \u0027../models/view.model\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027./github.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { UserService } from \u0027./user.service\u0027;"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"import { ViewService } from \u0027./view.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":13,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":14,"author":{"gitId":"-"},"content":"})"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * Responsible for creating and updating issues, and periodically fetching issues"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * using GitHub."},{"lineNumber":19,"author":{"gitId":"-"},"content":" */"},{"lineNumber":20,"author":{"gitId":"-"},"content":"export class IssueService {"},{"lineNumber":21,"author":{"gitId":"nknguyenhc"},"content":" static readonly POLL_INTERVAL \u003d 20000; // 20 seconds"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" issues: Issues;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" issues$: BehaviorSubject\u003cIssue[]\u003e;"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" private sessionId: string;"},{"lineNumber":27,"author":{"gitId":"-"},"content":" private issueTeamFilter \u003d \u0027All Teams\u0027;"},{"lineNumber":28,"author":{"gitId":"-"},"content":" private issuesPollSubscription: Subscription;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" /** Whether the IssueService is downloading the data from Github*/"},{"lineNumber":30,"author":{"gitId":"-"},"content":" public isLoading \u003d new BehaviorSubject\u003cboolean\u003e(false);"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" constructor(private githubService: GithubService, private userService: UserService, private viewService: ViewService) {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" this.issues$ \u003d new BehaviorSubject(new Array\u003cIssue\u003e());"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" startPollIssues() {"},{"lineNumber":37,"author":{"gitId":"-"},"content":" if (this.issuesPollSubscription \u003d\u003d\u003d undefined) {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" if (this.issues$.getValue().length \u003d\u003d\u003d 0) {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.isLoading.next(true);"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" this.issuesPollSubscription \u003d timer(0, IssueService.POLL_INTERVAL)"},{"lineNumber":43,"author":{"gitId":"-"},"content":" .pipe("},{"lineNumber":44,"author":{"gitId":"-"},"content":" exhaustMap(() \u003d\u003e {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" return this.reloadAllIssues().pipe("},{"lineNumber":46,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e throwError(err)),"},{"lineNumber":47,"author":{"gitId":"-"},"content":" finalize(() \u003d\u003e this.isLoading.next(false))"},{"lineNumber":48,"author":{"gitId":"-"},"content":" );"},{"lineNumber":49,"author":{"gitId":"-"},"content":" })"},{"lineNumber":50,"author":{"gitId":"-"},"content":" )"},{"lineNumber":51,"author":{"gitId":"-"},"content":" .subscribe();"},{"lineNumber":52,"author":{"gitId":"-"},"content":" }"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" stopPollIssues() {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" if (this.issuesPollSubscription) {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" this.issuesPollSubscription.unsubscribe();"},{"lineNumber":58,"author":{"gitId":"-"},"content":" this.issuesPollSubscription \u003d undefined;"},{"lineNumber":59,"author":{"gitId":"-"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" reloadAllIssues() {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" return this.initializeData();"},{"lineNumber":64,"author":{"gitId":"-"},"content":" }"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" getIssue(id: number): Observable\u003cIssue\u003e {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" if (this.issues \u003d\u003d\u003d undefined) {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" return this.getLatestIssue(id);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" return of(this.issues[id]);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" getLatestIssue(id: number): Observable\u003cIssue\u003e {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" return this.githubService.fetchIssueGraphql(id).pipe("},{"lineNumber":76,"author":{"gitId":"-"},"content":" map((response: GithubIssue) \u003d\u003e {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" this.createAndSaveIssueModels([response]);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" return this.issues[id];"},{"lineNumber":79,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":80,"author":{"gitId":"-"},"content":" catchError((err) \u003d\u003e {"},{"lineNumber":81,"author":{"gitId":"-"},"content":" return of(this.issues[id]);"},{"lineNumber":82,"author":{"gitId":"-"},"content":" })"},{"lineNumber":83,"author":{"gitId":"-"},"content":" );"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":87,"author":{"gitId":"-"},"content":" * This function will update the issue\u0027s state of the application. This function needs to be called whenever a issue is added/updated."},{"lineNumber":88,"author":{"gitId":"-"},"content":" *"},{"lineNumber":89,"author":{"gitId":"-"},"content":" * @params issuesToUpdate - An array of issues to update the state of the application with."},{"lineNumber":90,"author":{"gitId":"-"},"content":" */"},{"lineNumber":91,"author":{"gitId":"-"},"content":" private updateLocalStore(issuesToUpdate: Issue[]) {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" const newIssues \u003d { ...this.issues };"},{"lineNumber":93,"author":{"gitId":"-"},"content":" issuesToUpdate.forEach((issue) \u003d\u003e {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" newIssues[issue.id] \u003d issue;"},{"lineNumber":95,"author":{"gitId":"-"},"content":" });"},{"lineNumber":96,"author":{"gitId":"-"},"content":" this.issues \u003d newIssues;"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" this.issues$.next(Object.values(this.issues));"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" reset(resetSessionId: boolean) {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" if (resetSessionId) {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" this.sessionId \u003d undefined;"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" this.issues \u003d undefined;"},{"lineNumber":107,"author":{"gitId":"-"},"content":" this.issues$.next(new Array\u003cIssue\u003e());"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" this.stopPollIssues();"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" private initializeData(): Observable\u003cIssue[]\u003e {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" let issuesAPICallsByFilter: Observable\u003cArray\u003cGithubIssue\u003e\u003e;"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"NereusWB922"},"content":" switch (IssuesFilter[this.viewService.currentView][this.userService.currentUser.role]) {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" case \u0027FILTER_BY_CREATOR\u0027:"},{"lineNumber":117,"author":{"gitId":"-"},"content":" issuesAPICallsByFilter \u003d this.githubService.fetchIssuesGraphql("},{"lineNumber":118,"author":{"gitId":"-"},"content":" new RestGithubIssueFilter({ creator: this.userService.currentUser.loginId })"},{"lineNumber":119,"author":{"gitId":"-"},"content":" );"},{"lineNumber":120,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":121,"author":{"gitId":"-"},"content":" case \u0027NO_FILTER\u0027:"},{"lineNumber":122,"author":{"gitId":"-"},"content":" issuesAPICallsByFilter \u003d this.githubService.fetchIssuesGraphql(new RestGithubIssueFilter({}));"},{"lineNumber":123,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":124,"author":{"gitId":"-"},"content":" case \u0027NO_ACCESS\u0027:"},{"lineNumber":125,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":126,"author":{"gitId":"-"},"content":" return of([]);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" const fetchedIssueIds: number[] \u003d [];"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" return issuesAPICallsByFilter.pipe("},{"lineNumber":132,"author":{"gitId":"-"},"content":" map((githubIssues: GithubIssue[]) \u003d\u003e {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" const issues \u003d this.createAndSaveIssueModels(githubIssues);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" for (const issue of issues) {"},{"lineNumber":135,"author":{"gitId":"-"},"content":" fetchedIssueIds.push(issue.id);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" }"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" const outdatedIssueIds: number[] \u003d this.getOutdatedIssueIds(fetchedIssueIds);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" this.deleteIssuesFromLocalStore(outdatedIssueIds);"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" if (this.issues \u003d\u003d\u003d undefined) {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" return [];"},{"lineNumber":143,"author":{"gitId":"-"},"content":" }"},{"lineNumber":144,"author":{"gitId":"-"},"content":" return Object.values(this.issues);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" })"},{"lineNumber":146,"author":{"gitId":"-"},"content":" );"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" private createAndSaveIssueModels(githubIssues: GithubIssue[]): Issue[] {"},{"lineNumber":150,"author":{"gitId":"-"},"content":" const issues: Issue[] \u003d [];"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" for (const githubIssue of githubIssues) {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" const issue \u003d this.createIssueModel(githubIssue);"},{"lineNumber":154,"author":{"gitId":"-"},"content":" issues.push(issue);"},{"lineNumber":155,"author":{"gitId":"-"},"content":" }"},{"lineNumber":156,"author":{"gitId":"-"},"content":" this.updateLocalStore(issues);"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"-"},"content":" return issues;"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" private deleteIssuesFromLocalStore(ids: number[]): void {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" const withoutIssuesToRemove \u003d { ...this.issues };"},{"lineNumber":163,"author":{"gitId":"-"},"content":" for (const id of ids) {"},{"lineNumber":164,"author":{"gitId":"-"},"content":" delete withoutIssuesToRemove[id];"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" this.issues \u003d withoutIssuesToRemove;"},{"lineNumber":168,"author":{"gitId":"-"},"content":""},{"lineNumber":169,"author":{"gitId":"-"},"content":" this.issues$.next(Object.values(this.issues));"},{"lineNumber":170,"author":{"gitId":"-"},"content":" }"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":173,"author":{"gitId":"-"},"content":" * Returns an array of outdated issue ids by comparing the ids of the recently"},{"lineNumber":174,"author":{"gitId":"-"},"content":" * fetched issues with the current issue ids in the local store"},{"lineNumber":175,"author":{"gitId":"-"},"content":" */"},{"lineNumber":176,"author":{"gitId":"-"},"content":" private getOutdatedIssueIds(fetchedIssueIds: number[]): number[] {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" /*"},{"lineNumber":178,"author":{"gitId":"-"},"content":" Ignore for first fetch or ignore if there is no fetch result"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" We also have to ignore for no fetch result as the cache might return a"},{"lineNumber":181,"author":{"gitId":"-"},"content":" 304 reponse with no differences in issues, resulting in the fetchIssueIds"},{"lineNumber":182,"author":{"gitId":"-"},"content":" to be empty"},{"lineNumber":183,"author":{"gitId":"-"},"content":" */"},{"lineNumber":184,"author":{"gitId":"-"},"content":" if (this.issues \u003d\u003d\u003d undefined || !fetchedIssueIds.length) {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" return [];"},{"lineNumber":186,"author":{"gitId":"-"},"content":" }"},{"lineNumber":187,"author":{"gitId":"-"},"content":""},{"lineNumber":188,"author":{"gitId":"-"},"content":" const fetchedIssueIdsSet \u003d new Set\u003cnumber\u003e(fetchedIssueIds);"},{"lineNumber":189,"author":{"gitId":"-"},"content":""},{"lineNumber":190,"author":{"gitId":"-"},"content":" const result \u003d Object.keys(this.issues)"},{"lineNumber":191,"author":{"gitId":"-"},"content":" .map((x) \u003d\u003e +x)"},{"lineNumber":192,"author":{"gitId":"-"},"content":" .filter((issueId) \u003d\u003e !fetchedIssueIdsSet.has(issueId));"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"-"},"content":" return result;"},{"lineNumber":195,"author":{"gitId":"-"},"content":" }"},{"lineNumber":196,"author":{"gitId":"-"},"content":""},{"lineNumber":197,"author":{"gitId":"-"},"content":" private createIssueModel(githubIssue: GithubIssue): Issue {"},{"lineNumber":198,"author":{"gitId":"NereusWB922"},"content":" switch (this.viewService.currentView) {"},{"lineNumber":199,"author":{"gitId":"NereusWB922"},"content":" case View.issuesViewer:"},{"lineNumber":200,"author":{"gitId":"-"},"content":" return Issue.createPhaseBugReportingIssue(githubIssue);"},{"lineNumber":201,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":202,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":203,"author":{"gitId":"-"},"content":" }"},{"lineNumber":204,"author":{"gitId":"-"},"content":" }"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" setIssueTeamFilter(filterValue: string) {"},{"lineNumber":207,"author":{"gitId":"-"},"content":" if (filterValue) {"},{"lineNumber":208,"author":{"gitId":"-"},"content":" this.issueTeamFilter \u003d filterValue;"},{"lineNumber":209,"author":{"gitId":"-"},"content":" }"},{"lineNumber":210,"author":{"gitId":"-"},"content":" }"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" setSessionId(sessionId: string) {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" this.sessionId \u003d sessionId;"},{"lineNumber":214,"author":{"gitId":"-"},"content":" }"},{"lineNumber":215,"author":{"gitId":"-"},"content":""},{"lineNumber":216,"author":{"gitId":"-"},"content":" getIssueTeamFilter(): string {"},{"lineNumber":217,"author":{"gitId":"-"},"content":" return this.issueTeamFilter;"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":1,"NereusWB922":6,"-":212}},{"path":"src/app/core/services/label.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"Arif-Khalid"},"content":"import { BehaviorSubject, EMPTY, Observable, of, Subject, Subscription, timer } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { catchError, exhaustMap, finalize, map } from \u0027rxjs/operators\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { Label, SimpleLabel } from \u0027../models/label.model\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027./github.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"/* The threshold to decide if color is dark or light."},{"lineNumber":8,"author":{"gitId":"-"},"content":"A higher threshold value will result in more colors determined to be \"dark\"."},{"lineNumber":9,"author":{"gitId":"-"},"content":"W3C recommendation is 0.179, but 0.184 is chosen so that some colors (like bright red)"},{"lineNumber":10,"author":{"gitId":"-"},"content":"are considered dark (Github too consider them dark) */"},{"lineNumber":11,"author":{"gitId":"-"},"content":"const COLOR_DARKNESS_THRESHOLD \u003d 0.184;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"const COLOR_BLACK \u003d \u0027000000\u0027; // Dark color for text with light background"},{"lineNumber":14,"author":{"gitId":"-"},"content":"const COLOR_WHITE \u003d \u0027ffffff\u0027; // Light color for text with dark background"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":17,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":18,"author":{"gitId":"-"},"content":"})"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":21,"author":{"gitId":"-"},"content":" * Responsible for retrieval and parsing of label data"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * from the GitHub repository for the WATcher application."},{"lineNumber":23,"author":{"gitId":"-"},"content":" */"},{"lineNumber":24,"author":{"gitId":"-"},"content":"export class LabelService {"},{"lineNumber":25,"author":{"gitId":"nknguyenhc"},"content":" static readonly POLL_INTERVAL \u003d 20000; // 20 seconds"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" labels: Label[];"},{"lineNumber":28,"author":{"gitId":"-"},"content":" simpleLabels: SimpleLabel[];"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" private labelsPollSubscription: Subscription;"},{"lineNumber":31,"author":{"gitId":"Arif-Khalid"},"content":" private labelsSubject \u003d new Subject\u003cSimpleLabel[]\u003e();"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" constructor(private githubService: GithubService) {}"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" startPollLabels() {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" if (this.labelsPollSubscription) {"},{"lineNumber":37,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" }"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.labelsPollSubscription \u003d timer(0, LabelService.POLL_INTERVAL)"},{"lineNumber":40,"author":{"gitId":"-"},"content":" .pipe("},{"lineNumber":41,"author":{"gitId":"-"},"content":" exhaustMap(() \u003d\u003e {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" return this.fetchLabels().pipe("},{"lineNumber":43,"author":{"gitId":"-"},"content":" catchError(() \u003d\u003e {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return EMPTY;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" })"},{"lineNumber":46,"author":{"gitId":"-"},"content":" );"},{"lineNumber":47,"author":{"gitId":"-"},"content":" })"},{"lineNumber":48,"author":{"gitId":"-"},"content":" )"},{"lineNumber":49,"author":{"gitId":"-"},"content":" .subscribe(() \u003d\u003e {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" this.labelsSubject.next(this.simpleLabels);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" });"},{"lineNumber":52,"author":{"gitId":"-"},"content":" }"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" stopPollLabels() {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" if (this.labelsPollSubscription) {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" this.labelsPollSubscription.unsubscribe();"},{"lineNumber":57,"author":{"gitId":"-"},"content":" this.labelsPollSubscription \u003d undefined;"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" connect(): Observable\u003cSimpleLabel[]\u003e {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" return this.labelsSubject.asObservable();"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":66,"author":{"gitId":"-"},"content":" * Fetch labels from Github."},{"lineNumber":67,"author":{"gitId":"-"},"content":" */"},{"lineNumber":68,"author":{"gitId":"-"},"content":" public fetchLabels(): Observable\u003cany\u003e {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" return this.githubService.fetchAllLabels().pipe("},{"lineNumber":70,"author":{"gitId":"-"},"content":" map((response) \u003d\u003e {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" this.labels \u003d this.parseLabelData(response);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" this.simpleLabels \u003d this.labels;"},{"lineNumber":73,"author":{"gitId":"-"},"content":" this.labelsSubject.next(this.simpleLabels);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" return response;"},{"lineNumber":75,"author":{"gitId":"-"},"content":" })"},{"lineNumber":76,"author":{"gitId":"-"},"content":" );"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":80,"author":{"gitId":"-"},"content":" * Parses label information and returns an array of Label objects."},{"lineNumber":81,"author":{"gitId":"-"},"content":" * @param labels - Label Information from API."},{"lineNumber":82,"author":{"gitId":"-"},"content":" */"},{"lineNumber":83,"author":{"gitId":"-"},"content":" parseLabelData(labels: Array\u003cany\u003e): Label[] {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" const labelData: Label[] \u003d [];"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" for (const label of labels) {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" labelData.push(new Label(label));"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":" return labelData;"},{"lineNumber":90,"author":{"gitId":"-"},"content":" }"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":93,"author":{"gitId":"-"},"content":" * Returns true if the given color is considered \"dark\""},{"lineNumber":94,"author":{"gitId":"-"},"content":" * The color is considered \"dark\" if its luminance is less than COLOR_DARKNESS_THRESHOLD"},{"lineNumber":95,"author":{"gitId":"-"},"content":" * @param inputColor: the color"},{"lineNumber":96,"author":{"gitId":"-"},"content":" */"},{"lineNumber":97,"author":{"gitId":"-"},"content":" isDarkColor(inputColor: string): boolean {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" const COLOR \u003d inputColor.charAt(0) \u003d\u003d\u003d \u0027#\u0027 ? inputColor.substring(1, 7) : inputColor;"},{"lineNumber":99,"author":{"gitId":"-"},"content":" const R \u003d parseInt(COLOR.substring(0, 2), 16);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" const G \u003d parseInt(COLOR.substring(2, 4), 16);"},{"lineNumber":101,"author":{"gitId":"-"},"content":" const B \u003d parseInt(COLOR.substring(4, 6), 16);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" const RGB \u003d [R / 255, G / 255, B / 255];"},{"lineNumber":103,"author":{"gitId":"-"},"content":" const LINEAR_RGB \u003d RGB.map((col) \u003d\u003e {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" if (col \u003c\u003d 0.03928) {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" return col / 12.92;"},{"lineNumber":106,"author":{"gitId":"-"},"content":" }"},{"lineNumber":107,"author":{"gitId":"-"},"content":" return Math.pow((col + 0.055) / 1.055, 2.4);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" });"},{"lineNumber":109,"author":{"gitId":"-"},"content":" // Calculate the luminance of the color"},{"lineNumber":110,"author":{"gitId":"-"},"content":" const LUMINANCE \u003d 0.2126 * LINEAR_RGB[0] + 0.7152 * LINEAR_RGB[1] + 0.0722 * LINEAR_RGB[2];"},{"lineNumber":111,"author":{"gitId":"-"},"content":" // The color is \"dark\" if the luminance is lower than the threshold"},{"lineNumber":112,"author":{"gitId":"-"},"content":" return LUMINANCE \u003c COLOR_DARKNESS_THRESHOLD;"},{"lineNumber":113,"author":{"gitId":"-"},"content":" }"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":116,"author":{"gitId":"-"},"content":" * Returns a css style for the background and text color of the label"},{"lineNumber":117,"author":{"gitId":"-"},"content":" * @param color: the color of the label"},{"lineNumber":118,"author":{"gitId":"-"},"content":" * @return the style with background-color in rgb"},{"lineNumber":119,"author":{"gitId":"-"},"content":" * @throws exception if input is an invalid color code"},{"lineNumber":120,"author":{"gitId":"-"},"content":" */"},{"lineNumber":121,"author":{"gitId":"-"},"content":" setLabelStyle(color: string) {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" let textColor: string;"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" textColor \u003d this.isDarkColor(color) ? COLOR_WHITE : COLOR_BLACK;"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" const styles \u003d {"},{"lineNumber":127,"author":{"gitId":"-"},"content":" \u0027background-color\u0027: `#${color}`,"},{"lineNumber":128,"author":{"gitId":"-"},"content":" color: `#${textColor}`"},{"lineNumber":129,"author":{"gitId":"-"},"content":" };"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" return styles;"},{"lineNumber":132,"author":{"gitId":"-"},"content":" }"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" reset() {"},{"lineNumber":135,"author":{"gitId":"-"},"content":" this.labels \u003d undefined;"},{"lineNumber":136,"author":{"gitId":"-"},"content":" this.simpleLabels \u003d undefined;"},{"lineNumber":137,"author":{"gitId":"-"},"content":" this.stopPollLabels();"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":1,"Arif-Khalid":2,"-":136}},{"path":"src/app/core/services/milestone.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { map } from \u0027rxjs/operators\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { Milestone } from \u0027../models/milestone.model\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027./github.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":8,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":9,"author":{"gitId":"-"},"content":"})"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":12,"author":{"gitId":"-"},"content":" * Responsible for retrieval and parsing and syncing of milestone data"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * from the GitHub repository for the WATcher application."},{"lineNumber":14,"author":{"gitId":"-"},"content":" */"},{"lineNumber":15,"author":{"gitId":"-"},"content":"export class MilestoneService {"},{"lineNumber":16,"author":{"gitId":"nknguyenhc"},"content":" milestones: Milestone[] \u003d [];"},{"lineNumber":17,"author":{"gitId":"-"},"content":" hasNoMilestones: boolean;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":" constructor(private githubService: GithubService) {}"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * Fetch all milestones from github."},{"lineNumber":23,"author":{"gitId":"-"},"content":" */"},{"lineNumber":24,"author":{"gitId":"-"},"content":" public fetchMilestones(): Observable\u003cany\u003e {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" return this.githubService.fetchAllMilestones().pipe("},{"lineNumber":26,"author":{"gitId":"-"},"content":" map((response) \u003d\u003e {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" this.milestones \u003d this.parseMilestoneData(response);"},{"lineNumber":28,"author":{"gitId":"-"},"content":" this.hasNoMilestones \u003d response.length \u003d\u003d\u003d 0;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" return response;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" })"},{"lineNumber":31,"author":{"gitId":"-"},"content":" );"},{"lineNumber":32,"author":{"gitId":"-"},"content":" }"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":35,"author":{"gitId":"-"},"content":" * Parses milestone information and returns an array of Milestone objects."},{"lineNumber":36,"author":{"gitId":"-"},"content":" * @param milestones - Milestone Information from API."},{"lineNumber":37,"author":{"gitId":"-"},"content":" */"},{"lineNumber":38,"author":{"gitId":"-"},"content":" parseMilestoneData(milestones: Array\u003cany\u003e): Milestone[] {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" const milestoneData: Milestone[] \u003d [];"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" for (const milestone of milestones) {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" milestoneData.push(new Milestone(milestone));"},{"lineNumber":43,"author":{"gitId":"-"},"content":" }"},{"lineNumber":44,"author":{"gitId":"-"},"content":" milestoneData.sort((a: Milestone, b: Milestone) \u003d\u003e a.title.localeCompare(b.title));"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" return milestoneData;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" }"},{"lineNumber":48,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":49,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" * Returns the open milestone with earliest deadline."},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":" * If no deadline exists, returns milestone with alphabetically smallest title."},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" * Returns null if there are no open milestones."},{"lineNumber":53,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":54,"author":{"gitId":"nknguyenhc"},"content":" getEarliestOpenMilestone(): Milestone {"},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" const openMilestones: Milestone[] \u003d this.milestones.filter((milestone: Milestone) \u003d\u003e milestone.state \u003d\u003d\u003d \u0027open\u0027);"},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":57,"author":{"gitId":"NereusWB922"},"content":" if (openMilestones.length \u003d\u003d\u003d 0) {"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" return null;"},{"lineNumber":59,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":61,"author":{"gitId":"NereusWB922"},"content":" const target \u003d openMilestones.reduce((prev, curr) \u003d\u003e {"},{"lineNumber":62,"author":{"gitId":"NereusWB922"},"content":" if (prev \u003d\u003d\u003d null) {"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" return curr;"},{"lineNumber":64,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" if (prev.deadline !\u003d\u003d curr.deadline) {"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":" if (!prev.deadline) {"},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":" return curr;"},{"lineNumber":69,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":" if (!curr.deadline) {"},{"lineNumber":71,"author":{"gitId":"NereusWB922"},"content":" return prev;"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" return prev.deadline \u003c curr.deadline ? prev : curr;"},{"lineNumber":74,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" // Both without due date or with the same due date"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" return prev.title.localeCompare(curr.title) \u003c 0 ? prev : curr;"},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":" }, null);"},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":" return target;"},{"lineNumber":81,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":82,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":83,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":84,"author":{"gitId":"nknguyenhc"},"content":" * Gets the closed milestone with the latest deadline."},{"lineNumber":85,"author":{"gitId":"nknguyenhc"},"content":" * Returns null if there is no closed milestone with deadline."},{"lineNumber":86,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":87,"author":{"gitId":"nknguyenhc"},"content":" getLatestClosedMilestone(): Milestone {"},{"lineNumber":88,"author":{"gitId":"nknguyenhc"},"content":" let latestClosedMilestone: Milestone \u003d null;"},{"lineNumber":89,"author":{"gitId":"nknguyenhc"},"content":" for (const milestone of this.milestones) {"},{"lineNumber":90,"author":{"gitId":"nknguyenhc"},"content":" if (!milestone.deadline || milestone.state !\u003d\u003d \u0027closed\u0027) {"},{"lineNumber":91,"author":{"gitId":"nknguyenhc"},"content":" continue;"},{"lineNumber":92,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":93,"author":{"gitId":"nknguyenhc"},"content":" if (latestClosedMilestone \u003d\u003d\u003d null) {"},{"lineNumber":94,"author":{"gitId":"nknguyenhc"},"content":" latestClosedMilestone \u003d milestone;"},{"lineNumber":95,"author":{"gitId":"nknguyenhc"},"content":" } else if (milestone.deadline \u003e latestClosedMilestone.deadline) {"},{"lineNumber":96,"author":{"gitId":"nknguyenhc"},"content":" latestClosedMilestone \u003d milestone;"},{"lineNumber":97,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":98,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":99,"author":{"gitId":"nknguyenhc"},"content":" return latestClosedMilestone;"},{"lineNumber":100,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":28,"NereusWB922":26,"-":47}},{"path":"src/app/core/services/view.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { ActivatedRoute, Router } from \u0027@angular/router\u0027;"},{"lineNumber":3,"author":{"gitId":"nknguyenhc"},"content":"import { BehaviorSubject, Observable, of, Subject } from \u0027rxjs\u0027;"},{"lineNumber":4,"author":{"gitId":"nknguyenhc"},"content":"import { map } from \u0027rxjs/operators\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { STORAGE_KEYS } from \u0027../constants/storage-keys.constants\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { Repo } from \u0027../models/repo.model\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { SessionData } from \u0027../models/session.model\u0027;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"import { View } from \u0027../models/view.model\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { ErrorMessageService } from \u0027./error-message.service\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027./github.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027./logging.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { RepoUrlCacheService } from \u0027./repo-url-cache.service\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"export const SESSION_AVALIABILITY_FIX_FAILED \u003d \u0027Session Availability Fix failed.\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" * The title of each view that appears in the header bar."},{"lineNumber":18,"author":{"gitId":"-"},"content":" */"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":"export const ViewDescription \u003d {"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" [View.issuesViewer]: \u0027Issues Dashboard\u0027,"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" [View.activityDashboard]: \u0027Activity Dashboard\u0027"},{"lineNumber":22,"author":{"gitId":"-"},"content":"};"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * All data of the session."},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" * Add accessible views here."},{"lineNumber":27,"author":{"gitId":"-"},"content":" */"},{"lineNumber":28,"author":{"gitId":"-"},"content":"export const STARTING_SESSION_DATA: SessionData \u003d {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" sessionRepo: ["},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" { view: View.issuesViewer, repos: [] }"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" // { view: View.activityDashboard, repos: [] }"},{"lineNumber":32,"author":{"gitId":"-"},"content":" ]"},{"lineNumber":33,"author":{"gitId":"-"},"content":"};"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":"export const STARTING_VIEW \u003d View.issuesViewer;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":38,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027"},{"lineNumber":39,"author":{"gitId":"-"},"content":"})"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":42,"author":{"gitId":"-"},"content":" * Responsible for managing the current selected feature of WATcher as well as the"},{"lineNumber":43,"author":{"gitId":"-"},"content":" * current session data and repository details related to the session."},{"lineNumber":44,"author":{"gitId":"-"},"content":" */"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":"export class ViewService {"},{"lineNumber":46,"author":{"gitId":"nknguyenhc"},"content":" public static readonly REPO_QUERY_PARAM_KEY \u003d \u0027repo\u0027;"},{"lineNumber":47,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" public currentView: View \u003d STARTING_VIEW;"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":" public currentRepo: Repo; // current or main repository of current view"},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" public otherRepos: Repo[]; // more repositories relevant to this view"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" repoSetSource \u003d new BehaviorSubject(false);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" repoSetState \u003d this.repoSetSource.asObservable();"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":56,"author":{"gitId":"-"},"content":" * Expose an observable to track changes to currentRepo"},{"lineNumber":57,"author":{"gitId":"-"},"content":" *"},{"lineNumber":58,"author":{"gitId":"-"},"content":" * TODO - replace all references to currentRepo to have"},{"lineNumber":59,"author":{"gitId":"-"},"content":" * dependencies subscribe to this observable?"},{"lineNumber":60,"author":{"gitId":"-"},"content":" */"},{"lineNumber":61,"author":{"gitId":"-"},"content":" public repoChanged$: Subject\u003cRepo | null\u003e \u003d new Subject();"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" /** Whether the ViewService is changing the repository */"},{"lineNumber":64,"author":{"gitId":"-"},"content":" public isChangingRepo \u003d new BehaviorSubject\u003cboolean\u003e(false);"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" public sessionData \u003d STARTING_SESSION_DATA; // stores session data for the session"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"nknguyenhc"},"content":" constructor("},{"lineNumber":69,"author":{"gitId":"nknguyenhc"},"content":" private githubService: GithubService,"},{"lineNumber":70,"author":{"gitId":"nknguyenhc"},"content":" private repoUrlCacheService: RepoUrlCacheService,"},{"lineNumber":71,"author":{"gitId":"nknguyenhc"},"content":" public logger: LoggingService,"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" private route: ActivatedRoute,"},{"lineNumber":73,"author":{"gitId":"nknguyenhc"},"content":" private router: Router"},{"lineNumber":74,"author":{"gitId":"nknguyenhc"},"content":" ) {}"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":77,"author":{"gitId":"-"},"content":" * Sets the current main repository and additional repos if any."},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":" * Updates session data in View Service and local storage."},{"lineNumber":79,"author":{"gitId":"-"},"content":" * Updates Github Service with current repository."},{"lineNumber":80,"author":{"gitId":"-"},"content":" * @param repo Main current repository"},{"lineNumber":81,"author":{"gitId":"-"},"content":" * @param repos Additional repositories"},{"lineNumber":82,"author":{"gitId":"-"},"content":" */"},{"lineNumber":83,"author":{"gitId":"-"},"content":" setRepository(repo: Repo, repos?: Repo[]): void {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" this.currentRepo \u003d repo;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" this.otherRepos \u003d repos ? repos : [];"},{"lineNumber":86,"author":{"gitId":"NereusWB922"},"content":" this.sessionData.sessionRepo.find((x) \u003d\u003e x.view \u003d\u003d\u003d this.currentView).repos \u003d this.getRepository();"},{"lineNumber":87,"author":{"gitId":"NereusWB922"},"content":" this.githubService.storeViewDetails(this.currentRepo.owner, this.currentRepo.name);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" localStorage.setItem(\u0027sessionData\u0027, JSON.stringify(this.sessionData));"},{"lineNumber":89,"author":{"gitId":"nknguyenhc"},"content":" this.router.navigate([\u0027issuesViewer\u0027], {"},{"lineNumber":90,"author":{"gitId":"nknguyenhc"},"content":" queryParams: {"},{"lineNumber":91,"author":{"gitId":"NereusWB922"},"content":" [ViewService.REPO_QUERY_PARAM_KEY]: repo.toString()"},{"lineNumber":92,"author":{"gitId":"NereusWB922"},"content":" },"},{"lineNumber":93,"author":{"gitId":"NereusWB922"},"content":" queryParamsHandling: \u0027merge\u0027"},{"lineNumber":94,"author":{"gitId":"nknguyenhc"},"content":" });"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":98,"author":{"gitId":"-"},"content":" * Changes current respository to a new repository."},{"lineNumber":99,"author":{"gitId":"-"},"content":" * @param repo New current repository"},{"lineNumber":100,"author":{"gitId":"-"},"content":" */"},{"lineNumber":101,"author":{"gitId":"-"},"content":" private changeCurrentRepository(repo: Repo): void {"},{"lineNumber":102,"author":{"gitId":"NereusWB922"},"content":" this.logger.info(`ViewService: Changing current repository to \u0027${repo}\u0027`);"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"NereusWB922"},"content":" if (this.currentView \u003d\u003d\u003d View.issuesViewer) {"},{"lineNumber":105,"author":{"gitId":"NereusWB922"},"content":" /** Adds past repositories to view */"},{"lineNumber":106,"author":{"gitId":"-"},"content":" (this.otherRepos || []).push(this.currentRepo);"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"nknguyenhc"},"content":" if (!repo.equals(this.currentRepo)) {"},{"lineNumber":109,"author":{"gitId":"-"},"content":" this.setRepository(repo, this.otherRepos);"},{"lineNumber":110,"author":{"gitId":"nknguyenhc"},"content":" this.repoChanged$.next(repo);"},{"lineNumber":111,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" this.repoUrlCacheService.cache(repo.toString());"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":117,"author":{"gitId":"-"},"content":" * Change repository if a valid repository is provided"},{"lineNumber":118,"author":{"gitId":"-"},"content":" * @param repo New repository"},{"lineNumber":119,"author":{"gitId":"-"},"content":" */"},{"lineNumber":120,"author":{"gitId":"-"},"content":" async changeRepositoryIfValid(repo: Repo) {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" this.isChangingRepo.next(true);"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" const isValidRepository \u003d await this.githubService.isRepositoryPresent(repo.owner, repo.name).toPromise();"},{"lineNumber":124,"author":{"gitId":"-"},"content":" if (!isValidRepository) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" this.isChangingRepo.next(false);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" throw new Error(ErrorMessageService.repositoryNotPresentMessage());"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" this.changeCurrentRepository(repo);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" this.isChangingRepo.next(false);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" }"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":134,"author":{"gitId":"-"},"content":" * Returns the full repository array of the current feature."},{"lineNumber":135,"author":{"gitId":"-"},"content":" */"},{"lineNumber":136,"author":{"gitId":"-"},"content":" getRepository(): Repo[] {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" return [this.currentRepo].concat(this.otherRepos);"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":141,"author":{"gitId":"-"},"content":" * Retrieves the repository url from local storage and sets to current repository."},{"lineNumber":142,"author":{"gitId":"-"},"content":" */"},{"lineNumber":143,"author":{"gitId":"-"},"content":" async initializeCurrentRepository() {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" const org \u003d window.localStorage.getItem(STORAGE_KEYS.ORG);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" const repoName \u003d window.localStorage.getItem(STORAGE_KEYS.DATA_REPO);"},{"lineNumber":146,"author":{"gitId":"NereusWB922"},"content":" this.logger.info(`ViewService: received initial org (${org}) and initial name (${repoName})`);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" let repo: Repo;"},{"lineNumber":148,"author":{"gitId":"-"},"content":" if (!org || !repoName) {"},{"lineNumber":149,"author":{"gitId":"-"},"content":" repo \u003d Repo.ofEmptyRepo();"},{"lineNumber":150,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" repo \u003d new Repo(org, repoName);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" }"},{"lineNumber":153,"author":{"gitId":"-"},"content":" const isValidRepository \u003d await this.githubService.isRepositoryPresent(repo.owner, repo.name).toPromise();"},{"lineNumber":154,"author":{"gitId":"-"},"content":" if (!isValidRepository) {"},{"lineNumber":155,"author":{"gitId":"-"},"content":" throw new Error(ErrorMessageService.repositoryNotPresentMessage());"},{"lineNumber":156,"author":{"gitId":"-"},"content":" }"},{"lineNumber":157,"author":{"gitId":"NereusWB922"},"content":" this.logger.info(`ViewService: Repo is ${repo}`);"},{"lineNumber":158,"author":{"gitId":"-"},"content":" this.setRepository(repo);"},{"lineNumber":159,"author":{"gitId":"-"},"content":" this.repoSetSource.next(true);"},{"lineNumber":160,"author":{"gitId":"-"},"content":" }"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":163,"author":{"gitId":"nknguyenhc"},"content":" * Set items in the local storage corresponding to the next URL."},{"lineNumber":164,"author":{"gitId":"NereusWB922"},"content":" * This includes checking if the view is valid, and if the repo is of the correct format."},{"lineNumber":165,"author":{"gitId":"nknguyenhc"},"content":" * @param url The partial URL without the host, e.g. `/issuesViewer?repo\u003dCATcher%2FWATcher."},{"lineNumber":166,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":167,"author":{"gitId":"nknguyenhc"},"content":" setupFromUrl(url: string): Observable\u003cvoid\u003e {"},{"lineNumber":168,"author":{"gitId":"NereusWB922"},"content":" return of(this.getViewAndRepoFromUrl(url)).pipe("},{"lineNumber":169,"author":{"gitId":"NereusWB922"},"content":" map(([viewName, repoName]) \u003d\u003e {"},{"lineNumber":170,"author":{"gitId":"NereusWB922"},"content":" if (!this.isViewAllowed(viewName)) {"},{"lineNumber":171,"author":{"gitId":"nknguyenhc"},"content":" throw new Error(ErrorMessageService.invalidUrlMessage());"},{"lineNumber":172,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":173,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":174,"author":{"gitId":"nknguyenhc"},"content":" if (repoName \u003d\u003d\u003d null) {"},{"lineNumber":175,"author":{"gitId":"nknguyenhc"},"content":" throw new Error(ErrorMessageService.invalidUrlMessage());"},{"lineNumber":176,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":177,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":178,"author":{"gitId":"nknguyenhc"},"content":" const newRepo \u003d Repo.of(repoName);"},{"lineNumber":179,"author":{"gitId":"nknguyenhc"},"content":" if (newRepo) {"},{"lineNumber":180,"author":{"gitId":"nknguyenhc"},"content":" window.localStorage.setItem(STORAGE_KEYS.ORG, newRepo.owner);"},{"lineNumber":181,"author":{"gitId":"nknguyenhc"},"content":" window.localStorage.setItem(STORAGE_KEYS.DATA_REPO, newRepo.name);"},{"lineNumber":182,"author":{"gitId":"nknguyenhc"},"content":" this.repoUrlCacheService.cache(newRepo.toString());"},{"lineNumber":183,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":184,"author":{"gitId":"nknguyenhc"},"content":" })"},{"lineNumber":185,"author":{"gitId":"nknguyenhc"},"content":" );"},{"lineNumber":186,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":187,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":188,"author":{"gitId":"NereusWB922"},"content":" /**"},{"lineNumber":189,"author":{"gitId":"NereusWB922"},"content":" * Initializes a repo based on the URL parameters and changes the repo if valid."},{"lineNumber":190,"author":{"gitId":"NereusWB922"},"content":" */"},{"lineNumber":191,"author":{"gitId":"NereusWB922"},"content":" initializeRepoFromUrlParams(): void {"},{"lineNumber":192,"author":{"gitId":"NereusWB922"},"content":" const repoParams \u003d this.route.snapshot.queryParamMap.get(ViewService.REPO_QUERY_PARAM_KEY);"},{"lineNumber":193,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":194,"author":{"gitId":"NereusWB922"},"content":" const newRepo \u003d Repo.of(repoParams);"},{"lineNumber":195,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":196,"author":{"gitId":"NereusWB922"},"content":" this.changeRepositoryIfValid(newRepo);"},{"lineNumber":197,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":198,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":199,"author":{"gitId":"NereusWB922"},"content":" getViewAndRepoFromUrl(url: string): [string, string] {"},{"lineNumber":200,"author":{"gitId":"nknguyenhc"},"content":" const urlObject \u003d new URL(`${location.protocol}//${location.host}${url}`);"},{"lineNumber":201,"author":{"gitId":"nknguyenhc"},"content":" const pathname \u003d urlObject.pathname;"},{"lineNumber":202,"author":{"gitId":"NereusWB922"},"content":" const reponame \u003d urlObject.searchParams.get(ViewService.REPO_QUERY_PARAM_KEY);"},{"lineNumber":203,"author":{"gitId":"nknguyenhc"},"content":" return [pathname, reponame];"},{"lineNumber":204,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":205,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":206,"author":{"gitId":"NereusWB922"},"content":" isViewAllowed(viewName: string) {"},{"lineNumber":207,"author":{"gitId":"NereusWB922"},"content":" return viewName \u003d\u003d\u003d \u0027/\u0027 + View.issuesViewer;"},{"lineNumber":208,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":209,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":210,"author":{"gitId":"-"},"content":" isRepoSet(): boolean {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" return this.repoSetSource.getValue();"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":215,"author":{"gitId":"NereusWB922"},"content":" * Changes view and updates View Service\u0027s properties."},{"lineNumber":216,"author":{"gitId":"NereusWB922"},"content":" * @param view New view"},{"lineNumber":217,"author":{"gitId":"-"},"content":" */"},{"lineNumber":218,"author":{"gitId":"NereusWB922"},"content":" changeView(view: View) {"},{"lineNumber":219,"author":{"gitId":"NereusWB922"},"content":" this.currentView \u003d view;"},{"lineNumber":220,"author":{"gitId":"-"},"content":""},{"lineNumber":221,"author":{"gitId":"-"},"content":" // For now, assumes repository stays the same"},{"lineNumber":222,"author":{"gitId":"NereusWB922"},"content":" this.githubService.storeViewDetails(this.currentRepo.owner, this.currentRepo.name);"},{"lineNumber":223,"author":{"gitId":"-"},"content":" }"},{"lineNumber":224,"author":{"gitId":"-"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":" public getCurrentRepositoryURL() {"},{"lineNumber":226,"author":{"gitId":"-"},"content":" return this.currentRepo.owner.concat(\u0027/\u0027).concat(this.currentRepo.name);"},{"lineNumber":227,"author":{"gitId":"-"},"content":" }"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" reset() {"},{"lineNumber":230,"author":{"gitId":"NereusWB922"},"content":" this.currentView \u003d STARTING_VIEW;"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":45,"NereusWB922":52,"-":135}},{"path":"src/app/issues-viewer/card-view/card-view.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":".card-column {"},{"lineNumber":2,"author":{"gitId":"-"},"content":" margin: 8px;"},{"lineNumber":3,"author":{"gitId":"nknguyenhc"},"content":" height: 77vh;"},{"lineNumber":4,"author":{"gitId":"nknguyenhc"},"content":" display: flex;"},{"lineNumber":5,"author":{"gitId":"nknguyenhc"},"content":" flex-direction: column;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"}"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":".card {"},{"lineNumber":9,"author":{"gitId":"-"},"content":" margin: 8px 0px 8px 0px;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"}"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":".mat-card-title {"},{"lineNumber":13,"author":{"gitId":"-"},"content":" display: flex;"},{"lineNumber":14,"author":{"gitId":"-"},"content":" align-items: center;"},{"lineNumber":15,"author":{"gitId":"-"},"content":" font-size: 12px;"},{"lineNumber":16,"author":{"gitId":"-"},"content":" text-align: center;"},{"lineNumber":17,"author":{"gitId":"-"},"content":" overflow: auto;"},{"lineNumber":18,"author":{"gitId":"-"},"content":" word-break: break-word;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"}"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":".column-header .mat-card-title {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" font-size: 14px;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"}"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":".mat-card {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" padding: 10px;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"}"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":":host ::ng-deep div.mat-card-header-text {"},{"lineNumber":30,"author":{"gitId":"-"},"content":" margin: 2px;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"}"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":"div.column-header .mat-card-title {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" justify-content: center;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" margin: 0;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"}"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":"div.column-header {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" justify-content: center;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" position: relative;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" z-index: 5;"},{"lineNumber":42,"author":{"gitId":"-"},"content":"}"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":"div.column-header .mat-card-header {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" display: flex;"},{"lineNumber":46,"author":{"gitId":"-"},"content":" align-items: center;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" justify-content: center;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"}"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":".scrollable-container {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" margin-bottom: 2px;"},{"lineNumber":52,"author":{"gitId":"-"},"content":" position: relative;"},{"lineNumber":53,"author":{"gitId":"-"},"content":"}"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"Arif-Khalid"},"content":"/* Ref: https://lea.verou.me/blog/2012/04/background-attachment-local/ */"},{"lineNumber":56,"author":{"gitId":"Arif-Khalid"},"content":".scroll-shadow {"},{"lineNumber":57,"author":{"gitId":"Arif-Khalid"},"content":" background:"},{"lineNumber":58,"author":{"gitId":"Arif-Khalid"},"content":" /* Shadow covers */ linear-gradient(white 30%, rgba(255, 255, 255, 0)),"},{"lineNumber":59,"author":{"gitId":"Arif-Khalid"},"content":" linear-gradient(rgba(255, 255, 255, 0), white 70%) 0 100%,"},{"lineNumber":60,"author":{"gitId":"Arif-Khalid"},"content":" /* Shadows */ radial-gradient(50% 0, farthest-side, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0)),"},{"lineNumber":61,"author":{"gitId":"Arif-Khalid"},"content":" radial-gradient(50% 100%, farthest-side, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0)) 0 100%;"},{"lineNumber":62,"author":{"gitId":"Arif-Khalid"},"content":" background:"},{"lineNumber":63,"author":{"gitId":"Arif-Khalid"},"content":" /* Shadow covers */ linear-gradient(white 30%, rgba(255, 255, 255, 0)),"},{"lineNumber":64,"author":{"gitId":"Arif-Khalid"},"content":" linear-gradient(rgba(255, 255, 255, 0), white 70%) 0 100%,"},{"lineNumber":65,"author":{"gitId":"Arif-Khalid"},"content":" /* Shadows */ radial-gradient(farthest-side at 50% 0, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0)),"},{"lineNumber":66,"author":{"gitId":"Arif-Khalid"},"content":" radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0)) 0 100%;"},{"lineNumber":67,"author":{"gitId":"Arif-Khalid"},"content":" background-repeat: no-repeat;"},{"lineNumber":68,"author":{"gitId":"Arif-Khalid"},"content":" background-color: white;"},{"lineNumber":69,"author":{"gitId":"Arif-Khalid"},"content":" background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px;"},{"lineNumber":70,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":71,"author":{"gitId":"Arif-Khalid"},"content":" /* Opera doesn\u0027t support this in the shorthand */"},{"lineNumber":72,"author":{"gitId":"Arif-Khalid"},"content":" background-attachment: local, local, scroll, scroll;"},{"lineNumber":73,"author":{"gitId":"-"},"content":"}"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":".scrollable-container::before {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" pointer-events: none;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" content: \u0027\u0027;"},{"lineNumber":78,"author":{"gitId":"-"},"content":" position: absolute;"},{"lineNumber":79,"author":{"gitId":"-"},"content":" z-index: 2;"},{"lineNumber":80,"author":{"gitId":"-"},"content":" height: 6px;"},{"lineNumber":81,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":82,"author":{"gitId":"-"},"content":" display: block;"},{"lineNumber":83,"author":{"gitId":"-"},"content":" background-image: linear-gradient(to bottom, white 66%, transparent);"},{"lineNumber":84,"author":{"gitId":"-"},"content":"}"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":".scrollable-container::after {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" pointer-events: none;"},{"lineNumber":88,"author":{"gitId":"-"},"content":" content: \u0027\u0027;"},{"lineNumber":89,"author":{"gitId":"-"},"content":" position: sticky;"},{"lineNumber":90,"author":{"gitId":"-"},"content":" z-index: 2;"},{"lineNumber":91,"author":{"gitId":"-"},"content":" top: 100%;"},{"lineNumber":92,"author":{"gitId":"-"},"content":" height: 6px;"},{"lineNumber":93,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":94,"author":{"gitId":"-"},"content":" display: block;"},{"lineNumber":95,"author":{"gitId":"-"},"content":" background-image: linear-gradient(to top, white 66%, transparent);"},{"lineNumber":96,"author":{"gitId":"-"},"content":"}"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":".scrollable-container-wrapper {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" position: relative;"},{"lineNumber":100,"author":{"gitId":"nknguyenhc"},"content":" scrollbar-width: none;"},{"lineNumber":101,"author":{"gitId":"nknguyenhc"},"content":" overflow: auto;"},{"lineNumber":102,"author":{"gitId":"nknguyenhc"},"content":" flex-grow: 1;"},{"lineNumber":103,"author":{"gitId":"-"},"content":"}"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"nknguyenhc"},"content":".scrollable-container-wrapper::-webkit-scrollbar {"},{"lineNumber":106,"author":{"gitId":"nknguyenhc"},"content":" display: none;"},{"lineNumber":107,"author":{"gitId":"-"},"content":"}"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":".loading-spinner {"},{"lineNumber":110,"author":{"gitId":"-"},"content":" display: flex;"},{"lineNumber":111,"author":{"gitId":"-"},"content":" justify-content: center;"},{"lineNumber":112,"author":{"gitId":"-"},"content":" align-items: center;"},{"lineNumber":113,"author":{"gitId":"-"},"content":"}"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":".mat-card-subtitle {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" display: flex;"},{"lineNumber":117,"author":{"gitId":"-"},"content":" align-items: center;"},{"lineNumber":118,"author":{"gitId":"-"},"content":" font-size: 11px;"},{"lineNumber":119,"author":{"gitId":"-"},"content":" text-align: left;"},{"lineNumber":120,"author":{"gitId":"-"},"content":" overflow: auto;"},{"lineNumber":121,"author":{"gitId":"-"},"content":" margin: 6px 0;"},{"lineNumber":122,"author":{"gitId":"-"},"content":"}"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":".row-count {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" background-color: rgb(222, 222, 222);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" border-radius: 3px;"},{"lineNumber":127,"author":{"gitId":"-"},"content":" cursor: default;"},{"lineNumber":128,"author":{"gitId":"-"},"content":" padding: 6px;"},{"lineNumber":129,"author":{"gitId":"-"},"content":" color: rgb(0, 0, 0);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" font-weight: 410;"},{"lineNumber":131,"author":{"gitId":"-"},"content":" display: inline-flex;"},{"lineNumber":132,"author":{"gitId":"-"},"content":" font-size: 14px;"},{"lineNumber":133,"author":{"gitId":"-"},"content":"}"},{"lineNumber":134,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":135,"author":{"gitId":"nknguyenhc"},"content":":host ::ng-deep .pagination-hide-arrow .mat-paginator-navigation-previous {"},{"lineNumber":136,"author":{"gitId":"nknguyenhc"},"content":" display: none !important;"},{"lineNumber":137,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":138,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":139,"author":{"gitId":"nknguyenhc"},"content":":host ::ng-deep .pagination-hide-arrow .mat-paginator-navigation-next {"},{"lineNumber":140,"author":{"gitId":"nknguyenhc"},"content":" display: none !important;"},{"lineNumber":141,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":142,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":143,"author":{"gitId":"nknguyenhc"},"content":":host ::ng-deep .pagination-hide-arrow .mat-paginator-range-actions {"},{"lineNumber":144,"author":{"gitId":"nknguyenhc"},"content":" display: none !important;"},{"lineNumber":145,"author":{"gitId":"nknguyenhc"},"content":"}"}],"authorContributionMap":{"nknguyenhc":20,"Arif-Khalid":18,"-":107}},{"path":"src/app/issues-viewer/card-view/card-view.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"card-column\"\u003e"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" \u003cng-container"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" [ngTemplateOutlet]\u003d\"getHeaderTemplate() || defaultHeader\""},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" [ngTemplateOutletContext]\u003d\"{ $implicit: this.group }\""},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" \u003e\u003c/ng-container\u003e"},{"lineNumber":6,"author":{"gitId":"Arif-Khalid"},"content":" \u003cdiv class\u003d\"scrollable-container-wrapper scroll-shadow\"\u003e"},{"lineNumber":7,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"scrollable-container\"\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"issue-pr-cards\" *ngFor\u003d\"let issue of this.issues$ | async; index as i\"\u003e"},{"lineNumber":9,"author":{"gitId":"MadLamprey"},"content":" \u003capp-issue-pr-card [issue]\u003d\"issue\" [filter]\u003d\"issues.filter\" [milestoneService]\u003d\"milestoneService\"\u003e\u003c/app-issue-pr-card\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003cmat-card class\u003d\"loading-spinner\" *ngIf\u003d\"this.issues.isLoading$ | async\"\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003cmat-progress-spinner color\u003d\"primary\" mode\u003d\"indeterminate\" diameter\u003d\"50\" strokeWidth\u003d\"5\"\u003e\u003c/mat-progress-spinner\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003c/mat-card\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":16,"author":{"gitId":"nknguyenhc"},"content":" \u003cmat-paginator"},{"lineNumber":17,"author":{"gitId":"nknguyenhc"},"content":" [pageSize]\u003d\"pageSize\""},{"lineNumber":18,"author":{"gitId":"MadLamprey"},"content":" [hidePageSize]\u003d\"true\""},{"lineNumber":19,"author":{"gitId":"nknguyenhc"},"content":" [pageSizeOptions]\u003d\"[10, 20, 50]\""},{"lineNumber":20,"author":{"gitId":"nknguyenhc"},"content":" [class]\u003d\"pageSize \u003e\u003d issueLength ? \u0027pagination-hide-arrow\u0027 : \u0027\u0027\""},{"lineNumber":21,"author":{"gitId":"nknguyenhc"},"content":" \u003e\u003c/mat-paginator\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":"\u003c!-- Template --\u003e"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":"\u003cng-template #defaultHeader\u003e"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card class\u003d\"loading-spinner\"\u003e"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-progress-spinner color\u003d\"primary\" mode\u003d\"indeterminate\" diameter\u003d\"50\" strokeWidth\u003d\"5\"\u003e\u003c/mat-progress-spinner\u003e"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card\u003e"},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":"\u003c/ng-template\u003e"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":"\u003cng-template #assigneeHeader let-assignee\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"column-header\"\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003cmat-card\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003cmat-card-header [ngStyle]\u003d\"{ height: \u002740px\u0027 }\"\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":" \u003cdiv"},{"lineNumber":36,"author":{"gitId":"-"},"content":" mat-card-avatar"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":" *ngIf\u003d\"assignee\""},{"lineNumber":38,"author":{"gitId":"-"},"content":" [ngStyle]\u003d\"{"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" background: \u0027url(\u0027 + assignee.avatar_url + \u0027)\u0027,"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u0027background-size\u0027: \u002740px\u0027"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }\""},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u003e\u003c/div\u003e"},{"lineNumber":43,"author":{"gitId":"-"},"content":" \u003cmat-card-title\u003e"},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" {{ assignee.login }}"},{"lineNumber":45,"author":{"gitId":"-"},"content":" \u003c/mat-card-title\u003e"},{"lineNumber":46,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row-count\"\u003e{{ this.issues.count }}\u003c/div\u003e"},{"lineNumber":47,"author":{"gitId":"-"},"content":" \u003c/mat-card-header\u003e"},{"lineNumber":48,"author":{"gitId":"-"},"content":" \u003c/mat-card\u003e"},{"lineNumber":49,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":"\u003c/ng-template\u003e"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":"\u003cng-template #milestoneHeader let-milestone\u003e"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv class\u003d\"column-header\"\u003e"},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card\u003e"},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card-header [ngStyle]\u003d\"{ height: \u002740px\u0027 }\"\u003e"},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card-title\u003e"},{"lineNumber":57,"author":{"gitId":"NereusWB922"},"content":" {{ milestone.title }}"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card-title\u003e"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv class\u003d\"row-count\"\u003e{{ this.issues.count }}\u003c/div\u003e"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card-header\u003e"},{"lineNumber":61,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card\u003e"},{"lineNumber":62,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":"\u003c/ng-template\u003e"}],"authorContributionMap":{"nknguyenhc":5,"NereusWB922":28,"Arif-Khalid":1,"MadLamprey":2,"-":27}},{"path":"src/app/issues-viewer/card-view/card-view.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import {"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" AfterViewInit,"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" Component,"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" ElementRef,"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" EventEmitter,"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" Input,"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" OnDestroy,"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" OnInit,"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" Output,"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" TemplateRef,"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" ViewChild"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":"} from \u0027@angular/core\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { MatPaginator } from \u0027@angular/material/paginator\u0027;"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"import { Observable, Subscription } from \u0027rxjs\u0027;"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":"import { Group } from \u0027../../core/models/github/group.interface\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import { Issue } from \u0027../../core/models/issue.model\u0027;"},{"lineNumber":17,"author":{"gitId":"nknguyenhc"},"content":"import { FiltersService } from \u0027../../core/services/filters.service\u0027;"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":"import { GroupBy, GroupingContextService } from \u0027../../core/services/grouping/grouping-context.service\u0027;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import { IssueService } from \u0027../../core/services/issue.service\u0027;"},{"lineNumber":20,"author":{"gitId":"nknguyenhc"},"content":"import { MilestoneService } from \u0027../../core/services/milestone.service\u0027;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import { FilterableComponent, FilterableSource } from \u0027../../shared/issue-tables/filterableTypes\u0027;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import { IssuesDataTable } from \u0027../../shared/issue-tables/IssuesDataTable\u0027;"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":25,"author":{"gitId":"-"},"content":" selector: \u0027app-card-view\u0027,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" templateUrl: \u0027./card-view.component.html\u0027,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./card-view.component.css\u0027]"},{"lineNumber":28,"author":{"gitId":"-"},"content":"})"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":31,"author":{"gitId":"-"},"content":" * Displays issues as Cards."},{"lineNumber":32,"author":{"gitId":"-"},"content":" */"},{"lineNumber":33,"author":{"gitId":"-"},"content":"export class CardViewComponent implements OnInit, AfterViewInit, OnDestroy, FilterableComponent {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" @Input() headers: string[];"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" @Input() group?: Group \u003d undefined;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" @Input() filters?: any \u003d undefined;"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" @ViewChild(\u0027defaultHeader\u0027) defaultHeaderTemplate: TemplateRef\u003cany\u003e;"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" @ViewChild(\u0027assigneeHeader\u0027) assigneeHeaderTemplate: TemplateRef\u003cany\u003e;"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" @ViewChild(\u0027milestoneHeader\u0027) milestoneHeaderTemplate: TemplateRef\u003cany\u003e;"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" issues: IssuesDataTable;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" issues$: Observable\u003cIssue[]\u003e;"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":" private timeoutId: NodeJS.Timeout | null \u003d null;"},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" private issuesLengthSubscription: Subscription;"},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" private issuesLoadingStateSubscription: Subscription;"},{"lineNumber":49,"author":{"gitId":"MadLamprey"},"content":" private filterSubscription: Subscription;"},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":51,"author":{"gitId":"Arif-Khalid"},"content":" isLoading \u003d true;"},{"lineNumber":52,"author":{"gitId":"Arif-Khalid"},"content":" issueLength \u003d 0;"},{"lineNumber":53,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":54,"author":{"gitId":"nknguyenhc"},"content":" pageSize \u003d 20;"},{"lineNumber":55,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":56,"author":{"gitId":"nknguyenhc"},"content":" @Output() issueLengthChange: EventEmitter\u003cNumber\u003e \u003d new EventEmitter\u003cNumber\u003e();"},{"lineNumber":57,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":58,"author":{"gitId":"nknguyenhc"},"content":" constructor("},{"lineNumber":59,"author":{"gitId":"nknguyenhc"},"content":" public element: ElementRef,"},{"lineNumber":60,"author":{"gitId":"nknguyenhc"},"content":" public issueService: IssueService,"},{"lineNumber":61,"author":{"gitId":"nknguyenhc"},"content":" public groupingContextService: GroupingContextService,"},{"lineNumber":62,"author":{"gitId":"nknguyenhc"},"content":" private filtersService: FiltersService,"},{"lineNumber":63,"author":{"gitId":"nknguyenhc"},"content":" private milestoneService: MilestoneService"},{"lineNumber":64,"author":{"gitId":"nknguyenhc"},"content":" ) {}"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" ngOnInit() {"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":" this.issues \u003d new IssuesDataTable("},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":" this.issueService,"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":" this.groupingContextService,"},{"lineNumber":70,"author":{"gitId":"nknguyenhc"},"content":" this.filtersService,"},{"lineNumber":71,"author":{"gitId":"nknguyenhc"},"content":" this.milestoneService,"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" this.paginator,"},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" this.headers,"},{"lineNumber":74,"author":{"gitId":"NereusWB922"},"content":" this.group,"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":" this.filters"},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" );"},{"lineNumber":77,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":78,"author":{"gitId":"MadLamprey"},"content":" this.filterSubscription \u003d this.filtersService.filter$.subscribe((filter: any) \u003d\u003e {"},{"lineNumber":79,"author":{"gitId":"MadLamprey"},"content":" this.pageSize \u003d filter.itemsPerPage;"},{"lineNumber":80,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" ngAfterViewInit(): void {"},{"lineNumber":84,"author":{"gitId":"NereusWB922"},"content":" this.timeoutId \u003d setTimeout(() \u003d\u003e {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" this.issues.loadIssues();"},{"lineNumber":86,"author":{"gitId":"-"},"content":" this.issues$ \u003d this.issues.connect();"},{"lineNumber":87,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":88,"author":{"gitId":"Arif-Khalid"},"content":" // Emit event when issues change"},{"lineNumber":89,"author":{"gitId":"NereusWB922"},"content":" this.issuesLengthSubscription \u003d this.issues$.subscribe(() \u003d\u003e {"},{"lineNumber":90,"author":{"gitId":"nknguyenhc"},"content":" this.issueLength \u003d this.issues.count;"},{"lineNumber":91,"author":{"gitId":"nknguyenhc"},"content":" this.issueLengthChange.emit(this.issueLength);"},{"lineNumber":92,"author":{"gitId":"Arif-Khalid"},"content":" });"},{"lineNumber":93,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":94,"author":{"gitId":"Arif-Khalid"},"content":" // Emit event when loading state changes"},{"lineNumber":95,"author":{"gitId":"NereusWB922"},"content":" this.issuesLoadingStateSubscription \u003d this.issues.isLoading$.subscribe((isLoadingUpdate) \u003d\u003e {"},{"lineNumber":96,"author":{"gitId":"Arif-Khalid"},"content":" this.isLoading \u003d isLoadingUpdate;"},{"lineNumber":97,"author":{"gitId":"Arif-Khalid"},"content":" });"},{"lineNumber":98,"author":{"gitId":"-"},"content":" });"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"NereusWB922"},"content":" getHeaderTemplate(): TemplateRef\u003cany\u003e {"},{"lineNumber":102,"author":{"gitId":"NereusWB922"},"content":" switch (this.groupingContextService.currGroupBy) {"},{"lineNumber":103,"author":{"gitId":"NereusWB922"},"content":" case GroupBy.Assignee:"},{"lineNumber":104,"author":{"gitId":"NereusWB922"},"content":" return this.assigneeHeaderTemplate;"},{"lineNumber":105,"author":{"gitId":"NereusWB922"},"content":" case GroupBy.Milestone:"},{"lineNumber":106,"author":{"gitId":"NereusWB922"},"content":" return this.milestoneHeaderTemplate;"},{"lineNumber":107,"author":{"gitId":"NereusWB922"},"content":" default:"},{"lineNumber":108,"author":{"gitId":"NereusWB922"},"content":" return this.defaultHeaderTemplate;"},{"lineNumber":109,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":110,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":111,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" ngOnDestroy(): void {"},{"lineNumber":113,"author":{"gitId":"NereusWB922"},"content":" if (this.timeoutId) {"},{"lineNumber":114,"author":{"gitId":"NereusWB922"},"content":" clearTimeout(this.timeoutId);"},{"lineNumber":115,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":116,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":117,"author":{"gitId":"NereusWB922"},"content":" if (this.issues) {"},{"lineNumber":118,"author":{"gitId":"-"},"content":" this.issues.disconnect();"},{"lineNumber":119,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":120,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":121,"author":{"gitId":"NereusWB922"},"content":" if (this.issuesLengthSubscription) {"},{"lineNumber":122,"author":{"gitId":"NereusWB922"},"content":" this.issuesLengthSubscription.unsubscribe();"},{"lineNumber":123,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":124,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":125,"author":{"gitId":"NereusWB922"},"content":" if (this.issuesLoadingStateSubscription) {"},{"lineNumber":126,"author":{"gitId":"NereusWB922"},"content":" this.issuesLoadingStateSubscription.unsubscribe();"},{"lineNumber":127,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" retrieveFilterable(): FilterableSource {"},{"lineNumber":131,"author":{"gitId":"-"},"content":" return this.issues;"},{"lineNumber":132,"author":{"gitId":"-"},"content":" }"},{"lineNumber":133,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":17,"NereusWB922":59,"Arif-Khalid":10,"MadLamprey":5,"-":42}},{"path":"src/app/issues-viewer/hidden-groups/hidden-groups.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":".hidden-groups {"},{"lineNumber":2,"author":{"gitId":"nknguyenhc"},"content":" margin: 8px;"},{"lineNumber":3,"author":{"gitId":"nknguyenhc"},"content":" min-width: 150px;"},{"lineNumber":4,"author":{"gitId":"nknguyenhc"},"content":" max-width: 300px;"},{"lineNumber":5,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":6,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":7,"author":{"gitId":"nknguyenhc"},"content":".row-count {"},{"lineNumber":8,"author":{"gitId":"nknguyenhc"},"content":" background-color: rgb(222, 222, 222);"},{"lineNumber":9,"author":{"gitId":"nknguyenhc"},"content":" border-radius: 3px;"},{"lineNumber":10,"author":{"gitId":"nknguyenhc"},"content":" cursor: default;"},{"lineNumber":11,"author":{"gitId":"nknguyenhc"},"content":" padding: 6px;"},{"lineNumber":12,"author":{"gitId":"nknguyenhc"},"content":" color: rgb(0, 0, 0);"},{"lineNumber":13,"author":{"gitId":"nknguyenhc"},"content":" font-weight: 410;"},{"lineNumber":14,"author":{"gitId":"nknguyenhc"},"content":" display: inline-flex;"},{"lineNumber":15,"author":{"gitId":"nknguyenhc"},"content":" font-size: 14px;"},{"lineNumber":16,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":17,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":18,"author":{"gitId":"nknguyenhc"},"content":".mat-card-header {"},{"lineNumber":19,"author":{"gitId":"nknguyenhc"},"content":" display: flex;"},{"lineNumber":20,"author":{"gitId":"nknguyenhc"},"content":" flex-direction: row;"},{"lineNumber":21,"author":{"gitId":"nknguyenhc"},"content":" align-items: center;"},{"lineNumber":22,"author":{"gitId":"nknguyenhc"},"content":" width: 100%;"},{"lineNumber":23,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":24,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":25,"author":{"gitId":"nknguyenhc"},"content":".mat-card {"},{"lineNumber":26,"author":{"gitId":"nknguyenhc"},"content":" margin: 8px 0px;"},{"lineNumber":27,"author":{"gitId":"nknguyenhc"},"content":" height: 40px;"},{"lineNumber":28,"author":{"gitId":"nknguyenhc"},"content":" padding: 10px;"},{"lineNumber":29,"author":{"gitId":"nknguyenhc"},"content":" display: flex;"},{"lineNumber":30,"author":{"gitId":"nknguyenhc"},"content":" align-items: center;"},{"lineNumber":31,"author":{"gitId":"nknguyenhc"},"content":" justify-content: center;"},{"lineNumber":32,"author":{"gitId":"nknguyenhc"},"content":" flex-direction: row;"},{"lineNumber":33,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":34,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":35,"author":{"gitId":"nknguyenhc"},"content":".mat-card-title {"},{"lineNumber":36,"author":{"gitId":"nknguyenhc"},"content":" font-size: 14px;"},{"lineNumber":37,"author":{"gitId":"nknguyenhc"},"content":" text-align: center;"},{"lineNumber":38,"author":{"gitId":"nknguyenhc"},"content":" margin: 0;"},{"lineNumber":39,"author":{"gitId":"nknguyenhc"},"content":" flex-grow: 1;"},{"lineNumber":40,"author":{"gitId":"nknguyenhc"},"content":" margin: 2px;"},{"lineNumber":41,"author":{"gitId":"nknguyenhc"},"content":" word-break: break-word;"},{"lineNumber":42,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":43,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":44,"author":{"gitId":"nknguyenhc"},"content":".mat-card-avatar {"},{"lineNumber":45,"author":{"gitId":"nknguyenhc"},"content":" height: 30px;"},{"lineNumber":46,"author":{"gitId":"nknguyenhc"},"content":" width: 30px;"},{"lineNumber":47,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":48,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":49,"author":{"gitId":"nknguyenhc"},"content":".mat-card-header .mat-card-title {"},{"lineNumber":50,"author":{"gitId":"nknguyenhc"},"content":" font-size: 12px;"},{"lineNumber":51,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":52,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":53,"author":{"gitId":"nknguyenhc"},"content":".scrollable-container {"},{"lineNumber":54,"author":{"gitId":"nknguyenhc"},"content":" height: 67vh;"},{"lineNumber":55,"author":{"gitId":"nknguyenhc"},"content":" overflow: auto;"},{"lineNumber":56,"author":{"gitId":"nknguyenhc"},"content":" scrollbar-width: none;"},{"lineNumber":57,"author":{"gitId":"nknguyenhc"},"content":" -ms-overflow-style: none;"},{"lineNumber":58,"author":{"gitId":"nknguyenhc"},"content":" position: relative;"},{"lineNumber":59,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":60,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":61,"author":{"gitId":"nknguyenhc"},"content":".scrollable-containers::-webkit-scrollbar {"},{"lineNumber":62,"author":{"gitId":"nknguyenhc"},"content":" display: none;"},{"lineNumber":63,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":64,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":65,"author":{"gitId":"nknguyenhc"},"content":".scrollable-container::before,"},{"lineNumber":66,"author":{"gitId":"nknguyenhc"},"content":".scrollable-container::after {"},{"lineNumber":67,"author":{"gitId":"nknguyenhc"},"content":" pointer-events: none;"},{"lineNumber":68,"author":{"gitId":"nknguyenhc"},"content":" content: \u0027\u0027;"},{"lineNumber":69,"author":{"gitId":"nknguyenhc"},"content":" z-index: 2;"},{"lineNumber":70,"author":{"gitId":"nknguyenhc"},"content":" height: 6px;"},{"lineNumber":71,"author":{"gitId":"nknguyenhc"},"content":" width: 100%;"},{"lineNumber":72,"author":{"gitId":"nknguyenhc"},"content":" display: block;"},{"lineNumber":73,"author":{"gitId":"nknguyenhc"},"content":" background-image: linear-gradient(to bottom, white 66%, transparent);"},{"lineNumber":74,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":75,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":76,"author":{"gitId":"nknguyenhc"},"content":".scrollable-container::before {"},{"lineNumber":77,"author":{"gitId":"nknguyenhc"},"content":" position: absolute;"},{"lineNumber":78,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":79,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":80,"author":{"gitId":"nknguyenhc"},"content":".scrollable-container::after {"},{"lineNumber":81,"author":{"gitId":"nknguyenhc"},"content":" position: sticky;"},{"lineNumber":82,"author":{"gitId":"nknguyenhc"},"content":"}"}],"authorContributionMap":{"nknguyenhc":81,"NereusWB922":1}},{"path":"src/app/issues-viewer/hidden-groups/hidden-groups.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"\u003cdiv *ngIf\u003d\"groups.length \u003e 0\" class\u003d\"hidden-groups\"\u003e"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card matTooltip\u003d\"Users that have no Issues/PRs pertaining to the current filter\" matTooltipShowDelay\u003d\"0\" matTooltipHideDelay\u003d\"0\"\u003e"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card-title\u003eHidden {{ this.groupingContextService.currGroupBy }}s\u003c/mat-card-title\u003e"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv class\u003d\"row-count\"\u003e{{ groups.length }}\u003c/div\u003e"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card\u003e"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv class\u003d\"scrollable-container\"\u003e"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv *ngFor\u003d\"let group of groups\"\u003e"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" \u003cng-container [ngTemplateOutlet]\u003d\"getCardTemplate()\" [ngTemplateOutletContext]\u003d\"{ $implicit: group }\"\u003e\u003c/ng-container\u003e"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" \u003c/div\u003e"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" \u003c/div\u003e"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":"\u003c/div\u003e"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":"\u003c!-- Templates --\u003e"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"\u003cng-template #defaultCard let-group\u003e"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card class\u003d\"loading-spinner\"\u003e"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-progress-spinner color\u003d\"primary\" mode\u003d\"indeterminate\" diameter\u003d\"50\" strokeWidth\u003d\"5\"\u003e\u003c/mat-progress-spinner\u003e"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card\u003e"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":"\u003c/ng-template\u003e"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":"\u003cng-template #assigneeCard let-assignee\u003e"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card\u003e"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" \u003cmar-card-header class\u003d\"mat-card-header\"\u003e"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" mat-card-avatar"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" [ngStyle]\u003d\"{"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" background: \u0027url(\u0027 + assignee.avatar_url + \u0027)\u0027,"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" \u0027background-size\u0027: \u002730px\u0027"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" }\""},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" \u003e\u003c/div\u003e"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card-title\u003e{{ assignee.login }}\u003c/mat-card-title\u003e"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" \u003c/mar-card-header\u003e"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card\u003e"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":"\u003c/ng-template\u003e"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":"\u003cng-template #milestoneCard let-milestone\u003e"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card\u003e"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":" \u003cmar-card-header class\u003d\"mat-card-header\"\u003e"},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-card-title\u003e{{ milestone.title }}\u003c/mat-card-title\u003e"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" \u003c/mar-card-header\u003e"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-card\u003e"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":"\u003c/ng-template\u003e"}],"authorContributionMap":{"NereusWB922":41}},{"path":"src/app/issues-viewer/hidden-groups/hidden-groups.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Component, Input, TemplateRef, ViewChild } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { Group } from \u0027../../core/models/github/group.interface\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { GroupBy, GroupingContextService } from \u0027../../core/services/grouping/grouping-context.service\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"@Component({"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" selector: \u0027app-hidden-groups\u0027,"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" templateUrl: \u0027./hidden-groups.component.html\u0027,"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" styleUrls: [\u0027./hidden-groups.component.css\u0027]"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"})"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"export class HiddenGroupsComponent {"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" @Input() groups: Group[] \u003d [];"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" @ViewChild(\u0027defaultCard\u0027) defaultCardTemplate: TemplateRef\u003cany\u003e;"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" @ViewChild(\u0027assigneeCard\u0027) assigneeCardTemplate: TemplateRef\u003cany\u003e;"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" @ViewChild(\u0027milestoneCard\u0027) milestoneCardTemplate: TemplateRef\u003cany\u003e;"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" constructor(public groupingContextService: GroupingContextService) {}"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" getCardTemplate(): TemplateRef\u003cany\u003e {"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" switch (this.groupingContextService.currGroupBy) {"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" case GroupBy.Assignee:"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" return this.assigneeCardTemplate;"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" case GroupBy.Milestone:"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" return this.milestoneCardTemplate;"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" default:"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" return this.defaultCardTemplate;"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":29}},{"path":"src/app/issues-viewer/issues-viewer.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cdiv\u003e"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv class\u003d\"loading-spinner\" *ngIf\u003d\"(this.viewService.isChangingRepo | async) || this.groups.length \u003d\u003d\u003d 0; else elseBlock\"\u003e"},{"lineNumber":3,"author":{"gitId":"-"},"content":" \u003cmat-progress-spinner color\u003d\"primary\" mode\u003d\"indeterminate\" diameter\u003d\"50\" strokeWidth\u003d\"5\"\u003e \u003c/mat-progress-spinner\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003cng-template #elseBlock\u003e"},{"lineNumber":7,"author":{"gitId":"Arif-Khalid"},"content":" \u003capp-filter-bar [views$]\u003d\"views\"\u003e\u003c/app-filter-bar\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"wrapper\"\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003capp-card-view"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" *ngFor\u003d\"let group of groups\""},{"lineNumber":12,"author":{"gitId":"-"},"content":" class\u003d\"issue-table\""},{"lineNumber":13,"author":{"gitId":"Arif-Khalid"},"content":" #card"},{"lineNumber":14,"author":{"gitId":"Arif-Khalid"},"content":" [ngStyle]\u003d\"{ display: card.isLoading || card.issueLength \u003e 0 ? \u0027initial\u0027 : \u0027none\u0027 }\""},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" [group]\u003d\"group\""},{"lineNumber":16,"author":{"gitId":"-"},"content":" [headers]\u003d\"this.displayedColumns\""},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" (issueLengthChange)\u003d\"updateHiddenGroups($event, group)\""},{"lineNumber":18,"author":{"gitId":"-"},"content":" \u003e\u003c/app-card-view\u003e"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" \u003capp-hidden-groups [groups]\u003d\"this.hiddenGroups\"\u003e\u003c/app-hidden-groups\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003c/ng-template\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"NereusWB922":5,"Arif-Khalid":3,"-":14}},{"path":"src/app/issues-viewer/issues-viewer.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { AfterViewInit, Component, OnDestroy, OnInit, QueryList, ViewChildren } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { NavigationEnd, NavigationStart, Router } from \u0027@angular/router\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { BehaviorSubject, of, Subscription } from \u0027rxjs\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { filter } from \u0027rxjs/operators\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import { Group } from \u0027../core/models/github/group.interface\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { Repo } from \u0027../core/models/repo.model\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { ErrorMessageService } from \u0027../core/services/error-message.service\u0027;"},{"lineNumber":8,"author":{"gitId":"Arif-Khalid"},"content":"import { FiltersService } from \u0027../core/services/filters.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027../core/services/github.service\u0027;"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"import { GroupingContextService } from \u0027../core/services/grouping/grouping-context.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { IssueService } from \u0027../core/services/issue.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { LabelService } from \u0027../core/services/label.service\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { MilestoneService } from \u0027../core/services/milestone.service\u0027;"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"import { ViewService } from \u0027../core/services/view.service\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import { TABLE_COLUMNS } from \u0027../shared/issue-tables/issue-tables-columns\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import { CardViewComponent } from \u0027./card-view/card-view.component\u0027;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":19,"author":{"gitId":"-"},"content":" selector: \u0027app-issues-viewer\u0027,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" templateUrl: \u0027./issues-viewer.component.html\u0027,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./issues-viewer.component.css\u0027]"},{"lineNumber":22,"author":{"gitId":"-"},"content":"})"},{"lineNumber":23,"author":{"gitId":"-"},"content":"export class IssuesViewerComponent implements OnInit, AfterViewInit, OnDestroy {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" readonly displayedColumns \u003d [TABLE_COLUMNS.ID, TABLE_COLUMNS.TITLE, TABLE_COLUMNS.ASSIGNEE, TABLE_COLUMNS.LABEL];"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" /** Observes for any change in repo*/"},{"lineNumber":27,"author":{"gitId":"-"},"content":" repoChangeSubscription: Subscription;"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" groupByChangeSubscription: Subscription;"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" /** Observes for any change in the cardviews */"},{"lineNumber":32,"author":{"gitId":"-"},"content":" viewChange: Subscription;"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" popStateEventSubscription: Subscription;"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" availableGroupsSubscription: Subscription;"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" popStateNavigationId: number;"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" /** Users to show as columns */"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" groups: Group[] \u003d [];"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"nknguyenhc"},"content":" /** The list of users with 0 issues (hidden) */"},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" hiddenGroups: Group[] \u003d [];"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" @ViewChildren(CardViewComponent) cardViews: QueryList\u003cCardViewComponent\u003e;"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" views \u003d new BehaviorSubject\u003cQueryList\u003cCardViewComponent\u003e\u003e(undefined);"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" constructor("},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":" public viewService: ViewService,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" public githubService: GithubService,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" public issueService: IssueService,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" public labelService: LabelService,"},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" public milestoneService: MilestoneService,"},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" public groupingContextService: GroupingContextService,"},{"lineNumber":57,"author":{"gitId":"Arif-Khalid"},"content":" private router: Router,"},{"lineNumber":58,"author":{"gitId":"Arif-Khalid"},"content":" private filtersService: FiltersService"},{"lineNumber":59,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":" this.repoChangeSubscription \u003d this.viewService.repoChanged$.subscribe((newRepo) \u003d\u003e {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" this.issueService.reset(false);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" this.labelService.reset();"},{"lineNumber":63,"author":{"gitId":"-"},"content":" this.initialize();"},{"lineNumber":64,"author":{"gitId":"-"},"content":" });"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" this.groupByChangeSubscription \u003d this.groupingContextService.currGroupBy$.subscribe((newGroupBy) \u003d\u003e {"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":" this.initialize();"},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":" this.popStateEventSubscription \u003d this.router.events"},{"lineNumber":71,"author":{"gitId":"NereusWB922"},"content":" .pipe(filter((event) \u003d\u003e event instanceof NavigationEnd || event instanceof NavigationStart))"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" .subscribe((event) \u003d\u003e {"},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" if (event instanceof NavigationStart \u0026\u0026 event.navigationTrigger \u003d\u003d\u003d \u0027popstate\u0027) {"},{"lineNumber":74,"author":{"gitId":"NereusWB922"},"content":" this.popStateNavigationId \u003d event.id;"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" if (event instanceof NavigationEnd \u0026\u0026 event.id \u003d\u003d\u003d this.popStateNavigationId) {"},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":" this.viewService.initializeRepoFromUrlParams();"},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":" this.groupingContextService.initializeFromUrlParams();"},{"lineNumber":80,"author":{"gitId":"Arif-Khalid"},"content":" this.filtersService.initializeFromURLParams();"},{"lineNumber":81,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":82,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":83,"author":{"gitId":"-"},"content":" }"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" ngOnInit() {"},{"lineNumber":86,"author":{"gitId":"-"},"content":" this.initialize();"},{"lineNumber":87,"author":{"gitId":"NereusWB922"},"content":" this.groupingContextService.initializeFromUrlParams();"},{"lineNumber":88,"author":{"gitId":"Arif-Khalid"},"content":" this.filtersService.initializeFromURLParams();"},{"lineNumber":89,"author":{"gitId":"-"},"content":" }"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" ngAfterViewInit(): void {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" this.viewChange \u003d this.cardViews.changes.subscribe((x) \u003d\u003e this.views.next(x));"},{"lineNumber":93,"author":{"gitId":"-"},"content":" }"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" ngOnDestroy(): void {"},{"lineNumber":96,"author":{"gitId":"-"},"content":" this.repoChangeSubscription.unsubscribe();"},{"lineNumber":97,"author":{"gitId":"-"},"content":" this.viewChange.unsubscribe();"},{"lineNumber":98,"author":{"gitId":"NereusWB922"},"content":" this.popStateEventSubscription.unsubscribe();"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":102,"author":{"gitId":"-"},"content":" * Fetch and initialize all information from repository to populate Issue Dashboard."},{"lineNumber":103,"author":{"gitId":"-"},"content":" */"},{"lineNumber":104,"author":{"gitId":"-"},"content":" private initialize() {"},{"lineNumber":105,"author":{"gitId":"NereusWB922"},"content":" if (this.availableGroupsSubscription) {"},{"lineNumber":106,"author":{"gitId":"NereusWB922"},"content":" this.availableGroupsSubscription.unsubscribe();"},{"lineNumber":107,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" // Fetch assignees"},{"lineNumber":110,"author":{"gitId":"NereusWB922"},"content":" this.groups \u003d [];"},{"lineNumber":111,"author":{"gitId":"NereusWB922"},"content":" this.hiddenGroups \u003d [];"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"NereusWB922"},"content":" this.availableGroupsSubscription \u003d this.groupingContextService.getGroups().subscribe((x) \u003d\u003e (this.groups \u003d x));"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":117,"author":{"gitId":"NereusWB922"},"content":" * Checks if our current repository available on view service is indeed a valid repository"},{"lineNumber":118,"author":{"gitId":"-"},"content":" */"},{"lineNumber":119,"author":{"gitId":"-"},"content":" private checkIfValidRepository() {"},{"lineNumber":120,"author":{"gitId":"NereusWB922"},"content":" const currentRepo \u003d this.viewService.currentRepo;"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" if (Repo.isInvalidRepoName(currentRepo)) {"},{"lineNumber":123,"author":{"gitId":"-"},"content":" return of(false);"},{"lineNumber":124,"author":{"gitId":"-"},"content":" }"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" return this.githubService.isRepositoryPresent(currentRepo.owner, currentRepo.name);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":129,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":130,"author":{"gitId":"NereusWB922"},"content":" * Update the list of hidden group based on the new info."},{"lineNumber":131,"author":{"gitId":"NereusWB922"},"content":" * @param issueLength The number of issues under this group."},{"lineNumber":132,"author":{"gitId":"NereusWB922"},"content":" * @param group The group."},{"lineNumber":133,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":134,"author":{"gitId":"NereusWB922"},"content":" updateHiddenGroups(issueLength: number, target: Group) {"},{"lineNumber":135,"author":{"gitId":"NereusWB922"},"content":" if (issueLength \u003d\u003d\u003d 0 \u0026\u0026 this.groupingContextService.isInHiddenList(target)) {"},{"lineNumber":136,"author":{"gitId":"NereusWB922"},"content":" this.addToHiddenGroups(target);"},{"lineNumber":137,"author":{"gitId":"nknguyenhc"},"content":" } else {"},{"lineNumber":138,"author":{"gitId":"NereusWB922"},"content":" this.removeFromHiddenGroups(target);"},{"lineNumber":139,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":140,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":141,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":142,"author":{"gitId":"NereusWB922"},"content":" private addToHiddenGroups(target: Group) {"},{"lineNumber":143,"author":{"gitId":"NereusWB922"},"content":" const isGroupPresent \u003d this.hiddenGroups.some((group) \u003d\u003e group.equals(target));"},{"lineNumber":144,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":145,"author":{"gitId":"NereusWB922"},"content":" if (!isGroupPresent) {"},{"lineNumber":146,"author":{"gitId":"NereusWB922"},"content":" this.hiddenGroups.push(target);"},{"lineNumber":147,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":148,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":149,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":150,"author":{"gitId":"NereusWB922"},"content":" private removeFromHiddenGroups(target: Group) {"},{"lineNumber":151,"author":{"gitId":"NereusWB922"},"content":" this.hiddenGroups \u003d this.hiddenGroups.filter((group) \u003d\u003e !group.equals(target));"},{"lineNumber":152,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":153,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":12,"NereusWB922":61,"Arif-Khalid":5,"-":75}},{"path":"src/app/issues-viewer/issues-viewer.module.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { NgModule } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { FilterBarModule } from \u0027../shared/filter-bar/filter-bar.module\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { IssuesPrCardModule } from \u0027../shared/issue-pr-card/issue-pr-card.module\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { SharedModule } from \u0027../shared/shared.module\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { CardViewComponent } from \u0027./card-view/card-view.component\u0027;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"import { HiddenGroupsComponent } from \u0027./hidden-groups/hidden-groups.component\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { IssuesViewerRoutingModule } from \u0027./issues-viewer-routing.module\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { IssuesViewerComponent } from \u0027./issues-viewer.component\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"@NgModule({"},{"lineNumber":11,"author":{"gitId":"-"},"content":" imports: [FilterBarModule, IssuesViewerRoutingModule, IssuesPrCardModule, SharedModule],"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" declarations: [IssuesViewerComponent, CardViewComponent, HiddenGroupsComponent],"},{"lineNumber":13,"author":{"gitId":"-"},"content":" exports: [IssuesViewerComponent, CardViewComponent]"},{"lineNumber":14,"author":{"gitId":"-"},"content":"})"},{"lineNumber":15,"author":{"gitId":"-"},"content":"export class IssuesViewerModule {}"}],"authorContributionMap":{"NereusWB922":2,"-":13}},{"path":"src/app/shared/filter-bar/filter-bar.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":".dropdown-filters .mat-form-field {"},{"lineNumber":2,"author":{"gitId":"-"},"content":" margin: 8px;"},{"lineNumber":3,"author":{"gitId":"-"},"content":" font-size: 14px;"},{"lineNumber":4,"author":{"gitId":"-"},"content":" max-width: 20%;"},{"lineNumber":5,"author":{"gitId":"MadLamprey"},"content":" width: 14%; /* depends on number of filters*/"},{"lineNumber":6,"author":{"gitId":"-"},"content":"}"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":".search-bar {"},{"lineNumber":9,"author":{"gitId":"MadLamprey"},"content":" width: 80%;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"}"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":".dropdown-filters {"},{"lineNumber":13,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"}"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":".label-filter-grid-tile {"},{"lineNumber":17,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"}"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":".submit-button {"},{"lineNumber":21,"author":{"gitId":"-"},"content":" margin-left: 8px;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"MadLamprey":2,"-":20}},{"path":"src/app/shared/filter-bar/filter-bar.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cmat-grid-list cols\u003d\"7\" rowHeight\u003d\"80px\"\u003e"},{"lineNumber":2,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-grid-tile colspan\u003d\"2\"\u003e"},{"lineNumber":3,"author":{"gitId":"-"},"content":" \u003cmat-form-field class\u003d\"search-bar\"\u003e"},{"lineNumber":4,"author":{"gitId":"Arif-Khalid"},"content":" \u003cinput"},{"lineNumber":5,"author":{"gitId":"Arif-Khalid"},"content":" matInput"},{"lineNumber":6,"author":{"gitId":"Arif-Khalid"},"content":" value\u003d\"{{ this.filtersService.filter$.value.title }}\""},{"lineNumber":7,"author":{"gitId":"Arif-Khalid"},"content":" (keyup)\u003d\"this.filtersService.updateFilters({ title: $event.target.value })\""},{"lineNumber":8,"author":{"gitId":"Arif-Khalid"},"content":" placeholder\u003d\"Search\""},{"lineNumber":9,"author":{"gitId":"Arif-Khalid"},"content":" /\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003c/mat-grid-tile\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-grid-tile colspan\u003d\"4\"\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"dropdown-filters\"\u003e"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-form-field appearance\u003d\"standard\"\u003e"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-label\u003eGroup by\u003c/mat-label\u003e"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-select"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" [value]\u003d\"this.groupingContextService.currGroupBy$ | async\""},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" (selectionChange)\u003d\"this.groupingContextService.setCurrentGroupingType($event.value)\""},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" \u003e"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-option *ngFor\u003d\"let option of this.groupByEnum | keyvalue\" [value]\u003d\"option.value\"\u003e{{ option.key }}\u003c/mat-option\u003e"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-select\u003e"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":" \u003cmat-form-field appearance\u003d\"standard\"\u003e"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u003cmat-label\u003eStatus\u003c/mat-label\u003e"},{"lineNumber":26,"author":{"gitId":"nknguyenhc"},"content":" \u003cmat-select [value]\u003d\"this.filter.status\" (selectionChange)\u003d\"this.filtersService.updateFilters({ status: $event.value })\" multiple\u003e"},{"lineNumber":27,"author":{"gitId":"nknguyenhc"},"content":" \u003cmat-option *ngIf\u003d\"isFilterPullRequest()\" value\u003d\"open pullrequest\"\u003eOpen Pull Requests\u003c/mat-option\u003e"},{"lineNumber":28,"author":{"gitId":"nknguyenhc"},"content":" \u003cmat-option *ngIf\u003d\"isFilterPullRequest()\" value\u003d\"merged pullrequest\"\u003eMerged Pull Requests\u003c/mat-option\u003e"},{"lineNumber":29,"author":{"gitId":"nknguyenhc"},"content":" \u003cmat-option *ngIf\u003d\"isFilterPullRequest()\" value\u003d\"closed pullrequest\"\u003eClosed Pull Request\u003c/mat-option\u003e"},{"lineNumber":30,"author":{"gitId":"nknguyenhc"},"content":" \u003cmat-option *ngIf\u003d\"isFilterIssue()\" value\u003d\"open issue\"\u003eOpen Issues\u003c/mat-option\u003e"},{"lineNumber":31,"author":{"gitId":"nknguyenhc"},"content":" \u003cmat-option *ngIf\u003d\"isFilterIssue()\" value\u003d\"closed issue\"\u003eClosed Issues\u003c/mat-option\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003c/mat-select\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003cmat-form-field appearance\u003d\"standard\"\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":" \u003cmat-label\u003eType\u003c/mat-label\u003e"},{"lineNumber":36,"author":{"gitId":"Arif-Khalid"},"content":" \u003cmat-select [value]\u003d\"this.filter.type\" (selectionChange)\u003d\"this.filtersService.updateFilters({ type: $event.value })\"\u003e"},{"lineNumber":37,"author":{"gitId":"-"},"content":" \u003cmat-option value\u003d\"all\"\u003eAll\u003c/mat-option\u003e"},{"lineNumber":38,"author":{"gitId":"-"},"content":" \u003cmat-option value\u003d\"issue\"\u003eIssue\u003c/mat-option\u003e"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003cmat-option value\u003d\"pullrequest\"\u003ePull Request\u003c/mat-option\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003c/mat-select\u003e"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":42,"author":{"gitId":"Arif-Khalid"},"content":" \u003cmat-form-field"},{"lineNumber":43,"author":{"gitId":"Arif-Khalid"},"content":" appearance\u003d\"standard\""},{"lineNumber":44,"author":{"gitId":"Arif-Khalid"},"content":" matSort"},{"lineNumber":45,"author":{"gitId":"Arif-Khalid"},"content":" [matSortDisableClear]\u003d\"true\""},{"lineNumber":46,"author":{"gitId":"Arif-Khalid"},"content":" (matSortChange)\u003d\"this.filtersService.updateFilters({ sort: $event })\""},{"lineNumber":47,"author":{"gitId":"Arif-Khalid"},"content":" \u003e"},{"lineNumber":48,"author":{"gitId":"-"},"content":" \u003cmat-label\u003eSort\u003c/mat-label\u003e"},{"lineNumber":49,"author":{"gitId":"Arif-Khalid"},"content":" \u003cmat-select [value]\u003d\"this.filter.sort.active\"\u003e"},{"lineNumber":50,"author":{"gitId":"-"},"content":" \u003cmat-option value\u003d\"id\"\u003e"},{"lineNumber":51,"author":{"gitId":"-"},"content":" \u003cspan mat-sort-header\u003d\"id\"\u003eID\u003c/span\u003e"},{"lineNumber":52,"author":{"gitId":"-"},"content":" \u003c/mat-option\u003e"},{"lineNumber":53,"author":{"gitId":"-"},"content":" \u003cmat-option value\u003d\"title\"\u003e"},{"lineNumber":54,"author":{"gitId":"-"},"content":" \u003cspan mat-sort-header\u003d\"title\"\u003eTitle\u003c/span\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":" \u003c/mat-option\u003e"},{"lineNumber":56,"author":{"gitId":"-"},"content":" \u003cmat-option value\u003d\"date\"\u003e"},{"lineNumber":57,"author":{"gitId":"-"},"content":" \u003cspan mat-sort-header\u003d\"date\"\u003eDate Updated\u003c/span\u003e"},{"lineNumber":58,"author":{"gitId":"-"},"content":" \u003c/mat-option\u003e"},{"lineNumber":59,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-option value\u003d\"status\"\u003e"},{"lineNumber":60,"author":{"gitId":"MadLamprey"},"content":" \u003cspan mat-sort-header\u003d\"status\"\u003eStatus\u003c/span\u003e"},{"lineNumber":61,"author":{"gitId":"MadLamprey"},"content":" \u003c/mat-option\u003e"},{"lineNumber":62,"author":{"gitId":"-"},"content":" \u003c/mat-select\u003e"},{"lineNumber":63,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":64,"author":{"gitId":"-"},"content":" \u003cmat-form-field appearance\u003d\"standard\"\u003e"},{"lineNumber":65,"author":{"gitId":"-"},"content":" \u003cmat-label\u003eMilestone\u003c/mat-label\u003e"},{"lineNumber":66,"author":{"gitId":"-"},"content":" \u003cmat-select"},{"lineNumber":67,"author":{"gitId":"-"},"content":" #milestoneSelectorRef"},{"lineNumber":68,"author":{"gitId":"Arif-Khalid"},"content":" [value]\u003d\"this.filter.milestones\""},{"lineNumber":69,"author":{"gitId":"Arif-Khalid"},"content":" (selectionChange)\u003d\"this.filtersService.updateFilters({ milestones: $event.value })\""},{"lineNumber":70,"author":{"gitId":"-"},"content":" [disabled]\u003d\"this.milestoneService.hasNoMilestones\""},{"lineNumber":71,"author":{"gitId":"-"},"content":" multiple"},{"lineNumber":72,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":73,"author":{"gitId":"-"},"content":" \u003cmat-select-trigger *ngIf\u003d\"this.milestoneService.hasNoMilestones\"\u003e"},{"lineNumber":74,"author":{"gitId":"-"},"content":" \u003cspan\u003eNo Milestones\u003c/span\u003e"},{"lineNumber":75,"author":{"gitId":"-"},"content":" \u003c/mat-select-trigger\u003e"},{"lineNumber":76,"author":{"gitId":"Arif-Khalid"},"content":" \u003cmat-option *ngFor\u003d\"let milestone of this.milestoneService.milestones\" [value]\u003d\"milestone.title\"\u003e"},{"lineNumber":77,"author":{"gitId":"-"},"content":" {{ milestone.title }}"},{"lineNumber":78,"author":{"gitId":"-"},"content":" \u003c/mat-option\u003e"},{"lineNumber":79,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-option *ngIf\u003d\"isFilterIssue()\" [value]\u003d\"\u0027Issue without a milestone\u0027\"\u003eIssues without a milestone\u003c/mat-option\u003e"},{"lineNumber":80,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-option *ngIf\u003d\"isFilterPullRequest()\" [value]\u003d\"\u0027PR without a milestone\u0027\"\u003ePRs without a milestone\u003c/mat-option\u003e"},{"lineNumber":81,"author":{"gitId":"-"},"content":" \u003c/mat-select\u003e"},{"lineNumber":82,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":83,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-form-field appearance\u003d\"standard\"\u003e"},{"lineNumber":84,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-label\u003eItems per page\u003c/mat-label\u003e"},{"lineNumber":85,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-select"},{"lineNumber":86,"author":{"gitId":"MadLamprey"},"content":" [value]\u003d\"this.filter.itemsPerPage\""},{"lineNumber":87,"author":{"gitId":"MadLamprey"},"content":" (selectionChange)\u003d\"this.filtersService.updateFilters({ itemsPerPage: $event.value })\""},{"lineNumber":88,"author":{"gitId":"MadLamprey"},"content":" \u003e"},{"lineNumber":89,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-option [value]\u003d\"10\"\u003e10\u003c/mat-option\u003e"},{"lineNumber":90,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-option [value]\u003d\"20\"\u003e20\u003c/mat-option\u003e"},{"lineNumber":91,"author":{"gitId":"MadLamprey"},"content":" \u003cmat-option [value]\u003d\"50\"\u003e50\u003c/mat-option\u003e"},{"lineNumber":92,"author":{"gitId":"-"},"content":" \u003c/mat-select\u003e"},{"lineNumber":93,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":94,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":95,"author":{"gitId":"-"},"content":" \u003c/mat-grid-tile\u003e"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" \u003cmat-grid-tile class\u003d\"label-filter-grid-tile\" colspan\u003d\"1\"\u003e"},{"lineNumber":98,"author":{"gitId":"Arif-Khalid"},"content":" \u003capp-label-filter-bar\u003e\u003c/app-label-filter-bar\u003e"},{"lineNumber":99,"author":{"gitId":"-"},"content":" \u003c/mat-grid-tile\u003e"},{"lineNumber":100,"author":{"gitId":"-"},"content":"\u003c/mat-grid-list\u003e"}],"authorContributionMap":{"nknguyenhc":6,"Arif-Khalid":18,"NereusWB922":9,"MadLamprey":16,"-":51}},{"path":"src/app/shared/filter-bar/filter-bar.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { AfterViewInit, Component, Input, OnDestroy, OnInit, QueryList, ViewChild } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { MatSelect } from \u0027@angular/material/select\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { BehaviorSubject, Subscription } from \u0027rxjs\u0027;"},{"lineNumber":4,"author":{"gitId":"nknguyenhc"},"content":"import { Filter, FiltersService } from \u0027../../core/services/filters.service\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import { GroupBy, GroupingContextService } from \u0027../../core/services/grouping/grouping-context.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027../../core/services/logging.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { MilestoneService } from \u0027../../core/services/milestone.service\u0027;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"import { ViewService } from \u0027../../core/services/view.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { FilterableComponent } from \u0027../issue-tables/filterableTypes\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { LabelFilterBarComponent } from \u0027./label-filter-bar/label-filter-bar.component\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * This component is abstracted out filterbar used by both detailed-viewer page"},{"lineNumber":14,"author":{"gitId":"-"},"content":" * and Issues-viewer"},{"lineNumber":15,"author":{"gitId":"-"},"content":" */"},{"lineNumber":16,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":17,"author":{"gitId":"-"},"content":" selector: \u0027app-filter-bar\u0027,"},{"lineNumber":18,"author":{"gitId":"-"},"content":" templateUrl: \u0027./filter-bar.component.html\u0027,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./filter-bar.component.css\u0027]"},{"lineNumber":20,"author":{"gitId":"-"},"content":"})"},{"lineNumber":21,"author":{"gitId":"Arif-Khalid"},"content":"export class FilterBarComponent implements OnInit, OnDestroy {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Input() views$: BehaviorSubject\u003cQueryList\u003cFilterableComponent\u003e\u003e;"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" repoChangeSubscription: Subscription;"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" /** Selected dropdown filter value */"},{"lineNumber":27,"author":{"gitId":"Arif-Khalid"},"content":" filter: Filter \u003d this.filtersService.defaultFilter;"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" groupByEnum: typeof GroupBy \u003d GroupBy;"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" /** Milestone subscription */"},{"lineNumber":32,"author":{"gitId":"-"},"content":" milestoneSubscription: Subscription;"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" @ViewChild(LabelFilterBarComponent, { static: true }) labelFilterBar: LabelFilterBarComponent;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" @ViewChild(\u0027milestoneSelectorRef\u0027, { static: false }) milestoneSelectorRef: MatSelect;"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"Arif-Khalid"},"content":" constructor("},{"lineNumber":39,"author":{"gitId":"Arif-Khalid"},"content":" public milestoneService: MilestoneService,"},{"lineNumber":40,"author":{"gitId":"Arif-Khalid"},"content":" public filtersService: FiltersService,"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" private viewService: ViewService,"},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":" public groupingContextService: GroupingContextService,"},{"lineNumber":43,"author":{"gitId":"Arif-Khalid"},"content":" private logger: LoggingService"},{"lineNumber":44,"author":{"gitId":"Arif-Khalid"},"content":" ) {"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" this.repoChangeSubscription \u003d this.viewService.repoChanged$.subscribe((newRepo) \u003d\u003e this.newRepoInitialize());"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" ngOnInit() {"},{"lineNumber":49,"author":{"gitId":"Arif-Khalid"},"content":" this.newRepoInitialize();"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"Arif-Khalid"},"content":" // One-time initializations"},{"lineNumber":52,"author":{"gitId":"Arif-Khalid"},"content":" this.filtersService.filter$.subscribe((filter) \u003d\u003e {"},{"lineNumber":53,"author":{"gitId":"Arif-Khalid"},"content":" this.filter \u003d filter;"},{"lineNumber":54,"author":{"gitId":"Arif-Khalid"},"content":" this.applyFilter();"},{"lineNumber":55,"author":{"gitId":"-"},"content":" });"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"Arif-Khalid"},"content":" this.views$.subscribe(() \u003d\u003e this.applyFilter());"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" ngOnDestroy(): void {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" this.milestoneSubscription.unsubscribe();"},{"lineNumber":62,"author":{"gitId":"-"},"content":" this.repoChangeSubscription.unsubscribe();"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":66,"author":{"gitId":"-"},"content":" * Signals to IssuesDataTable that a change has occurred in filter."},{"lineNumber":67,"author":{"gitId":"-"},"content":" */"},{"lineNumber":68,"author":{"gitId":"Arif-Khalid"},"content":" applyFilter() {"},{"lineNumber":69,"author":{"gitId":"Arif-Khalid"},"content":" this.views$?.value?.forEach((v) \u003d\u003e (v.retrieveFilterable().filter \u003d this.filter));"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":73,"author":{"gitId":"-"},"content":" * Checks if program is filtering by type issue."},{"lineNumber":74,"author":{"gitId":"-"},"content":" */"},{"lineNumber":75,"author":{"gitId":"nknguyenhc"},"content":" isFilterIssue() {"},{"lineNumber":76,"author":{"gitId":"nknguyenhc"},"content":" return this.filter.type \u003d\u003d\u003d \u0027issue\u0027 || this.filter.type \u003d\u003d\u003d \u0027all\u0027;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"nknguyenhc"},"content":" isFilterPullRequest() {"},{"lineNumber":80,"author":{"gitId":"nknguyenhc"},"content":" return this.filter.type \u003d\u003d\u003d \u0027pullrequest\u0027 || this.filter.type \u003d\u003d\u003d \u0027all\u0027;"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":84,"author":{"gitId":"-"},"content":" * Fetch and initialize all information from repository to populate Issue Dashboard."},{"lineNumber":85,"author":{"gitId":"Arif-Khalid"},"content":" * Re-called when repo has changed"},{"lineNumber":86,"author":{"gitId":"-"},"content":" */"},{"lineNumber":87,"author":{"gitId":"Arif-Khalid"},"content":" private newRepoInitialize() {"},{"lineNumber":88,"author":{"gitId":"-"},"content":" // Fetch milestones and update dropdown filter"},{"lineNumber":89,"author":{"gitId":"-"},"content":" this.milestoneSubscription \u003d this.milestoneService.fetchMilestones().subscribe("},{"lineNumber":90,"author":{"gitId":"-"},"content":" (response) \u003d\u003e {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" this.logger.debug(\u0027IssuesViewerComponent: Fetched milestones from Github\u0027);"},{"lineNumber":92,"author":{"gitId":"Arif-Khalid"},"content":" this.filtersService.sanitizeMilestones(this.milestoneService.milestones);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" },"},{"lineNumber":94,"author":{"gitId":"-"},"content":" (err) \u003d\u003e {},"},{"lineNumber":95,"author":{"gitId":"-"},"content":" () \u003d\u003e {}"},{"lineNumber":96,"author":{"gitId":"-"},"content":" );"},{"lineNumber":97,"author":{"gitId":"-"},"content":" }"},{"lineNumber":98,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":5,"NereusWB922":6,"Arif-Khalid":18,"-":69}},{"path":"src/app/shared/filter-bar/label-filter-bar/label-filter-bar.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"::ng-deep.mat-menu-content:not(:empty) {"},{"lineNumber":2,"author":{"gitId":"-"},"content":" /* Override mat-menu-content\u0027s non-empty default CSS. */"},{"lineNumber":3,"author":{"gitId":"-"},"content":" padding-top: 0px !important;"},{"lineNumber":4,"author":{"gitId":"-"},"content":" padding-bottom: 0px !important;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"}"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"::ng-deep.mat-menu-panel {"},{"lineNumber":8,"author":{"gitId":"-"},"content":" /* Override mat-menu-panel\u0027s default CSS. */"},{"lineNumber":9,"author":{"gitId":"-"},"content":" width: 280px;"},{"lineNumber":10,"author":{"gitId":"-"},"content":" max-width: none !important;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"}"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":".popup-container {"},{"lineNumber":14,"author":{"gitId":"-"},"content":" flex-direction: column;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"}"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":".popupmenu {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" width: max-content;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"}"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":".scroll-container {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" max-height: 400px;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" overflow-y: auto;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" position: relative;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" -ms-overflow-style: none; /* IE and Edge */"},{"lineNumber":27,"author":{"gitId":"-"},"content":" scrollbar-width: none; /* Firefox */"},{"lineNumber":28,"author":{"gitId":"-"},"content":"}"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":"/* Ref: https://css-scroll-shadows.vercel.app */"},{"lineNumber":31,"author":{"gitId":"-"},"content":".scroll-container::before {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" pointer-events: none;"},{"lineNumber":33,"author":{"gitId":"-"},"content":" content: \u0027\u0027;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" position: absolute;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" z-index: 2;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" height: 7px;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" display: block;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" background-image: linear-gradient(to bottom, white 66%, transparent);"},{"lineNumber":40,"author":{"gitId":"-"},"content":"}"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":".scroll-container::after {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" pointer-events: none;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" content: \u0027\u0027;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" position: sticky;"},{"lineNumber":46,"author":{"gitId":"-"},"content":" z-index: 2;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" top: 100%;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" height: 7px;"},{"lineNumber":49,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":50,"author":{"gitId":"-"},"content":" display: block;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" background-image: linear-gradient(to top, white 66%, transparent);"},{"lineNumber":52,"author":{"gitId":"-"},"content":"}"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":".scroll-container-wrapper {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" position: relative;"},{"lineNumber":56,"author":{"gitId":"-"},"content":"}"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":".scroll-container-wrapper::before {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" pointer-events: none;"},{"lineNumber":60,"author":{"gitId":"-"},"content":" content: \u0027\u0027;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" position: absolute;"},{"lineNumber":62,"author":{"gitId":"-"},"content":" z-index: 1;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" top: 0;"},{"lineNumber":64,"author":{"gitId":"-"},"content":" left: 0;"},{"lineNumber":65,"author":{"gitId":"-"},"content":" right: 0;"},{"lineNumber":66,"author":{"gitId":"-"},"content":" height: 5px;"},{"lineNumber":67,"author":{"gitId":"-"},"content":" background-image: radial-gradient(farthest-side at 50% 0, rgba(0, 0, 0, 0.7), transparent);"},{"lineNumber":68,"author":{"gitId":"-"},"content":"}"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":".scroll-container-wrapper::after {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" pointer-events: none;"},{"lineNumber":72,"author":{"gitId":"-"},"content":" content: \u0027\u0027;"},{"lineNumber":73,"author":{"gitId":"-"},"content":" position: absolute;"},{"lineNumber":74,"author":{"gitId":"-"},"content":" z-index: 1;"},{"lineNumber":75,"author":{"gitId":"-"},"content":" bottom: 0;"},{"lineNumber":76,"author":{"gitId":"-"},"content":" left: 0;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" right: 0;"},{"lineNumber":78,"author":{"gitId":"-"},"content":" height: 5px;"},{"lineNumber":79,"author":{"gitId":"-"},"content":" background-image: radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, 0.7), transparent);"},{"lineNumber":80,"author":{"gitId":"-"},"content":"}"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":".scroll-container::-webkit-scrollbar {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" display: none; /* Hide scrollbar for Chrome, Safari and Opera */"},{"lineNumber":84,"author":{"gitId":"-"},"content":"}"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":".flexbox-container {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" display: flex;"},{"lineNumber":88,"author":{"gitId":"-"},"content":" flex-direction: row;"},{"lineNumber":89,"author":{"gitId":"-"},"content":" justify-content: flex-start;"},{"lineNumber":90,"author":{"gitId":"-"},"content":" align-items: center;"},{"lineNumber":91,"author":{"gitId":"nknguyenhc"},"content":" border-radius: 10px;"},{"lineNumber":92,"author":{"gitId":"nknguyenhc"},"content":" height: 40px;"},{"lineNumber":93,"author":{"gitId":"nknguyenhc"},"content":" padding: 0px 12px;"},{"lineNumber":94,"author":{"gitId":"nknguyenhc"},"content":" margin: 8px 4px;"},{"lineNumber":95,"author":{"gitId":"nknguyenhc"},"content":" box-sizing: border-box;"},{"lineNumber":96,"author":{"gitId":"nknguyenhc"},"content":" position: relative;"},{"lineNumber":97,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":98,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":99,"author":{"gitId":"nknguyenhc"},"content":".flexbox-container:hover {"},{"lineNumber":100,"author":{"gitId":"nknguyenhc"},"content":" background-color: rgba(0, 0, 0, 0.04);"},{"lineNumber":101,"author":{"gitId":"nknguyenhc"},"content":"}"},{"lineNumber":102,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":103,"author":{"gitId":"nknguyenhc"},"content":".flexbox-container-strikethrough {"},{"lineNumber":104,"author":{"gitId":"nknguyenhc"},"content":" position: absolute;"},{"lineNumber":105,"author":{"gitId":"nknguyenhc"},"content":" top: 50%;"},{"lineNumber":106,"author":{"gitId":"nknguyenhc"},"content":" width: 90%;"},{"lineNumber":107,"author":{"gitId":"nknguyenhc"},"content":" left: 50%;"},{"lineNumber":108,"author":{"gitId":"nknguyenhc"},"content":" transform: translate(-50%, -50%);"},{"lineNumber":109,"author":{"gitId":"nknguyenhc"},"content":" height: 2px;"},{"lineNumber":110,"author":{"gitId":"nknguyenhc"},"content":" background-color: black;"},{"lineNumber":111,"author":{"gitId":"-"},"content":"}"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":".input-field {"},{"lineNumber":114,"author":{"gitId":"-"},"content":" width: calc(100% - (2 * 15px)); /* To account for left and right padding. */"},{"lineNumber":115,"author":{"gitId":"-"},"content":" padding: 0 15px;"},{"lineNumber":116,"author":{"gitId":"-"},"content":"}"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":".mat-chip {"},{"lineNumber":119,"author":{"gitId":"-"},"content":" height: auto;"},{"lineNumber":120,"author":{"gitId":"-"},"content":" padding: 5.5px 7px;"},{"lineNumber":121,"author":{"gitId":"-"},"content":" line-height: 1.1em;"},{"lineNumber":122,"author":{"gitId":"-"},"content":" position: inherit;"},{"lineNumber":123,"author":{"gitId":"-"},"content":" border-radius: 6px;"},{"lineNumber":124,"author":{"gitId":"-"},"content":" font-size: 12px;"},{"lineNumber":125,"author":{"gitId":"-"},"content":" min-height: 16px;"},{"lineNumber":126,"author":{"gitId":"-"},"content":" max-height: 42px;"},{"lineNumber":127,"author":{"gitId":"-"},"content":" margin: 0px;"},{"lineNumber":128,"author":{"gitId":"-"},"content":"}"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":".mat-stroked-button {"},{"lineNumber":131,"author":{"gitId":"-"},"content":" font-weight: normal;"},{"lineNumber":132,"author":{"gitId":"-"},"content":"}"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":".hidden {"},{"lineNumber":135,"author":{"gitId":"-"},"content":" display: none !important;"},{"lineNumber":136,"author":{"gitId":"-"},"content":"}"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":"mat-list-option {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" width: max-content;"},{"lineNumber":140,"author":{"gitId":"-"},"content":"}"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":".no-labels {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" /* Chosen to look similar to button above. */"},{"lineNumber":144,"author":{"gitId":"-"},"content":" padding: 0 16px;"},{"lineNumber":145,"author":{"gitId":"-"},"content":" font-size: 14px;"},{"lineNumber":146,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":20,"-":126}},{"path":"src/app/shared/filter-bar/label-filter-bar/label-filter-bar.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cbutton mat-stroked-button *ngIf\u003d\"loaded\" [matMenuTriggerFor]\u003d\"menu\"\u003e"},{"lineNumber":2,"author":{"gitId":"nknguyenhc"},"content":" {{ selectedLabelNames.size \u003d\u003d\u003d 0 ? \u0027All\u0027 : selectedLabelNames.size }} Selected | {{ hiddenLabelNames?.size || 0 }} Hidden ▾"},{"lineNumber":3,"author":{"gitId":"-"},"content":"\u003c/button\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"\u003cbutton mat-stroked-button disabled *ngIf\u003d\"!loaded\" color\u003d\"accent\"\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003cmat-progress-bar mode\u003d\"query\"\u003e\u003c/mat-progress-bar\u003e"},{"lineNumber":7,"author":{"gitId":"-"},"content":"\u003c/button\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"\u003cmat-menu #menu\u003d\"matMenu\" class\u003d\"popupmenu\"\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003cdiv (click)\u003d\"$event.stopPropagation()\" class\u003d\"popup-container\"\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003cmat-form-field appearance\u003d\"standard\" class\u003d\"input-field\"\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003cmat-label\u003eLabels\u003c/mat-label\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003cinput #input matInput placeholder\u003d\"Find labels\" /\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":" \u003cbutton mat-button (click)\u003d\"removeAllSelection()\"\u003eRemove all\u003c/button\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"!hasLabels(input.value)\" class\u003d\"no-labels\"\u003eNo Labels Found!\u003c/div\u003e"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"scroll-container-wrapper\"\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"scroll-container\"\u003e"},{"lineNumber":22,"author":{"gitId":"nknguyenhc"},"content":" \u003cdiv"},{"lineNumber":23,"author":{"gitId":"nknguyenhc"},"content":" *ngFor\u003d\"let label of this.allLabels\""},{"lineNumber":24,"author":{"gitId":"nknguyenhc"},"content":" class\u003d\"flexbox-container\""},{"lineNumber":25,"author":{"gitId":"nknguyenhc"},"content":" (click)\u003d\"changeLabelState(label)\""},{"lineNumber":26,"author":{"gitId":"-"},"content":" [class.hidden]\u003d\"filter(input.value, label.name)\""},{"lineNumber":27,"author":{"gitId":"nknguyenhc"},"content":" [style]\u003d\"{ border: \u00272px solid \u0027 + getColor(label) }\""},{"lineNumber":28,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":29,"author":{"gitId":"nknguyenhc"},"content":" \u003cbutton mat-icon-button *ngIf\u003d\"!hiddenLabelNames.has(label.name)\" (click)\u003d\"hide(label.name); $event.stopPropagation()\"\u003e"},{"lineNumber":30,"author":{"gitId":"-"},"content":" \u003cmat-icon\u003evisibility\u003c/mat-icon\u003e"},{"lineNumber":31,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":32,"author":{"gitId":"nknguyenhc"},"content":" \u003cbutton mat-icon-button *ngIf\u003d\"hiddenLabelNames.has(label.name)\" (click)\u003d\"show(label.name); $event.stopPropagation()\"\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003cmat-icon\u003evisibility_off\u003c/mat-icon\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":" \u003cmat-chip"},{"lineNumber":36,"author":{"gitId":"-"},"content":" [ngStyle]\u003d\"labelService.setLabelStyle(label.color)\""},{"lineNumber":37,"author":{"gitId":"nknguyenhc"},"content":" [disabled]\u003d\"hiddenLabelNames.has(label.name)\""},{"lineNumber":38,"author":{"gitId":"nknguyenhc"},"content":" (click)\u003d\"changeLabelState(label)\""},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":40,"author":{"gitId":"nknguyenhc"},"content":" {{ label.name }}"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003c/mat-chip\u003e"},{"lineNumber":42,"author":{"gitId":"nknguyenhc"},"content":" \u003cdiv *ngIf\u003d\"deselectedLabelNames.has(label.name)\" class\u003d\"flexbox-container-strikethrough\"\u003e\u003c/div\u003e"},{"lineNumber":43,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":45,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":46,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":47,"author":{"gitId":"-"},"content":"\u003c/mat-menu\u003e"}],"authorContributionMap":{"nknguyenhc":12,"-":35}},{"path":"src/app/shared/filter-bar/label-filter-bar/label-filter-bar.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"Arif-Khalid"},"content":"import { AfterViewInit, Component, OnDestroy, OnInit, ViewChild } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"Arif-Khalid"},"content":"import { Observable, Subscription } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { SimpleLabel } from \u0027../../../core/models/label.model\u0027;"},{"lineNumber":4,"author":{"gitId":"Arif-Khalid"},"content":"import { FiltersService } from \u0027../../../core/services/filters.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { LabelService } from \u0027../../../core/services/label.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027../../../core/services/logging.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":9,"author":{"gitId":"-"},"content":" selector: \u0027app-label-filter-bar\u0027,"},{"lineNumber":10,"author":{"gitId":"-"},"content":" templateUrl: \u0027./label-filter-bar.component.html\u0027,"},{"lineNumber":11,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./label-filter-bar.component.css\u0027]"},{"lineNumber":12,"author":{"gitId":"-"},"content":"})"},{"lineNumber":13,"author":{"gitId":"-"},"content":"export class LabelFilterBarComponent implements OnInit, AfterViewInit, OnDestroy {"},{"lineNumber":14,"author":{"gitId":"nknguyenhc"},"content":" private static readonly DEFAULT_LABEL_COLOR: string \u003d \u0027transparent\u0027;"},{"lineNumber":15,"author":{"gitId":"nknguyenhc"},"content":" private static readonly DESELECTED_LABEL_COLOR: string \u003d \u0027#b00020\u0027;"},{"lineNumber":16,"author":{"gitId":"nknguyenhc"},"content":" private static readonly SELECTED_LABEL_COLOR: string \u003d \u0027#41c300\u0027;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":" labels$: Observable\u003cSimpleLabel[]\u003e;"},{"lineNumber":19,"author":{"gitId":"-"},"content":" allLabels: SimpleLabel[];"},{"lineNumber":20,"author":{"gitId":"nknguyenhc"},"content":" selectedLabelNames: Set\u003cstring\u003e \u003d new Set\u003cstring\u003e();"},{"lineNumber":21,"author":{"gitId":"nknguyenhc"},"content":" deselectedLabelNames: Set\u003cstring\u003e \u003d new Set\u003cstring\u003e();"},{"lineNumber":22,"author":{"gitId":"-"},"content":" hiddenLabelNames: Set\u003cstring\u003e \u003d new Set();"},{"lineNumber":23,"author":{"gitId":"-"},"content":" loaded \u003d false;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" labelSubscription: Subscription;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"Arif-Khalid"},"content":" constructor(private labelService: LabelService, private logger: LoggingService, private filtersService: FiltersService) {}"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" ngOnInit() {"},{"lineNumber":30,"author":{"gitId":"-"},"content":" this.loaded \u003d false;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" }"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" ngAfterViewInit(): void {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" setTimeout(() \u003d\u003e {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" this.load();"},{"lineNumber":36,"author":{"gitId":"-"},"content":" this.labels$ \u003d this.labelService.connect();"},{"lineNumber":37,"author":{"gitId":"-"},"content":" this.labels$.subscribe((labels) \u003d\u003e {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" this.allLabels \u003d labels;"},{"lineNumber":39,"author":{"gitId":"Arif-Khalid"},"content":" this.filtersService.sanitizeLabels(this.allLabels);"},{"lineNumber":40,"author":{"gitId":"nknguyenhc"},"content":" this.selectedLabelNames \u003d new Set\u003cstring\u003e(this.filtersService.filter$.value.labels);"},{"lineNumber":41,"author":{"gitId":"nknguyenhc"},"content":" this.deselectedLabelNames \u003d this.filtersService.filter$.value.deselectedLabels;"},{"lineNumber":42,"author":{"gitId":"Arif-Khalid"},"content":" this.hiddenLabelNames \u003d this.filtersService.filter$.value.hiddenLabels;"},{"lineNumber":43,"author":{"gitId":"nknguyenhc"},"content":" this.loaded \u003d true;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" });"},{"lineNumber":45,"author":{"gitId":"-"},"content":" });"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" ngOnDestroy(): void {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" this.labelSubscription?.unsubscribe();"},{"lineNumber":50,"author":{"gitId":"-"},"content":" }"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" hide(label: string): void {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" if (this.hiddenLabelNames.has(label)) {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" this.hiddenLabelNames.add(label);"},{"lineNumber":58,"author":{"gitId":"Arif-Khalid"},"content":" this.filtersService.updateFilters({ hiddenLabels: this.hiddenLabelNames });"},{"lineNumber":59,"author":{"gitId":"-"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" /** Show labels that were hidden */"},{"lineNumber":62,"author":{"gitId":"-"},"content":" show(label: string): void {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" if (!this.hiddenLabelNames.has(label)) {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":" this.hiddenLabelNames.delete(label);"},{"lineNumber":67,"author":{"gitId":"Arif-Khalid"},"content":" this.filtersService.updateFilters({ hiddenLabels: this.hiddenLabelNames });"},{"lineNumber":68,"author":{"gitId":"-"},"content":" }"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":71,"author":{"gitId":"nknguyenhc"},"content":" * Change label to the next state."},{"lineNumber":72,"author":{"gitId":"nknguyenhc"},"content":" * Label has the following state rotation: default -\u003e selected -\u003e deselected."},{"lineNumber":73,"author":{"gitId":"nknguyenhc"},"content":" * @param label The label to change state"},{"lineNumber":74,"author":{"gitId":"-"},"content":" */"},{"lineNumber":75,"author":{"gitId":"nknguyenhc"},"content":" changeLabelState(label: SimpleLabel) {"},{"lineNumber":76,"author":{"gitId":"nknguyenhc"},"content":" if (this.selectedLabelNames.has(label.name)) {"},{"lineNumber":77,"author":{"gitId":"nknguyenhc"},"content":" this.selectedLabelNames.delete(label.name);"},{"lineNumber":78,"author":{"gitId":"nknguyenhc"},"content":" this.deselectedLabelNames.add(label.name);"},{"lineNumber":79,"author":{"gitId":"nknguyenhc"},"content":" } else if (this.deselectedLabelNames.has(label.name)) {"},{"lineNumber":80,"author":{"gitId":"nknguyenhc"},"content":" this.deselectedLabelNames.delete(label.name);"},{"lineNumber":81,"author":{"gitId":"nknguyenhc"},"content":" } else {"},{"lineNumber":82,"author":{"gitId":"nknguyenhc"},"content":" this.selectedLabelNames.add(label.name);"},{"lineNumber":83,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":84,"author":{"gitId":"nknguyenhc"},"content":" this.updateSelection();"},{"lineNumber":85,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":86,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":87,"author":{"gitId":"nknguyenhc"},"content":" /**"},{"lineNumber":88,"author":{"gitId":"nknguyenhc"},"content":" * Returns the border color of the label."},{"lineNumber":89,"author":{"gitId":"nknguyenhc"},"content":" * The border color represents the state of the label."},{"lineNumber":90,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":91,"author":{"gitId":"nknguyenhc"},"content":" getColor(label: SimpleLabel): string {"},{"lineNumber":92,"author":{"gitId":"nknguyenhc"},"content":" if (this.selectedLabelNames.has(label.name)) {"},{"lineNumber":93,"author":{"gitId":"nknguyenhc"},"content":" return LabelFilterBarComponent.SELECTED_LABEL_COLOR;"},{"lineNumber":94,"author":{"gitId":"nknguyenhc"},"content":" } else if (this.deselectedLabelNames.has(label.name)) {"},{"lineNumber":95,"author":{"gitId":"nknguyenhc"},"content":" return LabelFilterBarComponent.DESELECTED_LABEL_COLOR;"},{"lineNumber":96,"author":{"gitId":"nknguyenhc"},"content":" } else {"},{"lineNumber":97,"author":{"gitId":"nknguyenhc"},"content":" return LabelFilterBarComponent.DEFAULT_LABEL_COLOR;"},{"lineNumber":98,"author":{"gitId":"-"},"content":" }"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" /** loads in the labels in the repository */"},{"lineNumber":102,"author":{"gitId":"-"},"content":" public load() {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" this.labelService.startPollLabels();"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" filter(filter: string, target: string): boolean {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" return !target.toLowerCase().includes(filter.toLowerCase());"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" hasLabels(filter: string): boolean {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" if (this.allLabels \u003d\u003d\u003d undefined || this.allLabels.length \u003d\u003d\u003d 0) {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":113,"author":{"gitId":"-"},"content":" }"},{"lineNumber":114,"author":{"gitId":"nknguyenhc"},"content":" return this.allLabels.some((label) \u003d\u003e !this.filter(filter, label.name));"},{"lineNumber":115,"author":{"gitId":"-"},"content":" }"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" updateSelection(): void {"},{"lineNumber":118,"author":{"gitId":"nknguyenhc"},"content":" this.filtersService.updateFilters({"},{"lineNumber":119,"author":{"gitId":"nknguyenhc"},"content":" labels: Array.from(this.selectedLabelNames),"},{"lineNumber":120,"author":{"gitId":"nknguyenhc"},"content":" deselectedLabels: this.deselectedLabelNames"},{"lineNumber":121,"author":{"gitId":"Arif-Khalid"},"content":" });"},{"lineNumber":122,"author":{"gitId":"-"},"content":" }"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" removeAllSelection(): void {"},{"lineNumber":125,"author":{"gitId":"nknguyenhc"},"content":" this.selectedLabelNames \u003d new Set\u003cstring\u003e();"},{"lineNumber":126,"author":{"gitId":"nknguyenhc"},"content":" this.deselectedLabelNames \u003d new Set\u003cstring\u003e();"},{"lineNumber":127,"author":{"gitId":"-"},"content":" this.updateSelection();"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":40,"Arif-Khalid":9,"-":80}},{"path":"src/app/shared/issue-pr-card/issue-pr-card-labels/issue-pr-card-labels.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component, Input } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"nknguyenhc"},"content":"import { GithubLabel } from \u0027../../../core/models/github/github-label.model\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { LabelService } from \u0027../../../core/services/label.service\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":6,"author":{"gitId":"-"},"content":" selector: \u0027app-issue-pr-card-labels\u0027,"},{"lineNumber":7,"author":{"gitId":"-"},"content":" templateUrl: \u0027./issue-pr-card-labels.component.html\u0027,"},{"lineNumber":8,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./issue-pr-card-labels.component.css\u0027]"},{"lineNumber":9,"author":{"gitId":"-"},"content":"})"},{"lineNumber":10,"author":{"gitId":"-"},"content":"export class IssuePrCardLabelsComponent {"},{"lineNumber":11,"author":{"gitId":"nknguyenhc"},"content":" @Input() labels: GithubLabel[];"},{"lineNumber":12,"author":{"gitId":"nknguyenhc"},"content":" @Input() labelSet: Set\u003cstring\u003e;"},{"lineNumber":13,"author":{"gitId":"-"},"content":" constructor(public labelService: LabelService) {}"},{"lineNumber":14,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":3,"-":11}},{"path":"src/app/shared/issue-pr-card/issue-pr-card-milestone/issue-pr-card-milestone.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"MadLamprey"},"content":"\u003cdiv *ngIf\u003d\"repoHasMilestones\" class\u003d\"milestone\" [ngStyle]\u003d\"{ color: milestone.state ? \u0027grey\u0027 : \u0027red\u0027 }\"\u003e"},{"lineNumber":2,"author":{"gitId":"MadLamprey"},"content":" \u003cspan class\u003d\"octicon-milestone\" octicon\u003d\"milestone\" [color]\u003d\"milestone.state ? \u0027grey\u0027 : \u0027red\u0027\" size\u003d\"8\"\u003e \u003c/span\u003e"},{"lineNumber":3,"author":{"gitId":"MadLamprey"},"content":" {{ milestone.state ? milestone.title : \u0027???\u0027 }}"},{"lineNumber":4,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"MadLamprey":3,"-":1}},{"path":"src/app/shared/issue-pr-card/issue-pr-card-milestone/issue-pr-card-milestone.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component, Input } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Milestone } from \u0027../../../core/models/milestone.model\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":""},{"lineNumber":4,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":5,"author":{"gitId":"-"},"content":" selector: \u0027app-issue-pr-card-milestone\u0027,"},{"lineNumber":6,"author":{"gitId":"-"},"content":" templateUrl: \u0027./issue-pr-card-milestone.component.html\u0027,"},{"lineNumber":7,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./issue-pr-card-milestone.component.css\u0027]"},{"lineNumber":8,"author":{"gitId":"-"},"content":"})"},{"lineNumber":9,"author":{"gitId":"-"},"content":"export class IssuePrCardMilestoneComponent {"},{"lineNumber":10,"author":{"gitId":"-"},"content":" @Input() milestone: Milestone;"},{"lineNumber":11,"author":{"gitId":"MadLamprey"},"content":" @Input() repoHasMilestones: boolean;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":" constructor() {}"},{"lineNumber":14,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"MadLamprey":1,"-":13}},{"path":"src/app/shared/issue-pr-card/issue-pr-card.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":".card {"},{"lineNumber":2,"author":{"gitId":"-"},"content":" margin: 8px 0px 8px 0px;"},{"lineNumber":3,"author":{"gitId":"Arif-Khalid"},"content":" background-color: transparent;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"}"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":".mat-card {"},{"lineNumber":7,"author":{"gitId":"-"},"content":" padding: 10px;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"}"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":".column-header {"},{"lineNumber":11,"author":{"gitId":"-"},"content":" justify-content: center;"},{"lineNumber":12,"author":{"gitId":"-"},"content":" margin: 0;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"}"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":".border-green {"},{"lineNumber":16,"author":{"gitId":"-"},"content":" border-left: 2.4px solid green;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"}"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":".border-purple {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" border-left: 2.4px solid purple;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"}"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":".border-red {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" border-left: 2.4px solid red;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"}"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":".border-gray {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" border-left: 2.4px solid gray;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"}"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":".mat-card-content {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" display: flex;"},{"lineNumber":33,"author":{"gitId":"-"},"content":" align-items: center;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" font-size: 11px;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" text-align: left;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" margin: 0px;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" padding: 0px;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"}"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":".mat-card-subtitle {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" display: flex;"},{"lineNumber":42,"author":{"gitId":"-"},"content":" align-items: center;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" font-size: 11px;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" text-align: left;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" overflow: auto;"},{"lineNumber":46,"author":{"gitId":"-"},"content":" margin: 6px 0;"},{"lineNumber":47,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"Arif-Khalid":1,"-":46}},{"path":"src/app/shared/issue-pr-card/issue-pr-card.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cmat-card class\u003d\"card\" [ngClass]\u003d\"getIssueOpenOrCloseColorCSSClass()\"\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"no-underline link-grey-dark\" (click)\u003d\"viewIssueInBrowser($event)\"\u003e"},{"lineNumber":3,"author":{"gitId":"-"},"content":" \u003cspan [matTooltip]\u003d\"this.issue.updated_at\"\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003capp-issue-pr-card-header [issue]\u003d\"issue\"\u003e\u003c/app-issue-pr-card-header\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":" \u003cmat-card-content\u003e"},{"lineNumber":6,"author":{"gitId":"MadLamprey"},"content":" \u003capp-issue-pr-card-milestone"},{"lineNumber":7,"author":{"gitId":"MadLamprey"},"content":" [milestone]\u003d\"issue.milestone\""},{"lineNumber":8,"author":{"gitId":"MadLamprey"},"content":" [repoHasMilestones]\u003d\"!milestoneService.hasNoMilestones\""},{"lineNumber":9,"author":{"gitId":"MadLamprey"},"content":" \u003e\u003c/app-issue-pr-card-milestone\u003e"},{"lineNumber":10,"author":{"gitId":"Arif-Khalid"},"content":" \u003capp-issue-pr-card-labels [labels]\u003d\"issue.githubLabels\" [labelSet]\u003d\"filter?.hiddenLabels\"\u003e\u003c/app-issue-pr-card-labels\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003c/mat-card-content\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":"\u003c/mat-card\u003e"}],"authorContributionMap":{"Arif-Khalid":1,"MadLamprey":4,"-":9}},{"path":"src/app/shared/issue-pr-card/issue-pr-card.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component, Input } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Issue } from \u0027../../core/models/issue.model\u0027;"},{"lineNumber":3,"author":{"gitId":"Arif-Khalid"},"content":"import { Filter } from \u0027../../core/services/filters.service\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027../../core/services/github.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { LabelService } from \u0027../../core/services/label.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027../../core/services/logging.service\u0027;"},{"lineNumber":7,"author":{"gitId":"MadLamprey"},"content":"import { MilestoneService } from \u0027../../core/services/milestone.service\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":10,"author":{"gitId":"-"},"content":" selector: \u0027app-issue-pr-card\u0027,"},{"lineNumber":11,"author":{"gitId":"-"},"content":" templateUrl: \u0027./issue-pr-card.component.html\u0027,"},{"lineNumber":12,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./issue-pr-card.component.css\u0027]"},{"lineNumber":13,"author":{"gitId":"-"},"content":"})"},{"lineNumber":14,"author":{"gitId":"-"},"content":"export class IssuePrCardComponent {"},{"lineNumber":15,"author":{"gitId":"-"},"content":" @Input() issue: Issue;"},{"lineNumber":16,"author":{"gitId":"Arif-Khalid"},"content":" @Input() filter?: Filter;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"MadLamprey"},"content":" constructor("},{"lineNumber":19,"author":{"gitId":"MadLamprey"},"content":" private logger: LoggingService,"},{"lineNumber":20,"author":{"gitId":"MadLamprey"},"content":" private githubService: GithubService,"},{"lineNumber":21,"author":{"gitId":"MadLamprey"},"content":" public labelService: LabelService,"},{"lineNumber":22,"author":{"gitId":"MadLamprey"},"content":" public milestoneService: MilestoneService"},{"lineNumber":23,"author":{"gitId":"MadLamprey"},"content":" ) {}"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" /** Opens issue in new window */"},{"lineNumber":26,"author":{"gitId":"-"},"content":" viewIssueInBrowser(event: Event) {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" this.logger.info(`CardViewComponent: Opening Issue ${this.issue.id} on Github`);"},{"lineNumber":28,"author":{"gitId":"-"},"content":" this.githubService.viewIssueInBrowser(this.issue.id, event);"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" /** Returns CSS class for border color */"},{"lineNumber":32,"author":{"gitId":"-"},"content":" getIssueOpenOrCloseColorCSSClass() {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" if (this.issue.state \u003d\u003d\u003d \u0027OPEN\u0027) {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" if (this.issue.isDraft) {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" return \u0027grey\u0027;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":37,"author":{"gitId":"-"},"content":" return \u0027border-green\u0027;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" }"},{"lineNumber":39,"author":{"gitId":"-"},"content":" } else if (this.issue.issueOrPr \u003d\u003d\u003d \u0027PullRequest\u0027 \u0026\u0026 this.issue.state \u003d\u003d\u003d \u0027CLOSED\u0027) {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" return \u0027border-red\u0027;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" } else if (this.issue.issueOrPr \u003d\u003d\u003d \u0027Issue\u0027 \u0026\u0026 this.issue.stateReason \u003d\u003d\u003d \u0027NOT_PLANNED\u0027) {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" return \u0027border-gray\u0027;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return \u0027border-purple\u0027;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":49,"author":{"gitId":"-"},"content":" * Truncates description to fit in card content."},{"lineNumber":50,"author":{"gitId":"-"},"content":" * @param description - Description of Issue that is to be displayed."},{"lineNumber":51,"author":{"gitId":"-"},"content":" */"},{"lineNumber":52,"author":{"gitId":"-"},"content":" fitDescriptionText(): string {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" // Arbitrary Length of Characters beyond which an overflow occurs."},{"lineNumber":54,"author":{"gitId":"-"},"content":" const MAX_CHARACTER_LENGTH \u003d 72;"},{"lineNumber":55,"author":{"gitId":"-"},"content":" const ELLIPSES \u003d \u0027...\u0027;"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" return this.issue.description.slice(0, MAX_CHARACTER_LENGTH) + ELLIPSES;"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"Arif-Khalid":2,"MadLamprey":7,"-":50}},{"path":"src/app/shared/issue-tables/IssuesDataTable.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { DataSource } from \u0027@angular/cdk/table\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { MatPaginator } from \u0027@angular/material/paginator\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { BehaviorSubject, merge, Observable, Subscription } from \u0027rxjs\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { map } from \u0027rxjs/operators\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import { Group } from \u0027../../core/models/github/group.interface\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { Issue } from \u0027../../core/models/issue.model\u0027;"},{"lineNumber":7,"author":{"gitId":"nknguyenhc"},"content":"import { Filter, FiltersService } from \u0027../../core/services/filters.service\u0027;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"import { GroupingContextService } from \u0027../../core/services/grouping/grouping-context.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { IssueService } from \u0027../../core/services/issue.service\u0027;"},{"lineNumber":10,"author":{"gitId":"nknguyenhc"},"content":"import { MilestoneService } from \u0027../../core/services/milestone.service\u0027;"},{"lineNumber":11,"author":{"gitId":"Arif-Khalid"},"content":"import { applyDropdownFilter } from \u0027./dropdownfilter\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { FilterableSource } from \u0027./filterableTypes\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { paginateData } from \u0027./issue-paginator\u0027;"},{"lineNumber":14,"author":{"gitId":"Arif-Khalid"},"content":"import { applySort } from \u0027./issue-sorter\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import { applySearchFilter } from \u0027./search-filter\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"export class IssuesDataTable extends DataSource\u003cIssue\u003e implements FilterableSource {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" public count \u003d 0;"},{"lineNumber":19,"author":{"gitId":"Arif-Khalid"},"content":" private filterChange \u003d new BehaviorSubject(this.filtersService.defaultFilter);"},{"lineNumber":20,"author":{"gitId":"-"},"content":" private issuesSubject \u003d new BehaviorSubject\u003cIssue[]\u003e([]);"},{"lineNumber":21,"author":{"gitId":"-"},"content":" private issueSubscription: Subscription;"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" public isLoading$ \u003d this.issueService.isLoading.asObservable();"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" constructor("},{"lineNumber":26,"author":{"gitId":"-"},"content":" private issueService: IssueService,"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" private groupingContextService: GroupingContextService,"},{"lineNumber":28,"author":{"gitId":"nknguyenhc"},"content":" private filtersService: FiltersService,"},{"lineNumber":29,"author":{"gitId":"nknguyenhc"},"content":" private milestoneService: MilestoneService,"},{"lineNumber":30,"author":{"gitId":"-"},"content":" private paginator: MatPaginator,"},{"lineNumber":31,"author":{"gitId":"-"},"content":" private displayedColumn: string[],"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" private group?: Group,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" private defaultFilter?: (issue: Issue) \u003d\u003e boolean"},{"lineNumber":34,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" super();"},{"lineNumber":36,"author":{"gitId":"-"},"content":" }"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" connect(): Observable\u003cIssue[]\u003e {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" return this.issuesSubject.asObservable();"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" disconnect() {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" this.filterChange.complete();"},{"lineNumber":44,"author":{"gitId":"-"},"content":" this.issuesSubject.complete();"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" if (this.issueSubscription) {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" this.issueSubscription.unsubscribe();"},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":48,"author":{"gitId":"-"},"content":" this.issueService.stopPollIssues();"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" loadIssues() {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" let page;"},{"lineNumber":53,"author":{"gitId":"-"},"content":" if (this.paginator !\u003d\u003d undefined) {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" page \u003d this.paginator.page;"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"Arif-Khalid"},"content":" const displayDataChanges \u003d [this.issueService.issues$, page, this.filterChange].filter((x) \u003d\u003e x !\u003d\u003d undefined);"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" this.issueService.startPollIssues();"},{"lineNumber":60,"author":{"gitId":"-"},"content":" this.issueSubscription \u003d merge(...displayDataChanges)"},{"lineNumber":61,"author":{"gitId":"-"},"content":" .pipe("},{"lineNumber":62,"author":{"gitId":"-"},"content":" // maps each change in display value to new issue ordering or filtering"},{"lineNumber":63,"author":{"gitId":"-"},"content":" map(() \u003d\u003e {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" let data \u003d \u003cIssue[]\u003eObject.values(this.issueService.issues$.getValue()).reverse();"},{"lineNumber":65,"author":{"gitId":"-"},"content":" if (this.defaultFilter) {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" data \u003d data.filter(this.defaultFilter);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":" // Filter by assignee of issue"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":" data \u003d this.groupingContextService.getDataForGroup(data, this.group);"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"Arif-Khalid"},"content":" // Apply Filters"},{"lineNumber":72,"author":{"gitId":"nknguyenhc"},"content":" data \u003d applyDropdownFilter(this.filter, data, !this.milestoneService.hasNoMilestones);"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"Arif-Khalid"},"content":" data \u003d applySearchFilter(this.filter.title, this.displayedColumn, this.issueService, data);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" this.count \u003d data.length;"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"Arif-Khalid"},"content":" data \u003d applySort(this.filter.sort, data);"},{"lineNumber":78,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" if (this.paginator !\u003d\u003d undefined) {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" data \u003d paginateData(this.paginator, data);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":" return data;"},{"lineNumber":83,"author":{"gitId":"-"},"content":" })"},{"lineNumber":84,"author":{"gitId":"-"},"content":" )"},{"lineNumber":85,"author":{"gitId":"-"},"content":" .subscribe((issues) \u003d\u003e {"},{"lineNumber":86,"author":{"gitId":"-"},"content":" this.issuesSubject.next(issues);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" });"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"Arif-Khalid"},"content":" get filter(): Filter {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" return this.filterChange.value;"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"Arif-Khalid"},"content":" set filter(filter: Filter) {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" this.filterChange.next(filter);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" }"},{"lineNumber":97,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":5,"NereusWB922":7,"Arif-Khalid":10,"-":75}},{"path":"src/app/shared/issue-tables/dropdownfilter.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Issue } from \u0027../../core/models/issue.model\u0027;"},{"lineNumber":2,"author":{"gitId":"Arif-Khalid"},"content":"import { Filter } from \u0027../../core/services/filters.service\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":""},{"lineNumber":4,"author":{"gitId":"nknguyenhc"},"content":"type StatusInfo \u003d {"},{"lineNumber":5,"author":{"gitId":"-"},"content":" type: string;"},{"lineNumber":6,"author":{"gitId":"nknguyenhc"},"content":" status: string;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"};"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"nknguyenhc"},"content":"/**"},{"lineNumber":10,"author":{"gitId":"nknguyenhc"},"content":" * Converts a status string into an info object"},{"lineNumber":11,"author":{"gitId":"nknguyenhc"},"content":" */"},{"lineNumber":12,"author":{"gitId":"nknguyenhc"},"content":"const infoFromStatus \u003d (statusString: string): StatusInfo \u003d\u003e {"},{"lineNumber":13,"author":{"gitId":"nknguyenhc"},"content":" const [status, type] \u003d statusString.split(\u0027 \u0027);"},{"lineNumber":14,"author":{"gitId":"nknguyenhc"},"content":" return { status, type };"},{"lineNumber":15,"author":{"gitId":"-"},"content":"};"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * This module serves to improve separation of concerns in IssuesDataTable.ts and IssueList.ts module by containing the logic for"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * applying dropdownFilter to the issues data table in this module."},{"lineNumber":20,"author":{"gitId":"-"},"content":" * This module exports a single function applyDropDownFilter which is called by IssueList."},{"lineNumber":21,"author":{"gitId":"Arif-Khalid"},"content":" * This functions returns the data passed in after all the filters of dropdownFilters are applied"},{"lineNumber":22,"author":{"gitId":"-"},"content":" */"},{"lineNumber":23,"author":{"gitId":"nknguyenhc"},"content":"export function applyDropdownFilter(filter: Filter, data: Issue[], isFilteringByMilestone: boolean): Issue[] {"},{"lineNumber":24,"author":{"gitId":"Arif-Khalid"},"content":" const filteredData: Issue[] \u003d data.filter((issue) \u003d\u003e {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" let ret \u003d true;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"nknguyenhc"},"content":" // status can either be \u0027open\u0027, \u0027closed\u0027, or \u0027merged\u0027"},{"lineNumber":28,"author":{"gitId":"nknguyenhc"},"content":" ret \u003d"},{"lineNumber":29,"author":{"gitId":"nknguyenhc"},"content":" ret \u0026\u0026"},{"lineNumber":30,"author":{"gitId":"nknguyenhc"},"content":" filter.status.some((item) \u003d\u003e {"},{"lineNumber":31,"author":{"gitId":"nknguyenhc"},"content":" const statusInfo \u003d infoFromStatus(item);"},{"lineNumber":32,"author":{"gitId":"nknguyenhc"},"content":" return statusInfo.status \u003d\u003d\u003d issue.state.toLowerCase() \u0026\u0026 statusInfo.type \u003d\u003d\u003d issue.issueOrPr.toLowerCase();"},{"lineNumber":33,"author":{"gitId":"nknguyenhc"},"content":" });"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"Arif-Khalid"},"content":" if (filter.type \u003d\u003d\u003d \u0027issue\u0027) {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" ret \u003d ret \u0026\u0026 issue.issueOrPr \u003d\u003d\u003d \u0027Issue\u0027;"},{"lineNumber":37,"author":{"gitId":"Arif-Khalid"},"content":" } else if (filter.type \u003d\u003d\u003d \u0027pullrequest\u0027) {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" ret \u003d ret \u0026\u0026 issue.issueOrPr \u003d\u003d\u003d \u0027PullRequest\u0027;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"nknguyenhc"},"content":" ret \u003d ret \u0026\u0026 (!isFilteringByMilestone || filter.milestones.some((milestone) \u003d\u003e issue.milestone.title \u003d\u003d\u003d milestone));"},{"lineNumber":42,"author":{"gitId":"nknguyenhc"},"content":" ret \u003d ret \u0026\u0026 issue.labels.every((label) \u003d\u003e !filter.deselectedLabels.has(label));"},{"lineNumber":43,"author":{"gitId":"Arif-Khalid"},"content":" return ret \u0026\u0026 filter.labels.every((label) \u003d\u003e issue.labels.includes(label));"},{"lineNumber":44,"author":{"gitId":"Arif-Khalid"},"content":" });"},{"lineNumber":45,"author":{"gitId":"Arif-Khalid"},"content":" return filteredData;"},{"lineNumber":46,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":18,"Arif-Khalid":8,"-":20}},{"path":"src/app/shared/issue-tables/filterableTypes.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":2,"author":{"gitId":"-"},"content":" * This module aims to abstract out classes that can be filtered"},{"lineNumber":3,"author":{"gitId":"-"},"content":" */"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"Arif-Khalid"},"content":"import { Filter } from \u0027../../core/services/filters.service\u0027;"},{"lineNumber":6,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":8,"author":{"gitId":"-"},"content":" * FilterableSource is an interface that contains a source that can be filtered"},{"lineNumber":9,"author":{"gitId":"-"},"content":" * by a string filter or dropdownFilter."},{"lineNumber":10,"author":{"gitId":"-"},"content":" * The source should set filter and dropdownFilter as a getter and setter"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * and applies the filter when these variables are changed."},{"lineNumber":12,"author":{"gitId":"-"},"content":" */"},{"lineNumber":13,"author":{"gitId":"-"},"content":"export interface FilterableSource {"},{"lineNumber":14,"author":{"gitId":"Arif-Khalid"},"content":" filter: Filter;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"}"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * FilterComponent is a component that contains a FilterableSource"},{"lineNumber":19,"author":{"gitId":"-"},"content":" */"},{"lineNumber":20,"author":{"gitId":"-"},"content":"export interface FilterableComponent {"},{"lineNumber":21,"author":{"gitId":"-"},"content":" retrieveFilterable: () \u003d\u003e FilterableSource;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"Arif-Khalid":3,"-":19}},{"path":"src/app/shared/issue-tables/issue-sorter.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"Arif-Khalid"},"content":"import { Sort } from \u0027@angular/material/sort\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import * as moment from \u0027moment\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { Issue } from \u0027../../core/models/issue.model\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"Arif-Khalid"},"content":"export function applySort(sort: Sort, data: Issue[]): Issue[] {"},{"lineNumber":6,"author":{"gitId":"-"},"content":" if (!sort.active) {"},{"lineNumber":7,"author":{"gitId":"-"},"content":" return data;"},{"lineNumber":8,"author":{"gitId":"-"},"content":" }"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":" const direction: number \u003d sort.direction \u003d\u003d\u003d \u0027asc\u0027 ? 1 : -1;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":" switch (sort.active) {"},{"lineNumber":13,"author":{"gitId":"-"},"content":" case \u0027id\u0027:"},{"lineNumber":14,"author":{"gitId":"MadLamprey"},"content":" return data.sort((a, b) \u003d\u003e direction * compareByIntegerValue(a.id, b.id));"},{"lineNumber":15,"author":{"gitId":"-"},"content":" case \u0027date\u0027:"},{"lineNumber":16,"author":{"gitId":"MadLamprey"},"content":" return data.sort((a, b) \u003d\u003e direction * compareByDateValue(a.updated_at, b.updated_at));"},{"lineNumber":17,"author":{"gitId":"MadLamprey"},"content":" case \u0027status\u0027:"},{"lineNumber":18,"author":{"gitId":"MadLamprey"},"content":" return data.sort((a, b) \u003d\u003e direction * compareByIssueType(a, b));"},{"lineNumber":19,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":20,"author":{"gitId":"-"},"content":" // title, responseTag are string values"},{"lineNumber":21,"author":{"gitId":"MadLamprey"},"content":" return data.sort((a, b) \u003d\u003e direction * compareByStringValue(a[sort.active], b[sort.active]));"},{"lineNumber":22,"author":{"gitId":"-"},"content":" }"},{"lineNumber":23,"author":{"gitId":"-"},"content":"}"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":"function compareByStringValue(valueA: string, valueB: string): number {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" const orderA \u003d String(valueA || \u0027\u0027).toUpperCase();"},{"lineNumber":27,"author":{"gitId":"-"},"content":" const orderB \u003d String(valueB || \u0027\u0027).toUpperCase();"},{"lineNumber":28,"author":{"gitId":"-"},"content":" return orderA \u003c orderB ? -1 : 1;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"}"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":"function compareByIntegerValue(valueA: number, valueB: number): number {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" return valueA \u003c valueB ? -1 : 1;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"}"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":"function compareByDateValue(valueA: string, valueB: string): number {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" return moment(valueA).isBefore(valueB) ? -1 : 1;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"}"},{"lineNumber":38,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":39,"author":{"gitId":"MadLamprey"},"content":"function compareByIssueType(valueA: Issue, valueB: Issue): number {"},{"lineNumber":40,"author":{"gitId":"MadLamprey"},"content":" const sortOrder \u003d {"},{"lineNumber":41,"author":{"gitId":"MadLamprey"},"content":" \u0027OPEN PullRequest\u0027: 0,"},{"lineNumber":42,"author":{"gitId":"MadLamprey"},"content":" \u0027OPEN Issue\u0027: 1,"},{"lineNumber":43,"author":{"gitId":"MadLamprey"},"content":" \u0027MERGED PullRequest\u0027: 2,"},{"lineNumber":44,"author":{"gitId":"MadLamprey"},"content":" \u0027CLOSED Issue\u0027: 3,"},{"lineNumber":45,"author":{"gitId":"MadLamprey"},"content":" \u0027CLOSED PullRequest\u0027: 4"},{"lineNumber":46,"author":{"gitId":"MadLamprey"},"content":" };"},{"lineNumber":47,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":48,"author":{"gitId":"MadLamprey"},"content":" const aOrder \u003d sortOrder[valueA.state + \u0027 \u0027 + valueA.issueOrPr] || -1;"},{"lineNumber":49,"author":{"gitId":"MadLamprey"},"content":" const bOrder \u003d sortOrder[valueB.state + \u0027 \u0027 + valueB.issueOrPr] || -1;"},{"lineNumber":50,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":51,"author":{"gitId":"MadLamprey"},"content":" if (aOrder \u003d\u003d\u003d bOrder) {"},{"lineNumber":52,"author":{"gitId":"MadLamprey"},"content":" return compareByStringValue(valueA.title, valueB.title);"},{"lineNumber":53,"author":{"gitId":"MadLamprey"},"content":" } else if (aOrder \u003e bOrder) {"},{"lineNumber":54,"author":{"gitId":"MadLamprey"},"content":" return 1;"},{"lineNumber":55,"author":{"gitId":"MadLamprey"},"content":" } else {"},{"lineNumber":56,"author":{"gitId":"MadLamprey"},"content":" return -1;"},{"lineNumber":57,"author":{"gitId":"MadLamprey"},"content":" }"},{"lineNumber":58,"author":{"gitId":"MadLamprey"},"content":"}"}],"authorContributionMap":{"Arif-Khalid":2,"MadLamprey":26,"-":30}},{"path":"src/app/shared/layout/header.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":".repo-menu-footer {"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":" display: flex;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":" justify-content: space-between;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" align-items: center;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" position: sticky;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" bottom: 0;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" z-index: 1;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" padding: 10px;"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":".new-repo-button {"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" flex-grow: 1;"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":".keep-filter-button {"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" margin-left: 2px;"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":".repo-options {"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" max-height: 300px;"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" overflow-y: auto;"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":".repo-options button {"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" font-size: 17px;"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":"}"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":"/* Overwrite the width of the menu */"},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":"::ng-deep .repo-menu {"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" width: fit-content !important;"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" min-width: 320px !important;"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":"}"}],"authorContributionMap":{"NereusWB922":32}},{"path":"src/app/shared/layout/header.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cmat-toolbar color\u003d\"primary\" style\u003d\"position: sticky; position: -webkit-sticky; top: 0; z-index: 1000\"\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" \u003cbutton"},{"lineNumber":3,"author":{"gitId":"-"},"content":" *ngIf\u003d\"isBackButtonShown()\""},{"lineNumber":4,"author":{"gitId":"-"},"content":" mat-icon-button"},{"lineNumber":5,"author":{"gitId":"-"},"content":" class\u003d\"mat-toolbar mat-primary back-button\""},{"lineNumber":6,"author":{"gitId":"-"},"content":" style\u003d\"transform: scale(0.9)\""},{"lineNumber":7,"author":{"gitId":"-"},"content":" (click)\u003d\"goBack()\""},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":9,"author":{"gitId":"-"},"content":" \u003cmat-icon\u003earrow_back_ios\u003c/mat-icon\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":" \u003ca class\u003d\"mat-toolbar mat-primary\" style\u003d\"text-decoration: none\" [routerLink]\u003d\"viewService.isRepoSet() ? viewService.currentView : null\""},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003eWATcher v{{ this.getVersion() }}\u003c/a"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":14,"author":{"gitId":"Arif-Khalid"},"content":" \u003cspan id\u003d\"view-descriptor\" *ngIf\u003d\"viewService.isRepoSet()\" style\u003d\"margin-left: 70px\"\u003e"},{"lineNumber":15,"author":{"gitId":"nknguyenhc"},"content":" {{ this.presetViews[this.filtersService.presetView$.value] }}"},{"lineNumber":16,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"nknguyenhc"},"content":" \u003c!-- Gateway to activity dashboard, do not delete --\u003e"},{"lineNumber":19,"author":{"gitId":"nknguyenhc"},"content":" \u003c!--div *ngIf\u003d\"auth.isAuthenticated() \u0026\u0026 this.viewService.sessionData.sessionRepo.length \u003e 1\"\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003cbutton mat-button [matMenuTriggerFor]\u003d\"menu\"\u003e\u003cmat-icon style\u003d\"color: white\"\u003eexpand_more\u003c/mat-icon\u003e\u003c/button\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003cmat-menu #menu\u003d\"matMenu\"\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u003cbutton"},{"lineNumber":23,"author":{"gitId":"-"},"content":" mat-menu-item"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" *ngFor\u003d\"let sessionRepo of this.viewService.sessionData.sessionRepo\""},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" (click)\u003d\"this.routeToSelectedView(sessionRepo.view)\""},{"lineNumber":26,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003cspan\u003e"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-icon [ngStyle]\u003d\"{ color: \u0027green\u0027, visibility: this.viewService.currentView \u003d\u003d\u003d sessionRepo.view ? \u0027visible\u0027 : \u0027hidden\u0027 }\""},{"lineNumber":29,"author":{"gitId":"-"},"content":" \u003edone\u003c/mat-icon"},{"lineNumber":30,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" {{ this.getViewDescription(sessionRepo.view) }}"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003c/mat-menu\u003e"},{"lineNumber":35,"author":{"gitId":"nknguyenhc"},"content":" \u003c/div--\u003e"},{"lineNumber":36,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":37,"author":{"gitId":"Arif-Khalid"},"content":" \u003cdiv *ngIf\u003d\"viewService.isRepoSet()\"\u003e"},{"lineNumber":38,"author":{"gitId":"nknguyenhc"},"content":" \u003cbutton mat-button [matMenuTriggerFor]\u003d\"menu\"\u003e\u003cmat-icon style\u003d\"color: white\"\u003eexpand_more\u003c/mat-icon\u003e\u003c/button\u003e"},{"lineNumber":39,"author":{"gitId":"nknguyenhc"},"content":" \u003cmat-menu #menu\u003d\"matMenu\"\u003e"},{"lineNumber":40,"author":{"gitId":"nknguyenhc"},"content":" \u003cdiv *ngFor\u003d\"let presetView of this.presetViews | keyvalue\"\u003e"},{"lineNumber":41,"author":{"gitId":"nknguyenhc"},"content":" \u003cbutton mat-menu-item *ngIf\u003d\"presetView.key !\u003d\u003d \u0027custom\u0027\" (click)\u003d\"this.filtersService.updatePresetView(presetView.key)\"\u003e"},{"lineNumber":42,"author":{"gitId":"nknguyenhc"},"content":" \u003cspan\u003e"},{"lineNumber":43,"author":{"gitId":"nknguyenhc"},"content":" \u003cmat-icon"},{"lineNumber":44,"author":{"gitId":"nknguyenhc"},"content":" [ngStyle]\u003d\"{ color: \u0027green\u0027, visibility: this.filtersService.presetView$.value \u003d\u003d\u003d presetView.key ? \u0027visible\u0027 : \u0027hidden\u0027 }\""},{"lineNumber":45,"author":{"gitId":"nknguyenhc"},"content":" \u003edone\u003c/mat-icon"},{"lineNumber":46,"author":{"gitId":"nknguyenhc"},"content":" \u003e"},{"lineNumber":47,"author":{"gitId":"nknguyenhc"},"content":" {{ presetView.value }}"},{"lineNumber":48,"author":{"gitId":"nknguyenhc"},"content":" \u003c/span\u003e"},{"lineNumber":49,"author":{"gitId":"nknguyenhc"},"content":" \u003c/button\u003e"},{"lineNumber":50,"author":{"gitId":"nknguyenhc"},"content":" \u003c/div\u003e"},{"lineNumber":51,"author":{"gitId":"nknguyenhc"},"content":" \u003c/mat-menu\u003e"},{"lineNumber":52,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" \u003c!-- everything else --\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" \u003cspan style\u003d\"flex: 1 1 auto\"\u003e\u003c/span\u003e"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv *ngIf\u003d\"auth.isAuthenticated() \u0026\u0026 viewService.isRepoSet()\"\u003e"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" \u003cspan id\u003d\"view-descriptor\" style\u003d\"margin-left: 10px\"\u003e"},{"lineNumber":60,"author":{"gitId":"-"},"content":" {{ this.currentRepo || \u0027No Repository Set\u0027 }}"},{"lineNumber":61,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":62,"author":{"gitId":"-"},"content":" \u003cbutton"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" mat-icon-button"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" matTooltip\u003d\"{{ viewService.isRepoSet() ? \u0027Change Repository\u0027 : \u0027Select Repository\u0027 }}\""},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":" [matMenuTriggerFor]\u003d\"repoMenu\""},{"lineNumber":66,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":67,"author":{"gitId":"-"},"content":" \u003cmat-icon\u003eedit\u003c/mat-icon\u003e"},{"lineNumber":68,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":69,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-menu #repoMenu xPosition\u003d\"before\" class\u003d\"repo-menu\"\u003e"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv class\u003d\"repo-options\"\u003e"},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv *ngFor\u003d\"let repo of this.repoUrlCacheService.suggestions\"\u003e"},{"lineNumber":74,"author":{"gitId":"NereusWB922"},"content":" \u003cbutton mat-menu-item *ngIf\u003d\"repo !\u003d\u003d this.currentRepo\" (click)\u003d\"this.applyRepoDropdown(repo, true)\"\u003e"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":" {{ repo }}"},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" \u003c/button\u003e"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" \u003c/div\u003e"},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":" \u003c/div\u003e"},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":" \u003cdiv class\u003d\"repo-menu-footer\"\u003e"},{"lineNumber":81,"author":{"gitId":"NereusWB922"},"content":" \u003cbutton mat-flat-button color\u003d\"primary\" class\u003d\"new-repo-button\" (click)\u003d\"this.openChangeRepoDialog()\" matTooltip\u003d\"Add new repository\"\u003e"},{"lineNumber":82,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-icon\u003eadd\u003c/mat-icon\u003e"},{"lineNumber":83,"author":{"gitId":"NereusWB922"},"content":" \u003c/button\u003e"},{"lineNumber":84,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":85,"author":{"gitId":"NereusWB922"},"content":" \u003cbutton"},{"lineNumber":86,"author":{"gitId":"NereusWB922"},"content":" mat-icon-button"},{"lineNumber":87,"author":{"gitId":"NereusWB922"},"content":" (click)\u003d\"toggleKeepFilters($event)\""},{"lineNumber":88,"author":{"gitId":"NereusWB922"},"content":" class\u003d\"keep-filter-button\""},{"lineNumber":89,"author":{"gitId":"NereusWB922"},"content":" matTooltip\u003d\"{{ keepFilters ? \u0027Keep filter on\u0027 : \u0027Keep filter off\u0027 }}\""},{"lineNumber":90,"author":{"gitId":"NereusWB922"},"content":" color\u003d\"{{ keepFilters ? \u0027primary\u0027 : \u0027warn\u0027 }}\""},{"lineNumber":91,"author":{"gitId":"NereusWB922"},"content":" \u003e"},{"lineNumber":92,"author":{"gitId":"NereusWB922"},"content":" \u003cmat-icon\u003e{{ keepFilters ? \u0027filter_alt\u0027 : \u0027filter_alt_off\u0027 }}\u003c/mat-icon\u003e"},{"lineNumber":93,"author":{"gitId":"NereusWB922"},"content":" \u003c/button\u003e"},{"lineNumber":94,"author":{"gitId":"NereusWB922"},"content":" \u003c/div\u003e"},{"lineNumber":95,"author":{"gitId":"NereusWB922"},"content":" \u003c/mat-menu\u003e"},{"lineNumber":96,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" \u003cspan style\u003d\"flex: 1 1 auto\"\u003e\u003c/span\u003e"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" \u003cbutton mat-button matTooltip\u003d\"Download WATcher Log\" (click)\u003d\"this.exportLogFile()\"\u003e"},{"lineNumber":100,"author":{"gitId":"-"},"content":" \u003cmat-icon\u003ereceipt\u003c/mat-icon\u003e"},{"lineNumber":101,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":102,"author":{"gitId":"-"},"content":" \u003cbutton mat-button matTooltip\u003d\"Give feedback about WATcher\" (click)\u003d\"openIssueTracker()\"\u003e"},{"lineNumber":103,"author":{"gitId":"-"},"content":" \u003cmat-icon\u003email\u003c/mat-icon\u003e"},{"lineNumber":104,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" \u003cbutton"},{"lineNumber":107,"author":{"gitId":"NereusWB922"},"content":" *ngIf\u003d\"auth.isAuthenticated() \u0026\u0026 viewService.isRepoSet() \u0026\u0026 isOpenUrlButtonShown()\""},{"lineNumber":108,"author":{"gitId":"-"},"content":" mat-button"},{"lineNumber":109,"author":{"gitId":"-"},"content":" matTooltip\u003d\"View current page on GitHub\""},{"lineNumber":110,"author":{"gitId":"-"},"content":" (click)\u003d\"viewBrowser()\""},{"lineNumber":111,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":112,"author":{"gitId":"-"},"content":" \u003cmat-icon\u003eopen_in_new\u003c/mat-icon\u003e"},{"lineNumber":113,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"sync-spinner\" *ngIf\u003d\"auth.isAuthenticated() \u0026\u0026 (this.isLoading$ | async); else notLoading\"\u003e"},{"lineNumber":116,"author":{"gitId":"-"},"content":" \u003cmat-spinner class\u003d\"white-spinner\" [diameter]\u003d\"20\"\u003e\u003c/mat-spinner\u003e"},{"lineNumber":117,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" \u003cng-template #notLoading\u003e"},{"lineNumber":120,"author":{"gitId":"-"},"content":" \u003cbutton"},{"lineNumber":121,"author":{"gitId":"NereusWB922"},"content":" *ngIf\u003d\"auth.isAuthenticated() \u0026\u0026 viewService.isRepoSet() \u0026\u0026 isReloadButtonShown() \u0026\u0026 !this.isReloadButtonDisabled\""},{"lineNumber":122,"author":{"gitId":"-"},"content":" mat-button"},{"lineNumber":123,"author":{"gitId":"-"},"content":" matTooltip\u003d\"Synchronize with Github data\""},{"lineNumber":124,"author":{"gitId":"-"},"content":" (click)\u003d\"reload()\""},{"lineNumber":125,"author":{"gitId":"-"},"content":" \u003e"},{"lineNumber":126,"author":{"gitId":"-"},"content":" Sync"},{"lineNumber":127,"author":{"gitId":"-"},"content":" \u003cmat-icon\u003erefresh\u003c/mat-icon\u003e"},{"lineNumber":128,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":129,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"sync-spinner\" *ngIf\u003d\"auth.isAuthenticated() \u0026\u0026 isReloadButtonShown() \u0026\u0026 this.isReloadButtonDisabled\"\u003e"},{"lineNumber":130,"author":{"gitId":"-"},"content":" \u003cspan style\u003d\"font-size: 14px; margin-right: 7px\"\u003eSync\u003c/span\u003e"},{"lineNumber":131,"author":{"gitId":"-"},"content":" \u003cmat-spinner class\u003d\"white-spinner\" [diameter]\u003d\"20\"\u003e\u003c/mat-spinner\u003e"},{"lineNumber":132,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":133,"author":{"gitId":"-"},"content":" \u003c/ng-template\u003e"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" \u003cbutton *ngIf\u003d\"auth.isAuthenticated()\" mat-button matTooltip\u003d\"Log out\" (click)\u003d\"openLogOutDialog(); $event.stopPropagation()\"\u003e"},{"lineNumber":136,"author":{"gitId":"-"},"content":" ({{ userService.currentUser.loginId }})"},{"lineNumber":137,"author":{"gitId":"-"},"content":" \u003cmat-icon style\u003d\"margin-left: 2px\"\u003eexit_to_app\u003c/mat-icon\u003e"},{"lineNumber":138,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":139,"author":{"gitId":"-"},"content":"\u003c/mat-toolbar\u003e"}],"authorContributionMap":{"nknguyenhc":19,"NereusWB922":38,"Arif-Khalid":2,"-":80}},{"path":"src/app/shared/layout/header.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Location } from \u0027@angular/common\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Component, OnInit } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { Router, RoutesRecognized } from \u0027@angular/router\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { filter, pairwise, switchMap } from \u0027rxjs/operators\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { AppConfig } from \u0027../../../environments/environment\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { STORAGE_KEYS } from \u0027../../core/constants/storage-keys.constants\u0027;"},{"lineNumber":8,"author":{"gitId":"Arif-Khalid"},"content":"import { RepoChangeResponse } from \u0027../../core/models/repo-change-response.model\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { Repo } from \u0027../../core/models/repo.model\u0027;"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"import { View } from \u0027../../core/models/view.model\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { AuthService } from \u0027../../core/services/auth.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { DialogService } from \u0027../../core/services/dialog.service\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { ErrorHandlingService } from \u0027../../core/services/error-handling.service\u0027;"},{"lineNumber":14,"author":{"gitId":"Arif-Khalid"},"content":"import { FiltersService } from \u0027../../core/services/filters.service\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import { GithubService } from \u0027../../core/services/github.service\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import { GithubEventService } from \u0027../../core/services/githubevent.service\u0027;"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":"import { GroupingContextService } from \u0027../../core/services/grouping/grouping-context.service\u0027;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import { IssueService } from \u0027../../core/services/issue.service\u0027;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import { LabelService } from \u0027../../core/services/label.service\u0027;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027../../core/services/logging.service\u0027;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import { RepoSessionStorageService } from \u0027../../core/services/repo-session-storage.service\u0027;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import { RepoUrlCacheService } from \u0027../../core/services/repo-url-cache.service\u0027;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import { UserService } from \u0027../../core/services/user.service\u0027;"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":"import { ViewDescription, ViewService } from \u0027../../core/services/view.service\u0027;"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":"const ISSUE_TRACKER_URL \u003d \u0027https://github.com/CATcher-org/WATcher/issues\u0027;"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":29,"author":{"gitId":"-"},"content":" selector: \u0027app-layout-header\u0027,"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" templateUrl: \u0027./header.component.html\u0027,"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" styleUrls: [\u0027./header.component.css\u0027]"},{"lineNumber":32,"author":{"gitId":"-"},"content":"})"},{"lineNumber":33,"author":{"gitId":"-"},"content":"export class HeaderComponent implements OnInit {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" private prevUrl;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" isReloadButtonDisabled \u003d false;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" ISSUE_FILTER \u003d \u0027/issues?q\u003dis:issue+is:all\u0027; // the filtered list must be an issue and must be open"},{"lineNumber":37,"author":{"gitId":"-"},"content":" TUTORIAL_LABEL \u003d \u0027+label:tutorial.\u0027;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" TEAM_LABEL \u003d \u0027+label:team.\u0027;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" EXCLUDE_DUPLICATE \u003d \u0027+-label:duplicate\u0027; // exclude duplicate issues"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" public isLoading$: Observable\u003cboolean\u003e;"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" // Messages for the modal popup window upon logging out"},{"lineNumber":44,"author":{"gitId":"-"},"content":" private readonly logOutDialogMessages \u003d [\u0027Do you wish to log out?\u0027];"},{"lineNumber":45,"author":{"gitId":"-"},"content":" private readonly yesButtonDialogMessage \u003d \u0027Yes, I wish to log out\u0027;"},{"lineNumber":46,"author":{"gitId":"-"},"content":" private readonly noButtonDialogMessage \u003d \"No, I don\u0027t wish to log out\";"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"nknguyenhc"},"content":" readonly presetViews: {"},{"lineNumber":49,"author":{"gitId":"nknguyenhc"},"content":" [key: string]: string;"},{"lineNumber":50,"author":{"gitId":"nknguyenhc"},"content":" } \u003d {"},{"lineNumber":51,"author":{"gitId":"nknguyenhc"},"content":" currentlyActive: \u0027Currently active\u0027,"},{"lineNumber":52,"author":{"gitId":"nknguyenhc"},"content":" contributions: \u0027Contributions\u0027,"},{"lineNumber":53,"author":{"gitId":"nknguyenhc"},"content":" custom: \u0027Custom\u0027"},{"lineNumber":54,"author":{"gitId":"nknguyenhc"},"content":" };"},{"lineNumber":55,"author":{"gitId":"nknguyenhc"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" /** Model for the displayed repository name */"},{"lineNumber":57,"author":{"gitId":"-"},"content":" currentRepo \u003d \u0027\u0027;"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" keepFilters \u003d false;"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" constructor("},{"lineNumber":62,"author":{"gitId":"-"},"content":" private router: Router,"},{"lineNumber":63,"author":{"gitId":"-"},"content":" public auth: AuthService,"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" public viewService: ViewService,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" public userService: UserService,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" public logger: LoggingService,"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":" public repoUrlCacheService: RepoUrlCacheService,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" private location: Location,"},{"lineNumber":69,"author":{"gitId":"-"},"content":" private githubEventService: GithubEventService,"},{"lineNumber":70,"author":{"gitId":"-"},"content":" private issueService: IssueService,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" private labelService: LabelService,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" private errorHandlingService: ErrorHandlingService,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" private githubService: GithubService,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" private dialogService: DialogService,"},{"lineNumber":75,"author":{"gitId":"Arif-Khalid"},"content":" private repoSessionStorageService: RepoSessionStorageService,"},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" private filtersService: FiltersService,"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" private groupingContextService: GroupingContextService"},{"lineNumber":78,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" router.events"},{"lineNumber":80,"author":{"gitId":"-"},"content":" .pipe("},{"lineNumber":81,"author":{"gitId":"-"},"content":" filter((e: any) \u003d\u003e e instanceof RoutesRecognized),"},{"lineNumber":82,"author":{"gitId":"-"},"content":" pairwise()"},{"lineNumber":83,"author":{"gitId":"-"},"content":" )"},{"lineNumber":84,"author":{"gitId":"-"},"content":" .subscribe((e) \u003d\u003e {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" this.prevUrl \u003d e[0].urlAfterRedirects;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" });"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" this.auth.currentAuthState.subscribe(() \u003d\u003e {"},{"lineNumber":89,"author":{"gitId":"-"},"content":" if (auth.isAuthenticated() \u0026\u0026 !repoSessionStorageService.hasRepoLocation()) {"},{"lineNumber":90,"author":{"gitId":"nknguyenhc"},"content":" if (!this.auth.hasNext()) {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" this.openChangeRepoDialog();"},{"lineNumber":92,"author":{"gitId":"nknguyenhc"},"content":" } else {"},{"lineNumber":93,"author":{"gitId":"nknguyenhc"},"content":" this.auth.redirectToNext();"},{"lineNumber":94,"author":{"gitId":"nknguyenhc"},"content":" }"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":" });"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"NereusWB922"},"content":" this.viewService.repoSetState.subscribe((state) \u003d\u003e {"},{"lineNumber":99,"author":{"gitId":"NereusWB922"},"content":" if (auth.isAuthenticated() \u0026\u0026 viewService.isRepoSet()) {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" this.initializeRepoNameInTitle();"},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":" });"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"NereusWB922"},"content":" this.viewService.repoChanged$.subscribe((repo) \u003d\u003e {"},{"lineNumber":105,"author":{"gitId":"NereusWB922"},"content":" this.initializeRepoNameInTitle();"},{"lineNumber":106,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":107,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" this.isLoading$ \u003d this.issueService.isLoading.asObservable();"},{"lineNumber":109,"author":{"gitId":"-"},"content":" }"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" ngOnInit() {}"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":114,"author":{"gitId":"NereusWB922"},"content":" * Replaces and resets the current view data and routes the app to the"},{"lineNumber":115,"author":{"gitId":"NereusWB922"},"content":" * newly selected view."},{"lineNumber":116,"author":{"gitId":"NereusWB922"},"content":" * @param selectedView - Selected View that is selected by the user."},{"lineNumber":117,"author":{"gitId":"-"},"content":" */"},{"lineNumber":118,"author":{"gitId":"NereusWB922"},"content":" routeToSelectedView(selectedView: string): void {"},{"lineNumber":119,"author":{"gitId":"NereusWB922"},"content":" // Do nothing if the selected view is the current view."},{"lineNumber":120,"author":{"gitId":"NereusWB922"},"content":" if (this.viewService.currentView \u003d\u003d\u003d View[selectedView]) {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":122,"author":{"gitId":"-"},"content":" }"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"NereusWB922"},"content":" // Replace Current View Data."},{"lineNumber":125,"author":{"gitId":"NereusWB922"},"content":" this.viewService.changeView(View[selectedView]);"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"NereusWB922"},"content":" // Remove current view issues and load selected view issues."},{"lineNumber":128,"author":{"gitId":"-"},"content":" this.githubService.reset();"},{"lineNumber":129,"author":{"gitId":"-"},"content":" this.issueService.reset(false);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" this.labelService.reset();"},{"lineNumber":131,"author":{"gitId":"-"},"content":" this.reload();"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"NereusWB922"},"content":" // Route app to new view."},{"lineNumber":134,"author":{"gitId":"NereusWB922"},"content":" this.router.navigateByUrl(this.viewService.currentView);"},{"lineNumber":135,"author":{"gitId":"-"},"content":" }"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" isBackButtonShown(): boolean {"},{"lineNumber":138,"author":{"gitId":"NereusWB922"},"content":" return `/${this.viewService.currentView}` !\u003d\u003d this.router.url \u0026\u0026 this.router.url !\u003d\u003d \u0027/\u0027 \u0026\u0026 !this.router.url.startsWith(\u0027/?code\u0027);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" }"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" isReloadButtonShown(): boolean {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" return this.router.url !\u003d\u003d \u0027/phaseBugReporting/issues/new\u0027;"},{"lineNumber":143,"author":{"gitId":"-"},"content":" }"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" isOpenUrlButtonShown(): boolean {"},{"lineNumber":146,"author":{"gitId":"NereusWB922"},"content":" return this.viewService.currentView \u003d\u003d\u003d View.issuesViewer || this.viewService.currentView \u003d\u003d\u003d View.activityDashboard;"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" getVersion(): string {"},{"lineNumber":150,"author":{"gitId":"-"},"content":" return AppConfig.version;"},{"lineNumber":151,"author":{"gitId":"-"},"content":" }"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"NereusWB922"},"content":" getViewDescription(openView: string): string {"},{"lineNumber":154,"author":{"gitId":"NereusWB922"},"content":" return ViewDescription[openView];"},{"lineNumber":155,"author":{"gitId":"-"},"content":" }"},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"-"},"content":" goBack() {"},{"lineNumber":158,"author":{"gitId":"NereusWB922"},"content":" if (this.prevUrl \u003d\u003d\u003d `/${this.viewService.currentView}/issues/new`) {"},{"lineNumber":159,"author":{"gitId":"NereusWB922"},"content":" this.router.navigateByUrl(this.viewService.currentView);"},{"lineNumber":160,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":161,"author":{"gitId":"-"},"content":" this.location.back();"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" viewBrowser() {"},{"lineNumber":166,"author":{"gitId":"NereusWB922"},"content":" if (this.viewService.currentView \u003d\u003d\u003d View.activityDashboard) {"},{"lineNumber":167,"author":{"gitId":"NereusWB922"},"content":" window.open(`https://github.com/${this.viewService.currentRepo.owner}/${this.viewService.currentRepo.name}/pulse`);"},{"lineNumber":168,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":169,"author":{"gitId":"-"},"content":" }"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" const routerUrl \u003d this.router.url.substring(1); // remove the first \u0027/\u0027 from string"},{"lineNumber":172,"author":{"gitId":"-"},"content":" const issueUrlIndex \u003d routerUrl.indexOf(\u0027/\u0027); // find the index of second \u0027/\u0027"},{"lineNumber":173,"author":{"gitId":"-"},"content":" let issueUrl: string;"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" // If can\u0027t find the index of second \u0027/\u0027, then router is at the /issues (table list) page"},{"lineNumber":176,"author":{"gitId":"-"},"content":" if (issueUrlIndex \u003c 0) {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" // Apply filters to the issueUrl"},{"lineNumber":178,"author":{"gitId":"-"},"content":" issueUrl \u003d this.ISSUE_FILTER;"},{"lineNumber":179,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" // issueUrl will be from the second \u0027/\u0027"},{"lineNumber":181,"author":{"gitId":"-"},"content":" issueUrl \u003d routerUrl.substring(issueUrlIndex);"},{"lineNumber":182,"author":{"gitId":"-"},"content":" }"},{"lineNumber":183,"author":{"gitId":"-"},"content":" // Open the url in user\u0027s preferred browser"},{"lineNumber":184,"author":{"gitId":"-"},"content":" window.open(\u0027https://github.com/\u0027.concat(this.githubService.getRepoURL()).concat(issueUrl));"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" openIssueTracker() {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" window.open(ISSUE_TRACKER_URL);"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" reload() {"},{"lineNumber":192,"author":{"gitId":"-"},"content":" this.isReloadButtonDisabled \u003d true;"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"-"},"content":" this.githubEventService.reloadPage().subscribe("},{"lineNumber":195,"author":{"gitId":"-"},"content":" (success) \u003d\u003e success,"},{"lineNumber":196,"author":{"gitId":"-"},"content":" (error) \u003d\u003e {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" this.errorHandlingService.handleError(error, () \u003d\u003e this.githubEventService.reloadPage());"},{"lineNumber":198,"author":{"gitId":"-"},"content":" }"},{"lineNumber":199,"author":{"gitId":"-"},"content":" );"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":" this.labelService.fetchLabels().subscribe("},{"lineNumber":202,"author":{"gitId":"-"},"content":" (success) \u003d\u003e success,"},{"lineNumber":203,"author":{"gitId":"-"},"content":" (error) \u003d\u003e {"},{"lineNumber":204,"author":{"gitId":"-"},"content":" this.errorHandlingService.handleError(error, () \u003d\u003e this.labelService.fetchLabels());"},{"lineNumber":205,"author":{"gitId":"-"},"content":" }"},{"lineNumber":206,"author":{"gitId":"-"},"content":" );"},{"lineNumber":207,"author":{"gitId":"-"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" // Prevent user from spamming the reload button"},{"lineNumber":209,"author":{"gitId":"-"},"content":" setTimeout(() \u003d\u003e {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" this.isReloadButtonDisabled \u003d false;"},{"lineNumber":211,"author":{"gitId":"-"},"content":" }, 3000);"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" logOut() {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" this.auth.logOut();"},{"lineNumber":216,"author":{"gitId":"-"},"content":" }"},{"lineNumber":217,"author":{"gitId":"-"},"content":""},{"lineNumber":218,"author":{"gitId":"-"},"content":" openLogOutDialog() {"},{"lineNumber":219,"author":{"gitId":"-"},"content":" const dialogRef \u003d this.dialogService.openUserConfirmationModal("},{"lineNumber":220,"author":{"gitId":"-"},"content":" this.logOutDialogMessages,"},{"lineNumber":221,"author":{"gitId":"-"},"content":" this.yesButtonDialogMessage,"},{"lineNumber":222,"author":{"gitId":"-"},"content":" this.noButtonDialogMessage"},{"lineNumber":223,"author":{"gitId":"-"},"content":" );"},{"lineNumber":224,"author":{"gitId":"-"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":" dialogRef.afterClosed().subscribe((res) \u003d\u003e {"},{"lineNumber":226,"author":{"gitId":"-"},"content":" if (res) {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" this.logger.info(`HeaderComponent: Logging out from ${this.userService.currentUser.loginId}`);"},{"lineNumber":228,"author":{"gitId":"-"},"content":" this.logOut();"},{"lineNumber":229,"author":{"gitId":"-"},"content":" }"},{"lineNumber":230,"author":{"gitId":"-"},"content":" });"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" exportLogFile() {"},{"lineNumber":234,"author":{"gitId":"-"},"content":" this.logger.exportLogFile();"},{"lineNumber":235,"author":{"gitId":"-"},"content":" }"},{"lineNumber":236,"author":{"gitId":"-"},"content":""},{"lineNumber":237,"author":{"gitId":"-"},"content":" initializeRepoNameInTitle() {"},{"lineNumber":238,"author":{"gitId":"NereusWB922"},"content":" if (Repo.isInvalidRepoName(this.viewService.currentRepo)) {"},{"lineNumber":239,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":240,"author":{"gitId":"-"},"content":" }"},{"lineNumber":241,"author":{"gitId":"NereusWB922"},"content":" const currentRepoString \u003d this.viewService.currentRepo.toString();"},{"lineNumber":242,"author":{"gitId":"-"},"content":" this.logger.info(`HeaderComponent: initializing current repository name as ${currentRepoString}`);"},{"lineNumber":243,"author":{"gitId":"-"},"content":" this.currentRepo \u003d currentRepoString;"},{"lineNumber":244,"author":{"gitId":"-"},"content":" }"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":247,"author":{"gitId":"-"},"content":" * Change repository viewed on Issue Dashboard, if a valid repository is provided."},{"lineNumber":248,"author":{"gitId":"-"},"content":" * Re-open dialog to prompt for another repository if an invalid one is provided."},{"lineNumber":249,"author":{"gitId":"-"},"content":" */"},{"lineNumber":250,"author":{"gitId":"Arif-Khalid"},"content":" changeRepositoryIfValid(repo: Repo, newRepoString: string, keepFilters: boolean) {"},{"lineNumber":251,"author":{"gitId":"-"},"content":" if (newRepoString \u003d\u003d\u003d this.currentRepo) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":253,"author":{"gitId":"-"},"content":" }"},{"lineNumber":254,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":255,"author":{"gitId":"NereusWB922"},"content":" this.viewService"},{"lineNumber":256,"author":{"gitId":"-"},"content":" .changeRepositoryIfValid(repo)"},{"lineNumber":257,"author":{"gitId":"-"},"content":" .then(() \u003d\u003e {"},{"lineNumber":258,"author":{"gitId":"NereusWB922"},"content":" this.auth.setTitleWithViewDetail();"},{"lineNumber":259,"author":{"gitId":"-"},"content":" this.currentRepo \u003d newRepoString;"},{"lineNumber":260,"author":{"gitId":"NereusWB922"},"content":" if (!keepFilters) {"},{"lineNumber":261,"author":{"gitId":"NereusWB922"},"content":" this.groupingContextService.reset();"},{"lineNumber":262,"author":{"gitId":"Arif-Khalid"},"content":" this.filtersService.clearFilters();"},{"lineNumber":263,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":264,"author":{"gitId":"-"},"content":" })"},{"lineNumber":265,"author":{"gitId":"-"},"content":" .catch((error) \u003d\u003e {"},{"lineNumber":266,"author":{"gitId":"-"},"content":" this.openChangeRepoDialog();"},{"lineNumber":267,"author":{"gitId":"-"},"content":" this.errorHandlingService.handleError(error);"},{"lineNumber":268,"author":{"gitId":"-"},"content":" });"},{"lineNumber":269,"author":{"gitId":"-"},"content":" }"},{"lineNumber":270,"author":{"gitId":"-"},"content":""},{"lineNumber":271,"author":{"gitId":"NereusWB922"},"content":" applyRepoDropdown(repoString: string) {"},{"lineNumber":272,"author":{"gitId":"NereusWB922"},"content":" const newRepo \u003d Repo.of(repoString);"},{"lineNumber":273,"author":{"gitId":"NereusWB922"},"content":" this.changeRepositoryIfValid(newRepo, newRepo.toString(), this.keepFilters);"},{"lineNumber":274,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":275,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":276,"author":{"gitId":"NereusWB922"},"content":" toggleKeepFilters(event: MouseEvent) {"},{"lineNumber":277,"author":{"gitId":"NereusWB922"},"content":" event.stopPropagation();"},{"lineNumber":278,"author":{"gitId":"NereusWB922"},"content":" this.keepFilters \u003d !this.keepFilters;"},{"lineNumber":279,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":280,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":281,"author":{"gitId":"-"},"content":" openChangeRepoDialog() {"},{"lineNumber":282,"author":{"gitId":"-"},"content":" const dialogRef \u003d this.dialogService.openChangeRepoDialog(this.currentRepo);"},{"lineNumber":283,"author":{"gitId":"-"},"content":""},{"lineNumber":284,"author":{"gitId":"Arif-Khalid"},"content":" dialogRef.afterClosed().subscribe((res: RepoChangeResponse | null) \u003d\u003e {"},{"lineNumber":285,"author":{"gitId":"-"},"content":" if (!res) {"},{"lineNumber":286,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":287,"author":{"gitId":"-"},"content":" }"},{"lineNumber":288,"author":{"gitId":"Arif-Khalid"},"content":" const newRepo \u003d Repo.of(res.repo);"},{"lineNumber":289,"author":{"gitId":"-"},"content":""},{"lineNumber":290,"author":{"gitId":"NereusWB922"},"content":" if (this.viewService.isRepoSet()) {"},{"lineNumber":291,"author":{"gitId":"Arif-Khalid"},"content":" this.changeRepositoryIfValid(newRepo, newRepo.toString(), res.keepFilters);"},{"lineNumber":292,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":293,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":294,"author":{"gitId":"-"},"content":" * From session-selection.component.ts"},{"lineNumber":295,"author":{"gitId":"-"},"content":" *"},{"lineNumber":296,"author":{"gitId":"-"},"content":" * Persist repo information in local browser storage"},{"lineNumber":297,"author":{"gitId":"-"},"content":" * To retrieve after authentication redirects back to WATcher"},{"lineNumber":298,"author":{"gitId":"-"},"content":" *"},{"lineNumber":299,"author":{"gitId":"-"},"content":" * Since localStorage::setItem with an undefined value can result in"},{"lineNumber":300,"author":{"gitId":"-"},"content":" * the subsequent value being stored as a string being \u0027undefined\u0027, check"},{"lineNumber":301,"author":{"gitId":"-"},"content":" * if undefined before storing it. Let\u0027s reset the items before setting them."},{"lineNumber":302,"author":{"gitId":"-"},"content":" */"},{"lineNumber":303,"author":{"gitId":"-"},"content":" window.localStorage.removeItem(STORAGE_KEYS.ORG);"},{"lineNumber":304,"author":{"gitId":"-"},"content":" window.localStorage.removeItem(STORAGE_KEYS.DATA_REPO);"},{"lineNumber":305,"author":{"gitId":"-"},"content":""},{"lineNumber":306,"author":{"gitId":"-"},"content":" if (newRepo) {"},{"lineNumber":307,"author":{"gitId":"-"},"content":" window.localStorage.setItem(STORAGE_KEYS.ORG, newRepo.owner);"},{"lineNumber":308,"author":{"gitId":"-"},"content":" window.localStorage.setItem(STORAGE_KEYS.DATA_REPO, newRepo.name);"},{"lineNumber":309,"author":{"gitId":"-"},"content":""},{"lineNumber":310,"author":{"gitId":"-"},"content":" this.repoUrlCacheService.cache(newRepo.toString());"},{"lineNumber":311,"author":{"gitId":"-"},"content":" }"},{"lineNumber":312,"author":{"gitId":"-"},"content":" this.auth.setRepo().subscribe();"},{"lineNumber":313,"author":{"gitId":"-"},"content":" }"},{"lineNumber":314,"author":{"gitId":"-"},"content":" });"},{"lineNumber":315,"author":{"gitId":"-"},"content":" }"},{"lineNumber":316,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"nknguyenhc":12,"Arif-Khalid":9,"NereusWB922":54,"-":241}},{"path":"src/app/shared/repo-change-form/repo-change-form.component.css","fileType":"css","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":".change-repo-form-title {"},{"lineNumber":2,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"}"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":".mat-dialog-content {"},{"lineNumber":6,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"}"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":".mat-form-field {"},{"lineNumber":10,"author":{"gitId":"-"},"content":" width: 100%;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"}"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":".mat-dialog-actions {"},{"lineNumber":14,"author":{"gitId":"-"},"content":" justify-content: flex-end;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"}"},{"lineNumber":16,"author":{"gitId":"Arif-Khalid"},"content":""},{"lineNumber":17,"author":{"gitId":"Arif-Khalid"},"content":".change-repo-form-header {"},{"lineNumber":18,"author":{"gitId":"Arif-Khalid"},"content":" display: flex;"},{"lineNumber":19,"author":{"gitId":"Arif-Khalid"},"content":" justify-content: space-between;"},{"lineNumber":20,"author":{"gitId":"Arif-Khalid"},"content":"}"}],"authorContributionMap":{"Arif-Khalid":5,"-":15}},{"path":"src/app/shared/repo-change-form/repo-change-form.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"Arif-Khalid"},"content":"\u003cdiv class\u003d\"change-repo-form-header\"\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" \u003ch1 mat-dialog-title class\u003d\"change-repo-form-title\"\u003e{{ data.repoName ? \u0027Change repository\u0027 : \u0027Select repository\u0027 }}\u003c/h1\u003e"},{"lineNumber":3,"author":{"gitId":"Arif-Khalid"},"content":" \u003cmat-checkbox *ngIf\u003d\"data.repoName\" [(ngModel)]\u003d\"this.keepFilters\"\u003eKeep Filters\u003c/mat-checkbox\u003e"},{"lineNumber":4,"author":{"gitId":"Arif-Khalid"},"content":"\u003c/div\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":"\u003cdiv mat-dialog-content\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003cform (ngSubmit)\u003d\"onYesClick()\"\u003e"},{"lineNumber":7,"author":{"gitId":"-"},"content":" \u003cmat-form-field appearance\u003d\"fill\"\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003cmat-label\u003eRepository Location (Github Link or Org/Repo)\u003c/mat-label\u003e"},{"lineNumber":9,"author":{"gitId":"-"},"content":" \u003cinput matInput [(ngModel)]\u003d\"this.repoName\" [formControl]\u003d\"repoChangeForm\" [matAutocomplete]\u003d\"auto\" /\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003cmat-autocomplete #auto\u003d\"matAutocomplete\"\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003cmat-option *ngFor\u003d\"let suggestion of filteredSuggestions | async\" [value]\u003d\"suggestion\"\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" {{ suggestion }}"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003c/mat-option\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":" \u003c/mat-autocomplete\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":" \u003c/mat-form-field\u003e"},{"lineNumber":16,"author":{"gitId":"-"},"content":" \u003c/form\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":18,"author":{"gitId":"-"},"content":"\u003cdiv mat-dialog-actions\u003e"},{"lineNumber":19,"author":{"gitId":"-"},"content":" \u003cbutton mat-button (click)\u003d\"onNoClick()\" color\u003d\"warn\"\u003eCancel\u003c/button\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003cbutton mat-button (click)\u003d\"onYesClick()\" color\u003d\"primary\"\u003e{{ data.repoName ? \u0027Change Repo\u0027 : \u0027Select Repo\u0027 }}\u003c/button\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"Arif-Khalid":3,"-":18}},{"path":"src/app/shared/repo-change-form/repo-change-form.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component, Inject, OnInit } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { FormControl } from \u0027@angular/forms\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { MatDialogRef, MAT_DIALOG_DATA } from \u0027@angular/material/dialog\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":5,"author":{"gitId":"Arif-Khalid"},"content":"import { RepoChangeResponse } from \u0027../../core/models/repo-change-response.model\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { RepoUrlCacheService } from \u0027../../core/services/repo-url-cache.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":9,"author":{"gitId":"-"},"content":" selector: \u0027app-repo-change-form\u0027,"},{"lineNumber":10,"author":{"gitId":"-"},"content":" templateUrl: \u0027./repo-change-form.component.html\u0027,"},{"lineNumber":11,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./repo-change-form.component.css\u0027]"},{"lineNumber":12,"author":{"gitId":"-"},"content":"})"},{"lineNumber":13,"author":{"gitId":"-"},"content":"export class RepoChangeFormComponent implements OnInit {"},{"lineNumber":14,"author":{"gitId":"Arif-Khalid"},"content":" public repoName: string;"},{"lineNumber":15,"author":{"gitId":"Arif-Khalid"},"content":" public keepFilters: boolean;"},{"lineNumber":16,"author":{"gitId":"-"},"content":" filteredSuggestions: Observable\u003cstring[]\u003e;"},{"lineNumber":17,"author":{"gitId":"-"},"content":" repoChangeForm \u003d new FormControl();"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":" constructor("},{"lineNumber":20,"author":{"gitId":"-"},"content":" public dialogRef: MatDialogRef\u003cRepoChangeFormComponent\u003e,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" private repoUrlCacheService: RepoUrlCacheService,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Inject(MAT_DIALOG_DATA) public data"},{"lineNumber":23,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" this.repoName \u003d data.repoName;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" ngOnInit() {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" this.initRepoChangeForm();"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" private initRepoChangeForm() {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" this.filteredSuggestions \u003d this.repoUrlCacheService.getFilteredSuggestions(this.repoChangeForm);"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" onYesClick(): void {"},{"lineNumber":36,"author":{"gitId":"Arif-Khalid"},"content":" const response: RepoChangeResponse \u003d {"},{"lineNumber":37,"author":{"gitId":"Arif-Khalid"},"content":" repo: this.repoName,"},{"lineNumber":38,"author":{"gitId":"Arif-Khalid"},"content":" keepFilters: this.keepFilters"},{"lineNumber":39,"author":{"gitId":"Arif-Khalid"},"content":" };"},{"lineNumber":40,"author":{"gitId":"Arif-Khalid"},"content":" this.dialogRef.close(response);"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" onNoClick(): void {"},{"lineNumber":44,"author":{"gitId":"Arif-Khalid"},"content":" this.dialogRef.close(null);"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"Arif-Khalid":9,"-":37}},{"path":"src/test.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"// This file is required by karma.conf.js and loads recursively all the .spec and framework files"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"// tslint:disable:ordered-imports"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"// Ordered-imports rule is disabled here because the import statement for \u0027zone-testing\u0027 must be"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"// at the top to prevent test setup breakage in \u0027npm run test\u0027."},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"import \u0027zone.js/dist/zone-testing\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { getTestBed } from \u0027@angular/core/testing\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from \u0027@angular/platform-browser-dynamic/testing\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"declare const require: any;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"// First, initialize the Angular testing environment."},{"lineNumber":13,"author":{"gitId":"-"},"content":"getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());"},{"lineNumber":14,"author":{"gitId":"-"},"content":"// Then we find all the tests."},{"lineNumber":15,"author":{"gitId":"-"},"content":"const context \u003d require.context(\u0027../tests\u0027, true, /\\.spec\\.ts$/);"},{"lineNumber":16,"author":{"gitId":"-"},"content":"// And load the modules."},{"lineNumber":17,"author":{"gitId":"-"},"content":"context.keys().map(context);"}],"authorContributionMap":{"NereusWB922":4,"-":13}},{"path":"tests/app/auth/login/login.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { ComponentFixture, TestBed, waitForAsync } from \u0027@angular/core/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { LoginComponent } from \u0027../../../../src/app/auth/login/login.component\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { AuthService, AuthState } from \u0027../../../../src/app/core/services/auth.service\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { ErrorHandlingService } from \u0027../../../../src/app/core/services/error-handling.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { LoggingService } from \u0027../../../../src/app/core/services/logging.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"describe(\u0027LoginComponent\u0027, () \u003d\u003e {"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" let authServiceSpy: jasmine.SpyObj\u003cAuthService\u003e;"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" let errorHandlingServiceSpy: jasmine.SpyObj\u003cErrorHandlingService\u003e;"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" let loggingServiceSpy: jasmine.SpyObj\u003cLoggingService\u003e;"},{"lineNumber":11,"author":{"gitId":"-"},"content":" let component: LoginComponent;"},{"lineNumber":12,"author":{"gitId":"-"},"content":" let fixture: ComponentFixture\u003cLoginComponent\u003e;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":" beforeEach("},{"lineNumber":15,"author":{"gitId":"-"},"content":" waitForAsync(() \u003d\u003e {"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" authServiceSpy \u003d jasmine.createSpyObj\u003cAuthService\u003e(\u0027AuthService\u0027, [\u0027startOAuthProcess\u0027, \u0027changeAuthState\u0027]);"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" loggingServiceSpy \u003d jasmine.createSpyObj\u003cLoggingService\u003e(\u0027LoggingService\u0027, [\u0027info\u0027]);"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" errorHandlingServiceSpy \u003d jasmine.createSpyObj\u003cErrorHandlingService\u003e(\u0027ErrorHandlingService\u0027, [\u0027handleError\u0027]);"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" TestBed.configureTestingModule({"},{"lineNumber":21,"author":{"gitId":"-"},"content":" providers: ["},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" { provide: AuthService, useValue: authServiceSpy },"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" { provide: LoggingService, useValue: loggingServiceSpy },"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" { provide: ErrorHandlingService, useValue: errorHandlingServiceSpy }"},{"lineNumber":25,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":26,"author":{"gitId":"-"},"content":" declarations: [LoginComponent]"},{"lineNumber":27,"author":{"gitId":"-"},"content":" }).compileComponents();"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" fixture \u003d TestBed.createComponent(LoginComponent);"},{"lineNumber":30,"author":{"gitId":"-"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":32,"author":{"gitId":"-"},"content":" })"},{"lineNumber":33,"author":{"gitId":"-"},"content":" );"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" expect(component).toBeTruthy();"},{"lineNumber":37,"author":{"gitId":"-"},"content":" });"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" it(\u0027startPublicOnlyLoginProcess should call startLoginProcess with false\u0027, () \u003d\u003e {"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" spyOn(component, \u0027startLoginProcess\u0027);"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":" component.startPublicOnlyLoginProcess();"},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" expect(component.startLoginProcess).toHaveBeenCalledWith(false);"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" it(\u0027startIncludePrivateLoginProcess should call startLoginProcess with true\u0027, () \u003d\u003e {"},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" spyOn(component, \u0027startLoginProcess\u0027);"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" component.startIncludePrivateLoginProcess();"},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" expect(component.startLoginProcess).toHaveBeenCalledWith(true);"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should call authService.startOAuthProcess on startLoginProcess\u0027, () \u003d\u003e {"},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" const hasPrivateConsent \u003d false;"},{"lineNumber":57,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" component.startLoginProcess(hasPrivateConsent);"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":" expect(authServiceSpy.startOAuthProcess).toHaveBeenCalledWith(hasPrivateConsent);"},{"lineNumber":61,"author":{"gitId":"NereusWB922"},"content":" expect(loggingServiceSpy.info).toHaveBeenCalledWith(\u0027LoginComponent: Beginning login process\u0027);"},{"lineNumber":62,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should call error handling methods when error is thrown\u0027, () \u003d\u003e {"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":" const hasPrivateConsent \u003d false;"},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" const errorMessage \u003d \u0027Error!\u0027;"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":" const error: Error \u003d new Error(errorMessage);"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":" authServiceSpy.startOAuthProcess.and.throwError(error);"},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":71,"author":{"gitId":"NereusWB922"},"content":" component.startLoginProcess(hasPrivateConsent);"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" expect(authServiceSpy.changeAuthState).toHaveBeenCalledWith(AuthState.NotAuthenticated);"},{"lineNumber":74,"author":{"gitId":"NereusWB922"},"content":" expect(errorHandlingServiceSpy.handleError).toHaveBeenCalledWith(error);"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":" expect(loggingServiceSpy.info.calls.allArgs()).toEqual(["},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" [\u0027LoginComponent: Beginning login process\u0027],"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" [`LoginComponent: Login process failed with an error: ${error}`]"},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":" ]);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" });"},{"lineNumber":80,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"NereusWB922":49,"-":31}},{"path":"tests/app/core/models/session-model.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { of } from \u0027rxjs\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":3,"author":{"gitId":"-"},"content":" assertSessionDataIntegrity,"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":" NO_VALID_OPEN_VIEWS,"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" OPENED_VIEW_REPO_UNDEFINED,"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" SESSION_DATA_MISSING_FIELDS,"},{"lineNumber":7,"author":{"gitId":"-"},"content":" SESSION_DATA_UNAVAILABLE"},{"lineNumber":8,"author":{"gitId":"-"},"content":"} from \u0027../../../../src/app/core/models/session.model\u0027;"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"import { View } from \u0027../../../../src/app/core/models/view.model\u0027;"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"import { VALID_SESSION_DATA, WATCHER_REPO } from \u0027../../../constants/session.constants\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"describe(\u0027Session Model\u0027, () \u003d\u003e {"},{"lineNumber":13,"author":{"gitId":"-"},"content":" describe(\u0027assertSessionDataIntegrity()\u0027, () \u003d\u003e {"},{"lineNumber":14,"author":{"gitId":"-"},"content":" it(\u0027should throw error on unavailable session\u0027, () \u003d\u003e {"},{"lineNumber":15,"author":{"gitId":"-"},"content":" of(undefined)"},{"lineNumber":16,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":17,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":18,"author":{"gitId":"-"},"content":" next: () \u003d\u003e fail(),"},{"lineNumber":19,"author":{"gitId":"-"},"content":" error: (err) \u003d\u003e expect(err).toEqual(new Error(SESSION_DATA_UNAVAILABLE))"},{"lineNumber":20,"author":{"gitId":"-"},"content":" });"},{"lineNumber":21,"author":{"gitId":"-"},"content":" });"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should throw error on session data with invalid session\u0027, () \u003d\u003e {"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" of({ sessionRepo: null })"},{"lineNumber":25,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":26,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":27,"author":{"gitId":"-"},"content":" next: () \u003d\u003e fail(),"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e expect(err).toEqual(new Error(SESSION_DATA_MISSING_FIELDS))"},{"lineNumber":29,"author":{"gitId":"-"},"content":" });"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" of({ sessionRepo: [] })"},{"lineNumber":31,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":32,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":33,"author":{"gitId":"-"},"content":" next: () \u003d\u003e fail(),"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e expect(err).toEqual(new Error(SESSION_DATA_MISSING_FIELDS))"},{"lineNumber":35,"author":{"gitId":"-"},"content":" });"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" of({ sessionRepo: \u0027repo\u0027 })"},{"lineNumber":37,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":38,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":39,"author":{"gitId":"-"},"content":" next: () \u003d\u003e fail(),"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e expect(err).toEqual(new Error(SESSION_DATA_MISSING_FIELDS))"},{"lineNumber":41,"author":{"gitId":"-"},"content":" });"},{"lineNumber":42,"author":{"gitId":"-"},"content":" });"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should throw error on session with invalid views\u0027, () \u003d\u003e {"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" of({ sessionRepo: [{ view: \u0027invalidView\u0027 as View, repos: [WATCHER_REPO] }] })"},{"lineNumber":46,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":47,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":48,"author":{"gitId":"-"},"content":" next: () \u003d\u003e fail(),"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e expect(err).toEqual(new Error(NO_VALID_OPEN_VIEWS))"},{"lineNumber":50,"author":{"gitId":"-"},"content":" });"},{"lineNumber":51,"author":{"gitId":"-"},"content":" });"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should throw error on session data with invalid repo\u0027, () \u003d\u003e {"},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":" of({ sessionRepo: [{ view: View.issuesViewer, repo: undefined }] })"},{"lineNumber":55,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":56,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":57,"author":{"gitId":"-"},"content":" next: () \u003d\u003e fail(),"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e expect(err).toEqual(new Error(OPENED_VIEW_REPO_UNDEFINED))"},{"lineNumber":59,"author":{"gitId":"-"},"content":" });"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":" of({ sessionRepo: [{ view: View.issuesViewer, repo: null }] })"},{"lineNumber":61,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":62,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":63,"author":{"gitId":"-"},"content":" next: () \u003d\u003e fail(),"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e expect(err).toEqual(new Error(OPENED_VIEW_REPO_UNDEFINED))"},{"lineNumber":65,"author":{"gitId":"-"},"content":" });"},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" of({ sessionRepo: [{ view: View.issuesViewer, repo: \u0027\u0027 }] })"},{"lineNumber":67,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":68,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":69,"author":{"gitId":"-"},"content":" next: () \u003d\u003e fail(),"},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e expect(err).toEqual(new Error(OPENED_VIEW_REPO_UNDEFINED))"},{"lineNumber":71,"author":{"gitId":"-"},"content":" });"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" of({ sessionRepo: [{ view: View.issuesViewer, repo: [] }] })"},{"lineNumber":73,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":74,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":" next: () \u003d\u003e fail(),"},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e expect(err).toEqual(new Error(OPENED_VIEW_REPO_UNDEFINED))"},{"lineNumber":77,"author":{"gitId":"-"},"content":" });"},{"lineNumber":78,"author":{"gitId":"-"},"content":" });"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should pass for valid session data\u0027, () \u003d\u003e {"},{"lineNumber":81,"author":{"gitId":"NereusWB922"},"content":" of(VALID_SESSION_DATA)"},{"lineNumber":82,"author":{"gitId":"-"},"content":" .pipe(assertSessionDataIntegrity())"},{"lineNumber":83,"author":{"gitId":"NereusWB922"},"content":" .subscribe((el) \u003d\u003e expect(el).toEqual(VALID_SESSION_DATA));"},{"lineNumber":84,"author":{"gitId":"-"},"content":" });"},{"lineNumber":85,"author":{"gitId":"-"},"content":" });"},{"lineNumber":86,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"NereusWB922":28,"-":58}},{"path":"tests/app/shared/filter-bar/label-filter-bar/label-filter-bar.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { NO_ERRORS_SCHEMA } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { ComponentFixture, fakeAsync, TestBed, tick } from \u0027@angular/core/testing\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { MatSelectionList } from \u0027@angular/material/list\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { MatMenuModule } from \u0027@angular/material/menu\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import { BehaviorSubject, of } from \u0027rxjs\u0027;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"import { SimpleLabel } from \u0027../../../../../src/app/core/models/label.model\u0027;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"import { FiltersService } from \u0027../../../../../src/app/core/services/filters.service\u0027;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"import { LabelService } from \u0027../../../../../src/app/core/services/label.service\u0027;"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"import { LoggingService } from \u0027../../../../../src/app/core/services/logging.service\u0027;"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"import { LabelFilterBarComponent } from \u0027../../../../../src/app/shared/filter-bar/label-filter-bar/label-filter-bar.component\u0027;"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":"import { LABEL_NAME_SEVERITY_HIGH, LABEL_NAME_SEVERITY_LOW, SEVERITY_SIMPLE_LABELS } from \u0027../../../../constants/label.constants\u0027;"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":"describe(\u0027LabelFilterBarComponent\u0027, () \u003d\u003e {"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" let component: LabelFilterBarComponent;"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" let fixture: ComponentFixture\u003cLabelFilterBarComponent\u003e;"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" let labelServiceSpy: jasmine.SpyObj\u003cLabelService\u003e;"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" let loggingServiceSpy: jasmine.SpyObj\u003cLoggingService\u003e;"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" let filtersServiceSpy: jasmine.SpyObj\u003cFiltersService\u003e;"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" let labelsSubject: BehaviorSubject\u003cSimpleLabel[]\u003e;"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" beforeEach(async () \u003d\u003e {"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" labelServiceSpy \u003d jasmine.createSpyObj(\u0027LabelService\u0027, [\u0027connect\u0027, \u0027startPollLabels\u0027, \u0027fetchLabels\u0027]);"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" loggingServiceSpy \u003d jasmine.createSpyObj(\u0027LoggingService\u0027, [\u0027info\u0027, \u0027debug\u0027]);"},{"lineNumber":24,"author":{"gitId":"Arif-Khalid"},"content":" filtersServiceSpy \u003d jasmine.createSpyObj(\u0027FiltersService\u0027, [\u0027updateFilters\u0027, \u0027sanitizeLabels\u0027]);"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" TestBed.configureTestingModule({"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" providers: ["},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" { provide: LabelService, useValue: labelServiceSpy },"},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" { provide: LoggingService, useValue: loggingServiceSpy },"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" { provide: FiltersService, useValue: filtersServiceSpy }"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" ],"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" imports: [MatMenuModule],"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" declarations: [LabelFilterBarComponent],"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" schemas: [NO_ERRORS_SCHEMA]"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" }).compileComponents();"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":" fixture \u003d TestBed.createComponent(LabelFilterBarComponent);"},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" fixture.detectChanges();"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":" expect(component).toBeTruthy();"},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027ngAfterViewInit\u0027, () \u003d\u003e {"},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" // Setup labels observable"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":" labelsSubject \u003d new BehaviorSubject\u003cSimpleLabel[]\u003e([]);"},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" labelServiceSpy.fetchLabels.and.returnValue(of([]));"},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":" labelServiceSpy.connect.and.returnValue(labelsSubject.asObservable());"},{"lineNumber":52,"author":{"gitId":"Arif-Khalid"},"content":" filtersServiceSpy.sanitizeLabels.and.callThrough();"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":55,"author":{"gitId":"Arif-Khalid"},"content":" // it(\u0027should update allLabels with latest emmitted value after ngAfterViewInit\u0027, fakeAsync(() \u003d\u003e {"},{"lineNumber":56,"author":{"gitId":"Arif-Khalid"},"content":" // component.ngAfterViewInit();"},{"lineNumber":57,"author":{"gitId":"Arif-Khalid"},"content":" // tick();"},{"lineNumber":58,"author":{"gitId":"Arif-Khalid"},"content":" // labelsSubject.next(SEVERITY_SIMPLE_LABELS);"},{"lineNumber":59,"author":{"gitId":"Arif-Khalid"},"content":" // expect(component.allLabels).toEqual(SEVERITY_SIMPLE_LABELS);"},{"lineNumber":60,"author":{"gitId":"Arif-Khalid"},"content":" // }));"},{"lineNumber":61,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":62,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027hide(label)\u0027, () \u003d\u003e {"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should add label to hidden labels set and update filter\u0027, () \u003d\u003e {"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":" const label \u003d LABEL_NAME_SEVERITY_HIGH;"},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" expect(component.hiddenLabelNames).not.toContain(label);"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":" component.hide(label);"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":" expect(component.hiddenLabelNames).toContain(label);"},{"lineNumber":71,"author":{"gitId":"NereusWB922"},"content":" expect(filtersServiceSpy.updateFilters).toHaveBeenCalledWith({ hiddenLabels: component.hiddenLabelNames });"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":74,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027show(label)\u0027, () \u003d\u003e {"},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should remove label from hidden labels set and update filter\u0027, () \u003d\u003e {"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" const label \u003d LABEL_NAME_SEVERITY_HIGH;"},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":" component.hide(label);"},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":" expect(component.hiddenLabelNames).toContain(label);"},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":81,"author":{"gitId":"NereusWB922"},"content":" component.show(label);"},{"lineNumber":82,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":83,"author":{"gitId":"NereusWB922"},"content":" expect(component.hiddenLabelNames).not.toContain(label);"},{"lineNumber":84,"author":{"gitId":"NereusWB922"},"content":" expect(filtersServiceSpy.updateFilters).toHaveBeenCalledWith({ hiddenLabels: component.hiddenLabelNames });"},{"lineNumber":85,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":86,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":87,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":88,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027hasLabels\u0027, () \u003d\u003e {"},{"lineNumber":89,"author":{"gitId":"NereusWB922"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":90,"author":{"gitId":"NereusWB922"},"content":" component.allLabels \u003d SEVERITY_SIMPLE_LABELS;"},{"lineNumber":91,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":92,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":93,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should return true if any label match the filter\u0027, () \u003d\u003e {"},{"lineNumber":94,"author":{"gitId":"NereusWB922"},"content":" const filter \u003d \u0027low\u0027;"},{"lineNumber":95,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":96,"author":{"gitId":"NereusWB922"},"content":" const result \u003d component.hasLabels(filter);"},{"lineNumber":97,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":98,"author":{"gitId":"NereusWB922"},"content":" expect(result).toBeTrue();"},{"lineNumber":99,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":100,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":101,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should return false if no label match the filter\u0027, () \u003d\u003e {"},{"lineNumber":102,"author":{"gitId":"NereusWB922"},"content":" const filter \u003d \u0027priority\u0027;"},{"lineNumber":103,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":104,"author":{"gitId":"NereusWB922"},"content":" const result \u003d component.hasLabels(filter);"},{"lineNumber":105,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":106,"author":{"gitId":"NereusWB922"},"content":" expect(result).toBeFalse();"},{"lineNumber":107,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":108,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":109,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should return false if no label exists\u0027, () \u003d\u003e {"},{"lineNumber":110,"author":{"gitId":"NereusWB922"},"content":" const filter \u003d \u0027low\u0027;"},{"lineNumber":111,"author":{"gitId":"NereusWB922"},"content":" component.allLabels \u003d [];"},{"lineNumber":112,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":113,"author":{"gitId":"NereusWB922"},"content":" const result \u003d component.hasLabels(filter);"},{"lineNumber":114,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":115,"author":{"gitId":"NereusWB922"},"content":" expect(result).toBeFalse();"},{"lineNumber":116,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":117,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":118,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":119,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027updateSelection\u0027, () \u003d\u003e {"},{"lineNumber":120,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should update filters service with selected labels\u0027, () \u003d\u003e {"},{"lineNumber":121,"author":{"gitId":"NereusWB922"},"content":" const selectedLabels \u003d [LABEL_NAME_SEVERITY_HIGH, LABEL_NAME_SEVERITY_LOW];"},{"lineNumber":122,"author":{"gitId":"nknguyenhc"},"content":" component.selectedLabelNames \u003d new Set\u003cstring\u003e(selectedLabels);"},{"lineNumber":123,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":124,"author":{"gitId":"nknguyenhc"},"content":" component.updateSelection();"},{"lineNumber":125,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":126,"author":{"gitId":"nknguyenhc"},"content":" expect(filtersServiceSpy.updateFilters).toHaveBeenCalledWith({ labels: selectedLabels, deselectedLabels: new Set\u003cstring\u003e() });"},{"lineNumber":127,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":128,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":129,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":130,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027removeAllSelection\u0027, () \u003d\u003e {"},{"lineNumber":131,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should deselect all labels and update the filter\u0027, () \u003d\u003e {"},{"lineNumber":132,"author":{"gitId":"NereusWB922"},"content":" component.removeAllSelection();"},{"lineNumber":133,"author":{"gitId":"nknguyenhc"},"content":" expect(component.selectedLabelNames).toEqual(new Set\u003cstring\u003e());"},{"lineNumber":134,"author":{"gitId":"nknguyenhc"},"content":" expect(component.deselectedLabelNames).toEqual(new Set\u003cstring\u003e());"},{"lineNumber":135,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":136,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":137,"author":{"gitId":"NereusWB922"},"content":"});"}],"authorContributionMap":{"nknguyenhc":5,"NereusWB922":124,"Arif-Khalid":8}},{"path":"tests/app/shared/issue-tables/issue-paginator.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { MatPaginator } from \u0027@angular/material/paginator\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Issue } from \u0027../../../../src/app/core/models/issue.model\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { paginateData } from \u0027../../../../src/app/shared/issue-tables/issue-paginator\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":5,"author":{"gitId":"-"},"content":" ISSUE_WITH_ASSIGNEES,"},{"lineNumber":6,"author":{"gitId":"-"},"content":" ISSUE_WITH_EMPTY_DESCRIPTION,"},{"lineNumber":7,"author":{"gitId":"-"},"content":" ISSUE_WITH_EMPTY_DESCRIPTION_HIGH_SEVERITY,"},{"lineNumber":8,"author":{"gitId":"-"},"content":" ISSUE_WITH_EMPTY_DESCRIPTION_LOW_SEVERITY"},{"lineNumber":9,"author":{"gitId":"-"},"content":"} from \u0027../../../constants/githubissue.constants\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"describe(\u0027issue-paginator\u0027, () \u003d\u003e {"},{"lineNumber":12,"author":{"gitId":"-"},"content":" describe(\u0027paginateData()\u0027, () \u003d\u003e {"},{"lineNumber":13,"author":{"gitId":"-"},"content":" let dataSet_7: Issue[];"},{"lineNumber":14,"author":{"gitId":"-"},"content":" let paginator: MatPaginator;"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" const mediumSeverityIssueWithResponse: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_EMPTY_DESCRIPTION);"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" const mediumSeverityIssueWithAssigneee: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_ASSIGNEES);"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" const lowSeverityFeatureFlawIssue: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_EMPTY_DESCRIPTION_LOW_SEVERITY);"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" const highSeverityDocumentationBugIssue: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_EMPTY_DESCRIPTION_HIGH_SEVERITY);"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":21,"author":{"gitId":"-"},"content":" dataSet_7 \u003d ["},{"lineNumber":22,"author":{"gitId":"-"},"content":" mediumSeverityIssueWithResponse,"},{"lineNumber":23,"author":{"gitId":"-"},"content":" mediumSeverityIssueWithAssigneee,"},{"lineNumber":24,"author":{"gitId":"-"},"content":" lowSeverityFeatureFlawIssue,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" mediumSeverityIssueWithResponse,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" mediumSeverityIssueWithAssigneee,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" lowSeverityFeatureFlawIssue,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" highSeverityDocumentationBugIssue"},{"lineNumber":29,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":30,"author":{"gitId":"-"},"content":" paginator \u003d { pageSize: 3 } as MatPaginator;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" });"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" it(\u0027should set the length of paginator to the length of data\u0027, () \u003d\u003e {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" paginateData(paginator, dataSet_7);"},{"lineNumber":35,"author":{"gitId":"-"},"content":" expect(paginator.length).toEqual(7);"},{"lineNumber":36,"author":{"gitId":"-"},"content":" });"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" it(\u0027should return list of issues according to page index\u0027, () \u003d\u003e {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" paginator.pageIndex \u003d 0;"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" // Returns issues index 0 to 2"},{"lineNumber":42,"author":{"gitId":"-"},"content":" const returnedList \u003d paginateData(paginator, dataSet_7);"},{"lineNumber":43,"author":{"gitId":"-"},"content":" expect(returnedList).toEqual([mediumSeverityIssueWithResponse, mediumSeverityIssueWithAssigneee, lowSeverityFeatureFlawIssue]);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" });"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" it(\u0027should return list of issues in the previous page if there are no issues on the current page\u0027, () \u003d\u003e {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" paginator.pageIndex \u003d 3;"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" // Returns issues index 6 on page 2"},{"lineNumber":50,"author":{"gitId":"-"},"content":" const returnedList \u003d paginateData(paginator, dataSet_7);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" expect(returnedList).toEqual([highSeverityDocumentationBugIssue]);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" });"},{"lineNumber":53,"author":{"gitId":"-"},"content":" });"},{"lineNumber":54,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"NereusWB922":4,"-":50}},{"path":"tests/app/shared/issue-tables/issue-sorter.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { MatSort } from \u0027@angular/material/sort\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Issue } from \u0027../../../../src/app/core/models/issue.model\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { applySort } from \u0027../../../../src/app/shared/issue-tables/issue-sorter\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import {"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" ISSUE_UPDATED_EARLIER,"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" ISSUE_UPDATED_LATER,"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" ISSUE_WITH_ASSIGNEES,"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" ISSUE_WITH_EMPTY_DESCRIPTION"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"} from \u0027../../../constants/githubissue.constants\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"describe(\u0027issuer-sorter\u0027, () \u003d\u003e {"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027applySort()\u0027, () \u003d\u003e {"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" const dummyIssue: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_EMPTY_DESCRIPTION);"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" const otherDummyIssue: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_ASSIGNEES);"},{"lineNumber":15,"author":{"gitId":"-"},"content":" const issuesList: Issue[] \u003d [dummyIssue, otherDummyIssue];"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" const issueUpdatedEarlier: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_UPDATED_EARLIER);"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" const issueUpdatedLater: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_UPDATED_LATER);"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" const issuesWithDifferentUpdatedDate: Issue[] \u003d [issueUpdatedEarlier, issueUpdatedLater];"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" const matSort: MatSort \u003d new MatSort();"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should return the same data if sort.active is not set\u0027, () \u003d\u003e {"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" const sortedData \u003d applySort(matSort, issuesList);"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" expect(sortedData).toEqual(issuesList);"},{"lineNumber":26,"author":{"gitId":"-"},"content":" });"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" it(\u0027sorts issues based on their string fields correctly\u0027, () \u003d\u003e {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" matSort.active \u003d \u0027title\u0027;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" matSort.direction \u003d \u0027asc\u0027;"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" const sortedIssuesByTitleAsc \u003d applySort(matSort, issuesList);"},{"lineNumber":32,"author":{"gitId":"-"},"content":" assertOrder(sortedIssuesByTitleAsc, dummyIssue, otherDummyIssue);"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" matSort.direction \u003d \u0027desc\u0027;"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" const sortedIssuesByTitleDesc \u003d applySort(matSort, issuesList);"},{"lineNumber":36,"author":{"gitId":"-"},"content":" assertOrder(sortedIssuesByTitleDesc, otherDummyIssue, dummyIssue);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" });"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" it(\u0027sorts issues based on their id fields correctly\u0027, () \u003d\u003e {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" matSort.active \u003d \u0027id\u0027;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" matSort.direction \u003d \u0027asc\u0027;"},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":" const sortedIssuedByIdAsc \u003d applySort(matSort, issuesList);"},{"lineNumber":43,"author":{"gitId":"-"},"content":" assertOrder(sortedIssuedByIdAsc, otherDummyIssue, dummyIssue);"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" matSort.direction \u003d \u0027desc\u0027;"},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":" const sortedIssuedByIdDesc \u003d applySort(matSort, issuesList);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" assertOrder(sortedIssuedByIdDesc, dummyIssue, otherDummyIssue);"},{"lineNumber":48,"author":{"gitId":"-"},"content":" });"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" it(\u0027sorts issues based on their updated date fields correctly\u0027, () \u003d\u003e {"},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":" matSort.active \u003d \u0027date\u0027;"},{"lineNumber":52,"author":{"gitId":"-"},"content":" matSort.direction \u003d \u0027asc\u0027;"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":" const sortedIssuedByDateAsc \u003d applySort(matSort, issuesWithDifferentUpdatedDate);"},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" assertOrder(sortedIssuedByDateAsc, issueUpdatedEarlier, issueUpdatedLater);"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" matSort.direction \u003d \u0027desc\u0027;"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" const sortedIssuedByDateDesc \u003d applySort(matSort, issuesWithDifferentUpdatedDate);"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" assertOrder(sortedIssuedByDateDesc, issueUpdatedLater, issueUpdatedEarlier);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" });"},{"lineNumber":61,"author":{"gitId":"-"},"content":" });"},{"lineNumber":62,"author":{"gitId":"-"},"content":"});"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":65,"author":{"gitId":"-"},"content":" * This helper method helps to check if the sorted issues are in their"},{"lineNumber":66,"author":{"gitId":"-"},"content":" * correct order based on the variable arguments provided."},{"lineNumber":67,"author":{"gitId":"-"},"content":" */"},{"lineNumber":68,"author":{"gitId":"-"},"content":"function assertOrder(sortedIssues: Issue[], ...expectedSortedIssues: Issue[]) {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" for (let i \u003d 0; i \u003c sortedIssues.length; i++) {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" expect(sortedIssues[i].id).toBe(expectedSortedIssues[i].id);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"NereusWB922":28,"-":44}},{"path":"tests/app/shared/issue-tables/search-filter.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Issue } from \u0027../../../../src/app/core/models/issue.model\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { IssueService } from \u0027../../../../src/app/core/services/issue.service\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { TABLE_COLUMNS } from \u0027../../../../src/app/shared/issue-tables/issue-tables-columns\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { applySearchFilter } from \u0027../../../../src/app/shared/issue-tables/search-filter\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { USER_ANUBHAV } from \u0027../../../constants/data.constants\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":7,"author":{"gitId":"-"},"content":" ISSUE_WITH_ASSIGNEES,"},{"lineNumber":8,"author":{"gitId":"-"},"content":" ISSUE_WITH_EMPTY_DESCRIPTION,"},{"lineNumber":9,"author":{"gitId":"-"},"content":" ISSUE_WITH_EMPTY_DESCRIPTION_HIGH_SEVERITY,"},{"lineNumber":10,"author":{"gitId":"-"},"content":" ISSUE_WITH_EMPTY_DESCRIPTION_LOW_SEVERITY"},{"lineNumber":11,"author":{"gitId":"-"},"content":"} from \u0027../../../constants/githubissue.constants\u0027;"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":"import { GITHUB_LABEL_FEATURE_FLAW } from \u0027../../../constants/githublabel.constants\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"describe(\u0027search-filter\u0027, () \u003d\u003e {"},{"lineNumber":15,"author":{"gitId":"-"},"content":" describe(\u0027applySearchFilter()\u0027, () \u003d\u003e {"},{"lineNumber":16,"author":{"gitId":"-"},"content":" let searchKey: string;"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" const mediumSeverityIssueWithResponse: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_EMPTY_DESCRIPTION);"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" const mediumSeverityIssueWithAssigneee: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_ASSIGNEES);"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" const lowSeverityFeatureFlawIssue: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_EMPTY_DESCRIPTION_LOW_SEVERITY);"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" const highSeverityDocumentationBugIssue: Issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_EMPTY_DESCRIPTION_HIGH_SEVERITY);"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" const issuesList: Issue[] \u003d ["},{"lineNumber":23,"author":{"gitId":"-"},"content":" mediumSeverityIssueWithResponse,"},{"lineNumber":24,"author":{"gitId":"-"},"content":" mediumSeverityIssueWithAssigneee,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" lowSeverityFeatureFlawIssue,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" highSeverityDocumentationBugIssue"},{"lineNumber":27,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" const displayedColumns: string[] \u003d [TABLE_COLUMNS.ID, TABLE_COLUMNS.TITLE, TABLE_COLUMNS.ASSIGNEE, TABLE_COLUMNS.LABEL];"},{"lineNumber":29,"author":{"gitId":"-"},"content":" const issueService: IssueService \u003d new IssueService(null, null, null);"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" it(\u0027can filter for issues which are assigned to a specific user\u0027, () \u003d\u003e {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" searchKey \u003d USER_ANUBHAV.loginId;"},{"lineNumber":33,"author":{"gitId":"-"},"content":" expect(applySearchFilter(searchKey, displayedColumns, issueService, issuesList)).toEqual([mediumSeverityIssueWithAssigneee]);"},{"lineNumber":34,"author":{"gitId":"-"},"content":" });"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" it(\u0027can filter for issues using label\u0027, () \u003d\u003e {"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":" searchKey \u003d GITHUB_LABEL_FEATURE_FLAW.name;"},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" expect(applySearchFilter(searchKey, displayedColumns, issueService, issuesList)).toEqual([lowSeverityFeatureFlawIssue]);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" });"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" it(\u0027can filter for issues that contain the search key in any other column\u0027, () \u003d\u003e {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" // Search by id of issue"},{"lineNumber":43,"author":{"gitId":"-"},"content":" searchKey \u003d mediumSeverityIssueWithResponse.id.toString();"},{"lineNumber":44,"author":{"gitId":"-"},"content":" expect(applySearchFilter(searchKey, displayedColumns, issueService, issuesList)).toEqual([mediumSeverityIssueWithResponse]);"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" // Search by title of issue"},{"lineNumber":47,"author":{"gitId":"-"},"content":" searchKey \u003d mediumSeverityIssueWithAssigneee.title;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" expect(applySearchFilter(searchKey, displayedColumns, issueService, issuesList)).toEqual([mediumSeverityIssueWithAssigneee]);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" });"},{"lineNumber":50,"author":{"gitId":"-"},"content":" });"},{"lineNumber":51,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"NereusWB922":9,"-":42}},{"path":"tests/constants/data.constants.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { UserRole } from \u0027../../src/app/core/models/user.model\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"export const csvString \u003d"},{"lineNumber":4,"author":{"gitId":"-"},"content":" `"},{"lineNumber":5,"author":{"gitId":"-"},"content":"role,name,team"},{"lineNumber":6,"author":{"gitId":"-"},"content":"student,JunWei96,CS2103T-W12-3"},{"lineNumber":7,"author":{"gitId":"-"},"content":"admin,damithc,"},{"lineNumber":8,"author":{"gitId":"-"},"content":"tutor,anubh-v,CS2103T-W12-3"},{"lineNumber":9,"author":{"gitId":"-"},"content":"admin,geshuming,"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"tutor,jj-lim,CS2103T-W12-3"},{"lineNumber":12,"author":{"gitId":"-"},"content":"tutor,jj-lim,CS2103T-W12-3"},{"lineNumber":13,"author":{"gitId":"-"},"content":"tutor,jj-lim,CS2103T-W12-4"},{"lineNumber":14,"author":{"gitId":"-"},"content":"tutor,q ,CS2103T-W12-4"},{"lineNumber":15,"author":{"gitId":"-"},"content":"student,003-samuel,CS2103T-W12-3"},{"lineNumber":16,"author":{"gitId":"-"},"content":"student,damithc,CS2103T-W12-3"},{"lineNumber":17,"author":{"gitId":"-"},"content":"student,RonakLakhotia,CS2103T-W12-4"},{"lineNumber":18,"author":{"gitId":"-"},"content":"student,ptvrajsk,CS2103T-W12-3` + ` `;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"// jsonData is a json representation of csvString"},{"lineNumber":21,"author":{"gitId":"-"},"content":"export const jsonData \u003d {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" roles: {"},{"lineNumber":23,"author":{"gitId":"-"},"content":" students: {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" junwei96: \u0027true\u0027,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u0027003-samuel\u0027: \u0027true\u0027,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" damithc: \u0027true\u0027,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" ronaklakhotia: \u0027true\u0027,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" ptvrajsk: \u0027true\u0027"},{"lineNumber":29,"author":{"gitId":"-"},"content":" },"},{"lineNumber":30,"author":{"gitId":"-"},"content":" tutors: { \u0027anubh-v\u0027: \u0027true\u0027, \u0027jj-lim\u0027: \u0027true\u0027, q: \u0027true\u0027 },"},{"lineNumber":31,"author":{"gitId":"-"},"content":" admins: { damithc: \u0027true\u0027, geshuming: \u0027true\u0027 }"},{"lineNumber":32,"author":{"gitId":"-"},"content":" },"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u0027team-structure\u0027: {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u0027CS2103T-W12-3\u0027: {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" junwei96: \u0027JunWei96\u0027,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" \u0027003-samuel\u0027: \u0027003-samuel\u0027,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" damithc: \u0027damithc\u0027,"},{"lineNumber":38,"author":{"gitId":"-"},"content":" ptvrajsk: \u0027ptvrajsk\u0027"},{"lineNumber":39,"author":{"gitId":"-"},"content":" },"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u0027CS2103T-W12-4\u0027: { ronaklakhotia: \u0027RonakLakhotia\u0027 }"},{"lineNumber":41,"author":{"gitId":"-"},"content":" },"},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u0027students-allocation\u0027: {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" junwei96: { teamId: \u0027CS2103T-W12-3\u0027 },"},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u0027003-samuel\u0027: { teamId: \u0027CS2103T-W12-3\u0027 },"},{"lineNumber":45,"author":{"gitId":"-"},"content":" damithc: { teamId: \u0027CS2103T-W12-3\u0027 },"},{"lineNumber":46,"author":{"gitId":"-"},"content":" ronaklakhotia: { teamId: \u0027CS2103T-W12-4\u0027 },"},{"lineNumber":47,"author":{"gitId":"-"},"content":" ptvrajsk: { teamId: \u0027CS2103T-W12-3\u0027 }"},{"lineNumber":48,"author":{"gitId":"-"},"content":" },"},{"lineNumber":49,"author":{"gitId":"-"},"content":" \u0027tutors-allocation\u0027: {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" \u0027anubh-v\u0027: { \u0027CS2103T-W12-3\u0027: \u0027true\u0027 },"},{"lineNumber":51,"author":{"gitId":"-"},"content":" \u0027jj-lim\u0027: { \u0027CS2103T-W12-3\u0027: \u0027true\u0027, \u0027CS2103T-W12-4\u0027: \u0027true\u0027 },"},{"lineNumber":52,"author":{"gitId":"-"},"content":" q: { \u0027CS2103T-W12-4\u0027: \u0027true\u0027 }"},{"lineNumber":53,"author":{"gitId":"-"},"content":" },"},{"lineNumber":54,"author":{"gitId":"-"},"content":" \u0027admins-allocation\u0027: { damithc: {}, geshuming: {} }"},{"lineNumber":55,"author":{"gitId":"-"},"content":"};"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":"export const USER_JUNWEI \u003d {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" loginId: \u0027JunWei96\u0027,"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" role: UserRole.Student"},{"lineNumber":60,"author":{"gitId":"-"},"content":"};"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":"export const USER_ANUBHAV \u003d {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" loginId: \u0027anubh-v\u0027,"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" role: UserRole.Student"},{"lineNumber":65,"author":{"gitId":"-"},"content":"};"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":"export const USER_Q \u003d {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" loginId: \u0027q\u0027,"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":" role: UserRole.Tutor"},{"lineNumber":70,"author":{"gitId":"-"},"content":"};"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":"export const USER_SHUMING \u003d {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" loginId: \u0027geshuming\u0027,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" role: UserRole.Admin,"},{"lineNumber":75,"author":{"gitId":"-"},"content":" allocatedTeams: []"},{"lineNumber":76,"author":{"gitId":"-"},"content":"};"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":"export const USER_WITH_TWO_ROLES \u003d {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" loginId: \u0027damithc\u0027,"},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":" role: UserRole.Admin"},{"lineNumber":81,"author":{"gitId":"-"},"content":"};"}],"authorContributionMap":{"NereusWB922":4,"-":77}},{"path":"tests/constants/error.constants.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"MadLamprey"},"content":"import { HttpErrorResponse } from \u0027@angular/common/http\u0027;"},{"lineNumber":2,"author":{"gitId":"MadLamprey"},"content":"import { RequestError } from \u0027@octokit/request-error\u0027;"},{"lineNumber":3,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":4,"author":{"gitId":"MadLamprey"},"content":"export const STANDARD_ERROR \u003d new Error(\u0027This is a normal error\u0027);"},{"lineNumber":5,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":6,"author":{"gitId":"MadLamprey"},"content":"export const ERROR_WITH_NO_MESSAGE \u003d new Error();"},{"lineNumber":7,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":8,"author":{"gitId":"MadLamprey"},"content":"export const HTTP_304_ERROR \u003d new HttpErrorResponse({ status: 304 });"},{"lineNumber":9,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":10,"author":{"gitId":"MadLamprey"},"content":"export const HTTP_422_ERROR \u003d new HttpErrorResponse({ status: 422 });"},{"lineNumber":11,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":12,"author":{"gitId":"MadLamprey"},"content":"export const HTTP_500_ERROR \u003d new HttpErrorResponse({ status: 500 });"},{"lineNumber":13,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":14,"author":{"gitId":"MadLamprey"},"content":"export const HTTP_400_ERROR \u003d new HttpErrorResponse({ status: 400 });"},{"lineNumber":15,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":16,"author":{"gitId":"MadLamprey"},"content":"export const HTTP_401_ERROR \u003d new HttpErrorResponse({ status: 401 });"},{"lineNumber":17,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":18,"author":{"gitId":"MadLamprey"},"content":"export const HTTP_404_ERROR \u003d new HttpErrorResponse({ status: 404 });"},{"lineNumber":19,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":20,"author":{"gitId":"MadLamprey"},"content":"export const HTTP_UNKNOWN_ERROR \u003d new HttpErrorResponse({ status: 999 });"},{"lineNumber":21,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":22,"author":{"gitId":"MadLamprey"},"content":"export const OCTOKIT_REQUEST_ERROR \u003d new RequestError(\u0027This is an octokit request error\u0027, 400, {"},{"lineNumber":23,"author":{"gitId":"MadLamprey"},"content":" request: { method: \u0027GET\u0027, url: \u0027\u0027, headers: {} }"},{"lineNumber":24,"author":{"gitId":"MadLamprey"},"content":"});"}],"authorContributionMap":{"MadLamprey":24}},{"path":"tests/constants/githubissue.constants.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { IssueState, IssueStateReason } from \u0027../../graphql/graphql-types\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { GithubIssue } from \u0027../../src/app/core/models/github/github-issue.model\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { GithubLabel } from \u0027../../src/app/core/models/github/github-label.model\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { USER_ANUBHAV } from \u0027./data.constants\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import { EMPTY_TEAM_RESPONSE } from \u0027./githubcomment.constants\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":7,"author":{"gitId":"-"},"content":" GITHUB_LABEL_DOCUMENTATION_BUG,"},{"lineNumber":8,"author":{"gitId":"-"},"content":" GITHUB_LABEL_FEATURE_FLAW,"},{"lineNumber":9,"author":{"gitId":"-"},"content":" GITHUB_LABEL_FUNCTIONALITY_BUG,"},{"lineNumber":10,"author":{"gitId":"-"},"content":" GITHUB_LABEL_HIGH_SEVERITY,"},{"lineNumber":11,"author":{"gitId":"-"},"content":" GITHUB_LABEL_LOW_SEVERITY,"},{"lineNumber":12,"author":{"gitId":"-"},"content":" GITHUB_LABEL_MEDIUM_SEVERITY,"},{"lineNumber":13,"author":{"gitId":"-"},"content":" GITHUB_LABEL_TEAM_LABEL,"},{"lineNumber":14,"author":{"gitId":"-"},"content":" GITHUB_LABEL_TUTORIAL_LABEL"},{"lineNumber":15,"author":{"gitId":"-"},"content":"} from \u0027./githublabel.constants\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"const randomId: () \u003d\u003e string \u003d () \u003d\u003e {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" return Math.floor(Math.random() * 1000000000).toString();"},{"lineNumber":19,"author":{"gitId":"-"},"content":"};"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"const randomIssueNumber: () \u003d\u003e number \u003d () \u003d\u003e {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" return Math.round(Math.random() * 1000);"},{"lineNumber":23,"author":{"gitId":"-"},"content":"};"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":"const randomISODate: (startDate?: Date, endDate?: Date) \u003d\u003e string \u003d ("},{"lineNumber":26,"author":{"gitId":"-"},"content":" startDate: Date \u003d new Date(2020, 1, 1),"},{"lineNumber":27,"author":{"gitId":"-"},"content":" endDate: Date \u003d new Date()"},{"lineNumber":28,"author":{"gitId":"-"},"content":") \u003d\u003e {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" return new Date(startDate.getTime() + Math.random() * (startDate.getTime() - endDate.getTime())).toISOString();"},{"lineNumber":30,"author":{"gitId":"-"},"content":"};"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":"const USER_ANUBHAV_DETAILS \u003d {"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" login: USER_ANUBHAV.loginId"},{"lineNumber":34,"author":{"gitId":"-"},"content":"};"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":"export const MILESTONE_ONE \u003d {"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":" number: \u00271\u0027,"},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" title: \u0027Milestone 1\u0027,"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" state: \u0027Open\u0027"},{"lineNumber":40,"author":{"gitId":"-"},"content":"};"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":"export const ISSUE_WITH_EMPTY_DESCRIPTION \u003d new GithubIssue({"},{"lineNumber":43,"author":{"gitId":"-"},"content":" id: \u0027574085971\u0027,"},{"lineNumber":44,"author":{"gitId":"-"},"content":" number: 92,"},{"lineNumber":45,"author":{"gitId":"-"},"content":" assignees: [],"},{"lineNumber":46,"author":{"gitId":"-"},"content":" body: \u0027\u0027,"},{"lineNumber":47,"author":{"gitId":"-"},"content":" created_at: \u00272020-03-02T16:19:02Z\u0027,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" labels: [GITHUB_LABEL_TEAM_LABEL, GITHUB_LABEL_TUTORIAL_LABEL, GITHUB_LABEL_FUNCTIONALITY_BUG, GITHUB_LABEL_MEDIUM_SEVERITY],"},{"lineNumber":49,"author":{"gitId":"-"},"content":" state: IssueState.Open,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" stateReason: IssueStateReason.Reopened,"},{"lineNumber":51,"author":{"gitId":"-"},"content":" title: \u0027App starts to lag when given large amount of input\u0027,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" updated_at: \u00272020-03-13T13:37:32Z\u0027,"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" closed_at: \u0027\u0027,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" url: \u0027https://api.github.com/repos/CATcher-org/pe-results/issues/92\u0027,"},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" user: USER_ANUBHAV_DETAILS,"},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" milestone: MILESTONE_ONE,"},{"lineNumber":57,"author":{"gitId":"NereusWB922"},"content":" comments: [],"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" issueOrPr: \u0027Issue\u0027,"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" isDraft: false"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":"});"},{"lineNumber":61,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":62,"author":{"gitId":"NereusWB922"},"content":"export const CLOSED_ISSUE_WITH_EMPTY_DESCRIPTION \u003d new GithubIssue({"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" id: \u0027574085971\u0027,"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" number: 92,"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":" assignees: [],"},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" body: \u0027\u0027,"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":" created_at: \u00272020-03-02T16:19:02Z\u0027,"},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":" labels: [GITHUB_LABEL_TEAM_LABEL, GITHUB_LABEL_TUTORIAL_LABEL, GITHUB_LABEL_FUNCTIONALITY_BUG, GITHUB_LABEL_MEDIUM_SEVERITY],"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":" state: IssueState.Closed,"},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":" stateReason: IssueStateReason.Completed,"},{"lineNumber":71,"author":{"gitId":"NereusWB922"},"content":" title: \u0027App starts to lag when given large amount of input\u0027,"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":" updated_at: \u00272020-03-13T13:37:32Z\u0027,"},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" closed_at: \u00272020-03-22T15:37:32Z\u0027,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" url: \u0027https://api.github.com/repos/CATcher-org/pe-results/issues/92\u0027,"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":" user: USER_ANUBHAV_DETAILS,"},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" milestone: MILESTONE_ONE,"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" comments: [],"},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":" issueOrPr: \u0027Issue\u0027,"},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":" isDraft: false"},{"lineNumber":80,"author":{"gitId":"-"},"content":"});"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"NereusWB922"},"content":"export const ISSUE_UPDATED_EARLIER \u003d new GithubIssue({"},{"lineNumber":83,"author":{"gitId":"NereusWB922"},"content":" id: \u0027000000001\u0027,"},{"lineNumber":84,"author":{"gitId":"NereusWB922"},"content":" number: 1,"},{"lineNumber":85,"author":{"gitId":"NereusWB922"},"content":" assignees: [],"},{"lineNumber":86,"author":{"gitId":"NereusWB922"},"content":" body: \u0027\u0027,"},{"lineNumber":87,"author":{"gitId":"NereusWB922"},"content":" created_at: \u00272020-09-02T16:19:02Z\u0027,"},{"lineNumber":88,"author":{"gitId":"NereusWB922"},"content":" labels: [GITHUB_LABEL_TEAM_LABEL, GITHUB_LABEL_TUTORIAL_LABEL, GITHUB_LABEL_FUNCTIONALITY_BUG, GITHUB_LABEL_MEDIUM_SEVERITY],"},{"lineNumber":89,"author":{"gitId":"NereusWB922"},"content":" state: IssueState.Open,"},{"lineNumber":90,"author":{"gitId":"NereusWB922"},"content":" stateReason: IssueStateReason.Reopened,"},{"lineNumber":91,"author":{"gitId":"NereusWB922"},"content":" title: \u0027App starts to lag when given large amount of input\u0027,"},{"lineNumber":92,"author":{"gitId":"NereusWB922"},"content":" updated_at: \u00272020-09-03T13:37:32Z\u0027,"},{"lineNumber":93,"author":{"gitId":"NereusWB922"},"content":" closed_at: \u0027\u0027,"},{"lineNumber":94,"author":{"gitId":"NereusWB922"},"content":" url: \u0027https://api.github.com/repos/CATcher-org/pe-results/issues/93\u0027,"},{"lineNumber":95,"author":{"gitId":"NereusWB922"},"content":" user: USER_ANUBHAV_DETAILS,"},{"lineNumber":96,"author":{"gitId":"NereusWB922"},"content":" milestone: MILESTONE_ONE,"},{"lineNumber":97,"author":{"gitId":"NereusWB922"},"content":" comments: [],"},{"lineNumber":98,"author":{"gitId":"NereusWB922"},"content":" issueOrPr: \u0027Issue\u0027,"},{"lineNumber":99,"author":{"gitId":"NereusWB922"},"content":" isDraft: false"},{"lineNumber":100,"author":{"gitId":"NereusWB922"},"content":"});"},{"lineNumber":101,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":102,"author":{"gitId":"NereusWB922"},"content":"export const ISSUE_UPDATED_LATER \u003d new GithubIssue({"},{"lineNumber":103,"author":{"gitId":"NereusWB922"},"content":" id: \u0027000000002\u0027,"},{"lineNumber":104,"author":{"gitId":"NereusWB922"},"content":" number: 2,"},{"lineNumber":105,"author":{"gitId":"NereusWB922"},"content":" assignees: [],"},{"lineNumber":106,"author":{"gitId":"NereusWB922"},"content":" body: \u0027\u0027,"},{"lineNumber":107,"author":{"gitId":"NereusWB922"},"content":" created_at: \u00272020-10-02T16:19:02Z\u0027,"},{"lineNumber":108,"author":{"gitId":"NereusWB922"},"content":" labels: [GITHUB_LABEL_TEAM_LABEL, GITHUB_LABEL_TUTORIAL_LABEL, GITHUB_LABEL_FUNCTIONALITY_BUG, GITHUB_LABEL_MEDIUM_SEVERITY],"},{"lineNumber":109,"author":{"gitId":"NereusWB922"},"content":" state: IssueState.Open,"},{"lineNumber":110,"author":{"gitId":"NereusWB922"},"content":" stateReason: IssueStateReason.Reopened,"},{"lineNumber":111,"author":{"gitId":"NereusWB922"},"content":" title: \u0027App starts to lag when given large amount of input\u0027,"},{"lineNumber":112,"author":{"gitId":"NereusWB922"},"content":" updated_at: \u00272020-10-22T13:37:32Z\u0027,"},{"lineNumber":113,"author":{"gitId":"NereusWB922"},"content":" closed_at: \u0027\u0027,"},{"lineNumber":114,"author":{"gitId":"NereusWB922"},"content":" url: \u0027https://api.github.com/repos/CATcher-org/pe-results/issues/94\u0027,"},{"lineNumber":115,"author":{"gitId":"NereusWB922"},"content":" user: USER_ANUBHAV_DETAILS,"},{"lineNumber":116,"author":{"gitId":"NereusWB922"},"content":" milestone: MILESTONE_ONE,"},{"lineNumber":117,"author":{"gitId":"NereusWB922"},"content":" comments: [],"},{"lineNumber":118,"author":{"gitId":"NereusWB922"},"content":" issueOrPr: \u0027Issue\u0027,"},{"lineNumber":119,"author":{"gitId":"NereusWB922"},"content":" isDraft: false"},{"lineNumber":120,"author":{"gitId":"-"},"content":"});"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":"export const ISSUE_WITH_EMPTY_DESCRIPTION_LOW_SEVERITY \u003d new GithubIssue({"},{"lineNumber":123,"author":{"gitId":"-"},"content":" id: \u0027384830567\u0027,"},{"lineNumber":124,"author":{"gitId":"-"},"content":" number: 130,"},{"lineNumber":125,"author":{"gitId":"-"},"content":" assignees: [],"},{"lineNumber":126,"author":{"gitId":"-"},"content":" body: \u0027\u0027,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" created_at: \u00272020-03-02T16:19:02Z\u0027,"},{"lineNumber":128,"author":{"gitId":"-"},"content":" labels: [GITHUB_LABEL_TEAM_LABEL, GITHUB_LABEL_TUTORIAL_LABEL, GITHUB_LABEL_FEATURE_FLAW, GITHUB_LABEL_LOW_SEVERITY],"},{"lineNumber":129,"author":{"gitId":"-"},"content":" state: IssueState.Open,"},{"lineNumber":130,"author":{"gitId":"-"},"content":" stateReason: IssueStateReason.Reopened,"},{"lineNumber":131,"author":{"gitId":"-"},"content":" title: \u0027App is sometimes slow\u0027,"},{"lineNumber":132,"author":{"gitId":"-"},"content":" updated_at: \u00272020-03-13T13:37:32Z\u0027,"},{"lineNumber":133,"author":{"gitId":"NereusWB922"},"content":" closed_at: \u0027\u0027,"},{"lineNumber":134,"author":{"gitId":"-"},"content":" url: \u0027https://api.github.com/repos/CATcher-org/pe-results/issues/130\u0027,"},{"lineNumber":135,"author":{"gitId":"NereusWB922"},"content":" user: USER_ANUBHAV_DETAILS,"},{"lineNumber":136,"author":{"gitId":"NereusWB922"},"content":" milestone: MILESTONE_ONE,"},{"lineNumber":137,"author":{"gitId":"NereusWB922"},"content":" comments: [],"},{"lineNumber":138,"author":{"gitId":"NereusWB922"},"content":" issueOrPr: \u0027Issue\u0027,"},{"lineNumber":139,"author":{"gitId":"NereusWB922"},"content":" isDraft: false"},{"lineNumber":140,"author":{"gitId":"-"},"content":"});"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":"export const ISSUE_WITH_EMPTY_DESCRIPTION_HIGH_SEVERITY \u003d new GithubIssue({"},{"lineNumber":143,"author":{"gitId":"-"},"content":" id: \u0027573957398\u0027,"},{"lineNumber":144,"author":{"gitId":"-"},"content":" number: 32,"},{"lineNumber":145,"author":{"gitId":"-"},"content":" assignees: [],"},{"lineNumber":146,"author":{"gitId":"-"},"content":" body: \u0027\u0027,"},{"lineNumber":147,"author":{"gitId":"-"},"content":" created_at: \u00272010-03-12T19:12:02Z\u0027,"},{"lineNumber":148,"author":{"gitId":"-"},"content":" labels: [GITHUB_LABEL_TEAM_LABEL, GITHUB_LABEL_TUTORIAL_LABEL, GITHUB_LABEL_DOCUMENTATION_BUG, GITHUB_LABEL_HIGH_SEVERITY],"},{"lineNumber":149,"author":{"gitId":"-"},"content":" state: IssueState.Open,"},{"lineNumber":150,"author":{"gitId":"-"},"content":" stateReason: IssueStateReason.Reopened,"},{"lineNumber":151,"author":{"gitId":"-"},"content":" title: \u0027Too many typos\u0027,"},{"lineNumber":152,"author":{"gitId":"-"},"content":" updated_at: \u00272012-03-12T19:12:02Z\u0027,"},{"lineNumber":153,"author":{"gitId":"NereusWB922"},"content":" closed_at: \u0027\u0027,"},{"lineNumber":154,"author":{"gitId":"-"},"content":" url: \u0027https://api.github.com/repos/CATcher-org/pe-results/issues/130\u0027,"},{"lineNumber":155,"author":{"gitId":"NereusWB922"},"content":" user: USER_ANUBHAV_DETAILS,"},{"lineNumber":156,"author":{"gitId":"NereusWB922"},"content":" milestone: MILESTONE_ONE,"},{"lineNumber":157,"author":{"gitId":"NereusWB922"},"content":" comments: [],"},{"lineNumber":158,"author":{"gitId":"NereusWB922"},"content":" issueOrPr: \u0027Issue\u0027,"},{"lineNumber":159,"author":{"gitId":"NereusWB922"},"content":" isDraft: false"},{"lineNumber":160,"author":{"gitId":"-"},"content":"});"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"NereusWB922"},"content":"export const ISSUE_WITHOUT_MILESTONE \u003d new GithubIssue({"},{"lineNumber":163,"author":{"gitId":"NereusWB922"},"content":" id: \u0027573957398\u0027,"},{"lineNumber":164,"author":{"gitId":"NereusWB922"},"content":" number: 32,"},{"lineNumber":165,"author":{"gitId":"-"},"content":" assignees: [],"},{"lineNumber":166,"author":{"gitId":"-"},"content":" body: \u0027\u0027,"},{"lineNumber":167,"author":{"gitId":"NereusWB922"},"content":" created_at: \u00272010-03-12T19:12:02Z\u0027,"},{"lineNumber":168,"author":{"gitId":"-"},"content":" labels: [GITHUB_LABEL_TEAM_LABEL, GITHUB_LABEL_TUTORIAL_LABEL, GITHUB_LABEL_DOCUMENTATION_BUG, GITHUB_LABEL_HIGH_SEVERITY],"},{"lineNumber":169,"author":{"gitId":"-"},"content":" state: IssueState.Open,"},{"lineNumber":170,"author":{"gitId":"-"},"content":" stateReason: IssueStateReason.Reopened,"},{"lineNumber":171,"author":{"gitId":"NereusWB922"},"content":" title: \u0027Too many typos\u0027,"},{"lineNumber":172,"author":{"gitId":"NereusWB922"},"content":" updated_at: \u00272012-03-12T19:12:02Z\u0027,"},{"lineNumber":173,"author":{"gitId":"NereusWB922"},"content":" closed_at: \u0027\u0027,"},{"lineNumber":174,"author":{"gitId":"-"},"content":" url: \u0027https://api.github.com/repos/CATcher-org/pe-results/issues/130\u0027,"},{"lineNumber":175,"author":{"gitId":"NereusWB922"},"content":" user: USER_ANUBHAV_DETAILS,"},{"lineNumber":176,"author":{"gitId":"NereusWB922"},"content":" comments: [],"},{"lineNumber":177,"author":{"gitId":"NereusWB922"},"content":" issueOrPr: \u0027Issue\u0027,"},{"lineNumber":178,"author":{"gitId":"NereusWB922"},"content":" isDraft: false"},{"lineNumber":179,"author":{"gitId":"-"},"content":"});"},{"lineNumber":180,"author":{"gitId":"-"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":"export const ISSUE_WITH_ASSIGNEES \u003d new GithubIssue({"},{"lineNumber":182,"author":{"gitId":"-"},"content":" id: \u0027551732011\u0027,"},{"lineNumber":183,"author":{"gitId":"-"},"content":" number: 91,"},{"lineNumber":184,"author":{"gitId":"NereusWB922"},"content":" assignees: [USER_ANUBHAV_DETAILS],"},{"lineNumber":185,"author":{"gitId":"-"},"content":" body: \u0027Screen freezes every few minutes\u0027,"},{"lineNumber":186,"author":{"gitId":"-"},"content":" created_at: \u00272020-01-18T07:01:45Z\u0027,"},{"lineNumber":187,"author":{"gitId":"-"},"content":" labels: [GITHUB_LABEL_TEAM_LABEL, GITHUB_LABEL_TUTORIAL_LABEL, GITHUB_LABEL_FUNCTIONALITY_BUG, GITHUB_LABEL_MEDIUM_SEVERITY],"},{"lineNumber":188,"author":{"gitId":"-"},"content":" state: IssueState.Open,"},{"lineNumber":189,"author":{"gitId":"-"},"content":" stateReason: IssueStateReason.Reopened,"},{"lineNumber":190,"author":{"gitId":"-"},"content":" title: \u0027Screen freezes\u0027,"},{"lineNumber":191,"author":{"gitId":"-"},"content":" updated_at: \u00272020-03-02T12:50:02Z\u0027,"},{"lineNumber":192,"author":{"gitId":"NereusWB922"},"content":" closed_at: \u0027\u0027,"},{"lineNumber":193,"author":{"gitId":"-"},"content":" url: \u0027https://api.github.com/repos/CATcher-org/pe-results/issues/91\u0027,"},{"lineNumber":194,"author":{"gitId":"-"},"content":" user: USER_ANUBHAV_DETAILS,"},{"lineNumber":195,"author":{"gitId":"NereusWB922"},"content":" milestone: MILESTONE_ONE,"},{"lineNumber":196,"author":{"gitId":"NereusWB922"},"content":" comments: [EMPTY_TEAM_RESPONSE],"},{"lineNumber":197,"author":{"gitId":"NereusWB922"},"content":" issueOrPr: \u0027Issue\u0027,"},{"lineNumber":198,"author":{"gitId":"NereusWB922"},"content":" isDraft: false"},{"lineNumber":199,"author":{"gitId":"-"},"content":"});"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":"export const generateIssueWithRandomData: () \u003d\u003e GithubIssue \u003d () \u003d\u003e {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" const created_and_updated_date: string \u003d randomISODate();"},{"lineNumber":203,"author":{"gitId":"-"},"content":" const issueNumber: number \u003d randomIssueNumber();"},{"lineNumber":204,"author":{"gitId":"-"},"content":" const severityLabels: GithubLabel[] \u003d [GITHUB_LABEL_LOW_SEVERITY, GITHUB_LABEL_MEDIUM_SEVERITY, GITHUB_LABEL_HIGH_SEVERITY];"},{"lineNumber":205,"author":{"gitId":"-"},"content":" const typeLabels: GithubLabel[] \u003d [GITHUB_LABEL_FUNCTIONALITY_BUG, GITHUB_LABEL_FEATURE_FLAW, GITHUB_LABEL_DOCUMENTATION_BUG];"},{"lineNumber":206,"author":{"gitId":"-"},"content":" return new GithubIssue({"},{"lineNumber":207,"author":{"gitId":"-"},"content":" id: randomId(),"},{"lineNumber":208,"author":{"gitId":"-"},"content":" number: issueNumber,"},{"lineNumber":209,"author":{"gitId":"-"},"content":" assignees: [],"},{"lineNumber":210,"author":{"gitId":"-"},"content":" comments: [],"},{"lineNumber":211,"author":{"gitId":"-"},"content":" body: `Issue No.: ${issueNumber}\\nSample Content.`,"},{"lineNumber":212,"author":{"gitId":"-"},"content":" created_at: created_and_updated_date,"},{"lineNumber":213,"author":{"gitId":"-"},"content":" labels: [GITHUB_LABEL_TEAM_LABEL, GITHUB_LABEL_TUTORIAL_LABEL, typeLabels[issueNumber % 3], severityLabels[issueNumber % 3]],"},{"lineNumber":214,"author":{"gitId":"-"},"content":" state: IssueState.Open,"},{"lineNumber":215,"author":{"gitId":"-"},"content":" stateReason: IssueStateReason.Reopened,"},{"lineNumber":216,"author":{"gitId":"-"},"content":" title: `Random Issue: ${issueNumber}`,"},{"lineNumber":217,"author":{"gitId":"-"},"content":" updated_at: created_and_updated_date,"},{"lineNumber":218,"author":{"gitId":"-"},"content":" url: `https://api.github.com/repos/CATcher-org/pe-results/issues/${issueNumber}`,"},{"lineNumber":219,"author":{"gitId":"-"},"content":" user: USER_ANUBHAV_DETAILS"},{"lineNumber":220,"author":{"gitId":"-"},"content":" });"},{"lineNumber":221,"author":{"gitId":"-"},"content":"};"}],"authorContributionMap":{"NereusWB922":99,"-":122}},{"path":"tests/constants/githublabel.constants.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { GithubLabel } from \u0027../../src/app/core/models/github/github-label.model\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"export const GITHUB_LABEL_FUNCTIONALITY_BUG \u003d {"},{"lineNumber":4,"author":{"gitId":"-"},"content":" color: \u00279900cc\u0027,"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":" name: \u0027type.FunctionalityBug\u0027"},{"lineNumber":6,"author":{"gitId":"-"},"content":"} as GithubLabel;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"export const GITHUB_LABEL_FEATURE_FLAW \u003d {"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" color: \u0027d966ff\u0027,"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" name: \u0027type.FeatureFlaw\u0027"},{"lineNumber":11,"author":{"gitId":"-"},"content":"} as GithubLabel;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"export const GITHUB_LABEL_DOCUMENTATION_BUG \u003d {"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" color: \u0027d966ff\u0027,"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" name: \u0027type.DocumentationBug\u0027"},{"lineNumber":16,"author":{"gitId":"-"},"content":"} as GithubLabel;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"export const GITHUB_LABEL_LOW_SEVERITY \u003d {"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" color: \u0027ffcccc\u0027,"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" name: \u0027severity.Low\u0027"},{"lineNumber":21,"author":{"gitId":"-"},"content":"} as GithubLabel;"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":"export const GITHUB_LABEL_HIGH_SEVERITY \u003d {"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" color: \u0027ff6666\u0027,"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" name: \u0027severity.High\u0027"},{"lineNumber":26,"author":{"gitId":"-"},"content":"} as GithubLabel;"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":"export const GITHUB_LABEL_MEDIUM_SEVERITY \u003d {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" color: \u0027ff9999\u0027,"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" name: \u0027severity.Medium\u0027"},{"lineNumber":31,"author":{"gitId":"-"},"content":"} as GithubLabel;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":"export const GITHUB_LABEL_TUTORIAL_LABEL \u003d {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" color: \u0027c2e0c6\u0027,"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" name: \u0027tutorial.CS2103T-W12\u0027"},{"lineNumber":36,"author":{"gitId":"-"},"content":"} as GithubLabel;"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":"export const GITHUB_LABEL_TEAM_LABEL \u003d {"},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" color: \u0027d4c5f9\u0027,"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" name: \u0027team.3\u0027"},{"lineNumber":41,"author":{"gitId":"-"},"content":"} as GithubLabel;"}],"authorContributionMap":{"NereusWB922":13,"-":28}},{"path":"tests/constants/label.constants.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { SimpleLabel } from \u0027../../src/app/core/models/label.model\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"// Label name constants"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"export const SEVERITY_VERY_LOW \u003d \u0027veryLow\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"export const SEVERITY_LOW \u003d \u0027low\u0027;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"export const SEVERITY_MEDIUM \u003d \u0027medium\u0027;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"export const SEVERITY_HIGH \u003d \u0027high\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"// Label category constants"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"export const CATEGORY_SEVERITY \u003d \u0027severity\u0027;"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":"// Label name constants"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":"export const LABEL_NAME_SEVERITY_VERY_LOW \u003d CATEGORY_SEVERITY + \u0027.\u0027 + SEVERITY_VERY_LOW;"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"export const LABEL_NAME_SEVERITY_LOW \u003d CATEGORY_SEVERITY + \u0027.\u0027 + SEVERITY_LOW;"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":"export const LABEL_NAME_SEVERITY_MEDIUM \u003d CATEGORY_SEVERITY + \u0027.\u0027 + SEVERITY_MEDIUM;"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":"export const LABEL_NAME_SEVERITY_HIGH \u003d CATEGORY_SEVERITY + \u0027.\u0027 + SEVERITY_HIGH;"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":"// Label definition constants"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":"export const DEFINITION_SEVERITY_VERY_LOW \u003d"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cp\u003eA flaw that is \u003cmark\u003epurely cosmetic\u003c/mark\u003e and \u003cmark\u003edoes not affect usage\u003c/mark\u003e. For example, \u0027 +"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cul\u003e\u0027 +"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cli\u003etypo issues\u003c/li\u003e\u0027 +"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cli\u003espacing issues\u003c/li\u003e\u0027 +"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cli\u003elayout issues\u003c/li\u003e\u0027 +"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cli\u003ecolor issues\u003c/li\u003e\u0027 +"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cli\u003efont issues\u003c/li\u003e\u0027 +"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003c/ul\u003e\u0027 +"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" \"in the docs or the UI that doesn\u0027t affect usage.\u003c/p\u003e\";"},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":"export const DEFINITION_SEVERITY_LOW \u003d"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cp\u003eA flaw that is unlikely to affect normal operations of the product. \u0027 +"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" \u0027Appears only in very rare situations and causes a minor inconvenience only.\u003c/p\u003e\u0027;"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":"export const DEFINITION_SEVERITY_MEDIUM \u003d"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cp\u003eA flaw that causes occasional inconvenience to some users but they can \u0027 + \u0027continue to use the product.\u003c/p\u003e\u0027;"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":"export const DEFINITION_SEVERITY_HIGH \u003d"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" \u0027\u003cp\u003eA flaw that affects most users and causes major problems for users.\u0027 + \u0027i.e., makes the product almost unusable for most users.\u003c/p\u003e\u0027;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":"// Label color constants"},{"lineNumber":38,"author":{"gitId":"-"},"content":"export const COLOR_BLACK \u003d \u0027000000\u0027;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"export const COLOR_WHITE \u003d \u0027ffffff\u0027;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"export const COLOR_SEVERITY_VERY_LOW \u003d \u0027ffe0e0\u0027;"},{"lineNumber":41,"author":{"gitId":"-"},"content":"export const COLOR_SEVERITY_LOW \u003d \u0027ffcccc\u0027;"},{"lineNumber":42,"author":{"gitId":"-"},"content":"export const COLOR_SEVERITY_MEDIUM \u003d \u0027ff9999\u0027;"},{"lineNumber":43,"author":{"gitId":"-"},"content":"export const COLOR_SEVERITY_HIGH \u003d \u0027ff6666\u0027;"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":"// CSS style constants"},{"lineNumber":46,"author":{"gitId":"-"},"content":"export const DARK_BG_LIGHT_TEXT \u003d {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" \u0027background-color\u0027: `#${COLOR_BLACK}`,"},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" color: `#${COLOR_WHITE}`"},{"lineNumber":49,"author":{"gitId":"-"},"content":"};"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":"export const LIGHT_BG_DARK_TEXT \u003d {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" \u0027background-color\u0027: `#${COLOR_WHITE}`,"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" color: `#${COLOR_BLACK}`"},{"lineNumber":54,"author":{"gitId":"-"},"content":"};"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":"export const SEVERITY_LABELS \u003d ["},{"lineNumber":57,"author":{"gitId":"-"},"content":" {"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" name: LABEL_NAME_SEVERITY_VERY_LOW,"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" color: COLOR_SEVERITY_VERY_LOW,"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":" definition: DEFINITION_SEVERITY_VERY_LOW"},{"lineNumber":61,"author":{"gitId":"-"},"content":" },"},{"lineNumber":62,"author":{"gitId":"-"},"content":" {"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" name: LABEL_NAME_SEVERITY_LOW,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" color: COLOR_SEVERITY_LOW,"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":" definition: DEFINITION_SEVERITY_LOW"},{"lineNumber":66,"author":{"gitId":"-"},"content":" },"},{"lineNumber":67,"author":{"gitId":"-"},"content":" {"},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":" name: LABEL_NAME_SEVERITY_MEDIUM,"},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":" color: COLOR_SEVERITY_MEDIUM,"},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":" definition: DEFINITION_SEVERITY_MEDIUM"},{"lineNumber":71,"author":{"gitId":"-"},"content":" },"},{"lineNumber":72,"author":{"gitId":"-"},"content":" {"},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" name: LABEL_NAME_SEVERITY_HIGH,"},{"lineNumber":74,"author":{"gitId":"NereusWB922"},"content":" color: COLOR_SEVERITY_HIGH,"},{"lineNumber":75,"author":{"gitId":"NereusWB922"},"content":" definition: DEFINITION_SEVERITY_HIGH"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":"];"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":"export const SEVERITY_SIMPLE_LABELS: SimpleLabel[] \u003d SEVERITY_LABELS.map((label) \u003d\u003e ({"},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":" name: label.name,"},{"lineNumber":81,"author":{"gitId":"NereusWB922"},"content":" color: label.color"},{"lineNumber":82,"author":{"gitId":"NereusWB922"},"content":"}));"}],"authorContributionMap":{"NereusWB922":49,"-":33}},{"path":"tests/constants/session.constants.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { Repo } from \u0027../../src/app/core/models/repo.model\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { SessionData, SessionRepo } from \u0027../../src/app/core/models/session.model\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { View } from \u0027../../src/app/core/models/view.model\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"export const WATCHER_REPO: Repo \u003d Repo.of(\u0027CATcher-org/WATcher\u0027);"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"export const CATCHER_REPO: Repo \u003d Repo.of(\u0027CATcher-org/CATcher\u0027);"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"const ISSUES_VIEWER_SESSION_REPO: SessionRepo \u003d {"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" view: View.issuesViewer,"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" repos: [WATCHER_REPO]"},{"lineNumber":11,"author":{"gitId":"-"},"content":"};"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":"const ACTIVITY_DASHBOARD_SESSION_REPO: SessionRepo \u003d {"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" view: View.activityDashboard,"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" repos: [WATCHER_REPO]"},{"lineNumber":16,"author":{"gitId":"-"},"content":"};"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":"export const VALID_SESSION_DATA: SessionData \u003d {"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" sessionRepo: [ISSUES_VIEWER_SESSION_REPO, ACTIVITY_DASHBOARD_SESSION_REPO]"},{"lineNumber":20,"author":{"gitId":"-"},"content":"};"}],"authorContributionMap":{"NereusWB922":13,"-":7}},{"path":"tests/model/issue.model.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import * as moment from \u0027moment\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Issue } from \u0027../../src/app/core/models/issue.model\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { Milestone } from \u0027../../src/app/core/models/milestone.model\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { USER_ANUBHAV } from \u0027../constants/data.constants\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import {"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":" CLOSED_ISSUE_WITH_EMPTY_DESCRIPTION,"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":" ISSUE_WITHOUT_MILESTONE,"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":" ISSUE_WITH_ASSIGNEES,"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":" ISSUE_WITH_EMPTY_DESCRIPTION,"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":" MILESTONE_ONE"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":"} from \u0027../constants/githubissue.constants\u0027;"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":"import {"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" GITHUB_LABEL_FUNCTIONALITY_BUG,"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" GITHUB_LABEL_MEDIUM_SEVERITY,"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":" GITHUB_LABEL_TEAM_LABEL,"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":" GITHUB_LABEL_TUTORIAL_LABEL"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":"} from \u0027../constants/githublabel.constants\u0027;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"describe(\u0027Issue model class\u0027, () \u003d\u003e {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" describe(\u0027.createPhaseBugReportIssue(githubIssue)\u0027, () \u003d\u003e {"},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should correctly create a issue that has an empty description\u0027, async () \u003d\u003e {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" const issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_EMPTY_DESCRIPTION);"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" expect(issue.globalId).toEqual(ISSUE_WITH_EMPTY_DESCRIPTION.id);"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" expect(issue.id).toEqual(ISSUE_WITH_EMPTY_DESCRIPTION.number);"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" expect(issue.created_at).toEqual(moment(ISSUE_WITH_EMPTY_DESCRIPTION.created_at).format(\u0027lll\u0027));"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" expect(issue.title).toEqual(ISSUE_WITH_EMPTY_DESCRIPTION.title);"},{"lineNumber":28,"author":{"gitId":"NereusWB922"},"content":" expect(issue.description).toEqual(\u0027No details provided by bug reporter.\u0027);"},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" expect(issue.updated_at).toEqual(moment(ISSUE_WITH_EMPTY_DESCRIPTION.updated_at).format(\u0027lll\u0027));"},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" expect(issue.closed_at).toEqual(\u0027Invalid date\u0027);"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" expect(issue.milestone).toEqual(new Milestone(MILESTONE_ONE));"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" expect(issue.state).toEqual(ISSUE_WITH_EMPTY_DESCRIPTION.state);"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":" expect(issue.stateReason).toEqual(ISSUE_WITH_EMPTY_DESCRIPTION.stateReason);"},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" expect(issue.issueOrPr).toEqual(\u0027Issue\u0027);"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":" expect(issue.author).toEqual(ISSUE_WITH_EMPTY_DESCRIPTION.user.login);"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" expect(issue.isDraft).toEqual(ISSUE_WITH_EMPTY_DESCRIPTION.isDraft);"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":" expect(issue.assignees).toEqual([]);"},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":" expect(issue.labels).toEqual(["},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" GITHUB_LABEL_TEAM_LABEL.name,"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" GITHUB_LABEL_TUTORIAL_LABEL.name,"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" GITHUB_LABEL_FUNCTIONALITY_BUG.name,"},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":" GITHUB_LABEL_MEDIUM_SEVERITY.name"},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":" ]);"},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" expect(issue.githubLabels).toEqual(ISSUE_WITH_EMPTY_DESCRIPTION.labels);"},{"lineNumber":45,"author":{"gitId":"-"},"content":" });"},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set close date correctly for closed issue\u0027, () \u003d\u003e {"},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" const issue \u003d Issue.createPhaseBugReportingIssue(CLOSED_ISSUE_WITH_EMPTY_DESCRIPTION);"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" expect(issue.closed_at).toEqual(moment(CLOSED_ISSUE_WITH_EMPTY_DESCRIPTION.closed_at).format(\u0027lll\u0027));"},{"lineNumber":51,"author":{"gitId":"-"},"content":" });"},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set milestone to default milestone for issue without milestone\u0027, () \u003d\u003e {"},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":" const issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITHOUT_MILESTONE);"},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":56,"author":{"gitId":"MadLamprey"},"content":" expect(issue.milestone).toEqual(Milestone.IssueWithoutMilestone);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" });"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set assignees correctly for issue with assignees\u0027, () \u003d\u003e {"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":" const issue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_ASSIGNEES);"},{"lineNumber":61,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":62,"author":{"gitId":"NereusWB922"},"content":" expect(issue.assignees).toEqual([USER_ANUBHAV.loginId]);"},{"lineNumber":63,"author":{"gitId":"-"},"content":" });"},{"lineNumber":64,"author":{"gitId":"-"},"content":" });"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027.updateDescription(description)\u0027, () \u003d\u003e {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" it(\u0027correctly clean strings obtained from users\u0027, () \u003d\u003e {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" const noDetailsFromBugReporter \u003d \u0027No details provided by bug reporter.\u0027;"},{"lineNumber":69,"author":{"gitId":"-"},"content":" expect(Issue.updateDescription(\u0027\u0027)).toBe(noDetailsFromBugReporter);"},{"lineNumber":70,"author":{"gitId":"-"},"content":" expect(Issue.updateDescription(null)).toBe(noDetailsFromBugReporter);"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" const typicalDescription \u003d \u0027The app crashes after parsing config files.\u0027;"},{"lineNumber":73,"author":{"gitId":"-"},"content":" expect(Issue.updateDescription(typicalDescription)).toBe(typicalDescription + \u0027\\n\\n\u0027);"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" const inputWithSpecialChars \u003d \u0027$%^!@\u0026-_test\u0027;"},{"lineNumber":76,"author":{"gitId":"-"},"content":" expect(Issue.updateDescription(inputWithSpecialChars)).toBe(inputWithSpecialChars + \u0027\\n\\n\u0027);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" });"},{"lineNumber":78,"author":{"gitId":"-"},"content":" });"},{"lineNumber":79,"author":{"gitId":"-"},"content":"});"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":"describe(\u0027Issue\u0027, () \u003d\u003e {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" const dummyIssue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_EMPTY_DESCRIPTION);"},{"lineNumber":83,"author":{"gitId":"-"},"content":" const otherDummyIssue \u003d Issue.createPhaseBugReportingIssue(ISSUE_WITH_ASSIGNEES);"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" const noReportedDescriptionString \u003d \u0027No details provided by bug reporter.\\n\u0027;"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" it(\u0027.createGithubIssueDescription() forms the correct GitHub Issue description for the issue\u0027, () \u003d\u003e {"},{"lineNumber":88,"author":{"gitId":"NereusWB922"},"content":" expect(dummyIssue.createGithubIssueDescription()).toEqual(noReportedDescriptionString);"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"NereusWB922"},"content":" expect(otherDummyIssue.createGithubIssueDescription()).toEqual(`${otherDummyIssue.description}\\n`);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" });"},{"lineNumber":92,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"NereusWB922":57,"MadLamprey":1,"-":34}},{"path":"tests/services/error-handling.service.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"MadLamprey"},"content":"import { ErrorHandlingService } from \u0027../../src/app/core/services/error-handling.service\u0027;"},{"lineNumber":2,"author":{"gitId":"MadLamprey"},"content":"import { FormErrorComponent } from \u0027../../src/app/shared/error-toasters/form-error/form-error.component\u0027;"},{"lineNumber":3,"author":{"gitId":"MadLamprey"},"content":"import { GeneralMessageErrorComponent } from \u0027../../src/app/shared/error-toasters/general-message-error/general-message-error.component\u0027;"},{"lineNumber":4,"author":{"gitId":"MadLamprey"},"content":"import {"},{"lineNumber":5,"author":{"gitId":"MadLamprey"},"content":" ERROR_WITH_NO_MESSAGE,"},{"lineNumber":6,"author":{"gitId":"MadLamprey"},"content":" HTTP_304_ERROR,"},{"lineNumber":7,"author":{"gitId":"MadLamprey"},"content":" HTTP_400_ERROR,"},{"lineNumber":8,"author":{"gitId":"MadLamprey"},"content":" HTTP_401_ERROR,"},{"lineNumber":9,"author":{"gitId":"MadLamprey"},"content":" HTTP_404_ERROR,"},{"lineNumber":10,"author":{"gitId":"MadLamprey"},"content":" HTTP_422_ERROR,"},{"lineNumber":11,"author":{"gitId":"MadLamprey"},"content":" HTTP_500_ERROR,"},{"lineNumber":12,"author":{"gitId":"MadLamprey"},"content":" HTTP_UNKNOWN_ERROR,"},{"lineNumber":13,"author":{"gitId":"MadLamprey"},"content":" OCTOKIT_REQUEST_ERROR,"},{"lineNumber":14,"author":{"gitId":"MadLamprey"},"content":" STANDARD_ERROR"},{"lineNumber":15,"author":{"gitId":"MadLamprey"},"content":"} from \u0027../constants/error.constants\u0027;"},{"lineNumber":16,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":17,"author":{"gitId":"MadLamprey"},"content":"let errorHandlingService: ErrorHandlingService;"},{"lineNumber":18,"author":{"gitId":"MadLamprey"},"content":"let mockLoggingService;"},{"lineNumber":19,"author":{"gitId":"MadLamprey"},"content":"let mockSnackBar;"},{"lineNumber":20,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":21,"author":{"gitId":"MadLamprey"},"content":"describe(\u0027ErrorHandlingService\u0027, () \u003d\u003e {"},{"lineNumber":22,"author":{"gitId":"MadLamprey"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":23,"author":{"gitId":"MadLamprey"},"content":" mockLoggingService \u003d jasmine.createSpyObj(\u0027LoggingService\u0027, [\u0027error\u0027, \u0027debug\u0027]);"},{"lineNumber":24,"author":{"gitId":"MadLamprey"},"content":" mockSnackBar \u003d jasmine.createSpyObj(\u0027MatSnackBar\u0027, [\u0027openFromComponent\u0027]);"},{"lineNumber":25,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService \u003d new ErrorHandlingService(mockSnackBar, mockLoggingService);"},{"lineNumber":26,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":27,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":28,"author":{"gitId":"MadLamprey"},"content":" describe(\u0027ErrorHandlingService: handleError()\u0027, () \u003d\u003e {"},{"lineNumber":29,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should log errors when handling errors\u0027, () \u003d\u003e {"},{"lineNumber":30,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(STANDARD_ERROR);"},{"lineNumber":31,"author":{"gitId":"MadLamprey"},"content":" expect(mockLoggingService.error).toHaveBeenCalledWith(STANDARD_ERROR);"},{"lineNumber":32,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":33,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":34,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should use the GeneralMessageErrorComponent when handling Errors\u0027, () \u003d\u003e {"},{"lineNumber":35,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(STANDARD_ERROR);"},{"lineNumber":36,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledWith(GeneralMessageErrorComponent, {"},{"lineNumber":37,"author":{"gitId":"MadLamprey"},"content":" data: { message: STANDARD_ERROR.message }"},{"lineNumber":38,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":39,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":40,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":41,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should stringify Errors if there is no message before displaying\u0027, () \u003d\u003e {"},{"lineNumber":42,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(ERROR_WITH_NO_MESSAGE);"},{"lineNumber":43,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledWith(GeneralMessageErrorComponent, {"},{"lineNumber":44,"author":{"gitId":"MadLamprey"},"content":" data: { message: JSON.stringify(ERROR_WITH_NO_MESSAGE) }"},{"lineNumber":45,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":46,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":47,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":48,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should not open the snackbar when handling http status 304 errors\u0027, () \u003d\u003e {"},{"lineNumber":49,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(HTTP_304_ERROR);"},{"lineNumber":50,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).not.toHaveBeenCalled();"},{"lineNumber":51,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":52,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":53,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should use the FormErrorComponent when handling http status 422 errors\u0027, () \u003d\u003e {"},{"lineNumber":54,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(HTTP_422_ERROR);"},{"lineNumber":55,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledWith(FormErrorComponent, { data: HTTP_422_ERROR });"},{"lineNumber":56,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":57,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":58,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should use the GeneralMessageErrorComponent when handling other http errors\u0027, () \u003d\u003e {"},{"lineNumber":59,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(HTTP_500_ERROR);"},{"lineNumber":60,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledWith(GeneralMessageErrorComponent, { data: HTTP_500_ERROR });"},{"lineNumber":61,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(HTTP_400_ERROR);"},{"lineNumber":62,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledWith(GeneralMessageErrorComponent, { data: HTTP_400_ERROR });"},{"lineNumber":63,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(HTTP_401_ERROR);"},{"lineNumber":64,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledWith(GeneralMessageErrorComponent, { data: HTTP_401_ERROR });"},{"lineNumber":65,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(HTTP_404_ERROR);"},{"lineNumber":66,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledWith(GeneralMessageErrorComponent, { data: HTTP_404_ERROR });"},{"lineNumber":67,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(HTTP_UNKNOWN_ERROR);"},{"lineNumber":68,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledWith(GeneralMessageErrorComponent, { data: HTTP_UNKNOWN_ERROR });"},{"lineNumber":69,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledTimes(5);"},{"lineNumber":70,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":71,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":72,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should treat octokit request errors as http errors\u0027, () \u003d\u003e {"},{"lineNumber":73,"author":{"gitId":"MadLamprey"},"content":" errorHandlingService.handleError(OCTOKIT_REQUEST_ERROR);"},{"lineNumber":74,"author":{"gitId":"MadLamprey"},"content":" expect(mockSnackBar.openFromComponent).toHaveBeenCalledWith(GeneralMessageErrorComponent, { data: OCTOKIT_REQUEST_ERROR });"},{"lineNumber":75,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":76,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":77,"author":{"gitId":"MadLamprey"},"content":"});"}],"authorContributionMap":{"MadLamprey":77}},{"path":"tests/services/label.service.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { of } from \u0027rxjs\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Label } from \u0027../../src/app/core/models/label.model\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { GithubService } from \u0027../../src/app/core/services/github.service\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { LabelService } from \u0027../../src/app/core/services/label.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import * as LabelConstant from \u0027../constants/label.constants\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"let labelService: LabelService;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"let labelList: Label[];"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"let githubServiceSpy: jasmine.SpyObj\u003cGithubService\u003e;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":"describe(\u0027LabelService: fetchLabels()\u0027, () \u003d\u003e {"},{"lineNumber":12,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" githubServiceSpy \u003d jasmine.createSpyObj(\u0027GithubService\u0027, [\u0027fetchAllLabels\u0027]);"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" labelService \u003d new LabelService(githubServiceSpy);"},{"lineNumber":15,"author":{"gitId":"-"},"content":" });"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should fetch labels successfully\u0027, () \u003d\u003e {"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" const mockLabels \u003d LabelConstant.SEVERITY_LABELS;"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" const parsedLabels \u003d labelService.parseLabelData(mockLabels);"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"NereusWB922"},"content":" githubServiceSpy.fetchAllLabels.and.returnValue(of(mockLabels));"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" labelService.fetchLabels().subscribe((response) \u003d\u003e {"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" expect(response).toEqual(mockLabels);"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" expect(labelService.labels).toEqual(parsedLabels);"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" expect(labelService.simpleLabels).toEqual(parsedLabels);"},{"lineNumber":27,"author":{"gitId":"-"},"content":" });"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" expect(githubServiceSpy.fetchAllLabels).toHaveBeenCalled();"},{"lineNumber":30,"author":{"gitId":"-"},"content":" });"},{"lineNumber":31,"author":{"gitId":"-"},"content":"});"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":"describe(\u0027LabelService: parseLabelData()\u0027, () \u003d\u003e {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" beforeAll(() \u003d\u003e {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" labelService \u003d new LabelService(null);"},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" labelList \u003d labelService.parseLabelData(LabelConstant.SEVERITY_LABELS);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" });"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" afterAll(() \u003d\u003e {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" labelService \u003d null;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" });"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should be severity very low label\u0027, () \u003d\u003e {"},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[0].name).toBe(LabelConstant.LABEL_NAME_SEVERITY_VERY_LOW);"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[0].color).toBe(LabelConstant.COLOR_SEVERITY_VERY_LOW);"},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[0].definition).toBe(LabelConstant.DEFINITION_SEVERITY_VERY_LOW);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" });"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should be severity low label\u0027, () \u003d\u003e {"},{"lineNumber":50,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[1].name).toBe(LabelConstant.LABEL_NAME_SEVERITY_LOW);"},{"lineNumber":51,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[1].color).toBe(LabelConstant.COLOR_SEVERITY_LOW);"},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[1].definition).toBe(LabelConstant.DEFINITION_SEVERITY_LOW);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" });"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should be severity medium label\u0027, () \u003d\u003e {"},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[2].name).toBe(LabelConstant.LABEL_NAME_SEVERITY_MEDIUM);"},{"lineNumber":57,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[2].color).toBe(LabelConstant.COLOR_SEVERITY_MEDIUM);"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[2].definition).toBe(LabelConstant.DEFINITION_SEVERITY_MEDIUM);"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":60,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":61,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should be severity high label\u0027, () \u003d\u003e {"},{"lineNumber":62,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[3].name).toBe(LabelConstant.LABEL_NAME_SEVERITY_HIGH);"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[3].color).toBe(LabelConstant.COLOR_SEVERITY_HIGH);"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" expect(labelList[3].definition).toBe(LabelConstant.DEFINITION_SEVERITY_HIGH);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" });"},{"lineNumber":66,"author":{"gitId":"-"},"content":"});"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":"describe(\u0027LabelService: isDarkColor()\u0027, () \u003d\u003e {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" labelService \u003d new LabelService(null);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" });"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" afterEach(() \u003d\u003e {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" labelService \u003d null;"},{"lineNumber":75,"author":{"gitId":"-"},"content":" });"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" it(\u0027should be true for dark color\u0027, () \u003d\u003e {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" expect(labelService.isDarkColor(LabelConstant.COLOR_BLACK)).toBeTruthy();"},{"lineNumber":79,"author":{"gitId":"-"},"content":" });"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" it(\u0027should be false for light color\u0027, () \u003d\u003e {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" expect(labelService.isDarkColor(LabelConstant.COLOR_WHITE)).toBeFalsy();"},{"lineNumber":83,"author":{"gitId":"-"},"content":" });"},{"lineNumber":84,"author":{"gitId":"-"},"content":"});"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":"describe(\u0027LabelService: setLabelStyle()\u0027, () \u003d\u003e {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":88,"author":{"gitId":"-"},"content":" labelService \u003d new LabelService(null);"},{"lineNumber":89,"author":{"gitId":"-"},"content":" });"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" afterEach(() \u003d\u003e {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" labelService \u003d null;"},{"lineNumber":93,"author":{"gitId":"-"},"content":" });"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" it(\u0027should be dark color background with light color text\u0027, () \u003d\u003e {"},{"lineNumber":96,"author":{"gitId":"-"},"content":" expect(labelService.setLabelStyle(LabelConstant.COLOR_BLACK)).toEqual(LabelConstant.DARK_BG_LIGHT_TEXT);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" });"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" it(\u0027should be light color background with dark color text\u0027, () \u003d\u003e {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" expect(labelService.setLabelStyle(LabelConstant.COLOR_WHITE)).toEqual(LabelConstant.LIGHT_BG_DARK_TEXT);"},{"lineNumber":101,"author":{"gitId":"-"},"content":" });"},{"lineNumber":102,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"NereusWB922":34,"-":68}},{"path":"tests/services/milestone.service.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"MadLamprey"},"content":"import { of } from \u0027rxjs\u0027;"},{"lineNumber":2,"author":{"gitId":"MadLamprey"},"content":"import { Milestone } from \u0027../../src/app/core/models/milestone.model\u0027;"},{"lineNumber":3,"author":{"gitId":"MadLamprey"},"content":"import { GithubService } from \u0027../../src/app/core/services/github.service\u0027;"},{"lineNumber":4,"author":{"gitId":"MadLamprey"},"content":"import { MilestoneService } from \u0027../../src/app/core/services/milestone.service\u0027;"},{"lineNumber":5,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":6,"author":{"gitId":"MadLamprey"},"content":"let milestoneService: MilestoneService;"},{"lineNumber":7,"author":{"gitId":"MadLamprey"},"content":"let githubServiceSpy: jasmine.SpyObj\u003cGithubService\u003e;"},{"lineNumber":8,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":9,"author":{"gitId":"MadLamprey"},"content":"describe(\u0027MilestoneService\u0027, () \u003d\u003e {"},{"lineNumber":10,"author":{"gitId":"MadLamprey"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":11,"author":{"gitId":"MadLamprey"},"content":" githubServiceSpy \u003d jasmine.createSpyObj(\u0027GithubService\u0027, [\u0027fetchAllMilestones\u0027]);"},{"lineNumber":12,"author":{"gitId":"MadLamprey"},"content":" milestoneService \u003d new MilestoneService(githubServiceSpy);"},{"lineNumber":13,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":14,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":15,"author":{"gitId":"MadLamprey"},"content":" describe(\u0027MilestoneService: fetchMilestones()\u0027, () \u003d\u003e {"},{"lineNumber":16,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should fetch all milestones\u0027, (done) \u003d\u003e {"},{"lineNumber":17,"author":{"gitId":"MadLamprey"},"content":" const mockMilestones \u003d [{ title: \u0027Milestone 1\u0027 }, { title: \u0027Milestone 2\u0027 }];"},{"lineNumber":18,"author":{"gitId":"MadLamprey"},"content":" githubServiceSpy.fetchAllMilestones.and.returnValue(of(mockMilestones));"},{"lineNumber":19,"author":{"gitId":"MadLamprey"},"content":" milestoneService.fetchMilestones().subscribe((response) \u003d\u003e {"},{"lineNumber":20,"author":{"gitId":"MadLamprey"},"content":" expect(githubServiceSpy.fetchAllMilestones).toHaveBeenCalled();"},{"lineNumber":21,"author":{"gitId":"MadLamprey"},"content":" expect(milestoneService.milestones.length).toBe(2);"},{"lineNumber":22,"author":{"gitId":"MadLamprey"},"content":" expect(milestoneService.milestones[0].title).toBe(\u0027Milestone 1\u0027);"},{"lineNumber":23,"author":{"gitId":"MadLamprey"},"content":" expect(milestoneService.hasNoMilestones).toBeFalse();"},{"lineNumber":24,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":25,"author":{"gitId":"MadLamprey"},"content":" done();"},{"lineNumber":26,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":27,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":28,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":29,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should handle no milestones\u0027, (done) \u003d\u003e {"},{"lineNumber":30,"author":{"gitId":"MadLamprey"},"content":" githubServiceSpy.fetchAllMilestones.and.returnValue(of([]));"},{"lineNumber":31,"author":{"gitId":"MadLamprey"},"content":" milestoneService.fetchMilestones().subscribe((response) \u003d\u003e {"},{"lineNumber":32,"author":{"gitId":"MadLamprey"},"content":" expect(githubServiceSpy.fetchAllMilestones).toHaveBeenCalled();"},{"lineNumber":33,"author":{"gitId":"MadLamprey"},"content":" expect(milestoneService.milestones.length).toBe(0);"},{"lineNumber":34,"author":{"gitId":"MadLamprey"},"content":" expect(milestoneService.hasNoMilestones).toBeTrue();"},{"lineNumber":35,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":36,"author":{"gitId":"MadLamprey"},"content":" done();"},{"lineNumber":37,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":38,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":39,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":40,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":41,"author":{"gitId":"MadLamprey"},"content":" describe(\u0027MilestoneService: parseMilestoneData()\u0027, () \u003d\u003e {"},{"lineNumber":42,"author":{"gitId":"MadLamprey"},"content":" it(\u0027should parse milestone data correctly\u0027, () \u003d\u003e {"},{"lineNumber":43,"author":{"gitId":"MadLamprey"},"content":" const mockMilestones \u003d [{ title: \u0027Milestone 2\u0027 }, { title: \u0027Milestone 1\u0027 }];"},{"lineNumber":44,"author":{"gitId":"MadLamprey"},"content":" const parsedMilestones \u003d milestoneService.parseMilestoneData(mockMilestones);"},{"lineNumber":45,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":46,"author":{"gitId":"MadLamprey"},"content":" for (const milestone of parsedMilestones) {"},{"lineNumber":47,"author":{"gitId":"MadLamprey"},"content":" expect(milestone).toBeInstanceOf(Milestone);"},{"lineNumber":48,"author":{"gitId":"MadLamprey"},"content":" }"},{"lineNumber":49,"author":{"gitId":"MadLamprey"},"content":""},{"lineNumber":50,"author":{"gitId":"MadLamprey"},"content":" expect(parsedMilestones.length).toBe(2);"},{"lineNumber":51,"author":{"gitId":"MadLamprey"},"content":" expect(parsedMilestones[0].title).toBe(\u0027Milestone 1\u0027);"},{"lineNumber":52,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":53,"author":{"gitId":"MadLamprey"},"content":" });"},{"lineNumber":54,"author":{"gitId":"MadLamprey"},"content":"});"}],"authorContributionMap":{"MadLamprey":54}},{"path":"tests/services/user.service.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { GithubService } from \u0027../../src/app/core/services/github.service\u0027;"},{"lineNumber":2,"author":{"gitId":"NereusWB922"},"content":"import { LoggingService } from \u0027../../src/app/core/services/logging.service\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { UserService } from \u0027../../src/app/core/services/user.service\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { USER_JUNWEI } from \u0027../constants/data.constants\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"let githubServiceSpy: jasmine.SpyObj\u003cGithubService\u003e;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"let loggingServiceSpy: jasmine.SpyObj\u003cLoggingService\u003e;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"let userService: UserService;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"describe(\u0027UserService\u0027, () \u003d\u003e {"},{"lineNumber":11,"author":{"gitId":"-"},"content":" beforeAll(() \u003d\u003e {"},{"lineNumber":12,"author":{"gitId":"NereusWB922"},"content":" githubServiceSpy \u003d jasmine.createSpyObj(\u0027GithubService\u0027, [\u0027fetchAuthenticatedUser\u0027]);"},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":" loggingServiceSpy \u003d jasmine.createSpyObj(\u0027LoggingService\u0027, [\u0027info\u0027]);"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":" userService \u003d new UserService(githubServiceSpy, loggingServiceSpy);"},{"lineNumber":15,"author":{"gitId":"-"},"content":" });"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027createUserModel(loginId)\u0027, () \u003d\u003e {"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should create a user correctly\u0027, async () \u003d\u003e {"},{"lineNumber":19,"author":{"gitId":"NereusWB922"},"content":" const createdUser \u003d await userService.createUserModel(USER_JUNWEI.loginId).toPromise();"},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":" expect(createdUser).toEqual(USER_JUNWEI);"},{"lineNumber":21,"author":{"gitId":"-"},"content":" });"},{"lineNumber":22,"author":{"gitId":"-"},"content":" });"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027reset()\u0027, () \u003d\u003e {"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set current user as undefined\u0027, async () \u003d\u003e {"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" await userService.createUserModel(USER_JUNWEI.loginId).toPromise();"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" expect(userService.currentUser).toEqual(USER_JUNWEI);"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"NereusWB922"},"content":" userService.reset();"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" expect(loggingServiceSpy.info).toHaveBeenCalledWith(\u0027UserService: Clearing current user\u0027);"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" expect(userService.currentUser).toEqual(undefined);"},{"lineNumber":33,"author":{"gitId":"-"},"content":" });"},{"lineNumber":34,"author":{"gitId":"-"},"content":" });"},{"lineNumber":35,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"NereusWB922":20,"-":15}},{"path":"tests/services/view.service.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"NereusWB922"},"content":"import { ActivatedRoute, Router } from \u0027@angular/router\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { of } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"NereusWB922"},"content":"import { STORAGE_KEYS } from \u0027../../src/app/core/constants/storage-keys.constants\u0027;"},{"lineNumber":4,"author":{"gitId":"NereusWB922"},"content":"import { Repo } from \u0027../../src/app/core/models/repo.model\u0027;"},{"lineNumber":5,"author":{"gitId":"NereusWB922"},"content":"import { View } from \u0027../../src/app/core/models/view.model\u0027;"},{"lineNumber":6,"author":{"gitId":"NereusWB922"},"content":"import { ErrorMessageService } from \u0027../../src/app/core/services/error-message.service\u0027;"},{"lineNumber":7,"author":{"gitId":"NereusWB922"},"content":"import { GithubService } from \u0027../../src/app/core/services/github.service\u0027;"},{"lineNumber":8,"author":{"gitId":"NereusWB922"},"content":"import { LoggingService } from \u0027../../src/app/core/services/logging.service\u0027;"},{"lineNumber":9,"author":{"gitId":"NereusWB922"},"content":"import { RepoUrlCacheService } from \u0027../../src/app/core/services/repo-url-cache.service\u0027;"},{"lineNumber":10,"author":{"gitId":"NereusWB922"},"content":"import { ViewService } from \u0027../../src/app/core/services/view.service\u0027;"},{"lineNumber":11,"author":{"gitId":"NereusWB922"},"content":"import { CATCHER_REPO, WATCHER_REPO } from \u0027../constants/session.constants\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"NereusWB922"},"content":"let viewService: ViewService;"},{"lineNumber":14,"author":{"gitId":"NereusWB922"},"content":"let githubServiceSpy: jasmine.SpyObj\u003cGithubService\u003e;"},{"lineNumber":15,"author":{"gitId":"NereusWB922"},"content":"let repoUrlCacheServiceSpy: jasmine.SpyObj\u003cRepoUrlCacheService\u003e;"},{"lineNumber":16,"author":{"gitId":"NereusWB922"},"content":"let loggingServiceSpy: jasmine.SpyObj\u003cLoggingService\u003e;"},{"lineNumber":17,"author":{"gitId":"NereusWB922"},"content":"let routerSpy: jasmine.SpyObj\u003cRouter\u003e;"},{"lineNumber":18,"author":{"gitId":"NereusWB922"},"content":"let activatedRouteSpy: jasmine.SpyObj\u003cActivatedRoute\u003e;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"NereusWB922"},"content":"describe(\u0027ViewService\u0027, () \u003d\u003e {"},{"lineNumber":21,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":22,"author":{"gitId":"NereusWB922"},"content":" githubServiceSpy \u003d jasmine.createSpyObj(\u0027GithubService\u0027, [\u0027isRepositoryPresent\u0027, \u0027storeViewDetails\u0027]);"},{"lineNumber":23,"author":{"gitId":"NereusWB922"},"content":" activatedRouteSpy \u003d jasmine.createSpyObj(\u0027ActivatedRoute\u0027, [\u0027snapshot\u0027]);"},{"lineNumber":24,"author":{"gitId":"NereusWB922"},"content":" routerSpy \u003d jasmine.createSpyObj(\u0027Router\u0027, [\u0027navigate\u0027]);"},{"lineNumber":25,"author":{"gitId":"NereusWB922"},"content":" repoUrlCacheServiceSpy \u003d jasmine.createSpyObj(\u0027RepoUrlCacheService\u0027, [\u0027cache\u0027]);"},{"lineNumber":26,"author":{"gitId":"NereusWB922"},"content":" loggingServiceSpy \u003d jasmine.createSpyObj(\u0027LoggingService\u0027, [\u0027info\u0027]);"},{"lineNumber":27,"author":{"gitId":"NereusWB922"},"content":" viewService \u003d new ViewService(githubServiceSpy, repoUrlCacheServiceSpy, loggingServiceSpy, activatedRouteSpy, routerSpy);"},{"lineNumber":28,"author":{"gitId":"-"},"content":" });"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027setRepository(Repo, Repo[])\u0027, () \u003d\u003e {"},{"lineNumber":31,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set the current repositories and update session data\u0027, () \u003d\u003e {"},{"lineNumber":32,"author":{"gitId":"NereusWB922"},"content":" const repos: Repo[] \u003d [CATCHER_REPO];"},{"lineNumber":33,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":34,"author":{"gitId":"NereusWB922"},"content":" viewService.setRepository(WATCHER_REPO, repos);"},{"lineNumber":35,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":36,"author":{"gitId":"NereusWB922"},"content":" expect(viewService.currentRepo).toEqual(WATCHER_REPO);"},{"lineNumber":37,"author":{"gitId":"NereusWB922"},"content":" expect(viewService.otherRepos).toEqual(repos);"},{"lineNumber":38,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":39,"author":{"gitId":"NereusWB922"},"content":" const currentSessionRepo \u003d viewService.sessionData.sessionRepo.find((x) \u003d\u003e x.view \u003d\u003d\u003d viewService.currentView);"},{"lineNumber":40,"author":{"gitId":"NereusWB922"},"content":" expect(currentSessionRepo?.repos).toEqual([WATCHER_REPO, CATCHER_REPO]);"},{"lineNumber":41,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":42,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":43,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should store view details via githubService and update localStorage\u0027, () \u003d\u003e {"},{"lineNumber":44,"author":{"gitId":"NereusWB922"},"content":" const localStorageSetItem \u003d spyOn(localStorage, \u0027setItem\u0027);"},{"lineNumber":45,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":46,"author":{"gitId":"NereusWB922"},"content":" viewService.setRepository(WATCHER_REPO);"},{"lineNumber":47,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":48,"author":{"gitId":"NereusWB922"},"content":" expect(githubServiceSpy.storeViewDetails).toHaveBeenCalledWith(WATCHER_REPO.owner, WATCHER_REPO.name);"},{"lineNumber":49,"author":{"gitId":"NereusWB922"},"content":" expect(localStorageSetItem).toHaveBeenCalledWith(\u0027sessionData\u0027, JSON.stringify(viewService.sessionData));"},{"lineNumber":50,"author":{"gitId":"-"},"content":" });"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should navigate to the new repository\u0027, () \u003d\u003e {"},{"lineNumber":53,"author":{"gitId":"NereusWB922"},"content":" viewService.setRepository(WATCHER_REPO);"},{"lineNumber":54,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":55,"author":{"gitId":"NereusWB922"},"content":" expect(routerSpy.navigate).toHaveBeenCalledWith([\u0027issuesViewer\u0027], {"},{"lineNumber":56,"author":{"gitId":"NereusWB922"},"content":" queryParams: { repo: WATCHER_REPO.toString() },"},{"lineNumber":57,"author":{"gitId":"NereusWB922"},"content":" queryParamsHandling: \u0027merge\u0027"},{"lineNumber":58,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":59,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":60,"author":{"gitId":"-"},"content":" });"},{"lineNumber":61,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":62,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027changeRepositoryIfValid(Repo)\u0027, () \u003d\u003e {"},{"lineNumber":63,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set isChangingRepo to true at the start and false at the end\u0027, async () \u003d\u003e {"},{"lineNumber":64,"author":{"gitId":"NereusWB922"},"content":" githubServiceSpy.isRepositoryPresent.and.returnValue(of(true));"},{"lineNumber":65,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":66,"author":{"gitId":"NereusWB922"},"content":" const isChangingRepoNextSpy \u003d spyOn(viewService.isChangingRepo, \u0027next\u0027);"},{"lineNumber":67,"author":{"gitId":"NereusWB922"},"content":" spyOn(viewService, \u0027setRepository\u0027);"},{"lineNumber":68,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":69,"author":{"gitId":"NereusWB922"},"content":" await viewService.changeRepositoryIfValid(WATCHER_REPO);"},{"lineNumber":70,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":71,"author":{"gitId":"NereusWB922"},"content":" expect(isChangingRepoNextSpy.calls.first().args[0]).toBe(true);"},{"lineNumber":72,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":73,"author":{"gitId":"NereusWB922"},"content":" expect(isChangingRepoNextSpy.calls.mostRecent().args[0]).toBe(false);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" });"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should throw error if repository is not valid\u0027, async () \u003d\u003e {"},{"lineNumber":77,"author":{"gitId":"NereusWB922"},"content":" githubServiceSpy.isRepositoryPresent.and.returnValue(of(false));"},{"lineNumber":78,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":79,"author":{"gitId":"NereusWB922"},"content":" await expectAsync(viewService.changeRepositoryIfValid(WATCHER_REPO)).toBeRejectedWithError("},{"lineNumber":80,"author":{"gitId":"NereusWB922"},"content":" ErrorMessageService.repositoryNotPresentMessage()"},{"lineNumber":81,"author":{"gitId":"NereusWB922"},"content":" );"},{"lineNumber":82,"author":{"gitId":"-"},"content":" });"},{"lineNumber":83,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":84,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set and navigate to new repo if repo is valid\u0027, async () \u003d\u003e {"},{"lineNumber":85,"author":{"gitId":"NereusWB922"},"content":" githubServiceSpy.isRepositoryPresent.and.returnValue(of(true));"},{"lineNumber":86,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":87,"author":{"gitId":"NereusWB922"},"content":" const repoChanged$Spy \u003d spyOn(viewService.repoChanged$, \u0027next\u0027);"},{"lineNumber":88,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":89,"author":{"gitId":"NereusWB922"},"content":" await viewService.changeRepositoryIfValid(WATCHER_REPO);"},{"lineNumber":90,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":91,"author":{"gitId":"NereusWB922"},"content":" expect(loggingServiceSpy.info).toHaveBeenCalledWith(`ViewService: Changing current repository to \u0027${WATCHER_REPO}\u0027`);"},{"lineNumber":92,"author":{"gitId":"NereusWB922"},"content":" expect(viewService.currentRepo).toEqual(WATCHER_REPO);"},{"lineNumber":93,"author":{"gitId":"NereusWB922"},"content":" expect(routerSpy.navigate).toHaveBeenCalledWith([\u0027issuesViewer\u0027], {"},{"lineNumber":94,"author":{"gitId":"NereusWB922"},"content":" queryParams: { repo: WATCHER_REPO.toString() },"},{"lineNumber":95,"author":{"gitId":"NereusWB922"},"content":" queryParamsHandling: \u0027merge\u0027"},{"lineNumber":96,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":97,"author":{"gitId":"NereusWB922"},"content":" expect(repoUrlCacheServiceSpy.cache).toHaveBeenCalledWith(WATCHER_REPO.toString());"},{"lineNumber":98,"author":{"gitId":"NereusWB922"},"content":" expect(repoChanged$Spy).toHaveBeenCalledWith(WATCHER_REPO);"},{"lineNumber":99,"author":{"gitId":"-"},"content":" });"},{"lineNumber":100,"author":{"gitId":"-"},"content":" });"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027initializeCurrentRepository()\u0027, () \u003d\u003e {"},{"lineNumber":103,"author":{"gitId":"NereusWB922"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":104,"author":{"gitId":"NereusWB922"},"content":" const org \u003d WATCHER_REPO.owner;"},{"lineNumber":105,"author":{"gitId":"NereusWB922"},"content":" const repoName \u003d WATCHER_REPO.name;"},{"lineNumber":106,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":107,"author":{"gitId":"NereusWB922"},"content":" const localStorageGetItemSpy \u003d spyOn(window.localStorage, \u0027getItem\u0027);"},{"lineNumber":108,"author":{"gitId":"NereusWB922"},"content":" localStorageGetItemSpy.withArgs(STORAGE_KEYS.ORG).and.returnValue(org);"},{"lineNumber":109,"author":{"gitId":"NereusWB922"},"content":" localStorageGetItemSpy.withArgs(STORAGE_KEYS.DATA_REPO).and.returnValue(repoName);"},{"lineNumber":110,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":111,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":112,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set and navigate to new repo if repo is valid\u0027, async () \u003d\u003e {"},{"lineNumber":113,"author":{"gitId":"NereusWB922"},"content":" githubServiceSpy.isRepositoryPresent.and.returnValue(of(true));"},{"lineNumber":114,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":115,"author":{"gitId":"NereusWB922"},"content":" const repoSetSourceNext \u003d spyOn(viewService.repoSetSource, \u0027next\u0027);"},{"lineNumber":116,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":117,"author":{"gitId":"NereusWB922"},"content":" await viewService.initializeCurrentRepository();"},{"lineNumber":118,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":119,"author":{"gitId":"NereusWB922"},"content":" expect(loggingServiceSpy.info).toHaveBeenCalledWith(`ViewService: Repo is ${WATCHER_REPO}`);"},{"lineNumber":120,"author":{"gitId":"NereusWB922"},"content":" expect(viewService.currentRepo).toEqual(WATCHER_REPO);"},{"lineNumber":121,"author":{"gitId":"NereusWB922"},"content":" expect(routerSpy.navigate).toHaveBeenCalledWith([\u0027issuesViewer\u0027], {"},{"lineNumber":122,"author":{"gitId":"NereusWB922"},"content":" queryParams: { repo: WATCHER_REPO.toString() },"},{"lineNumber":123,"author":{"gitId":"NereusWB922"},"content":" queryParamsHandling: \u0027merge\u0027"},{"lineNumber":124,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":125,"author":{"gitId":"NereusWB922"},"content":" expect(repoSetSourceNext).toHaveBeenCalledWith(true);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" });"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should throw error if repository is invalid\u0027, async () \u003d\u003e {"},{"lineNumber":129,"author":{"gitId":"NereusWB922"},"content":" githubServiceSpy.isRepositoryPresent.and.returnValue(of(false));"},{"lineNumber":130,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":131,"author":{"gitId":"NereusWB922"},"content":" await expectAsync(viewService.initializeCurrentRepository()).toBeRejectedWithError(ErrorMessageService.repositoryNotPresentMessage());"},{"lineNumber":132,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":133,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":134,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":135,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027changeView(View)\u0027, () \u003d\u003e {"},{"lineNumber":136,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set current view\u0027, () \u003d\u003e {"},{"lineNumber":137,"author":{"gitId":"NereusWB922"},"content":" viewService.setRepository(WATCHER_REPO);"},{"lineNumber":138,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":139,"author":{"gitId":"NereusWB922"},"content":" expect(viewService.currentView).toEqual(View.issuesViewer);"},{"lineNumber":140,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":141,"author":{"gitId":"NereusWB922"},"content":" viewService.changeView(View.activityDashboard);"},{"lineNumber":142,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":143,"author":{"gitId":"NereusWB922"},"content":" expect(viewService.currentView).toEqual(View.activityDashboard);"},{"lineNumber":144,"author":{"gitId":"-"},"content":" });"},{"lineNumber":145,"author":{"gitId":"-"},"content":" });"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" describe(\u0027.reset()\u0027, () \u003d\u003e {"},{"lineNumber":148,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should reset the currentView of the ViewService\u0027, () \u003d\u003e {"},{"lineNumber":149,"author":{"gitId":"NereusWB922"},"content":" viewService.currentView \u003d View.activityDashboard;"},{"lineNumber":150,"author":{"gitId":"NereusWB922"},"content":" viewService.reset();"},{"lineNumber":151,"author":{"gitId":"NereusWB922"},"content":" expect(viewService.currentView).toBe(View.issuesViewer);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" });"},{"lineNumber":153,"author":{"gitId":"-"},"content":" });"},{"lineNumber":154,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":155,"author":{"gitId":"NereusWB922"},"content":" describe(\u0027setupFromUrl(url)\u0027, () \u003d\u003e {"},{"lineNumber":156,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should set items in local storage if url is valid\u0027, async () \u003d\u003e {"},{"lineNumber":157,"author":{"gitId":"NereusWB922"},"content":" const validUrl \u003d `/issuesViewer?repo\u003d${WATCHER_REPO.owner}%2F${WATCHER_REPO.name}`;"},{"lineNumber":158,"author":{"gitId":"NereusWB922"},"content":" const localStorageSetItemSpy \u003d spyOn(window.localStorage, \u0027setItem\u0027);"},{"lineNumber":159,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":160,"author":{"gitId":"NereusWB922"},"content":" await viewService.setupFromUrl(validUrl).toPromise();"},{"lineNumber":161,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":162,"author":{"gitId":"NereusWB922"},"content":" expect(localStorageSetItemSpy).toHaveBeenCalledWith(STORAGE_KEYS.ORG, WATCHER_REPO.owner);"},{"lineNumber":163,"author":{"gitId":"NereusWB922"},"content":" expect(localStorageSetItemSpy).toHaveBeenCalledWith(STORAGE_KEYS.DATA_REPO, WATCHER_REPO.name);"},{"lineNumber":164,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":165,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":166,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should throw error for url without repo paramater\u0027, (done) \u003d\u003e {"},{"lineNumber":167,"author":{"gitId":"NereusWB922"},"content":" const urlWithoutRepo \u003d \u0027/issuesViewer\u0027;"},{"lineNumber":168,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":169,"author":{"gitId":"NereusWB922"},"content":" viewService.setupFromUrl(urlWithoutRepo).subscribe({"},{"lineNumber":170,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e {"},{"lineNumber":171,"author":{"gitId":"NereusWB922"},"content":" expect(err).toEqual(new Error(ErrorMessageService.invalidUrlMessage()));"},{"lineNumber":172,"author":{"gitId":"NereusWB922"},"content":" done();"},{"lineNumber":173,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":174,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":175,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":176,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":177,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should throw error for empty url\u0027, (done) \u003d\u003e {"},{"lineNumber":178,"author":{"gitId":"NereusWB922"},"content":" const emptyUrl \u003d \u0027\u0027;"},{"lineNumber":179,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":180,"author":{"gitId":"NereusWB922"},"content":" viewService.setupFromUrl(emptyUrl).subscribe({"},{"lineNumber":181,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e {"},{"lineNumber":182,"author":{"gitId":"NereusWB922"},"content":" expect(err).toEqual(new Error(ErrorMessageService.invalidUrlMessage()));"},{"lineNumber":183,"author":{"gitId":"NereusWB922"},"content":" done();"},{"lineNumber":184,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":185,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":186,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":187,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":188,"author":{"gitId":"NereusWB922"},"content":" it(\u0027should throw error for url with invalid repo format\u0027, (done) \u003d\u003e {"},{"lineNumber":189,"author":{"gitId":"NereusWB922"},"content":" const urlWithInvalidRepoFormat \u003d \u0027/issuesViewer?repo\u003dInvalidRepo\u0027;"},{"lineNumber":190,"author":{"gitId":"NereusWB922"},"content":""},{"lineNumber":191,"author":{"gitId":"NereusWB922"},"content":" viewService.setupFromUrl(urlWithInvalidRepoFormat).subscribe({"},{"lineNumber":192,"author":{"gitId":"NereusWB922"},"content":" error: (err) \u003d\u003e {"},{"lineNumber":193,"author":{"gitId":"NereusWB922"},"content":" expect(err).toEqual(new Error(ErrorMessageService.repositoryNotPresentMessage()));"},{"lineNumber":194,"author":{"gitId":"NereusWB922"},"content":" done();"},{"lineNumber":195,"author":{"gitId":"NereusWB922"},"content":" }"},{"lineNumber":196,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":197,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":198,"author":{"gitId":"NereusWB922"},"content":" });"},{"lineNumber":199,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"NereusWB922":175,"-":24}}] diff --git a/CATcher-org_WATcher_main/commits.json b/CATcher-org_WATcher_main/commits.json index 74faf79..9d182d7 100644 --- a/CATcher-org_WATcher_main/commits.json +++ b/CATcher-org_WATcher_main/commits.json @@ -1 +1 @@ -{"authorDailyContributionsMap":{"xenosf":[],"sopa301":[],"mingyuanc":[],"jingting1412":[],"KevinEyo1":[],"LamJiuFong":[],"yiwen101":[],"jonasongg":[],"domoberzin":[],"asdfghjkxd":[],"yuanxi1":[],"supermii2":[],"marquestye":[],"nknguyenhc":[{"date":"2024-02-06","commitResults":[{"hash":"043311b90c12118a4d9d8468a64e1fc7021ad64d","isMergeCommit":false,"messageTitle":"Fix label filter not working (#230)","messageBody":"Fix label filter not working\r\n\r\nFilters takes the value of `label.formattedName` instead of `label.name`.","fileTypesAndContributionMap":{"html":{"insertions":13,"deletions":5}}}]},{"date":"2024-02-13","commitResults":[{"hash":"64a68624b77c88cee70cd870e2966c1c27b89eb8","isMergeCommit":false,"messageTitle":"Add column of hidden users (#235)","messageBody":"After #192, assignees of a repo without any issues or PRs\r\nare hidden. Now, add the column to display such users\r\nwith 0 PRs and issues.\r\n\r\nCo-authored-by: Gabriel Goh \u003c77230723+gycgabriel@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"css":{"insertions":82,"deletions":0},"html":{"insertions":24,"deletions":0},"ts":{"insertions":44,"deletions":2}}}]},{"date":"2024-02-19","commitResults":[{"hash":"d6dadf4a49a6fc19e2eaa99bb37c7fe89f458a81","isMergeCommit":false,"messageTitle":"Refactor Label model (#254)","messageBody":"Previously, label full names are separated into label name\r\nand label category. However, this is not necessary for WATcher.\r\n\r\nLet\u0027s remove the separation so that filters only make use\r\nof the full name.","fileTypesAndContributionMap":{"html":{"insertions":6,"deletions":14},"ts":{"insertions":6,"deletions":14}}}]},{"date":"2024-02-26","commitResults":[{"hash":"3db1c8aa33942114acfd55af87da3d7c8d751390","isMergeCommit":false,"messageTitle":"Add shareable repo-specific URL (#255)","messageBody":"Previously, URLs are fixed upon repo change, hence URLs are not shareable.\r\n\r\nLet\u0027s make the current repo visible in the URL, so that it shareable.\r\n\r\nFurthermore, login is automated when there is such next route to be redirected to.","fileTypesAndContributionMap":{"ts":{"insertions":163,"deletions":9}}}]},{"date":"2024-03-21","commitResults":[{"hash":"6fb348ea31d05320af1ecc2e7c83dcfecf95e2f7","isMergeCommit":false,"messageTitle":"Hide redundant column pagination (#309)","messageBody":"Column pagination arrows cause unnecessary clogs\r\nif they are disabled.\r\n\r\nWe hide arrows on columns that only has one page.","fileTypesAndContributionMap":{"css":{"insertions":12,"deletions":0},"html":{"insertions":6,"deletions":1},"ts":{"insertions":8,"deletions":2}}}]},{"date":"2024-03-22","commitResults":[{"hash":"e3d4a3464879414ab4724dde0f9b4cc24aebf7df","isMergeCommit":false,"messageTitle":"Three-state labels (#282)","messageBody":"Previously, each label only has 2 states, either selected or\r\nnot selected. However, with such design,\r\nthe feature of hiding labels can be confused\r\nwith hiding issues/PRs with the label.\r\n\r\nWe implement the three-state label filters,\r\nso that each label can also be used to hide\r\nissues/PRs with the label.","fileTypesAndContributionMap":{"css":{"insertions":20,"deletions":5},"html":{"insertions":22,"deletions":26},"ts":{"insertions":48,"deletions":36}}}]},{"date":"2024-03-25","commitResults":[{"hash":"a65bb59578c4157be05f3c38fd712e411e43a155","isMergeCommit":false,"messageTitle":"Status filter checkboxes (#310)","messageBody":"We implement checkboxes for status, so that\r\nmultiple types of PRs/issues can be viewed concurrently.","fileTypesAndContributionMap":{"html":{"insertions":6,"deletions":5},"ts":{"insertions":39,"deletions":39}}}]},{"date":"2024-03-29","commitResults":[{"hash":"c3418d8d50071cde7ea19040df0ec411a0f49786","isMergeCommit":false,"messageTitle":"Add preset views (#320)","messageBody":"Currently, there are a lot of options of filters,\r\nbut there are no suggested useful preset views.\r\n\r\nWe add preset views for users to choose from,\r\nand via a button on the header.","fileTypesAndContributionMap":{"html":{"insertions":22,"deletions":2},"ts":{"insertions":156,"deletions":23}}}]},{"date":"2024-03-30","commitResults":[{"hash":"3ce551efd72e12ec9b43698d84e293892d1e4964","isMergeCommit":false,"messageTitle":"Fix for no milestone case (#326)","messageBody":"When there are no milestones in the repo,\r\nthe issue viewer shows nothing.\r\n\r\nChange is made so that if there is no milestone\r\nin the milestone service, do not apply the milestone filter.","fileTypesAndContributionMap":{"ts":{"insertions":9,"deletions":4}}}]},{"date":"2024-04-01","commitResults":[{"hash":"e7fb0f992c82b05cd5418a1e747351b4a8af254a","isMergeCommit":false,"messageTitle":"Fix preset view selection appearance (#338)","messageBody":"For the preset view selection, brackets are removed\r\nand left margin is added to increase visibility.","fileTypesAndContributionMap":{"html":{"insertions":13,"deletions":15}}}]},{"date":"2024-04-03","commitResults":[{"hash":"d356fbe192b4b4761a512afbb9ba7409cc4b1362","isMergeCommit":false,"messageTitle":"Hide column issue count (#346)","messageBody":"We hide the issue column count when there is only one page,\r\nto make space for the issues.","fileTypesAndContributionMap":{"css":{"insertions":12,"deletions":9}}}]},{"date":"2024-04-11","commitResults":[{"hash":"95a5486be2ecaade7f43496356b0a1f76be7710e","isMergeCommit":false,"messageTitle":"Optimise Github API calls (#360)","messageBody":"Previously, multiple Github API calls causes Github\r\nto ask users for reauthorisation, or in rare cases,\r\nrate limit is exceeded.\r\n\r\nWe reduce the number of API calls to Github\r\nto reduce such issues.","fileTypesAndContributionMap":{"ts":{"insertions":25,"deletions":45}}}]}],"Arif-Khalid":[{"date":"2024-01-25","commitResults":[{"hash":"79602d69bd13e2ab8c06ab6d9a6eca8b4a61e8b0","isMergeCommit":false,"messageTitle":"Hide 0 issue columns (#223)","messageBody":"Hide 0 issue columns.\r\n\r\n0 Issue columns are shown.\r\n\r\nHiding issues with 0 columns reduces the clutter on screen, \r\ncreating a better user experience. \r\nIllogical columns such as issues that are unassigned when sorting by\r\npull requests are also removed inherently.\r\n\r\nLet\u0027s add logic to hide the columns when they have no issues \r\nassociated to them.","fileTypesAndContributionMap":{"html":{"insertions":10,"deletions":1},"ts":{"insertions":15,"deletions":2}}}]},{"date":"2024-02-06","commitResults":[{"hash":"cd0d7e9f2a5169307c0c92a89a33e24610381839","isMergeCommit":false,"messageTitle":"Remove unused services (#238)","messageBody":"Couple of unused services copied from CATcher.\r\n\r\nUnused code should be removed to simplify code base \r\nand improve developer experience.\r\n\r\nLet\u0027s remove these unused services.","fileTypesAndContributionMap":{"ts":{"insertions":0,"deletions":359}}}]},{"date":"2024-02-14","commitResults":[{"hash":"5031ee2e33b49d0275892849703b81a1fc028a3d","isMergeCommit":false,"messageTitle":"Remove unused models in WATcher","messageBody":"There are a few of unused models ported from CATcher.\r\n\r\nUnnecessary models contributes to code clutter and hurts understandability\r\nof code base.\r\n\r\nLet\u0027s remove these unused models from WATcher to increase code cleanliness.","fileTypesAndContributionMap":{"ts":{"insertions":0,"deletions":40}}},{"hash":"09ef51d1e360350d0d73a4a66063df59f805d3e2","isMergeCommit":false,"messageTitle":"Remove unused session-fix-confirmation component in WATcher","messageBody":"This is a component only used in CATcher.\r\n\r\nUnnecessary components contributes to code clutter and hurts understandability\r\nof code base.\r\n\r\nLet\u0027s remove this unused component from WATcher to increase code cleanliness.","fileTypesAndContributionMap":{"css":{"insertions":0,"deletions":0},"html":{"insertions":0,"deletions":9},"ts":{"insertions":1,"deletions":27}}}]},{"date":"2024-02-22","commitResults":[{"hash":"7dbc28230cf4e6d2aa3d95448a0e247b03a5fcee","isMergeCommit":false,"messageTitle":"Refactor certain filters into its own service (#259)","messageBody":"Filters are observed, subscribed and emitted in many different \r\ncomponents.\r\n\r\nThis makes the code base hard to understand\r\nand adapt for filtering in future components.\r\n\r\nLet\u0027s refactor the filters into its own centralised service.","fileTypesAndContributionMap":{"html":{"insertions":3,"deletions":3},"ts":{"insertions":73,"deletions":35}}}]},{"date":"2024-02-28","commitResults":[{"hash":"ad94663e1ac524b83b022a622544181209881c1f","isMergeCommit":false,"messageTitle":"Refactor sorting (#261)","messageBody":"MatSort is passed by reference into IssueDataTables,\r\nlifted up from filter-bar component. Changes to \r\nMatSort are detected and handled in IssueDataTables.\r\n\r\nMatSort reference in IssueDataTables performs the \r\nresponsibility of a dropdown filter outside of the \r\nfilters service.\r\nThis violates good programming practices.\r\n\r\nLet\u0027s refactor the sort filter into the filters service.","fileTypesAndContributionMap":{"html":{"insertions":8,"deletions":5},"ts":{"insertions":19,"deletions":40}}},{"hash":"ac150e0c2c69d668481bd6594339618a59ebde7c","isMergeCommit":false,"messageTitle":"Refactor milestone filters (#264)","messageBody":"","fileTypesAndContributionMap":{"html":{"insertions":2,"deletions":2}}}]},{"date":"2024-03-04","commitResults":[{"hash":"06260a9f2baada4cff35e536143ce6adae1d2c42","isMergeCommit":false,"messageTitle":"Refactor title filter (#265)","messageBody":"Title filter is handled outside of filters service\r\n\r\nThis violates the responsibility of the filters service\r\n\r\nLet\u0027s refactor the search filter to use the filters service","fileTypesAndContributionMap":{"html":{"insertions":7,"deletions":7},"ts":{"insertions":61,"deletions":83}}}]},{"date":"2024-03-12","commitResults":[{"hash":"f6a8f236d9d0b0dde9f0f97db3997e983b2b85a1","isMergeCommit":false,"messageTitle":"Refactor milestones to save by name (#289)","messageBody":"We store milestones by number.\r\n\r\nThis works when filters are confined to one repo, but\r\ndoesn\u0027t make sense when saving filters across repos.\r\n\r\nLet\u0027s refactor the milestones to save by title instead\r\nof number","fileTypesAndContributionMap":{"html":{"insertions":1,"deletions":1},"ts":{"insertions":5,"deletions":7}}}]},{"date":"2024-03-20","commitResults":[{"hash":"8817ca32edd30d76509d0f3134c3d47b90a42d92","isMergeCommit":false,"messageTitle":"Keep filters when switching repos (#281)","messageBody":"No way to keep filters when changing repos.\r\n\r\nAn option to keep the common filters will be useful for anyone\r\nmanaging multiple repositories without the hassle of reapplying \r\nthe same filters.\r\n\r\nLet\u0027s add a checkbox to the change repo dialog allowing \r\nusers to keep their filters.","fileTypesAndContributionMap":{"css":{"insertions":5,"deletions":0},"html":{"insertions":11,"deletions":3},"ts":{"insertions":89,"deletions":41}}}]},{"date":"2024-03-27","commitResults":[{"hash":"b226977751a2300b470958e5fa248edcbeb4922a","isMergeCommit":false,"messageTitle":"Keep milestones when switching repo (#311)","messageBody":"Milestones are not saved even when filters are kept.\r\n\r\nThis is inconsistent with the meaning of keeping filters.\r\n\r\nLet\u0027s implement keeping milestones across repos.","fileTypesAndContributionMap":{"ts":{"insertions":32,"deletions":1}}}]},{"date":"2024-03-30","commitResults":[{"hash":"fa69625226c3b95b08251b51d254c606d6ed888c","isMergeCommit":false,"messageTitle":"Add filters to url (#314)","messageBody":"Filters cannot be shared to among users.\r\n\r\nUsers might want to share their current view\r\nto others, consisting of their current filters.\r\n\r\nLet\u0027s pull and store filters in the URL to allow\r\nsharing of filter combinations.","fileTypesAndContributionMap":{"ts":{"insertions":71,"deletions":11}}}]},{"date":"2024-04-01","commitResults":[{"hash":"44fd3ca4c69dfd50ee8d825c5c318255530b3963","isMergeCommit":false,"messageTitle":"Fix default preset view (#334)","messageBody":"The default view is custom instead of currently active.\r\n\r\nThe default view should show the most relevant information\r\nto users. This should be the currently active preset view.\r\n\r\nLet\u0027s change the default view to be currently active.","fileTypesAndContributionMap":{"ts":{"insertions":6,"deletions":0}}}]},{"date":"2024-04-03","commitResults":[{"hash":"99d2c72e7b7ce4ccffc190e918fb0639ffe020f9","isMergeCommit":false,"messageTitle":"Remove quotation marks from url (#345)","messageBody":"Quotation marks and null parameters are present for\r\nfilters saved in url.\r\n\r\nQuotation marks are unnecessary and empty filters\r\ncan be removed from the URL in order to make it\r\nmore readable and editable by advanced users.\r\n\r\nLet\u0027s remove null params and remove quotation marks\r\nfrom the url.","fileTypesAndContributionMap":{"ts":{"insertions":65,"deletions":14}}}]},{"date":"2024-04-08","commitResults":[{"hash":"709afa760ec06204f463ce476aaefd008b8e8c0a","isMergeCommit":false,"messageTitle":"Show preset view only when repo is set (#355)","messageBody":"Preset view is shown before a repo is selected.\r\n\r\nThere is no reason to show the current preset\r\nview and might confuse users as to its purpose\r\nwhen no repo is selected.\r\n\r\nLet\u0027s hide the preset view until a repo is selected.","fileTypesAndContributionMap":{"html":{"insertions":2,"deletions":2}}}]},{"date":"2024-04-10","commitResults":[{"hash":"5ff13fec764fee4239503d43734594127ee2ba85","isMergeCommit":false,"messageTitle":"Fix top and bottom shadow of columns (#357)","messageBody":"A few bugs exist related to column shadows. \r\nTop shadow is shown when there are no elements\r\nbehind header and hidden when there are.\r\nBottom shadow sticks to the column as a user scrolls.\r\n\r\nThese are not the intended behaviour of the shadows\r\nto indicate presence of elements behind above or\r\nbelow columns respectively.\r\n\r\nLet\u0027s update the CSS to correspond to\r\nappropriate shadow behaviours.","fileTypesAndContributionMap":{"css":{"insertions":21,"deletions":25},"html":{"insertions":1,"deletions":1}}}]}],"NereusWB922":[{"date":"2024-02-06","commitResults":[{"hash":"552868032ec6a8340d1f8c8d662ad22189d134f1","isMergeCommit":false,"messageTitle":"Improve activity dashboard design (#233)","messageBody":"Improve activity dashboard design\r\n\r\nThe ID column in the event table is not useful for the user.\r\n\r\nThe design of the dashboard is too simple. The event table\u0027s height is\r\nnot fixed, and the expanded event details might cause the table to be\r\ntoo long, which is very inconvenient.\r\n\r\nTo address this, let\u0027s hide the ID column, add some information about\r\nthe actor, fix the event table height and make it scrollable, and\r\nimplement a dialog to display event details.","fileTypesAndContributionMap":{"css":{"insertions":129,"deletions":10},"html":{"insertions":72,"deletions":67},"ts":{"insertions":48,"deletions":18}}}]},{"date":"2024-02-08","commitResults":[{"hash":"a6efcb9a2fa9bcd321c37a824e4d2aafa8d07a81","isMergeCommit":false,"messageTitle":"Refactor test cases","messageBody":"The test cases for the Login Component and Session Model are outdated. \r\n\r\nAdditionally, the Conflict Model has been removed. \r\n\r\nLet\u0027s refactor the test cases for the Login Component and Session Model \r\nand remove the test cases for the Conflict Model.\r\n","fileTypesAndContributionMap":{"ts":{"insertions":86,"deletions":106}}},{"hash":"339b319aaa87913d2109774f1fc6826d37992172","isMergeCommit":false,"messageTitle":"Refactor test cases for issue paginator","messageBody":"The test cases for the issue paginator are outdated. \r\n\r\nLet\u0027s refactor the test cases for the issue paginator.","fileTypesAndContributionMap":{"ts":{"insertions":4,"deletions":9}}},{"hash":"6dc82ffeb34973054ecfb3a10ea107f2c653c7cc","isMergeCommit":false,"messageTitle":"Refactor test cases for issue sorter","messageBody":"The test cases for the issue sorter are outdated. \r\n\r\nLet\u0027s refactor the test cases for the issue sorter.","fileTypesAndContributionMap":{"ts":{"insertions":57,"deletions":15}}},{"hash":"aefd63e82bad15390696d3aa88c9cbe93cdecaf4","isMergeCommit":false,"messageTitle":"Refactor github label constants","messageBody":"GithubLabel model\u0027s properties have been changed.\r\n\r\nLet\u0027s refactor the github label constants.","fileTypesAndContributionMap":{"ts":{"insertions":13,"deletions":29}}},{"hash":"bb4cb781ae5ba81e77cd83d789277530d37aaea6","isMergeCommit":false,"messageTitle":"Refactor test cases for search filter","messageBody":"The test cases for the search filter are outdated. \r\n\r\nLet\u0027s refactor the test cases for the search filter.","fileTypesAndContributionMap":{"ts":{"insertions":9,"deletions":48}}}]},{"date":"2024-02-22","commitResults":[{"hash":"ba39c0647b5d9064fc9ccd0c4714d2eb03c9e862","isMergeCommit":false,"messageTitle":"Remove test cases for permissions service","messageBody":"The permission service has been removed. \r\n\r\nLet\u0027s remove the test cases for the permission service.","fileTypesAndContributionMap":{"ts":{"insertions":0,"deletions":74}}}]},{"date":"2024-02-26","commitResults":[{"hash":"70c883ae370d033a6ceb5edb4e42aa39e8df2b60","isMergeCommit":false,"messageTitle":"Remove constants for DataFile and Team model","messageBody":"DataFile and Team model are removed.\r\n\r\nLet\u0027s remove the constants of these models.","fileTypesAndContributionMap":{"ts":{"insertions":4,"deletions":44}}},{"hash":"2c36a3846be3987bf96ec5e482e05b96a69a1f57","isMergeCommit":false,"messageTitle":"Refactor test cases for label service","messageBody":"The test cases for the label service are outdated. \r\n\r\nLet\u0027s refactor the test cases for the label service and\r\nadd test case for fetchLabels method.","fileTypesAndContributionMap":{"ts":{"insertions":74,"deletions":241}}}]},{"date":"2024-03-02","commitResults":[{"hash":"121795c9f92a508d69c0d3490f92e161c5017eee","isMergeCommit":false,"messageTitle":"Refactor test cases for issue model","messageBody":"The GithubIssue constants and the test cases\r\nfor the issue model are outdated. \r\n\r\nLet\u0027s refactor the GithubIssue constants and the\r\ntest cases for the issue model.","fileTypesAndContributionMap":{"ts":{"insertions":133,"deletions":210}}},{"hash":"dfa05628791716d3341e4ac0f96699dca2f5362f","isMergeCommit":false,"messageTitle":"Refactor test cases for phase service","messageBody":"The test cases for the phase service are outdated. \r\n\r\nLet\u0027s refactor old test cases and add test cases for new methods.","fileTypesAndContributionMap":{"ts":{"insertions":126,"deletions":39}}}]},{"date":"2024-03-04","commitResults":[{"hash":"518ea791f4f838009c79aabed6db12d94d9ebce5","isMergeCommit":false,"messageTitle":"Fix zone testing import error (#269)","messageBody":"Npm run test will break if the import statement \r\nfor zone-testing is not at the top of test.ts file. \r\n\r\nLet\u0027s reorder the import statement and disable\r\ntslint rule for test.ts file.","fileTypesAndContributionMap":{"ts":{"insertions":4,"deletions":1}}},{"hash":"00f64fbecc6030c83f2fda114bb2a6a09e15dad2","isMergeCommit":false,"messageTitle":"Refactor test cases for issue sorter (#270)","messageBody":"The method in issue sorter has been updated.\r\n\r\nLet\u0027s refactor the test cases to match the changes.","fileTypesAndContributionMap":{"ts":{"insertions":11,"deletions":11}}},{"hash":"48b63155ba859ba7362b118740c4e40cb7785c7c","isMergeCommit":false,"messageTitle":"Refactor test cases for user service (#271)","messageBody":"The test cases for the user service are outdated. \r\n\r\nLet\u0027s refactor test cases for user service.","fileTypesAndContributionMap":{"ts":{"insertions":23,"deletions":50}}},{"hash":"8c36423a20ad868f665ef65e30d1c73cf1b2428a","isMergeCommit":false,"messageTitle":"Refactor test cases for label filter bar component (#274)","messageBody":"The test cases for the label filter bar component are outdated. \r\n\r\nLet\u0027s refactor test cases for label filter bar component","fileTypesAndContributionMap":{"ts":{"insertions":151,"deletions":60}}}]},{"date":"2024-03-08","commitResults":[{"hash":"f435ca142f7d92bcbe8651e8f4c437f13c833a50","isMergeCommit":false,"messageTitle":"Update test cases for phase service (#275)","messageBody":"Refactor and add test cases for phase service\r\n\r\nPhase service has been updated. \r\n\r\nLet\u0027s refactor and add test cases to match the changes.","fileTypesAndContributionMap":{"ts":{"insertions":71,"deletions":27}}}]},{"date":"2024-03-20","commitResults":[{"hash":"663dec3e90481c31c1411b2cd3f1829795c686f2","isMergeCommit":false,"messageTitle":"Refactor Phase Service and remove Phase (#291)","messageBody":"The concept of \"Phase\" is inherited from CATcher. Instead of \"Phase\", \r\nWATcher provides different \"Views\" of contributions in a repository.\r\n\r\nLet\u0027s replace \"Phase\" with \"View\".","fileTypesAndContributionMap":{"html":{"insertions":14,"deletions":17},"ts":{"insertions":189,"deletions":199}}}]},{"date":"2024-03-22","commitResults":[{"hash":"caadd668b7142b6efcd99080c87ac7855fc76b25","isMergeCommit":false,"messageTitle":"Setup grouping strategy and service (#308)","messageBody":"Implement GroupBy feature to allow users to group the issues/prs\r\nbased on different criteria such as milestone, status and etc.\r\n\r\nLet\u0027s set up the Grouping Strategy and Service.","fileTypesAndContributionMap":{"ts":{"insertions":259,"deletions":4}}}]},{"date":"2024-03-25","commitResults":[{"hash":"3420a738482dfb852ca23a69849b74c9c378be0e","isMergeCommit":false,"messageTitle":"Integrate Grouping Service (#313)","messageBody":"Implement GroupBy feature to allow users to group the issues/prs\r\nbased on different criteria such as milestone, status and etc.\r\n\r\nLet\u0027s integrate the grouping service in the components.","fileTypesAndContributionMap":{"css":{"insertions":2,"deletions":2},"html":{"insertions":79,"deletions":53},"ts":{"insertions":103,"deletions":58}}}]},{"date":"2024-03-29","commitResults":[{"hash":"cd4614f34a1d0707271d1782a97b3537ed32b1e5","isMergeCommit":false,"messageTitle":"Implement group by milestone (#316)","messageBody":"WATcher\u0027s default view displays issues and pull requests based solely on\r\ntheir assignees. Grouping issues and pull requests based on their\r\nassociated milestones may provide another useful view for the user.\r\n\r\nLet\u0027s implement the \"Group by Milestone\" feature.","fileTypesAndContributionMap":{"html":{"insertions":21,"deletions":0},"ts":{"insertions":61,"deletions":4}}},{"hash":"83dcdae8faa8c5ae4f8a4e73eb4ea419e88d251b","isMergeCommit":false,"messageTitle":"Include groupby params in url (#319)","messageBody":"With groupby parameters in the URL, users can easily share \r\nthe current grouping by using the URL.\r\n\r\nLet\u0027s implement initialization with URL parameters and \r\nthe ability to set groupby parameters.","fileTypesAndContributionMap":{"ts":{"insertions":93,"deletions":17}}},{"hash":"8ddcdcdb9759da81986d0d0bdb35b45b5ba39bdc","isMergeCommit":false,"messageTitle":"Reset GroupingContextService only if \"keep filter\" is selected. (#324)","messageBody":"GroupingContextService is being reset when the \"keep filter\" \r\noption is selected.\r\n\r\nLet\u0027s check if the \"keep filter\" option is selected before\r\nresetting the service.","fileTypesAndContributionMap":{"ts":{"insertions":3,"deletions":1}}},{"hash":"70bae914be0b1aae5a4ceb6a8fb1273c022797c7","isMergeCommit":false,"messageTitle":"Refactor MilestoneGroupingStrategy to match the changes in #315 (#323)","messageBody":"Special milestone groups are not added in the parseMilestoneData\r\nmethod.\r\n\r\nLet\u0027s add the special milestone groups to the result of the getGroups\r\nmethod.","fileTypesAndContributionMap":{"ts":{"insertions":4,"deletions":1}}},{"hash":"2eb2aba8980fb39dd9cfd9cd704873ed48aed0d4","isMergeCommit":false,"messageTitle":"Update repo on back and forward navigation (#322)","messageBody":"IssueViewer\u0027s repository is not updated when navigating back or forward\r\nin the URL history. This will lead to inconsistency between the URL\r\nparameters and the application state.\r\n\r\nLet\u0027s ensure that IssueViewer\u0027s repository is updated on back and forward\r\nnavigation.","fileTypesAndContributionMap":{"ts":{"insertions":18,"deletions":1}}}]},{"date":"2024-03-30","commitResults":[{"hash":"3f0aa1fac438fdc1ba505494a4b75ad1b364fa86","isMergeCommit":false,"messageTitle":"Enable npm run test in GitHub Action (#325)","messageBody":"Enabling automate testing in GitHub Actions with enhanced \r\ncode quality of the codebase.\r\n\r\nLet\u0027s enable automate testing.","fileTypesAndContributionMap":{"ts":{"insertions":8,"deletions":5}}}]},{"date":"2024-04-01","commitResults":[{"hash":"b603307a9e30e8bb74773c354fc41e1c36983df9","isMergeCommit":false,"messageTitle":"Show PRs without milestone in \"Currently Active\"","messageBody":"PRs without milestone requires urgent action from the user.\r\n\r\nLet\u0027s show it in the \"Currently Active\" preset view.","fileTypesAndContributionMap":{"ts":{"insertions":3,"deletions":3}}}]},{"date":"2024-04-03","commitResults":[{"hash":"775e59ce6371251c8ae2cb075f75ccb29ad8b6d2","isMergeCommit":false,"messageTitle":"Implement dropdown menu for repo change (#347)","messageBody":"Introduce a dropdown menu for repository selection,\r\nsimplifying the process of switching between repositories. \r\n\r\nThis enhancement offers users a quicker and more\r\nintuitive method to navigate to previously visited repositories.","fileTypesAndContributionMap":{"css":{"insertions":32,"deletions":0},"html":{"insertions":28,"deletions":2},"ts":{"insertions":15,"deletions":2}}}]},{"date":"2024-04-10","commitResults":[{"hash":"a5e695ab2f183b6d10f2c1bf1db20ef7403e4cc1","isMergeCommit":false,"messageTitle":"Consider open milestone without deadline as currently active (#359)","messageBody":"For open milestones, only those with deadlines were considered as currently\r\nactive. This led to setting a closed milestone with the latest deadline as\r\ncurrently active when there is an open milestone without deadline.\r\n\r\nLet\u0027s update the selection logic to also include open milestones\r\nwithout deadlines.","fileTypesAndContributionMap":{"ts":{"insertions":27,"deletions":12}}}]}],"dishenggg":[],"MadLamprey":[{"date":"2024-01-27","commitResults":[{"hash":"bb4a7f4063c0aa33b80188a83bfc610fe147950a","isMergeCommit":false,"messageTitle":"Prevent redirection when repo not set (#228)","messageBody":"Co-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e","fileTypesAndContributionMap":{"html":{"insertions":4,"deletions":1}}}]},{"date":"2024-02-29","commitResults":[{"hash":"db460275c3952308858654140b7ccdbe93b33a12","isMergeCommit":false,"messageTitle":"Upgrade to Angular 11 (#252)","messageBody":"Co-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e\r\nCo-authored-by: Chee Hong \u003cc.h.wong2606@gmail.com\u003e","fileTypesAndContributionMap":{"ts":{"insertions":17,"deletions":13}}}]},{"date":"2024-03-12","commitResults":[{"hash":"7e68bbdaeceb5bdfcc8c09e0f3f7cbd9bd3000f4","isMergeCommit":false,"messageTitle":"Remove sorting by assignees in Issue Sorter (#286)","messageBody":"Co-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e","fileTypesAndContributionMap":{"ts":{"insertions":9,"deletions":24}}}]},{"date":"2024-03-21","commitResults":[{"hash":"63ed6a2329d9343bdf18afc39b44653809e3370a","isMergeCommit":false,"messageTitle":"Add tool tip for hidden users (#307)","messageBody":"Currently, there is no tool tip for the Hidden Users mat-card.\r\nIt is not immediately obvious what the column is referring to.\r\n\r\nLet\u0027s add a tool tip to make it more explanatory.\r\n\r\nCo-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e","fileTypesAndContributionMap":{"html":{"insertions":1,"deletions":1}}}]},{"date":"2024-03-25","commitResults":[{"hash":"43ea689bd406857d7dae518ab089bf4d3029b564","isMergeCommit":false,"messageTitle":"Create tests for Error Handling service (#304)","messageBody":"Co-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e","fileTypesAndContributionMap":{"ts":{"insertions":101,"deletions":0}}},{"hash":"1fa6138cd5d66d33203fcab810011e9eaefab9c9","isMergeCommit":false,"messageTitle":"Create tests for Milestone service (#303)","messageBody":"Co-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e","fileTypesAndContributionMap":{"ts":{"insertions":55,"deletions":0}}}]},{"date":"2024-03-29","commitResults":[{"hash":"0867e1cbf2725df92870a321f91dd328af09e19c","isMergeCommit":false,"messageTitle":"Add sorting by Status (#318)","messageBody":"Co-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e\r\nCo-authored-by: Nguyen \u003c87511888+nknguyenhc@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"html":{"insertions":3,"deletions":0},"ts":{"insertions":23,"deletions":0}}},{"hash":"b1f3eed7d98e8fb6589e5bcde167f03d5942fe98","isMergeCommit":false,"messageTitle":"Split \u0027Without a milestone\u0027 option (#315)","messageBody":"Co-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e\r\nCo-authored-by: nknguyenhc \u003c87511888+nknguyenhc@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"html":{"insertions":2,"deletions":0},"ts":{"insertions":17,"deletions":14}}}]},{"date":"2024-04-03","commitResults":[{"hash":"d92079ba532ffc56283da245efe295f5edb4f203","isMergeCommit":false,"messageTitle":"Add icon for PRs without milestones (#337)","messageBody":"Co-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e","fileTypesAndContributionMap":{"html":{"insertions":8,"deletions":5},"ts":{"insertions":8,"deletions":1}}}]},{"date":"2024-04-11","commitResults":[{"hash":"d70f9b1881972d0491ee92774f04ae29f0a9233b","isMergeCommit":false,"messageTitle":"Make ItemsPerPage common for all card views (#362)","messageBody":"Co-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e","fileTypesAndContributionMap":{"css":{"insertions":2,"deletions":2},"html":{"insertions":14,"deletions":3},"ts":{"insertions":23,"deletions":7}}}]}],"Tim-Siu":[]},"authorFileTypeContributionMap":{"xenosf":{"js":0,"css":0,"html":0,"ts":0},"sopa301":{"js":0,"css":0,"html":0,"ts":0},"mingyuanc":{"js":0,"css":0,"html":0,"ts":0},"jingting1412":{"js":0,"css":0,"html":0,"ts":0},"KevinEyo1":{"js":0,"css":0,"html":0,"ts":0},"LamJiuFong":{"js":0,"css":0,"html":0,"ts":0},"yiwen101":{"js":0,"css":0,"html":0,"ts":0},"jonasongg":{"js":0,"css":0,"html":0,"ts":0},"domoberzin":{"js":0,"css":0,"html":0,"ts":0},"asdfghjkxd":{"js":0,"css":0,"html":0,"ts":0},"yuanxi1":{"js":0,"css":0,"html":0,"ts":0},"supermii2":{"js":0,"css":0,"html":0,"ts":0},"marquestye":{"js":0,"css":0,"html":0,"ts":0},"nknguyenhc":{"js":0,"css":121,"html":42,"ts":402},"Arif-Khalid":{"js":0,"css":24,"html":28,"ts":292},"NereusWB922":{"js":0,"css":162,"html":157,"ts":1450},"dishenggg":{"js":0,"css":0,"html":0,"ts":0},"MadLamprey":{"js":0,"css":2,"html":25,"ts":243},"Tim-Siu":{"js":0,"css":0,"html":0,"ts":0}},"authorContributionVariance":{"xenosf":0.0,"sopa301":0.0,"mingyuanc":0.0,"jingting1412":0.0,"KevinEyo1":0.0,"LamJiuFong":0.0,"yiwen101":0.0,"jonasongg":0.0,"domoberzin":0.0,"asdfghjkxd":0.0,"yuanxi1":0.0,"supermii2":0.0,"marquestye":0.0,"nknguyenhc":963.3614,"Arif-Khalid":1555.0162,"NereusWB922":8005.9688,"dishenggg":0.0,"MadLamprey":240.27345,"Tim-Siu":0.0},"authorDisplayNameMap":{"xenosf":"XENO..NONG","sopa301":"POON..RYAN","mingyuanc":"CHIN..YUAN","jingting1412":"WANG..TING","KevinEyo1":"EYO ..EVIN","LamJiuFong":"LAM ..FONG","yiwen101":"WANG..IWEN","jonasongg":"JONA.. WEI","domoberzin":"DOMI.. GIN","asdfghjkxd":"GEOR.. YAO","yuanxi1":"ZHU ..ANXI","supermii2":"ALVI..S NG","marquestye":"TYE ..QUES","nknguyenhc":"NGUY..UYEN","Arif-Khalid":"ARIF..ALID","NereusWB922":"NERE.. BIN","dishenggg":"YEO ..HENG","MadLamprey":"MISR..ITYA","Tim-Siu":"XU S..UYAO"}} +{"authorDailyContributionsMap":{"xenosf":[],"sopa301":[],"mingyuanc":[],"jingting1412":[],"KevinEyo1":[],"LamJiuFong":[],"yiwen101":[],"jonasongg":[],"domoberzin":[],"asdfghjkxd":[],"yuanxi1":[],"supermii2":[],"marquestye":[],"nknguyenhc":[{"date":"2024-02-06","commitResults":[{"hash":"043311b90c12118a4d9d8468a64e1fc7021ad64d","isMergeCommit":false,"messageTitle":"Fix label filter not working (#230)","messageBody":"Fix label filter not working\r\n\r\nFilters takes the value of `label.formattedName` instead of `label.name`.","fileTypesAndContributionMap":{"html":{"insertions":13,"deletions":5}}}]},{"date":"2024-02-13","commitResults":[{"hash":"64a68624b77c88cee70cd870e2966c1c27b89eb8","isMergeCommit":false,"messageTitle":"Add column of hidden users (#235)","messageBody":"After #192, assignees of a repo without any issues or PRs\r\nare hidden. Now, add the column to display such users\r\nwith 0 PRs and issues.\r\n\r\nCo-authored-by: Gabriel Goh \u003c77230723+gycgabriel@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"css":{"insertions":82,"deletions":0},"html":{"insertions":24,"deletions":0},"ts":{"insertions":44,"deletions":2}}}]},{"date":"2024-02-19","commitResults":[{"hash":"d6dadf4a49a6fc19e2eaa99bb37c7fe89f458a81","isMergeCommit":false,"messageTitle":"Refactor Label model (#254)","messageBody":"Previously, label full names are separated into label name\r\nand label category. However, this is not necessary for WATcher.\r\n\r\nLet\u0027s remove the separation so that filters only make use\r\nof the full name.","fileTypesAndContributionMap":{"html":{"insertions":6,"deletions":14},"ts":{"insertions":6,"deletions":14}}}]},{"date":"2024-02-26","commitResults":[{"hash":"3db1c8aa33942114acfd55af87da3d7c8d751390","isMergeCommit":false,"messageTitle":"Add shareable repo-specific URL (#255)","messageBody":"Previously, URLs are fixed upon repo change, hence URLs are not shareable.\r\n\r\nLet\u0027s make the current repo visible in the URL, so that it shareable.\r\n\r\nFurthermore, login is automated when there is such next route to be redirected to.","fileTypesAndContributionMap":{"ts":{"insertions":163,"deletions":9}}}]},{"date":"2024-03-21","commitResults":[{"hash":"6fb348ea31d05320af1ecc2e7c83dcfecf95e2f7","isMergeCommit":false,"messageTitle":"Hide redundant column pagination (#309)","messageBody":"Column pagination arrows cause unnecessary clogs\r\nif they are disabled.\r\n\r\nWe hide arrows on columns that only has one page.","fileTypesAndContributionMap":{"css":{"insertions":12,"deletions":0},"html":{"insertions":6,"deletions":1},"ts":{"insertions":8,"deletions":2}}}]},{"date":"2024-03-22","commitResults":[{"hash":"e3d4a3464879414ab4724dde0f9b4cc24aebf7df","isMergeCommit":false,"messageTitle":"Three-state labels (#282)","messageBody":"Previously, each label only has 2 states, either selected or\r\nnot selected. However, with such design,\r\nthe feature of hiding labels can be confused\r\nwith hiding issues/PRs with the label.\r\n\r\nWe implement the three-state label filters,\r\nso that each label can also be used to hide\r\nissues/PRs with the label.","fileTypesAndContributionMap":{"css":{"insertions":20,"deletions":5},"html":{"insertions":22,"deletions":26},"ts":{"insertions":48,"deletions":36}}}]},{"date":"2024-03-25","commitResults":[{"hash":"a65bb59578c4157be05f3c38fd712e411e43a155","isMergeCommit":false,"messageTitle":"Status filter checkboxes (#310)","messageBody":"We implement checkboxes for status, so that\r\nmultiple types of PRs/issues can be viewed concurrently.","fileTypesAndContributionMap":{"html":{"insertions":6,"deletions":5},"ts":{"insertions":39,"deletions":39}}}]},{"date":"2024-03-29","commitResults":[{"hash":"c3418d8d50071cde7ea19040df0ec411a0f49786","isMergeCommit":false,"messageTitle":"Add preset views (#320)","messageBody":"Currently, there are a lot of options of filters,\r\nbut there are no suggested useful preset views.\r\n\r\nWe add preset views for users to choose from,\r\nand via a button on the header.","fileTypesAndContributionMap":{"html":{"insertions":22,"deletions":2},"ts":{"insertions":156,"deletions":23}}}]},{"date":"2024-03-30","commitResults":[{"hash":"3ce551efd72e12ec9b43698d84e293892d1e4964","isMergeCommit":false,"messageTitle":"Fix for no milestone case (#326)","messageBody":"When there are no milestones in the repo,\r\nthe issue viewer shows nothing.\r\n\r\nChange is made so that if there is no milestone\r\nin the milestone service, do not apply the milestone filter.","fileTypesAndContributionMap":{"ts":{"insertions":9,"deletions":4}}}]},{"date":"2024-04-01","commitResults":[{"hash":"e7fb0f992c82b05cd5418a1e747351b4a8af254a","isMergeCommit":false,"messageTitle":"Fix preset view selection appearance (#338)","messageBody":"For the preset view selection, brackets are removed\r\nand left margin is added to increase visibility.","fileTypesAndContributionMap":{"html":{"insertions":13,"deletions":15}}}]},{"date":"2024-04-03","commitResults":[{"hash":"d356fbe192b4b4761a512afbb9ba7409cc4b1362","isMergeCommit":false,"messageTitle":"Hide column issue count (#346)","messageBody":"We hide the issue column count when there is only one page,\r\nto make space for the issues.","fileTypesAndContributionMap":{"css":{"insertions":12,"deletions":9}}}]},{"date":"2024-04-11","commitResults":[{"hash":"95a5486be2ecaade7f43496356b0a1f76be7710e","isMergeCommit":false,"messageTitle":"Optimise Github API calls (#360)","messageBody":"Previously, multiple Github API calls causes Github\r\nto ask users for reauthorisation, or in rare cases,\r\nrate limit is exceeded.\r\n\r\nWe reduce the number of API calls to Github\r\nto reduce such issues.","fileTypesAndContributionMap":{"ts":{"insertions":25,"deletions":45}}}]}],"Arif-Khalid":[{"date":"2024-01-25","commitResults":[{"hash":"79602d69bd13e2ab8c06ab6d9a6eca8b4a61e8b0","isMergeCommit":false,"messageTitle":"Hide 0 issue columns (#223)","messageBody":"Hide 0 issue columns.\r\n\r\n0 Issue columns are shown.\r\n\r\nHiding issues with 0 columns reduces the clutter on screen, \r\ncreating a better user experience. \r\nIllogical columns such as issues that are unassigned when sorting by\r\npull requests are also removed inherently.\r\n\r\nLet\u0027s add logic to hide the columns when they have no issues \r\nassociated to them.","fileTypesAndContributionMap":{"html":{"insertions":10,"deletions":1},"ts":{"insertions":15,"deletions":2}}}]},{"date":"2024-02-06","commitResults":[{"hash":"cd0d7e9f2a5169307c0c92a89a33e24610381839","isMergeCommit":false,"messageTitle":"Remove unused services (#238)","messageBody":"Couple of unused services copied from CATcher.\r\n\r\nUnused code should be removed to simplify code base \r\nand improve developer experience.\r\n\r\nLet\u0027s remove these unused services.","fileTypesAndContributionMap":{"ts":{"insertions":0,"deletions":359}}}]},{"date":"2024-02-14","commitResults":[{"hash":"5031ee2e33b49d0275892849703b81a1fc028a3d","isMergeCommit":false,"messageTitle":"Remove unused models in WATcher","messageBody":"There are a few of unused models ported from CATcher.\r\n\r\nUnnecessary models contributes to code clutter and hurts understandability\r\nof code base.\r\n\r\nLet\u0027s remove these unused models from WATcher to increase code cleanliness.","fileTypesAndContributionMap":{"ts":{"insertions":0,"deletions":40}}},{"hash":"09ef51d1e360350d0d73a4a66063df59f805d3e2","isMergeCommit":false,"messageTitle":"Remove unused session-fix-confirmation component in WATcher","messageBody":"This is a component only used in CATcher.\r\n\r\nUnnecessary components contributes to code clutter and hurts understandability\r\nof code base.\r\n\r\nLet\u0027s remove this unused component from WATcher to increase code cleanliness.","fileTypesAndContributionMap":{"css":{"insertions":0,"deletions":0},"html":{"insertions":0,"deletions":9},"ts":{"insertions":1,"deletions":27}}}]},{"date":"2024-02-22","commitResults":[{"hash":"7dbc28230cf4e6d2aa3d95448a0e247b03a5fcee","isMergeCommit":false,"messageTitle":"Refactor certain filters into its own service (#259)","messageBody":"Filters are observed, subscribed and emitted in many different \r\ncomponents.\r\n\r\nThis makes the code base hard to understand\r\nand adapt for filtering in future components.\r\n\r\nLet\u0027s refactor the filters into its own centralised service.","fileTypesAndContributionMap":{"html":{"insertions":3,"deletions":3},"ts":{"insertions":73,"deletions":35}}}]},{"date":"2024-02-28","commitResults":[{"hash":"ad94663e1ac524b83b022a622544181209881c1f","isMergeCommit":false,"messageTitle":"Refactor sorting (#261)","messageBody":"MatSort is passed by reference into IssueDataTables,\r\nlifted up from filter-bar component. Changes to \r\nMatSort are detected and handled in IssueDataTables.\r\n\r\nMatSort reference in IssueDataTables performs the \r\nresponsibility of a dropdown filter outside of the \r\nfilters service.\r\nThis violates good programming practices.\r\n\r\nLet\u0027s refactor the sort filter into the filters service.","fileTypesAndContributionMap":{"html":{"insertions":8,"deletions":5},"ts":{"insertions":19,"deletions":40}}},{"hash":"ac150e0c2c69d668481bd6594339618a59ebde7c","isMergeCommit":false,"messageTitle":"Refactor milestone filters (#264)","messageBody":"","fileTypesAndContributionMap":{"html":{"insertions":2,"deletions":2}}}]},{"date":"2024-03-04","commitResults":[{"hash":"06260a9f2baada4cff35e536143ce6adae1d2c42","isMergeCommit":false,"messageTitle":"Refactor title filter (#265)","messageBody":"Title filter is handled outside of filters service\r\n\r\nThis violates the responsibility of the filters service\r\n\r\nLet\u0027s refactor the search filter to use the filters service","fileTypesAndContributionMap":{"html":{"insertions":7,"deletions":7},"ts":{"insertions":61,"deletions":83}}}]},{"date":"2024-03-12","commitResults":[{"hash":"f6a8f236d9d0b0dde9f0f97db3997e983b2b85a1","isMergeCommit":false,"messageTitle":"Refactor milestones to save by name (#289)","messageBody":"We store milestones by number.\r\n\r\nThis works when filters are confined to one repo, but\r\ndoesn\u0027t make sense when saving filters across repos.\r\n\r\nLet\u0027s refactor the milestones to save by title instead\r\nof number","fileTypesAndContributionMap":{"html":{"insertions":1,"deletions":1},"ts":{"insertions":5,"deletions":7}}}]},{"date":"2024-03-20","commitResults":[{"hash":"8817ca32edd30d76509d0f3134c3d47b90a42d92","isMergeCommit":false,"messageTitle":"Keep filters when switching repos (#281)","messageBody":"No way to keep filters when changing repos.\r\n\r\nAn option to keep the common filters will be useful for anyone\r\nmanaging multiple repositories without the hassle of reapplying \r\nthe same filters.\r\n\r\nLet\u0027s add a checkbox to the change repo dialog allowing \r\nusers to keep their filters.","fileTypesAndContributionMap":{"css":{"insertions":5,"deletions":0},"html":{"insertions":11,"deletions":3},"ts":{"insertions":89,"deletions":41}}}]},{"date":"2024-03-27","commitResults":[{"hash":"b226977751a2300b470958e5fa248edcbeb4922a","isMergeCommit":false,"messageTitle":"Keep milestones when switching repo (#311)","messageBody":"Milestones are not saved even when filters are kept.\r\n\r\nThis is inconsistent with the meaning of keeping filters.\r\n\r\nLet\u0027s implement keeping milestones across repos.","fileTypesAndContributionMap":{"ts":{"insertions":32,"deletions":1}}}]},{"date":"2024-03-30","commitResults":[{"hash":"fa69625226c3b95b08251b51d254c606d6ed888c","isMergeCommit":false,"messageTitle":"Add filters to url (#314)","messageBody":"Filters cannot be shared to among users.\r\n\r\nUsers might want to share their current view\r\nto others, consisting of their current filters.\r\n\r\nLet\u0027s pull and store filters in the URL to allow\r\nsharing of filter combinations.","fileTypesAndContributionMap":{"ts":{"insertions":71,"deletions":11}}}]},{"date":"2024-04-01","commitResults":[{"hash":"44fd3ca4c69dfd50ee8d825c5c318255530b3963","isMergeCommit":false,"messageTitle":"Fix default preset view (#334)","messageBody":"The default view is custom instead of currently active.\r\n\r\nThe default view should show the most relevant information\r\nto users. This should be the currently active preset view.\r\n\r\nLet\u0027s change the default view to be currently active.","fileTypesAndContributionMap":{"ts":{"insertions":6,"deletions":0}}}]},{"date":"2024-04-03","commitResults":[{"hash":"99d2c72e7b7ce4ccffc190e918fb0639ffe020f9","isMergeCommit":false,"messageTitle":"Remove quotation marks from url (#345)","messageBody":"Quotation marks and null parameters are present for\r\nfilters saved in url.\r\n\r\nQuotation marks are unnecessary and empty filters\r\ncan be removed from the URL in order to make it\r\nmore readable and editable by advanced users.\r\n\r\nLet\u0027s remove null params and remove quotation marks\r\nfrom the url.","fileTypesAndContributionMap":{"ts":{"insertions":65,"deletions":14}}}]},{"date":"2024-04-08","commitResults":[{"hash":"709afa760ec06204f463ce476aaefd008b8e8c0a","isMergeCommit":false,"messageTitle":"Show preset view only when repo is set (#355)","messageBody":"Preset view is shown before a repo is selected.\r\n\r\nThere is no reason to show the current preset\r\nview and might confuse users as to its purpose\r\nwhen no repo is selected.\r\n\r\nLet\u0027s hide the preset view until a repo is selected.","fileTypesAndContributionMap":{"html":{"insertions":2,"deletions":2}}}]},{"date":"2024-04-10","commitResults":[{"hash":"5ff13fec764fee4239503d43734594127ee2ba85","isMergeCommit":false,"messageTitle":"Fix top and bottom shadow of columns (#357)","messageBody":"A few bugs exist related to column shadows. \r\nTop shadow is shown when there are no elements\r\nbehind header and hidden when there are.\r\nBottom shadow sticks to the column as a user scrolls.\r\n\r\nThese are not the intended behaviour of the shadows\r\nto indicate presence of elements behind above or\r\nbelow columns respectively.\r\n\r\nLet\u0027s update the CSS to correspond to\r\nappropriate shadow behaviours.","fileTypesAndContributionMap":{"css":{"insertions":21,"deletions":25},"html":{"insertions":1,"deletions":1}}}]},{"date":"2024-04-19","commitResults":[{"hash":"1fc836f10412e10a15fb0bb8bdaae1df2cc54b66","isMergeCommit":false,"messageTitle":"Fix reset of filters on label fetch (#374)","messageBody":"There is a bug where filters are reset when \r\nlabels are fetched.\r\n\r\nThis bug can cause sudden, unprompted\r\nchanges to filters.\r\n\r\nLet\u0027s change the filter\u0027s service behaviour\r\nwhen fetching labels to stop resetting filters.","fileTypesAndContributionMap":{"ts":{"insertions":42,"deletions":30}}}]}],"NereusWB922":[{"date":"2024-02-06","commitResults":[{"hash":"552868032ec6a8340d1f8c8d662ad22189d134f1","isMergeCommit":false,"messageTitle":"Improve activity dashboard design (#233)","messageBody":"Improve activity dashboard design\r\n\r\nThe ID column in the event table is not useful for the user.\r\n\r\nThe design of the dashboard is too simple. The event table\u0027s height is\r\nnot fixed, and the expanded event details might cause the table to be\r\ntoo long, which is very inconvenient.\r\n\r\nTo address this, let\u0027s hide the ID column, add some information about\r\nthe actor, fix the event table height and make it scrollable, and\r\nimplement a dialog to display event details.","fileTypesAndContributionMap":{"css":{"insertions":129,"deletions":10},"html":{"insertions":72,"deletions":67},"ts":{"insertions":48,"deletions":18}}}]},{"date":"2024-02-08","commitResults":[{"hash":"a6efcb9a2fa9bcd321c37a824e4d2aafa8d07a81","isMergeCommit":false,"messageTitle":"Refactor test cases","messageBody":"The test cases for the Login Component and Session Model are outdated. \r\n\r\nAdditionally, the Conflict Model has been removed. \r\n\r\nLet\u0027s refactor the test cases for the Login Component and Session Model \r\nand remove the test cases for the Conflict Model.\r\n","fileTypesAndContributionMap":{"ts":{"insertions":86,"deletions":106}}},{"hash":"339b319aaa87913d2109774f1fc6826d37992172","isMergeCommit":false,"messageTitle":"Refactor test cases for issue paginator","messageBody":"The test cases for the issue paginator are outdated. \r\n\r\nLet\u0027s refactor the test cases for the issue paginator.","fileTypesAndContributionMap":{"ts":{"insertions":4,"deletions":9}}},{"hash":"6dc82ffeb34973054ecfb3a10ea107f2c653c7cc","isMergeCommit":false,"messageTitle":"Refactor test cases for issue sorter","messageBody":"The test cases for the issue sorter are outdated. \r\n\r\nLet\u0027s refactor the test cases for the issue sorter.","fileTypesAndContributionMap":{"ts":{"insertions":57,"deletions":15}}},{"hash":"aefd63e82bad15390696d3aa88c9cbe93cdecaf4","isMergeCommit":false,"messageTitle":"Refactor github label constants","messageBody":"GithubLabel model\u0027s properties have been changed.\r\n\r\nLet\u0027s refactor the github label constants.","fileTypesAndContributionMap":{"ts":{"insertions":13,"deletions":29}}},{"hash":"bb4cb781ae5ba81e77cd83d789277530d37aaea6","isMergeCommit":false,"messageTitle":"Refactor test cases for search filter","messageBody":"The test cases for the search filter are outdated. \r\n\r\nLet\u0027s refactor the test cases for the search filter.","fileTypesAndContributionMap":{"ts":{"insertions":9,"deletions":48}}}]},{"date":"2024-02-22","commitResults":[{"hash":"ba39c0647b5d9064fc9ccd0c4714d2eb03c9e862","isMergeCommit":false,"messageTitle":"Remove test cases for permissions service","messageBody":"The permission service has been removed. \r\n\r\nLet\u0027s remove the test cases for the permission service.","fileTypesAndContributionMap":{"ts":{"insertions":0,"deletions":74}}}]},{"date":"2024-02-26","commitResults":[{"hash":"70c883ae370d033a6ceb5edb4e42aa39e8df2b60","isMergeCommit":false,"messageTitle":"Remove constants for DataFile and Team model","messageBody":"DataFile and Team model are removed.\r\n\r\nLet\u0027s remove the constants of these models.","fileTypesAndContributionMap":{"ts":{"insertions":4,"deletions":44}}},{"hash":"2c36a3846be3987bf96ec5e482e05b96a69a1f57","isMergeCommit":false,"messageTitle":"Refactor test cases for label service","messageBody":"The test cases for the label service are outdated. \r\n\r\nLet\u0027s refactor the test cases for the label service and\r\nadd test case for fetchLabels method.","fileTypesAndContributionMap":{"ts":{"insertions":74,"deletions":241}}}]},{"date":"2024-03-02","commitResults":[{"hash":"121795c9f92a508d69c0d3490f92e161c5017eee","isMergeCommit":false,"messageTitle":"Refactor test cases for issue model","messageBody":"The GithubIssue constants and the test cases\r\nfor the issue model are outdated. \r\n\r\nLet\u0027s refactor the GithubIssue constants and the\r\ntest cases for the issue model.","fileTypesAndContributionMap":{"ts":{"insertions":133,"deletions":210}}},{"hash":"dfa05628791716d3341e4ac0f96699dca2f5362f","isMergeCommit":false,"messageTitle":"Refactor test cases for phase service","messageBody":"The test cases for the phase service are outdated. \r\n\r\nLet\u0027s refactor old test cases and add test cases for new methods.","fileTypesAndContributionMap":{"ts":{"insertions":126,"deletions":39}}}]},{"date":"2024-03-04","commitResults":[{"hash":"518ea791f4f838009c79aabed6db12d94d9ebce5","isMergeCommit":false,"messageTitle":"Fix zone testing import error (#269)","messageBody":"Npm run test will break if the import statement \r\nfor zone-testing is not at the top of test.ts file. \r\n\r\nLet\u0027s reorder the import statement and disable\r\ntslint rule for test.ts file.","fileTypesAndContributionMap":{"ts":{"insertions":4,"deletions":1}}},{"hash":"00f64fbecc6030c83f2fda114bb2a6a09e15dad2","isMergeCommit":false,"messageTitle":"Refactor test cases for issue sorter (#270)","messageBody":"The method in issue sorter has been updated.\r\n\r\nLet\u0027s refactor the test cases to match the changes.","fileTypesAndContributionMap":{"ts":{"insertions":11,"deletions":11}}},{"hash":"48b63155ba859ba7362b118740c4e40cb7785c7c","isMergeCommit":false,"messageTitle":"Refactor test cases for user service (#271)","messageBody":"The test cases for the user service are outdated. \r\n\r\nLet\u0027s refactor test cases for user service.","fileTypesAndContributionMap":{"ts":{"insertions":23,"deletions":50}}},{"hash":"8c36423a20ad868f665ef65e30d1c73cf1b2428a","isMergeCommit":false,"messageTitle":"Refactor test cases for label filter bar component (#274)","messageBody":"The test cases for the label filter bar component are outdated. \r\n\r\nLet\u0027s refactor test cases for label filter bar component","fileTypesAndContributionMap":{"ts":{"insertions":151,"deletions":60}}}]},{"date":"2024-03-08","commitResults":[{"hash":"f435ca142f7d92bcbe8651e8f4c437f13c833a50","isMergeCommit":false,"messageTitle":"Update test cases for phase service (#275)","messageBody":"Refactor and add test cases for phase service\r\n\r\nPhase service has been updated. \r\n\r\nLet\u0027s refactor and add test cases to match the changes.","fileTypesAndContributionMap":{"ts":{"insertions":71,"deletions":27}}}]},{"date":"2024-03-20","commitResults":[{"hash":"663dec3e90481c31c1411b2cd3f1829795c686f2","isMergeCommit":false,"messageTitle":"Refactor Phase Service and remove Phase (#291)","messageBody":"The concept of \"Phase\" is inherited from CATcher. Instead of \"Phase\", \r\nWATcher provides different \"Views\" of contributions in a repository.\r\n\r\nLet\u0027s replace \"Phase\" with \"View\".","fileTypesAndContributionMap":{"html":{"insertions":14,"deletions":17},"ts":{"insertions":189,"deletions":199}}}]},{"date":"2024-03-22","commitResults":[{"hash":"caadd668b7142b6efcd99080c87ac7855fc76b25","isMergeCommit":false,"messageTitle":"Setup grouping strategy and service (#308)","messageBody":"Implement GroupBy feature to allow users to group the issues/prs\r\nbased on different criteria such as milestone, status and etc.\r\n\r\nLet\u0027s set up the Grouping Strategy and Service.","fileTypesAndContributionMap":{"ts":{"insertions":259,"deletions":4}}}]},{"date":"2024-03-25","commitResults":[{"hash":"3420a738482dfb852ca23a69849b74c9c378be0e","isMergeCommit":false,"messageTitle":"Integrate Grouping Service (#313)","messageBody":"Implement GroupBy feature to allow users to group the issues/prs\r\nbased on different criteria such as milestone, status and etc.\r\n\r\nLet\u0027s integrate the grouping service in the components.","fileTypesAndContributionMap":{"css":{"insertions":2,"deletions":2},"html":{"insertions":79,"deletions":53},"ts":{"insertions":103,"deletions":58}}}]},{"date":"2024-03-29","commitResults":[{"hash":"cd4614f34a1d0707271d1782a97b3537ed32b1e5","isMergeCommit":false,"messageTitle":"Implement group by milestone (#316)","messageBody":"WATcher\u0027s default view displays issues and pull requests based solely on\r\ntheir assignees. Grouping issues and pull requests based on their\r\nassociated milestones may provide another useful view for the user.\r\n\r\nLet\u0027s implement the \"Group by Milestone\" feature.","fileTypesAndContributionMap":{"html":{"insertions":21,"deletions":0},"ts":{"insertions":61,"deletions":4}}},{"hash":"83dcdae8faa8c5ae4f8a4e73eb4ea419e88d251b","isMergeCommit":false,"messageTitle":"Include groupby params in url (#319)","messageBody":"With groupby parameters in the URL, users can easily share \r\nthe current grouping by using the URL.\r\n\r\nLet\u0027s implement initialization with URL parameters and \r\nthe ability to set groupby parameters.","fileTypesAndContributionMap":{"ts":{"insertions":93,"deletions":17}}},{"hash":"8ddcdcdb9759da81986d0d0bdb35b45b5ba39bdc","isMergeCommit":false,"messageTitle":"Reset GroupingContextService only if \"keep filter\" is selected. (#324)","messageBody":"GroupingContextService is being reset when the \"keep filter\" \r\noption is selected.\r\n\r\nLet\u0027s check if the \"keep filter\" option is selected before\r\nresetting the service.","fileTypesAndContributionMap":{"ts":{"insertions":3,"deletions":1}}},{"hash":"70bae914be0b1aae5a4ceb6a8fb1273c022797c7","isMergeCommit":false,"messageTitle":"Refactor MilestoneGroupingStrategy to match the changes in #315 (#323)","messageBody":"Special milestone groups are not added in the parseMilestoneData\r\nmethod.\r\n\r\nLet\u0027s add the special milestone groups to the result of the getGroups\r\nmethod.","fileTypesAndContributionMap":{"ts":{"insertions":4,"deletions":1}}},{"hash":"2eb2aba8980fb39dd9cfd9cd704873ed48aed0d4","isMergeCommit":false,"messageTitle":"Update repo on back and forward navigation (#322)","messageBody":"IssueViewer\u0027s repository is not updated when navigating back or forward\r\nin the URL history. This will lead to inconsistency between the URL\r\nparameters and the application state.\r\n\r\nLet\u0027s ensure that IssueViewer\u0027s repository is updated on back and forward\r\nnavigation.","fileTypesAndContributionMap":{"ts":{"insertions":18,"deletions":1}}}]},{"date":"2024-03-30","commitResults":[{"hash":"3f0aa1fac438fdc1ba505494a4b75ad1b364fa86","isMergeCommit":false,"messageTitle":"Enable npm run test in GitHub Action (#325)","messageBody":"Enabling automate testing in GitHub Actions with enhanced \r\ncode quality of the codebase.\r\n\r\nLet\u0027s enable automate testing.","fileTypesAndContributionMap":{"ts":{"insertions":8,"deletions":5}}}]},{"date":"2024-04-01","commitResults":[{"hash":"b603307a9e30e8bb74773c354fc41e1c36983df9","isMergeCommit":false,"messageTitle":"Show PRs without milestone in \"Currently Active\"","messageBody":"PRs without milestone requires urgent action from the user.\r\n\r\nLet\u0027s show it in the \"Currently Active\" preset view.","fileTypesAndContributionMap":{"ts":{"insertions":3,"deletions":3}}}]},{"date":"2024-04-03","commitResults":[{"hash":"775e59ce6371251c8ae2cb075f75ccb29ad8b6d2","isMergeCommit":false,"messageTitle":"Implement dropdown menu for repo change (#347)","messageBody":"Introduce a dropdown menu for repository selection,\r\nsimplifying the process of switching between repositories. \r\n\r\nThis enhancement offers users a quicker and more\r\nintuitive method to navigate to previously visited repositories.","fileTypesAndContributionMap":{"css":{"insertions":32,"deletions":0},"html":{"insertions":28,"deletions":2},"ts":{"insertions":15,"deletions":2}}}]},{"date":"2024-04-10","commitResults":[{"hash":"a5e695ab2f183b6d10f2c1bf1db20ef7403e4cc1","isMergeCommit":false,"messageTitle":"Consider open milestone without deadline as currently active (#359)","messageBody":"For open milestones, only those with deadlines were considered as currently\r\nactive. This led to setting a closed milestone with the latest deadline as\r\ncurrently active when there is an open milestone without deadline.\r\n\r\nLet\u0027s update the selection logic to also include open milestones\r\nwithout deadlines.","fileTypesAndContributionMap":{"ts":{"insertions":27,"deletions":12}}}]}],"dishenggg":[],"MadLamprey":[{"date":"2024-01-27","commitResults":[{"hash":"bb4a7f4063c0aa33b80188a83bfc610fe147950a","isMergeCommit":false,"messageTitle":"Prevent redirection when repo not set (#228)","messageBody":"Co-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e","fileTypesAndContributionMap":{"html":{"insertions":4,"deletions":1}}}]},{"date":"2024-02-29","commitResults":[{"hash":"db460275c3952308858654140b7ccdbe93b33a12","isMergeCommit":false,"messageTitle":"Upgrade to Angular 11 (#252)","messageBody":"Co-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e\r\nCo-authored-by: Chee Hong \u003cc.h.wong2606@gmail.com\u003e","fileTypesAndContributionMap":{"ts":{"insertions":17,"deletions":13}}}]},{"date":"2024-03-12","commitResults":[{"hash":"7e68bbdaeceb5bdfcc8c09e0f3f7cbd9bd3000f4","isMergeCommit":false,"messageTitle":"Remove sorting by assignees in Issue Sorter (#286)","messageBody":"Co-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e","fileTypesAndContributionMap":{"ts":{"insertions":9,"deletions":24}}}]},{"date":"2024-03-21","commitResults":[{"hash":"63ed6a2329d9343bdf18afc39b44653809e3370a","isMergeCommit":false,"messageTitle":"Add tool tip for hidden users (#307)","messageBody":"Currently, there is no tool tip for the Hidden Users mat-card.\r\nIt is not immediately obvious what the column is referring to.\r\n\r\nLet\u0027s add a tool tip to make it more explanatory.\r\n\r\nCo-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e","fileTypesAndContributionMap":{"html":{"insertions":1,"deletions":1}}}]},{"date":"2024-03-25","commitResults":[{"hash":"43ea689bd406857d7dae518ab089bf4d3029b564","isMergeCommit":false,"messageTitle":"Create tests for Error Handling service (#304)","messageBody":"Co-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e","fileTypesAndContributionMap":{"ts":{"insertions":101,"deletions":0}}},{"hash":"1fa6138cd5d66d33203fcab810011e9eaefab9c9","isMergeCommit":false,"messageTitle":"Create tests for Milestone service (#303)","messageBody":"Co-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e","fileTypesAndContributionMap":{"ts":{"insertions":55,"deletions":0}}}]},{"date":"2024-03-29","commitResults":[{"hash":"0867e1cbf2725df92870a321f91dd328af09e19c","isMergeCommit":false,"messageTitle":"Add sorting by Status (#318)","messageBody":"Co-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e\r\nCo-authored-by: Nguyen \u003c87511888+nknguyenhc@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"html":{"insertions":3,"deletions":0},"ts":{"insertions":23,"deletions":0}}},{"hash":"b1f3eed7d98e8fb6589e5bcde167f03d5942fe98","isMergeCommit":false,"messageTitle":"Split \u0027Without a milestone\u0027 option (#315)","messageBody":"Co-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e\r\nCo-authored-by: nknguyenhc \u003c87511888+nknguyenhc@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"html":{"insertions":2,"deletions":0},"ts":{"insertions":17,"deletions":14}}}]},{"date":"2024-04-03","commitResults":[{"hash":"d92079ba532ffc56283da245efe295f5edb4f203","isMergeCommit":false,"messageTitle":"Add icon for PRs without milestones (#337)","messageBody":"Co-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e","fileTypesAndContributionMap":{"html":{"insertions":8,"deletions":5},"ts":{"insertions":8,"deletions":1}}}]},{"date":"2024-04-11","commitResults":[{"hash":"d70f9b1881972d0491ee92774f04ae29f0a9233b","isMergeCommit":false,"messageTitle":"Make ItemsPerPage common for all card views (#362)","messageBody":"Co-authored-by: Misra Aditya \u003ce1096355@u.nus.edu\u003e","fileTypesAndContributionMap":{"css":{"insertions":2,"deletions":2},"html":{"insertions":14,"deletions":3},"ts":{"insertions":23,"deletions":7}}}]}],"Tim-Siu":[]},"authorFileTypeContributionMap":{"xenosf":{"js":0,"css":0,"html":0,"ts":0},"sopa301":{"js":0,"css":0,"html":0,"ts":0},"mingyuanc":{"js":0,"css":0,"html":0,"ts":0},"jingting1412":{"js":0,"css":0,"html":0,"ts":0},"KevinEyo1":{"js":0,"css":0,"html":0,"ts":0},"LamJiuFong":{"js":0,"css":0,"html":0,"ts":0},"yiwen101":{"js":0,"css":0,"html":0,"ts":0},"jonasongg":{"js":0,"css":0,"html":0,"ts":0},"domoberzin":{"js":0,"css":0,"html":0,"ts":0},"asdfghjkxd":{"js":0,"css":0,"html":0,"ts":0},"yuanxi1":{"js":0,"css":0,"html":0,"ts":0},"supermii2":{"js":0,"css":0,"html":0,"ts":0},"marquestye":{"js":0,"css":0,"html":0,"ts":0},"nknguyenhc":{"js":0,"css":121,"html":42,"ts":388},"Arif-Khalid":{"js":0,"css":24,"html":28,"ts":320},"NereusWB922":{"js":0,"css":162,"html":157,"ts":1450},"dishenggg":{"js":0,"css":0,"html":0,"ts":0},"MadLamprey":{"js":0,"css":2,"html":25,"ts":241},"Tim-Siu":{"js":0,"css":0,"html":0,"ts":0}},"authorContributionVariance":{"xenosf":0.0,"sopa301":0.0,"mingyuanc":0.0,"jingting1412":0.0,"KevinEyo1":0.0,"LamJiuFong":0.0,"yiwen101":0.0,"jonasongg":0.0,"domoberzin":0.0,"asdfghjkxd":0.0,"yuanxi1":0.0,"supermii2":0.0,"marquestye":0.0,"nknguyenhc":911.67975,"Arif-Khalid":1498.9617,"NereusWB922":7586.987,"dishenggg":0.0,"MadLamprey":227.02873,"Tim-Siu":0.0},"authorDisplayNameMap":{"xenosf":"XENO..NONG","sopa301":"POON..RYAN","mingyuanc":"CHIN..YUAN","jingting1412":"WANG..TING","KevinEyo1":"EYO ..EVIN","LamJiuFong":"LAM ..FONG","yiwen101":"WANG..IWEN","jonasongg":"JONA.. WEI","domoberzin":"DOMI.. GIN","asdfghjkxd":"GEOR.. YAO","yuanxi1":"ZHU ..ANXI","supermii2":"ALVI..S NG","marquestye":"TYE ..QUES","nknguyenhc":"NGUY..UYEN","Arif-Khalid":"ARIF..ALID","NereusWB922":"NERE.. BIN","dishenggg":"YEO ..HENG","MadLamprey":"MISR..ITYA","Tim-Siu":"XU S..UYAO"}} diff --git a/TEAMMATES_teammates_master/authorship.json b/TEAMMATES_teammates_master/authorship.json index 8c5df77..bc08052 100644 --- a/TEAMMATES_teammates_master/authorship.json +++ b/TEAMMATES_teammates_master/authorship.json @@ -1 +1 @@ -[{"path":"docs/_markbind/layouts/default.md","fileType":"md","lines":[{"lineNumber":1,"author":{"gitId":"jingting1412"},"content":"{% include \"_markbind/layouts/header.md\" %}"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"\u003cdiv id\u003d\"flex-body\"\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003cnav id\u003d\"site-nav\" class\u003d\"fixed-header-padding\"\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"nav-component slim-scroll\"\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003csite-nav\u003e"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"* About TEAMMATES :expanded:"},{"lineNumber":9,"author":{"gitId":"-"},"content":" * [Introduction]({{ baseUrl }}/index.html)"},{"lineNumber":10,"author":{"gitId":"-"},"content":" * [Overview]({{ baseUrl }}/overview.html)"},{"lineNumber":11,"author":{"gitId":"-"},"content":"* Getting Started :expanded:"},{"lineNumber":12,"author":{"gitId":"-"},"content":" * [Setting Up]({{ baseUrl }}/setting-up.html)"},{"lineNumber":13,"author":{"gitId":"-"},"content":"* [Contributing]({{ baseUrl }}/contributing-doc.html)"},{"lineNumber":14,"author":{"gitId":"-"},"content":"* Workflow :expanded:"},{"lineNumber":15,"author":{"gitId":"-"},"content":" * [Issues]({{ baseUrl }}/issues.html)"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * [Process]({{ baseUrl }}/process.html)"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * [Development]({{ baseUrl }}/development.html)"},{"lineNumber":18,"author":{"gitId":"-"},"content":"* [Design]({{ baseUrl }}/design.html)"},{"lineNumber":19,"author":{"gitId":"-"},"content":"* Best Practices :expanded:"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * [Coding]({{ baseUrl }}/best-practices/coding.html)"},{"lineNumber":21,"author":{"gitId":"-"},"content":" * [Testing]({{ baseUrl }}/best-practices/testing.html)"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * [Data Migration]({{ baseUrl }}/best-practices/data-migration.html)"},{"lineNumber":23,"author":{"gitId":"-"},"content":" * [UI Design]({{ baseUrl }}/best-practices/ui-design.html)"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * [Accessibility]({{ baseUrl }}/best-practices/accessibility.html)"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * [Mobile-Friendliness]({{ baseUrl }}/best-practices/mobile-friendliness.html)"},{"lineNumber":26,"author":{"gitId":"-"},"content":"* How-to :expanded:"},{"lineNumber":27,"author":{"gitId":"-"},"content":" * [Captcha]({{ baseUrl }}/captcha.html)"},{"lineNumber":28,"author":{"gitId":"-"},"content":" * [Documentation]({{ baseUrl }}/documentation.html)"},{"lineNumber":29,"author":{"gitId":"-"},"content":" * [Emails]({{ baseUrl }}/emails.html)"},{"lineNumber":30,"author":{"gitId":"-"},"content":" * [Unit Testing]({{ baseUrl }}/unit-testing.html)"},{"lineNumber":31,"author":{"gitId":"-"},"content":" * [End-to-End Testing]({{ baseUrl }}/e2e-testing.html)"},{"lineNumber":32,"author":{"gitId":"-"},"content":" * [Performance Testing]({{ baseUrl }}/performance-testing.html)"},{"lineNumber":33,"author":{"gitId":"-"},"content":" * [Accessibility Testing]({{ baseUrl }}/axe-testing.html)"},{"lineNumber":34,"author":{"gitId":"-"},"content":" * [Search]({{ baseUrl }}/search.html)"},{"lineNumber":35,"author":{"gitId":"-"},"content":" * [Snapshot Testing]({{ baseUrl }}/snapshot-testing.html)"},{"lineNumber":36,"author":{"gitId":"-"},"content":" * [Static Analysis]({{ baseUrl }}/static-analysis.html)"},{"lineNumber":37,"author":{"gitId":"-"},"content":"* [Troubleshooting Guide]({{ baseUrl }}/troubleshooting-guide.html)"},{"lineNumber":38,"author":{"gitId":"-"},"content":"* [Glossary]({{ baseUrl }}/glossary.html)"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003c/site-nav\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003c/nav\u003e"},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"content-wrapper\" class\u003d\"fixed-header-padding\"\u003e"},{"lineNumber":43,"author":{"gitId":"jingting1412"},"content":" \u003cbreadcrumb/\u003e"},{"lineNumber":44,"author":{"gitId":"-"},"content":" {{ content }}"},{"lineNumber":45,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":46,"author":{"gitId":"-"},"content":" \u003cnav id\u003d\"page-nav\" class\u003d\"fixed-header-padding\"\u003e"},{"lineNumber":47,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"nav-component slim-scroll\"\u003e"},{"lineNumber":48,"author":{"gitId":"-"},"content":" \u003cpage-nav /\u003e"},{"lineNumber":49,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":50,"author":{"gitId":"-"},"content":" \u003c/nav\u003e"},{"lineNumber":51,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"jingting1412"},"content":"{% include \"_markbind/layouts/footer.md\" %}"}],"authorContributionMap":{"jingting1412":3,"-":50}},{"path":"docs/_markbind/layouts/footer.md","fileType":"md","lines":[{"lineNumber":1,"author":{"gitId":"jingting1412"},"content":"\u003cfooter\u003e"},{"lineNumber":2,"author":{"gitId":"jingting1412"},"content":"\u003c!-- Support MarkBind by including a link to us on your landing page! --\u003e"},{"lineNumber":3,"author":{"gitId":"jingting1412"},"content":"\u003cdiv class\u003d\"text-center\"\u003e"},{"lineNumber":4,"author":{"gitId":"jingting1412"},"content":" \u003csmall\u003e[Generated by {{MarkBind}} on {{timestamp}}]\u003c/small\u003e"},{"lineNumber":5,"author":{"gitId":"jingting1412"},"content":"\u003c/div\u003e"},{"lineNumber":6,"author":{"gitId":"jingting1412"},"content":"\u003c/footer\u003e"}],"authorContributionMap":{"jingting1412":6}},{"path":"docs/_markbind/layouts/header.md","fileType":"md","lines":[{"lineNumber":1,"author":{"gitId":"jingting1412"},"content":"\u003chead-bottom\u003e"},{"lineNumber":2,"author":{"gitId":"jingting1412"},"content":" \u003clink rel\u003d\"stylesheet\" href\u003d\"{{ baseUrl }}/stylesheets/main.css\"\u003e"},{"lineNumber":3,"author":{"gitId":"jingting1412"},"content":"\u003c/head-bottom\u003e"},{"lineNumber":4,"author":{"gitId":"jingting1412"},"content":""},{"lineNumber":5,"author":{"gitId":"jingting1412"},"content":"\u003cheader sticky\u003e"},{"lineNumber":6,"author":{"gitId":"jingting1412"},"content":" \u003cnavbar type\u003d\"inverse\"\u003e"},{"lineNumber":7,"author":{"gitId":"jingting1412"},"content":" \u003ca slot\u003d\"brand\" href\u003d\"{{ baseUrl }}/index.html\" title\u003d\"Home\" class\u003d\"navbar-brand\"\u003e"},{"lineNumber":8,"author":{"gitId":"jingting1412"},"content":" \u003cpic src\u003d\"{{ baseUrl }}/images/teammateslogo.png\" width\u003d\"150\" alt\u003d\"Logo\" caption\u003d\"\"/\u003e"},{"lineNumber":9,"author":{"gitId":"jingting1412"},"content":" \u003cspan style\u003d\"font-style:italic;font-size:small\"\u003e[dev docs]\u003c/span\u003e"},{"lineNumber":10,"author":{"gitId":"jingting1412"},"content":" \u003c/a\u003e"},{"lineNumber":11,"author":{"gitId":"jingting1412"},"content":" \u003cli\u003e\u003ca href\u003d\"{{ baseUrl }}/index.html\" class\u003d\"nav-link\"\u003eHome\u003c/a\u003e\u003c/li\u003e"},{"lineNumber":12,"author":{"gitId":"jingting1412"},"content":" \u003cli\u003e\u003ca href\u003d\"{{ baseUrl }}/contributing-doc.html\" class\u003d\"nav-link\"\u003eContributing\u003c/a\u003e\u003c/li\u003e"},{"lineNumber":13,"author":{"gitId":"jingting1412"},"content":" \u003cli\u003e\u003ca href\u003d\"https://teammatesv4.appspot.com/\" target\u003d\"_blank\" class\u003d\"nav-link\"\u003eProduct Website \u003cmd\u003e:glyphicon-share-alt:\u003c/md\u003e\u003c/a\u003e\u003c/li\u003e"},{"lineNumber":14,"author":{"gitId":"jingting1412"},"content":" \u003cli\u003e\u003ca href\u003d\"https://github.com/TEAMMATES/teammates\" target\u003d\"_blank\" class\u003d\"nav-link\"\u003e\u003cmd\u003e:fab-github:\u003c/md\u003e\u003c/a\u003e\u003c/li\u003e"},{"lineNumber":15,"author":{"gitId":"jingting1412"},"content":" \u003cli slot\u003d\"right\"\u003e"},{"lineNumber":16,"author":{"gitId":"jingting1412"},"content":" \u003cform class\u003d\"navbar-form\"\u003e"},{"lineNumber":17,"author":{"gitId":"jingting1412"},"content":" \u003csearchbar :data\u003d\"searchData\" placeholder\u003d\"Search\" :on-hit\u003d\"searchCallback\" menu-align-right\u003e\u003c/searchbar\u003e"},{"lineNumber":18,"author":{"gitId":"jingting1412"},"content":" \u003c/form\u003e"},{"lineNumber":19,"author":{"gitId":"jingting1412"},"content":" \u003c/li\u003e"},{"lineNumber":20,"author":{"gitId":"jingting1412"},"content":" \u003c/navbar\u003e"},{"lineNumber":21,"author":{"gitId":"jingting1412"},"content":"\u003c/header\u003e"}],"authorContributionMap":{"jingting1412":21}},{"path":"docs/design.md","fileType":"md","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cfrontmatter\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" title: \"Design\""},{"lineNumber":3,"author":{"gitId":"-"},"content":"\u003c/frontmatter\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"# Design"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"## Architecture"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/highlevelArchitecture.puml\"/\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"TEAMMATES is a Web application that runs on Google App Engine (GAE). Given above is an overview of the main components."},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"- **UI (Browser)**: The UI seen by users consists of Web pages containing HTML, CSS (for styling) and JavaScript (for client-side interactions such as sorting, input validation, etc.). This UI is a single HTML page generated by Angular framework. The initial page request is sent to the server over HTTP, and requests for data are sent asynchronously with AJAX."},{"lineNumber":14,"author":{"gitId":"-"},"content":"- **UI (Server)**: The entry point for the application back end logic is designed as a REST-ful controller."},{"lineNumber":15,"author":{"gitId":"-"},"content":"- **Logic**: The main logic of the application is in POJOs (Plain Old Java Objects)."},{"lineNumber":16,"author":{"gitId":"-"},"content":"- **Storage**: The storage layer of the application uses the persistence framework provided by **Google Cloud Datastore**, a NoSQL database."},{"lineNumber":17,"author":{"gitId":"-"},"content":"- **Test Driver**: TEAMMATES makes heavy use of automated regression testing. Test data is transmitted using JSON format."},{"lineNumber":18,"author":{"gitId":"-"},"content":" - `TestNG` is used for Java testing (all levels) and `Jest` for JavaScript unit-testing."},{"lineNumber":19,"author":{"gitId":"-"},"content":"- **E2E**: The E2E (end-to-end) component is used to interact with the application as a whole with Web browsers. Its primary function is for E2E tests."},{"lineNumber":20,"author":{"gitId":"-"},"content":" - `Selenium (Java)` is used to automate E2E testing with actual Web browsers."},{"lineNumber":21,"author":{"gitId":"-"},"content":"- **Client**: The Client component can connect to the back end directly without using a Web browser. It is used for administrative purposes, e.g. migrating data to a new schema."},{"lineNumber":22,"author":{"gitId":"-"},"content":"- **Common**: The Common component contains utility code (data transfer objects, helper classes, etc.) used across the application."},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":"The diagram below shows how the code in each component is organized into packages and the dependencies between them."},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/packageDiagram.puml\"/\u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":"Notes:"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":"- `[logic] - [ui::website] - [ui::webapi]` represent an application of `Model-View-Controller` pattern."},{"lineNumber":31,"author":{"gitId":"-"},"content":" - `ui::website` is not a real package; it is a conceptual package representing the front-end of the application."},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":"## UI Component"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":"The diagram below shows the object structure of the UI component."},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/UiComponent.puml\"/\u003e"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":"Notes:"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":"- `ui::website` is not a Java package. It is written in Angular framework and consists of HTML, SCSS, and TypeScript files. The framework will build those files into HTML, CSS and JavaScript files ready to be used by standard Web browsers."},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":"The UI component is the first stop for 99% of all requests that are received by the application."},{"lineNumber":44,"author":{"gitId":"-"},"content":"Such a request will go through the following steps:"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":"1. Request received by the GAE server."},{"lineNumber":47,"author":{"gitId":"-"},"content":"1. Custom filters are applied according to the order specified in `web.xml`, e.g. `OriginCheckFilter`."},{"lineNumber":48,"author":{"gitId":"-"},"content":"1. Request forwarded to a `*Servlet` object as specified in `web.xml` for further processing, depending on the type of request."},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":"There are two general types of requests: user-invoked requests and automated (GAE server-invoked) requests, which are processed differently."},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":"### User-invoked requests"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":"User-invoked requests are all requests made by the users of the application, typically from the Web browser (i.e. by navigating to a particular URL of the application)."},{"lineNumber":55,"author":{"gitId":"-"},"content":"The request will be processed as follows:"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/UiWorkflow.puml\"/\u003e"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":"The initial request for the web page will be processed as follows:"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":"1. Request forwarded to `WebPageServlet`."},{"lineNumber":62,"author":{"gitId":"-"},"content":"1. `WebPageServlet` returns the built single web page (`index.html`)."},{"lineNumber":63,"author":{"gitId":"-"},"content":"1. The browser will render the page and execute the page scripts, most of the time requiring AJAX requests to the server."},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":"Subsequent AJAX requests sent to the server will be processed as follows:"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":"1. Request forwarded to the `WebApiServlet`."},{"lineNumber":68,"author":{"gitId":"-"},"content":"1. `WebApiServlet` uses the `ActionFactory` to generate the matching `Action` object, e.g. `GetFeedbackSessionsAction`."},{"lineNumber":69,"author":{"gitId":"-"},"content":"1. `WebApiServlet` executes the action."},{"lineNumber":70,"author":{"gitId":"-"},"content":" 1. The `Action` object checks the access rights of the user. If the action is allowed, it will be performed, interacting with the `Logic` component as necessary."},{"lineNumber":71,"author":{"gitId":"-"},"content":" 1. The `Action` packages and processes the result into an `ActionResult` object. The most common format is `JsonResult` (requests for obtaining data or processing existing data) and other formats can be defined as necessary."},{"lineNumber":72,"author":{"gitId":"-"},"content":"1. `WebApiServlet` sends the result back to the browser which will then process it on the front-end."},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":"Requests for static asset files (e.g. CSS, JS files, images) are served directly without going through `web.xml` configuration at all."},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":"The Web API is protected by two layers of access control check:"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":"- Origin check: This mitigates [CSRF attack](https://owasp.org/www-community/attacks/csrf)."},{"lineNumber":79,"author":{"gitId":"-"},"content":"- Authentication and authorization check: This checks if the logged in user (or lack thereof) has sufficient privileges to trigger the API\u0027s actions."},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":"Special keys (`csrf key` and `backdoor key`) can be used to bypass each of the checks, typically for testing purpose. Those keys are strings known only to the person who deployed the application (typically, the administrator)."},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":"### Automated requests"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":"Automated requests are all requests sent automatically by the GAE server during specific periods of time."},{"lineNumber":86,"author":{"gitId":"-"},"content":"This type of request will be processed as follows:"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":"1. The source of the request will be checked for administrator privilege. If this privilege is absent (e.g. non-administrator users trying to invoke the automated actions), the request will be dropped and a `403 Forbidden` status will be returned."},{"lineNumber":89,"author":{"gitId":"-"},"content":" - Requests generated by the GAE server are equipped with this privilege."},{"lineNumber":90,"author":{"gitId":"-"},"content":" - Administrators can manually invoke these requests; this is particularly useful in testing the actions associated with those requests."},{"lineNumber":91,"author":{"gitId":"-"},"content":"1. Request forwarded to the `WebApiServlet` and subsequent actions are the same as user-invoked AJAX requests."},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":"GAE server sends such automated requests through two different configurations:"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":"- Cron jobs: These are jobs that are automatically scheduled for a specified period of time, e.g. scheduling feedback session opening reminders. It is configured in `cron.yaml`."},{"lineNumber":96,"author":{"gitId":"-"},"content":"- Task queue workers: These are hybrids of user-invoked and GAE-invoked in that they are queued by users (i.e. users request for the tasks to be added to queue), but executed by GAE (i.e. GAE determines when and which tasks in the queue are executed at any point of time). This is typically used for tasks that may take a long time to finish and might be blocking user\u0027s interaction. It is configured in `queue.yaml` as well as the `TaskQueue` nested class of the [Const](https://github.com/TEAMMATES/teammates/blob/master/src/main/java/teammates/common/util/Const.java) class."},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":"### Template Method pattern"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":"- Since the high-level workflow of processing a request is same for any request (differing by the two request types only), we use the [Template Method pattern](http://en.wikipedia.org/wiki/Template_method_pattern) to abstract the process flow into the `Action` classes."},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":"### Policies"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":"On designing API endpoints (for AJAX requests):"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":"- Design endpoints for resources. For example, `FeedbackSession` is a resource. The corresponding endpoint is `/session`. We use `GET`, `POST`, `PUT`, `DELETE` HTTP methods to get, create, update and delete the resource respectively."},{"lineNumber":107,"author":{"gitId":"-"},"content":"- Prefer multiple REST calls over single RPC (Remote Procedure Call) calls."},{"lineNumber":108,"author":{"gitId":"-"},"content":" - Reason 1: REST paradigm promotes reuse of many business logic and is not dependent of the structure of the requesting web page (or any other type of requesting agent)."},{"lineNumber":109,"author":{"gitId":"-"},"content":" - Reason 2: Multiple REST calls can be parallelized which will improve performance."},{"lineNumber":110,"author":{"gitId":"-"},"content":"- Separate access control logic and execution logic completely."},{"lineNumber":111,"author":{"gitId":"-"},"content":" - In the case that an endpoint serves multiple purposes, we use `Intent` to distinguish the intent for the request. For example, instructors can access `/session` with intent `INSTRUCTOR_SUBMISSION` or `FULL_DETAIL`. Some `Intent` will naturally require stricter access rights."},{"lineNumber":112,"author":{"gitId":"-"},"content":"- Prefer HTTP request body over URL parameters (key-value) to contain data for `POST` and `PUT` requests."},{"lineNumber":113,"author":{"gitId":"-"},"content":" - Reason 1: The URL parameters are used to identify a specific resource for an endpoint, not what should be done to them."},{"lineNumber":114,"author":{"gitId":"-"},"content":" - Reason 2: Request body is not limited to key-value format which allows proper design and validation."},{"lineNumber":115,"author":{"gitId":"-"},"content":" - Data Transfer Objects (DTOs) which represent different API requests and responses are defined in `request` and `output` package respectively."},{"lineNumber":116,"author":{"gitId":"-"},"content":"- Preprocess data sent/received by the server to hide complexities. For example, timestamp is passed as UNIX epoch milliseconds in the output while it is represented as `Instant` in the back-end."},{"lineNumber":117,"author":{"gitId":"-"},"content":" - Some constructors in the `output` package contain logic to hide \"hacks\" in the backend."},{"lineNumber":118,"author":{"gitId":"-"},"content":" - Some getters/setters in the `request` package contain logic to cater the conventions in the backend."},{"lineNumber":119,"author":{"gitId":"-"},"content":" - Some fields are required be hidden in the API response, mostly for data privacy purposes. Whenever required, there should be methods in the request output objects catered for this."},{"lineNumber":120,"author":{"gitId":"-"},"content":"- API endpoints should not be concerned with how data is presented."},{"lineNumber":121,"author":{"gitId":"-"},"content":" - Case study 1: some endpoint will pass timezone information via two information: timezone ID and UNIX epoch milliseconds. It is up to the front-end on how to make use of those two pieces of information."},{"lineNumber":122,"author":{"gitId":"-"},"content":" - Case study 2: CSV file for session result or student list is just a different way of presenting the same information in the web page. Due to this, when downloading CSV, the web page will request the same information as that used when displaying in web page and do the necessary conversion to CSV."},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":"On data exchange between front-end and back-end:"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":"- Back-end is the single source of truth for all data format and the code used by front-end is generated from this."},{"lineNumber":127,"author":{"gitId":"-"},"content":" - Some important constants (including API endpoints information) are synced to `api-const.ts`."},{"lineNumber":128,"author":{"gitId":"-"},"content":" - The schemas of the DTOs defined in `output` and `request` packages are synced to `api-output.ts` and `api-request.ts` in the frontend."},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":"On handling exceptions:"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":"- The UI component is responsible for catching all exceptions and transforming them to properly formed, user-friendly output format. It includes the status message shown to user as well as the HTTP status code."},{"lineNumber":133,"author":{"gitId":"-"},"content":" - As a consequence, the UI component cannot throw any exception, because there is no layer which will catch those exceptions if it does."},{"lineNumber":134,"author":{"gitId":"-"},"content":"- In order to streamline the process, custom runtime exception classes which correspond to different HTTP status codes are used. For example, there is `EntityNotFoundException` which corresponds to HTTP 404, `UnauthorizedAccessException` which corresponds to HTTP 403, etc."},{"lineNumber":135,"author":{"gitId":"-"},"content":" - It is highly preferred to throw these custom exceptions instead of setting the HTTP status manually in the action class, as the API layer has been configured to automatically log the exception and assign the correct status code to the HTTP response."},{"lineNumber":136,"author":{"gitId":"-"},"content":"- All `4XX` responses must be accompanied with logging at `warning` level or above. `5XX` responses must be accompanied with `severe` level logging."},{"lineNumber":137,"author":{"gitId":"-"},"content":" - `502` (Bad Gateway) responses may skip the `severe` level logging if the upstream components (where the error happened) already did the `severe` level logging."},{"lineNumber":138,"author":{"gitId":"-"},"content":"- We use the HTTP status codes as close to their standard definition in [RFC7231](https://tools.ietf.org/html/rfc7231) as possible."},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":"## Logic Component"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":"The `Logic` component handles the business logic of TEAMMATES. In particular, it is responsible for:"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":"- Managing relationships between entities, e.g. cascade logic for create/update/delete."},{"lineNumber":145,"author":{"gitId":"-"},"content":"- Managing transactions, e.g. ensuring atomicity of a transaction."},{"lineNumber":146,"author":{"gitId":"-"},"content":"- Sanitizing input values received from the UI component."},{"lineNumber":147,"author":{"gitId":"-"},"content":"- Connecting to GCP or third-party services, e.g. for adding tasks to the task queue and for sending emails with third-party providers."},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/LogicComponent.puml\"/\u003e"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":"Package overview:"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":"- **`logic.api`**: Provides the API of the component to be accessed by the UI."},{"lineNumber":154,"author":{"gitId":"-"},"content":"- **`logic.core`**: Contains the core logic of the system."},{"lineNumber":155,"author":{"gitId":"-"},"content":"- **`logic.external`**: Holds the logic of external services such as task queue service."},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"-"},"content":"### Logic API"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":"Represented by these classes:"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":"- `Logic`: A [Facade class](http://en.wikipedia.org/wiki/Facade_pattern) which connects to the several `*Logic` classes to handle the logic related to various types of data and to access data from the `Storage` component."},{"lineNumber":162,"author":{"gitId":"-"},"content":"- `UserProvision`: Retrieves user information (based on request cookies)."},{"lineNumber":163,"author":{"gitId":"-"},"content":"- `EmailGenerator`: Generates emails to be sent."},{"lineNumber":164,"author":{"gitId":"-"},"content":"- `EmailSender`: Sends email with the provider chosen based on the build configuration."},{"lineNumber":165,"author":{"gitId":"-"},"content":"- `TaskQueuer`: Adds tasks to the task queue, i.e. to be executed at a later time."},{"lineNumber":166,"author":{"gitId":"-"},"content":"- `LogsProcessor`: For more advanced usage of logging that cannot be captured by the standard logger class."},{"lineNumber":167,"author":{"gitId":"-"},"content":"- `RecaptchaVerifier`: For verification of the reCAPTCHA token."},{"lineNumber":168,"author":{"gitId":"-"},"content":""},{"lineNumber":169,"author":{"gitId":"-"},"content":"Many classes in this layer make use of proxy pattern, i.e. they only connect to production services such as Google Cloud Tasks in the staging/production server."},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":"### Policies"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":"Access control:"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":"+ Although this component provides methods that are relevant to access control (e.g. providing user information), the access control check itself does not happen in this component. The UI is expected to check access control (using `GateKeeper` class) before calling a method in the logic component."},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":"API for creating entities:"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":"+ Null parameters: Causes an assertion failure."},{"lineNumber":180,"author":{"gitId":"-"},"content":"+ Invalid parameters: Throws `InvalidParametersException`."},{"lineNumber":181,"author":{"gitId":"-"},"content":"+ Entity already exists: Throws `EntityAlreadyExistsException` (escalated from Storage level)."},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":"API for retrieving entities:"},{"lineNumber":184,"author":{"gitId":"-"},"content":""},{"lineNumber":185,"author":{"gitId":"-"},"content":"+ Attempting to retrieve objects using `null` parameters: Causes an assertion failure."},{"lineNumber":186,"author":{"gitId":"-"},"content":"+ Entity not found:"},{"lineNumber":187,"author":{"gitId":"-"},"content":" - Returns `null` if the target entity not found. This way, read operations can be used easily for checking the existence of an entity."},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":"API for updating entities:"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":"+ Update is done using `*UpdateOptions` inside every `*Attributes`. The `UpdateOptions` will specify what is used to identify the entity to update and what will be updated."},{"lineNumber":192,"author":{"gitId":"-"},"content":"+ Entity not found: Throws `EntityDoesNotExistException`."},{"lineNumber":193,"author":{"gitId":"-"},"content":"+ Invalid parameters: Throws `InvalidParametersException`."},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"-"},"content":"API for deleting entities:"},{"lineNumber":196,"author":{"gitId":"-"},"content":""},{"lineNumber":197,"author":{"gitId":"-"},"content":"+ FailDeleteSilentlyPolicy: In general, delete operation do not throw exceptions if the target entity does not exist. This is because if it does not exist, it is as good as deleted."},{"lineNumber":198,"author":{"gitId":"-"},"content":"+ Cascade policy: When a parent entity is deleted, entities that have referential integrity with the deleted entity should also be deleted."},{"lineNumber":199,"author":{"gitId":"-"},"content":" Refer to the API for the cascade logic."},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":"## Storage Component"},{"lineNumber":202,"author":{"gitId":"-"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":"The `Storage` component performs CRUD (Create, Read, Update, Delete) operations on data entities individually."},{"lineNumber":204,"author":{"gitId":"-"},"content":"It contains minimal logic beyond what is directly relevant to CRUD operations."},{"lineNumber":205,"author":{"gitId":"-"},"content":"In particular, it is reponsible for:"},{"lineNumber":206,"author":{"gitId":"-"},"content":""},{"lineNumber":207,"author":{"gitId":"-"},"content":"- Validating data inside entities before creating/updating them, to ensure they are in a valid state."},{"lineNumber":208,"author":{"gitId":"-"},"content":"- Hiding the complexities of the database from the `Logic` component."},{"lineNumber":209,"author":{"gitId":"-"},"content":"- Hiding the persistable objects: Classes in the `storage::entity` package are not visible outside this component to hide information specific to data persistence."},{"lineNumber":210,"author":{"gitId":"-"},"content":" - Instead, a corresponding non-persistent [data transfer object](http://en.wikipedia.org/wiki/Data_transfer_object) named `*Attributes` (e.g., `CourseAttributes` is the data transfer object for `Course` entities) object is returned. These datatransfer classes are in `common::datatransfer` package, to be explained later."},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":"The `Storage` component does not perform any cascade delete/create operations. Cascade logic is handled by the `Logic` component."},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/StorageComponent.puml\"/\u003e"},{"lineNumber":215,"author":{"gitId":"-"},"content":""},{"lineNumber":216,"author":{"gitId":"-"},"content":"Package overview:"},{"lineNumber":217,"author":{"gitId":"-"},"content":""},{"lineNumber":218,"author":{"gitId":"-"},"content":"+ **`storage.api`**: Provides the API of the component to be accessed by the logic component."},{"lineNumber":219,"author":{"gitId":"-"},"content":"+ **`storage.entity`**: Classes that represent persistable entities."},{"lineNumber":220,"author":{"gitId":"-"},"content":"+ **`storage.search`**: Classes for dealing with searching and indexing."},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/StorageClassDiagram.puml\"/\u003e"},{"lineNumber":223,"author":{"gitId":"-"},"content":""},{"lineNumber":224,"author":{"gitId":"-"},"content":"Note that the navigability of the association links between entity objects appear to be in the reverse direction of what we see in a normal OOP design."},{"lineNumber":225,"author":{"gitId":"-"},"content":"This is because we want to keep the data schema flexible so that new entity types can be added later with minimal modifications to existing elements."},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"-"},"content":"### Storage API"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":"Represented by the `*Db` classes. These classes act as the bridge to the database."},{"lineNumber":230,"author":{"gitId":"-"},"content":""},{"lineNumber":231,"author":{"gitId":"-"},"content":"### Policies"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":"Add and Delete operations try to wait until data is persisted in the database before returning. This is not enough to compensate for eventual consistency involving multiple servers in the Google Cloud Datastore environment. However, it is expected to avoid test failures caused by eventual consistency in dev server and reduce such problems in the live server."},{"lineNumber":234,"author":{"gitId":"-"},"content":"Note: \u0027Eventual consistency\u0027 here means it takes some time for a database operation to propagate across all replicas of the Google Cloud Datastore. As a result, the data may be in an inconsistent states for short periods of time although things should become consistent \u0027eventually\u0027. For example, an object we deleted may appear to still exist for a short while."},{"lineNumber":235,"author":{"gitId":"-"},"content":""},{"lineNumber":236,"author":{"gitId":"-"},"content":"Implementation of Transaction Control has been minimized due to limitations of Google Cloud Datastore environment and the nature of our data schema."},{"lineNumber":237,"author":{"gitId":"-"},"content":""},{"lineNumber":238,"author":{"gitId":"-"},"content":"API for creating:"},{"lineNumber":239,"author":{"gitId":"-"},"content":""},{"lineNumber":240,"author":{"gitId":"-"},"content":"+ Attempt to create an entity that already exists: Throws `EntityAlreadyExistsException`."},{"lineNumber":241,"author":{"gitId":"-"},"content":"+ Attempt to create an entity with invalid data: Throws `InvalidParametersException`."},{"lineNumber":242,"author":{"gitId":"-"},"content":""},{"lineNumber":243,"author":{"gitId":"-"},"content":"API for retrieving:"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":"+ Attempt to retrieve an entity that does not exist: Returns `null`."},{"lineNumber":246,"author":{"gitId":"-"},"content":""},{"lineNumber":247,"author":{"gitId":"-"},"content":"API for updating:"},{"lineNumber":248,"author":{"gitId":"-"},"content":""},{"lineNumber":249,"author":{"gitId":"-"},"content":"+ Attempt to update an entity that does not exist: Throws `EntityDoesNotExistException`."},{"lineNumber":250,"author":{"gitId":"-"},"content":"+ Attempt to update an entity with invalid data: Throws `InvalidParametersException`."},{"lineNumber":251,"author":{"gitId":"-"},"content":""},{"lineNumber":252,"author":{"gitId":"-"},"content":"API for deleting:"},{"lineNumber":253,"author":{"gitId":"-"},"content":""},{"lineNumber":254,"author":{"gitId":"-"},"content":"+ Attempt to delete an entity that does not exist: Fails silently."},{"lineNumber":255,"author":{"gitId":"-"},"content":""},{"lineNumber":256,"author":{"gitId":"-"},"content":"## Common Component"},{"lineNumber":257,"author":{"gitId":"-"},"content":""},{"lineNumber":258,"author":{"gitId":"-"},"content":"The Common component contains common utilities used across TEAMMATES."},{"lineNumber":259,"author":{"gitId":"-"},"content":""},{"lineNumber":260,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/CommonComponent.puml\"/\u003e"},{"lineNumber":261,"author":{"gitId":"-"},"content":""},{"lineNumber":262,"author":{"gitId":"-"},"content":"Package overview:"},{"lineNumber":263,"author":{"gitId":"-"},"content":""},{"lineNumber":264,"author":{"gitId":"-"},"content":"- **`common.util`**: Contains utility classes."},{"lineNumber":265,"author":{"gitId":"-"},"content":"- **`common.exceptions`**: Contains custom exceptions."},{"lineNumber":266,"author":{"gitId":"-"},"content":"- **`common.datatransfer`**: Contains data transfer objects."},{"lineNumber":267,"author":{"gitId":"-"},"content":""},{"lineNumber":268,"author":{"gitId":"-"},"content":"`common.datatransfer` package contains lightweight \"data transfer object\" classes for transferring data among components. They can be combined in various ways to transfer structured data between components. Given below are three examples."},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/DataTransferClasses.puml\"/\u003e"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":"1. `Test Driver` can use the `DataBundle` in this manner to send an arbitrary number of objects to be persisted in the database."},{"lineNumber":273,"author":{"gitId":"-"},"content":"1. This structure can be used to transfer search results of a student or instructor or response comments."},{"lineNumber":274,"author":{"gitId":"-"},"content":"1. This structure can be used to send results of a feedback session (e.g., when showing a feedback session report to an instructor)."},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":"Some of these classes are methodless (and thus more of a data structure rather than a class); these classes use public variables for data for easy access."},{"lineNumber":277,"author":{"gitId":"-"},"content":""},{"lineNumber":278,"author":{"gitId":"-"},"content":"## Test Driver Component"},{"lineNumber":279,"author":{"gitId":"-"},"content":""},{"lineNumber":280,"author":{"gitId":"-"},"content":"This component automates the testing of TEAMMATES."},{"lineNumber":281,"author":{"gitId":"-"},"content":""},{"lineNumber":282,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/TestDriverComponent.puml\"/\u003e"},{"lineNumber":283,"author":{"gitId":"-"},"content":""},{"lineNumber":284,"author":{"gitId":"-"},"content":"The test driver component\u0027s package structure follows the corresponding production package structure\u0027s exactly,"},{"lineNumber":285,"author":{"gitId":"-"},"content":"e.g. `teammates.logic.core.*` will contain the test cases for the production code inside `teammates.logic.core` package."},{"lineNumber":286,"author":{"gitId":"-"},"content":"In the same spirit, for the front end, each `*.component.ts` will have the corresponding `*.component.spec.ts` in the same folder (similarly for `*.service.ts`, `*.pipe.ts`, etc.)."},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":"The test driver component introduces the following additional packages:"},{"lineNumber":289,"author":{"gitId":"-"},"content":""},{"lineNumber":290,"author":{"gitId":"-"},"content":"- **`architecture`**: Contains test cases used by one of the lint tools to check for architectural integrity."},{"lineNumber":291,"author":{"gitId":"-"},"content":"- **`test`**: Contains infrastructure and helpers needed for running the tests. Also contains the test cases for the said infrastructure/helpers."},{"lineNumber":292,"author":{"gitId":"-"},"content":""},{"lineNumber":293,"author":{"gitId":"-"},"content":"Notes:"},{"lineNumber":294,"author":{"gitId":"-"},"content":""},{"lineNumber":295,"author":{"gitId":"-"},"content":"- Component tests: Some of these are pure unit tests (i.e. testing one component in isolation) while others are integration tests that test units as well as integration of units with each other."},{"lineNumber":296,"author":{"gitId":"-"},"content":"- Front-end files (particularly TypeScript) are tested separately with `Jest`. The test cases are found in `*.spec.ts` files."},{"lineNumber":297,"author":{"gitId":"-"},"content":""},{"lineNumber":298,"author":{"gitId":"-"},"content":"This is how TEAMMATES testing maps to standard types of testing."},{"lineNumber":299,"author":{"gitId":"-"},"content":""},{"lineNumber":300,"author":{"gitId":"-"},"content":"```"},{"lineNumber":301,"author":{"gitId":"-"},"content":"Normal"},{"lineNumber":302,"author":{"gitId":"-"},"content":"|-----acceptance tests-----|-------------------system tests-------------------|-----integration tests-----|-----unit tests-----|"},{"lineNumber":303,"author":{"gitId":"-"},"content":"|--------manual testing--------|------automated E2E tests------|-------------------automated component tests-------------------|"},{"lineNumber":304,"author":{"gitId":"-"},"content":"TEAMMATES"},{"lineNumber":305,"author":{"gitId":"-"},"content":"```"},{"lineNumber":306,"author":{"gitId":"-"},"content":""},{"lineNumber":307,"author":{"gitId":"-"},"content":"## E2E Component"},{"lineNumber":308,"author":{"gitId":"-"},"content":""},{"lineNumber":309,"author":{"gitId":"-"},"content":"The E2E component has no knowledge of the internal workings of the application and can only interact either with Web browser (as a whole application) or REST API calls (for the back-end logic). Its primary function is for E2E tests."},{"lineNumber":310,"author":{"gitId":"-"},"content":""},{"lineNumber":311,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/E2EComponent.puml\"/\u003e"},{"lineNumber":312,"author":{"gitId":"-"},"content":""},{"lineNumber":313,"author":{"gitId":"-"},"content":"Package overview:"},{"lineNumber":314,"author":{"gitId":"-"},"content":""},{"lineNumber":315,"author":{"gitId":"-"},"content":"- **`e2e.util`**: Contains helpers needed for running E2E tests. Also contains the test cases for the said infrastructure/helpers."},{"lineNumber":316,"author":{"gitId":"-"},"content":"- **`e2e.pageobjects`**: Contains abstractions of the pages as they appear on a Browser (i.e. SUTs)."},{"lineNumber":317,"author":{"gitId":"-"},"content":"- **`e2e.cases`**: Contains system test cases for testing the application as a whole."},{"lineNumber":318,"author":{"gitId":"-"},"content":""},{"lineNumber":319,"author":{"gitId":"-"},"content":"## Client Component"},{"lineNumber":320,"author":{"gitId":"-"},"content":""},{"lineNumber":321,"author":{"gitId":"-"},"content":"The Client component contains scripts that can connect directly to the application back-end for administrative purposes, such as migrating data to a new schema and calculating statistics."},{"lineNumber":322,"author":{"gitId":"-"},"content":""},{"lineNumber":323,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/ClientComponent.puml\"/\u003e"},{"lineNumber":324,"author":{"gitId":"-"},"content":""},{"lineNumber":325,"author":{"gitId":"-"},"content":"Package overview:"},{"lineNumber":326,"author":{"gitId":"-"},"content":""},{"lineNumber":327,"author":{"gitId":"-"},"content":"- **`client.util`**: Contains helpers needed for client scripts."},{"lineNumber":328,"author":{"gitId":"-"},"content":"- **`client.connector`**: Classes needed to connect to the back end directly."},{"lineNumber":329,"author":{"gitId":"-"},"content":"- **`client.scripts`**: Scripts that deal with the back end data for administrative purposes."}],"authorContributionMap":{"jingting1412":12,"-":317}},{"path":"src/e2e/java/teammates/e2e/cases/AdminNotificationsPageE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.LocalDate;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.time.LocalDateTime;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.ZoneId;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import java.util.UUID;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationStyle;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationTargetUser;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.AdminNotificationsPage;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.output.NotificationData;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * SUT: {@link Const.WebPageURIs#ADMIN_NOTIFICATIONS_PAGE}."},{"lineNumber":21,"author":{"gitId":"-"},"content":" */"},{"lineNumber":22,"author":{"gitId":"-"},"content":"public class AdminNotificationsPageE2ETest extends BaseE2ETestCase {"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" private Notification[] notifications \u003d new Notification[2];"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":26,"author":{"gitId":"-"},"content":" protected void prepareTestData() {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" testData \u003d loadDataBundle(\"/AdminNotificationsPageE2ETest.json\");"},{"lineNumber":28,"author":{"gitId":"-"},"content":" removeAndRestoreDataBundle(testData);"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" sqlTestData \u003d removeAndRestoreSqlDataBundle("},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" loadSqlDataBundle(\"/AdminNotificationsPageE2ETest_SqlEntities.json\"));"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" notifications[0] \u003d sqlTestData.notifications.get(\"notification1\");"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" notifications[1] \u003d sqlTestData.notifications.get(\"notification2\");"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":36,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":37,"author":{"gitId":"-"},"content":" public void testAll() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" ______TS(\"verify loaded data\");"},{"lineNumber":40,"author":{"gitId":"-"},"content":" AppUrl url \u003d createFrontendUrl(Const.WebPageURIs.ADMIN_NOTIFICATIONS_PAGE);"},{"lineNumber":41,"author":{"gitId":"-"},"content":" AdminNotificationsPage notificationsPage \u003d loginAdminToPage(url, AdminNotificationsPage.class);"},{"lineNumber":42,"author":{"gitId":"-"},"content":" // Only validates that the notifications are present in the notifications table instead of checking every row"},{"lineNumber":43,"author":{"gitId":"-"},"content":" // This is because the page will display all notifications in the database, which is not predictable"},{"lineNumber":44,"author":{"gitId":"-"},"content":" notificationsPage.verifyNotificationsTableRow(notifications[0]);"},{"lineNumber":45,"author":{"gitId":"-"},"content":" notificationsPage.verifyNotificationsTableRow(notifications[1]);"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" NotificationData notif \u003d BACKDOOR.getNotificationData(notifications[0].getId().toString());"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" assertEquals(notif.getNotificationId(), notifications[0].getId().toString());"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" assertEquals(notif.getMessage(), notifications[0].getMessage());"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" assertEquals(notif.getTitle(), notifications[0].getTitle());"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" notif \u003d BACKDOOR.getNotificationData(notifications[1].getId().toString());"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" assertEquals(notif.getNotificationId(), notifications[1].getId().toString());"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" assertEquals(notif.getMessage(), notifications[1].getMessage());"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" assertEquals(notif.getTitle(), notifications[1].getTitle());"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" ______TS(\"add new notification\");"},{"lineNumber":56,"author":{"gitId":"-"},"content":" int currentYear \u003d LocalDate.now().getYear();"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" Notification newNotification \u003d new Notification("},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" LocalDateTime.of(currentYear + 5, 2, 2, 12, 0).atZone(ZoneId.of(\"UTC\")).toInstant(),"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" LocalDateTime.of(currentYear + 5, 2, 3, 12, 0).atZone(ZoneId.of(\"UTC\")).toInstant(),"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" NotificationStyle.INFO,"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" NotificationTargetUser.STUDENT,"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" \"New E2E test notification 1\","},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" \"\u003cp\u003eNew E2E test notification message\u003c/p\u003e\""},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" );"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" notificationsPage.addNotification(newNotification);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" notificationsPage.verifyStatusMessage(\"Notification created successfully.\");"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" // Replace placeholder ID with actual ID of created notification"},{"lineNumber":70,"author":{"gitId":"-"},"content":" notificationsPage.sortNotificationsTableByDescendingCreateTime();"},{"lineNumber":71,"author":{"gitId":"-"},"content":" String newestNotificationId \u003d notificationsPage.getFirstRowNotificationId();"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" newNotification.setId(UUID.fromString(newestNotificationId));"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" // Checks that notification is in the database first"},{"lineNumber":75,"author":{"gitId":"-"},"content":" // so that newNotification is updated with the created time before checking table row"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" notif \u003d BACKDOOR.getNotificationData(newestNotificationId);"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" assertEquals(notif.getNotificationId(), newestNotificationId);"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" assertEquals(notif.getMessage(), newNotification.getMessage());"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" assertEquals(notif.getTitle(), newNotification.getTitle());"},{"lineNumber":80,"author":{"gitId":"-"},"content":" notificationsPage.verifyNotificationsTableRow(newNotification);"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" ______TS(\"edit notification\");"},{"lineNumber":83,"author":{"gitId":"-"},"content":" newNotification.setStartTime(LocalDateTime.of(currentYear + 7, 2, 2, 12, 0).atZone(ZoneId.of(\"UTC\")).toInstant());"},{"lineNumber":84,"author":{"gitId":"-"},"content":" newNotification.setEndTime(LocalDateTime.of(currentYear + 7, 2, 3, 12, 0).atZone(ZoneId.of(\"UTC\")).toInstant());"},{"lineNumber":85,"author":{"gitId":"-"},"content":" newNotification.setStyle(NotificationStyle.DANGER);"},{"lineNumber":86,"author":{"gitId":"-"},"content":" newNotification.setTargetUser(NotificationTargetUser.INSTRUCTOR);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" newNotification.setTitle(\"Edited E2E test notification 1\");"},{"lineNumber":88,"author":{"gitId":"-"},"content":" newNotification.setMessage(\"\u003cp\u003eEdited E2E test notification message\u003c/p\u003e\");"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" notificationsPage.editNotification(newNotification);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" notificationsPage.verifyStatusMessage(\"Notification updated successfully.\");"},{"lineNumber":92,"author":{"gitId":"-"},"content":" notificationsPage.verifyNotificationsTableRow(newNotification);"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" // verify that notification is present in database by reloading"},{"lineNumber":95,"author":{"gitId":"-"},"content":" notificationsPage.reloadPage();"},{"lineNumber":96,"author":{"gitId":"-"},"content":" notificationsPage.verifyNotificationsTableRow(newNotification);"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" ______TS(\"delete notification\");"},{"lineNumber":99,"author":{"gitId":"-"},"content":" notificationsPage.deleteNotification(newNotification);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" notificationsPage.verifyStatusMessage(\"Notification has been deleted.\");"},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" notif \u003d BACKDOOR.getNotificationData(newestNotificationId);"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" assertNull(notif);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" }"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":106,"author":{"gitId":"-"},"content":" public void classTeardown() {"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" for (Notification notification : sqlTestData.notifications.values()) {"},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" BACKDOOR.deleteNotification(notification.getId().toString());"},{"lineNumber":109,"author":{"gitId":"-"},"content":" }"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":33,"-":79}},{"path":"src/e2e/java/teammates/e2e/cases/AdminSearchPageE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.AdminSearchPage;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.e2e.util.TestProperties;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * SUT: {@link Const.WebPageURIs#ADMIN_SEARCH_PAGE}."},{"lineNumber":20,"author":{"gitId":"-"},"content":" */"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public class AdminSearchPageE2ETest extends BaseE2ETestCase {"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":24,"author":{"gitId":"-"},"content":" protected void prepareTestData() {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":27,"author":{"gitId":"-"},"content":" }"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" testData \u003d loadDataBundle(\"/AdminSearchPageE2ETest.json\");"},{"lineNumber":30,"author":{"gitId":"-"},"content":" removeAndRestoreDataBundle(testData);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" putDocuments(testData);"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" sqlTestData \u003d loadSqlDataBundle(\"/AdminSearchPageE2ETest_SqlEntities.json\");"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" removeAndRestoreSqlDataBundle(sqlTestData);"},{"lineNumber":34,"author":{"gitId":"-"},"content":" putSqlDocuments(sqlTestData);"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":38,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":39,"author":{"gitId":"-"},"content":" public void testAll() {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":42,"author":{"gitId":"-"},"content":" }"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" AppUrl url \u003d createFrontendUrl(Const.WebPageURIs.ADMIN_SEARCH_PAGE);"},{"lineNumber":45,"author":{"gitId":"-"},"content":" AdminSearchPage searchPage \u003d loginAdminToPage(url, AdminSearchPage.class);"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" CourseAttributes course \u003d testData.courses.get(\"typicalCourse1\");"},{"lineNumber":48,"author":{"gitId":"-"},"content":" StudentAttributes student \u003d testData.students.get(\"student1InCourse1\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d testData.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d sqlTestData.accountRequests.get(\"instructor1OfCourse1\");"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Search student email\");"},{"lineNumber":53,"author":{"gitId":"-"},"content":" String searchContent \u003d student.getEmail();"},{"lineNumber":54,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":56,"author":{"gitId":"-"},"content":" String studentDetails \u003d getExpectedStudentDetails(student);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" String studentManageAccountLink \u003d getExpectedStudentManageAccountLink(student);"},{"lineNumber":58,"author":{"gitId":"-"},"content":" String studentHomePageLink \u003d getExpectedStudentHomePageLink(student);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" int numExpandedRows \u003d getExpectedNumExpandedRows(student);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" searchPage.verifyStudentRowContent(student, course, studentDetails, studentManageAccountLink,"},{"lineNumber":61,"author":{"gitId":"-"},"content":" studentHomePageLink);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" searchPage.verifyStudentExpandedLinks(student, numExpandedRows);"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Reset student google id\");"},{"lineNumber":65,"author":{"gitId":"-"},"content":" searchPage.resetStudentGoogleId(student);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" student.setGoogleId(null);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" studentManageAccountLink \u003d getExpectedStudentManageAccountLink(student);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" studentHomePageLink \u003d getExpectedStudentHomePageLink(student);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" searchPage.verifyStudentRowContent(student, course, studentDetails, studentManageAccountLink,"},{"lineNumber":70,"author":{"gitId":"-"},"content":" studentHomePageLink);"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Regenerate registration key for a course student\");"},{"lineNumber":73,"author":{"gitId":"-"},"content":" searchPage.clickExpandStudentLinks();"},{"lineNumber":74,"author":{"gitId":"-"},"content":" String originalJoinLink \u003d searchPage.getStudentJoinLink(student);"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" searchPage.regenerateStudentKey(student);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" searchPage.verifyRegenerateStudentKey(student, originalJoinLink);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" searchPage.waitForPageToLoad();"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Search for instructor email\");"},{"lineNumber":81,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":82,"author":{"gitId":"-"},"content":" searchContent \u003d instructor.getEmail();"},{"lineNumber":83,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":85,"author":{"gitId":"-"},"content":" String instructorManageAccountLink \u003d getExpectedInstructorManageAccountLink(instructor);"},{"lineNumber":86,"author":{"gitId":"-"},"content":" String instructorHomePageLink \u003d getExpectedInstructorHomePageLink(instructor);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" searchPage.verifyInstructorRowContent(instructor, course, instructorManageAccountLink,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" instructorHomePageLink);"},{"lineNumber":89,"author":{"gitId":"-"},"content":" searchPage.verifyInstructorExpandedLinks(instructor);"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Reset instructor google id\");"},{"lineNumber":92,"author":{"gitId":"-"},"content":" searchPage.resetInstructorGoogleId(instructor);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" instructor.setGoogleId(null);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" instructorManageAccountLink \u003d getExpectedInstructorManageAccountLink(instructor);"},{"lineNumber":95,"author":{"gitId":"-"},"content":" instructorHomePageLink \u003d getExpectedInstructorHomePageLink(instructor);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" searchPage.verifyInstructorRowContent(instructor, course, instructorManageAccountLink,"},{"lineNumber":97,"author":{"gitId":"-"},"content":" instructorHomePageLink);"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Regenerate registration key for an instructor\");"},{"lineNumber":100,"author":{"gitId":"-"},"content":" searchPage.clickExpandInstructorLinks();"},{"lineNumber":101,"author":{"gitId":"-"},"content":" originalJoinLink \u003d searchPage.getInstructorJoinLink(instructor);"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" searchPage.regenerateInstructorKey(instructor);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" searchPage.verifyRegenerateInstructorKey(instructor, originalJoinLink);"},{"lineNumber":105,"author":{"gitId":"-"},"content":" searchPage.waitForPageToLoad();"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Search for account request by email\");"},{"lineNumber":108,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":109,"author":{"gitId":"-"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":110,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":112,"author":{"gitId":"-"},"content":" searchPage.verifyAccountRequestRowContent(accountRequest);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" searchPage.verifyAccountRequestExpandedLinks(accountRequest);"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Search common search key\");"},{"lineNumber":116,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":117,"author":{"gitId":"-"},"content":" searchContent \u003d \"Course1\";"},{"lineNumber":118,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":120,"author":{"gitId":"-"},"content":" searchPage.verifyStudentRowContent(student, course, studentDetails, studentManageAccountLink,"},{"lineNumber":121,"author":{"gitId":"-"},"content":" studentHomePageLink);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" searchPage.verifyInstructorRowContent(instructor, course, instructorManageAccountLink,"},{"lineNumber":123,"author":{"gitId":"-"},"content":" instructorHomePageLink);"},{"lineNumber":124,"author":{"gitId":"-"},"content":" searchPage.verifyAccountRequestRowContent(accountRequest);"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Expand and collapse links\");"},{"lineNumber":127,"author":{"gitId":"-"},"content":" searchPage.verifyLinkExpansionButtons(student, instructor, accountRequest);"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Reset account request successful\");"},{"lineNumber":130,"author":{"gitId":"-"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":131,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":132,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":134,"author":{"gitId":"-"},"content":" searchPage.clickResetAccountRequestButton(accountRequest);"},{"lineNumber":135,"author":{"gitId":"-"},"content":" assertNull(BACKDOOR.getAccountRequest(accountRequest.getId()).getRegisteredAt());"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Delete account request successful\");"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d sqlTestData.accountRequests.get(\"unregisteredInstructor1\");"},{"lineNumber":139,"author":{"gitId":"-"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":140,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":141,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":142,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":143,"author":{"gitId":"-"},"content":" searchPage.clickDeleteAccountRequestButton(accountRequest);"},{"lineNumber":144,"author":{"gitId":"-"},"content":" assertNull(BACKDOOR.getAccountRequest(accountRequest.getId()));"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" private String getExpectedStudentDetails(StudentAttributes student) {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" return String.format(\"%s [%s] (%s)\", student.getCourse(),"},{"lineNumber":149,"author":{"gitId":"-"},"content":" student.getSection() \u003d\u003d null ? Const.DEFAULT_SECTION : student.getSection(), student.getTeam());"},{"lineNumber":150,"author":{"gitId":"-"},"content":" }"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" private String getExpectedStudentHomePageLink(StudentAttributes student) {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" return student.isRegistered() ? createFrontendUrl(Const.WebPageURIs.STUDENT_HOME_PAGE)"},{"lineNumber":154,"author":{"gitId":"-"},"content":" .withUserId(student.getGoogleId())"},{"lineNumber":155,"author":{"gitId":"-"},"content":" .toAbsoluteString()"},{"lineNumber":156,"author":{"gitId":"-"},"content":" : \"\";"},{"lineNumber":157,"author":{"gitId":"-"},"content":" }"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" private String getExpectedStudentManageAccountLink(StudentAttributes student) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" return student.isRegistered() ? createFrontendUrl(Const.WebPageURIs.ADMIN_ACCOUNTS_PAGE)"},{"lineNumber":161,"author":{"gitId":"-"},"content":" .withParam(Const.ParamsNames.INSTRUCTOR_ID, student.getGoogleId())"},{"lineNumber":162,"author":{"gitId":"-"},"content":" .toAbsoluteString()"},{"lineNumber":163,"author":{"gitId":"-"},"content":" : \"\";"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" private int getExpectedNumExpandedRows(StudentAttributes student) {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" int expectedNumExpandedRows \u003d 2;"},{"lineNumber":168,"author":{"gitId":"-"},"content":" for (FeedbackSessionAttributes sessions : testData.feedbackSessions.values()) {"},{"lineNumber":169,"author":{"gitId":"-"},"content":" if (sessions.getCourseId().equals(student.getCourse())) {"},{"lineNumber":170,"author":{"gitId":"-"},"content":" expectedNumExpandedRows +\u003d 1;"},{"lineNumber":171,"author":{"gitId":"-"},"content":" if (sessions.getResultsVisibleFromTime().isBefore(Instant.now())) {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" expectedNumExpandedRows +\u003d 1;"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":" }"},{"lineNumber":175,"author":{"gitId":"-"},"content":" }"},{"lineNumber":176,"author":{"gitId":"-"},"content":" return expectedNumExpandedRows;"},{"lineNumber":177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" private String getExpectedInstructorHomePageLink(InstructorAttributes instructor) {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" String googleId \u003d instructor.isRegistered() ? instructor.getGoogleId() : \"\";"},{"lineNumber":181,"author":{"gitId":"-"},"content":" return createFrontendUrl(Const.WebPageURIs.INSTRUCTOR_HOME_PAGE)"},{"lineNumber":182,"author":{"gitId":"-"},"content":" .withUserId(googleId)"},{"lineNumber":183,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":184,"author":{"gitId":"-"},"content":" }"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" private String getExpectedInstructorManageAccountLink(InstructorAttributes instructor) {"},{"lineNumber":187,"author":{"gitId":"-"},"content":" String googleId \u003d instructor.isRegistered() ? instructor.getGoogleId() : \"\";"},{"lineNumber":188,"author":{"gitId":"-"},"content":" return createFrontendUrl(Const.WebPageURIs.ADMIN_ACCOUNTS_PAGE)"},{"lineNumber":189,"author":{"gitId":"-"},"content":" .withParam(Const.ParamsNames.INSTRUCTOR_ID, googleId)"},{"lineNumber":190,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":191,"author":{"gitId":"-"},"content":" }"},{"lineNumber":192,"author":{"gitId":"-"},"content":""},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":" @AfterClass"},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" public void classTeardown() {"},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" for (AccountRequest request : sqlTestData.accountRequests.values()) {"},{"lineNumber":196,"author":{"gitId":"dishenggg"},"content":" BACKDOOR.deleteAccountRequest(request.getId());"},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":200,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":12,"dishenggg":1,"-":187}},{"path":"src/e2e/java/teammates/e2e/cases/BaseE2ETestCase.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.io.IOException;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.nio.file.Files;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.nio.file.Paths;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.ITestContext;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.DataBundle;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountAttributes;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountRequestAttributes;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.DeadlineExtensionAttributes;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseAttributes;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseCommentAttributes;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.NotificationAttributes;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.exception.HttpRequestFailedException;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.AppPage;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.Browser;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.DevServerLoginPage;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.HomePage;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.e2e.util.BackDoor;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.e2e.util.EmailAccount;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.e2e.util.TestProperties;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCaseWithDatabaseAccess;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.test.FileHelper;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import teammates.test.ThreadHelper;"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":41,"author":{"gitId":"-"},"content":" * Base class for all browser tests."},{"lineNumber":42,"author":{"gitId":"-"},"content":" *"},{"lineNumber":43,"author":{"gitId":"-"},"content":" * \u003cp\u003eThis type of test has no knowledge of the workings of the application,"},{"lineNumber":44,"author":{"gitId":"-"},"content":" * and can only communicate via the UI or via {@link BackDoor} to obtain/transmit data."},{"lineNumber":45,"author":{"gitId":"-"},"content":" */"},{"lineNumber":46,"author":{"gitId":"-"},"content":"public abstract class BaseE2ETestCase extends BaseTestCaseWithDatabaseAccess {"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":49,"author":{"gitId":"-"},"content":" * Backdoor used to call APIs."},{"lineNumber":50,"author":{"gitId":"-"},"content":" */"},{"lineNumber":51,"author":{"gitId":"-"},"content":" protected static final BackDoor BACKDOOR \u003d BackDoor.getInstance();"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":54,"author":{"gitId":"-"},"content":" * Data to be used in the test."},{"lineNumber":55,"author":{"gitId":"-"},"content":" */"},{"lineNumber":56,"author":{"gitId":"-"},"content":" protected DataBundle testData;"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":59,"author":{"gitId":"-"},"content":" * Sql Data to be used in the test."},{"lineNumber":60,"author":{"gitId":"-"},"content":" */"},{"lineNumber":61,"author":{"gitId":"-"},"content":" protected SqlDataBundle sqlTestData;"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" private Browser browser;"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" @BeforeClass"},{"lineNumber":66,"author":{"gitId":"-"},"content":" public void baseClassSetup() {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" prepareTestData();"},{"lineNumber":68,"author":{"gitId":"-"},"content":" prepareBrowser();"},{"lineNumber":69,"author":{"gitId":"-"},"content":" }"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":72,"author":{"gitId":"-"},"content":" * Prepares the browser used for the current test."},{"lineNumber":73,"author":{"gitId":"-"},"content":" */"},{"lineNumber":74,"author":{"gitId":"-"},"content":" protected void prepareBrowser() {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" browser \u003d new Browser();"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":79,"author":{"gitId":"-"},"content":" * Prepares the test data used for the current test."},{"lineNumber":80,"author":{"gitId":"-"},"content":" */"},{"lineNumber":81,"author":{"gitId":"-"},"content":" protected abstract void prepareTestData();"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":84,"author":{"gitId":"-"},"content":" * Contains all the tests for the page."},{"lineNumber":85,"author":{"gitId":"-"},"content":" *"},{"lineNumber":86,"author":{"gitId":"-"},"content":" * \u003cp\u003eThis approach is chosen so that setup and teardown are only needed once per test page,"},{"lineNumber":87,"author":{"gitId":"-"},"content":" * thereby saving time. While it necessitates failed tests to be restarted from the beginning,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" * test failures are rare and thus not causing significant overhead."},{"lineNumber":89,"author":{"gitId":"-"},"content":" */"},{"lineNumber":90,"author":{"gitId":"-"},"content":" protected abstract void testAll();"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":93,"author":{"gitId":"-"},"content":" protected String getTestDataFolder() {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" return TestProperties.TEST_DATA_FOLDER;"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":98,"author":{"gitId":"-"},"content":" public void baseClassTearDown(ITestContext context) {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" if (browser \u003d\u003d null) {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":" boolean isSuccess \u003d context.getFailedTests().getAllMethods()"},{"lineNumber":103,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":104,"author":{"gitId":"-"},"content":" .noneMatch(method -\u003e method.getConstructorOrMethod().getMethod().getDeclaringClass() \u003d\u003d this.getClass());"},{"lineNumber":105,"author":{"gitId":"-"},"content":" if (isSuccess || TestProperties.CLOSE_BROWSER_ON_FAILURE) {"},{"lineNumber":106,"author":{"gitId":"-"},"content":" browser.close();"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":111,"author":{"gitId":"-"},"content":" * Creates an {@link AppUrl} for the supplied {@code relativeUrl} parameter."},{"lineNumber":112,"author":{"gitId":"-"},"content":" * The base URL will be the value of test.app.frontend.url in test.properties."},{"lineNumber":113,"author":{"gitId":"-"},"content":" * {@code relativeUrl} must start with a \"/\"."},{"lineNumber":114,"author":{"gitId":"-"},"content":" */"},{"lineNumber":115,"author":{"gitId":"-"},"content":" protected static AppUrl createFrontendUrl(String relativeUrl) {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" return new AppUrl(TestProperties.TEAMMATES_FRONTEND_URL + relativeUrl);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" }"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":120,"author":{"gitId":"-"},"content":" * Creates an {@link AppUrl} for the supplied {@code relativeUrl} parameter."},{"lineNumber":121,"author":{"gitId":"-"},"content":" * The base URL will be the value of test.app.backend.url in test.properties."},{"lineNumber":122,"author":{"gitId":"-"},"content":" * {@code relativeUrl} must start with a \"/\"."},{"lineNumber":123,"author":{"gitId":"-"},"content":" */"},{"lineNumber":124,"author":{"gitId":"-"},"content":" protected static AppUrl createBackendUrl(String relativeUrl) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" return new AppUrl(TestProperties.TEAMMATES_BACKEND_URL + relativeUrl);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" }"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":129,"author":{"gitId":"-"},"content":" * Logs in to a page using the given credentials."},{"lineNumber":130,"author":{"gitId":"-"},"content":" */"},{"lineNumber":131,"author":{"gitId":"-"},"content":" protected \u003cT extends AppPage\u003e T loginToPage(AppUrl url, Class\u003cT\u003e typeOfPage, String userId) {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" // When not using dev server, Google blocks log in by automation."},{"lineNumber":133,"author":{"gitId":"-"},"content":" // To work around that, we inject the user cookie directly into the browser session."},{"lineNumber":134,"author":{"gitId":"-"},"content":" if (!TestProperties.isDevServer()) {"},{"lineNumber":135,"author":{"gitId":"-"},"content":" // In order for the cookie injection to work, we need to be in the domain."},{"lineNumber":136,"author":{"gitId":"-"},"content":" // Use the home page to minimize the page load time."},{"lineNumber":137,"author":{"gitId":"-"},"content":" browser.goToUrl(TestProperties.TEAMMATES_FRONTEND_URL);"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" String cookieValue \u003d BACKDOOR.getUserCookie(userId);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" browser.addCookie(Const.SecurityConfig.AUTH_COOKIE_NAME, cookieValue, true, true);"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" return getNewPageInstance(url, typeOfPage);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" }"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" // This will be redirected to the dev server login page."},{"lineNumber":146,"author":{"gitId":"-"},"content":" browser.goToUrl(url.toAbsoluteString());"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" DevServerLoginPage loginPage \u003d AppPage.getNewPageInstance(browser, DevServerLoginPage.class);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" loginPage.loginAsUser(userId);"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" return getNewPageInstance(url, typeOfPage);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" }"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":155,"author":{"gitId":"-"},"content":" * Logs in to a page using admin credentials."},{"lineNumber":156,"author":{"gitId":"-"},"content":" */"},{"lineNumber":157,"author":{"gitId":"-"},"content":" protected \u003cT extends AppPage\u003e T loginAdminToPage(AppUrl url, Class\u003cT\u003e typeOfPage) {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" return loginToPage(url, typeOfPage, TestProperties.TEST_ADMIN);"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":162,"author":{"gitId":"-"},"content":" * Equivalent to clicking the \u0027logout\u0027 link in the top menu of the page."},{"lineNumber":163,"author":{"gitId":"-"},"content":" */"},{"lineNumber":164,"author":{"gitId":"-"},"content":" protected void logout() {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" AppUrl url \u003d createBackendUrl(Const.WebPageURIs.LOGOUT);"},{"lineNumber":166,"author":{"gitId":"-"},"content":" if (!TestProperties.TEAMMATES_FRONTEND_URL.equals(TestProperties.TEAMMATES_BACKEND_URL)) {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" url \u003d url.withParam(\"frontendUrl\", TestProperties.TEAMMATES_FRONTEND_URL);"},{"lineNumber":168,"author":{"gitId":"-"},"content":" }"},{"lineNumber":169,"author":{"gitId":"-"},"content":""},{"lineNumber":170,"author":{"gitId":"-"},"content":" browser.goToUrl(url.toAbsoluteString());"},{"lineNumber":171,"author":{"gitId":"-"},"content":" AppPage.getNewPageInstance(browser, HomePage.class).waitForPageToLoad();"},{"lineNumber":172,"author":{"gitId":"-"},"content":" }"},{"lineNumber":173,"author":{"gitId":"-"},"content":""},{"lineNumber":174,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":175,"author":{"gitId":"-"},"content":" * Deletes file with fileName from the downloads folder."},{"lineNumber":176,"author":{"gitId":"-"},"content":" */"},{"lineNumber":177,"author":{"gitId":"-"},"content":" protected void deleteDownloadsFile(String fileName) {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" String filePath \u003d TestProperties.TEST_DOWNLOADS_FOLDER + fileName;"},{"lineNumber":179,"author":{"gitId":"-"},"content":" FileHelper.deleteFile(filePath);"},{"lineNumber":180,"author":{"gitId":"-"},"content":" }"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":183,"author":{"gitId":"-"},"content":" * Verifies downloaded file has correct fileName and contains expected content."},{"lineNumber":184,"author":{"gitId":"-"},"content":" */"},{"lineNumber":185,"author":{"gitId":"-"},"content":" protected void verifyDownloadedFile(String expectedFileName, List\u003cString\u003e expectedContent) {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" String filePath \u003d TestProperties.TEST_DOWNLOADS_FOLDER + expectedFileName;"},{"lineNumber":187,"author":{"gitId":"-"},"content":" int retryLimit \u003d TestProperties.TEST_TIMEOUT;"},{"lineNumber":188,"author":{"gitId":"-"},"content":" boolean actual \u003d Files.exists(Paths.get(filePath));"},{"lineNumber":189,"author":{"gitId":"-"},"content":" while (!actual \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":191,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(1000);"},{"lineNumber":192,"author":{"gitId":"-"},"content":" actual \u003d Files.exists(Paths.get(filePath));"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":" assertTrue(actual);"},{"lineNumber":195,"author":{"gitId":"-"},"content":""},{"lineNumber":196,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" String actualContent \u003d FileHelper.readFile(filePath);"},{"lineNumber":198,"author":{"gitId":"-"},"content":" for (String content : expectedContent) {"},{"lineNumber":199,"author":{"gitId":"-"},"content":" assertTrue(actualContent.contains(content));"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }"},{"lineNumber":201,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":203,"author":{"gitId":"-"},"content":" }"},{"lineNumber":204,"author":{"gitId":"-"},"content":" }"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":207,"author":{"gitId":"-"},"content":" * Visits the URL and gets the page object representation of the visited web page in the browser."},{"lineNumber":208,"author":{"gitId":"-"},"content":" */"},{"lineNumber":209,"author":{"gitId":"-"},"content":" protected \u003cT extends AppPage\u003e T getNewPageInstance(AppUrl url, Class\u003cT\u003e typeOfPage) {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" browser.goToUrl(url.toAbsoluteString());"},{"lineNumber":211,"author":{"gitId":"-"},"content":" return AppPage.getNewPageInstance(browser, typeOfPage);"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":215,"author":{"gitId":"-"},"content":" * Verifies that email with subject is found in inbox."},{"lineNumber":216,"author":{"gitId":"-"},"content":" * Email used must be an authentic gmail account."},{"lineNumber":217,"author":{"gitId":"-"},"content":" */"},{"lineNumber":218,"author":{"gitId":"-"},"content":" protected void verifyEmailSent(String email, String subject) {"},{"lineNumber":219,"author":{"gitId":"-"},"content":" if (TestProperties.isDevServer() || !TestProperties.INCLUDE_EMAIL_VERIFICATION) {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":221,"author":{"gitId":"-"},"content":" }"},{"lineNumber":222,"author":{"gitId":"-"},"content":" if (!TestProperties.TEST_EMAIL.equals(email)) {"},{"lineNumber":223,"author":{"gitId":"-"},"content":" fail(\"Email verification is allowed only on preset test email.\");"},{"lineNumber":224,"author":{"gitId":"-"},"content":" }"},{"lineNumber":225,"author":{"gitId":"-"},"content":" EmailAccount emailAccount \u003d new EmailAccount(email);"},{"lineNumber":226,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" emailAccount.getUserAuthenticated();"},{"lineNumber":228,"author":{"gitId":"-"},"content":" int retryLimit \u003d 5;"},{"lineNumber":229,"author":{"gitId":"-"},"content":" boolean actual \u003d emailAccount.isRecentEmailWithSubjectPresent(subject, TestProperties.TEST_SENDER_EMAIL);"},{"lineNumber":230,"author":{"gitId":"-"},"content":" while (!actual \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":231,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":232,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(1000);"},{"lineNumber":233,"author":{"gitId":"-"},"content":" actual \u003d emailAccount.isRecentEmailWithSubjectPresent(subject, TestProperties.TEST_SENDER_EMAIL);"},{"lineNumber":234,"author":{"gitId":"-"},"content":" }"},{"lineNumber":235,"author":{"gitId":"-"},"content":" assertTrue(actual);"},{"lineNumber":236,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":237,"author":{"gitId":"-"},"content":" fail(\"Failed to verify email sent:\" + e);"},{"lineNumber":238,"author":{"gitId":"-"},"content":" }"},{"lineNumber":239,"author":{"gitId":"-"},"content":" }"},{"lineNumber":240,"author":{"gitId":"-"},"content":""},{"lineNumber":241,"author":{"gitId":"-"},"content":" AccountAttributes getAccount(String googleId) {"},{"lineNumber":242,"author":{"gitId":"-"},"content":" return BACKDOOR.getAccount(googleId);"},{"lineNumber":243,"author":{"gitId":"-"},"content":" }"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":246,"author":{"gitId":"-"},"content":" protected AccountAttributes getAccount(AccountAttributes account) {"},{"lineNumber":247,"author":{"gitId":"-"},"content":" return getAccount(account.getGoogleId());"},{"lineNumber":248,"author":{"gitId":"-"},"content":" }"},{"lineNumber":249,"author":{"gitId":"-"},"content":""},{"lineNumber":250,"author":{"gitId":"-"},"content":" CourseAttributes getCourse(String courseId) {"},{"lineNumber":251,"author":{"gitId":"-"},"content":" return BACKDOOR.getCourse(courseId);"},{"lineNumber":252,"author":{"gitId":"-"},"content":" }"},{"lineNumber":253,"author":{"gitId":"-"},"content":""},{"lineNumber":254,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":255,"author":{"gitId":"-"},"content":" protected CourseAttributes getCourse(CourseAttributes course) {"},{"lineNumber":256,"author":{"gitId":"-"},"content":" return getCourse(course.getId());"},{"lineNumber":257,"author":{"gitId":"-"},"content":" }"},{"lineNumber":258,"author":{"gitId":"-"},"content":""},{"lineNumber":259,"author":{"gitId":"-"},"content":" CourseAttributes getArchivedCourse(String instructorId, String courseId) {"},{"lineNumber":260,"author":{"gitId":"-"},"content":" return BACKDOOR.getArchivedCourse(instructorId, courseId);"},{"lineNumber":261,"author":{"gitId":"-"},"content":" }"},{"lineNumber":262,"author":{"gitId":"-"},"content":""},{"lineNumber":263,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes getFeedbackQuestion(String courseId, String feedbackSessionName, int qnNumber) {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" return BACKDOOR.getFeedbackQuestion(courseId, feedbackSessionName, qnNumber);"},{"lineNumber":265,"author":{"gitId":"-"},"content":" }"},{"lineNumber":266,"author":{"gitId":"-"},"content":""},{"lineNumber":267,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":268,"author":{"gitId":"-"},"content":" protected FeedbackQuestionAttributes getFeedbackQuestion(FeedbackQuestionAttributes fq) {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" return getFeedbackQuestion(fq.getCourseId(), fq.getFeedbackSessionName(), fq.getQuestionNumber());"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" FeedbackResponseCommentAttributes getFeedbackResponseComment(String feedbackResponseId) {"},{"lineNumber":273,"author":{"gitId":"-"},"content":" return BACKDOOR.getFeedbackResponseComment(feedbackResponseId);"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":277,"author":{"gitId":"-"},"content":" protected FeedbackResponseCommentAttributes getFeedbackResponseComment(FeedbackResponseCommentAttributes frc) {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" return getFeedbackResponseComment(frc.getFeedbackResponseId());"},{"lineNumber":279,"author":{"gitId":"-"},"content":" }"},{"lineNumber":280,"author":{"gitId":"-"},"content":""},{"lineNumber":281,"author":{"gitId":"-"},"content":" FeedbackResponseAttributes getFeedbackResponse(String feedbackQuestionId, String giver, String recipient) {"},{"lineNumber":282,"author":{"gitId":"-"},"content":" return BACKDOOR.getFeedbackResponse(feedbackQuestionId, giver, recipient);"},{"lineNumber":283,"author":{"gitId":"-"},"content":" }"},{"lineNumber":284,"author":{"gitId":"-"},"content":""},{"lineNumber":285,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":286,"author":{"gitId":"-"},"content":" protected FeedbackResponseAttributes getFeedbackResponse(FeedbackResponseAttributes fr) {"},{"lineNumber":287,"author":{"gitId":"-"},"content":" return getFeedbackResponse(fr.getFeedbackQuestionId(), fr.getGiver(), fr.getRecipient());"},{"lineNumber":288,"author":{"gitId":"-"},"content":" }"},{"lineNumber":289,"author":{"gitId":"-"},"content":""},{"lineNumber":290,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes getFeedbackSession(String courseId, String feedbackSessionName) {"},{"lineNumber":291,"author":{"gitId":"-"},"content":" return BACKDOOR.getFeedbackSession(courseId, feedbackSessionName);"},{"lineNumber":292,"author":{"gitId":"-"},"content":" }"},{"lineNumber":293,"author":{"gitId":"-"},"content":""},{"lineNumber":294,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":295,"author":{"gitId":"-"},"content":" protected FeedbackSessionAttributes getFeedbackSession(FeedbackSessionAttributes fs) {"},{"lineNumber":296,"author":{"gitId":"-"},"content":" return getFeedbackSession(fs.getCourseId(), fs.getFeedbackSessionName());"},{"lineNumber":297,"author":{"gitId":"-"},"content":" }"},{"lineNumber":298,"author":{"gitId":"-"},"content":""},{"lineNumber":299,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes getSoftDeletedSession(String feedbackSessionName, String instructorId) {"},{"lineNumber":300,"author":{"gitId":"-"},"content":" return BACKDOOR.getSoftDeletedSession(feedbackSessionName, instructorId);"},{"lineNumber":301,"author":{"gitId":"-"},"content":" }"},{"lineNumber":302,"author":{"gitId":"-"},"content":""},{"lineNumber":303,"author":{"gitId":"-"},"content":" InstructorAttributes getInstructor(String courseId, String instructorEmail) {"},{"lineNumber":304,"author":{"gitId":"-"},"content":" return BACKDOOR.getInstructor(courseId, instructorEmail);"},{"lineNumber":305,"author":{"gitId":"-"},"content":" }"},{"lineNumber":306,"author":{"gitId":"-"},"content":""},{"lineNumber":307,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":308,"author":{"gitId":"-"},"content":" protected InstructorAttributes getInstructor(InstructorAttributes instructor) {"},{"lineNumber":309,"author":{"gitId":"-"},"content":" return getInstructor(instructor.getCourseId(), instructor.getEmail());"},{"lineNumber":310,"author":{"gitId":"-"},"content":" }"},{"lineNumber":311,"author":{"gitId":"-"},"content":""},{"lineNumber":312,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":313,"author":{"gitId":"-"},"content":" * Gets registration key for a given instructor."},{"lineNumber":314,"author":{"gitId":"-"},"content":" */"},{"lineNumber":315,"author":{"gitId":"-"},"content":" protected String getKeyForInstructor(String courseId, String instructorEmail) {"},{"lineNumber":316,"author":{"gitId":"-"},"content":" return getInstructor(courseId, instructorEmail).getKey();"},{"lineNumber":317,"author":{"gitId":"-"},"content":" }"},{"lineNumber":318,"author":{"gitId":"-"},"content":""},{"lineNumber":319,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":320,"author":{"gitId":"-"},"content":" protected StudentAttributes getStudent(StudentAttributes student) {"},{"lineNumber":321,"author":{"gitId":"-"},"content":" return BACKDOOR.getStudent(student.getCourse(), student.getEmail());"},{"lineNumber":322,"author":{"gitId":"-"},"content":" }"},{"lineNumber":323,"author":{"gitId":"-"},"content":""},{"lineNumber":324,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":325,"author":{"gitId":"-"},"content":" * Gets registration key for a given student."},{"lineNumber":326,"author":{"gitId":"-"},"content":" */"},{"lineNumber":327,"author":{"gitId":"-"},"content":" protected String getKeyForStudent(StudentAttributes student) {"},{"lineNumber":328,"author":{"gitId":"-"},"content":" return getStudent(student).getKey();"},{"lineNumber":329,"author":{"gitId":"-"},"content":" }"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":332,"author":{"gitId":"-"},"content":" protected AccountRequestAttributes getAccountRequest(AccountRequestAttributes accountRequest) {"},{"lineNumber":333,"author":{"gitId":"-"},"content":" return BACKDOOR.getAccountRequest(UUID.fromString(accountRequest.getId()));"},{"lineNumber":334,"author":{"gitId":"-"},"content":" }"},{"lineNumber":335,"author":{"gitId":"-"},"content":""},{"lineNumber":336,"author":{"gitId":"-"},"content":" NotificationAttributes getNotification(String notificationId) {"},{"lineNumber":337,"author":{"gitId":"-"},"content":" return BACKDOOR.getNotification(notificationId);"},{"lineNumber":338,"author":{"gitId":"-"},"content":" }"},{"lineNumber":339,"author":{"gitId":"-"},"content":""},{"lineNumber":340,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":341,"author":{"gitId":"-"},"content":" protected NotificationAttributes getNotification(NotificationAttributes notification) {"},{"lineNumber":342,"author":{"gitId":"-"},"content":" return getNotification(notification.getNotificationId());"},{"lineNumber":343,"author":{"gitId":"-"},"content":" }"},{"lineNumber":344,"author":{"gitId":"-"},"content":""},{"lineNumber":345,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":346,"author":{"gitId":"-"},"content":" protected DeadlineExtensionAttributes getDeadlineExtension(DeadlineExtensionAttributes deadlineExtension) {"},{"lineNumber":347,"author":{"gitId":"-"},"content":" return BACKDOOR.getDeadlineExtension("},{"lineNumber":348,"author":{"gitId":"-"},"content":" deadlineExtension.getCourseId(), deadlineExtension.getFeedbackSessionName(),"},{"lineNumber":349,"author":{"gitId":"-"},"content":" deadlineExtension.getUserEmail(), deadlineExtension.getIsInstructor());"},{"lineNumber":350,"author":{"gitId":"-"},"content":" }"},{"lineNumber":351,"author":{"gitId":"-"},"content":""},{"lineNumber":352,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":353,"author":{"gitId":"-"},"content":" protected boolean doRemoveAndRestoreDataBundle(DataBundle testData) {"},{"lineNumber":354,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":355,"author":{"gitId":"-"},"content":" BACKDOOR.removeAndRestoreDataBundle(testData);"},{"lineNumber":356,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":357,"author":{"gitId":"-"},"content":" } catch (HttpRequestFailedException e) {"},{"lineNumber":358,"author":{"gitId":"-"},"content":" e.printStackTrace();"},{"lineNumber":359,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":360,"author":{"gitId":"-"},"content":" }"},{"lineNumber":361,"author":{"gitId":"-"},"content":" }"},{"lineNumber":362,"author":{"gitId":"-"},"content":""},{"lineNumber":363,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":364,"author":{"gitId":"-"},"content":" protected SqlDataBundle doRemoveAndRestoreSqlDataBundle(SqlDataBundle testData) {"},{"lineNumber":365,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":366,"author":{"gitId":"-"},"content":" return BACKDOOR.removeAndRestoreSqlDataBundle(testData);"},{"lineNumber":367,"author":{"gitId":"-"},"content":" } catch (HttpRequestFailedException e) {"},{"lineNumber":368,"author":{"gitId":"-"},"content":" e.printStackTrace();"},{"lineNumber":369,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":370,"author":{"gitId":"-"},"content":" }"},{"lineNumber":371,"author":{"gitId":"-"},"content":" }"},{"lineNumber":372,"author":{"gitId":"-"},"content":""},{"lineNumber":373,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":374,"author":{"gitId":"-"},"content":" protected boolean doPutDocuments(DataBundle testData) {"},{"lineNumber":375,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":376,"author":{"gitId":"-"},"content":" BACKDOOR.putDocuments(testData);"},{"lineNumber":377,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":378,"author":{"gitId":"-"},"content":" } catch (HttpRequestFailedException e) {"},{"lineNumber":379,"author":{"gitId":"-"},"content":" e.printStackTrace();"},{"lineNumber":380,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":381,"author":{"gitId":"-"},"content":" }"},{"lineNumber":382,"author":{"gitId":"-"},"content":" }"},{"lineNumber":383,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":384,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":385,"author":{"gitId":"domoberzin"},"content":" protected boolean doPutDocumentsSql(SqlDataBundle testData) {"},{"lineNumber":386,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":387,"author":{"gitId":"domoberzin"},"content":" BACKDOOR.putSqlDocuments(testData);"},{"lineNumber":388,"author":{"gitId":"domoberzin"},"content":" return true;"},{"lineNumber":389,"author":{"gitId":"domoberzin"},"content":" } catch (HttpRequestFailedException e) {"},{"lineNumber":390,"author":{"gitId":"domoberzin"},"content":" e.printStackTrace();"},{"lineNumber":391,"author":{"gitId":"domoberzin"},"content":" return false;"},{"lineNumber":392,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":393,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":394,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":11,"-":383}},{"path":"src/e2e/java/teammates/e2e/cases/InstructorNotificationsPageE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.Set;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.stream.Collectors;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.stream.Stream;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.NotificationAttributes;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.InstructorNotificationsPage;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.output.AccountData;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * SUT: {@link Const.WebPageURIs#INSTRUCTOR_NOTIFICATIONS_PAGE}."},{"lineNumber":20,"author":{"gitId":"-"},"content":" */"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public class InstructorNotificationsPageE2ETest extends BaseE2ETestCase {"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":24,"author":{"gitId":"-"},"content":" protected void prepareTestData() {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" testData \u003d loadDataBundle(\"/InstructorNotificationsPageE2ETest.json\");"},{"lineNumber":26,"author":{"gitId":"-"},"content":" removeAndRestoreDataBundle(testData);"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" sqlTestData \u003d removeAndRestoreSqlDataBundle("},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" loadSqlDataBundle(\"/InstructorNotificationsPageE2ETest_SqlEntities.json\"));"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":32,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":33,"author":{"gitId":"-"},"content":" public void testAll() {"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" Account account \u003d sqlTestData.accounts.get(\"INotifs.instr\");"},{"lineNumber":35,"author":{"gitId":"-"},"content":" AppUrl notificationsPageUrl \u003d createFrontendUrl(Const.WebPageURIs.INSTRUCTOR_NOTIFICATIONS_PAGE);"},{"lineNumber":36,"author":{"gitId":"-"},"content":" InstructorNotificationsPage notificationsPage \u003d loginToPage(notificationsPageUrl, InstructorNotificationsPage.class,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" account.getGoogleId());"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" ______TS(\"verify that only active notifications with correct target user are shown\");"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" Notification[] notShownNotifications \u003d {"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" sqlTestData.notifications.get(\"notification2\"),"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" sqlTestData.notifications.get(\"expiredNotification1\"),"},{"lineNumber":43,"author":{"gitId":"-"},"content":" };"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" Notification[] shownNotifications \u003d {"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" sqlTestData.notifications.get(\"notification1\"),"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" sqlTestData.notifications.get(\"notification3\"),"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" sqlTestData.notifications.get(\"notification4\"),"},{"lineNumber":48,"author":{"gitId":"-"},"content":" };"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" Notification[] readNotifications \u003d {"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" sqlTestData.notifications.get(\"notification4\"),"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" Set\u003cString\u003e readNotificationsIds \u003d Stream.of(readNotifications)"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" .map(readNotification -\u003e readNotification.getId().toString())"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" .collect(Collectors.toSet());"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" notificationsPage.verifyNotShownNotifications(notShownNotifications);"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" notificationsPage.verifyShownNotifications(shownNotifications, readNotificationsIds);"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" ______TS(\"mark notification as read\");"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" Notification notificationToMarkAsRead \u003d sqlTestData.notifications.get(\"notification3\");"},{"lineNumber":63,"author":{"gitId":"-"},"content":" notificationsPage.markNotificationAsRead(notificationToMarkAsRead);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" notificationsPage.verifyStatusMessage(\"Notification marked as read.\");"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" // Verify that account\u0027s readNotifications attribute is updated"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" AccountData accountFromDb \u003d BACKDOOR.getAccountData(account.getGoogleId());"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" assertTrue(accountFromDb.getReadNotifications().containsKey(notificationToMarkAsRead.getId().toString()));"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" ______TS(\"notification banner is not visible\");"},{"lineNumber":71,"author":{"gitId":"-"},"content":" assertFalse(notificationsPage.isBannerVisible());"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public void classTeardown() {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" for (NotificationAttributes notification : testData.notifications.values()) {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" BACKDOOR.deleteNotification(notification.getNotificationId());"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }"},{"lineNumber":79,"author":{"gitId":"-"},"content":" }"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":28,"-":53}},{"path":"src/e2e/java/teammates/e2e/cases/InstructorSearchPageE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.InstructorCourseStudentDetailsEditPage;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.InstructorCourseStudentDetailsViewPage;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.InstructorSearchPage;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.InstructorStudentRecordsPage;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.e2e.util.TestProperties;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * SUT: {@link Const.WebPageURIs#INSTRUCTOR_SEARCH_PAGE}."},{"lineNumber":20,"author":{"gitId":"-"},"content":" */"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public class InstructorSearchPageE2ETest extends BaseE2ETestCase {"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":24,"author":{"gitId":"-"},"content":" protected void prepareTestData() {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":27,"author":{"gitId":"-"},"content":" }"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" sqlTestData \u003d removeAndRestoreSqlDataBundle("},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" loadSqlDataBundle(\"/InstructorSearchPageE2ETest_SqlEntities.json\"));"},{"lineNumber":30,"author":{"gitId":"-"},"content":" testData \u003d loadDataBundle(\"/InstructorSearchPageE2ETest.json\");"},{"lineNumber":31,"author":{"gitId":"-"},"content":" removeAndRestoreDataBundle(testData);"},{"lineNumber":32,"author":{"gitId":"-"},"content":" putDocuments(testData);"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":36,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":37,"author":{"gitId":"-"},"content":" public void testAll() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" String instructorId \u003d sqlTestData.accounts.get(\"instructor1OfCourse1\").getGoogleId();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" AppUrl searchPageUrl \u003d createFrontendUrl(Const.WebPageURIs.INSTRUCTOR_SEARCH_PAGE);"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" InstructorSearchPage searchPage \u003d loginToPage(searchPageUrl, InstructorSearchPage.class, instructorId);"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" ______TS(\"cannot click search button if no search term is entered\");"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" searchPage.search(\"\");"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" ______TS(\"search with no result\");"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" searchPage.search(\"thiswillnothitanything\");"},{"lineNumber":54,"author":{"gitId":"-"},"content":" searchPage.verifyStatusMessage(\"No results found.\");"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" ______TS(\"search for students\");"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" searchPage.search(\"student2\");"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" CourseAttributes course1 \u003d testData.courses.get(\"typicalCourse1\");"},{"lineNumber":61,"author":{"gitId":"-"},"content":" CourseAttributes course2 \u003d testData.courses.get(\"typicalCourse2\");"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" StudentAttributes[] studentsInCourse1 \u003d {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" testData.students.get(\"student2.2InCourse1\"),"},{"lineNumber":65,"author":{"gitId":"-"},"content":" testData.students.get(\"student2InCourse1\"),"},{"lineNumber":66,"author":{"gitId":"-"},"content":" };"},{"lineNumber":67,"author":{"gitId":"-"},"content":" StudentAttributes[] studentsInCourse2 \u003d {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" testData.students.get(\"student2.2InCourse2\"),"},{"lineNumber":69,"author":{"gitId":"-"},"content":" testData.students.get(\"student2InCourse2\"),"},{"lineNumber":70,"author":{"gitId":"-"},"content":" };"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" Map\u003cString, StudentAttributes[]\u003e courseIdToStudents \u003d new HashMap\u003c\u003e();"},{"lineNumber":73,"author":{"gitId":"-"},"content":" courseIdToStudents.put(course1.getId(), studentsInCourse1);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" courseIdToStudents.put(course2.getId(), studentsInCourse2);"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" Map\u003cString, CourseAttributes\u003e courseIdToCourse \u003d new HashMap\u003c\u003e();"},{"lineNumber":77,"author":{"gitId":"-"},"content":" courseIdToCourse.put(course1.getId(), course1);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" courseIdToCourse.put(course2.getId(), course2);"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" searchPage.verifyStudentDetails(courseIdToCourse, courseIdToStudents);"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" ______TS(\"link: view student details page\");"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" StudentAttributes studentToView \u003d testData.students.get(\"student2.2InCourse1\");"},{"lineNumber":85,"author":{"gitId":"-"},"content":" String studentEmail \u003d studentToView.getEmail();"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" InstructorCourseStudentDetailsViewPage studentDetailsViewPage \u003d"},{"lineNumber":88,"author":{"gitId":"-"},"content":" searchPage.clickViewStudent(course1, studentEmail);"},{"lineNumber":89,"author":{"gitId":"-"},"content":" studentDetailsViewPage.verifyIsCorrectPage(course1.getId(), studentEmail);"},{"lineNumber":90,"author":{"gitId":"-"},"content":" studentDetailsViewPage.closeCurrentWindowAndSwitchToParentWindow();"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" ______TS(\"link: edit student details page\");"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" InstructorCourseStudentDetailsEditPage studentDetailsEditPage \u003d"},{"lineNumber":95,"author":{"gitId":"-"},"content":" searchPage.clickEditStudent(course1, studentEmail);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" studentDetailsEditPage.verifyIsCorrectPage(course1.getId(), studentEmail);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" studentDetailsEditPage.closeCurrentWindowAndSwitchToParentWindow();"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" ______TS(\"link: view all records page\");"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" InstructorStudentRecordsPage studentRecordsPage \u003d"},{"lineNumber":102,"author":{"gitId":"-"},"content":" searchPage.clickViewAllRecords(course1, studentEmail);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" studentRecordsPage.verifyIsCorrectPage(course1.getId(), studentToView.getName());"},{"lineNumber":104,"author":{"gitId":"-"},"content":" studentRecordsPage.closeCurrentWindowAndSwitchToParentWindow();"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" ______TS(\"action: delete student\");"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" StudentAttributes studentToDelete \u003d testData.students.get(\"student2InCourse2\");"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" searchPage.deleteStudent(course2, studentToDelete.getEmail());"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" StudentAttributes[] studentsAfterDelete \u003d {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" testData.students.get(\"student2.2InCourse2\"),"},{"lineNumber":114,"author":{"gitId":"-"},"content":" };"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" searchPage.verifyStudentDetails(course2, studentsAfterDelete);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" verifyAbsentInDatabase(studentToDelete);"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" }"},{"lineNumber":120,"author":{"gitId":"-"},"content":""},{"lineNumber":121,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":3,"-":118}},{"path":"src/e2e/java/teammates/e2e/cases/NotificationBannerE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.NotificationAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.StudentHomePage;"},{"lineNumber":10,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":11,"author":{"gitId":"yuanxi1"},"content":"import teammates.ui.output.AccountData;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"-"},"content":" * SUT: The reusable notification banner, which can be displayed across many pages."},{"lineNumber":15,"author":{"gitId":"-"},"content":" * {@link Const.WebPageURIs#STUDENT_HOME_PAGE} is used to test the behaviour of the banner in this case,"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * {@link Const.WebPageURIs#STUDENT_NOTIFICATIONS_PAGE}"},{"lineNumber":17,"author":{"gitId":"-"},"content":" */"},{"lineNumber":18,"author":{"gitId":"-"},"content":"public class NotificationBannerE2ETest extends BaseE2ETestCase {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":20,"author":{"gitId":"-"},"content":" protected void prepareTestData() {"},{"lineNumber":21,"author":{"gitId":"-"},"content":" testData \u003d loadDataBundle(\"/NotificationBannerE2ETest.json\");"},{"lineNumber":22,"author":{"gitId":"-"},"content":" removeAndRestoreDataBundle(testData);"},{"lineNumber":23,"author":{"gitId":"yuanxi1"},"content":" sqlTestData \u003d removeAndRestoreSqlDataBundle("},{"lineNumber":24,"author":{"gitId":"yuanxi1"},"content":" loadSqlDataBundle(\"/NotificationBannerE2ETest_SqlEntities.json\"));"},{"lineNumber":25,"author":{"gitId":"-"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":28,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":29,"author":{"gitId":"-"},"content":" protected void testAll() {"},{"lineNumber":30,"author":{"gitId":"yuanxi1"},"content":" Account account \u003d sqlTestData.accounts.get(\"NotifBanner.student\");"},{"lineNumber":31,"author":{"gitId":"-"},"content":" AppUrl studentHomePageUrl \u003d createFrontendUrl(Const.WebPageURIs.STUDENT_HOME_PAGE);"},{"lineNumber":32,"author":{"gitId":"-"},"content":" StudentHomePage studentHomePage \u003d loginToPage(studentHomePageUrl, StudentHomePage.class,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" account.getGoogleId());"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" ______TS(\"verify active notification with correct information is shown\");"},{"lineNumber":36,"author":{"gitId":"-"},"content":" assertTrue(studentHomePage.isBannerVisible());"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" ______TS(\"close notification\");"},{"lineNumber":39,"author":{"gitId":"-"},"content":" // After user closes a notification banner, it should not appear till user refreshes page"},{"lineNumber":40,"author":{"gitId":"-"},"content":" studentHomePage.clickCloseNotificationBannerButton();"},{"lineNumber":41,"author":{"gitId":"-"},"content":" assertFalse(studentHomePage.isBannerVisible());"},{"lineNumber":42,"author":{"gitId":"-"},"content":" studentHomePage.reloadPage();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" assertTrue(studentHomePage.isBannerVisible());"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" ______TS(\"mark notification as read\");"},{"lineNumber":46,"author":{"gitId":"-"},"content":" studentHomePage.reloadPage();"},{"lineNumber":47,"author":{"gitId":"-"},"content":" assertTrue(studentHomePage.isBannerVisible());"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"yuanxi1"},"content":" String notificationId \u003d studentHomePage.getNotificationId();"},{"lineNumber":50,"author":{"gitId":"-"},"content":" studentHomePage.clickMarkAsReadButton();"},{"lineNumber":51,"author":{"gitId":"yuanxi1"},"content":" AccountData accountFromDb \u003d BACKDOOR.getAccountData(account.getGoogleId());"},{"lineNumber":52,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" studentHomePage.verifyStatusMessage(\"Notification marked as read.\");"},{"lineNumber":54,"author":{"gitId":"-"},"content":" assertFalse(studentHomePage.isBannerVisible());"},{"lineNumber":55,"author":{"gitId":"yuanxi1"},"content":" assertTrue(accountFromDb.getReadNotifications().containsKey(notificationId));"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":60,"author":{"gitId":"-"},"content":" public void classTeardown() {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" for (NotificationAttributes notification : testData.notifications.values()) {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" BACKDOOR.deleteNotification(notification.getNotificationId());"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"-"},"content":" }"},{"lineNumber":65,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"yuanxi1":9,"-":56}},{"path":"src/e2e/java/teammates/e2e/cases/axe/AdminSearchPageAxeTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases.axe;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import com.deque.html.axecore.results.Results;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.AdminSearchPage;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.e2e.util.TestProperties;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * SUT: {@link Const.WebPageURIs#ADMIN_SEARCH_PAGE}."},{"lineNumber":14,"author":{"gitId":"-"},"content":" */"},{"lineNumber":15,"author":{"gitId":"-"},"content":"public class AdminSearchPageAxeTest extends BaseAxeTestCase {"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":18,"author":{"gitId":"-"},"content":" protected void prepareTestData() {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" }"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" testData \u003d loadDataBundle(\"/AdminSearchPageE2ETest.json\");"},{"lineNumber":24,"author":{"gitId":"-"},"content":" removeAndRestoreDataBundle(testData);"},{"lineNumber":25,"author":{"gitId":"-"},"content":" putDocuments(testData);"},{"lineNumber":26,"author":{"gitId":"-"},"content":" sqlTestData \u003d loadSqlDataBundle(\"/AdminSearchPageE2ETest_SqlEntities.json\");"},{"lineNumber":27,"author":{"gitId":"-"},"content":" removeAndRestoreSqlDataBundle(sqlTestData);"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" putSqlDocuments(sqlTestData);"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":32,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":33,"author":{"gitId":"-"},"content":" public void testAll() {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" }"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" AppUrl url \u003d createFrontendUrl(Const.WebPageURIs.ADMIN_SEARCH_PAGE);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" AdminSearchPage searchPage \u003d loginAdminToPage(url, AdminSearchPage.class);"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(testData.students.get(\"student1InCourse1\").getEmail());"},{"lineNumber":42,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" Results results \u003d getAxeBuilder().analyze(searchPage.getBrowser().getDriver());"},{"lineNumber":45,"author":{"gitId":"-"},"content":" assertTrue(formatViolations(results), results.violationFree());"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":1,"-":47}},{"path":"src/e2e/java/teammates/e2e/cases/axe/InstructorSearchPageAxeTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases.axe;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import com.deque.html.axecore.results.Results;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.InstructorSearchPage;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.e2e.util.TestProperties;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * SUT: {@link Const.WebPageURIs#INSTRUCTOR_SEARCH_PAGE}."},{"lineNumber":14,"author":{"gitId":"-"},"content":" */"},{"lineNumber":15,"author":{"gitId":"-"},"content":"public class InstructorSearchPageAxeTest extends BaseAxeTestCase {"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":18,"author":{"gitId":"-"},"content":" protected void prepareTestData() {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" }"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" sqlTestData \u003d loadSqlDataBundle(\"/InstructorSearchPageE2ETest_SqlEntities.json\");"},{"lineNumber":24,"author":{"gitId":"-"},"content":" testData \u003d loadDataBundle(\"/InstructorSearchPageE2ETest.json\");"},{"lineNumber":25,"author":{"gitId":"-"},"content":" removeAndRestoreDataBundle(testData);"},{"lineNumber":26,"author":{"gitId":"-"},"content":" putDocuments(testData);"},{"lineNumber":27,"author":{"gitId":"-"},"content":" }"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":30,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":31,"author":{"gitId":"-"},"content":" public void testAll() {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" AppUrl searchPageUrl \u003d createFrontendUrl(Const.WebPageURIs.INSTRUCTOR_SEARCH_PAGE);"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" InstructorSearchPage searchPage \u003d loginToPage(searchPageUrl, InstructorSearchPage.class,"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" sqlTestData.accounts.get(\"instructor1OfCourse1\").getGoogleId());"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" searchPage.search(\"student2\");"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" Results results \u003d getAxeBuilder().analyze(searchPage.getBrowser().getDriver());"},{"lineNumber":44,"author":{"gitId":"-"},"content":" assertTrue(formatViolations(results), results.violationFree());"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":2,"-":45}},{"path":"src/e2e/java/teammates/e2e/cases/sql/AdminHomePageE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.e2e.cases.sql;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.Test;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.Const;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import teammates.e2e.pageobjects.AdminHomePage;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" * SUT: {@link Const.WebPageURIs#ADMIN_HOME_PAGE}."},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"public class AdminHomePageE2ETest extends BaseE2ETestCase {"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" protected void prepareTestData() {"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" // not needed"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" public void testAll() {"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" AppUrl url \u003d createFrontendUrl(Const.WebPageURIs.ADMIN_HOME_PAGE);"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" AdminHomePage homePage \u003d loginAdminToPage(url, AdminHomePage.class);"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Test adding instructors with both valid and invalid details\");"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" String name \u003d \"AHPUiT Instrúctör WithPlusInEmail\";"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" String email \u003d \"AHPUiT+++_.instr1!@gmail.tmt\";"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" String institute \u003d \"TEAMMATES Test Institute 1\";"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" homePage.queueInstructorForAdding(name, email, institute);"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" String singleLineDetails \u003d \"Instructor With Invalid Email | invalidemail | TEAMMATES Test Institute 1\";"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" homePage.queueInstructorForAdding(singleLineDetails);"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" homePage.addAllInstructors();"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" String successMessage \u003d homePage.getMessageForInstructor(0);"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" assertTrue(successMessage.contains("},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" \"Instructor \\\"AHPUiT Instrúctör WithPlusInEmail\\\" has been successfully created\"));"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" String failureMessage \u003d homePage.getMessageForInstructor(1);"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" assertTrue(failureMessage.contains("},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" \"\\\"invalidemail\\\" is not acceptable to TEAMMATES as a/an email because it is not in the correct format.\"));"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" homePage.reloadPage();"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Verify that newly added instructor appears in account request table\");"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" homePage.verifyInstructorInAccountRequestTable(name, email, institute);"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":55}},{"path":"src/e2e/java/teammates/e2e/cases/sql/AdminSearchPageE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases.sql;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.StringHelperExtension;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.AdminSearchPage;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.e2e.util.TestProperties;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * SUT: {@link Const.WebPageURIs#ADMIN_SEARCH_PAGE}."},{"lineNumber":23,"author":{"gitId":"-"},"content":" */"},{"lineNumber":24,"author":{"gitId":"-"},"content":"public class AdminSearchPageE2ETest extends BaseE2ETestCase {"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":27,"author":{"gitId":"-"},"content":" protected void prepareTestData() {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":" testData \u003d removeAndRestoreDataBundle(loadSqlDataBundle(\"/AdminSearchPageE2ESqlTest.json\"));"},{"lineNumber":32,"author":{"gitId":"-"},"content":" putDocuments(testData);"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":36,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":37,"author":{"gitId":"-"},"content":" public void testAll() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" AppUrl url \u003d createFrontendUrl(Const.WebPageURIs.ADMIN_SEARCH_PAGE);"},{"lineNumber":43,"author":{"gitId":"-"},"content":" AdminSearchPage searchPage \u003d loginAdminToPage(url, AdminSearchPage.class);"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" Course course \u003d testData.courses.get(\"typicalCourse1\");"},{"lineNumber":46,"author":{"gitId":"-"},"content":" Student student \u003d testData.students.get(\"student1InCourse1\");"},{"lineNumber":47,"author":{"gitId":"-"},"content":" Instructor instructor \u003d testData.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":48,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d testData.accountRequests.get(\"instructor1OfCourse1\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Search student email\");"},{"lineNumber":51,"author":{"gitId":"-"},"content":" String searchContent \u003d student.getEmail();"},{"lineNumber":52,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":54,"author":{"gitId":"-"},"content":" String studentDetails \u003d getExpectedStudentDetails(student);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" String studentManageAccountLink \u003d getExpectedStudentManageAccountLink(student);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" String studentHomePageLink \u003d getExpectedStudentHomePageLink(student);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" int numExpandedRows \u003d getExpectedNumExpandedRows(student);"},{"lineNumber":58,"author":{"gitId":"-"},"content":" searchPage.verifyStudentRowContent(student, course, studentDetails, studentManageAccountLink,"},{"lineNumber":59,"author":{"gitId":"-"},"content":" studentHomePageLink);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" searchPage.verifyStudentExpandedLinks(student, numExpandedRows);"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Reset student google id\");"},{"lineNumber":63,"author":{"gitId":"-"},"content":" searchPage.resetStudentGoogleId(student);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" student.setGoogleId(null);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" searchPage.verifyStudentRowContentAfterReset(student, course);"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Regenerate registration key for a course student\");"},{"lineNumber":68,"author":{"gitId":"-"},"content":" searchPage.clickExpandStudentLinks();"},{"lineNumber":69,"author":{"gitId":"-"},"content":" String originalJoinLink \u003d searchPage.getStudentJoinLink(student);"},{"lineNumber":70,"author":{"gitId":"-"},"content":" searchPage.regenerateStudentKey(student);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" searchPage.verifyRegenerateStudentKey(student, originalJoinLink);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" searchPage.waitForPageToLoad();"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Search for instructor email\");"},{"lineNumber":75,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":76,"author":{"gitId":"-"},"content":" searchContent \u003d instructor.getEmail();"},{"lineNumber":77,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":79,"author":{"gitId":"-"},"content":" String instructorManageAccountLink \u003d getExpectedInstructorManageAccountLink(instructor);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" String instructorHomePageLink \u003d getExpectedInstructorHomePageLink(instructor);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" searchPage.verifyInstructorRowContent(instructor, course, instructorManageAccountLink,"},{"lineNumber":82,"author":{"gitId":"-"},"content":" instructorHomePageLink);"},{"lineNumber":83,"author":{"gitId":"-"},"content":" searchPage.verifyInstructorExpandedLinks(instructor);"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Reset instructor google id\");"},{"lineNumber":86,"author":{"gitId":"-"},"content":" searchPage.resetInstructorGoogleId(instructor);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" searchPage.verifyInstructorRowContentAfterReset(instructor, course);"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Regenerate registration key for an instructor\");"},{"lineNumber":90,"author":{"gitId":"-"},"content":" searchPage.clickExpandInstructorLinks();"},{"lineNumber":91,"author":{"gitId":"-"},"content":" originalJoinLink \u003d searchPage.getInstructorJoinLink(instructor);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" searchPage.regenerateInstructorKey(instructor);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" searchPage.verifyRegenerateInstructorKey(instructor, originalJoinLink);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" searchPage.waitForPageToLoad();"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Search for account request by email\");"},{"lineNumber":97,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":98,"author":{"gitId":"-"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":99,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":101,"author":{"gitId":"-"},"content":" searchPage.verifyAccountRequestRowContent(accountRequest);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" searchPage.verifyAccountRequestExpandedLinks(accountRequest);"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Search common search key\");"},{"lineNumber":105,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":106,"author":{"gitId":"-"},"content":" searchContent \u003d \"Course1\";"},{"lineNumber":107,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":109,"author":{"gitId":"-"},"content":" searchPage.verifyStudentRowContentAfterReset(student, course);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" searchPage.verifyInstructorRowContentAfterReset(instructor, course);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" searchPage.verifyAccountRequestRowContent(accountRequest);"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Expand and collapse links\");"},{"lineNumber":114,"author":{"gitId":"-"},"content":" searchPage.verifyLinkExpansionButtons(student, instructor, accountRequest);"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Reset account request successful\");"},{"lineNumber":117,"author":{"gitId":"-"},"content":" searchContent \u003d \"ASearch.instructor1@gmail.tmt\";"},{"lineNumber":118,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":119,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":121,"author":{"gitId":"-"},"content":" searchPage.clickResetAccountRequestButton(accountRequest);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" assertNull(BACKDOOR.getAccountRequest(accountRequest.getId()).getRegisteredAt());"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Delete account request successful\");"},{"lineNumber":125,"author":{"gitId":"-"},"content":" accountRequest \u003d testData.accountRequests.get(\"unregisteredInstructor1\");"},{"lineNumber":126,"author":{"gitId":"-"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":127,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":128,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":129,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":130,"author":{"gitId":"-"},"content":" searchPage.clickDeleteAccountRequestButton(accountRequest);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" assertNull(BACKDOOR.getAccountRequest(accountRequest.getId()));"},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Typical case: Edit account request successful\");"},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d testData.accountRequests.get(\"unregisteredInstructor2\");"},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" searchPage.clearSearchBox();"},{"lineNumber":137,"author":{"gitId":"domoberzin"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSearchButton();"},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":" searchPage.clickEditAccountRequestButton(accountRequest);"},{"lineNumber":140,"author":{"gitId":"domoberzin"},"content":" searchPage.fillInEditModalFields(\"Different name\", accountRequest.getEmail(),"},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":" accountRequest.getInstitute(), \"New comment\");"},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSaveEditAccountRequestButton();"},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":" accountRequest.setName(\"Different name\");"},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":" accountRequest.setComments(\"New comment\");"},{"lineNumber":145,"author":{"gitId":"domoberzin"},"content":" searchPage.verifyAccountRequestRowContent(accountRequest);"},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":147,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Typical case: View comment of account request\");"},{"lineNumber":148,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d testData.accountRequests.get(\"unregisteredInstructor2\");"},{"lineNumber":149,"author":{"gitId":"domoberzin"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":150,"author":{"gitId":"domoberzin"},"content":" searchPage.clearSearchBox();"},{"lineNumber":151,"author":{"gitId":"domoberzin"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":152,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSearchButton();"},{"lineNumber":153,"author":{"gitId":"domoberzin"},"content":" searchPage.clickViewAccountRequestAndVerifyCommentsButton(accountRequest, \"New comment\");"},{"lineNumber":154,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":155,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Edit account request with invalid details\");"},{"lineNumber":156,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d testData.accountRequests.get(\"unregisteredInstructor2\");"},{"lineNumber":157,"author":{"gitId":"domoberzin"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":158,"author":{"gitId":"domoberzin"},"content":" searchPage.clearSearchBox();"},{"lineNumber":159,"author":{"gitId":"domoberzin"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":160,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSearchButton();"},{"lineNumber":161,"author":{"gitId":"domoberzin"},"content":" searchPage.clickEditAccountRequestButton(accountRequest);"},{"lineNumber":162,"author":{"gitId":"domoberzin"},"content":" searchPage.fillInEditModalFields(accountRequest.getName(), \"invalid\","},{"lineNumber":163,"author":{"gitId":"domoberzin"},"content":" accountRequest.getInstitute(), \"New comment\");"},{"lineNumber":164,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSaveEditAccountRequestButton();"},{"lineNumber":165,"author":{"gitId":"domoberzin"},"content":" String formattedErrorMessage \u003d String.format(\"\\\"%s\\\" is not acceptable to TEAMMATES as a/an %s because it %s. \""},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":" + \"An email address contains some text followed by one \u0027@\u0027 sign followed by some more text, \""},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" + \"and should end with a top level domain address like .com. It cannot be longer than %d characters, \""},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":" + \"cannot be empty and cannot contain spaces.\","},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" \"invalid\", FieldValidator.EMAIL_FIELD_NAME, FieldValidator.REASON_INCORRECT_FORMAT,"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" FieldValidator.EMAIL_MAX_LENGTH);"},{"lineNumber":171,"author":{"gitId":"domoberzin"},"content":" searchPage.verifyStatusMessage(formattedErrorMessage);"},{"lineNumber":172,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":" String name \u003d StringHelperExtension.generateStringOfLength(FieldValidator.PERSON_NAME_MAX_LENGTH + 1);"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" searchPage.clickEditAccountRequestButton(accountRequest);"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":" searchPage.fillInEditModalFields(name, accountRequest.getEmail(), accountRequest.getInstitute(), \"New comment\");"},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSaveEditAccountRequestButton();"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":" formattedErrorMessage \u003d String.format(\"\\\"%s\\\" is not acceptable to TEAMMATES as a/an %s because it %s. \""},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" + \"The value of a/an %s should be no longer than %d characters. It should not be empty.\","},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" name, FieldValidator.PERSON_NAME_FIELD_NAME, FieldValidator.REASON_TOO_LONG,"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":" FieldValidator.PERSON_NAME_FIELD_NAME, FieldValidator.PERSON_NAME_MAX_LENGTH);"},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":" searchPage.verifyStatusMessage(formattedErrorMessage);"},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":184,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Typical case: Approve account request successful\");"},{"lineNumber":185,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d testData.accountRequests.get(\"unregisteredInstructor2\");"},{"lineNumber":186,"author":{"gitId":"domoberzin"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":187,"author":{"gitId":"domoberzin"},"content":" searchPage.clearSearchBox();"},{"lineNumber":188,"author":{"gitId":"domoberzin"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":189,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSearchButton();"},{"lineNumber":190,"author":{"gitId":"domoberzin"},"content":" searchPage.clickApproveAccountRequestButton(accountRequest);"},{"lineNumber":191,"author":{"gitId":"domoberzin"},"content":" accountRequest.setStatus(AccountRequestStatus.APPROVED);"},{"lineNumber":192,"author":{"gitId":"domoberzin"},"content":" searchPage.verifyAccountRequestRowContent(accountRequest);"},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Typical case: Reject account request successfully\");"},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d testData.accountRequests.get(\"unregisteredInstructor3\");"},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":" searchPage.clearSearchBox();"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSearchButton();"},{"lineNumber":200,"author":{"gitId":"domoberzin"},"content":" searchPage.clickRejectAccountRequestButton(accountRequest);"},{"lineNumber":201,"author":{"gitId":"domoberzin"},"content":" accountRequest.setStatus(AccountRequestStatus.REJECTED);"},{"lineNumber":202,"author":{"gitId":"domoberzin"},"content":" searchPage.verifyAccountRequestRowContent(accountRequest);"},{"lineNumber":203,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":204,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Reject account request with empty body\");"},{"lineNumber":205,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d testData.accountRequests.get(\"unregisteredInstructor5\");"},{"lineNumber":206,"author":{"gitId":"domoberzin"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":207,"author":{"gitId":"domoberzin"},"content":" searchPage.clearSearchBox();"},{"lineNumber":208,"author":{"gitId":"domoberzin"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":209,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSearchButton();"},{"lineNumber":210,"author":{"gitId":"domoberzin"},"content":" searchPage.clickRejectAccountRequestWithReasonButton(accountRequest);"},{"lineNumber":211,"author":{"gitId":"domoberzin"},"content":" searchPage.fillInRejectionModalBody(\"\");"},{"lineNumber":212,"author":{"gitId":"domoberzin"},"content":" searchPage.clickConfirmRejectAccountRequest();"},{"lineNumber":213,"author":{"gitId":"domoberzin"},"content":" searchPage.verifyStatusMessage(\"Please provide an email body for the rejection email.\");"},{"lineNumber":214,"author":{"gitId":"domoberzin"},"content":" searchPage.closeRejectionModal();"},{"lineNumber":215,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":216,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Typical case: Reject account request with reason successfully\");"},{"lineNumber":217,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d testData.accountRequests.get(\"unregisteredInstructor4\");"},{"lineNumber":218,"author":{"gitId":"domoberzin"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":219,"author":{"gitId":"domoberzin"},"content":" searchPage.clearSearchBox();"},{"lineNumber":220,"author":{"gitId":"domoberzin"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":221,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSearchButton();"},{"lineNumber":222,"author":{"gitId":"domoberzin"},"content":" searchPage.clickRejectAccountRequestWithReasonButton(accountRequest);"},{"lineNumber":223,"author":{"gitId":"domoberzin"},"content":" accountRequest.setStatus(AccountRequestStatus.REJECTED);"},{"lineNumber":224,"author":{"gitId":"domoberzin"},"content":" searchPage.verifyAccountRequestRowContent(accountRequest);"},{"lineNumber":225,"author":{"gitId":"-"},"content":" }"},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"-"},"content":" private String getExpectedStudentDetails(Student student) {"},{"lineNumber":228,"author":{"gitId":"-"},"content":" return String.format(\"%s [%s] (%s)\", student.getCourse().getId(),"},{"lineNumber":229,"author":{"gitId":"-"},"content":" student.getSection() \u003d\u003d null"},{"lineNumber":230,"author":{"gitId":"-"},"content":" ? Const.DEFAULT_SECTION"},{"lineNumber":231,"author":{"gitId":"-"},"content":" : student.getSection().getName(),"},{"lineNumber":232,"author":{"gitId":"-"},"content":" student.getTeam().getName());"},{"lineNumber":233,"author":{"gitId":"-"},"content":" }"},{"lineNumber":234,"author":{"gitId":"-"},"content":""},{"lineNumber":235,"author":{"gitId":"-"},"content":" private String getExpectedStudentHomePageLink(Student student) {"},{"lineNumber":236,"author":{"gitId":"-"},"content":" return student.isRegistered() ? createFrontendUrl(Const.WebPageURIs.STUDENT_HOME_PAGE)"},{"lineNumber":237,"author":{"gitId":"-"},"content":" .withUserId(student.getGoogleId())"},{"lineNumber":238,"author":{"gitId":"-"},"content":" .toAbsoluteString()"},{"lineNumber":239,"author":{"gitId":"-"},"content":" : \"\";"},{"lineNumber":240,"author":{"gitId":"-"},"content":" }"},{"lineNumber":241,"author":{"gitId":"-"},"content":""},{"lineNumber":242,"author":{"gitId":"-"},"content":" private String getExpectedStudentManageAccountLink(Student student) {"},{"lineNumber":243,"author":{"gitId":"-"},"content":" return student.isRegistered() ? createFrontendUrl(Const.WebPageURIs.ADMIN_ACCOUNTS_PAGE)"},{"lineNumber":244,"author":{"gitId":"-"},"content":" .withParam(Const.ParamsNames.INSTRUCTOR_ID, student.getGoogleId())"},{"lineNumber":245,"author":{"gitId":"-"},"content":" .toAbsoluteString()"},{"lineNumber":246,"author":{"gitId":"-"},"content":" : \"\";"},{"lineNumber":247,"author":{"gitId":"-"},"content":" }"},{"lineNumber":248,"author":{"gitId":"-"},"content":""},{"lineNumber":249,"author":{"gitId":"-"},"content":" private int getExpectedNumExpandedRows(Student student) {"},{"lineNumber":250,"author":{"gitId":"-"},"content":" int expectedNumExpandedRows \u003d 2;"},{"lineNumber":251,"author":{"gitId":"-"},"content":" for (FeedbackSession sessions : testData.feedbackSessions.values()) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" if (sessions.getCourse().equals(student.getCourse())) {"},{"lineNumber":253,"author":{"gitId":"-"},"content":" expectedNumExpandedRows +\u003d 1;"},{"lineNumber":254,"author":{"gitId":"-"},"content":" if (sessions.getResultsVisibleFromTime().isBefore(Instant.now())) {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" expectedNumExpandedRows +\u003d 1;"},{"lineNumber":256,"author":{"gitId":"-"},"content":" }"},{"lineNumber":257,"author":{"gitId":"-"},"content":" }"},{"lineNumber":258,"author":{"gitId":"-"},"content":" }"},{"lineNumber":259,"author":{"gitId":"-"},"content":" return expectedNumExpandedRows;"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":""},{"lineNumber":262,"author":{"gitId":"-"},"content":" private String getExpectedInstructorHomePageLink(Instructor instructor) {"},{"lineNumber":263,"author":{"gitId":"-"},"content":" String googleId \u003d instructor.isRegistered() ? instructor.getGoogleId() : \"\";"},{"lineNumber":264,"author":{"gitId":"-"},"content":" return createFrontendUrl(Const.WebPageURIs.INSTRUCTOR_HOME_PAGE)"},{"lineNumber":265,"author":{"gitId":"-"},"content":" .withUserId(googleId)"},{"lineNumber":266,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":267,"author":{"gitId":"-"},"content":" }"},{"lineNumber":268,"author":{"gitId":"-"},"content":""},{"lineNumber":269,"author":{"gitId":"-"},"content":" private String getExpectedInstructorManageAccountLink(Instructor instructor) {"},{"lineNumber":270,"author":{"gitId":"-"},"content":" String googleId \u003d instructor.isRegistered() ? instructor.getGoogleId() : \"\";"},{"lineNumber":271,"author":{"gitId":"-"},"content":" return createFrontendUrl(Const.WebPageURIs.ADMIN_ACCOUNTS_PAGE)"},{"lineNumber":272,"author":{"gitId":"-"},"content":" .withParam(Const.ParamsNames.INSTRUCTOR_ID, googleId)"},{"lineNumber":273,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":277,"author":{"gitId":"-"},"content":" public void classTeardown() {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" for (AccountRequest request : testData.accountRequests.values()) {"},{"lineNumber":279,"author":{"gitId":"-"},"content":" BACKDOOR.deleteAccountRequest(request.getId());"},{"lineNumber":280,"author":{"gitId":"-"},"content":" }"},{"lineNumber":281,"author":{"gitId":"-"},"content":" }"},{"lineNumber":282,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":96,"-":186}},{"path":"src/e2e/java/teammates/e2e/cases/sql/BaseE2ETestCase.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases.sql;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.io.IOException;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.nio.file.Files;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.nio.file.Paths;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.ITestContext;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.exception.HttpRequestFailedException;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.AppPage;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.Browser;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.DevServerLoginPage;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.HomePage;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.e2e.util.BackDoor;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.e2e.util.EmailAccount;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.e2e.util.TestProperties;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.test.FileHelper;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.test.ThreadHelper;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackQuestionData;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackResponseData;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionData;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionPublishStatus;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.ui.output.StudentData;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":37,"author":{"gitId":"-"},"content":" * Base class for all browser tests."},{"lineNumber":38,"author":{"gitId":"-"},"content":" *"},{"lineNumber":39,"author":{"gitId":"-"},"content":" * \u003cp\u003eThis type of test has no knowledge of the workings of the application,"},{"lineNumber":40,"author":{"gitId":"-"},"content":" * and can only communicate via the UI or via {@link BackDoor} to obtain/transmit data."},{"lineNumber":41,"author":{"gitId":"-"},"content":" */"},{"lineNumber":42,"author":{"gitId":"-"},"content":"public abstract class BaseE2ETestCase extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":45,"author":{"gitId":"-"},"content":" * Backdoor used to call APIs."},{"lineNumber":46,"author":{"gitId":"-"},"content":" */"},{"lineNumber":47,"author":{"gitId":"-"},"content":" protected static final BackDoor BACKDOOR \u003d BackDoor.getInstance();"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":50,"author":{"gitId":"-"},"content":" * DataBundle used in tests."},{"lineNumber":51,"author":{"gitId":"-"},"content":" */"},{"lineNumber":52,"author":{"gitId":"-"},"content":" protected SqlDataBundle testData;"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" private Browser browser;"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" @BeforeClass"},{"lineNumber":57,"author":{"gitId":"-"},"content":" public void baseClassSetup() {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" prepareTestData();"},{"lineNumber":59,"author":{"gitId":"-"},"content":" prepareBrowser();"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":63,"author":{"gitId":"-"},"content":" * Prepares the browser used for the current test."},{"lineNumber":64,"author":{"gitId":"-"},"content":" */"},{"lineNumber":65,"author":{"gitId":"-"},"content":" protected void prepareBrowser() {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" browser \u003d new Browser();"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":70,"author":{"gitId":"-"},"content":" * Prepares the test data used for the current test."},{"lineNumber":71,"author":{"gitId":"-"},"content":" */"},{"lineNumber":72,"author":{"gitId":"-"},"content":" protected abstract void prepareTestData();"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":75,"author":{"gitId":"-"},"content":" * Contains all the tests for the page."},{"lineNumber":76,"author":{"gitId":"-"},"content":" *"},{"lineNumber":77,"author":{"gitId":"-"},"content":" * \u003cp\u003eThis approach is chosen so that setup and teardown are only needed once per test page,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" * thereby saving time. While it necessitates failed tests to be restarted from the beginning,"},{"lineNumber":79,"author":{"gitId":"-"},"content":" * test failures are rare and thus not causing significant overhead."},{"lineNumber":80,"author":{"gitId":"-"},"content":" */"},{"lineNumber":81,"author":{"gitId":"-"},"content":" protected abstract void testAll();"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":84,"author":{"gitId":"-"},"content":" protected String getTestDataFolder() {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" return TestProperties.TEST_DATA_FOLDER;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" }"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":89,"author":{"gitId":"-"},"content":" public void baseClassTearDown(ITestContext context) {"},{"lineNumber":90,"author":{"gitId":"-"},"content":" if (browser \u003d\u003d null) {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":" boolean isSuccess \u003d context.getFailedTests().getAllMethods()"},{"lineNumber":94,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":95,"author":{"gitId":"-"},"content":" .noneMatch(method -\u003e method.getConstructorOrMethod().getMethod().getDeclaringClass() \u003d\u003d this.getClass());"},{"lineNumber":96,"author":{"gitId":"-"},"content":" if (isSuccess || TestProperties.CLOSE_BROWSER_ON_FAILURE) {"},{"lineNumber":97,"author":{"gitId":"-"},"content":" browser.close();"},{"lineNumber":98,"author":{"gitId":"-"},"content":" }"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":102,"author":{"gitId":"-"},"content":" * Creates an {@link AppUrl} for the supplied {@code relativeUrl} parameter."},{"lineNumber":103,"author":{"gitId":"-"},"content":" * The base URL will be the value of test.app.frontend.url in test.properties."},{"lineNumber":104,"author":{"gitId":"-"},"content":" * {@code relativeUrl} must start with a \"/\"."},{"lineNumber":105,"author":{"gitId":"-"},"content":" */"},{"lineNumber":106,"author":{"gitId":"-"},"content":" protected static AppUrl createFrontendUrl(String relativeUrl) {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" return new AppUrl(TestProperties.TEAMMATES_FRONTEND_URL + relativeUrl);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":111,"author":{"gitId":"-"},"content":" * Creates an {@link AppUrl} for the supplied {@code relativeUrl} parameter."},{"lineNumber":112,"author":{"gitId":"-"},"content":" * The base URL will be the value of test.app.backend.url in test.properties."},{"lineNumber":113,"author":{"gitId":"-"},"content":" * {@code relativeUrl} must start with a \"/\"."},{"lineNumber":114,"author":{"gitId":"-"},"content":" */"},{"lineNumber":115,"author":{"gitId":"-"},"content":" protected static AppUrl createBackendUrl(String relativeUrl) {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" return new AppUrl(TestProperties.TEAMMATES_BACKEND_URL + relativeUrl);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" }"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":120,"author":{"gitId":"-"},"content":" * Logs in to a page using the given credentials."},{"lineNumber":121,"author":{"gitId":"-"},"content":" */"},{"lineNumber":122,"author":{"gitId":"-"},"content":" protected \u003cT extends AppPage\u003e T loginToPage(AppUrl url, Class\u003cT\u003e typeOfPage, String userId) {"},{"lineNumber":123,"author":{"gitId":"-"},"content":" // When not using dev server, Google blocks log in by automation."},{"lineNumber":124,"author":{"gitId":"-"},"content":" // To work around that, we inject the user cookie directly into the browser session."},{"lineNumber":125,"author":{"gitId":"-"},"content":" if (!TestProperties.isDevServer()) {"},{"lineNumber":126,"author":{"gitId":"-"},"content":" // In order for the cookie injection to work, we need to be in the domain."},{"lineNumber":127,"author":{"gitId":"-"},"content":" // Use the home page to minimize the page load time."},{"lineNumber":128,"author":{"gitId":"-"},"content":" browser.goToUrl(TestProperties.TEAMMATES_FRONTEND_URL);"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" String cookieValue \u003d BACKDOOR.getUserCookie(userId);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" browser.addCookie(Const.SecurityConfig.AUTH_COOKIE_NAME, cookieValue, true, true);"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" return getNewPageInstance(url, typeOfPage);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" }"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" // This will be redirected to the dev server login page."},{"lineNumber":137,"author":{"gitId":"-"},"content":" browser.goToUrl(url.toAbsoluteString());"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" DevServerLoginPage loginPage \u003d AppPage.getNewPageInstance(browser, DevServerLoginPage.class);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" loginPage.loginAsUser(userId);"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" return getNewPageInstance(url, typeOfPage);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" }"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":146,"author":{"gitId":"-"},"content":" * Logs in to a page using admin credentials."},{"lineNumber":147,"author":{"gitId":"-"},"content":" */"},{"lineNumber":148,"author":{"gitId":"-"},"content":" protected \u003cT extends AppPage\u003e T loginAdminToPage(AppUrl url, Class\u003cT\u003e typeOfPage) {"},{"lineNumber":149,"author":{"gitId":"-"},"content":" return loginToPage(url, typeOfPage, TestProperties.TEST_ADMIN);"},{"lineNumber":150,"author":{"gitId":"-"},"content":" }"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":153,"author":{"gitId":"-"},"content":" * Equivalent to clicking the \u0027logout\u0027 link in the top menu of the page."},{"lineNumber":154,"author":{"gitId":"-"},"content":" */"},{"lineNumber":155,"author":{"gitId":"-"},"content":" protected void logout() {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" AppUrl url \u003d createBackendUrl(Const.WebPageURIs.LOGOUT);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" if (!TestProperties.TEAMMATES_FRONTEND_URL.equals(TestProperties.TEAMMATES_BACKEND_URL)) {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" url \u003d url.withParam(\"frontendUrl\", TestProperties.TEAMMATES_FRONTEND_URL);"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" browser.goToUrl(url.toAbsoluteString());"},{"lineNumber":162,"author":{"gitId":"-"},"content":" AppPage.getNewPageInstance(browser, HomePage.class).waitForPageToLoad();"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":166,"author":{"gitId":"-"},"content":" * Deletes file with fileName from the downloads folder."},{"lineNumber":167,"author":{"gitId":"-"},"content":" */"},{"lineNumber":168,"author":{"gitId":"-"},"content":" protected void deleteDownloadsFile(String fileName) {"},{"lineNumber":169,"author":{"gitId":"-"},"content":" String filePath \u003d TestProperties.TEST_DOWNLOADS_FOLDER + fileName;"},{"lineNumber":170,"author":{"gitId":"-"},"content":" FileHelper.deleteFile(filePath);"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":174,"author":{"gitId":"-"},"content":" * Verifies downloaded file has correct fileName and contains expected content."},{"lineNumber":175,"author":{"gitId":"-"},"content":" */"},{"lineNumber":176,"author":{"gitId":"-"},"content":" protected void verifyDownloadedFile(String expectedFileName, List\u003cString\u003e expectedContent) {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" String filePath \u003d TestProperties.TEST_DOWNLOADS_FOLDER + expectedFileName;"},{"lineNumber":178,"author":{"gitId":"-"},"content":" int retryLimit \u003d TestProperties.TEST_TIMEOUT;"},{"lineNumber":179,"author":{"gitId":"-"},"content":" boolean actual \u003d Files.exists(Paths.get(filePath));"},{"lineNumber":180,"author":{"gitId":"-"},"content":" while (!actual \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":181,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":182,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(1000);"},{"lineNumber":183,"author":{"gitId":"-"},"content":" actual \u003d Files.exists(Paths.get(filePath));"},{"lineNumber":184,"author":{"gitId":"-"},"content":" }"},{"lineNumber":185,"author":{"gitId":"-"},"content":" assertTrue(actual);"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" String actualContent \u003d FileHelper.readFile(filePath);"},{"lineNumber":189,"author":{"gitId":"-"},"content":" for (String content : expectedContent) {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" assertTrue(actualContent.contains(content));"},{"lineNumber":191,"author":{"gitId":"-"},"content":" }"},{"lineNumber":192,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":193,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":194,"author":{"gitId":"-"},"content":" }"},{"lineNumber":195,"author":{"gitId":"-"},"content":" }"},{"lineNumber":196,"author":{"gitId":"-"},"content":""},{"lineNumber":197,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":198,"author":{"gitId":"-"},"content":" * Visits the URL and gets the page object representation of the visited web page in the browser."},{"lineNumber":199,"author":{"gitId":"-"},"content":" */"},{"lineNumber":200,"author":{"gitId":"-"},"content":" protected \u003cT extends AppPage\u003e T getNewPageInstance(AppUrl url, Class\u003cT\u003e typeOfPage) {"},{"lineNumber":201,"author":{"gitId":"-"},"content":" browser.goToUrl(url.toAbsoluteString());"},{"lineNumber":202,"author":{"gitId":"-"},"content":" return AppPage.getNewPageInstance(browser, typeOfPage);"},{"lineNumber":203,"author":{"gitId":"-"},"content":" }"},{"lineNumber":204,"author":{"gitId":"-"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":206,"author":{"gitId":"-"},"content":" * Verifies that email with subject is found in inbox."},{"lineNumber":207,"author":{"gitId":"-"},"content":" * Email used must be an authentic gmail account."},{"lineNumber":208,"author":{"gitId":"-"},"content":" */"},{"lineNumber":209,"author":{"gitId":"-"},"content":" protected void verifyEmailSent(String email, String subject) {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" if (TestProperties.isDevServer() || !TestProperties.INCLUDE_EMAIL_VERIFICATION) {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":" if (!TestProperties.TEST_EMAIL.equals(email)) {"},{"lineNumber":214,"author":{"gitId":"-"},"content":" fail(\"Email verification is allowed only on preset test email.\");"},{"lineNumber":215,"author":{"gitId":"-"},"content":" }"},{"lineNumber":216,"author":{"gitId":"-"},"content":" EmailAccount emailAccount \u003d new EmailAccount(email);"},{"lineNumber":217,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":218,"author":{"gitId":"-"},"content":" emailAccount.getUserAuthenticated();"},{"lineNumber":219,"author":{"gitId":"-"},"content":" int retryLimit \u003d 5;"},{"lineNumber":220,"author":{"gitId":"-"},"content":" boolean actual \u003d emailAccount.isRecentEmailWithSubjectPresent(subject, TestProperties.TEST_SENDER_EMAIL);"},{"lineNumber":221,"author":{"gitId":"-"},"content":" while (!actual \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":222,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":223,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(1000);"},{"lineNumber":224,"author":{"gitId":"-"},"content":" actual \u003d emailAccount.isRecentEmailWithSubjectPresent(subject, TestProperties.TEST_SENDER_EMAIL);"},{"lineNumber":225,"author":{"gitId":"-"},"content":" }"},{"lineNumber":226,"author":{"gitId":"-"},"content":" assertTrue(actual);"},{"lineNumber":227,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":228,"author":{"gitId":"-"},"content":" fail(\"Failed to verify email sent:\" + e);"},{"lineNumber":229,"author":{"gitId":"-"},"content":" }"},{"lineNumber":230,"author":{"gitId":"-"},"content":" }"},{"lineNumber":231,"author":{"gitId":"-"},"content":""},{"lineNumber":232,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":233,"author":{"gitId":"-"},"content":" * Removes and restores the databundle using BACKDOOR."},{"lineNumber":234,"author":{"gitId":"-"},"content":" */"},{"lineNumber":235,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":236,"author":{"gitId":"-"},"content":" protected SqlDataBundle doRemoveAndRestoreDataBundle(SqlDataBundle testData) {"},{"lineNumber":237,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":238,"author":{"gitId":"-"},"content":" return BACKDOOR.removeAndRestoreSqlDataBundle(testData);"},{"lineNumber":239,"author":{"gitId":"-"},"content":" } catch (HttpRequestFailedException e) {"},{"lineNumber":240,"author":{"gitId":"-"},"content":" e.printStackTrace();"},{"lineNumber":241,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":242,"author":{"gitId":"-"},"content":" }"},{"lineNumber":243,"author":{"gitId":"-"},"content":" }"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":" FeedbackQuestionData getFeedbackQuestion(String courseId, String feedbackSessionName, int qnNumber) {"},{"lineNumber":246,"author":{"gitId":"-"},"content":" return BACKDOOR.getFeedbackQuestionData(courseId, feedbackSessionName, qnNumber);"},{"lineNumber":247,"author":{"gitId":"-"},"content":" }"},{"lineNumber":248,"author":{"gitId":"-"},"content":""},{"lineNumber":249,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":250,"author":{"gitId":"-"},"content":" protected FeedbackQuestionData getFeedbackQuestion(FeedbackQuestion fq) {"},{"lineNumber":251,"author":{"gitId":"-"},"content":" return getFeedbackQuestion(fq.getCourseId(), fq.getFeedbackSession().getName(), fq.getQuestionNumber());"},{"lineNumber":252,"author":{"gitId":"-"},"content":" }"},{"lineNumber":253,"author":{"gitId":"-"},"content":""},{"lineNumber":254,"author":{"gitId":"-"},"content":" FeedbackResponseData getFeedbackResponse(String questionId, String giver, String recipient) {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" return BACKDOOR.getFeedbackResponseData(questionId, giver, recipient);"},{"lineNumber":256,"author":{"gitId":"-"},"content":" }"},{"lineNumber":257,"author":{"gitId":"-"},"content":""},{"lineNumber":258,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":259,"author":{"gitId":"-"},"content":" protected FeedbackResponseData getFeedbackResponse(FeedbackResponse fr) {"},{"lineNumber":260,"author":{"gitId":"-"},"content":" return getFeedbackResponse(fr.getFeedbackQuestion().getId().toString(), fr.getGiver(), fr.getRecipient());"},{"lineNumber":261,"author":{"gitId":"-"},"content":" }"},{"lineNumber":262,"author":{"gitId":"-"},"content":""},{"lineNumber":263,"author":{"gitId":"-"},"content":" StudentData getStudent(String courseId, String studentEmailAddress) {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" return BACKDOOR.getStudentData(courseId, studentEmailAddress);"},{"lineNumber":265,"author":{"gitId":"-"},"content":" }"},{"lineNumber":266,"author":{"gitId":"-"},"content":""},{"lineNumber":267,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":268,"author":{"gitId":"-"},"content":" protected StudentData getStudent(Student student) {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" return getStudent(student.getCourseId(), student.getEmail());"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" FeedbackSessionData getFeedbackSession(String courseId, String feedbackSessionName) {"},{"lineNumber":273,"author":{"gitId":"-"},"content":" return BACKDOOR.getFeedbackSessionData(courseId, feedbackSessionName);"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":277,"author":{"gitId":"-"},"content":" protected FeedbackSessionData getFeedbackSession(FeedbackSession feedbackSession) {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" return getFeedbackSession(feedbackSession.getCourse().getId(), feedbackSession.getName());"},{"lineNumber":279,"author":{"gitId":"-"},"content":" }"},{"lineNumber":280,"author":{"gitId":"-"},"content":""},{"lineNumber":281,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":282,"author":{"gitId":"-"},"content":" * Checks if the feedback session is published."},{"lineNumber":283,"author":{"gitId":"-"},"content":" */"},{"lineNumber":284,"author":{"gitId":"-"},"content":" protected boolean isFeedbackSessionPublished(FeedbackSessionPublishStatus status) {"},{"lineNumber":285,"author":{"gitId":"-"},"content":" return status \u003d\u003d FeedbackSessionPublishStatus.PUBLISHED;"},{"lineNumber":286,"author":{"gitId":"-"},"content":" }"},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":" FeedbackSessionData getSoftDeletedSession(String feedbackSessionName, String instructorId) {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" return BACKDOOR.getSoftDeletedSessionData(feedbackSessionName, instructorId);"},{"lineNumber":290,"author":{"gitId":"-"},"content":" }"},{"lineNumber":291,"author":{"gitId":"-"},"content":""},{"lineNumber":292,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":293,"author":{"gitId":"domoberzin"},"content":" * Puts the documents in the database using BACKDOOR."},{"lineNumber":294,"author":{"gitId":"domoberzin"},"content":" * @param dataBundle the data to be put in the database"},{"lineNumber":295,"author":{"gitId":"domoberzin"},"content":" * @return the result of the operation"},{"lineNumber":296,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":297,"author":{"gitId":"domoberzin"},"content":" protected String putDocuments(SqlDataBundle dataBundle) {"},{"lineNumber":298,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":299,"author":{"gitId":"domoberzin"},"content":" return BACKDOOR.putSqlDocuments(dataBundle);"},{"lineNumber":300,"author":{"gitId":"domoberzin"},"content":" } catch (HttpRequestFailedException e) {"},{"lineNumber":301,"author":{"gitId":"domoberzin"},"content":" e.printStackTrace();"},{"lineNumber":302,"author":{"gitId":"domoberzin"},"content":" return null;"},{"lineNumber":303,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":304,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":305,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":14,"-":291}},{"path":"src/e2e/java/teammates/e2e/cases/sql/FeedbackMcqQuestionE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.e2e.cases.sql;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.stream.Collectors;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.questions.FeedbackMcqQuestionDetails;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.questions.FeedbackMcqResponseDetails;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import teammates.e2e.pageobjects.FeedbackSubmitPage;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.e2e.pageobjects.InstructorFeedbackEditPage;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link Const.WebPageURIs#INSTRUCTOR_SESSION_EDIT_PAGE},"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" * {@link Const.WebPageURIs#SESSION_SUBMISSION_PAGE}"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":" * specifically for MCQ questions."},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":"public class FeedbackMcqQuestionE2ETest extends BaseFeedbackQuestionE2ETest {"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":" protected void prepareTestData() {"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":" testData \u003d removeAndRestoreDataBundle(loadSqlDataBundle(\"/FeedbackMcqQuestionE2ESqlTest.json\"));"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" instructor \u003d testData.instructors.get(\"instructor\");"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" course \u003d testData.courses.get(\"course\");"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" feedbackSession \u003d testData.feedbackSessions.get(\"openSession\");"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" student \u003d testData.students.get(\"alice.tmms@FMcqQn.CS2104\");"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" public void testAll() {"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" testEditPage();"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" logout();"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" testSubmitPage();"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" protected void testEditPage() {"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" InstructorFeedbackEditPage feedbackEditPage \u003d loginToFeedbackEditPage();"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" ______TS(\"verify loaded question\");"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion loadedQuestion \u003d testData.feedbackQuestions.get(\"qn1ForFirstSession\");"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" FeedbackMcqQuestionDetails questionDetails \u003d (FeedbackMcqQuestionDetails) loadedQuestion"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" .getQuestionDetailsCopy();"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.verifyMcqQuestionDetails(1, questionDetails);"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" ______TS(\"add new question\");"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" // add new question exactly like loaded question"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" loadedQuestion.setQuestionNumber(2);"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.addMcqQuestion(loadedQuestion);"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.verifyMcqQuestionDetails(2, questionDetails);"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" verifyPresentInDatabase(loadedQuestion);"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" ______TS(\"copy question\");"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion copiedQuestion \u003d testData.feedbackQuestions.get(\"qn1ForSecondSession\");"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" questionDetails \u003d (FeedbackMcqQuestionDetails) copiedQuestion.getQuestionDetailsCopy();"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.copyQuestion(copiedQuestion.getCourseId(),"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" copiedQuestion.getQuestionDetailsCopy().getQuestionText());"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" copiedQuestion.setFeedbackSession(feedbackSession);"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" copiedQuestion.setQuestionNumber(3);"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.verifyMcqQuestionDetails(3, questionDetails);"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" verifyPresentInDatabase(copiedQuestion);"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" ______TS(\"edit question\");"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" questionDetails \u003d (FeedbackMcqQuestionDetails) loadedQuestion.getQuestionDetailsCopy();"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" questionDetails.setHasAssignedWeights(false);"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" questionDetails.setMcqWeights(new ArrayList\u003c\u003e());"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" questionDetails.setOtherEnabled(false);"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" questionDetails.setQuestionDropdownEnabled(false);"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" questionDetails.setMcqOtherWeight(0);"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" List\u003cString\u003e choices \u003d questionDetails.getMcqChoices();"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" choices.add(\"Edited choice\");"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" questionDetails.setMcqChoices(choices);"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" loadedQuestion \u003d testData.feedbackQuestions.get(\"qn1ForFirstSession\").makeDeepCopy(feedbackSession);"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":" loadedQuestion.setQuestionDetails(questionDetails);"},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.editMcqQuestion(2, questionDetails);"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.waitForPageToLoad();"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.verifyMcqQuestionDetails(2, questionDetails);"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":" verifyPresentInDatabase(loadedQuestion);"},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" protected void testSubmitPage() {"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":" FeedbackSubmitPage feedbackSubmitPage \u003d loginToFeedbackSubmitPage();"},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":" ______TS(\"verify loaded question\");"},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion question \u003d testData.feedbackQuestions.get(\"qn1ForFirstSession\");"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" feedbackSubmitPage.verifyMcqQuestion(1, \"\","},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" (FeedbackMcqQuestionDetails) question.getQuestionDetailsCopy());"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" ______TS(\"verify question with generated options\");"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" feedbackSubmitPage.verifyGeneratedMcqQuestion(3, \"\", getGeneratedStudentOptions());"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":" ______TS(\"submit response\");"},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" FeedbackResponse response \u003d getResponse(question, false, \"UI\");"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":" feedbackSubmitPage.fillMcqResponse(1, \"\", response);"},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" feedbackSubmitPage.clickSubmitQuestionButton(1);"},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" // verifyPresentInDatabase(response);"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" // ______TS(\"check previous response\");"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage \u003d getFeedbackSubmitPage();"},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage.verifyMcqResponse(1, \"\", response);"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":" // ______TS(\"edit response\");"},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" // response \u003d getResponse(questionId, true, \"This is the edited response.\");"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage.fillMcqResponse(1, \"\", response);"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage.clickSubmitQuestionButton(1);"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage \u003d getFeedbackSubmitPage();"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage.verifyMcqResponse(1, \"\", response);"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" // verifyPresentInDatabase(response);"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" private List\u003cString\u003e getGeneratedStudentOptions() {"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" return testData.students.values().stream()"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" .filter(s -\u003e s.getCourse().equals(student.getCourse()))"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" .map(s -\u003e s.getName() + \" (\" + s.getTeam().getName() + \")\")"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" .collect(Collectors.toList());"},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":" private FeedbackResponse getResponse(FeedbackQuestion feedbackQuestion, boolean isOther, String answer) {"},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":" FeedbackMcqResponseDetails details \u003d new FeedbackMcqResponseDetails();"},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" if (isOther) {"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" details.setOther(true);"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" details.setOtherFieldContent(answer);"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":" details.setAnswer(answer);"},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":" return FeedbackResponse.makeResponse(feedbackQuestion, student.getEmail(), null, instructor.getEmail(), null,"},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":" details);"},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":140}},{"path":"src/e2e/java/teammates/e2e/cases/sql/FeedbackMsqQuestionE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.e2e.cases.sql;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.Arrays;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import java.util.stream.Collectors;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.questions.FeedbackMsqQuestionDetails;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.questions.FeedbackMsqResponseDetails;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Const;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.e2e.pageobjects.FeedbackSubmitPage;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.e2e.pageobjects.InstructorFeedbackEditPage;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link Const.WebPageURIs#INSTRUCTOR_SESSION_EDIT_PAGE},"},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":" * {@link Const.WebPageURIs#SESSION_SUBMISSION_PAGE}"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" * specifically for msq questions."},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":"public class FeedbackMsqQuestionE2ETest extends BaseFeedbackQuestionE2ETest {"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" protected void prepareTestData() {"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" testData \u003d removeAndRestoreDataBundle(loadSqlDataBundle(\"/FeedbackMsqQuestionE2ESqlTest.json\"));"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" instructor \u003d testData.instructors.get(\"instructor\");"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" course \u003d testData.courses.get(\"course\");"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" feedbackSession \u003d testData.feedbackSessions.get(\"openSession\");"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" student \u003d testData.students.get(\"alice.tmms@FMsqQn.CS2104\");"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" public void testAll() {"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" testEditPage();"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" logout();"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" testSubmitPage();"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" protected void testEditPage() {"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" InstructorFeedbackEditPage feedbackEditPage \u003d loginToFeedbackEditPage();"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" ______TS(\"verify loaded question\");"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion loadedQuestion \u003d testData.feedbackQuestions.get(\"qn1ForFirstSession\")"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" .makeDeepCopy(feedbackSession);"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" FeedbackMsqQuestionDetails questionDetails \u003d (FeedbackMsqQuestionDetails) loadedQuestion"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" .getQuestionDetailsCopy();"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.verifyMsqQuestionDetails(1, questionDetails);"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" ______TS(\"add new question\");"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" // add new question exactly like loaded question"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" loadedQuestion.setQuestionNumber(2);"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.addMsqQuestion(loadedQuestion);"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.verifyMsqQuestionDetails(2, questionDetails);"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" verifyPresentInDatabase(loadedQuestion);"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" ______TS(\"copy question\");"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion copiedQuestion \u003d testData.feedbackQuestions.get(\"qn1ForSecondSession\");"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" questionDetails \u003d (FeedbackMsqQuestionDetails) copiedQuestion.getQuestionDetailsCopy();"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.copyQuestion(copiedQuestion.getCourseId(),"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" copiedQuestion.getQuestionDetailsCopy().getQuestionText());"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" copiedQuestion.setFeedbackSession(feedbackSession);"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" copiedQuestion.setQuestionNumber(3);"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.verifyMsqQuestionDetails(3, questionDetails);"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" verifyPresentInDatabase(copiedQuestion);"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" ______TS(\"edit question\");"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" questionDetails \u003d (FeedbackMsqQuestionDetails) loadedQuestion.getQuestionDetailsCopy();"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" questionDetails.setHasAssignedWeights(false);"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" questionDetails.setMsqWeights(new ArrayList\u003c\u003e());"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" questionDetails.setOtherEnabled(false);"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" questionDetails.setMsqOtherWeight(0);"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" questionDetails.setMaxSelectableChoices(Const.POINTS_NO_VALUE);"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" List\u003cString\u003e choices \u003d questionDetails.getMsqChoices();"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":" choices.add(\"Edited choice\");"},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" questionDetails.setMsqChoices(choices);"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" loadedQuestion.setQuestionDetails(questionDetails);"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.editMsqQuestion(2, questionDetails);"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.waitForPageToLoad();"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.verifyMsqQuestionDetails(2, questionDetails);"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" verifyPresentInDatabase(loadedQuestion);"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" protected void testSubmitPage() {"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":" FeedbackSubmitPage feedbackSubmitPage \u003d loginToFeedbackSubmitPage();"},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" ______TS(\"verify loaded question\");"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion question \u003d testData.feedbackQuestions.get(\"qn1ForFirstSession\");"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" Student receiver \u003d testData.students.get(\"benny.tmms@FMsqQn.CS2104\");"},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" feedbackSubmitPage.verifyMsqQuestion(1, receiver.getName(),"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" (FeedbackMsqQuestionDetails) question.getQuestionDetailsCopy());"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":" ______TS(\"verify loaded question with generated options\");"},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion generatedQn \u003d testData.feedbackQuestions.get(\"qn1ForSecondSession\");"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":" feedbackSubmitPage.verifyGeneratedMsqQuestion(3, \"\","},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" (FeedbackMsqQuestionDetails) generatedQn.getQuestionDetailsCopy(), getGeneratedTeams());"},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" ______TS(\"submit response\");"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":" List\u003cString\u003e answers \u003d Arrays.asList(\"Leadership\", \"This is the other response.\");"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" FeedbackResponse response \u003d getResponse(question, receiver, answers.get(answers.size() - 1), answers);"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":" feedbackSubmitPage.fillMsqResponse(1, receiver.getName(), response);"},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" feedbackSubmitPage.clickSubmitQuestionButton(1);"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":" // TODO: uncomment when SubmitFeedbackResponse is working"},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" // verifyPresentInDatabase(response);"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" // ______TS(\"check previous response\");"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage \u003d getFeedbackSubmitPage();"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage.verifyMsqResponse(1, receiver.getName(), response);"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" // ______TS(\"edit response\");"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" // answers \u003d Arrays.asList(\"\");"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" // response \u003d getResponse(question, receiver, \"\", answers);"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage.fillMsqResponse(1, receiver.getName(), response);"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage.clickSubmitQuestionButton(1);"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage \u003d getFeedbackSubmitPage();"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage.verifyMsqResponse(1, receiver.getName(), response);"},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" // verifyPresentInDatabase(response);"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":" private List\u003cString\u003e getGeneratedTeams() {"},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" return testData.students.values().stream()"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" .filter(s -\u003e s.getCourse().equals(student.getCourse()))"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" .map(s -\u003e s.getTeam().getName())"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":" .distinct()"},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":" .collect(Collectors.toList());"},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":" private FeedbackResponse getResponse(FeedbackQuestion feedbackQuestion, Student receiver, String other,"},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" List\u003cString\u003e answers) {"},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":" FeedbackMsqResponseDetails details \u003d new FeedbackMsqResponseDetails();"},{"lineNumber":141,"author":{"gitId":"dishenggg"},"content":" if (!other.isEmpty()) {"},{"lineNumber":142,"author":{"gitId":"dishenggg"},"content":" details.setOther(true);"},{"lineNumber":143,"author":{"gitId":"dishenggg"},"content":" details.setOtherFieldContent(other);"},{"lineNumber":144,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":145,"author":{"gitId":"dishenggg"},"content":" details.setAnswers(answers);"},{"lineNumber":146,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":" return FeedbackResponse.makeResponse(feedbackQuestion, student.getEmail(), student.getSection(),"},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":" receiver.getEmail(), receiver.getSection(), details);"},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":150}},{"path":"src/e2e/java/teammates/e2e/cases/sql/FeedbackNumScaleQuestionE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"marquestye"},"content":"package teammates.e2e.cases.sql;"},{"lineNumber":2,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":3,"author":{"gitId":"marquestye"},"content":"import org.testng.annotations.Test;"},{"lineNumber":4,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":5,"author":{"gitId":"marquestye"},"content":"import teammates.common.datatransfer.questions.FeedbackNumericalScaleQuestionDetails;"},{"lineNumber":6,"author":{"gitId":"marquestye"},"content":"import teammates.common.datatransfer.questions.FeedbackNumericalScaleResponseDetails;"},{"lineNumber":7,"author":{"gitId":"marquestye"},"content":"import teammates.e2e.pageobjects.FeedbackSubmitPage;"},{"lineNumber":8,"author":{"gitId":"marquestye"},"content":"import teammates.e2e.pageobjects.InstructorFeedbackEditPage;"},{"lineNumber":9,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":10,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":11,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":12,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":13,"author":{"gitId":"marquestye"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"marquestye"},"content":" * SUT: {@link Const.WebPageURIs#INSTRUCTOR_SESSION_EDIT_PAGE}, {@link Const.WebPageURIs#SESSION_SUBMISSION_PAGE}"},{"lineNumber":15,"author":{"gitId":"marquestye"},"content":" * specifically for NumScale questions."},{"lineNumber":16,"author":{"gitId":"marquestye"},"content":" */"},{"lineNumber":17,"author":{"gitId":"marquestye"},"content":"public class FeedbackNumScaleQuestionE2ETest extends BaseFeedbackQuestionE2ETest {"},{"lineNumber":18,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":19,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":20,"author":{"gitId":"marquestye"},"content":" protected void prepareTestData() {"},{"lineNumber":21,"author":{"gitId":"marquestye"},"content":" testData \u003d removeAndRestoreDataBundle(loadSqlDataBundle(\"/FeedbackNumScaleQuestionE2ESqlTest.json\"));"},{"lineNumber":22,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":23,"author":{"gitId":"marquestye"},"content":" instructor \u003d testData.instructors.get(\"instructor\");"},{"lineNumber":24,"author":{"gitId":"marquestye"},"content":" course \u003d testData.courses.get(\"course\");"},{"lineNumber":25,"author":{"gitId":"marquestye"},"content":" feedbackSession \u003d testData.feedbackSessions.get(\"openSession\");"},{"lineNumber":26,"author":{"gitId":"marquestye"},"content":" student \u003d testData.students.get(\"alice.tmms@FNumScaleQn.CS2104\");"},{"lineNumber":27,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":28,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":29,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":30,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":31,"author":{"gitId":"marquestye"},"content":" public void testAll() {"},{"lineNumber":32,"author":{"gitId":"marquestye"},"content":" testEditPage();"},{"lineNumber":33,"author":{"gitId":"marquestye"},"content":" logout();"},{"lineNumber":34,"author":{"gitId":"marquestye"},"content":" testSubmitPage();"},{"lineNumber":35,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":36,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":37,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"marquestye"},"content":" protected void testEditPage() {"},{"lineNumber":39,"author":{"gitId":"marquestye"},"content":" InstructorFeedbackEditPage feedbackEditPage \u003d loginToFeedbackEditPage();"},{"lineNumber":40,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":41,"author":{"gitId":"marquestye"},"content":" ______TS(\"verify loaded question\");"},{"lineNumber":42,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion loadedQuestion \u003d testData.feedbackQuestions.get(\"qn1ForFirstSession\");"},{"lineNumber":43,"author":{"gitId":"marquestye"},"content":" FeedbackNumericalScaleQuestionDetails questionDetails \u003d"},{"lineNumber":44,"author":{"gitId":"marquestye"},"content":" (FeedbackNumericalScaleQuestionDetails) loadedQuestion.getQuestionDetailsCopy();"},{"lineNumber":45,"author":{"gitId":"marquestye"},"content":" feedbackEditPage.verifyNumScaleQuestionDetails(1, questionDetails);"},{"lineNumber":46,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":47,"author":{"gitId":"marquestye"},"content":" ______TS(\"add new question\");"},{"lineNumber":48,"author":{"gitId":"marquestye"},"content":" // add new question exactly like loaded question"},{"lineNumber":49,"author":{"gitId":"marquestye"},"content":" loadedQuestion.setQuestionNumber(2);"},{"lineNumber":50,"author":{"gitId":"marquestye"},"content":" feedbackEditPage.addNumScaleQuestion(loadedQuestion);"},{"lineNumber":51,"author":{"gitId":"marquestye"},"content":" feedbackEditPage.waitUntilAnimationFinish();"},{"lineNumber":52,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":53,"author":{"gitId":"marquestye"},"content":" feedbackEditPage.verifyNumScaleQuestionDetails(2, questionDetails);"},{"lineNumber":54,"author":{"gitId":"marquestye"},"content":" verifyPresentInDatabase(loadedQuestion);"},{"lineNumber":55,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":56,"author":{"gitId":"marquestye"},"content":" ______TS(\"copy question\");"},{"lineNumber":57,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion copiedQuestion \u003d testData.feedbackQuestions.get(\"qn1ForSecondSession\");"},{"lineNumber":58,"author":{"gitId":"marquestye"},"content":" questionDetails \u003d (FeedbackNumericalScaleQuestionDetails) copiedQuestion.getQuestionDetailsCopy();"},{"lineNumber":59,"author":{"gitId":"marquestye"},"content":" feedbackEditPage.copyQuestion(copiedQuestion.getCourseId(),"},{"lineNumber":60,"author":{"gitId":"marquestye"},"content":" copiedQuestion.getQuestionDetailsCopy().getQuestionText());"},{"lineNumber":61,"author":{"gitId":"marquestye"},"content":" copiedQuestion.setQuestionNumber(3);"},{"lineNumber":62,"author":{"gitId":"marquestye"},"content":" copiedQuestion.setFeedbackSession(feedbackSession);"},{"lineNumber":63,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":64,"author":{"gitId":"marquestye"},"content":" feedbackEditPage.verifyNumScaleQuestionDetails(3, questionDetails);"},{"lineNumber":65,"author":{"gitId":"marquestye"},"content":" verifyPresentInDatabase(copiedQuestion);"},{"lineNumber":66,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":67,"author":{"gitId":"marquestye"},"content":" ______TS(\"edit question\");"},{"lineNumber":68,"author":{"gitId":"marquestye"},"content":" questionDetails \u003d (FeedbackNumericalScaleQuestionDetails) loadedQuestion.getQuestionDetailsCopy();"},{"lineNumber":69,"author":{"gitId":"marquestye"},"content":" FeedbackNumericalScaleQuestionDetails newQuestionDetails \u003d"},{"lineNumber":70,"author":{"gitId":"marquestye"},"content":" (FeedbackNumericalScaleQuestionDetails) questionDetails.getDeepCopy();"},{"lineNumber":71,"author":{"gitId":"marquestye"},"content":" newQuestionDetails.setMinScale(0);"},{"lineNumber":72,"author":{"gitId":"marquestye"},"content":" newQuestionDetails.setStep(1);"},{"lineNumber":73,"author":{"gitId":"marquestye"},"content":" newQuestionDetails.setMaxScale(100);"},{"lineNumber":74,"author":{"gitId":"marquestye"},"content":" loadedQuestion.setQuestionDetails(newQuestionDetails);"},{"lineNumber":75,"author":{"gitId":"marquestye"},"content":" feedbackEditPage.editNumScaleQuestion(2, newQuestionDetails);"},{"lineNumber":76,"author":{"gitId":"marquestye"},"content":" feedbackEditPage.waitForPageToLoad();"},{"lineNumber":77,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":78,"author":{"gitId":"marquestye"},"content":" feedbackEditPage.verifyNumScaleQuestionDetails(2, newQuestionDetails);"},{"lineNumber":79,"author":{"gitId":"marquestye"},"content":" verifyPresentInDatabase(loadedQuestion);"},{"lineNumber":80,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":81,"author":{"gitId":"marquestye"},"content":" // reset question details to original"},{"lineNumber":82,"author":{"gitId":"marquestye"},"content":" loadedQuestion.setQuestionDetails(questionDetails);"},{"lineNumber":83,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":84,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":85,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":86,"author":{"gitId":"marquestye"},"content":" protected void testSubmitPage() {"},{"lineNumber":87,"author":{"gitId":"marquestye"},"content":" FeedbackSubmitPage feedbackSubmitPage \u003d loginToFeedbackSubmitPage();"},{"lineNumber":88,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":89,"author":{"gitId":"marquestye"},"content":" ______TS(\"verify loaded question\");"},{"lineNumber":90,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion question \u003d testData.feedbackQuestions.get(\"qn1ForFirstSession\");"},{"lineNumber":91,"author":{"gitId":"marquestye"},"content":" Student receiver \u003d testData.students.get(\"benny.tmms@FNumScaleQn.CS2104\");"},{"lineNumber":92,"author":{"gitId":"marquestye"},"content":" feedbackSubmitPage.verifyNumScaleQuestion(1, receiver.getTeamName(),"},{"lineNumber":93,"author":{"gitId":"marquestye"},"content":" (FeedbackNumericalScaleQuestionDetails) question.getQuestionDetailsCopy());"},{"lineNumber":94,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":95,"author":{"gitId":"marquestye"},"content":" ______TS(\"submit response\");"},{"lineNumber":96,"author":{"gitId":"marquestye"},"content":" FeedbackResponse response \u003d getResponse(question, receiver, 5.4);"},{"lineNumber":97,"author":{"gitId":"marquestye"},"content":" feedbackSubmitPage.fillNumScaleResponse(1, receiver.getTeamName(), response);"},{"lineNumber":98,"author":{"gitId":"marquestye"},"content":" feedbackSubmitPage.clickSubmitQuestionButton(1);"},{"lineNumber":99,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":100,"author":{"gitId":"marquestye"},"content":" // TODO: uncomment when SubmitFeedbackResponse is working"},{"lineNumber":101,"author":{"gitId":"marquestye"},"content":" // verifyPresentInDatabase(response);"},{"lineNumber":102,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":103,"author":{"gitId":"marquestye"},"content":" // ______TS(\"check previous response\");"},{"lineNumber":104,"author":{"gitId":"marquestye"},"content":" // feedbackSubmitPage \u003d getFeedbackSubmitPage();"},{"lineNumber":105,"author":{"gitId":"marquestye"},"content":" // feedbackSubmitPage.verifyNumScaleResponse(1, receiver.getTeamName(), response);"},{"lineNumber":106,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":107,"author":{"gitId":"marquestye"},"content":" // ______TS(\"edit response\");"},{"lineNumber":108,"author":{"gitId":"marquestye"},"content":" // response \u003d getResponse(question, receiver, 10.0);"},{"lineNumber":109,"author":{"gitId":"marquestye"},"content":" // feedbackSubmitPage.fillNumScaleResponse(1, receiver.getTeamName(), response);"},{"lineNumber":110,"author":{"gitId":"marquestye"},"content":" // feedbackSubmitPage.clickSubmitQuestionButton(1);"},{"lineNumber":111,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":112,"author":{"gitId":"marquestye"},"content":" // feedbackSubmitPage \u003d getFeedbackSubmitPage();"},{"lineNumber":113,"author":{"gitId":"marquestye"},"content":" // feedbackSubmitPage.verifyNumScaleResponse(1, receiver.getTeamName(), response);"},{"lineNumber":114,"author":{"gitId":"marquestye"},"content":" // verifyPresentInDatabase(response);"},{"lineNumber":115,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":116,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":117,"author":{"gitId":"marquestye"},"content":" private FeedbackResponse getResponse(FeedbackQuestion feedbackQuestion, Student receiver, Double answer) {"},{"lineNumber":118,"author":{"gitId":"marquestye"},"content":" FeedbackNumericalScaleResponseDetails details \u003d new FeedbackNumericalScaleResponseDetails();"},{"lineNumber":119,"author":{"gitId":"marquestye"},"content":" details.setAnswer(answer);"},{"lineNumber":120,"author":{"gitId":"marquestye"},"content":" return FeedbackResponse.makeResponse("},{"lineNumber":121,"author":{"gitId":"marquestye"},"content":" feedbackQuestion, student.getEmail(), null, receiver.getTeamName(), null, details);"},{"lineNumber":122,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":123,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":124,"author":{"gitId":"marquestye"},"content":"}"}],"authorContributionMap":{"marquestye":124}},{"path":"src/e2e/java/teammates/e2e/cases/sql/FeedbackRankOptionQuestionE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"mingyuanc"},"content":"package teammates.e2e.cases.sql;"},{"lineNumber":2,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":3,"author":{"gitId":"mingyuanc"},"content":"import java.util.Arrays;"},{"lineNumber":4,"author":{"gitId":"mingyuanc"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":6,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":8,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.datatransfer.questions.FeedbackRankOptionsQuestionDetails;"},{"lineNumber":9,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.datatransfer.questions.FeedbackRankOptionsResponseDetails;"},{"lineNumber":10,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.datatransfer.questions.FeedbackRankQuestionDetails;"},{"lineNumber":11,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"mingyuanc"},"content":"import teammates.e2e.pageobjects.FeedbackSubmitPage;"},{"lineNumber":13,"author":{"gitId":"mingyuanc"},"content":"import teammates.e2e.pageobjects.InstructorFeedbackEditPage;"},{"lineNumber":14,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":15,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":16,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":17,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":18,"author":{"gitId":"mingyuanc"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"mingyuanc"},"content":" * SUT: {@link Const.WebPageURIs#INSTRUCTOR_SESSION_EDIT_PAGE},"},{"lineNumber":20,"author":{"gitId":"mingyuanc"},"content":" * {@link Const.WebPageURIs#SESSION_SUBMISSION_PAGE}"},{"lineNumber":21,"author":{"gitId":"mingyuanc"},"content":" * specifically for RankOption questions."},{"lineNumber":22,"author":{"gitId":"mingyuanc"},"content":" */"},{"lineNumber":23,"author":{"gitId":"mingyuanc"},"content":"public class FeedbackRankOptionQuestionE2ETest extends BaseFeedbackQuestionE2ETest {"},{"lineNumber":24,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":25,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":26,"author":{"gitId":"mingyuanc"},"content":" protected void prepareTestData() {"},{"lineNumber":27,"author":{"gitId":"mingyuanc"},"content":" testData \u003d removeAndRestoreDataBundle(loadSqlDataBundle(\"/FeedbackRankOptionQuestionE2ESqlTest.json\"));"},{"lineNumber":28,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":29,"author":{"gitId":"mingyuanc"},"content":" instructor \u003d testData.instructors.get(\"instructor\");"},{"lineNumber":30,"author":{"gitId":"mingyuanc"},"content":" course \u003d testData.courses.get(\"course\");"},{"lineNumber":31,"author":{"gitId":"mingyuanc"},"content":" feedbackSession \u003d testData.feedbackSessions.get(\"openSession\");"},{"lineNumber":32,"author":{"gitId":"mingyuanc"},"content":" student \u003d testData.students.get(\"alice.tmms@FRankOptQn.CS2104\");"},{"lineNumber":33,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":34,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":35,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":36,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":37,"author":{"gitId":"mingyuanc"},"content":" public void testAll() {"},{"lineNumber":38,"author":{"gitId":"mingyuanc"},"content":" testEditPage();"},{"lineNumber":39,"author":{"gitId":"mingyuanc"},"content":" logout();"},{"lineNumber":40,"author":{"gitId":"mingyuanc"},"content":" testSubmitPage();"},{"lineNumber":41,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":42,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":43,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":44,"author":{"gitId":"mingyuanc"},"content":" protected void testEditPage() {"},{"lineNumber":45,"author":{"gitId":"mingyuanc"},"content":" InstructorFeedbackEditPage feedbackEditPage \u003d loginToFeedbackEditPage();"},{"lineNumber":46,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":47,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"verify loaded question\");"},{"lineNumber":48,"author":{"gitId":"mingyuanc"},"content":" FeedbackQuestion loadedQuestion \u003d testData.feedbackQuestions.get(\"qn1ForFirstSession\")"},{"lineNumber":49,"author":{"gitId":"mingyuanc"},"content":" .makeDeepCopy(feedbackSession);"},{"lineNumber":50,"author":{"gitId":"mingyuanc"},"content":" FeedbackRankOptionsQuestionDetails questionDetails \u003d (FeedbackRankOptionsQuestionDetails) loadedQuestion"},{"lineNumber":51,"author":{"gitId":"mingyuanc"},"content":" .getQuestionDetailsCopy();"},{"lineNumber":52,"author":{"gitId":"mingyuanc"},"content":" feedbackEditPage.verifyRankQuestionDetails(1, questionDetails);"},{"lineNumber":53,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":54,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"add new question\");"},{"lineNumber":55,"author":{"gitId":"mingyuanc"},"content":" // add new question exactly like loaded question"},{"lineNumber":56,"author":{"gitId":"mingyuanc"},"content":" loadedQuestion.setQuestionNumber(2);"},{"lineNumber":57,"author":{"gitId":"mingyuanc"},"content":" feedbackEditPage.addRankOptionsQuestion(loadedQuestion);"},{"lineNumber":58,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":59,"author":{"gitId":"mingyuanc"},"content":" feedbackEditPage.verifyRankQuestionDetails(2, questionDetails);"},{"lineNumber":60,"author":{"gitId":"mingyuanc"},"content":" verifyPresentInDatabase(loadedQuestion);"},{"lineNumber":61,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":62,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"copy question\");"},{"lineNumber":63,"author":{"gitId":"mingyuanc"},"content":" FeedbackQuestion copiedQuestion \u003d testData.feedbackQuestions.get(\"qn1ForSecondSession\");"},{"lineNumber":64,"author":{"gitId":"mingyuanc"},"content":" questionDetails \u003d (FeedbackRankOptionsQuestionDetails) copiedQuestion.getQuestionDetailsCopy();"},{"lineNumber":65,"author":{"gitId":"mingyuanc"},"content":" feedbackEditPage.copyQuestion(copiedQuestion.getCourseId(),"},{"lineNumber":66,"author":{"gitId":"mingyuanc"},"content":" copiedQuestion.getQuestionDetailsCopy().getQuestionText());"},{"lineNumber":67,"author":{"gitId":"mingyuanc"},"content":" copiedQuestion.setFeedbackSession(feedbackSession);"},{"lineNumber":68,"author":{"gitId":"mingyuanc"},"content":" copiedQuestion.setQuestionNumber(3);"},{"lineNumber":69,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":70,"author":{"gitId":"mingyuanc"},"content":" feedbackEditPage.verifyRankQuestionDetails(3, questionDetails);"},{"lineNumber":71,"author":{"gitId":"mingyuanc"},"content":" verifyPresentInDatabase(copiedQuestion);"},{"lineNumber":72,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":73,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"edit question\");"},{"lineNumber":74,"author":{"gitId":"mingyuanc"},"content":" questionDetails \u003d (FeedbackRankOptionsQuestionDetails) loadedQuestion.getQuestionDetailsCopy();"},{"lineNumber":75,"author":{"gitId":"mingyuanc"},"content":" List\u003cString\u003e options \u003d questionDetails.getOptions();"},{"lineNumber":76,"author":{"gitId":"mingyuanc"},"content":" options.remove(0);"},{"lineNumber":77,"author":{"gitId":"mingyuanc"},"content":" options.set(1, \"Edited option.\");"},{"lineNumber":78,"author":{"gitId":"mingyuanc"},"content":" questionDetails.setOptions(options);"},{"lineNumber":79,"author":{"gitId":"mingyuanc"},"content":" questionDetails.setAreDuplicatesAllowed(true);"},{"lineNumber":80,"author":{"gitId":"mingyuanc"},"content":" questionDetails.setMaxOptionsToBeRanked(Const.POINTS_NO_VALUE);"},{"lineNumber":81,"author":{"gitId":"mingyuanc"},"content":" questionDetails.setMinOptionsToBeRanked(1);"},{"lineNumber":82,"author":{"gitId":"mingyuanc"},"content":" loadedQuestion.setQuestionDetails(questionDetails);"},{"lineNumber":83,"author":{"gitId":"mingyuanc"},"content":" feedbackEditPage.editRankQuestion(2, questionDetails);"},{"lineNumber":84,"author":{"gitId":"mingyuanc"},"content":" feedbackEditPage.waitForPageToLoad();"},{"lineNumber":85,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":86,"author":{"gitId":"mingyuanc"},"content":" feedbackEditPage.verifyRankQuestionDetails(2, questionDetails);"},{"lineNumber":87,"author":{"gitId":"mingyuanc"},"content":" verifyPresentInDatabase(loadedQuestion);"},{"lineNumber":88,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":89,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":90,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":91,"author":{"gitId":"mingyuanc"},"content":" protected void testSubmitPage() {"},{"lineNumber":92,"author":{"gitId":"mingyuanc"},"content":" FeedbackSubmitPage feedbackSubmitPage \u003d loginToFeedbackSubmitPage();"},{"lineNumber":93,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":94,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"verify loaded question\");"},{"lineNumber":95,"author":{"gitId":"mingyuanc"},"content":" FeedbackQuestion question \u003d testData.feedbackQuestions.get(\"qn1ForFirstSession\");"},{"lineNumber":96,"author":{"gitId":"mingyuanc"},"content":" Student receiver \u003d testData.students.get(\"benny.tmms@FRankOptQn.CS2104\");"},{"lineNumber":97,"author":{"gitId":"mingyuanc"},"content":" feedbackSubmitPage.verifyRankQuestion(1, receiver.getName(),"},{"lineNumber":98,"author":{"gitId":"mingyuanc"},"content":" (FeedbackRankQuestionDetails) question.getQuestionDetailsCopy());"},{"lineNumber":99,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":100,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"submit response\");"},{"lineNumber":101,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponse response \u003d getResponse(question, receiver, Arrays.asList(2, 1, 3,"},{"lineNumber":102,"author":{"gitId":"mingyuanc"},"content":" Const.POINTS_NOT_SUBMITTED));"},{"lineNumber":103,"author":{"gitId":"mingyuanc"},"content":" feedbackSubmitPage.fillRankOptionResponse(1, receiver.getName(), response);"},{"lineNumber":104,"author":{"gitId":"mingyuanc"},"content":" feedbackSubmitPage.clickSubmitQuestionButton(1);"},{"lineNumber":105,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":106,"author":{"gitId":"mingyuanc"},"content":" // verifyPresentInDatabase(response);"},{"lineNumber":107,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":108,"author":{"gitId":"mingyuanc"},"content":" // ______TS(\"check previous response\");"},{"lineNumber":109,"author":{"gitId":"mingyuanc"},"content":" // feedbackSubmitPage \u003d getFeedbackSubmitPage();"},{"lineNumber":110,"author":{"gitId":"mingyuanc"},"content":" // feedbackSubmitPage.verifyRankOptionResponse(1, receiver.getName(), response);"},{"lineNumber":111,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":112,"author":{"gitId":"mingyuanc"},"content":" // ______TS(\"edit response\");"},{"lineNumber":113,"author":{"gitId":"mingyuanc"},"content":" // response \u003d getResponse(questionId, receiver,"},{"lineNumber":114,"author":{"gitId":"mingyuanc"},"content":" // Arrays.asList(Const.POINTS_NOT_SUBMITTED, 1, 3, 2));"},{"lineNumber":115,"author":{"gitId":"mingyuanc"},"content":" // feedbackSubmitPage.fillRankOptionResponse(1, receiver.getName(), response);"},{"lineNumber":116,"author":{"gitId":"mingyuanc"},"content":" // feedbackSubmitPage.clickSubmitQuestionButton(1);"},{"lineNumber":117,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":118,"author":{"gitId":"mingyuanc"},"content":" // feedbackSubmitPage \u003d getFeedbackSubmitPage();"},{"lineNumber":119,"author":{"gitId":"mingyuanc"},"content":" // feedbackSubmitPage.verifyRankOptionResponse(1, receiver.getName(), response);"},{"lineNumber":120,"author":{"gitId":"mingyuanc"},"content":" // verifyPresentInDatabase(response);"},{"lineNumber":121,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":122,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":123,"author":{"gitId":"mingyuanc"},"content":" private FeedbackResponse getResponse(FeedbackQuestion question, Student receiver, List\u003cInteger\u003e answers) {"},{"lineNumber":124,"author":{"gitId":"mingyuanc"},"content":" FeedbackRankOptionsResponseDetails details \u003d new FeedbackRankOptionsResponseDetails();"},{"lineNumber":125,"author":{"gitId":"mingyuanc"},"content":" details.setAnswers(answers);"},{"lineNumber":126,"author":{"gitId":"mingyuanc"},"content":" return FeedbackResponse.makeResponse(question, student.getEmail(), null, receiver.getEmail(), null, details);"},{"lineNumber":127,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":128,"author":{"gitId":"mingyuanc"},"content":"}"}],"authorContributionMap":{"mingyuanc":128}},{"path":"src/e2e/java/teammates/e2e/cases/sql/InstructorNotificationsPageE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"yuanxi1"},"content":"package teammates.e2e.cases.sql;"},{"lineNumber":2,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":3,"author":{"gitId":"yuanxi1"},"content":"import java.util.Set;"},{"lineNumber":4,"author":{"gitId":"yuanxi1"},"content":"import java.util.stream.Collectors;"},{"lineNumber":5,"author":{"gitId":"yuanxi1"},"content":"import java.util.stream.Stream;"},{"lineNumber":6,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":7,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":8,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.Test;"},{"lineNumber":9,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":10,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":11,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"yuanxi1"},"content":"import teammates.e2e.pageobjects.InstructorNotificationsPage;"},{"lineNumber":13,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":14,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":15,"author":{"gitId":"yuanxi1"},"content":"import teammates.ui.output.AccountData;"},{"lineNumber":16,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":17,"author":{"gitId":"yuanxi1"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"yuanxi1"},"content":" * SUT: {@link Const.WebPageURIs#INSTRUCTOR_NOTIFICATIONS_PAGE}."},{"lineNumber":19,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":20,"author":{"gitId":"yuanxi1"},"content":"public class InstructorNotificationsPageE2ETest extends BaseE2ETestCase {"},{"lineNumber":21,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":22,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":23,"author":{"gitId":"yuanxi1"},"content":" protected void prepareTestData() {"},{"lineNumber":24,"author":{"gitId":"yuanxi1"},"content":" testData \u003d loadSqlDataBundle(\"/InstructorNotificationsPageE2ESqlTest.json\");"},{"lineNumber":25,"author":{"gitId":"yuanxi1"},"content":" removeAndRestoreDataBundle(testData);"},{"lineNumber":26,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":27,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":28,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":29,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":30,"author":{"gitId":"yuanxi1"},"content":" protected void testAll() {"},{"lineNumber":31,"author":{"gitId":"yuanxi1"},"content":" Account account \u003d testData.accounts.get(\"INotifs.instr\");"},{"lineNumber":32,"author":{"gitId":"yuanxi1"},"content":" AppUrl notificationsPageUrl \u003d createFrontendUrl(Const.WebPageURIs.INSTRUCTOR_NOTIFICATIONS_PAGE);"},{"lineNumber":33,"author":{"gitId":"yuanxi1"},"content":" InstructorNotificationsPage notificationsPage \u003d loginToPage(notificationsPageUrl, InstructorNotificationsPage.class,"},{"lineNumber":34,"author":{"gitId":"yuanxi1"},"content":" account.getGoogleId());"},{"lineNumber":35,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":36,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"verify that only active notifications with correct target user are shown\");"},{"lineNumber":37,"author":{"gitId":"yuanxi1"},"content":" Notification[] notShownNotifications \u003d {"},{"lineNumber":38,"author":{"gitId":"yuanxi1"},"content":" testData.notifications.get(\"notification2\"),"},{"lineNumber":39,"author":{"gitId":"yuanxi1"},"content":" testData.notifications.get(\"expiredNotification1\"),"},{"lineNumber":40,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":41,"author":{"gitId":"yuanxi1"},"content":" Notification[] shownNotifications \u003d {"},{"lineNumber":42,"author":{"gitId":"yuanxi1"},"content":" testData.notifications.get(\"notification1\"),"},{"lineNumber":43,"author":{"gitId":"yuanxi1"},"content":" testData.notifications.get(\"notification3\"),"},{"lineNumber":44,"author":{"gitId":"yuanxi1"},"content":" testData.notifications.get(\"notification4\"),"},{"lineNumber":45,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":46,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":47,"author":{"gitId":"yuanxi1"},"content":" Notification[] readNotifications \u003d {"},{"lineNumber":48,"author":{"gitId":"yuanxi1"},"content":" testData.notifications.get(\"notification4\"),"},{"lineNumber":49,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":50,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":51,"author":{"gitId":"yuanxi1"},"content":" Set\u003cString\u003e readNotificationsIds \u003d Stream.of(readNotifications)"},{"lineNumber":52,"author":{"gitId":"yuanxi1"},"content":" .map(readNotification -\u003e readNotification.getId().toString())"},{"lineNumber":53,"author":{"gitId":"yuanxi1"},"content":" .collect(Collectors.toSet());"},{"lineNumber":54,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":55,"author":{"gitId":"yuanxi1"},"content":" notificationsPage.verifyNotShownNotifications(notShownNotifications);"},{"lineNumber":56,"author":{"gitId":"yuanxi1"},"content":" notificationsPage.verifyShownNotifications(shownNotifications, readNotificationsIds);"},{"lineNumber":57,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":58,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"mark notification as read\");"},{"lineNumber":59,"author":{"gitId":"yuanxi1"},"content":" Notification notificationToMarkAsRead \u003d testData.notifications.get(\"notification3\");"},{"lineNumber":60,"author":{"gitId":"yuanxi1"},"content":" notificationsPage.markNotificationAsRead(notificationToMarkAsRead);"},{"lineNumber":61,"author":{"gitId":"yuanxi1"},"content":" notificationsPage.verifyStatusMessage(\"Notification marked as read.\");"},{"lineNumber":62,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":63,"author":{"gitId":"yuanxi1"},"content":" // Verify that account\u0027s readNotifications attribute is updated"},{"lineNumber":64,"author":{"gitId":"yuanxi1"},"content":" AccountData accountFromDb \u003d BACKDOOR.getAccountData(account.getGoogleId());"},{"lineNumber":65,"author":{"gitId":"yuanxi1"},"content":" assertTrue(accountFromDb.getReadNotifications().containsKey(notificationToMarkAsRead.getId().toString()));"},{"lineNumber":66,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":67,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"notification banner is not visible\");"},{"lineNumber":68,"author":{"gitId":"yuanxi1"},"content":" assertFalse(notificationsPage.isBannerVisible());"},{"lineNumber":69,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":70,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":71,"author":{"gitId":"yuanxi1"},"content":" @AfterClass"},{"lineNumber":72,"author":{"gitId":"yuanxi1"},"content":" public void classTeardown() {"},{"lineNumber":73,"author":{"gitId":"yuanxi1"},"content":" for (Notification notification : testData.notifications.values()) {"},{"lineNumber":74,"author":{"gitId":"yuanxi1"},"content":" BACKDOOR.deleteNotification(notification.getId());"},{"lineNumber":75,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":76,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":77,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":78,"author":{"gitId":"yuanxi1"},"content":"}"}],"authorContributionMap":{"yuanxi1":78}},{"path":"src/e2e/java/teammates/e2e/cases/sql/RequestPageE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.e2e.cases.sql;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Const;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.EmailType;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import teammates.e2e.pageobjects.RequestPage;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import teammates.e2e.util.TestProperties;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link Const.WebPageURIs#ACCOUNT_REQUEST_PAGE}."},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"public class RequestPageE2ETest extends BaseE2ETestCase {"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":" protected void prepareTestData() {"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" // No test data needed"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" protected void testAll() {"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":" String name \u003d \"arf-test-name\";"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":" String institution \u003d \"arf-test-institution\";"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" String country \u003d \"arf-test-country\";"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" String email \u003d TestProperties.TEST_EMAIL;"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" String comments \u003d \"arf-test-comments\";"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" AppUrl url \u003d createFrontendUrl(Const.WebPageURIs.ACCOUNT_REQUEST_PAGE);"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" RequestPage requestPage \u003d getNewPageInstance(url, RequestPage.class);"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" ______TS(\"verify submission with comments\");"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" requestPage.clickAmInstructorButton();"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" requestPage.fillForm(name, institution, country, email, comments);"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" requestPage.clickSubmitFormButton();"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" requestPage.verifySubmittedInfo(name, institution, country, email, comments);"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" String expectedEmailSubject \u003d EmailType.NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT.toString();"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" verifyEmailSent(email, expectedEmailSubject);"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" ______TS(\"verify submission without comments\");"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" requestPage \u003d getNewPageInstance(url, RequestPage.class);"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" requestPage.clickAmInstructorButton();"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" requestPage.fillForm(name, institution, country, email, \"\");"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" requestPage.clickSubmitFormButton();"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" requestPage.verifySubmittedInfo(name, institution, country, email, \"\");"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" expectedEmailSubject \u003d EmailType.NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT.toString();"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" verifyEmailSent(email, expectedEmailSubject);"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":52}},{"path":"src/e2e/java/teammates/e2e/pageobjects/AdminHomePage.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.pageobjects;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import static org.junit.Assert.assertNotNull;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.openqa.selenium.By;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.openqa.selenium.WebElement;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.openqa.selenium.support.FindBy;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.test.ThreadHelper;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"-"},"content":" * Represents the admin home page of the website."},{"lineNumber":15,"author":{"gitId":"-"},"content":" */"},{"lineNumber":16,"author":{"gitId":"-"},"content":"public class AdminHomePage extends AppPage {"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" private static final int ACCOUNT_REQUEST_COL_NAME \u003d 1;"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" private static final int ACCOUNT_REQUEST_COL_EMAIL \u003d 2;"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" private static final int ACCOUNT_REQUEST_COL_INSTITUTE \u003d 4;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"instructor-details-single-line\")"},{"lineNumber":22,"author":{"gitId":"-"},"content":" private WebElement detailsSingleLineTextBox;"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" @FindBy (id \u003d \"instructor-name\")"},{"lineNumber":25,"author":{"gitId":"-"},"content":" private WebElement nameTextBox;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @FindBy (id \u003d \"instructor-email\")"},{"lineNumber":28,"author":{"gitId":"-"},"content":" private WebElement emailTextBox;"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" @FindBy (id \u003d \"instructor-institution\")"},{"lineNumber":31,"author":{"gitId":"-"},"content":" private WebElement institutionTextBox;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" @FindBy (id \u003d \"add-instructor\")"},{"lineNumber":34,"author":{"gitId":"-"},"content":" private WebElement submitButton;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" @FindBy (id \u003d \"add-instructor-single-line\")"},{"lineNumber":37,"author":{"gitId":"-"},"content":" private WebElement submitButtonDetailsSingleLineForm;"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" @FindBy (id \u003d \"add-all-instructors\")"},{"lineNumber":40,"author":{"gitId":"-"},"content":" private WebElement addAllInstructorsButton;"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" public AdminHomePage(Browser browser) {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" super(browser);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" }"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":47,"author":{"gitId":"-"},"content":" protected boolean containsExpectedPageContents() {"},{"lineNumber":48,"author":{"gitId":"-"},"content":" return getPageSource().contains(\"Add New Instructor\u003c/h1\u003e\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" public void queueInstructorForAdding(String name, String email, String institute) {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" if (name !\u003d null) {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" fillTextBox(nameTextBox, name);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" }"},{"lineNumber":55,"author":{"gitId":"-"},"content":" if (email !\u003d null) {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" fillTextBox(emailTextBox, email);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":" if (institute !\u003d null) {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" fillTextBox(institutionTextBox, institute);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" click(submitButton);"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" public void queueInstructorForAdding(String instructorDetails) {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" if (instructorDetails !\u003d null) {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" fillTextBox(detailsSingleLineTextBox, instructorDetails);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" }"},{"lineNumber":69,"author":{"gitId":"-"},"content":" click(submitButtonDetailsSingleLineForm);"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" public void addAllInstructors() {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" click(addAllInstructorsButton);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" waitForElementToBeClickable(addAllInstructorsButton);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" }"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" public String getMessageForInstructor(int i) {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" By by \u003d By.id(\"message-instructor-\" + i);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" waitForElementVisibility(by);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" WebElement element \u003d browser.driver.findElement(by);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" if (element \u003d\u003d null) {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":83,"author":{"gitId":"-"},"content":" }"},{"lineNumber":84,"author":{"gitId":"-"},"content":" return element.getText();"},{"lineNumber":85,"author":{"gitId":"-"},"content":" }"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" public void clickMoreInfoButtonForRegisteredInstructor(int i) {"},{"lineNumber":88,"author":{"gitId":"-"},"content":" By by \u003d By.id(\"instructor-\" + i + \"-registered-info-button\");"},{"lineNumber":89,"author":{"gitId":"-"},"content":" waitForElementVisibility(by);"},{"lineNumber":90,"author":{"gitId":"-"},"content":" WebElement element \u003d browser.driver.findElement(by);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" click(element);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" waitForElementVisibility(By.id(\"reset-account-request-link\"));"},{"lineNumber":93,"author":{"gitId":"-"},"content":" }"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" public void clickResetAccountRequestLink() {"},{"lineNumber":96,"author":{"gitId":"-"},"content":" By by \u003d By.id(\"reset-account-request-link\");"},{"lineNumber":97,"author":{"gitId":"-"},"content":" WebElement element \u003d browser.driver.findElement(by);"},{"lineNumber":98,"author":{"gitId":"-"},"content":" click(element);"},{"lineNumber":99,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(1000); // Modals are stacked, wait briefly to ensure confirmation modal is shown"},{"lineNumber":100,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e okButtons \u003d browser.driver.findElements(By.className(\"modal-btn-ok\"));"},{"lineNumber":101,"author":{"gitId":"-"},"content":" clickDismissModalButtonAndWaitForModalHidden(okButtons.get(1)); // Second modal is confirmation modal"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" public String removeSpanFromText(String text) {"},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" return text.replace(\"\u003cspan class\u003d\\\"highlighted-text\\\"\u003e\", \"\").replace(\"\u003c/span\u003e\", \"\");"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" public WebElement getAccountRequestRow(String name, String email, String institute) {"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" List\u003cWebElement\u003e rows \u003d browser.driver.findElements(By.cssSelector(\"tm-account-request-table tbody tr\"));"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" for (WebElement row : rows) {"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" List\u003cWebElement\u003e columns \u003d row.findElements(By.tagName(\"td\"));"},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" if (removeSpanFromText(columns.get(ACCOUNT_REQUEST_COL_NAME - 1)"},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" .getAttribute(\"innerHTML\")).contains(name)"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" \u0026\u0026 removeSpanFromText(columns.get(ACCOUNT_REQUEST_COL_EMAIL - 1)"},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" .getAttribute(\"innerHTML\")).contains(email)"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" \u0026\u0026 removeSpanFromText(columns.get(ACCOUNT_REQUEST_COL_INSTITUTE - 1)"},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":" .getAttribute(\"innerHTML\")).contains(institute)) {"},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":" return row;"},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":" return null;"},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" public void verifyInstructorInAccountRequestTable(String name, String email, String institute) {"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" WebElement row \u003d getAccountRequestRow(name, email, institute);"},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" assertNotNull(row);"},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":30,"-":98}},{"path":"src/e2e/java/teammates/e2e/pageobjects/AdminNotificationsPage.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.pageobjects;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.time.ZoneId;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.ZonedDateTime;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.openqa.selenium.By;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.openqa.selenium.WebElement;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.openqa.selenium.support.FindBy;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationStyle;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationTargetUser;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * Page Object Model for the admin notifications page."},{"lineNumber":18,"author":{"gitId":"-"},"content":" */"},{"lineNumber":19,"author":{"gitId":"-"},"content":"public class AdminNotificationsPage extends AppPage {"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-add-notification\")"},{"lineNumber":22,"author":{"gitId":"-"},"content":" private WebElement addNotificationButton;"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-create-notification\")"},{"lineNumber":25,"author":{"gitId":"-"},"content":" private WebElement createNotificationButton;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-edit-notification\")"},{"lineNumber":28,"author":{"gitId":"-"},"content":" private WebElement editNotificationButton;"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notifications-timezone\")"},{"lineNumber":31,"author":{"gitId":"-"},"content":" private WebElement notificationsTimezone;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notification-target-user\")"},{"lineNumber":34,"author":{"gitId":"-"},"content":" private WebElement notificationTargetUserDropdown;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notification-style\")"},{"lineNumber":37,"author":{"gitId":"-"},"content":" private WebElement notificationStyleDropdown;"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notification-title\")"},{"lineNumber":40,"author":{"gitId":"-"},"content":" private WebElement notificationTitleTextBox;"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notification-message\")"},{"lineNumber":43,"author":{"gitId":"-"},"content":" private WebElement notificationMessageEditor;"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notification-start-date\")"},{"lineNumber":46,"author":{"gitId":"-"},"content":" private WebElement startDateBox;"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notification-start-time\")"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private WebElement startTimeDropdown;"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notification-end-date\")"},{"lineNumber":52,"author":{"gitId":"-"},"content":" private WebElement endDateBox;"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notification-end-time\")"},{"lineNumber":55,"author":{"gitId":"-"},"content":" private WebElement endTimeDropdown;"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notifications-table\")"},{"lineNumber":58,"author":{"gitId":"-"},"content":" private WebElement notificationsTable;"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" public AdminNotificationsPage(Browser browser) {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" super(browser);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" }"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":65,"author":{"gitId":"-"},"content":" protected boolean containsExpectedPageContents() {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" return getPageSource().contains(\"Notifications\");"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" public void verifyNotificationsTableRow(Notification notification) {"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" WebElement notificationRow \u003d notificationsTable.findElement(By.id(notification.getId().toString()));"},{"lineNumber":71,"author":{"gitId":"-"},"content":" verifyTableRowValues(notificationRow, getNotificationTableDisplayDetails(notification));"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" public void addNotification(Notification notification) {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" clickAddNotificationButton();"},{"lineNumber":76,"author":{"gitId":"-"},"content":" waitForElementPresence(By.id(\"btn-create-notification\"));"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" fillNotificationForm(notification);"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" clickCreateNotificationButton();"},{"lineNumber":81,"author":{"gitId":"-"},"content":" waitForPageToLoad(true);"},{"lineNumber":82,"author":{"gitId":"-"},"content":" }"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" public void editNotification(Notification notification) {"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" WebElement notificationRow \u003d notificationsTable.findElement(By.id(notification.getId().toString()));"},{"lineNumber":86,"author":{"gitId":"-"},"content":" WebElement editButton \u003d notificationRow.findElement(By.className(\"btn-light\"));"},{"lineNumber":87,"author":{"gitId":"-"},"content":" editButton.click();"},{"lineNumber":88,"author":{"gitId":"-"},"content":" waitForElementPresence(By.id(\"btn-edit-notification\"));"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" fillNotificationForm(notification);"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" clickEditNotificationButton();"},{"lineNumber":93,"author":{"gitId":"-"},"content":" waitForPageToLoad(true);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" }"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" public void deleteNotification(Notification notification) {"},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":" WebElement notificationRow \u003d notificationsTable.findElement(By.id(notification.getId().toString()));"},{"lineNumber":98,"author":{"gitId":"-"},"content":" WebElement deleteButton \u003d notificationRow.findElement(By.className(\"btn-danger\"));"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" deleteButton.click();"},{"lineNumber":101,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":102,"author":{"gitId":"-"},"content":" waitForPageToLoad(true);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" }"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" public void fillNotificationForm(Notification notification) {"},{"lineNumber":106,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(notificationTargetUserDropdown, getTargetUserText(notification.getTargetUser()));"},{"lineNumber":107,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(notificationStyleDropdown, getNotificationStyle(notification.getStyle()));"},{"lineNumber":108,"author":{"gitId":"-"},"content":" fillTextBox(notificationTitleTextBox, notification.getTitle());"},{"lineNumber":109,"author":{"gitId":"-"},"content":" setMessage(notification.getMessage());"},{"lineNumber":110,"author":{"gitId":"-"},"content":" setNotificationStartDateTime(notification.getStartTime());"},{"lineNumber":111,"author":{"gitId":"-"},"content":" setNotificationEndDateTime(notification.getEndTime());"},{"lineNumber":112,"author":{"gitId":"-"},"content":" }"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" public String getFirstRowNotificationId() {"},{"lineNumber":115,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e notificationRows \u003d"},{"lineNumber":116,"author":{"gitId":"-"},"content":" notificationsTable.findElement(By.tagName(\"tbody\")).findElements(By.tagName(\"tr\"));"},{"lineNumber":117,"author":{"gitId":"-"},"content":" return notificationRows.get(0).getAttribute(\"id\");"},{"lineNumber":118,"author":{"gitId":"-"},"content":" }"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" public void sortNotificationsTableByDescendingCreateTime() {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" WebElement creationTimeHeader \u003d notificationsTable.findElements(By.tagName(\"th\")).get(5);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" if (creationTimeHeader.findElements(By.className(\"fa-sort-down\")).isEmpty()) {"},{"lineNumber":123,"author":{"gitId":"-"},"content":" click(creationTimeHeader);"},{"lineNumber":124,"author":{"gitId":"-"},"content":" }"},{"lineNumber":125,"author":{"gitId":"-"},"content":" }"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" private void clickAddNotificationButton() {"},{"lineNumber":128,"author":{"gitId":"-"},"content":" click(addNotificationButton);"},{"lineNumber":129,"author":{"gitId":"-"},"content":" }"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" private void clickCreateNotificationButton() {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" click(createNotificationButton);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" }"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" private void clickEditNotificationButton() {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" click(editNotificationButton);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" private void setMessage(String message) {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" writeToRichTextEditor(notificationMessageEditor, message);"},{"lineNumber":141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" private void setNotificationStartDateTime(Instant startInstant) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" setDateTime(startDateBox, startTimeDropdown, startInstant);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" private void setNotificationEndDateTime(Instant endInstant) {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" setDateTime(endDateBox, endTimeDropdown, endInstant);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" }"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" private void setDateTime(WebElement dateBox, WebElement timeBox, Instant startInstant) {"},{"lineNumber":152,"author":{"gitId":"-"},"content":" fillDatePicker(dateBox, startInstant, getTimezone());"},{"lineNumber":153,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(timeBox.findElement(By.tagName(\"select\")), getInputTimeString(startInstant));"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"domoberzin"},"content":" private String[] getNotificationTableDisplayDetails(Notification notification) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" return new String[] {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" notification.getTitle(),"},{"lineNumber":159,"author":{"gitId":"-"},"content":" getTableDisplayDateString(notification.getStartTime()),"},{"lineNumber":160,"author":{"gitId":"-"},"content":" getTableDisplayDateString(notification.getEndTime()),"},{"lineNumber":161,"author":{"gitId":"-"},"content":" notification.getTargetUser().toString(),"},{"lineNumber":162,"author":{"gitId":"-"},"content":" getNotificationStyle(notification.getStyle()),"},{"lineNumber":163,"author":{"gitId":"-"},"content":" };"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" private String getTimezone() {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" return notificationsTimezone.getText().replace(\"All dates are displayed in \", \"\").replace(\" time.\", \"\");"},{"lineNumber":168,"author":{"gitId":"-"},"content":" }"},{"lineNumber":169,"author":{"gitId":"-"},"content":""},{"lineNumber":170,"author":{"gitId":"-"},"content":" private String getInputTimeString(Instant instant) {"},{"lineNumber":171,"author":{"gitId":"-"},"content":" String timezone \u003d getTimezone();"},{"lineNumber":172,"author":{"gitId":"-"},"content":" ZonedDateTime dateTime \u003d instant.atZone(ZoneId.of(timezone));"},{"lineNumber":173,"author":{"gitId":"-"},"content":" if (dateTime.getHour() \u003d\u003d 0 \u0026\u0026 dateTime.getMinute() \u003d\u003d 0) {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" return \"23:59H\";"},{"lineNumber":175,"author":{"gitId":"-"},"content":" }"},{"lineNumber":176,"author":{"gitId":"-"},"content":" return getDisplayedDateTime(instant, timezone, \"HH:00\") + \"H\";"},{"lineNumber":177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" private String getTableDisplayDateString(Instant date) {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" return getDisplayedDateTime(date, getTimezone(), \"d MMM h:mm a\");"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" private String getTargetUserText(NotificationTargetUser userType) {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" switch (userType) {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" case STUDENT:"},{"lineNumber":186,"author":{"gitId":"-"},"content":" return \"Students\";"},{"lineNumber":187,"author":{"gitId":"-"},"content":" case INSTRUCTOR:"},{"lineNumber":188,"author":{"gitId":"-"},"content":" return \"Instructors\";"},{"lineNumber":189,"author":{"gitId":"-"},"content":" case GENERAL:"},{"lineNumber":190,"author":{"gitId":"-"},"content":" return \"General (for both students and instructors)\";"},{"lineNumber":191,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":192,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":" }"},{"lineNumber":195,"author":{"gitId":"-"},"content":""},{"lineNumber":196,"author":{"gitId":"-"},"content":" private String getNotificationStyle(NotificationStyle style) {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" switch (style) {"},{"lineNumber":198,"author":{"gitId":"-"},"content":" case PRIMARY:"},{"lineNumber":199,"author":{"gitId":"-"},"content":" return \"Primary (blue)\";"},{"lineNumber":200,"author":{"gitId":"-"},"content":" case SECONDARY:"},{"lineNumber":201,"author":{"gitId":"-"},"content":" return \"Secondary (grey)\";"},{"lineNumber":202,"author":{"gitId":"-"},"content":" case SUCCESS:"},{"lineNumber":203,"author":{"gitId":"-"},"content":" return \"Success (green)\";"},{"lineNumber":204,"author":{"gitId":"-"},"content":" case DANGER:"},{"lineNumber":205,"author":{"gitId":"-"},"content":" return \"Danger (red)\";"},{"lineNumber":206,"author":{"gitId":"-"},"content":" case WARNING:"},{"lineNumber":207,"author":{"gitId":"-"},"content":" return \"Warning (yellow)\";"},{"lineNumber":208,"author":{"gitId":"-"},"content":" case INFO:"},{"lineNumber":209,"author":{"gitId":"-"},"content":" return \"Info (cyan)\";"},{"lineNumber":210,"author":{"gitId":"-"},"content":" case LIGHT:"},{"lineNumber":211,"author":{"gitId":"-"},"content":" return \"Light\";"},{"lineNumber":212,"author":{"gitId":"-"},"content":" case DARK:"},{"lineNumber":213,"author":{"gitId":"-"},"content":" return \"Dark\";"},{"lineNumber":214,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":215,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":216,"author":{"gitId":"-"},"content":" }"},{"lineNumber":217,"author":{"gitId":"-"},"content":" }"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":10,"-":209}},{"path":"src/e2e/java/teammates/e2e/pageobjects/AdminSearchPage.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.pageobjects;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertEquals;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertFalse;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertNotEquals;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.openqa.selenium.By;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.openqa.selenium.NoSuchElementException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import org.openqa.selenium.WebElement;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.openqa.selenium.support.FindBy;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountRequestAttributes;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.util.StringHelper;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"-"},"content":" * Represents the admin home page of the website."},{"lineNumber":27,"author":{"gitId":"-"},"content":" */"},{"lineNumber":28,"author":{"gitId":"-"},"content":"public class AdminSearchPage extends AppPage {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" private static final int STUDENT_COL_DETAILS \u003d 1;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" private static final int STUDENT_COL_NAME \u003d 2;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" private static final int STUDENT_COL_GOOGLE_ID \u003d 3;"},{"lineNumber":32,"author":{"gitId":"-"},"content":" private static final int STUDENT_COL_INSTITUTE \u003d 4;"},{"lineNumber":33,"author":{"gitId":"-"},"content":" private static final int STUDENT_COL_COMMENTS \u003d 5;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" private static final int STUDENT_COL_OPTIONS \u003d 6;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" private static final int INSTRUCTOR_COL_COURSE_ID \u003d 1;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" private static final int INSTRUCTOR_COL_NAME \u003d 2;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" private static final int INSTRUCTOR_COL_GOOGLE_ID \u003d 3;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" private static final int INSTRUCTOR_COL_INSTITUTE \u003d 4;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" private static final int INSTRUCTOR_COL_OPTIONS \u003d 5;"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" private static final int ACCOUNT_REQUEST_COL_NAME \u003d 1;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" private static final int ACCOUNT_REQUEST_COL_EMAIL \u003d 2;"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" private static final int ACCOUNT_REQUEST_COL_INSTITUTE \u003d 4;"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" private static final int ACCOUNT_REQUEST_COL_CREATED_AT \u003d 5;"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" private static final int ACCOUNT_REQUEST_COL_REGISTERED_AT \u003d 6;"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" private static final String EXPANDED_ROWS_HEADER_EMAIL \u003d \"Email\";"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private static final String EXPANDED_ROWS_HEADER_COURSE_JOIN_LINK \u003d \"Course Join Link\";"},{"lineNumber":50,"author":{"gitId":"-"},"content":" private static final String EXPANDED_ROWS_HEADER_ACCOUNT_REGISTRATION_LINK \u003d \"Account Registration Link\";"},{"lineNumber":51,"author":{"gitId":"-"},"content":" private static final String LINK_TEXT_RESET_GOOGLE_ID \u003d \"Reset Google ID\";"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"search-box\")"},{"lineNumber":54,"author":{"gitId":"-"},"content":" private WebElement inputBox;"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"search-button\")"},{"lineNumber":57,"author":{"gitId":"-"},"content":" private WebElement searchButton;"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"show-student-links\")"},{"lineNumber":60,"author":{"gitId":"-"},"content":" private WebElement expandStudentLinksButton;"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"show-instructor-links\")"},{"lineNumber":63,"author":{"gitId":"-"},"content":" private WebElement expandInstructorLinksButton;"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"show-account-request-links\")"},{"lineNumber":66,"author":{"gitId":"-"},"content":" private WebElement expandAccountRequestLinksButton;"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"hide-student-links\")"},{"lineNumber":69,"author":{"gitId":"-"},"content":" private WebElement collapseStudentLinksButton;"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"hide-instructor-links\")"},{"lineNumber":72,"author":{"gitId":"-"},"content":" private WebElement collapseInstructorLinksButton;"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"hide-account-request-links\")"},{"lineNumber":75,"author":{"gitId":"-"},"content":" private WebElement collapseAccountRequestLinksButton;"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" public AdminSearchPage(Browser browser) {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" super(browser);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" }"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":82,"author":{"gitId":"-"},"content":" protected boolean containsExpectedPageContents() {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" return getPageSource().contains(\"Admin Search\u003c/h1\u003e\");"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" public void inputSearchContent(String content) {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" inputBox.sendKeys(content);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" public void clearSearchBox() {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" inputBox.clear();"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" public void clickSearchButton() {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" click(searchButton);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":97,"author":{"gitId":"-"},"content":" }"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" public void regenerateStudentKey(Student student) {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":101,"author":{"gitId":"-"},"content":" studentRow.findElement(By.xpath(\"//button[text()\u003d\u0027Regenerate key\u0027]\")).click();"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":104,"author":{"gitId":"-"},"content":" waitForPageToLoad(true);"},{"lineNumber":105,"author":{"gitId":"-"},"content":" }"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" public void regenerateStudentKey(StudentAttributes student) {"},{"lineNumber":108,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" studentRow.findElement(By.xpath(\"//button[text()\u003d\u0027Regenerate key\u0027]\")).click();"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":112,"author":{"gitId":"-"},"content":" waitForPageToLoad(true);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" }"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" public void verifyRegenerateStudentKey(Student student, String originalJoinLink) {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" verifyStatusMessage(\"Student\u0027s key for this course has been successfully regenerated,\""},{"lineNumber":117,"author":{"gitId":"-"},"content":" + \" and the email has been sent.\");"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" String regeneratedJoinLink \u003d getStudentJoinLink(student);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" assertNotEquals(regeneratedJoinLink, originalJoinLink);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" }"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" public void verifyRegenerateStudentKey(StudentAttributes student, String originalJoinLink) {"},{"lineNumber":124,"author":{"gitId":"-"},"content":" verifyStatusMessage(\"Student\u0027s key for this course has been successfully regenerated,\""},{"lineNumber":125,"author":{"gitId":"-"},"content":" + \" and the email has been sent.\");"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" String regeneratedJoinLink \u003d getStudentJoinLink(student);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" assertNotEquals(regeneratedJoinLink, originalJoinLink);"},{"lineNumber":129,"author":{"gitId":"-"},"content":" }"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" public void regenerateInstructorKey(Instructor instructor) {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" instructorRow.findElement(By.xpath(\"//button[text()\u003d\u0027Regenerate key\u0027]\")).click();"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":136,"author":{"gitId":"-"},"content":" waitForPageToLoad(true);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" public void regenerateInstructorKey(InstructorAttributes instructor) {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":141,"author":{"gitId":"-"},"content":" instructorRow.findElement(By.xpath(\"//button[text()\u003d\u0027Regenerate key\u0027]\")).click();"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":144,"author":{"gitId":"-"},"content":" waitForPageToLoad(true);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" public void clickExpandStudentLinks() {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" click(expandStudentLinksButton);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":150,"author":{"gitId":"-"},"content":" }"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" public void clickExpandInstructorLinks() {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" click(expandInstructorLinksButton);"},{"lineNumber":154,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":155,"author":{"gitId":"-"},"content":" }"},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"-"},"content":" public void clickExpandAccountRequestLinks() {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" click(expandAccountRequestLinksButton);"},{"lineNumber":159,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":160,"author":{"gitId":"-"},"content":" }"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"-"},"content":" public void clickCollapseStudentLinks() {"},{"lineNumber":163,"author":{"gitId":"-"},"content":" click(collapseStudentLinksButton);"},{"lineNumber":164,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" public void clickCollapseInstructorLinks() {"},{"lineNumber":168,"author":{"gitId":"-"},"content":" click(collapseInstructorLinksButton);"},{"lineNumber":169,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":170,"author":{"gitId":"-"},"content":" }"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" public void clickCollapseAccountRequestLinks() {"},{"lineNumber":173,"author":{"gitId":"-"},"content":" click(collapseAccountRequestLinksButton);"},{"lineNumber":174,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":175,"author":{"gitId":"-"},"content":" }"},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":" public String removeSpanFromText(String text) {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" return text.replace(\"\u003cspan class\u003d\\\"highlighted-text\\\"\u003e\", \"\").replace(\"\u003c/span\u003e\", \"\");"},{"lineNumber":179,"author":{"gitId":"-"},"content":" }"},{"lineNumber":180,"author":{"gitId":"-"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":" public WebElement getStudentRow(Student student) {"},{"lineNumber":182,"author":{"gitId":"-"},"content":" String details \u003d String.format(\"%s [%s] (%s)\", student.getCourse().getId(),"},{"lineNumber":183,"author":{"gitId":"-"},"content":" student.getSection() \u003d\u003d null"},{"lineNumber":184,"author":{"gitId":"-"},"content":" ? Const.DEFAULT_SECTION"},{"lineNumber":185,"author":{"gitId":"-"},"content":" : student.getSection().getName(), student.getTeam().getName());"},{"lineNumber":186,"author":{"gitId":"-"},"content":" WebElement table \u003d browser.driver.findElement(By.id(\"search-table-student\"));"},{"lineNumber":187,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d table.findElements(By.tagName(\"tr\"));"},{"lineNumber":188,"author":{"gitId":"-"},"content":" for (WebElement row : rows) {"},{"lineNumber":189,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e columns \u003d row.findElements(By.tagName(\"td\"));"},{"lineNumber":190,"author":{"gitId":"-"},"content":" if (!columns.isEmpty() \u0026\u0026 removeSpanFromText(columns.get(STUDENT_COL_DETAILS - 1)"},{"lineNumber":191,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(details)"},{"lineNumber":192,"author":{"gitId":"-"},"content":" \u0026\u0026 removeSpanFromText(columns.get(STUDENT_COL_NAME - 1)"},{"lineNumber":193,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(student.getName())) {"},{"lineNumber":194,"author":{"gitId":"-"},"content":" return row;"},{"lineNumber":195,"author":{"gitId":"-"},"content":" }"},{"lineNumber":196,"author":{"gitId":"-"},"content":" }"},{"lineNumber":197,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":198,"author":{"gitId":"-"},"content":" }"},{"lineNumber":199,"author":{"gitId":"-"},"content":""},{"lineNumber":200,"author":{"gitId":"-"},"content":" public WebElement getStudentRow(StudentAttributes student) {"},{"lineNumber":201,"author":{"gitId":"-"},"content":" String details \u003d String.format(\"%s [%s] (%s)\", student.getCourse(),"},{"lineNumber":202,"author":{"gitId":"-"},"content":" student.getSection() \u003d\u003d null ? Const.DEFAULT_SECTION : student.getSection(), student.getTeam());"},{"lineNumber":203,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d browser.driver.findElements(By.cssSelector(\"#search-table-student tbody tr\"));"},{"lineNumber":204,"author":{"gitId":"-"},"content":" for (WebElement row : rows) {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e columns \u003d row.findElements(By.tagName(\"td\"));"},{"lineNumber":206,"author":{"gitId":"-"},"content":" if (removeSpanFromText(columns.get(STUDENT_COL_DETAILS - 1)"},{"lineNumber":207,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(details)"},{"lineNumber":208,"author":{"gitId":"-"},"content":" \u0026\u0026 removeSpanFromText(columns.get(STUDENT_COL_NAME - 1)"},{"lineNumber":209,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(student.getName())) {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" return row;"},{"lineNumber":211,"author":{"gitId":"-"},"content":" }"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":214,"author":{"gitId":"-"},"content":" }"},{"lineNumber":215,"author":{"gitId":"-"},"content":""},{"lineNumber":216,"author":{"gitId":"-"},"content":" public String getStudentDetails(WebElement studentRow) {"},{"lineNumber":217,"author":{"gitId":"-"},"content":" return getColumnText(studentRow, STUDENT_COL_DETAILS);"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" public String getStudentName(WebElement studentRow) {"},{"lineNumber":221,"author":{"gitId":"-"},"content":" return getColumnText(studentRow, STUDENT_COL_NAME);"},{"lineNumber":222,"author":{"gitId":"-"},"content":" }"},{"lineNumber":223,"author":{"gitId":"-"},"content":""},{"lineNumber":224,"author":{"gitId":"-"},"content":" public String getStudentGoogleId(WebElement studentRow) {"},{"lineNumber":225,"author":{"gitId":"-"},"content":" return getColumnText(studentRow, STUDENT_COL_GOOGLE_ID);"},{"lineNumber":226,"author":{"gitId":"-"},"content":" }"},{"lineNumber":227,"author":{"gitId":"-"},"content":""},{"lineNumber":228,"author":{"gitId":"-"},"content":" public String getStudentHomeLink(WebElement studentRow) {"},{"lineNumber":229,"author":{"gitId":"-"},"content":" return getColumnLink(studentRow, STUDENT_COL_GOOGLE_ID);"},{"lineNumber":230,"author":{"gitId":"-"},"content":" }"},{"lineNumber":231,"author":{"gitId":"-"},"content":""},{"lineNumber":232,"author":{"gitId":"-"},"content":" public String getStudentInstitute(WebElement studentRow) {"},{"lineNumber":233,"author":{"gitId":"-"},"content":" return getColumnText(studentRow, STUDENT_COL_INSTITUTE);"},{"lineNumber":234,"author":{"gitId":"-"},"content":" }"},{"lineNumber":235,"author":{"gitId":"-"},"content":""},{"lineNumber":236,"author":{"gitId":"-"},"content":" public String getStudentComments(WebElement studentRow) {"},{"lineNumber":237,"author":{"gitId":"-"},"content":" return getColumnText(studentRow, STUDENT_COL_COMMENTS);"},{"lineNumber":238,"author":{"gitId":"-"},"content":" }"},{"lineNumber":239,"author":{"gitId":"-"},"content":""},{"lineNumber":240,"author":{"gitId":"-"},"content":" public String getStudentManageAccountLink(WebElement studentRow) {"},{"lineNumber":241,"author":{"gitId":"-"},"content":" return getColumnLink(studentRow, STUDENT_COL_OPTIONS);"},{"lineNumber":242,"author":{"gitId":"-"},"content":" }"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" public String getStudentEmail(WebElement studentRow) {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" return getExpandedRowInputValue(studentRow, EXPANDED_ROWS_HEADER_EMAIL);"},{"lineNumber":246,"author":{"gitId":"-"},"content":" }"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" public String getStudentJoinLink(WebElement studentRow) {"},{"lineNumber":249,"author":{"gitId":"-"},"content":" return getExpandedRowInputValue(studentRow, EXPANDED_ROWS_HEADER_COURSE_JOIN_LINK);"},{"lineNumber":250,"author":{"gitId":"-"},"content":" }"},{"lineNumber":251,"author":{"gitId":"-"},"content":""},{"lineNumber":252,"author":{"gitId":"-"},"content":" public String getStudentJoinLink(Student student) {"},{"lineNumber":253,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":254,"author":{"gitId":"-"},"content":" return getStudentJoinLink(studentRow);"},{"lineNumber":255,"author":{"gitId":"-"},"content":" }"},{"lineNumber":256,"author":{"gitId":"-"},"content":""},{"lineNumber":257,"author":{"gitId":"-"},"content":" public String getStudentJoinLink(StudentAttributes student) {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":259,"author":{"gitId":"-"},"content":" return getStudentJoinLink(studentRow);"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":""},{"lineNumber":262,"author":{"gitId":"-"},"content":" public void resetStudentGoogleId(Student student) {"},{"lineNumber":263,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":264,"author":{"gitId":"-"},"content":" WebElement link \u003d studentRow.findElement(By.linkText(LINK_TEXT_RESET_GOOGLE_ID));"},{"lineNumber":265,"author":{"gitId":"-"},"content":" link.click();"},{"lineNumber":266,"author":{"gitId":"-"},"content":""},{"lineNumber":267,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":268,"author":{"gitId":"-"},"content":" waitForElementStaleness(link);"},{"lineNumber":269,"author":{"gitId":"-"},"content":" }"},{"lineNumber":270,"author":{"gitId":"-"},"content":""},{"lineNumber":271,"author":{"gitId":"-"},"content":" public void resetStudentGoogleId(StudentAttributes student) {"},{"lineNumber":272,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":273,"author":{"gitId":"-"},"content":" WebElement link \u003d studentRow.findElement(By.linkText(LINK_TEXT_RESET_GOOGLE_ID));"},{"lineNumber":274,"author":{"gitId":"-"},"content":" link.click();"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":277,"author":{"gitId":"-"},"content":" waitForElementStaleness(link);"},{"lineNumber":278,"author":{"gitId":"-"},"content":" }"},{"lineNumber":279,"author":{"gitId":"-"},"content":""},{"lineNumber":280,"author":{"gitId":"-"},"content":" public WebElement getInstructorRow(Instructor instructor) {"},{"lineNumber":281,"author":{"gitId":"-"},"content":" WebElement table \u003d browser.driver.findElement(By.id(\"search-table-instructor\"));"},{"lineNumber":282,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d table.findElements(By.tagName(\"tr\"));"},{"lineNumber":283,"author":{"gitId":"-"},"content":" for (WebElement row : rows) {"},{"lineNumber":284,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e columns \u003d row.findElements(By.tagName(\"td\"));"},{"lineNumber":285,"author":{"gitId":"-"},"content":" if (columns.size() \u003e\u003d 3 \u0026\u0026 (removeSpanFromText(columns.get(2)"},{"lineNumber":286,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(instructor.getGoogleId())"},{"lineNumber":287,"author":{"gitId":"-"},"content":" || removeSpanFromText(columns.get(1)"},{"lineNumber":288,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(instructor.getName()))) {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" return row;"},{"lineNumber":290,"author":{"gitId":"-"},"content":" }"},{"lineNumber":291,"author":{"gitId":"-"},"content":" }"},{"lineNumber":292,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":293,"author":{"gitId":"-"},"content":" }"},{"lineNumber":294,"author":{"gitId":"-"},"content":""},{"lineNumber":295,"author":{"gitId":"-"},"content":" public WebElement getInstructorRow(InstructorAttributes instructor) {"},{"lineNumber":296,"author":{"gitId":"-"},"content":" String courseId \u003d instructor.getCourseId();"},{"lineNumber":297,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d browser.driver.findElements(By.cssSelector(\"#search-table-instructor tbody tr\"));"},{"lineNumber":298,"author":{"gitId":"-"},"content":" for (WebElement row : rows) {"},{"lineNumber":299,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e columns \u003d row.findElements(By.tagName(\"td\"));"},{"lineNumber":300,"author":{"gitId":"-"},"content":" if (removeSpanFromText(columns.get(INSTRUCTOR_COL_COURSE_ID - 1)"},{"lineNumber":301,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(courseId)"},{"lineNumber":302,"author":{"gitId":"-"},"content":" \u0026\u0026 removeSpanFromText(columns.get(INSTRUCTOR_COL_NAME - 1)"},{"lineNumber":303,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(instructor.getName())) {"},{"lineNumber":304,"author":{"gitId":"-"},"content":" return row;"},{"lineNumber":305,"author":{"gitId":"-"},"content":" }"},{"lineNumber":306,"author":{"gitId":"-"},"content":" }"},{"lineNumber":307,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":308,"author":{"gitId":"-"},"content":" }"},{"lineNumber":309,"author":{"gitId":"-"},"content":""},{"lineNumber":310,"author":{"gitId":"-"},"content":" public String getInstructorCourseId(WebElement instructorRow) {"},{"lineNumber":311,"author":{"gitId":"-"},"content":" return getColumnText(instructorRow, INSTRUCTOR_COL_COURSE_ID);"},{"lineNumber":312,"author":{"gitId":"-"},"content":" }"},{"lineNumber":313,"author":{"gitId":"-"},"content":""},{"lineNumber":314,"author":{"gitId":"-"},"content":" public String getInstructorName(WebElement instructorRow) {"},{"lineNumber":315,"author":{"gitId":"-"},"content":" return getColumnText(instructorRow, INSTRUCTOR_COL_NAME);"},{"lineNumber":316,"author":{"gitId":"-"},"content":" }"},{"lineNumber":317,"author":{"gitId":"-"},"content":""},{"lineNumber":318,"author":{"gitId":"-"},"content":" public String getInstructorGoogleId(WebElement instructorRow) {"},{"lineNumber":319,"author":{"gitId":"-"},"content":" return getColumnText(instructorRow, INSTRUCTOR_COL_GOOGLE_ID);"},{"lineNumber":320,"author":{"gitId":"-"},"content":" }"},{"lineNumber":321,"author":{"gitId":"-"},"content":""},{"lineNumber":322,"author":{"gitId":"-"},"content":" public String getInstructorHomePageLink(WebElement instructorRow) {"},{"lineNumber":323,"author":{"gitId":"-"},"content":" return getColumnLink(instructorRow, INSTRUCTOR_COL_GOOGLE_ID);"},{"lineNumber":324,"author":{"gitId":"-"},"content":" }"},{"lineNumber":325,"author":{"gitId":"-"},"content":""},{"lineNumber":326,"author":{"gitId":"-"},"content":" public String getInstructorInstitute(WebElement instructorRow) {"},{"lineNumber":327,"author":{"gitId":"-"},"content":" return getColumnText(instructorRow, INSTRUCTOR_COL_INSTITUTE);"},{"lineNumber":328,"author":{"gitId":"-"},"content":" }"},{"lineNumber":329,"author":{"gitId":"-"},"content":""},{"lineNumber":330,"author":{"gitId":"-"},"content":" public String getInstructorManageAccountLink(WebElement instructorRow) {"},{"lineNumber":331,"author":{"gitId":"-"},"content":" return getColumnLink(instructorRow, INSTRUCTOR_COL_OPTIONS);"},{"lineNumber":332,"author":{"gitId":"-"},"content":" }"},{"lineNumber":333,"author":{"gitId":"-"},"content":""},{"lineNumber":334,"author":{"gitId":"-"},"content":" public String getInstructorEmail(WebElement instructorRow) {"},{"lineNumber":335,"author":{"gitId":"-"},"content":" return getExpandedRowInputValue(instructorRow, EXPANDED_ROWS_HEADER_EMAIL);"},{"lineNumber":336,"author":{"gitId":"-"},"content":" }"},{"lineNumber":337,"author":{"gitId":"-"},"content":""},{"lineNumber":338,"author":{"gitId":"-"},"content":" public String getInstructorJoinLink(WebElement instructorRow) {"},{"lineNumber":339,"author":{"gitId":"-"},"content":" return getExpandedRowInputValue(instructorRow, EXPANDED_ROWS_HEADER_COURSE_JOIN_LINK);"},{"lineNumber":340,"author":{"gitId":"-"},"content":" }"},{"lineNumber":341,"author":{"gitId":"-"},"content":""},{"lineNumber":342,"author":{"gitId":"-"},"content":" public String getInstructorJoinLink(Instructor instructor) {"},{"lineNumber":343,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":344,"author":{"gitId":"-"},"content":" return getInstructorJoinLink(instructorRow);"},{"lineNumber":345,"author":{"gitId":"-"},"content":" }"},{"lineNumber":346,"author":{"gitId":"-"},"content":""},{"lineNumber":347,"author":{"gitId":"-"},"content":" public String getInstructorJoinLink(InstructorAttributes instructor) {"},{"lineNumber":348,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":349,"author":{"gitId":"-"},"content":" return getInstructorJoinLink(instructorRow);"},{"lineNumber":350,"author":{"gitId":"-"},"content":" }"},{"lineNumber":351,"author":{"gitId":"-"},"content":""},{"lineNumber":352,"author":{"gitId":"-"},"content":" public void resetInstructorGoogleId(Instructor instructor) {"},{"lineNumber":353,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":354,"author":{"gitId":"-"},"content":" WebElement link \u003d instructorRow.findElement(By.linkText(LINK_TEXT_RESET_GOOGLE_ID));"},{"lineNumber":355,"author":{"gitId":"-"},"content":" link.click();"},{"lineNumber":356,"author":{"gitId":"-"},"content":""},{"lineNumber":357,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":358,"author":{"gitId":"-"},"content":" waitForElementStaleness(link);"},{"lineNumber":359,"author":{"gitId":"-"},"content":" }"},{"lineNumber":360,"author":{"gitId":"-"},"content":""},{"lineNumber":361,"author":{"gitId":"-"},"content":" public void resetInstructorGoogleId(InstructorAttributes instructor) {"},{"lineNumber":362,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":363,"author":{"gitId":"-"},"content":" WebElement link \u003d instructorRow.findElement(By.linkText(LINK_TEXT_RESET_GOOGLE_ID));"},{"lineNumber":364,"author":{"gitId":"-"},"content":" link.click();"},{"lineNumber":365,"author":{"gitId":"-"},"content":""},{"lineNumber":366,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":367,"author":{"gitId":"-"},"content":" waitForElementStaleness(link);"},{"lineNumber":368,"author":{"gitId":"-"},"content":" }"},{"lineNumber":369,"author":{"gitId":"-"},"content":""},{"lineNumber":370,"author":{"gitId":"-"},"content":" public WebElement getAccountRequestRow(AccountRequestAttributes accountRequest) {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" String email \u003d accountRequest.getEmail();"},{"lineNumber":372,"author":{"gitId":"-"},"content":" String institute \u003d accountRequest.getInstitute();"},{"lineNumber":373,"author":{"gitId":"domoberzin"},"content":" List\u003cWebElement\u003e rows \u003d browser.driver.findElements(By.cssSelector(\"tm-account-request-table tbody tr\"));"},{"lineNumber":374,"author":{"gitId":"-"},"content":" for (WebElement row : rows) {"},{"lineNumber":375,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e columns \u003d row.findElements(By.tagName(\"td\"));"},{"lineNumber":376,"author":{"gitId":"-"},"content":" if (removeSpanFromText(columns.get(ACCOUNT_REQUEST_COL_EMAIL - 1)"},{"lineNumber":377,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(email)"},{"lineNumber":378,"author":{"gitId":"-"},"content":" \u0026\u0026 removeSpanFromText(columns.get(ACCOUNT_REQUEST_COL_INSTITUTE - 1)"},{"lineNumber":379,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(institute)) {"},{"lineNumber":380,"author":{"gitId":"-"},"content":" return row;"},{"lineNumber":381,"author":{"gitId":"-"},"content":" }"},{"lineNumber":382,"author":{"gitId":"-"},"content":" }"},{"lineNumber":383,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":384,"author":{"gitId":"-"},"content":" }"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"domoberzin"},"content":" public WebElement getAccountRequestRow(AccountRequest accountRequest) {"},{"lineNumber":387,"author":{"gitId":"domoberzin"},"content":" String email \u003d accountRequest.getEmail();"},{"lineNumber":388,"author":{"gitId":"domoberzin"},"content":" String institute \u003d accountRequest.getInstitute();"},{"lineNumber":389,"author":{"gitId":"domoberzin"},"content":" List\u003cWebElement\u003e rows \u003d browser.driver.findElements(By.cssSelector(\"tm-account-request-table tbody tr\"));"},{"lineNumber":390,"author":{"gitId":"-"},"content":" for (WebElement row : rows) {"},{"lineNumber":391,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e columns \u003d row.findElements(By.tagName(\"td\"));"},{"lineNumber":392,"author":{"gitId":"-"},"content":" if (removeSpanFromText(columns.get(ACCOUNT_REQUEST_COL_EMAIL - 1)"},{"lineNumber":393,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(email)"},{"lineNumber":394,"author":{"gitId":"-"},"content":" \u0026\u0026 removeSpanFromText(columns.get(ACCOUNT_REQUEST_COL_INSTITUTE - 1)"},{"lineNumber":395,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(institute)) {"},{"lineNumber":396,"author":{"gitId":"-"},"content":" return row;"},{"lineNumber":397,"author":{"gitId":"-"},"content":" }"},{"lineNumber":398,"author":{"gitId":"-"},"content":" }"},{"lineNumber":399,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":400,"author":{"gitId":"-"},"content":" }"},{"lineNumber":401,"author":{"gitId":"-"},"content":""},{"lineNumber":402,"author":{"gitId":"-"},"content":" public String getAccountRequestName(WebElement accountRequestRow) {"},{"lineNumber":403,"author":{"gitId":"-"},"content":" return getColumnText(accountRequestRow, ACCOUNT_REQUEST_COL_NAME);"},{"lineNumber":404,"author":{"gitId":"-"},"content":" }"},{"lineNumber":405,"author":{"gitId":"-"},"content":""},{"lineNumber":406,"author":{"gitId":"-"},"content":" public String getAccountRequestEmail(WebElement accountRequestRow) {"},{"lineNumber":407,"author":{"gitId":"-"},"content":" return getColumnText(accountRequestRow, ACCOUNT_REQUEST_COL_EMAIL);"},{"lineNumber":408,"author":{"gitId":"-"},"content":" }"},{"lineNumber":409,"author":{"gitId":"-"},"content":""},{"lineNumber":410,"author":{"gitId":"-"},"content":" public String getAccountRequestInstitute(WebElement accountRequestRow) {"},{"lineNumber":411,"author":{"gitId":"-"},"content":" return getColumnText(accountRequestRow, ACCOUNT_REQUEST_COL_INSTITUTE);"},{"lineNumber":412,"author":{"gitId":"-"},"content":" }"},{"lineNumber":413,"author":{"gitId":"-"},"content":""},{"lineNumber":414,"author":{"gitId":"-"},"content":" public String getAccountRequestCreatedAt(WebElement accountRequestRow) {"},{"lineNumber":415,"author":{"gitId":"-"},"content":" return getColumnText(accountRequestRow, ACCOUNT_REQUEST_COL_CREATED_AT);"},{"lineNumber":416,"author":{"gitId":"-"},"content":" }"},{"lineNumber":417,"author":{"gitId":"-"},"content":""},{"lineNumber":418,"author":{"gitId":"-"},"content":" public String getAccountRequestRegisteredAt(WebElement accountRequestRow) {"},{"lineNumber":419,"author":{"gitId":"-"},"content":" return getColumnText(accountRequestRow, ACCOUNT_REQUEST_COL_REGISTERED_AT);"},{"lineNumber":420,"author":{"gitId":"-"},"content":" }"},{"lineNumber":421,"author":{"gitId":"-"},"content":""},{"lineNumber":422,"author":{"gitId":"-"},"content":" public String getAccountRequestRegistrationLink(WebElement accountRequestRow) {"},{"lineNumber":423,"author":{"gitId":"-"},"content":" return getExpandedRowInputValue(accountRequestRow, EXPANDED_ROWS_HEADER_ACCOUNT_REGISTRATION_LINK);"},{"lineNumber":424,"author":{"gitId":"-"},"content":" }"},{"lineNumber":425,"author":{"gitId":"-"},"content":""},{"lineNumber":426,"author":{"gitId":"-"},"content":" public void clickDeleteAccountRequestButton(AccountRequestAttributes accountRequest) {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":428,"author":{"gitId":"-"},"content":" WebElement deleteButton \u003d accountRequestRow.findElement(By.cssSelector(\"[id^\u003d\u0027delete-account-request-\u0027]\"));"},{"lineNumber":429,"author":{"gitId":"-"},"content":" deleteButton.click();"},{"lineNumber":430,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":431,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":432,"author":{"gitId":"-"},"content":" }"},{"lineNumber":433,"author":{"gitId":"-"},"content":""},{"lineNumber":434,"author":{"gitId":"domoberzin"},"content":" public void clickDeleteAccountRequestButton(AccountRequest accountRequest) {"},{"lineNumber":435,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":436,"author":{"gitId":"domoberzin"},"content":" WebElement deleteButton \u003d accountRequestRow.findElement(By.cssSelector(\"[id^\u003d\u0027delete-account-request-\u0027]\"));"},{"lineNumber":437,"author":{"gitId":"domoberzin"},"content":" deleteButton.click();"},{"lineNumber":438,"author":{"gitId":"domoberzin"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":439,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":440,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":441,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":442,"author":{"gitId":"domoberzin"},"content":" public void clickApproveAccountRequestButton(AccountRequest accountRequest) {"},{"lineNumber":443,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":444,"author":{"gitId":"domoberzin"},"content":" waitForElementPresence(By.cssSelector(\"[id^\u003d\u0027approve-account-request-\u0027]\"));"},{"lineNumber":445,"author":{"gitId":"domoberzin"},"content":" WebElement approveButton \u003d accountRequestRow.findElement(By.cssSelector(\"[id^\u003d\u0027approve-account-request-\u0027]\"));"},{"lineNumber":446,"author":{"gitId":"domoberzin"},"content":" waitForElementToBeClickable(approveButton);"},{"lineNumber":447,"author":{"gitId":"domoberzin"},"content":" approveButton.click();"},{"lineNumber":448,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":449,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":450,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":451,"author":{"gitId":"domoberzin"},"content":" public void clickRejectAccountRequestButton(AccountRequest accountRequest) {"},{"lineNumber":452,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":453,"author":{"gitId":"domoberzin"},"content":" WebElement rejectButton \u003d accountRequestRow.findElement(By.cssSelector(\"[id^\u003d\u0027reject-account-request-\u0027]\"));"},{"lineNumber":454,"author":{"gitId":"domoberzin"},"content":" rejectButton.click();"},{"lineNumber":455,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":456,"author":{"gitId":"domoberzin"},"content":" WebElement rejectWithoutReasonButton \u003d browser.driver.findElement(By.cssSelector(\"[id^\u003d\u0027reject-request-\u0027]\"));"},{"lineNumber":457,"author":{"gitId":"domoberzin"},"content":" rejectWithoutReasonButton.click();"},{"lineNumber":458,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":459,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":460,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":461,"author":{"gitId":"domoberzin"},"content":" public void clickRejectAccountRequestWithReasonButton(AccountRequest accountRequest) {"},{"lineNumber":462,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":463,"author":{"gitId":"domoberzin"},"content":" WebElement rejectButton \u003d accountRequestRow.findElement(By.cssSelector(\"[id^\u003d\u0027reject-account-request-\u0027]\"));"},{"lineNumber":464,"author":{"gitId":"domoberzin"},"content":" rejectButton.click();"},{"lineNumber":465,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":466,"author":{"gitId":"domoberzin"},"content":" WebElement rejectWithReasonButton \u003d browser.driver.findElement(By.cssSelector(\"[id^\u003d\u0027reject-request-with-reason\u0027]\"));"},{"lineNumber":467,"author":{"gitId":"domoberzin"},"content":" waitForElementToBeClickable(rejectWithReasonButton);"},{"lineNumber":468,"author":{"gitId":"domoberzin"},"content":" rejectWithReasonButton.click();"},{"lineNumber":469,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":470,"author":{"gitId":"domoberzin"},"content":" waitForElementPresence(By.cssSelector(\"tm-reject-with-reason-modal\"));"},{"lineNumber":471,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":472,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":473,"author":{"gitId":"domoberzin"},"content":" public void fillInRejectionModalTitle(String title) {"},{"lineNumber":474,"author":{"gitId":"domoberzin"},"content":" WebElement rejectionModal \u003d browser.driver.findElement(By.cssSelector(\"tm-reject-with-reason-modal\"));"},{"lineNumber":475,"author":{"gitId":"domoberzin"},"content":" WebElement titleInput \u003d rejectionModal.findElement(By.cssSelector(\"[id^\u003d\u0027rejection-reason-title\u0027]\"));"},{"lineNumber":476,"author":{"gitId":"domoberzin"},"content":" titleInput.clear();"},{"lineNumber":477,"author":{"gitId":"domoberzin"},"content":" titleInput.sendKeys(title);"},{"lineNumber":478,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":479,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":480,"author":{"gitId":"domoberzin"},"content":" public void fillInRejectionModalBody(String body) {"},{"lineNumber":481,"author":{"gitId":"domoberzin"},"content":" WebElement rejectionModal \u003d browser.driver.findElement(By.cssSelector(\"tm-reject-with-reason-modal\"));"},{"lineNumber":482,"author":{"gitId":"domoberzin"},"content":" WebElement bodyInput \u003d rejectionModal.findElement(By.cssSelector(\"tm-rich-text-editor\"));"},{"lineNumber":483,"author":{"gitId":"domoberzin"},"content":" clearRichTextEditor(bodyInput);"},{"lineNumber":484,"author":{"gitId":"domoberzin"},"content":" writeToRichTextEditor(bodyInput, body);"},{"lineNumber":485,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":486,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":487,"author":{"gitId":"domoberzin"},"content":" public void clickConfirmRejectAccountRequest() {"},{"lineNumber":488,"author":{"gitId":"domoberzin"},"content":" WebElement rejectionModal \u003d browser.driver.findElement(By.cssSelector(\"tm-reject-with-reason-modal\"));"},{"lineNumber":489,"author":{"gitId":"domoberzin"},"content":" WebElement clickReject \u003d rejectionModal.findElement(By.cssSelector(\"[id^\u003d\u0027btn-confirm-reject-request\u0027]\"));"},{"lineNumber":490,"author":{"gitId":"domoberzin"},"content":" clickReject.click();"},{"lineNumber":491,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":492,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":493,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":494,"author":{"gitId":"domoberzin"},"content":" public void closeRejectionModal() {"},{"lineNumber":495,"author":{"gitId":"domoberzin"},"content":" WebElement rejectionModal \u003d browser.driver.findElement(By.cssSelector(\"tm-reject-with-reason-modal\"));"},{"lineNumber":496,"author":{"gitId":"domoberzin"},"content":" WebElement clickCancel \u003d rejectionModal.findElement(By.cssSelector(\"[id^\u003d\u0027btn-cancel-reject-request\u0027]\"));"},{"lineNumber":497,"author":{"gitId":"domoberzin"},"content":" clickCancel.click();"},{"lineNumber":498,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":499,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":500,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":501,"author":{"gitId":"domoberzin"},"content":" public void clickEditAccountRequestButton(AccountRequest accountRequest) {"},{"lineNumber":502,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":503,"author":{"gitId":"domoberzin"},"content":" WebElement editButton \u003d accountRequestRow.findElement(By.cssSelector(\"[id^\u003d\u0027edit-account-request-\u0027]\"));"},{"lineNumber":504,"author":{"gitId":"domoberzin"},"content":" editButton.click();"},{"lineNumber":505,"author":{"gitId":"domoberzin"},"content":" waitForElementPresence(By.cssSelector(\"tm-edit-request-modal\"));"},{"lineNumber":506,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":507,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":508,"author":{"gitId":"domoberzin"},"content":" public void fillInEditModalFields(String name, String email, String institute, String comments) {"},{"lineNumber":509,"author":{"gitId":"domoberzin"},"content":" waitForElementPresence(By.cssSelector(\"tm-edit-request-modal\"));"},{"lineNumber":510,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":511,"author":{"gitId":"domoberzin"},"content":" WebElement editModal \u003d browser.driver.findElement(By.cssSelector(\"tm-edit-request-modal\"));"},{"lineNumber":512,"author":{"gitId":"domoberzin"},"content":" WebElement nameInput \u003d editModal.findElement(By.cssSelector(\"[id^\u003d\u0027request-name\u0027]\"));"},{"lineNumber":513,"author":{"gitId":"domoberzin"},"content":" nameInput.clear();"},{"lineNumber":514,"author":{"gitId":"domoberzin"},"content":" nameInput.sendKeys(name);"},{"lineNumber":515,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":516,"author":{"gitId":"domoberzin"},"content":" WebElement emailInput \u003d editModal.findElement(By.cssSelector(\"[id^\u003d\u0027request-email\u0027]\"));"},{"lineNumber":517,"author":{"gitId":"domoberzin"},"content":" emailInput.clear();"},{"lineNumber":518,"author":{"gitId":"domoberzin"},"content":" emailInput.sendKeys(email);"},{"lineNumber":519,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":520,"author":{"gitId":"domoberzin"},"content":" WebElement instituteInput \u003d editModal.findElement(By.cssSelector(\"[id^\u003d\u0027request-institution\u0027]\"));"},{"lineNumber":521,"author":{"gitId":"domoberzin"},"content":" instituteInput.clear();"},{"lineNumber":522,"author":{"gitId":"domoberzin"},"content":" instituteInput.sendKeys(institute);"},{"lineNumber":523,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":524,"author":{"gitId":"domoberzin"},"content":" WebElement commentsInput \u003d editModal.findElement(By.cssSelector(\"[id^\u003d\u0027request-comments\u0027]\"));"},{"lineNumber":525,"author":{"gitId":"domoberzin"},"content":" commentsInput.clear();"},{"lineNumber":526,"author":{"gitId":"domoberzin"},"content":" commentsInput.sendKeys(comments);"},{"lineNumber":527,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":528,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":529,"author":{"gitId":"domoberzin"},"content":" public void clickSaveEditAccountRequestButton() {"},{"lineNumber":530,"author":{"gitId":"domoberzin"},"content":" WebElement editModal \u003d browser.driver.findElement(By.cssSelector(\"tm-edit-request-modal\"));"},{"lineNumber":531,"author":{"gitId":"domoberzin"},"content":" WebElement saveButton \u003d editModal.findElement(By.cssSelector(\"[id^\u003d\u0027btn-confirm-edit-request\u0027]\"));"},{"lineNumber":532,"author":{"gitId":"domoberzin"},"content":" saveButton.click();"},{"lineNumber":533,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":534,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":535,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":536,"author":{"gitId":"domoberzin"},"content":" public void clickViewAccountRequestAndVerifyCommentsButton(AccountRequest accountRequest, String comments) {"},{"lineNumber":537,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":538,"author":{"gitId":"domoberzin"},"content":" WebElement viewCommentsButton \u003d accountRequestRow.findElement(By.cssSelector(\"[id^\u003d\u0027view-account-request-\u0027]\"));"},{"lineNumber":539,"author":{"gitId":"domoberzin"},"content":" viewCommentsButton.click();"},{"lineNumber":540,"author":{"gitId":"domoberzin"},"content":" waitForElementVisibility(By.className(\"modal-btn-ok\"));"},{"lineNumber":541,"author":{"gitId":"domoberzin"},"content":" WebElement modal \u003d browser.driver.findElement(By.className(\"modal-body\"));"},{"lineNumber":542,"author":{"gitId":"domoberzin"},"content":" String actualComments \u003d modal.findElement(By.tagName(\"div\")).getText();"},{"lineNumber":543,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"Comment: \" + comments, actualComments);"},{"lineNumber":544,"author":{"gitId":"domoberzin"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":545,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":546,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":547,"author":{"gitId":"-"},"content":" public void clickResetAccountRequestButton(AccountRequestAttributes accountRequest) {"},{"lineNumber":548,"author":{"gitId":"-"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":549,"author":{"gitId":"-"},"content":" WebElement deleteButton \u003d accountRequestRow.findElement(By.cssSelector(\"[id^\u003d\u0027reset-account-request-\u0027]\"));"},{"lineNumber":550,"author":{"gitId":"-"},"content":" deleteButton.click();"},{"lineNumber":551,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":552,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":553,"author":{"gitId":"-"},"content":" }"},{"lineNumber":554,"author":{"gitId":"-"},"content":""},{"lineNumber":555,"author":{"gitId":"domoberzin"},"content":" public void clickResetAccountRequestButton(AccountRequest accountRequest) {"},{"lineNumber":556,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":557,"author":{"gitId":"domoberzin"},"content":" WebElement deleteButton \u003d accountRequestRow.findElement(By.cssSelector(\"[id^\u003d\u0027reset-account-request-\u0027]\"));"},{"lineNumber":558,"author":{"gitId":"domoberzin"},"content":" deleteButton.click();"},{"lineNumber":559,"author":{"gitId":"domoberzin"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":560,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":561,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":562,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":563,"author":{"gitId":"-"},"content":" public int getNumExpandedRows(WebElement row) {"},{"lineNumber":564,"author":{"gitId":"-"},"content":" String xpath \u003d \"following-sibling::tr[1]/td/ul/li\";"},{"lineNumber":565,"author":{"gitId":"-"},"content":" return row.findElements(By.xpath(xpath)).size();"},{"lineNumber":566,"author":{"gitId":"-"},"content":" }"},{"lineNumber":567,"author":{"gitId":"-"},"content":""},{"lineNumber":568,"author":{"gitId":"-"},"content":" private String getColumnText(WebElement row, int columnNum) {"},{"lineNumber":569,"author":{"gitId":"-"},"content":" String xpath \u003d String.format(\"td[%d]\", columnNum);"},{"lineNumber":570,"author":{"gitId":"-"},"content":" return row.findElement(By.xpath(xpath)).getText();"},{"lineNumber":571,"author":{"gitId":"-"},"content":" }"},{"lineNumber":572,"author":{"gitId":"-"},"content":""},{"lineNumber":573,"author":{"gitId":"-"},"content":" private String getColumnLink(WebElement row, int columnNum) {"},{"lineNumber":574,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":575,"author":{"gitId":"-"},"content":" String xpath \u003d String.format(\"td[%d]/a\", columnNum);"},{"lineNumber":576,"author":{"gitId":"-"},"content":" return row.findElement(By.xpath(xpath)).getAttribute(\"href\");"},{"lineNumber":577,"author":{"gitId":"-"},"content":" } catch (NoSuchElementException e) {"},{"lineNumber":578,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":579,"author":{"gitId":"-"},"content":" }"},{"lineNumber":580,"author":{"gitId":"-"},"content":" }"},{"lineNumber":581,"author":{"gitId":"-"},"content":""},{"lineNumber":582,"author":{"gitId":"-"},"content":" private String getExpandedRowInputValue(WebElement row, String rowHeader) {"},{"lineNumber":583,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":584,"author":{"gitId":"-"},"content":" String xpath \u003d String.format(\"following-sibling::tr[1]/td/ul/li[contains(., \u0027%s\u0027)]/input\", rowHeader);"},{"lineNumber":585,"author":{"gitId":"-"},"content":" return row.findElement(By.xpath(xpath)).getAttribute(\"value\");"},{"lineNumber":586,"author":{"gitId":"-"},"content":" } catch (NoSuchElementException e) {"},{"lineNumber":587,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":588,"author":{"gitId":"-"},"content":" }"},{"lineNumber":589,"author":{"gitId":"-"},"content":" }"},{"lineNumber":590,"author":{"gitId":"-"},"content":""},{"lineNumber":591,"author":{"gitId":"-"},"content":" public void verifyStudentRowContent(Student student, Course course,"},{"lineNumber":592,"author":{"gitId":"-"},"content":" String expectedDetails, String expectedManageAccountLink,"},{"lineNumber":593,"author":{"gitId":"-"},"content":" String expectedHomePageLink) {"},{"lineNumber":594,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":595,"author":{"gitId":"-"},"content":" String actualDetails \u003d getStudentDetails(studentRow);"},{"lineNumber":596,"author":{"gitId":"-"},"content":" String actualName \u003d getStudentName(studentRow);"},{"lineNumber":597,"author":{"gitId":"-"},"content":" String actualGoogleId \u003d getStudentGoogleId(studentRow);"},{"lineNumber":598,"author":{"gitId":"-"},"content":" String actualHomepageLink \u003d getStudentHomeLink(studentRow);"},{"lineNumber":599,"author":{"gitId":"-"},"content":" String actualInstitute \u003d getStudentInstitute(studentRow);"},{"lineNumber":600,"author":{"gitId":"-"},"content":" String actualComment \u003d getStudentComments(studentRow);"},{"lineNumber":601,"author":{"gitId":"-"},"content":" String actualManageAccountLink \u003d getStudentManageAccountLink(studentRow);"},{"lineNumber":602,"author":{"gitId":"-"},"content":""},{"lineNumber":603,"author":{"gitId":"-"},"content":" String expectedName \u003d student.getName();"},{"lineNumber":604,"author":{"gitId":"-"},"content":" String expectedGoogleId \u003d StringHelper.convertToEmptyStringIfNull(student.getGoogleId());"},{"lineNumber":605,"author":{"gitId":"-"},"content":" String expectedInstitute \u003d StringHelper.convertToEmptyStringIfNull(course.getInstitute());"},{"lineNumber":606,"author":{"gitId":"-"},"content":" String expectedComment \u003d StringHelper.convertToEmptyStringIfNull(student.getComments());"},{"lineNumber":607,"author":{"gitId":"-"},"content":""},{"lineNumber":608,"author":{"gitId":"-"},"content":" assertEquals(expectedDetails, actualDetails);"},{"lineNumber":609,"author":{"gitId":"-"},"content":" assertEquals(expectedName, actualName);"},{"lineNumber":610,"author":{"gitId":"-"},"content":" assertEquals(expectedGoogleId, actualGoogleId);"},{"lineNumber":611,"author":{"gitId":"-"},"content":" assertEquals(expectedInstitute, actualInstitute);"},{"lineNumber":612,"author":{"gitId":"-"},"content":" assertEquals(expectedComment, actualComment);"},{"lineNumber":613,"author":{"gitId":"-"},"content":" assertEquals(expectedManageAccountLink, actualManageAccountLink);"},{"lineNumber":614,"author":{"gitId":"-"},"content":" assertEquals(expectedHomePageLink, actualHomepageLink);"},{"lineNumber":615,"author":{"gitId":"-"},"content":" }"},{"lineNumber":616,"author":{"gitId":"-"},"content":""},{"lineNumber":617,"author":{"gitId":"-"},"content":" public void verifyStudentRowContent(StudentAttributes student, CourseAttributes course,"},{"lineNumber":618,"author":{"gitId":"-"},"content":" String expectedDetails, String expectedManageAccountLink,"},{"lineNumber":619,"author":{"gitId":"-"},"content":" String expectedHomePageLink) {"},{"lineNumber":620,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":621,"author":{"gitId":"-"},"content":" String actualDetails \u003d getStudentDetails(studentRow);"},{"lineNumber":622,"author":{"gitId":"-"},"content":" String actualName \u003d getStudentName(studentRow);"},{"lineNumber":623,"author":{"gitId":"-"},"content":" String actualGoogleId \u003d getStudentGoogleId(studentRow);"},{"lineNumber":624,"author":{"gitId":"-"},"content":" String actualHomepageLink \u003d getStudentHomeLink(studentRow);"},{"lineNumber":625,"author":{"gitId":"-"},"content":" String actualInstitute \u003d getStudentInstitute(studentRow);"},{"lineNumber":626,"author":{"gitId":"-"},"content":" String actualComment \u003d getStudentComments(studentRow);"},{"lineNumber":627,"author":{"gitId":"-"},"content":" String actualManageAccountLink \u003d getStudentManageAccountLink(studentRow);"},{"lineNumber":628,"author":{"gitId":"-"},"content":""},{"lineNumber":629,"author":{"gitId":"-"},"content":" String expectedName \u003d student.getName();"},{"lineNumber":630,"author":{"gitId":"-"},"content":" String expectedGoogleId \u003d StringHelper.convertToEmptyStringIfNull(student.getGoogleId());"},{"lineNumber":631,"author":{"gitId":"-"},"content":" String expectedInstitute \u003d StringHelper.convertToEmptyStringIfNull(course.getInstitute());"},{"lineNumber":632,"author":{"gitId":"-"},"content":" String expectedComment \u003d StringHelper.convertToEmptyStringIfNull(student.getComments());"},{"lineNumber":633,"author":{"gitId":"-"},"content":""},{"lineNumber":634,"author":{"gitId":"-"},"content":" assertEquals(expectedDetails, actualDetails);"},{"lineNumber":635,"author":{"gitId":"-"},"content":" assertEquals(expectedName, actualName);"},{"lineNumber":636,"author":{"gitId":"-"},"content":" assertEquals(expectedGoogleId, actualGoogleId);"},{"lineNumber":637,"author":{"gitId":"-"},"content":" assertEquals(expectedInstitute, actualInstitute);"},{"lineNumber":638,"author":{"gitId":"-"},"content":" assertEquals(expectedComment, actualComment);"},{"lineNumber":639,"author":{"gitId":"-"},"content":" assertEquals(expectedManageAccountLink, actualManageAccountLink);"},{"lineNumber":640,"author":{"gitId":"-"},"content":" assertEquals(expectedHomePageLink, actualHomepageLink);"},{"lineNumber":641,"author":{"gitId":"-"},"content":" }"},{"lineNumber":642,"author":{"gitId":"-"},"content":""},{"lineNumber":643,"author":{"gitId":"-"},"content":" public void verifyStudentRowContentAfterReset(Student student, Course course) {"},{"lineNumber":644,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":645,"author":{"gitId":"-"},"content":" String actualName \u003d getStudentName(studentRow);"},{"lineNumber":646,"author":{"gitId":"-"},"content":" String actualInstitute \u003d getStudentInstitute(studentRow);"},{"lineNumber":647,"author":{"gitId":"-"},"content":" String actualComment \u003d getStudentComments(studentRow);"},{"lineNumber":648,"author":{"gitId":"-"},"content":""},{"lineNumber":649,"author":{"gitId":"-"},"content":" String expectedName \u003d student.getName();"},{"lineNumber":650,"author":{"gitId":"-"},"content":" String expectedInstitute \u003d StringHelper.convertToEmptyStringIfNull(course.getInstitute());"},{"lineNumber":651,"author":{"gitId":"-"},"content":" String expectedComment \u003d StringHelper.convertToEmptyStringIfNull(student.getComments());"},{"lineNumber":652,"author":{"gitId":"-"},"content":""},{"lineNumber":653,"author":{"gitId":"-"},"content":" assertEquals(expectedName, actualName);"},{"lineNumber":654,"author":{"gitId":"-"},"content":" assertEquals(expectedInstitute, actualInstitute);"},{"lineNumber":655,"author":{"gitId":"-"},"content":" assertEquals(expectedComment, actualComment);"},{"lineNumber":656,"author":{"gitId":"-"},"content":" }"},{"lineNumber":657,"author":{"gitId":"-"},"content":""},{"lineNumber":658,"author":{"gitId":"-"},"content":" public void verifyStudentExpandedLinks(Student student, int expectedNumExpandedRows) {"},{"lineNumber":659,"author":{"gitId":"-"},"content":" clickExpandStudentLinks();"},{"lineNumber":660,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":661,"author":{"gitId":"-"},"content":" String actualEmail \u003d getStudentEmail(studentRow);"},{"lineNumber":662,"author":{"gitId":"-"},"content":" String actualJoinLink \u003d getStudentJoinLink(studentRow);"},{"lineNumber":663,"author":{"gitId":"-"},"content":" int actualNumExpandedRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":664,"author":{"gitId":"-"},"content":""},{"lineNumber":665,"author":{"gitId":"-"},"content":" String expectedEmail \u003d student.getEmail();"},{"lineNumber":666,"author":{"gitId":"-"},"content":""},{"lineNumber":667,"author":{"gitId":"-"},"content":" assertEquals(expectedEmail, actualEmail);"},{"lineNumber":668,"author":{"gitId":"-"},"content":" assertNotEquals(\"\", actualJoinLink);"},{"lineNumber":669,"author":{"gitId":"-"},"content":" assertEquals(expectedNumExpandedRows, actualNumExpandedRows);"},{"lineNumber":670,"author":{"gitId":"-"},"content":" }"},{"lineNumber":671,"author":{"gitId":"-"},"content":""},{"lineNumber":672,"author":{"gitId":"-"},"content":" public void verifyStudentExpandedLinks(StudentAttributes student, int expectedNumExpandedRows) {"},{"lineNumber":673,"author":{"gitId":"-"},"content":" clickExpandStudentLinks();"},{"lineNumber":674,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":675,"author":{"gitId":"-"},"content":" String actualEmail \u003d getStudentEmail(studentRow);"},{"lineNumber":676,"author":{"gitId":"-"},"content":" String actualJoinLink \u003d getStudentJoinLink(studentRow);"},{"lineNumber":677,"author":{"gitId":"-"},"content":" int actualNumExpandedRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":678,"author":{"gitId":"-"},"content":""},{"lineNumber":679,"author":{"gitId":"-"},"content":" String expectedEmail \u003d student.getEmail();"},{"lineNumber":680,"author":{"gitId":"-"},"content":""},{"lineNumber":681,"author":{"gitId":"-"},"content":" assertEquals(expectedEmail, actualEmail);"},{"lineNumber":682,"author":{"gitId":"-"},"content":" assertNotEquals(\"\", actualJoinLink);"},{"lineNumber":683,"author":{"gitId":"-"},"content":" assertEquals(expectedNumExpandedRows, actualNumExpandedRows);"},{"lineNumber":684,"author":{"gitId":"-"},"content":" }"},{"lineNumber":685,"author":{"gitId":"-"},"content":""},{"lineNumber":686,"author":{"gitId":"-"},"content":" public void verifyInstructorRowContent(Instructor instructor, Course course,"},{"lineNumber":687,"author":{"gitId":"-"},"content":" String expectedManageAccountLink, String expectedHomePageLink) {"},{"lineNumber":688,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":689,"author":{"gitId":"-"},"content":" String actualCourseId \u003d getInstructorCourseId(instructorRow);"},{"lineNumber":690,"author":{"gitId":"-"},"content":" String actualName \u003d getInstructorName(instructorRow);"},{"lineNumber":691,"author":{"gitId":"-"},"content":" String actualGoogleId \u003d getInstructorGoogleId(instructorRow);"},{"lineNumber":692,"author":{"gitId":"-"},"content":" String actualHomePageLink \u003d getInstructorHomePageLink(instructorRow);"},{"lineNumber":693,"author":{"gitId":"-"},"content":" String actualInstitute \u003d getInstructorInstitute(instructorRow);"},{"lineNumber":694,"author":{"gitId":"-"},"content":" String actualManageAccountLink \u003d getInstructorManageAccountLink(instructorRow);"},{"lineNumber":695,"author":{"gitId":"-"},"content":""},{"lineNumber":696,"author":{"gitId":"-"},"content":" String expectedCourseId \u003d instructor.getCourseId();"},{"lineNumber":697,"author":{"gitId":"-"},"content":" String expectedName \u003d instructor.getName();"},{"lineNumber":698,"author":{"gitId":"-"},"content":" String expectedGoogleId \u003d StringHelper.convertToEmptyStringIfNull(instructor.getGoogleId());"},{"lineNumber":699,"author":{"gitId":"-"},"content":" String expectedInstitute \u003d StringHelper.convertToEmptyStringIfNull(course.getInstitute());"},{"lineNumber":700,"author":{"gitId":"-"},"content":""},{"lineNumber":701,"author":{"gitId":"-"},"content":" assertEquals(expectedCourseId, actualCourseId);"},{"lineNumber":702,"author":{"gitId":"-"},"content":" assertEquals(expectedName, actualName);"},{"lineNumber":703,"author":{"gitId":"-"},"content":" assertEquals(expectedGoogleId, actualGoogleId);"},{"lineNumber":704,"author":{"gitId":"-"},"content":" assertEquals(expectedHomePageLink, actualHomePageLink);"},{"lineNumber":705,"author":{"gitId":"-"},"content":" assertEquals(expectedInstitute, actualInstitute);"},{"lineNumber":706,"author":{"gitId":"-"},"content":" assertEquals(expectedManageAccountLink, actualManageAccountLink);"},{"lineNumber":707,"author":{"gitId":"-"},"content":" }"},{"lineNumber":708,"author":{"gitId":"-"},"content":""},{"lineNumber":709,"author":{"gitId":"-"},"content":" public void verifyInstructorRowContent(InstructorAttributes instructor, CourseAttributes course,"},{"lineNumber":710,"author":{"gitId":"-"},"content":" String expectedManageAccountLink, String expectedHomePageLink) {"},{"lineNumber":711,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":712,"author":{"gitId":"-"},"content":" String actualCourseId \u003d getInstructorCourseId(instructorRow);"},{"lineNumber":713,"author":{"gitId":"-"},"content":" String actualName \u003d getInstructorName(instructorRow);"},{"lineNumber":714,"author":{"gitId":"-"},"content":" String actualGoogleId \u003d getInstructorGoogleId(instructorRow);"},{"lineNumber":715,"author":{"gitId":"-"},"content":" String actualHomePageLink \u003d getInstructorHomePageLink(instructorRow);"},{"lineNumber":716,"author":{"gitId":"-"},"content":" String actualInstitute \u003d getInstructorInstitute(instructorRow);"},{"lineNumber":717,"author":{"gitId":"-"},"content":" String actualManageAccountLink \u003d getInstructorManageAccountLink(instructorRow);"},{"lineNumber":718,"author":{"gitId":"-"},"content":""},{"lineNumber":719,"author":{"gitId":"-"},"content":" String expectedCourseId \u003d instructor.getCourseId();"},{"lineNumber":720,"author":{"gitId":"-"},"content":" String expectedName \u003d instructor.getName();"},{"lineNumber":721,"author":{"gitId":"-"},"content":" String expectedGoogleId \u003d StringHelper.convertToEmptyStringIfNull(instructor.getGoogleId());"},{"lineNumber":722,"author":{"gitId":"-"},"content":" String expectedInstitute \u003d StringHelper.convertToEmptyStringIfNull(course.getInstitute());"},{"lineNumber":723,"author":{"gitId":"-"},"content":""},{"lineNumber":724,"author":{"gitId":"-"},"content":" assertEquals(expectedCourseId, actualCourseId);"},{"lineNumber":725,"author":{"gitId":"-"},"content":" assertEquals(expectedName, actualName);"},{"lineNumber":726,"author":{"gitId":"-"},"content":" assertEquals(expectedGoogleId, actualGoogleId);"},{"lineNumber":727,"author":{"gitId":"-"},"content":" assertEquals(expectedHomePageLink, actualHomePageLink);"},{"lineNumber":728,"author":{"gitId":"-"},"content":" assertEquals(expectedInstitute, actualInstitute);"},{"lineNumber":729,"author":{"gitId":"-"},"content":" assertEquals(expectedManageAccountLink, actualManageAccountLink);"},{"lineNumber":730,"author":{"gitId":"-"},"content":" }"},{"lineNumber":731,"author":{"gitId":"-"},"content":""},{"lineNumber":732,"author":{"gitId":"-"},"content":" public void verifyInstructorRowContentAfterReset(Instructor instructor, Course course) {"},{"lineNumber":733,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":734,"author":{"gitId":"-"},"content":" String actualCourseId \u003d getInstructorCourseId(instructorRow);"},{"lineNumber":735,"author":{"gitId":"-"},"content":" String actualName \u003d getInstructorName(instructorRow);"},{"lineNumber":736,"author":{"gitId":"-"},"content":" String actualInstitute \u003d getInstructorInstitute(instructorRow);"},{"lineNumber":737,"author":{"gitId":"-"},"content":""},{"lineNumber":738,"author":{"gitId":"-"},"content":" String expectedCourseId \u003d instructor.getCourseId();"},{"lineNumber":739,"author":{"gitId":"-"},"content":" String expectedName \u003d instructor.getName();"},{"lineNumber":740,"author":{"gitId":"-"},"content":" String expectedInstitute \u003d StringHelper.convertToEmptyStringIfNull(course.getInstitute());"},{"lineNumber":741,"author":{"gitId":"-"},"content":""},{"lineNumber":742,"author":{"gitId":"-"},"content":" assertEquals(expectedCourseId, actualCourseId);"},{"lineNumber":743,"author":{"gitId":"-"},"content":" assertEquals(expectedName, actualName);"},{"lineNumber":744,"author":{"gitId":"-"},"content":" assertEquals(expectedInstitute, actualInstitute);"},{"lineNumber":745,"author":{"gitId":"-"},"content":" }"},{"lineNumber":746,"author":{"gitId":"-"},"content":""},{"lineNumber":747,"author":{"gitId":"-"},"content":" public void verifyInstructorExpandedLinks(Instructor instructor) {"},{"lineNumber":748,"author":{"gitId":"-"},"content":" clickExpandInstructorLinks();"},{"lineNumber":749,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":750,"author":{"gitId":"-"},"content":" String actualEmail \u003d getInstructorEmail(instructorRow);"},{"lineNumber":751,"author":{"gitId":"-"},"content":" String actualJoinLink \u003d getInstructorJoinLink(instructorRow);"},{"lineNumber":752,"author":{"gitId":"-"},"content":""},{"lineNumber":753,"author":{"gitId":"-"},"content":" String expectedEmail \u003d instructor.getEmail();"},{"lineNumber":754,"author":{"gitId":"-"},"content":""},{"lineNumber":755,"author":{"gitId":"-"},"content":" assertEquals(expectedEmail, actualEmail);"},{"lineNumber":756,"author":{"gitId":"-"},"content":" assertNotEquals(\"\", actualJoinLink);"},{"lineNumber":757,"author":{"gitId":"-"},"content":" }"},{"lineNumber":758,"author":{"gitId":"-"},"content":""},{"lineNumber":759,"author":{"gitId":"-"},"content":" public void verifyInstructorExpandedLinks(InstructorAttributes instructor) {"},{"lineNumber":760,"author":{"gitId":"-"},"content":" clickExpandInstructorLinks();"},{"lineNumber":761,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":762,"author":{"gitId":"-"},"content":" String actualEmail \u003d getInstructorEmail(instructorRow);"},{"lineNumber":763,"author":{"gitId":"-"},"content":" String actualJoinLink \u003d getInstructorJoinLink(instructorRow);"},{"lineNumber":764,"author":{"gitId":"-"},"content":""},{"lineNumber":765,"author":{"gitId":"-"},"content":" String expectedEmail \u003d instructor.getEmail();"},{"lineNumber":766,"author":{"gitId":"-"},"content":""},{"lineNumber":767,"author":{"gitId":"-"},"content":" assertEquals(expectedEmail, actualEmail);"},{"lineNumber":768,"author":{"gitId":"-"},"content":" assertNotEquals(\"\", actualJoinLink);"},{"lineNumber":769,"author":{"gitId":"-"},"content":" }"},{"lineNumber":770,"author":{"gitId":"-"},"content":""},{"lineNumber":771,"author":{"gitId":"-"},"content":" public void verifyAccountRequestRowContent(AccountRequestAttributes accountRequest) {"},{"lineNumber":772,"author":{"gitId":"-"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":773,"author":{"gitId":"-"},"content":" String actualName \u003d getAccountRequestName(accountRequestRow);"},{"lineNumber":774,"author":{"gitId":"-"},"content":" String actualEmail \u003d getAccountRequestEmail(accountRequestRow);"},{"lineNumber":775,"author":{"gitId":"-"},"content":" String actualInstitute \u003d getAccountRequestInstitute(accountRequestRow);"},{"lineNumber":776,"author":{"gitId":"-"},"content":" String actualCreatedAt \u003d getAccountRequestCreatedAt(accountRequestRow);"},{"lineNumber":777,"author":{"gitId":"-"},"content":" String actualRegisteredAt \u003d getAccountRequestRegisteredAt(accountRequestRow);"},{"lineNumber":778,"author":{"gitId":"-"},"content":""},{"lineNumber":779,"author":{"gitId":"-"},"content":" assertEquals(accountRequest.getName(), actualName);"},{"lineNumber":780,"author":{"gitId":"-"},"content":" assertEquals(accountRequest.getEmail(), actualEmail);"},{"lineNumber":781,"author":{"gitId":"-"},"content":" assertEquals(accountRequest.getInstitute(), actualInstitute);"},{"lineNumber":782,"author":{"gitId":"-"},"content":" assertFalse(actualCreatedAt.isBlank());"},{"lineNumber":783,"author":{"gitId":"-"},"content":" if (accountRequest.getRegisteredAt() \u003d\u003d null) {"},{"lineNumber":784,"author":{"gitId":"-"},"content":" assertEquals(\"Not Registered Yet\", actualRegisteredAt);"},{"lineNumber":785,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":786,"author":{"gitId":"-"},"content":" assertFalse(actualRegisteredAt.isBlank());"},{"lineNumber":787,"author":{"gitId":"-"},"content":" }"},{"lineNumber":788,"author":{"gitId":"-"},"content":" }"},{"lineNumber":789,"author":{"gitId":"-"},"content":""},{"lineNumber":790,"author":{"gitId":"domoberzin"},"content":" public void verifyAccountRequestRowContent(AccountRequest accountRequest) {"},{"lineNumber":791,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":792,"author":{"gitId":"domoberzin"},"content":" String actualName \u003d getAccountRequestName(accountRequestRow);"},{"lineNumber":793,"author":{"gitId":"domoberzin"},"content":" String actualEmail \u003d getAccountRequestEmail(accountRequestRow);"},{"lineNumber":794,"author":{"gitId":"domoberzin"},"content":" String actualInstitute \u003d getAccountRequestInstitute(accountRequestRow);"},{"lineNumber":795,"author":{"gitId":"domoberzin"},"content":" String actualCreatedAt \u003d getAccountRequestCreatedAt(accountRequestRow);"},{"lineNumber":796,"author":{"gitId":"domoberzin"},"content":" String actualRegisteredAt \u003d getAccountRequestRegisteredAt(accountRequestRow);"},{"lineNumber":797,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":798,"author":{"gitId":"domoberzin"},"content":" assertEquals(accountRequest.getName(), actualName);"},{"lineNumber":799,"author":{"gitId":"domoberzin"},"content":" assertEquals(accountRequest.getEmail(), actualEmail);"},{"lineNumber":800,"author":{"gitId":"domoberzin"},"content":" assertEquals(accountRequest.getInstitute(), actualInstitute);"},{"lineNumber":801,"author":{"gitId":"domoberzin"},"content":" assertFalse(actualCreatedAt.isBlank());"},{"lineNumber":802,"author":{"gitId":"domoberzin"},"content":" if (accountRequest.getRegisteredAt() \u003d\u003d null) {"},{"lineNumber":803,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"Not Registered Yet\", actualRegisteredAt);"},{"lineNumber":804,"author":{"gitId":"domoberzin"},"content":" } else {"},{"lineNumber":805,"author":{"gitId":"domoberzin"},"content":" assertFalse(actualRegisteredAt.isBlank());"},{"lineNumber":806,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":807,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":808,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":809,"author":{"gitId":"-"},"content":" public void verifyAccountRequestExpandedLinks(AccountRequestAttributes accountRequest) {"},{"lineNumber":810,"author":{"gitId":"-"},"content":" clickExpandAccountRequestLinks();"},{"lineNumber":811,"author":{"gitId":"-"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":812,"author":{"gitId":"-"},"content":" String actualRegistrationLink \u003d getAccountRequestRegistrationLink(accountRequestRow);"},{"lineNumber":813,"author":{"gitId":"-"},"content":""},{"lineNumber":814,"author":{"gitId":"-"},"content":" assertFalse(actualRegistrationLink.isBlank());"},{"lineNumber":815,"author":{"gitId":"-"},"content":" }"},{"lineNumber":816,"author":{"gitId":"-"},"content":""},{"lineNumber":817,"author":{"gitId":"domoberzin"},"content":" public void verifyAccountRequestExpandedLinks(AccountRequest accountRequest) {"},{"lineNumber":818,"author":{"gitId":"domoberzin"},"content":" clickExpandAccountRequestLinks();"},{"lineNumber":819,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":820,"author":{"gitId":"domoberzin"},"content":" String actualRegistrationLink \u003d getAccountRequestRegistrationLink(accountRequestRow);"},{"lineNumber":821,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":822,"author":{"gitId":"domoberzin"},"content":" assertFalse(actualRegistrationLink.isBlank());"},{"lineNumber":823,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":824,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":825,"author":{"gitId":"-"},"content":" public void verifyLinkExpansionButtons(Student student,"},{"lineNumber":826,"author":{"gitId":"-"},"content":" Instructor instructor, AccountRequest accountRequest) {"},{"lineNumber":827,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":828,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":829,"author":{"gitId":"-"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":830,"author":{"gitId":"-"},"content":""},{"lineNumber":831,"author":{"gitId":"-"},"content":" clickExpandStudentLinks();"},{"lineNumber":832,"author":{"gitId":"-"},"content":" clickExpandInstructorLinks();"},{"lineNumber":833,"author":{"gitId":"-"},"content":" clickExpandAccountRequestLinks();"},{"lineNumber":834,"author":{"gitId":"-"},"content":" int numExpandedStudentRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":835,"author":{"gitId":"-"},"content":" int numExpandedInstructorRows \u003d getNumExpandedRows(instructorRow);"},{"lineNumber":836,"author":{"gitId":"-"},"content":" int numExpandedAccountRequestRows \u003d getNumExpandedRows(accountRequestRow);"},{"lineNumber":837,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedStudentRows, 0);"},{"lineNumber":838,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedInstructorRows, 0);"},{"lineNumber":839,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedAccountRequestRows, 0);"},{"lineNumber":840,"author":{"gitId":"-"},"content":""},{"lineNumber":841,"author":{"gitId":"-"},"content":" clickCollapseInstructorLinks();"},{"lineNumber":842,"author":{"gitId":"-"},"content":" numExpandedStudentRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":843,"author":{"gitId":"-"},"content":" numExpandedInstructorRows \u003d getNumExpandedRows(instructorRow);"},{"lineNumber":844,"author":{"gitId":"-"},"content":" numExpandedAccountRequestRows \u003d getNumExpandedRows(accountRequestRow);"},{"lineNumber":845,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedStudentRows, 0);"},{"lineNumber":846,"author":{"gitId":"-"},"content":" assertEquals(numExpandedInstructorRows, 0);"},{"lineNumber":847,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedAccountRequestRows, 0);"},{"lineNumber":848,"author":{"gitId":"-"},"content":""},{"lineNumber":849,"author":{"gitId":"-"},"content":" clickExpandInstructorLinks();"},{"lineNumber":850,"author":{"gitId":"-"},"content":" clickCollapseStudentLinks();"},{"lineNumber":851,"author":{"gitId":"-"},"content":" clickCollapseAccountRequestLinks();"},{"lineNumber":852,"author":{"gitId":"-"},"content":" waitUntilAnimationFinish();"},{"lineNumber":853,"author":{"gitId":"-"},"content":""},{"lineNumber":854,"author":{"gitId":"-"},"content":" numExpandedStudentRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":855,"author":{"gitId":"-"},"content":" numExpandedInstructorRows \u003d getNumExpandedRows(instructorRow);"},{"lineNumber":856,"author":{"gitId":"-"},"content":" numExpandedAccountRequestRows \u003d getNumExpandedRows(accountRequestRow);"},{"lineNumber":857,"author":{"gitId":"-"},"content":" assertEquals(numExpandedStudentRows, 0);"},{"lineNumber":858,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedInstructorRows, 0);"},{"lineNumber":859,"author":{"gitId":"-"},"content":" assertEquals(numExpandedAccountRequestRows, 0);"},{"lineNumber":860,"author":{"gitId":"-"},"content":" }"},{"lineNumber":861,"author":{"gitId":"-"},"content":""},{"lineNumber":862,"author":{"gitId":"-"},"content":" public void verifyLinkExpansionButtons(StudentAttributes student,"},{"lineNumber":863,"author":{"gitId":"-"},"content":" InstructorAttributes instructor, AccountRequestAttributes accountRequest) {"},{"lineNumber":864,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":865,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":866,"author":{"gitId":"-"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":867,"author":{"gitId":"-"},"content":""},{"lineNumber":868,"author":{"gitId":"-"},"content":" clickExpandStudentLinks();"},{"lineNumber":869,"author":{"gitId":"-"},"content":" clickExpandInstructorLinks();"},{"lineNumber":870,"author":{"gitId":"-"},"content":" clickExpandAccountRequestLinks();"},{"lineNumber":871,"author":{"gitId":"-"},"content":" int numExpandedStudentRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":872,"author":{"gitId":"-"},"content":" int numExpandedInstructorRows \u003d getNumExpandedRows(instructorRow);"},{"lineNumber":873,"author":{"gitId":"-"},"content":" int numExpandedAccountRequestRows \u003d getNumExpandedRows(accountRequestRow);"},{"lineNumber":874,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedStudentRows, 0);"},{"lineNumber":875,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedInstructorRows, 0);"},{"lineNumber":876,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedAccountRequestRows, 0);"},{"lineNumber":877,"author":{"gitId":"-"},"content":""},{"lineNumber":878,"author":{"gitId":"-"},"content":" clickCollapseInstructorLinks();"},{"lineNumber":879,"author":{"gitId":"-"},"content":" numExpandedStudentRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":880,"author":{"gitId":"-"},"content":" numExpandedInstructorRows \u003d getNumExpandedRows(instructorRow);"},{"lineNumber":881,"author":{"gitId":"-"},"content":" numExpandedAccountRequestRows \u003d getNumExpandedRows(accountRequestRow);"},{"lineNumber":882,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedStudentRows, 0);"},{"lineNumber":883,"author":{"gitId":"-"},"content":" assertEquals(numExpandedInstructorRows, 0);"},{"lineNumber":884,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedAccountRequestRows, 0);"},{"lineNumber":885,"author":{"gitId":"-"},"content":""},{"lineNumber":886,"author":{"gitId":"-"},"content":" clickExpandInstructorLinks();"},{"lineNumber":887,"author":{"gitId":"-"},"content":" clickCollapseStudentLinks();"},{"lineNumber":888,"author":{"gitId":"-"},"content":" clickCollapseAccountRequestLinks();"},{"lineNumber":889,"author":{"gitId":"-"},"content":" waitUntilAnimationFinish();"},{"lineNumber":890,"author":{"gitId":"-"},"content":""},{"lineNumber":891,"author":{"gitId":"-"},"content":" numExpandedStudentRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":892,"author":{"gitId":"-"},"content":" numExpandedInstructorRows \u003d getNumExpandedRows(instructorRow);"},{"lineNumber":893,"author":{"gitId":"-"},"content":" numExpandedAccountRequestRows \u003d getNumExpandedRows(accountRequestRow);"},{"lineNumber":894,"author":{"gitId":"-"},"content":" assertEquals(numExpandedStudentRows, 0);"},{"lineNumber":895,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedInstructorRows, 0);"},{"lineNumber":896,"author":{"gitId":"-"},"content":" assertEquals(numExpandedAccountRequestRows, 0);"},{"lineNumber":897,"author":{"gitId":"-"},"content":" }"},{"lineNumber":898,"author":{"gitId":"-"},"content":""},{"lineNumber":899,"author":{"gitId":"domoberzin"},"content":" public void verifyLinkExpansionButtons(StudentAttributes student,"},{"lineNumber":900,"author":{"gitId":"domoberzin"},"content":" InstructorAttributes instructor, AccountRequest accountRequest) {"},{"lineNumber":901,"author":{"gitId":"domoberzin"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":902,"author":{"gitId":"domoberzin"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":903,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":904,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":905,"author":{"gitId":"domoberzin"},"content":" clickExpandStudentLinks();"},{"lineNumber":906,"author":{"gitId":"domoberzin"},"content":" clickExpandInstructorLinks();"},{"lineNumber":907,"author":{"gitId":"domoberzin"},"content":" clickExpandAccountRequestLinks();"},{"lineNumber":908,"author":{"gitId":"domoberzin"},"content":" int numExpandedStudentRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":909,"author":{"gitId":"domoberzin"},"content":" int numExpandedInstructorRows \u003d getNumExpandedRows(instructorRow);"},{"lineNumber":910,"author":{"gitId":"-"},"content":" int numExpandedAccountRequestRows \u003d getNumExpandedRows(accountRequestRow);"},{"lineNumber":911,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedStudentRows, 0);"},{"lineNumber":912,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedInstructorRows, 0);"},{"lineNumber":913,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedAccountRequestRows, 0);"},{"lineNumber":914,"author":{"gitId":"-"},"content":""},{"lineNumber":915,"author":{"gitId":"-"},"content":" clickCollapseInstructorLinks();"},{"lineNumber":916,"author":{"gitId":"-"},"content":" numExpandedStudentRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":917,"author":{"gitId":"-"},"content":" numExpandedInstructorRows \u003d getNumExpandedRows(instructorRow);"},{"lineNumber":918,"author":{"gitId":"-"},"content":" numExpandedAccountRequestRows \u003d getNumExpandedRows(accountRequestRow);"},{"lineNumber":919,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedStudentRows, 0);"},{"lineNumber":920,"author":{"gitId":"-"},"content":" assertEquals(numExpandedInstructorRows, 0);"},{"lineNumber":921,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedAccountRequestRows, 0);"},{"lineNumber":922,"author":{"gitId":"-"},"content":""},{"lineNumber":923,"author":{"gitId":"-"},"content":" clickExpandInstructorLinks();"},{"lineNumber":924,"author":{"gitId":"-"},"content":" clickCollapseStudentLinks();"},{"lineNumber":925,"author":{"gitId":"-"},"content":" clickCollapseAccountRequestLinks();"},{"lineNumber":926,"author":{"gitId":"-"},"content":" waitUntilAnimationFinish();"},{"lineNumber":927,"author":{"gitId":"-"},"content":""},{"lineNumber":928,"author":{"gitId":"-"},"content":" numExpandedStudentRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":929,"author":{"gitId":"-"},"content":" numExpandedInstructorRows \u003d getNumExpandedRows(instructorRow);"},{"lineNumber":930,"author":{"gitId":"-"},"content":" numExpandedAccountRequestRows \u003d getNumExpandedRows(accountRequestRow);"},{"lineNumber":931,"author":{"gitId":"-"},"content":" assertEquals(numExpandedStudentRows, 0);"},{"lineNumber":932,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedInstructorRows, 0);"},{"lineNumber":933,"author":{"gitId":"-"},"content":" assertEquals(numExpandedAccountRequestRows, 0);"},{"lineNumber":934,"author":{"gitId":"-"},"content":" }"},{"lineNumber":935,"author":{"gitId":"-"},"content":""},{"lineNumber":936,"author":{"gitId":"-"},"content":" public void verifyRegenerateInstructorKey(Instructor instructor, String originalJoinLink) {"},{"lineNumber":937,"author":{"gitId":"-"},"content":" verifyStatusMessage(\"Instructor\u0027s key for this course has been successfully regenerated,\""},{"lineNumber":938,"author":{"gitId":"-"},"content":" + \" and the email has been sent.\");"},{"lineNumber":939,"author":{"gitId":"-"},"content":""},{"lineNumber":940,"author":{"gitId":"-"},"content":" String regeneratedJoinLink \u003d getInstructorJoinLink(instructor);"},{"lineNumber":941,"author":{"gitId":"-"},"content":" assertNotEquals(regeneratedJoinLink, originalJoinLink);"},{"lineNumber":942,"author":{"gitId":"-"},"content":" }"},{"lineNumber":943,"author":{"gitId":"-"},"content":""},{"lineNumber":944,"author":{"gitId":"-"},"content":" public void verifyRegenerateInstructorKey(InstructorAttributes instructor, String originalJoinLink) {"},{"lineNumber":945,"author":{"gitId":"-"},"content":" verifyStatusMessage(\"Instructor\u0027s key for this course has been successfully regenerated,\""},{"lineNumber":946,"author":{"gitId":"-"},"content":" + \" and the email has been sent.\");"},{"lineNumber":947,"author":{"gitId":"-"},"content":""},{"lineNumber":948,"author":{"gitId":"-"},"content":" String regeneratedJoinLink \u003d getInstructorJoinLink(instructor);"},{"lineNumber":949,"author":{"gitId":"-"},"content":" assertNotEquals(regeneratedJoinLink, originalJoinLink);"},{"lineNumber":950,"author":{"gitId":"-"},"content":" }"},{"lineNumber":951,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":168,"-":783}},{"path":"src/e2e/java/teammates/e2e/pageobjects/AppPage.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.pageobjects;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static com.google.common.base.Preconditions.checkNotNull;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertEquals;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertNotEquals;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertNotNull;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertTrue;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.io.File;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.io.IOException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import java.lang.reflect.Constructor;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import java.lang.reflect.InvocationTargetException;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import java.time.Duration;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import java.time.ZoneId;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import java.time.ZonedDateTime;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import java.time.format.DateTimeFormatter;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":19,"author":{"gitId":"yuanxi1"},"content":"import java.util.Locale;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":"import org.openqa.selenium.By;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import org.openqa.selenium.InvalidElementStateException;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import org.openqa.selenium.JavascriptExecutor;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import org.openqa.selenium.Keys;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import org.openqa.selenium.NoSuchElementException;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import org.openqa.selenium.WebDriverException;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import org.openqa.selenium.WebElement;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import org.openqa.selenium.remote.RemoteWebElement;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import org.openqa.selenium.remote.UselessFileDetector;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import org.openqa.selenium.support.PageFactory;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import org.openqa.selenium.support.ui.ExpectedCondition;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import org.openqa.selenium.support.ui.ExpectedConditions;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import org.openqa.selenium.support.ui.Select;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import org.openqa.selenium.support.ui.WebDriverWait;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.NotificationAttributes;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"import teammates.e2e.util.MaximumRetriesExceededException;"},{"lineNumber":41,"author":{"gitId":"-"},"content":"import teammates.e2e.util.RetryManager;"},{"lineNumber":42,"author":{"gitId":"-"},"content":"import teammates.e2e.util.Retryable;"},{"lineNumber":43,"author":{"gitId":"-"},"content":"import teammates.e2e.util.TestProperties;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"import teammates.test.FileHelper;"},{"lineNumber":45,"author":{"gitId":"-"},"content":"import teammates.test.ThreadHelper;"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":48,"author":{"gitId":"-"},"content":" * An abstract class that represents a browser-loaded page of the app and"},{"lineNumber":49,"author":{"gitId":"-"},"content":" * provides ways to interact with it. Also contains methods to validate some"},{"lineNumber":50,"author":{"gitId":"-"},"content":" * aspects of the page, e.g. HTML page source."},{"lineNumber":51,"author":{"gitId":"-"},"content":" *"},{"lineNumber":52,"author":{"gitId":"-"},"content":" * \u003cp\u003eNote: We are using the Page Object pattern here."},{"lineNumber":53,"author":{"gitId":"-"},"content":" *"},{"lineNumber":54,"author":{"gitId":"-"},"content":" * @see \u003ca href\u003d\"https://martinfowler.com/bliki/PageObject.html\"\u003ehttps://martinfowler.com/bliki/PageObject.html\u003c/a\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":" */"},{"lineNumber":56,"author":{"gitId":"-"},"content":"public abstract class AppPage {"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" private static final String CLEAR_ELEMENT_SCRIPT;"},{"lineNumber":59,"author":{"gitId":"-"},"content":" private static final String SCROLL_ELEMENT_TO_CENTER_AND_CLICK_SCRIPT;"},{"lineNumber":60,"author":{"gitId":"-"},"content":" private static final String READ_TINYMCE_CONTENT_SCRIPT;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" private static final String WRITE_TO_TINYMCE_SCRIPT;"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" static {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" CLEAR_ELEMENT_SCRIPT \u003d FileHelper.readFile(\"src/e2e/resources/scripts/clearElementWithoutEvents.js\");"},{"lineNumber":66,"author":{"gitId":"-"},"content":" SCROLL_ELEMENT_TO_CENTER_AND_CLICK_SCRIPT \u003d FileHelper"},{"lineNumber":67,"author":{"gitId":"-"},"content":" .readFile(\"src/e2e/resources/scripts/scrollElementToCenterAndClick.js\");"},{"lineNumber":68,"author":{"gitId":"-"},"content":" READ_TINYMCE_CONTENT_SCRIPT \u003d FileHelper.readFile(\"src/e2e/resources/scripts/readTinyMCEContent.js\");"},{"lineNumber":69,"author":{"gitId":"-"},"content":" WRITE_TO_TINYMCE_SCRIPT \u003d FileHelper.readFile(\"src/e2e/resources/scripts/writeToTinyMCE.js\");"},{"lineNumber":70,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":" }"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" /** Browser instance the page is loaded into. */"},{"lineNumber":76,"author":{"gitId":"-"},"content":" protected Browser browser;"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" /** Use for retrying due to transient UI issues. */"},{"lineNumber":79,"author":{"gitId":"-"},"content":" protected RetryManager uiRetryManager \u003d new RetryManager((TestProperties.TEST_TIMEOUT + 1) / 2);"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":82,"author":{"gitId":"-"},"content":" * Used by subclasses to create a {@code AppPage} object to wrap around the"},{"lineNumber":83,"author":{"gitId":"-"},"content":" * given {@code browser} object. Fails if the page content does not match"},{"lineNumber":84,"author":{"gitId":"-"},"content":" * the page type, as defined by the sub-class."},{"lineNumber":85,"author":{"gitId":"-"},"content":" */"},{"lineNumber":86,"author":{"gitId":"-"},"content":" public AppPage(Browser browser) {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" this.browser \u003d browser;"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" boolean isCorrectPageType;"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" isCorrectPageType \u003d containsExpectedPageContents();"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" if (isCorrectPageType) {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":96,"author":{"gitId":"-"},"content":" }"},{"lineNumber":97,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" // ignore and try again"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" // To minimize test failures due to eventual consistency, we try to"},{"lineNumber":102,"author":{"gitId":"-"},"content":" // reload the page and compare once more."},{"lineNumber":103,"author":{"gitId":"-"},"content":" System.out.println(\"#### Incorrect page type: going to try reloading the page.\");"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(2000);"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" reloadPage();"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" isCorrectPageType \u003d containsExpectedPageContents();"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" if (isCorrectPageType) {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":113,"author":{"gitId":"-"},"content":" }"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" System.out.println(\"######### Not in the correct page! ##########\");"},{"lineNumber":116,"author":{"gitId":"-"},"content":" throw new IllegalStateException(\"Not in the correct page!\");"},{"lineNumber":117,"author":{"gitId":"-"},"content":" }"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" public Browser getBrowser() {"},{"lineNumber":120,"author":{"gitId":"-"},"content":" return browser;"},{"lineNumber":121,"author":{"gitId":"-"},"content":" }"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":124,"author":{"gitId":"-"},"content":" * Gets a new page object representation of the currently open web page in the browser."},{"lineNumber":125,"author":{"gitId":"-"},"content":" *"},{"lineNumber":126,"author":{"gitId":"-"},"content":" * \u003cp\u003eFails if the new page content does not match content expected in a page of"},{"lineNumber":127,"author":{"gitId":"-"},"content":" * the type indicated by the parameter {@code typeOfPage}."},{"lineNumber":128,"author":{"gitId":"-"},"content":" */"},{"lineNumber":129,"author":{"gitId":"-"},"content":" public static \u003cT extends AppPage\u003e T getNewPageInstance(Browser currentBrowser, Class\u003cT\u003e typeOfPage) {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" waitUntilAnimationFinish(currentBrowser);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" Constructor\u003cT\u003e constructor \u003d typeOfPage.getConstructor(Browser.class);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" T page \u003d constructor.newInstance(currentBrowser);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" PageFactory.initElements(currentBrowser.driver, page);"},{"lineNumber":135,"author":{"gitId":"-"},"content":" page.waitForPageToLoad();"},{"lineNumber":136,"author":{"gitId":"-"},"content":" return page;"},{"lineNumber":137,"author":{"gitId":"-"},"content":" } catch (InvocationTargetException e) {"},{"lineNumber":138,"author":{"gitId":"-"},"content":" if (e.getCause() instanceof IllegalStateException) {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" throw (IllegalStateException) e.getCause();"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":142,"author":{"gitId":"-"},"content":" } catch (NoSuchMethodException | IllegalAccessException | InstantiationException e) {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":144,"author":{"gitId":"-"},"content":" }"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":148,"author":{"gitId":"-"},"content":" * Fails if the new page content does not match content expected in a page of"},{"lineNumber":149,"author":{"gitId":"-"},"content":" * the type indicated by the parameter {@code newPageType}."},{"lineNumber":150,"author":{"gitId":"-"},"content":" */"},{"lineNumber":151,"author":{"gitId":"-"},"content":" public \u003cT extends AppPage\u003e T changePageType(Class\u003cT\u003e newPageType) {"},{"lineNumber":152,"author":{"gitId":"-"},"content":" return getNewPageInstance(browser, newPageType);"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" public \u003cE\u003e E waitFor(ExpectedCondition\u003cE\u003e expectedCondition) {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" WebDriverWait wait \u003d new WebDriverWait(browser.driver, Duration.ofSeconds(TestProperties.TEST_TIMEOUT));"},{"lineNumber":157,"author":{"gitId":"-"},"content":" return wait.until(expectedCondition);"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":161,"author":{"gitId":"-"},"content":" * Waits until the page is fully loaded."},{"lineNumber":162,"author":{"gitId":"-"},"content":" */"},{"lineNumber":163,"author":{"gitId":"-"},"content":" public void waitForPageToLoad() {"},{"lineNumber":164,"author":{"gitId":"-"},"content":" waitForPageToLoad(false);"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":168,"author":{"gitId":"-"},"content":" * Waits until the page is fully loaded."},{"lineNumber":169,"author":{"gitId":"-"},"content":" *"},{"lineNumber":170,"author":{"gitId":"-"},"content":" * @param excludeToast Set this to true if toast message\u0027s disappearance should not be counted"},{"lineNumber":171,"author":{"gitId":"-"},"content":" * as criteria for page load\u0027s completion."},{"lineNumber":172,"author":{"gitId":"-"},"content":" */"},{"lineNumber":173,"author":{"gitId":"-"},"content":" public void waitForPageToLoad(boolean excludeToast) {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" browser.waitForPageLoad(excludeToast);"},{"lineNumber":175,"author":{"gitId":"-"},"content":" }"},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":" public void waitForElementVisibility(WebElement element) {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" waitFor(ExpectedConditions.visibilityOf(element));"},{"lineNumber":179,"author":{"gitId":"-"},"content":" }"},{"lineNumber":180,"author":{"gitId":"-"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":" public void waitForElementVisibility(By by) {"},{"lineNumber":182,"author":{"gitId":"-"},"content":" waitFor(ExpectedConditions.visibilityOfElementLocated(by));"},{"lineNumber":183,"author":{"gitId":"-"},"content":" }"},{"lineNumber":184,"author":{"gitId":"-"},"content":""},{"lineNumber":185,"author":{"gitId":"-"},"content":" public void waitForElementToBeClickable(WebElement element) {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" waitFor(ExpectedConditions.elementToBeClickable(element));"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":" public static void waitUntilAnimationFinish(Browser browser) {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" WebDriverWait wait \u003d new WebDriverWait(browser.driver, Duration.ofSeconds(TestProperties.TEST_TIMEOUT));"},{"lineNumber":191,"author":{"gitId":"-"},"content":" wait.until(ExpectedConditions.invisibilityOfElementLocated(By.className(\"ng-animating\")));"},{"lineNumber":192,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(1000);"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"-"},"content":" public void waitUntilAnimationFinish() {"},{"lineNumber":196,"author":{"gitId":"-"},"content":" waitUntilAnimationFinish(browser);"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":200,"author":{"gitId":"-"},"content":" * Waits until an element is no longer attached to the DOM or the timeout expires."},{"lineNumber":201,"author":{"gitId":"-"},"content":" * @param element the WebElement that expires after {@link TestProperties#TEST_TIMEOUT}"},{"lineNumber":202,"author":{"gitId":"-"},"content":" * @see org.openqa.selenium.support.ui.FluentWait#until(java.util.function.Function)"},{"lineNumber":203,"author":{"gitId":"-"},"content":" */"},{"lineNumber":204,"author":{"gitId":"-"},"content":" public void waitForElementStaleness(WebElement element) {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" waitFor(ExpectedConditions.stalenessOf(element));"},{"lineNumber":206,"author":{"gitId":"-"},"content":" }"},{"lineNumber":207,"author":{"gitId":"-"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" public void verifyUnclickable(WebElement element) {"},{"lineNumber":209,"author":{"gitId":"-"},"content":" if (\"a\".equals(element.getTagName())) {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" assertTrue(element.getAttribute(\"class\").contains(\"disabled\"));"},{"lineNumber":211,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" assertNotNull(element.getAttribute(\"disabled\"));"},{"lineNumber":213,"author":{"gitId":"-"},"content":" }"},{"lineNumber":214,"author":{"gitId":"-"},"content":" }"},{"lineNumber":215,"author":{"gitId":"-"},"content":""},{"lineNumber":216,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":217,"author":{"gitId":"-"},"content":" * Waits for a confirmation modal to appear and click the confirm button."},{"lineNumber":218,"author":{"gitId":"-"},"content":" */"},{"lineNumber":219,"author":{"gitId":"-"},"content":" public void waitForConfirmationModalAndClickOk() {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" waitForModalShown();"},{"lineNumber":221,"author":{"gitId":"-"},"content":" waitForElementVisibility(By.className(\"modal-btn-ok\"));"},{"lineNumber":222,"author":{"gitId":"-"},"content":" WebElement okayButton \u003d browser.driver.findElement(By.className(\"modal-btn-ok\"));"},{"lineNumber":223,"author":{"gitId":"-"},"content":" waitForElementToBeClickable(okayButton);"},{"lineNumber":224,"author":{"gitId":"-"},"content":" clickDismissModalButtonAndWaitForModalHidden(okayButton);"},{"lineNumber":225,"author":{"gitId":"-"},"content":" }"},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"-"},"content":" private void waitForModalShown() {"},{"lineNumber":228,"author":{"gitId":"-"},"content":" // Possible exploration: Change to listening to modal shown event as"},{"lineNumber":229,"author":{"gitId":"-"},"content":" // this is based on the implementation detail assumption that once modal-backdrop is added the modal is shown"},{"lineNumber":230,"author":{"gitId":"-"},"content":" waitForElementVisibility(By.className(\"modal-backdrop\"));"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" void waitForModalHidden(WebElement modalBackdrop) {"},{"lineNumber":234,"author":{"gitId":"-"},"content":" // Possible exploration: Change to listening to modal hidden event as"},{"lineNumber":235,"author":{"gitId":"-"},"content":" // this is based on the implementation detail assumption that once modal-backdrop is removed the modal is hidden"},{"lineNumber":236,"author":{"gitId":"-"},"content":" waitForElementStaleness(modalBackdrop);"},{"lineNumber":237,"author":{"gitId":"-"},"content":" }"},{"lineNumber":238,"author":{"gitId":"-"},"content":""},{"lineNumber":239,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":240,"author":{"gitId":"-"},"content":" * Waits for the element to appear in the page, up to the timeout specified."},{"lineNumber":241,"author":{"gitId":"-"},"content":" */"},{"lineNumber":242,"author":{"gitId":"-"},"content":" public WebElement waitForElementPresence(By by) {"},{"lineNumber":243,"author":{"gitId":"-"},"content":" return waitFor(ExpectedConditions.presenceOfElementLocated(by));"},{"lineNumber":244,"author":{"gitId":"-"},"content":" }"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" public void reloadPage() {"},{"lineNumber":247,"author":{"gitId":"-"},"content":" browser.goToUrl(browser.driver.getCurrentUrl());"},{"lineNumber":248,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":249,"author":{"gitId":"-"},"content":" }"},{"lineNumber":250,"author":{"gitId":"-"},"content":""},{"lineNumber":251,"author":{"gitId":"-"},"content":" protected Object executeScript(String script, Object... args) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" JavascriptExecutor javascriptExecutor \u003d (JavascriptExecutor) browser.driver;"},{"lineNumber":253,"author":{"gitId":"-"},"content":" return javascriptExecutor.executeScript(script, args);"},{"lineNumber":254,"author":{"gitId":"-"},"content":" }"},{"lineNumber":255,"author":{"gitId":"-"},"content":""},{"lineNumber":256,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":257,"author":{"gitId":"-"},"content":" * Returns the HTML source of the currently loaded page."},{"lineNumber":258,"author":{"gitId":"-"},"content":" */"},{"lineNumber":259,"author":{"gitId":"-"},"content":" public String getPageSource() {"},{"lineNumber":260,"author":{"gitId":"-"},"content":" return browser.driver.getPageSource();"},{"lineNumber":261,"author":{"gitId":"-"},"content":" }"},{"lineNumber":262,"author":{"gitId":"-"},"content":""},{"lineNumber":263,"author":{"gitId":"-"},"content":" public String getTitle() {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" return browser.driver.getTitle();"},{"lineNumber":265,"author":{"gitId":"-"},"content":" }"},{"lineNumber":266,"author":{"gitId":"-"},"content":""},{"lineNumber":267,"author":{"gitId":"-"},"content":" public String getPageTitle() {"},{"lineNumber":268,"author":{"gitId":"-"},"content":" return waitForElementPresence(By.tagName(\"h1\")).getText();"},{"lineNumber":269,"author":{"gitId":"-"},"content":" }"},{"lineNumber":270,"author":{"gitId":"-"},"content":""},{"lineNumber":271,"author":{"gitId":"-"},"content":" public void click(By by) {"},{"lineNumber":272,"author":{"gitId":"-"},"content":" WebElement element \u003d browser.driver.findElement(by);"},{"lineNumber":273,"author":{"gitId":"-"},"content":" click(element);"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" protected void click(WebElement element) {"},{"lineNumber":277,"author":{"gitId":"-"},"content":" executeScript(\"arguments[0].click();\", element);"},{"lineNumber":278,"author":{"gitId":"-"},"content":" }"},{"lineNumber":279,"author":{"gitId":"-"},"content":""},{"lineNumber":280,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":281,"author":{"gitId":"-"},"content":" * Simulates the clearing and sending of keys to an element."},{"lineNumber":282,"author":{"gitId":"-"},"content":" *"},{"lineNumber":283,"author":{"gitId":"-"},"content":" * \u003cp\u003e\u003cb\u003eNote:\u003c/b\u003e This method is not the same as using {@link WebElement#clear} followed by {@link WebElement#sendKeys}."},{"lineNumber":284,"author":{"gitId":"-"},"content":" * It avoids double firing of the {@code change} event which may occur when {@link WebElement#clear} is followed by"},{"lineNumber":285,"author":{"gitId":"-"},"content":" * {@link WebElement#sendKeys}."},{"lineNumber":286,"author":{"gitId":"-"},"content":" *"},{"lineNumber":287,"author":{"gitId":"-"},"content":" * @see AppPage#clearWithoutEvents(WebElement)"},{"lineNumber":288,"author":{"gitId":"-"},"content":" */"},{"lineNumber":289,"author":{"gitId":"-"},"content":" private void clearAndSendKeys(WebElement element, CharSequence... keysToSend) {"},{"lineNumber":290,"author":{"gitId":"-"},"content":" Map\u003cString, Object\u003e result \u003d clearWithoutEvents(element);"},{"lineNumber":291,"author":{"gitId":"-"},"content":" @SuppressWarnings(\"unchecked\")"},{"lineNumber":292,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e errors \u003d (Map\u003cString, String\u003e) result.get(\"errors\");"},{"lineNumber":293,"author":{"gitId":"-"},"content":" if (errors !\u003d null) {"},{"lineNumber":294,"author":{"gitId":"-"},"content":" throw new InvalidElementStateException(errors.get(\"detail\"));"},{"lineNumber":295,"author":{"gitId":"-"},"content":" }"},{"lineNumber":296,"author":{"gitId":"-"},"content":""},{"lineNumber":297,"author":{"gitId":"-"},"content":" element.sendKeys(keysToSend);"},{"lineNumber":298,"author":{"gitId":"-"},"content":" }"},{"lineNumber":299,"author":{"gitId":"-"},"content":""},{"lineNumber":300,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":301,"author":{"gitId":"-"},"content":" * Clears any kind of editable element, but without firing the {@code change} event (unlike {@link WebElement#clear()})."},{"lineNumber":302,"author":{"gitId":"-"},"content":" * Avoid using this method if {@link WebElement#clear()} meets the requirements as this method depends on implementation"},{"lineNumber":303,"author":{"gitId":"-"},"content":" * details."},{"lineNumber":304,"author":{"gitId":"-"},"content":" */"},{"lineNumber":305,"author":{"gitId":"-"},"content":" private Map\u003cString, Object\u003e clearWithoutEvents(WebElement element) {"},{"lineNumber":306,"author":{"gitId":"-"},"content":" // This method is a close mirror of HtmlUnitWebElement#clear(), except that events are not handled. Note that"},{"lineNumber":307,"author":{"gitId":"-"},"content":" // HtmlUnitWebElement is mirrored as opposed to RemoteWebElement (which is used with actual browsers) for convenience"},{"lineNumber":308,"author":{"gitId":"-"},"content":" // and the implementation can differ."},{"lineNumber":309,"author":{"gitId":"-"},"content":" checkNotNull(element);"},{"lineNumber":310,"author":{"gitId":"-"},"content":""},{"lineNumber":311,"author":{"gitId":"-"},"content":" // Adapted from ExpectedConditions#stalenessOf which forces a staleness check. This allows a meaningful"},{"lineNumber":312,"author":{"gitId":"-"},"content":" // StaleElementReferenceException to be thrown rather than just getting a boolean from ExpectedConditions."},{"lineNumber":313,"author":{"gitId":"-"},"content":" element.isEnabled();"},{"lineNumber":314,"author":{"gitId":"-"},"content":""},{"lineNumber":315,"author":{"gitId":"-"},"content":" // Fail safe in case the implementation of staleness checks is changed"},{"lineNumber":316,"author":{"gitId":"-"},"content":" if (isExpectedCondition(ExpectedConditions.stalenessOf(element))) {"},{"lineNumber":317,"author":{"gitId":"-"},"content":" throw new AssertionError("},{"lineNumber":318,"author":{"gitId":"-"},"content":" \"Element is stale but should have been caught earlier by element.isEnabled().\");"},{"lineNumber":319,"author":{"gitId":"-"},"content":" }"},{"lineNumber":320,"author":{"gitId":"-"},"content":""},{"lineNumber":321,"author":{"gitId":"-"},"content":" @SuppressWarnings(\"unchecked\")"},{"lineNumber":322,"author":{"gitId":"-"},"content":" Map\u003cString, Object\u003e result \u003d (Map\u003cString, Object\u003e) executeScript(CLEAR_ELEMENT_SCRIPT, element);"},{"lineNumber":323,"author":{"gitId":"-"},"content":" return result;"},{"lineNumber":324,"author":{"gitId":"-"},"content":" }"},{"lineNumber":325,"author":{"gitId":"-"},"content":""},{"lineNumber":326,"author":{"gitId":"-"},"content":" protected void fillTextBox(WebElement textBoxElement, String value) {"},{"lineNumber":327,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":328,"author":{"gitId":"-"},"content":" scrollElementToCenterAndClick(textBoxElement);"},{"lineNumber":329,"author":{"gitId":"-"},"content":" } catch (WebDriverException e) {"},{"lineNumber":330,"author":{"gitId":"-"},"content":" // It is important that a text box element is clickable before we fill it but due to legacy reasons we continue"},{"lineNumber":331,"author":{"gitId":"-"},"content":" // attempting to fill the text box element even if it\u0027s not clickable (which may lead to an unexpected failure"},{"lineNumber":332,"author":{"gitId":"-"},"content":" // later on)"},{"lineNumber":333,"author":{"gitId":"-"},"content":" System.out.println(\"Unexpectedly not able to click on the text box element because of: \");"},{"lineNumber":334,"author":{"gitId":"-"},"content":" System.out.println(e);"},{"lineNumber":335,"author":{"gitId":"-"},"content":" }"},{"lineNumber":336,"author":{"gitId":"-"},"content":""},{"lineNumber":337,"author":{"gitId":"-"},"content":" // If the intended value is empty `clear` works well enough for us"},{"lineNumber":338,"author":{"gitId":"-"},"content":" if (value.isEmpty()) {"},{"lineNumber":339,"author":{"gitId":"-"},"content":" textBoxElement.clear();"},{"lineNumber":340,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":341,"author":{"gitId":"-"},"content":" }"},{"lineNumber":342,"author":{"gitId":"-"},"content":""},{"lineNumber":343,"author":{"gitId":"-"},"content":" // Otherwise we need to do special handling of entering input because `clear` and `sendKeys` work differently."},{"lineNumber":344,"author":{"gitId":"-"},"content":" // See documentation for `clearAndSendKeys` for more details."},{"lineNumber":345,"author":{"gitId":"-"},"content":" clearAndSendKeys(textBoxElement, value);"},{"lineNumber":346,"author":{"gitId":"-"},"content":""},{"lineNumber":347,"author":{"gitId":"-"},"content":" textBoxElement.sendKeys(Keys.TAB); // blur the element to receive events"},{"lineNumber":348,"author":{"gitId":"-"},"content":" }"},{"lineNumber":349,"author":{"gitId":"-"},"content":""},{"lineNumber":350,"author":{"gitId":"-"},"content":" protected void fillDatePicker(WebElement dateBox, Instant startInstant, String timeZone) {"},{"lineNumber":351,"author":{"gitId":"-"},"content":" WebElement buttonToOpenPicker \u003d dateBox.findElement(By.tagName(\"button\"));"},{"lineNumber":352,"author":{"gitId":"-"},"content":" click(buttonToOpenPicker);"},{"lineNumber":353,"author":{"gitId":"-"},"content":""},{"lineNumber":354,"author":{"gitId":"-"},"content":" WebElement datePicker \u003d dateBox.findElement(By.tagName(\"ngb-datepicker\"));"},{"lineNumber":355,"author":{"gitId":"-"},"content":" WebElement monthAndYearPicker \u003d datePicker.findElement(By.tagName(\"ngb-datepicker-navigation-select\"));"},{"lineNumber":356,"author":{"gitId":"-"},"content":" WebElement monthPicker \u003d monthAndYearPicker.findElement(By.cssSelector(\"[title\u003d\u0027Select month\u0027]\"));"},{"lineNumber":357,"author":{"gitId":"-"},"content":" WebElement yearPicker \u003d monthAndYearPicker.findElement(By.cssSelector(\"[title\u003d\u0027Select year\u0027]\"));"},{"lineNumber":358,"author":{"gitId":"-"},"content":" WebElement dayPicker \u003d datePicker.findElement(By.cssSelector(\"ngb-datepicker-month\"));"},{"lineNumber":359,"author":{"gitId":"-"},"content":""},{"lineNumber":360,"author":{"gitId":"-"},"content":" String year \u003d getYearString(startInstant, timeZone);"},{"lineNumber":361,"author":{"gitId":"-"},"content":" String month \u003d getMonthString(startInstant, timeZone);"},{"lineNumber":362,"author":{"gitId":"-"},"content":" String date \u003d getFullDateString(startInstant, timeZone);"},{"lineNumber":363,"author":{"gitId":"-"},"content":""},{"lineNumber":364,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(yearPicker, year);"},{"lineNumber":365,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(monthPicker, month);"},{"lineNumber":366,"author":{"gitId":"-"},"content":" click(dayPicker.findElement(By.cssSelector(String.format(\"[aria-label\u003d\u0027%s\u0027]\", date))));"},{"lineNumber":367,"author":{"gitId":"-"},"content":" }"},{"lineNumber":368,"author":{"gitId":"-"},"content":""},{"lineNumber":369,"author":{"gitId":"-"},"content":" protected void fillFileBox(RemoteWebElement fileBoxElement, String fileName) {"},{"lineNumber":370,"author":{"gitId":"-"},"content":" if (fileName.isEmpty()) {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" fileBoxElement.clear();"},{"lineNumber":372,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":373,"author":{"gitId":"-"},"content":" fileBoxElement.setFileDetector(new UselessFileDetector());"},{"lineNumber":374,"author":{"gitId":"-"},"content":" String filePath \u003d new File(fileName).getAbsolutePath();"},{"lineNumber":375,"author":{"gitId":"-"},"content":" fileBoxElement.sendKeys(filePath);"},{"lineNumber":376,"author":{"gitId":"-"},"content":" }"},{"lineNumber":377,"author":{"gitId":"-"},"content":" }"},{"lineNumber":378,"author":{"gitId":"-"},"content":""},{"lineNumber":379,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":380,"author":{"gitId":"-"},"content":" * Get rich text from editor."},{"lineNumber":381,"author":{"gitId":"-"},"content":" */"},{"lineNumber":382,"author":{"gitId":"-"},"content":" protected String getEditorRichText(WebElement editor) {"},{"lineNumber":383,"author":{"gitId":"-"},"content":" waitForElementPresence(By.tagName(\"iframe\"));"},{"lineNumber":384,"author":{"gitId":"-"},"content":" String id \u003d editor.findElement(By.tagName(\"textarea\")).getAttribute(\"id\");"},{"lineNumber":385,"author":{"gitId":"-"},"content":" return (String) ((JavascriptExecutor) browser.driver)"},{"lineNumber":386,"author":{"gitId":"-"},"content":" .executeAsyncScript(READ_TINYMCE_CONTENT_SCRIPT, id);"},{"lineNumber":387,"author":{"gitId":"-"},"content":" }"},{"lineNumber":388,"author":{"gitId":"-"},"content":""},{"lineNumber":389,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":390,"author":{"gitId":"-"},"content":" * Write rich text to editor."},{"lineNumber":391,"author":{"gitId":"-"},"content":" */"},{"lineNumber":392,"author":{"gitId":"-"},"content":" protected void writeToRichTextEditor(WebElement editor, String text) {"},{"lineNumber":393,"author":{"gitId":"-"},"content":" waitForElementPresence(By.tagName(\"iframe\"));"},{"lineNumber":394,"author":{"gitId":"-"},"content":" String id \u003d editor.findElement(By.tagName(\"textarea\")).getAttribute(\"id\");"},{"lineNumber":395,"author":{"gitId":"-"},"content":" ((JavascriptExecutor) browser.driver).executeAsyncScript(WRITE_TO_TINYMCE_SCRIPT, id, text);"},{"lineNumber":396,"author":{"gitId":"-"},"content":" }"},{"lineNumber":397,"author":{"gitId":"-"},"content":""},{"lineNumber":398,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":399,"author":{"gitId":"domoberzin"},"content":" * Clear existing text in the editor."},{"lineNumber":400,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":401,"author":{"gitId":"domoberzin"},"content":" protected void clearRichTextEditor(WebElement editor) {"},{"lineNumber":402,"author":{"gitId":"domoberzin"},"content":" writeToRichTextEditor(editor, \"\");"},{"lineNumber":403,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":404,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":405,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":406,"author":{"gitId":"-"},"content":" * Select the option, if it is not already selected."},{"lineNumber":407,"author":{"gitId":"-"},"content":" * No action taken if it is already selected."},{"lineNumber":408,"author":{"gitId":"-"},"content":" */"},{"lineNumber":409,"author":{"gitId":"-"},"content":" protected void markOptionAsSelected(WebElement option) {"},{"lineNumber":410,"author":{"gitId":"-"},"content":" waitForElementVisibility(option);"},{"lineNumber":411,"author":{"gitId":"-"},"content":" if (!option.isSelected()) {"},{"lineNumber":412,"author":{"gitId":"-"},"content":" click(option);"},{"lineNumber":413,"author":{"gitId":"-"},"content":" }"},{"lineNumber":414,"author":{"gitId":"-"},"content":" }"},{"lineNumber":415,"author":{"gitId":"-"},"content":""},{"lineNumber":416,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":417,"author":{"gitId":"-"},"content":" * Unselect the option, if it is not already unselected."},{"lineNumber":418,"author":{"gitId":"-"},"content":" * No action taken if it is already unselected\u0027."},{"lineNumber":419,"author":{"gitId":"-"},"content":" */"},{"lineNumber":420,"author":{"gitId":"-"},"content":" protected void markOptionAsUnselected(WebElement option) {"},{"lineNumber":421,"author":{"gitId":"-"},"content":" waitForElementVisibility(option);"},{"lineNumber":422,"author":{"gitId":"-"},"content":" if (option.isSelected()) {"},{"lineNumber":423,"author":{"gitId":"-"},"content":" click(option);"},{"lineNumber":424,"author":{"gitId":"-"},"content":" }"},{"lineNumber":425,"author":{"gitId":"-"},"content":" }"},{"lineNumber":426,"author":{"gitId":"-"},"content":""},{"lineNumber":427,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":428,"author":{"gitId":"-"},"content":" * Returns the text of the option selected in the dropdown."},{"lineNumber":429,"author":{"gitId":"-"},"content":" */"},{"lineNumber":430,"author":{"gitId":"-"},"content":" protected String getSelectedDropdownOptionText(WebElement dropdown) {"},{"lineNumber":431,"author":{"gitId":"-"},"content":" Select select \u003d new Select(dropdown);"},{"lineNumber":432,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":433,"author":{"gitId":"-"},"content":" uiRetryManager.runUntilNoRecognizedException(new Retryable(\"Wait for dropdown text to load\") {"},{"lineNumber":434,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":435,"author":{"gitId":"-"},"content":" public void run() {"},{"lineNumber":436,"author":{"gitId":"-"},"content":" String txt \u003d select.getFirstSelectedOption().getText();"},{"lineNumber":437,"author":{"gitId":"-"},"content":" assertNotEquals(\"\", txt);"},{"lineNumber":438,"author":{"gitId":"-"},"content":" }"},{"lineNumber":439,"author":{"gitId":"-"},"content":" }, WebDriverException.class, AssertionError.class);"},{"lineNumber":440,"author":{"gitId":"-"},"content":" return select.getFirstSelectedOption().getText();"},{"lineNumber":441,"author":{"gitId":"-"},"content":" } catch (MaximumRetriesExceededException e) {"},{"lineNumber":442,"author":{"gitId":"-"},"content":" return select.getFirstSelectedOption().getText();"},{"lineNumber":443,"author":{"gitId":"-"},"content":" }"},{"lineNumber":444,"author":{"gitId":"-"},"content":" }"},{"lineNumber":445,"author":{"gitId":"-"},"content":""},{"lineNumber":446,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":447,"author":{"gitId":"-"},"content":" * Selects option in dropdown based on visible text."},{"lineNumber":448,"author":{"gitId":"-"},"content":" */"},{"lineNumber":449,"author":{"gitId":"-"},"content":" protected void selectDropdownOptionByText(WebElement dropdown, String text) {"},{"lineNumber":450,"author":{"gitId":"-"},"content":" scrollElementToCenter(dropdown);"},{"lineNumber":451,"author":{"gitId":"-"},"content":" Select select \u003d new Select(dropdown);"},{"lineNumber":452,"author":{"gitId":"-"},"content":" select.selectByVisibleText(text);"},{"lineNumber":453,"author":{"gitId":"-"},"content":" }"},{"lineNumber":454,"author":{"gitId":"-"},"content":""},{"lineNumber":455,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":456,"author":{"gitId":"-"},"content":" * Selects option in dropdown based on value."},{"lineNumber":457,"author":{"gitId":"-"},"content":" */"},{"lineNumber":458,"author":{"gitId":"-"},"content":" protected void selectDropdownOptionByValue(WebElement dropdown, String value) {"},{"lineNumber":459,"author":{"gitId":"-"},"content":" scrollElementToCenter(dropdown);"},{"lineNumber":460,"author":{"gitId":"-"},"content":" Select select \u003d new Select(dropdown);"},{"lineNumber":461,"author":{"gitId":"-"},"content":" select.selectByValue(value);"},{"lineNumber":462,"author":{"gitId":"-"},"content":" }"},{"lineNumber":463,"author":{"gitId":"-"},"content":""},{"lineNumber":464,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":465,"author":{"gitId":"-"},"content":" * Asserts that all values in the body of the given table are equal to the expectedTableBodyValues."},{"lineNumber":466,"author":{"gitId":"-"},"content":" */"},{"lineNumber":467,"author":{"gitId":"-"},"content":" protected void verifyTableBodyValues(WebElement table, String[][] expectedTableBodyValues) {"},{"lineNumber":468,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d table.findElement(By.tagName(\"tbody\")).findElements(By.tagName(\"tr\"));"},{"lineNumber":469,"author":{"gitId":"-"},"content":" assertTrue(expectedTableBodyValues.length \u003c\u003d rows.size());"},{"lineNumber":470,"author":{"gitId":"-"},"content":" for (int rowIndex \u003d 0; rowIndex \u003c expectedTableBodyValues.length; rowIndex++) {"},{"lineNumber":471,"author":{"gitId":"-"},"content":" verifyTableRowValues(rows.get(rowIndex), expectedTableBodyValues[rowIndex]);"},{"lineNumber":472,"author":{"gitId":"-"},"content":" }"},{"lineNumber":473,"author":{"gitId":"-"},"content":" }"},{"lineNumber":474,"author":{"gitId":"-"},"content":""},{"lineNumber":475,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":476,"author":{"gitId":"-"},"content":" * Asserts that all values in the row header of the given table are equal to the expectedRowHeaderValues."},{"lineNumber":477,"author":{"gitId":"-"},"content":" */"},{"lineNumber":478,"author":{"gitId":"-"},"content":" protected void verifyTableRowHeaderValues(WebElement table, String[][] expectedTableRowHeaderValues) {"},{"lineNumber":479,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d table.findElement(By.tagName(\"thead\")).findElements(By.tagName(\"tr\"));"},{"lineNumber":480,"author":{"gitId":"-"},"content":" assertTrue(expectedTableRowHeaderValues.length \u003c\u003d rows.size());"},{"lineNumber":481,"author":{"gitId":"-"},"content":" for (int rowIndex \u003d 0; rowIndex \u003c expectedTableRowHeaderValues.length; rowIndex++) {"},{"lineNumber":482,"author":{"gitId":"-"},"content":" verifyTableHeaderValues(rows.get(rowIndex), expectedTableRowHeaderValues[rowIndex]);"},{"lineNumber":483,"author":{"gitId":"-"},"content":" }"},{"lineNumber":484,"author":{"gitId":"-"},"content":" }"},{"lineNumber":485,"author":{"gitId":"-"},"content":""},{"lineNumber":486,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":487,"author":{"gitId":"-"},"content":" * Asserts that all values in the column header of the given table are equal to the expectedTablColumnHeaderValues."},{"lineNumber":488,"author":{"gitId":"-"},"content":" */"},{"lineNumber":489,"author":{"gitId":"-"},"content":" protected void verifyTableColumnHeaderValues(WebElement table, String[][] expectedTablColumnHeaderValues) {"},{"lineNumber":490,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d table.findElement(By.tagName(\"tbody\")).findElements(By.tagName(\"tr\"));"},{"lineNumber":491,"author":{"gitId":"-"},"content":" assertTrue(expectedTablColumnHeaderValues.length \u003c\u003d rows.size());"},{"lineNumber":492,"author":{"gitId":"-"},"content":" for (int rowIndex \u003d 0; rowIndex \u003c expectedTablColumnHeaderValues.length; rowIndex++) {"},{"lineNumber":493,"author":{"gitId":"-"},"content":" verifyTableHeaderValues(rows.get(rowIndex), expectedTablColumnHeaderValues[rowIndex]);"},{"lineNumber":494,"author":{"gitId":"-"},"content":" }"},{"lineNumber":495,"author":{"gitId":"-"},"content":" }"},{"lineNumber":496,"author":{"gitId":"-"},"content":""},{"lineNumber":497,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":498,"author":{"gitId":"-"},"content":" * Asserts that all data values in the given table row are equal to the expectedRowValues."},{"lineNumber":499,"author":{"gitId":"-"},"content":" */"},{"lineNumber":500,"author":{"gitId":"-"},"content":" protected void verifyTableRowValues(WebElement row, String[] expectedRowValues) {"},{"lineNumber":501,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e cells \u003d row.findElements(By.tagName(\"td\"));"},{"lineNumber":502,"author":{"gitId":"-"},"content":" assertTrue(expectedRowValues.length \u003c\u003d cells.size());"},{"lineNumber":503,"author":{"gitId":"-"},"content":" for (int cellIndex \u003d 0; cellIndex \u003c expectedRowValues.length; cellIndex++) {"},{"lineNumber":504,"author":{"gitId":"-"},"content":" assertEquals(expectedRowValues[cellIndex], cells.get(cellIndex).getText());"},{"lineNumber":505,"author":{"gitId":"-"},"content":" }"},{"lineNumber":506,"author":{"gitId":"-"},"content":" }"},{"lineNumber":507,"author":{"gitId":"-"},"content":""},{"lineNumber":508,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":509,"author":{"gitId":"-"},"content":" * Asserts that all header values in the given table row are equal to the expectedRowHeaderValues."},{"lineNumber":510,"author":{"gitId":"-"},"content":" */"},{"lineNumber":511,"author":{"gitId":"-"},"content":" protected void verifyTableHeaderValues(WebElement row, String[] expectedRowHeaderValues) {"},{"lineNumber":512,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e cells \u003d row.findElements(By.tagName(\"th\"));"},{"lineNumber":513,"author":{"gitId":"-"},"content":" assertTrue(expectedRowHeaderValues.length \u003c\u003d cells.size());"},{"lineNumber":514,"author":{"gitId":"-"},"content":" for (int cellIndex \u003d 0; cellIndex \u003c expectedRowHeaderValues.length; cellIndex++) {"},{"lineNumber":515,"author":{"gitId":"-"},"content":" assertEquals(expectedRowHeaderValues[cellIndex], cells.get(cellIndex).getText());"},{"lineNumber":516,"author":{"gitId":"-"},"content":" }"},{"lineNumber":517,"author":{"gitId":"-"},"content":" }"},{"lineNumber":518,"author":{"gitId":"-"},"content":""},{"lineNumber":519,"author":{"gitId":"-"},"content":" public void verifyBannerContent(NotificationAttributes expected) {"},{"lineNumber":520,"author":{"gitId":"-"},"content":" WebElement banner \u003d browser.driver.findElement(By.className(\"banner\"));"},{"lineNumber":521,"author":{"gitId":"-"},"content":" String title \u003d banner.findElement(By.tagName(\"h5\")).getText();"},{"lineNumber":522,"author":{"gitId":"-"},"content":" String message \u003d banner.findElement(By.className(\"banner-text\")).getAttribute(\"innerHTML\");"},{"lineNumber":523,"author":{"gitId":"-"},"content":" assertEquals(expected.getTitle(), title);"},{"lineNumber":524,"author":{"gitId":"-"},"content":" assertEquals(expected.getMessage(), message);"},{"lineNumber":525,"author":{"gitId":"-"},"content":" }"},{"lineNumber":526,"author":{"gitId":"-"},"content":""},{"lineNumber":527,"author":{"gitId":"-"},"content":" public boolean isBannerVisible() {"},{"lineNumber":528,"author":{"gitId":"-"},"content":" return isElementVisible(By.className(\"banner\"));"},{"lineNumber":529,"author":{"gitId":"-"},"content":" }"},{"lineNumber":530,"author":{"gitId":"-"},"content":""},{"lineNumber":531,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":532,"author":{"gitId":"-"},"content":" * Clicks the element and clicks \u0027Yes\u0027 in the follow up dialog box."},{"lineNumber":533,"author":{"gitId":"-"},"content":" * Fails if there is no dialog box."},{"lineNumber":534,"author":{"gitId":"-"},"content":" * @return the resulting page."},{"lineNumber":535,"author":{"gitId":"-"},"content":" */"},{"lineNumber":536,"author":{"gitId":"-"},"content":" public AppPage clickAndConfirm(WebElement elementToClick) {"},{"lineNumber":537,"author":{"gitId":"-"},"content":" click(elementToClick);"},{"lineNumber":538,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":539,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":540,"author":{"gitId":"-"},"content":" }"},{"lineNumber":541,"author":{"gitId":"-"},"content":""},{"lineNumber":542,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":543,"author":{"gitId":"-"},"content":" * Returns True if the page contains some basic elements expected in a page of the"},{"lineNumber":544,"author":{"gitId":"-"},"content":" * specific type. e.g., the top heading."},{"lineNumber":545,"author":{"gitId":"-"},"content":" */"},{"lineNumber":546,"author":{"gitId":"-"},"content":" protected abstract boolean containsExpectedPageContents();"},{"lineNumber":547,"author":{"gitId":"-"},"content":""},{"lineNumber":548,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":549,"author":{"gitId":"-"},"content":" * Returns True if there is a corresponding element for the given locator."},{"lineNumber":550,"author":{"gitId":"-"},"content":" */"},{"lineNumber":551,"author":{"gitId":"-"},"content":" public boolean isElementPresent(By by) {"},{"lineNumber":552,"author":{"gitId":"-"},"content":" return !browser.driver.findElements(by).isEmpty();"},{"lineNumber":553,"author":{"gitId":"-"},"content":" }"},{"lineNumber":554,"author":{"gitId":"-"},"content":""},{"lineNumber":555,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":556,"author":{"gitId":"-"},"content":" * Returns True if there is a corresponding element for the given id or name."},{"lineNumber":557,"author":{"gitId":"-"},"content":" */"},{"lineNumber":558,"author":{"gitId":"-"},"content":" public boolean isElementPresent(String elementId) {"},{"lineNumber":559,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":560,"author":{"gitId":"-"},"content":" browser.driver.findElement(By.id(elementId));"},{"lineNumber":561,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":562,"author":{"gitId":"-"},"content":" } catch (NoSuchElementException e) {"},{"lineNumber":563,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":564,"author":{"gitId":"-"},"content":" }"},{"lineNumber":565,"author":{"gitId":"-"},"content":" }"},{"lineNumber":566,"author":{"gitId":"-"},"content":""},{"lineNumber":567,"author":{"gitId":"-"},"content":" public boolean isElementVisible(By by) {"},{"lineNumber":568,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":569,"author":{"gitId":"-"},"content":" return browser.driver.findElement(by).isDisplayed();"},{"lineNumber":570,"author":{"gitId":"-"},"content":" } catch (NoSuchElementException e) {"},{"lineNumber":571,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":572,"author":{"gitId":"-"},"content":" }"},{"lineNumber":573,"author":{"gitId":"-"},"content":" }"},{"lineNumber":574,"author":{"gitId":"-"},"content":""},{"lineNumber":575,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":576,"author":{"gitId":"-"},"content":" * Returns true if the expected condition is evaluated to true immediately."},{"lineNumber":577,"author":{"gitId":"-"},"content":" * @see ExpectedConditions"},{"lineNumber":578,"author":{"gitId":"-"},"content":" */"},{"lineNumber":579,"author":{"gitId":"-"},"content":" private boolean isExpectedCondition(ExpectedCondition\u003c?\u003e expectedCondition) {"},{"lineNumber":580,"author":{"gitId":"-"},"content":" Object value \u003d expectedCondition.apply(browser.driver);"},{"lineNumber":581,"author":{"gitId":"-"},"content":" if (value \u003d\u003d null) {"},{"lineNumber":582,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":583,"author":{"gitId":"-"},"content":" }"},{"lineNumber":584,"author":{"gitId":"-"},"content":""},{"lineNumber":585,"author":{"gitId":"-"},"content":" if (value.getClass() \u003d\u003d Boolean.class) {"},{"lineNumber":586,"author":{"gitId":"-"},"content":" return (boolean) value;"},{"lineNumber":587,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":588,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":589,"author":{"gitId":"-"},"content":" }"},{"lineNumber":590,"author":{"gitId":"-"},"content":" }"},{"lineNumber":591,"author":{"gitId":"-"},"content":""},{"lineNumber":592,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":593,"author":{"gitId":"-"},"content":" * Clicks a button (can be inside or outside the modal) that dismisses the modal and waits for the modal to be hidden."},{"lineNumber":594,"author":{"gitId":"-"},"content":" * The caller must ensure the button is in the modal or a timeout will occur while waiting for the modal to be hidden."},{"lineNumber":595,"author":{"gitId":"-"},"content":" * @param dismissModalButton a button that dismisses the modal"},{"lineNumber":596,"author":{"gitId":"-"},"content":" */"},{"lineNumber":597,"author":{"gitId":"-"},"content":" public void clickDismissModalButtonAndWaitForModalHidden(WebElement dismissModalButton) {"},{"lineNumber":598,"author":{"gitId":"-"},"content":" // Note: Should first check if the button can actually dismiss the modal otherwise the state will be consistent."},{"lineNumber":599,"author":{"gitId":"-"},"content":" // However, it is too difficult to check."},{"lineNumber":600,"author":{"gitId":"-"},"content":""},{"lineNumber":601,"author":{"gitId":"-"},"content":" WebElement modalBackdrop \u003d browser.driver.findElement(By.className(\"modal-backdrop\"));"},{"lineNumber":602,"author":{"gitId":"-"},"content":""},{"lineNumber":603,"author":{"gitId":"-"},"content":" click(dismissModalButton);"},{"lineNumber":604,"author":{"gitId":"-"},"content":" waitForModalHidden(modalBackdrop);"},{"lineNumber":605,"author":{"gitId":"-"},"content":" }"},{"lineNumber":606,"author":{"gitId":"-"},"content":""},{"lineNumber":607,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":608,"author":{"gitId":"-"},"content":" * Scrolls element to center and clicks on it."},{"lineNumber":609,"author":{"gitId":"-"},"content":" *"},{"lineNumber":610,"author":{"gitId":"-"},"content":" * \u003cp\u003eAs compared to {@link org.openqa.selenium.interactions.Actions#moveToElement(WebElement)}, this method is"},{"lineNumber":611,"author":{"gitId":"-"},"content":" * more reliable as the element will not get blocked by elements such as the header."},{"lineNumber":612,"author":{"gitId":"-"},"content":" *"},{"lineNumber":613,"author":{"gitId":"-"},"content":" * \u003cp\u003eFurthermore, {@link org.openqa.selenium.interactions.Actions#moveToElement(WebElement)} is currently not"},{"lineNumber":614,"author":{"gitId":"-"},"content":" * working in Geckodriver."},{"lineNumber":615,"author":{"gitId":"-"},"content":" *"},{"lineNumber":616,"author":{"gitId":"-"},"content":" * \u003cp\u003e\u003cb\u003eNote:\u003c/b\u003e A \"scroll into view\" Actions primitive is in progress and may allow scrolling element to center."},{"lineNumber":617,"author":{"gitId":"-"},"content":" * Tracking issue:"},{"lineNumber":618,"author":{"gitId":"-"},"content":" * \u003ca href\u003d\"https://github.com/w3c/webdriver/issues/1005\"\u003eMissing \"scroll into view\" Actions primitive\u003c/a\u003e."},{"lineNumber":619,"author":{"gitId":"-"},"content":" *"},{"lineNumber":620,"author":{"gitId":"-"},"content":" * \u003cp\u003eAlso note that there are some other caveats, for example"},{"lineNumber":621,"author":{"gitId":"-"},"content":" * {@code new Actions(browser.driver).moveToElement(...).click(...).perform()} does not behave consistently across"},{"lineNumber":622,"author":{"gitId":"-"},"content":" * browsers."},{"lineNumber":623,"author":{"gitId":"-"},"content":" * \u003cul\u003e"},{"lineNumber":624,"author":{"gitId":"-"},"content":" * \u003cli\u003eIn FirefoxDriver, the element is scrolled to and then a click is attempted on the element."},{"lineNumber":625,"author":{"gitId":"-"},"content":" * \u003cli\u003eIn ChromeDriver, the mouse is scrolled to the element and then a click is attempted on the mouse coordinate,"},{"lineNumber":626,"author":{"gitId":"-"},"content":" * which means another element can actually be clicked (such as the header or a blocking pop-up)."},{"lineNumber":627,"author":{"gitId":"-"},"content":" * \u003c/ul\u003e"},{"lineNumber":628,"author":{"gitId":"-"},"content":" *"},{"lineNumber":629,"author":{"gitId":"-"},"content":" * \u003cp\u003eChromeDriver also automatically scrolls to an element when clicking an element if it is not in the viewport."},{"lineNumber":630,"author":{"gitId":"-"},"content":" */"},{"lineNumber":631,"author":{"gitId":"-"},"content":" void scrollElementToCenterAndClick(WebElement element) {"},{"lineNumber":632,"author":{"gitId":"-"},"content":" // TODO: migrate to `scrollIntoView` when Geckodriver is adopted"},{"lineNumber":633,"author":{"gitId":"-"},"content":" scrollElementToCenter(element);"},{"lineNumber":634,"author":{"gitId":"-"},"content":" element.click();"},{"lineNumber":635,"author":{"gitId":"-"},"content":" }"},{"lineNumber":636,"author":{"gitId":"-"},"content":""},{"lineNumber":637,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":638,"author":{"gitId":"-"},"content":" * Scrolls element to center."},{"lineNumber":639,"author":{"gitId":"-"},"content":" */"},{"lineNumber":640,"author":{"gitId":"-"},"content":" void scrollElementToCenter(WebElement element) {"},{"lineNumber":641,"author":{"gitId":"-"},"content":" executeScript(SCROLL_ELEMENT_TO_CENTER_AND_CLICK_SCRIPT, element);"},{"lineNumber":642,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(1000);"},{"lineNumber":643,"author":{"gitId":"-"},"content":" }"},{"lineNumber":644,"author":{"gitId":"-"},"content":""},{"lineNumber":645,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":646,"author":{"gitId":"-"},"content":" * Asserts message in toast is equal to the expected message."},{"lineNumber":647,"author":{"gitId":"-"},"content":" */"},{"lineNumber":648,"author":{"gitId":"-"},"content":" public void verifyStatusMessage(String expectedMessage) {"},{"lineNumber":649,"author":{"gitId":"-"},"content":" verifyStatusMessageWithLinks(expectedMessage, new String[] {});"},{"lineNumber":650,"author":{"gitId":"-"},"content":" closeToast();"},{"lineNumber":651,"author":{"gitId":"-"},"content":" }"},{"lineNumber":652,"author":{"gitId":"-"},"content":""},{"lineNumber":653,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":654,"author":{"gitId":"-"},"content":" * Asserts message in toast is equal to the expected message and contains the expected links."},{"lineNumber":655,"author":{"gitId":"-"},"content":" */"},{"lineNumber":656,"author":{"gitId":"-"},"content":" public void verifyStatusMessageWithLinks(String expectedMessage, String[] expectedLinks) {"},{"lineNumber":657,"author":{"gitId":"-"},"content":" WebElement[] statusMessage \u003d new WebElement[1];"},{"lineNumber":658,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":659,"author":{"gitId":"-"},"content":" uiRetryManager.runUntilNoRecognizedException(new Retryable(\"Verify status to user\") {"},{"lineNumber":660,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":661,"author":{"gitId":"-"},"content":" public void run() {"},{"lineNumber":662,"author":{"gitId":"-"},"content":" statusMessage[0] \u003d waitForElementPresence(By.className(\"toast-body\"));"},{"lineNumber":663,"author":{"gitId":"-"},"content":" assertEquals(expectedMessage, statusMessage[0].getText());"},{"lineNumber":664,"author":{"gitId":"-"},"content":" }"},{"lineNumber":665,"author":{"gitId":"-"},"content":" }, WebDriverException.class, AssertionError.class);"},{"lineNumber":666,"author":{"gitId":"-"},"content":" } catch (MaximumRetriesExceededException e) {"},{"lineNumber":667,"author":{"gitId":"-"},"content":" statusMessage[0] \u003d waitForElementPresence(By.className(\"toast-body\"));"},{"lineNumber":668,"author":{"gitId":"-"},"content":" assertEquals(expectedMessage, statusMessage[0].getText());"},{"lineNumber":669,"author":{"gitId":"-"},"content":" } finally {"},{"lineNumber":670,"author":{"gitId":"-"},"content":" if (expectedLinks.length \u003e 0) {"},{"lineNumber":671,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e actualLinks \u003d statusMessage[0].findElements(By.tagName(\"a\"));"},{"lineNumber":672,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c expectedLinks.length; i++) {"},{"lineNumber":673,"author":{"gitId":"-"},"content":" assertTrue(actualLinks.get(i).getAttribute(\"href\").contains(expectedLinks[i]));"},{"lineNumber":674,"author":{"gitId":"-"},"content":" }"},{"lineNumber":675,"author":{"gitId":"-"},"content":" }"},{"lineNumber":676,"author":{"gitId":"-"},"content":" }"},{"lineNumber":677,"author":{"gitId":"-"},"content":" }"},{"lineNumber":678,"author":{"gitId":"-"},"content":""},{"lineNumber":679,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":680,"author":{"gitId":"-"},"content":" * Closes toast message."},{"lineNumber":681,"author":{"gitId":"-"},"content":" */"},{"lineNumber":682,"author":{"gitId":"-"},"content":" public void closeToast() {"},{"lineNumber":683,"author":{"gitId":"-"},"content":" WebElement toastCloseButton \u003d waitForElementPresence(By.className(\"btn-close\"));"},{"lineNumber":684,"author":{"gitId":"-"},"content":" click(toastCloseButton);"},{"lineNumber":685,"author":{"gitId":"-"},"content":" }"},{"lineNumber":686,"author":{"gitId":"-"},"content":""},{"lineNumber":687,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":688,"author":{"gitId":"-"},"content":" * Switches to the new browser window just opened."},{"lineNumber":689,"author":{"gitId":"-"},"content":" */"},{"lineNumber":690,"author":{"gitId":"-"},"content":" protected void switchToNewWindow() {"},{"lineNumber":691,"author":{"gitId":"-"},"content":" browser.switchToNewWindow();"},{"lineNumber":692,"author":{"gitId":"-"},"content":" }"},{"lineNumber":693,"author":{"gitId":"-"},"content":""},{"lineNumber":694,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":695,"author":{"gitId":"-"},"content":" * Closes current window and switches back to parent window."},{"lineNumber":696,"author":{"gitId":"-"},"content":" */"},{"lineNumber":697,"author":{"gitId":"-"},"content":" public void closeCurrentWindowAndSwitchToParentWindow() {"},{"lineNumber":698,"author":{"gitId":"-"},"content":" browser.closeCurrentWindowAndSwitchToParentWindow();"},{"lineNumber":699,"author":{"gitId":"-"},"content":" }"},{"lineNumber":700,"author":{"gitId":"-"},"content":""},{"lineNumber":701,"author":{"gitId":"-"},"content":" String getDisplayGiverName(FeedbackParticipantType type) {"},{"lineNumber":702,"author":{"gitId":"-"},"content":" switch (type) {"},{"lineNumber":703,"author":{"gitId":"-"},"content":" case SELF:"},{"lineNumber":704,"author":{"gitId":"-"},"content":" return \"Feedback session creator (i.e., me)\";"},{"lineNumber":705,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":706,"author":{"gitId":"-"},"content":" return \"Students in this course\";"},{"lineNumber":707,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":708,"author":{"gitId":"-"},"content":" return \"Instructors in this course\";"},{"lineNumber":709,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":710,"author":{"gitId":"-"},"content":" return \"Teams in this course\";"},{"lineNumber":711,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":712,"author":{"gitId":"-"},"content":" throw new IllegalArgumentException(\"Unknown FeedbackParticipantType: \" + type);"},{"lineNumber":713,"author":{"gitId":"-"},"content":" }"},{"lineNumber":714,"author":{"gitId":"-"},"content":" }"},{"lineNumber":715,"author":{"gitId":"-"},"content":""},{"lineNumber":716,"author":{"gitId":"-"},"content":" String getDisplayRecipientName(FeedbackParticipantType type) {"},{"lineNumber":717,"author":{"gitId":"-"},"content":" switch (type) {"},{"lineNumber":718,"author":{"gitId":"-"},"content":" case SELF:"},{"lineNumber":719,"author":{"gitId":"-"},"content":" return \"Giver (Self feedback)\";"},{"lineNumber":720,"author":{"gitId":"-"},"content":" case STUDENTS_IN_SAME_SECTION:"},{"lineNumber":721,"author":{"gitId":"-"},"content":" return \"Other students in the same section\";"},{"lineNumber":722,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":723,"author":{"gitId":"-"},"content":" return \"Students in the course\";"},{"lineNumber":724,"author":{"gitId":"-"},"content":" case STUDENTS_EXCLUDING_SELF:"},{"lineNumber":725,"author":{"gitId":"-"},"content":" return \"Other students in the course\";"},{"lineNumber":726,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":727,"author":{"gitId":"-"},"content":" return \"Instructors in the course\";"},{"lineNumber":728,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":729,"author":{"gitId":"-"},"content":" return \"Other teams in the same section\";"},{"lineNumber":730,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":731,"author":{"gitId":"-"},"content":" return \"Teams in the course\";"},{"lineNumber":732,"author":{"gitId":"-"},"content":" case TEAMS_EXCLUDING_SELF:"},{"lineNumber":733,"author":{"gitId":"-"},"content":" return \"Other teams in the course\";"},{"lineNumber":734,"author":{"gitId":"-"},"content":" case OWN_TEAM:"},{"lineNumber":735,"author":{"gitId":"-"},"content":" return \"Giver\u0027s team\";"},{"lineNumber":736,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":737,"author":{"gitId":"-"},"content":" return \"Giver\u0027s team members\";"},{"lineNumber":738,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS_INCLUDING_SELF:"},{"lineNumber":739,"author":{"gitId":"-"},"content":" return \"Giver\u0027s team members and Giver\";"},{"lineNumber":740,"author":{"gitId":"-"},"content":" case NONE:"},{"lineNumber":741,"author":{"gitId":"-"},"content":" return \"Nobody specific (For general class feedback)\";"},{"lineNumber":742,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":743,"author":{"gitId":"-"},"content":" throw new IllegalArgumentException(\"Unknown FeedbackParticipantType: \" + type);"},{"lineNumber":744,"author":{"gitId":"-"},"content":" }"},{"lineNumber":745,"author":{"gitId":"-"},"content":" }"},{"lineNumber":746,"author":{"gitId":"-"},"content":""},{"lineNumber":747,"author":{"gitId":"-"},"content":" String getDisplayedDateTime(Instant instant, String timeZone, String pattern) {"},{"lineNumber":748,"author":{"gitId":"-"},"content":" ZonedDateTime zonedDateTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone(instant, timeZone, false)"},{"lineNumber":749,"author":{"gitId":"-"},"content":" .atZone(ZoneId.of(timeZone));"},{"lineNumber":750,"author":{"gitId":"yuanxi1"},"content":" return DateTimeFormatter.ofPattern(pattern, Locale.ENGLISH).format(zonedDateTime);"},{"lineNumber":751,"author":{"gitId":"-"},"content":" }"},{"lineNumber":752,"author":{"gitId":"-"},"content":""},{"lineNumber":753,"author":{"gitId":"-"},"content":" private String getFullDateString(Instant instant, String timeZone) {"},{"lineNumber":754,"author":{"gitId":"-"},"content":" return getDisplayedDateTime(instant, timeZone, \"EEEE, MMMM d, yyyy\");"},{"lineNumber":755,"author":{"gitId":"-"},"content":" }"},{"lineNumber":756,"author":{"gitId":"-"},"content":""},{"lineNumber":757,"author":{"gitId":"-"},"content":" private String getYearString(Instant instant, String timeZone) {"},{"lineNumber":758,"author":{"gitId":"-"},"content":" return getDisplayedDateTime(instant, timeZone, \"yyyy\");"},{"lineNumber":759,"author":{"gitId":"-"},"content":" }"},{"lineNumber":760,"author":{"gitId":"-"},"content":""},{"lineNumber":761,"author":{"gitId":"-"},"content":" private String getMonthString(Instant instant, String timeZone) {"},{"lineNumber":762,"author":{"gitId":"-"},"content":" return getDisplayedDateTime(instant, timeZone, \"MMM\");"},{"lineNumber":763,"author":{"gitId":"-"},"content":" }"},{"lineNumber":764,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":7,"yuanxi1":2,"-":755}},{"path":"src/e2e/java/teammates/e2e/pageobjects/FeedbackSubmitPage.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.pageobjects;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertEquals;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertFalse;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertTrue;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.fail;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.Collections;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.openqa.selenium.By;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import org.openqa.selenium.NoSuchElementException;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import org.openqa.selenium.WebElement;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseAttributes;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackConstantSumQuestionDetails;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackConstantSumResponseDetails;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackContributionQuestionDetails;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackContributionResponseDetails;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackMcqQuestionDetails;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackMcqResponseDetails;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackMsqQuestionDetails;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackMsqResponseDetails;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackNumericalScaleQuestionDetails;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackNumericalScaleResponseDetails;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRankOptionsQuestionDetails;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRankOptionsResponseDetails;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRankQuestionDetails;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRankRecipientsResponseDetails;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRubricQuestionDetails;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRubricResponseDetails;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackTextQuestionDetails;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackTextResponseDetails;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":43,"author":{"gitId":"-"},"content":" * Represents the feedback submission page of the website."},{"lineNumber":44,"author":{"gitId":"-"},"content":" */"},{"lineNumber":45,"author":{"gitId":"-"},"content":"public class FeedbackSubmitPage extends AppPage {"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" public FeedbackSubmitPage(Browser browser) {"},{"lineNumber":48,"author":{"gitId":"-"},"content":" super(browser);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":52,"author":{"gitId":"-"},"content":" protected boolean containsExpectedPageContents() {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" if (isElementPresent(By.className(\"modal-content\"))) {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":" return getPageTitle().contains(\"Submit Feedback\");"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" public void verifyFeedbackSessionDetails(FeedbackSessionAttributes feedbackSession, CourseAttributes course) {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" assertEquals(getCourseId(), feedbackSession.getCourseId());"},{"lineNumber":61,"author":{"gitId":"-"},"content":" assertEquals(getCourseName(), course.getName());"},{"lineNumber":62,"author":{"gitId":"-"},"content":" assertEquals(getCourseInstitute(), course.getInstitute());"},{"lineNumber":63,"author":{"gitId":"-"},"content":" assertEquals(getFeedbackSessionName(), feedbackSession.getFeedbackSessionName());"},{"lineNumber":64,"author":{"gitId":"-"},"content":" assertDateEquals(getOpeningTime(), feedbackSession.getStartTime(), feedbackSession.getTimeZone());"},{"lineNumber":65,"author":{"gitId":"-"},"content":" assertDateEquals(getClosingTime(), feedbackSession.getEndTime(), feedbackSession.getTimeZone());"},{"lineNumber":66,"author":{"gitId":"-"},"content":" assertEquals(getInstructions(), feedbackSession.getInstructions());"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" public void verifyNumQuestions(int expected) {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" assertEquals(browser.driver.findElements(By.cssSelector(\"[id^\u003d\u0027question-submission-form-qn-\u0027]\")).size(), expected);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" public void verifyQuestionDetails(int qnNumber, FeedbackQuestionAttributes questionAttributes) {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" assertEquals(getQuestionBrief(qnNumber), questionAttributes.getQuestionDetailsCopy().getQuestionText());"},{"lineNumber":75,"author":{"gitId":"-"},"content":" verifyVisibilityList(qnNumber, questionAttributes);"},{"lineNumber":76,"author":{"gitId":"-"},"content":" if (questionAttributes.getQuestionDescription() !\u003d null) {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" assertEquals(getQuestionDescription(qnNumber), questionAttributes.getQuestionDescription());"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }"},{"lineNumber":79,"author":{"gitId":"-"},"content":" }"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" public void verifyLimitedRecipients(int qnNumber, int numRecipients, List\u003cString\u003e recipientNames) {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e recipientDropdowns \u003d getQuestionForm(qnNumber)"},{"lineNumber":83,"author":{"gitId":"-"},"content":" .findElements(By.cssSelector(\"[id^\u003d\u0027recipient-dropdown-qn-\u0027]\"));"},{"lineNumber":84,"author":{"gitId":"-"},"content":" assertEquals(numRecipients, recipientDropdowns.size());"},{"lineNumber":85,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e recipients \u003d recipientDropdowns.get(0).findElements(By.tagName(\"option\"));"},{"lineNumber":86,"author":{"gitId":"-"},"content":" assertEquals(recipientNames.size(), recipients.size() - 1);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" Collections.sort(recipientNames);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c recipientNames.size(); i++) {"},{"lineNumber":89,"author":{"gitId":"-"},"content":" assertEquals(recipientNames.get(i), recipients.get(i + 1).getText());"},{"lineNumber":90,"author":{"gitId":"-"},"content":" }"},{"lineNumber":91,"author":{"gitId":"-"},"content":" }"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" public void verifyRecipients(int qnNumber, List\u003cString\u003e recipientNames, String role) {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(qnNumber);"},{"lineNumber":95,"author":{"gitId":"-"},"content":" Collections.sort(recipientNames);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c recipientNames.size(); i++) {"},{"lineNumber":97,"author":{"gitId":"-"},"content":" assertEquals(recipientNames.get(i) + \" (\" + role + \")\","},{"lineNumber":98,"author":{"gitId":"-"},"content":" questionForm.findElement(By.id(\"recipient-name-qn-\" + qnNumber + \"-idx-\" + i)).getText());"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" public void verifyWarningMessageForPartialResponse(int[] unansweredQuestions) {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" click(getSubmitAllQuestionsButton());"},{"lineNumber":104,"author":{"gitId":"-"},"content":" StringBuilder expectedSb \u003d new StringBuilder();"},{"lineNumber":105,"author":{"gitId":"-"},"content":" for (int unansweredQuestion : unansweredQuestions) {"},{"lineNumber":106,"author":{"gitId":"-"},"content":" expectedSb.append(unansweredQuestion).append(\", \");"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":" String expectedString \u003d expectedSb.toString().substring(0, expectedSb.length() - 2) + \".\";"},{"lineNumber":109,"author":{"gitId":"-"},"content":" String warningString \u003d waitForElementPresence(By.id(\"not-answered-questions\")).getText();"},{"lineNumber":110,"author":{"gitId":"-"},"content":" assertEquals(warningString.split(\": \")[1], expectedString);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":112,"author":{"gitId":"-"},"content":" }"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" public void verifyCannotSubmit() {"},{"lineNumber":115,"author":{"gitId":"-"},"content":" WebElement submitButton \u003d waitForElementPresence(By.cssSelector(\"[id^\u003d\u0027btn-submit-qn-\u0027]\"));"},{"lineNumber":116,"author":{"gitId":"-"},"content":" if (submitButton !\u003d null) {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" assertFalse(submitButton.isEnabled());"},{"lineNumber":118,"author":{"gitId":"-"},"content":" }"},{"lineNumber":119,"author":{"gitId":"-"},"content":" }"},{"lineNumber":120,"author":{"gitId":"-"},"content":""},{"lineNumber":121,"author":{"gitId":"-"},"content":" public void addComment(int qnNumber, String recipient, String newComment) {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" WebElement commentSection \u003d getCommentSection(qnNumber, recipient);"},{"lineNumber":123,"author":{"gitId":"-"},"content":" click(commentSection.findElement(By.className(\"btn-add-comment\")));"},{"lineNumber":124,"author":{"gitId":"-"},"content":" writeToCommentEditor(commentSection, newComment);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" }"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" public void editComment(int qnNumber, String recipient, String editedComment) {"},{"lineNumber":128,"author":{"gitId":"-"},"content":" WebElement commentSection \u003d getCommentSection(qnNumber, recipient);"},{"lineNumber":129,"author":{"gitId":"-"},"content":" click(commentSection.findElement(By.className(\"btn-edit-comment\")));"},{"lineNumber":130,"author":{"gitId":"-"},"content":" writeToCommentEditor(commentSection, editedComment);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" }"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" public void deleteComment(int qnNumber, String recipient) {"},{"lineNumber":134,"author":{"gitId":"-"},"content":" clickAndConfirm(getCommentSection(qnNumber, recipient).findElement(By.className(\"btn-delete-comment\")));"},{"lineNumber":135,"author":{"gitId":"-"},"content":" }"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" public void verifyComment(int qnNumber, String recipient, String expectedComment) {"},{"lineNumber":138,"author":{"gitId":"-"},"content":" WebElement commentSection \u003d getCommentSection(qnNumber, recipient);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" String actualComment \u003d commentSection.findElement(By.className(\"comment-text\")).getAttribute(\"innerHTML\");"},{"lineNumber":140,"author":{"gitId":"-"},"content":" assertEquals(expectedComment, actualComment);"},{"lineNumber":141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" public void verifyNoCommentPresent(int qnNumber, String recipient) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" int numComments \u003d getCommentSection(qnNumber, recipient).findElements(By.className(\"comment-text\")).size();"},{"lineNumber":145,"author":{"gitId":"-"},"content":" assertEquals(numComments, 0);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" }"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" public void verifyTextQuestion(int qnNumber, FeedbackTextQuestionDetails questionDetails) {"},{"lineNumber":149,"author":{"gitId":"-"},"content":" String recommendedLengthText \u003d getQuestionForm(qnNumber).findElement(By.id(\"recommended-length\")).getText();"},{"lineNumber":150,"author":{"gitId":"-"},"content":" assertEquals(recommendedLengthText, \"Recommended length for the answer: \""},{"lineNumber":151,"author":{"gitId":"-"},"content":" + questionDetails.getRecommendedLength() + \" words\");"},{"lineNumber":152,"author":{"gitId":"-"},"content":" }"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"-"},"content":" public void fillTextResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":155,"author":{"gitId":"-"},"content":" FeedbackTextResponseDetails responseDetails \u003d (FeedbackTextResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":156,"author":{"gitId":"-"},"content":" writeToRichTextEditor(getTextResponseEditor(qnNumber, recipient), responseDetails.getAnswer());"},{"lineNumber":157,"author":{"gitId":"-"},"content":" }"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" public void fillTextResponse(int qnNumber, String recipient, FeedbackResponse response) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" FeedbackTextResponseDetails responseDetails \u003d"},{"lineNumber":161,"author":{"gitId":"-"},"content":" (FeedbackTextResponseDetails) response.getFeedbackResponseDetailsCopy();"},{"lineNumber":162,"author":{"gitId":"-"},"content":" writeToRichTextEditor(getTextResponseEditor(qnNumber, recipient), responseDetails.getAnswer());"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" public void verifyTextResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":166,"author":{"gitId":"-"},"content":" FeedbackTextResponseDetails responseDetails \u003d (FeedbackTextResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":167,"author":{"gitId":"-"},"content":" int responseLength \u003d responseDetails.getAnswer().split(\" \").length;"},{"lineNumber":168,"author":{"gitId":"-"},"content":" assertEquals(getEditorRichText(getTextResponseEditor(qnNumber, recipient)), responseDetails.getAnswer());"},{"lineNumber":169,"author":{"gitId":"-"},"content":" assertEquals(getResponseLengthText(qnNumber, recipient), \"Response length: \" + responseLength"},{"lineNumber":170,"author":{"gitId":"-"},"content":" + \" words\");"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" public void verifyTextResponse(int qnNumber, String recipient, FeedbackResponse response) {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" FeedbackTextResponseDetails responseDetails \u003d"},{"lineNumber":175,"author":{"gitId":"-"},"content":" (FeedbackTextResponseDetails) response.getFeedbackResponseDetailsCopy();"},{"lineNumber":176,"author":{"gitId":"-"},"content":" int responseLength \u003d responseDetails.getAnswer().split(\" \").length;"},{"lineNumber":177,"author":{"gitId":"-"},"content":" assertEquals(getEditorRichText(getTextResponseEditor(qnNumber, recipient)), responseDetails.getAnswer());"},{"lineNumber":178,"author":{"gitId":"-"},"content":" assertEquals(getResponseLengthText(qnNumber, recipient), \"Response length: \" + responseLength"},{"lineNumber":179,"author":{"gitId":"-"},"content":" + \" words\");"},{"lineNumber":180,"author":{"gitId":"-"},"content":" }"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" public void verifyMcqQuestion(int qnNumber, String recipient, FeedbackMcqQuestionDetails questionDetails) {"},{"lineNumber":183,"author":{"gitId":"-"},"content":" List\u003cString\u003e mcqChoices \u003d questionDetails.getMcqChoices();"},{"lineNumber":184,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMcqOptions(qnNumber, recipient);"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c mcqChoices.size(); i++) {"},{"lineNumber":187,"author":{"gitId":"-"},"content":" assertEquals(mcqChoices.get(i), optionTexts.get(i).getText());"},{"lineNumber":188,"author":{"gitId":"-"},"content":" }"},{"lineNumber":189,"author":{"gitId":"-"},"content":""},{"lineNumber":190,"author":{"gitId":"-"},"content":" if (questionDetails.isOtherEnabled()) {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" assertEquals(\"Other\", getMcqSection(qnNumber, recipient).findElement(By.id(\"other-option\")).getText());"},{"lineNumber":192,"author":{"gitId":"-"},"content":" }"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"-"},"content":" public void verifyGeneratedMcqQuestion(int qnNumber, String recipient, List\u003cString\u003e options) {"},{"lineNumber":196,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMcqOptions(qnNumber, recipient);"},{"lineNumber":197,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c options.size(); i++) {"},{"lineNumber":198,"author":{"gitId":"-"},"content":" assertEquals(options.get(i), optionTexts.get(i).getText());"},{"lineNumber":199,"author":{"gitId":"-"},"content":" }"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }"},{"lineNumber":201,"author":{"gitId":"-"},"content":""},{"lineNumber":202,"author":{"gitId":"-"},"content":" public void fillMcqResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":203,"author":{"gitId":"-"},"content":" FeedbackMcqResponseDetails responseDetails \u003d (FeedbackMcqResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":204,"author":{"gitId":"-"},"content":" if (responseDetails.isOther()) {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" markOptionAsSelected(getMcqOtherOptionRadioBtn(qnNumber, recipient));"},{"lineNumber":206,"author":{"gitId":"-"},"content":" fillTextBox(getMcqOtherOptionTextbox(qnNumber, recipient), responseDetails.getOtherFieldContent());"},{"lineNumber":207,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":208,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMcqOptions(qnNumber, recipient);"},{"lineNumber":209,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c optionTexts.size(); i++) {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" if (optionTexts.get(i).getText().equals(responseDetails.getAnswer())) {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" markOptionAsSelected(getMcqRadioBtns(qnNumber, recipient).get(i));"},{"lineNumber":212,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":213,"author":{"gitId":"-"},"content":" }"},{"lineNumber":214,"author":{"gitId":"-"},"content":" }"},{"lineNumber":215,"author":{"gitId":"-"},"content":" }"},{"lineNumber":216,"author":{"gitId":"-"},"content":" }"},{"lineNumber":217,"author":{"gitId":"-"},"content":""},{"lineNumber":218,"author":{"gitId":"dishenggg"},"content":" public void fillMcqResponse(int qnNumber, String recipient, FeedbackResponse response) {"},{"lineNumber":219,"author":{"gitId":"dishenggg"},"content":" FeedbackMcqResponseDetails responseDetails \u003d (FeedbackMcqResponseDetails) response.getFeedbackResponseDetailsCopy();"},{"lineNumber":220,"author":{"gitId":"dishenggg"},"content":" if (responseDetails.isOther()) {"},{"lineNumber":221,"author":{"gitId":"dishenggg"},"content":" markOptionAsSelected(getMcqOtherOptionRadioBtn(qnNumber, recipient));"},{"lineNumber":222,"author":{"gitId":"dishenggg"},"content":" fillTextBox(getMcqOtherOptionTextbox(qnNumber, recipient), responseDetails.getOtherFieldContent());"},{"lineNumber":223,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":224,"author":{"gitId":"dishenggg"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMcqOptions(qnNumber, recipient);"},{"lineNumber":225,"author":{"gitId":"dishenggg"},"content":" for (int i \u003d 0; i \u003c optionTexts.size(); i++) {"},{"lineNumber":226,"author":{"gitId":"dishenggg"},"content":" if (optionTexts.get(i).getText().equals(responseDetails.getAnswer())) {"},{"lineNumber":227,"author":{"gitId":"dishenggg"},"content":" markOptionAsSelected(getMcqRadioBtns(qnNumber, recipient).get(i));"},{"lineNumber":228,"author":{"gitId":"dishenggg"},"content":" break;"},{"lineNumber":229,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":230,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":231,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":232,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":233,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":234,"author":{"gitId":"-"},"content":" public void verifyMcqResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":235,"author":{"gitId":"-"},"content":" FeedbackMcqResponseDetails responseDetails \u003d (FeedbackMcqResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":236,"author":{"gitId":"-"},"content":" if (responseDetails.isOther()) {"},{"lineNumber":237,"author":{"gitId":"-"},"content":" assertTrue(getMcqOtherOptionRadioBtn(qnNumber, recipient).isSelected());"},{"lineNumber":238,"author":{"gitId":"-"},"content":" assertEquals(getMcqOtherOptionTextbox(qnNumber, recipient).getAttribute(\"value\"),"},{"lineNumber":239,"author":{"gitId":"-"},"content":" responseDetails.getOtherFieldContent());"},{"lineNumber":240,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":241,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMcqOptions(qnNumber, recipient);"},{"lineNumber":242,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e radioBtns \u003d getMcqRadioBtns(qnNumber, recipient);"},{"lineNumber":243,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c optionTexts.size(); i++) {"},{"lineNumber":244,"author":{"gitId":"-"},"content":" if (optionTexts.get(i).getText().equals(responseDetails.getAnswer())) {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" assertTrue(radioBtns.get(i).isSelected());"},{"lineNumber":246,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":247,"author":{"gitId":"-"},"content":" }"},{"lineNumber":248,"author":{"gitId":"-"},"content":" assertFalse(radioBtns.get(i).isSelected());"},{"lineNumber":249,"author":{"gitId":"-"},"content":" }"},{"lineNumber":250,"author":{"gitId":"-"},"content":" }"},{"lineNumber":251,"author":{"gitId":"-"},"content":" }"},{"lineNumber":252,"author":{"gitId":"-"},"content":""},{"lineNumber":253,"author":{"gitId":"-"},"content":" public void verifyMsqQuestion(int qnNumber, String recipient, FeedbackMsqQuestionDetails questionDetails) {"},{"lineNumber":254,"author":{"gitId":"-"},"content":" List\u003cString\u003e msqChoices \u003d questionDetails.getMsqChoices();"},{"lineNumber":255,"author":{"gitId":"-"},"content":" if (questionDetails.isOtherEnabled()) {"},{"lineNumber":256,"author":{"gitId":"-"},"content":" msqChoices.add(\"Other\");"},{"lineNumber":257,"author":{"gitId":"-"},"content":" }"},{"lineNumber":258,"author":{"gitId":"-"},"content":" if (questionDetails.getMinSelectableChoices() \u003d\u003d Const.POINTS_NO_VALUE) {"},{"lineNumber":259,"author":{"gitId":"-"},"content":" msqChoices.add(\"None of the above\");"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMsqOptions(qnNumber, recipient);"},{"lineNumber":262,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c msqChoices.size(); i++) {"},{"lineNumber":263,"author":{"gitId":"-"},"content":" assertEquals(msqChoices.get(i), optionTexts.get(i).getText());"},{"lineNumber":264,"author":{"gitId":"-"},"content":" }"},{"lineNumber":265,"author":{"gitId":"-"},"content":" verifyMsqSelectableOptionsMessage(qnNumber, questionDetails);"},{"lineNumber":266,"author":{"gitId":"-"},"content":" }"},{"lineNumber":267,"author":{"gitId":"-"},"content":""},{"lineNumber":268,"author":{"gitId":"-"},"content":" private void verifyMsqSelectableOptionsMessage(int qnNumber, FeedbackMsqQuestionDetails questionDetails) {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" if (questionDetails.getMinSelectableChoices() !\u003d Const.POINTS_NO_VALUE) {"},{"lineNumber":270,"author":{"gitId":"-"},"content":" assertEquals(getQuestionForm(qnNumber).findElement(By.id(\"min-options-message\")).getText(),"},{"lineNumber":271,"author":{"gitId":"-"},"content":" \"Choose at least \" + questionDetails.getMinSelectableChoices() + \" options.\");"},{"lineNumber":272,"author":{"gitId":"-"},"content":" }"},{"lineNumber":273,"author":{"gitId":"-"},"content":" if (questionDetails.getMaxSelectableChoices() !\u003d Const.POINTS_NO_VALUE) {"},{"lineNumber":274,"author":{"gitId":"-"},"content":" assertEquals(getQuestionForm(qnNumber).findElement(By.id(\"max-options-message\")).getText(),"},{"lineNumber":275,"author":{"gitId":"-"},"content":" \"Choose no more than \" + questionDetails.getMaxSelectableChoices() + \" options.\");"},{"lineNumber":276,"author":{"gitId":"-"},"content":" }"},{"lineNumber":277,"author":{"gitId":"-"},"content":" }"},{"lineNumber":278,"author":{"gitId":"-"},"content":""},{"lineNumber":279,"author":{"gitId":"-"},"content":" public void verifyGeneratedMsqQuestion(int qnNumber, String recipient, FeedbackMsqQuestionDetails questionDetails,"},{"lineNumber":280,"author":{"gitId":"-"},"content":" List\u003cString\u003e options) {"},{"lineNumber":281,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMsqOptions(qnNumber, recipient);"},{"lineNumber":282,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c options.size(); i++) {"},{"lineNumber":283,"author":{"gitId":"-"},"content":" assertEquals(options.get(i), optionTexts.get(i).getText());"},{"lineNumber":284,"author":{"gitId":"-"},"content":" }"},{"lineNumber":285,"author":{"gitId":"-"},"content":" verifyMsqSelectableOptionsMessage(qnNumber, questionDetails);"},{"lineNumber":286,"author":{"gitId":"-"},"content":" }"},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":" public void fillMsqResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" FeedbackMsqResponseDetails responseDetails \u003d (FeedbackMsqResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":290,"author":{"gitId":"-"},"content":" List\u003cString\u003e answers \u003d responseDetails.getAnswers();"},{"lineNumber":291,"author":{"gitId":"-"},"content":" if (answers.get(0).isEmpty()) {"},{"lineNumber":292,"author":{"gitId":"-"},"content":" answers.add(\"None of the above\");"},{"lineNumber":293,"author":{"gitId":"-"},"content":" }"},{"lineNumber":294,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMsqOptions(qnNumber, recipient);"},{"lineNumber":295,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e checkboxes \u003d getMsqCheckboxes(qnNumber, recipient);"},{"lineNumber":296,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c optionTexts.size(); i++) {"},{"lineNumber":297,"author":{"gitId":"-"},"content":" if (answers.contains(optionTexts.get(i).getText())) {"},{"lineNumber":298,"author":{"gitId":"-"},"content":" markOptionAsSelected(checkboxes.get(i));"},{"lineNumber":299,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":300,"author":{"gitId":"-"},"content":" markOptionAsUnselected(checkboxes.get(i));"},{"lineNumber":301,"author":{"gitId":"-"},"content":" }"},{"lineNumber":302,"author":{"gitId":"-"},"content":" }"},{"lineNumber":303,"author":{"gitId":"-"},"content":" if (responseDetails.isOther()) {"},{"lineNumber":304,"author":{"gitId":"-"},"content":" markOptionAsSelected(getMsqOtherOptionCheckbox(qnNumber, recipient));"},{"lineNumber":305,"author":{"gitId":"-"},"content":" fillTextBox(getMsqOtherOptionTextbox(qnNumber, recipient), responseDetails.getOtherFieldContent());"},{"lineNumber":306,"author":{"gitId":"-"},"content":" }"},{"lineNumber":307,"author":{"gitId":"-"},"content":" }"},{"lineNumber":308,"author":{"gitId":"-"},"content":""},{"lineNumber":309,"author":{"gitId":"dishenggg"},"content":" public void fillMsqResponse(int qnNumber, String recipient, FeedbackResponse response) {"},{"lineNumber":310,"author":{"gitId":"dishenggg"},"content":" FeedbackMsqResponseDetails responseDetails \u003d (FeedbackMsqResponseDetails) response.getFeedbackResponseDetailsCopy();"},{"lineNumber":311,"author":{"gitId":"dishenggg"},"content":" List\u003cString\u003e answers \u003d responseDetails.getAnswers();"},{"lineNumber":312,"author":{"gitId":"dishenggg"},"content":" if (answers.get(0).isEmpty()) {"},{"lineNumber":313,"author":{"gitId":"dishenggg"},"content":" answers.add(\"None of the above\");"},{"lineNumber":314,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":315,"author":{"gitId":"dishenggg"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMsqOptions(qnNumber, recipient);"},{"lineNumber":316,"author":{"gitId":"dishenggg"},"content":" List\u003cWebElement\u003e checkboxes \u003d getMsqCheckboxes(qnNumber, recipient);"},{"lineNumber":317,"author":{"gitId":"dishenggg"},"content":" for (int i \u003d 0; i \u003c optionTexts.size(); i++) {"},{"lineNumber":318,"author":{"gitId":"dishenggg"},"content":" if (answers.contains(optionTexts.get(i).getText())) {"},{"lineNumber":319,"author":{"gitId":"dishenggg"},"content":" markOptionAsSelected(checkboxes.get(i));"},{"lineNumber":320,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":321,"author":{"gitId":"dishenggg"},"content":" markOptionAsUnselected(checkboxes.get(i));"},{"lineNumber":322,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":323,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":324,"author":{"gitId":"dishenggg"},"content":" if (responseDetails.isOther()) {"},{"lineNumber":325,"author":{"gitId":"dishenggg"},"content":" markOptionAsSelected(getMsqOtherOptionCheckbox(qnNumber, recipient));"},{"lineNumber":326,"author":{"gitId":"dishenggg"},"content":" fillTextBox(getMsqOtherOptionTextbox(qnNumber, recipient), responseDetails.getOtherFieldContent());"},{"lineNumber":327,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":328,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":329,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":330,"author":{"gitId":"-"},"content":" public void verifyMsqResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":331,"author":{"gitId":"-"},"content":" FeedbackMsqResponseDetails responseDetails \u003d (FeedbackMsqResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":332,"author":{"gitId":"-"},"content":" List\u003cString\u003e answers \u003d responseDetails.getAnswers();"},{"lineNumber":333,"author":{"gitId":"-"},"content":" if (answers.get(0).isEmpty()) {"},{"lineNumber":334,"author":{"gitId":"-"},"content":" answers.add(\"None of the above\");"},{"lineNumber":335,"author":{"gitId":"-"},"content":" }"},{"lineNumber":336,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMsqOptions(qnNumber, recipient);"},{"lineNumber":337,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e checkboxes \u003d getMsqCheckboxes(qnNumber, recipient);"},{"lineNumber":338,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c optionTexts.size(); i++) {"},{"lineNumber":339,"author":{"gitId":"-"},"content":" if (answers.contains(optionTexts.get(i).getText())) {"},{"lineNumber":340,"author":{"gitId":"-"},"content":" assertTrue(checkboxes.get(i).isSelected());"},{"lineNumber":341,"author":{"gitId":"-"},"content":" } else if (\"Other\".equals(optionTexts.get(i).getText())) {"},{"lineNumber":342,"author":{"gitId":"-"},"content":" assertEquals(checkboxes.get(i).isSelected(), responseDetails.isOther());"},{"lineNumber":343,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":344,"author":{"gitId":"-"},"content":" assertFalse(checkboxes.get(i).isSelected());"},{"lineNumber":345,"author":{"gitId":"-"},"content":" }"},{"lineNumber":346,"author":{"gitId":"-"},"content":" }"},{"lineNumber":347,"author":{"gitId":"-"},"content":" if (responseDetails.isOther()) {"},{"lineNumber":348,"author":{"gitId":"-"},"content":" assertEquals(getMsqOtherOptionTextbox(qnNumber, recipient).getAttribute(\"value\"),"},{"lineNumber":349,"author":{"gitId":"-"},"content":" responseDetails.getOtherFieldContent());"},{"lineNumber":350,"author":{"gitId":"-"},"content":" }"},{"lineNumber":351,"author":{"gitId":"-"},"content":" }"},{"lineNumber":352,"author":{"gitId":"-"},"content":""},{"lineNumber":353,"author":{"gitId":"dishenggg"},"content":" public void verifyMsqResponse(int qnNumber, String recipient, FeedbackResponse response) {"},{"lineNumber":354,"author":{"gitId":"dishenggg"},"content":" FeedbackMsqResponseDetails responseDetails \u003d (FeedbackMsqResponseDetails) response.getFeedbackResponseDetailsCopy();"},{"lineNumber":355,"author":{"gitId":"dishenggg"},"content":" List\u003cString\u003e answers \u003d responseDetails.getAnswers();"},{"lineNumber":356,"author":{"gitId":"dishenggg"},"content":" if (answers.get(0).isEmpty()) {"},{"lineNumber":357,"author":{"gitId":"dishenggg"},"content":" answers.add(\"None of the above\");"},{"lineNumber":358,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":359,"author":{"gitId":"dishenggg"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMsqOptions(qnNumber, recipient);"},{"lineNumber":360,"author":{"gitId":"dishenggg"},"content":" List\u003cWebElement\u003e checkboxes \u003d getMsqCheckboxes(qnNumber, recipient);"},{"lineNumber":361,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c optionTexts.size(); i++) {"},{"lineNumber":362,"author":{"gitId":"-"},"content":" if (answers.contains(optionTexts.get(i).getText())) {"},{"lineNumber":363,"author":{"gitId":"-"},"content":" assertTrue(checkboxes.get(i).isSelected());"},{"lineNumber":364,"author":{"gitId":"-"},"content":" } else if (\"Other\".equals(optionTexts.get(i).getText())) {"},{"lineNumber":365,"author":{"gitId":"-"},"content":" assertEquals(checkboxes.get(i).isSelected(), responseDetails.isOther());"},{"lineNumber":366,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":367,"author":{"gitId":"-"},"content":" assertFalse(checkboxes.get(i).isSelected());"},{"lineNumber":368,"author":{"gitId":"-"},"content":" }"},{"lineNumber":369,"author":{"gitId":"-"},"content":" }"},{"lineNumber":370,"author":{"gitId":"-"},"content":" if (responseDetails.isOther()) {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" assertEquals(getMsqOtherOptionTextbox(qnNumber, recipient).getAttribute(\"value\"),"},{"lineNumber":372,"author":{"gitId":"-"},"content":" responseDetails.getOtherFieldContent());"},{"lineNumber":373,"author":{"gitId":"-"},"content":" }"},{"lineNumber":374,"author":{"gitId":"-"},"content":" }"},{"lineNumber":375,"author":{"gitId":"-"},"content":""},{"lineNumber":376,"author":{"gitId":"-"},"content":" public void verifyNumScaleQuestion(int qnNumber, String recipient,"},{"lineNumber":377,"author":{"gitId":"-"},"content":" FeedbackNumericalScaleQuestionDetails questionDetails) {"},{"lineNumber":378,"author":{"gitId":"-"},"content":" double step \u003d questionDetails.getStep();"},{"lineNumber":379,"author":{"gitId":"-"},"content":" double twoSteps \u003d 2 * step;"},{"lineNumber":380,"author":{"gitId":"-"},"content":" double min \u003d questionDetails.getMinScale();"},{"lineNumber":381,"author":{"gitId":"-"},"content":" double max \u003d questionDetails.getMaxScale();"},{"lineNumber":382,"author":{"gitId":"-"},"content":" String possibleValues \u003d String.format(\"Possible values: [%s, %s, %s, ..., %s, %s, %s]\","},{"lineNumber":383,"author":{"gitId":"-"},"content":" getDoubleString(min), getDoubleString(min + step), getDoubleString(min + twoSteps),"},{"lineNumber":384,"author":{"gitId":"-"},"content":" getDoubleString(max - twoSteps), getDoubleString(max - step), getDoubleString(max));"},{"lineNumber":385,"author":{"gitId":"-"},"content":" String actualValues \u003d getNumScaleSection(qnNumber, recipient).findElement(By.id(\"possible-values\")).getText();"},{"lineNumber":386,"author":{"gitId":"-"},"content":" assertEquals(actualValues, possibleValues);"},{"lineNumber":387,"author":{"gitId":"-"},"content":" }"},{"lineNumber":388,"author":{"gitId":"-"},"content":""},{"lineNumber":389,"author":{"gitId":"-"},"content":" public void fillNumScaleResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":390,"author":{"gitId":"-"},"content":" FeedbackNumericalScaleResponseDetails responseDetails \u003d"},{"lineNumber":391,"author":{"gitId":"-"},"content":" (FeedbackNumericalScaleResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":392,"author":{"gitId":"-"},"content":" fillTextBox(getNumScaleInput(qnNumber, recipient), Double.toString(responseDetails.getAnswer()));"},{"lineNumber":393,"author":{"gitId":"-"},"content":" }"},{"lineNumber":394,"author":{"gitId":"-"},"content":""},{"lineNumber":395,"author":{"gitId":"marquestye"},"content":" public void fillNumScaleResponse(int qnNumber, String recipient, FeedbackResponse response) {"},{"lineNumber":396,"author":{"gitId":"marquestye"},"content":" FeedbackNumericalScaleResponseDetails responseDetails \u003d"},{"lineNumber":397,"author":{"gitId":"marquestye"},"content":" (FeedbackNumericalScaleResponseDetails) response.getFeedbackResponseDetailsCopy();"},{"lineNumber":398,"author":{"gitId":"marquestye"},"content":" fillTextBox(getNumScaleInput(qnNumber, recipient), Double.toString(responseDetails.getAnswer()));"},{"lineNumber":399,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":400,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":401,"author":{"gitId":"-"},"content":" public void verifyNumScaleResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":402,"author":{"gitId":"-"},"content":" FeedbackNumericalScaleResponseDetails responseDetails \u003d"},{"lineNumber":403,"author":{"gitId":"-"},"content":" (FeedbackNumericalScaleResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":404,"author":{"gitId":"-"},"content":" assertEquals(getNumScaleInput(qnNumber, recipient).getAttribute(\"value\"),"},{"lineNumber":405,"author":{"gitId":"-"},"content":" getDoubleString(responseDetails.getAnswer()));"},{"lineNumber":406,"author":{"gitId":"-"},"content":" }"},{"lineNumber":407,"author":{"gitId":"-"},"content":""},{"lineNumber":408,"author":{"gitId":"marquestye"},"content":" public void verifyNumScaleResponse(int qnNumber, String recipient, FeedbackResponse response) {"},{"lineNumber":409,"author":{"gitId":"marquestye"},"content":" FeedbackNumericalScaleResponseDetails responseDetails \u003d"},{"lineNumber":410,"author":{"gitId":"marquestye"},"content":" (FeedbackNumericalScaleResponseDetails) response.getFeedbackResponseDetailsCopy();"},{"lineNumber":411,"author":{"gitId":"marquestye"},"content":" assertEquals(getNumScaleInput(qnNumber, recipient).getAttribute(\"value\"),"},{"lineNumber":412,"author":{"gitId":"marquestye"},"content":" getDoubleString(responseDetails.getAnswer()));"},{"lineNumber":413,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":414,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":415,"author":{"gitId":"-"},"content":" public void verifyConstSumQuestion(int qnNumber, String recipient,"},{"lineNumber":416,"author":{"gitId":"-"},"content":" FeedbackConstantSumQuestionDetails questionDetails) {"},{"lineNumber":417,"author":{"gitId":"-"},"content":" if (!questionDetails.isDistributeToRecipients()) {"},{"lineNumber":418,"author":{"gitId":"-"},"content":" List\u003cString\u003e constSumOptions \u003d questionDetails.getConstSumOptions();"},{"lineNumber":419,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getConstSumOptions(qnNumber, recipient);"},{"lineNumber":420,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c constSumOptions.size(); i++) {"},{"lineNumber":421,"author":{"gitId":"-"},"content":" assertEquals(constSumOptions.get(i), optionTexts.get(i).getText());"},{"lineNumber":422,"author":{"gitId":"-"},"content":" }"},{"lineNumber":423,"author":{"gitId":"-"},"content":" }"},{"lineNumber":424,"author":{"gitId":"-"},"content":""},{"lineNumber":425,"author":{"gitId":"-"},"content":" int totalPoints \u003d questionDetails.getPoints();"},{"lineNumber":426,"author":{"gitId":"-"},"content":" if (questionDetails.isPointsPerOption()) {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" totalPoints *\u003d questionDetails.getNumOfConstSumOptions();"},{"lineNumber":428,"author":{"gitId":"-"},"content":" }"},{"lineNumber":429,"author":{"gitId":"-"},"content":" assertEquals(getQuestionForm(qnNumber).findElement(By.id(\"total-points-message\")).getText(),"},{"lineNumber":430,"author":{"gitId":"-"},"content":" \"Total points distributed should add up to \" + totalPoints + \".\");"},{"lineNumber":431,"author":{"gitId":"-"},"content":""},{"lineNumber":432,"author":{"gitId":"-"},"content":" if (questionDetails.isForceUnevenDistribution()) {"},{"lineNumber":433,"author":{"gitId":"-"},"content":" String entityType \u003d questionDetails.isDistributeToRecipients() ? \"recipient\" : \"option\";"},{"lineNumber":434,"author":{"gitId":"-"},"content":" if (\"All options\".equals(questionDetails.getDistributePointsFor())) {"},{"lineNumber":435,"author":{"gitId":"-"},"content":" assertEquals(getQuestionForm(qnNumber).findElement(By.id(\"all-uneven-message\")).getText(),"},{"lineNumber":436,"author":{"gitId":"-"},"content":" \"Every \" + entityType + \" should be allocated different number of points.\");"},{"lineNumber":437,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":438,"author":{"gitId":"-"},"content":" assertEquals(getQuestionForm(qnNumber).findElement(By.id(\"one-uneven-message\")).getText(),"},{"lineNumber":439,"author":{"gitId":"-"},"content":" \"At least one \" + entityType + \" should be allocated different number of points.\");"},{"lineNumber":440,"author":{"gitId":"-"},"content":" }"},{"lineNumber":441,"author":{"gitId":"-"},"content":" }"},{"lineNumber":442,"author":{"gitId":"-"},"content":" }"},{"lineNumber":443,"author":{"gitId":"-"},"content":""},{"lineNumber":444,"author":{"gitId":"-"},"content":" public void fillConstSumOptionResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":445,"author":{"gitId":"-"},"content":" FeedbackConstantSumResponseDetails responseDetails \u003d"},{"lineNumber":446,"author":{"gitId":"-"},"content":" (FeedbackConstantSumResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":447,"author":{"gitId":"-"},"content":" List\u003cInteger\u003e answers \u003d responseDetails.getAnswers();"},{"lineNumber":448,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e constSumInputs \u003d getConstSumInputs(qnNumber, recipient);"},{"lineNumber":449,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c answers.size(); i++) {"},{"lineNumber":450,"author":{"gitId":"-"},"content":" fillTextBox(constSumInputs.get(i), Integer.toString(answers.get(i)));"},{"lineNumber":451,"author":{"gitId":"-"},"content":" }"},{"lineNumber":452,"author":{"gitId":"-"},"content":" }"},{"lineNumber":453,"author":{"gitId":"-"},"content":""},{"lineNumber":454,"author":{"gitId":"-"},"content":" public void verifyConstSumOptionResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":455,"author":{"gitId":"-"},"content":" FeedbackConstantSumResponseDetails responseDetails \u003d"},{"lineNumber":456,"author":{"gitId":"-"},"content":" (FeedbackConstantSumResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":457,"author":{"gitId":"-"},"content":" List\u003cInteger\u003e answers \u003d responseDetails.getAnswers();"},{"lineNumber":458,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e constSumInputs \u003d getConstSumInputs(qnNumber, recipient);"},{"lineNumber":459,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c answers.size(); i++) {"},{"lineNumber":460,"author":{"gitId":"-"},"content":" assertEquals(constSumInputs.get(i).getAttribute(\"value\"), Integer.toString(answers.get(i)));"},{"lineNumber":461,"author":{"gitId":"-"},"content":" }"},{"lineNumber":462,"author":{"gitId":"-"},"content":" }"},{"lineNumber":463,"author":{"gitId":"-"},"content":""},{"lineNumber":464,"author":{"gitId":"-"},"content":" public void fillConstSumRecipientResponse(int qnNumber, List\u003cFeedbackResponseAttributes\u003e responses) {"},{"lineNumber":465,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e recipientInputs \u003d getConstSumRecipientInputs(qnNumber);"},{"lineNumber":466,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c responses.size(); i++) {"},{"lineNumber":467,"author":{"gitId":"-"},"content":" FeedbackConstantSumResponseDetails response \u003d"},{"lineNumber":468,"author":{"gitId":"-"},"content":" (FeedbackConstantSumResponseDetails) responses.get(i).getResponseDetailsCopy();"},{"lineNumber":469,"author":{"gitId":"-"},"content":" fillTextBox(recipientInputs.get(i), Integer.toString(response.getAnswers().get(0)));"},{"lineNumber":470,"author":{"gitId":"-"},"content":" }"},{"lineNumber":471,"author":{"gitId":"-"},"content":" }"},{"lineNumber":472,"author":{"gitId":"-"},"content":""},{"lineNumber":473,"author":{"gitId":"-"},"content":" public void verifyConstSumRecipientResponse(int qnNumber, List\u003cFeedbackResponseAttributes\u003e responses) {"},{"lineNumber":474,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e recipientInputs \u003d getConstSumRecipientInputs(qnNumber);"},{"lineNumber":475,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c responses.size(); i++) {"},{"lineNumber":476,"author":{"gitId":"-"},"content":" FeedbackConstantSumResponseDetails response \u003d"},{"lineNumber":477,"author":{"gitId":"-"},"content":" (FeedbackConstantSumResponseDetails) responses.get(i).getResponseDetailsCopy();"},{"lineNumber":478,"author":{"gitId":"-"},"content":" assertEquals(recipientInputs.get(i).getAttribute(\"value\"),"},{"lineNumber":479,"author":{"gitId":"-"},"content":" Integer.toString(response.getAnswers().get(0)));"},{"lineNumber":480,"author":{"gitId":"-"},"content":" }"},{"lineNumber":481,"author":{"gitId":"-"},"content":" }"},{"lineNumber":482,"author":{"gitId":"-"},"content":""},{"lineNumber":483,"author":{"gitId":"-"},"content":" public void verifyContributionQuestion(int qnNumber, FeedbackContributionQuestionDetails questionDetails) {"},{"lineNumber":484,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":485,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(getContributionDropdowns(qnNumber).get(0), \"Not Sure\");"},{"lineNumber":486,"author":{"gitId":"-"},"content":" assertTrue(questionDetails.isNotSureAllowed());"},{"lineNumber":487,"author":{"gitId":"-"},"content":" assertFalse(questionDetails.isZeroSum());"},{"lineNumber":488,"author":{"gitId":"-"},"content":" } catch (NoSuchElementException e) {"},{"lineNumber":489,"author":{"gitId":"-"},"content":" assertFalse(questionDetails.isNotSureAllowed());"},{"lineNumber":490,"author":{"gitId":"-"},"content":" }"},{"lineNumber":491,"author":{"gitId":"-"},"content":" }"},{"lineNumber":492,"author":{"gitId":"-"},"content":""},{"lineNumber":493,"author":{"gitId":"-"},"content":" public void fillContributionResponse(int qnNumber, List\u003cFeedbackResponseAttributes\u003e responses) {"},{"lineNumber":494,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e dropdowns \u003d getContributionDropdowns(qnNumber);"},{"lineNumber":495,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c responses.size(); i++) {"},{"lineNumber":496,"author":{"gitId":"-"},"content":" FeedbackContributionResponseDetails response \u003d"},{"lineNumber":497,"author":{"gitId":"-"},"content":" (FeedbackContributionResponseDetails) responses.get(i).getResponseDetailsCopy();"},{"lineNumber":498,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(dropdowns.get(i), getContributionString(response.getAnswer()));"},{"lineNumber":499,"author":{"gitId":"-"},"content":" }"},{"lineNumber":500,"author":{"gitId":"-"},"content":" }"},{"lineNumber":501,"author":{"gitId":"-"},"content":""},{"lineNumber":502,"author":{"gitId":"-"},"content":" public void verifyContributionResponse(int qnNumber, List\u003cFeedbackResponseAttributes\u003e responses) {"},{"lineNumber":503,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e dropdowns \u003d getContributionDropdowns(qnNumber);"},{"lineNumber":504,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c responses.size(); i++) {"},{"lineNumber":505,"author":{"gitId":"-"},"content":" FeedbackContributionResponseDetails response \u003d"},{"lineNumber":506,"author":{"gitId":"-"},"content":" (FeedbackContributionResponseDetails) responses.get(i).getResponseDetailsCopy();"},{"lineNumber":507,"author":{"gitId":"-"},"content":" assertEquals(getSelectedDropdownOptionText(dropdowns.get(i)), getContributionString(response.getAnswer()));"},{"lineNumber":508,"author":{"gitId":"-"},"content":" }"},{"lineNumber":509,"author":{"gitId":"-"},"content":" }"},{"lineNumber":510,"author":{"gitId":"-"},"content":""},{"lineNumber":511,"author":{"gitId":"-"},"content":" public void verifyRubricQuestion(int qnNumber, String recipient, FeedbackRubricQuestionDetails questionDetails) {"},{"lineNumber":512,"author":{"gitId":"-"},"content":" List\u003cString\u003e choices \u003d questionDetails.getRubricChoices();"},{"lineNumber":513,"author":{"gitId":"-"},"content":" List\u003cString\u003e subQuestions \u003d questionDetails.getRubricSubQuestions();"},{"lineNumber":514,"author":{"gitId":"-"},"content":" List\u003cList\u003cString\u003e\u003e descriptions \u003d questionDetails.getRubricDescriptions();"},{"lineNumber":515,"author":{"gitId":"-"},"content":""},{"lineNumber":516,"author":{"gitId":"-"},"content":" String[][] expectedTableData \u003d new String[subQuestions.size()][choices.size()];"},{"lineNumber":517,"author":{"gitId":"-"},"content":" String[][] expectedTableRowHeader \u003d new String[1][choices.size()];"},{"lineNumber":518,"author":{"gitId":"-"},"content":" String[][] expectedTableColumnHeader \u003d new String[subQuestions.size()][1];"},{"lineNumber":519,"author":{"gitId":"-"},"content":""},{"lineNumber":520,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c choices.size(); i++) {"},{"lineNumber":521,"author":{"gitId":"-"},"content":" expectedTableRowHeader[0][i] \u003d choices.get(i);"},{"lineNumber":522,"author":{"gitId":"-"},"content":" }"},{"lineNumber":523,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c subQuestions.size(); i++) {"},{"lineNumber":524,"author":{"gitId":"-"},"content":" expectedTableColumnHeader[i][0] \u003d subQuestions.get(i);"},{"lineNumber":525,"author":{"gitId":"-"},"content":" }"},{"lineNumber":526,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c descriptions.size(); i++) {"},{"lineNumber":527,"author":{"gitId":"-"},"content":" List\u003cString\u003e description \u003d descriptions.get(i);"},{"lineNumber":528,"author":{"gitId":"-"},"content":" for (int j \u003d 0; j \u003c description.size(); j++) {"},{"lineNumber":529,"author":{"gitId":"-"},"content":" expectedTableData[i][j] \u003d description.get(j);"},{"lineNumber":530,"author":{"gitId":"-"},"content":" }"},{"lineNumber":531,"author":{"gitId":"-"},"content":" }"},{"lineNumber":532,"author":{"gitId":"-"},"content":" WebElement rubricTable \u003d getRubricTable(qnNumber, recipient);"},{"lineNumber":533,"author":{"gitId":"-"},"content":" verifyTableBodyValues(rubricTable, expectedTableData);"},{"lineNumber":534,"author":{"gitId":"-"},"content":" verifyTableRowHeaderValues(rubricTable, expectedTableRowHeader);"},{"lineNumber":535,"author":{"gitId":"-"},"content":" verifyTableColumnHeaderValues(rubricTable, expectedTableColumnHeader);"},{"lineNumber":536,"author":{"gitId":"-"},"content":" }"},{"lineNumber":537,"author":{"gitId":"-"},"content":""},{"lineNumber":538,"author":{"gitId":"-"},"content":" public void fillRubricResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":539,"author":{"gitId":"-"},"content":" FeedbackRubricResponseDetails responseDetails \u003d"},{"lineNumber":540,"author":{"gitId":"-"},"content":" (FeedbackRubricResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":541,"author":{"gitId":"-"},"content":" List\u003cInteger\u003e answers \u003d responseDetails.getAnswer();"},{"lineNumber":542,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c answers.size(); i++) {"},{"lineNumber":543,"author":{"gitId":"-"},"content":" click(getRubricInputs(qnNumber, recipient, i + 2).get(answers.get(i)));"},{"lineNumber":544,"author":{"gitId":"-"},"content":" }"},{"lineNumber":545,"author":{"gitId":"-"},"content":" }"},{"lineNumber":546,"author":{"gitId":"-"},"content":""},{"lineNumber":547,"author":{"gitId":"-"},"content":" public void verifyRubricResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":548,"author":{"gitId":"-"},"content":" FeedbackRubricResponseDetails responseDetails \u003d"},{"lineNumber":549,"author":{"gitId":"-"},"content":" (FeedbackRubricResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":550,"author":{"gitId":"-"},"content":" List\u003cInteger\u003e answers \u003d responseDetails.getAnswer();"},{"lineNumber":551,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c answers.size(); i++) {"},{"lineNumber":552,"author":{"gitId":"-"},"content":" assertTrue(getRubricInputs(qnNumber, recipient, i + 2).get(answers.get(i)).isSelected());"},{"lineNumber":553,"author":{"gitId":"-"},"content":" }"},{"lineNumber":554,"author":{"gitId":"-"},"content":" }"},{"lineNumber":555,"author":{"gitId":"-"},"content":""},{"lineNumber":556,"author":{"gitId":"-"},"content":" public void verifyRankQuestion(int qnNumber, String recipient, FeedbackRankQuestionDetails questionDetails) {"},{"lineNumber":557,"author":{"gitId":"-"},"content":" if (questionDetails.getMaxOptionsToBeRanked() !\u003d Const.POINTS_NO_VALUE) {"},{"lineNumber":558,"author":{"gitId":"-"},"content":" assertEquals(getQuestionForm(qnNumber).findElement(By.id(\"max-options-message\")).getText(),"},{"lineNumber":559,"author":{"gitId":"-"},"content":" \"Rank no more than \" + questionDetails.getMaxOptionsToBeRanked() + \" options.\");"},{"lineNumber":560,"author":{"gitId":"-"},"content":" }"},{"lineNumber":561,"author":{"gitId":"-"},"content":" if (questionDetails.getMinOptionsToBeRanked() !\u003d Const.POINTS_NO_VALUE) {"},{"lineNumber":562,"author":{"gitId":"-"},"content":" assertEquals(getQuestionForm(qnNumber).findElement(By.id(\"min-options-message\")).getText(),"},{"lineNumber":563,"author":{"gitId":"-"},"content":" \"Rank at least \" + questionDetails.getMinOptionsToBeRanked() + \" options.\");"},{"lineNumber":564,"author":{"gitId":"-"},"content":" }"},{"lineNumber":565,"author":{"gitId":"-"},"content":" if (questionDetails instanceof FeedbackRankOptionsQuestionDetails) {"},{"lineNumber":566,"author":{"gitId":"-"},"content":" FeedbackRankOptionsQuestionDetails optionDetails \u003d (FeedbackRankOptionsQuestionDetails) questionDetails;"},{"lineNumber":567,"author":{"gitId":"-"},"content":" List\u003cString\u003e options \u003d optionDetails.getOptions();"},{"lineNumber":568,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getRankOptions(qnNumber, recipient);"},{"lineNumber":569,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c options.size(); i++) {"},{"lineNumber":570,"author":{"gitId":"-"},"content":" assertEquals(options.get(i), optionTexts.get(i).getText());"},{"lineNumber":571,"author":{"gitId":"-"},"content":" }"},{"lineNumber":572,"author":{"gitId":"-"},"content":" }"},{"lineNumber":573,"author":{"gitId":"-"},"content":" }"},{"lineNumber":574,"author":{"gitId":"-"},"content":""},{"lineNumber":575,"author":{"gitId":"-"},"content":" public void fillRankOptionResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":576,"author":{"gitId":"-"},"content":" FeedbackRankOptionsResponseDetails responseDetails \u003d"},{"lineNumber":577,"author":{"gitId":"-"},"content":" (FeedbackRankOptionsResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":578,"author":{"gitId":"-"},"content":" List\u003cInteger\u003e answers \u003d responseDetails.getAnswers();"},{"lineNumber":579,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c answers.size(); i++) {"},{"lineNumber":580,"author":{"gitId":"-"},"content":" if (answers.get(i) \u003d\u003d Const.POINTS_NOT_SUBMITTED) {"},{"lineNumber":581,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(getRankOptionsDropdowns(qnNumber, recipient).get(i), \"\");"},{"lineNumber":582,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":583,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(getRankOptionsDropdowns(qnNumber, recipient).get(i),"},{"lineNumber":584,"author":{"gitId":"-"},"content":" Integer.toString(answers.get(i)));"},{"lineNumber":585,"author":{"gitId":"-"},"content":" }"},{"lineNumber":586,"author":{"gitId":"-"},"content":" }"},{"lineNumber":587,"author":{"gitId":"-"},"content":" }"},{"lineNumber":588,"author":{"gitId":"-"},"content":""},{"lineNumber":589,"author":{"gitId":"mingyuanc"},"content":" public void fillRankOptionResponse(int qnNumber, String recipient, FeedbackResponse response) {"},{"lineNumber":590,"author":{"gitId":"mingyuanc"},"content":" FeedbackRankOptionsResponseDetails responseDetails \u003d"},{"lineNumber":591,"author":{"gitId":"mingyuanc"},"content":" (FeedbackRankOptionsResponseDetails) response.getFeedbackResponseDetailsCopy();"},{"lineNumber":592,"author":{"gitId":"mingyuanc"},"content":" List\u003cInteger\u003e answers \u003d responseDetails.getAnswers();"},{"lineNumber":593,"author":{"gitId":"mingyuanc"},"content":" for (int i \u003d 0; i \u003c answers.size(); i++) {"},{"lineNumber":594,"author":{"gitId":"mingyuanc"},"content":" if (answers.get(i) \u003d\u003d Const.POINTS_NOT_SUBMITTED) {"},{"lineNumber":595,"author":{"gitId":"mingyuanc"},"content":" selectDropdownOptionByText(getRankOptionsDropdowns(qnNumber, recipient).get(i), \"\");"},{"lineNumber":596,"author":{"gitId":"mingyuanc"},"content":" } else {"},{"lineNumber":597,"author":{"gitId":"mingyuanc"},"content":" selectDropdownOptionByText(getRankOptionsDropdowns(qnNumber, recipient).get(i),"},{"lineNumber":598,"author":{"gitId":"mingyuanc"},"content":" Integer.toString(answers.get(i)));"},{"lineNumber":599,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":600,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":601,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":602,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":603,"author":{"gitId":"-"},"content":" public void verifyRankOptionResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":604,"author":{"gitId":"-"},"content":" FeedbackRankOptionsResponseDetails responseDetails \u003d"},{"lineNumber":605,"author":{"gitId":"-"},"content":" (FeedbackRankOptionsResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":606,"author":{"gitId":"-"},"content":" List\u003cInteger\u003e answers \u003d responseDetails.getAnswers();"},{"lineNumber":607,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c answers.size(); i++) {"},{"lineNumber":608,"author":{"gitId":"-"},"content":" if (answers.get(i) \u003d\u003d Const.POINTS_NOT_SUBMITTED) {"},{"lineNumber":609,"author":{"gitId":"-"},"content":" assertEquals(getSelectedDropdownOptionText(getRankOptionsDropdowns(qnNumber, recipient).get(i)),"},{"lineNumber":610,"author":{"gitId":"-"},"content":" \"\");"},{"lineNumber":611,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":612,"author":{"gitId":"-"},"content":" assertEquals(getSelectedDropdownOptionText(getRankOptionsDropdowns(qnNumber, recipient).get(i)),"},{"lineNumber":613,"author":{"gitId":"-"},"content":" Integer.toString(answers.get(i)));"},{"lineNumber":614,"author":{"gitId":"-"},"content":" }"},{"lineNumber":615,"author":{"gitId":"-"},"content":" }"},{"lineNumber":616,"author":{"gitId":"-"},"content":" }"},{"lineNumber":617,"author":{"gitId":"-"},"content":""},{"lineNumber":618,"author":{"gitId":"-"},"content":" public void fillRankRecipientResponse(int qnNumber, List\u003cFeedbackResponseAttributes\u003e responses) {"},{"lineNumber":619,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e recipientDropdowns \u003d getRankRecipientDropdowns(qnNumber);"},{"lineNumber":620,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c responses.size(); i++) {"},{"lineNumber":621,"author":{"gitId":"-"},"content":" FeedbackRankRecipientsResponseDetails response \u003d"},{"lineNumber":622,"author":{"gitId":"-"},"content":" (FeedbackRankRecipientsResponseDetails) responses.get(i).getResponseDetailsCopy();"},{"lineNumber":623,"author":{"gitId":"-"},"content":" if (response.getAnswer() \u003d\u003d Const.POINTS_NOT_SUBMITTED) {"},{"lineNumber":624,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(recipientDropdowns.get(i), \"\");"},{"lineNumber":625,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":626,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(recipientDropdowns.get(i), Integer.toString(response.getAnswer()));"},{"lineNumber":627,"author":{"gitId":"-"},"content":" }"},{"lineNumber":628,"author":{"gitId":"-"},"content":" }"},{"lineNumber":629,"author":{"gitId":"-"},"content":" }"},{"lineNumber":630,"author":{"gitId":"-"},"content":""},{"lineNumber":631,"author":{"gitId":"-"},"content":" public void verifyRankRecipientResponse(int qnNumber, List\u003cFeedbackResponseAttributes\u003e responses) {"},{"lineNumber":632,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e recipientDropdowns \u003d getRankRecipientDropdowns(qnNumber);"},{"lineNumber":633,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c responses.size(); i++) {"},{"lineNumber":634,"author":{"gitId":"-"},"content":" FeedbackRankRecipientsResponseDetails response \u003d"},{"lineNumber":635,"author":{"gitId":"-"},"content":" (FeedbackRankRecipientsResponseDetails) responses.get(i).getResponseDetailsCopy();"},{"lineNumber":636,"author":{"gitId":"-"},"content":" if (response.getAnswer() \u003d\u003d Const.POINTS_NOT_SUBMITTED) {"},{"lineNumber":637,"author":{"gitId":"-"},"content":" assertEquals(getSelectedDropdownOptionText(recipientDropdowns.get(i)), \"\");"},{"lineNumber":638,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":639,"author":{"gitId":"-"},"content":" assertEquals(getSelectedDropdownOptionText(recipientDropdowns.get(i)),"},{"lineNumber":640,"author":{"gitId":"-"},"content":" Integer.toString(response.getAnswer()));"},{"lineNumber":641,"author":{"gitId":"-"},"content":" }"},{"lineNumber":642,"author":{"gitId":"-"},"content":" }"},{"lineNumber":643,"author":{"gitId":"-"},"content":" }"},{"lineNumber":644,"author":{"gitId":"-"},"content":""},{"lineNumber":645,"author":{"gitId":"-"},"content":" private String getCourseId() {"},{"lineNumber":646,"author":{"gitId":"-"},"content":" return browser.driver.findElement(By.id(\"course-id\")).getText();"},{"lineNumber":647,"author":{"gitId":"-"},"content":" }"},{"lineNumber":648,"author":{"gitId":"-"},"content":""},{"lineNumber":649,"author":{"gitId":"-"},"content":" private String getCourseName() {"},{"lineNumber":650,"author":{"gitId":"-"},"content":" return browser.driver.findElement(By.id(\"course-name\")).getText();"},{"lineNumber":651,"author":{"gitId":"-"},"content":" }"},{"lineNumber":652,"author":{"gitId":"-"},"content":""},{"lineNumber":653,"author":{"gitId":"-"},"content":" private String getCourseInstitute() {"},{"lineNumber":654,"author":{"gitId":"-"},"content":" return browser.driver.findElement(By.id(\"course-institute\")).getText();"},{"lineNumber":655,"author":{"gitId":"-"},"content":" }"},{"lineNumber":656,"author":{"gitId":"-"},"content":""},{"lineNumber":657,"author":{"gitId":"-"},"content":" private String getFeedbackSessionName() {"},{"lineNumber":658,"author":{"gitId":"-"},"content":" return browser.driver.findElement(By.id(\"fs-name\")).getText();"},{"lineNumber":659,"author":{"gitId":"-"},"content":" }"},{"lineNumber":660,"author":{"gitId":"-"},"content":""},{"lineNumber":661,"author":{"gitId":"-"},"content":" private String getOpeningTime() {"},{"lineNumber":662,"author":{"gitId":"-"},"content":" return browser.driver.findElement(By.id(\"opening-time\")).getText();"},{"lineNumber":663,"author":{"gitId":"-"},"content":" }"},{"lineNumber":664,"author":{"gitId":"-"},"content":""},{"lineNumber":665,"author":{"gitId":"-"},"content":" private String getClosingTime() {"},{"lineNumber":666,"author":{"gitId":"-"},"content":" return browser.driver.findElement(By.id(\"closing-time\")).getText();"},{"lineNumber":667,"author":{"gitId":"-"},"content":" }"},{"lineNumber":668,"author":{"gitId":"-"},"content":""},{"lineNumber":669,"author":{"gitId":"-"},"content":" private String getInstructions() {"},{"lineNumber":670,"author":{"gitId":"-"},"content":" return browser.driver.findElement(By.id(\"instructions\")).getAttribute(\"innerHTML\");"},{"lineNumber":671,"author":{"gitId":"-"},"content":" }"},{"lineNumber":672,"author":{"gitId":"-"},"content":""},{"lineNumber":673,"author":{"gitId":"-"},"content":" private void assertDateEquals(String actual, Instant instant, String timeZone) {"},{"lineNumber":674,"author":{"gitId":"-"},"content":" String dateStrWithAbbr \u003d getDateStringWithAbbr(instant, timeZone);"},{"lineNumber":675,"author":{"gitId":"-"},"content":" String dateStrWithOffset \u003d getDateStringWithOffset(instant, timeZone);"},{"lineNumber":676,"author":{"gitId":"-"},"content":""},{"lineNumber":677,"author":{"gitId":"-"},"content":" boolean isExpected \u003d actual.equals(dateStrWithAbbr) || actual.equals(dateStrWithOffset);"},{"lineNumber":678,"author":{"gitId":"-"},"content":" assertTrue(isExpected);"},{"lineNumber":679,"author":{"gitId":"-"},"content":" }"},{"lineNumber":680,"author":{"gitId":"-"},"content":""},{"lineNumber":681,"author":{"gitId":"-"},"content":" private String getDateStringWithAbbr(Instant instant, String timeZone) {"},{"lineNumber":682,"author":{"gitId":"-"},"content":" return getDisplayedDateTime(instant, timeZone, \"EE, dd MMM, yyyy, hh:mm a z\");"},{"lineNumber":683,"author":{"gitId":"-"},"content":" }"},{"lineNumber":684,"author":{"gitId":"-"},"content":""},{"lineNumber":685,"author":{"gitId":"-"},"content":" private String getDateStringWithOffset(Instant instant, String timeZone) {"},{"lineNumber":686,"author":{"gitId":"-"},"content":" return getDisplayedDateTime(instant, timeZone, \"EE, dd MMM, yyyy, hh:mm a X\");"},{"lineNumber":687,"author":{"gitId":"-"},"content":" }"},{"lineNumber":688,"author":{"gitId":"-"},"content":""},{"lineNumber":689,"author":{"gitId":"-"},"content":" private WebElement getQuestionForm(int qnNumber) {"},{"lineNumber":690,"author":{"gitId":"-"},"content":" By questionFormId \u003d By.id(\"question-submission-form-qn-\" + qnNumber);"},{"lineNumber":691,"author":{"gitId":"-"},"content":" waitForElementPresence(questionFormId);"},{"lineNumber":692,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d browser.driver.findElement(questionFormId);"},{"lineNumber":693,"author":{"gitId":"-"},"content":" // Scroll to the question to ensure that the details are fully loaded"},{"lineNumber":694,"author":{"gitId":"-"},"content":" scrollElementToCenter(questionForm);"},{"lineNumber":695,"author":{"gitId":"-"},"content":" waitUntilAnimationFinish();"},{"lineNumber":696,"author":{"gitId":"-"},"content":" return questionForm;"},{"lineNumber":697,"author":{"gitId":"-"},"content":" }"},{"lineNumber":698,"author":{"gitId":"-"},"content":""},{"lineNumber":699,"author":{"gitId":"-"},"content":" private String getQuestionBrief(int qnNumber) {"},{"lineNumber":700,"author":{"gitId":"-"},"content":" String questionDetails \u003d getQuestionForm(qnNumber).findElement(By.className(\"question-details\")).getText();"},{"lineNumber":701,"author":{"gitId":"-"},"content":" return questionDetails.split(\": \")[1];"},{"lineNumber":702,"author":{"gitId":"-"},"content":" }"},{"lineNumber":703,"author":{"gitId":"-"},"content":""},{"lineNumber":704,"author":{"gitId":"-"},"content":" private void verifyVisibilityList(int qnNumber, FeedbackQuestionAttributes questionAttributes) {"},{"lineNumber":705,"author":{"gitId":"-"},"content":" if (questionAttributes.getShowResponsesTo().isEmpty()) {"},{"lineNumber":706,"author":{"gitId":"-"},"content":" verifyVisibilityStringPresent(qnNumber, \"No-one can see your responses\");"},{"lineNumber":707,"author":{"gitId":"-"},"content":" }"},{"lineNumber":708,"author":{"gitId":"-"},"content":" if (questionAttributes.getRecipientType().equals(FeedbackParticipantType.SELF)) {"},{"lineNumber":709,"author":{"gitId":"-"},"content":" verifyVisibilityStringPresent(qnNumber, \"You can see your own feedback in the results page later on.\");"},{"lineNumber":710,"author":{"gitId":"-"},"content":" }"},{"lineNumber":711,"author":{"gitId":"-"},"content":" for (FeedbackParticipantType viewerType : questionAttributes.getShowResponsesTo()) {"},{"lineNumber":712,"author":{"gitId":"-"},"content":" verifyVisibilityStringPresent(qnNumber, getVisibilityString(questionAttributes, viewerType));"},{"lineNumber":713,"author":{"gitId":"-"},"content":" }"},{"lineNumber":714,"author":{"gitId":"-"},"content":" }"},{"lineNumber":715,"author":{"gitId":"-"},"content":""},{"lineNumber":716,"author":{"gitId":"-"},"content":" private void verifyVisibilityStringPresent(int qnNumber, String expectedString) {"},{"lineNumber":717,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e visibilityStrings \u003d getQuestionForm(qnNumber).findElement(By.className(\"visibility-list\"))"},{"lineNumber":718,"author":{"gitId":"-"},"content":" .findElements(By.tagName(\"li\"));"},{"lineNumber":719,"author":{"gitId":"-"},"content":" for (WebElement visibilityString : visibilityStrings) {"},{"lineNumber":720,"author":{"gitId":"-"},"content":" if (visibilityString.getText().equals(expectedString)) {"},{"lineNumber":721,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":722,"author":{"gitId":"-"},"content":" }"},{"lineNumber":723,"author":{"gitId":"-"},"content":" }"},{"lineNumber":724,"author":{"gitId":"-"},"content":" fail(\"Expected visibility string not found: \" + qnNumber + \": \" + expectedString);"},{"lineNumber":725,"author":{"gitId":"-"},"content":" }"},{"lineNumber":726,"author":{"gitId":"-"},"content":""},{"lineNumber":727,"author":{"gitId":"-"},"content":" private String getVisibilityString(FeedbackQuestionAttributes questionAttributes,"},{"lineNumber":728,"author":{"gitId":"-"},"content":" FeedbackParticipantType viewerType) {"},{"lineNumber":729,"author":{"gitId":"-"},"content":" if (!questionAttributes.getShowResponsesTo().contains(viewerType)) {"},{"lineNumber":730,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":731,"author":{"gitId":"-"},"content":" }"},{"lineNumber":732,"author":{"gitId":"-"},"content":""},{"lineNumber":733,"author":{"gitId":"-"},"content":" StringBuilder message \u003d new StringBuilder(getViewerString(viewerType, questionAttributes.getRecipientType()));"},{"lineNumber":734,"author":{"gitId":"-"},"content":" message.append(\" can see your response\");"},{"lineNumber":735,"author":{"gitId":"-"},"content":" if (questionAttributes.getShowRecipientNameTo().contains(viewerType)) {"},{"lineNumber":736,"author":{"gitId":"-"},"content":" message.append(\", the name of the recipient\");"},{"lineNumber":737,"author":{"gitId":"-"},"content":" if (questionAttributes.getShowGiverNameTo().contains(viewerType)) {"},{"lineNumber":738,"author":{"gitId":"-"},"content":" message.append(\", and your name\");"},{"lineNumber":739,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":740,"author":{"gitId":"-"},"content":" message.append(\", but not your name\");"},{"lineNumber":741,"author":{"gitId":"-"},"content":" }"},{"lineNumber":742,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":743,"author":{"gitId":"-"},"content":" if (questionAttributes.getShowGiverNameTo().contains(viewerType)) {"},{"lineNumber":744,"author":{"gitId":"-"},"content":" message.append(\", and your name, but not the name of the recipient\");"},{"lineNumber":745,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":746,"author":{"gitId":"-"},"content":" message.append(\", but not the name of the recipient, or your name\");"},{"lineNumber":747,"author":{"gitId":"-"},"content":" }"},{"lineNumber":748,"author":{"gitId":"-"},"content":" }"},{"lineNumber":749,"author":{"gitId":"-"},"content":" return message.toString();"},{"lineNumber":750,"author":{"gitId":"-"},"content":" }"},{"lineNumber":751,"author":{"gitId":"-"},"content":""},{"lineNumber":752,"author":{"gitId":"-"},"content":" private String getViewerString(FeedbackParticipantType viewerType, FeedbackParticipantType recipientType) {"},{"lineNumber":753,"author":{"gitId":"-"},"content":" switch (viewerType) {"},{"lineNumber":754,"author":{"gitId":"-"},"content":" case RECEIVER:"},{"lineNumber":755,"author":{"gitId":"-"},"content":" return \"The receiving \" + getRecipientString(recipientType);"},{"lineNumber":756,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":757,"author":{"gitId":"-"},"content":" return \"Your team members\";"},{"lineNumber":758,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":759,"author":{"gitId":"-"},"content":" return \"Other students in the course\";"},{"lineNumber":760,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":761,"author":{"gitId":"-"},"content":" return \"Instructors in this course\";"},{"lineNumber":762,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":763,"author":{"gitId":"-"},"content":" throw new RuntimeException(\"Unknown viewer type\");"},{"lineNumber":764,"author":{"gitId":"-"},"content":" }"},{"lineNumber":765,"author":{"gitId":"-"},"content":" }"},{"lineNumber":766,"author":{"gitId":"-"},"content":""},{"lineNumber":767,"author":{"gitId":"-"},"content":" private String getRecipientString(FeedbackParticipantType recipientType) {"},{"lineNumber":768,"author":{"gitId":"-"},"content":" switch (recipientType) {"},{"lineNumber":769,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":770,"author":{"gitId":"-"},"content":" case TEAMS_EXCLUDING_SELF:"},{"lineNumber":771,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":772,"author":{"gitId":"-"},"content":" return \"teams\";"},{"lineNumber":773,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":774,"author":{"gitId":"-"},"content":" return \"student\";"},{"lineNumber":775,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":776,"author":{"gitId":"-"},"content":" case STUDENTS_EXCLUDING_SELF:"},{"lineNumber":777,"author":{"gitId":"-"},"content":" case STUDENTS_IN_SAME_SECTION:"},{"lineNumber":778,"author":{"gitId":"-"},"content":" return \"students\";"},{"lineNumber":779,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":780,"author":{"gitId":"-"},"content":" return \"instructors\";"},{"lineNumber":781,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":782,"author":{"gitId":"-"},"content":" throw new RuntimeException(\"Unknown recipientType\");"},{"lineNumber":783,"author":{"gitId":"-"},"content":" }"},{"lineNumber":784,"author":{"gitId":"-"},"content":" }"},{"lineNumber":785,"author":{"gitId":"-"},"content":""},{"lineNumber":786,"author":{"gitId":"-"},"content":" public void clickSubmitQuestionButton(int qnNumber) {"},{"lineNumber":787,"author":{"gitId":"-"},"content":" WebElement submitQnButton \u003d waitForElementPresence(By.id(\"btn-submit-qn-\" + qnNumber));"},{"lineNumber":788,"author":{"gitId":"-"},"content":" clickAndConfirm(submitQnButton);"},{"lineNumber":789,"author":{"gitId":"-"},"content":" }"},{"lineNumber":790,"author":{"gitId":"-"},"content":""},{"lineNumber":791,"author":{"gitId":"-"},"content":" public void clickSubmitAllQuestionsButton() {"},{"lineNumber":792,"author":{"gitId":"-"},"content":" clickAndConfirm(getSubmitAllQuestionsButton());"},{"lineNumber":793,"author":{"gitId":"-"},"content":" }"},{"lineNumber":794,"author":{"gitId":"-"},"content":""},{"lineNumber":795,"author":{"gitId":"-"},"content":" private WebElement getSubmitAllQuestionsButton() {"},{"lineNumber":796,"author":{"gitId":"-"},"content":" return waitForElementPresence(By.id(\"btn-submit\"));"},{"lineNumber":797,"author":{"gitId":"-"},"content":" }"},{"lineNumber":798,"author":{"gitId":"-"},"content":""},{"lineNumber":799,"author":{"gitId":"-"},"content":" private String getQuestionDescription(int qnNumber) {"},{"lineNumber":800,"author":{"gitId":"-"},"content":" return getQuestionForm(qnNumber).findElement(By.className(\"question-description\")).getAttribute(\"innerHTML\");"},{"lineNumber":801,"author":{"gitId":"-"},"content":" }"},{"lineNumber":802,"author":{"gitId":"-"},"content":""},{"lineNumber":803,"author":{"gitId":"-"},"content":" private WebElement getCommentSection(int qnNumber, String recipient) {"},{"lineNumber":804,"author":{"gitId":"-"},"content":" int recipientIndex \u003d getRecipientIndex(qnNumber, recipient);"},{"lineNumber":805,"author":{"gitId":"-"},"content":" return getQuestionForm(qnNumber).findElement(By.id(\"comment-section-qn-\" + qnNumber + \"-idx-\" + recipientIndex));"},{"lineNumber":806,"author":{"gitId":"-"},"content":" }"},{"lineNumber":807,"author":{"gitId":"-"},"content":""},{"lineNumber":808,"author":{"gitId":"-"},"content":" private void writeToCommentEditor(WebElement commentSection, String comment) {"},{"lineNumber":809,"author":{"gitId":"-"},"content":" scrollElementToCenter(commentSection);"},{"lineNumber":810,"author":{"gitId":"-"},"content":" waitForElementPresence(By.tagName(\"editor\"));"},{"lineNumber":811,"author":{"gitId":"-"},"content":" writeToRichTextEditor(commentSection.findElement(By.tagName(\"editor\")), comment);"},{"lineNumber":812,"author":{"gitId":"-"},"content":" }"},{"lineNumber":813,"author":{"gitId":"-"},"content":""},{"lineNumber":814,"author":{"gitId":"-"},"content":" private int getRecipientIndex(int qnNumber, String recipient) {"},{"lineNumber":815,"author":{"gitId":"-"},"content":" // For questions with recipient none or self."},{"lineNumber":816,"author":{"gitId":"-"},"content":" if (recipient.isEmpty()) {"},{"lineNumber":817,"author":{"gitId":"-"},"content":" return 0;"},{"lineNumber":818,"author":{"gitId":"-"},"content":" }"},{"lineNumber":819,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(qnNumber);"},{"lineNumber":820,"author":{"gitId":"-"},"content":" // For questions with flexible recipient."},{"lineNumber":821,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":822,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e recipientDropdowns \u003d"},{"lineNumber":823,"author":{"gitId":"-"},"content":" questionForm.findElements(By.cssSelector(\"[id^\u003d\u0027recipient-dropdown-qn-\u0027]\"));"},{"lineNumber":824,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c recipientDropdowns.size(); i++) {"},{"lineNumber":825,"author":{"gitId":"-"},"content":" String dropdownText \u003d getSelectedDropdownOptionText(recipientDropdowns.get(i));"},{"lineNumber":826,"author":{"gitId":"-"},"content":" if (dropdownText.isEmpty()) {"},{"lineNumber":827,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(recipientDropdowns.get(i), recipient);"},{"lineNumber":828,"author":{"gitId":"-"},"content":" return i;"},{"lineNumber":829,"author":{"gitId":"-"},"content":" } else if (dropdownText.equals(recipient)) {"},{"lineNumber":830,"author":{"gitId":"-"},"content":" return i;"},{"lineNumber":831,"author":{"gitId":"-"},"content":" }"},{"lineNumber":832,"author":{"gitId":"-"},"content":" }"},{"lineNumber":833,"author":{"gitId":"-"},"content":" } catch (NoSuchElementException e) {"},{"lineNumber":834,"author":{"gitId":"-"},"content":" // continue"},{"lineNumber":835,"author":{"gitId":"-"},"content":" }"},{"lineNumber":836,"author":{"gitId":"-"},"content":" int limit \u003d 20; // we are not likely to set test data exceeding this number"},{"lineNumber":837,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c limit; i++) {"},{"lineNumber":838,"author":{"gitId":"-"},"content":" if (questionForm.findElement(By.id(\"recipient-name-qn-\" + qnNumber + \"-idx-\" + i))"},{"lineNumber":839,"author":{"gitId":"-"},"content":" .getText().contains(recipient)) {"},{"lineNumber":840,"author":{"gitId":"-"},"content":" return i;"},{"lineNumber":841,"author":{"gitId":"-"},"content":" }"},{"lineNumber":842,"author":{"gitId":"-"},"content":" }"},{"lineNumber":843,"author":{"gitId":"-"},"content":" return -1;"},{"lineNumber":844,"author":{"gitId":"-"},"content":" }"},{"lineNumber":845,"author":{"gitId":"-"},"content":""},{"lineNumber":846,"author":{"gitId":"-"},"content":" private WebElement getTextResponseEditor(int qnNumber, String recipient) {"},{"lineNumber":847,"author":{"gitId":"-"},"content":" int recipientIndex \u003d getRecipientIndex(qnNumber, recipient);"},{"lineNumber":848,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(qnNumber);"},{"lineNumber":849,"author":{"gitId":"-"},"content":" WebElement editor \u003d questionForm.findElements(By.tagName(\"tm-rich-text-editor\")).get(recipientIndex);"},{"lineNumber":850,"author":{"gitId":"-"},"content":" scrollElementToCenter(editor);"},{"lineNumber":851,"author":{"gitId":"-"},"content":" return editor;"},{"lineNumber":852,"author":{"gitId":"-"},"content":" }"},{"lineNumber":853,"author":{"gitId":"-"},"content":""},{"lineNumber":854,"author":{"gitId":"-"},"content":" private String getResponseLengthText(int qnNumber, String recipient) {"},{"lineNumber":855,"author":{"gitId":"-"},"content":" int recipientIndex \u003d getRecipientIndex(qnNumber, recipient);"},{"lineNumber":856,"author":{"gitId":"-"},"content":" return getQuestionForm(qnNumber).findElements(By.id(\"response-length\")).get(recipientIndex).getText();"},{"lineNumber":857,"author":{"gitId":"-"},"content":" }"},{"lineNumber":858,"author":{"gitId":"-"},"content":""},{"lineNumber":859,"author":{"gitId":"-"},"content":" private String getDoubleString(Double value) {"},{"lineNumber":860,"author":{"gitId":"-"},"content":" return value % 1 \u003d\u003d 0 ? Integer.toString(value.intValue()) : Double.toString(value);"},{"lineNumber":861,"author":{"gitId":"-"},"content":" }"},{"lineNumber":862,"author":{"gitId":"-"},"content":""},{"lineNumber":863,"author":{"gitId":"-"},"content":" private WebElement getMcqSection(int qnNumber, String recipient) {"},{"lineNumber":864,"author":{"gitId":"-"},"content":" int recipientIndex \u003d getRecipientIndex(qnNumber, recipient);"},{"lineNumber":865,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(qnNumber);"},{"lineNumber":866,"author":{"gitId":"-"},"content":" return questionForm.findElements(By.tagName(\"tm-mcq-question-edit-answer-form\")).get(recipientIndex);"},{"lineNumber":867,"author":{"gitId":"-"},"content":" }"},{"lineNumber":868,"author":{"gitId":"-"},"content":""},{"lineNumber":869,"author":{"gitId":"-"},"content":" private WebElement getMcqOtherOptionRadioBtn(int qnNumber, String recipient) {"},{"lineNumber":870,"author":{"gitId":"-"},"content":" WebElement mcqSection \u003d getMcqSection(qnNumber, recipient);"},{"lineNumber":871,"author":{"gitId":"-"},"content":" return mcqSection.findElement(By.cssSelector(\"#other-option input[type\u003dradio]\"));"},{"lineNumber":872,"author":{"gitId":"-"},"content":" }"},{"lineNumber":873,"author":{"gitId":"-"},"content":""},{"lineNumber":874,"author":{"gitId":"-"},"content":" private WebElement getMcqOtherOptionTextbox(int qnNumber, String recipient) {"},{"lineNumber":875,"author":{"gitId":"-"},"content":" WebElement mcqSection \u003d getMcqSection(qnNumber, recipient);"},{"lineNumber":876,"author":{"gitId":"-"},"content":" return mcqSection.findElement(By.cssSelector(\"#other-option input[type\u003dtext]\"));"},{"lineNumber":877,"author":{"gitId":"-"},"content":" }"},{"lineNumber":878,"author":{"gitId":"-"},"content":""},{"lineNumber":879,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getMcqOptions(int qnNumber, String recipient) {"},{"lineNumber":880,"author":{"gitId":"-"},"content":" WebElement mcqSection \u003d getMcqSection(qnNumber, recipient);"},{"lineNumber":881,"author":{"gitId":"-"},"content":" return mcqSection.findElements(By.className(\"option-text\"));"},{"lineNumber":882,"author":{"gitId":"-"},"content":" }"},{"lineNumber":883,"author":{"gitId":"-"},"content":""},{"lineNumber":884,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getMcqRadioBtns(int qnNumber, String recipient) {"},{"lineNumber":885,"author":{"gitId":"-"},"content":" WebElement mcqSection \u003d getMcqSection(qnNumber, recipient);"},{"lineNumber":886,"author":{"gitId":"-"},"content":" return mcqSection.findElements(By.cssSelector(\"input[type\u003dradio]\"));"},{"lineNumber":887,"author":{"gitId":"-"},"content":" }"},{"lineNumber":888,"author":{"gitId":"-"},"content":""},{"lineNumber":889,"author":{"gitId":"-"},"content":" private WebElement getMsqSection(int qnNumber, String recipient) {"},{"lineNumber":890,"author":{"gitId":"-"},"content":" int recipientIndex \u003d getRecipientIndex(qnNumber, recipient);"},{"lineNumber":891,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(qnNumber);"},{"lineNumber":892,"author":{"gitId":"-"},"content":" return questionForm.findElements(By.tagName(\"tm-msq-question-edit-answer-form\")).get(recipientIndex);"},{"lineNumber":893,"author":{"gitId":"-"},"content":" }"},{"lineNumber":894,"author":{"gitId":"-"},"content":""},{"lineNumber":895,"author":{"gitId":"-"},"content":" private WebElement getMsqOtherOptionCheckbox(int qnNumber, String recipient) {"},{"lineNumber":896,"author":{"gitId":"-"},"content":" WebElement msqSection \u003d getMsqSection(qnNumber, recipient);"},{"lineNumber":897,"author":{"gitId":"-"},"content":" return msqSection.findElement(By.cssSelector(\"#other-option input[type\u003dcheckbox]\"));"},{"lineNumber":898,"author":{"gitId":"-"},"content":" }"},{"lineNumber":899,"author":{"gitId":"-"},"content":""},{"lineNumber":900,"author":{"gitId":"-"},"content":" private WebElement getMsqOtherOptionTextbox(int qnNumber, String recipient) {"},{"lineNumber":901,"author":{"gitId":"-"},"content":" WebElement msqSection \u003d getMsqSection(qnNumber, recipient);"},{"lineNumber":902,"author":{"gitId":"-"},"content":" return msqSection.findElement(By.cssSelector(\"#other-option input[type\u003dtext]\"));"},{"lineNumber":903,"author":{"gitId":"-"},"content":" }"},{"lineNumber":904,"author":{"gitId":"-"},"content":""},{"lineNumber":905,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getMsqOptions(int qnNumber, String recipient) {"},{"lineNumber":906,"author":{"gitId":"-"},"content":" WebElement msqSection \u003d getMsqSection(qnNumber, recipient);"},{"lineNumber":907,"author":{"gitId":"-"},"content":" return msqSection.findElements(By.tagName(\"strong\"));"},{"lineNumber":908,"author":{"gitId":"-"},"content":" }"},{"lineNumber":909,"author":{"gitId":"-"},"content":""},{"lineNumber":910,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getMsqCheckboxes(int qnNumber, String recipient) {"},{"lineNumber":911,"author":{"gitId":"-"},"content":" WebElement msqSection \u003d getMsqSection(qnNumber, recipient);"},{"lineNumber":912,"author":{"gitId":"-"},"content":" return msqSection.findElements(By.cssSelector(\"input[type\u003dcheckbox]\"));"},{"lineNumber":913,"author":{"gitId":"-"},"content":" }"},{"lineNumber":914,"author":{"gitId":"-"},"content":""},{"lineNumber":915,"author":{"gitId":"-"},"content":" private WebElement getNumScaleSection(int qnNumber, String recipient) {"},{"lineNumber":916,"author":{"gitId":"-"},"content":" int recipientIndex \u003d getRecipientIndex(qnNumber, recipient);"},{"lineNumber":917,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(qnNumber);"},{"lineNumber":918,"author":{"gitId":"-"},"content":" return questionForm.findElements(By.tagName(\"tm-num-scale-question-edit-answer-form\")).get(recipientIndex);"},{"lineNumber":919,"author":{"gitId":"-"},"content":" }"},{"lineNumber":920,"author":{"gitId":"-"},"content":""},{"lineNumber":921,"author":{"gitId":"-"},"content":" private WebElement getNumScaleInput(int qnNumber, String recipient) {"},{"lineNumber":922,"author":{"gitId":"-"},"content":" WebElement numScaleSection \u003d getNumScaleSection(qnNumber, recipient);"},{"lineNumber":923,"author":{"gitId":"-"},"content":" return numScaleSection.findElement(By.tagName(\"input\"));"},{"lineNumber":924,"author":{"gitId":"-"},"content":" }"},{"lineNumber":925,"author":{"gitId":"-"},"content":""},{"lineNumber":926,"author":{"gitId":"-"},"content":" private WebElement getConstSumOptionsSection(int qnNumber, String recipient) {"},{"lineNumber":927,"author":{"gitId":"-"},"content":" int recipientIndex \u003d getRecipientIndex(qnNumber, recipient);"},{"lineNumber":928,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(qnNumber);"},{"lineNumber":929,"author":{"gitId":"-"},"content":" return questionForm.findElements(By.tagName(\"tm-constsum-options-question-edit-answer-form\")).get(recipientIndex);"},{"lineNumber":930,"author":{"gitId":"-"},"content":" }"},{"lineNumber":931,"author":{"gitId":"-"},"content":""},{"lineNumber":932,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getConstSumOptions(int qnNumber, String recipient) {"},{"lineNumber":933,"author":{"gitId":"-"},"content":" WebElement constSumOptionSection \u003d getConstSumOptionsSection(qnNumber, recipient);"},{"lineNumber":934,"author":{"gitId":"-"},"content":" return constSumOptionSection.findElements(By.tagName(\"strong\"));"},{"lineNumber":935,"author":{"gitId":"-"},"content":" }"},{"lineNumber":936,"author":{"gitId":"-"},"content":""},{"lineNumber":937,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getConstSumInputs(int qnNumber, String recipient) {"},{"lineNumber":938,"author":{"gitId":"-"},"content":" WebElement constSumOptionSection \u003d getConstSumOptionsSection(qnNumber, recipient);"},{"lineNumber":939,"author":{"gitId":"-"},"content":" return constSumOptionSection.findElements(By.cssSelector(\"input[type\u003dnumber]\"));"},{"lineNumber":940,"author":{"gitId":"-"},"content":" }"},{"lineNumber":941,"author":{"gitId":"-"},"content":""},{"lineNumber":942,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getConstSumRecipientInputs(int qnNumber) {"},{"lineNumber":943,"author":{"gitId":"-"},"content":" return getQuestionForm(qnNumber).findElements(By.cssSelector(\"input[type\u003dnumber]\"));"},{"lineNumber":944,"author":{"gitId":"-"},"content":" }"},{"lineNumber":945,"author":{"gitId":"-"},"content":""},{"lineNumber":946,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getContributionDropdowns(int questionNum) {"},{"lineNumber":947,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElements(By.tagName(\"select\"));"},{"lineNumber":948,"author":{"gitId":"-"},"content":" }"},{"lineNumber":949,"author":{"gitId":"-"},"content":""},{"lineNumber":950,"author":{"gitId":"-"},"content":" private String getContributionString(int answer) {"},{"lineNumber":951,"author":{"gitId":"-"},"content":" if (answer \u003d\u003d Const.POINTS_NOT_SURE) {"},{"lineNumber":952,"author":{"gitId":"-"},"content":" return \"Not Sure\";"},{"lineNumber":953,"author":{"gitId":"-"},"content":" } else if (answer \u003d\u003d Const.POINTS_EQUAL_SHARE) {"},{"lineNumber":954,"author":{"gitId":"-"},"content":" return \"Equal share\";"},{"lineNumber":955,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":956,"author":{"gitId":"-"},"content":" return \"Equal share\" + (answer \u003e 100 ? \" + \" : \" - \") + Math.abs(answer - 100) + \"%\";"},{"lineNumber":957,"author":{"gitId":"-"},"content":" }"},{"lineNumber":958,"author":{"gitId":"-"},"content":" }"},{"lineNumber":959,"author":{"gitId":"-"},"content":""},{"lineNumber":960,"author":{"gitId":"-"},"content":" private WebElement getRubricSection(int qnNumber, String recipient) {"},{"lineNumber":961,"author":{"gitId":"-"},"content":" int recipientIndex \u003d getRecipientIndex(qnNumber, recipient);"},{"lineNumber":962,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(qnNumber);"},{"lineNumber":963,"author":{"gitId":"-"},"content":" return questionForm.findElements(By.tagName(\"tm-rubric-question-edit-answer-form\")).get(recipientIndex);"},{"lineNumber":964,"author":{"gitId":"-"},"content":" }"},{"lineNumber":965,"author":{"gitId":"-"},"content":""},{"lineNumber":966,"author":{"gitId":"-"},"content":" private WebElement getRubricTable(int qnNumber, String recipient) {"},{"lineNumber":967,"author":{"gitId":"-"},"content":" return getRubricSection(qnNumber, recipient).findElement(By.tagName(\"table\"));"},{"lineNumber":968,"author":{"gitId":"-"},"content":" }"},{"lineNumber":969,"author":{"gitId":"-"},"content":""},{"lineNumber":970,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getRubricInputs(int qnNumber, String recipient, int rowNumber) {"},{"lineNumber":971,"author":{"gitId":"-"},"content":" WebElement rubricRow \u003d getRubricSection(qnNumber, recipient).findElements(By.tagName(\"tr\")).get(rowNumber - 1);"},{"lineNumber":972,"author":{"gitId":"-"},"content":" return rubricRow.findElements(By.tagName(\"input\"));"},{"lineNumber":973,"author":{"gitId":"-"},"content":" }"},{"lineNumber":974,"author":{"gitId":"-"},"content":""},{"lineNumber":975,"author":{"gitId":"-"},"content":" private WebElement getRankOptionsSection(int qnNumber, String recipient) {"},{"lineNumber":976,"author":{"gitId":"-"},"content":" int recipientIndex \u003d getRecipientIndex(qnNumber, recipient);"},{"lineNumber":977,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(qnNumber);"},{"lineNumber":978,"author":{"gitId":"-"},"content":" return questionForm.findElements(By.tagName(\"tm-rank-options-question-edit-answer-form\")).get(recipientIndex);"},{"lineNumber":979,"author":{"gitId":"-"},"content":" }"},{"lineNumber":980,"author":{"gitId":"-"},"content":""},{"lineNumber":981,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getRankOptions(int questionNum, String recipient) {"},{"lineNumber":982,"author":{"gitId":"-"},"content":" WebElement rankSection \u003d getRankOptionsSection(questionNum, recipient);"},{"lineNumber":983,"author":{"gitId":"-"},"content":" return rankSection.findElements(By.tagName(\"strong\"));"},{"lineNumber":984,"author":{"gitId":"-"},"content":" }"},{"lineNumber":985,"author":{"gitId":"-"},"content":""},{"lineNumber":986,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getRankOptionsDropdowns(int questionNum, String recipient) {"},{"lineNumber":987,"author":{"gitId":"-"},"content":" WebElement rankSection \u003d getRankOptionsSection(questionNum, recipient);"},{"lineNumber":988,"author":{"gitId":"-"},"content":" return rankSection.findElements(By.tagName(\"select\"));"},{"lineNumber":989,"author":{"gitId":"-"},"content":" }"},{"lineNumber":990,"author":{"gitId":"-"},"content":""},{"lineNumber":991,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getRankRecipientDropdowns(int questionNum) {"},{"lineNumber":992,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElements(By.tagName(\"select\"));"},{"lineNumber":993,"author":{"gitId":"-"},"content":" }"},{"lineNumber":994,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":13,"dishenggg":45,"mingyuanc":14,"-":922}},{"path":"src/e2e/java/teammates/e2e/pageobjects/InstructorFeedbackEditPage.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.pageobjects;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertEquals;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertFalse;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertTrue;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.time.ZoneId;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.time.ZonedDateTime;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import java.util.Arrays;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import org.openqa.selenium.By;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import org.openqa.selenium.Keys;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import org.openqa.selenium.WebElement;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import org.openqa.selenium.support.FindBy;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackConstantSumQuestionDetails;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackContributionQuestionDetails;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackMcqQuestionDetails;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackMsqQuestionDetails;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackNumericalScaleQuestionDetails;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionType;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRankOptionsQuestionDetails;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRankQuestionDetails;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRubricQuestionDetails;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackTextQuestionDetails;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.test.ThreadHelper;"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":40,"author":{"gitId":"-"},"content":" * Represents the instructor feedback edit page of the website."},{"lineNumber":41,"author":{"gitId":"-"},"content":" */"},{"lineNumber":42,"author":{"gitId":"-"},"content":"public class InstructorFeedbackEditPage extends AppPage {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" private static final String CUSTOM_FEEDBACK_PATH_OPTION \u003d \"Custom feedback path\";"},{"lineNumber":44,"author":{"gitId":"-"},"content":" private static final String FEEDBACK_PATH_SEPARATOR \u003d \" will give feedback on \";"},{"lineNumber":45,"author":{"gitId":"-"},"content":" private static final String CUSTOM_VISIBILITY_OPTION \u003d \"Custom visibility options\";"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-fs-edit\")"},{"lineNumber":48,"author":{"gitId":"-"},"content":" private WebElement fsEditButton;"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-fs-save\")"},{"lineNumber":51,"author":{"gitId":"-"},"content":" private WebElement fsSaveButton;"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-fs-copy\")"},{"lineNumber":54,"author":{"gitId":"-"},"content":" private WebElement fsCopyButton;"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"edit-course-id\")"},{"lineNumber":57,"author":{"gitId":"-"},"content":" private WebElement courseIdTextBox;"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"time-zone\")"},{"lineNumber":60,"author":{"gitId":"-"},"content":" private WebElement timezoneDropDown;"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"course-name\")"},{"lineNumber":63,"author":{"gitId":"-"},"content":" private WebElement courseNameTextBox;"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"edit-session-name\")"},{"lineNumber":66,"author":{"gitId":"-"},"content":" private WebElement sessionNameTextBox;"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"instructions\")"},{"lineNumber":69,"author":{"gitId":"-"},"content":" private WebElement instructionsEditor;"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"submission-start-date\")"},{"lineNumber":72,"author":{"gitId":"-"},"content":" private WebElement startDateBox;"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"submission-start-time\")"},{"lineNumber":75,"author":{"gitId":"-"},"content":" private WebElement startTimeDropdown;"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"submission-end-date\")"},{"lineNumber":78,"author":{"gitId":"-"},"content":" private WebElement endDateBox;"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"submission-end-time\")"},{"lineNumber":81,"author":{"gitId":"-"},"content":" private WebElement endTimeDropdown;"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"grace-period\")"},{"lineNumber":84,"author":{"gitId":"-"},"content":" private WebElement gracePeriodDropdown;"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"submission-status\")"},{"lineNumber":87,"author":{"gitId":"-"},"content":" private WebElement submissionStatusTextBox;"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"published-status\")"},{"lineNumber":90,"author":{"gitId":"-"},"content":" private WebElement publishStatusTextBox;"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-change-visibility\")"},{"lineNumber":93,"author":{"gitId":"-"},"content":" private WebElement changeVisibilityButton;"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"session-visibility-custom\")"},{"lineNumber":96,"author":{"gitId":"-"},"content":" private WebElement customSessionVisibleTimeButton;"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"session-visibility-date\")"},{"lineNumber":99,"author":{"gitId":"-"},"content":" private WebElement sessionVisibilityDateBox;"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"session-visibility-time\")"},{"lineNumber":102,"author":{"gitId":"-"},"content":" private WebElement sessionVisibilityTimeDropdown;"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"session-visibility-at-open\")"},{"lineNumber":105,"author":{"gitId":"-"},"content":" private WebElement openSessionVisibleTimeButton;"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"response-visibility-custom\")"},{"lineNumber":108,"author":{"gitId":"-"},"content":" private WebElement customResponseVisibleTimeButton;"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"response-visibility-date\")"},{"lineNumber":111,"author":{"gitId":"-"},"content":" private WebElement responseVisibilityDateBox;"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"response-visibility-time\")"},{"lineNumber":114,"author":{"gitId":"-"},"content":" private WebElement responseVisibilityTimeDropdown;"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"response-visibility-immediately\")"},{"lineNumber":117,"author":{"gitId":"-"},"content":" private WebElement immediateResponseVisibleTimeButton;"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"response-visibility-manually\")"},{"lineNumber":120,"author":{"gitId":"-"},"content":" private WebElement manualResponseVisibleTimeButton;"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-change-email\")"},{"lineNumber":123,"author":{"gitId":"-"},"content":" private WebElement changeEmailButton;"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"email-opening\")"},{"lineNumber":126,"author":{"gitId":"-"},"content":" private WebElement openingSessionEmailCheckbox;"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"email-closing\")"},{"lineNumber":129,"author":{"gitId":"-"},"content":" private WebElement closingSessionEmailCheckbox;"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"email-published\")"},{"lineNumber":132,"author":{"gitId":"-"},"content":" private WebElement publishedSessionEmailCheckbox;"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-new-question\")"},{"lineNumber":135,"author":{"gitId":"-"},"content":" private WebElement addNewQuestionButton;"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-copy-question\")"},{"lineNumber":138,"author":{"gitId":"-"},"content":" private WebElement copyQuestionButton;"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"preview-student\")"},{"lineNumber":141,"author":{"gitId":"-"},"content":" private WebElement previewAsStudentDropdown;"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-preview-student\")"},{"lineNumber":144,"author":{"gitId":"-"},"content":" private WebElement previewAsStudentButton;"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"preview-instructor\")"},{"lineNumber":147,"author":{"gitId":"-"},"content":" private WebElement previewAsInstructorDropdown;"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-preview-instructor\")"},{"lineNumber":150,"author":{"gitId":"-"},"content":" private WebElement previewAsInstructorButton;"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" public InstructorFeedbackEditPage(Browser browser) {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" super(browser);"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":157,"author":{"gitId":"-"},"content":" protected boolean containsExpectedPageContents() {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" return getPageTitle().contains(\"Edit Feedback Session\");"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" public void verifySessionDetails(CourseAttributes course, FeedbackSessionAttributes feedbackSession) {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" waitForElementPresence(By.id(\"instructions\"));"},{"lineNumber":163,"author":{"gitId":"-"},"content":" assertEquals(getCourseId(), course.getId());"},{"lineNumber":164,"author":{"gitId":"-"},"content":" assertEquals(getCourseName(), course.getName());"},{"lineNumber":165,"author":{"gitId":"-"},"content":" assertEquals(getTimeZone(), feedbackSession.getTimeZone());"},{"lineNumber":166,"author":{"gitId":"-"},"content":" assertEquals(getFeedbackSessionName(), feedbackSession.getFeedbackSessionName());"},{"lineNumber":167,"author":{"gitId":"-"},"content":" assertEquals(getInstructions(), feedbackSession.getInstructions());"},{"lineNumber":168,"author":{"gitId":"-"},"content":" assertEquals(getStartDate(), getDateString(feedbackSession.getStartTime(), feedbackSession.getTimeZone()));"},{"lineNumber":169,"author":{"gitId":"-"},"content":" assertEquals(getStartTime(), getTimeString(feedbackSession.getStartTime(), feedbackSession.getTimeZone()));"},{"lineNumber":170,"author":{"gitId":"-"},"content":" assertEquals(getEndDate(), getDateString(feedbackSession.getEndTime(), feedbackSession.getTimeZone()));"},{"lineNumber":171,"author":{"gitId":"-"},"content":" assertEquals(getEndTime(), getTimeString(feedbackSession.getEndTime(), feedbackSession.getTimeZone()));"},{"lineNumber":172,"author":{"gitId":"-"},"content":" assertEquals(getGracePeriod(), feedbackSession.getGracePeriodMinutes() + \" min\");"},{"lineNumber":173,"author":{"gitId":"-"},"content":" verifySubmissionStatus(feedbackSession);"},{"lineNumber":174,"author":{"gitId":"-"},"content":" verifyPublishedStatus(feedbackSession);"},{"lineNumber":175,"author":{"gitId":"-"},"content":" verifyVisibilitySettings(feedbackSession);"},{"lineNumber":176,"author":{"gitId":"-"},"content":" verifyEmailSettings(feedbackSession);"},{"lineNumber":177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" private void verifySubmissionStatus(FeedbackSessionAttributes feedbackSession) {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" String submissionStatus \u003d getSubmissionStatus();"},{"lineNumber":181,"author":{"gitId":"-"},"content":" if (feedbackSession.isClosed()) {"},{"lineNumber":182,"author":{"gitId":"-"},"content":" assertEquals(submissionStatus, \"Closed\");"},{"lineNumber":183,"author":{"gitId":"-"},"content":" } else if (feedbackSession.isVisible() \u0026\u0026 (feedbackSession.isOpened() || feedbackSession.isInGracePeriod())) {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" assertEquals(submissionStatus, \"Open\");"},{"lineNumber":185,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" assertEquals(submissionStatus, \"Awaiting\");"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":" }"},{"lineNumber":189,"author":{"gitId":"-"},"content":""},{"lineNumber":190,"author":{"gitId":"-"},"content":" private void verifyPublishedStatus(FeedbackSessionAttributes feedbackSession) {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" String publishedStatus \u003d getPublishedStatus();"},{"lineNumber":192,"author":{"gitId":"-"},"content":" if (feedbackSession.isPublished()) {"},{"lineNumber":193,"author":{"gitId":"-"},"content":" assertEquals(publishedStatus, \"Published\");"},{"lineNumber":194,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":195,"author":{"gitId":"-"},"content":" assertEquals(publishedStatus, \"Not Published\");"},{"lineNumber":196,"author":{"gitId":"-"},"content":" }"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" private void verifyVisibilitySettings(FeedbackSessionAttributes feedbackSession) {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" Instant sessionVisibleTime \u003d feedbackSession.getSessionVisibleFromTime();"},{"lineNumber":201,"author":{"gitId":"-"},"content":" Instant responseVisibleTime \u003d feedbackSession.getResultsVisibleFromTime();"},{"lineNumber":202,"author":{"gitId":"-"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":" // Default settings, assert setting section not expanded"},{"lineNumber":204,"author":{"gitId":"-"},"content":" if (sessionVisibleTime.equals(Const.TIME_REPRESENTS_FOLLOW_OPENING)"},{"lineNumber":205,"author":{"gitId":"-"},"content":" \u0026\u0026 responseVisibleTime.equals(Const.TIME_REPRESENTS_LATER)) {"},{"lineNumber":206,"author":{"gitId":"-"},"content":" assertTrue(isElementPresent(\"btn-change-visibility\"));"},{"lineNumber":207,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":208,"author":{"gitId":"-"},"content":" }"},{"lineNumber":209,"author":{"gitId":"-"},"content":" verifySessionVisibilitySettings(sessionVisibleTime, feedbackSession);"},{"lineNumber":210,"author":{"gitId":"-"},"content":" verifyResponseVisibilitySettings(responseVisibleTime, feedbackSession);"},{"lineNumber":211,"author":{"gitId":"-"},"content":" }"},{"lineNumber":212,"author":{"gitId":"-"},"content":""},{"lineNumber":213,"author":{"gitId":"-"},"content":" private void verifySessionVisibilitySettings(Instant sessionVisibleTime,"},{"lineNumber":214,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes feedbackSession) {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" if (sessionVisibleTime.equals(Const.TIME_REPRESENTS_FOLLOW_OPENING)) {"},{"lineNumber":216,"author":{"gitId":"-"},"content":" assertTrue(openSessionVisibleTimeButton.isSelected());"},{"lineNumber":217,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":218,"author":{"gitId":"-"},"content":" assertTrue(customSessionVisibleTimeButton.isSelected());"},{"lineNumber":219,"author":{"gitId":"-"},"content":" assertEquals(getSessionVisibilityDate(), getDateString(feedbackSession.getSessionVisibleFromTime(),"},{"lineNumber":220,"author":{"gitId":"-"},"content":" feedbackSession.getTimeZone()));"},{"lineNumber":221,"author":{"gitId":"-"},"content":" assertEquals(getSessionVisibilityTime(), getTimeString(feedbackSession.getSessionVisibleFromTime(),"},{"lineNumber":222,"author":{"gitId":"-"},"content":" feedbackSession.getTimeZone()));"},{"lineNumber":223,"author":{"gitId":"-"},"content":" }"},{"lineNumber":224,"author":{"gitId":"-"},"content":" }"},{"lineNumber":225,"author":{"gitId":"-"},"content":""},{"lineNumber":226,"author":{"gitId":"-"},"content":" private void verifyResponseVisibilitySettings(Instant responseVisibleTime,"},{"lineNumber":227,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes feedbackSession) {"},{"lineNumber":228,"author":{"gitId":"-"},"content":" if (responseVisibleTime.equals(Const.TIME_REPRESENTS_FOLLOW_VISIBLE)) {"},{"lineNumber":229,"author":{"gitId":"-"},"content":" assertTrue(immediateResponseVisibleTimeButton.isSelected());"},{"lineNumber":230,"author":{"gitId":"-"},"content":" } else if (responseVisibleTime.equals(Const.TIME_REPRESENTS_LATER)) {"},{"lineNumber":231,"author":{"gitId":"-"},"content":" assertTrue(manualResponseVisibleTimeButton.isSelected());"},{"lineNumber":232,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":233,"author":{"gitId":"-"},"content":" assertTrue(customSessionVisibleTimeButton.isSelected());"},{"lineNumber":234,"author":{"gitId":"-"},"content":" assertEquals(getResponseVisibilityDate(), getDateString(feedbackSession.getResultsVisibleFromTime(),"},{"lineNumber":235,"author":{"gitId":"-"},"content":" feedbackSession.getTimeZone()));"},{"lineNumber":236,"author":{"gitId":"-"},"content":" assertEquals(getResponseVisibilityTime(), getTimeString(feedbackSession.getResultsVisibleFromTime(),"},{"lineNumber":237,"author":{"gitId":"-"},"content":" feedbackSession.getTimeZone()));"},{"lineNumber":238,"author":{"gitId":"-"},"content":" }"},{"lineNumber":239,"author":{"gitId":"-"},"content":" }"},{"lineNumber":240,"author":{"gitId":"-"},"content":""},{"lineNumber":241,"author":{"gitId":"-"},"content":" private void verifyEmailSettings(FeedbackSessionAttributes feedbackSession) {"},{"lineNumber":242,"author":{"gitId":"-"},"content":" boolean isOpeningEmailEnabled \u003d feedbackSession.isOpeningEmailEnabled();"},{"lineNumber":243,"author":{"gitId":"-"},"content":" boolean isClosingEmailEnabled \u003d feedbackSession.isClosingEmailEnabled();"},{"lineNumber":244,"author":{"gitId":"-"},"content":" boolean isPublishedEmailEnabled \u003d feedbackSession.isPublishedEmailEnabled();"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" // Default settings, assert setting section not expanded"},{"lineNumber":247,"author":{"gitId":"-"},"content":" if (isOpeningEmailEnabled \u0026\u0026 isClosingEmailEnabled \u0026\u0026 isPublishedEmailEnabled) {"},{"lineNumber":248,"author":{"gitId":"-"},"content":" assertTrue(isElementPresent(\"btn-change-email\"));"},{"lineNumber":249,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":250,"author":{"gitId":"-"},"content":" }"},{"lineNumber":251,"author":{"gitId":"-"},"content":" if (isOpeningEmailEnabled) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" assertTrue(openingSessionEmailCheckbox.isSelected());"},{"lineNumber":253,"author":{"gitId":"-"},"content":" }"},{"lineNumber":254,"author":{"gitId":"-"},"content":" if (isClosingEmailEnabled) {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" assertTrue(closingSessionEmailCheckbox.isSelected());"},{"lineNumber":256,"author":{"gitId":"-"},"content":" }"},{"lineNumber":257,"author":{"gitId":"-"},"content":" if (isPublishedEmailEnabled) {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" assertTrue(publishedSessionEmailCheckbox.isSelected());"},{"lineNumber":259,"author":{"gitId":"-"},"content":" }"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":""},{"lineNumber":262,"author":{"gitId":"-"},"content":" public void editSessionDetails(FeedbackSessionAttributes newFeedbackSessionDetails) {"},{"lineNumber":263,"author":{"gitId":"-"},"content":" click(fsEditButton);"},{"lineNumber":264,"author":{"gitId":"-"},"content":" setInstructions(newFeedbackSessionDetails.getInstructions());"},{"lineNumber":265,"author":{"gitId":"-"},"content":" setSessionStartDateTime(newFeedbackSessionDetails.getStartTime(), newFeedbackSessionDetails.getTimeZone());"},{"lineNumber":266,"author":{"gitId":"-"},"content":" setSessionEndDateTime(newFeedbackSessionDetails.getEndTime(), newFeedbackSessionDetails.getTimeZone());"},{"lineNumber":267,"author":{"gitId":"-"},"content":" selectGracePeriod(newFeedbackSessionDetails.getGracePeriodMinutes());"},{"lineNumber":268,"author":{"gitId":"-"},"content":" setVisibilitySettings(newFeedbackSessionDetails);"},{"lineNumber":269,"author":{"gitId":"-"},"content":" setEmailSettings(newFeedbackSessionDetails);"},{"lineNumber":270,"author":{"gitId":"-"},"content":" click(fsSaveButton);"},{"lineNumber":271,"author":{"gitId":"-"},"content":" }"},{"lineNumber":272,"author":{"gitId":"-"},"content":""},{"lineNumber":273,"author":{"gitId":"-"},"content":" public void copySessionToOtherCourse(CourseAttributes otherCourse, String sessionName) {"},{"lineNumber":274,"author":{"gitId":"-"},"content":" click(fsCopyButton);"},{"lineNumber":275,"author":{"gitId":"-"},"content":" WebElement copyFsModal \u003d waitForElementPresence(By.id(\"copy-course-modal\"));"},{"lineNumber":276,"author":{"gitId":"-"},"content":""},{"lineNumber":277,"author":{"gitId":"-"},"content":" fillTextBox(copyFsModal.findElement(By.id(\"copy-session-name\")), sessionName);"},{"lineNumber":278,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e options \u003d copyFsModal.findElements(By.className(\"form-check\"));"},{"lineNumber":279,"author":{"gitId":"-"},"content":" for (WebElement option : options) {"},{"lineNumber":280,"author":{"gitId":"-"},"content":" String courseId \u003d option.findElement(By.cssSelector(\"label span\")).getText();"},{"lineNumber":281,"author":{"gitId":"-"},"content":" if (courseId.equals(otherCourse.getId())) {"},{"lineNumber":282,"author":{"gitId":"-"},"content":" click(option.findElement(By.tagName(\"input\")));"},{"lineNumber":283,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":284,"author":{"gitId":"-"},"content":" }"},{"lineNumber":285,"author":{"gitId":"-"},"content":" }"},{"lineNumber":286,"author":{"gitId":"-"},"content":" click(browser.driver.findElement(By.id(\"btn-confirm-copy-course\")));"},{"lineNumber":287,"author":{"gitId":"-"},"content":" }"},{"lineNumber":288,"author":{"gitId":"-"},"content":""},{"lineNumber":289,"author":{"gitId":"-"},"content":" public void deleteSession() {"},{"lineNumber":290,"author":{"gitId":"-"},"content":" clickAndConfirm(waitForElementPresence(By.id(\"btn-fs-delete\")));"},{"lineNumber":291,"author":{"gitId":"-"},"content":" }"},{"lineNumber":292,"author":{"gitId":"-"},"content":""},{"lineNumber":293,"author":{"gitId":"-"},"content":" public FeedbackSubmitPage previewAsStudent(StudentAttributes student) {"},{"lineNumber":294,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(previewAsStudentDropdown, String.format(\"[%s] %s\", student.getTeam(), student.getName()));"},{"lineNumber":295,"author":{"gitId":"-"},"content":" click(previewAsStudentButton);"},{"lineNumber":296,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(2000);"},{"lineNumber":297,"author":{"gitId":"-"},"content":" switchToNewWindow();"},{"lineNumber":298,"author":{"gitId":"-"},"content":" return changePageType(FeedbackSubmitPage.class);"},{"lineNumber":299,"author":{"gitId":"-"},"content":" }"},{"lineNumber":300,"author":{"gitId":"-"},"content":""},{"lineNumber":301,"author":{"gitId":"-"},"content":" public FeedbackSubmitPage previewAsInstructor(InstructorAttributes instructor) {"},{"lineNumber":302,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(previewAsInstructorDropdown, instructor.getName());"},{"lineNumber":303,"author":{"gitId":"-"},"content":" click(previewAsInstructorButton);"},{"lineNumber":304,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(2000);"},{"lineNumber":305,"author":{"gitId":"-"},"content":" switchToNewWindow();"},{"lineNumber":306,"author":{"gitId":"-"},"content":" return changePageType(FeedbackSubmitPage.class);"},{"lineNumber":307,"author":{"gitId":"-"},"content":" }"},{"lineNumber":308,"author":{"gitId":"-"},"content":""},{"lineNumber":309,"author":{"gitId":"-"},"content":" public void verifyNumQuestions(int expected) {"},{"lineNumber":310,"author":{"gitId":"-"},"content":" assertEquals(getNumQuestions(), expected);"},{"lineNumber":311,"author":{"gitId":"-"},"content":" }"},{"lineNumber":312,"author":{"gitId":"-"},"content":""},{"lineNumber":313,"author":{"gitId":"-"},"content":" public void verifyQuestionDetails(int questionNum, FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":314,"author":{"gitId":"-"},"content":" scrollElementToCenter(getQuestionForm(questionNum));"},{"lineNumber":315,"author":{"gitId":"-"},"content":" assertEquals(feedbackQuestion.getQuestionType(), getQuestionType(questionNum));"},{"lineNumber":316,"author":{"gitId":"-"},"content":" assertEquals(feedbackQuestion.getQuestionNumber(), getQuestionNumber(questionNum));"},{"lineNumber":317,"author":{"gitId":"-"},"content":" assertEquals(feedbackQuestion.getQuestionDetailsCopy().getQuestionText(), getQuestionBrief(questionNum));"},{"lineNumber":318,"author":{"gitId":"-"},"content":" assertEquals(getQuestionDescription(questionNum), feedbackQuestion.getQuestionDescription());"},{"lineNumber":319,"author":{"gitId":"-"},"content":" verifyFeedbackPathSettings(questionNum, feedbackQuestion);"},{"lineNumber":320,"author":{"gitId":"-"},"content":" verifyQuestionVisibilitySettings(questionNum, feedbackQuestion);"},{"lineNumber":321,"author":{"gitId":"-"},"content":" }"},{"lineNumber":322,"author":{"gitId":"-"},"content":""},{"lineNumber":323,"author":{"gitId":"-"},"content":" private void verifyFeedbackPathSettings(int questionNum, FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":324,"author":{"gitId":"-"},"content":" assertEquals(getDisplayGiverName(feedbackQuestion.getGiverType()), getFeedbackGiver(questionNum));"},{"lineNumber":325,"author":{"gitId":"-"},"content":" String feedbackReceiver \u003d getFeedbackReceiver(questionNum);"},{"lineNumber":326,"author":{"gitId":"-"},"content":" assertEquals(getDisplayRecipientName(feedbackQuestion.getRecipientType()), feedbackReceiver);"},{"lineNumber":327,"author":{"gitId":"-"},"content":""},{"lineNumber":328,"author":{"gitId":"-"},"content":" if (feedbackReceiver.equals(getDisplayRecipientName(FeedbackParticipantType.INSTRUCTORS))"},{"lineNumber":329,"author":{"gitId":"-"},"content":" || feedbackReceiver.equals(getDisplayRecipientName(FeedbackParticipantType.STUDENTS_EXCLUDING_SELF))"},{"lineNumber":330,"author":{"gitId":"-"},"content":" || feedbackReceiver.equals(getDisplayRecipientName(FeedbackParticipantType.TEAMS_EXCLUDING_SELF))) {"},{"lineNumber":331,"author":{"gitId":"-"},"content":" verifyNumberOfEntitiesToGiveFeedbackTo(questionNum, feedbackQuestion.getNumberOfEntitiesToGiveFeedbackTo());"},{"lineNumber":332,"author":{"gitId":"-"},"content":" }"},{"lineNumber":333,"author":{"gitId":"-"},"content":" }"},{"lineNumber":334,"author":{"gitId":"-"},"content":""},{"lineNumber":335,"author":{"gitId":"-"},"content":" private void verifyNumberOfEntitiesToGiveFeedbackTo(int questionNum, int numberOfEntitiesToGiveFeedbackTo) {"},{"lineNumber":336,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(questionNum);"},{"lineNumber":337,"author":{"gitId":"-"},"content":" WebElement feedbackPathPanel \u003d questionForm.findElement(By.tagName(\"tm-feedback-path-panel\"));"},{"lineNumber":338,"author":{"gitId":"-"},"content":" if (numberOfEntitiesToGiveFeedbackTo \u003d\u003d Const.MAX_POSSIBLE_RECIPIENTS) {"},{"lineNumber":339,"author":{"gitId":"-"},"content":" assertTrue(feedbackPathPanel.findElement(By.id(\"unlimited-recipients\")).isSelected());"},{"lineNumber":340,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":341,"author":{"gitId":"-"},"content":" assertTrue(feedbackPathPanel.findElement(By.id(\"custom-recipients\")).isSelected());"},{"lineNumber":342,"author":{"gitId":"-"},"content":" assertEquals(feedbackPathPanel.findElement(By.id(\"custom-recipients-number\")).getAttribute(\"value\"),"},{"lineNumber":343,"author":{"gitId":"-"},"content":" Integer.toString(numberOfEntitiesToGiveFeedbackTo));"},{"lineNumber":344,"author":{"gitId":"-"},"content":" }"},{"lineNumber":345,"author":{"gitId":"-"},"content":" }"},{"lineNumber":346,"author":{"gitId":"-"},"content":""},{"lineNumber":347,"author":{"gitId":"-"},"content":" private void verifyQuestionVisibilitySettings(int questionNum, FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":348,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(questionNum);"},{"lineNumber":349,"author":{"gitId":"-"},"content":" WebElement visibilityPanel \u003d questionForm.findElement(By.tagName(\"tm-visibility-panel\"));"},{"lineNumber":350,"author":{"gitId":"-"},"content":" String visibility \u003d visibilityPanel.findElement(By.cssSelector(\"#btn-question-visibility span\")).getText();"},{"lineNumber":351,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showResponsesTo \u003d feedbackQuestion.getShowResponsesTo();"},{"lineNumber":352,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showGiverNameTo \u003d feedbackQuestion.getShowGiverNameTo();"},{"lineNumber":353,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showRecipientNameTo \u003d feedbackQuestion.getShowRecipientNameTo();"},{"lineNumber":354,"author":{"gitId":"-"},"content":""},{"lineNumber":355,"author":{"gitId":"-"},"content":" switch (visibility) {"},{"lineNumber":356,"author":{"gitId":"-"},"content":" case \"Shown anonymously to recipient and giver\u0027s team members, visible to instructors\":"},{"lineNumber":357,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":358,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":359,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.OWN_TEAM_MEMBERS));"},{"lineNumber":360,"author":{"gitId":"-"},"content":" assertEquals(showResponsesTo.size(), 3);"},{"lineNumber":361,"author":{"gitId":"-"},"content":""},{"lineNumber":362,"author":{"gitId":"-"},"content":" assertTrue(showGiverNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":363,"author":{"gitId":"-"},"content":" assertEquals(showGiverNameTo.size(), 1);"},{"lineNumber":364,"author":{"gitId":"-"},"content":""},{"lineNumber":365,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":366,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":367,"author":{"gitId":"-"},"content":" assertEquals(showRecipientNameTo.size(), 2);"},{"lineNumber":368,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":369,"author":{"gitId":"-"},"content":""},{"lineNumber":370,"author":{"gitId":"-"},"content":" case \"Visible to instructors only\":"},{"lineNumber":371,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":372,"author":{"gitId":"-"},"content":" assertEquals(showResponsesTo.size(), 1);"},{"lineNumber":373,"author":{"gitId":"-"},"content":""},{"lineNumber":374,"author":{"gitId":"-"},"content":" assertTrue(showGiverNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":375,"author":{"gitId":"-"},"content":" assertEquals(showGiverNameTo.size(), 1);"},{"lineNumber":376,"author":{"gitId":"-"},"content":""},{"lineNumber":377,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":378,"author":{"gitId":"-"},"content":" assertEquals(showRecipientNameTo.size(), 1);"},{"lineNumber":379,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":380,"author":{"gitId":"-"},"content":""},{"lineNumber":381,"author":{"gitId":"-"},"content":" case \"Shown anonymously to recipient and instructors\":"},{"lineNumber":382,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":383,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":384,"author":{"gitId":"-"},"content":" assertEquals(showResponsesTo.size(), 2);"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"-"},"content":" assertEquals(showGiverNameTo.size(), 0);"},{"lineNumber":387,"author":{"gitId":"-"},"content":""},{"lineNumber":388,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":389,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":390,"author":{"gitId":"-"},"content":" assertEquals(showRecipientNameTo.size(), 2);"},{"lineNumber":391,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":392,"author":{"gitId":"-"},"content":""},{"lineNumber":393,"author":{"gitId":"-"},"content":" case \"Shown anonymously to recipient, visible to instructors\":"},{"lineNumber":394,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":395,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":396,"author":{"gitId":"-"},"content":" assertEquals(showResponsesTo.size(), 2);"},{"lineNumber":397,"author":{"gitId":"-"},"content":""},{"lineNumber":398,"author":{"gitId":"-"},"content":" assertTrue(showGiverNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":399,"author":{"gitId":"-"},"content":" assertEquals(showGiverNameTo.size(), 1);"},{"lineNumber":400,"author":{"gitId":"-"},"content":""},{"lineNumber":401,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":402,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":403,"author":{"gitId":"-"},"content":" assertEquals(showRecipientNameTo.size(), 2);"},{"lineNumber":404,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":405,"author":{"gitId":"-"},"content":""},{"lineNumber":406,"author":{"gitId":"-"},"content":" case \"Shown anonymously to recipient and giver/recipient\u0027s team members, visible to instructors\":"},{"lineNumber":407,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":408,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":409,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.OWN_TEAM_MEMBERS));"},{"lineNumber":410,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.RECEIVER_TEAM_MEMBERS));"},{"lineNumber":411,"author":{"gitId":"-"},"content":" assertEquals(showResponsesTo.size(), 4);"},{"lineNumber":412,"author":{"gitId":"-"},"content":""},{"lineNumber":413,"author":{"gitId":"-"},"content":" assertTrue(showGiverNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":414,"author":{"gitId":"-"},"content":" assertEquals(showGiverNameTo.size(), 1);"},{"lineNumber":415,"author":{"gitId":"-"},"content":""},{"lineNumber":416,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":417,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":418,"author":{"gitId":"-"},"content":" assertEquals(showRecipientNameTo.size(), 2);"},{"lineNumber":419,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":420,"author":{"gitId":"-"},"content":""},{"lineNumber":421,"author":{"gitId":"-"},"content":" case \"Visible to recipient and instructors\":"},{"lineNumber":422,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":423,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":424,"author":{"gitId":"-"},"content":" assertEquals(showResponsesTo.size(), 2);"},{"lineNumber":425,"author":{"gitId":"-"},"content":""},{"lineNumber":426,"author":{"gitId":"-"},"content":" assertTrue(showGiverNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":427,"author":{"gitId":"-"},"content":" assertTrue(showGiverNameTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":428,"author":{"gitId":"-"},"content":" assertEquals(showGiverNameTo.size(), 2);"},{"lineNumber":429,"author":{"gitId":"-"},"content":""},{"lineNumber":430,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":431,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":432,"author":{"gitId":"-"},"content":" assertEquals(showRecipientNameTo.size(), 2);"},{"lineNumber":433,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":434,"author":{"gitId":"-"},"content":""},{"lineNumber":435,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":436,"author":{"gitId":"-"},"content":" verifyCustomQuestionVisibility(questionNum, feedbackQuestion);"},{"lineNumber":437,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":438,"author":{"gitId":"-"},"content":" }"},{"lineNumber":439,"author":{"gitId":"-"},"content":" }"},{"lineNumber":440,"author":{"gitId":"-"},"content":""},{"lineNumber":441,"author":{"gitId":"-"},"content":" private void verifyCustomQuestionVisibility(int questionNum, FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":442,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(questionNum);"},{"lineNumber":443,"author":{"gitId":"-"},"content":" WebElement visibilityPanel \u003d questionForm.findElement(By.tagName(\"tm-visibility-panel\"));"},{"lineNumber":444,"author":{"gitId":"-"},"content":" String visibility \u003d visibilityPanel.findElement(By.cssSelector(\"#btn-question-visibility span\")).getText();"},{"lineNumber":445,"author":{"gitId":"-"},"content":" assertEquals(visibility, CUSTOM_VISIBILITY_OPTION);"},{"lineNumber":446,"author":{"gitId":"-"},"content":""},{"lineNumber":447,"author":{"gitId":"-"},"content":" FeedbackParticipantType giver \u003d feedbackQuestion.getGiverType();"},{"lineNumber":448,"author":{"gitId":"-"},"content":" FeedbackParticipantType receiver \u003d feedbackQuestion.getRecipientType();"},{"lineNumber":449,"author":{"gitId":"-"},"content":" WebElement customVisibilityTable \u003d visibilityPanel.findElement(By.id(\"custom-visibility-table\"));"},{"lineNumber":450,"author":{"gitId":"-"},"content":" assertVisibilityBoxesSelected(customVisibilityTable, giver, receiver, feedbackQuestion.getShowResponsesTo(), 1);"},{"lineNumber":451,"author":{"gitId":"-"},"content":" assertVisibilityBoxesSelected(customVisibilityTable, giver, receiver, feedbackQuestion.getShowGiverNameTo(), 2);"},{"lineNumber":452,"author":{"gitId":"-"},"content":" assertVisibilityBoxesSelected(customVisibilityTable, giver, receiver, feedbackQuestion.getShowRecipientNameTo(), 3);"},{"lineNumber":453,"author":{"gitId":"-"},"content":" }"},{"lineNumber":454,"author":{"gitId":"-"},"content":""},{"lineNumber":455,"author":{"gitId":"-"},"content":" private void assertVisibilityBoxesSelected(WebElement table, FeedbackParticipantType giver,"},{"lineNumber":456,"author":{"gitId":"-"},"content":" FeedbackParticipantType receiver, List\u003cFeedbackParticipantType\u003e participants,"},{"lineNumber":457,"author":{"gitId":"-"},"content":" int colNum) {"},{"lineNumber":458,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e possibleTypes \u003d new ArrayList\u003c\u003e(Arrays.asList(FeedbackParticipantType.RECEIVER,"},{"lineNumber":459,"author":{"gitId":"-"},"content":" FeedbackParticipantType.OWN_TEAM_MEMBERS, FeedbackParticipantType.RECEIVER_TEAM_MEMBERS,"},{"lineNumber":460,"author":{"gitId":"-"},"content":" FeedbackParticipantType.STUDENTS, FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":461,"author":{"gitId":"-"},"content":" if (!giver.equals(FeedbackParticipantType.STUDENTS)) {"},{"lineNumber":462,"author":{"gitId":"-"},"content":" possibleTypes.remove(FeedbackParticipantType.OWN_TEAM_MEMBERS);"},{"lineNumber":463,"author":{"gitId":"-"},"content":" }"},{"lineNumber":464,"author":{"gitId":"-"},"content":" if (!receiver.equals(FeedbackParticipantType.STUDENTS)) {"},{"lineNumber":465,"author":{"gitId":"-"},"content":" possibleTypes.remove(FeedbackParticipantType.RECEIVER_TEAM_MEMBERS);"},{"lineNumber":466,"author":{"gitId":"-"},"content":" }"},{"lineNumber":467,"author":{"gitId":"-"},"content":" if (receiver.equals(FeedbackParticipantType.NONE)"},{"lineNumber":468,"author":{"gitId":"-"},"content":" || receiver.equals(FeedbackParticipantType.SELF)"},{"lineNumber":469,"author":{"gitId":"-"},"content":" || receiver.equals(FeedbackParticipantType.OWN_TEAM)) {"},{"lineNumber":470,"author":{"gitId":"-"},"content":" possibleTypes.remove(FeedbackParticipantType.RECEIVER);"},{"lineNumber":471,"author":{"gitId":"-"},"content":" possibleTypes.remove(FeedbackParticipantType.RECEIVER_TEAM_MEMBERS);"},{"lineNumber":472,"author":{"gitId":"-"},"content":" }"},{"lineNumber":473,"author":{"gitId":"-"},"content":""},{"lineNumber":474,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d table.findElements(By.tagName(\"tr\"));"},{"lineNumber":475,"author":{"gitId":"-"},"content":" int index \u003d colNum - 1;"},{"lineNumber":476,"author":{"gitId":"-"},"content":" for (FeedbackParticipantType participant : participants) {"},{"lineNumber":477,"author":{"gitId":"-"},"content":" assertTrue(rows.get(possibleTypes.indexOf(participant)).findElements(By.tagName(\"input\")).get(index)"},{"lineNumber":478,"author":{"gitId":"-"},"content":" .isSelected());"},{"lineNumber":479,"author":{"gitId":"-"},"content":" }"},{"lineNumber":480,"author":{"gitId":"-"},"content":" }"},{"lineNumber":481,"author":{"gitId":"-"},"content":""},{"lineNumber":482,"author":{"gitId":"-"},"content":" public void addTemplateQuestion(int optionNum) {"},{"lineNumber":483,"author":{"gitId":"-"},"content":" addNewQuestion(1);"},{"lineNumber":484,"author":{"gitId":"-"},"content":" WebElement templateQuestionModal \u003d waitForElementPresence(By.id(\"template-question-modal\"));"},{"lineNumber":485,"author":{"gitId":"-"},"content":""},{"lineNumber":486,"author":{"gitId":"-"},"content":" click(templateQuestionModal.findElements(By.tagName(\"input\")).get(optionNum - 1));"},{"lineNumber":487,"author":{"gitId":"-"},"content":" clickAndWaitForNewQuestion(browser.driver.findElement(By.id(\"btn-confirm-template\")));"},{"lineNumber":488,"author":{"gitId":"-"},"content":" }"},{"lineNumber":489,"author":{"gitId":"-"},"content":""},{"lineNumber":490,"author":{"gitId":"-"},"content":" public void copyQuestion(String courseId, String questionText) {"},{"lineNumber":491,"author":{"gitId":"-"},"content":" click(copyQuestionButton);"},{"lineNumber":492,"author":{"gitId":"-"},"content":" WebElement copyQuestionModal \u003d waitForElementPresence(By.id(\"copy-question-modal\"));"},{"lineNumber":493,"author":{"gitId":"-"},"content":""},{"lineNumber":494,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e cards \u003d copyQuestionModal.findElements(By.className(\"card\"));"},{"lineNumber":495,"author":{"gitId":"-"},"content":" for (WebElement card : cards) {"},{"lineNumber":496,"author":{"gitId":"-"},"content":" WebElement cardHeader \u003d card.findElement(By.className(\"card-header\"));"},{"lineNumber":497,"author":{"gitId":"-"},"content":" if (cardHeader.getText().startsWith(\"[\" + courseId + \"]\")) {"},{"lineNumber":498,"author":{"gitId":"-"},"content":" click(cardHeader);"},{"lineNumber":499,"author":{"gitId":"-"},"content":" WebElement cardBody \u003d waitForElementPresence(By.className(\"card-body\"));"},{"lineNumber":500,"author":{"gitId":"-"},"content":" // Reload questions"},{"lineNumber":501,"author":{"gitId":"-"},"content":" WebElement reloadBtn \u003d cardBody.findElement(By.tagName(\"button\"));"},{"lineNumber":502,"author":{"gitId":"-"},"content":" click(reloadBtn);"},{"lineNumber":503,"author":{"gitId":"-"},"content":" WebElement table \u003d waitForElementPresence(By.id(\"copy-question-table\"));"},{"lineNumber":504,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d table.findElements(By.cssSelector(\"tbody tr\"));"},{"lineNumber":505,"author":{"gitId":"-"},"content":" for (WebElement row : rows) {"},{"lineNumber":506,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e cells \u003d row.findElements(By.tagName(\"td\"));"},{"lineNumber":507,"author":{"gitId":"-"},"content":" if (cells.get(2).getText().equals(questionText)) {"},{"lineNumber":508,"author":{"gitId":"-"},"content":" markOptionAsSelected(cells.get(0).findElement(By.tagName(\"input\")));"},{"lineNumber":509,"author":{"gitId":"-"},"content":" }"},{"lineNumber":510,"author":{"gitId":"-"},"content":" }"},{"lineNumber":511,"author":{"gitId":"-"},"content":" }"},{"lineNumber":512,"author":{"gitId":"-"},"content":" }"},{"lineNumber":513,"author":{"gitId":"-"},"content":" clickAndWaitForNewQuestion(browser.driver.findElement(By.id(\"btn-confirm-copy-question\")));"},{"lineNumber":514,"author":{"gitId":"-"},"content":" }"},{"lineNumber":515,"author":{"gitId":"-"},"content":""},{"lineNumber":516,"author":{"gitId":"-"},"content":" public void editQuestionNumber(int questionNum, int newQuestionNumber) {"},{"lineNumber":517,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":518,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(getQuestionForm(questionNum).findElement(By.id(\"question-number-dropdown\")),"},{"lineNumber":519,"author":{"gitId":"-"},"content":" Integer.toString(newQuestionNumber));"},{"lineNumber":520,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":521,"author":{"gitId":"-"},"content":" }"},{"lineNumber":522,"author":{"gitId":"-"},"content":""},{"lineNumber":523,"author":{"gitId":"-"},"content":" public void editQuestionDetails(int questionNum, FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":524,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":525,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":526,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":527,"author":{"gitId":"-"},"content":" }"},{"lineNumber":528,"author":{"gitId":"-"},"content":""},{"lineNumber":529,"author":{"gitId":"-"},"content":" private void inputQuestionDetails(int questionNum, FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":530,"author":{"gitId":"-"},"content":" setQuestionBrief(questionNum, feedbackQuestion.getQuestionDetailsCopy().getQuestionText());"},{"lineNumber":531,"author":{"gitId":"-"},"content":" setQuestionDescription(questionNum, feedbackQuestion.getQuestionDescription());"},{"lineNumber":532,"author":{"gitId":"-"},"content":" FeedbackQuestionType questionType \u003d feedbackQuestion.getQuestionType();"},{"lineNumber":533,"author":{"gitId":"-"},"content":" if (!questionType.equals(FeedbackQuestionType.CONTRIB)) {"},{"lineNumber":534,"author":{"gitId":"-"},"content":" setFeedbackPath(questionNum, feedbackQuestion);"},{"lineNumber":535,"author":{"gitId":"-"},"content":" setQuestionVisibility(questionNum, feedbackQuestion);"},{"lineNumber":536,"author":{"gitId":"-"},"content":" }"},{"lineNumber":537,"author":{"gitId":"-"},"content":" }"},{"lineNumber":538,"author":{"gitId":"-"},"content":""},{"lineNumber":539,"author":{"gitId":"-"},"content":" private void inputQuestionDetails(int questionNum, FeedbackQuestion feedbackQuestion) {"},{"lineNumber":540,"author":{"gitId":"-"},"content":" setQuestionBrief(questionNum, feedbackQuestion.getQuestionDetailsCopy().getQuestionText());"},{"lineNumber":541,"author":{"gitId":"-"},"content":" setQuestionDescription(questionNum, feedbackQuestion.getDescription());"},{"lineNumber":542,"author":{"gitId":"-"},"content":" FeedbackQuestionType questionType \u003d feedbackQuestion.getQuestionDetailsCopy().getQuestionType();"},{"lineNumber":543,"author":{"gitId":"-"},"content":" if (!questionType.equals(FeedbackQuestionType.CONTRIB)) {"},{"lineNumber":544,"author":{"gitId":"-"},"content":" setFeedbackPath(questionNum, feedbackQuestion);"},{"lineNumber":545,"author":{"gitId":"-"},"content":" setQuestionVisibility(questionNum, feedbackQuestion);"},{"lineNumber":546,"author":{"gitId":"-"},"content":" }"},{"lineNumber":547,"author":{"gitId":"-"},"content":" }"},{"lineNumber":548,"author":{"gitId":"-"},"content":""},{"lineNumber":549,"author":{"gitId":"-"},"content":" public void duplicateQuestion(int questionNum) {"},{"lineNumber":550,"author":{"gitId":"-"},"content":" clickAndWaitForNewQuestion(getQuestionForm(questionNum).findElement(By.id(\"btn-duplicate-question\")));"},{"lineNumber":551,"author":{"gitId":"-"},"content":" }"},{"lineNumber":552,"author":{"gitId":"-"},"content":""},{"lineNumber":553,"author":{"gitId":"-"},"content":" public void deleteQuestion(int questionNum) {"},{"lineNumber":554,"author":{"gitId":"-"},"content":" clickAndConfirm(getQuestionForm(questionNum).findElement(By.id(\"btn-delete-question\")));"},{"lineNumber":555,"author":{"gitId":"-"},"content":" }"},{"lineNumber":556,"author":{"gitId":"-"},"content":""},{"lineNumber":557,"author":{"gitId":"-"},"content":" public void verifyTextQuestionDetails(int questionNum, FeedbackTextQuestionDetails questionDetails) {"},{"lineNumber":558,"author":{"gitId":"-"},"content":" String recommendLength \u003d getRecommendedTextLengthField(questionNum).getAttribute(\"value\");"},{"lineNumber":559,"author":{"gitId":"-"},"content":" assertEquals(recommendLength, questionDetails.getRecommendedLength().toString());"},{"lineNumber":560,"author":{"gitId":"-"},"content":" }"},{"lineNumber":561,"author":{"gitId":"-"},"content":""},{"lineNumber":562,"author":{"gitId":"-"},"content":" public void addTextQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":563,"author":{"gitId":"-"},"content":" addNewQuestion(2);"},{"lineNumber":564,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":565,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":566,"author":{"gitId":"-"},"content":" FeedbackTextQuestionDetails questionDetails \u003d"},{"lineNumber":567,"author":{"gitId":"-"},"content":" (FeedbackTextQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":568,"author":{"gitId":"-"},"content":" fillTextBox(getRecommendedTextLengthField(questionNum), questionDetails.getRecommendedLength().toString());"},{"lineNumber":569,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":570,"author":{"gitId":"-"},"content":" }"},{"lineNumber":571,"author":{"gitId":"-"},"content":""},{"lineNumber":572,"author":{"gitId":"-"},"content":" public void addTextQuestion(FeedbackQuestion feedbackQuestion) {"},{"lineNumber":573,"author":{"gitId":"-"},"content":" addNewQuestion(2);"},{"lineNumber":574,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":575,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":576,"author":{"gitId":"-"},"content":" FeedbackTextQuestionDetails questionDetails \u003d"},{"lineNumber":577,"author":{"gitId":"-"},"content":" (FeedbackTextQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":578,"author":{"gitId":"-"},"content":" fillTextBox(getRecommendedTextLengthField(questionNum), questionDetails.getRecommendedLength().toString());"},{"lineNumber":579,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":580,"author":{"gitId":"-"},"content":" }"},{"lineNumber":581,"author":{"gitId":"-"},"content":""},{"lineNumber":582,"author":{"gitId":"-"},"content":" public void editTextQuestion(int questionNum, FeedbackTextQuestionDetails textQuestionDetails) {"},{"lineNumber":583,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":584,"author":{"gitId":"-"},"content":" WebElement recommendedTextLengthField \u003d getRecommendedTextLengthField(questionNum);"},{"lineNumber":585,"author":{"gitId":"-"},"content":" waitForElementToBeClickable(recommendedTextLengthField);"},{"lineNumber":586,"author":{"gitId":"-"},"content":" fillTextBox(recommendedTextLengthField, textQuestionDetails.getRecommendedLength().toString());"},{"lineNumber":587,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":588,"author":{"gitId":"-"},"content":" }"},{"lineNumber":589,"author":{"gitId":"-"},"content":""},{"lineNumber":590,"author":{"gitId":"-"},"content":" public void verifyMcqQuestionDetails(int questionNum, FeedbackMcqQuestionDetails questionDetails) {"},{"lineNumber":591,"author":{"gitId":"-"},"content":" if (verifyGeneratedOptions(questionNum, questionDetails.getGenerateOptionsFor())) {"},{"lineNumber":592,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":593,"author":{"gitId":"-"},"content":" }"},{"lineNumber":594,"author":{"gitId":"-"},"content":" verifyOptions(questionNum, questionDetails.getMcqChoices());"},{"lineNumber":595,"author":{"gitId":"-"},"content":" verifyOptionWeights(questionNum, questionDetails.isHasAssignedWeights(), questionDetails.getMcqWeights());"},{"lineNumber":596,"author":{"gitId":"-"},"content":" verifyOtherOption(questionNum, questionDetails.isOtherEnabled(), questionDetails.getMcqOtherWeight());"},{"lineNumber":597,"author":{"gitId":"-"},"content":" }"},{"lineNumber":598,"author":{"gitId":"-"},"content":""},{"lineNumber":599,"author":{"gitId":"-"},"content":" public void addMcqQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":600,"author":{"gitId":"-"},"content":" addNewQuestion(3);"},{"lineNumber":601,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":602,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":603,"author":{"gitId":"-"},"content":" FeedbackMcqQuestionDetails questionDetails \u003d (FeedbackMcqQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":604,"author":{"gitId":"-"},"content":" inputMcqDetails(questionNum, questionDetails);"},{"lineNumber":605,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":606,"author":{"gitId":"-"},"content":" }"},{"lineNumber":607,"author":{"gitId":"-"},"content":""},{"lineNumber":608,"author":{"gitId":"dishenggg"},"content":" public void addMcqQuestion(FeedbackQuestion feedbackQuestion) {"},{"lineNumber":609,"author":{"gitId":"dishenggg"},"content":" addNewQuestion(3);"},{"lineNumber":610,"author":{"gitId":"dishenggg"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":611,"author":{"gitId":"dishenggg"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":612,"author":{"gitId":"-"},"content":" FeedbackMcqQuestionDetails questionDetails \u003d (FeedbackMcqQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":613,"author":{"gitId":"-"},"content":" inputMcqDetails(questionNum, questionDetails);"},{"lineNumber":614,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":615,"author":{"gitId":"-"},"content":" }"},{"lineNumber":616,"author":{"gitId":"-"},"content":""},{"lineNumber":617,"author":{"gitId":"-"},"content":" public void editMcqQuestion(int questionNum, FeedbackMcqQuestionDetails questionDetails) {"},{"lineNumber":618,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":619,"author":{"gitId":"-"},"content":" inputMcqDetails(questionNum, questionDetails);"},{"lineNumber":620,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":621,"author":{"gitId":"-"},"content":" }"},{"lineNumber":622,"author":{"gitId":"-"},"content":""},{"lineNumber":623,"author":{"gitId":"-"},"content":" public void verifyMsqQuestionDetails(int questionNum, FeedbackMsqQuestionDetails questionDetails) {"},{"lineNumber":624,"author":{"gitId":"-"},"content":" verifyMaxOptions(questionNum, questionDetails.getMaxSelectableChoices());"},{"lineNumber":625,"author":{"gitId":"-"},"content":" verifyMinOptions(questionNum, questionDetails.getMinSelectableChoices());"},{"lineNumber":626,"author":{"gitId":"-"},"content":" if (verifyGeneratedOptions(questionNum, questionDetails.getGenerateOptionsFor())) {"},{"lineNumber":627,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":628,"author":{"gitId":"-"},"content":" }"},{"lineNumber":629,"author":{"gitId":"-"},"content":" verifyOptions(questionNum, questionDetails.getMsqChoices());"},{"lineNumber":630,"author":{"gitId":"-"},"content":" verifyOptionWeights(questionNum, questionDetails.isHasAssignedWeights(), questionDetails.getMsqWeights());"},{"lineNumber":631,"author":{"gitId":"-"},"content":" verifyOtherOption(questionNum, questionDetails.isOtherEnabled(), questionDetails.getMsqOtherWeight());"},{"lineNumber":632,"author":{"gitId":"-"},"content":" }"},{"lineNumber":633,"author":{"gitId":"-"},"content":""},{"lineNumber":634,"author":{"gitId":"-"},"content":" public void addMsqQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":635,"author":{"gitId":"-"},"content":" addNewQuestion(4);"},{"lineNumber":636,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":637,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":638,"author":{"gitId":"-"},"content":" FeedbackMsqQuestionDetails questionDetails \u003d (FeedbackMsqQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":639,"author":{"gitId":"-"},"content":" inputMsqDetails(questionNum, questionDetails);"},{"lineNumber":640,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":641,"author":{"gitId":"-"},"content":" }"},{"lineNumber":642,"author":{"gitId":"-"},"content":""},{"lineNumber":643,"author":{"gitId":"dishenggg"},"content":" public void addMsqQuestion(FeedbackQuestion feedbackQuestion) {"},{"lineNumber":644,"author":{"gitId":"dishenggg"},"content":" addNewQuestion(4);"},{"lineNumber":645,"author":{"gitId":"dishenggg"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":646,"author":{"gitId":"dishenggg"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":647,"author":{"gitId":"dishenggg"},"content":" FeedbackMsqQuestionDetails questionDetails \u003d (FeedbackMsqQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":648,"author":{"gitId":"dishenggg"},"content":" inputMsqDetails(questionNum, questionDetails);"},{"lineNumber":649,"author":{"gitId":"dishenggg"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":650,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":651,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":652,"author":{"gitId":"-"},"content":" public void editMsqQuestion(int questionNum, FeedbackMsqQuestionDetails msqQuestionDetails) {"},{"lineNumber":653,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":654,"author":{"gitId":"-"},"content":" inputMsqDetails(questionNum, msqQuestionDetails);"},{"lineNumber":655,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":656,"author":{"gitId":"-"},"content":" }"},{"lineNumber":657,"author":{"gitId":"-"},"content":""},{"lineNumber":658,"author":{"gitId":"-"},"content":" public void verifyNumScaleQuestionDetails(int questionNum, FeedbackNumericalScaleQuestionDetails questionDetails) {"},{"lineNumber":659,"author":{"gitId":"-"},"content":" assertEquals(getMinNumscaleInput(questionNum).getAttribute(\"value\"),"},{"lineNumber":660,"author":{"gitId":"-"},"content":" Integer.toString(questionDetails.getMinScale()));"},{"lineNumber":661,"author":{"gitId":"-"},"content":" assertEquals(getNumScaleIncrementInput(questionNum).getAttribute(\"value\"),"},{"lineNumber":662,"author":{"gitId":"-"},"content":" getDoubleString(questionDetails.getStep()));"},{"lineNumber":663,"author":{"gitId":"-"},"content":" assertEquals(getMaxNumscaleInput(questionNum).getAttribute(\"value\"),"},{"lineNumber":664,"author":{"gitId":"-"},"content":" Integer.toString(questionDetails.getMaxScale()));"},{"lineNumber":665,"author":{"gitId":"-"},"content":" }"},{"lineNumber":666,"author":{"gitId":"-"},"content":""},{"lineNumber":667,"author":{"gitId":"-"},"content":" public void addNumScaleQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":668,"author":{"gitId":"-"},"content":" addNewQuestion(5);"},{"lineNumber":669,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":670,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":671,"author":{"gitId":"-"},"content":" FeedbackNumericalScaleQuestionDetails questionDetails \u003d"},{"lineNumber":672,"author":{"gitId":"-"},"content":" (FeedbackNumericalScaleQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":673,"author":{"gitId":"-"},"content":" inputNumScaleDetails(questionNum, questionDetails);"},{"lineNumber":674,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":675,"author":{"gitId":"-"},"content":" }"},{"lineNumber":676,"author":{"gitId":"-"},"content":""},{"lineNumber":677,"author":{"gitId":"marquestye"},"content":" public void addNumScaleQuestion(FeedbackQuestion feedbackQuestion) {"},{"lineNumber":678,"author":{"gitId":"marquestye"},"content":" addNewQuestion(5);"},{"lineNumber":679,"author":{"gitId":"marquestye"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":680,"author":{"gitId":"marquestye"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":681,"author":{"gitId":"marquestye"},"content":" FeedbackNumericalScaleQuestionDetails questionDetails \u003d"},{"lineNumber":682,"author":{"gitId":"-"},"content":" (FeedbackNumericalScaleQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":683,"author":{"gitId":"-"},"content":" inputNumScaleDetails(questionNum, questionDetails);"},{"lineNumber":684,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":685,"author":{"gitId":"-"},"content":" }"},{"lineNumber":686,"author":{"gitId":"-"},"content":""},{"lineNumber":687,"author":{"gitId":"-"},"content":" public void editNumScaleQuestion(int questionNum, FeedbackNumericalScaleQuestionDetails questionDetails) {"},{"lineNumber":688,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":689,"author":{"gitId":"-"},"content":" inputNumScaleDetails(questionNum, questionDetails);"},{"lineNumber":690,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":691,"author":{"gitId":"-"},"content":" }"},{"lineNumber":692,"author":{"gitId":"-"},"content":""},{"lineNumber":693,"author":{"gitId":"-"},"content":" public void verifyConstSumQuestionDetails(int questionNum, FeedbackConstantSumQuestionDetails questionDetails) {"},{"lineNumber":694,"author":{"gitId":"-"},"content":" if (!questionDetails.isDistributeToRecipients()) {"},{"lineNumber":695,"author":{"gitId":"-"},"content":" verifyOptions(questionNum, questionDetails.getConstSumOptions());"},{"lineNumber":696,"author":{"gitId":"-"},"content":" }"},{"lineNumber":697,"author":{"gitId":"-"},"content":""},{"lineNumber":698,"author":{"gitId":"-"},"content":" if (questionDetails.isPointsPerOption()) {"},{"lineNumber":699,"author":{"gitId":"-"},"content":" assertTrue(getConstSumPerOptionPointsRadioBtn(questionNum).isSelected());"},{"lineNumber":700,"author":{"gitId":"-"},"content":" assertEquals(getConstSumPerOptionPointsInput(questionNum).getAttribute(\"value\"),"},{"lineNumber":701,"author":{"gitId":"-"},"content":" Integer.toString(questionDetails.getPoints()));"},{"lineNumber":702,"author":{"gitId":"-"},"content":" assertFalse(getConstSumTotalPointsRadioBtn(questionNum).isSelected());"},{"lineNumber":703,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":704,"author":{"gitId":"-"},"content":" assertTrue(getConstSumTotalPointsRadioBtn(questionNum).isSelected());"},{"lineNumber":705,"author":{"gitId":"-"},"content":" assertEquals(getConstSumTotalPointsInput(questionNum).getAttribute(\"value\"),"},{"lineNumber":706,"author":{"gitId":"-"},"content":" Integer.toString(questionDetails.getPoints()));"},{"lineNumber":707,"author":{"gitId":"-"},"content":" assertFalse(getConstSumPerOptionPointsRadioBtn(questionNum).isSelected());"},{"lineNumber":708,"author":{"gitId":"-"},"content":" }"},{"lineNumber":709,"author":{"gitId":"-"},"content":""},{"lineNumber":710,"author":{"gitId":"-"},"content":" if (questionDetails.isForceUnevenDistribution()) {"},{"lineNumber":711,"author":{"gitId":"-"},"content":" String distributeFor \u003d questionDetails.getDistributePointsFor();"},{"lineNumber":712,"author":{"gitId":"-"},"content":" assertTrue(getConstSumUnevenDistributionCheckbox(questionNum).isSelected());"},{"lineNumber":713,"author":{"gitId":"-"},"content":" assertEquals(getSelectedDropdownOptionText(getConstSumUnevenDistributionDropdown(questionNum)).trim(),"},{"lineNumber":714,"author":{"gitId":"-"},"content":" \"All options\".equals(distributeFor) ? \"Every option\" : distributeFor);"},{"lineNumber":715,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":716,"author":{"gitId":"-"},"content":" assertFalse(getConstSumUnevenDistributionCheckbox(questionNum).isSelected());"},{"lineNumber":717,"author":{"gitId":"-"},"content":" }"},{"lineNumber":718,"author":{"gitId":"-"},"content":" }"},{"lineNumber":719,"author":{"gitId":"-"},"content":""},{"lineNumber":720,"author":{"gitId":"-"},"content":" public void addConstSumOptionQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":721,"author":{"gitId":"-"},"content":" addNewQuestion(6);"},{"lineNumber":722,"author":{"gitId":"-"},"content":" addConstSumQuestion(feedbackQuestion);"},{"lineNumber":723,"author":{"gitId":"-"},"content":" }"},{"lineNumber":724,"author":{"gitId":"-"},"content":""},{"lineNumber":725,"author":{"gitId":"-"},"content":" public void addConstSumRecipientQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":726,"author":{"gitId":"-"},"content":" addNewQuestion(7);"},{"lineNumber":727,"author":{"gitId":"-"},"content":" addConstSumQuestion(feedbackQuestion);"},{"lineNumber":728,"author":{"gitId":"-"},"content":" }"},{"lineNumber":729,"author":{"gitId":"-"},"content":""},{"lineNumber":730,"author":{"gitId":"-"},"content":" public void addConstSumQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":731,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":732,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":733,"author":{"gitId":"-"},"content":" FeedbackConstantSumQuestionDetails questionDetails \u003d"},{"lineNumber":734,"author":{"gitId":"-"},"content":" (FeedbackConstantSumQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":735,"author":{"gitId":"-"},"content":" inputConstSumDetails(questionNum, questionDetails);"},{"lineNumber":736,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":737,"author":{"gitId":"-"},"content":" }"},{"lineNumber":738,"author":{"gitId":"-"},"content":""},{"lineNumber":739,"author":{"gitId":"-"},"content":" public void editConstSumQuestion(int questionNum, FeedbackConstantSumQuestionDetails csQuestionDetails) {"},{"lineNumber":740,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":741,"author":{"gitId":"-"},"content":" inputConstSumDetails(questionNum, csQuestionDetails);"},{"lineNumber":742,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":743,"author":{"gitId":"-"},"content":" }"},{"lineNumber":744,"author":{"gitId":"-"},"content":""},{"lineNumber":745,"author":{"gitId":"-"},"content":" public void verifyContributionQuestionDetails(int questionNum, FeedbackContributionQuestionDetails questionDetails) {"},{"lineNumber":746,"author":{"gitId":"-"},"content":" assertEquals(questionDetails.isZeroSum(), getZeroSumCheckbox(questionNum).isSelected());"},{"lineNumber":747,"author":{"gitId":"-"},"content":" assertEquals(questionDetails.isNotSureAllowed(), getAllowNotSureContributionCheckbox(questionNum).isSelected());"},{"lineNumber":748,"author":{"gitId":"-"},"content":" if (questionDetails.isZeroSum()) {"},{"lineNumber":749,"author":{"gitId":"-"},"content":" assertFalse(questionDetails.isNotSureAllowed());"},{"lineNumber":750,"author":{"gitId":"-"},"content":" }"},{"lineNumber":751,"author":{"gitId":"-"},"content":" }"},{"lineNumber":752,"author":{"gitId":"-"},"content":""},{"lineNumber":753,"author":{"gitId":"-"},"content":" public void addContributionQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":754,"author":{"gitId":"-"},"content":" addNewQuestion(8);"},{"lineNumber":755,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":756,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":757,"author":{"gitId":"-"},"content":" FeedbackContributionQuestionDetails questionDetails \u003d"},{"lineNumber":758,"author":{"gitId":"-"},"content":" (FeedbackContributionQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":759,"author":{"gitId":"-"},"content":" inputContributionDetails(questionNum, questionDetails);"},{"lineNumber":760,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":761,"author":{"gitId":"-"},"content":" }"},{"lineNumber":762,"author":{"gitId":"-"},"content":""},{"lineNumber":763,"author":{"gitId":"-"},"content":" public void editContributionQuestion(int questionNum, FeedbackContributionQuestionDetails questionDetails) {"},{"lineNumber":764,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":765,"author":{"gitId":"-"},"content":" inputContributionDetails(questionNum, questionDetails);"},{"lineNumber":766,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":767,"author":{"gitId":"-"},"content":" }"},{"lineNumber":768,"author":{"gitId":"-"},"content":""},{"lineNumber":769,"author":{"gitId":"-"},"content":" public void verifyRubricQuestionDetails(int questionNum, FeedbackRubricQuestionDetails questionDetails) {"},{"lineNumber":770,"author":{"gitId":"-"},"content":" int numChoices \u003d questionDetails.getNumOfRubricChoices();"},{"lineNumber":771,"author":{"gitId":"-"},"content":" List\u003cString\u003e choices \u003d questionDetails.getRubricChoices();"},{"lineNumber":772,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c numChoices; i++) {"},{"lineNumber":773,"author":{"gitId":"-"},"content":" assertEquals(choices.get(i), getRubricChoiceInputs(questionNum).get(i).getAttribute(\"value\"));"},{"lineNumber":774,"author":{"gitId":"-"},"content":" }"},{"lineNumber":775,"author":{"gitId":"-"},"content":""},{"lineNumber":776,"author":{"gitId":"-"},"content":" int numSubQn \u003d questionDetails.getNumOfRubricSubQuestions();"},{"lineNumber":777,"author":{"gitId":"-"},"content":" List\u003cString\u003e subQuestions \u003d questionDetails.getRubricSubQuestions();"},{"lineNumber":778,"author":{"gitId":"-"},"content":" List\u003cList\u003cString\u003e\u003e descriptions \u003d questionDetails.getRubricDescriptions();"},{"lineNumber":779,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c numSubQn; i++) {"},{"lineNumber":780,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e textAreas \u003d getRubricTextareas(questionNum, i + 2);"},{"lineNumber":781,"author":{"gitId":"-"},"content":" assertEquals(subQuestions.get(i), textAreas.get(0).getAttribute(\"value\"));"},{"lineNumber":782,"author":{"gitId":"-"},"content":" for (int j \u003d 0; j \u003c numChoices; j++) {"},{"lineNumber":783,"author":{"gitId":"-"},"content":" assertEquals(descriptions.get(i).get(j), textAreas.get(j + 1).getAttribute(\"value\"));"},{"lineNumber":784,"author":{"gitId":"-"},"content":" }"},{"lineNumber":785,"author":{"gitId":"-"},"content":" }"},{"lineNumber":786,"author":{"gitId":"-"},"content":""},{"lineNumber":787,"author":{"gitId":"-"},"content":" if (questionDetails.isHasAssignedWeights()) {"},{"lineNumber":788,"author":{"gitId":"-"},"content":" assertTrue(getWeightCheckbox(questionNum).isSelected());"},{"lineNumber":789,"author":{"gitId":"-"},"content":" List\u003cList\u003cDouble\u003e\u003e weights \u003d questionDetails.getRubricWeights();"},{"lineNumber":790,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c numSubQn; i++) {"},{"lineNumber":791,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rubricWeights \u003d getRubricWeights(questionNum, i + 2);"},{"lineNumber":792,"author":{"gitId":"-"},"content":" for (int j \u003d 0; j \u003c numChoices; j++) {"},{"lineNumber":793,"author":{"gitId":"-"},"content":" assertEquals(getDoubleString(weights.get(i).get(j)),"},{"lineNumber":794,"author":{"gitId":"-"},"content":" rubricWeights.get(j).getAttribute(\"value\"));"},{"lineNumber":795,"author":{"gitId":"-"},"content":" }"},{"lineNumber":796,"author":{"gitId":"-"},"content":" }"},{"lineNumber":797,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":798,"author":{"gitId":"-"},"content":" assertFalse(getWeightCheckbox(questionNum).isSelected());"},{"lineNumber":799,"author":{"gitId":"-"},"content":" }"},{"lineNumber":800,"author":{"gitId":"-"},"content":" }"},{"lineNumber":801,"author":{"gitId":"-"},"content":""},{"lineNumber":802,"author":{"gitId":"-"},"content":" public void addRubricQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":803,"author":{"gitId":"-"},"content":" addNewQuestion(9);"},{"lineNumber":804,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":805,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":806,"author":{"gitId":"-"},"content":" FeedbackRubricQuestionDetails questionDetails \u003d"},{"lineNumber":807,"author":{"gitId":"-"},"content":" (FeedbackRubricQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":808,"author":{"gitId":"-"},"content":" inputRubricDetails(questionNum, questionDetails);"},{"lineNumber":809,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":810,"author":{"gitId":"-"},"content":" }"},{"lineNumber":811,"author":{"gitId":"-"},"content":""},{"lineNumber":812,"author":{"gitId":"-"},"content":" public void editRubricQuestion(int questionNum, FeedbackRubricQuestionDetails questionDetails) {"},{"lineNumber":813,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":814,"author":{"gitId":"-"},"content":" inputRubricDetails(questionNum, questionDetails);"},{"lineNumber":815,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":816,"author":{"gitId":"-"},"content":" }"},{"lineNumber":817,"author":{"gitId":"-"},"content":""},{"lineNumber":818,"author":{"gitId":"-"},"content":" public void verifyRankQuestionDetails(int questionNum, FeedbackRankQuestionDetails questionDetails) {"},{"lineNumber":819,"author":{"gitId":"-"},"content":" if (questionDetails instanceof FeedbackRankOptionsQuestionDetails) {"},{"lineNumber":820,"author":{"gitId":"-"},"content":" FeedbackRankOptionsQuestionDetails optionDetails \u003d (FeedbackRankOptionsQuestionDetails) questionDetails;"},{"lineNumber":821,"author":{"gitId":"-"},"content":" verifyOptions(questionNum, optionDetails.getOptions());"},{"lineNumber":822,"author":{"gitId":"-"},"content":" }"},{"lineNumber":823,"author":{"gitId":"-"},"content":" assertEquals(getAllowDuplicateRankCheckbox(questionNum).isSelected(), questionDetails.isAreDuplicatesAllowed());"},{"lineNumber":824,"author":{"gitId":"-"},"content":" verifyMaxOptions(questionNum, questionDetails.getMaxOptionsToBeRanked());"},{"lineNumber":825,"author":{"gitId":"-"},"content":" verifyMinOptions(questionNum, questionDetails.getMinOptionsToBeRanked());"},{"lineNumber":826,"author":{"gitId":"-"},"content":" }"},{"lineNumber":827,"author":{"gitId":"-"},"content":""},{"lineNumber":828,"author":{"gitId":"-"},"content":" public void addRankOptionsQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":829,"author":{"gitId":"-"},"content":" addNewQuestion(10);"},{"lineNumber":830,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":831,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":832,"author":{"gitId":"-"},"content":" FeedbackRankOptionsQuestionDetails questionDetails \u003d"},{"lineNumber":833,"author":{"gitId":"-"},"content":" (FeedbackRankOptionsQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":834,"author":{"gitId":"-"},"content":" inputRankDetails(questionNum, questionDetails);"},{"lineNumber":835,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":836,"author":{"gitId":"-"},"content":" }"},{"lineNumber":837,"author":{"gitId":"-"},"content":""},{"lineNumber":838,"author":{"gitId":"mingyuanc"},"content":" public void addRankOptionsQuestion(FeedbackQuestion feedbackQuestion) {"},{"lineNumber":839,"author":{"gitId":"mingyuanc"},"content":" addNewQuestion(10);"},{"lineNumber":840,"author":{"gitId":"mingyuanc"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":841,"author":{"gitId":"mingyuanc"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":842,"author":{"gitId":"mingyuanc"},"content":" FeedbackRankOptionsQuestionDetails questionDetails \u003d"},{"lineNumber":843,"author":{"gitId":"-"},"content":" (FeedbackRankOptionsQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":844,"author":{"gitId":"-"},"content":" inputRankDetails(questionNum, questionDetails);"},{"lineNumber":845,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":846,"author":{"gitId":"-"},"content":" }"},{"lineNumber":847,"author":{"gitId":"-"},"content":""},{"lineNumber":848,"author":{"gitId":"-"},"content":" public void addRankRecipientsQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":849,"author":{"gitId":"-"},"content":" addNewQuestion(11);"},{"lineNumber":850,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":851,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":852,"author":{"gitId":"-"},"content":" FeedbackRankQuestionDetails questionDetails \u003d"},{"lineNumber":853,"author":{"gitId":"-"},"content":" (FeedbackRankQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":854,"author":{"gitId":"-"},"content":" inputRankDetails(questionNum, questionDetails);"},{"lineNumber":855,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":856,"author":{"gitId":"-"},"content":" }"},{"lineNumber":857,"author":{"gitId":"-"},"content":""},{"lineNumber":858,"author":{"gitId":"-"},"content":" public void editRankQuestion(int questionNum, FeedbackRankQuestionDetails questionDetails) {"},{"lineNumber":859,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":860,"author":{"gitId":"-"},"content":" inputRankDetails(questionNum, questionDetails);"},{"lineNumber":861,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":862,"author":{"gitId":"-"},"content":" }"},{"lineNumber":863,"author":{"gitId":"-"},"content":""},{"lineNumber":864,"author":{"gitId":"-"},"content":" private String getCourseId() {"},{"lineNumber":865,"author":{"gitId":"-"},"content":" return courseIdTextBox.getText();"},{"lineNumber":866,"author":{"gitId":"-"},"content":" }"},{"lineNumber":867,"author":{"gitId":"-"},"content":""},{"lineNumber":868,"author":{"gitId":"-"},"content":" private String getCourseName() {"},{"lineNumber":869,"author":{"gitId":"-"},"content":" return courseNameTextBox.getText();"},{"lineNumber":870,"author":{"gitId":"-"},"content":" }"},{"lineNumber":871,"author":{"gitId":"-"},"content":""},{"lineNumber":872,"author":{"gitId":"-"},"content":" private String getTimeZone() {"},{"lineNumber":873,"author":{"gitId":"-"},"content":" return timezoneDropDown.getText();"},{"lineNumber":874,"author":{"gitId":"-"},"content":" }"},{"lineNumber":875,"author":{"gitId":"-"},"content":""},{"lineNumber":876,"author":{"gitId":"-"},"content":" private String getFeedbackSessionName() {"},{"lineNumber":877,"author":{"gitId":"-"},"content":" return sessionNameTextBox.getText();"},{"lineNumber":878,"author":{"gitId":"-"},"content":" }"},{"lineNumber":879,"author":{"gitId":"-"},"content":""},{"lineNumber":880,"author":{"gitId":"-"},"content":" private String getInstructions() {"},{"lineNumber":881,"author":{"gitId":"-"},"content":" return getEditorRichText(instructionsEditor.findElement(By.tagName(\"editor\")));"},{"lineNumber":882,"author":{"gitId":"-"},"content":" }"},{"lineNumber":883,"author":{"gitId":"-"},"content":""},{"lineNumber":884,"author":{"gitId":"-"},"content":" private String getStartDate() {"},{"lineNumber":885,"author":{"gitId":"-"},"content":" return startDateBox.findElement(By.tagName(\"input\")).getAttribute(\"value\");"},{"lineNumber":886,"author":{"gitId":"-"},"content":" }"},{"lineNumber":887,"author":{"gitId":"-"},"content":""},{"lineNumber":888,"author":{"gitId":"-"},"content":" private String getStartTime() {"},{"lineNumber":889,"author":{"gitId":"-"},"content":" return getSelectedDropdownOptionText(startTimeDropdown.findElement(By.tagName(\"select\")));"},{"lineNumber":890,"author":{"gitId":"-"},"content":" }"},{"lineNumber":891,"author":{"gitId":"-"},"content":""},{"lineNumber":892,"author":{"gitId":"-"},"content":" private String getEndDate() {"},{"lineNumber":893,"author":{"gitId":"-"},"content":" return endDateBox.findElement(By.tagName(\"input\")).getAttribute(\"value\");"},{"lineNumber":894,"author":{"gitId":"-"},"content":" }"},{"lineNumber":895,"author":{"gitId":"-"},"content":""},{"lineNumber":896,"author":{"gitId":"-"},"content":" private String getEndTime() {"},{"lineNumber":897,"author":{"gitId":"-"},"content":" return getSelectedDropdownOptionText(endTimeDropdown.findElement(By.tagName(\"select\")));"},{"lineNumber":898,"author":{"gitId":"-"},"content":" }"},{"lineNumber":899,"author":{"gitId":"-"},"content":""},{"lineNumber":900,"author":{"gitId":"-"},"content":" private String getSessionVisibilityDate() {"},{"lineNumber":901,"author":{"gitId":"-"},"content":" return sessionVisibilityDateBox.findElement(By.tagName(\"input\")).getAttribute(\"value\");"},{"lineNumber":902,"author":{"gitId":"-"},"content":" }"},{"lineNumber":903,"author":{"gitId":"-"},"content":""},{"lineNumber":904,"author":{"gitId":"-"},"content":" private String getSessionVisibilityTime() {"},{"lineNumber":905,"author":{"gitId":"-"},"content":" return getSelectedDropdownOptionText(sessionVisibilityTimeDropdown.findElement(By.tagName(\"select\")));"},{"lineNumber":906,"author":{"gitId":"-"},"content":" }"},{"lineNumber":907,"author":{"gitId":"-"},"content":""},{"lineNumber":908,"author":{"gitId":"-"},"content":" private String getResponseVisibilityDate() {"},{"lineNumber":909,"author":{"gitId":"-"},"content":" return responseVisibilityDateBox.findElement(By.tagName(\"input\"))"},{"lineNumber":910,"author":{"gitId":"-"},"content":" .getAttribute(\"value\");"},{"lineNumber":911,"author":{"gitId":"-"},"content":" }"},{"lineNumber":912,"author":{"gitId":"-"},"content":""},{"lineNumber":913,"author":{"gitId":"-"},"content":" private String getResponseVisibilityTime() {"},{"lineNumber":914,"author":{"gitId":"-"},"content":" return getSelectedDropdownOptionText(responseVisibilityTimeDropdown.findElement(By.tagName(\"select\")));"},{"lineNumber":915,"author":{"gitId":"-"},"content":" }"},{"lineNumber":916,"author":{"gitId":"-"},"content":""},{"lineNumber":917,"author":{"gitId":"-"},"content":" private String getGracePeriod() {"},{"lineNumber":918,"author":{"gitId":"-"},"content":" return getSelectedDropdownOptionText(gracePeriodDropdown);"},{"lineNumber":919,"author":{"gitId":"-"},"content":" }"},{"lineNumber":920,"author":{"gitId":"-"},"content":""},{"lineNumber":921,"author":{"gitId":"-"},"content":" private String getSubmissionStatus() {"},{"lineNumber":922,"author":{"gitId":"-"},"content":" return submissionStatusTextBox.getText();"},{"lineNumber":923,"author":{"gitId":"-"},"content":" }"},{"lineNumber":924,"author":{"gitId":"-"},"content":""},{"lineNumber":925,"author":{"gitId":"-"},"content":" private String getPublishedStatus() {"},{"lineNumber":926,"author":{"gitId":"-"},"content":" return publishStatusTextBox.getText();"},{"lineNumber":927,"author":{"gitId":"-"},"content":" }"},{"lineNumber":928,"author":{"gitId":"-"},"content":""},{"lineNumber":929,"author":{"gitId":"-"},"content":" private String getDateString(Instant instant, String timeZone) {"},{"lineNumber":930,"author":{"gitId":"-"},"content":" return getDisplayedDateTime(instant, timeZone, \"EE, dd MMM, yyyy\");"},{"lineNumber":931,"author":{"gitId":"-"},"content":" }"},{"lineNumber":932,"author":{"gitId":"-"},"content":""},{"lineNumber":933,"author":{"gitId":"-"},"content":" private String getTimeString(Instant instant, String timeZone) {"},{"lineNumber":934,"author":{"gitId":"-"},"content":" ZonedDateTime dateTime \u003d instant.atZone(ZoneId.of(timeZone));"},{"lineNumber":935,"author":{"gitId":"-"},"content":" if (dateTime.getHour() \u003d\u003d 0 \u0026\u0026 dateTime.getMinute() \u003d\u003d 0) {"},{"lineNumber":936,"author":{"gitId":"-"},"content":" return \"23:59H\";"},{"lineNumber":937,"author":{"gitId":"-"},"content":" }"},{"lineNumber":938,"author":{"gitId":"-"},"content":" return getDisplayedDateTime(instant, timeZone, \"HH:00\") + \"H\";"},{"lineNumber":939,"author":{"gitId":"-"},"content":" }"},{"lineNumber":940,"author":{"gitId":"-"},"content":""},{"lineNumber":941,"author":{"gitId":"-"},"content":" private void setInstructions(String newInstructions) {"},{"lineNumber":942,"author":{"gitId":"-"},"content":" writeToRichTextEditor(instructionsEditor.findElement(By.tagName(\"editor\")), newInstructions);"},{"lineNumber":943,"author":{"gitId":"-"},"content":" }"},{"lineNumber":944,"author":{"gitId":"-"},"content":""},{"lineNumber":945,"author":{"gitId":"-"},"content":" private void setSessionStartDateTime(Instant startInstant, String timeZone) {"},{"lineNumber":946,"author":{"gitId":"-"},"content":" setDateTime(startDateBox, startTimeDropdown, startInstant, timeZone);"},{"lineNumber":947,"author":{"gitId":"-"},"content":" }"},{"lineNumber":948,"author":{"gitId":"-"},"content":""},{"lineNumber":949,"author":{"gitId":"-"},"content":" private void setSessionEndDateTime(Instant endInstant, String timeZone) {"},{"lineNumber":950,"author":{"gitId":"-"},"content":" setDateTime(endDateBox, endTimeDropdown, endInstant, timeZone);"},{"lineNumber":951,"author":{"gitId":"-"},"content":" }"},{"lineNumber":952,"author":{"gitId":"-"},"content":""},{"lineNumber":953,"author":{"gitId":"-"},"content":" private void setVisibilityDateTime(Instant startInstant, String timeZone) {"},{"lineNumber":954,"author":{"gitId":"-"},"content":" setDateTime(sessionVisibilityDateBox, sessionVisibilityTimeDropdown, startInstant, timeZone);"},{"lineNumber":955,"author":{"gitId":"-"},"content":" }"},{"lineNumber":956,"author":{"gitId":"-"},"content":""},{"lineNumber":957,"author":{"gitId":"-"},"content":" private void setResponseDateTime(Instant endInstant, String timeZone) {"},{"lineNumber":958,"author":{"gitId":"-"},"content":" setDateTime(responseVisibilityDateBox, responseVisibilityTimeDropdown, endInstant, timeZone);"},{"lineNumber":959,"author":{"gitId":"-"},"content":" }"},{"lineNumber":960,"author":{"gitId":"-"},"content":""},{"lineNumber":961,"author":{"gitId":"-"},"content":" private void setDateTime(WebElement dateBox, WebElement timeBox, Instant startInstant, String timeZone) {"},{"lineNumber":962,"author":{"gitId":"-"},"content":" fillDatePicker(dateBox, startInstant, timeZone);"},{"lineNumber":963,"author":{"gitId":"-"},"content":""},{"lineNumber":964,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(timeBox.findElement(By.tagName(\"select\")), getTimeString(startInstant, timeZone));"},{"lineNumber":965,"author":{"gitId":"-"},"content":" }"},{"lineNumber":966,"author":{"gitId":"-"},"content":""},{"lineNumber":967,"author":{"gitId":"-"},"content":" private void selectGracePeriod(long gracePeriodMinutes) {"},{"lineNumber":968,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(gracePeriodDropdown, gracePeriodMinutes + \" min\");"},{"lineNumber":969,"author":{"gitId":"-"},"content":" }"},{"lineNumber":970,"author":{"gitId":"-"},"content":""},{"lineNumber":971,"author":{"gitId":"-"},"content":" private void setVisibilitySettings(FeedbackSessionAttributes newFeedbackSession) {"},{"lineNumber":972,"author":{"gitId":"-"},"content":" showVisibilitySettings();"},{"lineNumber":973,"author":{"gitId":"-"},"content":""},{"lineNumber":974,"author":{"gitId":"-"},"content":" setSessionVisibilitySettings(newFeedbackSession);"},{"lineNumber":975,"author":{"gitId":"-"},"content":" setResponseVisibilitySettings(newFeedbackSession);"},{"lineNumber":976,"author":{"gitId":"-"},"content":" }"},{"lineNumber":977,"author":{"gitId":"-"},"content":""},{"lineNumber":978,"author":{"gitId":"-"},"content":" private void setSessionVisibilitySettings(FeedbackSessionAttributes newFeedbackSession) {"},{"lineNumber":979,"author":{"gitId":"-"},"content":" Instant sessionDateTime \u003d newFeedbackSession.getSessionVisibleFromTime();"},{"lineNumber":980,"author":{"gitId":"-"},"content":" if (sessionDateTime.equals(Const.TIME_REPRESENTS_FOLLOW_OPENING)) {"},{"lineNumber":981,"author":{"gitId":"-"},"content":" click(openSessionVisibleTimeButton);"},{"lineNumber":982,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":983,"author":{"gitId":"-"},"content":" click(customSessionVisibleTimeButton);"},{"lineNumber":984,"author":{"gitId":"-"},"content":" setVisibilityDateTime(sessionDateTime, newFeedbackSession.getTimeZone());"},{"lineNumber":985,"author":{"gitId":"-"},"content":" }"},{"lineNumber":986,"author":{"gitId":"-"},"content":" }"},{"lineNumber":987,"author":{"gitId":"-"},"content":""},{"lineNumber":988,"author":{"gitId":"-"},"content":" private void setResponseVisibilitySettings(FeedbackSessionAttributes newFeedbackSession) {"},{"lineNumber":989,"author":{"gitId":"-"},"content":" Instant responseDateTime \u003d newFeedbackSession.getResultsVisibleFromTime();"},{"lineNumber":990,"author":{"gitId":"-"},"content":" if (responseDateTime.equals(Const.TIME_REPRESENTS_FOLLOW_VISIBLE)) {"},{"lineNumber":991,"author":{"gitId":"-"},"content":" click(immediateResponseVisibleTimeButton);"},{"lineNumber":992,"author":{"gitId":"-"},"content":" } else if (responseDateTime.equals(Const.TIME_REPRESENTS_LATER)) {"},{"lineNumber":993,"author":{"gitId":"-"},"content":" click(manualResponseVisibleTimeButton);"},{"lineNumber":994,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":995,"author":{"gitId":"-"},"content":" click(customResponseVisibleTimeButton);"},{"lineNumber":996,"author":{"gitId":"-"},"content":" setResponseDateTime(responseDateTime, newFeedbackSession.getTimeZone());"},{"lineNumber":997,"author":{"gitId":"-"},"content":" }"},{"lineNumber":998,"author":{"gitId":"-"},"content":" }"},{"lineNumber":999,"author":{"gitId":"-"},"content":""},{"lineNumber":1000,"author":{"gitId":"-"},"content":" private void setEmailSettings(FeedbackSessionAttributes newFeedbackSessionDetails) {"},{"lineNumber":1001,"author":{"gitId":"-"},"content":" showEmailSettings();"},{"lineNumber":1002,"author":{"gitId":"-"},"content":" if (newFeedbackSessionDetails.isOpeningEmailEnabled() !\u003d openingSessionEmailCheckbox.isSelected()) {"},{"lineNumber":1003,"author":{"gitId":"-"},"content":" click(openingSessionEmailCheckbox);"},{"lineNumber":1004,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1005,"author":{"gitId":"-"},"content":" if (newFeedbackSessionDetails.isClosingEmailEnabled() !\u003d closingSessionEmailCheckbox.isSelected()) {"},{"lineNumber":1006,"author":{"gitId":"-"},"content":" click(closingSessionEmailCheckbox);"},{"lineNumber":1007,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1008,"author":{"gitId":"-"},"content":" if (newFeedbackSessionDetails.isPublishedEmailEnabled() !\u003d publishedSessionEmailCheckbox.isSelected()) {"},{"lineNumber":1009,"author":{"gitId":"-"},"content":" click(publishedSessionEmailCheckbox);"},{"lineNumber":1010,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1011,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1012,"author":{"gitId":"-"},"content":""},{"lineNumber":1013,"author":{"gitId":"-"},"content":" private void showVisibilitySettings() {"},{"lineNumber":1014,"author":{"gitId":"-"},"content":" if (isElementPresent(By.id(\"btn-change-visibility\"))) {"},{"lineNumber":1015,"author":{"gitId":"-"},"content":" click(changeVisibilityButton);"},{"lineNumber":1016,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1017,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1018,"author":{"gitId":"-"},"content":""},{"lineNumber":1019,"author":{"gitId":"-"},"content":" private void showEmailSettings() {"},{"lineNumber":1020,"author":{"gitId":"-"},"content":" if (isElementPresent(By.id(\"btn-change-email\"))) {"},{"lineNumber":1021,"author":{"gitId":"-"},"content":" click(changeEmailButton);"},{"lineNumber":1022,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1023,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1024,"author":{"gitId":"-"},"content":""},{"lineNumber":1025,"author":{"gitId":"-"},"content":" private int getNumQuestions() {"},{"lineNumber":1026,"author":{"gitId":"-"},"content":" return browser.driver.findElements(By.tagName(\"tm-question-edit-form\")).size();"},{"lineNumber":1027,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1028,"author":{"gitId":"-"},"content":""},{"lineNumber":1029,"author":{"gitId":"-"},"content":" private WebElement getQuestionForm(int questionNum) {"},{"lineNumber":1030,"author":{"gitId":"-"},"content":" return browser.driver.findElements(By.tagName(\"tm-question-edit-form\")).get(questionNum - 1);"},{"lineNumber":1031,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1032,"author":{"gitId":"-"},"content":""},{"lineNumber":1033,"author":{"gitId":"-"},"content":" private FeedbackQuestionType getQuestionType(int questionNum) {"},{"lineNumber":1034,"author":{"gitId":"-"},"content":" String questionType \u003d getQuestionForm(questionNum).findElement(By.id(\"question-type\")).getText().trim();"},{"lineNumber":1035,"author":{"gitId":"-"},"content":""},{"lineNumber":1036,"author":{"gitId":"-"},"content":" switch (questionType) {"},{"lineNumber":1037,"author":{"gitId":"-"},"content":" case \"Essay question\":"},{"lineNumber":1038,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.TEXT;"},{"lineNumber":1039,"author":{"gitId":"-"},"content":" case \"Multiple-Choice (single answer) question\":"},{"lineNumber":1040,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.MCQ;"},{"lineNumber":1041,"author":{"gitId":"-"},"content":" case \"Multiple-choice (multiple answers) question\":"},{"lineNumber":1042,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.MSQ;"},{"lineNumber":1043,"author":{"gitId":"-"},"content":" case \"Numerical Scale Question\":"},{"lineNumber":1044,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.NUMSCALE;"},{"lineNumber":1045,"author":{"gitId":"-"},"content":" case \"Distribute points (among options) question\":"},{"lineNumber":1046,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.CONSTSUM_OPTIONS;"},{"lineNumber":1047,"author":{"gitId":"-"},"content":" case \"Distribute points (among recipients) question\":"},{"lineNumber":1048,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.CONSTSUM_RECIPIENTS;"},{"lineNumber":1049,"author":{"gitId":"-"},"content":" case \"Team contribution question\":"},{"lineNumber":1050,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.CONTRIB;"},{"lineNumber":1051,"author":{"gitId":"-"},"content":" case \"Rubric question\":"},{"lineNumber":1052,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.RUBRIC;"},{"lineNumber":1053,"author":{"gitId":"-"},"content":" case \"Rank (options) question\":"},{"lineNumber":1054,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.RANK_OPTIONS;"},{"lineNumber":1055,"author":{"gitId":"-"},"content":" case \"Rank (recipients) question\":"},{"lineNumber":1056,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.RANK_RECIPIENTS;"},{"lineNumber":1057,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":1058,"author":{"gitId":"-"},"content":" throw new IllegalArgumentException(\"Unknown FeedbackQuestionType\");"},{"lineNumber":1059,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1060,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1061,"author":{"gitId":"-"},"content":""},{"lineNumber":1062,"author":{"gitId":"-"},"content":" private int getQuestionNumber(int questionNum) {"},{"lineNumber":1063,"author":{"gitId":"-"},"content":" return Integer.parseInt(getQuestionForm(questionNum).findElement(By.id(\"question-number\")).getText());"},{"lineNumber":1064,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1065,"author":{"gitId":"-"},"content":""},{"lineNumber":1066,"author":{"gitId":"-"},"content":" private String getQuestionBrief(int questionNum) {"},{"lineNumber":1067,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"question-brief\")).getAttribute(\"value\");"},{"lineNumber":1068,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1069,"author":{"gitId":"-"},"content":""},{"lineNumber":1070,"author":{"gitId":"-"},"content":" private String getQuestionDescription(int questionNum) {"},{"lineNumber":1071,"author":{"gitId":"-"},"content":" WebElement editor \u003d waitForElementPresence(By.cssSelector(\"#question-form-\" + questionNum + \" editor\"));"},{"lineNumber":1072,"author":{"gitId":"-"},"content":" return getEditorRichText(editor);"},{"lineNumber":1073,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1074,"author":{"gitId":"-"},"content":""},{"lineNumber":1075,"author":{"gitId":"-"},"content":" private String getFeedbackGiver(int questionNum) {"},{"lineNumber":1076,"author":{"gitId":"-"},"content":" String feedbackPath \u003d getFeedbackPath(questionNum);"},{"lineNumber":1077,"author":{"gitId":"-"},"content":" if (CUSTOM_FEEDBACK_PATH_OPTION.equals(feedbackPath)) {"},{"lineNumber":1078,"author":{"gitId":"-"},"content":" return getSelectedDropdownOptionText(getQuestionForm(questionNum)"},{"lineNumber":1079,"author":{"gitId":"-"},"content":" .findElement(By.tagName(\"tm-feedback-path-panel\"))"},{"lineNumber":1080,"author":{"gitId":"-"},"content":" .findElement(By.id(\"giver-type\")));"},{"lineNumber":1081,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1082,"author":{"gitId":"-"},"content":" return feedbackPath.split(FEEDBACK_PATH_SEPARATOR)[0];"},{"lineNumber":1083,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1084,"author":{"gitId":"-"},"content":""},{"lineNumber":1085,"author":{"gitId":"-"},"content":" private String getFeedbackReceiver(int questionNum) {"},{"lineNumber":1086,"author":{"gitId":"-"},"content":" String feedbackPath \u003d getFeedbackPath(questionNum);"},{"lineNumber":1087,"author":{"gitId":"-"},"content":" if (CUSTOM_FEEDBACK_PATH_OPTION.equals(feedbackPath)) {"},{"lineNumber":1088,"author":{"gitId":"-"},"content":" return getSelectedDropdownOptionText(getQuestionForm(questionNum)"},{"lineNumber":1089,"author":{"gitId":"-"},"content":" .findElement(By.tagName(\"tm-feedback-path-panel\"))"},{"lineNumber":1090,"author":{"gitId":"-"},"content":" .findElement(By.id(\"receiver-type\")));"},{"lineNumber":1091,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1092,"author":{"gitId":"-"},"content":" return feedbackPath.split(FEEDBACK_PATH_SEPARATOR)[1];"},{"lineNumber":1093,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1094,"author":{"gitId":"-"},"content":""},{"lineNumber":1095,"author":{"gitId":"-"},"content":" private String getFeedbackPath(int questionNum) {"},{"lineNumber":1096,"author":{"gitId":"-"},"content":" WebElement feedbackPathPanel \u003d getQuestionForm(questionNum).findElement(By.tagName(\"tm-feedback-path-panel\"));"},{"lineNumber":1097,"author":{"gitId":"-"},"content":" return feedbackPathPanel.findElement(By.cssSelector(\"#btn-feedback-path span\")).getText();"},{"lineNumber":1098,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1099,"author":{"gitId":"-"},"content":""},{"lineNumber":1100,"author":{"gitId":"-"},"content":" private void setQuestionBrief(int questionNum, String newBrief) {"},{"lineNumber":1101,"author":{"gitId":"-"},"content":" fillTextBox(getQuestionForm(questionNum).findElement(By.id(\"question-brief\")), newBrief);"},{"lineNumber":1102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1103,"author":{"gitId":"-"},"content":""},{"lineNumber":1104,"author":{"gitId":"-"},"content":" private void setQuestionDescription(int questionNum, String newDescription) {"},{"lineNumber":1105,"author":{"gitId":"-"},"content":" WebElement editor \u003d waitForElementPresence(By.cssSelector(\"#question-form-\" + questionNum + \" editor\"));"},{"lineNumber":1106,"author":{"gitId":"-"},"content":" writeToRichTextEditor(editor, newDescription);"},{"lineNumber":1107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1108,"author":{"gitId":"-"},"content":""},{"lineNumber":1109,"author":{"gitId":"-"},"content":" private void setFeedbackPath(int questionNum, FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":1110,"author":{"gitId":"-"},"content":" FeedbackParticipantType newGiver \u003d feedbackQuestion.getGiverType();"},{"lineNumber":1111,"author":{"gitId":"-"},"content":" FeedbackParticipantType newRecipient \u003d feedbackQuestion.getRecipientType();"},{"lineNumber":1112,"author":{"gitId":"-"},"content":" String feedbackPath \u003d getFeedbackPath(questionNum);"},{"lineNumber":1113,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(questionNum).findElement(By.tagName(\"tm-feedback-path-panel\"));"},{"lineNumber":1114,"author":{"gitId":"-"},"content":" if (!CUSTOM_FEEDBACK_PATH_OPTION.equals(feedbackPath)) {"},{"lineNumber":1115,"author":{"gitId":"-"},"content":" selectFeedbackPathDropdownOption(questionNum, CUSTOM_FEEDBACK_PATH_OPTION + \"...\");"},{"lineNumber":1116,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1117,"author":{"gitId":"-"},"content":" // Set to type STUDENT first to adjust NumberOfEntitiesToGiveFeedbackTo"},{"lineNumber":1118,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(questionForm.findElement(By.id(\"giver-type\")),"},{"lineNumber":1119,"author":{"gitId":"-"},"content":" getDisplayGiverName(FeedbackParticipantType.STUDENTS));"},{"lineNumber":1120,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(questionForm.findElement(By.id(\"receiver-type\")),"},{"lineNumber":1121,"author":{"gitId":"-"},"content":" getDisplayRecipientName(FeedbackParticipantType.STUDENTS_EXCLUDING_SELF));"},{"lineNumber":1122,"author":{"gitId":"-"},"content":" if (feedbackQuestion.getNumberOfEntitiesToGiveFeedbackTo() \u003d\u003d Const.MAX_POSSIBLE_RECIPIENTS) {"},{"lineNumber":1123,"author":{"gitId":"-"},"content":" click(questionForm.findElement(By.id(\"unlimited-recipients\")));"},{"lineNumber":1124,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1125,"author":{"gitId":"-"},"content":" click(questionForm.findElement(By.id(\"custom-recipients\")));"},{"lineNumber":1126,"author":{"gitId":"-"},"content":" fillTextBox(questionForm.findElement(By.id(\"custom-recipients-number\")),"},{"lineNumber":1127,"author":{"gitId":"-"},"content":" Integer.toString(feedbackQuestion.getNumberOfEntitiesToGiveFeedbackTo()));"},{"lineNumber":1128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1129,"author":{"gitId":"-"},"content":""},{"lineNumber":1130,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(questionForm.findElement(By.id(\"giver-type\")), getDisplayGiverName(newGiver));"},{"lineNumber":1131,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(questionForm.findElement(By.id(\"receiver-type\")),"},{"lineNumber":1132,"author":{"gitId":"-"},"content":" getDisplayRecipientName(newRecipient));"},{"lineNumber":1133,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1134,"author":{"gitId":"-"},"content":""},{"lineNumber":1135,"author":{"gitId":"-"},"content":" private void setFeedbackPath(int questionNum, FeedbackQuestion feedbackQuestion) {"},{"lineNumber":1136,"author":{"gitId":"-"},"content":" FeedbackParticipantType newGiver \u003d feedbackQuestion.getGiverType();"},{"lineNumber":1137,"author":{"gitId":"-"},"content":" FeedbackParticipantType newRecipient \u003d feedbackQuestion.getRecipientType();"},{"lineNumber":1138,"author":{"gitId":"-"},"content":" String feedbackPath \u003d getFeedbackPath(questionNum);"},{"lineNumber":1139,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(questionNum).findElement(By.tagName(\"tm-feedback-path-panel\"));"},{"lineNumber":1140,"author":{"gitId":"-"},"content":" if (!CUSTOM_FEEDBACK_PATH_OPTION.equals(feedbackPath)) {"},{"lineNumber":1141,"author":{"gitId":"-"},"content":" selectFeedbackPathDropdownOption(questionNum, CUSTOM_FEEDBACK_PATH_OPTION + \"...\");"},{"lineNumber":1142,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1143,"author":{"gitId":"-"},"content":" // Set to type STUDENT first to adjust NumberOfEntitiesToGiveFeedbackTo"},{"lineNumber":1144,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(questionForm.findElement(By.id(\"giver-type\")),"},{"lineNumber":1145,"author":{"gitId":"-"},"content":" getDisplayGiverName(FeedbackParticipantType.STUDENTS));"},{"lineNumber":1146,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(questionForm.findElement(By.id(\"receiver-type\")),"},{"lineNumber":1147,"author":{"gitId":"-"},"content":" getDisplayRecipientName(FeedbackParticipantType.STUDENTS_EXCLUDING_SELF));"},{"lineNumber":1148,"author":{"gitId":"-"},"content":" if (feedbackQuestion.getNumOfEntitiesToGiveFeedbackTo() \u003d\u003d Const.MAX_POSSIBLE_RECIPIENTS) {"},{"lineNumber":1149,"author":{"gitId":"-"},"content":" click(questionForm.findElement(By.id(\"unlimited-recipients\")));"},{"lineNumber":1150,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1151,"author":{"gitId":"-"},"content":" click(questionForm.findElement(By.id(\"custom-recipients\")));"},{"lineNumber":1152,"author":{"gitId":"-"},"content":" fillTextBox(questionForm.findElement(By.id(\"custom-recipients-number\")),"},{"lineNumber":1153,"author":{"gitId":"-"},"content":" Integer.toString(feedbackQuestion.getNumOfEntitiesToGiveFeedbackTo()));"},{"lineNumber":1154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1155,"author":{"gitId":"-"},"content":""},{"lineNumber":1156,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(questionForm.findElement(By.id(\"giver-type\")), getDisplayGiverName(newGiver));"},{"lineNumber":1157,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(questionForm.findElement(By.id(\"receiver-type\")),"},{"lineNumber":1158,"author":{"gitId":"-"},"content":" getDisplayRecipientName(newRecipient));"},{"lineNumber":1159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1160,"author":{"gitId":"-"},"content":""},{"lineNumber":1161,"author":{"gitId":"-"},"content":" private void selectFeedbackPathDropdownOption(int questionNum, String text) {"},{"lineNumber":1162,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(questionNum);"},{"lineNumber":1163,"author":{"gitId":"-"},"content":" WebElement feedbackPathPanel \u003d questionForm.findElement(By.tagName(\"tm-feedback-path-panel\"));"},{"lineNumber":1164,"author":{"gitId":"-"},"content":" click(feedbackPathPanel.findElement(By.id(\"btn-feedback-path\")));"},{"lineNumber":1165,"author":{"gitId":"-"},"content":" WebElement dropdown \u003d feedbackPathPanel.findElement(By.id(\"feedback-path-dropdown\"));"},{"lineNumber":1166,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e options \u003d dropdown.findElements(By.className(\"dropdown-button\"));"},{"lineNumber":1167,"author":{"gitId":"-"},"content":" for (WebElement option : options) {"},{"lineNumber":1168,"author":{"gitId":"-"},"content":" if (option.getText().equals(text)) {"},{"lineNumber":1169,"author":{"gitId":"-"},"content":" click(option);"},{"lineNumber":1170,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":1171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1172,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1174,"author":{"gitId":"-"},"content":""},{"lineNumber":1175,"author":{"gitId":"-"},"content":" private void clickEditQuestionButton(int questionNum) {"},{"lineNumber":1176,"author":{"gitId":"-"},"content":" click(getQuestionForm(questionNum).findElement(By.id(\"btn-edit-question\")));"},{"lineNumber":1177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1178,"author":{"gitId":"-"},"content":""},{"lineNumber":1179,"author":{"gitId":"-"},"content":" private void clickSaveQuestionButton(int questionNum) {"},{"lineNumber":1180,"author":{"gitId":"-"},"content":" WebElement saveButton \u003d getQuestionForm(questionNum).findElement(By.id(\"btn-save-question\"));"},{"lineNumber":1181,"author":{"gitId":"-"},"content":" click(saveButton);"},{"lineNumber":1182,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(1000);"},{"lineNumber":1183,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1184,"author":{"gitId":"-"},"content":""},{"lineNumber":1185,"author":{"gitId":"-"},"content":" private void setQuestionVisibility(int questionNum, FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":1186,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(questionNum);"},{"lineNumber":1187,"author":{"gitId":"-"},"content":" WebElement visibilityPanel \u003d questionForm.findElement(By.tagName(\"tm-visibility-panel\"));"},{"lineNumber":1188,"author":{"gitId":"-"},"content":" String visibility \u003d visibilityPanel.findElement(By.cssSelector(\"#btn-question-visibility span\")).getText();"},{"lineNumber":1189,"author":{"gitId":"-"},"content":" if (!CUSTOM_VISIBILITY_OPTION.equals(visibility)) {"},{"lineNumber":1190,"author":{"gitId":"-"},"content":" selectVisibilityDropdownOption(questionNum, CUSTOM_VISIBILITY_OPTION + \"...\");"},{"lineNumber":1191,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1192,"author":{"gitId":"-"},"content":""},{"lineNumber":1193,"author":{"gitId":"-"},"content":" FeedbackParticipantType giver \u003d feedbackQuestion.getGiverType();"},{"lineNumber":1194,"author":{"gitId":"-"},"content":" FeedbackParticipantType receiver \u003d feedbackQuestion.getRecipientType();"},{"lineNumber":1195,"author":{"gitId":"-"},"content":" WebElement customVisibilityTable \u003d visibilityPanel.findElement(By.id(\"custom-visibility-table\"));"},{"lineNumber":1196,"author":{"gitId":"-"},"content":" selectVisibilityBoxes(customVisibilityTable, giver, receiver, feedbackQuestion.getShowResponsesTo(), 1);"},{"lineNumber":1197,"author":{"gitId":"-"},"content":" selectVisibilityBoxes(customVisibilityTable, giver, receiver, feedbackQuestion.getShowGiverNameTo(), 2);"},{"lineNumber":1198,"author":{"gitId":"-"},"content":" selectVisibilityBoxes(customVisibilityTable, giver, receiver, feedbackQuestion.getShowRecipientNameTo(), 3);"},{"lineNumber":1199,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1200,"author":{"gitId":"-"},"content":""},{"lineNumber":1201,"author":{"gitId":"-"},"content":" private void setQuestionVisibility(int questionNum, FeedbackQuestion feedbackQuestion) {"},{"lineNumber":1202,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(questionNum);"},{"lineNumber":1203,"author":{"gitId":"-"},"content":" WebElement visibilityPanel \u003d questionForm.findElement(By.tagName(\"tm-visibility-panel\"));"},{"lineNumber":1204,"author":{"gitId":"-"},"content":" String visibility \u003d visibilityPanel.findElement(By.cssSelector(\"#btn-question-visibility span\")).getText();"},{"lineNumber":1205,"author":{"gitId":"-"},"content":" if (!CUSTOM_VISIBILITY_OPTION.equals(visibility)) {"},{"lineNumber":1206,"author":{"gitId":"-"},"content":" selectVisibilityDropdownOption(questionNum, CUSTOM_VISIBILITY_OPTION + \"...\");"},{"lineNumber":1207,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1208,"author":{"gitId":"-"},"content":""},{"lineNumber":1209,"author":{"gitId":"-"},"content":" FeedbackParticipantType giver \u003d feedbackQuestion.getGiverType();"},{"lineNumber":1210,"author":{"gitId":"-"},"content":" FeedbackParticipantType receiver \u003d feedbackQuestion.getRecipientType();"},{"lineNumber":1211,"author":{"gitId":"-"},"content":" WebElement customVisibilityTable \u003d visibilityPanel.findElement(By.id(\"custom-visibility-table\"));"},{"lineNumber":1212,"author":{"gitId":"-"},"content":" selectVisibilityBoxes(customVisibilityTable, giver, receiver, feedbackQuestion.getShowResponsesTo(), 1);"},{"lineNumber":1213,"author":{"gitId":"-"},"content":" selectVisibilityBoxes(customVisibilityTable, giver, receiver, feedbackQuestion.getShowGiverNameTo(), 2);"},{"lineNumber":1214,"author":{"gitId":"-"},"content":" selectVisibilityBoxes(customVisibilityTable, giver, receiver, feedbackQuestion.getShowRecipientNameTo(), 3);"},{"lineNumber":1215,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1216,"author":{"gitId":"-"},"content":""},{"lineNumber":1217,"author":{"gitId":"-"},"content":" private void selectVisibilityBoxes(WebElement table, FeedbackParticipantType giver,"},{"lineNumber":1218,"author":{"gitId":"-"},"content":" FeedbackParticipantType receiver, List\u003cFeedbackParticipantType\u003e participants,"},{"lineNumber":1219,"author":{"gitId":"-"},"content":" int colNum) {"},{"lineNumber":1220,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e possibleTypes \u003d new ArrayList\u003c\u003e(Arrays.asList(FeedbackParticipantType.RECEIVER,"},{"lineNumber":1221,"author":{"gitId":"-"},"content":" FeedbackParticipantType.OWN_TEAM_MEMBERS, FeedbackParticipantType.RECEIVER_TEAM_MEMBERS,"},{"lineNumber":1222,"author":{"gitId":"-"},"content":" FeedbackParticipantType.STUDENTS, FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":1223,"author":{"gitId":"-"},"content":" if (!giver.equals(FeedbackParticipantType.STUDENTS)) {"},{"lineNumber":1224,"author":{"gitId":"-"},"content":" possibleTypes.remove(FeedbackParticipantType.OWN_TEAM_MEMBERS);"},{"lineNumber":1225,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1226,"author":{"gitId":"-"},"content":" if (!receiver.equals(FeedbackParticipantType.STUDENTS_EXCLUDING_SELF)) {"},{"lineNumber":1227,"author":{"gitId":"-"},"content":" possibleTypes.remove(FeedbackParticipantType.RECEIVER_TEAM_MEMBERS);"},{"lineNumber":1228,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1229,"author":{"gitId":"-"},"content":" if (receiver.equals(FeedbackParticipantType.NONE)"},{"lineNumber":1230,"author":{"gitId":"-"},"content":" || receiver.equals(FeedbackParticipantType.SELF)"},{"lineNumber":1231,"author":{"gitId":"-"},"content":" || receiver.equals(FeedbackParticipantType.OWN_TEAM)) {"},{"lineNumber":1232,"author":{"gitId":"-"},"content":" possibleTypes.remove(FeedbackParticipantType.RECEIVER);"},{"lineNumber":1233,"author":{"gitId":"-"},"content":" possibleTypes.remove(FeedbackParticipantType.RECEIVER_TEAM_MEMBERS);"},{"lineNumber":1234,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1235,"author":{"gitId":"-"},"content":""},{"lineNumber":1236,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d table.findElements(By.tagName(\"tr\"));"},{"lineNumber":1237,"author":{"gitId":"-"},"content":" int index \u003d colNum - 1;"},{"lineNumber":1238,"author":{"gitId":"-"},"content":" for (FeedbackParticipantType participant : participants) {"},{"lineNumber":1239,"author":{"gitId":"-"},"content":" markOptionAsSelected(rows.get(possibleTypes.indexOf(participant)).findElements(By.tagName(\"input\")).get(index));"},{"lineNumber":1240,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1241,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1242,"author":{"gitId":"-"},"content":""},{"lineNumber":1243,"author":{"gitId":"-"},"content":" private void selectVisibilityDropdownOption(int questionNum, String text) {"},{"lineNumber":1244,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(questionNum);"},{"lineNumber":1245,"author":{"gitId":"-"},"content":" WebElement visibilityPanel \u003d questionForm.findElement(By.tagName(\"tm-visibility-panel\"));"},{"lineNumber":1246,"author":{"gitId":"-"},"content":" click(visibilityPanel.findElement(By.id(\"btn-question-visibility\")));"},{"lineNumber":1247,"author":{"gitId":"-"},"content":" WebElement dropdown \u003d visibilityPanel.findElement(By.id(\"question-visibility-dropdown\"));"},{"lineNumber":1248,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e options \u003d dropdown.findElements(By.className(\"dropdown-button\"));"},{"lineNumber":1249,"author":{"gitId":"-"},"content":" for (WebElement option : options) {"},{"lineNumber":1250,"author":{"gitId":"-"},"content":" if (option.getText().equals(text)) {"},{"lineNumber":1251,"author":{"gitId":"-"},"content":" click(option);"},{"lineNumber":1252,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":1253,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1254,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1255,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1256,"author":{"gitId":"-"},"content":""},{"lineNumber":1257,"author":{"gitId":"-"},"content":" private void clickAndWaitForNewQuestion(WebElement button) {"},{"lineNumber":1258,"author":{"gitId":"-"},"content":" int newQuestionNum \u003d getNumQuestions() + 1;"},{"lineNumber":1259,"author":{"gitId":"-"},"content":" click(button);"},{"lineNumber":1260,"author":{"gitId":"-"},"content":" waitForElementPresence(By.id(\"question-form-\" + newQuestionNum));"},{"lineNumber":1261,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1262,"author":{"gitId":"-"},"content":""},{"lineNumber":1263,"author":{"gitId":"-"},"content":" private void addNewQuestion(int optionNumber) {"},{"lineNumber":1264,"author":{"gitId":"-"},"content":" click(addNewQuestionButton);"},{"lineNumber":1265,"author":{"gitId":"-"},"content":" WebElement newQuestionDropdown \u003d waitForElementPresence(By.id(\"new-question-dropdown\"));"},{"lineNumber":1266,"author":{"gitId":"-"},"content":" WebElement optionButton \u003d newQuestionDropdown.findElements(By.tagName(\"button\")).get(optionNumber - 1);"},{"lineNumber":1267,"author":{"gitId":"-"},"content":" if (optionNumber \u003d\u003d 1) {"},{"lineNumber":1268,"author":{"gitId":"-"},"content":" click(optionButton);"},{"lineNumber":1269,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1270,"author":{"gitId":"-"},"content":" clickAndWaitForNewQuestion(optionButton);"},{"lineNumber":1271,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1272,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1273,"author":{"gitId":"-"},"content":""},{"lineNumber":1274,"author":{"gitId":"-"},"content":" private void clickSaveNewQuestionButton() {"},{"lineNumber":1275,"author":{"gitId":"-"},"content":" WebElement saveButton \u003d browser.driver.findElement(By.id(\"btn-save-new\"));"},{"lineNumber":1276,"author":{"gitId":"-"},"content":" click(saveButton);"},{"lineNumber":1277,"author":{"gitId":"-"},"content":" waitForElementStaleness(saveButton);"},{"lineNumber":1278,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1279,"author":{"gitId":"-"},"content":""},{"lineNumber":1280,"author":{"gitId":"-"},"content":" private WebElement getRecommendedTextLengthField(int questionNum) {"},{"lineNumber":1281,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum)"},{"lineNumber":1282,"author":{"gitId":"-"},"content":" .findElement(By.tagName(\"tm-text-question-edit-details-form\"))"},{"lineNumber":1283,"author":{"gitId":"-"},"content":" .findElement(By.id(\"recommended-length\"));"},{"lineNumber":1284,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1285,"author":{"gitId":"-"},"content":""},{"lineNumber":1286,"author":{"gitId":"-"},"content":" private WebElement getGenerateOptionsCheckbox(int questionNum) {"},{"lineNumber":1287,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"generate-checkbox\"));"},{"lineNumber":1288,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1289,"author":{"gitId":"-"},"content":""},{"lineNumber":1290,"author":{"gitId":"-"},"content":" private WebElement getGenerateOptionsDropdown(int questionNum) {"},{"lineNumber":1291,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"generate-dropdown\"));"},{"lineNumber":1292,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1293,"author":{"gitId":"-"},"content":""},{"lineNumber":1294,"author":{"gitId":"-"},"content":" private WebElement getWeightCheckbox(int questionNum) {"},{"lineNumber":1295,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"weights-checkbox\"));"},{"lineNumber":1296,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1297,"author":{"gitId":"-"},"content":""},{"lineNumber":1298,"author":{"gitId":"-"},"content":" private WebElement getOtherOptionCheckbox(int questionNum) {"},{"lineNumber":1299,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"other-checkbox\"));"},{"lineNumber":1300,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1301,"author":{"gitId":"-"},"content":""},{"lineNumber":1302,"author":{"gitId":"-"},"content":" private WebElement getQuestionDropdownCheckbox(int questionNum) {"},{"lineNumber":1303,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"make-question-dropdown\"));"},{"lineNumber":1304,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1305,"author":{"gitId":"-"},"content":""},{"lineNumber":1306,"author":{"gitId":"-"},"content":" private String getGeneratedOptionString(FeedbackParticipantType type) {"},{"lineNumber":1307,"author":{"gitId":"-"},"content":" switch (type) {"},{"lineNumber":1308,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":1309,"author":{"gitId":"-"},"content":" case STUDENTS_IN_SAME_SECTION:"},{"lineNumber":1310,"author":{"gitId":"-"},"content":" return \"students\";"},{"lineNumber":1311,"author":{"gitId":"-"},"content":" case STUDENTS_EXCLUDING_SELF:"},{"lineNumber":1312,"author":{"gitId":"-"},"content":" return \"students (excluding self)\";"},{"lineNumber":1313,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":1314,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":1315,"author":{"gitId":"-"},"content":" return \"teams\";"},{"lineNumber":1316,"author":{"gitId":"-"},"content":" case TEAMS_EXCLUDING_SELF:"},{"lineNumber":1317,"author":{"gitId":"-"},"content":" return \"teams (excluding own team)\";"},{"lineNumber":1318,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":1319,"author":{"gitId":"-"},"content":" return \"instructors\";"},{"lineNumber":1320,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":1321,"author":{"gitId":"-"},"content":" return \"unknown\";"},{"lineNumber":1322,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1323,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1324,"author":{"gitId":"-"},"content":""},{"lineNumber":1325,"author":{"gitId":"-"},"content":" private String getDoubleString(Double value) {"},{"lineNumber":1326,"author":{"gitId":"-"},"content":" return value % 1 \u003d\u003d 0 ? Integer.toString(value.intValue()) : Double.toString(value);"},{"lineNumber":1327,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1328,"author":{"gitId":"-"},"content":""},{"lineNumber":1329,"author":{"gitId":"-"},"content":" private WebElement getOptionsSection(int questionNum) {"},{"lineNumber":1330,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"options-section\"));"},{"lineNumber":1331,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1332,"author":{"gitId":"-"},"content":""},{"lineNumber":1333,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getOptionInputs(int questionNum) {"},{"lineNumber":1334,"author":{"gitId":"-"},"content":" WebElement optionsSection \u003d getOptionsSection(questionNum);"},{"lineNumber":1335,"author":{"gitId":"-"},"content":" return optionsSection.findElements(By.cssSelector(\"input[type\u003d\u0027text\u0027]\"));"},{"lineNumber":1336,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1337,"author":{"gitId":"-"},"content":""},{"lineNumber":1338,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getOptionWeightInputs(int questionNum) {"},{"lineNumber":1339,"author":{"gitId":"-"},"content":" WebElement optionsSection \u003d getOptionsSection(questionNum);"},{"lineNumber":1340,"author":{"gitId":"-"},"content":" return optionsSection.findElements(By.cssSelector(\"tm-weight-field input\"));"},{"lineNumber":1341,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1342,"author":{"gitId":"-"},"content":""},{"lineNumber":1343,"author":{"gitId":"-"},"content":" private WebElement getOtherWeightInput(int questionNum) {"},{"lineNumber":1344,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"other-weight\"));"},{"lineNumber":1345,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1346,"author":{"gitId":"-"},"content":""},{"lineNumber":1347,"author":{"gitId":"-"},"content":" private boolean verifyGeneratedOptions(int questionNum, FeedbackParticipantType participantType) {"},{"lineNumber":1348,"author":{"gitId":"-"},"content":" if (!participantType.equals(FeedbackParticipantType.NONE)) {"},{"lineNumber":1349,"author":{"gitId":"-"},"content":" assertTrue(getGenerateOptionsCheckbox(questionNum).isSelected());"},{"lineNumber":1350,"author":{"gitId":"-"},"content":" assertEquals(getSelectedDropdownOptionText(getGenerateOptionsDropdown(questionNum)),"},{"lineNumber":1351,"author":{"gitId":"-"},"content":" getGeneratedOptionString(participantType));"},{"lineNumber":1352,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":1353,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1354,"author":{"gitId":"-"},"content":" assertFalse(getGenerateOptionsCheckbox(questionNum).isSelected());"},{"lineNumber":1355,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":1356,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1357,"author":{"gitId":"-"},"content":""},{"lineNumber":1358,"author":{"gitId":"-"},"content":" private void verifyOptions(int questionNum, List\u003cString\u003e options) {"},{"lineNumber":1359,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e inputs \u003d getOptionInputs(questionNum);"},{"lineNumber":1360,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c options.size(); i++) {"},{"lineNumber":1361,"author":{"gitId":"-"},"content":" assertEquals(options.get(i), inputs.get(i).getAttribute(\"value\"));"},{"lineNumber":1362,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1363,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1364,"author":{"gitId":"-"},"content":""},{"lineNumber":1365,"author":{"gitId":"-"},"content":" private void verifyOptionWeights(int questionNum, boolean hasWeights, List\u003cDouble\u003e weights) {"},{"lineNumber":1366,"author":{"gitId":"-"},"content":" if (hasWeights) {"},{"lineNumber":1367,"author":{"gitId":"-"},"content":" assertTrue(getWeightCheckbox(questionNum).isSelected());"},{"lineNumber":1368,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e weightInputs \u003d getOptionWeightInputs(questionNum);"},{"lineNumber":1369,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c weights.size(); i++) {"},{"lineNumber":1370,"author":{"gitId":"-"},"content":" assertEquals(getDoubleString(weights.get(i)), weightInputs.get(i).getAttribute(\"value\"));"},{"lineNumber":1371,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1372,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1373,"author":{"gitId":"-"},"content":" assertFalse(getWeightCheckbox(questionNum).isSelected());"},{"lineNumber":1374,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1375,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1376,"author":{"gitId":"-"},"content":""},{"lineNumber":1377,"author":{"gitId":"-"},"content":" private void verifyOtherOption(int questionNum, boolean hasOther, Double weight) {"},{"lineNumber":1378,"author":{"gitId":"-"},"content":" if (hasOther) {"},{"lineNumber":1379,"author":{"gitId":"-"},"content":" assertTrue(getOtherOptionCheckbox(questionNum).isSelected());"},{"lineNumber":1380,"author":{"gitId":"-"},"content":" if (weight \u003e 0) {"},{"lineNumber":1381,"author":{"gitId":"-"},"content":" String otherWeight \u003d getOtherWeightInput(questionNum).getAttribute(\"value\");"},{"lineNumber":1382,"author":{"gitId":"-"},"content":" assertEquals(getDoubleString(weight), otherWeight);"},{"lineNumber":1383,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1384,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1385,"author":{"gitId":"-"},"content":" assertFalse(getOtherOptionCheckbox(questionNum).isSelected());"},{"lineNumber":1386,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1387,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1388,"author":{"gitId":"-"},"content":""},{"lineNumber":1389,"author":{"gitId":"-"},"content":" private void inputMcqDetails(int questionNum, FeedbackMcqQuestionDetails questionDetails) {"},{"lineNumber":1390,"author":{"gitId":"-"},"content":" if (inputGenerateOptions(questionNum, questionDetails.getGenerateOptionsFor())) {"},{"lineNumber":1391,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":1392,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1393,"author":{"gitId":"-"},"content":""},{"lineNumber":1394,"author":{"gitId":"-"},"content":" inputOptions(questionNum, questionDetails.getMcqChoices());"},{"lineNumber":1395,"author":{"gitId":"-"},"content":" inputOptionWeights(questionNum, questionDetails.isHasAssignedWeights(), questionDetails.getMcqWeights());"},{"lineNumber":1396,"author":{"gitId":"-"},"content":" inputOtherChoice(questionNum, questionDetails.isOtherEnabled(), questionDetails.getMcqOtherWeight());"},{"lineNumber":1397,"author":{"gitId":"-"},"content":" inputDropdownEnabledChoice(questionNum, questionDetails.isQuestionDropdownEnabled());"},{"lineNumber":1398,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1399,"author":{"gitId":"-"},"content":""},{"lineNumber":1400,"author":{"gitId":"-"},"content":" private boolean inputGenerateOptions(int questionNum, FeedbackParticipantType participantType) {"},{"lineNumber":1401,"author":{"gitId":"-"},"content":" if (!participantType.equals(FeedbackParticipantType.NONE)) {"},{"lineNumber":1402,"author":{"gitId":"-"},"content":" markOptionAsSelected(getGenerateOptionsCheckbox(questionNum));"},{"lineNumber":1403,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(getGenerateOptionsDropdown(questionNum),"},{"lineNumber":1404,"author":{"gitId":"-"},"content":" getGeneratedOptionString(participantType));"},{"lineNumber":1405,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":1406,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":1407,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1408,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getGenerateOptionsCheckbox(questionNum));"},{"lineNumber":1409,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":1410,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1411,"author":{"gitId":"-"},"content":""},{"lineNumber":1412,"author":{"gitId":"-"},"content":" private void inputOptions(int questionNum, List\u003cString\u003e options) {"},{"lineNumber":1413,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e inputs \u003d getOptionInputs(questionNum);"},{"lineNumber":1414,"author":{"gitId":"-"},"content":" int numInputsNeeded \u003d options.size() - inputs.size();"},{"lineNumber":1415,"author":{"gitId":"-"},"content":" if (numInputsNeeded \u003e 0) {"},{"lineNumber":1416,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c numInputsNeeded; i++) {"},{"lineNumber":1417,"author":{"gitId":"-"},"content":" click(getQuestionForm(questionNum).findElement(By.id(\"btn-add-option\")));"},{"lineNumber":1418,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1419,"author":{"gitId":"-"},"content":" inputs \u003d getOptionInputs(questionNum);"},{"lineNumber":1420,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1421,"author":{"gitId":"-"},"content":" if (numInputsNeeded \u003c 0) {"},{"lineNumber":1422,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c -numInputsNeeded; i++) {"},{"lineNumber":1423,"author":{"gitId":"-"},"content":" click(getOptionsSection(questionNum).findElement(By.tagName(\"button\")));"},{"lineNumber":1424,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1425,"author":{"gitId":"-"},"content":" inputs \u003d getOptionInputs(questionNum);"},{"lineNumber":1426,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1427,"author":{"gitId":"-"},"content":""},{"lineNumber":1428,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c options.size(); i++) {"},{"lineNumber":1429,"author":{"gitId":"-"},"content":" fillTextBox(inputs.get(i), options.get(i));"},{"lineNumber":1430,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1431,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1432,"author":{"gitId":"-"},"content":""},{"lineNumber":1433,"author":{"gitId":"-"},"content":" private void inputOptionWeights(int questionNum, boolean hasWeights, List\u003cDouble\u003e weights) {"},{"lineNumber":1434,"author":{"gitId":"-"},"content":" if (hasWeights) {"},{"lineNumber":1435,"author":{"gitId":"-"},"content":" markOptionAsSelected(getWeightCheckbox(questionNum));"},{"lineNumber":1436,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e weightInputs \u003d getOptionWeightInputs(questionNum);"},{"lineNumber":1437,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c weights.size(); i++) {"},{"lineNumber":1438,"author":{"gitId":"-"},"content":" fillTextBox(weightInputs.get(i), getDoubleString(weights.get(i)));"},{"lineNumber":1439,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1440,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1441,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getWeightCheckbox(questionNum));"},{"lineNumber":1442,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1443,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1444,"author":{"gitId":"-"},"content":""},{"lineNumber":1445,"author":{"gitId":"-"},"content":" private void inputOtherChoice(int questionNum, boolean hasOther, Double otherWeight) {"},{"lineNumber":1446,"author":{"gitId":"-"},"content":" if (hasOther) {"},{"lineNumber":1447,"author":{"gitId":"-"},"content":" markOptionAsSelected(getOtherOptionCheckbox(questionNum));"},{"lineNumber":1448,"author":{"gitId":"-"},"content":" if (otherWeight \u003e 0) {"},{"lineNumber":1449,"author":{"gitId":"-"},"content":" fillTextBox(getOtherWeightInput(questionNum), getDoubleString(otherWeight));"},{"lineNumber":1450,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1451,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1452,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getOtherOptionCheckbox(questionNum));"},{"lineNumber":1453,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1454,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1455,"author":{"gitId":"-"},"content":""},{"lineNumber":1456,"author":{"gitId":"-"},"content":" private void inputDropdownEnabledChoice(int questionNum, boolean hasOther) {"},{"lineNumber":1457,"author":{"gitId":"-"},"content":" if (hasOther) {"},{"lineNumber":1458,"author":{"gitId":"-"},"content":" markOptionAsSelected(getQuestionDropdownCheckbox(questionNum));"},{"lineNumber":1459,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1460,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getQuestionDropdownCheckbox(questionNum));"},{"lineNumber":1461,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1462,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1463,"author":{"gitId":"-"},"content":""},{"lineNumber":1464,"author":{"gitId":"-"},"content":" private WebElement getMaxOptionsCheckbox(int questionNum) {"},{"lineNumber":1465,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"max-options-checkbox\"));"},{"lineNumber":1466,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1467,"author":{"gitId":"-"},"content":""},{"lineNumber":1468,"author":{"gitId":"-"},"content":" private WebElement getMaxOptionsInput(int questionNum) {"},{"lineNumber":1469,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"max-options\"));"},{"lineNumber":1470,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1471,"author":{"gitId":"-"},"content":""},{"lineNumber":1472,"author":{"gitId":"-"},"content":" private WebElement getMinOptionsCheckbox(int questionNum) {"},{"lineNumber":1473,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"min-options-checkbox\"));"},{"lineNumber":1474,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1475,"author":{"gitId":"-"},"content":""},{"lineNumber":1476,"author":{"gitId":"-"},"content":" private WebElement getMinOptionsInput(int questionNum) {"},{"lineNumber":1477,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"min-options\"));"},{"lineNumber":1478,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1479,"author":{"gitId":"-"},"content":""},{"lineNumber":1480,"author":{"gitId":"-"},"content":" private void verifyMaxOptions(int questionNum, int maxOptions) {"},{"lineNumber":1481,"author":{"gitId":"-"},"content":" if (maxOptions \u003d\u003d Const.POINTS_NO_VALUE) {"},{"lineNumber":1482,"author":{"gitId":"-"},"content":" assertFalse(getMaxOptionsCheckbox(questionNum).isSelected());"},{"lineNumber":1483,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1484,"author":{"gitId":"-"},"content":" assertTrue(getMaxOptionsCheckbox(questionNum).isSelected());"},{"lineNumber":1485,"author":{"gitId":"-"},"content":" assertEquals(getMaxOptionsInput(questionNum).getAttribute(\"value\"),"},{"lineNumber":1486,"author":{"gitId":"-"},"content":" Integer.toString(maxOptions));"},{"lineNumber":1487,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1488,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1489,"author":{"gitId":"-"},"content":""},{"lineNumber":1490,"author":{"gitId":"-"},"content":" private void verifyMinOptions(int questionNum, int minOptions) {"},{"lineNumber":1491,"author":{"gitId":"-"},"content":" if (minOptions \u003d\u003d Const.POINTS_NO_VALUE) {"},{"lineNumber":1492,"author":{"gitId":"-"},"content":" assertFalse(getMinOptionsCheckbox(questionNum).isSelected());"},{"lineNumber":1493,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1494,"author":{"gitId":"-"},"content":" assertTrue(getMinOptionsCheckbox(questionNum).isSelected());"},{"lineNumber":1495,"author":{"gitId":"-"},"content":" assertEquals(getMinOptionsInput(questionNum).getAttribute(\"value\"),"},{"lineNumber":1496,"author":{"gitId":"-"},"content":" Integer.toString(minOptions));"},{"lineNumber":1497,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1498,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1499,"author":{"gitId":"-"},"content":""},{"lineNumber":1500,"author":{"gitId":"-"},"content":" private void inputMsqDetails(int questionNum, FeedbackMsqQuestionDetails questionDetails) {"},{"lineNumber":1501,"author":{"gitId":"-"},"content":" if (inputGenerateOptions(questionNum, questionDetails.getGenerateOptionsFor())) {"},{"lineNumber":1502,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":1503,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1504,"author":{"gitId":"-"},"content":""},{"lineNumber":1505,"author":{"gitId":"-"},"content":" inputOptions(questionNum, questionDetails.getMsqChoices());"},{"lineNumber":1506,"author":{"gitId":"-"},"content":" inputOptionWeights(questionNum, questionDetails.isHasAssignedWeights(), questionDetails.getMsqWeights());"},{"lineNumber":1507,"author":{"gitId":"-"},"content":" inputOtherChoice(questionNum, questionDetails.isOtherEnabled(), questionDetails.getMsqOtherWeight());"},{"lineNumber":1508,"author":{"gitId":"-"},"content":" inputMaxOptions(questionNum, questionDetails.getMaxSelectableChoices());"},{"lineNumber":1509,"author":{"gitId":"-"},"content":" inputMinOptions(questionNum, questionDetails.getMinSelectableChoices());"},{"lineNumber":1510,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1511,"author":{"gitId":"-"},"content":""},{"lineNumber":1512,"author":{"gitId":"-"},"content":" private void inputMaxOptions(int questionNum, int maxOptions) {"},{"lineNumber":1513,"author":{"gitId":"-"},"content":" if (maxOptions \u003d\u003d Const.POINTS_NO_VALUE) {"},{"lineNumber":1514,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getMaxOptionsCheckbox(questionNum));"},{"lineNumber":1515,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1516,"author":{"gitId":"-"},"content":" markOptionAsSelected(getMaxOptionsCheckbox(questionNum));"},{"lineNumber":1517,"author":{"gitId":"-"},"content":" fillTextBox(getMaxOptionsInput(questionNum), Integer.toString(maxOptions));"},{"lineNumber":1518,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1519,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1520,"author":{"gitId":"-"},"content":""},{"lineNumber":1521,"author":{"gitId":"-"},"content":" private void inputMinOptions(int questionNum, int minOptions) {"},{"lineNumber":1522,"author":{"gitId":"-"},"content":" if (minOptions \u003d\u003d Const.POINTS_NO_VALUE) {"},{"lineNumber":1523,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getMinOptionsCheckbox(questionNum));"},{"lineNumber":1524,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1525,"author":{"gitId":"-"},"content":" markOptionAsSelected(getMinOptionsCheckbox(questionNum));"},{"lineNumber":1526,"author":{"gitId":"-"},"content":" fillTextBox(getMinOptionsInput(questionNum), Integer.toString(minOptions));"},{"lineNumber":1527,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1528,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1529,"author":{"gitId":"-"},"content":""},{"lineNumber":1530,"author":{"gitId":"-"},"content":" private WebElement getMinNumscaleInput(int questionNum) {"},{"lineNumber":1531,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"min-value\"));"},{"lineNumber":1532,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1533,"author":{"gitId":"-"},"content":""},{"lineNumber":1534,"author":{"gitId":"-"},"content":" private WebElement getMaxNumscaleInput(int questionNum) {"},{"lineNumber":1535,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"max-value\"));"},{"lineNumber":1536,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1537,"author":{"gitId":"-"},"content":""},{"lineNumber":1538,"author":{"gitId":"-"},"content":" private WebElement getNumScaleIncrementInput(int questionNum) {"},{"lineNumber":1539,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"increment-value\"));"},{"lineNumber":1540,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1541,"author":{"gitId":"-"},"content":""},{"lineNumber":1542,"author":{"gitId":"-"},"content":" private void inputNumScaleDetails(int questionNum, FeedbackNumericalScaleQuestionDetails questionDetails) {"},{"lineNumber":1543,"author":{"gitId":"-"},"content":" inputNumScaleValue(getMinNumscaleInput(questionNum), Integer.toString(questionDetails.getMinScale()));"},{"lineNumber":1544,"author":{"gitId":"-"},"content":" inputNumScaleValue(getNumScaleIncrementInput(questionNum), getDoubleString(questionDetails.getStep()));"},{"lineNumber":1545,"author":{"gitId":"-"},"content":" inputNumScaleValue(getMaxNumscaleInput(questionNum), Integer.toString(questionDetails.getMaxScale()));"},{"lineNumber":1546,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1547,"author":{"gitId":"-"},"content":""},{"lineNumber":1548,"author":{"gitId":"-"},"content":" private void inputNumScaleValue(WebElement input, String value) {"},{"lineNumber":1549,"author":{"gitId":"-"},"content":" input.clear();"},{"lineNumber":1550,"author":{"gitId":"-"},"content":" input.sendKeys(value);"},{"lineNumber":1551,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1552,"author":{"gitId":"-"},"content":""},{"lineNumber":1553,"author":{"gitId":"-"},"content":" private WebElement getConstSumTotalPointsRadioBtn(int questionNum) {"},{"lineNumber":1554,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"total-points-radio\"));"},{"lineNumber":1555,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1556,"author":{"gitId":"-"},"content":""},{"lineNumber":1557,"author":{"gitId":"-"},"content":" private WebElement getConstSumTotalPointsInput(int questionNum) {"},{"lineNumber":1558,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"total-points\"));"},{"lineNumber":1559,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1560,"author":{"gitId":"-"},"content":""},{"lineNumber":1561,"author":{"gitId":"-"},"content":" private WebElement getConstSumPerOptionPointsRadioBtn(int questionNum) {"},{"lineNumber":1562,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"per-option-points-radio\"));"},{"lineNumber":1563,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1564,"author":{"gitId":"-"},"content":""},{"lineNumber":1565,"author":{"gitId":"-"},"content":" private WebElement getConstSumPerOptionPointsInput(int questionNum) {"},{"lineNumber":1566,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"per-option-points\"));"},{"lineNumber":1567,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1568,"author":{"gitId":"-"},"content":""},{"lineNumber":1569,"author":{"gitId":"-"},"content":" private WebElement getConstSumUnevenDistributionCheckbox(int questionNum) {"},{"lineNumber":1570,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"uneven-distribution-checkbox\"));"},{"lineNumber":1571,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1572,"author":{"gitId":"-"},"content":""},{"lineNumber":1573,"author":{"gitId":"-"},"content":" private WebElement getConstSumUnevenDistributionDropdown(int questionNum) {"},{"lineNumber":1574,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"uneven-distribution-dropdown\"));"},{"lineNumber":1575,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1576,"author":{"gitId":"-"},"content":""},{"lineNumber":1577,"author":{"gitId":"-"},"content":" private void inputConstSumDetails(int questionNum, FeedbackConstantSumQuestionDetails questionDetails) {"},{"lineNumber":1578,"author":{"gitId":"-"},"content":" if (!questionDetails.isDistributeToRecipients()) {"},{"lineNumber":1579,"author":{"gitId":"-"},"content":" inputOptions(questionNum, questionDetails.getConstSumOptions());"},{"lineNumber":1580,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1581,"author":{"gitId":"-"},"content":" if (questionDetails.isPointsPerOption()) {"},{"lineNumber":1582,"author":{"gitId":"-"},"content":" click(getConstSumPerOptionPointsRadioBtn(questionNum));"},{"lineNumber":1583,"author":{"gitId":"-"},"content":" fillTextBox(getConstSumPerOptionPointsInput(questionNum), Integer.toString(questionDetails.getPoints()));"},{"lineNumber":1584,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1585,"author":{"gitId":"-"},"content":" click(getConstSumTotalPointsRadioBtn(questionNum));"},{"lineNumber":1586,"author":{"gitId":"-"},"content":" fillTextBox(getConstSumTotalPointsInput(questionNum), Integer.toString(questionDetails.getPoints()));"},{"lineNumber":1587,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1588,"author":{"gitId":"-"},"content":" String distributeFor \u003d questionDetails.getDistributePointsFor();"},{"lineNumber":1589,"author":{"gitId":"-"},"content":" if (questionDetails.isForceUnevenDistribution()) {"},{"lineNumber":1590,"author":{"gitId":"-"},"content":" markOptionAsSelected(getConstSumUnevenDistributionCheckbox(questionNum));"},{"lineNumber":1591,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(getConstSumUnevenDistributionDropdown(questionNum),"},{"lineNumber":1592,"author":{"gitId":"-"},"content":" \"All options\".equals(distributeFor) ? \"Every option\" : distributeFor);"},{"lineNumber":1593,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1594,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getConstSumUnevenDistributionCheckbox(questionNum));"},{"lineNumber":1595,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1596,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1597,"author":{"gitId":"-"},"content":""},{"lineNumber":1598,"author":{"gitId":"-"},"content":" private WebElement getZeroSumCheckbox(int questionNum) {"},{"lineNumber":1599,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"zero-sum-checkbox\"));"},{"lineNumber":1600,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1601,"author":{"gitId":"-"},"content":""},{"lineNumber":1602,"author":{"gitId":"-"},"content":" private WebElement getAllowNotSureContributionCheckbox(int questionNum) {"},{"lineNumber":1603,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"not-sure-checkbox\"));"},{"lineNumber":1604,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1605,"author":{"gitId":"-"},"content":""},{"lineNumber":1606,"author":{"gitId":"-"},"content":" private void inputContributionDetails(int questionNum, FeedbackContributionQuestionDetails questionDetails) {"},{"lineNumber":1607,"author":{"gitId":"-"},"content":" if (questionDetails.isZeroSum()) {"},{"lineNumber":1608,"author":{"gitId":"-"},"content":" markOptionAsSelected(getZeroSumCheckbox(questionNum));"},{"lineNumber":1609,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1610,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getZeroSumCheckbox(questionNum));"},{"lineNumber":1611,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1612,"author":{"gitId":"-"},"content":" if (questionDetails.isNotSureAllowed()) {"},{"lineNumber":1613,"author":{"gitId":"-"},"content":" markOptionAsSelected(getAllowNotSureContributionCheckbox(questionNum));"},{"lineNumber":1614,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1615,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getAllowNotSureContributionCheckbox(questionNum));"},{"lineNumber":1616,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1617,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1618,"author":{"gitId":"-"},"content":""},{"lineNumber":1619,"author":{"gitId":"-"},"content":" private WebElement getRubricRow(int questionNum, int rowNumber) {"},{"lineNumber":1620,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElements(By.cssSelector(\"tm-rubric-question-edit-details-form tr\"))"},{"lineNumber":1621,"author":{"gitId":"-"},"content":" .get(rowNumber - 1);"},{"lineNumber":1622,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1623,"author":{"gitId":"-"},"content":""},{"lineNumber":1624,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getRubricChoiceInputs(int questionNum) {"},{"lineNumber":1625,"author":{"gitId":"-"},"content":" return getRubricRow(questionNum, 1).findElements(By.tagName(\"input\"));"},{"lineNumber":1626,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1627,"author":{"gitId":"-"},"content":""},{"lineNumber":1628,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getRubricTextareas(int questionNum, int rowNum) {"},{"lineNumber":1629,"author":{"gitId":"-"},"content":" return getRubricRow(questionNum, rowNum).findElements(By.tagName(\"textarea\"));"},{"lineNumber":1630,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1631,"author":{"gitId":"-"},"content":""},{"lineNumber":1632,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getRubricWeights(int questionNum, int rowNum) {"},{"lineNumber":1633,"author":{"gitId":"-"},"content":" return getRubricRow(questionNum, rowNum).findElements(By.tagName(\"input\"));"},{"lineNumber":1634,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1635,"author":{"gitId":"-"},"content":""},{"lineNumber":1636,"author":{"gitId":"-"},"content":" private WebElement getRubricDeleteSubQnBtn(int questionNum, int rowNum) {"},{"lineNumber":1637,"author":{"gitId":"-"},"content":" return getRubricRow(questionNum, rowNum).findElement(By.id(\"btn-delete-subquestion\"));"},{"lineNumber":1638,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1639,"author":{"gitId":"-"},"content":""},{"lineNumber":1640,"author":{"gitId":"-"},"content":" private WebElement getRubricDeleteChoiceBtn(int questionNum, int colNum) {"},{"lineNumber":1641,"author":{"gitId":"-"},"content":" return getRubricRow(questionNum, getNumRubricRows(questionNum)).findElements(By.id(\"btn-delete-choice\")).get(colNum);"},{"lineNumber":1642,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1643,"author":{"gitId":"-"},"content":""},{"lineNumber":1644,"author":{"gitId":"-"},"content":" private int getNumRubricRows(int questionNum) {"},{"lineNumber":1645,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElements(By.cssSelector(\"#rubric-table tr\")).size();"},{"lineNumber":1646,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1647,"author":{"gitId":"-"},"content":""},{"lineNumber":1648,"author":{"gitId":"-"},"content":" private int getNumRubricCols(int questionNum) {"},{"lineNumber":1649,"author":{"gitId":"-"},"content":" WebElement row \u003d getRubricRow(questionNum, 1);"},{"lineNumber":1650,"author":{"gitId":"-"},"content":" return row.findElements(By.tagName(\"td\")).size() + row.findElements(By.tagName(\"th\")).size();"},{"lineNumber":1651,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1652,"author":{"gitId":"-"},"content":""},{"lineNumber":1653,"author":{"gitId":"-"},"content":" private void inputRubricDetails(int questionNum, FeedbackRubricQuestionDetails questionDetails) {"},{"lineNumber":1654,"author":{"gitId":"-"},"content":" int numSubQn \u003d questionDetails.getNumOfRubricSubQuestions();"},{"lineNumber":1655,"author":{"gitId":"-"},"content":" int numChoices \u003d questionDetails.getNumOfRubricChoices();"},{"lineNumber":1656,"author":{"gitId":"-"},"content":" adjustNumRubricFields(questionNum, numSubQn, numChoices);"},{"lineNumber":1657,"author":{"gitId":"-"},"content":""},{"lineNumber":1658,"author":{"gitId":"-"},"content":" List\u003cString\u003e choices \u003d questionDetails.getRubricChoices();"},{"lineNumber":1659,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c numChoices; i++) {"},{"lineNumber":1660,"author":{"gitId":"-"},"content":" fillTextBox(getRubricChoiceInputs(questionNum).get(i), choices.get(i));"},{"lineNumber":1661,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1662,"author":{"gitId":"-"},"content":""},{"lineNumber":1663,"author":{"gitId":"-"},"content":" List\u003cString\u003e subQuestions \u003d questionDetails.getRubricSubQuestions();"},{"lineNumber":1664,"author":{"gitId":"-"},"content":" List\u003cList\u003cString\u003e\u003e descriptions \u003d questionDetails.getRubricDescriptions();"},{"lineNumber":1665,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c numSubQn; i++) {"},{"lineNumber":1666,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e textAreas \u003d getRubricTextareas(questionNum, i + 2);"},{"lineNumber":1667,"author":{"gitId":"-"},"content":" fillTextBox(textAreas.get(0), subQuestions.get(i));"},{"lineNumber":1668,"author":{"gitId":"-"},"content":" for (int j \u003d 0; j \u003c numChoices; j++) {"},{"lineNumber":1669,"author":{"gitId":"-"},"content":" fillTextBox(textAreas.get(j + 1), descriptions.get(i).get(j));"},{"lineNumber":1670,"author":{"gitId":"-"},"content":" if (descriptions.get(i).get(j).isEmpty()) {"},{"lineNumber":1671,"author":{"gitId":"-"},"content":" // using clear does not send the required event"},{"lineNumber":1672,"author":{"gitId":"-"},"content":" // as a workaround, after clearing without event, enter a random character and delete it"},{"lineNumber":1673,"author":{"gitId":"-"},"content":" textAreas.get(j + 1).sendKeys(\"a\");"},{"lineNumber":1674,"author":{"gitId":"-"},"content":" textAreas.get(j + 1).sendKeys(Keys.BACK_SPACE);"},{"lineNumber":1675,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1676,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1677,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1678,"author":{"gitId":"-"},"content":""},{"lineNumber":1679,"author":{"gitId":"-"},"content":" if (questionDetails.isHasAssignedWeights()) {"},{"lineNumber":1680,"author":{"gitId":"-"},"content":" markOptionAsSelected(getWeightCheckbox(questionNum));"},{"lineNumber":1681,"author":{"gitId":"-"},"content":" List\u003cList\u003cDouble\u003e\u003e weights \u003d questionDetails.getRubricWeights();"},{"lineNumber":1682,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c numSubQn; i++) {"},{"lineNumber":1683,"author":{"gitId":"-"},"content":" for (int j \u003d 0; j \u003c numChoices; j++) {"},{"lineNumber":1684,"author":{"gitId":"-"},"content":" fillTextBox(getRubricWeights(questionNum, i + 2).get(j), getDoubleString(weights.get(i).get(j)));"},{"lineNumber":1685,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1686,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1687,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1688,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getWeightCheckbox(questionNum));"},{"lineNumber":1689,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1690,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1691,"author":{"gitId":"-"},"content":""},{"lineNumber":1692,"author":{"gitId":"-"},"content":" private void adjustNumRubricFields(int questionNum, int numSubQn, int numChoices) {"},{"lineNumber":1693,"author":{"gitId":"-"},"content":" int numSubQnsNeeded \u003d numSubQn - (getNumRubricRows(questionNum) - 2);"},{"lineNumber":1694,"author":{"gitId":"-"},"content":" int numChoicesNeeded \u003d numChoices - (getNumRubricCols(questionNum) - 1);"},{"lineNumber":1695,"author":{"gitId":"-"},"content":" if (numSubQnsNeeded \u003e 0) {"},{"lineNumber":1696,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c numSubQnsNeeded; i++) {"},{"lineNumber":1697,"author":{"gitId":"-"},"content":" click(getQuestionForm(questionNum).findElement(By.id(\"btn-add-row\")));"},{"lineNumber":1698,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1699,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1700,"author":{"gitId":"-"},"content":" if (numChoicesNeeded \u003e 0) {"},{"lineNumber":1701,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c numChoicesNeeded; i++) {"},{"lineNumber":1702,"author":{"gitId":"-"},"content":" click(getQuestionForm(questionNum).findElement(By.id(\"btn-add-col\")));"},{"lineNumber":1703,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1704,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1705,"author":{"gitId":"-"},"content":" if (numSubQnsNeeded \u003c 0) {"},{"lineNumber":1706,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c -numSubQnsNeeded; i++) {"},{"lineNumber":1707,"author":{"gitId":"-"},"content":" click(getRubricDeleteSubQnBtn(questionNum, 2));"},{"lineNumber":1708,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1709,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1710,"author":{"gitId":"-"},"content":" if (numChoicesNeeded \u003c 0) {"},{"lineNumber":1711,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c -numChoicesNeeded; i++) {"},{"lineNumber":1712,"author":{"gitId":"-"},"content":" clickAndConfirm(getRubricDeleteChoiceBtn(questionNum, 2));"},{"lineNumber":1713,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1714,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1715,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1716,"author":{"gitId":"-"},"content":""},{"lineNumber":1717,"author":{"gitId":"-"},"content":" private WebElement getAllowDuplicateRankCheckbox(int questionNum) {"},{"lineNumber":1718,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"duplicate-rank-checkbox\"));"},{"lineNumber":1719,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1720,"author":{"gitId":"-"},"content":""},{"lineNumber":1721,"author":{"gitId":"-"},"content":" private void inputRankDetails(int questionNum, FeedbackRankQuestionDetails questionDetails) {"},{"lineNumber":1722,"author":{"gitId":"-"},"content":" if (questionDetails instanceof FeedbackRankOptionsQuestionDetails) {"},{"lineNumber":1723,"author":{"gitId":"-"},"content":" FeedbackRankOptionsQuestionDetails optionDetails \u003d (FeedbackRankOptionsQuestionDetails) questionDetails;"},{"lineNumber":1724,"author":{"gitId":"-"},"content":" inputOptions(questionNum, optionDetails.getOptions());"},{"lineNumber":1725,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1726,"author":{"gitId":"-"},"content":" if (questionDetails.isAreDuplicatesAllowed()) {"},{"lineNumber":1727,"author":{"gitId":"-"},"content":" markOptionAsSelected(getAllowDuplicateRankCheckbox(questionNum));"},{"lineNumber":1728,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1729,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getAllowDuplicateRankCheckbox(questionNum));"},{"lineNumber":1730,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1731,"author":{"gitId":"-"},"content":" inputMaxOptions(questionNum, questionDetails.getMaxOptionsToBeRanked());"},{"lineNumber":1732,"author":{"gitId":"-"},"content":" inputMinOptions(questionNum, questionDetails.getMinOptionsToBeRanked());"},{"lineNumber":1733,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1734,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":5,"dishenggg":13,"mingyuanc":5,"-":1711}},{"path":"src/e2e/java/teammates/e2e/pageobjects/RequestPage.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.e2e.pageobjects;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import org.openqa.selenium.By;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import org.openqa.selenium.WebElement;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import org.openqa.selenium.support.FindBy;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":" * Page Object Model for account request form page."},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"public class RequestPage extends AppPage {"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":" @FindBy(id \u003d \"btn-am-instructor\")"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":" private WebElement amInstructorButton;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":" @FindBy(id \u003d \"name\")"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":" private WebElement nameBox;"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" @FindBy(id \u003d \"institution\")"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":" private WebElement institutionBox;"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":" @FindBy(id \u003d \"country\")"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" private WebElement countryBox;"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":" @FindBy(id \u003d \"email\")"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":" private WebElement emailBox;"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" @FindBy(id \u003d \"comments\")"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" private WebElement commentsBox;"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" @FindBy(id \u003d \"submit-button\")"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" private WebElement submitButton;"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" public RequestPage(Browser browser) {"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" super(browser);"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" protected boolean containsExpectedPageContents() {"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" return getPageTitle().contains(\"Request for an Instructor Account\");"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" public void clickAmInstructorButton() {"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" click(amInstructorButton);"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" waitForPageToLoad();"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" public void fillForm(String name, String institution, String country, String email, String comments) {"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" fillTextBox(nameBox, name);"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" fillTextBox(institutionBox, institution);"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" fillTextBox(countryBox, country);"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" fillTextBox(emailBox, email);"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" fillTextBox(commentsBox, comments);"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" public void clickSubmitFormButton() {"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" click(submitButton);"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" waitForPageToLoad();"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" public void verifySubmittedInfo(String name, String institution, String country, String email, String comments) {"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" WebElement table \u003d browser.driver.findElement(By.className(\"table\"));"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" String[][] expected \u003d {"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" { name },"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" { institution },"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" { country },"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" { email },"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" { comments },"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" verifyTableBodyValues(table, expected);"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":71}},{"path":"src/e2e/java/teammates/e2e/pageobjects/StudentHomePage.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.pageobjects;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertTrue;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.openqa.selenium.By;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.openqa.selenium.WebElement;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * Page Object Model for student home page."},{"lineNumber":12,"author":{"gitId":"-"},"content":" */"},{"lineNumber":13,"author":{"gitId":"-"},"content":"public class StudentHomePage extends AppPage {"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":" public StudentHomePage(Browser browser) {"},{"lineNumber":16,"author":{"gitId":"-"},"content":" super(browser);"},{"lineNumber":17,"author":{"gitId":"-"},"content":" }"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":20,"author":{"gitId":"-"},"content":" protected boolean containsExpectedPageContents() {"},{"lineNumber":21,"author":{"gitId":"-"},"content":" return \"Student Home\".equals(getPageTitle());"},{"lineNumber":22,"author":{"gitId":"-"},"content":" }"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getStudentHomeCoursePanels() {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" return browser.driver.findElements(By.cssSelector(\"div.card.bg-light\"));"},{"lineNumber":26,"author":{"gitId":"-"},"content":" }"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" public int getStudentHomeCoursePanelIndex(String courseName) {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e coursePanels \u003d getStudentHomeCoursePanels();"},{"lineNumber":30,"author":{"gitId":"-"},"content":" int coursePanelIndex \u003d -1;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c coursePanels.size(); i++) {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" if (coursePanels.get(i).getText().contains(courseName)) {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" coursePanelIndex \u003d i;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":" assertTrue(coursePanelIndex \u003e\u003d 0);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" return coursePanelIndex;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" }"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" public void verifyVisibleFeedbackSessionToStudents(String feedbackSessionName, int index) {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" assertTrue(getStudentHomeCoursePanels().get(index)"},{"lineNumber":42,"author":{"gitId":"-"},"content":" .findElement(By.cssSelector(\"div.table-responsive table.table tbody\")).getText()"},{"lineNumber":43,"author":{"gitId":"-"},"content":" .contains(feedbackSessionName));"},{"lineNumber":44,"author":{"gitId":"-"},"content":" }"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" public void clickCloseNotificationBannerButton() {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" WebElement closeNotifButton \u003d browser.driver.findElement(By.id(\"btn-close-notif\"));"},{"lineNumber":48,"author":{"gitId":"-"},"content":" waitForElementToBeClickable(closeNotifButton);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" click(closeNotifButton);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" waitUntilAnimationFinish();"},{"lineNumber":51,"author":{"gitId":"-"},"content":" }"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" public void clickMarkAsReadButton() {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" WebElement markNotifAsReadButton \u003d browser.driver.findElement(By.id(\"btn-mark-as-read\"));"},{"lineNumber":55,"author":{"gitId":"-"},"content":" waitForElementToBeClickable(markNotifAsReadButton);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" click(markNotifAsReadButton);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" waitUntilAnimationFinish();"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"yuanxi1"},"content":" public String getNotificationId() {"},{"lineNumber":61,"author":{"gitId":"yuanxi1"},"content":" WebElement notificationBanner \u003d browser.driver.findElement(By.id(\"notification-banner\"));"},{"lineNumber":62,"author":{"gitId":"yuanxi1"},"content":" return notificationBanner.getAttribute(\"data-testid\");"},{"lineNumber":63,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":64,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"yuanxi1":5,"-":60}},{"path":"src/it/java/teammates/it/sqllogic/core/AccountRequestsLogicIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.AccountRequestsLogic;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.AccountRequestsDb;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * SUT: {@link AccountRequestsLogic}."},{"lineNumber":19,"author":{"gitId":"-"},"content":" */"},{"lineNumber":20,"author":{"gitId":"-"},"content":"public class AccountRequestsLogicIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" private AccountRequestsLogic accountRequestsLogic \u003d AccountRequestsLogic.inst();"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":25,"author":{"gitId":"-"},"content":" public void testGetAccountRequest_nonExistentAccountRequest_returnsNull() {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" UUID id \u003d UUID.randomUUID();"},{"lineNumber":27,"author":{"gitId":"-"},"content":" AccountRequest actualAccountRequest \u003d accountRequestsLogic.getAccountRequest(id);"},{"lineNumber":28,"author":{"gitId":"-"},"content":" assertNull(actualAccountRequest);"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":32,"author":{"gitId":"-"},"content":" public void testGetAccountRequest_existingAccountRequest_getsSuccessfully() throws InvalidParametersException {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" AccountRequest expectedAccountRequest \u003d"},{"lineNumber":34,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":35,"author":{"gitId":"-"},"content":" UUID id \u003d expectedAccountRequest.getId();"},{"lineNumber":36,"author":{"gitId":"-"},"content":" accountRequestsLogic.createAccountRequest(expectedAccountRequest);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" AccountRequest actualAccountRequest \u003d accountRequestsLogic.getAccountRequest(id);"},{"lineNumber":38,"author":{"gitId":"-"},"content":" assertEquals(expectedAccountRequest, actualAccountRequest);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":42,"author":{"gitId":"-"},"content":" public void testResetAccountRequest()"},{"lineNumber":43,"author":{"gitId":"-"},"content":" throws EntityAlreadyExistsException, InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" ______TS(\"success: create account request and update registeredAt field\");"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" String name \u003d \"name lee\";"},{"lineNumber":48,"author":{"gitId":"-"},"content":" String email \u003d \"email@gmail.com\";"},{"lineNumber":49,"author":{"gitId":"-"},"content":" String institute \u003d \"institute\";"},{"lineNumber":50,"author":{"gitId":"-"},"content":" AccountRequestStatus status \u003d AccountRequestStatus.PENDING;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" String comments \u003d \"comments\";"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" AccountRequest toReset \u003d accountRequestsLogic.createAccountRequest(name, email, institute, status, comments);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" AccountRequestsDb accountRequestsDb \u003d AccountRequestsDb.inst();"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" toReset.setRegisteredAt(Instant.now());"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" UUID id \u003d toReset.getId();"},{"lineNumber":58,"author":{"gitId":"-"},"content":" toReset \u003d accountRequestsDb.getAccountRequest(id);"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" assertNotNull(toReset);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" assertNotNull(toReset.getRegisteredAt());"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" ______TS(\"success: reset account request that already exists\");"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" AccountRequest resetted \u003d accountRequestsLogic.resetAccountRequest(id);"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" assertNull(resetted.getRegisteredAt());"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" ______TS(\"success: test delete account request\");"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" accountRequestsLogic.deleteAccountRequest(toReset.getId());"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" assertNull(accountRequestsLogic.getAccountRequest(toReset.getId()));"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" ______TS(\"failure: reset account request that does not exist\");"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" () -\u003e accountRequestsLogic.resetAccountRequest(id));"},{"lineNumber":79,"author":{"gitId":"-"},"content":" }"},{"lineNumber":80,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":5,"-":75}},{"path":"src/it/java/teammates/it/sqllogic/core/AccountsLogicIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":8,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationStyle;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationTargetUser;"},{"lineNumber":13,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":17,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":18,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":19,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.StringHelper;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.AccountsLogic;"},{"lineNumber":22,"author":{"gitId":"yuanxi1"},"content":"import teammates.sqllogic.core.CoursesLogic;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.NotificationsLogic;"},{"lineNumber":24,"author":{"gitId":"yuanxi1"},"content":"import teammates.sqllogic.core.UsersLogic;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.AccountsDb;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":27,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":28,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.ReadNotification;"},{"lineNumber":31,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":32,"author":{"gitId":"yuanxi1"},"content":"import teammates.test.AssertHelper;"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":35,"author":{"gitId":"-"},"content":" * SUT: {@link AccountsLogic}."},{"lineNumber":36,"author":{"gitId":"-"},"content":" */"},{"lineNumber":37,"author":{"gitId":"-"},"content":"public class AccountsLogicIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" private AccountsLogic accountsLogic \u003d AccountsLogic.inst();"},{"lineNumber":40,"author":{"gitId":"-"},"content":" private NotificationsLogic notificationsLogic \u003d NotificationsLogic.inst();"},{"lineNumber":41,"author":{"gitId":"yuanxi1"},"content":" private UsersLogic usersLogic \u003d UsersLogic.inst();"},{"lineNumber":42,"author":{"gitId":"yuanxi1"},"content":" private CoursesLogic coursesLogic \u003d CoursesLogic.inst();"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" private AccountsDb accountsDb \u003d AccountsDb.inst();"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"yuanxi1"},"content":" private SqlDataBundle typicalDataBundle;"},{"lineNumber":47,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":48,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":49,"author":{"gitId":"yuanxi1"},"content":" @BeforeClass"},{"lineNumber":50,"author":{"gitId":"yuanxi1"},"content":" public void setupClass() {"},{"lineNumber":51,"author":{"gitId":"yuanxi1"},"content":" super.setupClass();"},{"lineNumber":52,"author":{"gitId":"yuanxi1"},"content":" typicalDataBundle \u003d getTypicalSqlDataBundle();"},{"lineNumber":53,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":54,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":55,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":56,"author":{"gitId":"yuanxi1"},"content":" @BeforeMethod"},{"lineNumber":57,"author":{"gitId":"yuanxi1"},"content":" protected void setUp() throws Exception {"},{"lineNumber":58,"author":{"gitId":"yuanxi1"},"content":" super.setUp();"},{"lineNumber":59,"author":{"gitId":"yuanxi1"},"content":" persistDataBundle(typicalDataBundle);"},{"lineNumber":60,"author":{"gitId":"yuanxi1"},"content":" HibernateUtil.flushSession();"},{"lineNumber":61,"author":{"gitId":"yuanxi1"},"content":" HibernateUtil.clearSession();"},{"lineNumber":62,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":63,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":65,"author":{"gitId":"-"},"content":" public void testUpdateReadNotifications()"},{"lineNumber":66,"author":{"gitId":"-"},"content":" throws EntityAlreadyExistsException, InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" ______TS(\"success: mark notification as read\");"},{"lineNumber":68,"author":{"gitId":"-"},"content":" Account account \u003d new Account(\"google-id\", \"name\", \"email@teammates.com\");"},{"lineNumber":69,"author":{"gitId":"-"},"content":" Notification notification \u003d new Notification(Instant.parse(\"2011-01-01T00:00:00Z\"),"},{"lineNumber":70,"author":{"gitId":"-"},"content":" Instant.parse(\"2099-01-01T00:00:00Z\"), NotificationStyle.DANGER, NotificationTargetUser.GENERAL,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" \"A deprecation note\", \"\u003cp\u003eDeprecation happens in three minutes\u003c/p\u003e\");"},{"lineNumber":72,"author":{"gitId":"-"},"content":" accountsDb.createAccount(account);"},{"lineNumber":73,"author":{"gitId":"-"},"content":" notificationsLogic.createNotification(notification);"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":76,"author":{"gitId":"-"},"content":" UUID notificationId \u003d notification.getId();"},{"lineNumber":77,"author":{"gitId":"-"},"content":" accountsLogic.updateReadNotifications(googleId, notificationId, notification.getEndTime());"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" Account actualAccount \u003d accountsDb.getAccountByGoogleId(googleId);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" List\u003cReadNotification\u003e accountReadNotifications \u003d actualAccount.getReadNotifications();"},{"lineNumber":81,"author":{"gitId":"-"},"content":" assertEquals(1, accountReadNotifications.size());"},{"lineNumber":82,"author":{"gitId":"-"},"content":" assertSame(actualAccount, accountReadNotifications.get(0).getAccount());"},{"lineNumber":83,"author":{"gitId":"-"},"content":" assertSame(notification, accountReadNotifications.get(0).getNotification());"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":86,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":87,"author":{"gitId":"yuanxi1"},"content":" public void testJoinCourseForStudent()"},{"lineNumber":88,"author":{"gitId":"yuanxi1"},"content":" throws EntityAlreadyExistsException, InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":89,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":90,"author":{"gitId":"yuanxi1"},"content":" Student student2YetToJoinCourse \u003d typicalDataBundle.students.get(\"student2YetToJoinCourse4\");"},{"lineNumber":91,"author":{"gitId":"yuanxi1"},"content":" Student student3YetToJoinCourse \u003d typicalDataBundle.students.get(\"student3YetToJoinCourse4\");"},{"lineNumber":92,"author":{"gitId":"yuanxi1"},"content":" Student studentInCourse \u003d typicalDataBundle.students.get(\"student1InCourse1\");"},{"lineNumber":93,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":94,"author":{"gitId":"yuanxi1"},"content":" String loggedInGoogleId \u003d \"AccLogicT.student.id\";"},{"lineNumber":95,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":96,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: wrong key\");"},{"lineNumber":97,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":98,"author":{"gitId":"yuanxi1"},"content":" String wrongKey \u003d StringHelper.encrypt(\"wrongkey\");"},{"lineNumber":99,"author":{"gitId":"yuanxi1"},"content":" EntityDoesNotExistException ednee \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":100,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForStudent(wrongKey, loggedInGoogleId));"},{"lineNumber":101,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"No student with given registration key: \" + wrongKey, ednee.getMessage());"},{"lineNumber":102,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":103,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: invalid parameters\");"},{"lineNumber":104,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":105,"author":{"gitId":"yuanxi1"},"content":" InvalidParametersException ipe \u003d assertThrows(InvalidParametersException.class,"},{"lineNumber":106,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForStudent(student2YetToJoinCourse.getRegKey(), \"wrong student\"));"},{"lineNumber":107,"author":{"gitId":"yuanxi1"},"content":" AssertHelper.assertContains(FieldValidator.REASON_INCORRECT_FORMAT, ipe.getMessage());"},{"lineNumber":108,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":109,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: googleID belongs to an existing student in the course\");"},{"lineNumber":110,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":111,"author":{"gitId":"yuanxi1"},"content":" EntityAlreadyExistsException eaee \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":112,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForStudent(student2YetToJoinCourse.getRegKey(),"},{"lineNumber":113,"author":{"gitId":"yuanxi1"},"content":" studentInCourse.getGoogleId()));"},{"lineNumber":114,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"Student has already joined course\", eaee.getMessage());"},{"lineNumber":115,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":116,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: with encryption and new account to be created\");"},{"lineNumber":117,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":118,"author":{"gitId":"yuanxi1"},"content":" accountsLogic.joinCourseForStudent(student2YetToJoinCourse.getRegKey(), loggedInGoogleId);"},{"lineNumber":119,"author":{"gitId":"yuanxi1"},"content":" Account accountCreated \u003d accountsLogic.getAccountForGoogleId(loggedInGoogleId);"},{"lineNumber":120,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":121,"author":{"gitId":"yuanxi1"},"content":" assertEquals(loggedInGoogleId, usersLogic.getStudentForEmail("},{"lineNumber":122,"author":{"gitId":"yuanxi1"},"content":" student2YetToJoinCourse.getCourseId(), student2YetToJoinCourse.getEmail()).getGoogleId());"},{"lineNumber":123,"author":{"gitId":"yuanxi1"},"content":" assertNotNull(accountCreated);"},{"lineNumber":124,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":125,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: student joined but account already exists\");"},{"lineNumber":126,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":127,"author":{"gitId":"yuanxi1"},"content":" String existingAccountId \u003d \"existingAccountId\";"},{"lineNumber":128,"author":{"gitId":"yuanxi1"},"content":" Account existingAccount \u003d new Account(existingAccountId, \"accountName\", student3YetToJoinCourse.getEmail());"},{"lineNumber":129,"author":{"gitId":"yuanxi1"},"content":" accountsDb.createAccount(existingAccount);"},{"lineNumber":130,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":131,"author":{"gitId":"yuanxi1"},"content":" accountsLogic.joinCourseForStudent(student3YetToJoinCourse.getRegKey(), existingAccountId);"},{"lineNumber":132,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":133,"author":{"gitId":"yuanxi1"},"content":" assertEquals(existingAccountId, usersLogic.getStudentForEmail("},{"lineNumber":134,"author":{"gitId":"yuanxi1"},"content":" student3YetToJoinCourse.getCourseId(), student3YetToJoinCourse.getEmail()).getGoogleId());"},{"lineNumber":135,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":136,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: already joined\");"},{"lineNumber":137,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":138,"author":{"gitId":"yuanxi1"},"content":" eaee \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":139,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForStudent(student2YetToJoinCourse.getRegKey(), loggedInGoogleId));"},{"lineNumber":140,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"Student has already joined course\", eaee.getMessage());"},{"lineNumber":141,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":142,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: course is deleted\");"},{"lineNumber":143,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":144,"author":{"gitId":"yuanxi1"},"content":" Course originalCourse \u003d usersLogic.getStudentForEmail("},{"lineNumber":145,"author":{"gitId":"yuanxi1"},"content":" student2YetToJoinCourse.getCourseId(), student2YetToJoinCourse.getEmail()).getCourse();"},{"lineNumber":146,"author":{"gitId":"yuanxi1"},"content":" coursesLogic.moveCourseToRecycleBin(originalCourse.getId());"},{"lineNumber":147,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":148,"author":{"gitId":"yuanxi1"},"content":" ednee \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":149,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForStudent(student2YetToJoinCourse.getRegKey(),"},{"lineNumber":150,"author":{"gitId":"yuanxi1"},"content":" loggedInGoogleId));"},{"lineNumber":151,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"The course you are trying to join has been deleted by an instructor\", ednee.getMessage());"},{"lineNumber":152,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":153,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":154,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":155,"author":{"gitId":"yuanxi1"},"content":" public void testJoinCourseForInstructor() throws Exception {"},{"lineNumber":156,"author":{"gitId":"yuanxi1"},"content":" String instructorIdAlreadyJoinedCourse \u003d \"instructor1\";"},{"lineNumber":157,"author":{"gitId":"yuanxi1"},"content":" Instructor instructor2YetToJoinCourse \u003d typicalDataBundle.instructors.get(\"instructor2YetToJoinCourse4\");"},{"lineNumber":158,"author":{"gitId":"yuanxi1"},"content":" Instructor instructor3YetToJoinCourse \u003d typicalDataBundle.instructors.get(\"instructor3YetToJoinCourse4\");"},{"lineNumber":159,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":160,"author":{"gitId":"yuanxi1"},"content":" String loggedInGoogleId \u003d \"AccLogicT.instr.id\";"},{"lineNumber":161,"author":{"gitId":"yuanxi1"},"content":" String[] key \u003d new String[] {"},{"lineNumber":162,"author":{"gitId":"yuanxi1"},"content":" getRegKeyForInstructor(instructor2YetToJoinCourse.getCourseId(), instructor2YetToJoinCourse.getEmail()),"},{"lineNumber":163,"author":{"gitId":"yuanxi1"},"content":" getRegKeyForInstructor(instructor2YetToJoinCourse.getCourseId(), instructor3YetToJoinCourse.getEmail()),"},{"lineNumber":164,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":165,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":166,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: googleID belongs to an existing instructor in the course\");"},{"lineNumber":167,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":168,"author":{"gitId":"yuanxi1"},"content":" EntityAlreadyExistsException eaee \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":169,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForInstructor("},{"lineNumber":170,"author":{"gitId":"yuanxi1"},"content":" key[0], instructorIdAlreadyJoinedCourse));"},{"lineNumber":171,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"Instructor has already joined course\", eaee.getMessage());"},{"lineNumber":172,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":173,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: instructor joined and new account be created\");"},{"lineNumber":174,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":175,"author":{"gitId":"yuanxi1"},"content":" accountsLogic.joinCourseForInstructor(key[0], loggedInGoogleId);"},{"lineNumber":176,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":177,"author":{"gitId":"yuanxi1"},"content":" Instructor joinedInstructor \u003d usersLogic.getInstructorForEmail("},{"lineNumber":178,"author":{"gitId":"yuanxi1"},"content":" instructor2YetToJoinCourse.getCourseId(), instructor2YetToJoinCourse.getEmail());"},{"lineNumber":179,"author":{"gitId":"yuanxi1"},"content":" assertEquals(loggedInGoogleId, joinedInstructor.getGoogleId());"},{"lineNumber":180,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":181,"author":{"gitId":"yuanxi1"},"content":" Account accountCreated \u003d accountsLogic.getAccountForGoogleId(loggedInGoogleId);"},{"lineNumber":182,"author":{"gitId":"yuanxi1"},"content":" assertNotNull(accountCreated);"},{"lineNumber":183,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":184,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: instructor joined but account already exists\");"},{"lineNumber":185,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":186,"author":{"gitId":"yuanxi1"},"content":" String existingAccountId \u003d \"existingAccountId\";"},{"lineNumber":187,"author":{"gitId":"yuanxi1"},"content":" Account existingAccount \u003d new Account(existingAccountId, \"accountName\", instructor3YetToJoinCourse.getEmail());"},{"lineNumber":188,"author":{"gitId":"yuanxi1"},"content":" accountsDb.createAccount(existingAccount);"},{"lineNumber":189,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":190,"author":{"gitId":"yuanxi1"},"content":" accountsLogic.joinCourseForInstructor(key[1], existingAccount.getGoogleId());"},{"lineNumber":191,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":192,"author":{"gitId":"yuanxi1"},"content":" joinedInstructor \u003d usersLogic.getInstructorForEmail("},{"lineNumber":193,"author":{"gitId":"yuanxi1"},"content":" instructor3YetToJoinCourse.getCourseId(), existingAccount.getEmail());"},{"lineNumber":194,"author":{"gitId":"yuanxi1"},"content":" assertEquals(existingAccountId, joinedInstructor.getGoogleId());"},{"lineNumber":195,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":196,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: instructor already joined\");"},{"lineNumber":197,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":198,"author":{"gitId":"yuanxi1"},"content":" eaee \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":199,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForInstructor(key[0], loggedInGoogleId));"},{"lineNumber":200,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"Instructor has already joined course\", eaee.getMessage());"},{"lineNumber":201,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":202,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: key belongs to a different user\");"},{"lineNumber":203,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":204,"author":{"gitId":"yuanxi1"},"content":" eaee \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":205,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForInstructor(key[0], \"otherUserId\"));"},{"lineNumber":206,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"Instructor has already joined course\", eaee.getMessage());"},{"lineNumber":207,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":208,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: invalid key\");"},{"lineNumber":209,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":210,"author":{"gitId":"yuanxi1"},"content":" String invalidKey \u003d StringHelper.encrypt(\"invalidKey\");"},{"lineNumber":211,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":212,"author":{"gitId":"yuanxi1"},"content":" EntityDoesNotExistException ednee \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":213,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForInstructor(invalidKey, loggedInGoogleId));"},{"lineNumber":214,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"No instructor with given registration key: \" + invalidKey,"},{"lineNumber":215,"author":{"gitId":"yuanxi1"},"content":" ednee.getMessage());"},{"lineNumber":216,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":217,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: course deleted\");"},{"lineNumber":218,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":219,"author":{"gitId":"yuanxi1"},"content":" Course originalCourse \u003d usersLogic.getInstructorForEmail("},{"lineNumber":220,"author":{"gitId":"yuanxi1"},"content":" instructor2YetToJoinCourse.getCourseId(), instructor2YetToJoinCourse.getEmail()).getCourse();"},{"lineNumber":221,"author":{"gitId":"yuanxi1"},"content":" coursesLogic.moveCourseToRecycleBin(originalCourse.getId());"},{"lineNumber":222,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":223,"author":{"gitId":"yuanxi1"},"content":" ednee \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":224,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForInstructor(instructor2YetToJoinCourse.getRegKey(),"},{"lineNumber":225,"author":{"gitId":"yuanxi1"},"content":" instructor2YetToJoinCourse.getGoogleId()));"},{"lineNumber":226,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"The course you are trying to join has been deleted by an instructor\", ednee.getMessage());"},{"lineNumber":227,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":228,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":229,"author":{"gitId":"yuanxi1"},"content":" private String getRegKeyForInstructor(String courseId, String email) {"},{"lineNumber":230,"author":{"gitId":"yuanxi1"},"content":" return usersLogic.getInstructorForEmail(courseId, email).getRegKey();"},{"lineNumber":231,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"yuanxi1":179,"-":53}},{"path":"src/it/java/teammates/it/sqllogic/core/FeedbackQuestionsLogicIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionDetails;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionType;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackTextQuestionDetails;"},{"lineNumber":16,"author":{"gitId":"marquestye"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.FeedbackQuestionsLogic;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackVisibilityType;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.ui.output.NumberOfEntitiesToGiveFeedbackToSetting;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.ui.request.FeedbackQuestionUpdateRequest;"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":29,"author":{"gitId":"-"},"content":" * SUT: {@link FeedbackQuestionsLogic}."},{"lineNumber":30,"author":{"gitId":"-"},"content":" */"},{"lineNumber":31,"author":{"gitId":"-"},"content":"public class FeedbackQuestionsLogicIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private FeedbackQuestionsLogic fqLogic \u003d FeedbackQuestionsLogic.inst();"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" private SqlDataBundle typicalDataBundle;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"-"},"content":" @BeforeClass"},{"lineNumber":39,"author":{"gitId":"-"},"content":" public void setupClass() {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" super.setupClass();"},{"lineNumber":41,"author":{"gitId":"-"},"content":" typicalDataBundle \u003d getTypicalSqlDataBundle();"},{"lineNumber":42,"author":{"gitId":"-"},"content":" }"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":45,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":46,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":48,"author":{"gitId":"-"},"content":" persistDataBundle(typicalDataBundle);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":50,"author":{"gitId":"-"},"content":" }"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":53,"author":{"gitId":"marquestye"},"content":" public void testCreateFeedbackQuestion() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d typicalDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":55,"author":{"gitId":"-"},"content":" FeedbackTextQuestionDetails newQuestionDetails \u003d new FeedbackTextQuestionDetails(\"New question text.\");"},{"lineNumber":56,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showTos \u003d new ArrayList\u003c\u003e();"},{"lineNumber":57,"author":{"gitId":"-"},"content":" showTos.add(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":58,"author":{"gitId":"-"},"content":" FeedbackQuestion newQuestion \u003d FeedbackQuestion.makeQuestion(fs, 6, \"This is a new text question\","},{"lineNumber":59,"author":{"gitId":"-"},"content":" FeedbackParticipantType.STUDENTS, FeedbackParticipantType.OWN_TEAM_MEMBERS, -100,"},{"lineNumber":60,"author":{"gitId":"-"},"content":" showTos, showTos, showTos, newQuestionDetails);"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" newQuestion \u003d fqLogic.createFeedbackQuestion(newQuestion);"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" FeedbackQuestion actualQuestion \u003d fqLogic.getFeedbackQuestion(newQuestion.getId());"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" verifyEquals(newQuestion, actualQuestion);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":70,"author":{"gitId":"-"},"content":" public void testGetFeedbackQuestionsForSession() {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d typicalDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":72,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d typicalDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":73,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d typicalDataBundle.feedbackQuestions.get(\"qn2InSession1InCourse1\");"},{"lineNumber":74,"author":{"gitId":"-"},"content":" FeedbackQuestion fq3 \u003d typicalDataBundle.feedbackQuestions.get(\"qn3InSession1InCourse1\");"},{"lineNumber":75,"author":{"gitId":"-"},"content":" FeedbackQuestion fq4 \u003d typicalDataBundle.feedbackQuestions.get(\"qn4InSession1InCourse1\");"},{"lineNumber":76,"author":{"gitId":"-"},"content":" FeedbackQuestion fq5 \u003d typicalDataBundle.feedbackQuestions.get(\"qn5InSession1InCourse1\");"},{"lineNumber":77,"author":{"gitId":"-"},"content":" FeedbackQuestion fq6 \u003d typicalDataBundle.feedbackQuestions.get(\"qn6InSession1InCourse1NoResponses\");"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e expectedQuestions \u003d List.of(fq1, fq2, fq3, fq4, fq5, fq6);"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e actualQuestions \u003d fqLogic.getFeedbackQuestionsForSession(fs);"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestions.size(), actualQuestions.size());"},{"lineNumber":84,"author":{"gitId":"-"},"content":" assertTrue(expectedQuestions.containsAll(actualQuestions));"},{"lineNumber":85,"author":{"gitId":"-"},"content":" }"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":88,"author":{"gitId":"-"},"content":" public void testUpdateFeedbackQuestionCascade() throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":89,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d typicalDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":90,"author":{"gitId":"-"},"content":" fq1.setDescription(\"New question description\");"},{"lineNumber":91,"author":{"gitId":"-"},"content":" FeedbackQuestionUpdateRequest updateRequest \u003d generateFeedbackQuestionUpdateRequest("},{"lineNumber":92,"author":{"gitId":"-"},"content":" fq1.getQuestionNumber(),"},{"lineNumber":93,"author":{"gitId":"-"},"content":" fq1.getDescription(),"},{"lineNumber":94,"author":{"gitId":"-"},"content":" fq1.getQuestionDetailsCopy(),"},{"lineNumber":95,"author":{"gitId":"-"},"content":" fq1.getQuestionDetailsCopy().getQuestionType(),"},{"lineNumber":96,"author":{"gitId":"-"},"content":" fq1.getGiverType(),"},{"lineNumber":97,"author":{"gitId":"-"},"content":" fq1.getRecipientType(),"},{"lineNumber":98,"author":{"gitId":"-"},"content":" fq1.getNumOfEntitiesToGiveFeedbackTo(),"},{"lineNumber":99,"author":{"gitId":"-"},"content":" fq1.getShowResponsesTo(),"},{"lineNumber":100,"author":{"gitId":"-"},"content":" fq1.getShowGiverNameTo(),"},{"lineNumber":101,"author":{"gitId":"-"},"content":" fq1.getShowRecipientNameTo()"},{"lineNumber":102,"author":{"gitId":"-"},"content":" );"},{"lineNumber":103,"author":{"gitId":"-"},"content":" updateRequest.setNumberOfEntitiesToGiveFeedbackToSetting(NumberOfEntitiesToGiveFeedbackToSetting.CUSTOM);"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" fqLogic.updateFeedbackQuestionCascade(fq1.getId(), updateRequest);"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" FeedbackQuestion actualFeedbackQuestion \u003d fqLogic.getFeedbackQuestion(fq1.getId());"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" verifyEquals(fq1, actualFeedbackQuestion);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" private FeedbackQuestionUpdateRequest generateFeedbackQuestionUpdateRequest("},{"lineNumber":113,"author":{"gitId":"-"},"content":" int questionNumber,"},{"lineNumber":114,"author":{"gitId":"-"},"content":" String questionDescription,"},{"lineNumber":115,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails questionDetails,"},{"lineNumber":116,"author":{"gitId":"-"},"content":" FeedbackQuestionType questionType,"},{"lineNumber":117,"author":{"gitId":"-"},"content":" FeedbackParticipantType giverType,"},{"lineNumber":118,"author":{"gitId":"-"},"content":" FeedbackParticipantType recipientType,"},{"lineNumber":119,"author":{"gitId":"-"},"content":" Integer customNumberOfEntitiesToGiveFeedbackTo,"},{"lineNumber":120,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showResponsesTo,"},{"lineNumber":121,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showGiverNameTo,"},{"lineNumber":122,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showRecipientNameTo"},{"lineNumber":123,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":124,"author":{"gitId":"-"},"content":" FeedbackQuestionUpdateRequest updateRequest \u003d new FeedbackQuestionUpdateRequest();"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" updateRequest.setQuestionNumber(questionNumber);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" updateRequest.setQuestionDescription(questionDescription);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" updateRequest.setQuestionDetails(questionDetails);"},{"lineNumber":129,"author":{"gitId":"-"},"content":" updateRequest.setQuestionType(questionType);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" updateRequest.setGiverType(giverType);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" updateRequest.setRecipientType(recipientType);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" updateRequest.setCustomNumberOfEntitiesToGiveFeedbackTo(customNumberOfEntitiesToGiveFeedbackTo);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" updateRequest.setShowResponsesTo(convertToFeedbackVisibilityType(showResponsesTo));"},{"lineNumber":134,"author":{"gitId":"-"},"content":" updateRequest.setShowGiverNameTo(convertToFeedbackVisibilityType(showGiverNameTo));"},{"lineNumber":135,"author":{"gitId":"-"},"content":" updateRequest.setShowRecipientNameTo(convertToFeedbackVisibilityType(showRecipientNameTo));"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" return updateRequest;"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" private List\u003cFeedbackVisibilityType\u003e convertToFeedbackVisibilityType("},{"lineNumber":141,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e feedbackParticipantTypes) {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" return feedbackParticipantTypes.stream().map(feedbackParticipantType -\u003e {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" switch (feedbackParticipantType) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":145,"author":{"gitId":"-"},"content":" return FeedbackVisibilityType.STUDENTS;"},{"lineNumber":146,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":147,"author":{"gitId":"-"},"content":" return FeedbackVisibilityType.INSTRUCTORS;"},{"lineNumber":148,"author":{"gitId":"-"},"content":" case RECEIVER:"},{"lineNumber":149,"author":{"gitId":"-"},"content":" return FeedbackVisibilityType.RECIPIENT;"},{"lineNumber":150,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":151,"author":{"gitId":"-"},"content":" return FeedbackVisibilityType.GIVER_TEAM_MEMBERS;"},{"lineNumber":152,"author":{"gitId":"-"},"content":" case RECEIVER_TEAM_MEMBERS:"},{"lineNumber":153,"author":{"gitId":"-"},"content":" return FeedbackVisibilityType.RECIPIENT_TEAM_MEMBERS;"},{"lineNumber":154,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":155,"author":{"gitId":"-"},"content":" assert false : \"Unknown feedbackParticipantType\" + feedbackParticipantType;"},{"lineNumber":156,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":157,"author":{"gitId":"-"},"content":" }"},{"lineNumber":158,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }).collect(Collectors.toList());"},{"lineNumber":160,"author":{"gitId":"-"},"content":" }"},{"lineNumber":161,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":2,"-":159}},{"path":"src/it/java/teammates/it/sqllogic/core/FeedbackSessionLogsLogicIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.it.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import teammates.sqllogic.core.FeedbackSessionLogsLogic;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link FeedbackSessionLogsLogic}."},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":"public class FeedbackSessionLogsLogicIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" private FeedbackSessionLogsLogic fslLogic \u003d FeedbackSessionLogsLogic.inst();"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" private SqlDataBundle typicalDataBundle;"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" @BeforeClass"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" public void setupClass() {"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" super.setupClass();"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" typicalDataBundle \u003d getTypicalSqlDataBundle();"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" @BeforeMethod"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" protected void setUp() throws Exception {"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" super.setUp();"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" persistDataBundle(typicalDataBundle);"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" HibernateUtil.flushSession();"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" HibernateUtil.clearSession();"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" public void test_createFeedbackSessionLog_success() {"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" Course course \u003d typicalDataBundle.courses.get(\"course1\");"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" FeedbackSession fs \u003d typicalDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" Student student \u003d typicalDataBundle.students.get(\"student1InCourse1\");"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" Instant timestamp \u003d Instant.now();"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog newLog1 \u003d new FeedbackSessionLog(student, fs, FeedbackSessionLogType.ACCESS, timestamp);"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog newLog2 \u003d new FeedbackSessionLog(student, fs, FeedbackSessionLogType.SUBMISSION, timestamp);"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog newLog3 \u003d new FeedbackSessionLog(student, fs, FeedbackSessionLogType.VIEW_RESULT, timestamp);"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e expected \u003d List.of(newLog1, newLog2, newLog3);"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" fslLogic.createFeedbackSessionLogs(expected);"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e actual \u003d fslLogic.getOrderedFeedbackSessionLogs(course.getId(), student.getId(),"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" fs.getId(), timestamp, timestamp.plusSeconds(1));"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" assertEquals(expected, actual);"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" public void test_getOrderedFeedbackSessionLogs_success() {"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" Instant startTime \u003d Instant.parse(\"2012-01-01T12:00:00Z\");"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" Instant endTime \u003d Instant.parse(\"2012-01-01T23:59:59Z\");"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" Course course \u003d typicalDataBundle.courses.get(\"course1\");"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" Student student1 \u003d typicalDataBundle.students.get(\"student1InCourse1\");"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" FeedbackSession fs1 \u003d typicalDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student1Session1Log1 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student1Session1Log1\");"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student1Session2Log1 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student1Session2Log1\");"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student1Session2Log2 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student1Session2Log2\");"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student2Session1Log1 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student2Session1Log1\");"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student2Session1Log2 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student2Session1Log2\");"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Return logs belonging to a course in time range\");"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e expectedLogs \u003d List.of("},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":" student1Session1Log1,"},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" student1Session2Log1,"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" student1Session2Log2,"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" student2Session1Log1,"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" student2Session1Log2);"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e actualLogs \u003d fslLogic.getOrderedFeedbackSessionLogs(course.getId(), null, null,"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" startTime, endTime);"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Return logs belonging to a student in a course in time range\");"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":" expectedLogs \u003d List.of("},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" student1Session1Log1,"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" student1Session2Log1,"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" student1Session2Log2);"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" actualLogs \u003d fslLogic.getOrderedFeedbackSessionLogs(course.getId(), student1.getId(), null, startTime,"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" endTime);"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Return logs belonging to a feedback session in time range\");"},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" expectedLogs \u003d List.of("},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":" student1Session1Log1,"},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" student2Session1Log1,"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":" student2Session1Log2);"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":" actualLogs \u003d fslLogic.getOrderedFeedbackSessionLogs(course.getId(), null, fs1.getId(), startTime, endTime);"},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Return logs belonging to a student in a feedback session in time range\");"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":" expectedLogs \u003d List.of(student1Session1Log1);"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" actualLogs \u003d fslLogic.getOrderedFeedbackSessionLogs(course.getId(), student1.getId(), fs1.getId(),"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" startTime,"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" endTime);"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" ______TS(\"No logs in time range, return empty list\");"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" expectedLogs \u003d new ArrayList\u003c\u003e();"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" actualLogs \u003d fslLogic.getOrderedFeedbackSessionLogs(course.getId(), null, null, endTime.plusSeconds(3600),"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" endTime.plusSeconds(7200));"},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":131}},{"path":"src/it/java/teammates/it/storage/sqlapi/AccountRequestsDbIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.AccountRequestsDb;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * SUT: {@link AccountRequestsDb}."},{"lineNumber":17,"author":{"gitId":"-"},"content":" */"},{"lineNumber":18,"author":{"gitId":"-"},"content":"public class AccountRequestsDbIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" private final AccountRequestsDb accountRequestDb \u003d AccountRequestsDb.inst();"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":23,"author":{"gitId":"-"},"content":" public void testCreateReadDeleteAccountRequest() throws Exception {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" ______TS(\"Create account request, does not exists, succeeds\");"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":27,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":28,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" ______TS(\"Read account request using the given ID\");"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" AccountRequest actualAccReqEmalAndInstitute \u003d accountRequestDb.getAccountRequest(accountRequest.getId());"},{"lineNumber":33,"author":{"gitId":"-"},"content":" verifyEquals(accountRequest, actualAccReqEmalAndInstitute);"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" ______TS(\"Read account request using the given registration key\");"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" AccountRequest actualAccReqRegistrationKey \u003d"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" accountRequestDb.getAccountRequestByRegistrationKey(accountRequest.getRegistrationKey());"},{"lineNumber":39,"author":{"gitId":"-"},"content":" verifyEquals(accountRequest, actualAccReqRegistrationKey);"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" ______TS(\"Read account request using the given start and end timing\");"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" List\u003cAccountRequest\u003e actualAccReqCreatedAt \u003d"},{"lineNumber":44,"author":{"gitId":"-"},"content":" accountRequestDb.getAccountRequests(accountRequest.getCreatedAt(), accountRequest.getCreatedAt());"},{"lineNumber":45,"author":{"gitId":"-"},"content":" assertEquals(1, actualAccReqCreatedAt.size());"},{"lineNumber":46,"author":{"gitId":"-"},"content":" verifyEquals(accountRequest, actualAccReqCreatedAt.get(0));"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" ______TS(\"Read account request not found using the outside start and end timing\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" List\u003cAccountRequest\u003e actualAccReqCreatedAtOutside \u003d"},{"lineNumber":51,"author":{"gitId":"-"},"content":" accountRequestDb.getAccountRequests("},{"lineNumber":52,"author":{"gitId":"-"},"content":" accountRequest.getCreatedAt().minusMillis(3000),"},{"lineNumber":53,"author":{"gitId":"-"},"content":" accountRequest.getCreatedAt().minusMillis(2000));"},{"lineNumber":54,"author":{"gitId":"-"},"content":" assertEquals(0, actualAccReqCreatedAtOutside.size());"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" ______TS(\"Create account request, same email address and institute already exist, creates successfully\");"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" AccountRequest identicalAccountRequest \u003d"},{"lineNumber":59,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":60,"author":{"gitId":"-"},"content":" assertNotSame(accountRequest, identicalAccountRequest);"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(identicalAccountRequest);"},{"lineNumber":63,"author":{"gitId":"-"},"content":" AccountRequest actualIdenticalAccountRequest \u003d"},{"lineNumber":64,"author":{"gitId":"-"},"content":" accountRequestDb.getAccountRequestByRegistrationKey(identicalAccountRequest.getRegistrationKey());"},{"lineNumber":65,"author":{"gitId":"-"},"content":" verifyEquals(identicalAccountRequest, actualIdenticalAccountRequest);"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" ______TS(\"Delete account request that was created\");"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" accountRequestDb.deleteAccountRequest(accountRequest);"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" AccountRequest actualAccountRequest \u003d"},{"lineNumber":72,"author":{"gitId":"-"},"content":" accountRequestDb.getAccountRequestByRegistrationKey(accountRequest.getRegistrationKey());"},{"lineNumber":73,"author":{"gitId":"-"},"content":" assertNull(actualAccountRequest);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" }"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":77,"author":{"gitId":"-"},"content":" public void testGetAccountRequest_nonExistentAccountRequest_returnsNull() {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" UUID id \u003d UUID.randomUUID();"},{"lineNumber":79,"author":{"gitId":"-"},"content":" AccountRequest actualAccountRequest \u003d accountRequestDb.getAccountRequest(id);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" assertNull(actualAccountRequest);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":84,"author":{"gitId":"-"},"content":" public void testGetAccountRequest_existingAccountRequest_getsSuccessfully() throws InvalidParametersException {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" AccountRequest expectedAccountRequest \u003d"},{"lineNumber":86,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":87,"author":{"gitId":"-"},"content":" UUID id \u003d expectedAccountRequest.getId();"},{"lineNumber":88,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(expectedAccountRequest);"},{"lineNumber":89,"author":{"gitId":"-"},"content":" AccountRequest actualAccountRequest \u003d accountRequestDb.getAccountRequest(id);"},{"lineNumber":90,"author":{"gitId":"-"},"content":" assertEquals(expectedAccountRequest, actualAccountRequest);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" }"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":94,"author":{"gitId":"-"},"content":" public void testUpdateAccountRequest() throws Exception {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" ______TS(\"Update account request, does not exists, exception thrown\");"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":98,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":101,"author":{"gitId":"-"},"content":" () -\u003e accountRequestDb.updateAccountRequest(accountRequest));"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" ______TS(\"Update account request, already exists, update successful\");"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":106,"author":{"gitId":"-"},"content":" accountRequest.setName(\"new account request name\");"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" accountRequestDb.updateAccountRequest(accountRequest);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" AccountRequest actual \u003d accountRequestDb.getAccountRequest(accountRequest.getId());"},{"lineNumber":110,"author":{"gitId":"-"},"content":" verifyEquals(accountRequest, actual);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":114,"author":{"gitId":"-"},"content":" public void testSqlInjectionInCreateAccountRequestEmailField() throws Exception {"},{"lineNumber":115,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in email field\");"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" // Attempt to use SQL commands in email field"},{"lineNumber":118,"author":{"gitId":"-"},"content":" String email \u003d \"email\u0027/**/OR/**/1\u003d1/**/@gmail.com\";"},{"lineNumber":119,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":120,"author":{"gitId":"-"},"content":" new AccountRequest(email, \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" // The system should treat the input as a plain text string"},{"lineNumber":123,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":124,"author":{"gitId":"-"},"content":" AccountRequest actual \u003d accountRequestDb.getAccountRequest(accountRequest.getId());"},{"lineNumber":125,"author":{"gitId":"-"},"content":" assertEquals(email, actual.getEmail());"},{"lineNumber":126,"author":{"gitId":"-"},"content":" }"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":129,"author":{"gitId":"-"},"content":" public void testSqlInjectionInCreateAccountRequestNameField() throws Exception {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in name field\");"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":" // Attempt to use SQL commands in name field"},{"lineNumber":133,"author":{"gitId":"-"},"content":" String name \u003d \"name\u0027; SELECT * FROM account_requests; --\";"},{"lineNumber":134,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":135,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", name, \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" // The system should treat the input as a plain text string"},{"lineNumber":138,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" AccountRequest actual \u003d accountRequestDb.getAccountRequest(accountRequest.getId());"},{"lineNumber":140,"author":{"gitId":"-"},"content":" assertEquals(name, actual.getName());"},{"lineNumber":141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":144,"author":{"gitId":"-"},"content":" public void testSqlInjectionInCreateAccountRequestInstituteField() throws Exception {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in institute field\");"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" // Attempt to use SQL commands in institute field"},{"lineNumber":148,"author":{"gitId":"-"},"content":" String institute \u003d \"institute\u0027; DROP TABLE account_requests; --\";"},{"lineNumber":149,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":150,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", institute, AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" // The system should treat the input as a plain text string"},{"lineNumber":153,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":154,"author":{"gitId":"-"},"content":" AccountRequest actual \u003d accountRequestDb.getAccountRequest(accountRequest.getId());"},{"lineNumber":155,"author":{"gitId":"-"},"content":" assertEquals(institute, actual.getInstitute());"},{"lineNumber":156,"author":{"gitId":"-"},"content":" }"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":159,"author":{"gitId":"xenosf"},"content":" public void testSqlInjectionInCreateAccountRequestCommentsField() throws Exception {"},{"lineNumber":160,"author":{"gitId":"xenosf"},"content":" ______TS(\"SQL Injection test in comments field\");"},{"lineNumber":161,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":162,"author":{"gitId":"xenosf"},"content":" // Attempt to use SQL commands in comments field"},{"lineNumber":163,"author":{"gitId":"xenosf"},"content":" String comments \u003d \"comment\u0027; DROP TABLE account_requests; --\";"},{"lineNumber":164,"author":{"gitId":"xenosf"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":165,"author":{"gitId":"xenosf"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, comments);"},{"lineNumber":166,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":167,"author":{"gitId":"xenosf"},"content":" // The system should treat the input as a plain text string"},{"lineNumber":168,"author":{"gitId":"xenosf"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":169,"author":{"gitId":"xenosf"},"content":" AccountRequest actual \u003d accountRequestDb.getAccountRequest(accountRequest.getId());"},{"lineNumber":170,"author":{"gitId":"xenosf"},"content":" assertEquals(comments, actual.getComments());"},{"lineNumber":171,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":172,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":174,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetAccountRequestByRegistrationKey() throws Exception {"},{"lineNumber":175,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in getAccountRequestByRegistrationKey\");"},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":178,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":179,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":180,"author":{"gitId":"-"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":" String regKeyInjection \u003d \"regKey\u0027; DROP TABLE account_requests; --\";"},{"lineNumber":182,"author":{"gitId":"-"},"content":" AccountRequest actualInjection \u003d accountRequestDb.getAccountRequestByRegistrationKey(regKeyInjection);"},{"lineNumber":183,"author":{"gitId":"-"},"content":" assertNull(actualInjection);"},{"lineNumber":184,"author":{"gitId":"-"},"content":""},{"lineNumber":185,"author":{"gitId":"-"},"content":" AccountRequest actual \u003d accountRequestDb.getAccountRequestByRegistrationKey(accountRequest.getRegistrationKey());"},{"lineNumber":186,"author":{"gitId":"-"},"content":" assertEquals(accountRequest, actual);"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":190,"author":{"gitId":"xenosf"},"content":" public void testSqlInjectionInGetApprovedAccountRequestsForEmail() throws Exception {"},{"lineNumber":191,"author":{"gitId":"xenosf"},"content":" ______TS(\"SQL Injection test in getApprovedAccountRequestsForEmail\");"},{"lineNumber":192,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":193,"author":{"gitId":"xenosf"},"content":" String email \u003d \"test@gmail.com\";"},{"lineNumber":194,"author":{"gitId":"xenosf"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":195,"author":{"gitId":"xenosf"},"content":" new AccountRequest(email, \"name\", \"institute\", AccountRequestStatus.APPROVED, \"comments\");"},{"lineNumber":196,"author":{"gitId":"xenosf"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":197,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":198,"author":{"gitId":"xenosf"},"content":" // Attempt to use SQL commands in email field"},{"lineNumber":199,"author":{"gitId":"xenosf"},"content":" String emailInjection \u003d \"email\u0027/**/OR/**/1\u003d1/**/@gmail.com\";"},{"lineNumber":200,"author":{"gitId":"xenosf"},"content":" List\u003cAccountRequest\u003e actualInjection \u003d accountRequestDb.getApprovedAccountRequestsForEmail(emailInjection);"},{"lineNumber":201,"author":{"gitId":"xenosf"},"content":" // The system should treat the input as a plain text string"},{"lineNumber":202,"author":{"gitId":"xenosf"},"content":" assertEquals(0, actualInjection.size());"},{"lineNumber":203,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":204,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":206,"author":{"gitId":"-"},"content":" public void testSqlInjectionInUpdateAccountRequest() throws Exception {"},{"lineNumber":207,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in updateAccountRequest\");"},{"lineNumber":208,"author":{"gitId":"-"},"content":""},{"lineNumber":209,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":210,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":211,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":212,"author":{"gitId":"-"},"content":""},{"lineNumber":213,"author":{"gitId":"-"},"content":" String nameInjection \u003d \"newName\u0027; DROP TABLE account_requests; --\";"},{"lineNumber":214,"author":{"gitId":"-"},"content":" accountRequest.setName(nameInjection);"},{"lineNumber":215,"author":{"gitId":"-"},"content":" accountRequestDb.updateAccountRequest(accountRequest);"},{"lineNumber":216,"author":{"gitId":"-"},"content":""},{"lineNumber":217,"author":{"gitId":"-"},"content":" AccountRequest actual \u003d accountRequestDb.getAccountRequest(accountRequest.getId());"},{"lineNumber":218,"author":{"gitId":"-"},"content":" assertEquals(accountRequest, actual);"},{"lineNumber":219,"author":{"gitId":"-"},"content":" }"},{"lineNumber":220,"author":{"gitId":"-"},"content":""},{"lineNumber":221,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":222,"author":{"gitId":"-"},"content":" public void testSqlInjectionInDeleteAccountRequest() throws Exception {"},{"lineNumber":223,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in deleteAccountRequest\");"},{"lineNumber":224,"author":{"gitId":"-"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":226,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":227,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" String emailInjection \u003d \"email\u0027/**/OR/**/1\u003d1/**/@gmail.com\";"},{"lineNumber":230,"author":{"gitId":"-"},"content":" String nameInjection \u003d \"name\u0027; DROP TABLE account_requests; --\";"},{"lineNumber":231,"author":{"gitId":"-"},"content":" String instituteInjection \u003d \"institute\u0027; DROP TABLE account_requests; --\";"},{"lineNumber":232,"author":{"gitId":"-"},"content":" AccountRequest accountRequestInjection \u003d new AccountRequest(emailInjection, nameInjection, instituteInjection,"},{"lineNumber":233,"author":{"gitId":"-"},"content":" AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":234,"author":{"gitId":"-"},"content":" accountRequestDb.deleteAccountRequest(accountRequestInjection);"},{"lineNumber":235,"author":{"gitId":"-"},"content":""},{"lineNumber":236,"author":{"gitId":"-"},"content":" AccountRequest actual \u003d accountRequestDb.getAccountRequest(accountRequest.getId());"},{"lineNumber":237,"author":{"gitId":"-"},"content":" assertEquals(accountRequest, actual);"},{"lineNumber":238,"author":{"gitId":"-"},"content":" }"},{"lineNumber":239,"author":{"gitId":"-"},"content":""},{"lineNumber":240,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":241,"author":{"gitId":"-"},"content":" public void testSqlInjectionSearchAccountRequestsInWholeSystem() throws Exception {"},{"lineNumber":242,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in searchAccountRequestsInWholeSystem\");"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":245,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":246,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" String searchInjection \u003d \"institute\u0027; DROP TABLE account_requests; --\";"},{"lineNumber":249,"author":{"gitId":"-"},"content":" List\u003cAccountRequest\u003e actualInjection \u003d accountRequestDb.searchAccountRequestsInWholeSystem(searchInjection);"},{"lineNumber":250,"author":{"gitId":"-"},"content":" assertEquals(0, actualInjection.size());"},{"lineNumber":251,"author":{"gitId":"-"},"content":""},{"lineNumber":252,"author":{"gitId":"-"},"content":" AccountRequest actual \u003d accountRequestDb.getAccountRequest(accountRequest.getId());"},{"lineNumber":253,"author":{"gitId":"-"},"content":" assertEquals(accountRequest, actual);"},{"lineNumber":254,"author":{"gitId":"-"},"content":" }"},{"lineNumber":255,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":31,"dishenggg":1,"-":223}},{"path":"src/it/java/teammates/it/storage/sqlapi/CoursesDbIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.CoursesDb;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * SUT: {@link CoursesDb}."},{"lineNumber":19,"author":{"gitId":"-"},"content":" */"},{"lineNumber":20,"author":{"gitId":"-"},"content":"public class CoursesDbIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" private final CoursesDb coursesDb \u003d CoursesDb.inst();"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" public void testGetCourse() throws Exception {"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: get course that does not exist\");"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" Course actual \u003d coursesDb.getCourse(\"non-existent-course-id\");"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" assertNull(actual);"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null assertion exception thrown\");"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.getCourse(null));"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: get course that already exists\");"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" Course expected \u003d getTypicalCourse();"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" coursesDb.createCourse(expected);"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" actual \u003d coursesDb.getCourse(expected.getId());"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" verifyEquals(expected, actual);"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":42,"author":{"gitId":"-"},"content":" public void testCreateCourse() throws Exception {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" ______TS(\"success: create course that does not exist\");"},{"lineNumber":44,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":45,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" Course actualCourse \u003d coursesDb.getCourse(\"course-id\");"},{"lineNumber":47,"author":{"gitId":"-"},"content":" verifyEquals(course, actualCourse);"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null course assertion exception thrown\");"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.createCourse(null));"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: invalid course details\");"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" Course invalidCourse \u003d new Course(\"course-id\", \"!@#!@#\", \"Asia/Singapore\", \"institute\");"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" assertThrows(InvalidParametersException.class, () -\u003e coursesDb.createCourse(invalidCourse));"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" ______TS(\"failure: create course that already exist, execption thrown\");"},{"lineNumber":57,"author":{"gitId":"-"},"content":" Course identicalCourse \u003d getTypicalCourse();"},{"lineNumber":58,"author":{"gitId":"-"},"content":" assertNotSame(course, identicalCourse);"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" assertThrows(EntityAlreadyExistsException.class, () -\u003e coursesDb.createCourse(identicalCourse));"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":64,"author":{"gitId":"-"},"content":" public void testUpdateCourse() throws Exception {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" ______TS(\"failure: update course that does not exist, exception thrown\");"},{"lineNumber":66,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":67,"author":{"gitId":"-"},"content":" assertThrows(EntityDoesNotExistException.class, () -\u003e coursesDb.updateCourse(course));"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null course assertion exception thrown\");"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.updateCourse(null));"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: update course that already exists\");"},{"lineNumber":73,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" course.setName(\"new course name\");"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" coursesDb.updateCourse(course);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" Course actual \u003d coursesDb.getCourse(\"course-id\");"},{"lineNumber":78,"author":{"gitId":"-"},"content":" verifyEquals(course, actual);"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" ______TS(\"success: update detached course that already exists\");"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" // same id, different name"},{"lineNumber":83,"author":{"gitId":"-"},"content":" Course detachedCourse \u003d getTypicalCourse();"},{"lineNumber":84,"author":{"gitId":"-"},"content":" detachedCourse.setName(\"different-name\");"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" coursesDb.updateCourse(detachedCourse);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" verifyEquals(course, detachedCourse);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" public void testDeleteCourse() throws Exception {"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: delete course that already exists\");"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":" coursesDb.createCourse(course);"},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" coursesDb.deleteCourse(course);"},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":" Course actualCourse \u003d coursesDb.getCourse(course.getId());"},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":" assertNull(actualCourse);"},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" public void testCreateSection() throws Exception {"},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" coursesDb.createCourse(course);"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: create section that does not exist\");"},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" coursesDb.createSection(section);"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" Section actualSection \u003d coursesDb.getSectionByName(course.getId(), section.getName());"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" verifyEquals(section, actualSection);"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null section assertion exception thrown\");"},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.createSection(null));"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: invalid section details\");"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" Section invalidSection \u003d new Section(course, null);"},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":" assertThrows(InvalidParametersException.class, () -\u003e coursesDb.createSection(invalidSection));"},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: create section that already exist, execption thrown\");"},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" assertThrows(EntityAlreadyExistsException.class, () -\u003e coursesDb.createSection(section));"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" public void testGetSectionByName() throws Exception {"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" coursesDb.createCourse(course);"},{"lineNumber":128,"author":{"gitId":"domoberzin"},"content":" coursesDb.createSection(section);"},{"lineNumber":129,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null courseId assertion exception thrown\");"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.getSectionByName(null, section.getName()));"},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null sectionName assertion exception thrown\");"},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.getSectionByName(course.getId(), null));"},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: get section that already exists\");"},{"lineNumber":137,"author":{"gitId":"domoberzin"},"content":" Section actualSection \u003d coursesDb.getSectionByName(course.getId(), section.getName());"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":" verifyEquals(section, actualSection);"},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":140,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: get section that does not exist\");"},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":" Section nonExistentSection \u003d coursesDb.getSectionByName(course.getId(), \"non-existent-section-name\");"},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":" assertNull(nonExistentSection);"},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":146,"author":{"gitId":"-"},"content":" public void testGetSectionByCourseIdAndTeam() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":147,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":148,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, \"section-name\");"},{"lineNumber":149,"author":{"gitId":"-"},"content":" course.addSection(section);"},{"lineNumber":150,"author":{"gitId":"-"},"content":" Team team \u003d new Team(section, \"team-name\");"},{"lineNumber":151,"author":{"gitId":"-"},"content":" section.addTeam(team);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null courseId assertion exception thrown\");"},{"lineNumber":155,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.getSectionByCourseIdAndTeam(null, team.getName()));"},{"lineNumber":156,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":157,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null teamName assertion exception thrown\");"},{"lineNumber":158,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.getSectionByCourseIdAndTeam(course.getId(), null));"},{"lineNumber":159,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":161,"author":{"gitId":"-"},"content":" Section actualSection \u003d coursesDb.getSectionByCourseIdAndTeam(course.getId(), team.getName());"},{"lineNumber":162,"author":{"gitId":"-"},"content":" verifyEquals(section, actualSection);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":166,"author":{"gitId":"-"},"content":" public void testGetTeamsForSection() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":168,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, \"section-name\");"},{"lineNumber":169,"author":{"gitId":"-"},"content":" course.addSection(section);"},{"lineNumber":170,"author":{"gitId":"-"},"content":" Team team1 \u003d new Team(section, \"team-name1\");"},{"lineNumber":171,"author":{"gitId":"-"},"content":" section.addTeam(team1);"},{"lineNumber":172,"author":{"gitId":"-"},"content":" Team team2 \u003d new Team(section, \"team-name2\");"},{"lineNumber":173,"author":{"gitId":"-"},"content":" section.addTeam(team2);"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" List\u003cTeam\u003e expectedTeams \u003d List.of(team1, team2);"},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null section assertion exception thrown\");"},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.getTeamsForSection(null));"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":183,"author":{"gitId":"-"},"content":" List\u003cTeam\u003e actualTeams \u003d coursesDb.getTeamsForSection(section);"},{"lineNumber":184,"author":{"gitId":"-"},"content":" assertEquals(expectedTeams.size(), actualTeams.size());"},{"lineNumber":185,"author":{"gitId":"-"},"content":" assertTrue(expectedTeams.containsAll(actualTeams));"},{"lineNumber":186,"author":{"gitId":"-"},"content":" }"},{"lineNumber":187,"author":{"gitId":"-"},"content":""},{"lineNumber":188,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":189,"author":{"gitId":"domoberzin"},"content":" public void testDeleteSectionsByCourseId() throws Exception {"},{"lineNumber":190,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":191,"author":{"gitId":"domoberzin"},"content":" coursesDb.createCourse(course);"},{"lineNumber":192,"author":{"gitId":"domoberzin"},"content":" List\u003cSection\u003e expectedSections \u003d new ArrayList\u003c\u003e();"},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":" for (int i \u003d 0; i \u003c 5; i++) {"},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" Section newSection \u003d new Section(course, \"section-name\" + i);"},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" expectedSections.add(newSection);"},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":" course.addSection(newSection);"},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":" assertNotNull(coursesDb.getSectionByName(course.getId(), newSection.getName()));"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":200,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: delete sections by course id\");"},{"lineNumber":201,"author":{"gitId":"domoberzin"},"content":" coursesDb.deleteSectionsByCourseId(course.getId());"},{"lineNumber":202,"author":{"gitId":"domoberzin"},"content":" for (Section section : expectedSections) {"},{"lineNumber":203,"author":{"gitId":"domoberzin"},"content":" Section actualSection \u003d coursesDb.getSectionByName(course.getId(), section.getName());"},{"lineNumber":204,"author":{"gitId":"domoberzin"},"content":" assertNull(actualSection);"},{"lineNumber":205,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":206,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":207,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":209,"author":{"gitId":"-"},"content":" public void testGetTeamsForCourse() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" Section section1 \u003d new Section(course, \"section-name1\");"},{"lineNumber":213,"author":{"gitId":"-"},"content":" course.addSection(section1);"},{"lineNumber":214,"author":{"gitId":"-"},"content":" Team team1 \u003d new Team(section1, \"team-name1\");"},{"lineNumber":215,"author":{"gitId":"-"},"content":" section1.addTeam(team1);"},{"lineNumber":216,"author":{"gitId":"-"},"content":" Team team2 \u003d new Team(section1, \"team-name2\");"},{"lineNumber":217,"author":{"gitId":"-"},"content":" section1.addTeam(team2);"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":" Section section2 \u003d new Section(course, \"section-name2\");"},{"lineNumber":220,"author":{"gitId":"-"},"content":" course.addSection(section2);"},{"lineNumber":221,"author":{"gitId":"-"},"content":" Team team3 \u003d new Team(section2, \"team-name3\");"},{"lineNumber":222,"author":{"gitId":"-"},"content":" section2.addTeam(team3);"},{"lineNumber":223,"author":{"gitId":"-"},"content":" Team team4 \u003d new Team(section2, \"team-name4\");"},{"lineNumber":224,"author":{"gitId":"-"},"content":" section2.addTeam(team4);"},{"lineNumber":225,"author":{"gitId":"-"},"content":""},{"lineNumber":226,"author":{"gitId":"-"},"content":" List\u003cTeam\u003e expectedTeams \u003d List.of(team1, team2, team3, team4);"},{"lineNumber":227,"author":{"gitId":"-"},"content":""},{"lineNumber":228,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":229,"author":{"gitId":"-"},"content":""},{"lineNumber":230,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null courseId assertion exception thrown\");"},{"lineNumber":231,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.getTeamsForCourse(null));"},{"lineNumber":232,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":234,"author":{"gitId":"-"},"content":" List\u003cTeam\u003e actualTeams \u003d coursesDb.getTeamsForCourse(course.getId());"},{"lineNumber":235,"author":{"gitId":"-"},"content":" assertEquals(expectedTeams.size(), actualTeams.size());"},{"lineNumber":236,"author":{"gitId":"-"},"content":" assertTrue(expectedTeams.containsAll(actualTeams));"},{"lineNumber":237,"author":{"gitId":"-"},"content":" }"},{"lineNumber":238,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":239,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":240,"author":{"gitId":"domoberzin"},"content":" public void testCreateTeam() throws Exception {"},{"lineNumber":241,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":242,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":243,"author":{"gitId":"domoberzin"},"content":" Team team \u003d new Team(section, \"team-name1\");"},{"lineNumber":244,"author":{"gitId":"domoberzin"},"content":" coursesDb.createCourse(course);"},{"lineNumber":245,"author":{"gitId":"domoberzin"},"content":" coursesDb.createSection(section);"},{"lineNumber":246,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":247,"author":{"gitId":"domoberzin"},"content":" assertNotNull(coursesDb.getSectionByName(course.getId(), section.getName()));"},{"lineNumber":248,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":249,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null team assertion exception thrown\");"},{"lineNumber":250,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.createTeam(null));"},{"lineNumber":251,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":252,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: create team that does not exist\");"},{"lineNumber":253,"author":{"gitId":"domoberzin"},"content":" coursesDb.createTeam(team);"},{"lineNumber":254,"author":{"gitId":"domoberzin"},"content":" Team actualTeam \u003d coursesDb.getTeamByName(section.getId(), team.getName());"},{"lineNumber":255,"author":{"gitId":"domoberzin"},"content":" verifyEquals(team, actualTeam);"},{"lineNumber":256,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":257,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: invalid team details\");"},{"lineNumber":258,"author":{"gitId":"domoberzin"},"content":" Team invalidTeam \u003d new Team(section, null);"},{"lineNumber":259,"author":{"gitId":"domoberzin"},"content":" assertThrows(InvalidParametersException.class, () -\u003e coursesDb.createTeam(invalidTeam));"},{"lineNumber":260,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":261,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: create team that already exist, execption thrown\");"},{"lineNumber":262,"author":{"gitId":"domoberzin"},"content":" assertThrows(EntityAlreadyExistsException.class, () -\u003e coursesDb.createTeam(team));"},{"lineNumber":263,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":264,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":265,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":266,"author":{"gitId":"domoberzin"},"content":" public void testGetTeamByName() throws Exception {"},{"lineNumber":267,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":268,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":269,"author":{"gitId":"domoberzin"},"content":" Team team \u003d new Team(section, \"team-name1\");"},{"lineNumber":270,"author":{"gitId":"domoberzin"},"content":" coursesDb.createCourse(course);"},{"lineNumber":271,"author":{"gitId":"domoberzin"},"content":" coursesDb.createSection(section);"},{"lineNumber":272,"author":{"gitId":"domoberzin"},"content":" coursesDb.createTeam(team);"},{"lineNumber":273,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":274,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: get team that already exists\");"},{"lineNumber":275,"author":{"gitId":"domoberzin"},"content":" Team actualTeam \u003d coursesDb.getTeamByName(section.getId(), team.getName());"},{"lineNumber":276,"author":{"gitId":"domoberzin"},"content":" verifyEquals(team, actualTeam);"},{"lineNumber":277,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":278,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null sectionId assertion exception thrown\");"},{"lineNumber":279,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.getTeamByName(null, team.getName()));"},{"lineNumber":280,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":281,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null teamName assertion exception thrown\");"},{"lineNumber":282,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.getTeamByName(section.getId(), null));"},{"lineNumber":283,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":284,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: null return\");"},{"lineNumber":285,"author":{"gitId":"domoberzin"},"content":" Team nonExistentTeam \u003d coursesDb.getTeamByName(section.getId(), \"non-existent-team-name\");"},{"lineNumber":286,"author":{"gitId":"domoberzin"},"content":" assertNull(nonExistentTeam);"},{"lineNumber":287,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":288,"author":{"gitId":"-"},"content":""},{"lineNumber":289,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":290,"author":{"gitId":"-"},"content":" public void testSqlInjectionInCreateCourse() throws Exception {"},{"lineNumber":291,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in createCourse\");"},{"lineNumber":292,"author":{"gitId":"-"},"content":""},{"lineNumber":293,"author":{"gitId":"-"},"content":" // Attempt to use SQL commands in name field"},{"lineNumber":294,"author":{"gitId":"-"},"content":" String courseName \u003d \"test\u0027; DROP TABLE courses; --\";"},{"lineNumber":295,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", courseName, \"UTC\", \"teammates\");"},{"lineNumber":296,"author":{"gitId":"-"},"content":""},{"lineNumber":297,"author":{"gitId":"-"},"content":" // The system should treat the input as a plain text string"},{"lineNumber":298,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":299,"author":{"gitId":"-"},"content":" Course actual \u003d coursesDb.getCourse(\"course-id\");"},{"lineNumber":300,"author":{"gitId":"-"},"content":" assertEquals(courseName, actual.getName());"},{"lineNumber":301,"author":{"gitId":"-"},"content":" }"},{"lineNumber":302,"author":{"gitId":"-"},"content":""},{"lineNumber":303,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":304,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetCourse() throws Exception {"},{"lineNumber":305,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in getCourse\");"},{"lineNumber":306,"author":{"gitId":"-"},"content":""},{"lineNumber":307,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"course-name\", \"UTC\", \"teammates\");"},{"lineNumber":308,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":309,"author":{"gitId":"-"},"content":""},{"lineNumber":310,"author":{"gitId":"-"},"content":" // Attempt to use SQL commands in courseId field"},{"lineNumber":311,"author":{"gitId":"-"},"content":" String courseId \u003d \"test\u0027 OR 1 \u003d 1; --\";"},{"lineNumber":312,"author":{"gitId":"-"},"content":" Course actual \u003d coursesDb.getCourse(courseId);"},{"lineNumber":313,"author":{"gitId":"-"},"content":" assertEquals(null, actual);"},{"lineNumber":314,"author":{"gitId":"-"},"content":" }"},{"lineNumber":315,"author":{"gitId":"-"},"content":""},{"lineNumber":316,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":317,"author":{"gitId":"-"},"content":" public void testSqlInjectionInUpdateCourse() throws Exception {"},{"lineNumber":318,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in updateCourse\");"},{"lineNumber":319,"author":{"gitId":"-"},"content":""},{"lineNumber":320,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"name\", \"UTC\", \"institute\");"},{"lineNumber":321,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":322,"author":{"gitId":"-"},"content":""},{"lineNumber":323,"author":{"gitId":"-"},"content":" // The system should treat the input as a plain text string"},{"lineNumber":324,"author":{"gitId":"-"},"content":" String newName \u003d \"newName\u0027; DROP TABLE courses; --\";"},{"lineNumber":325,"author":{"gitId":"-"},"content":" course.setName(newName);"},{"lineNumber":326,"author":{"gitId":"-"},"content":" coursesDb.updateCourse(course);"},{"lineNumber":327,"author":{"gitId":"-"},"content":" Course actual \u003d coursesDb.getCourse(\"course-id\");"},{"lineNumber":328,"author":{"gitId":"-"},"content":" assertEquals(newName, actual.getName());"},{"lineNumber":329,"author":{"gitId":"-"},"content":" }"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":332,"author":{"gitId":"-"},"content":" public void testSqlInjectionInDeleteCourse() throws Exception {"},{"lineNumber":333,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in deleteCourse\");"},{"lineNumber":334,"author":{"gitId":"-"},"content":""},{"lineNumber":335,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"name\", \"UTC\", \"institute\");"},{"lineNumber":336,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":337,"author":{"gitId":"-"},"content":""},{"lineNumber":338,"author":{"gitId":"-"},"content":" String name \u003d \"newName\u0027; DELETE FROM courses; --\";"},{"lineNumber":339,"author":{"gitId":"-"},"content":" Course injectionCourse \u003d new Course(\"course-id-injection\", name, \"UTC\", \"institute\");"},{"lineNumber":340,"author":{"gitId":"-"},"content":" coursesDb.createCourse(injectionCourse);"},{"lineNumber":341,"author":{"gitId":"-"},"content":""},{"lineNumber":342,"author":{"gitId":"-"},"content":" coursesDb.deleteCourse(injectionCourse);"},{"lineNumber":343,"author":{"gitId":"-"},"content":" Course actualInjectionCourse \u003d coursesDb.getCourse(\"course-id-injection\");"},{"lineNumber":344,"author":{"gitId":"-"},"content":""},{"lineNumber":345,"author":{"gitId":"-"},"content":" // The course should be deleted"},{"lineNumber":346,"author":{"gitId":"-"},"content":" assertEquals(null, actualInjectionCourse);"},{"lineNumber":347,"author":{"gitId":"-"},"content":""},{"lineNumber":348,"author":{"gitId":"-"},"content":" // All other courses should not be deleted"},{"lineNumber":349,"author":{"gitId":"-"},"content":" Course actualCourse \u003d coursesDb.getCourse(\"course-id\");"},{"lineNumber":350,"author":{"gitId":"-"},"content":" assertEquals(course, actualCourse);"},{"lineNumber":351,"author":{"gitId":"-"},"content":" }"},{"lineNumber":352,"author":{"gitId":"-"},"content":""},{"lineNumber":353,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":354,"author":{"gitId":"-"},"content":" public void testSqlInjectionInCreateSection() throws Exception {"},{"lineNumber":355,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in createSection\");"},{"lineNumber":356,"author":{"gitId":"-"},"content":""},{"lineNumber":357,"author":{"gitId":"-"},"content":" // Attempt to use SQL commands in sectionName fields"},{"lineNumber":358,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"name\", \"UTC\", \"institute\");"},{"lineNumber":359,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":360,"author":{"gitId":"-"},"content":" String sectionName \u003d \"section\u0027; DROP TABLE courses; --\";"},{"lineNumber":361,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, sectionName);"},{"lineNumber":362,"author":{"gitId":"-"},"content":""},{"lineNumber":363,"author":{"gitId":"-"},"content":" // The system should treat the input as a plain text string"},{"lineNumber":364,"author":{"gitId":"-"},"content":" coursesDb.createSection(section);"},{"lineNumber":365,"author":{"gitId":"-"},"content":""},{"lineNumber":366,"author":{"gitId":"-"},"content":" // Check that we are still able to get courses"},{"lineNumber":367,"author":{"gitId":"-"},"content":" Course actualCourse \u003d coursesDb.getCourse(\"course-id\");"},{"lineNumber":368,"author":{"gitId":"-"},"content":" assertEquals(course, actualCourse);"},{"lineNumber":369,"author":{"gitId":"-"},"content":" }"},{"lineNumber":370,"author":{"gitId":"-"},"content":""},{"lineNumber":371,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":372,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetSectionByName() throws Exception {"},{"lineNumber":373,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in getSectionByName\");"},{"lineNumber":374,"author":{"gitId":"-"},"content":""},{"lineNumber":375,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"course-name\", \"UTC\", \"institute\");"},{"lineNumber":376,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":377,"author":{"gitId":"-"},"content":" String sectionName \u003d \"section-name\";"},{"lineNumber":378,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, sectionName);"},{"lineNumber":379,"author":{"gitId":"-"},"content":""},{"lineNumber":380,"author":{"gitId":"-"},"content":" coursesDb.createSection(section);"},{"lineNumber":381,"author":{"gitId":"-"},"content":" Section actual \u003d coursesDb.getSectionByName(\"course-id\", \"section-name\u0027; DROP TABLE courses; --\");"},{"lineNumber":382,"author":{"gitId":"-"},"content":" assertEquals(null, actual);"},{"lineNumber":383,"author":{"gitId":"-"},"content":" Section actualSection \u003d coursesDb.getSectionByName(\"course-id\", sectionName);"},{"lineNumber":384,"author":{"gitId":"-"},"content":" assertEquals(sectionName, actualSection.getName());"},{"lineNumber":385,"author":{"gitId":"-"},"content":" }"},{"lineNumber":386,"author":{"gitId":"-"},"content":""},{"lineNumber":387,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":388,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetSectionByCourseIdAndTeam() throws Exception {"},{"lineNumber":389,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in getSectionByCourseIdAndTeam\");"},{"lineNumber":390,"author":{"gitId":"-"},"content":""},{"lineNumber":391,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"course-name\", \"UTC\", \"institute\");"},{"lineNumber":392,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, \"section-name\");"},{"lineNumber":393,"author":{"gitId":"-"},"content":" course.addSection(section);"},{"lineNumber":394,"author":{"gitId":"-"},"content":" Team team \u003d new Team(section, \"team-name\");"},{"lineNumber":395,"author":{"gitId":"-"},"content":" section.addTeam(team);"},{"lineNumber":396,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":397,"author":{"gitId":"-"},"content":""},{"lineNumber":398,"author":{"gitId":"-"},"content":" // The system should treat the input as a plain text string"},{"lineNumber":399,"author":{"gitId":"-"},"content":" String teamNameInjection \u003d \"team-name\u0027; DROP TABLE courses; --\";"},{"lineNumber":400,"author":{"gitId":"-"},"content":" Section actual \u003d coursesDb.getSectionByCourseIdAndTeam(\"course-id\", teamNameInjection);"},{"lineNumber":401,"author":{"gitId":"-"},"content":" assertEquals(null, actual);"},{"lineNumber":402,"author":{"gitId":"-"},"content":" Section actualSection \u003d coursesDb.getSectionByCourseIdAndTeam(\"course-id\", \"team-name\");"},{"lineNumber":403,"author":{"gitId":"-"},"content":" assertEquals(\"team-name\", actualSection.getTeams().get(0).getName());"},{"lineNumber":404,"author":{"gitId":"-"},"content":" }"},{"lineNumber":405,"author":{"gitId":"-"},"content":""},{"lineNumber":406,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":407,"author":{"gitId":"-"},"content":" public void testSqlInjectionInDeleteSectionsByCourseId() throws Exception {"},{"lineNumber":408,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in deleteSectionsByCourseId\");"},{"lineNumber":409,"author":{"gitId":"-"},"content":""},{"lineNumber":410,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"name\", \"UTC\", \"institute\");"},{"lineNumber":411,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, \"section-name\");"},{"lineNumber":412,"author":{"gitId":"-"},"content":" course.addSection(section);"},{"lineNumber":413,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":414,"author":{"gitId":"-"},"content":""},{"lineNumber":415,"author":{"gitId":"-"},"content":" String courseId \u003d \"course-id\u0027; DELETE FROM courses; --\";"},{"lineNumber":416,"author":{"gitId":"-"},"content":" coursesDb.deleteSectionsByCourseId(courseId);"},{"lineNumber":417,"author":{"gitId":"-"},"content":""},{"lineNumber":418,"author":{"gitId":"-"},"content":" // The sections should not be deleted"},{"lineNumber":419,"author":{"gitId":"-"},"content":" Section actualSection \u003d coursesDb.getSectionByName(\"course-id\", \"section-name\");"},{"lineNumber":420,"author":{"gitId":"-"},"content":" assertEquals(section, actualSection);"},{"lineNumber":421,"author":{"gitId":"-"},"content":" }"},{"lineNumber":422,"author":{"gitId":"-"},"content":""},{"lineNumber":423,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":424,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetTeamsForSection() throws Exception {"},{"lineNumber":425,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in getTeamsForSection\");"},{"lineNumber":426,"author":{"gitId":"-"},"content":""},{"lineNumber":427,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"course-name\", \"UTC\", \"institute\");"},{"lineNumber":428,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, \"section-name\");"},{"lineNumber":429,"author":{"gitId":"-"},"content":" course.addSection(section);"},{"lineNumber":430,"author":{"gitId":"-"},"content":" Team team \u003d new Team(section, \"team-name\");"},{"lineNumber":431,"author":{"gitId":"-"},"content":" section.addTeam(team);"},{"lineNumber":432,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":433,"author":{"gitId":"-"},"content":""},{"lineNumber":434,"author":{"gitId":"-"},"content":" String sectionName \u003d \"section-name\u0027 OR 1 \u003d 1; --\";"},{"lineNumber":435,"author":{"gitId":"-"},"content":" Section sectionInjection \u003d new Section(course, sectionName);"},{"lineNumber":436,"author":{"gitId":"-"},"content":" List\u003cTeam\u003e actual \u003d coursesDb.getTeamsForSection(sectionInjection);"},{"lineNumber":437,"author":{"gitId":"-"},"content":" assertEquals(0, actual.size());"},{"lineNumber":438,"author":{"gitId":"-"},"content":" }"},{"lineNumber":439,"author":{"gitId":"-"},"content":""},{"lineNumber":440,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":441,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetTeamsForCourse() throws Exception {"},{"lineNumber":442,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in getTeamsForCourse\");"},{"lineNumber":443,"author":{"gitId":"-"},"content":""},{"lineNumber":444,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"course-name\", \"UTC\", \"institute\");"},{"lineNumber":445,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, \"section-name\");"},{"lineNumber":446,"author":{"gitId":"-"},"content":" course.addSection(section);"},{"lineNumber":447,"author":{"gitId":"-"},"content":" Team team \u003d new Team(section, \"team-name\");"},{"lineNumber":448,"author":{"gitId":"-"},"content":" section.addTeam(team);"},{"lineNumber":449,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":450,"author":{"gitId":"-"},"content":""},{"lineNumber":451,"author":{"gitId":"-"},"content":" String courseId \u003d \"course-id\u0027 OR 1 \u003d 1; --\";"},{"lineNumber":452,"author":{"gitId":"-"},"content":" List\u003cTeam\u003e actual \u003d coursesDb.getTeamsForCourse(courseId);"},{"lineNumber":453,"author":{"gitId":"-"},"content":" assertEquals(0, actual.size());"},{"lineNumber":454,"author":{"gitId":"-"},"content":" }"},{"lineNumber":455,"author":{"gitId":"-"},"content":""},{"lineNumber":456,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":457,"author":{"gitId":"-"},"content":" public void testSqlInjectionInCreateTeam() throws Exception {"},{"lineNumber":458,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in createTeam\");"},{"lineNumber":459,"author":{"gitId":"-"},"content":""},{"lineNumber":460,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"course-name\", \"UTC\", \"institute\");"},{"lineNumber":461,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, \"section-name\");"},{"lineNumber":462,"author":{"gitId":"-"},"content":" course.addSection(section);"},{"lineNumber":463,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":464,"author":{"gitId":"-"},"content":""},{"lineNumber":465,"author":{"gitId":"-"},"content":" String teamName \u003d \"team\u0027; DROP TABLE courses; --\";"},{"lineNumber":466,"author":{"gitId":"-"},"content":" Team team \u003d new Team(section, teamName);"},{"lineNumber":467,"author":{"gitId":"-"},"content":" coursesDb.createTeam(team);"},{"lineNumber":468,"author":{"gitId":"-"},"content":""},{"lineNumber":469,"author":{"gitId":"-"},"content":" List\u003cTeam\u003e actual \u003d coursesDb.getTeamsForSection(section);"},{"lineNumber":470,"author":{"gitId":"-"},"content":" assertEquals(1, actual.size());"},{"lineNumber":471,"author":{"gitId":"-"},"content":" assertEquals(teamName, actual.get(0).getName());"},{"lineNumber":472,"author":{"gitId":"-"},"content":" }"},{"lineNumber":473,"author":{"gitId":"-"},"content":""},{"lineNumber":474,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":475,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetTeamByName() throws Exception {"},{"lineNumber":476,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in getTeamByName\");"},{"lineNumber":477,"author":{"gitId":"-"},"content":""},{"lineNumber":478,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"course-name\", \"UTC\", \"institute\");"},{"lineNumber":479,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, \"section-name\");"},{"lineNumber":480,"author":{"gitId":"-"},"content":" course.addSection(section);"},{"lineNumber":481,"author":{"gitId":"-"},"content":" Team team \u003d new Team(section, \"team-name\");"},{"lineNumber":482,"author":{"gitId":"-"},"content":" section.addTeam(team);"},{"lineNumber":483,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":484,"author":{"gitId":"-"},"content":""},{"lineNumber":485,"author":{"gitId":"-"},"content":" String teamName \u003d \"team-name\u0027; DROP TABLE courses; --\";"},{"lineNumber":486,"author":{"gitId":"-"},"content":" Team actual \u003d coursesDb.getTeamByName(section.getId(), teamName);"},{"lineNumber":487,"author":{"gitId":"-"},"content":" assertEquals(null, actual);"},{"lineNumber":488,"author":{"gitId":"-"},"content":" Team actualTeam \u003d coursesDb.getTeamByName(section.getId(), \"team-name\");"},{"lineNumber":489,"author":{"gitId":"-"},"content":" assertEquals(team, actualTeam);"},{"lineNumber":490,"author":{"gitId":"-"},"content":" }"},{"lineNumber":491,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":165,"-":326}},{"path":"src/it/java/teammates/it/storage/sqlapi/FeedbackQuestionsDbIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackQuestionsDb;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * SUT: {@link FeedbackQuestionsDb}."},{"lineNumber":23,"author":{"gitId":"-"},"content":" */"},{"lineNumber":24,"author":{"gitId":"-"},"content":"public class FeedbackQuestionsDbIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" private final FeedbackQuestionsDb fqDb \u003d FeedbackQuestionsDb.inst();"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" private SqlDataBundle typicalDataBundle;"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":31,"author":{"gitId":"-"},"content":" @BeforeClass"},{"lineNumber":32,"author":{"gitId":"-"},"content":" public void setupClass() {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" super.setupClass();"},{"lineNumber":34,"author":{"gitId":"-"},"content":" typicalDataBundle \u003d getTypicalSqlDataBundle();"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":39,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":41,"author":{"gitId":"-"},"content":" persistDataBundle(typicalDataBundle);"},{"lineNumber":42,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" }"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" public void testGetFeedbackQuestion() {"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion expectedFq \u003d typicalDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion actualFq \u003d fqDb.getFeedbackQuestion(expectedFq.getId());"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedFq, actualFq);"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" ______TS(\"failure: does not exist, returns null\");"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" actualFq \u003d fqDb.getFeedbackQuestion(UUID.randomUUID());"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" assertNull(actualFq);"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" ______TS(\"failure: null parameter, assertion error\");"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" assertThrows(AssertionError.class, () -\u003e fqDb.getFeedbackQuestion(null));"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" public void testCreateFeedbackQuestion() throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion expectedFq \u003d getTypicalFeedbackQuestionForSession("},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" getTypicalFeedbackSessionForCourse(getTypicalCourse()));"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" fqDb.createFeedbackQuestion(expectedFq);"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" verifyPresentInDatabase(expectedFq);"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" ______TS(\"failure: duplicate question, throws error\");"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" assertThrows(EntityAlreadyExistsException.class, () -\u003e fqDb.createFeedbackQuestion(expectedFq));"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" ______TS(\"failure: invalid question, throws error\");"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion invalidFq \u003d getTypicalFeedbackQuestionForSession("},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" getTypicalFeedbackSessionForCourse(getTypicalCourse()));"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" invalidFq.setGiverType(FeedbackParticipantType.RECEIVER);"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" assertThrows(InvalidParametersException.class, () -\u003e fqDb.createFeedbackQuestion(invalidFq));"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" assertNull(fqDb.getFeedbackQuestion(invalidFq.getId()));"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" ______TS(\"failure: null parameter, assertion error\");"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" assertThrows(AssertionError.class, () -\u003e fqDb.createFeedbackQuestion(null));"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":87,"author":{"gitId":"-"},"content":" public void testGetFeedbackQuestionsForSession() {"},{"lineNumber":88,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":89,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d typicalDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":90,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d typicalDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":91,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d typicalDataBundle.feedbackQuestions.get(\"qn2InSession1InCourse1\");"},{"lineNumber":92,"author":{"gitId":"-"},"content":" FeedbackQuestion fq3 \u003d typicalDataBundle.feedbackQuestions.get(\"qn3InSession1InCourse1\");"},{"lineNumber":93,"author":{"gitId":"-"},"content":" FeedbackQuestion fq4 \u003d typicalDataBundle.feedbackQuestions.get(\"qn4InSession1InCourse1\");"},{"lineNumber":94,"author":{"gitId":"-"},"content":" FeedbackQuestion fq5 \u003d typicalDataBundle.feedbackQuestions.get(\"qn5InSession1InCourse1\");"},{"lineNumber":95,"author":{"gitId":"-"},"content":" FeedbackQuestion fq6 \u003d typicalDataBundle.feedbackQuestions.get(\"qn6InSession1InCourse1NoResponses\");"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e expectedQuestions \u003d List.of(fq1, fq2, fq3, fq4, fq5, fq6);"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e actualQuestions \u003d fqDb.getFeedbackQuestionsForSession(fs.getId());"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestions.size(), actualQuestions.size());"},{"lineNumber":102,"author":{"gitId":"-"},"content":" assertTrue(expectedQuestions.containsAll(actualQuestions));"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" ______TS(\"failure: session does not exist, returns no questions\");"},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":" actualQuestions \u003d fqDb.getFeedbackQuestionsForSession(UUID.randomUUID());"},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" assertEquals(0, actualQuestions.size());"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":110,"author":{"gitId":"-"},"content":" public void testGetFeedbackQuestionsForGiverType() {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":112,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d typicalDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":113,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d typicalDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":114,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d typicalDataBundle.feedbackQuestions.get(\"qn2InSession1InCourse1\");"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e expectedQuestions \u003d List.of(fq1, fq2);"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e actualQuestions \u003d fqDb.getFeedbackQuestionsForGiverType(fs, FeedbackParticipantType.STUDENTS);"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestions.size(), actualQuestions.size());"},{"lineNumber":121,"author":{"gitId":"-"},"content":" assertTrue(expectedQuestions.containsAll(actualQuestions));"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" ______TS(\"failure: session does not exist, returns no questions\");"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" fs \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" actualQuestions \u003d fqDb.getFeedbackQuestionsForGiverType(fs, FeedbackParticipantType.STUDENTS);"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" assertEquals(0, actualQuestions.size());"},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":" public void testDeleteFeedbackQuestion() {"},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion fq \u003d typicalDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" verifyPresentInDatabase(fq);"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":" fqDb.deleteFeedbackQuestion(fq.getId());"},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" assertNull(fqDb.getFeedbackQuestion(fq.getId()));"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":" ______TS(\"failure: null parameter, assertion error\");"},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" assertThrows(AssertionError.class, () -\u003e fqDb.deleteFeedbackQuestion(null));"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":143,"author":{"gitId":"-"},"content":" public void testHasFeedbackQuestionsForGiverType() {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":145,"author":{"gitId":"-"},"content":" Course course \u003d typicalDataBundle.courses.get(\"course1\");"},{"lineNumber":146,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d typicalDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" boolean actual \u003d fqDb.hasFeedbackQuestionsForGiverType("},{"lineNumber":149,"author":{"gitId":"-"},"content":" fs.getName(), course.getId(), FeedbackParticipantType.STUDENTS);"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" assertTrue(actual);"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":153,"author":{"gitId":"dishenggg"},"content":" ______TS(\"failure: session/course does not exist, returns false\");"},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":" actual \u003d fqDb.hasFeedbackQuestionsForGiverType(\"session-name\", \"course-id\", FeedbackParticipantType.STUDENTS);"},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":" assertFalse(actual);"},{"lineNumber":156,"author":{"gitId":"-"},"content":" }"},{"lineNumber":157,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":70,"-":87}},{"path":"src/it/java/teammates/it/storage/sqlapi/FeedbackResponseCommentsDbIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import java.util.HashSet;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import java.util.UUID;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackResponseCommentsDb;"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":27,"author":{"gitId":"-"},"content":" * SUT: {@link FeedbackResponseCommentsDb}."},{"lineNumber":28,"author":{"gitId":"-"},"content":" */"},{"lineNumber":29,"author":{"gitId":"-"},"content":"public class FeedbackResponseCommentsDbIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" private final FeedbackResponseCommentsDb frcDb \u003d FeedbackResponseCommentsDb.inst();"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" private SqlDataBundle testDataBundle;"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":36,"author":{"gitId":"-"},"content":" @BeforeClass"},{"lineNumber":37,"author":{"gitId":"-"},"content":" public void setupClass() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" super.setupClass();"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" testDataBundle \u003d loadSqlDataBundle(\"/FeedbackResponsesITBundle.json\");"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":43,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":44,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" persistDataBundle(testDataBundle);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" HibernateUtil.clearSession();"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":52,"author":{"gitId":"-"},"content":" public void testGetFeedbackResponseCommentForResponseFromParticipant() {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" FeedbackResponse fr \u003d testDataBundle.feedbackResponses.get(\"response1ForQ1\");"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" FeedbackResponseComment expectedComment \u003d testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ1\");"},{"lineNumber":57,"author":{"gitId":"-"},"content":" FeedbackResponseComment actualComment \u003d frcDb.getFeedbackResponseCommentForResponseFromParticipant(fr.getId());"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" assertEquals(expectedComment, actualComment);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" private FeedbackResponseComment prepareSqlInjectionTest() {"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" FeedbackResponseComment frc \u003d testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ1\");"},{"lineNumber":64,"author":{"gitId":"-"},"content":" assertNotNull(frcDb.getFeedbackResponseComment(frc.getId()));"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" return frc;"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" private void checkSqlInjectionFailed(FeedbackResponseComment frc) {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" assertNotNull(frcDb.getFeedbackResponseComment(frc.getId()));"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":74,"author":{"gitId":"-"},"content":" public void testSqlInjectionInUpdateGiverEmailOfFeedbackResponseComments() {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" FeedbackResponseComment frc \u003d prepareSqlInjectionTest();"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" String sqli \u003d \"\u0027; DELETE FROM feedback_response_comments;--\";"},{"lineNumber":78,"author":{"gitId":"-"},"content":" frcDb.updateGiverEmailOfFeedbackResponseComments(sqli, \"\", \"\");"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" checkSqlInjectionFailed(frc);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":84,"author":{"gitId":"-"},"content":" public void testSqlInjectionInUpdateLastEditorEmailOfFeedbackResponseComments() {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" FeedbackResponseComment frc \u003d prepareSqlInjectionTest();"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" String sqli \u003d \"\u0027; DELETE FROM feedback_response_comments;--\";"},{"lineNumber":88,"author":{"gitId":"-"},"content":" frcDb.updateLastEditorEmailOfFeedbackResponseComments(sqli, \"\", \"\");"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" checkSqlInjectionFailed(frc);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" }"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":94,"author":{"gitId":"-"},"content":" public void testSqlInjectionInCreateFeedbackResponseComment() throws Exception {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" FeedbackResponseComment frc \u003d prepareSqlInjectionTest();"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" FeedbackResponse fr \u003d testDataBundle.feedbackResponses.get(\"response1ForQ1\");"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" Section s \u003d testDataBundle.sections.get(\"section2InCourse1\");"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" String sqli \u003d \"\u0027\u0027);/**/DELETE/**/FROM/**/feedback_response_comments;--@gmail.com\";"},{"lineNumber":101,"author":{"gitId":"-"},"content":" FeedbackResponseComment newFrc \u003d new FeedbackResponseComment("},{"lineNumber":102,"author":{"gitId":"-"},"content":" fr, \"\", FeedbackParticipantType.INSTRUCTORS, s, s, \"\","},{"lineNumber":103,"author":{"gitId":"-"},"content":" false, false,"},{"lineNumber":104,"author":{"gitId":"-"},"content":" new ArrayList\u003c\u003e(), new ArrayList\u003c\u003e(), sqli);"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" frcDb.createFeedbackResponseComment(newFrc);"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" checkSqlInjectionFailed(frc);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" }"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":112,"author":{"gitId":"-"},"content":" public void testSqlInjectionInUpdateFeedbackResponseComment() throws Exception {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" FeedbackResponseComment frc \u003d prepareSqlInjectionTest();"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" String sqli \u003d \"\u0027\u0027);/**/DELETE/**/FROM/**/feedback_response_comments;--@gmail.com\";"},{"lineNumber":116,"author":{"gitId":"-"},"content":" frc.setLastEditorEmail(sqli);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" frcDb.updateFeedbackResponseComment(frc);"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" checkSqlInjectionFailed(frc);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" }"},{"lineNumber":121,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":122,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":123,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponseCommentsForSession_matchFound_success() {"},{"lineNumber":124,"author":{"gitId":"xenosf"},"content":" Course course \u003d testDataBundle.courses.get(\"course1\");"},{"lineNumber":125,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":126,"author":{"gitId":"xenosf"},"content":" ______TS(\"Session with comments\");"},{"lineNumber":127,"author":{"gitId":"xenosf"},"content":" FeedbackSession sessionWithComments \u003d testDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":128,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e expected \u003d List.of("},{"lineNumber":129,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ1\"),"},{"lineNumber":130,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment2ToResponse1ForQ1\"),"},{"lineNumber":131,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment2ToResponse2ForQ1\"),"},{"lineNumber":132,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ2s\"),"},{"lineNumber":133,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ3\"),"},{"lineNumber":134,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse4ForQ1\")"},{"lineNumber":135,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":136,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e results \u003d frcDb.getFeedbackResponseCommentsForSession("},{"lineNumber":137,"author":{"gitId":"xenosf"},"content":" course.getId(), sessionWithComments.getName());"},{"lineNumber":138,"author":{"gitId":"xenosf"},"content":" assertListCommentsEqual(expected, results);"},{"lineNumber":139,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":140,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":141,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":142,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponseCommentsForSession_matchNotFound_shouldReturnEmptyList() {"},{"lineNumber":143,"author":{"gitId":"xenosf"},"content":" Course course \u003d testDataBundle.courses.get(\"course1\");"},{"lineNumber":144,"author":{"gitId":"xenosf"},"content":" FeedbackSession session \u003d testDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":145,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":146,"author":{"gitId":"xenosf"},"content":" ______TS(\"Course not found\");"},{"lineNumber":147,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e results \u003d frcDb.getFeedbackResponseCommentsForSession(\"not_exist\", session.getName());"},{"lineNumber":148,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":149,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":150,"author":{"gitId":"xenosf"},"content":" ______TS(\"Session not found\");"},{"lineNumber":151,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForSession(course.getId(), \"Nonexistent session\");"},{"lineNumber":152,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":153,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":154,"author":{"gitId":"xenosf"},"content":" ______TS(\"Session without comments\");"},{"lineNumber":155,"author":{"gitId":"xenosf"},"content":" FeedbackSession sessionWithoutComments \u003d testDataBundle.feedbackSessions.get(\"ongoingSession1InCourse1\");"},{"lineNumber":156,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForSession(course.getId(), sessionWithoutComments.getName());"},{"lineNumber":157,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":158,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":159,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":160,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":161,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponseCommentsForQuestion_matchFound_success() {"},{"lineNumber":162,"author":{"gitId":"xenosf"},"content":" ______TS(\"Question with comments\");"},{"lineNumber":163,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion questionWithComments \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":164,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e expectedComments \u003d List.of("},{"lineNumber":165,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ1\"),"},{"lineNumber":166,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment2ToResponse1ForQ1\"),"},{"lineNumber":167,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment2ToResponse2ForQ1\"),"},{"lineNumber":168,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse4ForQ1\")"},{"lineNumber":169,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":170,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e results \u003d frcDb.getFeedbackResponseCommentsForQuestion(questionWithComments.getId());"},{"lineNumber":171,"author":{"gitId":"xenosf"},"content":" assertListCommentsEqual(expectedComments, results);"},{"lineNumber":172,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":173,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":174,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":175,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponseCommentsForQuestion_matchNotFound_shouldReturnEmptyList() {"},{"lineNumber":176,"author":{"gitId":"xenosf"},"content":" ______TS(\"Question not found\");"},{"lineNumber":177,"author":{"gitId":"xenosf"},"content":" UUID nonexistentQuestionId \u003d UUID.fromString(\"11110000-0000-0000-0000-000000000000\");"},{"lineNumber":178,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e results \u003d frcDb.getFeedbackResponseCommentsForQuestion(nonexistentQuestionId);"},{"lineNumber":179,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":180,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":181,"author":{"gitId":"xenosf"},"content":" ______TS(\"Question without comments\");"},{"lineNumber":182,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion questionWithoutComments \u003d testDataBundle.feedbackQuestions.get(\"qn5InSession1InCourse1\");"},{"lineNumber":183,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForQuestion(questionWithoutComments.getId());"},{"lineNumber":184,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":185,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":186,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":187,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":188,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponseCommentsForSessionInSection_matchFound_success()"},{"lineNumber":189,"author":{"gitId":"xenosf"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":190,"author":{"gitId":"xenosf"},"content":" Section section1 \u003d testDataBundle.sections.get(\"section1InCourse1\");"},{"lineNumber":191,"author":{"gitId":"xenosf"},"content":" Section section2 \u003d testDataBundle.sections.get(\"section2InCourse1\");"},{"lineNumber":192,"author":{"gitId":"xenosf"},"content":" Course course \u003d testDataBundle.courses.get(\"course1\");"},{"lineNumber":193,"author":{"gitId":"xenosf"},"content":" FeedbackSession session1 \u003d testDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":194,"author":{"gitId":"xenosf"},"content":" FeedbackSession session2 \u003d testDataBundle.feedbackSessions.get(\"session2InTypicalCourse\");"},{"lineNumber":195,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":196,"author":{"gitId":"xenosf"},"content":" ______TS(\"Section 1 Session 2 match\");"},{"lineNumber":197,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e expected \u003d List.of("},{"lineNumber":198,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ1InSession2\")"},{"lineNumber":199,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":200,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e results \u003d frcDb.getFeedbackResponseCommentsForSessionInSection("},{"lineNumber":201,"author":{"gitId":"xenosf"},"content":" course.getId(), session2.getName(), section1.getName());"},{"lineNumber":202,"author":{"gitId":"xenosf"},"content":" assertListCommentsEqual(expected, results);"},{"lineNumber":203,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":204,"author":{"gitId":"xenosf"},"content":" ______TS(\"Section 2 Session 1 match\");"},{"lineNumber":205,"author":{"gitId":"xenosf"},"content":" expected \u003d List.of("},{"lineNumber":206,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse4ForQ1\")"},{"lineNumber":207,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":208,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForSessionInSection("},{"lineNumber":209,"author":{"gitId":"xenosf"},"content":" course.getId(), session1.getName(), section2.getName());"},{"lineNumber":210,"author":{"gitId":"xenosf"},"content":" assertListCommentsEqual(expected, results);"},{"lineNumber":211,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":212,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":213,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponseCommentsForSessionInSection_matchNotFound_shouldReturnEmptyList() {"},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" Course course \u003d testDataBundle.courses.get(\"course1\");"},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" FeedbackSession session1 \u003d testDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":217,"author":{"gitId":"xenosf"},"content":" FeedbackSession session2 \u003d testDataBundle.feedbackSessions.get(\"session2InTypicalCourse\");"},{"lineNumber":218,"author":{"gitId":"xenosf"},"content":" Section section1 \u003d testDataBundle.sections.get(\"section1InCourse1\");"},{"lineNumber":219,"author":{"gitId":"xenosf"},"content":" Section section2 \u003d testDataBundle.sections.get(\"section2InCourse1\");"},{"lineNumber":220,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":221,"author":{"gitId":"xenosf"},"content":" ______TS(\"Course not found\");"},{"lineNumber":222,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e results \u003d frcDb.getFeedbackResponseCommentsForSessionInSection("},{"lineNumber":223,"author":{"gitId":"xenosf"},"content":" \"not_exist\", session1.getName(), section1.getName());"},{"lineNumber":224,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":225,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":226,"author":{"gitId":"xenosf"},"content":" ______TS(\"Session not found\");"},{"lineNumber":227,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForSessionInSection("},{"lineNumber":228,"author":{"gitId":"xenosf"},"content":" course.getId(), \"Nonexistent session\", section1.getName());"},{"lineNumber":229,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":230,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":231,"author":{"gitId":"xenosf"},"content":" ______TS(\"Section not found\");"},{"lineNumber":232,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForSessionInSection("},{"lineNumber":233,"author":{"gitId":"xenosf"},"content":" course.getId(), session1.getName(), \"Nonexistent section\");"},{"lineNumber":234,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":235,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":236,"author":{"gitId":"xenosf"},"content":" ______TS(\"No matching comments exist\");"},{"lineNumber":237,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForSessionInSection("},{"lineNumber":238,"author":{"gitId":"xenosf"},"content":" course.getId(), session2.getName(), section2.getName());"},{"lineNumber":239,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":240,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":241,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":242,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":243,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponseCommentsForQuestionInSection_matchFound_success() {"},{"lineNumber":244,"author":{"gitId":"xenosf"},"content":" Section section1 \u003d testDataBundle.sections.get(\"section1InCourse1\");"},{"lineNumber":245,"author":{"gitId":"xenosf"},"content":" Section section2 \u003d testDataBundle.sections.get(\"section2InCourse1\");"},{"lineNumber":246,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question1 \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":247,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question2 \u003d testDataBundle.feedbackQuestions.get(\"qn2InSession1InCourse1\");"},{"lineNumber":248,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":249,"author":{"gitId":"xenosf"},"content":" ______TS(\"Section 1 Question 1 match\");"},{"lineNumber":250,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e expected \u003d List.of("},{"lineNumber":251,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ1\"),"},{"lineNumber":252,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment2ToResponse1ForQ1\"),"},{"lineNumber":253,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment2ToResponse2ForQ1\"),"},{"lineNumber":254,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse4ForQ1\")"},{"lineNumber":255,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":256,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e results \u003d frcDb.getFeedbackResponseCommentsForQuestionInSection("},{"lineNumber":257,"author":{"gitId":"xenosf"},"content":" question1.getId(), section1.getName());"},{"lineNumber":258,"author":{"gitId":"xenosf"},"content":" assertListCommentsEqual(expected, results);"},{"lineNumber":259,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":260,"author":{"gitId":"xenosf"},"content":" ______TS(\"Section 2 Question 1 match\");"},{"lineNumber":261,"author":{"gitId":"xenosf"},"content":" expected \u003d List.of("},{"lineNumber":262,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse4ForQ1\")"},{"lineNumber":263,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":264,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForQuestionInSection("},{"lineNumber":265,"author":{"gitId":"xenosf"},"content":" question1.getId(), section2.getName());"},{"lineNumber":266,"author":{"gitId":"xenosf"},"content":" assertListCommentsEqual(expected, results);"},{"lineNumber":267,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":268,"author":{"gitId":"xenosf"},"content":" ______TS(\"Section 1 Question 2 match\");"},{"lineNumber":269,"author":{"gitId":"xenosf"},"content":" expected \u003d List.of("},{"lineNumber":270,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ2s\")"},{"lineNumber":271,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":272,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForQuestionInSection("},{"lineNumber":273,"author":{"gitId":"xenosf"},"content":" question2.getId(), section1.getName());"},{"lineNumber":274,"author":{"gitId":"xenosf"},"content":" assertListCommentsEqual(expected, results);"},{"lineNumber":275,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":276,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":277,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":278,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponseCommentsForQuestionInSection_matchNotFound_shouldReturnEmptyList() {"},{"lineNumber":279,"author":{"gitId":"xenosf"},"content":" Section section \u003d testDataBundle.sections.get(\"section1InCourse1\");"},{"lineNumber":280,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question1 \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":281,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question2 \u003d testDataBundle.feedbackQuestions.get(\"qn4InSession1InCourse1\");"},{"lineNumber":282,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":283,"author":{"gitId":"xenosf"},"content":" ______TS(\"Question not found\");"},{"lineNumber":284,"author":{"gitId":"xenosf"},"content":" UUID nonexistentQuestionId \u003d UUID.fromString(\"11110000-0000-0000-0000-000000000000\");"},{"lineNumber":285,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e results \u003d frcDb.getFeedbackResponseCommentsForQuestionInSection("},{"lineNumber":286,"author":{"gitId":"xenosf"},"content":" nonexistentQuestionId, section.getName());"},{"lineNumber":287,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":288,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":289,"author":{"gitId":"xenosf"},"content":" ______TS(\"Section not found\");"},{"lineNumber":290,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForQuestionInSection(question1.getId(), \"Nonexistent section\");"},{"lineNumber":291,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":292,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":293,"author":{"gitId":"xenosf"},"content":" ______TS(\"No matching comments exist\");"},{"lineNumber":294,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForQuestionInSection(question2.getId(), section.getName());"},{"lineNumber":295,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":296,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":297,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":298,"author":{"gitId":"xenosf"},"content":" private void assertListCommentsEqual(List\u003cFeedbackResponseComment\u003e expected, List\u003cFeedbackResponseComment\u003e actual) {"},{"lineNumber":299,"author":{"gitId":"xenosf"},"content":" assertTrue("},{"lineNumber":300,"author":{"gitId":"xenosf"},"content":" String.format(\"List contents are not equal.%nExpected: %s,%nActual: %s\","},{"lineNumber":301,"author":{"gitId":"xenosf"},"content":" expected.toString(), actual.toString()),"},{"lineNumber":302,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(expected).equals(new HashSet\u003c\u003e(actual)));"},{"lineNumber":303,"author":{"gitId":"xenosf"},"content":" assertEquals(\"List size not equal.\", expected.size(), actual.size());"},{"lineNumber":304,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":305,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":306,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":202,"-":104}},{"path":"src/it/java/teammates/it/storage/sqlapi/FeedbackResponsesDbIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import java.util.HashSet;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import java.util.UUID;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.FeedbackResultFetchType;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackResponseDetails;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackTextResponseDetails;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackResponseCommentsDb;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackResponsesDb;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackTextResponse;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":28,"author":{"gitId":"-"},"content":" * SUT: {@link FeedbackResponsesDb}."},{"lineNumber":29,"author":{"gitId":"-"},"content":" */"},{"lineNumber":30,"author":{"gitId":"-"},"content":"public class FeedbackResponsesDbIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" private final FeedbackResponsesDb frDb \u003d FeedbackResponsesDb.inst();"},{"lineNumber":33,"author":{"gitId":"-"},"content":" private final FeedbackResponseCommentsDb frcDb \u003d FeedbackResponseCommentsDb.inst();"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" private SqlDataBundle testDataBundle;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"-"},"content":" @BeforeClass"},{"lineNumber":39,"author":{"gitId":"-"},"content":" public void setupClass() {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" super.setupClass();"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" testDataBundle \u003d loadSqlDataBundle(\"/FeedbackResponsesITBundle.json\");"},{"lineNumber":42,"author":{"gitId":"-"},"content":" }"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":45,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":46,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" persistDataBundle(testDataBundle);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":50,"author":{"gitId":"-"},"content":" HibernateUtil.clearSession();"},{"lineNumber":51,"author":{"gitId":"-"},"content":" }"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":54,"author":{"gitId":"-"},"content":" public void testGetFeedbackResponsesFromGiverForQuestion() {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion fq \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e expectedQuestions \u003d List.of("},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response1ForQ1\"),"},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response3ForQ1\")"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponse\u003e actualQuestions \u003d"},{"lineNumber":64,"author":{"gitId":"-"},"content":" frDb.getFeedbackResponsesFromGiverForQuestion(fq.getId(), \"student1@teammates.tmt\");"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestions.size(), actualQuestions.size());"},{"lineNumber":67,"author":{"gitId":"-"},"content":" assertTrue(expectedQuestions.containsAll(actualQuestions));"},{"lineNumber":68,"author":{"gitId":"-"},"content":" }"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":71,"author":{"gitId":"-"},"content":" public void testDeleteFeedbackResponsesForQuestionCascade() {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion fq \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" FeedbackResponse fr1 \u003d testDataBundle.feedbackResponses.get(\"response1ForQ1\");"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" FeedbackResponse fr2 \u003d testDataBundle.feedbackResponses.get(\"response2ForQ1\");"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" FeedbackResponseComment frc1 \u003d testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ1\");"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" frDb.deleteFeedbackResponsesForQuestionCascade(fq.getId());"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" assertNull(frDb.getFeedbackResponse(fr1.getId()));"},{"lineNumber":81,"author":{"gitId":"-"},"content":" assertNull(frDb.getFeedbackResponse(fr2.getId()));"},{"lineNumber":82,"author":{"gitId":"-"},"content":" assertNull(frcDb.getFeedbackResponseComment(frc1.getId()));"},{"lineNumber":83,"author":{"gitId":"-"},"content":" }"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":86,"author":{"gitId":"-"},"content":" public void testDeleteFeedback() {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" FeedbackResponse fr1 \u003d testDataBundle.feedbackResponses.get(\"response1ForQ1\");"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" frDb.deleteFeedbackResponse(fr1);"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" assertNull(frDb.getFeedbackResponse(fr1.getId()));"},{"lineNumber":93,"author":{"gitId":"-"},"content":" }"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":96,"author":{"gitId":"-"},"content":" public void testHasResponsesFromGiverInSession() {"},{"lineNumber":97,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" Course course \u003d testDataBundle.courses.get(\"course1\");"},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" FeedbackSession fs \u003d testDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" boolean actualHasReponses1 \u003d"},{"lineNumber":102,"author":{"gitId":"-"},"content":" frDb.hasResponsesFromGiverInSession(\"student1@teammates.tmt\", fs.getName(), course.getId());"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" assertTrue(actualHasReponses1);"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" ______TS(\"student with no responses\");"},{"lineNumber":107,"author":{"gitId":"-"},"content":" boolean actualHasReponses2 \u003d"},{"lineNumber":108,"author":{"gitId":"-"},"content":" frDb.hasResponsesFromGiverInSession(\"studentnorespones@teammates.tmt\", fs.getName(), course.getId());"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" assertFalse(actualHasReponses2);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":114,"author":{"gitId":"-"},"content":" public void testAreThereResponsesForQuestion() {"},{"lineNumber":115,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion fq1 \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" boolean actualResponse1 \u003d"},{"lineNumber":119,"author":{"gitId":"-"},"content":" frDb.areThereResponsesForQuestion(fq1.getId());"},{"lineNumber":120,"author":{"gitId":"-"},"content":""},{"lineNumber":121,"author":{"gitId":"-"},"content":" assertTrue(actualResponse1);"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" ______TS(\"feedback question with no responses\");"},{"lineNumber":124,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion fq2 \u003d testDataBundle.feedbackQuestions.get(\"qn6InSession1InCourse1NoResponses\");"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" boolean actualResponse2 \u003d"},{"lineNumber":127,"author":{"gitId":"-"},"content":" frDb.areThereResponsesForQuestion(fq2.getId());"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" assertFalse(actualResponse2);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" }"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":133,"author":{"gitId":"-"},"content":" public void testHasResponsesForCourse() {"},{"lineNumber":134,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":135,"author":{"gitId":"xenosf"},"content":" Course course \u003d testDataBundle.courses.get(\"course1\");"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" boolean actual \u003d"},{"lineNumber":138,"author":{"gitId":"-"},"content":" frDb.hasResponsesForCourse(course.getId());"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" assertTrue(actual);"},{"lineNumber":141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" private FeedbackResponse prepareSqlInjectionTest() {"},{"lineNumber":144,"author":{"gitId":"xenosf"},"content":" FeedbackResponse fr \u003d testDataBundle.feedbackResponses.get(\"response1ForQ1\");"},{"lineNumber":145,"author":{"gitId":"-"},"content":" assertNotNull(frDb.getFeedbackResponse(fr.getId()));"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" return fr;"},{"lineNumber":148,"author":{"gitId":"-"},"content":" }"},{"lineNumber":149,"author":{"gitId":"-"},"content":""},{"lineNumber":150,"author":{"gitId":"-"},"content":" private void checkSqliFailed(FeedbackResponse fr) {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" // If SQLi is successful, feedback responses would have been deleted from db."},{"lineNumber":152,"author":{"gitId":"-"},"content":" // So get will return null."},{"lineNumber":153,"author":{"gitId":"-"},"content":" assertNotNull(frDb.getFeedbackResponse(fr.getId()));"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":157,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetFeedbackResponsesFromGiverForCourse() {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" FeedbackResponse fr \u003d prepareSqlInjectionTest();"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in GetFeedbackResponsesFromGiverForCourse, courseId param\");"},{"lineNumber":161,"author":{"gitId":"-"},"content":" String courseId \u003d \"\u0027; DELETE FROM feedback_responses;--\";"},{"lineNumber":162,"author":{"gitId":"-"},"content":" frDb.getFeedbackResponsesFromGiverForCourse(courseId, \"\");"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" checkSqliFailed(fr);"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":168,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetFeedbackResponsesForRecipientForCourse() {"},{"lineNumber":169,"author":{"gitId":"-"},"content":" FeedbackResponse fr \u003d prepareSqlInjectionTest();"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in GetFeedbackResponsesForRecipientForCourse, courseId param\");"},{"lineNumber":172,"author":{"gitId":"-"},"content":" String courseId \u003d \"\u0027; DELETE FROM feedback_responses;--\";"},{"lineNumber":173,"author":{"gitId":"-"},"content":" frDb.getFeedbackResponsesForRecipientForCourse(courseId, \"\");"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" checkSqliFailed(fr);"},{"lineNumber":176,"author":{"gitId":"-"},"content":" }"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":179,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetFeedbackResponsesFromGiverForQuestion() {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" FeedbackResponse fr \u003d prepareSqlInjectionTest();"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in GetFeedbackResponsesFromGiverForQuestion, giverEmail param\");"},{"lineNumber":183,"author":{"gitId":"-"},"content":" String giverEmail \u003d \"\u0027;/**/DELETE/**/FROM/**/feedback_responses;--@gmail.com\";"},{"lineNumber":184,"author":{"gitId":"-"},"content":" frDb.getFeedbackResponsesFromGiverForQuestion(fr.getId(), giverEmail);"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" checkSqliFailed(fr);"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":190,"author":{"gitId":"-"},"content":" public void testSqlInjectionInHasResponsesFromGiverInSession() {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" FeedbackResponse fr \u003d prepareSqlInjectionTest();"},{"lineNumber":192,"author":{"gitId":"-"},"content":""},{"lineNumber":193,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in HasResponsesFromGiverInSession, giver param\");"},{"lineNumber":194,"author":{"gitId":"-"},"content":" String giver \u003d \"\u0027; DELETE FROM feedback_responses;--\";"},{"lineNumber":195,"author":{"gitId":"-"},"content":" frDb.hasResponsesFromGiverInSession(giver, \"\", \"\");"},{"lineNumber":196,"author":{"gitId":"-"},"content":""},{"lineNumber":197,"author":{"gitId":"-"},"content":" checkSqliFailed(fr);"},{"lineNumber":198,"author":{"gitId":"-"},"content":" }"},{"lineNumber":199,"author":{"gitId":"-"},"content":""},{"lineNumber":200,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":201,"author":{"gitId":"-"},"content":" public void testSqlInjectionInHasResponsesForCourse() {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" FeedbackResponse fr \u003d prepareSqlInjectionTest();"},{"lineNumber":203,"author":{"gitId":"-"},"content":""},{"lineNumber":204,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in HasResponsesForCourse, courseId param\");"},{"lineNumber":205,"author":{"gitId":"-"},"content":" String courseId \u003d \"\u0027; DELETE FROM feedback_responses;--\";"},{"lineNumber":206,"author":{"gitId":"-"},"content":" frDb.hasResponsesForCourse(courseId);"},{"lineNumber":207,"author":{"gitId":"-"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" checkSqliFailed(fr);"},{"lineNumber":209,"author":{"gitId":"-"},"content":" }"},{"lineNumber":210,"author":{"gitId":"-"},"content":""},{"lineNumber":211,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":212,"author":{"gitId":"-"},"content":" public void testSqlInjectionInCreateFeedbackResponse() throws Exception {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" FeedbackResponse fr \u003d prepareSqlInjectionTest();"},{"lineNumber":214,"author":{"gitId":"-"},"content":""},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion fq \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" Section s \u003d testDataBundle.sections.get(\"section1InCourse1\");"},{"lineNumber":217,"author":{"gitId":"-"},"content":" String dummyUuid \u003d \"00000000-0000-4000-8000-000000000001\";"},{"lineNumber":218,"author":{"gitId":"-"},"content":" FeedbackResponseDetails frd \u003d new FeedbackTextResponseDetails();"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" String sqli \u003d \"\u0027, \" + dummyUuid + \", \" + dummyUuid + \"); DELETE FROM feedback_responses;--\";"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"-"},"content":" FeedbackResponse newFr \u003d new FeedbackTextResponse(fq, \"\", s, sqli, s, frd);"},{"lineNumber":223,"author":{"gitId":"-"},"content":" frDb.createFeedbackResponse(newFr);"},{"lineNumber":224,"author":{"gitId":"-"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":" checkSqliFailed(fr);"},{"lineNumber":226,"author":{"gitId":"-"},"content":" }"},{"lineNumber":227,"author":{"gitId":"-"},"content":""},{"lineNumber":228,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":229,"author":{"gitId":"-"},"content":" public void testSqlInjectionInCpdateFeedbackResponse() throws Exception {"},{"lineNumber":230,"author":{"gitId":"-"},"content":" FeedbackResponse fr \u003d prepareSqlInjectionTest();"},{"lineNumber":231,"author":{"gitId":"-"},"content":""},{"lineNumber":232,"author":{"gitId":"-"},"content":" String sqli \u003d \"\u0027\u0027); DELETE FROM feedback_response_comments;--\";"},{"lineNumber":233,"author":{"gitId":"-"},"content":" fr.setGiver(sqli);"},{"lineNumber":234,"author":{"gitId":"-"},"content":" frDb.updateFeedbackResponse(fr);"},{"lineNumber":235,"author":{"gitId":"-"},"content":""},{"lineNumber":236,"author":{"gitId":"-"},"content":" checkSqliFailed(fr);"},{"lineNumber":237,"author":{"gitId":"-"},"content":" }"},{"lineNumber":238,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":239,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":240,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponsesForRecipientForQuestion_matchNotFound_shouldReturnEmptyList() {"},{"lineNumber":241,"author":{"gitId":"xenosf"},"content":" ______TS(\"Question not found\");"},{"lineNumber":242,"author":{"gitId":"xenosf"},"content":" String recipient \u003d \"student1@teammates.tmt\";"},{"lineNumber":243,"author":{"gitId":"xenosf"},"content":" UUID nonexistentQuestionId \u003d UUID.fromString(\"11110000-0000-0000-0000-000000000000\");"},{"lineNumber":244,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e results \u003d frDb.getFeedbackResponsesForRecipientForQuestion(nonexistentQuestionId, recipient);"},{"lineNumber":245,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":246,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":247,"author":{"gitId":"xenosf"},"content":" ______TS(\"No matching responses exist\");"},{"lineNumber":248,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion questionWithNoResponses \u003d testDataBundle.feedbackQuestions.get(\"qn4InSession1InCourse1\");"},{"lineNumber":249,"author":{"gitId":"xenosf"},"content":" results \u003d frDb.getFeedbackResponsesForRecipientForQuestion(questionWithNoResponses.getId(), recipient);"},{"lineNumber":250,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":251,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":252,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":253,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":254,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":255,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponsesForRecipientForQuestion_matchFound_success() {"},{"lineNumber":256,"author":{"gitId":"xenosf"},"content":" ______TS(\"Matching responses exist\");"},{"lineNumber":257,"author":{"gitId":"xenosf"},"content":" String recipient \u003d \"student2@teammates.tmt\";"},{"lineNumber":258,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":259,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e expected \u003d List.of("},{"lineNumber":260,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response2ForQ1\")"},{"lineNumber":261,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":262,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e actual \u003d frDb.getFeedbackResponsesForRecipientForQuestion(question.getId(), recipient);"},{"lineNumber":263,"author":{"gitId":"xenosf"},"content":" assertListResponsesEqual(expected, actual);"},{"lineNumber":264,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":265,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":266,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":267,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":268,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponsesForSessionInSection_matchNotFound_shouldReturnEmptyList() {"},{"lineNumber":269,"author":{"gitId":"xenosf"},"content":" String section3 \u003d testDataBundle.sections.get(\"section3InCourse1\").getName();"},{"lineNumber":270,"author":{"gitId":"xenosf"},"content":" FeedbackSession session \u003d testDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":271,"author":{"gitId":"xenosf"},"content":" String courseId \u003d session.getCourse().getId();"},{"lineNumber":272,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":273,"author":{"gitId":"xenosf"},"content":" ______TS(\"No matching responses exist for giver section\");"},{"lineNumber":274,"author":{"gitId":"xenosf"},"content":" FeedbackResultFetchType fetchType \u003d FeedbackResultFetchType.GIVER;"},{"lineNumber":275,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e results \u003d frDb.getFeedbackResponsesForSessionInSection("},{"lineNumber":276,"author":{"gitId":"xenosf"},"content":" session, courseId, section3, fetchType);"},{"lineNumber":277,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":278,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":279,"author":{"gitId":"xenosf"},"content":" ______TS(\"No matching responses exist for recipient section\");"},{"lineNumber":280,"author":{"gitId":"xenosf"},"content":" fetchType \u003d FeedbackResultFetchType.RECEIVER;"},{"lineNumber":281,"author":{"gitId":"xenosf"},"content":" results \u003d frDb.getFeedbackResponsesForSessionInSection(session, courseId, section3, fetchType);"},{"lineNumber":282,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":283,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":284,"author":{"gitId":"xenosf"},"content":" ______TS(\"No matching responses exist for both giver and recipient section\");"},{"lineNumber":285,"author":{"gitId":"xenosf"},"content":" fetchType \u003d FeedbackResultFetchType.BOTH;"},{"lineNumber":286,"author":{"gitId":"xenosf"},"content":" results \u003d frDb.getFeedbackResponsesForSessionInSection(session, courseId, section3, fetchType);"},{"lineNumber":287,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":288,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":289,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":290,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":291,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponsesForSessionInSection_matchFound_success() {"},{"lineNumber":292,"author":{"gitId":"xenosf"},"content":" Course course \u003d testDataBundle.courses.get(\"course1\");"},{"lineNumber":293,"author":{"gitId":"xenosf"},"content":" FeedbackSession session1 \u003d testDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":294,"author":{"gitId":"xenosf"},"content":" Section section1 \u003d testDataBundle.sections.get(\"section1InCourse1\");"},{"lineNumber":295,"author":{"gitId":"xenosf"},"content":" Section section2 \u003d testDataBundle.sections.get(\"section2InCourse1\");"},{"lineNumber":296,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":297,"author":{"gitId":"xenosf"},"content":" ______TS(\"Match giver section 1 in session 1\");"},{"lineNumber":298,"author":{"gitId":"xenosf"},"content":" FeedbackResultFetchType fetchType \u003d FeedbackResultFetchType.GIVER;"},{"lineNumber":299,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e expected \u003d List.of("},{"lineNumber":300,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response1ForQ1\"),"},{"lineNumber":301,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response2ForQ1\"),"},{"lineNumber":302,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response1ForQ2\"),"},{"lineNumber":303,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response2ForQ2\"),"},{"lineNumber":304,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response1ForQ3\"),"},{"lineNumber":305,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response3ForQ1\"),"},{"lineNumber":306,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response3ForQ2\")"},{"lineNumber":307,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":308,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e actual \u003d frDb.getFeedbackResponsesForSessionInSection("},{"lineNumber":309,"author":{"gitId":"xenosf"},"content":" session1, course.getId(), section1.getName(), fetchType);"},{"lineNumber":310,"author":{"gitId":"xenosf"},"content":" assertListResponsesEqual(expected, actual);"},{"lineNumber":311,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":312,"author":{"gitId":"xenosf"},"content":" ______TS(\"Match recipient section 2 in session 1\");"},{"lineNumber":313,"author":{"gitId":"xenosf"},"content":" fetchType \u003d FeedbackResultFetchType.RECEIVER;"},{"lineNumber":314,"author":{"gitId":"xenosf"},"content":" expected \u003d List.of("},{"lineNumber":315,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response3ForQ1\"),"},{"lineNumber":316,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response3ForQ2\"),"},{"lineNumber":317,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response4ForQ1\")"},{"lineNumber":318,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":319,"author":{"gitId":"xenosf"},"content":" actual \u003d frDb.getFeedbackResponsesForSessionInSection(session1, course.getId(),"},{"lineNumber":320,"author":{"gitId":"xenosf"},"content":" section2.getName(), fetchType);"},{"lineNumber":321,"author":{"gitId":"xenosf"},"content":" assertListResponsesEqual(expected, actual);"},{"lineNumber":322,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":323,"author":{"gitId":"xenosf"},"content":" ______TS(\"Match both giver and recipient section 2 in session 1\");"},{"lineNumber":324,"author":{"gitId":"xenosf"},"content":" fetchType \u003d FeedbackResultFetchType.BOTH;"},{"lineNumber":325,"author":{"gitId":"xenosf"},"content":" expected \u003d List.of("},{"lineNumber":326,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response4ForQ1\")"},{"lineNumber":327,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":328,"author":{"gitId":"xenosf"},"content":" actual \u003d frDb.getFeedbackResponsesForSessionInSection(session1, course.getId(),"},{"lineNumber":329,"author":{"gitId":"xenosf"},"content":" section2.getName(), fetchType);"},{"lineNumber":330,"author":{"gitId":"xenosf"},"content":" assertListResponsesEqual(expected, actual);"},{"lineNumber":331,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":332,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":333,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":334,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponsesForQuestionInSection_matchNotFound_shouldReturnEmptyList() {"},{"lineNumber":335,"author":{"gitId":"xenosf"},"content":" String section1 \u003d testDataBundle.sections.get(\"section1InCourse1\").getName();"},{"lineNumber":336,"author":{"gitId":"xenosf"},"content":" String section3 \u003d testDataBundle.sections.get(\"section3InCourse1\").getName();"},{"lineNumber":337,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":338,"author":{"gitId":"xenosf"},"content":" ______TS(\"Question not found\");"},{"lineNumber":339,"author":{"gitId":"xenosf"},"content":" UUID nonexistentQuestionId \u003d UUID.fromString(\"11110000-0000-0000-0000-000000000000\");"},{"lineNumber":340,"author":{"gitId":"xenosf"},"content":" FeedbackResultFetchType fetchType \u003d FeedbackResultFetchType.BOTH;"},{"lineNumber":341,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e results \u003d frDb.getFeedbackResponsesForQuestionInSection(nonexistentQuestionId,"},{"lineNumber":342,"author":{"gitId":"xenosf"},"content":" section1, fetchType);"},{"lineNumber":343,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":344,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":345,"author":{"gitId":"xenosf"},"content":" ______TS(\"No matching responses exist for giver section\");"},{"lineNumber":346,"author":{"gitId":"xenosf"},"content":" UUID questionId \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\").getId();"},{"lineNumber":347,"author":{"gitId":"xenosf"},"content":" fetchType \u003d FeedbackResultFetchType.GIVER;"},{"lineNumber":348,"author":{"gitId":"xenosf"},"content":" results \u003d frDb.getFeedbackResponsesForQuestionInSection(questionId, section3, fetchType);"},{"lineNumber":349,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":350,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":351,"author":{"gitId":"xenosf"},"content":" ______TS(\"No matching responses exist for recipient section\");"},{"lineNumber":352,"author":{"gitId":"xenosf"},"content":" fetchType \u003d FeedbackResultFetchType.RECEIVER;"},{"lineNumber":353,"author":{"gitId":"xenosf"},"content":" results \u003d frDb.getFeedbackResponsesForQuestionInSection(questionId, section3, fetchType);"},{"lineNumber":354,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":355,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":356,"author":{"gitId":"xenosf"},"content":" ______TS(\"No matching responses exist for both giver and recipient section\");"},{"lineNumber":357,"author":{"gitId":"xenosf"},"content":" fetchType \u003d FeedbackResultFetchType.BOTH;"},{"lineNumber":358,"author":{"gitId":"xenosf"},"content":" results \u003d frDb.getFeedbackResponsesForQuestionInSection(questionId, section3, fetchType);"},{"lineNumber":359,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":360,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":361,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":362,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":363,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponsesForQuestionInSection_matchFound_success() {"},{"lineNumber":364,"author":{"gitId":"xenosf"},"content":" Section section1 \u003d testDataBundle.sections.get(\"section1InCourse1\");"},{"lineNumber":365,"author":{"gitId":"xenosf"},"content":" Section section2 \u003d testDataBundle.sections.get(\"section2InCourse1\");"},{"lineNumber":366,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question1 \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":367,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":368,"author":{"gitId":"xenosf"},"content":" ______TS(\"Match giver section 1 for Q1\");"},{"lineNumber":369,"author":{"gitId":"xenosf"},"content":" FeedbackResultFetchType fetchType \u003d FeedbackResultFetchType.GIVER;"},{"lineNumber":370,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e expected \u003d List.of("},{"lineNumber":371,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response1ForQ1\"),"},{"lineNumber":372,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response2ForQ1\"),"},{"lineNumber":373,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response3ForQ1\")"},{"lineNumber":374,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":375,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e actual \u003d frDb.getFeedbackResponsesForQuestionInSection(question1.getId(),"},{"lineNumber":376,"author":{"gitId":"xenosf"},"content":" section1.getName(), fetchType);"},{"lineNumber":377,"author":{"gitId":"xenosf"},"content":" assertListResponsesEqual(expected, actual);"},{"lineNumber":378,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":379,"author":{"gitId":"xenosf"},"content":" ______TS(\"Match recipient section 2 for Q1\");"},{"lineNumber":380,"author":{"gitId":"xenosf"},"content":" fetchType \u003d FeedbackResultFetchType.RECEIVER;"},{"lineNumber":381,"author":{"gitId":"xenosf"},"content":" expected \u003d List.of("},{"lineNumber":382,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response3ForQ1\"),"},{"lineNumber":383,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response4ForQ1\")"},{"lineNumber":384,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":385,"author":{"gitId":"xenosf"},"content":" actual \u003d frDb.getFeedbackResponsesForQuestionInSection(question1.getId(), section2.getName(), fetchType);"},{"lineNumber":386,"author":{"gitId":"xenosf"},"content":" assertListResponsesEqual(expected, actual);"},{"lineNumber":387,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":388,"author":{"gitId":"xenosf"},"content":" ______TS(\"Match both giver and recipient section 2 for Q1\");"},{"lineNumber":389,"author":{"gitId":"xenosf"},"content":" fetchType \u003d FeedbackResultFetchType.BOTH;"},{"lineNumber":390,"author":{"gitId":"xenosf"},"content":" expected \u003d List.of("},{"lineNumber":391,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response4ForQ1\")"},{"lineNumber":392,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":393,"author":{"gitId":"xenosf"},"content":" actual \u003d frDb.getFeedbackResponsesForQuestionInSection(question1.getId(), section2.getName(), fetchType);"},{"lineNumber":394,"author":{"gitId":"xenosf"},"content":" assertListResponsesEqual(expected, actual);"},{"lineNumber":395,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":396,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":397,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":398,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponsesForSession() {"},{"lineNumber":399,"author":{"gitId":"xenosf"},"content":" ______TS(\"Session has responses\");"},{"lineNumber":400,"author":{"gitId":"xenosf"},"content":" FeedbackSession sessionWithResponses \u003d testDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":401,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e expected \u003d List.of("},{"lineNumber":402,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response1ForQ1\"),"},{"lineNumber":403,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response2ForQ1\"),"},{"lineNumber":404,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response1ForQ2\"),"},{"lineNumber":405,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response2ForQ2\"),"},{"lineNumber":406,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response1ForQ3\"),"},{"lineNumber":407,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response3ForQ1\"),"},{"lineNumber":408,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response3ForQ2\"),"},{"lineNumber":409,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response4ForQ1\")"},{"lineNumber":410,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":411,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e actual \u003d frDb.getFeedbackResponsesForSession(sessionWithResponses,"},{"lineNumber":412,"author":{"gitId":"xenosf"},"content":" sessionWithResponses.getCourse().getId());"},{"lineNumber":413,"author":{"gitId":"xenosf"},"content":" assertListResponsesEqual(expected, actual);"},{"lineNumber":414,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":415,"author":{"gitId":"xenosf"},"content":" ______TS(\"Session has no responses\");"},{"lineNumber":416,"author":{"gitId":"xenosf"},"content":" FeedbackSession sessionWithoutResponses \u003d testDataBundle.feedbackSessions.get("},{"lineNumber":417,"author":{"gitId":"xenosf"},"content":" \"unpublishedSession1InTypicalCourse\");"},{"lineNumber":418,"author":{"gitId":"xenosf"},"content":" actual \u003d frDb.getFeedbackResponsesForSession(sessionWithoutResponses, sessionWithResponses.getCourse().getId());"},{"lineNumber":419,"author":{"gitId":"xenosf"},"content":" assertEquals(0, actual.size());"},{"lineNumber":420,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":421,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":422,"author":{"gitId":"xenosf"},"content":" private void assertListResponsesEqual(List\u003cFeedbackResponse\u003e expected, List\u003cFeedbackResponse\u003e actual) {"},{"lineNumber":423,"author":{"gitId":"xenosf"},"content":" assertEquals(\"List size not equal.\", expected.size(), actual.size());"},{"lineNumber":424,"author":{"gitId":"xenosf"},"content":" assertTrue("},{"lineNumber":425,"author":{"gitId":"xenosf"},"content":" String.format(\"List contents are not equal.%nExpected: %s,%nActual: %s\","},{"lineNumber":426,"author":{"gitId":"xenosf"},"content":" expected.toString(), actual.toString()),"},{"lineNumber":427,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(expected).equals(new HashSet\u003c\u003e(actual)));"},{"lineNumber":428,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":429,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":215,"-":214}},{"path":"src/it/java/teammates/it/storage/sqlapi/FeedbackSessionLogsDbIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.it.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlapi.FeedbackSessionLogsDb;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link FeedbackSessionLogsDb}."},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":"public class FeedbackSessionLogsDbIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" private final FeedbackSessionLogsDb fslDb \u003d FeedbackSessionLogsDb.inst();"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" private SqlDataBundle typicalDataBundle;"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" @BeforeClass"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" public void setupClass() {"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" super.setupClass();"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" typicalDataBundle \u003d getTypicalSqlDataBundle();"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" @BeforeMethod"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" protected void setUp() throws Exception {"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" super.setUp();"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" persistDataBundle(typicalDataBundle);"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" HibernateUtil.flushSession();"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" public void test_createFeedbackSessionLog_success() {"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" Course course \u003d typicalDataBundle.courses.get(\"course1\");"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d typicalDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" Student student \u003d typicalDataBundle.students.get(\"student1InCourse1\");"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" Instant logTimestamp \u003d Instant.parse(\"2011-01-01T00:00:00Z\");"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog expected \u003d new FeedbackSessionLog(student, feedbackSession, FeedbackSessionLogType.ACCESS,"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" logTimestamp);"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" fslDb.createFeedbackSessionLog(expected);"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e actualLogs \u003d fslDb.getOrderedFeedbackSessionLogs(course.getId(), student.getId(),"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" feedbackSession.getId(), logTimestamp, logTimestamp.plusSeconds(1));"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" assertEquals(actualLogs.size(), 1);"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" assertEquals(expected, actualLogs.get(0));"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" public void test_getOrderedFeedbackSessionLogs_success() {"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" Instant startTime \u003d Instant.parse(\"2012-01-01T12:00:00Z\");"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" Instant endTime \u003d Instant.parse(\"2012-01-01T23:59:59Z\");"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" Course course \u003d typicalDataBundle.courses.get(\"course1\");"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" Student student1 \u003d typicalDataBundle.students.get(\"student1InCourse1\");"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" FeedbackSession fs1 \u003d typicalDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student1Session1Log1 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student1Session1Log1\");"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student1Session2Log1 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student1Session2Log1\");"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student1Session2Log2 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student1Session2Log2\");"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student2Session1Log1 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student2Session1Log1\");"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student2Session1Log2 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student2Session1Log2\");"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Return logs belonging to a course in time range\");"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e expectedLogs \u003d List.of("},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" student1Session1Log1,"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":" student1Session2Log1,"},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" student1Session2Log2,"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" student2Session1Log1,"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" student2Session1Log2"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" );"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e actualLogs \u003d fslDb.getOrderedFeedbackSessionLogs(course.getId(), null, null,"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" startTime, endTime);"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Return logs belonging to a student in time range\");"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":" expectedLogs \u003d List.of("},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" student1Session1Log1,"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" student1Session2Log1,"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" student1Session2Log2);"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" actualLogs \u003d fslDb.getOrderedFeedbackSessionLogs(course.getId(), student1.getId(), null, startTime, endTime);"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Return logs belonging to a feedback session in time range\");"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":" expectedLogs \u003d List.of("},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" student1Session1Log1,"},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":" student2Session1Log1,"},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" student2Session1Log2);"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" actualLogs \u003d fslDb.getOrderedFeedbackSessionLogs(course.getId(), null, fs1.getId(), startTime, endTime);"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Return logs belonging to a student in a feedback session in time range\");"},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" expectedLogs \u003d List.of(student1Session1Log1);"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" actualLogs \u003d fslDb.getOrderedFeedbackSessionLogs(course.getId(), student1.getId(), fs1.getId(), startTime,"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" endTime);"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" ______TS(\"No logs in time range, return empty list\");"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" expectedLogs \u003d new ArrayList\u003c\u003e();"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" actualLogs \u003d fslDb.getOrderedFeedbackSessionLogs(course.getId(), null, null, endTime.plusSeconds(3600),"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" endTime.plusSeconds(7200));"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":128}},{"path":"src/it/java/teammates/it/storage/sqlsearch/AccountRequestSearchIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.it.storage.sqlsearch;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.Arrays;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.Test;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlapi.AccountRequestsDb;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"import teammates.test.AssertHelper;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import teammates.test.TestProperties;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" * SUT: {@link AccountRequestsDb},"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" * {@link teammates.storage.search.AccountRequestSearchDocument}."},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":"public class AccountRequestSearchIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" private final SqlDataBundle typicalBundle \u003d getTypicalSqlDataBundle();"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" private final AccountRequestsDb accountRequestsDb \u003d AccountRequestsDb.inst();"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" @BeforeMethod"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" protected void setUp() throws Exception {"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" super.setUp();"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" putDocuments(typicalBundle);"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.flushSession();"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" public void allTests() throws Exception {"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" return;"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins1General \u003d typicalBundle.accountRequests.get(\"instructor1\");"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins2General \u003d typicalBundle.accountRequests.get(\"instructor2\");"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins1InCourse1 \u003d typicalBundle.accountRequests.get(\"instructor1OfCourse1\");"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins2InCourse1 \u003d typicalBundle.accountRequests.get(\"instructor2OfCourse1\");"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins1InCourse2 \u003d typicalBundle.accountRequests.get(\"instructor1OfCourse2\");"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins2InCourse2 \u003d typicalBundle.accountRequests.get(\"instructor2OfCourse2\");"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins1InCourse3 \u003d typicalBundle.accountRequests.get(\"instructor1OfCourse3\");"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins2InCourse3 \u003d typicalBundle.accountRequests.get(\"instructor2OfCourse3\");"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" AccountRequest insInUnregCourse \u003d typicalBundle.accountRequests.get(\"instructor3\");"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" AccountRequest unregisteredInstructor1 \u003d"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" typicalBundle.accountRequests.get(\"unregisteredInstructor1\");"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" AccountRequest unregisteredInstructor2 \u003d"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" typicalBundle.accountRequests.get(\"unregisteredInstructor2\");"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; query string does not match anyone\");"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" List\u003cAccountRequest\u003e results \u003d"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" accountRequestsDb.searchAccountRequestsInWholeSystem(\"non-existent\");"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results);"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; empty query string does not match anyone\");"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\");"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results);"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; query string matches some account requests\");"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"Instructor 1\\\"\");"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, ins1InCourse1, ins1InCourse2, ins1InCourse3, unregisteredInstructor1, ins1General);"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; query string should be case-insensitive\");"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"InStRuCtOr 2\\\"\");"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, ins2InCourse1, ins2InCourse2, ins2InCourse3, unregisteredInstructor2, ins2General);"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; account requests should be searchable by their name\");"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"Instructor 3 of CourseNoRegister\\\"\");"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, insInUnregCourse);"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; account requests should be searchable by their email\");"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"instr2@course2.tmt\");"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, ins2InCourse2);"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; account requests should be searchable by their institute\");"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"TEAMMATES Test Institute 2\\\"\");"},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, unregisteredInstructor2);"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" ______TS(\"success: search for account requests; account requests should be searchable by their comments\");"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"Comments for account request from instructor2\");"},{"lineNumber":95,"author":{"gitId":"-"},"content":" verifySearchResults(results, ins2General);"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" ______TS(\"success: search for account requests; account requests should be searchable by their status\");"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"registered\");"},{"lineNumber":100,"author":{"gitId":"-"},"content":" verifySearchResults(results, ins2General);"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; unregistered account requests should be searchable\");"},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"unregisteredinstructor1@gmail.tmt\\\"\");"},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, unregisteredInstructor1);"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; deleted account requests no longer searchable\");"},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" accountRequestsDb.deleteAccountRequest(ins1InCourse1);"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"instructor 1\\\"\");"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, ins1InCourse2, ins1InCourse3, unregisteredInstructor1, ins1General);"},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; account requests created without searchability unsearchable\");"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" accountRequestsDb.createAccountRequest(ins1InCourse1);"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"instructor 1\\\"\");"},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, ins1InCourse2, ins1InCourse3, unregisteredInstructor1, ins1General);"},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; deleting account request without deleting document:\""},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" + \"document deleted during search, account request unsearchable\");"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" accountRequestsDb.deleteAccountRequest(ins2InCourse1);"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"instructor 2\\\"\");"},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, ins2InCourse2, ins2InCourse3, unregisteredInstructor2, ins2General);"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":128,"author":{"gitId":"domoberzin"},"content":" public void testSearchAccountRequest_deleteAfterSearch_shouldNotBeSearchable() throws Exception {"},{"lineNumber":129,"author":{"gitId":"domoberzin"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":" return;"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins1InCourse2 \u003d typicalBundle.accountRequests.get(\"instructor1OfCourse2\");"},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins2InCourse2 \u003d typicalBundle.accountRequests.get(\"instructor2OfCourse2\");"},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" // there is search result before deletion"},{"lineNumber":137,"author":{"gitId":"domoberzin"},"content":" List\u003cAccountRequest\u003e results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"of Course 2\\\"\");"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, ins1InCourse2, ins2InCourse2);"},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":140,"author":{"gitId":"domoberzin"},"content":" // delete an account request"},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":" accountRequestsDb.deleteAccountRequest(ins1InCourse2);"},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":" // the search result will change"},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"of Course 2\\\"\");"},{"lineNumber":145,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, ins2InCourse2);"},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":147,"author":{"gitId":"domoberzin"},"content":" // delete all account requests"},{"lineNumber":148,"author":{"gitId":"domoberzin"},"content":" accountRequestsDb.deleteAccountRequest(ins2InCourse2);"},{"lineNumber":149,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":150,"author":{"gitId":"domoberzin"},"content":" // there should be no search result"},{"lineNumber":151,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"of Course 2\\\"\");"},{"lineNumber":152,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results);"},{"lineNumber":153,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":154,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":155,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":156,"author":{"gitId":"domoberzin"},"content":" public void testSearchAccountRequest_noSearchService_shouldThrowException() {"},{"lineNumber":157,"author":{"gitId":"domoberzin"},"content":" if (TestProperties.isSearchServiceActive()) {"},{"lineNumber":158,"author":{"gitId":"domoberzin"},"content":" return;"},{"lineNumber":159,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":160,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":161,"author":{"gitId":"domoberzin"},"content":" assertThrows(SearchServiceException.class,"},{"lineNumber":162,"author":{"gitId":"domoberzin"},"content":" () -\u003e accountRequestsDb.searchAccountRequestsInWholeSystem(\"anything\"));"},{"lineNumber":163,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":164,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":165,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":" * Verifies that search results match with expected output."},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":" * @param actual the results from the search query."},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" * @param expected the expected results for the search query."},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":171,"author":{"gitId":"domoberzin"},"content":" private static void verifySearchResults(List\u003cAccountRequest\u003e actual,"},{"lineNumber":172,"author":{"gitId":"domoberzin"},"content":" AccountRequest... expected) {"},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":" assertEquals(expected.length, actual.size());"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":" AssertHelper.assertSameContentIgnoreOrder(Arrays.asList(expected), actual);"},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":167,"-":10}},{"path":"src/it/java/teammates/it/storage/sqlsearch/InstructorSearchIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.storage.sqlsearch;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.Arrays;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.UsersDb;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.test.AssertHelper;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.test.TestProperties;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * SUT: {@link UsersDb},"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * {@link teammates.storage.sqlsearch.InstructorSearchDocument}."},{"lineNumber":21,"author":{"gitId":"-"},"content":" */"},{"lineNumber":22,"author":{"gitId":"-"},"content":"public class InstructorSearchIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" private final SqlDataBundle typicalBundle \u003d getTypicalSqlDataBundle();"},{"lineNumber":25,"author":{"gitId":"-"},"content":" private final UsersDb usersDb \u003d UsersDb.inst();"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":29,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":30,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":31,"author":{"gitId":"-"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":32,"author":{"gitId":"-"},"content":" putDocuments(typicalBundle);"},{"lineNumber":33,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":37,"author":{"gitId":"-"},"content":" public void allTests() throws Exception {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" Instructor ins1InCourse1 \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":43,"author":{"gitId":"-"},"content":" Instructor ins2InCourse1 \u003d typicalBundle.instructors.get(\"instructor2OfCourse1\");"},{"lineNumber":44,"author":{"gitId":"yuanxi1"},"content":" Instructor ins1InCourse4 \u003d typicalBundle.instructors.get(\"instructor1OfCourse4\");"},{"lineNumber":45,"author":{"gitId":"yuanxi1"},"content":" Instructor ins2InCourse4 \u003d typicalBundle.instructors.get(\"instructor2YetToJoinCourse4\");"},{"lineNumber":46,"author":{"gitId":"yuanxi1"},"content":" Instructor ins3InCourse4 \u003d typicalBundle.instructors.get(\"instructor3YetToJoinCourse4\");"},{"lineNumber":47,"author":{"gitId":"-"},"content":" Instructor insInArchivedCourse \u003d typicalBundle.instructors.get(\"instructorOfArchivedCourse\");"},{"lineNumber":48,"author":{"gitId":"-"},"content":" Instructor insInUnregCourse \u003d typicalBundle.instructors.get(\"instructorOfUnregisteredCourse\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":" Instructor insUniqueDisplayName \u003d typicalBundle.instructors.get(\"instructorOfCourse2WithUniqueDisplayName\");"},{"lineNumber":50,"author":{"gitId":"-"},"content":" Instructor ins1InCourse3 \u003d typicalBundle.instructors.get(\"instructor1OfCourse3\");"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" Instructor unregisteredInsInCourse1 \u003d typicalBundle.instructors.get(\"unregisteredInstructorOfCourse1\");"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; query string does not match anyone\");"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e results \u003d usersDb.searchInstructorsInWholeSystem(\"non-existent\");"},{"lineNumber":56,"author":{"gitId":"-"},"content":" verifySearchResults(results);"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; empty query string does not match anyone\");"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\");"},{"lineNumber":61,"author":{"gitId":"-"},"content":" verifySearchResults(results);"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; query string matches some instructors\");"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"Instructor of\\\"\");"},{"lineNumber":66,"author":{"gitId":"-"},"content":" verifySearchResults(results, insInArchivedCourse, insInUnregCourse, insUniqueDisplayName);"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; query string should be case-insensitive\");"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"InStRuCtOr 2\\\"\");"},{"lineNumber":71,"author":{"gitId":"yuanxi1"},"content":" verifySearchResults(results, ins2InCourse1, ins2InCourse4);"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; instructors in archived courses should be included\");"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"Instructor Of Archived Course\\\"\");"},{"lineNumber":76,"author":{"gitId":"-"},"content":" verifySearchResults(results, insInArchivedCourse);"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" ______TS("},{"lineNumber":79,"author":{"gitId":"-"},"content":" \"success: search for instructors in whole system; instructors in unregistered course should be included\");"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"Instructor Of Unregistered Course\\\"\");"},{"lineNumber":82,"author":{"gitId":"-"},"content":" verifySearchResults(results, insInUnregCourse);"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; instructors should be searchable by course id\");"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"course-1\\\"\");"},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" verifySearchResults(results, ins1InCourse1, ins2InCourse1, unregisteredInsInCourse1);"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; instructors should be searchable by course name\");"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"Typical Course 1\\\"\");"},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" verifySearchResults(results, ins1InCourse1, ins2InCourse1, unregisteredInsInCourse1);"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; instructors should be searchable by their name\");"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"Instructor Of Unregistered Course\\\"\");"},{"lineNumber":97,"author":{"gitId":"-"},"content":" verifySearchResults(results, insInUnregCourse);"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; instructors should be searchable by their email\");"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"instr2@teammates.tmt\");"},{"lineNumber":102,"author":{"gitId":"yuanxi1"},"content":" verifySearchResults(results, ins2InCourse1, ins2InCourse4);"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; instructors should be searchable by their role\");"},{"lineNumber":105,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"Co-owner\\\"\");"},{"lineNumber":106,"author":{"gitId":"-"},"content":" verifySearchResults(results, ins1InCourse1, insInArchivedCourse,"},{"lineNumber":107,"author":{"gitId":"yuanxi1"},"content":" insInUnregCourse, insUniqueDisplayName, ins1InCourse3,"},{"lineNumber":108,"author":{"gitId":"yuanxi1"},"content":" ins1InCourse4, ins2InCourse4, ins3InCourse4);"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; instructors should be searchable by displayed name\");"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" String displayName \u003d insUniqueDisplayName.getDisplayName();"},{"lineNumber":113,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(displayName);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" verifySearchResults(results, insUniqueDisplayName);"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; deleted instructors no longer searchable\");"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" usersDb.deleteUser(insUniqueDisplayName);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"Instructor of\\\"\");"},{"lineNumber":120,"author":{"gitId":"-"},"content":" verifySearchResults(results, insInArchivedCourse, insInUnregCourse);"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" // This method used to use usersDb.putEntity, not sure if the .createInstructor method has the same functionality"},{"lineNumber":123,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; instructors created without searchability unsearchable\");"},{"lineNumber":124,"author":{"gitId":"-"},"content":" usersDb.createInstructor(insUniqueDisplayName);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"Instructor of\\\"\");"},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, insInArchivedCourse, insInUnregCourse, insUniqueDisplayName);"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; deleting instructor without deleting document:\""},{"lineNumber":129,"author":{"gitId":"-"},"content":" + \"document deleted during search, instructor unsearchable\");"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" usersDb.deleteUser(ins1InCourse3);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"Instructor 1\\\"\");"},{"lineNumber":133,"author":{"gitId":"yuanxi1"},"content":" verifySearchResults(results, ins1InCourse1, ins1InCourse4);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" }"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":137,"author":{"gitId":"-"},"content":" public void testSearchInstructor_deleteAfterSearch_shouldNotBeSearchable() throws Exception {"},{"lineNumber":138,"author":{"gitId":"-"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" Instructor ins1InCourse1 \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":143,"author":{"gitId":"-"},"content":" Instructor ins2InCourse1 \u003d typicalBundle.instructors.get(\"instructor2OfCourse1\");"},{"lineNumber":144,"author":{"gitId":"dishenggg"},"content":" Instructor unregisteredInsInCourse1 \u003d typicalBundle.instructors.get(\"unregisteredInstructorOfCourse1\");"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"course-1\\\"\");"},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":" verifySearchResults(results, ins1InCourse1, ins2InCourse1, unregisteredInsInCourse1);"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" usersDb.deleteUser(ins1InCourse1);"},{"lineNumber":150,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"course-1\\\"\");"},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":" verifySearchResults(results, ins2InCourse1, unregisteredInsInCourse1);"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":" // This used to test .deleteInstructors, but we don\u0027t seem to have a similar method to delete all users in course"},{"lineNumber":154,"author":{"gitId":"-"},"content":" usersDb.deleteUser(ins2InCourse1);"},{"lineNumber":155,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"course-1\\\"\");"},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" verifySearchResults(results, unregisteredInsInCourse1);"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":158,"author":{"gitId":"dishenggg"},"content":" usersDb.deleteUser(unregisteredInsInCourse1);"},{"lineNumber":159,"author":{"gitId":"dishenggg"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"course-1\\\"\");"},{"lineNumber":160,"author":{"gitId":"-"},"content":" verifySearchResults(results);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":164,"author":{"gitId":"-"},"content":" public void testSearchInstructor_noSearchService_shouldThrowException() {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" if (TestProperties.isSearchServiceActive()) {"},{"lineNumber":166,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":167,"author":{"gitId":"-"},"content":" }"},{"lineNumber":168,"author":{"gitId":"-"},"content":""},{"lineNumber":169,"author":{"gitId":"-"},"content":" assertThrows(SearchServiceException.class,"},{"lineNumber":170,"author":{"gitId":"-"},"content":" () -\u003e usersDb.searchInstructorsInWholeSystem(\"anything\"));"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":174,"author":{"gitId":"-"},"content":" * Verifies that search results match with expected output."},{"lineNumber":175,"author":{"gitId":"-"},"content":" *"},{"lineNumber":176,"author":{"gitId":"-"},"content":" * @param actual the results from the search query."},{"lineNumber":177,"author":{"gitId":"-"},"content":" * @param expected the expected results for the search query."},{"lineNumber":178,"author":{"gitId":"-"},"content":" */"},{"lineNumber":179,"author":{"gitId":"-"},"content":" private static void verifySearchResults(List\u003cInstructor\u003e actual,"},{"lineNumber":180,"author":{"gitId":"-"},"content":" Instructor... expected) {"},{"lineNumber":181,"author":{"gitId":"-"},"content":" assertEquals(expected.length, actual.size());"},{"lineNumber":182,"author":{"gitId":"-"},"content":" AssertHelper.assertSameContentIgnoreOrder(Arrays.asList(expected), actual);"},{"lineNumber":183,"author":{"gitId":"-"},"content":" }"},{"lineNumber":184,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":1,"yuanxi1":8,"dishenggg":10,"-":165}},{"path":"src/it/java/teammates/it/storage/sqlsearch/StudentSearchIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"yuanxi1"},"content":"package teammates.it.storage.sqlsearch;"},{"lineNumber":2,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":3,"author":{"gitId":"yuanxi1"},"content":"import java.util.Arrays;"},{"lineNumber":4,"author":{"gitId":"yuanxi1"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":6,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":7,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.Test;"},{"lineNumber":8,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":9,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":10,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":11,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":12,"author":{"gitId":"yuanxi1"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":13,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlapi.UsersDb;"},{"lineNumber":14,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":15,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":16,"author":{"gitId":"yuanxi1"},"content":"import teammates.test.AssertHelper;"},{"lineNumber":17,"author":{"gitId":"yuanxi1"},"content":"import teammates.test.TestProperties;"},{"lineNumber":18,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":19,"author":{"gitId":"yuanxi1"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"yuanxi1"},"content":" * SUT: {@link UsersDb},"},{"lineNumber":21,"author":{"gitId":"yuanxi1"},"content":" * {@link teammates.storage.sqlsearch.InstructorSearchDocument}."},{"lineNumber":22,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":23,"author":{"gitId":"yuanxi1"},"content":"public class StudentSearchIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":24,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":25,"author":{"gitId":"yuanxi1"},"content":" private final SqlDataBundle typicalBundle \u003d getTypicalSqlDataBundle();"},{"lineNumber":26,"author":{"gitId":"yuanxi1"},"content":" private final UsersDb usersDb \u003d UsersDb.inst();"},{"lineNumber":27,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":28,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":29,"author":{"gitId":"yuanxi1"},"content":" @BeforeMethod"},{"lineNumber":30,"author":{"gitId":"yuanxi1"},"content":" protected void setUp() throws Exception {"},{"lineNumber":31,"author":{"gitId":"yuanxi1"},"content":" super.setUp();"},{"lineNumber":32,"author":{"gitId":"yuanxi1"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":33,"author":{"gitId":"yuanxi1"},"content":" putDocuments(typicalBundle);"},{"lineNumber":34,"author":{"gitId":"yuanxi1"},"content":" HibernateUtil.flushSession();"},{"lineNumber":35,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":36,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":37,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":38,"author":{"gitId":"yuanxi1"},"content":" public void allTests() throws Exception {"},{"lineNumber":39,"author":{"gitId":"yuanxi1"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":40,"author":{"gitId":"yuanxi1"},"content":" return;"},{"lineNumber":41,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":42,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":43,"author":{"gitId":"yuanxi1"},"content":" Student stu1InCourse1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":44,"author":{"gitId":"yuanxi1"},"content":" Student stu2InCourse1 \u003d typicalBundle.students.get(\"student2InCourse1\");"},{"lineNumber":45,"author":{"gitId":"yuanxi1"},"content":" Student stu3InCourse1 \u003d typicalBundle.students.get(\"student3InCourse1\");"},{"lineNumber":46,"author":{"gitId":"marquestye"},"content":" Student stu4InCourse1 \u003d typicalBundle.students.get(\"student4InCourse1\");"},{"lineNumber":47,"author":{"gitId":"yuanxi1"},"content":" Student stu1InCourse2 \u003d typicalBundle.students.get(\"student1InCourse2\");"},{"lineNumber":48,"author":{"gitId":"yuanxi1"},"content":" Student unregisteredStuInCourse1 \u003d typicalBundle.students.get(\"unregisteredStudentInCourse1\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":" Student stu1InCourse3 \u003d typicalBundle.students.get(\"student1InCourse3\");"},{"lineNumber":50,"author":{"gitId":"yuanxi1"},"content":" Student stu1InCourse4 \u003d typicalBundle.students.get(\"student1InCourse4\");"},{"lineNumber":51,"author":{"gitId":"yuanxi1"},"content":" Student stuOfArchivedCourse \u003d typicalBundle.students.get(\"studentOfArchivedCourse\");"},{"lineNumber":52,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":53,"author":{"gitId":"yuanxi1"},"content":" Instructor ins1InCourse1 \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":54,"author":{"gitId":"yuanxi1"},"content":" Instructor ins1InCourse4 \u003d typicalBundle.instructors.get(\"instructor1OfCourse4\");"},{"lineNumber":55,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":56,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; query string does not match anyone\");"},{"lineNumber":57,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":58,"author":{"gitId":"yuanxi1"},"content":" List\u003cStudent\u003e results \u003d usersDb.searchStudentsInWholeSystem(\"non-existent\");"},{"lineNumber":59,"author":{"gitId":"yuanxi1"},"content":" verifySearchResults(results);"},{"lineNumber":60,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":61,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; empty query string does not match anyone\");"},{"lineNumber":62,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":63,"author":{"gitId":"yuanxi1"},"content":" results \u003d usersDb.searchStudentsInWholeSystem(\"\");"},{"lineNumber":64,"author":{"gitId":"yuanxi1"},"content":" verifySearchResults(results);"},{"lineNumber":65,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":66,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; query string matches some students\");"},{"lineNumber":67,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":68,"author":{"gitId":"yuanxi1"},"content":" results \u003d usersDb.searchStudentsInWholeSystem(\"\\\"student1\\\"\");"},{"lineNumber":69,"author":{"gitId":"-"},"content":" verifySearchResults(results, stu1InCourse1, stu1InCourse2, stu1InCourse3, stu1InCourse4);"},{"lineNumber":70,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":71,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; query string should be case-insensitive\");"},{"lineNumber":72,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":73,"author":{"gitId":"yuanxi1"},"content":" results \u003d usersDb.searchStudentsInWholeSystem(\"\\\"sTuDeNt1\\\"\");"},{"lineNumber":74,"author":{"gitId":"-"},"content":" verifySearchResults(results, stu1InCourse1, stu1InCourse2, stu1InCourse3, stu1InCourse4);"},{"lineNumber":75,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":76,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; students in archived courses should be included\");"},{"lineNumber":77,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":78,"author":{"gitId":"yuanxi1"},"content":" results \u003d usersDb.searchStudentsInWholeSystem(\"\\\"Student In Archived Course\\\"\");"},{"lineNumber":79,"author":{"gitId":"yuanxi1"},"content":" verifySearchResults(results, stuOfArchivedCourse);"},{"lineNumber":80,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":81,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; students should be searchable by course id\");"},{"lineNumber":82,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":83,"author":{"gitId":"yuanxi1"},"content":" results \u003d usersDb.searchStudentsInWholeSystem(\"\\\"course-1\\\"\");"},{"lineNumber":84,"author":{"gitId":"marquestye"},"content":" verifySearchResults(results, stu1InCourse1, stu2InCourse1, stu3InCourse1, stu4InCourse1, unregisteredStuInCourse1);"},{"lineNumber":85,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":86,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; students should be searchable by course name\");"},{"lineNumber":87,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":88,"author":{"gitId":"yuanxi1"},"content":" results \u003d usersDb.searchStudentsInWholeSystem(\"\\\"Typical Course 1\\\"\");"},{"lineNumber":89,"author":{"gitId":"marquestye"},"content":" verifySearchResults(results, stu1InCourse1, stu2InCourse1, stu3InCourse1, stu4InCourse1, unregisteredStuInCourse1);"},{"lineNumber":90,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":91,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; students should be searchable by their name\");"},{"lineNumber":92,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":93,"author":{"gitId":"yuanxi1"},"content":" results \u003d usersDb.searchStudentsInWholeSystem(\"\\\"student3 In Course1\\\"\");"},{"lineNumber":94,"author":{"gitId":"yuanxi1"},"content":" verifySearchResults(results, stu3InCourse1);"},{"lineNumber":95,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":96,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; students should be searchable by their email\");"},{"lineNumber":97,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":98,"author":{"gitId":"yuanxi1"},"content":" results \u003d usersDb.searchStudentsInWholeSystem(\"student1@teammates.tmt\");"},{"lineNumber":99,"author":{"gitId":"-"},"content":" verifySearchResults(results, stu1InCourse1, stu1InCourse2, stu1InCourse3, stu1InCourse4);"},{"lineNumber":100,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":101,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students; query string matches some students; results restricted \""},{"lineNumber":102,"author":{"gitId":"yuanxi1"},"content":" + \"based on instructor\u0027s privilege\");"},{"lineNumber":103,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":104,"author":{"gitId":"yuanxi1"},"content":" List\u003cInstructor\u003e ins1OfCourse1 \u003d Arrays.asList("},{"lineNumber":105,"author":{"gitId":"yuanxi1"},"content":" new Instructor[] { ins1InCourse1 });"},{"lineNumber":106,"author":{"gitId":"yuanxi1"},"content":" List\u003cInstructor\u003e ins1OfCourse4 \u003d Arrays.asList("},{"lineNumber":107,"author":{"gitId":"yuanxi1"},"content":" new Instructor[] { ins1InCourse4 });"},{"lineNumber":108,"author":{"gitId":"yuanxi1"},"content":" List\u003cStudent\u003e studentList \u003d usersDb.searchStudents(\"student1\", ins1OfCourse1);"},{"lineNumber":109,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":110,"author":{"gitId":"yuanxi1"},"content":" verifySearchResults(studentList, stu1InCourse1);"},{"lineNumber":111,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":112,"author":{"gitId":"yuanxi1"},"content":" studentList \u003d usersDb.searchStudents(\"student1\", ins1OfCourse4);"},{"lineNumber":113,"author":{"gitId":"yuanxi1"},"content":" verifySearchResults(studentList, stu1InCourse4);"},{"lineNumber":114,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":115,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; deleted students no longer searchable\");"},{"lineNumber":116,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":117,"author":{"gitId":"yuanxi1"},"content":" usersDb.deleteUser(stu1InCourse1);"},{"lineNumber":118,"author":{"gitId":"yuanxi1"},"content":" results \u003d usersDb.searchStudentsInWholeSystem(\"\\\"student1\\\"\");"},{"lineNumber":119,"author":{"gitId":"-"},"content":" verifySearchResults(results, stu1InCourse2, stu1InCourse3, stu1InCourse4);"},{"lineNumber":120,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":121,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":122,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":123,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":124,"author":{"gitId":"yuanxi1"},"content":" public void testSearchStudent_deleteAfterSearch_shouldNotBeSearchable() throws Exception {"},{"lineNumber":125,"author":{"gitId":"yuanxi1"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":126,"author":{"gitId":"yuanxi1"},"content":" return;"},{"lineNumber":127,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":128,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":129,"author":{"gitId":"yuanxi1"},"content":" Student stu1InCourse1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":130,"author":{"gitId":"yuanxi1"},"content":" Student stu1InCourse2 \u003d typicalBundle.students.get(\"student1InCourse2\");"},{"lineNumber":131,"author":{"gitId":"-"},"content":" Student stu1InCourse3 \u003d typicalBundle.students.get(\"student1InCourse3\");"},{"lineNumber":132,"author":{"gitId":"yuanxi1"},"content":" Student stu1InCourse4 \u003d typicalBundle.students.get(\"student1InCourse4\");"},{"lineNumber":133,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":134,"author":{"gitId":"yuanxi1"},"content":" List\u003cStudent\u003e studentList \u003d usersDb.searchStudentsInWholeSystem(\"student1\");"},{"lineNumber":135,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":136,"author":{"gitId":"yuanxi1"},"content":" // there is search result before deletion"},{"lineNumber":137,"author":{"gitId":"-"},"content":" verifySearchResults(studentList, stu1InCourse1, stu1InCourse2, stu1InCourse3, stu1InCourse4);"},{"lineNumber":138,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":139,"author":{"gitId":"yuanxi1"},"content":" // delete a student"},{"lineNumber":140,"author":{"gitId":"yuanxi1"},"content":" usersDb.deleteUser(stu1InCourse1);"},{"lineNumber":141,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":142,"author":{"gitId":"yuanxi1"},"content":" // the search result will change"},{"lineNumber":143,"author":{"gitId":"yuanxi1"},"content":" studentList \u003d usersDb.searchStudentsInWholeSystem(\"student1\");"},{"lineNumber":144,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" verifySearchResults(studentList, stu1InCourse2, stu1InCourse3, stu1InCourse4);"},{"lineNumber":146,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":147,"author":{"gitId":"yuanxi1"},"content":" // delete all students in course 2"},{"lineNumber":148,"author":{"gitId":"yuanxi1"},"content":" usersDb.deleteUser(stu1InCourse2);"},{"lineNumber":149,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":150,"author":{"gitId":"yuanxi1"},"content":" // the search result will change"},{"lineNumber":151,"author":{"gitId":"yuanxi1"},"content":" studentList \u003d usersDb.searchStudentsInWholeSystem(\"student1\");"},{"lineNumber":152,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":" verifySearchResults(studentList, stu1InCourse3, stu1InCourse4);"},{"lineNumber":154,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":155,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":156,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":157,"author":{"gitId":"yuanxi1"},"content":" public void testSearchStudent_noSearchService_shouldThrowException() {"},{"lineNumber":158,"author":{"gitId":"yuanxi1"},"content":" if (TestProperties.isSearchServiceActive()) {"},{"lineNumber":159,"author":{"gitId":"yuanxi1"},"content":" return;"},{"lineNumber":160,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":161,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":162,"author":{"gitId":"yuanxi1"},"content":" assertThrows(SearchServiceException.class,"},{"lineNumber":163,"author":{"gitId":"yuanxi1"},"content":" () -\u003e usersDb.searchStudentsInWholeSystem(\"anything\"));"},{"lineNumber":164,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":165,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":166,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":167,"author":{"gitId":"yuanxi1"},"content":" * Verifies that search results match with expected output."},{"lineNumber":168,"author":{"gitId":"yuanxi1"},"content":" *"},{"lineNumber":169,"author":{"gitId":"yuanxi1"},"content":" * @param actual the results from the search query."},{"lineNumber":170,"author":{"gitId":"yuanxi1"},"content":" * @param expected the expected results for the search query."},{"lineNumber":171,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":172,"author":{"gitId":"yuanxi1"},"content":" private static void verifySearchResults(List\u003cStudent\u003e actual,"},{"lineNumber":173,"author":{"gitId":"yuanxi1"},"content":" Student... expected) {"},{"lineNumber":174,"author":{"gitId":"yuanxi1"},"content":" assertEquals(expected.length, actual.size());"},{"lineNumber":175,"author":{"gitId":"yuanxi1"},"content":" AssertHelper.assertSameContentIgnoreOrder(Arrays.asList(expected), actual);"},{"lineNumber":176,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":177,"author":{"gitId":"yuanxi1"},"content":"}"}],"authorContributionMap":{"yuanxi1":165,"marquestye":3,"-":9}},{"path":"src/it/java/teammates/it/test/BaseTestCaseWithSqlDatabaseAccess.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.test;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.testcontainers.containers.PostgreSQLContainer;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterMethod;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterSuite;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeSuite;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import com.google.cloud.datastore.DatastoreOptions;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import com.google.cloud.datastore.testing.LocalDatastoreHelper;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import com.googlecode.objectify.ObjectifyFactory;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import com.googlecode.objectify.ObjectifyService;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import com.googlecode.objectify.util.Closeable;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.sqllogic.api.Logic;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.LogicStarter;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.api.OfyHelper;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.BaseEntity;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":41,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.ReadNotification;"},{"lineNumber":42,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":43,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":45,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.UsageStatistics;"},{"lineNumber":46,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.AccountRequestSearchManager;"},{"lineNumber":47,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.InstructorSearchManager;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.SearchManagerFactory;"},{"lineNumber":49,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.StudentSearchManager;"},{"lineNumber":50,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":53,"author":{"gitId":"-"},"content":" * Base test case for tests that access the database."},{"lineNumber":54,"author":{"gitId":"-"},"content":" */"},{"lineNumber":55,"author":{"gitId":"-"},"content":"@Test(singleThreaded \u003d true)"},{"lineNumber":56,"author":{"gitId":"-"},"content":"public class BaseTestCaseWithSqlDatabaseAccess extends BaseTestCase {"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" private static final PostgreSQLContainer\u003c?\u003e PGSQL \u003d new PostgreSQLContainer\u003c\u003e(\"postgres:15.1-alpine\");"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" private static final LocalDatastoreHelper LOCAL_DATASTORE_HELPER \u003d LocalDatastoreHelper.newBuilder()"},{"lineNumber":61,"author":{"gitId":"-"},"content":" .setConsistency(1.0)"},{"lineNumber":62,"author":{"gitId":"-"},"content":" .setPort(TestProperties.TEST_LOCALDATASTORE_PORT)"},{"lineNumber":63,"author":{"gitId":"-"},"content":" .setStoreOnDisk(false)"},{"lineNumber":64,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" private final Logic logic \u003d Logic.inst();"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" private Closeable closeable;"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" @BeforeSuite"},{"lineNumber":71,"author":{"gitId":"-"},"content":" protected static void setUpSuite() throws Exception {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" PGSQL.start();"},{"lineNumber":73,"author":{"gitId":"-"},"content":" // Temporarily disable migration utility"},{"lineNumber":74,"author":{"gitId":"-"},"content":" // DbMigrationUtil.resetDb(PGSQL.getJdbcUrl(), PGSQL.getUsername(),"},{"lineNumber":75,"author":{"gitId":"-"},"content":" // PGSQL.getPassword());"},{"lineNumber":76,"author":{"gitId":"-"},"content":" HibernateUtil.buildSessionFactory(PGSQL.getJdbcUrl(), PGSQL.getUsername(), PGSQL.getPassword());"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" LogicStarter.initializeDependencies();"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" SearchManagerFactory.registerAccountRequestSearchManager("},{"lineNumber":81,"author":{"gitId":"-"},"content":" new AccountRequestSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":82,"author":{"gitId":"-"},"content":" SearchManagerFactory.registerInstructorSearchManager("},{"lineNumber":83,"author":{"gitId":"-"},"content":" new InstructorSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":84,"author":{"gitId":"-"},"content":" SearchManagerFactory.registerStudentSearchManager("},{"lineNumber":85,"author":{"gitId":"-"},"content":" new StudentSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" // TODO: remove after migration, needed for dual db support"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" teammates.storage.search.SearchManagerFactory.registerAccountRequestSearchManager("},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" new teammates.storage.search.AccountRequestSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" teammates.storage.search.SearchManagerFactory.registerInstructorSearchManager("},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" new teammates.storage.search.InstructorSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":" teammates.storage.search.SearchManagerFactory.registerStudentSearchManager("},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":" new teammates.storage.search.StudentSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" teammates.logic.core.LogicStarter.initializeDependencies();"},{"lineNumber":97,"author":{"gitId":"-"},"content":" LOCAL_DATASTORE_HELPER.start();"},{"lineNumber":98,"author":{"gitId":"-"},"content":" DatastoreOptions options \u003d LOCAL_DATASTORE_HELPER.getOptions();"},{"lineNumber":99,"author":{"gitId":"-"},"content":" ObjectifyService.init(new ObjectifyFactory("},{"lineNumber":100,"author":{"gitId":"-"},"content":" options.getService()));"},{"lineNumber":101,"author":{"gitId":"-"},"content":" OfyHelper.registerEntityClasses();"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" }"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" @BeforeClass"},{"lineNumber":106,"author":{"gitId":"-"},"content":" public void setupClass() {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" closeable \u003d ObjectifyService.begin();"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":111,"author":{"gitId":"-"},"content":" public void tearDownClass() {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" closeable.close();"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" SearchManagerFactory.getAccountRequestSearchManager().resetCollections();"},{"lineNumber":115,"author":{"gitId":"-"},"content":" SearchManagerFactory.getInstructorSearchManager().resetCollections();"},{"lineNumber":116,"author":{"gitId":"-"},"content":" SearchManagerFactory.getStudentSearchManager().resetCollections();"},{"lineNumber":117,"author":{"gitId":"-"},"content":" }"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" @AfterSuite"},{"lineNumber":120,"author":{"gitId":"-"},"content":" protected static void tearDownSuite() throws Exception {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" PGSQL.close();"},{"lineNumber":122,"author":{"gitId":"-"},"content":" LOCAL_DATASTORE_HELPER.stop();"},{"lineNumber":123,"author":{"gitId":"-"},"content":" }"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":126,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":127,"author":{"gitId":"-"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" @AfterMethod"},{"lineNumber":131,"author":{"gitId":"-"},"content":" protected void tearDown() {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" HibernateUtil.rollbackTransaction();"},{"lineNumber":133,"author":{"gitId":"-"},"content":" }"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":136,"author":{"gitId":"-"},"content":" protected String getTestDataFolder() {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" return TestProperties.TEST_DATA_FOLDER;"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":141,"author":{"gitId":"-"},"content":" * Persist data bundle into the db."},{"lineNumber":142,"author":{"gitId":"-"},"content":" */"},{"lineNumber":143,"author":{"gitId":"-"},"content":" protected void persistDataBundle(SqlDataBundle dataBundle)"},{"lineNumber":144,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException, EntityDoesNotExistException {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" logic.persistDataBundle(dataBundle);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" }"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":149,"author":{"gitId":"-"},"content":" * Puts searchable documents from the data bundle to the solr database."},{"lineNumber":150,"author":{"gitId":"-"},"content":" */"},{"lineNumber":151,"author":{"gitId":"-"},"content":" protected void putDocuments(SqlDataBundle dataBundle) throws SearchServiceException {"},{"lineNumber":152,"author":{"gitId":"-"},"content":" logic.putDocuments(dataBundle);"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":156,"author":{"gitId":"-"},"content":" * Verifies that two entities are equal."},{"lineNumber":157,"author":{"gitId":"-"},"content":" */"},{"lineNumber":158,"author":{"gitId":"-"},"content":" protected void verifyEquals(BaseEntity expected, BaseEntity actual) {"},{"lineNumber":159,"author":{"gitId":"-"},"content":" if (expected instanceof Course) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" Course expectedCourse \u003d (Course) expected;"},{"lineNumber":161,"author":{"gitId":"-"},"content":" Course actualCourse \u003d (Course) actual;"},{"lineNumber":162,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedCourse, actualCourse);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedCourse), JsonUtils.toJson(actualCourse));"},{"lineNumber":164,"author":{"gitId":"-"},"content":" } else if (expected instanceof DeadlineExtension) {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" DeadlineExtension expectedDeadlineExtension \u003d (DeadlineExtension) expected;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" DeadlineExtension actualDeadlineExtension \u003d (DeadlineExtension) actual;"},{"lineNumber":167,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedDeadlineExtension, actualDeadlineExtension);"},{"lineNumber":168,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedDeadlineExtension), JsonUtils.toJson(actualDeadlineExtension));"},{"lineNumber":169,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackSession) {"},{"lineNumber":170,"author":{"gitId":"-"},"content":" FeedbackSession expectedSession \u003d (FeedbackSession) expected;"},{"lineNumber":171,"author":{"gitId":"-"},"content":" FeedbackSession actualSession \u003d (FeedbackSession) actual;"},{"lineNumber":172,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedSession, actualSession);"},{"lineNumber":173,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedSession), JsonUtils.toJson(actualSession));"},{"lineNumber":174,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackQuestion) {"},{"lineNumber":175,"author":{"gitId":"-"},"content":" FeedbackQuestion expectedQuestion \u003d (FeedbackQuestion) expected;"},{"lineNumber":176,"author":{"gitId":"-"},"content":" FeedbackQuestion actualQuestion \u003d (FeedbackQuestion) actual;"},{"lineNumber":177,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedQuestion, actualQuestion);"},{"lineNumber":178,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedQuestion), JsonUtils.toJson(actualQuestion));"},{"lineNumber":179,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackResponse) {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" FeedbackResponse expectedResponse \u003d (FeedbackResponse) expected;"},{"lineNumber":181,"author":{"gitId":"-"},"content":" FeedbackResponse actualResponse \u003d (FeedbackResponse) actual;"},{"lineNumber":182,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedResponse, actualResponse);"},{"lineNumber":183,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedResponse), JsonUtils.toJson(actualResponse));"},{"lineNumber":184,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackResponseComment) {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" FeedbackResponseComment expectedComment \u003d (FeedbackResponseComment) expected;"},{"lineNumber":186,"author":{"gitId":"-"},"content":" FeedbackResponseComment actualComment \u003d (FeedbackResponseComment) actual;"},{"lineNumber":187,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedComment, actualComment);"},{"lineNumber":188,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedComment), JsonUtils.toJson(actualComment));"},{"lineNumber":189,"author":{"gitId":"-"},"content":" } else if (expected instanceof Notification) {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" Notification expectedNotification \u003d (Notification) expected;"},{"lineNumber":191,"author":{"gitId":"-"},"content":" Notification actualNotification \u003d (Notification) actual;"},{"lineNumber":192,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedNotification, actualNotification);"},{"lineNumber":193,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedNotification), JsonUtils.toJson(actualNotification));"},{"lineNumber":194,"author":{"gitId":"-"},"content":" } else if (expected instanceof Account) {"},{"lineNumber":195,"author":{"gitId":"-"},"content":" Account expectedAccount \u003d (Account) expected;"},{"lineNumber":196,"author":{"gitId":"-"},"content":" Account actualAccount \u003d (Account) actual;"},{"lineNumber":197,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedAccount, actualAccount);"},{"lineNumber":198,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedAccount), JsonUtils.toJson(actualAccount));"},{"lineNumber":199,"author":{"gitId":"-"},"content":" } else if (expected instanceof AccountRequest) {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" AccountRequest expectedAccountRequest \u003d (AccountRequest) expected;"},{"lineNumber":201,"author":{"gitId":"-"},"content":" AccountRequest actualAccountRequest \u003d (AccountRequest) actual;"},{"lineNumber":202,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedAccountRequest, actualAccountRequest);"},{"lineNumber":203,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedAccountRequest), JsonUtils.toJson(actualAccountRequest));"},{"lineNumber":204,"author":{"gitId":"-"},"content":" } else if (expected instanceof UsageStatistics) {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" UsageStatistics expectedUsageStatistics \u003d (UsageStatistics) expected;"},{"lineNumber":206,"author":{"gitId":"-"},"content":" UsageStatistics actualUsageStatistics \u003d (UsageStatistics) actual;"},{"lineNumber":207,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedUsageStatistics, actualUsageStatistics);"},{"lineNumber":208,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedUsageStatistics), JsonUtils.toJson(actualUsageStatistics));"},{"lineNumber":209,"author":{"gitId":"-"},"content":" } else if (expected instanceof Instructor) {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" Instructor expectedInstructor \u003d (Instructor) expected;"},{"lineNumber":211,"author":{"gitId":"-"},"content":" Instructor actualInstructor \u003d (Instructor) actual;"},{"lineNumber":212,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedInstructor, actualInstructor);"},{"lineNumber":213,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedInstructor), JsonUtils.toJson(actualInstructor));"},{"lineNumber":214,"author":{"gitId":"-"},"content":" } else if (expected instanceof Student) {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" Student expectedStudent \u003d (Student) expected;"},{"lineNumber":216,"author":{"gitId":"-"},"content":" Student actualStudent \u003d (Student) actual;"},{"lineNumber":217,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedStudent, actualStudent);"},{"lineNumber":218,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedStudent), JsonUtils.toJson(actualStudent));"},{"lineNumber":219,"author":{"gitId":"-"},"content":" } else if (expected instanceof Section) {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" Section expectedSection \u003d (Section) expected;"},{"lineNumber":221,"author":{"gitId":"-"},"content":" Section actualSection \u003d (Section) actual;"},{"lineNumber":222,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedSection, actualSection);"},{"lineNumber":223,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedSection), JsonUtils.toJson(actualSection));"},{"lineNumber":224,"author":{"gitId":"-"},"content":" } else if (expected instanceof Team) {"},{"lineNumber":225,"author":{"gitId":"-"},"content":" Team expectedTeam \u003d (Team) expected;"},{"lineNumber":226,"author":{"gitId":"-"},"content":" Team actualTeam \u003d (Team) actual;"},{"lineNumber":227,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedTeam, actualTeam);"},{"lineNumber":228,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedTeam), JsonUtils.toJson(actualTeam));"},{"lineNumber":229,"author":{"gitId":"-"},"content":" } else if (expected instanceof ReadNotification) {"},{"lineNumber":230,"author":{"gitId":"-"},"content":" ReadNotification expectedReadNotification \u003d (ReadNotification) expected;"},{"lineNumber":231,"author":{"gitId":"-"},"content":" ReadNotification actualReadNotification \u003d (ReadNotification) actual;"},{"lineNumber":232,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedReadNotification, actualReadNotification);"},{"lineNumber":233,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":234,"author":{"gitId":"-"},"content":" fail(\"Unknown entity\");"},{"lineNumber":235,"author":{"gitId":"-"},"content":" }"},{"lineNumber":236,"author":{"gitId":"-"},"content":" }"},{"lineNumber":237,"author":{"gitId":"-"},"content":""},{"lineNumber":238,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":239,"author":{"gitId":"-"},"content":" * Verifies that the given entity is present in the database."},{"lineNumber":240,"author":{"gitId":"-"},"content":" */"},{"lineNumber":241,"author":{"gitId":"-"},"content":" protected void verifyPresentInDatabase(BaseEntity expected) {"},{"lineNumber":242,"author":{"gitId":"-"},"content":" assertNotNull(expected);"},{"lineNumber":243,"author":{"gitId":"-"},"content":" BaseEntity actual \u003d getEntity(expected);"},{"lineNumber":244,"author":{"gitId":"-"},"content":" verifyEquals(expected, actual);"},{"lineNumber":245,"author":{"gitId":"-"},"content":" }"},{"lineNumber":246,"author":{"gitId":"-"},"content":""},{"lineNumber":247,"author":{"gitId":"-"},"content":" private BaseEntity getEntity(BaseEntity entity) {"},{"lineNumber":248,"author":{"gitId":"-"},"content":" if (entity instanceof Course) {"},{"lineNumber":249,"author":{"gitId":"-"},"content":" return logic.getCourse(((Course) entity).getId());"},{"lineNumber":250,"author":{"gitId":"-"},"content":" } else if (entity instanceof FeedbackSession) {"},{"lineNumber":251,"author":{"gitId":"-"},"content":" return logic.getFeedbackSession(((FeedbackSession) entity).getId());"},{"lineNumber":252,"author":{"gitId":"dishenggg"},"content":" } else if (entity instanceof FeedbackQuestion) {"},{"lineNumber":253,"author":{"gitId":"dishenggg"},"content":" return logic.getFeedbackQuestion(((FeedbackQuestion) entity).getId());"},{"lineNumber":254,"author":{"gitId":"-"},"content":" } else if (entity instanceof Account) {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" return logic.getAccount(((Account) entity).getId());"},{"lineNumber":256,"author":{"gitId":"-"},"content":" } else if (entity instanceof Notification) {"},{"lineNumber":257,"author":{"gitId":"-"},"content":" return logic.getNotification(((Notification) entity).getId());"},{"lineNumber":258,"author":{"gitId":"-"},"content":" } else if (entity instanceof AccountRequest) {"},{"lineNumber":259,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d (AccountRequest) entity;"},{"lineNumber":260,"author":{"gitId":"-"},"content":" return logic.getAccountRequest(accountRequest.getId());"},{"lineNumber":261,"author":{"gitId":"yuanxi1"},"content":" } else if (entity instanceof Instructor) {"},{"lineNumber":262,"author":{"gitId":"yuanxi1"},"content":" return logic.getInstructor(((Instructor) entity).getId());"},{"lineNumber":263,"author":{"gitId":"yuanxi1"},"content":" } else if (entity instanceof Student) {"},{"lineNumber":264,"author":{"gitId":"yuanxi1"},"content":" return logic.getStudent(((Student) entity).getId());"},{"lineNumber":265,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":266,"author":{"gitId":"-"},"content":" throw new RuntimeException(\"Unknown entity type\");"},{"lineNumber":267,"author":{"gitId":"-"},"content":" }"},{"lineNumber":268,"author":{"gitId":"-"},"content":" }"},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(Course expected, Course actual) {"},{"lineNumber":271,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":272,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":273,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(DeadlineExtension expected, DeadlineExtension actual) {"},{"lineNumber":277,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":278,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":279,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":280,"author":{"gitId":"-"},"content":" }"},{"lineNumber":281,"author":{"gitId":"-"},"content":""},{"lineNumber":282,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(FeedbackSession expected, FeedbackSession actual) {"},{"lineNumber":283,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":284,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":285,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":286,"author":{"gitId":"-"},"content":" }"},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(FeedbackQuestion expected, FeedbackQuestion actual) {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":290,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":291,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":292,"author":{"gitId":"-"},"content":" }"},{"lineNumber":293,"author":{"gitId":"-"},"content":""},{"lineNumber":294,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(FeedbackResponse expected, FeedbackResponse actual) {"},{"lineNumber":295,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":296,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":297,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":298,"author":{"gitId":"-"},"content":" }"},{"lineNumber":299,"author":{"gitId":"-"},"content":""},{"lineNumber":300,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(FeedbackResponseComment expected, FeedbackResponseComment actual) {"},{"lineNumber":301,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":302,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":303,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":304,"author":{"gitId":"-"},"content":" }"},{"lineNumber":305,"author":{"gitId":"-"},"content":""},{"lineNumber":306,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(Notification expected, Notification actual) {"},{"lineNumber":307,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":308,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":309,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":310,"author":{"gitId":"-"},"content":" }"},{"lineNumber":311,"author":{"gitId":"-"},"content":""},{"lineNumber":312,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(Account expected, Account actual) {"},{"lineNumber":313,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":314,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":315,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":316,"author":{"gitId":"-"},"content":" }"},{"lineNumber":317,"author":{"gitId":"-"},"content":""},{"lineNumber":318,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(AccountRequest expected, AccountRequest actual) {"},{"lineNumber":319,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":320,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":321,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":322,"author":{"gitId":"-"},"content":" }"},{"lineNumber":323,"author":{"gitId":"-"},"content":""},{"lineNumber":324,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(UsageStatistics expected, UsageStatistics actual) {"},{"lineNumber":325,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":326,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":327,"author":{"gitId":"-"},"content":" }"},{"lineNumber":328,"author":{"gitId":"-"},"content":""},{"lineNumber":329,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(Instructor expected, Instructor actual) {"},{"lineNumber":330,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":331,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":332,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":333,"author":{"gitId":"-"},"content":" }"},{"lineNumber":334,"author":{"gitId":"-"},"content":""},{"lineNumber":335,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(Student expected, Student actual) {"},{"lineNumber":336,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":337,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":338,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":339,"author":{"gitId":"-"},"content":" }"},{"lineNumber":340,"author":{"gitId":"-"},"content":""},{"lineNumber":341,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(Section expected, Section actual) {"},{"lineNumber":342,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":343,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":344,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":345,"author":{"gitId":"-"},"content":" }"},{"lineNumber":346,"author":{"gitId":"-"},"content":""},{"lineNumber":347,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(Team expected, Team actual) {"},{"lineNumber":348,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":349,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":350,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":351,"author":{"gitId":"-"},"content":" }"},{"lineNumber":352,"author":{"gitId":"-"},"content":""},{"lineNumber":353,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(ReadNotification expected, ReadNotification actual) {"},{"lineNumber":354,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":355,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":356,"author":{"gitId":"-"},"content":" }"},{"lineNumber":357,"author":{"gitId":"-"},"content":""},{"lineNumber":358,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":359,"author":{"gitId":"-"},"content":" * Generates a UUID that is different from the given {@code uuid}."},{"lineNumber":360,"author":{"gitId":"-"},"content":" */"},{"lineNumber":361,"author":{"gitId":"-"},"content":" protected UUID generateDifferentUuid(UUID uuid) {"},{"lineNumber":362,"author":{"gitId":"-"},"content":" UUID ret \u003d UUID.randomUUID();"},{"lineNumber":363,"author":{"gitId":"-"},"content":" while (ret.equals(uuid)) {"},{"lineNumber":364,"author":{"gitId":"-"},"content":" ret \u003d UUID.randomUUID();"},{"lineNumber":365,"author":{"gitId":"-"},"content":" }"},{"lineNumber":366,"author":{"gitId":"-"},"content":" return ret;"},{"lineNumber":367,"author":{"gitId":"-"},"content":" }"},{"lineNumber":368,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":8,"yuanxi1":4,"dishenggg":2,"-":354}},{"path":"src/it/java/teammates/it/ui/webapi/AccountRequestSearchIndexingWorkerActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import java.util.UUID;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.ParamsNames;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.test.TestProperties;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.AccountRequestSearchIndexingWorkerAction;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * SUT: {@link AccountRequestSearchIndexingWorkerAction}."},{"lineNumber":21,"author":{"gitId":"-"},"content":" */"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":"public class AccountRequestSearchIndexingWorkerActionIT extends BaseActionIT\u003cAccountRequestSearchIndexingWorkerAction\u003e {"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" @BeforeMethod"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" protected void setUp() throws Exception {"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" super.setUp();"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.flushSession();"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":33,"author":{"gitId":"-"},"content":" protected String getActionUri() {"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" return Const.TaskQueue.ACCOUNT_REQUEST_SEARCH_INDEXING_WORKER_URL;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"-"},"content":" protected String getRequestMethod() {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" return POST;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":43,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":44,"author":{"gitId":"-"},"content":" public void testExecute() throws Exception {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" }"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d typicalBundle.accountRequests.get(\"instructor1\");"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" UUID accountRequestId \u003d accountRequest.getId();"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" ______TS(\"account request not yet indexed should not be searchable\");"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" List\u003cAccountRequest\u003e accountRequestsList \u003d"},{"lineNumber":55,"author":{"gitId":"-"},"content":" logic.searchAccountRequestsInWholeSystem(accountRequest.getEmail());"},{"lineNumber":56,"author":{"gitId":"-"},"content":" assertEquals(0, accountRequestsList.size());"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" ______TS(\"account request indexed should be searchable\");"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" ParamsNames.ACCOUNT_REQUEST_ID, accountRequestId.toString(),"},{"lineNumber":62,"author":{"gitId":"-"},"content":" };"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" AccountRequestSearchIndexingWorkerAction action \u003d getAction(submissionParams);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" getJsonResult(action);"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" accountRequestsList \u003d logic.searchAccountRequestsInWholeSystem(accountRequest.getEmail());"},{"lineNumber":68,"author":{"gitId":"-"},"content":" assertEquals(1, accountRequestsList.size());"},{"lineNumber":69,"author":{"gitId":"-"},"content":" assertEquals(accountRequest.getName(), accountRequestsList.get(0).getName());"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" protected void testAccessControl() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" verifyOnlyAdminCanAccess(course);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":29,"-":50}},{"path":"src/it/java/teammates/it/ui/webapi/BaseActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Arrays;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import jakarta.servlet.http.Cookie;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpDelete;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpGet;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpPost;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpPut;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPermissionRole;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPrivileges;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.UserInfo;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.logic.api.MockEmailSender;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.logic.api.MockLogsProcessor;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.logic.api.MockRecaptchaVerifier;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.logic.api.MockTaskQueuer;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.logic.api.MockUserProvision;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.sqllogic.api.Logic;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import teammates.test.MockHttpServletRequest;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"import teammates.ui.request.BasicRequest;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":41,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.Action;"},{"lineNumber":42,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.ActionFactory;"},{"lineNumber":43,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.ActionMappingException;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.ActionResult;"},{"lineNumber":45,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.EntityNotFoundException;"},{"lineNumber":46,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.InvalidHttpParameterException;"},{"lineNumber":47,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.InvalidOperationException;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":49,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.UnauthorizedAccessException;"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":52,"author":{"gitId":"-"},"content":" * Base class for all action tests."},{"lineNumber":53,"author":{"gitId":"-"},"content":" *"},{"lineNumber":54,"author":{"gitId":"-"},"content":" * \u003cp\u003eOn top of having a local database, these tests require proxy services to be"},{"lineNumber":55,"author":{"gitId":"-"},"content":" * running (to be more precise, mocked)."},{"lineNumber":56,"author":{"gitId":"-"},"content":" *"},{"lineNumber":57,"author":{"gitId":"-"},"content":" * @param \u003cT\u003e The action class being tested."},{"lineNumber":58,"author":{"gitId":"-"},"content":" */"},{"lineNumber":59,"author":{"gitId":"-"},"content":"public abstract class BaseActionIT\u003cT extends Action\u003e extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" static final String GET \u003d HttpGet.METHOD_NAME;"},{"lineNumber":62,"author":{"gitId":"-"},"content":" static final String POST \u003d HttpPost.METHOD_NAME;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" static final String PUT \u003d HttpPut.METHOD_NAME;"},{"lineNumber":64,"author":{"gitId":"-"},"content":" static final String DELETE \u003d HttpDelete.METHOD_NAME;"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" SqlDataBundle typicalBundle \u003d getTypicalSqlDataBundle();"},{"lineNumber":67,"author":{"gitId":"-"},"content":" Logic logic \u003d Logic.inst();"},{"lineNumber":68,"author":{"gitId":"-"},"content":" MockTaskQueuer mockTaskQueuer \u003d new MockTaskQueuer();"},{"lineNumber":69,"author":{"gitId":"-"},"content":" MockEmailSender mockEmailSender \u003d new MockEmailSender();"},{"lineNumber":70,"author":{"gitId":"-"},"content":" MockLogsProcessor mockLogsProcessor \u003d new MockLogsProcessor();"},{"lineNumber":71,"author":{"gitId":"-"},"content":" MockUserProvision mockUserProvision \u003d new MockUserProvision();"},{"lineNumber":72,"author":{"gitId":"-"},"content":" MockRecaptchaVerifier mockRecaptchaVerifier \u003d new MockRecaptchaVerifier();"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" Course testCourseOther;"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" abstract String getActionUri();"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" abstract String getRequestMethod();"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":81,"author":{"gitId":"-"},"content":" * Gets an action with empty request body."},{"lineNumber":82,"author":{"gitId":"-"},"content":" */"},{"lineNumber":83,"author":{"gitId":"-"},"content":" protected T getAction(String... params) {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" return getAction(null, null, params);"},{"lineNumber":85,"author":{"gitId":"-"},"content":" }"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":88,"author":{"gitId":"-"},"content":" * Gets an action with request body."},{"lineNumber":89,"author":{"gitId":"-"},"content":" */"},{"lineNumber":90,"author":{"gitId":"-"},"content":" protected T getAction(BasicRequest requestBody, String... params) {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" return getAction(JsonUtils.toCompactJson(requestBody), null, params);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":95,"author":{"gitId":"-"},"content":" * Gets an action with request body and cookie."},{"lineNumber":96,"author":{"gitId":"-"},"content":" */"},{"lineNumber":97,"author":{"gitId":"-"},"content":" protected T getAction(String body, List\u003cCookie\u003e cookies, String... params) {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" mockTaskQueuer.clearTasks();"},{"lineNumber":99,"author":{"gitId":"-"},"content":" mockEmailSender.clearEmails();"},{"lineNumber":100,"author":{"gitId":"-"},"content":" MockHttpServletRequest req \u003d new MockHttpServletRequest(getRequestMethod(), getActionUri());"},{"lineNumber":101,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c params.length; i \u003d i + 2) {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" req.addParam(params[i], params[i + 1]);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" }"},{"lineNumber":104,"author":{"gitId":"-"},"content":" if (body !\u003d null) {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" req.setBody(body);"},{"lineNumber":106,"author":{"gitId":"-"},"content":" }"},{"lineNumber":107,"author":{"gitId":"-"},"content":" if (cookies !\u003d null) {"},{"lineNumber":108,"author":{"gitId":"-"},"content":" for (Cookie cookie : cookies) {"},{"lineNumber":109,"author":{"gitId":"-"},"content":" req.addCookie(cookie);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" @SuppressWarnings(\"unchecked\")"},{"lineNumber":114,"author":{"gitId":"-"},"content":" T action \u003d (T) ActionFactory.getAction(req, getRequestMethod());"},{"lineNumber":115,"author":{"gitId":"-"},"content":" action.setTaskQueuer(mockTaskQueuer);"},{"lineNumber":116,"author":{"gitId":"-"},"content":" action.setEmailSender(mockEmailSender);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" action.setLogsProcessor(mockLogsProcessor);"},{"lineNumber":118,"author":{"gitId":"-"},"content":" action.setUserProvision(mockUserProvision);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" action.setRecaptchaVerifier(mockRecaptchaVerifier);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" action.init(req);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" return action;"},{"lineNumber":122,"author":{"gitId":"-"},"content":" } catch (ActionMappingException e) {"},{"lineNumber":123,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":124,"author":{"gitId":"-"},"content":" }"},{"lineNumber":125,"author":{"gitId":"-"},"content":" }"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":128,"author":{"gitId":"-"},"content":" * Gets an action with list of cookies."},{"lineNumber":129,"author":{"gitId":"-"},"content":" */"},{"lineNumber":130,"author":{"gitId":"-"},"content":" protected T getActionWithCookie(List\u003cCookie\u003e cookies, String... params) {"},{"lineNumber":131,"author":{"gitId":"-"},"content":" return getAction(null, cookies, params);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" }"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":135,"author":{"gitId":"-"},"content":" * Tests the {@link Action#execute()} method."},{"lineNumber":136,"author":{"gitId":"-"},"content":" *"},{"lineNumber":137,"author":{"gitId":"-"},"content":" * \u003cp\u003eSome actions, particularly those with large number of different outcomes,"},{"lineNumber":138,"author":{"gitId":"-"},"content":" * can alternatively separate each test case to different test blocks."},{"lineNumber":139,"author":{"gitId":"-"},"content":" */"},{"lineNumber":140,"author":{"gitId":"-"},"content":" protected abstract void testExecute() throws Exception;"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":143,"author":{"gitId":"-"},"content":" * Tests the {@link Action#checkAccessControl()} method."},{"lineNumber":144,"author":{"gitId":"-"},"content":" *"},{"lineNumber":145,"author":{"gitId":"-"},"content":" * \u003cp\u003eSome actions, particularly those with large number of different access"},{"lineNumber":146,"author":{"gitId":"-"},"content":" * control settings,"},{"lineNumber":147,"author":{"gitId":"-"},"content":" * can alternatively separate each test case to different test blocks."},{"lineNumber":148,"author":{"gitId":"-"},"content":" */"},{"lineNumber":149,"author":{"gitId":"-"},"content":" protected abstract void testAccessControl() throws Exception;"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":152,"author":{"gitId":"-"},"content":" * Returns The {@code params} array with the {@code userId}"},{"lineNumber":153,"author":{"gitId":"-"},"content":" * (together with the parameter name) inserted at the beginning."},{"lineNumber":154,"author":{"gitId":"-"},"content":" */"},{"lineNumber":155,"author":{"gitId":"-"},"content":" protected String[] addUserIdToParams(String userId, String[] params) {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" List\u003cString\u003e list \u003d new ArrayList\u003c\u003e();"},{"lineNumber":157,"author":{"gitId":"-"},"content":" list.add(Const.ParamsNames.USER_ID);"},{"lineNumber":158,"author":{"gitId":"-"},"content":" list.add(userId);"},{"lineNumber":159,"author":{"gitId":"-"},"content":" list.addAll(Arrays.asList(params));"},{"lineNumber":160,"author":{"gitId":"-"},"content":" return list.toArray(new String[0]);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" // The next few methods are for logging in as various user"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":166,"author":{"gitId":"-"},"content":" * Logs in the user to the test environment as an admin."},{"lineNumber":167,"author":{"gitId":"-"},"content":" */"},{"lineNumber":168,"author":{"gitId":"-"},"content":" protected void loginAsAdmin() {"},{"lineNumber":169,"author":{"gitId":"-"},"content":" UserInfo user \u003d mockUserProvision.loginAsAdmin(Config.APP_ADMINS.get(0));"},{"lineNumber":170,"author":{"gitId":"-"},"content":" assertTrue(user.isAdmin);"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":" * Logs in the user to the test environment as an admin."},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":" protected void loginAsAdminWithTransaction() {"},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" UserInfo user \u003d mockUserProvision.loginAsAdminWithTransaction(Config.APP_ADMINS.get(0));"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":" assertTrue(user.isAdmin);"},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":182,"author":{"gitId":"-"},"content":" * Logs in the user to the test environment as an unregistered user"},{"lineNumber":183,"author":{"gitId":"-"},"content":" * (without any right)."},{"lineNumber":184,"author":{"gitId":"-"},"content":" */"},{"lineNumber":185,"author":{"gitId":"-"},"content":" protected void loginAsUnregistered(String userId) {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" UserInfo user \u003d mockUserProvision.loginUser(userId);"},{"lineNumber":187,"author":{"gitId":"-"},"content":" assertFalse(user.isStudent);"},{"lineNumber":188,"author":{"gitId":"-"},"content":" assertFalse(user.isInstructor);"},{"lineNumber":189,"author":{"gitId":"-"},"content":" assertFalse(user.isAdmin);"},{"lineNumber":190,"author":{"gitId":"-"},"content":" }"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":" * Logs in the user to the test environment as an unregistered user"},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" * (without any right)."},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":" protected void loginAsUnregisteredWithTransaction(String userId) {"},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":" UserInfo user \u003d mockUserProvision.loginUserWithTransaction(userId);"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" assertFalse(user.isStudent);"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":" assertFalse(user.isInstructor);"},{"lineNumber":200,"author":{"gitId":"domoberzin"},"content":" assertFalse(user.isAdmin);"},{"lineNumber":201,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":202,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":204,"author":{"gitId":"-"},"content":" * Logs in the user to the test environment as an instructor"},{"lineNumber":205,"author":{"gitId":"-"},"content":" * (without admin rights or student rights)."},{"lineNumber":206,"author":{"gitId":"-"},"content":" */"},{"lineNumber":207,"author":{"gitId":"-"},"content":" protected void loginAsInstructor(String userId) {"},{"lineNumber":208,"author":{"gitId":"-"},"content":" UserInfo user \u003d mockUserProvision.loginUser(userId);"},{"lineNumber":209,"author":{"gitId":"-"},"content":" assertFalse(user.isStudent);"},{"lineNumber":210,"author":{"gitId":"-"},"content":" assertTrue(user.isInstructor);"},{"lineNumber":211,"author":{"gitId":"-"},"content":" assertFalse(user.isAdmin);"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":215,"author":{"gitId":"domoberzin"},"content":" * Logs in the user to the test environment as an instructor"},{"lineNumber":216,"author":{"gitId":"domoberzin"},"content":" * (without admin rights or student rights)."},{"lineNumber":217,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":218,"author":{"gitId":"domoberzin"},"content":" protected void loginAsInstructorWithTransaction(String userId) {"},{"lineNumber":219,"author":{"gitId":"domoberzin"},"content":" UserInfo user \u003d mockUserProvision.loginUserWithTransaction(userId);"},{"lineNumber":220,"author":{"gitId":"domoberzin"},"content":" assertFalse(user.isStudent);"},{"lineNumber":221,"author":{"gitId":"domoberzin"},"content":" assertTrue(user.isInstructor);"},{"lineNumber":222,"author":{"gitId":"domoberzin"},"content":" assertFalse(user.isAdmin);"},{"lineNumber":223,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":224,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":226,"author":{"gitId":"-"},"content":" * Logs in the user to the test environment as a student"},{"lineNumber":227,"author":{"gitId":"-"},"content":" * (without admin rights or instructor rights)."},{"lineNumber":228,"author":{"gitId":"-"},"content":" */"},{"lineNumber":229,"author":{"gitId":"-"},"content":" protected void loginAsStudent(String userId) {"},{"lineNumber":230,"author":{"gitId":"-"},"content":" UserInfo user \u003d mockUserProvision.loginUser(userId);"},{"lineNumber":231,"author":{"gitId":"-"},"content":" assertTrue(user.isStudent);"},{"lineNumber":232,"author":{"gitId":"-"},"content":" assertFalse(user.isInstructor);"},{"lineNumber":233,"author":{"gitId":"-"},"content":" assertFalse(user.isAdmin);"},{"lineNumber":234,"author":{"gitId":"-"},"content":" }"},{"lineNumber":235,"author":{"gitId":"-"},"content":""},{"lineNumber":236,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":237,"author":{"gitId":"domoberzin"},"content":" * Logs in the user to the test environment as a student"},{"lineNumber":238,"author":{"gitId":"domoberzin"},"content":" * (without admin rights or instructor rights)."},{"lineNumber":239,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":240,"author":{"gitId":"domoberzin"},"content":" protected void loginAsStudentWithTransaction(String userId) {"},{"lineNumber":241,"author":{"gitId":"domoberzin"},"content":" UserInfo user \u003d mockUserProvision.loginUserWithTransaction(userId);"},{"lineNumber":242,"author":{"gitId":"domoberzin"},"content":" assertTrue(user.isStudent);"},{"lineNumber":243,"author":{"gitId":"domoberzin"},"content":" assertFalse(user.isInstructor);"},{"lineNumber":244,"author":{"gitId":"domoberzin"},"content":" assertFalse(user.isAdmin);"},{"lineNumber":245,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":246,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":247,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":248,"author":{"gitId":"-"},"content":" * Logs in the user to the test environment as a student-instructor (without"},{"lineNumber":249,"author":{"gitId":"-"},"content":" * admin rights)."},{"lineNumber":250,"author":{"gitId":"-"},"content":" */"},{"lineNumber":251,"author":{"gitId":"-"},"content":" protected void loginAsStudentInstructor(String userId) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" UserInfo user \u003d mockUserProvision.loginUser(userId);"},{"lineNumber":253,"author":{"gitId":"-"},"content":" assertTrue(user.isStudent);"},{"lineNumber":254,"author":{"gitId":"-"},"content":" assertTrue(user.isInstructor);"},{"lineNumber":255,"author":{"gitId":"-"},"content":" assertFalse(user.isAdmin);"},{"lineNumber":256,"author":{"gitId":"-"},"content":" }"},{"lineNumber":257,"author":{"gitId":"-"},"content":""},{"lineNumber":258,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":259,"author":{"gitId":"-"},"content":" * Logs in the user to the test environment as a maintainer."},{"lineNumber":260,"author":{"gitId":"-"},"content":" */"},{"lineNumber":261,"author":{"gitId":"-"},"content":" protected void loginAsMaintainer() {"},{"lineNumber":262,"author":{"gitId":"-"},"content":" UserInfo user \u003d mockUserProvision.loginUser(Config.APP_MAINTAINERS.get(0));"},{"lineNumber":263,"author":{"gitId":"-"},"content":" assertTrue(user.isMaintainer);"},{"lineNumber":264,"author":{"gitId":"-"},"content":" }"},{"lineNumber":265,"author":{"gitId":"-"},"content":""},{"lineNumber":266,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":267,"author":{"gitId":"-"},"content":" * Logs the current user out of the test environment."},{"lineNumber":268,"author":{"gitId":"-"},"content":" */"},{"lineNumber":269,"author":{"gitId":"-"},"content":" protected void logoutUser() {"},{"lineNumber":270,"author":{"gitId":"-"},"content":" mockUserProvision.logoutUser();"},{"lineNumber":271,"author":{"gitId":"-"},"content":" }"},{"lineNumber":272,"author":{"gitId":"-"},"content":""},{"lineNumber":273,"author":{"gitId":"-"},"content":" void grantInstructorWithSectionPrivilege("},{"lineNumber":274,"author":{"gitId":"-"},"content":" Instructor instructor, String privilege, String[] sections)"},{"lineNumber":275,"author":{"gitId":"-"},"content":" throws Exception {"},{"lineNumber":276,"author":{"gitId":"-"},"content":" InstructorPrivileges instructorPrivileges \u003d new InstructorPrivileges();"},{"lineNumber":277,"author":{"gitId":"-"},"content":""},{"lineNumber":278,"author":{"gitId":"-"},"content":" for (String section : sections) {"},{"lineNumber":279,"author":{"gitId":"-"},"content":" instructorPrivileges.updatePrivilege(section, privilege, true);"},{"lineNumber":280,"author":{"gitId":"-"},"content":" }"},{"lineNumber":281,"author":{"gitId":"-"},"content":""},{"lineNumber":282,"author":{"gitId":"-"},"content":" instructor.setPrivileges(instructorPrivileges);"},{"lineNumber":283,"author":{"gitId":"-"},"content":" assert instructor.isValid();"},{"lineNumber":284,"author":{"gitId":"-"},"content":" }"},{"lineNumber":285,"author":{"gitId":"-"},"content":""},{"lineNumber":286,"author":{"gitId":"-"},"content":" // The next few methods are for testing access control"},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":" // \u0027High-level\u0027 access-control tests: here it tests access control of an action"},{"lineNumber":289,"author":{"gitId":"-"},"content":" // for the full range of user types."},{"lineNumber":290,"author":{"gitId":"-"},"content":""},{"lineNumber":291,"author":{"gitId":"-"},"content":" void verifyAnyUserCanAccess(String... params) {"},{"lineNumber":292,"author":{"gitId":"-"},"content":" verifyAccessibleWithoutLogin(params);"},{"lineNumber":293,"author":{"gitId":"-"},"content":" verifyAccessibleForUnregisteredUsers(params);"},{"lineNumber":294,"author":{"gitId":"-"},"content":" verifyAccessibleForAdmin(params);"},{"lineNumber":295,"author":{"gitId":"-"},"content":" }"},{"lineNumber":296,"author":{"gitId":"-"},"content":""},{"lineNumber":297,"author":{"gitId":"-"},"content":" void verifyAnyLoggedInUserCanAccess(String... params) {"},{"lineNumber":298,"author":{"gitId":"-"},"content":" verifyInaccessibleWithoutLogin(params);"},{"lineNumber":299,"author":{"gitId":"-"},"content":" verifyAccessibleForUnregisteredUsers(params);"},{"lineNumber":300,"author":{"gitId":"-"},"content":" verifyAccessibleForAdmin(params);"},{"lineNumber":301,"author":{"gitId":"-"},"content":" }"},{"lineNumber":302,"author":{"gitId":"-"},"content":""},{"lineNumber":303,"author":{"gitId":"-"},"content":" void verifyOnlyAdminCanAccess(Course course, String... params)"},{"lineNumber":304,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":305,"author":{"gitId":"-"},"content":" verifyInaccessibleWithoutLogin(params);"},{"lineNumber":306,"author":{"gitId":"-"},"content":" verifyInaccessibleForUnregisteredUsers(params);"},{"lineNumber":307,"author":{"gitId":"-"},"content":" verifyInaccessibleForStudents(course, params);"},{"lineNumber":308,"author":{"gitId":"-"},"content":" verifyInaccessibleForInstructors(course, params);"},{"lineNumber":309,"author":{"gitId":"-"},"content":" verifyAccessibleForAdmin(params);"},{"lineNumber":310,"author":{"gitId":"-"},"content":" }"},{"lineNumber":311,"author":{"gitId":"-"},"content":""},{"lineNumber":312,"author":{"gitId":"domoberzin"},"content":" void verifyOnlyAdminCanAccessWithTransaction(String... params)"},{"lineNumber":313,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":314,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":315,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":316,"author":{"gitId":"domoberzin"},"content":" course \u003d logic.createCourse(course);"},{"lineNumber":317,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":318,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":319,"author":{"gitId":"domoberzin"},"content":" verifyInaccessibleWithoutLogin(params);"},{"lineNumber":320,"author":{"gitId":"domoberzin"},"content":" verifyInaccessibleForUnregisteredUsersWithTransaction(params);"},{"lineNumber":321,"author":{"gitId":"domoberzin"},"content":" verifyInaccessibleForStudentsWithTransaction(course, params);"},{"lineNumber":322,"author":{"gitId":"domoberzin"},"content":" verifyInaccessibleForInstructorsWithTransaction(course, params);"},{"lineNumber":323,"author":{"gitId":"domoberzin"},"content":" verifyAccessibleForAdminWithTransaction(params);"},{"lineNumber":324,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":325,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":326,"author":{"gitId":"domoberzin"},"content":" logic.deleteCourseCascade(course.getId());"},{"lineNumber":327,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":328,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":329,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":330,"author":{"gitId":"-"},"content":" void verifyOnlyInstructorsCanAccess(Course course, String... params)"},{"lineNumber":331,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":332,"author":{"gitId":"-"},"content":" verifyInaccessibleWithoutLogin(params);"},{"lineNumber":333,"author":{"gitId":"-"},"content":" verifyInaccessibleForUnregisteredUsers(params);"},{"lineNumber":334,"author":{"gitId":"-"},"content":" verifyInaccessibleForStudents(course, params);"},{"lineNumber":335,"author":{"gitId":"-"},"content":" verifyAccessibleForInstructorsOfTheSameCourse(course, params);"},{"lineNumber":336,"author":{"gitId":"-"},"content":" verifyAccessibleForInstructorsOfOtherCourse(course, params);"},{"lineNumber":337,"author":{"gitId":"-"},"content":" verifyAccessibleForAdminToMasqueradeAsInstructor(course, params);"},{"lineNumber":338,"author":{"gitId":"-"},"content":" }"},{"lineNumber":339,"author":{"gitId":"-"},"content":""},{"lineNumber":340,"author":{"gitId":"-"},"content":" void verifyOnlyInstructorsOfTheSameCourseCanAccess(Course course, String[] submissionParams)"},{"lineNumber":341,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":342,"author":{"gitId":"-"},"content":" verifyInaccessibleWithoutLogin(submissionParams);"},{"lineNumber":343,"author":{"gitId":"-"},"content":" verifyInaccessibleForUnregisteredUsers(submissionParams);"},{"lineNumber":344,"author":{"gitId":"-"},"content":" verifyInaccessibleForStudents(course, submissionParams);"},{"lineNumber":345,"author":{"gitId":"-"},"content":" verifyInaccessibleForInstructorsOfOtherCourses(course, submissionParams);"},{"lineNumber":346,"author":{"gitId":"-"},"content":" verifyAccessibleForInstructorsOfTheSameCourse(course, submissionParams);"},{"lineNumber":347,"author":{"gitId":"-"},"content":" verifyAccessibleForAdminToMasqueradeAsInstructor(course, submissionParams);"},{"lineNumber":348,"author":{"gitId":"-"},"content":" }"},{"lineNumber":349,"author":{"gitId":"-"},"content":""},{"lineNumber":350,"author":{"gitId":"-"},"content":" void verifyOnlyInstructorsOfTheSameCourseWithCorrectCoursePrivilegeCanAccess("},{"lineNumber":351,"author":{"gitId":"-"},"content":" Course course, String privilege, String[] submissionParams) throws Exception {"},{"lineNumber":352,"author":{"gitId":"-"},"content":" verifyInaccessibleWithoutLogin(submissionParams);"},{"lineNumber":353,"author":{"gitId":"-"},"content":" verifyInaccessibleForUnregisteredUsers(submissionParams);"},{"lineNumber":354,"author":{"gitId":"-"},"content":" verifyInaccessibleForStudents(course, submissionParams);"},{"lineNumber":355,"author":{"gitId":"-"},"content":" verifyInaccessibleForInstructorsOfOtherCourses(course, submissionParams);"},{"lineNumber":356,"author":{"gitId":"-"},"content":" verifyInaccessibleWithoutCorrectCoursePrivilege(course, privilege, submissionParams);"},{"lineNumber":357,"author":{"gitId":"-"},"content":" }"},{"lineNumber":358,"author":{"gitId":"-"},"content":""},{"lineNumber":359,"author":{"gitId":"-"},"content":" // \u0027Mid-level\u0027 access control tests: here it tests access control of an action"},{"lineNumber":360,"author":{"gitId":"-"},"content":" // for one user type."},{"lineNumber":361,"author":{"gitId":"-"},"content":""},{"lineNumber":362,"author":{"gitId":"-"},"content":" void verifyAccessibleWithoutLogin(String... params) {"},{"lineNumber":363,"author":{"gitId":"-"},"content":" ______TS(\"Non-logged-in users can access\");"},{"lineNumber":364,"author":{"gitId":"-"},"content":""},{"lineNumber":365,"author":{"gitId":"-"},"content":" logoutUser();"},{"lineNumber":366,"author":{"gitId":"-"},"content":" verifyCanAccess(params);"},{"lineNumber":367,"author":{"gitId":"-"},"content":" }"},{"lineNumber":368,"author":{"gitId":"-"},"content":""},{"lineNumber":369,"author":{"gitId":"-"},"content":" void verifyInaccessibleWithoutLogin(String... params) {"},{"lineNumber":370,"author":{"gitId":"-"},"content":" ______TS(\"Non-logged-in users cannot access\");"},{"lineNumber":371,"author":{"gitId":"-"},"content":""},{"lineNumber":372,"author":{"gitId":"-"},"content":" logoutUser();"},{"lineNumber":373,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":374,"author":{"gitId":"-"},"content":" }"},{"lineNumber":375,"author":{"gitId":"-"},"content":""},{"lineNumber":376,"author":{"gitId":"-"},"content":" void verifyAccessibleForUnregisteredUsers(String... params) {"},{"lineNumber":377,"author":{"gitId":"-"},"content":" ______TS(\"Non-registered users can access\");"},{"lineNumber":378,"author":{"gitId":"-"},"content":""},{"lineNumber":379,"author":{"gitId":"-"},"content":" String unregUserId \u003d \"unreg.user\";"},{"lineNumber":380,"author":{"gitId":"-"},"content":" loginAsUnregistered(unregUserId);"},{"lineNumber":381,"author":{"gitId":"-"},"content":" verifyCanAccess(params);"},{"lineNumber":382,"author":{"gitId":"-"},"content":" }"},{"lineNumber":383,"author":{"gitId":"-"},"content":""},{"lineNumber":384,"author":{"gitId":"-"},"content":" void verifyInaccessibleForUnregisteredUsers(String... params) {"},{"lineNumber":385,"author":{"gitId":"-"},"content":" ______TS(\"Non-registered users cannot access\");"},{"lineNumber":386,"author":{"gitId":"-"},"content":""},{"lineNumber":387,"author":{"gitId":"-"},"content":" String unregUserId \u003d \"unreg.user\";"},{"lineNumber":388,"author":{"gitId":"-"},"content":" loginAsUnregistered(unregUserId);"},{"lineNumber":389,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":390,"author":{"gitId":"-"},"content":" }"},{"lineNumber":391,"author":{"gitId":"-"},"content":""},{"lineNumber":392,"author":{"gitId":"domoberzin"},"content":" void verifyInaccessibleForUnregisteredUsersWithTransaction(String... params) {"},{"lineNumber":393,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Non-registered users cannot access\");"},{"lineNumber":394,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":395,"author":{"gitId":"domoberzin"},"content":" String unregUserId \u003d \"unreg.user\";"},{"lineNumber":396,"author":{"gitId":"domoberzin"},"content":" loginAsUnregisteredWithTransaction(unregUserId);"},{"lineNumber":397,"author":{"gitId":"domoberzin"},"content":" verifyCannotAccess(params);"},{"lineNumber":398,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":399,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":400,"author":{"gitId":"-"},"content":" void verifyAccessibleForAdmin(String... params) {"},{"lineNumber":401,"author":{"gitId":"-"},"content":" ______TS(\"Admin can access\");"},{"lineNumber":402,"author":{"gitId":"-"},"content":""},{"lineNumber":403,"author":{"gitId":"-"},"content":" loginAsAdmin();"},{"lineNumber":404,"author":{"gitId":"-"},"content":" verifyCanAccess(params);"},{"lineNumber":405,"author":{"gitId":"-"},"content":" }"},{"lineNumber":406,"author":{"gitId":"-"},"content":""},{"lineNumber":407,"author":{"gitId":"domoberzin"},"content":" void verifyAccessibleForAdminWithTransaction(String... params) {"},{"lineNumber":408,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Admin can access\");"},{"lineNumber":409,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":410,"author":{"gitId":"domoberzin"},"content":" loginAsAdminWithTransaction();"},{"lineNumber":411,"author":{"gitId":"domoberzin"},"content":" verifyCanAccess(params);"},{"lineNumber":412,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":413,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":414,"author":{"gitId":"-"},"content":" void verifyInaccessibleForAdmin(String... params) {"},{"lineNumber":415,"author":{"gitId":"-"},"content":" ______TS(\"Admin cannot access\");"},{"lineNumber":416,"author":{"gitId":"-"},"content":""},{"lineNumber":417,"author":{"gitId":"-"},"content":" loginAsAdmin();"},{"lineNumber":418,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":419,"author":{"gitId":"-"},"content":" }"},{"lineNumber":420,"author":{"gitId":"-"},"content":""},{"lineNumber":421,"author":{"gitId":"-"},"content":" void verifyInaccessibleForStudents(Course course, String... params)"},{"lineNumber":422,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":423,"author":{"gitId":"-"},"content":" ______TS(\"Students cannot access\");"},{"lineNumber":424,"author":{"gitId":"-"},"content":" Student student \u003d createTypicalStudent(course, \"InaccessibleForStudents@teammates.tmt\");"},{"lineNumber":425,"author":{"gitId":"-"},"content":""},{"lineNumber":426,"author":{"gitId":"-"},"content":" loginAsStudent(student.getAccount().getGoogleId());"},{"lineNumber":427,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":428,"author":{"gitId":"-"},"content":""},{"lineNumber":429,"author":{"gitId":"-"},"content":" }"},{"lineNumber":430,"author":{"gitId":"-"},"content":""},{"lineNumber":431,"author":{"gitId":"domoberzin"},"content":" void verifyInaccessibleForStudentsWithTransaction(Course course, String... params)"},{"lineNumber":432,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":433,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Students cannot access\");"},{"lineNumber":434,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":435,"author":{"gitId":"domoberzin"},"content":" Student student \u003d createTypicalStudent(course, \"InaccessibleForStudents@teammates.tmt\");"},{"lineNumber":436,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":437,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":438,"author":{"gitId":"domoberzin"},"content":" loginAsStudentWithTransaction(student.getAccount().getGoogleId());"},{"lineNumber":439,"author":{"gitId":"domoberzin"},"content":" verifyCannotAccess(params);"},{"lineNumber":440,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":441,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":442,"author":{"gitId":"domoberzin"},"content":" logic.deleteAccountCascade(student.getAccount().getGoogleId());"},{"lineNumber":443,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":444,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":445,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":446,"author":{"gitId":"-"},"content":" void verifyInaccessibleForInstructors(Course course, String... params)"},{"lineNumber":447,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":448,"author":{"gitId":"-"},"content":" ______TS(\"Instructors cannot access\");"},{"lineNumber":449,"author":{"gitId":"-"},"content":" Instructor instructor \u003d createTypicalInstructor(course, \"InaccessibleForInstructors@teammates.tmt\");"},{"lineNumber":450,"author":{"gitId":"-"},"content":""},{"lineNumber":451,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getAccount().getGoogleId());"},{"lineNumber":452,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":453,"author":{"gitId":"-"},"content":""},{"lineNumber":454,"author":{"gitId":"-"},"content":" }"},{"lineNumber":455,"author":{"gitId":"-"},"content":""},{"lineNumber":456,"author":{"gitId":"domoberzin"},"content":" void verifyInaccessibleForInstructorsWithTransaction(Course course, String... params)"},{"lineNumber":457,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":458,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Instructors cannot access\");"},{"lineNumber":459,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":460,"author":{"gitId":"domoberzin"},"content":" Instructor instructor \u003d createTypicalInstructor(course, \"InaccessibleForInstructors@teammates.tmt\");"},{"lineNumber":461,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":462,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":463,"author":{"gitId":"domoberzin"},"content":" loginAsInstructorWithTransaction(instructor.getAccount().getGoogleId());"},{"lineNumber":464,"author":{"gitId":"domoberzin"},"content":" verifyCannotAccess(params);"},{"lineNumber":465,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":466,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":467,"author":{"gitId":"domoberzin"},"content":" logic.deleteAccountCascade(instructor.getAccount().getGoogleId());"},{"lineNumber":468,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":469,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":470,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":471,"author":{"gitId":"-"},"content":" void verifyAccessibleForAdminToMasqueradeAsInstructor("},{"lineNumber":472,"author":{"gitId":"-"},"content":" Instructor instructor, String[] submissionParams) {"},{"lineNumber":473,"author":{"gitId":"-"},"content":" ______TS(\"admin can access\");"},{"lineNumber":474,"author":{"gitId":"-"},"content":""},{"lineNumber":475,"author":{"gitId":"-"},"content":" loginAsAdmin();"},{"lineNumber":476,"author":{"gitId":"-"},"content":" // not checking for non-masquerade mode because admin may not be an instructor"},{"lineNumber":477,"author":{"gitId":"-"},"content":" verifyCanMasquerade(instructor.getAccount().getGoogleId(), submissionParams);"},{"lineNumber":478,"author":{"gitId":"-"},"content":" }"},{"lineNumber":479,"author":{"gitId":"-"},"content":""},{"lineNumber":480,"author":{"gitId":"-"},"content":" void verifyAccessibleForAdminToMasqueradeAsInstructor(Course course, String[] submissionParams)"},{"lineNumber":481,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":482,"author":{"gitId":"-"},"content":" ______TS(\"admin can access\");"},{"lineNumber":483,"author":{"gitId":"-"},"content":" Instructor instructor \u003d createTypicalInstructor(course,"},{"lineNumber":484,"author":{"gitId":"-"},"content":" \"AccessibleForAdminToMasqueradeAsInstructor@teammates.tmt\");"},{"lineNumber":485,"author":{"gitId":"-"},"content":""},{"lineNumber":486,"author":{"gitId":"-"},"content":" loginAsAdmin();"},{"lineNumber":487,"author":{"gitId":"-"},"content":" // not checking for non-masquerade mode because admin may not be an instructor"},{"lineNumber":488,"author":{"gitId":"-"},"content":" verifyCanMasquerade(instructor.getAccount().getGoogleId(), submissionParams);"},{"lineNumber":489,"author":{"gitId":"-"},"content":" }"},{"lineNumber":490,"author":{"gitId":"-"},"content":""},{"lineNumber":491,"author":{"gitId":"-"},"content":" void verifyInaccessibleWithoutModifySessionPrivilege(Course course, String[] submissionParams)"},{"lineNumber":492,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":493,"author":{"gitId":"-"},"content":" ______TS(\"without Modify-Session privilege cannot access\");"},{"lineNumber":494,"author":{"gitId":"-"},"content":""},{"lineNumber":495,"author":{"gitId":"-"},"content":" Instructor instructor \u003d createTypicalInstructor(course,"},{"lineNumber":496,"author":{"gitId":"-"},"content":" \"InaccessibleWithoutModifySessionPrivilege@teammates.tmt\");"},{"lineNumber":497,"author":{"gitId":"-"},"content":""},{"lineNumber":498,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getAccount().getGoogleId());"},{"lineNumber":499,"author":{"gitId":"-"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":500,"author":{"gitId":"-"},"content":" }"},{"lineNumber":501,"author":{"gitId":"-"},"content":""},{"lineNumber":502,"author":{"gitId":"-"},"content":" void verifyInaccessibleWithoutSubmitSessionInSectionsPrivilege(Course course, String[] submissionParams)"},{"lineNumber":503,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":504,"author":{"gitId":"-"},"content":" ______TS(\"without Submit-Session-In-Sections privilege cannot access\");"},{"lineNumber":505,"author":{"gitId":"-"},"content":""},{"lineNumber":506,"author":{"gitId":"-"},"content":" Instructor instructor \u003d createTypicalInstructor(course,"},{"lineNumber":507,"author":{"gitId":"-"},"content":" \"InaccessibleWithoutSubmitSessionInSectionsPrivilege@teammates.tmt\");"},{"lineNumber":508,"author":{"gitId":"-"},"content":""},{"lineNumber":509,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getAccount().getGoogleId());"},{"lineNumber":510,"author":{"gitId":"-"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":511,"author":{"gitId":"-"},"content":" }"},{"lineNumber":512,"author":{"gitId":"-"},"content":""},{"lineNumber":513,"author":{"gitId":"-"},"content":" void verifyInaccessibleWithoutCorrectCoursePrivilege(Course course, String privilege, String[] submissionParams)"},{"lineNumber":514,"author":{"gitId":"-"},"content":" throws Exception {"},{"lineNumber":515,"author":{"gitId":"-"},"content":" Instructor instructor \u003d createTypicalInstructor(course,"},{"lineNumber":516,"author":{"gitId":"-"},"content":" \"InaccessibleWithoutCorrectCoursePrivilege@teammates.tmt\");"},{"lineNumber":517,"author":{"gitId":"-"},"content":""},{"lineNumber":518,"author":{"gitId":"-"},"content":" ______TS(\"without correct course privilege cannot access\");"},{"lineNumber":519,"author":{"gitId":"-"},"content":""},{"lineNumber":520,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getAccount().getGoogleId());"},{"lineNumber":521,"author":{"gitId":"-"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":522,"author":{"gitId":"-"},"content":""},{"lineNumber":523,"author":{"gitId":"-"},"content":" ______TS(\"only instructor with correct course privilege should pass\");"},{"lineNumber":524,"author":{"gitId":"-"},"content":" InstructorPrivileges instructorPrivileges \u003d new InstructorPrivileges();"},{"lineNumber":525,"author":{"gitId":"-"},"content":""},{"lineNumber":526,"author":{"gitId":"-"},"content":" instructorPrivileges.updatePrivilege(privilege, true);"},{"lineNumber":527,"author":{"gitId":"-"},"content":" instructor.setPrivileges(instructorPrivileges);"},{"lineNumber":528,"author":{"gitId":"-"},"content":""},{"lineNumber":529,"author":{"gitId":"-"},"content":" verifyCanAccess(submissionParams);"},{"lineNumber":530,"author":{"gitId":"-"},"content":" verifyAccessibleForAdminToMasqueradeAsInstructor(instructor, submissionParams);"},{"lineNumber":531,"author":{"gitId":"-"},"content":" }"},{"lineNumber":532,"author":{"gitId":"-"},"content":""},{"lineNumber":533,"author":{"gitId":"-"},"content":" void verifyAccessibleForInstructorsOfTheSameCourse(Course course, String[] submissionParams)"},{"lineNumber":534,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":535,"author":{"gitId":"-"},"content":" ______TS(\"course instructor can access\");"},{"lineNumber":536,"author":{"gitId":"-"},"content":" Course courseOther \u003d createTestCourseOther();"},{"lineNumber":537,"author":{"gitId":"-"},"content":" assert !course.getId().equals(courseOther.getId());"},{"lineNumber":538,"author":{"gitId":"-"},"content":""},{"lineNumber":539,"author":{"gitId":"-"},"content":" Instructor instructorSameCourse \u003d createTypicalInstructor(course,"},{"lineNumber":540,"author":{"gitId":"-"},"content":" \"AccessibleForInstructorsOfTheSameCourse-instructor@teammates.tmt\");"},{"lineNumber":541,"author":{"gitId":"-"},"content":" Student studentSameCourse \u003d createTypicalStudent(course,"},{"lineNumber":542,"author":{"gitId":"-"},"content":" \"AccessibleForInstructorsOfTheSameCourse-student@teammates.tmt\");"},{"lineNumber":543,"author":{"gitId":"-"},"content":" Instructor instructorOtherCourse \u003d createTypicalInstructor(courseOther,"},{"lineNumber":544,"author":{"gitId":"-"},"content":" \"AccessibleForInstructorsOfTheSameCourse-OtherInstructor@teammates.tmt\");"},{"lineNumber":545,"author":{"gitId":"-"},"content":""},{"lineNumber":546,"author":{"gitId":"-"},"content":" loginAsInstructor(instructorSameCourse.getAccount().getGoogleId());"},{"lineNumber":547,"author":{"gitId":"-"},"content":" verifyCanAccess(submissionParams);"},{"lineNumber":548,"author":{"gitId":"-"},"content":""},{"lineNumber":549,"author":{"gitId":"-"},"content":" verifyCannotMasquerade(studentSameCourse.getAccount().getGoogleId(), submissionParams);"},{"lineNumber":550,"author":{"gitId":"-"},"content":" verifyCannotMasquerade(instructorOtherCourse.getAccount().getGoogleId(), submissionParams);"},{"lineNumber":551,"author":{"gitId":"-"},"content":""},{"lineNumber":552,"author":{"gitId":"-"},"content":" }"},{"lineNumber":553,"author":{"gitId":"-"},"content":""},{"lineNumber":554,"author":{"gitId":"-"},"content":" void verifyAccessibleForInstructorsOfOtherCourse(Course course, String[] submissionParams)"},{"lineNumber":555,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":556,"author":{"gitId":"-"},"content":" ______TS(\"other course\u0027s instructor can access\");"},{"lineNumber":557,"author":{"gitId":"-"},"content":" Course courseOther \u003d createTestCourseOther();"},{"lineNumber":558,"author":{"gitId":"-"},"content":" assert !course.getId().equals(courseOther.getId());"},{"lineNumber":559,"author":{"gitId":"-"},"content":""},{"lineNumber":560,"author":{"gitId":"-"},"content":" Instructor instructorSameCourse \u003d createTypicalInstructor(course,"},{"lineNumber":561,"author":{"gitId":"-"},"content":" \"AccessibleForInstructorsOfOtherCourse-instructor@teammates.tmt\");"},{"lineNumber":562,"author":{"gitId":"-"},"content":" Student studentSameCourse \u003d createTypicalStudent(course,"},{"lineNumber":563,"author":{"gitId":"-"},"content":" \"AccessibleForInstructorsOfOtherCourse-student@teammates.tmt\");"},{"lineNumber":564,"author":{"gitId":"-"},"content":" Instructor instructorOtherCourse \u003d createTypicalInstructor(courseOther,"},{"lineNumber":565,"author":{"gitId":"-"},"content":" \"AccessibleForInstructorsOfOtherCourse-OtherInstructor@teammates.tmt\");"},{"lineNumber":566,"author":{"gitId":"-"},"content":""},{"lineNumber":567,"author":{"gitId":"-"},"content":" loginAsInstructor(instructorOtherCourse.getAccount().getGoogleId());"},{"lineNumber":568,"author":{"gitId":"-"},"content":" verifyCanAccess(submissionParams);"},{"lineNumber":569,"author":{"gitId":"-"},"content":""},{"lineNumber":570,"author":{"gitId":"-"},"content":" verifyCannotMasquerade(studentSameCourse.getAccount().getGoogleId(), submissionParams);"},{"lineNumber":571,"author":{"gitId":"-"},"content":" verifyCannotMasquerade(instructorSameCourse.getAccount().getGoogleId(), submissionParams);"},{"lineNumber":572,"author":{"gitId":"-"},"content":" }"},{"lineNumber":573,"author":{"gitId":"-"},"content":""},{"lineNumber":574,"author":{"gitId":"-"},"content":" void verifyAccessibleForStudentsOfTheSameCourse(Course course, String[] submissionParams)"},{"lineNumber":575,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":576,"author":{"gitId":"-"},"content":" ______TS(\"course students can access\");"},{"lineNumber":577,"author":{"gitId":"-"},"content":" Student student \u003d createTypicalStudent(course, \"AccessibleForStudentsOfTheSameCourse@teammates.tmt\");"},{"lineNumber":578,"author":{"gitId":"-"},"content":" loginAsStudent(student.getAccount().getGoogleId());"},{"lineNumber":579,"author":{"gitId":"-"},"content":" verifyCanAccess(submissionParams);"},{"lineNumber":580,"author":{"gitId":"-"},"content":" }"},{"lineNumber":581,"author":{"gitId":"-"},"content":""},{"lineNumber":582,"author":{"gitId":"-"},"content":" void verifyInaccessibleForStudentsOfOtherCourse(Course course, String[] submissionParams)"},{"lineNumber":583,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":584,"author":{"gitId":"-"},"content":" ______TS(\"other course student cannot access\");"},{"lineNumber":585,"author":{"gitId":"-"},"content":" Course courseOther \u003d createTestCourseOther();"},{"lineNumber":586,"author":{"gitId":"-"},"content":" Student otherStudent \u003d createTypicalStudent(courseOther,"},{"lineNumber":587,"author":{"gitId":"-"},"content":" \"InaccessibleForStudentsOfOtherCourse-other@teammates.tmt\");"},{"lineNumber":588,"author":{"gitId":"-"},"content":" assert !course.getId().equals(courseOther.getId());"},{"lineNumber":589,"author":{"gitId":"-"},"content":""},{"lineNumber":590,"author":{"gitId":"-"},"content":" loginAsStudent(otherStudent.getAccount().getGoogleId());"},{"lineNumber":591,"author":{"gitId":"-"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":592,"author":{"gitId":"-"},"content":" }"},{"lineNumber":593,"author":{"gitId":"-"},"content":""},{"lineNumber":594,"author":{"gitId":"-"},"content":" void verifyInaccessibleForInstructorsOfOtherCourses(Course course, String[] submissionParams)"},{"lineNumber":595,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":596,"author":{"gitId":"-"},"content":" ______TS(\"other course instructor cannot access\");"},{"lineNumber":597,"author":{"gitId":"-"},"content":" Course courseOther \u003d createTestCourseOther();"},{"lineNumber":598,"author":{"gitId":"-"},"content":" Instructor otherInstructor \u003d createTypicalInstructor(courseOther,"},{"lineNumber":599,"author":{"gitId":"-"},"content":" \"InaccessibleForInstructorsOfOtherCourses@teammates.tmt\");"},{"lineNumber":600,"author":{"gitId":"-"},"content":" assert !course.getId().equals(courseOther.getId());"},{"lineNumber":601,"author":{"gitId":"-"},"content":""},{"lineNumber":602,"author":{"gitId":"-"},"content":" loginAsInstructor(otherInstructor.getAccount().getGoogleId());"},{"lineNumber":603,"author":{"gitId":"-"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":604,"author":{"gitId":"-"},"content":" }"},{"lineNumber":605,"author":{"gitId":"-"},"content":""},{"lineNumber":606,"author":{"gitId":"-"},"content":" void verifyAccessibleForMaintainers(String... params) {"},{"lineNumber":607,"author":{"gitId":"-"},"content":" ______TS(\"Maintainer can access\");"},{"lineNumber":608,"author":{"gitId":"-"},"content":""},{"lineNumber":609,"author":{"gitId":"-"},"content":" loginAsMaintainer();"},{"lineNumber":610,"author":{"gitId":"-"},"content":" verifyCanAccess(params);"},{"lineNumber":611,"author":{"gitId":"-"},"content":" }"},{"lineNumber":612,"author":{"gitId":"-"},"content":""},{"lineNumber":613,"author":{"gitId":"-"},"content":" // \u0027Low-level\u0027 access control tests: here it tests an action once with the given"},{"lineNumber":614,"author":{"gitId":"-"},"content":" // parameters."},{"lineNumber":615,"author":{"gitId":"-"},"content":" // These methods are not aware of the user type."},{"lineNumber":616,"author":{"gitId":"-"},"content":""},{"lineNumber":617,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":618,"author":{"gitId":"-"},"content":" * Verifies that the {@link Action} matching the {@code params} is accessible to"},{"lineNumber":619,"author":{"gitId":"-"},"content":" * the logged in user."},{"lineNumber":620,"author":{"gitId":"-"},"content":" */"},{"lineNumber":621,"author":{"gitId":"-"},"content":" protected void verifyCanAccess(String... params) {"},{"lineNumber":622,"author":{"gitId":"-"},"content":" Action c \u003d getAction(params);"},{"lineNumber":623,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":624,"author":{"gitId":"-"},"content":" c.checkAccessControl();"},{"lineNumber":625,"author":{"gitId":"-"},"content":" } catch (UnauthorizedAccessException e) {"},{"lineNumber":626,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":627,"author":{"gitId":"-"},"content":" }"},{"lineNumber":628,"author":{"gitId":"-"},"content":" }"},{"lineNumber":629,"author":{"gitId":"-"},"content":""},{"lineNumber":630,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":631,"author":{"gitId":"-"},"content":" * Verifies that the {@link Action} matching the {@code params} is not"},{"lineNumber":632,"author":{"gitId":"-"},"content":" * accessible to the user."},{"lineNumber":633,"author":{"gitId":"-"},"content":" */"},{"lineNumber":634,"author":{"gitId":"-"},"content":" protected void verifyCannotAccess(String... params) {"},{"lineNumber":635,"author":{"gitId":"-"},"content":" Action c \u003d getAction(params);"},{"lineNumber":636,"author":{"gitId":"-"},"content":" assertThrows(UnauthorizedAccessException.class, c::checkAccessControl);"},{"lineNumber":637,"author":{"gitId":"-"},"content":" }"},{"lineNumber":638,"author":{"gitId":"-"},"content":""},{"lineNumber":639,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":640,"author":{"gitId":"-"},"content":" * Verifies that the {@link Action} matching the {@code params} is"},{"lineNumber":641,"author":{"gitId":"-"},"content":" * accessible to the logged in user masquerading as another user with"},{"lineNumber":642,"author":{"gitId":"-"},"content":" * {@code userId}."},{"lineNumber":643,"author":{"gitId":"-"},"content":" */"},{"lineNumber":644,"author":{"gitId":"-"},"content":" protected void verifyCanMasquerade(String userId, String... params) {"},{"lineNumber":645,"author":{"gitId":"-"},"content":" verifyCanAccess(addUserIdToParams(userId, params));"},{"lineNumber":646,"author":{"gitId":"-"},"content":" }"},{"lineNumber":647,"author":{"gitId":"-"},"content":""},{"lineNumber":648,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":649,"author":{"gitId":"-"},"content":" * Verifies that the {@link Action} matching the {@code params} is not"},{"lineNumber":650,"author":{"gitId":"-"},"content":" * accessible to the logged in user masquerading as another user with"},{"lineNumber":651,"author":{"gitId":"-"},"content":" * {@code userId}."},{"lineNumber":652,"author":{"gitId":"-"},"content":" */"},{"lineNumber":653,"author":{"gitId":"-"},"content":" protected void verifyCannotMasquerade(String userId, String... params) {"},{"lineNumber":654,"author":{"gitId":"-"},"content":" assertThrows(UnauthorizedAccessException.class,"},{"lineNumber":655,"author":{"gitId":"-"},"content":" () -\u003e getAction(addUserIdToParams(userId, params)).checkAccessControl());"},{"lineNumber":656,"author":{"gitId":"-"},"content":" }"},{"lineNumber":657,"author":{"gitId":"-"},"content":""},{"lineNumber":658,"author":{"gitId":"-"},"content":" // The next few methods are for parsing results"},{"lineNumber":659,"author":{"gitId":"-"},"content":""},{"lineNumber":660,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":661,"author":{"gitId":"-"},"content":" * Executes the action, verifies the status code as 200 OK, and returns the"},{"lineNumber":662,"author":{"gitId":"-"},"content":" * result."},{"lineNumber":663,"author":{"gitId":"-"},"content":" *"},{"lineNumber":664,"author":{"gitId":"-"},"content":" * \u003cp\u003eAssumption: The action returns a {@link JsonResult}."},{"lineNumber":665,"author":{"gitId":"-"},"content":" */"},{"lineNumber":666,"author":{"gitId":"-"},"content":" protected JsonResult getJsonResult(Action a) {"},{"lineNumber":667,"author":{"gitId":"-"},"content":" return getJsonResult(a, HttpStatus.SC_OK);"},{"lineNumber":668,"author":{"gitId":"-"},"content":" }"},{"lineNumber":669,"author":{"gitId":"-"},"content":""},{"lineNumber":670,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":671,"author":{"gitId":"-"},"content":" * Executes the action, verifies the status code, and returns the result."},{"lineNumber":672,"author":{"gitId":"-"},"content":" *"},{"lineNumber":673,"author":{"gitId":"-"},"content":" * \u003cp\u003eAssumption: The action returns a {@link JsonResult}."},{"lineNumber":674,"author":{"gitId":"-"},"content":" */"},{"lineNumber":675,"author":{"gitId":"-"},"content":" protected JsonResult getJsonResult(Action a, int statusCode) {"},{"lineNumber":676,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":677,"author":{"gitId":"-"},"content":" ActionResult r \u003d a.execute();"},{"lineNumber":678,"author":{"gitId":"-"},"content":" assertEquals(statusCode, r.getStatusCode());"},{"lineNumber":679,"author":{"gitId":"-"},"content":" return (JsonResult) r;"},{"lineNumber":680,"author":{"gitId":"-"},"content":" } catch (InvalidOperationException | InvalidHttpRequestBodyException e) {"},{"lineNumber":681,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":682,"author":{"gitId":"-"},"content":" }"},{"lineNumber":683,"author":{"gitId":"-"},"content":" }"},{"lineNumber":684,"author":{"gitId":"-"},"content":""},{"lineNumber":685,"author":{"gitId":"-"},"content":" // The next few methods are for verifying action results"},{"lineNumber":686,"author":{"gitId":"-"},"content":""},{"lineNumber":687,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":688,"author":{"gitId":"-"},"content":" * Verifies that the executed action results in"},{"lineNumber":689,"author":{"gitId":"-"},"content":" * {@link InvalidHttpParameterException} being thrown."},{"lineNumber":690,"author":{"gitId":"-"},"content":" */"},{"lineNumber":691,"author":{"gitId":"-"},"content":" protected InvalidHttpParameterException verifyHttpParameterFailure(String... params) {"},{"lineNumber":692,"author":{"gitId":"-"},"content":" Action c \u003d getAction(params);"},{"lineNumber":693,"author":{"gitId":"-"},"content":" return assertThrows(InvalidHttpParameterException.class, c::execute);"},{"lineNumber":694,"author":{"gitId":"-"},"content":" }"},{"lineNumber":695,"author":{"gitId":"-"},"content":""},{"lineNumber":696,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":697,"author":{"gitId":"-"},"content":" * Verifies that the executed action results in"},{"lineNumber":698,"author":{"gitId":"-"},"content":" * {@link InvalidHttpParameterException} being thrown."},{"lineNumber":699,"author":{"gitId":"-"},"content":" */"},{"lineNumber":700,"author":{"gitId":"-"},"content":" protected InvalidHttpParameterException verifyHttpParameterFailure(BasicRequest requestBody, String... params) {"},{"lineNumber":701,"author":{"gitId":"-"},"content":" Action c \u003d getAction(requestBody, params);"},{"lineNumber":702,"author":{"gitId":"-"},"content":" return assertThrows(InvalidHttpParameterException.class, c::execute);"},{"lineNumber":703,"author":{"gitId":"-"},"content":" }"},{"lineNumber":704,"author":{"gitId":"-"},"content":""},{"lineNumber":705,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":706,"author":{"gitId":"-"},"content":" * Verifies that the action results in {@link InvalidHttpParameterException}"},{"lineNumber":707,"author":{"gitId":"-"},"content":" * being thrown"},{"lineNumber":708,"author":{"gitId":"-"},"content":" * when checking for access control."},{"lineNumber":709,"author":{"gitId":"-"},"content":" */"},{"lineNumber":710,"author":{"gitId":"-"},"content":" protected InvalidHttpParameterException verifyHttpParameterFailureAcl(String... params) {"},{"lineNumber":711,"author":{"gitId":"-"},"content":" Action c \u003d getAction(params);"},{"lineNumber":712,"author":{"gitId":"-"},"content":" return assertThrows(InvalidHttpParameterException.class, c::checkAccessControl);"},{"lineNumber":713,"author":{"gitId":"-"},"content":" }"},{"lineNumber":714,"author":{"gitId":"-"},"content":""},{"lineNumber":715,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":716,"author":{"gitId":"-"},"content":" * Verifies that the executed action results in"},{"lineNumber":717,"author":{"gitId":"-"},"content":" * {@link InvalidHttpRequestBodyException} being thrown."},{"lineNumber":718,"author":{"gitId":"-"},"content":" */"},{"lineNumber":719,"author":{"gitId":"-"},"content":" protected InvalidHttpRequestBodyException verifyHttpRequestBodyFailure(BasicRequest requestBody, String... params) {"},{"lineNumber":720,"author":{"gitId":"-"},"content":" Action c \u003d getAction(requestBody, params);"},{"lineNumber":721,"author":{"gitId":"-"},"content":" return assertThrows(InvalidHttpRequestBodyException.class, c::execute);"},{"lineNumber":722,"author":{"gitId":"-"},"content":" }"},{"lineNumber":723,"author":{"gitId":"-"},"content":""},{"lineNumber":724,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":725,"author":{"gitId":"-"},"content":" * Verifies that the executed action results in {@link EntityNotFoundException}"},{"lineNumber":726,"author":{"gitId":"-"},"content":" * being thrown."},{"lineNumber":727,"author":{"gitId":"-"},"content":" */"},{"lineNumber":728,"author":{"gitId":"-"},"content":" protected EntityNotFoundException verifyEntityNotFound(String... params) {"},{"lineNumber":729,"author":{"gitId":"-"},"content":" Action c \u003d getAction(params);"},{"lineNumber":730,"author":{"gitId":"-"},"content":" return assertThrows(EntityNotFoundException.class, c::execute);"},{"lineNumber":731,"author":{"gitId":"-"},"content":" }"},{"lineNumber":732,"author":{"gitId":"-"},"content":""},{"lineNumber":733,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":734,"author":{"gitId":"-"},"content":" * Verifies that the executed action results in {@link EntityNotFoundException}"},{"lineNumber":735,"author":{"gitId":"-"},"content":" * being thrown."},{"lineNumber":736,"author":{"gitId":"-"},"content":" */"},{"lineNumber":737,"author":{"gitId":"-"},"content":" protected EntityNotFoundException verifyEntityNotFound(BasicRequest requestBody, String... params) {"},{"lineNumber":738,"author":{"gitId":"-"},"content":" Action c \u003d getAction(requestBody, params);"},{"lineNumber":739,"author":{"gitId":"-"},"content":" return assertThrows(EntityNotFoundException.class, c::execute);"},{"lineNumber":740,"author":{"gitId":"-"},"content":" }"},{"lineNumber":741,"author":{"gitId":"-"},"content":""},{"lineNumber":742,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":743,"author":{"gitId":"-"},"content":" * Verifies that the action results in {@link EntityNotFoundException} being"},{"lineNumber":744,"author":{"gitId":"-"},"content":" * thrown when checking for access control."},{"lineNumber":745,"author":{"gitId":"-"},"content":" */"},{"lineNumber":746,"author":{"gitId":"-"},"content":" protected EntityNotFoundException verifyEntityNotFoundAcl(String... params) {"},{"lineNumber":747,"author":{"gitId":"-"},"content":" Action c \u003d getAction(params);"},{"lineNumber":748,"author":{"gitId":"-"},"content":" return assertThrows(EntityNotFoundException.class, c::checkAccessControl);"},{"lineNumber":749,"author":{"gitId":"-"},"content":" }"},{"lineNumber":750,"author":{"gitId":"-"},"content":""},{"lineNumber":751,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":752,"author":{"gitId":"-"},"content":" * Verifies that the executed action results in"},{"lineNumber":753,"author":{"gitId":"-"},"content":" * {@link InvalidOperationException} being thrown."},{"lineNumber":754,"author":{"gitId":"-"},"content":" */"},{"lineNumber":755,"author":{"gitId":"-"},"content":" protected InvalidOperationException verifyInvalidOperation(String... params) {"},{"lineNumber":756,"author":{"gitId":"-"},"content":" Action c \u003d getAction(params);"},{"lineNumber":757,"author":{"gitId":"-"},"content":" return assertThrows(InvalidOperationException.class, c::execute);"},{"lineNumber":758,"author":{"gitId":"-"},"content":" }"},{"lineNumber":759,"author":{"gitId":"-"},"content":""},{"lineNumber":760,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":761,"author":{"gitId":"-"},"content":" * Verifies that the executed action results in"},{"lineNumber":762,"author":{"gitId":"-"},"content":" * {@link InvalidOperationException} being thrown."},{"lineNumber":763,"author":{"gitId":"-"},"content":" */"},{"lineNumber":764,"author":{"gitId":"-"},"content":" protected InvalidOperationException verifyInvalidOperation(BasicRequest requestBody, String... params) {"},{"lineNumber":765,"author":{"gitId":"-"},"content":" Action c \u003d getAction(requestBody, params);"},{"lineNumber":766,"author":{"gitId":"-"},"content":" return assertThrows(InvalidOperationException.class, c::execute);"},{"lineNumber":767,"author":{"gitId":"-"},"content":" }"},{"lineNumber":768,"author":{"gitId":"-"},"content":""},{"lineNumber":769,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":770,"author":{"gitId":"-"},"content":" * Verifies that the executed action does not result in any background task"},{"lineNumber":771,"author":{"gitId":"-"},"content":" * being added."},{"lineNumber":772,"author":{"gitId":"-"},"content":" */"},{"lineNumber":773,"author":{"gitId":"-"},"content":" protected void verifyNoTasksAdded() {"},{"lineNumber":774,"author":{"gitId":"-"},"content":" Map\u003cString, Integer\u003e tasksAdded \u003d mockTaskQueuer.getNumberOfTasksAdded();"},{"lineNumber":775,"author":{"gitId":"-"},"content":" assertEquals(0, tasksAdded.keySet().size());"},{"lineNumber":776,"author":{"gitId":"-"},"content":" }"},{"lineNumber":777,"author":{"gitId":"-"},"content":""},{"lineNumber":778,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":779,"author":{"gitId":"-"},"content":" * Verifies that the executed action results in the specified background tasks"},{"lineNumber":780,"author":{"gitId":"-"},"content":" * being added."},{"lineNumber":781,"author":{"gitId":"-"},"content":" */"},{"lineNumber":782,"author":{"gitId":"-"},"content":" protected void verifySpecifiedTasksAdded(String taskName, int taskCount) {"},{"lineNumber":783,"author":{"gitId":"-"},"content":" Map\u003cString, Integer\u003e tasksAdded \u003d mockTaskQueuer.getNumberOfTasksAdded();"},{"lineNumber":784,"author":{"gitId":"-"},"content":" assertEquals(taskCount, tasksAdded.get(taskName).intValue());"},{"lineNumber":785,"author":{"gitId":"-"},"content":" }"},{"lineNumber":786,"author":{"gitId":"-"},"content":""},{"lineNumber":787,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":788,"author":{"gitId":"-"},"content":" * Verifies that the executed action does not result in any email being sent."},{"lineNumber":789,"author":{"gitId":"-"},"content":" */"},{"lineNumber":790,"author":{"gitId":"-"},"content":" protected void verifyNoEmailsSent() {"},{"lineNumber":791,"author":{"gitId":"-"},"content":" assertTrue(getEmailsSent().isEmpty());"},{"lineNumber":792,"author":{"gitId":"-"},"content":" }"},{"lineNumber":793,"author":{"gitId":"-"},"content":""},{"lineNumber":794,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":795,"author":{"gitId":"-"},"content":" * Returns the list of emails sent as part of the executed action."},{"lineNumber":796,"author":{"gitId":"-"},"content":" */"},{"lineNumber":797,"author":{"gitId":"-"},"content":" protected List\u003cEmailWrapper\u003e getEmailsSent() {"},{"lineNumber":798,"author":{"gitId":"-"},"content":" return mockEmailSender.getEmailsSent();"},{"lineNumber":799,"author":{"gitId":"-"},"content":" }"},{"lineNumber":800,"author":{"gitId":"-"},"content":""},{"lineNumber":801,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":802,"author":{"gitId":"-"},"content":" * Verifies that the executed action results in the specified number of emails"},{"lineNumber":803,"author":{"gitId":"-"},"content":" * being sent."},{"lineNumber":804,"author":{"gitId":"-"},"content":" */"},{"lineNumber":805,"author":{"gitId":"-"},"content":" protected void verifyNumberOfEmailsSent(int emailCount) {"},{"lineNumber":806,"author":{"gitId":"-"},"content":" assertEquals(emailCount, mockEmailSender.getEmailsSent().size());"},{"lineNumber":807,"author":{"gitId":"-"},"content":" }"},{"lineNumber":808,"author":{"gitId":"-"},"content":""},{"lineNumber":809,"author":{"gitId":"-"},"content":" private Course createTestCourseOther() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":810,"author":{"gitId":"-"},"content":" if (testCourseOther \u003d\u003d null) {"},{"lineNumber":811,"author":{"gitId":"-"},"content":" testCourseOther \u003d new Course(\"test-course-other-id\", \"test course other\", Const.DEFAULT_TIME_ZONE,"},{"lineNumber":812,"author":{"gitId":"-"},"content":" \"test-institute\");"},{"lineNumber":813,"author":{"gitId":"-"},"content":" logic.createCourse(testCourseOther);"},{"lineNumber":814,"author":{"gitId":"-"},"content":" }"},{"lineNumber":815,"author":{"gitId":"-"},"content":" return testCourseOther;"},{"lineNumber":816,"author":{"gitId":"-"},"content":" }"},{"lineNumber":817,"author":{"gitId":"-"},"content":""},{"lineNumber":818,"author":{"gitId":"-"},"content":" private Instructor createTypicalInstructor(Course course, String email)"},{"lineNumber":819,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":820,"author":{"gitId":"-"},"content":" Instructor instructor \u003d logic.getInstructorForEmail(course.getId(), email);"},{"lineNumber":821,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":822,"author":{"gitId":"-"},"content":" instructor \u003d new Instructor(course, \"instructor-name\", email, true, \"display-name\","},{"lineNumber":823,"author":{"gitId":"-"},"content":" InstructorPermissionRole.INSTRUCTOR_PERMISSION_ROLE_COOWNER, new InstructorPrivileges());"},{"lineNumber":824,"author":{"gitId":"-"},"content":" logic.createInstructor(instructor);"},{"lineNumber":825,"author":{"gitId":"-"},"content":""},{"lineNumber":826,"author":{"gitId":"-"},"content":" Account account \u003d new Account(email, \"account\", email);"},{"lineNumber":827,"author":{"gitId":"-"},"content":" logic.createAccount(account);"},{"lineNumber":828,"author":{"gitId":"-"},"content":" instructor.setAccount(account);"},{"lineNumber":829,"author":{"gitId":"-"},"content":" }"},{"lineNumber":830,"author":{"gitId":"-"},"content":" return instructor;"},{"lineNumber":831,"author":{"gitId":"-"},"content":" }"},{"lineNumber":832,"author":{"gitId":"-"},"content":""},{"lineNumber":833,"author":{"gitId":"-"},"content":" private Student createTypicalStudent(Course course, String email)"},{"lineNumber":834,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":835,"author":{"gitId":"-"},"content":" Student student \u003d logic.getStudentForEmail(course.getId(), email);"},{"lineNumber":836,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":837,"author":{"gitId":"-"},"content":" student \u003d new Student(course, \"student-name\", email, \"\");"},{"lineNumber":838,"author":{"gitId":"-"},"content":" logic.createStudent(student);"},{"lineNumber":839,"author":{"gitId":"-"},"content":""},{"lineNumber":840,"author":{"gitId":"-"},"content":" Account account \u003d new Account(email, \"account\", email);"},{"lineNumber":841,"author":{"gitId":"-"},"content":" logic.createAccount(account);"},{"lineNumber":842,"author":{"gitId":"-"},"content":" student.setAccount(account);"},{"lineNumber":843,"author":{"gitId":"-"},"content":" }"},{"lineNumber":844,"author":{"gitId":"-"},"content":" return student;"},{"lineNumber":845,"author":{"gitId":"-"},"content":" }"},{"lineNumber":846,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":105,"-":741}},{"path":"src/it/java/teammates/it/ui/webapi/CreateAccountRequestActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.AfterMethod;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailType;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.ui.output.AccountRequestData;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.ui.request.AccountCreateRequest;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.CreateAccountRequestAction;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":23,"author":{"gitId":"-"},"content":" * SUT: {@link CreateAccountRequestAction}."},{"lineNumber":24,"author":{"gitId":"-"},"content":" */"},{"lineNumber":25,"author":{"gitId":"-"},"content":"public class CreateAccountRequestActionIT extends BaseActionIT\u003cCreateAccountRequestAction\u003e {"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"-"},"content":" String getActionUri() {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" return Const.ResourceURIs.ACCOUNT_REQUEST;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":33,"author":{"gitId":"-"},"content":" String getRequestMethod() {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" return POST;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":38,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":39,"author":{"gitId":"-"},"content":" protected void setUp() {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" // CreateAccountRequestAction handles its own transactions;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" // There is thus no need to setup a transaction."},{"lineNumber":42,"author":{"gitId":"-"},"content":" }"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":45,"author":{"gitId":"-"},"content":" protected void testExecute() throws Exception {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" // This is separated into different test methods."},{"lineNumber":47,"author":{"gitId":"-"},"content":" }"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":50,"author":{"gitId":"-"},"content":" void testExecute_nullEmail_throwsInvalidHttpRequestBodyException() {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":52,"author":{"gitId":"-"},"content":" request.setInstructorName(\"Paul Atreides\");"},{"lineNumber":53,"author":{"gitId":"-"},"content":" request.setInstructorInstitution(\"House Atreides\");"},{"lineNumber":54,"author":{"gitId":"-"},"content":" InvalidHttpRequestBodyException ihrbException \u003d verifyHttpRequestBodyFailure(request);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" assertEquals(\"email cannot be null\", ihrbException.getMessage());"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":59,"author":{"gitId":"-"},"content":" void testExecute_nullName_throwsInvalidHttpRequestBodyException() {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":61,"author":{"gitId":"-"},"content":" request.setInstructorEmail(\"kwisatz.haderach@atreides.org\");"},{"lineNumber":62,"author":{"gitId":"-"},"content":" request.setInstructorInstitution(\"House Atreides\");"},{"lineNumber":63,"author":{"gitId":"-"},"content":" InvalidHttpRequestBodyException ihrbException \u003d verifyHttpRequestBodyFailure(request);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" assertEquals(\"name cannot be null\", ihrbException.getMessage());"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":68,"author":{"gitId":"-"},"content":" void testExecute_nullInstitute_throwsInvalidHttpRequestBodyException() {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":70,"author":{"gitId":"-"},"content":" request.setInstructorEmail(\"kwisatz.haderach@atreides.org\");"},{"lineNumber":71,"author":{"gitId":"-"},"content":" request.setInstructorName(\"Paul Atreides\");"},{"lineNumber":72,"author":{"gitId":"-"},"content":" InvalidHttpRequestBodyException ihrbException \u003d verifyHttpRequestBodyFailure(request);"},{"lineNumber":73,"author":{"gitId":"-"},"content":" assertEquals(\"institute cannot be null\", ihrbException.getMessage());"},{"lineNumber":74,"author":{"gitId":"-"},"content":" }"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":77,"author":{"gitId":"-"},"content":" void testExecute_invalidEmail_throwsInvalidHttpRequestBodyException() {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":79,"author":{"gitId":"-"},"content":" request.setInstructorEmail(\"invalid email address\");"},{"lineNumber":80,"author":{"gitId":"-"},"content":" request.setInstructorName(\"Paul Atreides\");"},{"lineNumber":81,"author":{"gitId":"-"},"content":" request.setInstructorInstitution(\"House Atreides\");"},{"lineNumber":82,"author":{"gitId":"-"},"content":" InvalidHttpRequestBodyException ihrbException \u003d verifyHttpRequestBodyFailure(request);"},{"lineNumber":83,"author":{"gitId":"-"},"content":" String expectedMessage \u003d \"\\\"invalid email address\\\" is not acceptable to TEAMMATES as a/an email because it is not \""},{"lineNumber":84,"author":{"gitId":"-"},"content":" + \"in the correct format. An email address contains some text followed by one \u0027@\u0027 sign followed by some \""},{"lineNumber":85,"author":{"gitId":"-"},"content":" + \"more text, and should end with a top level domain address like .com. It cannot be longer than 254 \""},{"lineNumber":86,"author":{"gitId":"-"},"content":" + \"characters, cannot be empty and cannot contain spaces.\";"},{"lineNumber":87,"author":{"gitId":"-"},"content":" assertEquals(expectedMessage, ihrbException.getMessage());"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":91,"author":{"gitId":"-"},"content":" void testExecute_invalidName_throwsInvalidHttpRequestBodyException() {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":93,"author":{"gitId":"-"},"content":" request.setInstructorEmail(\"kwisatz.haderach@atreides.org\");"},{"lineNumber":94,"author":{"gitId":"-"},"content":" request.setInstructorName(\"Pau| Atreides\");"},{"lineNumber":95,"author":{"gitId":"-"},"content":" request.setInstructorInstitution(\"House Atreides\");"},{"lineNumber":96,"author":{"gitId":"-"},"content":" InvalidHttpRequestBodyException ihrbException \u003d verifyHttpRequestBodyFailure(request);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" String expectedMessage \u003d \"\\\"Pau| Atreides\\\" is not acceptable to TEAMMATES as a/an person name because it contains \""},{"lineNumber":98,"author":{"gitId":"-"},"content":" + \"invalid characters. A/An person name must start with an alphanumeric character, and cannot contain any \""},{"lineNumber":99,"author":{"gitId":"-"},"content":" + \"vertical bar (|) or percent sign (%).\";"},{"lineNumber":100,"author":{"gitId":"-"},"content":" assertEquals(expectedMessage, ihrbException.getMessage());"},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":104,"author":{"gitId":"-"},"content":" void testExecute_invalidInstitute_throwsInvalidHttpRequestBodyException() {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":106,"author":{"gitId":"-"},"content":" request.setInstructorEmail(\"kwisatz.haderach@atreides.org\");"},{"lineNumber":107,"author":{"gitId":"-"},"content":" request.setInstructorName(\"Paul Atreides\");"},{"lineNumber":108,"author":{"gitId":"-"},"content":" request.setInstructorInstitution(\"House Atreide%\");"},{"lineNumber":109,"author":{"gitId":"-"},"content":" InvalidHttpRequestBodyException ihrbException \u003d verifyHttpRequestBodyFailure(request);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" String expectedMessage \u003d \"\\\"House Atreide%\\\" is not acceptable to TEAMMATES as a/an institute name because it \""},{"lineNumber":111,"author":{"gitId":"-"},"content":" + \"contains invalid characters. A/An institute name must start with an alphanumeric character, and cannot \""},{"lineNumber":112,"author":{"gitId":"-"},"content":" + \"contain any vertical bar (|) or percent sign (%).\";"},{"lineNumber":113,"author":{"gitId":"-"},"content":" assertEquals(expectedMessage, ihrbException.getMessage());"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":117,"author":{"gitId":"-"},"content":" void testExecute_typicalCase_createsSuccessfully() {"},{"lineNumber":118,"author":{"gitId":"-"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":119,"author":{"gitId":"-"},"content":" request.setInstructorEmail(\"kwisatz.haderach@atreides.org\");"},{"lineNumber":120,"author":{"gitId":"-"},"content":" request.setInstructorName(\"Paul Atreides\");"},{"lineNumber":121,"author":{"gitId":"-"},"content":" request.setInstructorInstitution(\"House Atreides\");"},{"lineNumber":122,"author":{"gitId":"-"},"content":" request.setInstructorComments(\"My road leads into the desert. I can see it.\");"},{"lineNumber":123,"author":{"gitId":"-"},"content":" CreateAccountRequestAction action \u003d getAction(request);"},{"lineNumber":124,"author":{"gitId":"-"},"content":" JsonResult result \u003d getJsonResult(action);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" AccountRequestData output \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":126,"author":{"gitId":"-"},"content":" assertEquals(\"kwisatz.haderach@atreides.org\", output.getEmail());"},{"lineNumber":127,"author":{"gitId":"-"},"content":" assertEquals(\"Paul Atreides\", output.getName());"},{"lineNumber":128,"author":{"gitId":"-"},"content":" assertEquals(\"House Atreides\", output.getInstitute());"},{"lineNumber":129,"author":{"gitId":"-"},"content":" assertEquals(AccountRequestStatus.PENDING, output.getStatus());"},{"lineNumber":130,"author":{"gitId":"-"},"content":" assertEquals(\"My road leads into the desert. I can see it.\", output.getComments());"},{"lineNumber":131,"author":{"gitId":"-"},"content":" assertNull(output.getRegisteredAt());"},{"lineNumber":132,"author":{"gitId":"-"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":133,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d logic.getAccountRequestByRegistrationKey(output.getRegistrationKey());"},{"lineNumber":134,"author":{"gitId":"-"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":135,"author":{"gitId":"-"},"content":" assertEquals(\"kwisatz.haderach@atreides.org\", accountRequest.getEmail());"},{"lineNumber":136,"author":{"gitId":"-"},"content":" assertEquals(\"Paul Atreides\", accountRequest.getName());"},{"lineNumber":137,"author":{"gitId":"-"},"content":" assertEquals(\"House Atreides\", accountRequest.getInstitute());"},{"lineNumber":138,"author":{"gitId":"-"},"content":" assertEquals(AccountRequestStatus.PENDING, accountRequest.getStatus());"},{"lineNumber":139,"author":{"gitId":"-"},"content":" assertEquals(\"My road leads into the desert. I can see it.\", accountRequest.getComments());"},{"lineNumber":140,"author":{"gitId":"-"},"content":" assertNull(accountRequest.getRegisteredAt());"},{"lineNumber":141,"author":{"gitId":"-"},"content":" verifySpecifiedTasksAdded(Const.TaskQueue.SEARCH_INDEXING_QUEUE_NAME, 1);"},{"lineNumber":142,"author":{"gitId":"xenosf"},"content":" verifyNumberOfEmailsSent(2);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" EmailWrapper sentAdminAlertEmail \u003d mockEmailSender.getEmailsSent().get(0);"},{"lineNumber":144,"author":{"gitId":"xenosf"},"content":" EmailWrapper sentAcknowledgementEmail \u003d mockEmailSender.getEmailsSent().get(1);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" assertEquals(EmailType.NEW_ACCOUNT_REQUEST_ADMIN_ALERT, sentAdminAlertEmail.getType());"},{"lineNumber":146,"author":{"gitId":"xenosf"},"content":" assertEquals(EmailType.NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT, sentAcknowledgementEmail.getType());"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":150,"author":{"gitId":"-"},"content":" void testExecute_leadingAndTrailingSpacesAndNullComments_createsSuccessfully() {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":152,"author":{"gitId":"-"},"content":" request.setInstructorEmail(\" kwisatz.haderach@atreides.org \");"},{"lineNumber":153,"author":{"gitId":"-"},"content":" request.setInstructorName(\" Paul Atreides \");"},{"lineNumber":154,"author":{"gitId":"-"},"content":" request.setInstructorInstitution(\" House Atreides \");"},{"lineNumber":155,"author":{"gitId":"-"},"content":" CreateAccountRequestAction action \u003d getAction(request);"},{"lineNumber":156,"author":{"gitId":"-"},"content":" JsonResult result \u003d getJsonResult(action);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" AccountRequestData output \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":158,"author":{"gitId":"-"},"content":" assertEquals(\"kwisatz.haderach@atreides.org\", output.getEmail());"},{"lineNumber":159,"author":{"gitId":"-"},"content":" assertEquals(\"Paul Atreides\", output.getName());"},{"lineNumber":160,"author":{"gitId":"-"},"content":" assertEquals(\"House Atreides\", output.getInstitute());"},{"lineNumber":161,"author":{"gitId":"-"},"content":" assertEquals(AccountRequestStatus.PENDING, output.getStatus());"},{"lineNumber":162,"author":{"gitId":"-"},"content":" assertNull(output.getComments());"},{"lineNumber":163,"author":{"gitId":"-"},"content":" assertNull(output.getRegisteredAt());"},{"lineNumber":164,"author":{"gitId":"-"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":165,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d logic.getAccountRequestByRegistrationKey(output.getRegistrationKey());"},{"lineNumber":166,"author":{"gitId":"-"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":167,"author":{"gitId":"-"},"content":" assertEquals(\"kwisatz.haderach@atreides.org\", accountRequest.getEmail());"},{"lineNumber":168,"author":{"gitId":"-"},"content":" assertEquals(\"Paul Atreides\", accountRequest.getName());"},{"lineNumber":169,"author":{"gitId":"-"},"content":" assertEquals(\"House Atreides\", accountRequest.getInstitute());"},{"lineNumber":170,"author":{"gitId":"-"},"content":" assertEquals(AccountRequestStatus.PENDING, accountRequest.getStatus());"},{"lineNumber":171,"author":{"gitId":"-"},"content":" assertNull(accountRequest.getComments());"},{"lineNumber":172,"author":{"gitId":"-"},"content":" assertNull(accountRequest.getRegisteredAt());"},{"lineNumber":173,"author":{"gitId":"-"},"content":" verifySpecifiedTasksAdded(Const.TaskQueue.SEARCH_INDEXING_QUEUE_NAME, 1);"},{"lineNumber":174,"author":{"gitId":"xenosf"},"content":" verifyNumberOfEmailsSent(2);"},{"lineNumber":175,"author":{"gitId":"-"},"content":" EmailWrapper sentAdminAlertEmail \u003d mockEmailSender.getEmailsSent().get(0);"},{"lineNumber":176,"author":{"gitId":"xenosf"},"content":" EmailWrapper sentAcknowledgementEmail \u003d mockEmailSender.getEmailsSent().get(1);"},{"lineNumber":177,"author":{"gitId":"-"},"content":" assertEquals(EmailType.NEW_ACCOUNT_REQUEST_ADMIN_ALERT, sentAdminAlertEmail.getType());"},{"lineNumber":178,"author":{"gitId":"xenosf"},"content":" assertEquals(EmailType.NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT, sentAcknowledgementEmail.getType());"},{"lineNumber":179,"author":{"gitId":"-"},"content":" }"},{"lineNumber":180,"author":{"gitId":"-"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":182,"author":{"gitId":"-"},"content":" void testExecute_accountRequestWithSameEmailAddressAndInstituteAlreadyExists_createsSuccessfully()"},{"lineNumber":183,"author":{"gitId":"-"},"content":" throws InvalidParametersException {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":185,"author":{"gitId":"-"},"content":" AccountRequest existingAccountRequest \u003d logic.createAccountRequest(\"Paul Atreides\","},{"lineNumber":186,"author":{"gitId":"-"},"content":" \"kwisatz.haderach@atreides.org\","},{"lineNumber":187,"author":{"gitId":"-"},"content":" \"House Atreides\", AccountRequestStatus.PENDING, \"My road leads into the desert. I can see it.\");"},{"lineNumber":188,"author":{"gitId":"-"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":189,"author":{"gitId":"-"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":190,"author":{"gitId":"-"},"content":" request.setInstructorEmail(\"kwisatz.haderach@atreides.org\");"},{"lineNumber":191,"author":{"gitId":"-"},"content":" request.setInstructorName(\"Paul Atreides\");"},{"lineNumber":192,"author":{"gitId":"-"},"content":" request.setInstructorInstitution(\"House Atreides\");"},{"lineNumber":193,"author":{"gitId":"-"},"content":" request.setInstructorComments(\"My road leads into the desert. I can see it.\");"},{"lineNumber":194,"author":{"gitId":"-"},"content":" CreateAccountRequestAction action \u003d getAction(request);"},{"lineNumber":195,"author":{"gitId":"-"},"content":" JsonResult result \u003d getJsonResult(action);"},{"lineNumber":196,"author":{"gitId":"-"},"content":" AccountRequestData output \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":197,"author":{"gitId":"-"},"content":" assertEquals(\"kwisatz.haderach@atreides.org\", output.getEmail());"},{"lineNumber":198,"author":{"gitId":"-"},"content":" assertEquals(\"Paul Atreides\", output.getName());"},{"lineNumber":199,"author":{"gitId":"-"},"content":" assertEquals(\"House Atreides\", output.getInstitute());"},{"lineNumber":200,"author":{"gitId":"-"},"content":" assertEquals(AccountRequestStatus.PENDING, output.getStatus());"},{"lineNumber":201,"author":{"gitId":"-"},"content":" assertEquals(\"My road leads into the desert. I can see it.\", output.getComments());"},{"lineNumber":202,"author":{"gitId":"-"},"content":" assertNull(output.getRegisteredAt());"},{"lineNumber":203,"author":{"gitId":"-"},"content":" assertNotEquals(output.getRegistrationKey(), existingAccountRequest.getRegistrationKey());"},{"lineNumber":204,"author":{"gitId":"-"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":205,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d logic.getAccountRequestByRegistrationKey(output.getRegistrationKey());"},{"lineNumber":206,"author":{"gitId":"-"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":207,"author":{"gitId":"-"},"content":" assertEquals(\"kwisatz.haderach@atreides.org\", accountRequest.getEmail());"},{"lineNumber":208,"author":{"gitId":"-"},"content":" assertEquals(\"Paul Atreides\", accountRequest.getName());"},{"lineNumber":209,"author":{"gitId":"-"},"content":" assertEquals(\"House Atreides\", accountRequest.getInstitute());"},{"lineNumber":210,"author":{"gitId":"-"},"content":" assertEquals(AccountRequestStatus.PENDING, accountRequest.getStatus());"},{"lineNumber":211,"author":{"gitId":"-"},"content":" assertEquals(\"My road leads into the desert. I can see it.\", accountRequest.getComments());"},{"lineNumber":212,"author":{"gitId":"-"},"content":" assertNull(accountRequest.getRegisteredAt());"},{"lineNumber":213,"author":{"gitId":"-"},"content":" verifySpecifiedTasksAdded(Const.TaskQueue.SEARCH_INDEXING_QUEUE_NAME, 1);"},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" verifyNumberOfEmailsSent(2);"},{"lineNumber":215,"author":{"gitId":"-"},"content":" EmailWrapper sentAdminAlertEmail \u003d mockEmailSender.getEmailsSent().get(0);"},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" EmailWrapper sentAcknowledgementEmail \u003d mockEmailSender.getEmailsSent().get(1);"},{"lineNumber":217,"author":{"gitId":"-"},"content":" assertEquals(EmailType.NEW_ACCOUNT_REQUEST_ADMIN_ALERT, sentAdminAlertEmail.getType());"},{"lineNumber":218,"author":{"gitId":"xenosf"},"content":" assertEquals(EmailType.NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT, sentAcknowledgementEmail.getType());"},{"lineNumber":219,"author":{"gitId":"-"},"content":" }"},{"lineNumber":220,"author":{"gitId":"-"},"content":""},{"lineNumber":221,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":222,"author":{"gitId":"xenosf"},"content":" void testExecute_typicalCaseAsAdmin_noEmailsSent() {"},{"lineNumber":223,"author":{"gitId":"xenosf"},"content":" loginAsAdminWithTransaction();"},{"lineNumber":224,"author":{"gitId":"xenosf"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":225,"author":{"gitId":"xenosf"},"content":" request.setInstructorEmail(\"kwisatz.haderach@atreides.org\");"},{"lineNumber":226,"author":{"gitId":"xenosf"},"content":" request.setInstructorName(\"Paul Atreides\");"},{"lineNumber":227,"author":{"gitId":"xenosf"},"content":" request.setInstructorInstitution(\"House Atreides\");"},{"lineNumber":228,"author":{"gitId":"xenosf"},"content":" request.setInstructorComments(\"My road leads into the desert. I can see it.\");"},{"lineNumber":229,"author":{"gitId":"xenosf"},"content":" CreateAccountRequestAction action \u003d getAction(request);"},{"lineNumber":230,"author":{"gitId":"xenosf"},"content":" JsonResult result \u003d getJsonResult(action);"},{"lineNumber":231,"author":{"gitId":"xenosf"},"content":" AccountRequestData output \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":232,"author":{"gitId":"xenosf"},"content":" assertNull(output.getRegisteredAt());"},{"lineNumber":233,"author":{"gitId":"xenosf"},"content":" verifyNoEmailsSent();"},{"lineNumber":234,"author":{"gitId":"xenosf"},"content":" logoutUser();"},{"lineNumber":235,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":236,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":237,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":238,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":239,"author":{"gitId":"-"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":240,"author":{"gitId":"-"},"content":" verifyAccessibleWithoutLogin();"},{"lineNumber":241,"author":{"gitId":"-"},"content":" }"},{"lineNumber":242,"author":{"gitId":"-"},"content":""},{"lineNumber":243,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":244,"author":{"gitId":"domoberzin"},"content":" @AfterMethod"},{"lineNumber":245,"author":{"gitId":"domoberzin"},"content":" protected void tearDown() {"},{"lineNumber":246,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":247,"author":{"gitId":"domoberzin"},"content":" List\u003cAccountRequest\u003e accountRequests \u003d logic.getPendingAccountRequests();"},{"lineNumber":248,"author":{"gitId":"domoberzin"},"content":" for (AccountRequest ar : accountRequests) {"},{"lineNumber":249,"author":{"gitId":"dishenggg"},"content":" logic.deleteAccountRequest(ar.getId());"},{"lineNumber":250,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":251,"author":{"gitId":"domoberzin"},"content":" accountRequests \u003d logic.getPendingAccountRequests();"},{"lineNumber":252,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":253,"author":{"gitId":"domoberzin"},"content":" assert accountRequests.isEmpty();"},{"lineNumber":254,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":255,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":14,"xenosf":25,"dishenggg":1,"-":215}},{"path":"src/it/java/teammates/it/ui/webapi/CreateFeedbackSessionLogActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.output.MessageOutput;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.webapi.CreateFeedbackSessionLogAction;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link CreateFeedbackSessionLogAction}."},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"public class CreateFeedbackSessionLogActionIT extends BaseActionIT\u003cCreateFeedbackSessionLogAction\u003e {"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" protected String getActionUri() {"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" return Const.ResourceURIs.SESSION_LOGS;"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" protected String getRequestMethod() {"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" return POST;"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" protected void testExecute() throws Exception {"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" Course course1 \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" String courseId1 \u003d course1.getId();"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" FeedbackSession fs1 \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" FeedbackSession fs2 \u003d typicalBundle.feedbackSessions.get(\"session2InTypicalCourse\");"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" Student student2 \u003d typicalBundle.students.get(\"student2InCourse1\");"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" Student student3 \u003d typicalBundle.students.get(\"student1InCourse3\");"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: not enough parameters\");"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure(Const.ParamsNames.COURSE_ID, courseId1);"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure("},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fs1.getName()"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" );"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure("},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fs1.getName(),"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail()"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" );"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure("},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fs1.getName(),"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail()"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" );"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure("},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fs2.getId().toString(),"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student2.getId().toString()"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" );"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: invalid log type\");"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" String[] paramsInvalid \u003d {"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fs1.getName(),"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, \"invalid log type\","},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fs1.getId().toString(),"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student1.getId().toString(),"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure(paramsInvalid);"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: typical access\");"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" String[] paramsSuccessfulAccess \u003d {"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fs1.getName(),"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fs1.getId().toString(),"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student1.getId().toString(),"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":" JsonResult response \u003d getJsonResult(getAction(paramsSuccessfulAccess));"},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" MessageOutput output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: typical submission\");"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":" String[] paramsSuccessfulSubmission \u003d {"},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fs2.getName(),"},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_EMAIL, student2.getEmail(),"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fs2.getId().toString(),"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student2.getId().toString(),"},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" response \u003d getJsonResult(getAction(paramsSuccessfulSubmission));"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":" output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: should create even for invalid parameters\");"},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" String[] paramsNonExistentCourseId \u003d {"},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, \"non-existent-course-id\","},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fs1.getName(),"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fs1.getId().toString(),"},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student1.getId().toString(),"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":" response \u003d getJsonResult(getAction(paramsNonExistentCourseId));"},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: should create even for invalid parameters\");"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" String[] paramsNonExistentFsName \u003d {"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, \"non-existent-feedback-session-name\","},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, UUID.randomUUID().toString(),"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student1.getId().toString(),"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" response \u003d getJsonResult(getAction(paramsNonExistentFsName));"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":" String[] paramsNonExistentStudentEmail \u003d {"},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fs1.getName(),"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_EMAIL, \"non-existent-student@email.com\","},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fs1.getId().toString(),"},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, UUID.randomUUID().toString(),"},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":" response \u003d getJsonResult(getAction(paramsNonExistentStudentEmail));"},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":" output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":141,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: should create even when student cannot access feedback session in course\");"},{"lineNumber":142,"author":{"gitId":"dishenggg"},"content":" String[] paramsWithoutAccess \u003d {"},{"lineNumber":143,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":144,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fs1.getName(),"},{"lineNumber":145,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":146,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_EMAIL, student3.getEmail(),"},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fs1.getId().toString(),"},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student3.getId().toString(),"},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":" response \u003d getJsonResult(getAction(paramsWithoutAccess));"},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":" output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":153,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":158,"author":{"gitId":"dishenggg"},"content":" verifyAnyUserCanAccess();"},{"lineNumber":159,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":160}},{"path":"src/it/java/teammates/it/ui/webapi/CreateInstructorActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"mingyuanc"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":3,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":4,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.Test;"},{"lineNumber":5,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":6,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.util.Const;"},{"lineNumber":7,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":8,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":9,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":10,"author":{"gitId":"mingyuanc"},"content":"import teammates.ui.output.InstructorData;"},{"lineNumber":11,"author":{"gitId":"mingyuanc"},"content":"import teammates.ui.request.InstructorCreateRequest;"},{"lineNumber":12,"author":{"gitId":"mingyuanc"},"content":"import teammates.ui.webapi.CreateInstructorAction;"},{"lineNumber":13,"author":{"gitId":"mingyuanc"},"content":"import teammates.ui.webapi.InvalidOperationException;"},{"lineNumber":14,"author":{"gitId":"mingyuanc"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":15,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":16,"author":{"gitId":"mingyuanc"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"mingyuanc"},"content":" * SUT: {@link CreateInstructorAction}."},{"lineNumber":18,"author":{"gitId":"mingyuanc"},"content":" */"},{"lineNumber":19,"author":{"gitId":"mingyuanc"},"content":"public class CreateInstructorActionIT extends BaseActionIT\u003cCreateInstructorAction\u003e {"},{"lineNumber":20,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":21,"author":{"gitId":"mingyuanc"},"content":" @BeforeMethod"},{"lineNumber":22,"author":{"gitId":"mingyuanc"},"content":" protected void setUp() throws Exception {"},{"lineNumber":23,"author":{"gitId":"mingyuanc"},"content":" super.setUp();"},{"lineNumber":24,"author":{"gitId":"mingyuanc"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":25,"author":{"gitId":"mingyuanc"},"content":" HibernateUtil.flushSession();"},{"lineNumber":26,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":27,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":28,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":29,"author":{"gitId":"mingyuanc"},"content":" protected String getActionUri() {"},{"lineNumber":30,"author":{"gitId":"mingyuanc"},"content":" return Const.ResourceURIs.INSTRUCTOR;"},{"lineNumber":31,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":32,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":33,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":34,"author":{"gitId":"mingyuanc"},"content":" protected String getRequestMethod() {"},{"lineNumber":35,"author":{"gitId":"mingyuanc"},"content":" return POST;"},{"lineNumber":36,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":37,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":38,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":39,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":40,"author":{"gitId":"mingyuanc"},"content":" protected void testExecute() {"},{"lineNumber":41,"author":{"gitId":"mingyuanc"},"content":" // see test cases below"},{"lineNumber":42,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":43,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":44,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":45,"author":{"gitId":"mingyuanc"},"content":" protected void testExecute_typicalCase_shouldPass() throws Exception {"},{"lineNumber":46,"author":{"gitId":"mingyuanc"},"content":" loginAsAdmin();"},{"lineNumber":47,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":48,"author":{"gitId":"mingyuanc"},"content":" Course course1 \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":49,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":50,"author":{"gitId":"mingyuanc"},"content":" String[] params \u003d {"},{"lineNumber":51,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.COURSE_ID, course1.getId(),"},{"lineNumber":52,"author":{"gitId":"mingyuanc"},"content":" };"},{"lineNumber":53,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":54,"author":{"gitId":"mingyuanc"},"content":" InstructorCreateRequest instructorCreateRequest \u003d new InstructorCreateRequest("},{"lineNumber":55,"author":{"gitId":"mingyuanc"},"content":" \"00000000-0000-4000-8000-000000000006\", \"newInstructorName\","},{"lineNumber":56,"author":{"gitId":"mingyuanc"},"content":" \"newInstructorEmail@mail.com\", Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_COOWNER,"},{"lineNumber":57,"author":{"gitId":"mingyuanc"},"content":" \"instructorDisplayName\", false);"},{"lineNumber":58,"author":{"gitId":"mingyuanc"},"content":" CreateInstructorAction action \u003d getAction(instructorCreateRequest, params);"},{"lineNumber":59,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":60,"author":{"gitId":"mingyuanc"},"content":" JsonResult response \u003d getJsonResult(action);"},{"lineNumber":61,"author":{"gitId":"mingyuanc"},"content":" InstructorData instructorData \u003d (InstructorData) response.getOutput();"},{"lineNumber":62,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":63,"author":{"gitId":"mingyuanc"},"content":" Instructor createdInstructor \u003d logic.getInstructorForEmail(course1.getId(), instructorCreateRequest.getEmail());"},{"lineNumber":64,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":65,"author":{"gitId":"mingyuanc"},"content":" assertEquals(createdInstructor.getName(), instructorCreateRequest.getName());"},{"lineNumber":66,"author":{"gitId":"mingyuanc"},"content":" assertEquals(createdInstructor.getEmail(), instructorCreateRequest.getEmail());"},{"lineNumber":67,"author":{"gitId":"mingyuanc"},"content":" assertEquals(createdInstructor.getName(), instructorData.getName());"},{"lineNumber":68,"author":{"gitId":"mingyuanc"},"content":" assertEquals(createdInstructor.getEmail(), instructorData.getEmail());"},{"lineNumber":69,"author":{"gitId":"mingyuanc"},"content":" assertFalse(createdInstructor.isDisplayedToStudents());"},{"lineNumber":70,"author":{"gitId":"mingyuanc"},"content":" assertTrue(createdInstructor.isAllowedForPrivilege(Const.InstructorPermissions.CAN_MODIFY_COURSE));"},{"lineNumber":71,"author":{"gitId":"mingyuanc"},"content":" assertTrue(createdInstructor.isAllowedForPrivilege(Const.InstructorPermissions.CAN_MODIFY_INSTRUCTOR));"},{"lineNumber":72,"author":{"gitId":"mingyuanc"},"content":" assertTrue(createdInstructor.isAllowedForPrivilege(Const.InstructorPermissions.CAN_MODIFY_SESSION));"},{"lineNumber":73,"author":{"gitId":"mingyuanc"},"content":" assertTrue(createdInstructor.isAllowedForPrivilege(Const.InstructorPermissions.CAN_MODIFY_STUDENT));"},{"lineNumber":74,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":75,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":76,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":77,"author":{"gitId":"mingyuanc"},"content":" protected void testExecute_uniqueEmailClash_shouldFail() throws Exception {"},{"lineNumber":78,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":79,"author":{"gitId":"mingyuanc"},"content":" Instructor instructor1OfCourse1 \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":80,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":81,"author":{"gitId":"mingyuanc"},"content":" loginAsAdmin();"},{"lineNumber":82,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":83,"author":{"gitId":"mingyuanc"},"content":" String[] params \u003d {"},{"lineNumber":84,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.COURSE_ID, instructor1OfCourse1.getCourseId(),"},{"lineNumber":85,"author":{"gitId":"mingyuanc"},"content":" };"},{"lineNumber":86,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":87,"author":{"gitId":"mingyuanc"},"content":" InstructorCreateRequest instructorCreateRequest \u003d new InstructorCreateRequest("},{"lineNumber":88,"author":{"gitId":"mingyuanc"},"content":" instructor1OfCourse1.getCourseId(), \"instructor3ofCourse1\","},{"lineNumber":89,"author":{"gitId":"mingyuanc"},"content":" instructor1OfCourse1.getEmail(), Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_TUTOR,"},{"lineNumber":90,"author":{"gitId":"mingyuanc"},"content":" \"instructor3ofCourse1\", false);"},{"lineNumber":91,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":92,"author":{"gitId":"mingyuanc"},"content":" CreateInstructorAction action \u003d getAction(instructorCreateRequest, params);"},{"lineNumber":93,"author":{"gitId":"mingyuanc"},"content":" assertThrows(InvalidOperationException.class, action::execute);"},{"lineNumber":94,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":95,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":96,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":97,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":98,"author":{"gitId":"mingyuanc"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":99,"author":{"gitId":"mingyuanc"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":100,"author":{"gitId":"mingyuanc"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor2OfCourse1\");"},{"lineNumber":101,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":102,"author":{"gitId":"mingyuanc"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":103,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.COURSE_ID, instructor.getCourseId(),"},{"lineNumber":104,"author":{"gitId":"mingyuanc"},"content":" };"},{"lineNumber":105,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":106,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"Admins can access\");"},{"lineNumber":107,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":108,"author":{"gitId":"mingyuanc"},"content":" verifyAccessibleForAdmin(submissionParams);"},{"lineNumber":109,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":110,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"only instructors of the same course can access\");"},{"lineNumber":111,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":112,"author":{"gitId":"mingyuanc"},"content":" verifyOnlyInstructorsOfTheSameCourseWithCorrectCoursePrivilegeCanAccess(course,"},{"lineNumber":113,"author":{"gitId":"mingyuanc"},"content":" Const.InstructorPermissions.CAN_MODIFY_INSTRUCTOR, submissionParams);"},{"lineNumber":114,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"instructors of other courses cannot access\");"},{"lineNumber":115,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":116,"author":{"gitId":"mingyuanc"},"content":" verifyInaccessibleForInstructorsOfOtherCourses(course, submissionParams);"},{"lineNumber":117,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":118,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":119,"author":{"gitId":"mingyuanc"},"content":"}"}],"authorContributionMap":{"mingyuanc":119}},{"path":"src/it/java/teammates/it/ui/webapi/DeleteStudentsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.DeleteStudentsAction;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * SUT: {@link DeleteStudentsAction}."},{"lineNumber":17,"author":{"gitId":"-"},"content":" */"},{"lineNumber":18,"author":{"gitId":"-"},"content":"public class DeleteStudentsActionIT extends BaseActionIT\u003cDeleteStudentsAction\u003e {"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":21,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":22,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":23,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":24,"author":{"gitId":"-"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":25,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":26,"author":{"gitId":"-"},"content":" }"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":29,"author":{"gitId":"-"},"content":" String getActionUri() {"},{"lineNumber":30,"author":{"gitId":"-"},"content":" return Const.ResourceURIs.STUDENTS;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" }"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":34,"author":{"gitId":"-"},"content":" String getRequestMethod() {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" return DELETE;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" }"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":39,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":40,"author":{"gitId":"-"},"content":" protected void testExecute() throws Exception {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":42,"author":{"gitId":"-"},"content":" String courseId \u003d instructor.getCourseId();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" // TODO Remove limit after migration completes"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" int deleteLimit \u003d 4;"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case delete a limited number of students\");"},{"lineNumber":47,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e studentsToDelete \u003d logic.getStudentsForCourse(courseId);"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"marquestye"},"content":" assertEquals(5, studentsToDelete.size());"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" String[] params \u003d new String[] {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" Const.ParamsNames.LIMIT, String.valueOf(deleteLimit),"},{"lineNumber":56,"author":{"gitId":"-"},"content":" };"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" DeleteStudentsAction deleteStudentsAction \u003d getAction(params);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" getJsonResult(deleteStudentsAction);"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" for (Student student : studentsToDelete) {"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" assertNull(logic.getStudentByRegistrationKey(student.getRegKey()));"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" ______TS(\"Random course given, fails silently\");"},{"lineNumber":66,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, \"non-existent-course-id\","},{"lineNumber":68,"author":{"gitId":"-"},"content":" Const.ParamsNames.LIMIT, String.valueOf(deleteLimit),"},{"lineNumber":69,"author":{"gitId":"-"},"content":" };"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" deleteStudentsAction \u003d getAction(params);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" getJsonResult(deleteStudentsAction);"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" ______TS(\"Invalid params\");"},{"lineNumber":75,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure();"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":79,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":80,"author":{"gitId":"-"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":81,"author":{"gitId":"-"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" String[] params \u003d new String[] {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":85,"author":{"gitId":"-"},"content":" };"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" verifyOnlyInstructorsOfTheSameCourseWithCorrectCoursePrivilegeCanAccess("},{"lineNumber":88,"author":{"gitId":"-"},"content":" course, Const.InstructorPermissions.CAN_MODIFY_STUDENT, params);"},{"lineNumber":89,"author":{"gitId":"-"},"content":" }"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":1,"dishenggg":2,"-":88}},{"path":"src/it/java/teammates/it/ui/webapi/EnrollStudentsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import java.util.Arrays;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.Test;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.Const;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.output.EnrollStudentsData;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.request.StudentsEnrollRequest;"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.EnrollStudentsAction;"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.InvalidOperationException;"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" * SUT: {@link EnrollStudentsAction}."},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":"public class EnrollStudentsActionIT extends BaseActionIT\u003cEnrollStudentsAction\u003e {"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" @BeforeMethod"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" protected void setUp() throws Exception {"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" super.setUp();"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.flushSession();"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" protected String getActionUri() {"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" return Const.ResourceURIs.STUDENTS;"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" protected String getRequestMethod() {"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" return PUT;"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" private StudentsEnrollRequest prepareRequest(List\u003cStudent\u003e students) {"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" List\u003cStudentsEnrollRequest.StudentEnrollRequest\u003e studentEnrollRequests \u003d new ArrayList\u003c\u003e();"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" students.forEach(student -\u003e {"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" studentEnrollRequests.add(new StudentsEnrollRequest.StudentEnrollRequest(student.getName(),"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" student.getEmail(), student.getTeam().getName(), student.getSection().getName(), student.getComments()));"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" return new StudentsEnrollRequest(studentEnrollRequests);"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" public void testExecute() throws Exception {"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d typicalBundle.students.get(\"student1InCourse1\").getCourseId();"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" Course course \u003d logic.getCourse(courseId);"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" Section section \u003d logic.getSection(courseId, \"Section 1\");"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":" Team team \u003d logic.getTeamOrCreate(section, \"Team 1\");"},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" Student newStudent \u003d new Student(course, \"Test Student\", \"test@email.com\", \"Test Comment\", team);"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" String[] params \u003d new String[] {"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e students \u003d new ArrayList\u003c\u003e(logic.getStudentsForCourse(courseId));"},{"lineNumber":76,"author":{"gitId":"marquestye"},"content":" assertEquals(5, students.size());"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Typical Success Case For Enrolling a Student\");"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" StudentsEnrollRequest request \u003d prepareRequest(Arrays.asList(newStudent));"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" EnrollStudentsAction enrollStudentsAction \u003d getAction(request, params);"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" JsonResult res \u003d getJsonResult(enrollStudentsAction);"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" EnrollStudentsData data \u003d (EnrollStudentsData) res.getOutput();"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" assertEquals(1, data.getStudentsData().getStudents().size());"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e studentsInCourse \u003d logic.getStudentsForCourse(courseId);"},{"lineNumber":86,"author":{"gitId":"marquestye"},"content":" assertEquals(6, studentsInCourse.size());"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Fail to enroll due to duplicate team name across sections\");"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" String expectedMessage \u003d \"Team \\\"%s\\\" is detected in both Section \\\"%s\\\" and Section \\\"%s\\\".\""},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" + \" Please use different team names in different sections.\";"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" Section newSection \u003d logic.getSection(courseId, \"Section 3\");"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":" Team newTeam \u003d new Team(newSection, \"Team 1\");"},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":" newStudent \u003d new Student(course, \"Test Student\", \"test@email.com\", \"Test Comment\", newTeam);"},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" Student secondStudent \u003d new Student(course, \"Test Student 2\", \"test2@email.com\", \"Test Comment\","},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" team);"},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":" StudentsEnrollRequest req \u003d prepareRequest(Arrays.asList(secondStudent, newStudent));"},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":" InvalidOperationException exception \u003d verifyInvalidOperation(req, params);"},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" assertEquals(String.format(expectedMessage, \"Team 1\", \"Section 3\", \"Section 1\"), exception.getMessage());"},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Typical Success Case For Changing Details (except email) of a Student\");"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":" Section section3 \u003d logic.getSection(courseId, \"Section 3\");"},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" Team team3 \u003d logic.getTeamOrCreate(section3, \"Team 3\");"},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" Student changedTeam \u003d new Student(course, \"Student 1\", \"student1@teammates.tmt\", \"Test Comment\", team3);"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" request \u003d prepareRequest(Arrays.asList(changedTeam));"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" enrollStudentsAction \u003d getAction(request, params);"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" res \u003d getJsonResult(enrollStudentsAction);"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" data \u003d (EnrollStudentsData) res.getOutput();"},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" assertEquals(1, data.getStudentsData().getStudents().size());"},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" studentsInCourse \u003d logic.getStudentsForCourse(courseId);"},{"lineNumber":114,"author":{"gitId":"marquestye"},"content":" assertEquals(6, studentsInCourse.size());"},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" // Verify that changes have cascaded to feedback responses"},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":" String giverEmail \u003d \"student1@teammates.tmt\";"},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackResponse\u003e responsesFromUser \u003d"},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" logic.getFeedbackResponsesFromGiverForCourse(courseId, giverEmail);"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" for (FeedbackResponse response : responsesFromUser) {"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":" assertEquals(logic.getSection(courseId, \"Section 3\"), response.getGiverSection());"},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackResponse\u003e responsesToUser \u003d"},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" logic.getFeedbackResponsesForRecipientForCourse(courseId, giverEmail);"},{"lineNumber":128,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":129,"author":{"gitId":"domoberzin"},"content":" for (FeedbackResponse response : responsesToUser) {"},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":" assertEquals(logic.getSection(courseId, \"Section 3\"), response.getRecipientSection());"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackResponseComment\u003e commentsFromUser \u003d logic.getFeedbackResponseCommentsForResponse(response.getId());"},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":" for (FeedbackResponseComment comment : commentsFromUser) {"},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" if (comment.getGiver().equals(giverEmail)) {"},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" assertEquals(logic.getSection(courseId, \"Section 3\"), comment.getGiverSection());"},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":137,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":140,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":145,"author":{"gitId":"domoberzin"},"content":" String[] params \u003d new String[] {"},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":147,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":148,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":149,"author":{"gitId":"domoberzin"},"content":" verifyOnlyInstructorsOfTheSameCourseWithCorrectCoursePrivilegeCanAccess("},{"lineNumber":150,"author":{"gitId":"domoberzin"},"content":" course, Const.InstructorPermissions.CAN_MODIFY_STUDENT, params);"},{"lineNumber":151,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":152,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":149,"marquestye":3}},{"path":"src/it/java/teammates/it/ui/webapi/FeedbackSessionClosingRemindersActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Duration;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.ui.output.MessageOutput;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.FeedbackSessionClosingRemindersAction;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * SUT: {@link FeedbackSessionClosingRemindersAction}."},{"lineNumber":23,"author":{"gitId":"-"},"content":" */"},{"lineNumber":24,"author":{"gitId":"-"},"content":"public class FeedbackSessionClosingRemindersActionIT extends BaseActionIT\u003cFeedbackSessionClosingRemindersAction\u003e {"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":27,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":28,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":30,"author":{"gitId":"-"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":32,"author":{"gitId":"-"},"content":" prepareSession();"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" private void prepareSession() {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" // DEADLINE EXTENSIONS"},{"lineNumber":37,"author":{"gitId":"-"},"content":" String[] deKeys \u003d {\"student1InCourse1Session1\", \"instructor1InCourse1Session1\"};"},{"lineNumber":38,"author":{"gitId":"-"},"content":" List\u003cDeadlineExtension\u003e exts \u003d new ArrayList\u003c\u003e();"},{"lineNumber":39,"author":{"gitId":"-"},"content":" for (String deKey : deKeys) {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" exts.add(typicalBundle.deadlineExtensions.get(deKey));"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" // FEEDBACK QUESTIONS"},{"lineNumber":44,"author":{"gitId":"-"},"content":" String[] fqKeys \u003d {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" \"qn1InSession1InCourse1\","},{"lineNumber":46,"author":{"gitId":"-"},"content":" \"qn2InSession1InCourse1\","},{"lineNumber":47,"author":{"gitId":"-"},"content":" \"qn3InSession1InCourse1\","},{"lineNumber":48,"author":{"gitId":"-"},"content":" \"qn4InSession1InCourse1\","},{"lineNumber":49,"author":{"gitId":"-"},"content":" \"qn5InSession1InCourse1\","},{"lineNumber":50,"author":{"gitId":"-"},"content":" \"qn6InSession1InCourse1NoResponses\","},{"lineNumber":51,"author":{"gitId":"-"},"content":" };"},{"lineNumber":52,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e qns \u003d new ArrayList\u003c\u003e();"},{"lineNumber":53,"author":{"gitId":"-"},"content":" for (String fqKey : fqKeys) {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" qns.add(typicalBundle.feedbackQuestions.get(fqKey));"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" FeedbackSession session \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":58,"author":{"gitId":"-"},"content":" session.setDeadlineExtensions(exts);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" session.setFeedbackQuestions(qns);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":63,"author":{"gitId":"-"},"content":" String getActionUri() {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" return Const.CronJobURIs.AUTOMATED_FEEDBACK_CLOSING_REMINDERS;"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":68,"author":{"gitId":"-"},"content":" String getRequestMethod() {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" return GET;"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":73,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":74,"author":{"gitId":"-"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":76,"author":{"gitId":"-"},"content":" verifyOnlyAdminCanAccess(course);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":80,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":81,"author":{"gitId":"-"},"content":" protected void testExecute() throws Exception {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" loginAsAdmin();"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case 1: email tasks added for 1 all users of 1 session\");"},{"lineNumber":85,"author":{"gitId":"-"},"content":" textExecute_typicalSuccess1();"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case 2: email tasks added for 1 all users of 1 session and 1 deadline extension\");"},{"lineNumber":88,"author":{"gitId":"-"},"content":" textExecute_typicalSuccess2();"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case 3: Only 1 email task queued -- \""},{"lineNumber":91,"author":{"gitId":"-"},"content":" + \"0 for session: already sent, \""},{"lineNumber":92,"author":{"gitId":"-"},"content":" + \"1 for deadline extension: closing-soon not sent yet\");"},{"lineNumber":93,"author":{"gitId":"-"},"content":" textExecute_typicalSuccess3();"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case 4: No tasks queued -- \""},{"lineNumber":96,"author":{"gitId":"-"},"content":" + \"both session and deadline extensions have already sent closing-soon emails\");"},{"lineNumber":97,"author":{"gitId":"-"},"content":" textExecute_typicalSuccess4();"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case 5: No tasks queued -- session\u0027s closing-soon email disabled\");"},{"lineNumber":100,"author":{"gitId":"-"},"content":" textExecute_typicalSuccess5();"},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" private void textExecute_typicalSuccess1() {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" long oneHour \u003d 60 * 60;"},{"lineNumber":105,"author":{"gitId":"-"},"content":" Instant now \u003d Instant.now();"},{"lineNumber":106,"author":{"gitId":"-"},"content":" Duration noGracePeriod \u003d Duration.between(now, now);"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" FeedbackSession session \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":109,"author":{"gitId":"-"},"content":" session.setClosingSoonEmailSent(false);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" session.setEndTime(now.plusSeconds((oneHour * 23) + 60));"},{"lineNumber":111,"author":{"gitId":"-"},"content":" session.setGracePeriod(noGracePeriod);"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" String[] params \u003d {};"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" FeedbackSessionClosingRemindersAction action1 \u003d getAction(params);"},{"lineNumber":116,"author":{"gitId":"-"},"content":" JsonResult actionOutput1 \u003d getJsonResult(action1);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" MessageOutput response1 \u003d (MessageOutput) actionOutput1.getOutput();"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" assertEquals(\"Successful\", response1.getMessage());"},{"lineNumber":120,"author":{"gitId":"-"},"content":" assertTrue(session.isClosingSoonEmailSent());"},{"lineNumber":121,"author":{"gitId":"-"},"content":" assertTrue(session.getDeadlineExtensions().stream().allMatch(de -\u003e !de.isClosingSoonEmailSent()));"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"marquestye"},"content":" // 7 email tasks queued:"},{"lineNumber":124,"author":{"gitId":"marquestye"},"content":" // 1 co-owner, 5 students and 3 instructors,"},{"lineNumber":125,"author":{"gitId":"-"},"content":" // but 1 student and 1 instructor have deadline extensions (should not receive email)"},{"lineNumber":126,"author":{"gitId":"marquestye"},"content":" verifySpecifiedTasksAdded(Const.TaskQueue.SEND_EMAIL_QUEUE_NAME, 7);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" private void textExecute_typicalSuccess2() {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" long oneHour \u003d 60 * 60;"},{"lineNumber":131,"author":{"gitId":"-"},"content":" Instant now \u003d Instant.now();"},{"lineNumber":132,"author":{"gitId":"-"},"content":" Duration noGracePeriod \u003d Duration.between(now, now);"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" FeedbackSession session \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":135,"author":{"gitId":"-"},"content":" session.setClosingSoonEmailSent(false);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" session.setEndTime(now.plusSeconds((oneHour * 23) + 60));"},{"lineNumber":137,"author":{"gitId":"-"},"content":" session.setGracePeriod(noGracePeriod);"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" DeadlineExtension de \u003d session.getDeadlineExtensions().get(0);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" de.setEndTime(now.plusSeconds(oneHour * 16));"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" String[] params \u003d {};"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" FeedbackSessionClosingRemindersAction action1 \u003d getAction(params);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" JsonResult actionOutput1 \u003d getJsonResult(action1);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" MessageOutput response1 \u003d (MessageOutput) actionOutput1.getOutput();"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" assertEquals(\"Successful\", response1.getMessage());"},{"lineNumber":149,"author":{"gitId":"-"},"content":" assertTrue(session.isClosingSoonEmailSent());"},{"lineNumber":150,"author":{"gitId":"-"},"content":" assertTrue(de.isClosingSoonEmailSent());"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"marquestye"},"content":" // 8 email tasks queued:"},{"lineNumber":153,"author":{"gitId":"marquestye"},"content":" // - 7 emails: 1 co-owner, 5 students and 3 instructors,"},{"lineNumber":154,"author":{"gitId":"-"},"content":" // but 1 student and 1 instructor have deadline extensions (should not receive email)"},{"lineNumber":155,"author":{"gitId":"-"},"content":" // - 1 email: 1 student deadline extension"},{"lineNumber":156,"author":{"gitId":"marquestye"},"content":" verifySpecifiedTasksAdded(Const.TaskQueue.SEND_EMAIL_QUEUE_NAME, 8);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" }"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" private void textExecute_typicalSuccess3() {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" long oneHour \u003d 60 * 60;"},{"lineNumber":161,"author":{"gitId":"-"},"content":" Instant now \u003d Instant.now();"},{"lineNumber":162,"author":{"gitId":"-"},"content":" Duration noGracePeriod \u003d Duration.between(now, now);"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" FeedbackSession session \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":165,"author":{"gitId":"-"},"content":" session.setClosingSoonEmailSent(true);"},{"lineNumber":166,"author":{"gitId":"-"},"content":" session.setEndTime(now.plusSeconds((oneHour * 23) + 60));"},{"lineNumber":167,"author":{"gitId":"-"},"content":" session.setGracePeriod(noGracePeriod);"},{"lineNumber":168,"author":{"gitId":"-"},"content":""},{"lineNumber":169,"author":{"gitId":"-"},"content":" DeadlineExtension de \u003d session.getDeadlineExtensions().get(0);"},{"lineNumber":170,"author":{"gitId":"-"},"content":" de.setEndTime(now.plusSeconds(oneHour * 16));"},{"lineNumber":171,"author":{"gitId":"-"},"content":" de.setClosingSoonEmailSent(false);"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" String[] params \u003d {};"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" FeedbackSessionClosingRemindersAction action1 \u003d getAction(params);"},{"lineNumber":176,"author":{"gitId":"-"},"content":" JsonResult actionOutput1 \u003d getJsonResult(action1);"},{"lineNumber":177,"author":{"gitId":"-"},"content":" MessageOutput response1 \u003d (MessageOutput) actionOutput1.getOutput();"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" assertEquals(\"Successful\", response1.getMessage());"},{"lineNumber":180,"author":{"gitId":"-"},"content":" assertTrue(session.isClosingSoonEmailSent());"},{"lineNumber":181,"author":{"gitId":"-"},"content":" assertTrue(de.isClosingSoonEmailSent());"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" // 1 email tasks queued:"},{"lineNumber":184,"author":{"gitId":"-"},"content":" // - 0 emails: session already sent closing-soon emails"},{"lineNumber":185,"author":{"gitId":"-"},"content":" // - 1 email: 1 student deadline extension where closing-soon email not sent yet"},{"lineNumber":186,"author":{"gitId":"-"},"content":" verifySpecifiedTasksAdded(Const.TaskQueue.SEND_EMAIL_QUEUE_NAME, 1);"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":" private void textExecute_typicalSuccess4() {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" long oneHour \u003d 60 * 60;"},{"lineNumber":191,"author":{"gitId":"-"},"content":" Instant now \u003d Instant.now();"},{"lineNumber":192,"author":{"gitId":"-"},"content":" Duration noGracePeriod \u003d Duration.between(now, now);"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"-"},"content":" FeedbackSession session \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":195,"author":{"gitId":"-"},"content":" session.setClosingSoonEmailSent(true);"},{"lineNumber":196,"author":{"gitId":"-"},"content":" session.setEndTime(now.plusSeconds((oneHour * 23) + 60));"},{"lineNumber":197,"author":{"gitId":"-"},"content":" session.setGracePeriod(noGracePeriod);"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" DeadlineExtension de \u003d session.getDeadlineExtensions().get(0);"},{"lineNumber":200,"author":{"gitId":"-"},"content":" de.setEndTime(now.plusSeconds(oneHour * 16));"},{"lineNumber":201,"author":{"gitId":"-"},"content":" de.setClosingSoonEmailSent(true);"},{"lineNumber":202,"author":{"gitId":"-"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":" String[] params \u003d {};"},{"lineNumber":204,"author":{"gitId":"-"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" FeedbackSessionClosingRemindersAction action1 \u003d getAction(params);"},{"lineNumber":206,"author":{"gitId":"-"},"content":" JsonResult actionOutput1 \u003d getJsonResult(action1);"},{"lineNumber":207,"author":{"gitId":"-"},"content":" MessageOutput response1 \u003d (MessageOutput) actionOutput1.getOutput();"},{"lineNumber":208,"author":{"gitId":"-"},"content":""},{"lineNumber":209,"author":{"gitId":"-"},"content":" assertEquals(\"Successful\", response1.getMessage());"},{"lineNumber":210,"author":{"gitId":"-"},"content":" assertTrue(session.isClosingSoonEmailSent());"},{"lineNumber":211,"author":{"gitId":"-"},"content":" assertTrue(de.isClosingSoonEmailSent());"},{"lineNumber":212,"author":{"gitId":"-"},"content":""},{"lineNumber":213,"author":{"gitId":"-"},"content":" verifyNoTasksAdded();"},{"lineNumber":214,"author":{"gitId":"-"},"content":" }"},{"lineNumber":215,"author":{"gitId":"-"},"content":""},{"lineNumber":216,"author":{"gitId":"-"},"content":" private void textExecute_typicalSuccess5() {"},{"lineNumber":217,"author":{"gitId":"-"},"content":" long oneHour \u003d 60 * 60;"},{"lineNumber":218,"author":{"gitId":"-"},"content":" Instant now \u003d Instant.now();"},{"lineNumber":219,"author":{"gitId":"-"},"content":" Duration noGracePeriod \u003d Duration.between(now, now);"},{"lineNumber":220,"author":{"gitId":"-"},"content":""},{"lineNumber":221,"author":{"gitId":"-"},"content":" FeedbackSession session \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":222,"author":{"gitId":"-"},"content":" session.setClosingEmailEnabled(false);"},{"lineNumber":223,"author":{"gitId":"-"},"content":" session.setClosingSoonEmailSent(false);"},{"lineNumber":224,"author":{"gitId":"-"},"content":" session.setEndTime(now.plusSeconds((oneHour * 23) + 60));"},{"lineNumber":225,"author":{"gitId":"-"},"content":" session.setGracePeriod(noGracePeriod);"},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"-"},"content":" DeadlineExtension de \u003d session.getDeadlineExtensions().get(0);"},{"lineNumber":228,"author":{"gitId":"-"},"content":" de.setEndTime(now.plusSeconds(oneHour * 16));"},{"lineNumber":229,"author":{"gitId":"-"},"content":" de.setClosingSoonEmailSent(false);"},{"lineNumber":230,"author":{"gitId":"-"},"content":""},{"lineNumber":231,"author":{"gitId":"-"},"content":" String[] params \u003d {};"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" FeedbackSessionClosingRemindersAction action1 \u003d getAction(params);"},{"lineNumber":234,"author":{"gitId":"-"},"content":" JsonResult actionOutput1 \u003d getJsonResult(action1);"},{"lineNumber":235,"author":{"gitId":"-"},"content":" MessageOutput response1 \u003d (MessageOutput) actionOutput1.getOutput();"},{"lineNumber":236,"author":{"gitId":"-"},"content":""},{"lineNumber":237,"author":{"gitId":"-"},"content":" assertEquals(\"Successful\", response1.getMessage());"},{"lineNumber":238,"author":{"gitId":"-"},"content":" assertTrue(!session.isClosingSoonEmailSent());"},{"lineNumber":239,"author":{"gitId":"-"},"content":" assertTrue(!de.isClosingSoonEmailSent());"},{"lineNumber":240,"author":{"gitId":"-"},"content":""},{"lineNumber":241,"author":{"gitId":"-"},"content":" verifyNoTasksAdded();"},{"lineNumber":242,"author":{"gitId":"-"},"content":" }"},{"lineNumber":243,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":6,"-":237}},{"path":"src/it/java/teammates/it/ui/webapi/GetCourseJoinStatusActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Const;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.output.JoinStatus;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.webapi.GetCourseJoinStatusAction;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link GetCourseJoinStatusAction}."},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"public class GetCourseJoinStatusActionIT extends BaseActionIT\u003cGetCourseJoinStatusAction\u003e {"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":" @BeforeMethod"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":" protected void setUp() throws Exception {"},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":" super.setUp();"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" this.typicalBundle \u003d loadSqlDataBundle(\"/typicalDataBundle.json\");"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":" HibernateUtil.flushSession();"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" protected String getActionUri() {"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" return Const.ResourceURIs.JOIN;"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" protected String getRequestMethod() {"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" return GET;"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" protected void testExecute() {"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" loginAsUnregistered(\"unreg.user\");"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Not enough parameters\");"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure();"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure("},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, \"regkey\""},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" );"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure("},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.STUDENT"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" );"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Normal case: student is already registered\");"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" String registeredStudentKey \u003d"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" logic.getStudentForEmail(\"course-1\", \"student1@teammates.tmt\").getRegKey();"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" String[] params \u003d new String[] {"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, registeredStudentKey,"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.STUDENT,"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" GetCourseJoinStatusAction getCourseJoinStatusAction \u003d getAction(params);"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" JsonResult result \u003d getJsonResult(getCourseJoinStatusAction);"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" JoinStatus output \u003d (JoinStatus) result.getOutput();"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" assertTrue(output.getHasJoined());"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Normal case: student is not registered\");"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" String unregisteredStudentKey \u003d"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" logic.getStudentForEmail(\"course-1\", \"unregisteredStudentInCourse1@teammates.tmt\").getRegKey();"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" params \u003d new String[] {"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, unregisteredStudentKey,"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.STUDENT,"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" getCourseJoinStatusAction \u003d getAction(params);"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" result \u003d getJsonResult(getCourseJoinStatusAction);"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" output \u003d (JoinStatus) result.getOutput();"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":" assertFalse(output.getHasJoined());"},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: regkey is not valid for student\");"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" params \u003d new String[] {"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, \"ANXKJZNZXNJCZXKJDNKSDA\","},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.STUDENT,"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" verifyEntityNotFound(params);"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Normal case: instructor is already registered\");"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" String registeredInstructorKey \u003d"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" logic.getInstructorForEmail(\"course-1\", \"instr1@teammates.tmt\").getRegKey();"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" params \u003d new String[] {"},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, registeredInstructorKey,"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" getCourseJoinStatusAction \u003d getAction(params);"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":" result \u003d getJsonResult(getCourseJoinStatusAction);"},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":" output \u003d (JoinStatus) result.getOutput();"},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" assertTrue(output.getHasJoined());"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Normal case: instructor is not registered\");"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" String unregisteredInstructorKey \u003d"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":" logic.getInstructorForEmail(\"course-1\", \"unregisteredInstructor@teammates.tmt\").getRegKey();"},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" params \u003d new String[] {"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, unregisteredInstructorKey,"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" getCourseJoinStatusAction \u003d getAction(params);"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" result \u003d getJsonResult(getCourseJoinStatusAction);"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" output \u003d (JoinStatus) result.getOutput();"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" assertFalse(output.getHasJoined());"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: regkey is not valid for instructor\");"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" params \u003d new String[] {"},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, \"ANXKJZNZXNJCZXKJDNKSDA\","},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" verifyEntityNotFound(params);"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Normal case: account request not used, instructor has not joined course\");"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" AccountRequest unregisteredInstructor1AccountRequest \u003d typicalBundle.accountRequests.get(\"unregisteredInstructor1\");"},{"lineNumber":136,"author":{"gitId":"-"},"content":" String accountRequestNotUsedKey \u003d unregisteredInstructor1AccountRequest.getRegistrationKey();"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":" params \u003d new String[] {"},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, accountRequestNotUsedKey,"},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":141,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.IS_CREATING_ACCOUNT, \"true\","},{"lineNumber":142,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":143,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":144,"author":{"gitId":"dishenggg"},"content":" getCourseJoinStatusAction \u003d getAction(params);"},{"lineNumber":145,"author":{"gitId":"dishenggg"},"content":" result \u003d getJsonResult(getCourseJoinStatusAction);"},{"lineNumber":146,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":" output \u003d (JoinStatus) result.getOutput();"},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":" assertFalse(output.getHasJoined());"},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Normal case: account request already used, instructor has joined course\");"},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" AccountRequest instructor1AccountRequest \u003d typicalBundle.accountRequests.get(\"instructor1\");"},{"lineNumber":153,"author":{"gitId":"-"},"content":" String accountRequestUsedKey \u003d instructor1AccountRequest.getRegistrationKey();"},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":" params \u003d new String[] {"},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, accountRequestUsedKey,"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":158,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.IS_CREATING_ACCOUNT, \"true\","},{"lineNumber":159,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":161,"author":{"gitId":"dishenggg"},"content":" getCourseJoinStatusAction \u003d getAction(params);"},{"lineNumber":162,"author":{"gitId":"dishenggg"},"content":" result \u003d getJsonResult(getCourseJoinStatusAction);"},{"lineNumber":163,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":164,"author":{"gitId":"dishenggg"},"content":" output \u003d (JoinStatus) result.getOutput();"},{"lineNumber":165,"author":{"gitId":"dishenggg"},"content":" assertTrue(output.getHasJoined());"},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":167,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: account request regkey is not valid\");"},{"lineNumber":168,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":" params \u003d new String[] {"},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, \"invalid-registration-key\","},{"lineNumber":171,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.IS_CREATING_ACCOUNT, \"true\","},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":175,"author":{"gitId":"dishenggg"},"content":" verifyEntityNotFound(params);"},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: invalid entity type\");"},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":179,"author":{"gitId":"dishenggg"},"content":" params \u003d new String[] {"},{"lineNumber":180,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, unregisteredStudentKey,"},{"lineNumber":181,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, \"unknown\","},{"lineNumber":182,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure(params);"},{"lineNumber":185,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":186,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":187,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":188,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":189,"author":{"gitId":"dishenggg"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":190,"author":{"gitId":"dishenggg"},"content":" verifyAnyLoggedInUserCanAccess();"},{"lineNumber":191,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":192,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":187,"-":5}},{"path":"src/it/java/teammates/it/ui/webapi/GetFeedbackSessionLogsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionLogData;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionLogEntryData;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionLogsData;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.GetFeedbackSessionLogsAction;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":23,"author":{"gitId":"-"},"content":" * SUT: {@link GetFeedbackSessionLogsAction}."},{"lineNumber":24,"author":{"gitId":"-"},"content":" */"},{"lineNumber":25,"author":{"gitId":"-"},"content":"public class GetFeedbackSessionLogsActionIT extends BaseActionIT\u003cGetFeedbackSessionLogsAction\u003e {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":27,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":28,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":30,"author":{"gitId":"-"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":32,"author":{"gitId":"-"},"content":" }"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":35,"author":{"gitId":"-"},"content":" protected String getActionUri() {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" return Const.ResourceURIs.SESSION_LOGS;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" }"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":40,"author":{"gitId":"-"},"content":" protected String getRequestMethod() {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" return GET;"},{"lineNumber":42,"author":{"gitId":"-"},"content":" }"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":45,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":46,"author":{"gitId":"-"},"content":" protected void testExecute() {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" JsonResult actionOutput;"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":50,"author":{"gitId":"-"},"content":" String courseId \u003d course.getId();"},{"lineNumber":51,"author":{"gitId":"-"},"content":" FeedbackSession fsa1 \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":52,"author":{"gitId":"-"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":53,"author":{"gitId":"-"},"content":" Student student2 \u003d typicalBundle.students.get(\"student2InCourse1\");"},{"lineNumber":54,"author":{"gitId":"-"},"content":" String student1Email \u003d student1.getEmail();"},{"lineNumber":55,"author":{"gitId":"-"},"content":" String student2Email \u003d student2.getEmail();"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" long endTime \u003d Instant.parse(\"2012-01-02T12:00:00Z\").toEpochMilli();"},{"lineNumber":57,"author":{"gitId":"-"},"content":" long startTime \u003d endTime - (Const.LOGS_RETENTION_PERIOD.toDays() - 1) * 24 * 60 * 60 * 1000;"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: not enough parameters\");"},{"lineNumber":60,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure("},{"lineNumber":61,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId"},{"lineNumber":62,"author":{"gitId":"-"},"content":" );"},{"lineNumber":63,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure("},{"lineNumber":64,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime)"},{"lineNumber":66,"author":{"gitId":"-"},"content":" );"},{"lineNumber":67,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure("},{"lineNumber":68,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":69,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime)"},{"lineNumber":70,"author":{"gitId":"-"},"content":" );"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: invalid course id\");"},{"lineNumber":73,"author":{"gitId":"-"},"content":" String[] paramsInvalid1 \u003d {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, \"fake-course-id\","},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student1.getId().toString(),"},{"lineNumber":76,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":77,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":78,"author":{"gitId":"-"},"content":" };"},{"lineNumber":79,"author":{"gitId":"-"},"content":" verifyEntityNotFound(paramsInvalid1);"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: invalid student id\");"},{"lineNumber":82,"author":{"gitId":"-"},"content":" String[] paramsInvalid2 \u003d {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, \"00000000-0000-0000-0000-000000000000\","},{"lineNumber":85,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":86,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":87,"author":{"gitId":"-"},"content":" };"},{"lineNumber":88,"author":{"gitId":"-"},"content":" verifyEntityNotFound(paramsInvalid2);"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: invalid start or end times\");"},{"lineNumber":91,"author":{"gitId":"-"},"content":" String[] paramsInvalid3 \u003d {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":93,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, \"abc\","},{"lineNumber":94,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":95,"author":{"gitId":"-"},"content":" };"},{"lineNumber":96,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure(paramsInvalid3);"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" String[] paramsInvalid4 \u003d {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":100,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":101,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, \" \","},{"lineNumber":102,"author":{"gitId":"-"},"content":" };"},{"lineNumber":103,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure(paramsInvalid4);"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" ______TS(\"Success case: should group by feedback session\");"},{"lineNumber":106,"author":{"gitId":"-"},"content":" String[] paramsSuccessful1 \u003d {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":108,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":109,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":110,"author":{"gitId":"-"},"content":" };"},{"lineNumber":111,"author":{"gitId":"-"},"content":" actionOutput \u003d getJsonResult(getAction(paramsSuccessful1));"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" // The filtering by the logs processor cannot be tested directly, assume that it filters correctly"},{"lineNumber":114,"author":{"gitId":"-"},"content":" // Here, it simply returns all log entries"},{"lineNumber":115,"author":{"gitId":"-"},"content":" FeedbackSessionLogsData fslData \u003d (FeedbackSessionLogsData) actionOutput.getOutput();"},{"lineNumber":116,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogData\u003e fsLogs \u003d fslData.getFeedbackSessionLogs();"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" // Course has 6 feedback sessions, last 4 of which have no log entries"},{"lineNumber":119,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.size(), 6);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.get(2).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.get(3).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.get(4).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":123,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.get(5).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogEntryData\u003e fsLogEntries1 \u003d fsLogs.get(0).getFeedbackSessionLogEntries();"},{"lineNumber":126,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogEntryData\u003e fsLogEntries2 \u003d fsLogs.get(1).getFeedbackSessionLogEntries();"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.size(), 3);"},{"lineNumber":129,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(0).getStudentData().getEmail(), student1Email);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(1).getStudentData().getEmail(), student2Email);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(2).getStudentData().getEmail(), student2Email);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(2).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.size(), 2);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.get(0).getStudentData().getEmail(), student1Email);"},{"lineNumber":138,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.get(1).getStudentData().getEmail(), student1Email);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: should accept optional student Id\");"},{"lineNumber":143,"author":{"gitId":"-"},"content":" String[] paramsSuccessful2 \u003d {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":145,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student1.getId().toString(),"},{"lineNumber":146,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":147,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":148,"author":{"gitId":"-"},"content":" };"},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":" actionOutput \u003d getJsonResult(getAction(paramsSuccessful2));"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":" fslData \u003d (FeedbackSessionLogsData) actionOutput.getOutput();"},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":" fsLogs \u003d fslData.getFeedbackSessionLogs();"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":153,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.size(), 6);"},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(2).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(3).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(4).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(5).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":158,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":159,"author":{"gitId":"dishenggg"},"content":" fsLogEntries1 \u003d fsLogs.get(0).getFeedbackSessionLogEntries();"},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":" fsLogEntries2 \u003d fsLogs.get(1).getFeedbackSessionLogEntries();"},{"lineNumber":161,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":162,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.size(), 1);"},{"lineNumber":163,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getStudentData().getEmail(), student1Email);"},{"lineNumber":164,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":165,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.size(), 2);"},{"lineNumber":167,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(0).getStudentData().getEmail(), student1Email);"},{"lineNumber":168,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(1).getStudentData().getEmail(), student1Email);"},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":171,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: should accept optional feedback session\");"},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":" String[] paramsSuccessful3 \u003d {"},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":175,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fsa1.getId().toString(),"},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":179,"author":{"gitId":"dishenggg"},"content":" actionOutput \u003d getJsonResult(getAction(paramsSuccessful3));"},{"lineNumber":180,"author":{"gitId":"dishenggg"},"content":" fslData \u003d (FeedbackSessionLogsData) actionOutput.getOutput();"},{"lineNumber":181,"author":{"gitId":"dishenggg"},"content":" fsLogs \u003d fslData.getFeedbackSessionLogs();"},{"lineNumber":182,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.size(), 6);"},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(1).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":185,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(2).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":186,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(3).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":187,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(4).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":188,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(5).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":189,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":190,"author":{"gitId":"dishenggg"},"content":" fsLogEntries1 \u003d fsLogs.get(0).getFeedbackSessionLogEntries();"},{"lineNumber":191,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":192,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.size(), 3);"},{"lineNumber":193,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getStudentData().getEmail(), student1Email);"},{"lineNumber":194,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":195,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(1).getStudentData().getEmail(), student2Email);"},{"lineNumber":196,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":197,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(2).getStudentData().getEmail(), student2Email);"},{"lineNumber":198,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(2).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":199,"author":{"gitId":"-"},"content":""},{"lineNumber":200,"author":{"gitId":"-"},"content":" // TODO: if we restrict the range from start to end time, it should be tested here as well"},{"lineNumber":201,"author":{"gitId":"-"},"content":" }"},{"lineNumber":202,"author":{"gitId":"-"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":204,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":205,"author":{"gitId":"-"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":206,"author":{"gitId":"-"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":207,"author":{"gitId":"-"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":208,"author":{"gitId":"-"},"content":" String courseId \u003d course.getId();"},{"lineNumber":209,"author":{"gitId":"-"},"content":" Instructor helper \u003d typicalBundle.instructors.get(\"instructor2OfCourse1\");"},{"lineNumber":210,"author":{"gitId":"-"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":212,"author":{"gitId":"-"},"content":" };"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" ______TS(\"Only instructors with modify student, session and instructor privilege can access\");"},{"lineNumber":215,"author":{"gitId":"-"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":216,"author":{"gitId":"-"},"content":""},{"lineNumber":217,"author":{"gitId":"-"},"content":" loginAsInstructor(helper.getGoogleId());"},{"lineNumber":218,"author":{"gitId":"-"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" ______TS(\"Only instructors of the same course can access\");"},{"lineNumber":221,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":222,"author":{"gitId":"-"},"content":" verifyCanAccess(submissionParams);"},{"lineNumber":223,"author":{"gitId":"-"},"content":" }"},{"lineNumber":224,"author":{"gitId":"-"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":57,"-":168}},{"path":"src/it/java/teammates/it/ui/webapi/GetFeedbackSessionSubmittedGiverSetActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.Test;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import com.google.common.collect.Sets;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.output.FeedbackSessionSubmittedGiverSet;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.GetFeedbackSessionSubmittedGiverSetAction;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" * SUT: {@link GetFeedbackSessionSubmittedGiverSetAction}."},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":"public class GetFeedbackSessionSubmittedGiverSetActionIT extends BaseActionIT\u003cGetFeedbackSessionSubmittedGiverSetAction\u003e {"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" @BeforeMethod"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" protected void setUp() throws Exception {"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" super.setUp();"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.flushSession();"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" protected String getActionUri() {"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" return Const.ResourceURIs.SESSION_SUBMITTED_GIVER_SET;"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" protected String getRequestMethod() {"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" return GET;"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" protected void testExecute() {"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" Instructor instructor1OfCourse1 \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" String instructorId \u003d instructor1OfCourse1.getGoogleId();"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" FeedbackSession fsa \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" loginAsInstructor(instructorId);"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Not enough parameters\");"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" verifyHttpParameterFailure();"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Typical case\");"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fsa.getName(),"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" GetFeedbackSessionSubmittedGiverSetAction pageAction \u003d getAction(submissionParams);"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" JsonResult result \u003d getJsonResult(pageAction);"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" FeedbackSessionSubmittedGiverSet output \u003d (FeedbackSessionSubmittedGiverSet) result.getOutput();"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" assertEquals(Sets.newHashSet(\"student1@teammates.tmt\", \"student2@teammates.tmt\","},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" \"student3@teammates.tmt\"), output.getGiverIdentifiers());"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" FeedbackSession fsa \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fsa.getName(),"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" verifyOnlyInstructorsOfTheSameCourseCanAccess(course, submissionParams);"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":78}},{"path":"src/it/java/teammates/it/ui/webapi/GetInstructorsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.ui.output.InstructorData;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.ui.output.InstructorsData;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.ui.request.Intent;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.GetInstructorsAction;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * SUT: {@link GetInstructorsAction}."},{"lineNumber":20,"author":{"gitId":"-"},"content":" */"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public class GetInstructorsActionIT extends BaseActionIT\u003cGetInstructorsAction\u003e {"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":24,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":25,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":27,"author":{"gitId":"-"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":28,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":32,"author":{"gitId":"-"},"content":" protected String getActionUri() {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" return Const.ResourceURIs.INSTRUCTORS;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":37,"author":{"gitId":"-"},"content":" protected String getRequestMethod() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" return GET;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":42,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":43,"author":{"gitId":"-"},"content":" protected void testExecute() throws Exception {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case with FULL_DETAIL\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":" String[] params \u003d new String[] {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, instructor.getCourseId(),"},{"lineNumber":51,"author":{"gitId":"-"},"content":" Const.ParamsNames.INTENT, Intent.FULL_DETAIL.toString(),"},{"lineNumber":52,"author":{"gitId":"-"},"content":" };"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" GetInstructorsAction action \u003d getAction(params);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" JsonResult jsonResult \u003d getJsonResult(action);"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" InstructorsData output \u003d (InstructorsData) jsonResult.getOutput();"},{"lineNumber":58,"author":{"gitId":"-"},"content":" List\u003cInstructorData\u003e instructors \u003d output.getInstructors();"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" assertEquals(3, instructors.size());"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case with no intent\");"},{"lineNumber":63,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, instructor.getCourseId(),"},{"lineNumber":65,"author":{"gitId":"-"},"content":" Const.ParamsNames.INTENT, null,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" };"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" action \u003d getAction(params);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" jsonResult \u003d getJsonResult(action);"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" output \u003d (InstructorsData) jsonResult.getOutput();"},{"lineNumber":72,"author":{"gitId":"-"},"content":" instructors \u003d output.getInstructors();"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" assertEquals(3, instructors.size());"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" for (InstructorData instructorData : instructors) {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" assertNull(instructorData.getGoogleId());"},{"lineNumber":78,"author":{"gitId":"-"},"content":" assertNull(instructorData.getJoinState());"},{"lineNumber":79,"author":{"gitId":"-"},"content":" assertNull(instructorData.getIsDisplayedToStudents());"},{"lineNumber":80,"author":{"gitId":"-"},"content":" assertNull(instructorData.getRole());"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" ______TS(\"Unknown intent\");"},{"lineNumber":84,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, instructor.getCourseId(),"},{"lineNumber":86,"author":{"gitId":"-"},"content":" Const.ParamsNames.INTENT, \"Unknown\","},{"lineNumber":87,"author":{"gitId":"-"},"content":" };"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure(params);"},{"lineNumber":90,"author":{"gitId":"-"},"content":" }"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":93,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":94,"author":{"gitId":"-"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":96,"author":{"gitId":"-"},"content":" Student student \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" ______TS(\"Course not found, logged in as instructor, intent FULL_DETAIL\");"},{"lineNumber":99,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" String[] params \u003d new String[] {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, \"does-not-exist-id\","},{"lineNumber":103,"author":{"gitId":"-"},"content":" Const.ParamsNames.INTENT, Intent.FULL_DETAIL.toString(),"},{"lineNumber":104,"author":{"gitId":"-"},"content":" };"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" verifyEntityNotFoundAcl(params);"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" ______TS(\"Course not found, logged in as student, intent undefined\");"},{"lineNumber":109,"author":{"gitId":"-"},"content":" loginAsStudent(student.getGoogleId());"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, \"does-not-exist-id\","},{"lineNumber":113,"author":{"gitId":"-"},"content":" };"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" verifyEntityNotFoundAcl(params);"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" ______TS(\"Unknown login entity, intent FULL_DETAIL\");"},{"lineNumber":118,"author":{"gitId":"-"},"content":" loginAsUnregistered(\"unregistered\");"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, instructor.getCourseId(),"},{"lineNumber":122,"author":{"gitId":"-"},"content":" Const.ParamsNames.INTENT, Intent.FULL_DETAIL.toString(),"},{"lineNumber":123,"author":{"gitId":"-"},"content":" };"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" ______TS(\"Unknown login entity, intent undefined\");"},{"lineNumber":128,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":129,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, instructor.getCourseId(),"},{"lineNumber":130,"author":{"gitId":"-"},"content":" };"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" ______TS(\"Unknown intent, logged in as instructor\");"},{"lineNumber":135,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":138,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, instructor.getCourseId(),"},{"lineNumber":139,"author":{"gitId":"-"},"content":" Const.ParamsNames.INTENT, \"Unknown\","},{"lineNumber":140,"author":{"gitId":"-"},"content":" };"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" verifyHttpParameterFailureAcl(params);"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" ______TS(\"Intent FULL_DETAIL, should authenticate as instructor\");"},{"lineNumber":145,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":146,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, instructor.getCourseId(),"},{"lineNumber":147,"author":{"gitId":"-"},"content":" Const.ParamsNames.INTENT, Intent.FULL_DETAIL.toString(),"},{"lineNumber":148,"author":{"gitId":"-"},"content":" };"},{"lineNumber":149,"author":{"gitId":"-"},"content":""},{"lineNumber":150,"author":{"gitId":"-"},"content":" verifyOnlyInstructorsOfTheSameCourseCanAccess(instructor.getCourse(), params);"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" ______TS(\"Intent undefined, should authenticate as student, access own course\");"},{"lineNumber":153,"author":{"gitId":"-"},"content":" loginAsStudent(student.getGoogleId());"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, student.getCourseId(),"},{"lineNumber":157,"author":{"gitId":"-"},"content":" };"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" verifyCanAccess(params);"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" ______TS(\"Intent undefined, should authenticate as student, access other course\");"},{"lineNumber":162,"author":{"gitId":"-"},"content":" Student otherStudent \u003d typicalBundle.students.get(\"student1InCourse2\");"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" assertNotEquals(otherStudent.getCourse(), student.getCourse());"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, otherStudent.getCourseId(),"},{"lineNumber":168,"author":{"gitId":"-"},"content":" };"},{"lineNumber":169,"author":{"gitId":"-"},"content":""},{"lineNumber":170,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":2,"-":171}},{"path":"src/it/java/teammates/it/ui/webapi/GetSessionResponseStatsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.Test;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.Const;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.output.FeedbackSessionStatsData;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.GetSessionResponseStatsAction;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" * SUT: {@link GetSessionResponseStatsAction}."},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"public class GetSessionResponseStatsActionIT extends BaseActionIT\u003cGetSessionResponseStatsAction\u003e {"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" @BeforeMethod"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" protected void setUp() throws Exception {"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" super.setUp();"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.flushSession();"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" String getActionUri() {"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" return Const.ResourceURIs.SESSION_STATS;"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" String getRequestMethod() {"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" return GET;"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" protected void testExecute() {"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" ______TS(\"typical: instructor accesses feedback stats of his/her course\");"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" FeedbackSession accessibleFs \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, accessibleFs.getName(),"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.COURSE_ID, accessibleFs.getCourse().getId(),"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" GetSessionResponseStatsAction a \u003d getAction(submissionParams);"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" JsonResult r \u003d getJsonResult(a);"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" FeedbackSessionStatsData output \u003d (FeedbackSessionStatsData) r.getOutput();"},{"lineNumber":56,"author":{"gitId":"-"},"content":" assertEquals(8, output.getExpectedTotal());"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" assertEquals(3, output.getSubmittedTotal());"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" ______TS(\"fail: instructor accesses stats of non-existent feedback session\");"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" String nonexistentFeedbackSession \u003d \"nonexistentFeedbackSession\";"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, nonexistentFeedbackSession,"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.COURSE_ID, accessibleFs.getCourse().getId(),"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" verifyEntityNotFound(submissionParams);"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" ______TS(\"accessible for admin\");"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" verifyAccessibleForAdmin();"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" ______TS(\"accessible for authenticated instructor\");"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" Course course1 \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" FeedbackSession accessibleFs \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, accessibleFs.getName(),"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.COURSE_ID, accessibleFs.getCourse().getId(),"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" verifyOnlyInstructorsOfTheSameCourseCanAccess(course1, submissionParams);"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":85,"-":1}},{"path":"src/it/java/teammates/it/ui/webapi/GetSessionResultsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import java.util.HashSet;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import java.util.Set;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":"import org.testng.annotations.Test;"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.FeedbackResultFetchType;"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":15,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":"import teammates.ui.output.SessionResultsData;"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":"import teammates.ui.request.Intent;"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":"import teammates.ui.webapi.GetSessionResultsAction;"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" * SUT: {@link GetSessionResultsAction}."},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":"public class GetSessionResultsActionIT extends BaseActionIT\u003cGetSessionResultsAction\u003e {"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" protected String getActionUri() {"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" return Const.ResourceURIs.RESULT;"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" protected String getRequestMethod() {"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" return GET;"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" @BeforeMethod"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" protected void setUp() throws Exception {"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" super.setUp();"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" logoutUser();"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" HibernateUtil.flushSession();"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" HibernateUtil.clearSession();"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" protected void testExecute() {"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" ______TS(\"Typical: Instructor accesses results of their course\");"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" FeedbackSession accessibleFeedbackSession \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, accessibleFeedbackSession.getName(),"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.FULL_DETAIL.name(),"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":" GetSessionResultsAction a \u003d getAction(submissionParams);"},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":" JsonResult r \u003d getJsonResult(a);"},{"lineNumber":67,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":68,"author":{"gitId":"xenosf"},"content":" SessionResultsData output \u003d (SessionResultsData) r.getOutput();"},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":" SessionResultsData expectedResults \u003d SessionResultsData.initForInstructor("},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" logic.getSessionResultsForCourse(accessibleFeedbackSession,"},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":" instructor.getEmail(),"},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" null, null, FeedbackResultFetchType.BOTH));"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" assertTrue(isSessionResultsDataEqual(expectedResults, output));"},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" ______TS(\"Typical: Instructor accesses results of their course with breakdown\");"},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" Set\u003cSection\u003e sections \u003d new HashSet\u003c\u003e();"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":" typicalBundle.feedbackResponses.values().forEach(resp -\u003e {"},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":" sections.add(resp.getGiverSection());"},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" sections.add(resp.getRecipientSection());"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":" for (FeedbackResultFetchType fetchType : FeedbackResultFetchType.values()) {"},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":" for (Section section : sections) {"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, accessibleFeedbackSession.getName(),"},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.FULL_DETAIL.name(),"},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_RESULTS_GROUPBYSECTION, section.getName(),"},{"lineNumber":93,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_RESULTS_SECTION_BY_GIVER_RECEIVER, fetchType.name(),"},{"lineNumber":94,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":" a \u003d getAction(submissionParams);"},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" r \u003d getJsonResult(a);"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" output \u003d (SessionResultsData) r.getOutput();"},{"lineNumber":100,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":" expectedResults \u003d SessionResultsData.initForInstructor("},{"lineNumber":102,"author":{"gitId":"xenosf"},"content":" logic.getSessionResultsForCourse(accessibleFeedbackSession,"},{"lineNumber":103,"author":{"gitId":"xenosf"},"content":" accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":104,"author":{"gitId":"xenosf"},"content":" instructor.getEmail(),"},{"lineNumber":105,"author":{"gitId":"xenosf"},"content":" null, section.getName(), fetchType));"},{"lineNumber":106,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":107,"author":{"gitId":"xenosf"},"content":" assertTrue(isSessionResultsDataEqual(expectedResults, output));"},{"lineNumber":108,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":109,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":110,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":111,"author":{"gitId":"xenosf"},"content":" ______TS(\"Typical: Instructor previews session results as student\");"},{"lineNumber":112,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":113,"author":{"gitId":"xenosf"},"content":" Student student \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":114,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":115,"author":{"gitId":"xenosf"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, accessibleFeedbackSession.getName(),"},{"lineNumber":117,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":118,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.name(),"},{"lineNumber":119,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.PREVIEWAS, student.getEmail(),"},{"lineNumber":120,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":121,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":122,"author":{"gitId":"xenosf"},"content":" a \u003d getAction(submissionParams);"},{"lineNumber":123,"author":{"gitId":"xenosf"},"content":" r \u003d getJsonResult(a);"},{"lineNumber":124,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":125,"author":{"gitId":"xenosf"},"content":" output \u003d (SessionResultsData) r.getOutput();"},{"lineNumber":126,"author":{"gitId":"xenosf"},"content":" expectedResults \u003d SessionResultsData.initForStudent("},{"lineNumber":127,"author":{"gitId":"xenosf"},"content":" logic.getSessionResultsForUser(accessibleFeedbackSession,"},{"lineNumber":128,"author":{"gitId":"xenosf"},"content":" accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":129,"author":{"gitId":"xenosf"},"content":" student.getEmail(),"},{"lineNumber":130,"author":{"gitId":"xenosf"},"content":" false, null, true),"},{"lineNumber":131,"author":{"gitId":"xenosf"},"content":" student);"},{"lineNumber":132,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":133,"author":{"gitId":"xenosf"},"content":" assertTrue(isSessionResultsDataEqual(expectedResults, output));"},{"lineNumber":134,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":135,"author":{"gitId":"xenosf"},"content":" ______TS(\"Typical: Student accesses results of their course\");"},{"lineNumber":136,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":137,"author":{"gitId":"xenosf"},"content":" loginAsStudent(student.getGoogleId());"},{"lineNumber":138,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":139,"author":{"gitId":"xenosf"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":140,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, accessibleFeedbackSession.getName(),"},{"lineNumber":141,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":142,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.name(),"},{"lineNumber":143,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":144,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":145,"author":{"gitId":"xenosf"},"content":" a \u003d getAction(submissionParams);"},{"lineNumber":146,"author":{"gitId":"xenosf"},"content":" r \u003d getJsonResult(a);"},{"lineNumber":147,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":148,"author":{"gitId":"xenosf"},"content":" output \u003d (SessionResultsData) r.getOutput();"},{"lineNumber":149,"author":{"gitId":"xenosf"},"content":" expectedResults \u003d SessionResultsData.initForStudent("},{"lineNumber":150,"author":{"gitId":"xenosf"},"content":" logic.getSessionResultsForUser(accessibleFeedbackSession,"},{"lineNumber":151,"author":{"gitId":"xenosf"},"content":" accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":152,"author":{"gitId":"xenosf"},"content":" student.getEmail(),"},{"lineNumber":153,"author":{"gitId":"xenosf"},"content":" false, null, false),"},{"lineNumber":154,"author":{"gitId":"xenosf"},"content":" student);"},{"lineNumber":155,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":156,"author":{"gitId":"xenosf"},"content":" assertTrue(isSessionResultsDataEqual(expectedResults, output));"},{"lineNumber":157,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":158,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"Typical: Student accesses results of their course by questionId\");"},{"lineNumber":159,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":160,"author":{"gitId":"mingyuanc"},"content":" loginAsStudent(student.getGoogleId());"},{"lineNumber":161,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":162,"author":{"gitId":"mingyuanc"},"content":" FeedbackQuestion question \u003d typicalBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":163,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":164,"author":{"gitId":"mingyuanc"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":165,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, accessibleFeedbackSession.getName(),"},{"lineNumber":166,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.COURSE_ID, accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":167,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.FEEDBACK_QUESTION_ID, question.getId().toString(),"},{"lineNumber":168,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.name(),"},{"lineNumber":169,"author":{"gitId":"mingyuanc"},"content":" };"},{"lineNumber":170,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":171,"author":{"gitId":"mingyuanc"},"content":" a \u003d getAction(submissionParams);"},{"lineNumber":172,"author":{"gitId":"mingyuanc"},"content":" r \u003d getJsonResult(a);"},{"lineNumber":173,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":174,"author":{"gitId":"mingyuanc"},"content":" output \u003d (SessionResultsData) r.getOutput();"},{"lineNumber":175,"author":{"gitId":"mingyuanc"},"content":" expectedResults \u003d SessionResultsData.initForStudent("},{"lineNumber":176,"author":{"gitId":"mingyuanc"},"content":" logic.getSessionResultsForUser(accessibleFeedbackSession,"},{"lineNumber":177,"author":{"gitId":"mingyuanc"},"content":" accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":178,"author":{"gitId":"mingyuanc"},"content":" student.getEmail(),"},{"lineNumber":179,"author":{"gitId":"mingyuanc"},"content":" false, question.getId(), false),"},{"lineNumber":180,"author":{"gitId":"mingyuanc"},"content":" student);"},{"lineNumber":181,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":182,"author":{"gitId":"mingyuanc"},"content":" assertTrue(isSessionResultsDataEqual(expectedResults, output));"},{"lineNumber":183,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":184,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":185,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":186,"author":{"gitId":"xenosf"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":187,"author":{"gitId":"xenosf"},"content":" String[] submissionParams;"},{"lineNumber":188,"author":{"gitId":"xenosf"},"content":" FeedbackSession publishedFeedbackSession \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":189,"author":{"gitId":"xenosf"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":190,"author":{"gitId":"xenosf"},"content":" FeedbackSession inaccessibleFeedbackSession \u003d typicalBundle.feedbackSessions.get("},{"lineNumber":191,"author":{"gitId":"xenosf"},"content":" \"unpublishedSession1InTypicalCourse\");"},{"lineNumber":192,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":193,"author":{"gitId":"xenosf"},"content":" ______TS(\"Inaccessible for authenticated instructor when unpublished\");"},{"lineNumber":194,"author":{"gitId":"xenosf"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":195,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, inaccessibleFeedbackSession.getName(),"},{"lineNumber":196,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, inaccessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":197,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.INSTRUCTOR_RESULT.name(),"},{"lineNumber":198,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":199,"author":{"gitId":"xenosf"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":200,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":201,"author":{"gitId":"xenosf"},"content":" ______TS(\"Inaccessible for authenticated student when unpublished\");"},{"lineNumber":202,"author":{"gitId":"xenosf"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":203,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, inaccessibleFeedbackSession.getName(),"},{"lineNumber":204,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, inaccessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":205,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.name(),"},{"lineNumber":206,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":207,"author":{"gitId":"xenosf"},"content":" Student student1InCourse1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":208,"author":{"gitId":"xenosf"},"content":" loginAsStudent(student1InCourse1.getGoogleId());"},{"lineNumber":209,"author":{"gitId":"xenosf"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":210,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":211,"author":{"gitId":"xenosf"},"content":" ______TS(\"Accessible for authenticated instructor when published\");"},{"lineNumber":212,"author":{"gitId":"xenosf"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":213,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, publishedFeedbackSession.getName(),"},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.INSTRUCTOR_RESULT.name(),"},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":217,"author":{"gitId":"xenosf"},"content":" verifyAccessibleForInstructorsOfTheSameCourse(course, submissionParams);"},{"lineNumber":218,"author":{"gitId":"xenosf"},"content":" verifyInaccessibleForInstructorsOfOtherCourses(course, submissionParams);"},{"lineNumber":219,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":220,"author":{"gitId":"xenosf"},"content":" ______TS(\"Accessible for authenticated student when published\");"},{"lineNumber":221,"author":{"gitId":"xenosf"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":222,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, publishedFeedbackSession.getName(),"},{"lineNumber":223,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":224,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.name(),"},{"lineNumber":225,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":226,"author":{"gitId":"xenosf"},"content":" verifyAccessibleForStudentsOfTheSameCourse(course, submissionParams);"},{"lineNumber":227,"author":{"gitId":"xenosf"},"content":" verifyInaccessibleForStudentsOfOtherCourse(course, submissionParams);"},{"lineNumber":228,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":229,"author":{"gitId":"xenosf"},"content":" ______TS(\"Invalid intent\");"},{"lineNumber":230,"author":{"gitId":"xenosf"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":231,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, publishedFeedbackSession.getName(),"},{"lineNumber":232,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, publishedFeedbackSession.getCourse().getId(),"},{"lineNumber":233,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.INSTRUCTOR_SUBMISSION.name(),"},{"lineNumber":234,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":235,"author":{"gitId":"xenosf"},"content":" verifyHttpParameterFailure(submissionParams);"},{"lineNumber":236,"author":{"gitId":"xenosf"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":237,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, publishedFeedbackSession.getName(),"},{"lineNumber":238,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, publishedFeedbackSession.getCourse().getId(),"},{"lineNumber":239,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_SUBMISSION.name(),"},{"lineNumber":240,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":241,"author":{"gitId":"xenosf"},"content":" verifyHttpParameterFailure(submissionParams);"},{"lineNumber":242,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":243,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":244,"author":{"gitId":"xenosf"},"content":" private boolean isSessionResultsDataEqual(SessionResultsData self, SessionResultsData other) {"},{"lineNumber":245,"author":{"gitId":"xenosf"},"content":" List\u003cSessionResultsData.QuestionOutput\u003e thisQuestions \u003d self.getQuestions();"},{"lineNumber":246,"author":{"gitId":"xenosf"},"content":" List\u003cSessionResultsData.QuestionOutput\u003e otherQuestions \u003d other.getQuestions();"},{"lineNumber":247,"author":{"gitId":"xenosf"},"content":" if (thisQuestions.size() !\u003d otherQuestions.size()) {"},{"lineNumber":248,"author":{"gitId":"xenosf"},"content":" return false;"},{"lineNumber":249,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":250,"author":{"gitId":"xenosf"},"content":" for (int i \u003d 0; i \u003c thisQuestions.size(); i++) {"},{"lineNumber":251,"author":{"gitId":"xenosf"},"content":" SessionResultsData.QuestionOutput thisQuestion \u003d thisQuestions.get(i);"},{"lineNumber":252,"author":{"gitId":"xenosf"},"content":" SessionResultsData.QuestionOutput otherQuestion \u003d otherQuestions.get(i);"},{"lineNumber":253,"author":{"gitId":"xenosf"},"content":" if (!isQuestionOutputEqual(thisQuestion, otherQuestion)) {"},{"lineNumber":254,"author":{"gitId":"xenosf"},"content":" return false;"},{"lineNumber":255,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":256,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":257,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":258,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":259,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":260,"author":{"gitId":"xenosf"},"content":" private boolean isQuestionOutputEqual(SessionResultsData.QuestionOutput self,"},{"lineNumber":261,"author":{"gitId":"xenosf"},"content":" SessionResultsData.QuestionOutput other) {"},{"lineNumber":262,"author":{"gitId":"xenosf"},"content":" if (!JsonUtils.toJson(self.getFeedbackQuestion()).equals(JsonUtils.toJson(other.getFeedbackQuestion()))"},{"lineNumber":263,"author":{"gitId":"xenosf"},"content":" || !self.getQuestionStatistics().equals(other.getQuestionStatistics())"},{"lineNumber":264,"author":{"gitId":"xenosf"},"content":" || self.getHasResponseButNotVisibleForPreview() !\u003d other.getHasResponseButNotVisibleForPreview()"},{"lineNumber":265,"author":{"gitId":"xenosf"},"content":" || self.getHasCommentNotVisibleForPreview() !\u003d other.getHasCommentNotVisibleForPreview()) {"},{"lineNumber":266,"author":{"gitId":"xenosf"},"content":" return false;"},{"lineNumber":267,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":268,"author":{"gitId":"xenosf"},"content":" List\u003cSessionResultsData.ResponseOutput\u003e thisResponses;"},{"lineNumber":269,"author":{"gitId":"xenosf"},"content":" List\u003cSessionResultsData.ResponseOutput\u003e otherResponses;"},{"lineNumber":270,"author":{"gitId":"xenosf"},"content":" thisResponses \u003d self.getAllResponses();"},{"lineNumber":271,"author":{"gitId":"xenosf"},"content":" otherResponses \u003d other.getAllResponses();"},{"lineNumber":272,"author":{"gitId":"xenosf"},"content":" if (thisResponses.size() !\u003d otherResponses.size()) {"},{"lineNumber":273,"author":{"gitId":"xenosf"},"content":" return false;"},{"lineNumber":274,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":275,"author":{"gitId":"xenosf"},"content":" for (int j \u003d 0; j \u003c thisResponses.size(); j++) {"},{"lineNumber":276,"author":{"gitId":"xenosf"},"content":" if (!isResponseOutputEqual(thisResponses.get(j), otherResponses.get(j))) {"},{"lineNumber":277,"author":{"gitId":"xenosf"},"content":" return false;"},{"lineNumber":278,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":279,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":280,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":281,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":282,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":283,"author":{"gitId":"xenosf"},"content":" private boolean isResponseOutputEqual(SessionResultsData.ResponseOutput self,"},{"lineNumber":284,"author":{"gitId":"xenosf"},"content":" SessionResultsData.ResponseOutput other) {"},{"lineNumber":285,"author":{"gitId":"xenosf"},"content":" return self.getGiver().equals(other.getGiver())"},{"lineNumber":286,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 self.getGiverTeam().equals(other.getGiverTeam())"},{"lineNumber":287,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 self.getGiverSection().equals(other.getGiverSection())"},{"lineNumber":288,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 self.getRecipient().equals(other.getRecipient())"},{"lineNumber":289,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 self.getRecipientTeam().equals(other.getRecipientTeam())"},{"lineNumber":290,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 self.getRecipientSection().equals(other.getRecipientSection())"},{"lineNumber":291,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 self.getResponseDetails().getJsonString().equals(other.getResponseDetails().getJsonString());"},{"lineNumber":292,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":293,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":294,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":295,"author":{"gitId":"xenosf"},"content":" public void testAccessControl_withoutCorrectAuthInfoAccessStudentResult_shouldFail() throws Exception {"},{"lineNumber":296,"author":{"gitId":"xenosf"},"content":" Course typicalCourse1 \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":297,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":298,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":299,"author":{"gitId":"xenosf"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":300,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, typicalCourse1.getId(),"},{"lineNumber":301,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSession.getName(),"},{"lineNumber":302,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.toString(),"},{"lineNumber":303,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":304,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":305,"author":{"gitId":"xenosf"},"content":" verifyInaccessibleForUnregisteredUsers(submissionParams);"},{"lineNumber":306,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":307,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":308,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":309,"author":{"gitId":"xenosf"},"content":" public void testAccessControl_studentAccessOwnCourseSessionResult_shouldPass() throws Exception {"},{"lineNumber":310,"author":{"gitId":"xenosf"},"content":" Student student1InCourse1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":311,"author":{"gitId":"xenosf"},"content":" Course typicalCourse1 \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":312,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":313,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":314,"author":{"gitId":"xenosf"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":315,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, typicalCourse1.getId(),"},{"lineNumber":316,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSession.getName(),"},{"lineNumber":317,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.toString(),"},{"lineNumber":318,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":319,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":320,"author":{"gitId":"xenosf"},"content":" loginAsStudent(student1InCourse1.getGoogleId());"},{"lineNumber":321,"author":{"gitId":"xenosf"},"content":" verifyCanAccess(submissionParams);"},{"lineNumber":322,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":323,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":324,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":325,"author":{"gitId":"xenosf"},"content":" public void testAccessControl_studentAccessUnpublishedSessionStudentResult_shouldFail() {"},{"lineNumber":326,"author":{"gitId":"xenosf"},"content":" Student student1InCourse1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":327,"author":{"gitId":"xenosf"},"content":" Course typicalCourse \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":328,"author":{"gitId":"xenosf"},"content":" FeedbackSession unpublishedFeedbackSession \u003d typicalBundle.feedbackSessions.get(\"session2InTypicalCourse\");"},{"lineNumber":329,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":330,"author":{"gitId":"xenosf"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":331,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, typicalCourse.getId(),"},{"lineNumber":332,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, unpublishedFeedbackSession.getName(),"},{"lineNumber":333,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.toString(),"},{"lineNumber":334,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":335,"author":{"gitId":"xenosf"},"content":" loginAsStudent(student1InCourse1.getGoogleId());"},{"lineNumber":336,"author":{"gitId":"xenosf"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":337,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":338,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":339,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":340,"author":{"gitId":"xenosf"},"content":" public void testAccessControl_accessStudentSessionResultWithMasqueradeMode_shouldPass() throws Exception {"},{"lineNumber":341,"author":{"gitId":"xenosf"},"content":" Student student1InCourse1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":342,"author":{"gitId":"xenosf"},"content":" Course typicalCourse1 \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":343,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":344,"author":{"gitId":"xenosf"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":345,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, typicalCourse1.getId(),"},{"lineNumber":346,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSession.getName(),"},{"lineNumber":347,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.toString(),"},{"lineNumber":348,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":349,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":350,"author":{"gitId":"xenosf"},"content":" loginAsAdmin();"},{"lineNumber":351,"author":{"gitId":"xenosf"},"content":" verifyCanMasquerade(student1InCourse1.getGoogleId(), submissionParams);"},{"lineNumber":352,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":353,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":354,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":355,"author":{"gitId":"xenosf"},"content":" public void testAccessControl_studentAccessOtherCourseSessionResult_shouldFail() {"},{"lineNumber":356,"author":{"gitId":"xenosf"},"content":" Student studentInOtherCourse \u003d typicalBundle.students.get(\"student2InCourse1\");"},{"lineNumber":357,"author":{"gitId":"xenosf"},"content":" Course otherCourse \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":358,"author":{"gitId":"xenosf"},"content":" Course course \u003d typicalBundle.courses.get(\"course3\");"},{"lineNumber":359,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession \u003d typicalBundle.feedbackSessions.get(\"ongoingSession1InCourse3\");"},{"lineNumber":360,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":361,"author":{"gitId":"xenosf"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":362,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":363,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSession.getName(),"},{"lineNumber":364,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.toString(),"},{"lineNumber":365,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":366,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":367,"author":{"gitId":"xenosf"},"content":" loginAsStudent(studentInOtherCourse.getGoogleId());"},{"lineNumber":368,"author":{"gitId":"xenosf"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":369,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":370,"author":{"gitId":"xenosf"},"content":" // Malicious api call using course Id of the student to bypass the check"},{"lineNumber":371,"author":{"gitId":"xenosf"},"content":" submissionParams[1] \u003d otherCourse.getId();"},{"lineNumber":372,"author":{"gitId":"xenosf"},"content":" verifyEntityNotFoundAcl(submissionParams);"},{"lineNumber":373,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":374,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":375,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":376,"author":{"gitId":"xenosf"},"content":" public void testAccessControl_instructorAccessHisCourseFullDetail_shouldPass() throws Exception {"},{"lineNumber":377,"author":{"gitId":"xenosf"},"content":" Course typicalCourse1 \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":378,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":379,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":380,"author":{"gitId":"xenosf"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":381,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, typicalCourse1.getId(),"},{"lineNumber":382,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSession.getName(),"},{"lineNumber":383,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.FULL_DETAIL.toString(),"},{"lineNumber":384,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":385,"author":{"gitId":"xenosf"},"content":" verifyOnlyInstructorsOfTheSameCourseCanAccess(typicalCourse1, submissionParams);"},{"lineNumber":386,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":387,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":388,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":361,"mingyuanc":27}},{"path":"src/it/java/teammates/it/ui/webapi/GetStudentsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.ui.output.StudentData;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.ui.output.StudentsData;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.GetStudentsAction;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * SUT: {@link GetStudentsAction}."},{"lineNumber":20,"author":{"gitId":"-"},"content":" */"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public class GetStudentsActionIT extends BaseActionIT\u003cGetStudentsAction\u003e {"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":24,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":25,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":27,"author":{"gitId":"-"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":28,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":32,"author":{"gitId":"-"},"content":" String getActionUri() {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" return Const.ResourceURIs.STUDENTS;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":37,"author":{"gitId":"-"},"content":" String getRequestMethod() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" return GET;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":42,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":43,"author":{"gitId":"-"},"content":" protected void testExecute() throws Exception {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":45,"author":{"gitId":"-"},"content":" Student student \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":46,"author":{"gitId":"-"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case with only course id, logged in as instructor\");"},{"lineNumber":51,"author":{"gitId":"-"},"content":" String[] params \u003d new String[] {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":53,"author":{"gitId":"-"},"content":" };"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" GetStudentsAction getStudentsAction \u003d getAction(params);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" JsonResult jsonResult \u003d getJsonResult(getStudentsAction);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" StudentsData response \u003d (StudentsData) jsonResult.getOutput();"},{"lineNumber":58,"author":{"gitId":"-"},"content":" List\u003cStudentData\u003e students \u003d response.getStudents();"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"marquestye"},"content":" assertEquals(5, students.size());"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" StudentData firstStudentInStudents \u003d students.get(0);"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" assertNull(firstStudentInStudents.getGoogleId());"},{"lineNumber":65,"author":{"gitId":"-"},"content":" assertNull(firstStudentInStudents.getKey());"},{"lineNumber":66,"author":{"gitId":"-"},"content":" assertEquals(student.getName(), firstStudentInStudents.getName());"},{"lineNumber":67,"author":{"gitId":"-"},"content":" assertEquals(student.getCourseId(), firstStudentInStudents.getCourseId());"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" logoutUser();"},{"lineNumber":70,"author":{"gitId":"-"},"content":" loginAsStudent(student.getGoogleId());"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case with course id and team name, logged in as student\");"},{"lineNumber":73,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":75,"author":{"gitId":"-"},"content":" Const.ParamsNames.TEAM_NAME, student.getTeamName(),"},{"lineNumber":76,"author":{"gitId":"-"},"content":" };"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" getStudentsAction \u003d getAction(params);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" jsonResult \u003d getJsonResult(getStudentsAction);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" response \u003d (StudentsData) jsonResult.getOutput();"},{"lineNumber":81,"author":{"gitId":"-"},"content":" students \u003d response.getStudents();"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" Student expectedOtherTeamMember \u003d typicalBundle.students.get(\"student2InCourse1\");"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" assertEquals(4, students.size());"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" StudentData actualOtherTeamMember \u003d students.get(1);"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" assertNull(actualOtherTeamMember.getGoogleId());"},{"lineNumber":90,"author":{"gitId":"-"},"content":" assertNull(actualOtherTeamMember.getKey());"},{"lineNumber":91,"author":{"gitId":"-"},"content":" assertEquals(expectedOtherTeamMember.getName(), actualOtherTeamMember.getName());"},{"lineNumber":92,"author":{"gitId":"-"},"content":" assertEquals(expectedOtherTeamMember.getCourseId(), actualOtherTeamMember.getCourseId());"},{"lineNumber":93,"author":{"gitId":"-"},"content":" }"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":96,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":97,"author":{"gitId":"-"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":99,"author":{"gitId":"-"},"content":" Student student \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":100,"author":{"gitId":"-"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" ______TS(\"Only instructors with correct privilege can access\");"},{"lineNumber":103,"author":{"gitId":"-"},"content":" String[] params \u003d new String[] {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":105,"author":{"gitId":"-"},"content":" };"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" verifyCanAccess(params);"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" ______TS(\"Student to view team members\");"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":114,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":115,"author":{"gitId":"-"},"content":" Const.ParamsNames.TEAM_NAME, student.getTeamName(),"},{"lineNumber":116,"author":{"gitId":"-"},"content":" };"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" loginAsStudent(student.getGoogleId());"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" verifyCanAccess(params);"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" ______TS(\"Unknown login entity\");"},{"lineNumber":123,"author":{"gitId":"-"},"content":" loginAsUnregistered(\"does-not-exist-id\");"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":126,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":127,"author":{"gitId":"-"},"content":" };"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":133,"author":{"gitId":"-"},"content":" Const.ParamsNames.TEAM_NAME, student.getTeamName(),"},{"lineNumber":134,"author":{"gitId":"-"},"content":" };"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":1,"dishenggg":1,"-":137}},{"path":"src/it/java/teammates/it/ui/webapi/InstructorSearchIndexingWorkerActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"mingyuanc"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":3,"author":{"gitId":"mingyuanc"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":5,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":6,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":8,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":9,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":10,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.util.Const;"},{"lineNumber":11,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":12,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":13,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":14,"author":{"gitId":"mingyuanc"},"content":"import teammates.test.TestProperties;"},{"lineNumber":15,"author":{"gitId":"mingyuanc"},"content":"import teammates.ui.webapi.InstructorSearchIndexingWorkerAction;"},{"lineNumber":16,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":17,"author":{"gitId":"mingyuanc"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"mingyuanc"},"content":" * SUT: {@link InstructorSearchIndexingWorkerAction}."},{"lineNumber":19,"author":{"gitId":"mingyuanc"},"content":" */"},{"lineNumber":20,"author":{"gitId":"mingyuanc"},"content":"public class InstructorSearchIndexingWorkerActionIT extends BaseActionIT\u003cInstructorSearchIndexingWorkerAction\u003e {"},{"lineNumber":21,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":22,"author":{"gitId":"mingyuanc"},"content":" @BeforeMethod"},{"lineNumber":23,"author":{"gitId":"mingyuanc"},"content":" protected void setUp() throws Exception {"},{"lineNumber":24,"author":{"gitId":"mingyuanc"},"content":" super.setUp();"},{"lineNumber":25,"author":{"gitId":"mingyuanc"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":26,"author":{"gitId":"mingyuanc"},"content":" HibernateUtil.flushSession();"},{"lineNumber":27,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":28,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":29,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":30,"author":{"gitId":"mingyuanc"},"content":" protected String getActionUri() {"},{"lineNumber":31,"author":{"gitId":"mingyuanc"},"content":" return Const.TaskQueue.INSTRUCTOR_SEARCH_INDEXING_WORKER_URL;"},{"lineNumber":32,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":33,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":34,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":35,"author":{"gitId":"mingyuanc"},"content":" protected String getRequestMethod() {"},{"lineNumber":36,"author":{"gitId":"mingyuanc"},"content":" return POST;"},{"lineNumber":37,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":38,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":39,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":40,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":41,"author":{"gitId":"mingyuanc"},"content":" public void testExecute() throws Exception {"},{"lineNumber":42,"author":{"gitId":"mingyuanc"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":43,"author":{"gitId":"mingyuanc"},"content":" return;"},{"lineNumber":44,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":45,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":46,"author":{"gitId":"mingyuanc"},"content":" Instructor instructor1 \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":47,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":48,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"instructor not yet indexed should not be searchable\");"},{"lineNumber":49,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":50,"author":{"gitId":"mingyuanc"},"content":" List\u003cInstructor\u003e instructorList \u003d logic.searchInstructorsInWholeSystem(instructor1.getEmail());"},{"lineNumber":51,"author":{"gitId":"mingyuanc"},"content":" assertEquals(0, instructorList.size());"},{"lineNumber":52,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":53,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"instructor indexed should be searchable\");"},{"lineNumber":54,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":55,"author":{"gitId":"mingyuanc"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":56,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.COURSE_ID, instructor1.getCourseId(),"},{"lineNumber":57,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.INSTRUCTOR_EMAIL, instructor1.getEmail(),"},{"lineNumber":58,"author":{"gitId":"mingyuanc"},"content":" };"},{"lineNumber":59,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":60,"author":{"gitId":"mingyuanc"},"content":" InstructorSearchIndexingWorkerAction action \u003d getAction(submissionParams);"},{"lineNumber":61,"author":{"gitId":"mingyuanc"},"content":" getJsonResult(action);"},{"lineNumber":62,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":63,"author":{"gitId":"mingyuanc"},"content":" instructorList \u003d logic.searchInstructorsInWholeSystem(instructor1.getEmail());"},{"lineNumber":64,"author":{"gitId":"mingyuanc"},"content":" assertEquals(1, instructorList.size());"},{"lineNumber":65,"author":{"gitId":"mingyuanc"},"content":" assertEquals(instructor1.getId(), instructorList.get(0).getId());"},{"lineNumber":66,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":67,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":68,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":69,"author":{"gitId":"mingyuanc"},"content":" protected void testAccessControl() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":70,"author":{"gitId":"mingyuanc"},"content":" Instructor instructor1 \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":71,"author":{"gitId":"mingyuanc"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":72,"author":{"gitId":"mingyuanc"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":73,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.COURSE_ID, instructor1.getCourseId(),"},{"lineNumber":74,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.INSTRUCTOR_EMAIL, instructor1.getEmail(),"},{"lineNumber":75,"author":{"gitId":"mingyuanc"},"content":" };"},{"lineNumber":76,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":77,"author":{"gitId":"mingyuanc"},"content":" verifyOnlyAdminCanAccess(course, submissionParams);"},{"lineNumber":78,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":79,"author":{"gitId":"mingyuanc"},"content":"}"}],"authorContributionMap":{"mingyuanc":79}},{"path":"src/it/java/teammates/it/ui/webapi/JoinCourseActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"yuanxi1"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":3,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":4,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.Test;"},{"lineNumber":5,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":6,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.Const;"},{"lineNumber":7,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.EmailType;"},{"lineNumber":8,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":9,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":10,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":11,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":12,"author":{"gitId":"yuanxi1"},"content":"import teammates.ui.webapi.InvalidOperationException;"},{"lineNumber":13,"author":{"gitId":"yuanxi1"},"content":"import teammates.ui.webapi.JoinCourseAction;"},{"lineNumber":14,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":15,"author":{"gitId":"yuanxi1"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"yuanxi1"},"content":" * SUT: {@link JoinCourseAction}."},{"lineNumber":17,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":18,"author":{"gitId":"yuanxi1"},"content":"public class JoinCourseActionIT extends BaseActionIT\u003cJoinCourseAction\u003e {"},{"lineNumber":19,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":20,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":21,"author":{"gitId":"yuanxi1"},"content":" @BeforeMethod"},{"lineNumber":22,"author":{"gitId":"yuanxi1"},"content":" protected void setUp() throws Exception {"},{"lineNumber":23,"author":{"gitId":"yuanxi1"},"content":" super.setUp();"},{"lineNumber":24,"author":{"gitId":"yuanxi1"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":25,"author":{"gitId":"yuanxi1"},"content":" HibernateUtil.flushSession();"},{"lineNumber":26,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":27,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":28,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":29,"author":{"gitId":"yuanxi1"},"content":" String getActionUri() {"},{"lineNumber":30,"author":{"gitId":"yuanxi1"},"content":" return Const.ResourceURIs.JOIN;"},{"lineNumber":31,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":32,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":33,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":34,"author":{"gitId":"yuanxi1"},"content":" String getRequestMethod() {"},{"lineNumber":35,"author":{"gitId":"yuanxi1"},"content":" return PUT;"},{"lineNumber":36,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":37,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":38,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":39,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":40,"author":{"gitId":"yuanxi1"},"content":" protected void testExecute() throws Exception {"},{"lineNumber":41,"author":{"gitId":"yuanxi1"},"content":" Student studentYetToJoinCourse \u003d typicalBundle.students.get(\"student2YetToJoinCourse4\");"},{"lineNumber":42,"author":{"gitId":"yuanxi1"},"content":" String student1RegKey \u003d"},{"lineNumber":43,"author":{"gitId":"yuanxi1"},"content":" getRegKeyForStudent(studentYetToJoinCourse.getCourseId(), studentYetToJoinCourse.getEmail());"},{"lineNumber":44,"author":{"gitId":"yuanxi1"},"content":" String loggedInGoogleIdStu \u003d \"AccLogicT.student.id\";"},{"lineNumber":45,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":46,"author":{"gitId":"yuanxi1"},"content":" Instructor instructorYetToJoinCourse \u003d typicalBundle.instructors.get(\"instructor2YetToJoinCourse4\");"},{"lineNumber":47,"author":{"gitId":"yuanxi1"},"content":" String instructor1RegKey \u003d"},{"lineNumber":48,"author":{"gitId":"yuanxi1"},"content":" getRegKeyForInstructor(instructorYetToJoinCourse.getCourseId(), instructorYetToJoinCourse.getEmail());"},{"lineNumber":49,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":50,"author":{"gitId":"yuanxi1"},"content":" String loggedInGoogleIdInst \u003d \"AccLogicT.instr.id\";"},{"lineNumber":51,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":52,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: student joins course\");"},{"lineNumber":53,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":54,"author":{"gitId":"yuanxi1"},"content":" loginAsUnregistered(loggedInGoogleIdStu);"},{"lineNumber":55,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":56,"author":{"gitId":"yuanxi1"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":57,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.REGKEY, student1RegKey,"},{"lineNumber":58,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.STUDENT,"},{"lineNumber":59,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":60,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":61,"author":{"gitId":"yuanxi1"},"content":" JoinCourseAction joinCourseAction \u003d getAction(submissionParams);"},{"lineNumber":62,"author":{"gitId":"yuanxi1"},"content":" getJsonResult(joinCourseAction);"},{"lineNumber":63,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":64,"author":{"gitId":"yuanxi1"},"content":" verifyNumberOfEmailsSent(1);"},{"lineNumber":65,"author":{"gitId":"yuanxi1"},"content":" EmailWrapper email \u003d mockEmailSender.getEmailsSent().get(0);"},{"lineNumber":66,"author":{"gitId":"yuanxi1"},"content":" assertEquals("},{"lineNumber":67,"author":{"gitId":"yuanxi1"},"content":" String.format(EmailType.USER_COURSE_REGISTER.getSubject(), \"Typical Course 4\", \"course-4\"),"},{"lineNumber":68,"author":{"gitId":"yuanxi1"},"content":" email.getSubject());"},{"lineNumber":69,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":70,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: student is already registered\");"},{"lineNumber":71,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":72,"author":{"gitId":"yuanxi1"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":73,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.REGKEY, student1RegKey,"},{"lineNumber":74,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.STUDENT,"},{"lineNumber":75,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":76,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":77,"author":{"gitId":"yuanxi1"},"content":" InvalidOperationException ioe \u003d verifyInvalidOperation(submissionParams);"},{"lineNumber":78,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"Student has already joined course\", ioe.getMessage());"},{"lineNumber":79,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":80,"author":{"gitId":"yuanxi1"},"content":" verifyNoEmailsSent();"},{"lineNumber":81,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":82,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: instructor joins course\");"},{"lineNumber":83,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":84,"author":{"gitId":"yuanxi1"},"content":" loginAsUnregistered(loggedInGoogleIdInst);"},{"lineNumber":85,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":86,"author":{"gitId":"yuanxi1"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":87,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.REGKEY, instructor1RegKey,"},{"lineNumber":88,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":89,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":90,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":91,"author":{"gitId":"yuanxi1"},"content":" joinCourseAction \u003d getAction(submissionParams);"},{"lineNumber":92,"author":{"gitId":"yuanxi1"},"content":" getJsonResult(joinCourseAction);"},{"lineNumber":93,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":94,"author":{"gitId":"yuanxi1"},"content":" verifyNumberOfEmailsSent(1);"},{"lineNumber":95,"author":{"gitId":"yuanxi1"},"content":" email \u003d mockEmailSender.getEmailsSent().get(0);"},{"lineNumber":96,"author":{"gitId":"yuanxi1"},"content":" assertEquals("},{"lineNumber":97,"author":{"gitId":"yuanxi1"},"content":" String.format(EmailType.USER_COURSE_REGISTER.getSubject(), \"Typical Course 4\", \"course-4\"),"},{"lineNumber":98,"author":{"gitId":"yuanxi1"},"content":" email.getSubject());"},{"lineNumber":99,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":100,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: instructor is already registered\");"},{"lineNumber":101,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":102,"author":{"gitId":"yuanxi1"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":103,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.REGKEY, instructor1RegKey,"},{"lineNumber":104,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":105,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":106,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":107,"author":{"gitId":"yuanxi1"},"content":" ioe \u003d verifyInvalidOperation(submissionParams);"},{"lineNumber":108,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"Instructor has already joined course\", ioe.getMessage());"},{"lineNumber":109,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":110,"author":{"gitId":"yuanxi1"},"content":" verifyNoEmailsSent();"},{"lineNumber":111,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":112,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: invalid regkey\");"},{"lineNumber":113,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":114,"author":{"gitId":"yuanxi1"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":115,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.REGKEY, \"ANXKJZNZXNJCZXKJDNKSDA\","},{"lineNumber":116,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.STUDENT,"},{"lineNumber":117,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":118,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":119,"author":{"gitId":"yuanxi1"},"content":" verifyEntityNotFound(submissionParams);"},{"lineNumber":120,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":121,"author":{"gitId":"yuanxi1"},"content":" verifyNoEmailsSent();"},{"lineNumber":122,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":123,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: invalid entity type\");"},{"lineNumber":124,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":125,"author":{"gitId":"yuanxi1"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":126,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.REGKEY, student1RegKey,"},{"lineNumber":127,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, \"invalid_entity_type\","},{"lineNumber":128,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":129,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":130,"author":{"gitId":"yuanxi1"},"content":" verifyHttpParameterFailure(submissionParams);"},{"lineNumber":131,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":132,"author":{"gitId":"yuanxi1"},"content":" verifyNoEmailsSent();"},{"lineNumber":133,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":134,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":135,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":136,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":137,"author":{"gitId":"yuanxi1"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":138,"author":{"gitId":"yuanxi1"},"content":" verifyAnyLoggedInUserCanAccess();"},{"lineNumber":139,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":140,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":141,"author":{"gitId":"yuanxi1"},"content":" private String getRegKeyForStudent(String courseId, String email) {"},{"lineNumber":142,"author":{"gitId":"yuanxi1"},"content":" return logic.getStudentForEmail(courseId, email).getRegKey();"},{"lineNumber":143,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":144,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":145,"author":{"gitId":"yuanxi1"},"content":" private String getRegKeyForInstructor(String courseId, String email) {"},{"lineNumber":146,"author":{"gitId":"yuanxi1"},"content":" return logic.getInstructorForEmail(courseId, email).getRegKey();"},{"lineNumber":147,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":148,"author":{"gitId":"yuanxi1"},"content":"}"}],"authorContributionMap":{"yuanxi1":148}},{"path":"src/it/java/teammates/it/ui/webapi/RejectAccountRequestActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import java.util.UUID;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.AfterMethod;"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":"import org.testng.annotations.Test;"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Config;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const;"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.EmailType;"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":"import teammates.ui.output.AccountRequestData;"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":"import teammates.ui.request.AccountRequestRejectionRequest;"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":"import teammates.ui.webapi.EntityNotFoundException;"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":"import teammates.ui.webapi.InvalidHttpParameterException;"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":"import teammates.ui.webapi.InvalidOperationException;"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":"import teammates.ui.webapi.RejectAccountRequestAction;"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" * SUT: {@link RejectAccountRequestAction}."},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":"public class RejectAccountRequestActionIT extends BaseActionIT\u003cRejectAccountRequestAction\u003e {"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" private static final String TYPICAL_TITLE \u003d \"We are Unable to Create an Account for you\";"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" private static final String TYPICAL_BODY \u003d new StringBuilder()"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003eHi, Example\u003c/p\u003e\\n\")"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003eThanks for your interest in using TEAMMATES. \")"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" .append(\"We are unable to create a TEAMMATES instructor account for you.\u003c/p\u003e\\n\\n\")"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003e\\n\")"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" .append(\" \u003cstrong\u003eReason:\u003c/strong\u003e The email address you provided \")"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" .append(\"is not an \u0027official\u0027 email address provided by your institution.\u003cbr /\u003e\\n\")"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" .append(\" \u003cstrong\u003eRemedy:\u003c/strong\u003e \")"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" .append(\"Please re-submit an account request with your \u0027official\u0027 institution email address.\\n\")"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" .append(\"\u003c/p\u003e\\n\\n\")"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003eIf you need further clarification or would like to appeal this decision, \")"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" .append(\"please feel free to contact us at teammates@comp.nus.edu.sg.\u003c/p\u003e\\n\")"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003eRegards,\u003cbr /\u003eTEAMMATES Team.\u003c/p\u003e\\n\")"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" .toString();"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" @BeforeMethod"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" protected void setUp() throws Exception {"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" // no need to call super.setUp() because the action handles its own transactions"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" protected String getActionUri() {"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" return Const.ResourceURIs.ACCOUNT_REQUEST_REJECTION;"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" protected String getRequestMethod() {"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" return POST;"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":67,"author":{"gitId":"xenosf"},"content":" public void testExecute() throws Exception {"},{"lineNumber":68,"author":{"gitId":"xenosf"},"content":" // See individual test methods below"},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" protected void testExecute_withReasonTitleAndBody_shouldRejectWithEmail()"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" throws InvalidOperationException, InvalidHttpRequestBodyException, InvalidParametersException {"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" AccountRequest bundleAccountRequest \u003d typicalBundle.accountRequests.get(\"unregisteredInstructor1\");"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d logic.createAccountRequestWithTransaction(bundleAccountRequest.getName(),"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" bundleAccountRequest.getEmail(), bundleAccountRequest.getInstitute(),"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" AccountRequestStatus.PENDING, bundleAccountRequest.getComments());"},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" UUID id \u003d accountRequest.getId();"},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest requestBody \u003d new AccountRequestRejectionRequest(TYPICAL_TITLE, TYPICAL_BODY);"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":" String[] params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" RejectAccountRequestAction action \u003d getAction(requestBody, params);"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":" JsonResult result \u003d action.execute();"},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":" assertEquals(200, result.getStatusCode());"},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" AccountRequestData data \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getName(), data.getName());"},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getEmail(), data.getEmail());"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getInstitute(), data.getInstitute());"},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":" assertEquals(AccountRequestStatus.REJECTED, data.getStatus());"},{"lineNumber":93,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getComments(), data.getComments());"},{"lineNumber":94,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":" verifyNumberOfEmailsSent(1);"},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":" EmailWrapper sentEmail \u003d mockEmailSender.getEmailsSent().get(0);"},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" assertEquals(EmailType.ACCOUNT_REQUEST_REJECTION, sentEmail.getType());"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" assertEquals(Config.SUPPORT_EMAIL, sentEmail.getBcc());"},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getEmail(), sentEmail.getRecipient());"},{"lineNumber":100,"author":{"gitId":"xenosf"},"content":" assertEquals(SanitizationHelper.sanitizeForRichText(TYPICAL_BODY), sentEmail.getContent());"},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":" assertEquals(\"TEAMMATES: \" + TYPICAL_TITLE, sentEmail.getSubject());"},{"lineNumber":102,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":103,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":104,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":105,"author":{"gitId":"xenosf"},"content":" protected void testExecute_withoutReasonTitleAndBody_shouldRejectWithoutEmail()"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" throws InvalidOperationException, InvalidHttpRequestBodyException, InvalidParametersException {"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" AccountRequest bundleAccountRequest \u003d typicalBundle.accountRequests.get(\"unregisteredInstructor1\");"},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d logic.createAccountRequestWithTransaction(bundleAccountRequest.getName(),"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" bundleAccountRequest.getEmail(), bundleAccountRequest.getInstitute(),"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" AccountRequestStatus.PENDING, bundleAccountRequest.getComments());"},{"lineNumber":111,"author":{"gitId":"xenosf"},"content":" UUID id \u003d accountRequest.getId();"},{"lineNumber":112,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":113,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest requestBody \u003d new AccountRequestRejectionRequest(null, null);"},{"lineNumber":114,"author":{"gitId":"xenosf"},"content":" String[] params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":115,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" RejectAccountRequestAction action \u003d getAction(requestBody, params);"},{"lineNumber":117,"author":{"gitId":"xenosf"},"content":" JsonResult result \u003d action.execute();"},{"lineNumber":118,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":119,"author":{"gitId":"xenosf"},"content":" assertEquals(200, result.getStatusCode());"},{"lineNumber":120,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":121,"author":{"gitId":"xenosf"},"content":" AccountRequestData data \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":122,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getName(), data.getName());"},{"lineNumber":123,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getEmail(), data.getEmail());"},{"lineNumber":124,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getInstitute(), data.getInstitute());"},{"lineNumber":125,"author":{"gitId":"xenosf"},"content":" assertEquals(AccountRequestStatus.REJECTED, data.getStatus());"},{"lineNumber":126,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getComments(), data.getComments());"},{"lineNumber":127,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":128,"author":{"gitId":"xenosf"},"content":" verifyNoEmailsSent();"},{"lineNumber":129,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":130,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":131,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":" protected void testExecute_withReasonBodyButNoTitle_shouldThrow() throws InvalidParametersException {"},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" AccountRequest bundleAccountRequest \u003d typicalBundle.accountRequests.get(\"unregisteredInstructor1\");"},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d logic.createAccountRequestWithTransaction(bundleAccountRequest.getName(),"},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":" bundleAccountRequest.getEmail(), bundleAccountRequest.getInstitute(),"},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" bundleAccountRequest.getStatus(), bundleAccountRequest.getComments());"},{"lineNumber":137,"author":{"gitId":"xenosf"},"content":" UUID id \u003d accountRequest.getId();"},{"lineNumber":138,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":139,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest requestBody \u003d new AccountRequestRejectionRequest(null, TYPICAL_BODY);"},{"lineNumber":140,"author":{"gitId":"xenosf"},"content":" String[] params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":141,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":142,"author":{"gitId":"xenosf"},"content":" InvalidHttpRequestBodyException ihrbe \u003d verifyHttpRequestBodyFailure(requestBody, params);"},{"lineNumber":143,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":144,"author":{"gitId":"xenosf"},"content":" assertEquals(\"Both reason body and title need to be null to reject silently\", ihrbe.getMessage());"},{"lineNumber":145,"author":{"gitId":"xenosf"},"content":" verifyNoEmailsSent();"},{"lineNumber":146,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":147,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":148,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":149,"author":{"gitId":"domoberzin"},"content":" protected void testExecute_withReasonTitleButNoBody_shouldThrow() throws InvalidParametersException {"},{"lineNumber":150,"author":{"gitId":"domoberzin"},"content":" AccountRequest bundleAccountRequest \u003d typicalBundle.accountRequests.get(\"unregisteredInstructor1\");"},{"lineNumber":151,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d logic.createAccountRequestWithTransaction(bundleAccountRequest.getName(),"},{"lineNumber":152,"author":{"gitId":"domoberzin"},"content":" bundleAccountRequest.getEmail(), bundleAccountRequest.getInstitute(),"},{"lineNumber":153,"author":{"gitId":"domoberzin"},"content":" bundleAccountRequest.getStatus(), bundleAccountRequest.getComments());"},{"lineNumber":154,"author":{"gitId":"xenosf"},"content":" UUID id \u003d accountRequest.getId();"},{"lineNumber":155,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":156,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest requestBody \u003d new AccountRequestRejectionRequest(TYPICAL_TITLE, null);"},{"lineNumber":157,"author":{"gitId":"xenosf"},"content":" String[] params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":158,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":159,"author":{"gitId":"xenosf"},"content":" InvalidHttpRequestBodyException ihrbe \u003d verifyHttpRequestBodyFailure(requestBody, params);"},{"lineNumber":160,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":161,"author":{"gitId":"xenosf"},"content":" assertEquals(\"Both reason body and title need to be null to reject silently\", ihrbe.getMessage());"},{"lineNumber":162,"author":{"gitId":"xenosf"},"content":" verifyNoEmailsSent();"},{"lineNumber":163,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":164,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":165,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":166,"author":{"gitId":"xenosf"},"content":" protected void testExecute_alreadyRejected_shouldNotSendEmail()"},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" throws InvalidOperationException, InvalidHttpRequestBodyException, InvalidParametersException {"},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":" AccountRequest bundleAccountRequest \u003d typicalBundle.accountRequests.get(\"unregisteredInstructor1\");"},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d logic.createAccountRequestWithTransaction(bundleAccountRequest.getName(),"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" bundleAccountRequest.getEmail(), bundleAccountRequest.getInstitute(),"},{"lineNumber":171,"author":{"gitId":"domoberzin"},"content":" AccountRequestStatus.REJECTED, bundleAccountRequest.getComments());"},{"lineNumber":172,"author":{"gitId":"xenosf"},"content":" UUID id \u003d accountRequest.getId();"},{"lineNumber":173,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":174,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest requestBody \u003d new AccountRequestRejectionRequest(TYPICAL_TITLE, TYPICAL_BODY);"},{"lineNumber":175,"author":{"gitId":"xenosf"},"content":" String[] params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":176,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":177,"author":{"gitId":"xenosf"},"content":" RejectAccountRequestAction action \u003d getAction(requestBody, params);"},{"lineNumber":178,"author":{"gitId":"xenosf"},"content":" JsonResult result \u003d action.execute();"},{"lineNumber":179,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":180,"author":{"gitId":"xenosf"},"content":" assertEquals(result.getStatusCode(), 200);"},{"lineNumber":181,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":182,"author":{"gitId":"xenosf"},"content":" AccountRequestData data \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":183,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getName(), data.getName());"},{"lineNumber":184,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getEmail(), data.getEmail());"},{"lineNumber":185,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getInstitute(), data.getInstitute());"},{"lineNumber":186,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getStatus(), data.getStatus());"},{"lineNumber":187,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getComments(), data.getComments());"},{"lineNumber":188,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":189,"author":{"gitId":"xenosf"},"content":" verifyNoEmailsSent();"},{"lineNumber":190,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":191,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":192,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":" protected void testExecute_invalidUuid_shouldThrow() throws InvalidParametersException {"},{"lineNumber":194,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest requestBody \u003d new AccountRequestRejectionRequest(null, null);"},{"lineNumber":195,"author":{"gitId":"xenosf"},"content":" String[] params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, \"invalid\"};"},{"lineNumber":196,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":197,"author":{"gitId":"xenosf"},"content":" InvalidHttpParameterException ihpe \u003d verifyHttpParameterFailure(requestBody, params);"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"Expected UUID value for id parameter, but found: [invalid]\", ihpe.getMessage());"},{"lineNumber":199,"author":{"gitId":"xenosf"},"content":" verifyNoEmailsSent();"},{"lineNumber":200,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":201,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":202,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":203,"author":{"gitId":"xenosf"},"content":" protected void testExecute_accountRequestNotFound_shouldThrow() {"},{"lineNumber":204,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest requestBody \u003d new AccountRequestRejectionRequest(null, null);"},{"lineNumber":205,"author":{"gitId":"xenosf"},"content":" String uuid \u003d UUID.randomUUID().toString();"},{"lineNumber":206,"author":{"gitId":"xenosf"},"content":" String[] params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, uuid};"},{"lineNumber":207,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":208,"author":{"gitId":"xenosf"},"content":" EntityNotFoundException enfe \u003d verifyEntityNotFound(requestBody, params);"},{"lineNumber":209,"author":{"gitId":"xenosf"},"content":" assertEquals(String.format(\"Account request with id \u003d %s not found\", uuid), enfe.getMessage());"},{"lineNumber":210,"author":{"gitId":"xenosf"},"content":" verifyNoEmailsSent();"},{"lineNumber":211,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":212,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":213,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" protected void testAccessControl() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":216,"author":{"gitId":"domoberzin"},"content":" verifyOnlyAdminCanAccessWithTransaction();"},{"lineNumber":217,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":218,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":219,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":220,"author":{"gitId":"domoberzin"},"content":" @AfterMethod"},{"lineNumber":221,"author":{"gitId":"domoberzin"},"content":" protected void tearDown() {"},{"lineNumber":222,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":223,"author":{"gitId":"domoberzin"},"content":" List\u003cAccountRequest\u003e accountRequests \u003d logic.getAllAccountRequests();"},{"lineNumber":224,"author":{"gitId":"domoberzin"},"content":" for (AccountRequest ar : accountRequests) {"},{"lineNumber":225,"author":{"gitId":"-"},"content":" logic.deleteAccountRequest(ar.getId());"},{"lineNumber":226,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":227,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":228,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":229,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"domoberzin":41,"xenosf":187,"-":1}},{"path":"src/it/java/teammates/it/ui/webapi/SearchAccountRequestsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.Test;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.Const;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import teammates.test.TestProperties;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.output.AccountRequestsData;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.output.MessageOutput;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.SearchAccountRequestsAction;"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" * SUT: {@link SearchAccountRequestsAction}."},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":"public class SearchAccountRequestsActionIT extends BaseActionIT\u003cSearchAccountRequestsAction\u003e {"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" protected void testAccessControl() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" verifyOnlyAdminCanAccess(course);"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" @BeforeMethod"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" protected void setUp() throws Exception {"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" super.setUp();"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" putDocuments(typicalBundle);"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.flushSession();"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" protected String getActionUri() {"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" return Const.ResourceURIs.SEARCH_ACCOUNT_REQUESTS;"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" protected String getRequestMethod() {"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" return GET;"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" protected void testExecute() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Search with SearchService disabled\");"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" String[] submissionParams \u003d new String[] { Const.ParamsNames.SEARCH_KEY, \"randomString123\" };"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" SearchAccountRequestsAction action \u003d getAction(submissionParams);"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" JsonResult result \u003d getJsonResult(action, HttpStatus.SC_NOT_IMPLEMENTED);"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" MessageOutput output \u003d (MessageOutput) result.getOutput();"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"Full-text search is not available.\", output.getMessage());"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" return;"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d typicalBundle.accountRequests.get(\"instructor1\");"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" loginAsAdmin();"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Search via Email\");"},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" String[] submissionParams \u003d new String[] { Const.ParamsNames.SEARCH_KEY, accountRequest.getEmail() };"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":" SearchAccountRequestsAction action \u003d getAction(submissionParams);"},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" JsonResult result \u003d getJsonResult(action, 200);"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" AccountRequestsData response \u003d (AccountRequestsData) result.getOutput();"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" assertTrue(response.getAccountRequests().stream()"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" .filter(i -\u003e i.getName().equals(accountRequest.getName()))"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" .findAny()"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" .isPresent());"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" assertTrue(response.getAccountRequests().get(0).getRegistrationKey() !\u003d null);"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Search via Institute\");"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" submissionParams \u003d new String[] { Const.ParamsNames.SEARCH_KEY, accountRequest.getInstitute() };"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" action \u003d getAction(submissionParams);"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" result \u003d getJsonResult(action, 200);"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" response \u003d (AccountRequestsData) result.getOutput();"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" assertTrue(response.getAccountRequests().stream()"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" .filter(i -\u003e i.getName().equals(accountRequest.getName()))"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" .findAny()"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" .isPresent());"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":" assertTrue(response.getAccountRequests().get(0).getRegistrationKey() !\u003d null);"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Search via Name\");"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" submissionParams \u003d new String[] { Const.ParamsNames.SEARCH_KEY, accountRequest.getName() };"},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" action \u003d getAction(submissionParams);"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" result \u003d getJsonResult(action, 200);"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" response \u003d (AccountRequestsData) result.getOutput();"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":" assertTrue(response.getAccountRequests().stream()"},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":" .filter(i -\u003e i.getName().equals(accountRequest.getName()))"},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" .findAny()"},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" .isPresent());"},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":" assertTrue(response.getAccountRequests().get(0).getRegistrationKey() !\u003d null);"},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Search Duplicate Name\");"},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":" submissionParams \u003d new String[] { Const.ParamsNames.SEARCH_KEY, \"Instructor\" };"},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" action \u003d getAction(submissionParams);"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" result \u003d getJsonResult(action, 200);"},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":" response \u003d (AccountRequestsData) result.getOutput();"},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" assertTrue(response.getAccountRequests().get(0).getRegistrationKey() !\u003d null);"},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" assertEquals(11, response.getAccountRequests().size());"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Search result with 0 matches\");"},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" submissionParams \u003d new String[] { Const.ParamsNames.SEARCH_KEY, \"randomString123\" };"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" action \u003d getAction(submissionParams);"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" result \u003d getJsonResult(action, 200);"},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" response \u003d (AccountRequestsData) result.getOutput();"},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" assertEquals(0, response.getAccountRequests().size());"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":115}},{"path":"src/it/java/teammates/it/ui/webapi/SearchStudentsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"yuanxi1"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":3,"author":{"gitId":"yuanxi1"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":4,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":5,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.Test;"},{"lineNumber":6,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":7,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":8,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":9,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.Const;"},{"lineNumber":10,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":11,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":12,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":13,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":14,"author":{"gitId":"yuanxi1"},"content":"import teammates.test.TestProperties;"},{"lineNumber":15,"author":{"gitId":"yuanxi1"},"content":"import teammates.ui.output.MessageOutput;"},{"lineNumber":16,"author":{"gitId":"yuanxi1"},"content":"import teammates.ui.output.StudentsData;"},{"lineNumber":17,"author":{"gitId":"yuanxi1"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":18,"author":{"gitId":"yuanxi1"},"content":"import teammates.ui.webapi.SearchStudentsAction;"},{"lineNumber":19,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":20,"author":{"gitId":"yuanxi1"},"content":"/**"},{"lineNumber":21,"author":{"gitId":"yuanxi1"},"content":" * SUT: {@link SearchStudentsAction}."},{"lineNumber":22,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":23,"author":{"gitId":"yuanxi1"},"content":"public class SearchStudentsActionIT extends BaseActionIT\u003cSearchStudentsAction\u003e {"},{"lineNumber":24,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":25,"author":{"gitId":"yuanxi1"},"content":" private final Student student1InCourse1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":26,"author":{"gitId":"yuanxi1"},"content":" private final Instructor instructor1OfCourse1 \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":27,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":28,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":29,"author":{"gitId":"yuanxi1"},"content":" @BeforeMethod"},{"lineNumber":30,"author":{"gitId":"yuanxi1"},"content":" protected void setUp() throws Exception {"},{"lineNumber":31,"author":{"gitId":"yuanxi1"},"content":" super.setUp();"},{"lineNumber":32,"author":{"gitId":"yuanxi1"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":33,"author":{"gitId":"yuanxi1"},"content":" putDocuments(typicalBundle);"},{"lineNumber":34,"author":{"gitId":"yuanxi1"},"content":" HibernateUtil.flushSession();"},{"lineNumber":35,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":36,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":37,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"yuanxi1"},"content":" protected String getActionUri() {"},{"lineNumber":39,"author":{"gitId":"yuanxi1"},"content":" return Const.ResourceURIs.SEARCH_STUDENTS;"},{"lineNumber":40,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":41,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":42,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":43,"author":{"gitId":"yuanxi1"},"content":" protected String getRequestMethod() {"},{"lineNumber":44,"author":{"gitId":"yuanxi1"},"content":" return GET;"},{"lineNumber":45,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":46,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":47,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":48,"author":{"gitId":"yuanxi1"},"content":" protected void testExecute() {"},{"lineNumber":49,"author":{"gitId":"yuanxi1"},"content":" // See test cases below."},{"lineNumber":50,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":51,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":52,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":53,"author":{"gitId":"yuanxi1"},"content":" public void execute_invalidParameters_parameterFailure() {"},{"lineNumber":54,"author":{"gitId":"yuanxi1"},"content":" loginAsAdmin();"},{"lineNumber":55,"author":{"gitId":"yuanxi1"},"content":" verifyHttpParameterFailure();"},{"lineNumber":56,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":57,"author":{"gitId":"yuanxi1"},"content":" String[] notEnoughParams \u003d new String[] {"},{"lineNumber":58,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, \"dummy\","},{"lineNumber":59,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":60,"author":{"gitId":"yuanxi1"},"content":" verifyHttpParameterFailure(notEnoughParams);"},{"lineNumber":61,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":62,"author":{"gitId":"yuanxi1"},"content":" String[] invalidEntityParams \u003d new String[] {"},{"lineNumber":63,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, \"dummy\","},{"lineNumber":64,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, \"dummy\","},{"lineNumber":65,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":66,"author":{"gitId":"yuanxi1"},"content":" verifyHttpParameterFailure(invalidEntityParams);"},{"lineNumber":67,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":68,"author":{"gitId":"yuanxi1"},"content":" String[] adminParams \u003d new String[] {"},{"lineNumber":69,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, \"dummy\","},{"lineNumber":70,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.ADMIN,"},{"lineNumber":71,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":72,"author":{"gitId":"yuanxi1"},"content":" String[] instructorParams \u003d new String[] {"},{"lineNumber":73,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, \"dummy\","},{"lineNumber":74,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":75,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":76,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":77,"author":{"gitId":"yuanxi1"},"content":" loginAsAdmin();"},{"lineNumber":78,"author":{"gitId":"yuanxi1"},"content":" verifyHttpParameterFailure(instructorParams);"},{"lineNumber":79,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":80,"author":{"gitId":"yuanxi1"},"content":" loginAsInstructor(instructor1OfCourse1.getGoogleId());"},{"lineNumber":81,"author":{"gitId":"yuanxi1"},"content":" verifyHttpParameterFailure(adminParams);"},{"lineNumber":82,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":83,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":84,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":85,"author":{"gitId":"yuanxi1"},"content":" public void execute_adminSearchName_success() {"},{"lineNumber":86,"author":{"gitId":"yuanxi1"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":87,"author":{"gitId":"yuanxi1"},"content":" return;"},{"lineNumber":88,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":89,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":90,"author":{"gitId":"yuanxi1"},"content":" loginAsAdmin();"},{"lineNumber":91,"author":{"gitId":"yuanxi1"},"content":" String[] accNameParams \u003d new String[] {"},{"lineNumber":92,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, student1InCourse1.getName(),"},{"lineNumber":93,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.ADMIN,"},{"lineNumber":94,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":95,"author":{"gitId":"yuanxi1"},"content":" SearchStudentsAction a \u003d getAction(accNameParams);"},{"lineNumber":96,"author":{"gitId":"yuanxi1"},"content":" JsonResult result \u003d getJsonResult(a);"},{"lineNumber":97,"author":{"gitId":"yuanxi1"},"content":" StudentsData response \u003d (StudentsData) result.getOutput();"},{"lineNumber":98,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":99,"author":{"gitId":"marquestye"},"content":" assertEquals(11, response.getStudents().size());"},{"lineNumber":100,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":101,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":102,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":103,"author":{"gitId":"yuanxi1"},"content":" public void execute_adminSearchCourseId_success() {"},{"lineNumber":104,"author":{"gitId":"yuanxi1"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":105,"author":{"gitId":"yuanxi1"},"content":" return;"},{"lineNumber":106,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":107,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":108,"author":{"gitId":"yuanxi1"},"content":" loginAsAdmin();"},{"lineNumber":109,"author":{"gitId":"yuanxi1"},"content":" String[] accCourseIdParams \u003d new String[] {"},{"lineNumber":110,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, student1InCourse1.getCourseId(),"},{"lineNumber":111,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.ADMIN,"},{"lineNumber":112,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":113,"author":{"gitId":"yuanxi1"},"content":" SearchStudentsAction a \u003d getAction(accCourseIdParams);"},{"lineNumber":114,"author":{"gitId":"yuanxi1"},"content":" JsonResult result \u003d getJsonResult(a);"},{"lineNumber":115,"author":{"gitId":"yuanxi1"},"content":" StudentsData response \u003d (StudentsData) result.getOutput();"},{"lineNumber":116,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":117,"author":{"gitId":"marquestye"},"content":" assertEquals(11, response.getStudents().size());"},{"lineNumber":118,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":119,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":120,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":121,"author":{"gitId":"yuanxi1"},"content":" public void execute_adminSearchEmail_success() {"},{"lineNumber":122,"author":{"gitId":"yuanxi1"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":123,"author":{"gitId":"yuanxi1"},"content":" return;"},{"lineNumber":124,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":125,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":126,"author":{"gitId":"yuanxi1"},"content":" loginAsAdmin();"},{"lineNumber":127,"author":{"gitId":"yuanxi1"},"content":" String[] emailParams \u003d new String[] {"},{"lineNumber":128,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, student1InCourse1.getEmail(),"},{"lineNumber":129,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.ADMIN,"},{"lineNumber":130,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":131,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":132,"author":{"gitId":"yuanxi1"},"content":" SearchStudentsAction a \u003d getAction(emailParams);"},{"lineNumber":133,"author":{"gitId":"yuanxi1"},"content":" JsonResult result \u003d getJsonResult(a);"},{"lineNumber":134,"author":{"gitId":"yuanxi1"},"content":" StudentsData response \u003d (StudentsData) result.getOutput();"},{"lineNumber":135,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" assertEquals(4, response.getStudents().size());"},{"lineNumber":137,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":138,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":139,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":140,"author":{"gitId":"yuanxi1"},"content":" public void execute_adminSearchNoMatch_noMatch() {"},{"lineNumber":141,"author":{"gitId":"yuanxi1"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":142,"author":{"gitId":"yuanxi1"},"content":" return;"},{"lineNumber":143,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":144,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":145,"author":{"gitId":"yuanxi1"},"content":" loginAsAdmin();"},{"lineNumber":146,"author":{"gitId":"yuanxi1"},"content":" String[] accNameParams \u003d new String[] {"},{"lineNumber":147,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, \"minuscoronavirus\","},{"lineNumber":148,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.ADMIN,"},{"lineNumber":149,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":150,"author":{"gitId":"yuanxi1"},"content":" SearchStudentsAction a \u003d getAction(accNameParams);"},{"lineNumber":151,"author":{"gitId":"yuanxi1"},"content":" JsonResult result \u003d getJsonResult(a);"},{"lineNumber":152,"author":{"gitId":"yuanxi1"},"content":" StudentsData response \u003d (StudentsData) result.getOutput();"},{"lineNumber":153,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":154,"author":{"gitId":"yuanxi1"},"content":" assertEquals(0, response.getStudents().size());"},{"lineNumber":155,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":156,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":157,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":158,"author":{"gitId":"yuanxi1"},"content":" public void execute_instructorSearchGoogleId_matchOnlyStudentsInCourse() {"},{"lineNumber":159,"author":{"gitId":"yuanxi1"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":160,"author":{"gitId":"yuanxi1"},"content":" return;"},{"lineNumber":161,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":162,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":163,"author":{"gitId":"yuanxi1"},"content":" loginAsInstructor(instructor1OfCourse1.getGoogleId());"},{"lineNumber":164,"author":{"gitId":"yuanxi1"},"content":" String[] googleIdParams \u003d new String[] {"},{"lineNumber":165,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, \"student1\","},{"lineNumber":166,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":167,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":168,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":169,"author":{"gitId":"yuanxi1"},"content":" SearchStudentsAction a \u003d getAction(googleIdParams);"},{"lineNumber":170,"author":{"gitId":"yuanxi1"},"content":" JsonResult result \u003d getJsonResult(a);"},{"lineNumber":171,"author":{"gitId":"yuanxi1"},"content":" StudentsData response \u003d (StudentsData) result.getOutput();"},{"lineNumber":172,"author":{"gitId":"-"},"content":" assertEquals(3, response.getStudents().size());"},{"lineNumber":173,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":174,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":175,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":176,"author":{"gitId":"yuanxi1"},"content":" public void execute_noSearchService_shouldReturn501() {"},{"lineNumber":177,"author":{"gitId":"yuanxi1"},"content":" if (TestProperties.isSearchServiceActive()) {"},{"lineNumber":178,"author":{"gitId":"yuanxi1"},"content":" return;"},{"lineNumber":179,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":180,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":181,"author":{"gitId":"yuanxi1"},"content":" loginAsInstructor(instructor1OfCourse1.getGoogleId());"},{"lineNumber":182,"author":{"gitId":"yuanxi1"},"content":" String[] params \u003d new String[] {"},{"lineNumber":183,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, \"anything\","},{"lineNumber":184,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":185,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":186,"author":{"gitId":"yuanxi1"},"content":" SearchStudentsAction a \u003d getAction(params);"},{"lineNumber":187,"author":{"gitId":"yuanxi1"},"content":" JsonResult result \u003d getJsonResult(a, HttpStatus.SC_NOT_IMPLEMENTED);"},{"lineNumber":188,"author":{"gitId":"yuanxi1"},"content":" MessageOutput output \u003d (MessageOutput) result.getOutput();"},{"lineNumber":189,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":190,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"Full-text search is not available.\", output.getMessage());"},{"lineNumber":191,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":192,"author":{"gitId":"yuanxi1"},"content":" loginAsAdmin();"},{"lineNumber":193,"author":{"gitId":"yuanxi1"},"content":" params \u003d new String[] {"},{"lineNumber":194,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, \"anything\","},{"lineNumber":195,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.ADMIN,"},{"lineNumber":196,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":197,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":198,"author":{"gitId":"yuanxi1"},"content":" a \u003d getAction(params);"},{"lineNumber":199,"author":{"gitId":"yuanxi1"},"content":" result \u003d getJsonResult(a, HttpStatus.SC_NOT_IMPLEMENTED);"},{"lineNumber":200,"author":{"gitId":"yuanxi1"},"content":" output \u003d (MessageOutput) result.getOutput();"},{"lineNumber":201,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":202,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"Full-text search is not available.\", output.getMessage());"},{"lineNumber":203,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":204,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":205,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":206,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":207,"author":{"gitId":"yuanxi1"},"content":" protected void testAccessControl() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":208,"author":{"gitId":"yuanxi1"},"content":" verifyAccessibleForAdmin();"},{"lineNumber":209,"author":{"gitId":"yuanxi1"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":210,"author":{"gitId":"yuanxi1"},"content":" verifyOnlyInstructorsCanAccess(course);"},{"lineNumber":211,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":212,"author":{"gitId":"yuanxi1"},"content":"}"}],"authorContributionMap":{"yuanxi1":208,"marquestye":2,"-":2}},{"path":"src/it/java/teammates/it/ui/webapi/StudentSearchIndexingWorkerActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const.ParamsNames;"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const.TaskQueue;"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlsearch.SearchManagerFactory;"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":"import teammates.test.TestProperties;"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":"import teammates.ui.webapi.StudentSearchIndexingWorkerAction;"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" * SUT: {@link StudentSearchIndexingWorkerAction}."},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":"public class StudentSearchIndexingWorkerActionIT extends BaseActionIT\u003cStudentSearchIndexingWorkerAction\u003e {"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" private final Student student \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" @BeforeMethod"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" protected void setUp() throws Exception {"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" super.setUp();"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" HibernateUtil.flushSession();"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" SearchManagerFactory.getStudentSearchManager().resetCollections();"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" protected String getActionUri() {"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" return TaskQueue.STUDENT_SEARCH_INDEXING_WORKER_URL;"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" protected String getRequestMethod() {"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" return POST;"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" protected void testExecute() throws Exception {"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" // See test cases below"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" protected void testExecute_studentNotYetIndexed_shouldNotBeSearchable() throws Exception {"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" return;"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" List\u003cStudent\u003e studentList \u003d logic.searchStudentsInWholeSystem(student.getEmail());"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" assertEquals(0, studentList.size());"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" protected void testExecute_studentIndexed_shouldBeSearchable() throws Exception {"},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" return;"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":67,"author":{"gitId":"xenosf"},"content":" ParamsNames.COURSE_ID, student.getCourseId(),"},{"lineNumber":68,"author":{"gitId":"xenosf"},"content":" ParamsNames.STUDENT_EMAIL, student.getEmail(),"},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" StudentSearchIndexingWorkerAction action \u003d getAction(submissionParams);"},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" getJsonResult(action);"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" List\u003cStudent\u003e studentList \u003d logic.searchStudentsInWholeSystem(student.getEmail());"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" assertEquals(1, studentList.size());"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" assertEquals(student.getName(), studentList.get(0).getName());"},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":" protected void testAccessControl() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" verifyOnlyAdminCanAccess(course);"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":85}},{"path":"src/it/java/teammates/it/ui/webapi/UpdateAccountRequestActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import java.util.UUID;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.AfterMethod;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.Test;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.Const;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.StringHelperExtension;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.output.AccountRequestData;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.request.AccountRequestUpdateRequest;"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.EntityNotFoundException;"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.InvalidHttpParameterException;"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.InvalidOperationException;"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.UpdateAccountRequestAction;"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" * SUT: {@link UpdateAccountRequestAction}."},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":"public class UpdateAccountRequestActionIT extends BaseActionIT\u003cUpdateAccountRequestAction\u003e {"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" @BeforeMethod"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" protected void setUp() throws Exception {"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" // no need to call super.setUp() because the action handles its own transactions"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" protected String getActionUri() {"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" return Const.ResourceURIs.ACCOUNT_REQUEST;"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" protected String getRequestMethod() {"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" return PUT;"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" public void testExecute() throws Exception {"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" ______TS(\"edit fields of an account request\");"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d logic.createAccountRequestWithTransaction(\"name\", \"email@email.com\","},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" UUID id \u003d accountRequest.getId();"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" String name \u003d \"newName\";"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" String email \u003d \"newEmail@email.com\";"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" String institute \u003d \"newInstitute\";"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" String comments \u003d \"newComments\";"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" AccountRequestStatus status \u003d accountRequest.getStatus();"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" AccountRequestUpdateRequest requestBody \u003d new AccountRequestUpdateRequest(name, email, institute, status, comments);"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" String[] params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" UpdateAccountRequestAction action \u003d getAction(requestBody, params);"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":" JsonResult result \u003d action.execute();"},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":" assertEquals(result.getStatusCode(), 200);"},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" AccountRequestData data \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" assertEquals(name, data.getName());"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" assertEquals(email, data.getEmail());"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" assertEquals(institute, data.getInstitute());"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" assertEquals(status, data.getStatus());"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" assertEquals(comments, data.getComments());"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" verifyNoEmailsSent();"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" ______TS(\"approve a pending account request\");"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d logic.createAccountRequestWithTransaction(\"name\", \"email@email.com\","},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(accountRequest.getName(), accountRequest.getEmail(),"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" accountRequest.getInstitute(), AccountRequestStatus.APPROVED, accountRequest.getComments());"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, accountRequest.getId().toString()};"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" action \u003d getAction(requestBody, params);"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" result \u003d getJsonResult(action, 200);"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":" data \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" assertEquals(accountRequest.getName(), data.getName());"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" assertEquals(accountRequest.getEmail(), data.getEmail());"},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" assertEquals(accountRequest.getInstitute(), data.getInstitute());"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" assertEquals(AccountRequestStatus.APPROVED, data.getStatus());"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" assertEquals(accountRequest.getComments(), data.getComments());"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":" verifyNumberOfEmailsSent(1);"},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" ______TS(\"already registered account request has no email sent when approved\");"},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d logic.createAccountRequestWithTransaction(\"name\", \"email@email.com\","},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":" \"institute\", AccountRequestStatus.REGISTERED, \"comments\");"},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(name, email, institute, AccountRequestStatus.APPROVED, comments);"},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, accountRequest.getId().toString()};"},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" action \u003d getAction(requestBody, params);"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" result \u003d getJsonResult(action, 200);"},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":" data \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" assertEquals(name, data.getName());"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" assertEquals(email, data.getEmail());"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" assertEquals(institute, data.getInstitute());"},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" assertEquals(AccountRequestStatus.REGISTERED, data.getStatus());"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" assertEquals(comments, data.getComments());"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" verifyNumberOfEmailsSent(0);"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" ______TS(\"email with existing account throws exception\");"},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" Account account \u003d logic.createAccountWithTransaction(getTypicalAccount());"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d logic.createAccountRequestWithTransaction(\"name\", account.getEmail(),"},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(name, email, institute, AccountRequestStatus.APPROVED, comments);"},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, accountRequest.getId().toString()};"},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" InvalidOperationException ipe \u003d verifyInvalidOperation(requestBody, params);"},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":" assertEquals(String.format(\"An account with email %s already exists. \""},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" + \"Please reject or delete the account request instead.\", account.getEmail()), ipe.getMessage());"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" ______TS(\"non-existent but valid uuid\");"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(\"name\", \"email\","},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" String validUuid \u003d UUID.randomUUID().toString();"},{"lineNumber":128,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, validUuid};"},{"lineNumber":129,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":" EntityNotFoundException enfe \u003d verifyEntityNotFound(requestBody, params);"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":" assertEquals(String.format(\"Account request with id \u003d %s not found\", validUuid), enfe.getMessage());"},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" ______TS(\"invalid uuid\");"},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(\"name\", \"email\","},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":137,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, \"invalid\"};"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":" InvalidHttpParameterException ihpe \u003d verifyHttpParameterFailure(requestBody, params);"},{"lineNumber":140,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"Expected UUID value for id parameter, but found: [invalid]\", ihpe.getMessage());"},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":" ______TS(\"invalid email\");"},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d logic.createAccountRequestWithTransaction(\"name\", \"email@email.com\","},{"lineNumber":145,"author":{"gitId":"domoberzin"},"content":" \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":" id \u003d accountRequest.getId();"},{"lineNumber":147,"author":{"gitId":"domoberzin"},"content":" email \u003d \"newEmail\";"},{"lineNumber":148,"author":{"gitId":"domoberzin"},"content":" status \u003d accountRequest.getStatus();"},{"lineNumber":149,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":150,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(name, email, institute, status, comments);"},{"lineNumber":151,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":152,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":153,"author":{"gitId":"domoberzin"},"content":" InvalidHttpRequestBodyException ihrbe \u003d verifyHttpRequestBodyFailure(requestBody, params);"},{"lineNumber":154,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":155,"author":{"gitId":"domoberzin"},"content":" assertEquals(getPopulatedErrorMessage(FieldValidator.EMAIL_ERROR_MESSAGE, email,"},{"lineNumber":156,"author":{"gitId":"domoberzin"},"content":" FieldValidator.EMAIL_FIELD_NAME, FieldValidator.REASON_INCORRECT_FORMAT, FieldValidator.EMAIL_MAX_LENGTH),"},{"lineNumber":157,"author":{"gitId":"domoberzin"},"content":" ihrbe.getMessage());"},{"lineNumber":158,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":159,"author":{"gitId":"domoberzin"},"content":" ______TS(\"invalid name alphanumeric\");"},{"lineNumber":160,"author":{"gitId":"domoberzin"},"content":" name \u003d \"@$@#$#@#@$#@$\";"},{"lineNumber":161,"author":{"gitId":"domoberzin"},"content":" email \u003d \"newEmail@email.com\";"},{"lineNumber":162,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":163,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(name, email, institute, status, comments);"},{"lineNumber":164,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":165,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":" ihrbe \u003d verifyHttpRequestBodyFailure(requestBody, params);"},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":" assertEquals(getPopulatedErrorMessage(FieldValidator.INVALID_NAME_ERROR_MESSAGE, name,"},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" FieldValidator.PERSON_NAME_FIELD_NAME, FieldValidator.REASON_START_WITH_NON_ALPHANUMERIC_CHAR),"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" ihrbe.getMessage());"},{"lineNumber":171,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":172,"author":{"gitId":"domoberzin"},"content":" ______TS(\"invalid name too long\");"},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":" name \u003d StringHelperExtension.generateStringOfLength(FieldValidator.PERSON_NAME_MAX_LENGTH + 1);"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(name, email, institute, status, comments);"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":" ihrbe \u003d verifyHttpRequestBodyFailure(requestBody, params);"},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" assertEquals(getPopulatedErrorMessage(FieldValidator.SIZE_CAPPED_NON_EMPTY_STRING_ERROR_MESSAGE, name,"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":" FieldValidator.PERSON_NAME_FIELD_NAME, FieldValidator.REASON_TOO_LONG,"},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":" FieldValidator.PERSON_NAME_MAX_LENGTH), ihrbe.getMessage());"},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":184,"author":{"gitId":"domoberzin"},"content":" ______TS(\"null email value\");"},{"lineNumber":185,"author":{"gitId":"domoberzin"},"content":" name \u003d \"newName\";"},{"lineNumber":186,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":187,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(name, null, institute, status, comments);"},{"lineNumber":188,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":189,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":190,"author":{"gitId":"domoberzin"},"content":" ihrbe \u003d verifyHttpRequestBodyFailure(requestBody, params);"},{"lineNumber":191,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":192,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"email cannot be null\", ihrbe.getMessage());"},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" ______TS(\"null name value\");"},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(null, email, institute, status, comments);"},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" ihrbe \u003d verifyHttpRequestBodyFailure(requestBody, params);"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":200,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"name cannot be null\", ihrbe.getMessage());"},{"lineNumber":201,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":202,"author":{"gitId":"domoberzin"},"content":" ______TS(\"null status value\");"},{"lineNumber":203,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(name, email, institute, null, comments);"},{"lineNumber":204,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":205,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":206,"author":{"gitId":"domoberzin"},"content":" ihrbe \u003d verifyHttpRequestBodyFailure(requestBody, params);"},{"lineNumber":207,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":208,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"status cannot be null\", ihrbe.getMessage());"},{"lineNumber":209,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":210,"author":{"gitId":"domoberzin"},"content":" ______TS(\"null institute value\");"},{"lineNumber":211,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(name, email, null, status, comments);"},{"lineNumber":212,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":213,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":214,"author":{"gitId":"domoberzin"},"content":" ihrbe \u003d verifyHttpRequestBodyFailure(requestBody, params);"},{"lineNumber":215,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":216,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"institute cannot be null\", ihrbe.getMessage());"},{"lineNumber":217,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":218,"author":{"gitId":"domoberzin"},"content":" ______TS(\"allow null comments in request\");"},{"lineNumber":219,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(name, email, institute, status, null);"},{"lineNumber":220,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":221,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":222,"author":{"gitId":"domoberzin"},"content":" action \u003d getAction(requestBody, params);"},{"lineNumber":223,"author":{"gitId":"domoberzin"},"content":" result \u003d getJsonResult(action, 200);"},{"lineNumber":224,"author":{"gitId":"domoberzin"},"content":" data \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":225,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":226,"author":{"gitId":"domoberzin"},"content":" assertEquals(name, data.getName());"},{"lineNumber":227,"author":{"gitId":"domoberzin"},"content":" assertEquals(email, data.getEmail());"},{"lineNumber":228,"author":{"gitId":"domoberzin"},"content":" assertEquals(institute, data.getInstitute());"},{"lineNumber":229,"author":{"gitId":"domoberzin"},"content":" assertEquals(null, data.getComments());"},{"lineNumber":230,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":231,"author":{"gitId":"domoberzin"},"content":" ______TS(\"email with approved account request throws exception\");"},{"lineNumber":232,"author":{"gitId":"domoberzin"},"content":" logic.createAccountRequestWithTransaction(\"test\", \"test@email.com\","},{"lineNumber":233,"author":{"gitId":"domoberzin"},"content":" \"institute\", AccountRequestStatus.APPROVED, \"comments\");"},{"lineNumber":234,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d logic.createAccountRequestWithTransaction(\"test\", \"test@email.com\","},{"lineNumber":235,"author":{"gitId":"domoberzin"},"content":" \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":236,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(accountRequest.getName(), accountRequest.getEmail(),"},{"lineNumber":237,"author":{"gitId":"domoberzin"},"content":" accountRequest.getInstitute(), AccountRequestStatus.APPROVED, comments);"},{"lineNumber":238,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, accountRequest.getId().toString()};"},{"lineNumber":239,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":240,"author":{"gitId":"domoberzin"},"content":" ipe \u003d verifyInvalidOperation(requestBody, params);"},{"lineNumber":241,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":242,"author":{"gitId":"domoberzin"},"content":" assertEquals(String.format(\"An account request with email %s has already been approved. \""},{"lineNumber":243,"author":{"gitId":"domoberzin"},"content":" + \"Please reject or delete the account request instead.\", accountRequest.getEmail()), ipe.getMessage());"},{"lineNumber":244,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":245,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":246,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":247,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":248,"author":{"gitId":"domoberzin"},"content":" protected void testAccessControl() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":249,"author":{"gitId":"domoberzin"},"content":" verifyOnlyAdminCanAccessWithTransaction();"},{"lineNumber":250,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":251,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":252,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":253,"author":{"gitId":"domoberzin"},"content":" @AfterMethod"},{"lineNumber":254,"author":{"gitId":"domoberzin"},"content":" protected void tearDown() {"},{"lineNumber":255,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":256,"author":{"gitId":"domoberzin"},"content":" List\u003cAccountRequest\u003e accountRequests \u003d logic.getAllAccountRequests();"},{"lineNumber":257,"author":{"gitId":"domoberzin"},"content":" for (AccountRequest ar : accountRequests) {"},{"lineNumber":258,"author":{"gitId":"dishenggg"},"content":" logic.deleteAccountRequest(ar.getId());"},{"lineNumber":259,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":260,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":261,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":262,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":261,"dishenggg":1}},{"path":"src/it/java/teammates/it/ui/webapi/UpdateFeedbackSessionLogsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.time.temporal.ChronoUnit;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Const;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlsearch.SearchManagerFactory;"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.webapi.UpdateFeedbackSessionLogsAction;"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link UpdateFeedbackSessionLogsAction}."},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":"public class UpdateFeedbackSessionLogsActionIT extends BaseActionIT\u003cUpdateFeedbackSessionLogsAction\u003e {"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" static final long COLLECTION_TIME_PERIOD \u003d Const.STUDENT_ACTIVITY_LOGS_UPDATE_INTERVAL.toMinutes();"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" static final long SPAM_FILTER \u003d Const.STUDENT_ACTIVITY_LOGS_FILTER_WINDOW.toMillis();"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" Student student1InCourse1;"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" Student student2InCourse1;"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" Student student1InCourse3;"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" Course course1;"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" Course course3;"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" FeedbackSession session1InCourse1;"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" FeedbackSession session2InCourse1;"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" FeedbackSession session1InCourse3;"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" Instant endTime;"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" Instant startTime;"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" @BeforeMethod"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" protected void setUp() throws Exception {"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" super.setUp();"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" HibernateUtil.flushSession();"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" SearchManagerFactory.getStudentSearchManager().resetCollections();"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" endTime \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.now());"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" startTime \u003d endTime.minus(COLLECTION_TIME_PERIOD, ChronoUnit.MINUTES);"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" course1 \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" course3 \u003d typicalBundle.courses.get(\"course3\");"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" student1InCourse1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" student2InCourse1 \u003d typicalBundle.students.get(\"student2InCourse1\");"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" student1InCourse3 \u003d typicalBundle.students.get(\"student1InCourse3\");"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" session1InCourse1 \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" session2InCourse1 \u003d typicalBundle.feedbackSessions.get(\"session2InTypicalCourse\");"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" session1InCourse3 \u003d typicalBundle.feedbackSessions.get(\"ongoingSession1InCourse3\");"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.getOrderedFeedbackSessionLogs(\"\", \"\", 0, 0, \"\").clear();"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" String getActionUri() {"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" return Const.CronJobURIs.AUTOMATED_FEEDBACK_SESSION_LOGS_PROCESSING;"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" String getRequestMethod() {"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" return GET;"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" protected void testExecute() {"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" ______TS(\"No spam all logs added\");"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" // Different Types"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(100).toEpochMilli());"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(100).toEpochMilli());"},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.VIEW_RESULT.getLabel(),"},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(100).toEpochMilli());"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" // Different feedback sessions"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(200).toEpochMilli());"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":" session2InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(200).toEpochMilli());"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" // Different Student"},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(300).toEpochMilli());"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student2InCourse1.getId(),"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(300).toEpochMilli());"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":" // Different course"},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(400).toEpochMilli());"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course3.getId(), student1InCourse3.getId(),"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" session1InCourse3.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(400).toEpochMilli());"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" // Gap is larger than spam filter"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(), startTime.toEpochMilli());"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" startTime.plusMillis(SPAM_FILTER + 1).toEpochMilli());"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" UpdateFeedbackSessionLogsAction action \u003d getAction();"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":" getJsonResult(action);"},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":" // method returns all logs regardless of params"},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntry\u003e expected \u003d mockLogsProcessor.getOrderedFeedbackSessionLogs(\"\", \"\", 0, 0, \"\");"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e actual \u003d logic.getOrderedFeedbackSessionLogs(course1.getId(), null, null, startTime,"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" endTime);"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e actualCourse3 \u003d logic.getOrderedFeedbackSessionLogs(course3.getId(), null, null,"},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":" startTime, endTime);"},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" actual.addAll(actualCourse3);"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":" assertTrue(isEqual(expected, actual));"},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":141,"author":{"gitId":"dishenggg"},"content":" protected void testExecute_recentLogsWithSpam_someLogsCreated() {"},{"lineNumber":142,"author":{"gitId":"dishenggg"},"content":" // Gap is smaller than spam filter"},{"lineNumber":143,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":144,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(), startTime.toEpochMilli());"},{"lineNumber":145,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":146,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":" startTime.plusMillis(SPAM_FILTER - 2).toEpochMilli());"},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":" // Filters multiple logs within one spam window"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":" startTime.plusMillis(SPAM_FILTER - 1).toEpochMilli());"},{"lineNumber":153,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":" // Correctly adds new log after filtering"},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":" startTime.plusMillis(SPAM_FILTER + 1).toEpochMilli());"},{"lineNumber":158,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":159,"author":{"gitId":"dishenggg"},"content":" // Filters out spam in the new window"},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":161,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":162,"author":{"gitId":"dishenggg"},"content":" startTime.plusMillis(SPAM_FILTER + 2).toEpochMilli());"},{"lineNumber":163,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":164,"author":{"gitId":"dishenggg"},"content":" UpdateFeedbackSessionLogsAction action \u003d getAction();"},{"lineNumber":165,"author":{"gitId":"dishenggg"},"content":" action.execute();"},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":167,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntry\u003e expected \u003d new ArrayList\u003c\u003e();"},{"lineNumber":168,"author":{"gitId":"dishenggg"},"content":" expected.add(new FeedbackSessionLogEntry(course1.getId(), student1InCourse1.getId(), session1InCourse1.getId(),"},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.toEpochMilli()));"},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" expected.add(new FeedbackSessionLogEntry(course1.getId(), student1InCourse1.getId(), session1InCourse1.getId(),"},{"lineNumber":171,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusMillis(SPAM_FILTER + 1).toEpochMilli()));"},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e actual \u003d logic.getOrderedFeedbackSessionLogs(course1.getId(), null, null, startTime,"},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":" endTime);"},{"lineNumber":175,"author":{"gitId":"dishenggg"},"content":" assertTrue(isEqual(expected, actual));"},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":179,"author":{"gitId":"dishenggg"},"content":" protected void testExecute_badLogs_otherLogsCreated() {"},{"lineNumber":180,"author":{"gitId":"dishenggg"},"content":" UUID badUuid \u003d UUID.fromString(\"00000000-0000-0000-0000-000000000000\");"},{"lineNumber":181,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":182,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(100).toEpochMilli());"},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":185,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":186,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(300).toEpochMilli());"},{"lineNumber":187,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":188,"author":{"gitId":"dishenggg"},"content":" // bad student id"},{"lineNumber":189,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), badUuid, session1InCourse1.getId(),"},{"lineNumber":190,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(200).toEpochMilli());"},{"lineNumber":191,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":192,"author":{"gitId":"dishenggg"},"content":" // bad session id"},{"lineNumber":193,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(), badUuid,"},{"lineNumber":194,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(200).toEpochMilli());"},{"lineNumber":195,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":196,"author":{"gitId":"dishenggg"},"content":" UpdateFeedbackSessionLogsAction action \u003d getAction();"},{"lineNumber":197,"author":{"gitId":"dishenggg"},"content":" action.execute();"},{"lineNumber":198,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":199,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntry\u003e expected \u003d new ArrayList\u003c\u003e();"},{"lineNumber":200,"author":{"gitId":"dishenggg"},"content":" expected.add(new FeedbackSessionLogEntry(course1.getId(), student1InCourse1.getId(), session1InCourse1.getId(),"},{"lineNumber":201,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(100).toEpochMilli()));"},{"lineNumber":202,"author":{"gitId":"dishenggg"},"content":" expected.add(new FeedbackSessionLogEntry(course1.getId(), student1InCourse1.getId(), session1InCourse1.getId(),"},{"lineNumber":203,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(300).toEpochMilli()));"},{"lineNumber":204,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":205,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e actual \u003d logic.getOrderedFeedbackSessionLogs(course1.getId(), null, null, startTime,"},{"lineNumber":206,"author":{"gitId":"dishenggg"},"content":" endTime);"},{"lineNumber":207,"author":{"gitId":"dishenggg"},"content":" assertTrue(isEqual(expected, actual));"},{"lineNumber":208,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":209,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":210,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":211,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":212,"author":{"gitId":"dishenggg"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":213,"author":{"gitId":"dishenggg"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":214,"author":{"gitId":"dishenggg"},"content":" verifyOnlyAdminCanAccess(course);"},{"lineNumber":215,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":216,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":217,"author":{"gitId":"dishenggg"},"content":" private Boolean isEqual(List\u003cFeedbackSessionLogEntry\u003e expected, List\u003cFeedbackSessionLog\u003e actual) {"},{"lineNumber":218,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":219,"author":{"gitId":"dishenggg"},"content":" assertEquals(expected.size(), actual.size());"},{"lineNumber":220,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":221,"author":{"gitId":"dishenggg"},"content":" for (int i \u003d 0; i \u003c expected.size(); i++) {"},{"lineNumber":222,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogEntry expectedEntry \u003d expected.get(i);"},{"lineNumber":223,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog actualLog \u003d actual.get(i);"},{"lineNumber":224,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":225,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedEntry.getStudentId(), actualLog.getStudent().getId());"},{"lineNumber":226,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":227,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedEntry.getFeedbackSessionId(), actualLog.getFeedbackSession().getId());"},{"lineNumber":228,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":229,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedEntry.getFeedbackSessionLogType(), actualLog.getFeedbackSessionLogType().getLabel());"},{"lineNumber":230,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":231,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedEntry.getTimestamp(), actualLog.getTimestamp().toEpochMilli());"},{"lineNumber":232,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":233,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":234,"author":{"gitId":"dishenggg"},"content":" return true;"},{"lineNumber":235,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":236,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":236}},{"path":"src/it/java/teammates/it/ui/webapi/UpdateStudentActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"marquestye"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":3,"author":{"gitId":"marquestye"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"marquestye"},"content":"import java.util.UUID;"},{"lineNumber":5,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":6,"author":{"gitId":"marquestye"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":7,"author":{"gitId":"marquestye"},"content":"import org.testng.annotations.Test;"},{"lineNumber":8,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":9,"author":{"gitId":"marquestye"},"content":"import teammates.common.util.Const;"},{"lineNumber":10,"author":{"gitId":"marquestye"},"content":"import teammates.common.util.EmailType;"},{"lineNumber":11,"author":{"gitId":"marquestye"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":12,"author":{"gitId":"marquestye"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":13,"author":{"gitId":"marquestye"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":14,"author":{"gitId":"marquestye"},"content":"import teammates.common.util.StringHelperExtension;"},{"lineNumber":15,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":16,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":17,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":18,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":19,"author":{"gitId":"marquestye"},"content":"import teammates.ui.output.MessageOutput;"},{"lineNumber":20,"author":{"gitId":"marquestye"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":21,"author":{"gitId":"marquestye"},"content":"import teammates.ui.request.StudentUpdateRequest;"},{"lineNumber":22,"author":{"gitId":"marquestye"},"content":"import teammates.ui.webapi.EntityNotFoundException;"},{"lineNumber":23,"author":{"gitId":"marquestye"},"content":"import teammates.ui.webapi.InvalidOperationException;"},{"lineNumber":24,"author":{"gitId":"marquestye"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":25,"author":{"gitId":"marquestye"},"content":"import teammates.ui.webapi.UpdateStudentAction;"},{"lineNumber":26,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":27,"author":{"gitId":"marquestye"},"content":"/**"},{"lineNumber":28,"author":{"gitId":"marquestye"},"content":" * SUT: {@link UpdateStudentAction}."},{"lineNumber":29,"author":{"gitId":"marquestye"},"content":" */"},{"lineNumber":30,"author":{"gitId":"marquestye"},"content":"public class UpdateStudentActionIT extends BaseActionIT\u003cUpdateStudentAction\u003e {"},{"lineNumber":31,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":32,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":33,"author":{"gitId":"marquestye"},"content":" @BeforeMethod"},{"lineNumber":34,"author":{"gitId":"marquestye"},"content":" protected void setUp() throws Exception {"},{"lineNumber":35,"author":{"gitId":"marquestye"},"content":" super.setUp();"},{"lineNumber":36,"author":{"gitId":"marquestye"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":37,"author":{"gitId":"marquestye"},"content":" HibernateUtil.flushSession();"},{"lineNumber":38,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":39,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":40,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":41,"author":{"gitId":"marquestye"},"content":" protected String getActionUri() {"},{"lineNumber":42,"author":{"gitId":"marquestye"},"content":" return Const.ResourceURIs.STUDENT;"},{"lineNumber":43,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":44,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":45,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":46,"author":{"gitId":"marquestye"},"content":" protected String getRequestMethod() {"},{"lineNumber":47,"author":{"gitId":"marquestye"},"content":" return PUT;"},{"lineNumber":48,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":49,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":50,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":51,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":52,"author":{"gitId":"marquestye"},"content":" public void testExecute() throws Exception {"},{"lineNumber":53,"author":{"gitId":"marquestye"},"content":" assert true;"},{"lineNumber":54,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":55,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":56,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":57,"author":{"gitId":"marquestye"},"content":" public void testExecute_invalidParameters_failure() throws Exception {"},{"lineNumber":58,"author":{"gitId":"marquestye"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":59,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":60,"author":{"gitId":"marquestye"},"content":" ______TS(\"no parameters\");"},{"lineNumber":61,"author":{"gitId":"marquestye"},"content":" verifyHttpParameterFailure();"},{"lineNumber":62,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":63,"author":{"gitId":"marquestye"},"content":" ______TS(\"null student email\");"},{"lineNumber":64,"author":{"gitId":"marquestye"},"content":" String[] invalidParams \u003d new String[] {"},{"lineNumber":65,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, student1.getCourseId(),"},{"lineNumber":66,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":67,"author":{"gitId":"marquestye"},"content":" verifyHttpParameterFailure(invalidParams);"},{"lineNumber":68,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":69,"author":{"gitId":"marquestye"},"content":" ______TS(\"null course id\");"},{"lineNumber":70,"author":{"gitId":"marquestye"},"content":" invalidParams \u003d new String[] {"},{"lineNumber":71,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":72,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":73,"author":{"gitId":"marquestye"},"content":" verifyHttpParameterFailure(invalidParams);"},{"lineNumber":74,"author":{"gitId":"marquestye"},"content":" verifyNoTasksAdded();"},{"lineNumber":75,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":76,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":77,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":78,"author":{"gitId":"marquestye"},"content":" public void testExecute_typicalCase_success() throws Exception {"},{"lineNumber":79,"author":{"gitId":"marquestye"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":80,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":81,"author":{"gitId":"marquestye"},"content":" String originalEmail \u003d student1.getEmail();"},{"lineNumber":82,"author":{"gitId":"marquestye"},"content":" Team originalTeam \u003d student1.getTeam();"},{"lineNumber":83,"author":{"gitId":"marquestye"},"content":" String originalComments \u003d student1.getComments();"},{"lineNumber":84,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":85,"author":{"gitId":"marquestye"},"content":" String newStudentEmail \u003d \"newemail@gmail.tmt\";"},{"lineNumber":86,"author":{"gitId":"marquestye"},"content":" String newStudentTeam \u003d \"new student\u0027s team\";"},{"lineNumber":87,"author":{"gitId":"marquestye"},"content":" String newStudentComments \u003d \"this is new comment after editing\";"},{"lineNumber":88,"author":{"gitId":"marquestye"},"content":" StudentUpdateRequest updateRequest \u003d new StudentUpdateRequest(student1.getName(), newStudentEmail,"},{"lineNumber":89,"author":{"gitId":"marquestye"},"content":" newStudentTeam, student1.getSectionName(), newStudentComments, true);"},{"lineNumber":90,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":91,"author":{"gitId":"marquestye"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":92,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, student1.getCourseId(),"},{"lineNumber":93,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":94,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":95,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":96,"author":{"gitId":"marquestye"},"content":" UpdateStudentAction updateAction \u003d getAction(updateRequest, submissionParams);"},{"lineNumber":97,"author":{"gitId":"marquestye"},"content":" JsonResult actionOutput \u003d getJsonResult(updateAction);"},{"lineNumber":98,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":99,"author":{"gitId":"marquestye"},"content":" MessageOutput msgOutput \u003d (MessageOutput) actionOutput.getOutput();"},{"lineNumber":100,"author":{"gitId":"marquestye"},"content":" assertEquals(\"Student has been updated and email sent\", msgOutput.getMessage());"},{"lineNumber":101,"author":{"gitId":"marquestye"},"content":" verifyNumberOfEmailsSent(1);"},{"lineNumber":102,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":103,"author":{"gitId":"marquestye"},"content":" Student updatedStudent \u003d logic.getStudent(student1.getId());"},{"lineNumber":104,"author":{"gitId":"marquestye"},"content":" assertEquals(updatedStudent.getEmail(), newStudentEmail);"},{"lineNumber":105,"author":{"gitId":"marquestye"},"content":" assertEquals(updatedStudent.getTeamName(), newStudentTeam);"},{"lineNumber":106,"author":{"gitId":"marquestye"},"content":" assertEquals(updatedStudent.getComments(), newStudentComments);"},{"lineNumber":107,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":108,"author":{"gitId":"marquestye"},"content":" EmailWrapper email \u003d getEmailsSent().get(0);"},{"lineNumber":109,"author":{"gitId":"marquestye"},"content":" String courseName \u003d logic.getCourse(student1.getCourseId()).getName();"},{"lineNumber":110,"author":{"gitId":"marquestye"},"content":" assertEquals(String.format(EmailType.STUDENT_EMAIL_CHANGED.getSubject(), courseName,"},{"lineNumber":111,"author":{"gitId":"marquestye"},"content":" student1.getCourseId()), email.getSubject());"},{"lineNumber":112,"author":{"gitId":"marquestye"},"content":" assertEquals(newStudentEmail, email.getRecipient());"},{"lineNumber":113,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":114,"author":{"gitId":"marquestye"},"content":" verifySpecifiedTasksAdded(Const.TaskQueue.SEARCH_INDEXING_QUEUE_NAME, 1);"},{"lineNumber":115,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":116,"author":{"gitId":"marquestye"},"content":" resetStudent(student1.getId(), originalEmail, originalTeam, originalComments);"},{"lineNumber":117,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":118,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":119,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":120,"author":{"gitId":"marquestye"},"content":" public void testExecute_studentDetailsWithWhitespace_success() throws Exception {"},{"lineNumber":121,"author":{"gitId":"marquestye"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":122,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":123,"author":{"gitId":"marquestye"},"content":" String originalEmail \u003d student1.getEmail();"},{"lineNumber":124,"author":{"gitId":"marquestye"},"content":" Team originalTeam \u003d student1.getTeam();"},{"lineNumber":125,"author":{"gitId":"marquestye"},"content":" String originalComments \u003d student1.getComments();"},{"lineNumber":126,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":127,"author":{"gitId":"marquestye"},"content":" String newStudentEmailToBeTrimmed \u003d \" student1@teammates.tmt \"; // after trim, this is equal to originalEmail"},{"lineNumber":128,"author":{"gitId":"marquestye"},"content":" String newStudentTeamToBeTrimmed \u003d \" New team \";"},{"lineNumber":129,"author":{"gitId":"marquestye"},"content":" String newStudentCommentsToBeTrimmed \u003d \" this is new comment after editing \";"},{"lineNumber":130,"author":{"gitId":"marquestye"},"content":" StudentUpdateRequest updateRequest \u003d new StudentUpdateRequest(student1.getName(), newStudentEmailToBeTrimmed,"},{"lineNumber":131,"author":{"gitId":"marquestye"},"content":" newStudentTeamToBeTrimmed, student1.getSectionName(), newStudentCommentsToBeTrimmed, true);"},{"lineNumber":132,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":133,"author":{"gitId":"marquestye"},"content":" String[] submissionParamsToBeTrimmed \u003d new String[] {"},{"lineNumber":134,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, student1.getCourseId(),"},{"lineNumber":135,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":136,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":137,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":138,"author":{"gitId":"marquestye"},"content":" UpdateStudentAction actionToBeTrimmed \u003d getAction(updateRequest, submissionParamsToBeTrimmed);"},{"lineNumber":139,"author":{"gitId":"marquestye"},"content":" JsonResult outputToBeTrimmed \u003d getJsonResult(actionToBeTrimmed);"},{"lineNumber":140,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":141,"author":{"gitId":"marquestye"},"content":" MessageOutput msgTrimmedOutput \u003d (MessageOutput) outputToBeTrimmed.getOutput();"},{"lineNumber":142,"author":{"gitId":"marquestye"},"content":" assertEquals(\"Student has been updated\", msgTrimmedOutput.getMessage());"},{"lineNumber":143,"author":{"gitId":"marquestye"},"content":" verifyNoEmailsSent();"},{"lineNumber":144,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":145,"author":{"gitId":"marquestye"},"content":" resetStudent(student1.getId(), originalEmail, originalTeam, originalComments);"},{"lineNumber":146,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":147,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":148,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":149,"author":{"gitId":"marquestye"},"content":" public void testExecute_emailHasTooManyCharacters_failure() throws Exception {"},{"lineNumber":150,"author":{"gitId":"marquestye"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":151,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":152,"author":{"gitId":"marquestye"},"content":" String invalidStudentEmail \u003d StringHelperExtension.generateStringOfLength(255 - \"@gmail.tmt\".length())"},{"lineNumber":153,"author":{"gitId":"marquestye"},"content":" + \"@gmail.tmt\";"},{"lineNumber":154,"author":{"gitId":"marquestye"},"content":" assertEquals(FieldValidator.EMAIL_MAX_LENGTH + 1, invalidStudentEmail.length());"},{"lineNumber":155,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":156,"author":{"gitId":"marquestye"},"content":" StudentUpdateRequest updateRequest \u003d new StudentUpdateRequest(student1.getName(), invalidStudentEmail,"},{"lineNumber":157,"author":{"gitId":"marquestye"},"content":" student1.getTeamName(), student1.getSectionName(), student1.getComments(), false);"},{"lineNumber":158,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":159,"author":{"gitId":"marquestye"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":160,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, student1.getCourseId(),"},{"lineNumber":161,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":162,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":163,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":164,"author":{"gitId":"marquestye"},"content":" InvalidHttpRequestBodyException ihrbe \u003d verifyHttpRequestBodyFailure(updateRequest, submissionParams);"},{"lineNumber":165,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":166,"author":{"gitId":"marquestye"},"content":" assertEquals(getPopulatedErrorMessage(FieldValidator.EMAIL_ERROR_MESSAGE, invalidStudentEmail,"},{"lineNumber":167,"author":{"gitId":"marquestye"},"content":" FieldValidator.EMAIL_FIELD_NAME, FieldValidator.REASON_TOO_LONG,"},{"lineNumber":168,"author":{"gitId":"marquestye"},"content":" FieldValidator.EMAIL_MAX_LENGTH),"},{"lineNumber":169,"author":{"gitId":"marquestye"},"content":" ihrbe.getMessage());"},{"lineNumber":170,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":171,"author":{"gitId":"marquestye"},"content":" verifyNoTasksAdded();"},{"lineNumber":172,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":173,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":174,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":175,"author":{"gitId":"marquestye"},"content":" public void testExecute_emailTakenByOthers_failure() {"},{"lineNumber":176,"author":{"gitId":"marquestye"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":177,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":178,"author":{"gitId":"marquestye"},"content":" Student student2 \u003d typicalBundle.students.get(\"student2InCourse1\");"},{"lineNumber":179,"author":{"gitId":"marquestye"},"content":" String takenStudentEmail \u003d student2.getEmail();"},{"lineNumber":180,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":181,"author":{"gitId":"marquestye"},"content":" StudentUpdateRequest updateRequest \u003d new StudentUpdateRequest(student1.getName(), takenStudentEmail,"},{"lineNumber":182,"author":{"gitId":"marquestye"},"content":" student1.getTeamName(), student1.getSectionName(), student1.getComments(), false);"},{"lineNumber":183,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":184,"author":{"gitId":"marquestye"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":185,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, student1.getCourseId(),"},{"lineNumber":186,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":187,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":188,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":189,"author":{"gitId":"marquestye"},"content":" InvalidOperationException ioe \u003d verifyInvalidOperation(updateRequest, submissionParams);"},{"lineNumber":190,"author":{"gitId":"marquestye"},"content":" assertEquals(\"Trying to update to an email that is already in use\", ioe.getMessage());"},{"lineNumber":191,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":192,"author":{"gitId":"marquestye"},"content":" verifyNoTasksAdded();"},{"lineNumber":193,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":194,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":195,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":196,"author":{"gitId":"marquestye"},"content":" public void testExecute_studentDoesNotExist_failure() {"},{"lineNumber":197,"author":{"gitId":"marquestye"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":198,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":199,"author":{"gitId":"marquestye"},"content":" StudentUpdateRequest updateRequest \u003d new StudentUpdateRequest(student1.getName(), student1.getEmail(),"},{"lineNumber":200,"author":{"gitId":"marquestye"},"content":" student1.getTeamName(), student1.getSectionName(), student1.getComments(), false);"},{"lineNumber":201,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":202,"author":{"gitId":"marquestye"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":203,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, student1.getCourseId(),"},{"lineNumber":204,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, \"notinuseemail@gmail.tmt\","},{"lineNumber":205,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":206,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":207,"author":{"gitId":"marquestye"},"content":" EntityNotFoundException enfe \u003d verifyEntityNotFound(updateRequest, submissionParams);"},{"lineNumber":208,"author":{"gitId":"marquestye"},"content":" assertEquals(\"The student you tried to edit does not exist. \""},{"lineNumber":209,"author":{"gitId":"marquestye"},"content":" + \"If the student was created during the last few minutes, \""},{"lineNumber":210,"author":{"gitId":"marquestye"},"content":" + \"try again in a few more minutes as the student may still be being saved.\","},{"lineNumber":211,"author":{"gitId":"marquestye"},"content":" enfe.getMessage());"},{"lineNumber":212,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":213,"author":{"gitId":"marquestye"},"content":" verifyNoTasksAdded();"},{"lineNumber":214,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":215,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":216,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":217,"author":{"gitId":"marquestye"},"content":" public void testExecute_studentTeamExistsInAnotherSection_failure() throws Exception {"},{"lineNumber":218,"author":{"gitId":"marquestye"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":219,"author":{"gitId":"marquestye"},"content":" Student student4 \u003d typicalBundle.students.get(\"student4InCourse1\");"},{"lineNumber":220,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":221,"author":{"gitId":"marquestye"},"content":" assertNotEquals(student1.getSection(), student4.getSection());"},{"lineNumber":222,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":223,"author":{"gitId":"marquestye"},"content":" StudentUpdateRequest updateRequest \u003d new StudentUpdateRequest(student1.getName(), student1.getEmail(),"},{"lineNumber":224,"author":{"gitId":"marquestye"},"content":" student4.getTeamName(), student1.getSectionName(), student1.getComments(), true);"},{"lineNumber":225,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":226,"author":{"gitId":"marquestye"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":227,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, student1.getCourseId(),"},{"lineNumber":228,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":229,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":230,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":231,"author":{"gitId":"marquestye"},"content":" InvalidOperationException ioe \u003d verifyInvalidOperation(updateRequest, submissionParams);"},{"lineNumber":232,"author":{"gitId":"marquestye"},"content":" String expectedErrorMessage \u003d String.format(\"Team \\\"%s\\\" is detected in both Section \\\"%s\\\" and Section \\\"%s\\\".\""},{"lineNumber":233,"author":{"gitId":"marquestye"},"content":" + \" Please use different team names in different sections.\", student4.getTeamName(),"},{"lineNumber":234,"author":{"gitId":"marquestye"},"content":" student1.getSectionName(), student4.getSectionName());"},{"lineNumber":235,"author":{"gitId":"marquestye"},"content":" assertEquals(expectedErrorMessage, ioe.getMessage());"},{"lineNumber":236,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":237,"author":{"gitId":"marquestye"},"content":" verifyNoTasksAdded();"},{"lineNumber":238,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":239,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":240,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":241,"author":{"gitId":"marquestye"},"content":" public void testExecute_sectionFull_failure() throws Exception {"},{"lineNumber":242,"author":{"gitId":"marquestye"},"content":" Student studentToJoinMaxSection \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":243,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":244,"author":{"gitId":"marquestye"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":245,"author":{"gitId":"marquestye"},"content":" String courseId \u003d studentToJoinMaxSection.getCourseId();"},{"lineNumber":246,"author":{"gitId":"marquestye"},"content":" String sectionInMaxCapacity \u003d \"sectionInMaxCapacity\";"},{"lineNumber":247,"author":{"gitId":"marquestye"},"content":" Section section \u003d logic.getSectionOrCreate(courseId, sectionInMaxCapacity);"},{"lineNumber":248,"author":{"gitId":"marquestye"},"content":" Team team \u003d logic.getTeamOrCreate(section, \"randomTeamName\");"},{"lineNumber":249,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":250,"author":{"gitId":"marquestye"},"content":" for (int i \u003d 0; i \u003c Const.SECTION_SIZE_LIMIT; i++) {"},{"lineNumber":251,"author":{"gitId":"marquestye"},"content":" Student addedStudent \u003d new Student(course, \"Name \" + i, i + \"email@test.com\", \"cmt\" + i, team);"},{"lineNumber":252,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":253,"author":{"gitId":"marquestye"},"content":" logic.createStudent(addedStudent);"},{"lineNumber":254,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":255,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":256,"author":{"gitId":"marquestye"},"content":" List\u003cStudent\u003e studentList \u003d logic.getStudentsForCourse(courseId);"},{"lineNumber":257,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":258,"author":{"gitId":"marquestye"},"content":" assertEquals(Const.SECTION_SIZE_LIMIT,"},{"lineNumber":259,"author":{"gitId":"marquestye"},"content":" studentList.stream().filter(student -\u003e student.getSectionName().equals(sectionInMaxCapacity)).count());"},{"lineNumber":260,"author":{"gitId":"marquestye"},"content":" assertEquals(courseId, studentToJoinMaxSection.getCourseId());"},{"lineNumber":261,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":262,"author":{"gitId":"marquestye"},"content":" StudentUpdateRequest updateRequest \u003d"},{"lineNumber":263,"author":{"gitId":"marquestye"},"content":" new StudentUpdateRequest(studentToJoinMaxSection.getName(), studentToJoinMaxSection.getEmail(),"},{"lineNumber":264,"author":{"gitId":"marquestye"},"content":" \"randomTeamName\", sectionInMaxCapacity,"},{"lineNumber":265,"author":{"gitId":"marquestye"},"content":" studentToJoinMaxSection.getComments(), true);"},{"lineNumber":266,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":267,"author":{"gitId":"marquestye"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":268,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, studentToJoinMaxSection.getCourseId(),"},{"lineNumber":269,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, studentToJoinMaxSection.getEmail(),"},{"lineNumber":270,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":271,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":272,"author":{"gitId":"marquestye"},"content":" InvalidOperationException ioe \u003d verifyInvalidOperation(updateRequest, submissionParams);"},{"lineNumber":273,"author":{"gitId":"marquestye"},"content":" String expectedErrorMessage \u003d String.format(\"You are trying enroll more than %d students in section \\\"%s\\\". \""},{"lineNumber":274,"author":{"gitId":"marquestye"},"content":" + \"To avoid performance problems, please do not enroll more than %d students in a single section.\","},{"lineNumber":275,"author":{"gitId":"marquestye"},"content":" Const.SECTION_SIZE_LIMIT, sectionInMaxCapacity, Const.SECTION_SIZE_LIMIT);"},{"lineNumber":276,"author":{"gitId":"marquestye"},"content":" assertEquals(expectedErrorMessage, ioe.getMessage());"},{"lineNumber":277,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":278,"author":{"gitId":"marquestye"},"content":" verifyNoTasksAdded();"},{"lineNumber":279,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":280,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":281,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":282,"author":{"gitId":"marquestye"},"content":" public void testExecute_renameEmptySectionNameToDefault_success() {"},{"lineNumber":283,"author":{"gitId":"marquestye"},"content":" Student student4 \u003d typicalBundle.students.get(\"student4InCourse1\");"},{"lineNumber":284,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":285,"author":{"gitId":"marquestye"},"content":" Team originalTeam \u003d student4.getTeam();"},{"lineNumber":286,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":287,"author":{"gitId":"marquestye"},"content":" StudentUpdateRequest emptySectionUpdateRequest \u003d new StudentUpdateRequest(student4.getName(), student4.getEmail(),"},{"lineNumber":288,"author":{"gitId":"marquestye"},"content":" student4.getTeamName(), \"\", student4.getComments(), true);"},{"lineNumber":289,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":290,"author":{"gitId":"marquestye"},"content":" String[] emptySectionSubmissionParams \u003d new String[] {"},{"lineNumber":291,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, student4.getCourseId(),"},{"lineNumber":292,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, student4.getEmail(),"},{"lineNumber":293,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":294,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":295,"author":{"gitId":"marquestye"},"content":" UpdateStudentAction updateEmptySectionAction \u003d getAction(emptySectionUpdateRequest, emptySectionSubmissionParams);"},{"lineNumber":296,"author":{"gitId":"marquestye"},"content":" JsonResult emptySectionActionOutput \u003d getJsonResult(updateEmptySectionAction);"},{"lineNumber":297,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":298,"author":{"gitId":"marquestye"},"content":" MessageOutput emptySectionMsgOutput \u003d (MessageOutput) emptySectionActionOutput.getOutput();"},{"lineNumber":299,"author":{"gitId":"marquestye"},"content":" assertEquals(\"Student has been updated\", emptySectionMsgOutput.getMessage());"},{"lineNumber":300,"author":{"gitId":"marquestye"},"content":" verifyNoEmailsSent();"},{"lineNumber":301,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":302,"author":{"gitId":"marquestye"},"content":" // verify student in database"},{"lineNumber":303,"author":{"gitId":"marquestye"},"content":" Student actualStudent \u003d"},{"lineNumber":304,"author":{"gitId":"marquestye"},"content":" logic.getStudentForEmail(student4.getCourseId(), student4.getEmail());"},{"lineNumber":305,"author":{"gitId":"marquestye"},"content":" assertEquals(student4.getCourse(), actualStudent.getCourse());"},{"lineNumber":306,"author":{"gitId":"marquestye"},"content":" assertEquals(student4.getName(), actualStudent.getName());"},{"lineNumber":307,"author":{"gitId":"marquestye"},"content":" assertEquals(student4.getEmail(), actualStudent.getEmail());"},{"lineNumber":308,"author":{"gitId":"marquestye"},"content":" assertEquals(student4.getTeam(), actualStudent.getTeam());"},{"lineNumber":309,"author":{"gitId":"marquestye"},"content":" assertEquals(Const.DEFAULT_SECTION, actualStudent.getSectionName());"},{"lineNumber":310,"author":{"gitId":"marquestye"},"content":" assertEquals(student4.getComments(), actualStudent.getComments());"},{"lineNumber":311,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":312,"author":{"gitId":"marquestye"},"content":" resetStudent(student4.getId(), student4.getEmail(), originalTeam, student4.getComments());"},{"lineNumber":313,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":314,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":315,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":316,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":317,"author":{"gitId":"marquestye"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":318,"author":{"gitId":"marquestye"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":319,"author":{"gitId":"marquestye"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":320,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":321,"author":{"gitId":"marquestye"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":322,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, student1.getCourseId(),"},{"lineNumber":323,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":324,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":325,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":326,"author":{"gitId":"marquestye"},"content":" verifyOnlyInstructorsOfTheSameCourseWithCorrectCoursePrivilegeCanAccess("},{"lineNumber":327,"author":{"gitId":"marquestye"},"content":" course, Const.InstructorPermissions.CAN_MODIFY_STUDENT, submissionParams);"},{"lineNumber":328,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":329,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":330,"author":{"gitId":"marquestye"},"content":" private void resetStudent(UUID studentId, String originalEmail, Team originalTeam, String originalComments) {"},{"lineNumber":331,"author":{"gitId":"marquestye"},"content":" Student updatedStudent \u003d logic.getStudent(studentId);"},{"lineNumber":332,"author":{"gitId":"marquestye"},"content":" updatedStudent.setEmail(originalEmail);"},{"lineNumber":333,"author":{"gitId":"marquestye"},"content":" updatedStudent.setTeam(originalTeam);"},{"lineNumber":334,"author":{"gitId":"marquestye"},"content":" updatedStudent.setComments(originalComments);"},{"lineNumber":335,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":336,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":337,"author":{"gitId":"marquestye"},"content":"}"}],"authorContributionMap":{"marquestye":337}},{"path":"src/main/java/teammates/common/datatransfer/FeedbackSessionLogEntry.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.datatransfer;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":6,"author":{"gitId":"-"},"content":" * Represents a log entry of a feedback session."},{"lineNumber":7,"author":{"gitId":"-"},"content":" */"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"public class FeedbackSessionLogEntry implements Comparable\u003cFeedbackSessionLogEntry\u003e {"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":" private final String courseId;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":" private final UUID studentId;"},{"lineNumber":11,"author":{"gitId":"-"},"content":" private final String studentEmail;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":" private final UUID feedbackSessionId;"},{"lineNumber":13,"author":{"gitId":"-"},"content":" private final String feedbackSessionName;"},{"lineNumber":14,"author":{"gitId":"-"},"content":" private final String feedbackSessionLogType;"},{"lineNumber":15,"author":{"gitId":"-"},"content":" private final long timestamp;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":" public FeedbackSessionLogEntry(String courseId, String studentEmail,"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" String feedbackSessionName, String feedbackSessionLogType, long timestamp) {"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":" this.courseId \u003d courseId;"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":" this.studentId \u003d null;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" this.studentEmail \u003d studentEmail;"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionId \u003d null;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" this.feedbackSessionName \u003d feedbackSessionName;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" this.feedbackSessionLogType \u003d feedbackSessionLogType;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" this.timestamp \u003d timestamp;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" }"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" public FeedbackSessionLogEntry(String courseId, UUID studentId, UUID feedbackSessionId,"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" String feedbackSessionLogType, long timestamp) {"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" this.courseId \u003d courseId;"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" this.studentId \u003d studentId;"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" this.studentEmail \u003d null;"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionId \u003d feedbackSessionId;"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionName \u003d null;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" this.feedbackSessionLogType \u003d feedbackSessionLogType;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" this.timestamp \u003d timestamp;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" }"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" public String getCourseId() {"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" return courseId;"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" public UUID getStudentId() {"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" return studentId;"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" public String getStudentEmail() {"},{"lineNumber":48,"author":{"gitId":"-"},"content":" return studentEmail;"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" public UUID getFeedbackSessionId() {"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" return feedbackSessionId;"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" public String getFeedbackSessionName() {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" return feedbackSessionName;"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" public String getFeedbackSessionLogType() {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" return this.feedbackSessionLogType;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" public long getTimestamp() {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" return this.timestamp;"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" public int compareTo(FeedbackSessionLogEntry o) {"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" return Long.compare(this.getTimestamp(), o.getTimestamp());"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":35,"-":36}},{"path":"src/main/java/teammates/common/datatransfer/SqlDataBundle.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.datatransfer;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.LinkedHashMap;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.ReadNotification;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":23,"author":{"gitId":"-"},"content":" * Holds a bundle of entities."},{"lineNumber":24,"author":{"gitId":"-"},"content":" *"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * \u003cp\u003eThis class is mainly used for serializing JSON strings."},{"lineNumber":26,"author":{"gitId":"-"},"content":" */"},{"lineNumber":27,"author":{"gitId":"-"},"content":"// CHECKSTYLE.OFF:JavadocVariable each field represents different entity types"},{"lineNumber":28,"author":{"gitId":"-"},"content":"public class SqlDataBundle {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" public Map\u003cString, Account\u003e accounts \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":30,"author":{"gitId":"-"},"content":" public Map\u003cString, AccountRequest\u003e accountRequests \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":31,"author":{"gitId":"-"},"content":" public Map\u003cString, Course\u003e courses \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":32,"author":{"gitId":"-"},"content":" public Map\u003cString, Section\u003e sections \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":33,"author":{"gitId":"-"},"content":" public Map\u003cString, Team\u003e teams \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":34,"author":{"gitId":"-"},"content":" public Map\u003cString, DeadlineExtension\u003e deadlineExtensions \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":35,"author":{"gitId":"-"},"content":" public Map\u003cString, Instructor\u003e instructors \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":36,"author":{"gitId":"-"},"content":" public Map\u003cString, Student\u003e students \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":37,"author":{"gitId":"-"},"content":" public Map\u003cString, FeedbackSession\u003e feedbackSessions \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":38,"author":{"gitId":"-"},"content":" public Map\u003cString, FeedbackQuestion\u003e feedbackQuestions \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":39,"author":{"gitId":"-"},"content":" public Map\u003cString, FeedbackResponse\u003e feedbackResponses \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":40,"author":{"gitId":"-"},"content":" public Map\u003cString, FeedbackResponseComment\u003e feedbackResponseComments \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" public Map\u003cString, FeedbackSessionLog\u003e feedbackSessionLogs \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":42,"author":{"gitId":"-"},"content":" public Map\u003cString, Notification\u003e notifications \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" public Map\u003cString, ReadNotification\u003e readNotifications \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":44,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":2,"-":42}},{"path":"src/main/java/teammates/common/datatransfer/SqlSessionResultsBundle.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.common.datatransfer;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import java.util.LinkedHashMap;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import java.util.Map;"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import java.util.Set;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const;"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.StringHelper;"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" * Represents detailed results for a feedback session."},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":"public class SqlSessionResultsBundle {"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" private final List\u003cFeedbackQuestion\u003e questions;"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" private final Set\u003cFeedbackQuestion\u003e questionsNotVisibleForPreviewSet;"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" private final Set\u003cFeedbackQuestion\u003e questionsWithCommentNotVisibleForPreviewSet;"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" private final Map\u003cFeedbackQuestion, List\u003cFeedbackResponse\u003e\u003e questionResponseMap;"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" private final Map\u003cFeedbackQuestion, List\u003cFeedbackResponse\u003e\u003e questionMissingResponseMap;"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" private final Map\u003cFeedbackResponse, List\u003cFeedbackResponseComment\u003e\u003e responseCommentsMap;"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" private final Map\u003cFeedbackResponse, Boolean\u003e responseGiverVisibilityTable;"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" private final Map\u003cFeedbackResponse, Boolean\u003e responseRecipientVisibilityTable;"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" private final Map\u003cLong, Boolean\u003e commentGiverVisibilityTable;"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" private final SqlCourseRoster roster;"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" public SqlSessionResultsBundle(List\u003cFeedbackQuestion\u003e questions,"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" Set\u003cFeedbackQuestion\u003e questionsNotVisibleForPreviewSet,"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" Set\u003cFeedbackQuestion\u003e questionsWithCommentNotVisibleForPreviewSet,"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e responses,"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e missingResponses,"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackResponse, Boolean\u003e responseGiverVisibilityTable,"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackResponse, Boolean\u003e responseRecipientVisibilityTable,"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackResponse, List\u003cFeedbackResponseComment\u003e\u003e responseCommentsMap,"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" Map\u003cLong, Boolean\u003e commentGiverVisibilityTable,"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" SqlCourseRoster roster) {"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" this.questions \u003d questions;"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" this.questionsNotVisibleForPreviewSet \u003d questionsNotVisibleForPreviewSet;"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" this.questionsWithCommentNotVisibleForPreviewSet \u003d questionsWithCommentNotVisibleForPreviewSet;"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" this.responseCommentsMap \u003d responseCommentsMap;"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" this.responseGiverVisibilityTable \u003d responseGiverVisibilityTable;"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" this.responseRecipientVisibilityTable \u003d responseRecipientVisibilityTable;"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" this.commentGiverVisibilityTable \u003d commentGiverVisibilityTable;"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" this.roster \u003d roster;"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" this.questionResponseMap \u003d buildQuestionToResponseMap(responses);"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" this.questionMissingResponseMap \u003d buildQuestionToResponseMap(missingResponses);"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" private Map\u003cFeedbackQuestion, List\u003cFeedbackResponse\u003e\u003e buildQuestionToResponseMap("},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e responses) {"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" // build question to response map"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackQuestion, List\u003cFeedbackResponse\u003e\u003e questionToResponseMap \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" for (FeedbackQuestion question : questions) {"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" questionToResponseMap.put(question, new ArrayList\u003c\u003e());"},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" for (FeedbackResponse response : responses) {"},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question \u003d response.getFeedbackQuestion();"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e responsesForQuestion \u003d questionToResponseMap.get(question);"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" responsesForQuestion.add(response);"},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":" return questionToResponseMap;"},{"lineNumber":67,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":68,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":" * Returns true if the giver of a response is visible to the current user."},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" * Returns false otherwise."},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":" public boolean isResponseGiverVisible(FeedbackResponse response) {"},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" return isResponseParticipantVisible(true, response);"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" * Returns true if the recipient of a response is visible to the current user."},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":" * Returns false otherwise."},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":" public boolean isResponseRecipientVisible(FeedbackResponse response) {"},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":" return isResponseParticipantVisible(false, response);"},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":" * Checks if the giver/recipient for a response is visible/hidden from the current user."},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" private boolean isResponseParticipantVisible(boolean isGiver, FeedbackResponse response) {"},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question \u003d response.getFeedbackQuestion();"},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" FeedbackParticipantType participantType;"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":" boolean isVisible;"},{"lineNumber":93,"author":{"gitId":"xenosf"},"content":" if (isGiver) {"},{"lineNumber":94,"author":{"gitId":"xenosf"},"content":" isVisible \u003d responseGiverVisibilityTable.get(response);"},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":" participantType \u003d question.getGiverType();"},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" isVisible \u003d responseRecipientVisibilityTable.get(response);"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" participantType \u003d question.getRecipientType();"},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":100,"author":{"gitId":"xenosf"},"content":" boolean isTypeNone \u003d participantType \u003d\u003d FeedbackParticipantType.NONE;"},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":102,"author":{"gitId":"xenosf"},"content":" return isVisible || isTypeNone;"},{"lineNumber":103,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":104,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":105,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":106,"author":{"gitId":"xenosf"},"content":" * Returns true if the giver of a comment is visible to the current user."},{"lineNumber":107,"author":{"gitId":"xenosf"},"content":" * Returns false otherwise."},{"lineNumber":108,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":109,"author":{"gitId":"xenosf"},"content":" public boolean isCommentGiverVisible(FeedbackResponseComment comment) {"},{"lineNumber":110,"author":{"gitId":"xenosf"},"content":" return commentGiverVisibilityTable.get(comment.getId());"},{"lineNumber":111,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":112,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":113,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":114,"author":{"gitId":"xenosf"},"content":" * Gets the anonymous name for a given name."},{"lineNumber":115,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" * \u003cp\u003eThe anonymous name will be deterministic based on {@code name}."},{"lineNumber":117,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":118,"author":{"gitId":"xenosf"},"content":" public static String getAnonName(FeedbackParticipantType type, String name) {"},{"lineNumber":119,"author":{"gitId":"xenosf"},"content":" String hashedEncryptedName \u003d getHashOfName(getEncryptedName(name));"},{"lineNumber":120,"author":{"gitId":"xenosf"},"content":" String participantType \u003d type.toSingularFormString();"},{"lineNumber":121,"author":{"gitId":"xenosf"},"content":" return String.format("},{"lineNumber":122,"author":{"gitId":"xenosf"},"content":" Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT + \" %s %s\", participantType, hashedEncryptedName);"},{"lineNumber":123,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":124,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":125,"author":{"gitId":"xenosf"},"content":" public Map\u003cFeedbackQuestion, List\u003cFeedbackResponse\u003e\u003e getQuestionResponseMap() {"},{"lineNumber":126,"author":{"gitId":"xenosf"},"content":" return questionResponseMap;"},{"lineNumber":127,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":128,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":129,"author":{"gitId":"xenosf"},"content":" public Map\u003cFeedbackQuestion, List\u003cFeedbackResponse\u003e\u003e getQuestionMissingResponseMap() {"},{"lineNumber":130,"author":{"gitId":"xenosf"},"content":" return questionMissingResponseMap;"},{"lineNumber":131,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":132,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":133,"author":{"gitId":"xenosf"},"content":" private static String getEncryptedName(String name) {"},{"lineNumber":134,"author":{"gitId":"xenosf"},"content":" return StringHelper.encrypt(name);"},{"lineNumber":135,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":136,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":137,"author":{"gitId":"xenosf"},"content":" private static String getHashOfName(String name) {"},{"lineNumber":138,"author":{"gitId":"xenosf"},"content":" return Long.toString(Math.abs((long) name.hashCode()));"},{"lineNumber":139,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":140,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":141,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackQuestion\u003e getQuestions() {"},{"lineNumber":142,"author":{"gitId":"xenosf"},"content":" return questions;"},{"lineNumber":143,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":144,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":145,"author":{"gitId":"xenosf"},"content":" public Map\u003cFeedbackResponse, List\u003cFeedbackResponseComment\u003e\u003e getResponseCommentsMap() {"},{"lineNumber":146,"author":{"gitId":"xenosf"},"content":" return responseCommentsMap;"},{"lineNumber":147,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":148,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":149,"author":{"gitId":"xenosf"},"content":" public SqlCourseRoster getRoster() {"},{"lineNumber":150,"author":{"gitId":"xenosf"},"content":" return roster;"},{"lineNumber":151,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":152,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":153,"author":{"gitId":"xenosf"},"content":" public Map\u003cFeedbackResponse, Boolean\u003e getResponseGiverVisibilityTable() {"},{"lineNumber":154,"author":{"gitId":"xenosf"},"content":" return responseGiverVisibilityTable;"},{"lineNumber":155,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":156,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":157,"author":{"gitId":"xenosf"},"content":" public Map\u003cFeedbackResponse, Boolean\u003e getResponseRecipientVisibilityTable() {"},{"lineNumber":158,"author":{"gitId":"xenosf"},"content":" return responseRecipientVisibilityTable;"},{"lineNumber":159,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":160,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":161,"author":{"gitId":"xenosf"},"content":" public Map\u003cLong, Boolean\u003e getCommentGiverVisibilityTable() {"},{"lineNumber":162,"author":{"gitId":"xenosf"},"content":" return commentGiverVisibilityTable;"},{"lineNumber":163,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":164,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":165,"author":{"gitId":"xenosf"},"content":" public Set\u003cFeedbackQuestion\u003e getQuestionsNotVisibleForPreviewSet() {"},{"lineNumber":166,"author":{"gitId":"xenosf"},"content":" return questionsNotVisibleForPreviewSet;"},{"lineNumber":167,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":168,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":169,"author":{"gitId":"xenosf"},"content":" public Set\u003cFeedbackQuestion\u003e getQuestionsWithCommentNotVisibleForPreviewSet() {"},{"lineNumber":170,"author":{"gitId":"xenosf"},"content":" return questionsWithCommentNotVisibleForPreviewSet;"},{"lineNumber":171,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":172,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":172}},{"path":"src/main/java/teammates/common/datatransfer/attributes/StudentAttributes.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.datatransfer.attributes;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.Comparator;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.Objects;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.entity.CourseStudent;"},{"lineNumber":14,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * The data transfer object for {@link CourseStudent} entities."},{"lineNumber":18,"author":{"gitId":"-"},"content":" */"},{"lineNumber":19,"author":{"gitId":"-"},"content":"public final class StudentAttributes extends EntityAttributes\u003cCourseStudent\u003e {"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" private String email;"},{"lineNumber":22,"author":{"gitId":"-"},"content":" private String course;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" private String name;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" private String googleId;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" private String comments;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" private String team;"},{"lineNumber":27,"author":{"gitId":"-"},"content":" private String section;"},{"lineNumber":28,"author":{"gitId":"-"},"content":" private transient String key;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" private transient Instant createdAt;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" private transient Instant updatedAt;"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" private StudentAttributes(String courseId, String email) {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" this.course \u003d courseId;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" this.email \u003d email;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" this.googleId \u003d \"\";"},{"lineNumber":37,"author":{"gitId":"-"},"content":" this.section \u003d Const.DEFAULT_SECTION;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" this.createdAt \u003d Const.TIME_REPRESENTS_DEFAULT_TIMESTAMP;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.updatedAt \u003d Const.TIME_REPRESENTS_DEFAULT_TIMESTAMP;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":43,"author":{"gitId":"-"},"content":" * Gets the {@link StudentAttributes} instance of the given {@link CourseStudent}."},{"lineNumber":44,"author":{"gitId":"-"},"content":" */"},{"lineNumber":45,"author":{"gitId":"-"},"content":" public static StudentAttributes valueOf(CourseStudent student) {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" StudentAttributes studentAttributes \u003d new StudentAttributes(student.getCourseId(), student.getEmail());"},{"lineNumber":47,"author":{"gitId":"-"},"content":" studentAttributes.name \u003d student.getName();"},{"lineNumber":48,"author":{"gitId":"-"},"content":" if (student.getGoogleId() !\u003d null) {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" studentAttributes.googleId \u003d student.getGoogleId();"},{"lineNumber":50,"author":{"gitId":"-"},"content":" }"},{"lineNumber":51,"author":{"gitId":"-"},"content":" studentAttributes.team \u003d student.getTeamName();"},{"lineNumber":52,"author":{"gitId":"-"},"content":" if (student.getSectionName() !\u003d null) {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" studentAttributes.section \u003d student.getSectionName();"},{"lineNumber":54,"author":{"gitId":"-"},"content":" }"},{"lineNumber":55,"author":{"gitId":"-"},"content":" studentAttributes.comments \u003d student.getComments();"},{"lineNumber":56,"author":{"gitId":"-"},"content":" studentAttributes.key \u003d student.getRegistrationKey();"},{"lineNumber":57,"author":{"gitId":"-"},"content":" if (student.getCreatedAt() !\u003d null) {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" studentAttributes.createdAt \u003d student.getCreatedAt();"},{"lineNumber":59,"author":{"gitId":"-"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":" if (student.getUpdatedAt() !\u003d null) {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" studentAttributes.updatedAt \u003d student.getUpdatedAt();"},{"lineNumber":62,"author":{"gitId":"-"},"content":" }"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" return studentAttributes;"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"marquestye"},"content":" /**"},{"lineNumber":68,"author":{"gitId":"marquestye"},"content":" * Gets the {@link StudentAttributes} instance of the given {@link Student}."},{"lineNumber":69,"author":{"gitId":"marquestye"},"content":" */"},{"lineNumber":70,"author":{"gitId":"marquestye"},"content":" public static StudentAttributes valueOf(Student student) {"},{"lineNumber":71,"author":{"gitId":"marquestye"},"content":" StudentAttributes studentAttributes \u003d new StudentAttributes(student.getCourseId(), student.getEmail());"},{"lineNumber":72,"author":{"gitId":"marquestye"},"content":" studentAttributes.name \u003d student.getName();"},{"lineNumber":73,"author":{"gitId":"marquestye"},"content":" if (student.getGoogleId() !\u003d null) {"},{"lineNumber":74,"author":{"gitId":"marquestye"},"content":" studentAttributes.googleId \u003d student.getGoogleId();"},{"lineNumber":75,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":76,"author":{"gitId":"marquestye"},"content":" studentAttributes.team \u003d student.getTeamName();"},{"lineNumber":77,"author":{"gitId":"marquestye"},"content":" if (student.getSectionName() !\u003d null) {"},{"lineNumber":78,"author":{"gitId":"marquestye"},"content":" studentAttributes.section \u003d student.getSectionName();"},{"lineNumber":79,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":80,"author":{"gitId":"marquestye"},"content":" studentAttributes.comments \u003d student.getComments();"},{"lineNumber":81,"author":{"gitId":"marquestye"},"content":" // studentAttributes.key \u003d student.getRegistrationKey();"},{"lineNumber":82,"author":{"gitId":"marquestye"},"content":" if (student.getCreatedAt() !\u003d null) {"},{"lineNumber":83,"author":{"gitId":"marquestye"},"content":" studentAttributes.createdAt \u003d student.getCreatedAt();"},{"lineNumber":84,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":85,"author":{"gitId":"marquestye"},"content":" if (student.getUpdatedAt() !\u003d null) {"},{"lineNumber":86,"author":{"gitId":"marquestye"},"content":" studentAttributes.updatedAt \u003d student.getUpdatedAt();"},{"lineNumber":87,"author":{"gitId":"-"},"content":" }"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" return studentAttributes;"},{"lineNumber":90,"author":{"gitId":"-"},"content":" }"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":93,"author":{"gitId":"-"},"content":" * Return a builder for {@link StudentAttributes}."},{"lineNumber":94,"author":{"gitId":"-"},"content":" */"},{"lineNumber":95,"author":{"gitId":"-"},"content":" public static Builder builder(String courseId, String email) {"},{"lineNumber":96,"author":{"gitId":"-"},"content":" return new Builder(courseId, email);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" }"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":100,"author":{"gitId":"-"},"content":" * Gets a deep copy of this object."},{"lineNumber":101,"author":{"gitId":"-"},"content":" */"},{"lineNumber":102,"author":{"gitId":"-"},"content":" public StudentAttributes getCopy() {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" StudentAttributes studentAttributes \u003d new StudentAttributes(course, email);"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" studentAttributes.name \u003d name;"},{"lineNumber":106,"author":{"gitId":"-"},"content":" studentAttributes.googleId \u003d googleId;"},{"lineNumber":107,"author":{"gitId":"-"},"content":" studentAttributes.team \u003d team;"},{"lineNumber":108,"author":{"gitId":"-"},"content":" studentAttributes.section \u003d section;"},{"lineNumber":109,"author":{"gitId":"-"},"content":" studentAttributes.comments \u003d comments;"},{"lineNumber":110,"author":{"gitId":"-"},"content":" studentAttributes.key \u003d key;"},{"lineNumber":111,"author":{"gitId":"-"},"content":" studentAttributes.createdAt \u003d createdAt;"},{"lineNumber":112,"author":{"gitId":"-"},"content":" studentAttributes.updatedAt \u003d updatedAt;"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" return studentAttributes;"},{"lineNumber":115,"author":{"gitId":"-"},"content":" }"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" public boolean isRegistered() {"},{"lineNumber":118,"author":{"gitId":"-"},"content":" return googleId !\u003d null \u0026\u0026 !googleId.trim().isEmpty();"},{"lineNumber":119,"author":{"gitId":"-"},"content":" }"},{"lineNumber":120,"author":{"gitId":"-"},"content":""},{"lineNumber":121,"author":{"gitId":"-"},"content":" public String getRegistrationUrl() {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" return Config.getFrontEndAppUrl(Const.WebPageURIs.JOIN_PAGE)"},{"lineNumber":123,"author":{"gitId":"-"},"content":" .withRegistrationKey(key)"},{"lineNumber":124,"author":{"gitId":"-"},"content":" .withEntityType(Const.EntityType.STUDENT)"},{"lineNumber":125,"author":{"gitId":"-"},"content":" .toString();"},{"lineNumber":126,"author":{"gitId":"-"},"content":" }"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" public String getName() {"},{"lineNumber":129,"author":{"gitId":"-"},"content":" return name;"},{"lineNumber":130,"author":{"gitId":"-"},"content":" }"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":" public void setName(String name) {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" this.name \u003d name;"},{"lineNumber":134,"author":{"gitId":"-"},"content":" }"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" public String getEmail() {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" public void setEmail(String email) {"},{"lineNumber":141,"author":{"gitId":"-"},"content":" this.email \u003d email;"},{"lineNumber":142,"author":{"gitId":"-"},"content":" }"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" public String getCourse() {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" return course;"},{"lineNumber":146,"author":{"gitId":"-"},"content":" }"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" public void setCourse(String course) {"},{"lineNumber":149,"author":{"gitId":"-"},"content":" this.course \u003d course;"},{"lineNumber":150,"author":{"gitId":"-"},"content":" }"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" public String getGoogleId() {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" return googleId;"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" public void setGoogleId(String googleId) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" this.googleId \u003d googleId;"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" public String getKey() {"},{"lineNumber":161,"author":{"gitId":"-"},"content":" return key;"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" public void setKey(String key) {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" this.key \u003d key;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" }"},{"lineNumber":167,"author":{"gitId":"-"},"content":""},{"lineNumber":168,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":169,"author":{"gitId":"-"},"content":" * Format: email%courseId e.g., adam@gmail.com%cs1101."},{"lineNumber":170,"author":{"gitId":"-"},"content":" */"},{"lineNumber":171,"author":{"gitId":"-"},"content":" public String getId() {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" return email + \"%\" + course;"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" public String getSection() {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" return section;"},{"lineNumber":177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" public void setSection(String section) {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" this.section \u003d section;"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" public String getTeam() {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" return team;"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" public void setTeam(String team) {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" this.team \u003d team;"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" public String getComments() {"},{"lineNumber":192,"author":{"gitId":"-"},"content":" return comments;"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"-"},"content":" public void setComments(String comments) {"},{"lineNumber":196,"author":{"gitId":"-"},"content":" this.comments \u003d comments;"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":200,"author":{"gitId":"-"},"content":" public boolean equals(Object other) {"},{"lineNumber":201,"author":{"gitId":"-"},"content":" if (other \u003d\u003d null) {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":203,"author":{"gitId":"-"},"content":" } else if (this \u003d\u003d other) {"},{"lineNumber":204,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":205,"author":{"gitId":"-"},"content":" } else if (this.getClass() \u003d\u003d other.getClass()) {"},{"lineNumber":206,"author":{"gitId":"-"},"content":" StudentAttributes otherStudent \u003d (StudentAttributes) other;"},{"lineNumber":207,"author":{"gitId":"-"},"content":" return Objects.equals(this.course, otherStudent.course)"},{"lineNumber":208,"author":{"gitId":"-"},"content":" \u0026\u0026 Objects.equals(this.name, otherStudent.name)"},{"lineNumber":209,"author":{"gitId":"-"},"content":" \u0026\u0026 Objects.equals(this.email, otherStudent.email)"},{"lineNumber":210,"author":{"gitId":"-"},"content":" \u0026\u0026 Objects.equals(this.googleId, otherStudent.googleId)"},{"lineNumber":211,"author":{"gitId":"-"},"content":" \u0026\u0026 Objects.equals(this.comments, otherStudent.comments)"},{"lineNumber":212,"author":{"gitId":"-"},"content":" \u0026\u0026 Objects.equals(this.team, otherStudent.team)"},{"lineNumber":213,"author":{"gitId":"-"},"content":" \u0026\u0026 Objects.equals(this.section, otherStudent.section);"},{"lineNumber":214,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":216,"author":{"gitId":"-"},"content":" }"},{"lineNumber":217,"author":{"gitId":"-"},"content":" }"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":220,"author":{"gitId":"-"},"content":" public List\u003cString\u003e getInvalidityInfo() {"},{"lineNumber":221,"author":{"gitId":"-"},"content":" // id is allowed to be null when the student is not registered"},{"lineNumber":222,"author":{"gitId":"-"},"content":" assert team !\u003d null;"},{"lineNumber":223,"author":{"gitId":"-"},"content":" assert comments !\u003d null;"},{"lineNumber":224,"author":{"gitId":"-"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":" List\u003cString\u003e errors \u003d new ArrayList\u003c\u003e();"},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"-"},"content":" if (isRegistered()) {"},{"lineNumber":228,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForGoogleId(googleId), errors);"},{"lineNumber":229,"author":{"gitId":"-"},"content":" }"},{"lineNumber":230,"author":{"gitId":"-"},"content":""},{"lineNumber":231,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForCourseId(course), errors);"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForEmail(email), errors);"},{"lineNumber":234,"author":{"gitId":"-"},"content":""},{"lineNumber":235,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForTeamName(team), errors);"},{"lineNumber":236,"author":{"gitId":"-"},"content":""},{"lineNumber":237,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForSectionName(section), errors);"},{"lineNumber":238,"author":{"gitId":"-"},"content":""},{"lineNumber":239,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForStudentRoleComments(comments), errors);"},{"lineNumber":240,"author":{"gitId":"-"},"content":""},{"lineNumber":241,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForPersonName(name), errors);"},{"lineNumber":242,"author":{"gitId":"-"},"content":""},{"lineNumber":243,"author":{"gitId":"-"},"content":" return errors;"},{"lineNumber":244,"author":{"gitId":"-"},"content":" }"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":247,"author":{"gitId":"-"},"content":" * Sorts the list of students by the section name, then team name, then name."},{"lineNumber":248,"author":{"gitId":"-"},"content":" */"},{"lineNumber":249,"author":{"gitId":"-"},"content":" public static void sortBySectionName(List\u003cStudentAttributes\u003e students) {"},{"lineNumber":250,"author":{"gitId":"-"},"content":" students.sort(Comparator.comparing((StudentAttributes student) -\u003e student.section)"},{"lineNumber":251,"author":{"gitId":"-"},"content":" .thenComparing(student -\u003e student.team)"},{"lineNumber":252,"author":{"gitId":"-"},"content":" .thenComparing(student -\u003e student.name));"},{"lineNumber":253,"author":{"gitId":"-"},"content":" }"},{"lineNumber":254,"author":{"gitId":"-"},"content":""},{"lineNumber":255,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":256,"author":{"gitId":"-"},"content":" * Sorts the list of students by the team name, then name."},{"lineNumber":257,"author":{"gitId":"-"},"content":" */"},{"lineNumber":258,"author":{"gitId":"-"},"content":" public static void sortByTeamName(List\u003cStudentAttributes\u003e students) {"},{"lineNumber":259,"author":{"gitId":"-"},"content":" students.sort(Comparator.comparing((StudentAttributes student) -\u003e student.team)"},{"lineNumber":260,"author":{"gitId":"-"},"content":" .thenComparing(student -\u003e student.name));"},{"lineNumber":261,"author":{"gitId":"-"},"content":" }"},{"lineNumber":262,"author":{"gitId":"-"},"content":""},{"lineNumber":263,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":264,"author":{"gitId":"-"},"content":" public CourseStudent toEntity() {"},{"lineNumber":265,"author":{"gitId":"-"},"content":" return new CourseStudent(email, name, googleId, comments, course, team, section);"},{"lineNumber":266,"author":{"gitId":"-"},"content":" }"},{"lineNumber":267,"author":{"gitId":"-"},"content":""},{"lineNumber":268,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":269,"author":{"gitId":"-"},"content":" public int hashCode() {"},{"lineNumber":270,"author":{"gitId":"-"},"content":" StringBuilder stringBuilder \u003d new StringBuilder();"},{"lineNumber":271,"author":{"gitId":"-"},"content":" stringBuilder.append(this.email).append(this.name).append(this.course)"},{"lineNumber":272,"author":{"gitId":"-"},"content":" .append(this.googleId).append(this.team).append(this.section).append(this.comments);"},{"lineNumber":273,"author":{"gitId":"-"},"content":" return stringBuilder.toString().hashCode();"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":277,"author":{"gitId":"-"},"content":" public String toString() {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" return \"Student:\" + name + \"[\" + email + \"]\";"},{"lineNumber":279,"author":{"gitId":"-"},"content":" }"},{"lineNumber":280,"author":{"gitId":"-"},"content":""},{"lineNumber":281,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":282,"author":{"gitId":"-"},"content":" public void sanitizeForSaving() {"},{"lineNumber":283,"author":{"gitId":"-"},"content":" googleId \u003d SanitizationHelper.sanitizeGoogleId(googleId);"},{"lineNumber":284,"author":{"gitId":"-"},"content":" name \u003d SanitizationHelper.sanitizeName(name);"},{"lineNumber":285,"author":{"gitId":"-"},"content":" comments \u003d SanitizationHelper.sanitizeTextField(comments);"},{"lineNumber":286,"author":{"gitId":"-"},"content":" }"},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":" public Instant getCreatedAt() {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" return createdAt;"},{"lineNumber":290,"author":{"gitId":"-"},"content":" }"},{"lineNumber":291,"author":{"gitId":"-"},"content":""},{"lineNumber":292,"author":{"gitId":"-"},"content":" public Instant getUpdatedAt() {"},{"lineNumber":293,"author":{"gitId":"-"},"content":" return updatedAt;"},{"lineNumber":294,"author":{"gitId":"-"},"content":" }"},{"lineNumber":295,"author":{"gitId":"-"},"content":""},{"lineNumber":296,"author":{"gitId":"-"},"content":" public void setCreatedAt(Instant createdAt) {"},{"lineNumber":297,"author":{"gitId":"-"},"content":" this.createdAt \u003d createdAt;"},{"lineNumber":298,"author":{"gitId":"-"},"content":" }"},{"lineNumber":299,"author":{"gitId":"-"},"content":""},{"lineNumber":300,"author":{"gitId":"-"},"content":" public void setUpdatedAt(Instant updatedAt) {"},{"lineNumber":301,"author":{"gitId":"-"},"content":" this.updatedAt \u003d updatedAt;"},{"lineNumber":302,"author":{"gitId":"-"},"content":" }"},{"lineNumber":303,"author":{"gitId":"-"},"content":""},{"lineNumber":304,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":305,"author":{"gitId":"-"},"content":" * Updates with {@link UpdateOptions}."},{"lineNumber":306,"author":{"gitId":"-"},"content":" */"},{"lineNumber":307,"author":{"gitId":"-"},"content":" public void update(UpdateOptions updateOptions) {"},{"lineNumber":308,"author":{"gitId":"-"},"content":" updateOptions.newEmailOption.ifPresent(s -\u003e email \u003d s);"},{"lineNumber":309,"author":{"gitId":"-"},"content":" updateOptions.nameOption.ifPresent(s -\u003e name \u003d s);"},{"lineNumber":310,"author":{"gitId":"-"},"content":" updateOptions.commentOption.ifPresent(s -\u003e comments \u003d s);"},{"lineNumber":311,"author":{"gitId":"-"},"content":" updateOptions.googleIdOption.ifPresent(s -\u003e googleId \u003d s);"},{"lineNumber":312,"author":{"gitId":"-"},"content":" updateOptions.teamNameOption.ifPresent(s -\u003e team \u003d s);"},{"lineNumber":313,"author":{"gitId":"-"},"content":" updateOptions.sectionNameOption.ifPresent(s -\u003e section \u003d s);"},{"lineNumber":314,"author":{"gitId":"-"},"content":" }"},{"lineNumber":315,"author":{"gitId":"-"},"content":""},{"lineNumber":316,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":317,"author":{"gitId":"-"},"content":" * Returns a {@link UpdateOptions.Builder} to build {@link UpdateOptions} for a student."},{"lineNumber":318,"author":{"gitId":"-"},"content":" */"},{"lineNumber":319,"author":{"gitId":"-"},"content":" public static UpdateOptions.Builder updateOptionsBuilder(String courseId, String email) {"},{"lineNumber":320,"author":{"gitId":"-"},"content":" return new UpdateOptions.Builder(courseId, email);"},{"lineNumber":321,"author":{"gitId":"-"},"content":" }"},{"lineNumber":322,"author":{"gitId":"-"},"content":""},{"lineNumber":323,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":324,"author":{"gitId":"-"},"content":" * A builder class for {@link StudentAttributes}."},{"lineNumber":325,"author":{"gitId":"-"},"content":" */"},{"lineNumber":326,"author":{"gitId":"-"},"content":" public static final class Builder extends BasicBuilder\u003cStudentAttributes, Builder\u003e {"},{"lineNumber":327,"author":{"gitId":"-"},"content":""},{"lineNumber":328,"author":{"gitId":"-"},"content":" private final StudentAttributes studentAttributes;"},{"lineNumber":329,"author":{"gitId":"-"},"content":""},{"lineNumber":330,"author":{"gitId":"-"},"content":" private Builder(String courseId, String email) {"},{"lineNumber":331,"author":{"gitId":"-"},"content":" super(new UpdateOptions(courseId, email));"},{"lineNumber":332,"author":{"gitId":"-"},"content":" thisBuilder \u003d this;"},{"lineNumber":333,"author":{"gitId":"-"},"content":""},{"lineNumber":334,"author":{"gitId":"-"},"content":" studentAttributes \u003d new StudentAttributes(courseId, email);"},{"lineNumber":335,"author":{"gitId":"-"},"content":" }"},{"lineNumber":336,"author":{"gitId":"-"},"content":""},{"lineNumber":337,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":338,"author":{"gitId":"-"},"content":" public StudentAttributes build() {"},{"lineNumber":339,"author":{"gitId":"-"},"content":" studentAttributes.update(updateOptions);"},{"lineNumber":340,"author":{"gitId":"-"},"content":""},{"lineNumber":341,"author":{"gitId":"-"},"content":" return studentAttributes;"},{"lineNumber":342,"author":{"gitId":"-"},"content":" }"},{"lineNumber":343,"author":{"gitId":"-"},"content":" }"},{"lineNumber":344,"author":{"gitId":"-"},"content":""},{"lineNumber":345,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":346,"author":{"gitId":"-"},"content":" * Helper class to specify the fields to update in {@link StudentAttributes}."},{"lineNumber":347,"author":{"gitId":"-"},"content":" */"},{"lineNumber":348,"author":{"gitId":"-"},"content":" public static final class UpdateOptions {"},{"lineNumber":349,"author":{"gitId":"-"},"content":" private String courseId;"},{"lineNumber":350,"author":{"gitId":"-"},"content":" private String email;"},{"lineNumber":351,"author":{"gitId":"-"},"content":""},{"lineNumber":352,"author":{"gitId":"-"},"content":" private UpdateOption\u003cString\u003e newEmailOption \u003d UpdateOption.empty();"},{"lineNumber":353,"author":{"gitId":"-"},"content":" private UpdateOption\u003cString\u003e nameOption \u003d UpdateOption.empty();"},{"lineNumber":354,"author":{"gitId":"-"},"content":" private UpdateOption\u003cString\u003e commentOption \u003d UpdateOption.empty();"},{"lineNumber":355,"author":{"gitId":"-"},"content":" private UpdateOption\u003cString\u003e googleIdOption \u003d UpdateOption.empty();"},{"lineNumber":356,"author":{"gitId":"-"},"content":" private UpdateOption\u003cString\u003e teamNameOption \u003d UpdateOption.empty();"},{"lineNumber":357,"author":{"gitId":"-"},"content":" private UpdateOption\u003cString\u003e sectionNameOption \u003d UpdateOption.empty();"},{"lineNumber":358,"author":{"gitId":"-"},"content":""},{"lineNumber":359,"author":{"gitId":"-"},"content":" private UpdateOptions(String courseId, String email) {"},{"lineNumber":360,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":361,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":362,"author":{"gitId":"-"},"content":""},{"lineNumber":363,"author":{"gitId":"-"},"content":" this.courseId \u003d courseId;"},{"lineNumber":364,"author":{"gitId":"-"},"content":" this.email \u003d email;"},{"lineNumber":365,"author":{"gitId":"-"},"content":" }"},{"lineNumber":366,"author":{"gitId":"-"},"content":""},{"lineNumber":367,"author":{"gitId":"-"},"content":" public String getCourseId() {"},{"lineNumber":368,"author":{"gitId":"-"},"content":" return courseId;"},{"lineNumber":369,"author":{"gitId":"-"},"content":" }"},{"lineNumber":370,"author":{"gitId":"-"},"content":""},{"lineNumber":371,"author":{"gitId":"-"},"content":" public String getEmail() {"},{"lineNumber":372,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":373,"author":{"gitId":"-"},"content":" }"},{"lineNumber":374,"author":{"gitId":"-"},"content":""},{"lineNumber":375,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":376,"author":{"gitId":"-"},"content":" public String toString() {"},{"lineNumber":377,"author":{"gitId":"-"},"content":" return \"StudentAttributes.UpdateOptions [\""},{"lineNumber":378,"author":{"gitId":"-"},"content":" + \"courseId \u003d \" + courseId"},{"lineNumber":379,"author":{"gitId":"-"},"content":" + \", email \u003d \" + email"},{"lineNumber":380,"author":{"gitId":"-"},"content":" + \", newEmail \u003d \" + newEmailOption"},{"lineNumber":381,"author":{"gitId":"-"},"content":" + \", name \u003d \" + nameOption"},{"lineNumber":382,"author":{"gitId":"-"},"content":" + \", comment \u003d \" + commentOption"},{"lineNumber":383,"author":{"gitId":"-"},"content":" + \", googleId \u003d \" + googleIdOption"},{"lineNumber":384,"author":{"gitId":"-"},"content":" + \", teamName \u003d \" + teamNameOption"},{"lineNumber":385,"author":{"gitId":"-"},"content":" + \", sectionName \u003d \" + sectionNameOption"},{"lineNumber":386,"author":{"gitId":"-"},"content":" + \"]\";"},{"lineNumber":387,"author":{"gitId":"-"},"content":" }"},{"lineNumber":388,"author":{"gitId":"-"},"content":""},{"lineNumber":389,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":390,"author":{"gitId":"-"},"content":" * Builder class to build {@link UpdateOptions}."},{"lineNumber":391,"author":{"gitId":"-"},"content":" */"},{"lineNumber":392,"author":{"gitId":"-"},"content":" public static final class Builder extends BasicBuilder\u003cUpdateOptions, Builder\u003e {"},{"lineNumber":393,"author":{"gitId":"-"},"content":""},{"lineNumber":394,"author":{"gitId":"-"},"content":" private Builder(String courseId, String email) {"},{"lineNumber":395,"author":{"gitId":"-"},"content":" super(new UpdateOptions(courseId, email));"},{"lineNumber":396,"author":{"gitId":"-"},"content":" thisBuilder \u003d this;"},{"lineNumber":397,"author":{"gitId":"-"},"content":" }"},{"lineNumber":398,"author":{"gitId":"-"},"content":""},{"lineNumber":399,"author":{"gitId":"-"},"content":" public Builder withNewEmail(String email) {"},{"lineNumber":400,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":401,"author":{"gitId":"-"},"content":""},{"lineNumber":402,"author":{"gitId":"-"},"content":" updateOptions.newEmailOption \u003d UpdateOption.of(email);"},{"lineNumber":403,"author":{"gitId":"-"},"content":" return thisBuilder;"},{"lineNumber":404,"author":{"gitId":"-"},"content":" }"},{"lineNumber":405,"author":{"gitId":"-"},"content":""},{"lineNumber":406,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":407,"author":{"gitId":"-"},"content":" public UpdateOptions build() {"},{"lineNumber":408,"author":{"gitId":"-"},"content":" return updateOptions;"},{"lineNumber":409,"author":{"gitId":"-"},"content":" }"},{"lineNumber":410,"author":{"gitId":"-"},"content":""},{"lineNumber":411,"author":{"gitId":"-"},"content":" }"},{"lineNumber":412,"author":{"gitId":"-"},"content":""},{"lineNumber":413,"author":{"gitId":"-"},"content":" }"},{"lineNumber":414,"author":{"gitId":"-"},"content":""},{"lineNumber":415,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":416,"author":{"gitId":"-"},"content":" * Basic builder to build {@link StudentAttributes} related classes."},{"lineNumber":417,"author":{"gitId":"-"},"content":" *"},{"lineNumber":418,"author":{"gitId":"-"},"content":" * @param \u003cT\u003e type to be built"},{"lineNumber":419,"author":{"gitId":"-"},"content":" * @param \u003cB\u003e type of the builder"},{"lineNumber":420,"author":{"gitId":"-"},"content":" */"},{"lineNumber":421,"author":{"gitId":"-"},"content":" private abstract static class BasicBuilder\u003cT, B extends BasicBuilder\u003cT, B\u003e\u003e {"},{"lineNumber":422,"author":{"gitId":"-"},"content":""},{"lineNumber":423,"author":{"gitId":"-"},"content":" UpdateOptions updateOptions;"},{"lineNumber":424,"author":{"gitId":"-"},"content":" B thisBuilder;"},{"lineNumber":425,"author":{"gitId":"-"},"content":""},{"lineNumber":426,"author":{"gitId":"-"},"content":" BasicBuilder(UpdateOptions updateOptions) {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" this.updateOptions \u003d updateOptions;"},{"lineNumber":428,"author":{"gitId":"-"},"content":" }"},{"lineNumber":429,"author":{"gitId":"-"},"content":""},{"lineNumber":430,"author":{"gitId":"-"},"content":" public B withName(String name) {"},{"lineNumber":431,"author":{"gitId":"-"},"content":" assert name !\u003d null;"},{"lineNumber":432,"author":{"gitId":"-"},"content":""},{"lineNumber":433,"author":{"gitId":"-"},"content":" updateOptions.nameOption \u003d UpdateOption.of(name);"},{"lineNumber":434,"author":{"gitId":"-"},"content":" return thisBuilder;"},{"lineNumber":435,"author":{"gitId":"-"},"content":" }"},{"lineNumber":436,"author":{"gitId":"-"},"content":""},{"lineNumber":437,"author":{"gitId":"-"},"content":" public B withComment(String comment) {"},{"lineNumber":438,"author":{"gitId":"-"},"content":" assert comment !\u003d null;"},{"lineNumber":439,"author":{"gitId":"-"},"content":""},{"lineNumber":440,"author":{"gitId":"-"},"content":" updateOptions.commentOption \u003d UpdateOption.of(comment);"},{"lineNumber":441,"author":{"gitId":"-"},"content":" return thisBuilder;"},{"lineNumber":442,"author":{"gitId":"-"},"content":" }"},{"lineNumber":443,"author":{"gitId":"-"},"content":""},{"lineNumber":444,"author":{"gitId":"-"},"content":" public B withGoogleId(String googleId) {"},{"lineNumber":445,"author":{"gitId":"-"},"content":" // google id can be set to null"},{"lineNumber":446,"author":{"gitId":"-"},"content":" updateOptions.googleIdOption \u003d UpdateOption.of(googleId);"},{"lineNumber":447,"author":{"gitId":"-"},"content":" return thisBuilder;"},{"lineNumber":448,"author":{"gitId":"-"},"content":" }"},{"lineNumber":449,"author":{"gitId":"-"},"content":""},{"lineNumber":450,"author":{"gitId":"-"},"content":" public B withTeamName(String teamName) {"},{"lineNumber":451,"author":{"gitId":"-"},"content":" assert teamName !\u003d null;"},{"lineNumber":452,"author":{"gitId":"-"},"content":""},{"lineNumber":453,"author":{"gitId":"-"},"content":" updateOptions.teamNameOption \u003d UpdateOption.of(teamName);"},{"lineNumber":454,"author":{"gitId":"-"},"content":" return thisBuilder;"},{"lineNumber":455,"author":{"gitId":"-"},"content":" }"},{"lineNumber":456,"author":{"gitId":"-"},"content":""},{"lineNumber":457,"author":{"gitId":"-"},"content":" public B withSectionName(String sectionName) {"},{"lineNumber":458,"author":{"gitId":"-"},"content":" assert sectionName !\u003d null;"},{"lineNumber":459,"author":{"gitId":"-"},"content":""},{"lineNumber":460,"author":{"gitId":"-"},"content":" updateOptions.sectionNameOption \u003d UpdateOption.of(sectionName);"},{"lineNumber":461,"author":{"gitId":"-"},"content":" return thisBuilder;"},{"lineNumber":462,"author":{"gitId":"-"},"content":" }"},{"lineNumber":463,"author":{"gitId":"-"},"content":""},{"lineNumber":464,"author":{"gitId":"-"},"content":" public abstract T build();"},{"lineNumber":465,"author":{"gitId":"-"},"content":""},{"lineNumber":466,"author":{"gitId":"-"},"content":" }"},{"lineNumber":467,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":21,"-":446}},{"path":"src/main/java/teammates/common/datatransfer/logs/FeedbackSessionAuditLogDetails.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.datatransfer.logs;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":6,"author":{"gitId":"-"},"content":" * Contains specific structure and processing logic for feedback session audit log."},{"lineNumber":7,"author":{"gitId":"-"},"content":" */"},{"lineNumber":8,"author":{"gitId":"-"},"content":"public class FeedbackSessionAuditLogDetails extends LogDetails {"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":11,"author":{"gitId":"-"},"content":" private String courseId;"},{"lineNumber":12,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":" private String feedbackSessionId;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":" @Nullable"},{"lineNumber":15,"author":{"gitId":"-"},"content":" private String feedbackSessionName;"},{"lineNumber":16,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":" private String studentId;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" @Nullable"},{"lineNumber":19,"author":{"gitId":"-"},"content":" private String studentEmail;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" private String accessType;"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" public FeedbackSessionAuditLogDetails() {"},{"lineNumber":23,"author":{"gitId":"-"},"content":" super(LogEvent.FEEDBACK_SESSION_AUDIT);"},{"lineNumber":24,"author":{"gitId":"-"},"content":" }"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" public String getCourseId() {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" return courseId;"},{"lineNumber":28,"author":{"gitId":"-"},"content":" }"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" public void setCourseId(String courseId) {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" this.courseId \u003d courseId;"},{"lineNumber":32,"author":{"gitId":"-"},"content":" }"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" public String getFeedbackSessionName() {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" return feedbackSessionName;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" }"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" public void setFeedbackSessionName(String feedbackSessionName) {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.feedbackSessionName \u003d feedbackSessionName;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" public String getStudentEmail() {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" return studentEmail;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" }"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" public void setStudentEmail(String studentEmail) {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" this.studentEmail \u003d studentEmail;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" }"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" public String getAccessType() {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" return accessType;"},{"lineNumber":52,"author":{"gitId":"-"},"content":" }"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" public void setAccessType(String accessType) {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" this.accessType \u003d accessType;"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" public String getFeedbackSessionId() {"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" return feedbackSessionId;"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" public void setFeedbackSessionId(String feedbackSessionId) {"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionId \u003d feedbackSessionId;"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" public String getStudentId() {"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" return studentId;"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" public void setStudentId(String studentId) {"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" this.studentId \u003d studentId;"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public void hideSensitiveInformation() {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" courseId \u003d null;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" feedbackSessionName \u003d null;"},{"lineNumber":78,"author":{"gitId":"-"},"content":" studentEmail \u003d null;"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" studentId \u003d null;"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" feedbackSessionId \u003d null;"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":22,"-":61}},{"path":"src/main/java/teammates/common/datatransfer/questions/FeedbackQuestionDetails.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.datatransfer.questions;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SessionResultsBundle;"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.SqlSessionResultsBundle;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * A class holding the details for a specific question type."},{"lineNumber":14,"author":{"gitId":"-"},"content":" * This abstract class is inherited by concrete Feedback*QuestionDetails"},{"lineNumber":15,"author":{"gitId":"-"},"content":" * classes which provides the implementation for the various abstract methods"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * such that pages can render the correct information/forms depending on the"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * question type"},{"lineNumber":18,"author":{"gitId":"-"},"content":" */"},{"lineNumber":19,"author":{"gitId":"-"},"content":"public abstract class FeedbackQuestionDetails {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" private FeedbackQuestionType questionType;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" private String questionText;"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" protected FeedbackQuestionDetails(FeedbackQuestionType questionType) {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" this.questionType \u003d questionType;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" protected FeedbackQuestionDetails(FeedbackQuestionType questionType, String questionText) {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" this.questionType \u003d questionType;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" this.questionText \u003d questionText;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":33,"author":{"gitId":"-"},"content":" * Get question result statistics as JSON string."},{"lineNumber":34,"author":{"gitId":"-"},"content":" */"},{"lineNumber":35,"author":{"gitId":"-"},"content":" @SuppressWarnings(\"PMD.EmptyMethodInAbstractClassShouldBeAbstract\")"},{"lineNumber":36,"author":{"gitId":"-"},"content":" public String getQuestionResultStatisticsJson("},{"lineNumber":37,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes question, String studentEmail, SessionResultsBundle bundle) {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" // Statistics are calculated in the front-end as it is dependent on the responses being filtered."},{"lineNumber":39,"author":{"gitId":"-"},"content":" // The only exception is contribution question, where there is only one statistics for the entire question."},{"lineNumber":40,"author":{"gitId":"-"},"content":" // It is also necessary to calculate contribution question statistics here"},{"lineNumber":41,"author":{"gitId":"-"},"content":" // to be displayed in student result page as students are not supposed to be able to see the exact responses."},{"lineNumber":42,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":43,"author":{"gitId":"-"},"content":" }"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" * Get question result statistics as JSON string."},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" @SuppressWarnings(\"PMD.EmptyMethodInAbstractClassShouldBeAbstract\")"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" public String getQuestionResultStatisticsJson("},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question, String studentEmail, SqlSessionResultsBundle bundle) {"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" // Statistics are calculated in the front-end as it is dependent on the responses being filtered."},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" // The only exception is contribution question, where there is only one statistics for the entire question."},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" // It is also necessary to calculate contribution question statistics here"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" // to be displayed in student result page as students are not supposed to be able to see the exact responses."},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":" return \"\";"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":59,"author":{"gitId":"-"},"content":" * Checks whether the changes to the question details require deletion of corresponding responses."},{"lineNumber":60,"author":{"gitId":"-"},"content":" */"},{"lineNumber":61,"author":{"gitId":"-"},"content":" public abstract boolean shouldChangesRequireResponseDeletion(FeedbackQuestionDetails newDetails);"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":64,"author":{"gitId":"-"},"content":" * Individual responses are shown by default."},{"lineNumber":65,"author":{"gitId":"-"},"content":" * Override for specific question types if necessary."},{"lineNumber":66,"author":{"gitId":"-"},"content":" *"},{"lineNumber":67,"author":{"gitId":"-"},"content":" * @return boolean indicating if individual responses are to be shown to students."},{"lineNumber":68,"author":{"gitId":"-"},"content":" */"},{"lineNumber":69,"author":{"gitId":"-"},"content":" public boolean isIndividualResponsesShownToStudents() {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":74,"author":{"gitId":"-"},"content":" * Validates the question details."},{"lineNumber":75,"author":{"gitId":"-"},"content":" * @return A {@code List\u003cString\u003e} of error messages (to show as status message to user) if any, or an"},{"lineNumber":76,"author":{"gitId":"-"},"content":" * empty list if question details are valid."},{"lineNumber":77,"author":{"gitId":"-"},"content":" */"},{"lineNumber":78,"author":{"gitId":"-"},"content":" public abstract List\u003cString\u003e validateQuestionDetails();"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":81,"author":{"gitId":"-"},"content":" * Validates the list of response details."},{"lineNumber":82,"author":{"gitId":"-"},"content":" * @return A {@code List\u003cString\u003e} of error messages (to show as status message to user) if any, or an"},{"lineNumber":83,"author":{"gitId":"-"},"content":" * empty list if all response details are valid."},{"lineNumber":84,"author":{"gitId":"-"},"content":" */"},{"lineNumber":85,"author":{"gitId":"-"},"content":" public abstract List\u003cString\u003e validateResponsesDetails(List\u003cFeedbackResponseDetails\u003e responseDetails, int numRecipients);"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":88,"author":{"gitId":"-"},"content":" * Validates if giverType and recipientType are valid for the question type."},{"lineNumber":89,"author":{"gitId":"-"},"content":" * Validates visibility options as well."},{"lineNumber":90,"author":{"gitId":"-"},"content":" *"},{"lineNumber":91,"author":{"gitId":"-"},"content":" * \u003cp\u003eOverride in Feedback*QuestionDetails if necessary."},{"lineNumber":92,"author":{"gitId":"-"},"content":" * @return error message detailing the error, or an empty string if valid."},{"lineNumber":93,"author":{"gitId":"-"},"content":" */"},{"lineNumber":94,"author":{"gitId":"-"},"content":" public abstract String validateGiverRecipientVisibility(FeedbackQuestionAttributes feedbackQuestionAttributes);"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":97,"author":{"gitId":"-"},"content":" * Validates if giverType and recipientType are valid for the question type."},{"lineNumber":98,"author":{"gitId":"-"},"content":" * Validates visibility options as well."},{"lineNumber":99,"author":{"gitId":"-"},"content":" *"},{"lineNumber":100,"author":{"gitId":"-"},"content":" * \u003cp\u003eOverride in Feedback*QuestionDetails if necessary."},{"lineNumber":101,"author":{"gitId":"-"},"content":" * @return error message detailing the error, or an empty string if valid."},{"lineNumber":102,"author":{"gitId":"-"},"content":" */"},{"lineNumber":103,"author":{"gitId":"-"},"content":" public abstract String validateGiverRecipientVisibility(FeedbackQuestion feedbackQuestion);"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":106,"author":{"gitId":"-"},"content":" * Checks whether instructor comments are allowed for the question."},{"lineNumber":107,"author":{"gitId":"-"},"content":" */"},{"lineNumber":108,"author":{"gitId":"-"},"content":" public boolean isInstructorCommentsOnResponsesAllowed() {"},{"lineNumber":109,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":113,"author":{"gitId":"-"},"content":" * Checks whether missing responses should be generated."},{"lineNumber":114,"author":{"gitId":"-"},"content":" */"},{"lineNumber":115,"author":{"gitId":"-"},"content":" public boolean shouldGenerateMissingResponses(FeedbackQuestionAttributes question) {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" // generate combinations against all students/teams are meaningless"},{"lineNumber":117,"author":{"gitId":"-"},"content":" return question.getRecipientType() !\u003d FeedbackParticipantType.STUDENTS"},{"lineNumber":118,"author":{"gitId":"-"},"content":" \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.STUDENTS_EXCLUDING_SELF"},{"lineNumber":119,"author":{"gitId":"-"},"content":" \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":120,"author":{"gitId":"-"},"content":" \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.TEAMS_EXCLUDING_SELF;"},{"lineNumber":121,"author":{"gitId":"-"},"content":" }"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":124,"author":{"gitId":"xenosf"},"content":" * Checks whether missing responses should be generated."},{"lineNumber":125,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":126,"author":{"gitId":"xenosf"},"content":" public boolean shouldGenerateMissingResponses(FeedbackQuestion question) {"},{"lineNumber":127,"author":{"gitId":"xenosf"},"content":" // generate combinations against all students/teams are meaningless"},{"lineNumber":128,"author":{"gitId":"xenosf"},"content":" return question.getRecipientType() !\u003d FeedbackParticipantType.STUDENTS"},{"lineNumber":129,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.STUDENTS_EXCLUDING_SELF"},{"lineNumber":130,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":131,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.TEAMS_EXCLUDING_SELF;"},{"lineNumber":132,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":133,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":135,"author":{"gitId":"-"},"content":" public boolean equals(Object obj) {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" if (this \u003d\u003d obj) {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" if (obj \u003d\u003d null || obj.getClass() !\u003d this.getClass()) {"},{"lineNumber":141,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":142,"author":{"gitId":"-"},"content":" }"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" // Json string contains all attributes of a `FeedbackQuestionDetails` object,"},{"lineNumber":145,"author":{"gitId":"-"},"content":" // so it is sufficient to use it to compare two `FeedbackQuestionDetails` objects."},{"lineNumber":146,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails other \u003d (FeedbackQuestionDetails) obj;"},{"lineNumber":147,"author":{"gitId":"-"},"content":" return this.getJsonString().equals(other.getJsonString());"},{"lineNumber":148,"author":{"gitId":"-"},"content":" }"},{"lineNumber":149,"author":{"gitId":"-"},"content":""},{"lineNumber":150,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":151,"author":{"gitId":"-"},"content":" public int hashCode() {"},{"lineNumber":152,"author":{"gitId":"-"},"content":" return this.getJsonString().hashCode();"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":156,"author":{"gitId":"-"},"content":" * Returns a JSON string representation of the question details."},{"lineNumber":157,"author":{"gitId":"-"},"content":" */"},{"lineNumber":158,"author":{"gitId":"-"},"content":" public String getJsonString() {"},{"lineNumber":159,"author":{"gitId":"-"},"content":" assert questionType !\u003d null;"},{"lineNumber":160,"author":{"gitId":"-"},"content":" return JsonUtils.toJson(this, questionType.getQuestionDetailsClass());"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":164,"author":{"gitId":"-"},"content":" * Returns a deep copy of the question details."},{"lineNumber":165,"author":{"gitId":"-"},"content":" */"},{"lineNumber":166,"author":{"gitId":"-"},"content":" public FeedbackQuestionDetails getDeepCopy() {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" assert questionType !\u003d null;"},{"lineNumber":168,"author":{"gitId":"-"},"content":" String serializedDetails \u003d getJsonString();"},{"lineNumber":169,"author":{"gitId":"-"},"content":" return JsonUtils.fromJson(serializedDetails, questionType.getQuestionDetailsClass());"},{"lineNumber":170,"author":{"gitId":"-"},"content":" }"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" public FeedbackQuestionType getQuestionType() {"},{"lineNumber":173,"author":{"gitId":"-"},"content":" return questionType;"},{"lineNumber":174,"author":{"gitId":"-"},"content":" }"},{"lineNumber":175,"author":{"gitId":"-"},"content":""},{"lineNumber":176,"author":{"gitId":"-"},"content":" public void setQuestionType(FeedbackQuestionType questionType) {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" this.questionType \u003d questionType;"},{"lineNumber":178,"author":{"gitId":"-"},"content":" }"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" public String getQuestionText() {"},{"lineNumber":181,"author":{"gitId":"-"},"content":" return questionText;"},{"lineNumber":182,"author":{"gitId":"-"},"content":" }"},{"lineNumber":183,"author":{"gitId":"-"},"content":""},{"lineNumber":184,"author":{"gitId":"-"},"content":" public void setQuestionText(String questionText) {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" this.questionText \u003d questionText;"},{"lineNumber":186,"author":{"gitId":"-"},"content":" }"},{"lineNumber":187,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":25,"-":162}},{"path":"src/main/java/teammates/common/util/Const.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.util;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.nio.charset.Charset;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.nio.charset.StandardCharsets;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.Duration;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * Stores constants that are widely used across classes."},{"lineNumber":12,"author":{"gitId":"-"},"content":" * this class contains several nested classes, each containing a specific"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * category of constants."},{"lineNumber":14,"author":{"gitId":"-"},"content":" */"},{"lineNumber":15,"author":{"gitId":"-"},"content":"public final class Const {"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":" // This section holds constants that are defined as constants primarily because they are repeated in many places."},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":" public static final String USER_NOBODY_TEXT \u003d \"-\";"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" public static final String USER_TEAM_FOR_INSTRUCTOR \u003d \"Instructors\";"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" public static final String DEFAULT_DISPLAY_NAME_FOR_INSTRUCTOR \u003d \"Instructor\";"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" public static final String DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT \u003d \"Anonymous\";"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" public static final int SECTION_SIZE_LIMIT \u003d 100;"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" public static final String DEFAULT_SECTION \u003d \"None\";"},{"lineNumber":30,"author":{"gitId":"-"},"content":" public static final Section DEFAULT_SQL_SECTION \u003d null;"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" public static final String UNKNOWN_INSTITUTION \u003d \"Unknown Institution\";"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" public static final String DEFAULT_TIME_ZONE \u003d \"UTC\";"},{"lineNumber":35,"author":{"gitId":"-"},"content":" public static final Charset ENCODING \u003d StandardCharsets.UTF_8;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" public static final Duration FEEDBACK_SESSIONS_SEARCH_WINDOW \u003d Duration.ofDays(30);"},{"lineNumber":38,"author":{"gitId":"-"},"content":" public static final Duration LOGS_RETENTION_PERIOD \u003d Duration.ofDays(30);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" public static final Duration COOKIE_VALIDITY_PERIOD \u003d Duration.ofDays(7);"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" public static final int SEARCH_QUERY_SIZE_LIMIT \u003d 50;"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" public static final String ERROR_CREATE_ENTITY_ALREADY_EXISTS \u003d \"Trying to create an entity that exists: %s\";"},{"lineNumber":44,"author":{"gitId":"-"},"content":" public static final String ERROR_UPDATE_NON_EXISTENT \u003d \"Trying to update non-existent Entity: \";"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" public static final String MISSING_RESPONSE_TEXT \u003d \"No Response\";"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" public static final Duration STUDENT_ACTIVITY_LOGS_UPDATE_INTERVAL \u003d Duration.ofMinutes(15);"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" public static final Duration STUDENT_ACTIVITY_LOGS_FILTER_WINDOW \u003d Duration.ofSeconds(2);"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" public static final String ACCOUNT_REQUEST_NOT_FOUND \u003d \"Account request with id \u003d %s not found\";"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" // These constants are used as variable values to mean that the variable is in a \u0027special\u0027 state."},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" public static final int INT_UNINITIALIZED \u003d -9999;"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" public static final int MAX_POSSIBLE_RECIPIENTS \u003d -100;"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" public static final int POINTS_EQUAL_SHARE \u003d 100;"},{"lineNumber":60,"author":{"gitId":"-"},"content":" public static final int POINTS_NOT_SURE \u003d -101;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" public static final int POINTS_NOT_SUBMITTED \u003d -999;"},{"lineNumber":62,"author":{"gitId":"-"},"content":" public static final int POINTS_NO_VALUE \u003d Integer.MIN_VALUE;"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" public static final String GENERAL_QUESTION \u003d \"%GENERAL%\";"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" public static final Instant TIME_REPRESENTS_FOLLOW_OPENING;"},{"lineNumber":67,"author":{"gitId":"-"},"content":" public static final Instant TIME_REPRESENTS_FOLLOW_VISIBLE;"},{"lineNumber":68,"author":{"gitId":"-"},"content":" public static final Instant TIME_REPRESENTS_LATER;"},{"lineNumber":69,"author":{"gitId":"-"},"content":" public static final Instant TIME_REPRESENTS_NOW;"},{"lineNumber":70,"author":{"gitId":"-"},"content":" public static final Instant TIME_REPRESENTS_DEFAULT_TIMESTAMP;"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" static {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" TIME_REPRESENTS_FOLLOW_OPENING \u003d TimeHelper.parseInstant(\"1970-12-31T00:00:00Z\");"},{"lineNumber":74,"author":{"gitId":"-"},"content":" TIME_REPRESENTS_FOLLOW_VISIBLE \u003d TimeHelper.parseInstant(\"1970-06-22T00:00:00Z\");"},{"lineNumber":75,"author":{"gitId":"-"},"content":" TIME_REPRESENTS_LATER \u003d TimeHelper.parseInstant(\"1970-01-01T00:00:00Z\");"},{"lineNumber":76,"author":{"gitId":"-"},"content":" TIME_REPRESENTS_NOW \u003d TimeHelper.parseInstant(\"1970-02-14T00:00:00Z\");"},{"lineNumber":77,"author":{"gitId":"-"},"content":" TIME_REPRESENTS_DEFAULT_TIMESTAMP \u003d TimeHelper.parseInstant(\"2011-01-01T00:00:00Z\");"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" public static final String TEST_EMAIL_DOMAIN \u003d \"@gmail.tmt\";"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" // Other Constants"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" private Const() {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" // Utility class containing constants"},{"lineNumber":86,"author":{"gitId":"-"},"content":" }"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":89,"author":{"gitId":"-"},"content":" * Represents role names for instructors based on their permission settings."},{"lineNumber":90,"author":{"gitId":"-"},"content":" */"},{"lineNumber":91,"author":{"gitId":"-"},"content":" public static class InstructorPermissionRoleNames {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_PERMISSION_ROLE_COOWNER \u003d \"Co-owner\";"},{"lineNumber":93,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_PERMISSION_ROLE_MANAGER \u003d \"Manager\";"},{"lineNumber":94,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_PERMISSION_ROLE_OBSERVER \u003d \"Observer\";"},{"lineNumber":95,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_PERMISSION_ROLE_TUTOR \u003d \"Tutor\";"},{"lineNumber":96,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_PERMISSION_ROLE_CUSTOM \u003d \"Custom\";"},{"lineNumber":97,"author":{"gitId":"-"},"content":" }"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":100,"author":{"gitId":"-"},"content":" * Represents atomic permission for instructors."},{"lineNumber":101,"author":{"gitId":"-"},"content":" */"},{"lineNumber":102,"author":{"gitId":"-"},"content":" public static class InstructorPermissions {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" public static final String CAN_MODIFY_COURSE \u003d \"canmodifycourse\";"},{"lineNumber":104,"author":{"gitId":"-"},"content":" public static final String CAN_MODIFY_INSTRUCTOR \u003d \"canmodifyinstructor\";"},{"lineNumber":105,"author":{"gitId":"-"},"content":" public static final String CAN_MODIFY_SESSION \u003d \"canmodifysession\";"},{"lineNumber":106,"author":{"gitId":"-"},"content":" public static final String CAN_MODIFY_STUDENT \u003d \"canmodifystudent\";"},{"lineNumber":107,"author":{"gitId":"-"},"content":" public static final String CAN_VIEW_STUDENT_IN_SECTIONS \u003d \"canviewstudentinsection\";"},{"lineNumber":108,"author":{"gitId":"-"},"content":" public static final String CAN_VIEW_SESSION_IN_SECTIONS \u003d \"canviewsessioninsection\";"},{"lineNumber":109,"author":{"gitId":"-"},"content":" public static final String CAN_SUBMIT_SESSION_IN_SECTIONS \u003d \"cansubmitsessioninsection\";"},{"lineNumber":110,"author":{"gitId":"-"},"content":" public static final String CAN_MODIFY_SESSION_COMMENT_IN_SECTIONS \u003d \"canmodifysessioncommentinsection\";"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":114,"author":{"gitId":"-"},"content":" * Represents keys for HTTP requests to the API layer."},{"lineNumber":115,"author":{"gitId":"-"},"content":" */"},{"lineNumber":116,"author":{"gitId":"-"},"content":" public static class ParamsNames {"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" public static final String IS_IN_RECYCLE_BIN \u003d \"isinrecyclebin\";"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" public static final String IS_STUDENT_REJOINING \u003d \"isstudentrejoining\";"},{"lineNumber":121,"author":{"gitId":"-"},"content":" public static final String IS_INSTRUCTOR_REJOINING \u003d \"isinstructorrejoining\";"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" public static final String COURSE_ID \u003d \"courseid\";"},{"lineNumber":124,"author":{"gitId":"-"},"content":" public static final String COURSE_STATUS \u003d \"coursestatus\";"},{"lineNumber":125,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_ID \u003d \"instructorid\";"},{"lineNumber":126,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_EMAIL \u003d \"instructoremail\";"},{"lineNumber":127,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_INSTITUTION \u003d \"instructorinstitution\";"},{"lineNumber":128,"author":{"gitId":"-"},"content":" public static final String IS_CREATING_ACCOUNT \u003d \"iscreatingaccount\";"},{"lineNumber":129,"author":{"gitId":"-"},"content":" public static final String IS_INSTRUCTOR \u003d \"isinstructor\";"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" public static final String FEEDBACK_SESSION_ID \u003d \"fsid\";"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" public static final String ACCOUNT_REQUEST_ID \u003d \"id\";"},{"lineNumber":134,"author":{"gitId":"-"},"content":" public static final String ACCOUNT_REQUEST_STATUS \u003d \"status\";"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_NAME \u003d \"fsname\";"},{"lineNumber":137,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_STARTTIME \u003d \"starttime\";"},{"lineNumber":138,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_ENDTIME \u003d \"endtime\";"},{"lineNumber":139,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_MODERATED_PERSON \u003d \"moderatedperson\";"},{"lineNumber":140,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_LOG_TYPE \u003d \"fsltype\";"},{"lineNumber":141,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_LOG_STARTTIME \u003d \"fslstarttime\";"},{"lineNumber":142,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_LOG_ENDTIME \u003d \"fslendtime\";"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_QUESTION_ID \u003d \"questionid\";"},{"lineNumber":145,"author":{"gitId":"-"},"content":" public static final String SINGLE_RECIPIENT_ID_FOR_SUBMISSION \u003d \"singlerecipientidforsubmission\";"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_RESPONSE_ID \u003d \"responseid\";"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_RESPONSE_COMMENT_ID \u003d \"responsecommentid\";"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_RESULTS_GROUPBYSECTION \u003d \"frgroupbysection\";"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_RESULTS_SECTION_BY_GIVER_RECEIVER \u003d \"frsessionbygiverreceiver\";"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" public static final String PREVIEWAS \u003d \"previewas\";"},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":" public static final String STUDENT_SQL_ID \u003d \"studentid\";"},{"lineNumber":158,"author":{"gitId":"-"},"content":" public static final String STUDENT_ID \u003d \"googleid\";"},{"lineNumber":159,"author":{"gitId":"-"},"content":" public static final String INVITER_ID \u003d \"invitergoogleid\";"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" public static final String REGKEY \u003d \"key\";"},{"lineNumber":162,"author":{"gitId":"-"},"content":" public static final String STUDENT_EMAIL \u003d \"studentemail\";"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" public static final String SECTION_NAME \u003d \"sectionname\";"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" public static final String TEAM_NAME \u003d \"teamname\";"},{"lineNumber":167,"author":{"gitId":"-"},"content":""},{"lineNumber":168,"author":{"gitId":"-"},"content":" public static final String ERROR \u003d \"error\";"},{"lineNumber":169,"author":{"gitId":"-"},"content":" public static final String USER_ID \u003d \"user\";"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" public static final String SEARCH_KEY \u003d \"searchkey\";"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" public static final String USER_CAPTCHA_RESPONSE \u003d \"captcharesponse\";"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" public static final String EMAIL_TYPE \u003d \"emailtype\";"},{"lineNumber":176,"author":{"gitId":"-"},"content":" public static final String USER_EMAIL \u003d \"useremail\";"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" public static final String ENTITY_TYPE \u003d \"entitytype\";"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" public static final String INTENT \u003d \"intent\";"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" public static final String TIMEZONE \u003d \"timezone\";"},{"lineNumber":183,"author":{"gitId":"-"},"content":""},{"lineNumber":184,"author":{"gitId":"-"},"content":" public static final String NOTIFY_ABOUT_DEADLINES \u003d \"notifydeadlines\";"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_STARTTIME \u003d \"starttime\";"},{"lineNumber":187,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_ENDTIME \u003d \"endtime\";"},{"lineNumber":188,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_SEVERITY \u003d \"severity\";"},{"lineNumber":189,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_MIN_SEVERITY \u003d \"minseverity\";"},{"lineNumber":190,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_TRACE \u003d \"traceid\";"},{"lineNumber":191,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_ACTION_CLASS \u003d \"actionclass\";"},{"lineNumber":192,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_EMAIL \u003d \"email\";"},{"lineNumber":193,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_EVENT \u003d \"logevent\";"},{"lineNumber":194,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_SOURCE_LOCATION_FILE \u003d \"sourcelocationfile\";"},{"lineNumber":195,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_SOURCE_LOCATION_FUNCTION \u003d \"sourcelocationfunction\";"},{"lineNumber":196,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_EXCEPTION_CLASS \u003d \"exceptionclass\";"},{"lineNumber":197,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_LATENCY \u003d \"latency\";"},{"lineNumber":198,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_STATUS \u003d \"status\";"},{"lineNumber":199,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_VERSION \u003d \"version\";"},{"lineNumber":200,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_EXTRA_FILTERS \u003d \"extrafilters\";"},{"lineNumber":201,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_ORDER \u003d \"order\";"},{"lineNumber":202,"author":{"gitId":"-"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":" public static final String LIMIT \u003d \"limit\";"},{"lineNumber":204,"author":{"gitId":"-"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_ID \u003d \"notificationid\";"},{"lineNumber":206,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_TARGET_USER \u003d \"usertype\";"},{"lineNumber":207,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_IS_FETCHING_ALL \u003d \"isfetchingall\";"},{"lineNumber":208,"author":{"gitId":"-"},"content":" public static final String NOTFICATION_END_TIME \u003d \"endtime\";"},{"lineNumber":209,"author":{"gitId":"-"},"content":" public static final String CONTINUE_URL \u003d \"continueurl\";"},{"lineNumber":210,"author":{"gitId":"-"},"content":" }"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":213,"author":{"gitId":"-"},"content":" * Represents custom header names used by the system."},{"lineNumber":214,"author":{"gitId":"-"},"content":" */"},{"lineNumber":215,"author":{"gitId":"-"},"content":" public static class HeaderNames {"},{"lineNumber":216,"author":{"gitId":"-"},"content":" public static final String BACKDOOR_KEY \u003d \"Backdoor-Key\";"},{"lineNumber":217,"author":{"gitId":"-"},"content":" public static final String CSRF_KEY \u003d \"CSRF-Key\";"},{"lineNumber":218,"author":{"gitId":"-"},"content":" public static final String WEB_VERSION \u003d \"X-WEB-VERSION\";"},{"lineNumber":219,"author":{"gitId":"-"},"content":" public static final String CSRF_TOKEN \u003d \"X-CSRF-TOKEN\";"},{"lineNumber":220,"author":{"gitId":"-"},"content":" }"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":223,"author":{"gitId":"-"},"content":" * The course status respect to the instructor\u0027s point of view."},{"lineNumber":224,"author":{"gitId":"-"},"content":" * This parameter is used to get a course list for instructor."},{"lineNumber":225,"author":{"gitId":"-"},"content":" */"},{"lineNumber":226,"author":{"gitId":"-"},"content":" public static class CourseStatus {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" public static final String ACTIVE \u003d \"active\";"},{"lineNumber":228,"author":{"gitId":"-"},"content":" public static final String ARCHIVED \u003d \"archived\";"},{"lineNumber":229,"author":{"gitId":"-"},"content":" public static final String SOFT_DELETED \u003d \"softDeleted\";"},{"lineNumber":230,"author":{"gitId":"-"},"content":" }"},{"lineNumber":231,"author":{"gitId":"-"},"content":""},{"lineNumber":232,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":233,"author":{"gitId":"-"},"content":" * Represents user types."},{"lineNumber":234,"author":{"gitId":"-"},"content":" */"},{"lineNumber":235,"author":{"gitId":"-"},"content":" public static class EntityType {"},{"lineNumber":236,"author":{"gitId":"-"},"content":""},{"lineNumber":237,"author":{"gitId":"-"},"content":" public static final String STUDENT \u003d \"student\";"},{"lineNumber":238,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR \u003d \"instructor\";"},{"lineNumber":239,"author":{"gitId":"-"},"content":" public static final String ADMIN \u003d \"admin\";"},{"lineNumber":240,"author":{"gitId":"-"},"content":" public static final String MAINTAINER \u003d \"maintainer\";"},{"lineNumber":241,"author":{"gitId":"-"},"content":""},{"lineNumber":242,"author":{"gitId":"-"},"content":" }"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":245,"author":{"gitId":"-"},"content":" * Represents security-related configuration."},{"lineNumber":246,"author":{"gitId":"-"},"content":" */"},{"lineNumber":247,"author":{"gitId":"-"},"content":" public static class SecurityConfig {"},{"lineNumber":248,"author":{"gitId":"-"},"content":""},{"lineNumber":249,"author":{"gitId":"-"},"content":" public static final String CSRF_COOKIE_NAME \u003d \"CSRF-TOKEN\";"},{"lineNumber":250,"author":{"gitId":"-"},"content":" public static final String AUTH_COOKIE_NAME \u003d \"AUTH-TOKEN\";"},{"lineNumber":251,"author":{"gitId":"-"},"content":""},{"lineNumber":252,"author":{"gitId":"-"},"content":" }"},{"lineNumber":253,"author":{"gitId":"-"},"content":""},{"lineNumber":254,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":255,"author":{"gitId":"-"},"content":" * Represents URIs of accessible pages in the front-end in past versions (V6 and before)."},{"lineNumber":256,"author":{"gitId":"-"},"content":" */"},{"lineNumber":257,"author":{"gitId":"-"},"content":" @Deprecated"},{"lineNumber":258,"author":{"gitId":"-"},"content":" public static class LegacyURIs {"},{"lineNumber":259,"author":{"gitId":"-"},"content":""},{"lineNumber":260,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_COURSE_JOIN \u003d \"/page/instructorCourseJoin\";"},{"lineNumber":261,"author":{"gitId":"-"},"content":" public static final String STUDENT_COURSE_JOIN \u003d \"/page/studentCourseJoin\";"},{"lineNumber":262,"author":{"gitId":"-"},"content":" public static final String STUDENT_COURSE_JOIN_NEW \u003d \"/page/studentCourseJoinAuthentication\";"},{"lineNumber":263,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_HOME_PAGE \u003d \"/page/instructorHomePage\";"},{"lineNumber":264,"author":{"gitId":"-"},"content":" public static final String STUDENT_HOME_PAGE \u003d \"/page/studentHomePage\";"},{"lineNumber":265,"author":{"gitId":"-"},"content":" public static final String STUDENT_FEEDBACK_SUBMISSION_EDIT_PAGE \u003d \"/page/studentFeedbackSubmissionEditPage\";"},{"lineNumber":266,"author":{"gitId":"-"},"content":" public static final String STUDENT_FEEDBACK_RESULTS_PAGE \u003d \"/page/studentFeedbackResultsPage\";"},{"lineNumber":267,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_FEEDBACK_SUBMISSION_EDIT_PAGE \u003d \"/page/instructorFeedbackSubmissionEditPage\";"},{"lineNumber":268,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_FEEDBACK_RESULTS_PAGE \u003d \"/page/instructorFeedbackResultsPage\";"},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":273,"author":{"gitId":"-"},"content":" * Represents URIs of accessible pages in the front-end."},{"lineNumber":274,"author":{"gitId":"-"},"content":" */"},{"lineNumber":275,"author":{"gitId":"-"},"content":" public static class WebPageURIs {"},{"lineNumber":276,"author":{"gitId":"-"},"content":" public static final String LOGIN \u003d \"/login\";"},{"lineNumber":277,"author":{"gitId":"-"},"content":" public static final String LOGOUT \u003d \"/logout\";"},{"lineNumber":278,"author":{"gitId":"-"},"content":" private static final String URI_PREFIX \u003d \"/web\";"},{"lineNumber":279,"author":{"gitId":"-"},"content":""},{"lineNumber":280,"author":{"gitId":"-"},"content":" private static final String STUDENT_PAGE \u003d URI_PREFIX + \"/\" + EntityType.STUDENT;"},{"lineNumber":281,"author":{"gitId":"-"},"content":" private static final String INSTRUCTOR_PAGE \u003d URI_PREFIX + \"/\" + EntityType.INSTRUCTOR;"},{"lineNumber":282,"author":{"gitId":"-"},"content":" private static final String ADMIN_PAGE \u003d URI_PREFIX + \"/\" + EntityType.ADMIN;"},{"lineNumber":283,"author":{"gitId":"-"},"content":" private static final String MAINTAINER_PAGE \u003d URI_PREFIX + \"/\" + EntityType.MAINTAINER;"},{"lineNumber":284,"author":{"gitId":"-"},"content":" private static final String FRONT_PAGE \u003d URI_PREFIX + \"/front\";"},{"lineNumber":285,"author":{"gitId":"-"},"content":" public static final String JOIN_PAGE \u003d URI_PREFIX + \"/join\";"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"-"},"content":" public static final String ADMIN_HOME_PAGE \u003d ADMIN_PAGE + \"/home\";"},{"lineNumber":288,"author":{"gitId":"-"},"content":" public static final String ADMIN_ACCOUNTS_PAGE \u003d ADMIN_PAGE + \"/accounts\";"},{"lineNumber":289,"author":{"gitId":"-"},"content":" public static final String ADMIN_SEARCH_PAGE \u003d ADMIN_PAGE + \"/search\";"},{"lineNumber":290,"author":{"gitId":"-"},"content":" public static final String ADMIN_SESSIONS_PAGE \u003d ADMIN_PAGE + \"/sessions\";"},{"lineNumber":291,"author":{"gitId":"-"},"content":" public static final String ADMIN_TIMEZONE_PAGE \u003d ADMIN_PAGE + \"/timezone\";"},{"lineNumber":292,"author":{"gitId":"-"},"content":" public static final String ADMIN_LOGS_PAGE \u003d ADMIN_PAGE + \"/logs\";"},{"lineNumber":293,"author":{"gitId":"-"},"content":" public static final String ADMIN_NOTIFICATIONS_PAGE \u003d ADMIN_PAGE + \"/notifications\";"},{"lineNumber":294,"author":{"gitId":"-"},"content":""},{"lineNumber":295,"author":{"gitId":"-"},"content":" public static final String MAINTAINER_HOME_PAGE \u003d MAINTAINER_PAGE + \"/home\";"},{"lineNumber":296,"author":{"gitId":"-"},"content":""},{"lineNumber":297,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_HOME_PAGE \u003d INSTRUCTOR_PAGE + \"/home\";"},{"lineNumber":298,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_SEARCH_PAGE \u003d INSTRUCTOR_PAGE + \"/search\";"},{"lineNumber":299,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_SESSIONS_PAGE \u003d INSTRUCTOR_PAGE + \"/sessions\";"},{"lineNumber":300,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_SESSION_SUBMISSION_PAGE \u003d INSTRUCTOR_PAGE + \"/sessions/submission\";"},{"lineNumber":301,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_SESSION_EDIT_PAGE \u003d INSTRUCTOR_PAGE + \"/sessions/edit\";"},{"lineNumber":302,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_SESSION_INDIVIDUAL_EXTENSION_PAGE \u003d INSTRUCTOR_PAGE"},{"lineNumber":303,"author":{"gitId":"-"},"content":" + \"/sessions/individual-extension\";"},{"lineNumber":304,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_SESSION_RESULTS_PAGE \u003d INSTRUCTOR_PAGE + \"/sessions/result\";"},{"lineNumber":305,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_SESSION_REPORT_PAGE \u003d INSTRUCTOR_PAGE + \"/sessions/report\";"},{"lineNumber":306,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_COURSES_PAGE \u003d INSTRUCTOR_PAGE + \"/courses\";"},{"lineNumber":307,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_COURSE_DETAILS_PAGE \u003d INSTRUCTOR_PAGE + \"/courses/details\";"},{"lineNumber":308,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_COURSE_EDIT_PAGE \u003d INSTRUCTOR_PAGE + \"/courses/edit\";"},{"lineNumber":309,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_COURSE_ENROLL_PAGE \u003d INSTRUCTOR_PAGE + \"/courses/enroll\";"},{"lineNumber":310,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_COURSE_STUDENT_DETAILS_PAGE \u003d INSTRUCTOR_PAGE + \"/courses/student/details\";"},{"lineNumber":311,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_COURSE_STUDENT_DETAILS_EDIT_PAGE \u003d INSTRUCTOR_PAGE + \"/courses/student/edit\";"},{"lineNumber":312,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_STUDENT_LIST_PAGE \u003d INSTRUCTOR_PAGE + \"/students\";"},{"lineNumber":313,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_STUDENT_RECORDS_PAGE \u003d INSTRUCTOR_PAGE + \"/students/records\";"},{"lineNumber":314,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_STUDENT_ACTIVITY_LOGS_PAGE \u003d INSTRUCTOR_PAGE"},{"lineNumber":315,"author":{"gitId":"-"},"content":" + \"/courses/student-activity-logs\";"},{"lineNumber":316,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_NOTIFICATIONS_PAGE \u003d INSTRUCTOR_PAGE + \"/notifications\";"},{"lineNumber":317,"author":{"gitId":"-"},"content":""},{"lineNumber":318,"author":{"gitId":"-"},"content":" public static final String STUDENT_HOME_PAGE \u003d STUDENT_PAGE + \"/home\";"},{"lineNumber":319,"author":{"gitId":"-"},"content":" public static final String STUDENT_COURSE_DETAILS_PAGE \u003d STUDENT_PAGE + \"/course\";"},{"lineNumber":320,"author":{"gitId":"-"},"content":" public static final String STUDENT_SESSION_SUBMISSION_PAGE \u003d STUDENT_PAGE + \"/sessions/submission\";"},{"lineNumber":321,"author":{"gitId":"-"},"content":" public static final String STUDENT_SESSION_RESULTS_PAGE \u003d STUDENT_PAGE + \"/sessions/result\";"},{"lineNumber":322,"author":{"gitId":"-"},"content":" public static final String STUDENT_NOTIFICATIONS_PAGE \u003d STUDENT_PAGE + \"/notifications\";"},{"lineNumber":323,"author":{"gitId":"-"},"content":""},{"lineNumber":324,"author":{"gitId":"-"},"content":" public static final String SESSION_RESULTS_PAGE \u003d URI_PREFIX + \"/sessions/result\";"},{"lineNumber":325,"author":{"gitId":"-"},"content":" public static final String SESSION_SUBMISSION_PAGE \u003d URI_PREFIX + \"/sessions/submission\";"},{"lineNumber":326,"author":{"gitId":"-"},"content":" public static final String SESSIONS_LINK_RECOVERY_PAGE \u003d FRONT_PAGE + \"/help/session-links-recovery\";"},{"lineNumber":327,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":328,"author":{"gitId":"dishenggg"},"content":" public static final String ACCOUNT_REQUEST_PAGE \u003d FRONT_PAGE + \"/request\";"},{"lineNumber":329,"author":{"gitId":"-"},"content":" }"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":332,"author":{"gitId":"-"},"content":" * Represents URIs of resource endpoints."},{"lineNumber":333,"author":{"gitId":"-"},"content":" */"},{"lineNumber":334,"author":{"gitId":"-"},"content":" public static class ResourceURIs {"},{"lineNumber":335,"author":{"gitId":"-"},"content":" private static final String URI_PREFIX \u003d \"/webapi\";"},{"lineNumber":336,"author":{"gitId":"-"},"content":""},{"lineNumber":337,"author":{"gitId":"-"},"content":" public static final String DATABUNDLE \u003d URI_PREFIX + \"/databundle\";"},{"lineNumber":338,"author":{"gitId":"-"},"content":" public static final String SQL_DATABUNDLE \u003d URI_PREFIX + \"/databundle/sql\";"},{"lineNumber":339,"author":{"gitId":"-"},"content":" public static final String DATABUNDLE_DOCUMENTS \u003d URI_PREFIX + \"/databundle/documents\";"},{"lineNumber":340,"author":{"gitId":"-"},"content":" public static final String DEADLINE_EXTENSION \u003d URI_PREFIX + \"/deadlineextension\";"},{"lineNumber":341,"author":{"gitId":"-"},"content":" public static final String EXCEPTION \u003d URI_PREFIX + \"/exception\";"},{"lineNumber":342,"author":{"gitId":"-"},"content":" public static final String ERROR_REPORT \u003d URI_PREFIX + \"/errorreport\";"},{"lineNumber":343,"author":{"gitId":"-"},"content":" public static final String AUTH \u003d URI_PREFIX + \"/auth\";"},{"lineNumber":344,"author":{"gitId":"-"},"content":" public static final String AUTH_REGKEY \u003d URI_PREFIX + \"/auth/regkey\";"},{"lineNumber":345,"author":{"gitId":"-"},"content":" public static final String ACCOUNT \u003d URI_PREFIX + \"/account\";"},{"lineNumber":346,"author":{"gitId":"-"},"content":" public static final String ACCOUNT_RESET \u003d URI_PREFIX + \"/account/reset\";"},{"lineNumber":347,"author":{"gitId":"-"},"content":" public static final String ACCOUNT_REQUEST \u003d URI_PREFIX + \"/account/request\";"},{"lineNumber":348,"author":{"gitId":"-"},"content":" public static final String ACCOUNT_REQUESTS \u003d URI_PREFIX + \"/account/requests\";"},{"lineNumber":349,"author":{"gitId":"-"},"content":" public static final String ACCOUNT_REQUEST_RESET \u003d ACCOUNT_REQUEST + \"/reset\";"},{"lineNumber":350,"author":{"gitId":"xenosf"},"content":" public static final String ACCOUNT_REQUEST_REJECTION \u003d ACCOUNT_REQUEST + \"/rejection\";"},{"lineNumber":351,"author":{"gitId":"-"},"content":" public static final String ACCOUNTS \u003d URI_PREFIX + \"/accounts\";"},{"lineNumber":352,"author":{"gitId":"-"},"content":" public static final String RESPONSE_COMMENT \u003d URI_PREFIX + \"/responsecomment\";"},{"lineNumber":353,"author":{"gitId":"-"},"content":" public static final String COURSE \u003d URI_PREFIX + \"/course\";"},{"lineNumber":354,"author":{"gitId":"-"},"content":" public static final String COURSE_ARCHIVE \u003d URI_PREFIX + \"/course/archive\";"},{"lineNumber":355,"author":{"gitId":"-"},"content":" public static final String BIN_COURSE \u003d URI_PREFIX + \"/bin/course\";"},{"lineNumber":356,"author":{"gitId":"-"},"content":" public static final String COURSE_SECTIONS \u003d URI_PREFIX + \"/course/sections\";"},{"lineNumber":357,"author":{"gitId":"-"},"content":" public static final String COURSES \u003d URI_PREFIX + \"/courses\";"},{"lineNumber":358,"author":{"gitId":"-"},"content":" public static final String INSTRUCTORS \u003d URI_PREFIX + \"/instructors\";"},{"lineNumber":359,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR \u003d URI_PREFIX + \"/instructor\";"},{"lineNumber":360,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_PRIVILEGE \u003d URI_PREFIX + \"/instructor/privilege\";"},{"lineNumber":361,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_KEY \u003d URI_PREFIX + \"/instructor/key\";"},{"lineNumber":362,"author":{"gitId":"-"},"content":" public static final String RESULT \u003d URI_PREFIX + \"/result\";"},{"lineNumber":363,"author":{"gitId":"-"},"content":" public static final String STUDENTS \u003d URI_PREFIX + \"/students\";"},{"lineNumber":364,"author":{"gitId":"-"},"content":" public static final String STUDENT \u003d URI_PREFIX + \"/student\";"},{"lineNumber":365,"author":{"gitId":"-"},"content":" public static final String STUDENT_KEY \u003d URI_PREFIX + \"/student/key\";"},{"lineNumber":366,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION \u003d URI_PREFIX + \"/notification\";"},{"lineNumber":367,"author":{"gitId":"-"},"content":" public static final String NOTIFICATIONS \u003d URI_PREFIX + \"/notifications\";"},{"lineNumber":368,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_READ \u003d URI_PREFIX + \"/notification/read\";"},{"lineNumber":369,"author":{"gitId":"-"},"content":" public static final String SESSIONS_ONGOING \u003d URI_PREFIX + \"/sessions/ongoing\";"},{"lineNumber":370,"author":{"gitId":"-"},"content":" public static final String SESSION \u003d URI_PREFIX + \"/session\";"},{"lineNumber":371,"author":{"gitId":"-"},"content":" public static final String SESSION_PUBLISH \u003d URI_PREFIX + \"/session/publish\";"},{"lineNumber":372,"author":{"gitId":"-"},"content":" public static final String SESSION_REMIND_SUBMISSION \u003d URI_PREFIX + \"/session/remind/submission\";"},{"lineNumber":373,"author":{"gitId":"-"},"content":" public static final String SESSION_REMIND_RESULT \u003d URI_PREFIX + \"/session/remind/result\";"},{"lineNumber":374,"author":{"gitId":"-"},"content":" public static final String SESSION_STATS \u003d URI_PREFIX + \"/session/stats\";"},{"lineNumber":375,"author":{"gitId":"-"},"content":" public static final String SESSION_SUBMITTED_GIVER_SET \u003d URI_PREFIX + \"/session/submitted/giverset\";"},{"lineNumber":376,"author":{"gitId":"-"},"content":" public static final String SESSIONS \u003d URI_PREFIX + \"/sessions\";"},{"lineNumber":377,"author":{"gitId":"-"},"content":" public static final String SEARCH_ACCOUNT_REQUESTS \u003d URI_PREFIX + \"/search/accountrequests\";"},{"lineNumber":378,"author":{"gitId":"-"},"content":" public static final String SEARCH_INSTRUCTORS \u003d URI_PREFIX + \"/search/instructors\";"},{"lineNumber":379,"author":{"gitId":"-"},"content":" public static final String SEARCH_STUDENTS \u003d URI_PREFIX + \"/search/students\";"},{"lineNumber":380,"author":{"gitId":"-"},"content":" public static final String BIN_SESSION \u003d URI_PREFIX + \"/bin/session\";"},{"lineNumber":381,"author":{"gitId":"-"},"content":" public static final String QUESTIONS \u003d URI_PREFIX + \"/questions\";"},{"lineNumber":382,"author":{"gitId":"-"},"content":" public static final String QUESTION \u003d URI_PREFIX + \"/question\";"},{"lineNumber":383,"author":{"gitId":"-"},"content":" public static final String QUESTION_RECIPIENTS \u003d URI_PREFIX + \"/question/recipients\";"},{"lineNumber":384,"author":{"gitId":"-"},"content":" public static final String RESPONSES \u003d URI_PREFIX + \"/responses\";"},{"lineNumber":385,"author":{"gitId":"-"},"content":" public static final String USAGE_STATISTICS \u003d URI_PREFIX + \"/usagestats\";"},{"lineNumber":386,"author":{"gitId":"-"},"content":" public static final String HAS_RESPONSES \u003d URI_PREFIX + \"/hasResponses\";"},{"lineNumber":387,"author":{"gitId":"-"},"content":" public static final String JOIN \u003d URI_PREFIX + \"/join\";"},{"lineNumber":388,"author":{"gitId":"-"},"content":" public static final String JOIN_REMIND \u003d URI_PREFIX + \"/join/remind\";"},{"lineNumber":389,"author":{"gitId":"-"},"content":" public static final String TIMEZONE \u003d URI_PREFIX + \"/timezone\";"},{"lineNumber":390,"author":{"gitId":"-"},"content":" public static final String SESSION_LINKS_RECOVERY \u003d URI_PREFIX + \"/sessionlinksrecovery\";"},{"lineNumber":391,"author":{"gitId":"-"},"content":" public static final String EMAIL \u003d URI_PREFIX + \"/email\";"},{"lineNumber":392,"author":{"gitId":"-"},"content":" public static final String LOGIN_EMAIL \u003d URI_PREFIX + \"/email/login\";"},{"lineNumber":393,"author":{"gitId":"-"},"content":" public static final String SESSION_LOGS \u003d URI_PREFIX + \"/logs/session\";"},{"lineNumber":394,"author":{"gitId":"-"},"content":" public static final String LOGS \u003d URI_PREFIX + \"/logs/query\";"},{"lineNumber":395,"author":{"gitId":"-"},"content":" public static final String ACTION_CLASS \u003d URI_PREFIX + \"/actionclass\";"},{"lineNumber":396,"author":{"gitId":"-"},"content":" public static final String USER_COOKIE \u003d URI_PREFIX + \"/cookie\";"},{"lineNumber":397,"author":{"gitId":"-"},"content":" }"},{"lineNumber":398,"author":{"gitId":"-"},"content":""},{"lineNumber":399,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":400,"author":{"gitId":"-"},"content":" * Represents URIs of endpoints used by cron jobs."},{"lineNumber":401,"author":{"gitId":"-"},"content":" */"},{"lineNumber":402,"author":{"gitId":"-"},"content":" public static class CronJobURIs {"},{"lineNumber":403,"author":{"gitId":"-"},"content":" private static final String URI_PREFIX \u003d \"/auto\";"},{"lineNumber":404,"author":{"gitId":"-"},"content":""},{"lineNumber":405,"author":{"gitId":"-"},"content":" public static final String AUTOMATED_LOG_COMPILATION \u003d URI_PREFIX + \"/compileLogs\";"},{"lineNumber":406,"author":{"gitId":"-"},"content":" public static final String AUTOMATED_DATASTORE_BACKUP \u003d URI_PREFIX + \"/datastoreBackup\";"},{"lineNumber":407,"author":{"gitId":"-"},"content":" public static final String AUTOMATED_FEEDBACK_OPENING_SOON_REMINDERS \u003d"},{"lineNumber":408,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/feedbackSessionOpeningSoonReminders\";"},{"lineNumber":409,"author":{"gitId":"-"},"content":" public static final String AUTOMATED_FEEDBACK_OPENING_REMINDERS \u003d"},{"lineNumber":410,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/feedbackSessionOpeningReminders\";"},{"lineNumber":411,"author":{"gitId":"-"},"content":" public static final String AUTOMATED_FEEDBACK_CLOSED_REMINDERS \u003d"},{"lineNumber":412,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/feedbackSessionClosedReminders\";"},{"lineNumber":413,"author":{"gitId":"-"},"content":" public static final String AUTOMATED_FEEDBACK_CLOSING_REMINDERS \u003d"},{"lineNumber":414,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/feedbackSessionClosingReminders\";"},{"lineNumber":415,"author":{"gitId":"-"},"content":" public static final String AUTOMATED_FEEDBACK_PUBLISHED_REMINDERS \u003d"},{"lineNumber":416,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/feedbackSessionPublishedReminders\";"},{"lineNumber":417,"author":{"gitId":"-"},"content":" public static final String AUTOMATED_USAGE_STATISTICS_COLLECTION \u003d"},{"lineNumber":418,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/calculateUsageStatistics\";"},{"lineNumber":419,"author":{"gitId":"dishenggg"},"content":" public static final String AUTOMATED_FEEDBACK_SESSION_LOGS_PROCESSING \u003d"},{"lineNumber":420,"author":{"gitId":"dishenggg"},"content":" URI_PREFIX + \"/updateFeedbackSessionLogs\";"},{"lineNumber":421,"author":{"gitId":"-"},"content":" }"},{"lineNumber":422,"author":{"gitId":"-"},"content":""},{"lineNumber":423,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":424,"author":{"gitId":"-"},"content":" * Configurations for task queue."},{"lineNumber":425,"author":{"gitId":"-"},"content":" */"},{"lineNumber":426,"author":{"gitId":"-"},"content":" public static class TaskQueue {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" public static final String URI_PREFIX \u003d \"/worker\";"},{"lineNumber":428,"author":{"gitId":"-"},"content":""},{"lineNumber":429,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_PUBLISHED_EMAIL_QUEUE_NAME \u003d"},{"lineNumber":430,"author":{"gitId":"-"},"content":" \"feedback-session-published-email-queue\";"},{"lineNumber":431,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_PUBLISHED_EMAIL_WORKER_URL \u003d"},{"lineNumber":432,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/feedbackSessionPublishedEmail\";"},{"lineNumber":433,"author":{"gitId":"-"},"content":""},{"lineNumber":434,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_RESEND_PUBLISHED_EMAIL_QUEUE_NAME \u003d"},{"lineNumber":435,"author":{"gitId":"-"},"content":" \"feedback-session-resend-published-email-queue\";"},{"lineNumber":436,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_RESEND_PUBLISHED_EMAIL_WORKER_URL \u003d"},{"lineNumber":437,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/feedbackSessionResendPublishedEmail\";"},{"lineNumber":438,"author":{"gitId":"-"},"content":""},{"lineNumber":439,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_REMIND_EMAIL_QUEUE_NAME \u003d \"feedback-session-remind-email-queue\";"},{"lineNumber":440,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_REMIND_EMAIL_WORKER_URL \u003d URI_PREFIX + \"/feedbackSessionRemindEmail\";"},{"lineNumber":441,"author":{"gitId":"-"},"content":""},{"lineNumber":442,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_REMIND_PARTICULAR_USERS_EMAIL_QUEUE_NAME \u003d"},{"lineNumber":443,"author":{"gitId":"-"},"content":" \"feedback-session-remind-particular-users-email-queue\";"},{"lineNumber":444,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_REMIND_PARTICULAR_USERS_EMAIL_WORKER_URL \u003d"},{"lineNumber":445,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/feedbackSessionRemindParticularUsersEmail\";"},{"lineNumber":446,"author":{"gitId":"-"},"content":""},{"lineNumber":447,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_UNPUBLISHED_EMAIL_QUEUE_NAME \u003d"},{"lineNumber":448,"author":{"gitId":"-"},"content":" \"feedback-session-unpublished-email-queue\";"},{"lineNumber":449,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_UNPUBLISHED_EMAIL_WORKER_URL \u003d"},{"lineNumber":450,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/feedbackSessionUnpublishedEmail\";"},{"lineNumber":451,"author":{"gitId":"-"},"content":""},{"lineNumber":452,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_COURSE_JOIN_EMAIL_QUEUE_NAME \u003d \"instructor-course-join-email-queue\";"},{"lineNumber":453,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_COURSE_JOIN_EMAIL_WORKER_URL \u003d URI_PREFIX + \"/instructorCourseJoinEmail\";"},{"lineNumber":454,"author":{"gitId":"-"},"content":""},{"lineNumber":455,"author":{"gitId":"-"},"content":" public static final String SEND_EMAIL_QUEUE_NAME \u003d \"send-email-queue\";"},{"lineNumber":456,"author":{"gitId":"-"},"content":" public static final String SEND_EMAIL_WORKER_URL \u003d URI_PREFIX + \"/sendEmail\";"},{"lineNumber":457,"author":{"gitId":"-"},"content":""},{"lineNumber":458,"author":{"gitId":"-"},"content":" public static final String STUDENT_COURSE_JOIN_EMAIL_QUEUE_NAME \u003d \"student-course-join-email-queue\";"},{"lineNumber":459,"author":{"gitId":"-"},"content":" public static final String STUDENT_COURSE_JOIN_EMAIL_WORKER_URL \u003d URI_PREFIX + \"/studentCourseJoinEmail\";"},{"lineNumber":460,"author":{"gitId":"-"},"content":""},{"lineNumber":461,"author":{"gitId":"-"},"content":" public static final String SEARCH_INDEXING_QUEUE_NAME \u003d \"search-indexing-queue\";"},{"lineNumber":462,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_SEARCH_INDEXING_WORKER_URL \u003d URI_PREFIX + \"/instructorSearchIndexing\";"},{"lineNumber":463,"author":{"gitId":"-"},"content":" public static final String ACCOUNT_REQUEST_SEARCH_INDEXING_WORKER_URL \u003d"},{"lineNumber":464,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/accountRequestSearchIndexing\";"},{"lineNumber":465,"author":{"gitId":"-"},"content":" public static final String STUDENT_SEARCH_INDEXING_WORKER_URL \u003d URI_PREFIX + \"/studentSearchIndexing\";"},{"lineNumber":466,"author":{"gitId":"-"},"content":" }"},{"lineNumber":467,"author":{"gitId":"-"},"content":""},{"lineNumber":468,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":5,"dishenggg":9,"-":454}},{"path":"src/main/java/teammates/common/util/EmailType.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.util;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":4,"author":{"gitId":"-"},"content":" * The type object that defines an email based on its purpose."},{"lineNumber":5,"author":{"gitId":"-"},"content":" */"},{"lineNumber":6,"author":{"gitId":"-"},"content":"public enum EmailType {"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":" // CHECKSTYLE.OFF:JavadocVariable enum names are self-documenting"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":" DEADLINE_EXTENSION_GRANTED(\"TEAMMATES: Deadline extension granted [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":11,"author":{"gitId":"-"},"content":" DEADLINE_EXTENSION_UPDATED(\"TEAMMATES: Deadline extension updated [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":12,"author":{"gitId":"-"},"content":" DEADLINE_EXTENSION_REVOKED(\"TEAMMATES: Deadline extension revoked [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":13,"author":{"gitId":"-"},"content":" FEEDBACK_OPENING_SOON(\"TEAMMATES: Feedback session opening soon [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":14,"author":{"gitId":"-"},"content":" FEEDBACK_OPENING(\"TEAMMATES: Feedback session now open [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":15,"author":{"gitId":"-"},"content":" FEEDBACK_SESSION_REMINDER(\"TEAMMATES: Feedback session reminder [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":16,"author":{"gitId":"-"},"content":" FEEDBACK_CLOSING(\"TEAMMATES: Feedback session closing soon [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":17,"author":{"gitId":"-"},"content":" FEEDBACK_CLOSED(\"TEAMMATES: Feedback session closed [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":18,"author":{"gitId":"-"},"content":" FEEDBACK_PUBLISHED(\"TEAMMATES: Feedback session results published [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":19,"author":{"gitId":"-"},"content":" FEEDBACK_UNPUBLISHED(\"TEAMMATES: Feedback session results unpublished [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":20,"author":{"gitId":"-"},"content":" STUDENT_EMAIL_CHANGED(\"TEAMMATES: Summary of course [%s][Course ID: %s]\"),"},{"lineNumber":21,"author":{"gitId":"-"},"content":" STUDENT_COURSE_LINKS_REGENERATED(\"TEAMMATES: Your updated links for course [%s][Course ID: %s]\"),"},{"lineNumber":22,"author":{"gitId":"-"},"content":" INSTRUCTOR_COURSE_LINKS_REGENERATED(\"TEAMMATES: Your updated links for course [%s][Course ID: %s]\"),"},{"lineNumber":23,"author":{"gitId":"-"},"content":" NEW_INSTRUCTOR_ACCOUNT(\"TEAMMATES: Welcome to TEAMMATES! %s\"),"},{"lineNumber":24,"author":{"gitId":"-"},"content":" STUDENT_COURSE_JOIN(\"TEAMMATES: Invitation to join course [%s][Course ID: %s]\"),"},{"lineNumber":25,"author":{"gitId":"-"},"content":" STUDENT_COURSE_REJOIN_AFTER_GOOGLE_ID_RESET(\"TEAMMATES: Your account has been reset for course [%s][Course ID: %s]\"),"},{"lineNumber":26,"author":{"gitId":"-"},"content":" NEW_ACCOUNT_REQUEST_ADMIN_ALERT(\"TEAMMATES (Action Needed): New Account Request Received\"),"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT(\"TEAMMATES: Acknowledgement of Instructor Account Request\"),"},{"lineNumber":28,"author":{"gitId":"-"},"content":" ACCOUNT_REQUEST_REJECTION(\"TEAMMATES: %s\"),"},{"lineNumber":29,"author":{"gitId":"-"},"content":" INSTRUCTOR_COURSE_JOIN(\"TEAMMATES: Invitation to join course as an instructor [%s][Course ID: %s]\"),"},{"lineNumber":30,"author":{"gitId":"-"},"content":" INSTRUCTOR_COURSE_REJOIN_AFTER_GOOGLE_ID_RESET(\"TEAMMATES: Your account has been reset for course [%s][Course ID: %s]\"),"},{"lineNumber":31,"author":{"gitId":"-"},"content":" USER_COURSE_REGISTER(\"TEAMMATES: Registered for Course [%s][Course ID: %s]\"),"},{"lineNumber":32,"author":{"gitId":"-"},"content":" SEVERE_LOGS_COMPILATION(\"TEAMMATES (%s): Severe Error Logs Compilation\"),"},{"lineNumber":33,"author":{"gitId":"-"},"content":" SESSION_LINKS_RECOVERY(\"TEAMMATES: Access links for recent feedback sessions\"),"},{"lineNumber":34,"author":{"gitId":"-"},"content":" LOGIN(\"TEAMMATES: Log in to TEAMMATES\");"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" private final String subject;"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" EmailType(String subject) {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.subject \u003d subject;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":43,"author":{"gitId":"-"},"content":" * Gets the subject heading of this email type."},{"lineNumber":44,"author":{"gitId":"-"},"content":" */"},{"lineNumber":45,"author":{"gitId":"-"},"content":" public String getSubject() {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" return subject;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" }"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":1,"-":48}},{"path":"src/main/java/teammates/common/util/FieldValidator.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.util;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Duration;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.LocalDateTime;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.time.ZoneId;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.Arrays;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.Collection;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.Collections;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.HashSet;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import java.util.LinkedList;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import java.util.Set;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import java.util.function.BiPredicate;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationStyle;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationTargetUser;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * Used to handle the data validation aspect e.g. validate emails, names, etc."},{"lineNumber":25,"author":{"gitId":"-"},"content":" */"},{"lineNumber":26,"author":{"gitId":"-"},"content":"public final class FieldValidator {"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" /////////////////"},{"lineNumber":29,"author":{"gitId":"-"},"content":" // FIELD TYPES //"},{"lineNumber":30,"author":{"gitId":"-"},"content":" /////////////////"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" // name-related"},{"lineNumber":33,"author":{"gitId":"-"},"content":" public static final String PERSON_NAME_FIELD_NAME \u003d \"person name\";"},{"lineNumber":34,"author":{"gitId":"-"},"content":" public static final int PERSON_NAME_MAX_LENGTH \u003d 100;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" public static final String COURSE_NAME_FIELD_NAME \u003d \"course name\";"},{"lineNumber":37,"author":{"gitId":"-"},"content":" public static final int COURSE_NAME_MAX_LENGTH \u003d 80;"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_NAME_FIELD_NAME \u003d \"feedback session name\";"},{"lineNumber":40,"author":{"gitId":"-"},"content":" public static final int FEEDBACK_SESSION_NAME_MAX_LENGTH \u003d 64;"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" public static final String TEAM_NAME_FIELD_NAME \u003d \"team name\";"},{"lineNumber":43,"author":{"gitId":"-"},"content":" public static final int TEAM_NAME_MAX_LENGTH \u003d 60;"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" public static final String SECTION_NAME_FIELD_NAME \u003d \"section name\";"},{"lineNumber":46,"author":{"gitId":"-"},"content":" public static final int SECTION_NAME_MAX_LENGTH \u003d 60;"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" public static final String INSTITUTE_NAME_FIELD_NAME \u003d \"institute name\";"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" public static final int INSTITUTE_NAME_MAX_LENGTH \u003d 128;"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" // email-related"},{"lineNumber":52,"author":{"gitId":"-"},"content":" public static final String EMAIL_FIELD_NAME \u003d \"email\";"},{"lineNumber":53,"author":{"gitId":"-"},"content":" public static final int EMAIL_MAX_LENGTH \u003d 254;"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" // notification-related"},{"lineNumber":56,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_TITLE_FIELD_NAME \u003d \"notification title\";"},{"lineNumber":57,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_MESSAGE_FIELD_NAME \u003d \"notification message\";"},{"lineNumber":58,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_NAME \u003d \"notification\";"},{"lineNumber":59,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_VISIBLE_TIME_FIELD_NAME \u003d \"time when the notification will be visible\";"},{"lineNumber":60,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_EXPIRY_TIME_FIELD_NAME \u003d \"time when the notification will expire\";"},{"lineNumber":61,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_STYLE_FIELD_NAME \u003d \"notification style\";"},{"lineNumber":62,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_TARGET_USER_FIELD_NAME \u003d \"notification target user\";"},{"lineNumber":63,"author":{"gitId":"-"},"content":" public static final int NOTIFICATION_TITLE_MAX_LENGTH \u003d 80;"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" public static final List\u003cString\u003e NOTIFICATION_STYLE_ACCEPTED_VALUES \u003d"},{"lineNumber":66,"author":{"gitId":"-"},"content":" Collections.unmodifiableList("},{"lineNumber":67,"author":{"gitId":"-"},"content":" Arrays.stream("},{"lineNumber":68,"author":{"gitId":"-"},"content":" NotificationStyle.values())"},{"lineNumber":69,"author":{"gitId":"-"},"content":" .map(NotificationStyle::toString)"},{"lineNumber":70,"author":{"gitId":"-"},"content":" .collect(Collectors.toList())"},{"lineNumber":71,"author":{"gitId":"-"},"content":" );"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" public static final List\u003cString\u003e NOTIFICATION_TARGET_USER_ACCEPTED_VALUES \u003d"},{"lineNumber":74,"author":{"gitId":"-"},"content":" Collections.unmodifiableList("},{"lineNumber":75,"author":{"gitId":"-"},"content":" Arrays.stream("},{"lineNumber":76,"author":{"gitId":"-"},"content":" NotificationTargetUser.values())"},{"lineNumber":77,"author":{"gitId":"-"},"content":" .map(NotificationTargetUser::toString)"},{"lineNumber":78,"author":{"gitId":"-"},"content":" .collect(Collectors.toList())"},{"lineNumber":79,"author":{"gitId":"-"},"content":" );"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" // others"},{"lineNumber":82,"author":{"gitId":"-"},"content":" public static final String STUDENT_ROLE_COMMENTS_FIELD_NAME \u003d \"comments about a student enrolled in a course\";"},{"lineNumber":83,"author":{"gitId":"-"},"content":" public static final int STUDENT_ROLE_COMMENTS_MAX_LENGTH \u003d 500;"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" /*"},{"lineNumber":86,"author":{"gitId":"-"},"content":" * \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"lineNumber":87,"author":{"gitId":"-"},"content":" * Field: Course ID"},{"lineNumber":88,"author":{"gitId":"-"},"content":" * Unique: system-wide, not just among the course of that instructor."},{"lineNumber":89,"author":{"gitId":"-"},"content":" * Technically, we can get rid of CourseID field and enforce users to use"},{"lineNumber":90,"author":{"gitId":"-"},"content":" * CourseName as a unique ID. In that case, we have to enforce CourseName"},{"lineNumber":91,"author":{"gitId":"-"},"content":" * must be unique across the full system. However, users expect names to be"},{"lineNumber":92,"author":{"gitId":"-"},"content":" * non-unique and more tolerant of enforcing uniqueness on an ID. Whenever"},{"lineNumber":93,"author":{"gitId":"-"},"content":" * possible, must be displayed in the same case as user entered. This is"},{"lineNumber":94,"author":{"gitId":"-"},"content":" * because the case of the letters can mean something. Furthermore,"},{"lineNumber":95,"author":{"gitId":"-"},"content":" * converting to same case can reduce readability."},{"lineNumber":96,"author":{"gitId":"-"},"content":" *"},{"lineNumber":97,"author":{"gitId":"-"},"content":" * Course ID is necessary because the course name is not unique enough to"},{"lineNumber":98,"author":{"gitId":"-"},"content":" * distinguish between courses because the same course can be offered"},{"lineNumber":99,"author":{"gitId":"-"},"content":" * multiple times and courses can be shared between instructors and many"},{"lineNumber":100,"author":{"gitId":"-"},"content":" * students. Allowing same Course ID among different instructors could be"},{"lineNumber":101,"author":{"gitId":"-"},"content":" * problematic if we allow multiple instructors for a single course."},{"lineNumber":102,"author":{"gitId":"-"},"content":" * TODO: make case insensitive"},{"lineNumber":103,"author":{"gitId":"-"},"content":" */"},{"lineNumber":104,"author":{"gitId":"-"},"content":" public static final String COURSE_ID_FIELD_NAME \u003d \"course ID\";"},{"lineNumber":105,"author":{"gitId":"-"},"content":" public static final int COURSE_ID_MAX_LENGTH \u003d 64;"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" public static final String SESSION_NAME \u003d \"feedback session\";"},{"lineNumber":108,"author":{"gitId":"-"},"content":" public static final String SESSION_START_TIME_FIELD_NAME \u003d \"start time\";"},{"lineNumber":109,"author":{"gitId":"-"},"content":" public static final String SESSION_END_TIME_FIELD_NAME \u003d \"end time\";"},{"lineNumber":110,"author":{"gitId":"-"},"content":" public static final String TIME_ZONE_FIELD_NAME \u003d \"time zone\";"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" public static final String GOOGLE_ID_FIELD_NAME \u003d \"Google ID\";"},{"lineNumber":113,"author":{"gitId":"-"},"content":" public static final int GOOGLE_ID_MAX_LENGTH \u003d 254;"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" public static final String ROLE_FIELD_NAME \u003d \"access-level\";"},{"lineNumber":116,"author":{"gitId":"-"},"content":" public static final List\u003cString\u003e ROLE_ACCEPTED_VALUES \u003d"},{"lineNumber":117,"author":{"gitId":"-"},"content":" Collections.unmodifiableList("},{"lineNumber":118,"author":{"gitId":"-"},"content":" Arrays.asList(Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_COOWNER,"},{"lineNumber":119,"author":{"gitId":"-"},"content":" Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_MANAGER,"},{"lineNumber":120,"author":{"gitId":"-"},"content":" Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_OBSERVER,"},{"lineNumber":121,"author":{"gitId":"-"},"content":" Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_TUTOR,"},{"lineNumber":122,"author":{"gitId":"-"},"content":" Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_CUSTOM));"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" public static final String GIVER_TYPE_NAME \u003d \"feedback giver\";"},{"lineNumber":125,"author":{"gitId":"-"},"content":" public static final String RECIPIENT_TYPE_NAME \u003d \"feedback recipient\";"},{"lineNumber":126,"author":{"gitId":"-"},"content":" public static final String VIEWER_TYPE_NAME \u003d \"feedback viewer\";"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" public static final String EXTENDED_DEADLINES_FIELD_NAME \u003d \"extended deadlines\";"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" ////////////////////"},{"lineNumber":131,"author":{"gitId":"-"},"content":" // ERROR MESSAGES //"},{"lineNumber":132,"author":{"gitId":"-"},"content":" ////////////////////"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" public static final String REASON_TOO_LONG \u003d \"is too long\";"},{"lineNumber":135,"author":{"gitId":"-"},"content":" public static final String REASON_INCORRECT_FORMAT \u003d \"is not in the correct format\";"},{"lineNumber":136,"author":{"gitId":"-"},"content":" public static final String REASON_CONTAINS_INVALID_CHAR \u003d \"contains invalid characters\";"},{"lineNumber":137,"author":{"gitId":"-"},"content":" public static final String REASON_START_WITH_NON_ALPHANUMERIC_CHAR \u003d \"starts with a non-alphanumeric character\";"},{"lineNumber":138,"author":{"gitId":"-"},"content":" public static final String REASON_UNAVAILABLE_AS_CHOICE \u003d \"is not available as a choice\";"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" // error message components"},{"lineNumber":141,"author":{"gitId":"-"},"content":" public static final String EMPTY_STRING_ERROR_INFO \u003d"},{"lineNumber":142,"author":{"gitId":"-"},"content":" \"The field \u0027${fieldName}\u0027 is empty.\";"},{"lineNumber":143,"author":{"gitId":"-"},"content":" public static final String ERROR_INFO \u003d"},{"lineNumber":144,"author":{"gitId":"-"},"content":" \"\\\"${userInput}\\\" is not acceptable to TEAMMATES as a/an ${fieldName} because it ${reason}.\";"},{"lineNumber":145,"author":{"gitId":"-"},"content":" public static final String HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_POSSIBLY_EMPTY \u003d"},{"lineNumber":146,"author":{"gitId":"-"},"content":" \"The value of a/an ${fieldName} should be no longer than ${maxLength} characters.\";"},{"lineNumber":147,"author":{"gitId":"-"},"content":" public static final String HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_NON_EMPTY \u003d"},{"lineNumber":148,"author":{"gitId":"-"},"content":" HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_POSSIBLY_EMPTY + \" It should not be empty.\";"},{"lineNumber":149,"author":{"gitId":"-"},"content":" public static final String HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_NON_EMPTY_NO_SPACES \u003d"},{"lineNumber":150,"author":{"gitId":"-"},"content":" \"It cannot be longer than ${maxLength} characters, cannot be empty and cannot contain spaces.\";"},{"lineNumber":151,"author":{"gitId":"-"},"content":" public static final String HINT_FOR_CORRECT_FORMAT_FOR_INVALID_NAME \u003d"},{"lineNumber":152,"author":{"gitId":"-"},"content":" \"A/An ${fieldName} must start with an alphanumeric character, and cannot contain any vertical bar \""},{"lineNumber":153,"author":{"gitId":"-"},"content":" + \"(|) or percent sign (%).\";"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" // generic (i.e., not specific to any field) error messages"},{"lineNumber":156,"author":{"gitId":"-"},"content":" public static final String SIZE_CAPPED_NON_EMPTY_STRING_ERROR_MESSAGE \u003d"},{"lineNumber":157,"author":{"gitId":"-"},"content":" ERROR_INFO + \" \" + HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_NON_EMPTY;"},{"lineNumber":158,"author":{"gitId":"-"},"content":" public static final String SIZE_CAPPED_NON_EMPTY_STRING_ERROR_MESSAGE_EMPTY_STRING \u003d"},{"lineNumber":159,"author":{"gitId":"-"},"content":" EMPTY_STRING_ERROR_INFO + \" \" + HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_NON_EMPTY;"},{"lineNumber":160,"author":{"gitId":"-"},"content":" public static final String SIZE_CAPPED_POSSIBLY_EMPTY_STRING_ERROR_MESSAGE \u003d"},{"lineNumber":161,"author":{"gitId":"-"},"content":" ERROR_INFO + \" \" + HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_POSSIBLY_EMPTY;"},{"lineNumber":162,"author":{"gitId":"-"},"content":" public static final String SIZE_CAPPED_NON_EMPTY_STRING_ERROR_MESSAGE_EMPTY_STRING_FOR_SESSION_NAME \u003d"},{"lineNumber":163,"author":{"gitId":"-"},"content":" \"The field \u0027${fieldName}\u0027 should not be empty.\" + \" \""},{"lineNumber":164,"author":{"gitId":"-"},"content":" + \"The value of \u0027${fieldName}\u0027 field should be no longer than ${maxLength} characters.\";"},{"lineNumber":165,"author":{"gitId":"-"},"content":" public static final String INVALID_NAME_ERROR_MESSAGE \u003d"},{"lineNumber":166,"author":{"gitId":"-"},"content":" ERROR_INFO + \" \" + HINT_FOR_CORRECT_FORMAT_FOR_INVALID_NAME;"},{"lineNumber":167,"author":{"gitId":"-"},"content":" public static final String TEAM_NAME_IS_VALID_EMAIL_ERROR_MESSAGE \u003d"},{"lineNumber":168,"author":{"gitId":"-"},"content":" \"The field \" + TEAM_NAME_FIELD_NAME + \" is not acceptable to TEAMMATES as the suggested value for \""},{"lineNumber":169,"author":{"gitId":"-"},"content":" + TEAM_NAME_FIELD_NAME + \" can be mis-interpreted as an email.\";"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" public static final String WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE \u003d"},{"lineNumber":172,"author":{"gitId":"-"},"content":" \"The provided ${fieldName} is not acceptable to TEAMMATES as it contains only whitespace \""},{"lineNumber":173,"author":{"gitId":"-"},"content":" + \"or contains extra spaces at the beginning or at the end of the text.\";"},{"lineNumber":174,"author":{"gitId":"-"},"content":" public static final String NON_HTML_FIELD_ERROR_MESSAGE \u003d"},{"lineNumber":175,"author":{"gitId":"-"},"content":" \"The provided ${fieldName} is not acceptable to TEAMMATES \""},{"lineNumber":176,"author":{"gitId":"-"},"content":" + \"as it cannot contain the following special html characters\""},{"lineNumber":177,"author":{"gitId":"-"},"content":" + \" in brackets: (\u003c \u003e \\\" / \u0027 \u0026)\";"},{"lineNumber":178,"author":{"gitId":"-"},"content":" public static final String NON_NULL_FIELD_ERROR_MESSAGE \u003d"},{"lineNumber":179,"author":{"gitId":"-"},"content":" \"The provided ${fieldName} is not acceptable to TEAMMATES as it cannot be empty.\";"},{"lineNumber":180,"author":{"gitId":"-"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":" // field-specific error messages"},{"lineNumber":182,"author":{"gitId":"-"},"content":" public static final String HINT_FOR_CORRECT_EMAIL \u003d"},{"lineNumber":183,"author":{"gitId":"-"},"content":" \"An email address contains some text followed by one \u0027@\u0027 sign followed by some more text, and should end \""},{"lineNumber":184,"author":{"gitId":"-"},"content":" + \"with a top level domain address like .com. \""},{"lineNumber":185,"author":{"gitId":"-"},"content":" + HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_NON_EMPTY_NO_SPACES;"},{"lineNumber":186,"author":{"gitId":"-"},"content":" public static final String EMAIL_ERROR_MESSAGE \u003d"},{"lineNumber":187,"author":{"gitId":"-"},"content":" ERROR_INFO + \" \" + HINT_FOR_CORRECT_EMAIL;"},{"lineNumber":188,"author":{"gitId":"-"},"content":" public static final String EMAIL_ERROR_MESSAGE_EMPTY_STRING \u003d"},{"lineNumber":189,"author":{"gitId":"-"},"content":" EMPTY_STRING_ERROR_INFO + \" \" + HINT_FOR_CORRECT_EMAIL;"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" public static final String HINT_FOR_CORRECT_COURSE_ID \u003d"},{"lineNumber":192,"author":{"gitId":"-"},"content":" \"A course ID can contain letters, numbers, fullstops, hyphens, underscores, and dollar signs. \""},{"lineNumber":193,"author":{"gitId":"-"},"content":" + HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_NON_EMPTY_NO_SPACES;"},{"lineNumber":194,"author":{"gitId":"-"},"content":" public static final String COURSE_ID_ERROR_MESSAGE \u003d"},{"lineNumber":195,"author":{"gitId":"-"},"content":" ERROR_INFO + \" \" + HINT_FOR_CORRECT_COURSE_ID;"},{"lineNumber":196,"author":{"gitId":"-"},"content":" public static final String COURSE_ID_ERROR_MESSAGE_EMPTY_STRING \u003d"},{"lineNumber":197,"author":{"gitId":"-"},"content":" EMPTY_STRING_ERROR_INFO + \" \" + HINT_FOR_CORRECT_COURSE_ID;"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" public static final String HINT_FOR_CORRECT_FORMAT_OF_GOOGLE_ID \u003d"},{"lineNumber":200,"author":{"gitId":"-"},"content":" \"A Google ID must be a valid id already registered with Google. \""},{"lineNumber":201,"author":{"gitId":"-"},"content":" + HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_NON_EMPTY_NO_SPACES;"},{"lineNumber":202,"author":{"gitId":"-"},"content":" public static final String GOOGLE_ID_ERROR_MESSAGE \u003d"},{"lineNumber":203,"author":{"gitId":"-"},"content":" ERROR_INFO + \" \" + HINT_FOR_CORRECT_FORMAT_OF_GOOGLE_ID;"},{"lineNumber":204,"author":{"gitId":"-"},"content":" public static final String GOOGLE_ID_ERROR_MESSAGE_EMPTY_STRING \u003d"},{"lineNumber":205,"author":{"gitId":"-"},"content":" EMPTY_STRING_ERROR_INFO + \" \" + HINT_FOR_CORRECT_FORMAT_OF_GOOGLE_ID;"},{"lineNumber":206,"author":{"gitId":"-"},"content":""},{"lineNumber":207,"author":{"gitId":"-"},"content":" public static final String HINT_FOR_CORRECT_TIME_ZONE \u003d"},{"lineNumber":208,"author":{"gitId":"-"},"content":" \"The value must be one of the values from the time zone dropdown selector.\";"},{"lineNumber":209,"author":{"gitId":"-"},"content":" public static final String TIME_ZONE_ERROR_MESSAGE \u003d"},{"lineNumber":210,"author":{"gitId":"-"},"content":" ERROR_INFO + \" \" + HINT_FOR_CORRECT_TIME_ZONE;"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" public static final String HINT_FOR_CORRECT_GRACE_PERIOD \u003d"},{"lineNumber":213,"author":{"gitId":"-"},"content":" \"The value must be one of the options in the grace period dropdown selector.\";"},{"lineNumber":214,"author":{"gitId":"-"},"content":" public static final String GRACE_PERIOD_NEGATIVE_ERROR_MESSAGE \u003d \"Grace period should not be negative.\" + \" \""},{"lineNumber":215,"author":{"gitId":"-"},"content":" + HINT_FOR_CORRECT_GRACE_PERIOD;"},{"lineNumber":216,"author":{"gitId":"-"},"content":""},{"lineNumber":217,"author":{"gitId":"-"},"content":" public static final String ROLE_ERROR_MESSAGE \u003d"},{"lineNumber":218,"author":{"gitId":"-"},"content":" \"\\\"%s\\\" is not an accepted \" + ROLE_FIELD_NAME + \" to TEAMMATES. \";"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_STYLE_ERROR_MESSAGE \u003d"},{"lineNumber":221,"author":{"gitId":"-"},"content":" \"\\\"%s\\\" is not an accepted \" + NOTIFICATION_STYLE_FIELD_NAME + \" to TEAMMATES. \";"},{"lineNumber":222,"author":{"gitId":"-"},"content":""},{"lineNumber":223,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_TARGET_USER_ERROR_MESSAGE \u003d"},{"lineNumber":224,"author":{"gitId":"-"},"content":" \"\\\"%s\\\" is not an accepted \" + NOTIFICATION_TARGET_USER_FIELD_NAME + \" to TEAMMATES. \";"},{"lineNumber":225,"author":{"gitId":"-"},"content":""},{"lineNumber":226,"author":{"gitId":"-"},"content":" public static final String SESSION_VISIBLE_TIME_FIELD_NAME \u003d \"time when the session will be visible\";"},{"lineNumber":227,"author":{"gitId":"-"},"content":" public static final String RESULTS_VISIBLE_TIME_FIELD_NAME \u003d \"time when the results will be visible\";"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" public static final String TIME_BEFORE_ERROR_MESSAGE \u003d"},{"lineNumber":230,"author":{"gitId":"-"},"content":" \"The %s for this %s cannot be earlier than the %s.\";"},{"lineNumber":231,"author":{"gitId":"-"},"content":" public static final String TIME_BEFORE_OR_EQUAL_ERROR_MESSAGE \u003d"},{"lineNumber":232,"author":{"gitId":"-"},"content":" \"The %s for this %s cannot be earlier than or at the same time as the %s.\";"},{"lineNumber":233,"author":{"gitId":"-"},"content":""},{"lineNumber":234,"author":{"gitId":"-"},"content":" public static final String PARTICIPANT_TYPE_ERROR_MESSAGE \u003d \"%s is not a valid %s.\";"},{"lineNumber":235,"author":{"gitId":"-"},"content":" public static final String PARTICIPANT_TYPE_TEAM_ERROR_MESSAGE \u003d"},{"lineNumber":236,"author":{"gitId":"-"},"content":" \"The feedback recipients cannot be \\\"%s\\\" when the feedback giver is \\\"%s\\\". \""},{"lineNumber":237,"author":{"gitId":"-"},"content":" + \"Did you mean to use \\\"Self\\\" instead?\";"},{"lineNumber":238,"author":{"gitId":"-"},"content":""},{"lineNumber":239,"author":{"gitId":"-"},"content":" public static final String NOT_EXACT_HOUR_ERROR_MESSAGE \u003d \"The %s for this feedback session must be at exact hour mark.\";"},{"lineNumber":240,"author":{"gitId":"-"},"content":""},{"lineNumber":241,"author":{"gitId":"-"},"content":" ///////////////////////////////////////"},{"lineNumber":242,"author":{"gitId":"-"},"content":" // VALIDATION REGEX FOR INTERNAL USE //"},{"lineNumber":243,"author":{"gitId":"-"},"content":" ///////////////////////////////////////"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":246,"author":{"gitId":"-"},"content":" * Must start with alphanumeric character, cannot contain vertical bar(|) or percent sign(%)."},{"lineNumber":247,"author":{"gitId":"-"},"content":" */"},{"lineNumber":248,"author":{"gitId":"-"},"content":" public static final String REGEX_NAME \u003d \"^[\\\\p{IsL}\\\\p{IsN}][^|%]*+$\";"},{"lineNumber":249,"author":{"gitId":"-"},"content":""},{"lineNumber":250,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":251,"author":{"gitId":"-"},"content":" * Allows English alphabet, numbers, underscore, dot, dollar sign and hyphen."},{"lineNumber":252,"author":{"gitId":"-"},"content":" */"},{"lineNumber":253,"author":{"gitId":"-"},"content":" public static final String REGEX_COURSE_ID \u003d \"[a-zA-Z0-9_.$-]+\";"},{"lineNumber":254,"author":{"gitId":"-"},"content":""},{"lineNumber":255,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":256,"author":{"gitId":"-"},"content":" * Local part:"},{"lineNumber":257,"author":{"gitId":"-"},"content":" * \u003cli\u003eCan only start with letters, digits, hyphen or plus sign;"},{"lineNumber":258,"author":{"gitId":"-"},"content":" * \u003cli\u003eSpecial characters allowed are ! # $ % \u0026 \u0027 * + - / \u003d ? ^ _ ` { } ~"},{"lineNumber":259,"author":{"gitId":"-"},"content":" * \u003cli\u003eDot can only appear between any 2 characters and cannot appear continuously\u003cbr\u003e"},{"lineNumber":260,"author":{"gitId":"-"},"content":" * Domain part:"},{"lineNumber":261,"author":{"gitId":"-"},"content":" * \u003cli\u003eOnly allow letters, digits, hyphen and dot; Must end with letters; Must have TLD"},{"lineNumber":262,"author":{"gitId":"-"},"content":" */"},{"lineNumber":263,"author":{"gitId":"-"},"content":" public static final String REGEX_EMAIL \u003d \"^[\\\\w+-][\\\\w+!#$%\u0026\u0027*/\u003d?^_`{}~-]*+(\\\\.[\\\\w+!#$%\u0026\u0027*/\u003d?^_`{}~-]+)*+\""},{"lineNumber":264,"author":{"gitId":"-"},"content":" + \"@([A-Za-z0-9-]+\\\\.)+[A-Za-z]+$\";"},{"lineNumber":265,"author":{"gitId":"-"},"content":""},{"lineNumber":266,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":267,"author":{"gitId":"-"},"content":" * Allows English alphabet, numbers, underscore, dot and hyphen."},{"lineNumber":268,"author":{"gitId":"-"},"content":" */"},{"lineNumber":269,"author":{"gitId":"-"},"content":" public static final String REGEX_GOOGLE_ID_NON_EMAIL \u003d \"[a-zA-Z0-9_.-]+\";"},{"lineNumber":270,"author":{"gitId":"-"},"content":""},{"lineNumber":271,"author":{"gitId":"-"},"content":" private FieldValidator() {"},{"lineNumber":272,"author":{"gitId":"-"},"content":" // utility class"},{"lineNumber":273,"author":{"gitId":"-"},"content":" // Intentional private constructor to prevent instantiation."},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" /////////////////////////////////////////"},{"lineNumber":277,"author":{"gitId":"-"},"content":" // VALIDATION METHODS FOR EXTERNAL USE //"},{"lineNumber":278,"author":{"gitId":"-"},"content":" /////////////////////////////////////////"},{"lineNumber":279,"author":{"gitId":"-"},"content":""},{"lineNumber":280,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":281,"author":{"gitId":"-"},"content":" * Checks if {@code email} is not null, not empty, not longer than {@code EMAIL_MAX_LENGTH}, and is a"},{"lineNumber":282,"author":{"gitId":"-"},"content":" * valid email address according to {@code REGEX_EMAIL}."},{"lineNumber":283,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code email} is not acceptable."},{"lineNumber":284,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code email} is acceptable."},{"lineNumber":285,"author":{"gitId":"-"},"content":" */"},{"lineNumber":286,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForEmail(String email) {"},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":289,"author":{"gitId":"-"},"content":""},{"lineNumber":290,"author":{"gitId":"-"},"content":" if (email.isEmpty()) {"},{"lineNumber":291,"author":{"gitId":"-"},"content":" return getPopulatedEmptyStringErrorMessage(EMAIL_ERROR_MESSAGE_EMPTY_STRING, EMAIL_FIELD_NAME,"},{"lineNumber":292,"author":{"gitId":"-"},"content":" EMAIL_MAX_LENGTH);"},{"lineNumber":293,"author":{"gitId":"-"},"content":" } else if (isUntrimmed(email)) {"},{"lineNumber":294,"author":{"gitId":"-"},"content":" return WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace(\"${fieldName}\", EMAIL_FIELD_NAME);"},{"lineNumber":295,"author":{"gitId":"-"},"content":" } else if (email.length() \u003e EMAIL_MAX_LENGTH) {"},{"lineNumber":296,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(EMAIL_ERROR_MESSAGE, email, EMAIL_FIELD_NAME,"},{"lineNumber":297,"author":{"gitId":"-"},"content":" REASON_TOO_LONG, EMAIL_MAX_LENGTH);"},{"lineNumber":298,"author":{"gitId":"-"},"content":" } else if (!isValidEmailAddress(email)) {"},{"lineNumber":299,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(EMAIL_ERROR_MESSAGE, email, EMAIL_FIELD_NAME,"},{"lineNumber":300,"author":{"gitId":"-"},"content":" REASON_INCORRECT_FORMAT, EMAIL_MAX_LENGTH);"},{"lineNumber":301,"author":{"gitId":"-"},"content":" }"},{"lineNumber":302,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":303,"author":{"gitId":"-"},"content":" }"},{"lineNumber":304,"author":{"gitId":"-"},"content":""},{"lineNumber":305,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":306,"author":{"gitId":"-"},"content":" * Checks if {@code gracePeriod} is not negative."},{"lineNumber":307,"author":{"gitId":"-"},"content":" * @return An explanation why the {@code gracePeriod} is not acceptable."},{"lineNumber":308,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code gracePeriod} is acceptable."},{"lineNumber":309,"author":{"gitId":"-"},"content":" */"},{"lineNumber":310,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForGracePeriod(Duration gracePeriod) {"},{"lineNumber":311,"author":{"gitId":"-"},"content":" if (gracePeriod.isNegative()) {"},{"lineNumber":312,"author":{"gitId":"-"},"content":" return GRACE_PERIOD_NEGATIVE_ERROR_MESSAGE;"},{"lineNumber":313,"author":{"gitId":"-"},"content":" }"},{"lineNumber":314,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":315,"author":{"gitId":"-"},"content":" }"},{"lineNumber":316,"author":{"gitId":"-"},"content":""},{"lineNumber":317,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":318,"author":{"gitId":"-"},"content":" * Checks if {@code googleId} is not null, not empty, not longer than {@code GOOGLE_ID_MAX_LENGTH}, does"},{"lineNumber":319,"author":{"gitId":"-"},"content":" * not contain any invalid characters (| or %), AND is either a Google username (without the \"@gmail.com\")"},{"lineNumber":320,"author":{"gitId":"-"},"content":" * or a valid email address."},{"lineNumber":321,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code googleId} is not acceptable."},{"lineNumber":322,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code googleId} is acceptable."},{"lineNumber":323,"author":{"gitId":"-"},"content":" */"},{"lineNumber":324,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForGoogleId(String googleId) {"},{"lineNumber":325,"author":{"gitId":"-"},"content":""},{"lineNumber":326,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":327,"author":{"gitId":"-"},"content":""},{"lineNumber":328,"author":{"gitId":"-"},"content":" boolean isValidFullEmail \u003d isValidEmailAddress(googleId);"},{"lineNumber":329,"author":{"gitId":"-"},"content":" boolean isValidEmailWithoutDomain \u003d StringHelper.isMatching(googleId, REGEX_GOOGLE_ID_NON_EMAIL);"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" if (googleId.isEmpty()) {"},{"lineNumber":332,"author":{"gitId":"-"},"content":" return getPopulatedEmptyStringErrorMessage(GOOGLE_ID_ERROR_MESSAGE_EMPTY_STRING,"},{"lineNumber":333,"author":{"gitId":"-"},"content":" GOOGLE_ID_FIELD_NAME, GOOGLE_ID_MAX_LENGTH);"},{"lineNumber":334,"author":{"gitId":"-"},"content":" } else if (isUntrimmed(googleId)) {"},{"lineNumber":335,"author":{"gitId":"-"},"content":" return WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace(\"${fieldName}\", GOOGLE_ID_FIELD_NAME);"},{"lineNumber":336,"author":{"gitId":"-"},"content":" } else if (googleId.length() \u003e GOOGLE_ID_MAX_LENGTH) {"},{"lineNumber":337,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(GOOGLE_ID_ERROR_MESSAGE, googleId, GOOGLE_ID_FIELD_NAME,"},{"lineNumber":338,"author":{"gitId":"-"},"content":" REASON_TOO_LONG, GOOGLE_ID_MAX_LENGTH);"},{"lineNumber":339,"author":{"gitId":"-"},"content":" } else if (!(isValidFullEmail || isValidEmailWithoutDomain)) {"},{"lineNumber":340,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(GOOGLE_ID_ERROR_MESSAGE, googleId, GOOGLE_ID_FIELD_NAME,"},{"lineNumber":341,"author":{"gitId":"-"},"content":" REASON_INCORRECT_FORMAT, GOOGLE_ID_MAX_LENGTH);"},{"lineNumber":342,"author":{"gitId":"-"},"content":" }"},{"lineNumber":343,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":344,"author":{"gitId":"-"},"content":" }"},{"lineNumber":345,"author":{"gitId":"-"},"content":""},{"lineNumber":346,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":347,"author":{"gitId":"-"},"content":" * Checks if {@code courseId} is not null, not empty, has no surrounding whitespaces, not longer than"},{"lineNumber":348,"author":{"gitId":"-"},"content":" * {@code COURSE_ID_MAX_LENGTH}, is sanitized for HTML, and match the REGEX {@code REGEX_COURSE_ID}."},{"lineNumber":349,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code courseId} is not acceptable."},{"lineNumber":350,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code courseId} is acceptable."},{"lineNumber":351,"author":{"gitId":"-"},"content":" */"},{"lineNumber":352,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForCourseId(String courseId) {"},{"lineNumber":353,"author":{"gitId":"-"},"content":""},{"lineNumber":354,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":355,"author":{"gitId":"-"},"content":""},{"lineNumber":356,"author":{"gitId":"-"},"content":" if (courseId.isEmpty()) {"},{"lineNumber":357,"author":{"gitId":"-"},"content":" return getPopulatedEmptyStringErrorMessage(COURSE_ID_ERROR_MESSAGE_EMPTY_STRING,"},{"lineNumber":358,"author":{"gitId":"-"},"content":" COURSE_ID_FIELD_NAME, COURSE_ID_MAX_LENGTH);"},{"lineNumber":359,"author":{"gitId":"-"},"content":" }"},{"lineNumber":360,"author":{"gitId":"-"},"content":" if (isUntrimmed(courseId)) {"},{"lineNumber":361,"author":{"gitId":"-"},"content":" return WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace(\"${fieldName}\","},{"lineNumber":362,"author":{"gitId":"-"},"content":" COURSE_ID_FIELD_NAME);"},{"lineNumber":363,"author":{"gitId":"-"},"content":" }"},{"lineNumber":364,"author":{"gitId":"-"},"content":" if (courseId.length() \u003e COURSE_ID_MAX_LENGTH) {"},{"lineNumber":365,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(COURSE_ID_ERROR_MESSAGE, courseId, COURSE_ID_FIELD_NAME,"},{"lineNumber":366,"author":{"gitId":"-"},"content":" REASON_TOO_LONG, COURSE_ID_MAX_LENGTH);"},{"lineNumber":367,"author":{"gitId":"-"},"content":" }"},{"lineNumber":368,"author":{"gitId":"-"},"content":" if (!StringHelper.isMatching(courseId, REGEX_COURSE_ID)) {"},{"lineNumber":369,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(COURSE_ID_ERROR_MESSAGE, courseId, COURSE_ID_FIELD_NAME,"},{"lineNumber":370,"author":{"gitId":"-"},"content":" REASON_INCORRECT_FORMAT, COURSE_ID_MAX_LENGTH);"},{"lineNumber":371,"author":{"gitId":"-"},"content":" }"},{"lineNumber":372,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":373,"author":{"gitId":"-"},"content":" }"},{"lineNumber":374,"author":{"gitId":"-"},"content":""},{"lineNumber":375,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":376,"author":{"gitId":"-"},"content":" * Checks if {@code sectionName} is a non-null non-empty string no longer than the specified length"},{"lineNumber":377,"author":{"gitId":"-"},"content":" * {@code SECTION_NAME_MAX_LENGTH}, and also does not contain any invalid characters (| or %)."},{"lineNumber":378,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code sectionName} is not acceptable."},{"lineNumber":379,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code sectionName} is acceptable."},{"lineNumber":380,"author":{"gitId":"-"},"content":" */"},{"lineNumber":381,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForSectionName(String sectionName) {"},{"lineNumber":382,"author":{"gitId":"-"},"content":" return getValidityInfoForAllowedName(SECTION_NAME_FIELD_NAME, SECTION_NAME_MAX_LENGTH, sectionName);"},{"lineNumber":383,"author":{"gitId":"-"},"content":" }"},{"lineNumber":384,"author":{"gitId":"-"},"content":""},{"lineNumber":385,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":386,"author":{"gitId":"-"},"content":" * Checks if {@code teamName} is a non-null non-empty string no longer than the specified length"},{"lineNumber":387,"author":{"gitId":"-"},"content":" * {@code TEAM_NAME_MAX_LENGTH}, does not contain any invalid characters (| or %) and is not a valid email."},{"lineNumber":388,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code teamName} is not acceptable."},{"lineNumber":389,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code teamName} is acceptable."},{"lineNumber":390,"author":{"gitId":"-"},"content":" */"},{"lineNumber":391,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForTeamName(String teamName) {"},{"lineNumber":392,"author":{"gitId":"-"},"content":" boolean isValidEmail \u003d isValidEmailAddress(teamName);"},{"lineNumber":393,"author":{"gitId":"-"},"content":" if (isValidEmail) {"},{"lineNumber":394,"author":{"gitId":"-"},"content":" return TEAM_NAME_IS_VALID_EMAIL_ERROR_MESSAGE;"},{"lineNumber":395,"author":{"gitId":"-"},"content":" }"},{"lineNumber":396,"author":{"gitId":"-"},"content":" return getValidityInfoForAllowedName(TEAM_NAME_FIELD_NAME, TEAM_NAME_MAX_LENGTH, teamName);"},{"lineNumber":397,"author":{"gitId":"-"},"content":" }"},{"lineNumber":398,"author":{"gitId":"-"},"content":""},{"lineNumber":399,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":400,"author":{"gitId":"-"},"content":" * Checks if the given studentRoleComments is a non-null string no longer than"},{"lineNumber":401,"author":{"gitId":"-"},"content":" * the specified length {@code STUDENT_ROLE_COMMENTS_MAX_LENGTH}. However, this string can be empty."},{"lineNumber":402,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code studentRoleComments} is not acceptable."},{"lineNumber":403,"author":{"gitId":"-"},"content":" * Returns an empty string \"\" if the {@code studentRoleComments} is acceptable."},{"lineNumber":404,"author":{"gitId":"-"},"content":" */"},{"lineNumber":405,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForStudentRoleComments(String studentRoleComments) {"},{"lineNumber":406,"author":{"gitId":"-"},"content":" return getValidityInfoForSizeCappedPossiblyEmptyString(STUDENT_ROLE_COMMENTS_FIELD_NAME,"},{"lineNumber":407,"author":{"gitId":"-"},"content":" STUDENT_ROLE_COMMENTS_MAX_LENGTH,"},{"lineNumber":408,"author":{"gitId":"-"},"content":" studentRoleComments);"},{"lineNumber":409,"author":{"gitId":"-"},"content":" }"},{"lineNumber":410,"author":{"gitId":"-"},"content":""},{"lineNumber":411,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":412,"author":{"gitId":"-"},"content":" * Checks if {@code feedbackSessionName} is a non-null non-empty string no longer than the specified length"},{"lineNumber":413,"author":{"gitId":"-"},"content":" * {@code FEEDBACK_SESSION_NAME_MAX_LENGTH}, does not contain any invalid characters (| or %), and has no"},{"lineNumber":414,"author":{"gitId":"-"},"content":" * unsanitized HTML characters."},{"lineNumber":415,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code feedbackSessionName} is not acceptable."},{"lineNumber":416,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code feedbackSessionName} is acceptable."},{"lineNumber":417,"author":{"gitId":"-"},"content":" */"},{"lineNumber":418,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForFeedbackSessionName(String feedbackSessionName) {"},{"lineNumber":419,"author":{"gitId":"-"},"content":" String errorsFromAllowedNameValidation \u003d getValidityInfoForAllowedName("},{"lineNumber":420,"author":{"gitId":"-"},"content":" FEEDBACK_SESSION_NAME_FIELD_NAME, FEEDBACK_SESSION_NAME_MAX_LENGTH, feedbackSessionName);"},{"lineNumber":421,"author":{"gitId":"-"},"content":""},{"lineNumber":422,"author":{"gitId":"-"},"content":" // return early if error already exists because session name is too long etc."},{"lineNumber":423,"author":{"gitId":"-"},"content":" if (!errorsFromAllowedNameValidation.isEmpty()) {"},{"lineNumber":424,"author":{"gitId":"-"},"content":" return errorsFromAllowedNameValidation;"},{"lineNumber":425,"author":{"gitId":"-"},"content":" }"},{"lineNumber":426,"author":{"gitId":"-"},"content":""},{"lineNumber":427,"author":{"gitId":"-"},"content":" // checks for unsanitized HTML characters"},{"lineNumber":428,"author":{"gitId":"-"},"content":" return getValidityInfoForNonHtmlField(FEEDBACK_SESSION_NAME_FIELD_NAME, feedbackSessionName);"},{"lineNumber":429,"author":{"gitId":"-"},"content":" }"},{"lineNumber":430,"author":{"gitId":"-"},"content":""},{"lineNumber":431,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":432,"author":{"gitId":"-"},"content":" * Checks if {@code courseName} is a non-null non-empty string no longer than the specified length"},{"lineNumber":433,"author":{"gitId":"-"},"content":" * {@code COURSE_NAME_MAX_LENGTH}, and also does not contain any invalid characters (| or %)."},{"lineNumber":434,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code courseName} is not acceptable."},{"lineNumber":435,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code courseName} is acceptable."},{"lineNumber":436,"author":{"gitId":"-"},"content":" */"},{"lineNumber":437,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForCourseName(String courseName) {"},{"lineNumber":438,"author":{"gitId":"-"},"content":" return getValidityInfoForAllowedName(COURSE_NAME_FIELD_NAME, COURSE_NAME_MAX_LENGTH, courseName);"},{"lineNumber":439,"author":{"gitId":"-"},"content":" }"},{"lineNumber":440,"author":{"gitId":"-"},"content":""},{"lineNumber":441,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":442,"author":{"gitId":"-"},"content":" * Checks if {@code instituteName} is a non-null non-empty string no longer than the specified length"},{"lineNumber":443,"author":{"gitId":"-"},"content":" * {@code INSTITUTE_NAME_MAX_LENGTH}, and also does not contain any invalid characters (| or %)."},{"lineNumber":444,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code instituteName} is not acceptable."},{"lineNumber":445,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code instituteName} is acceptable."},{"lineNumber":446,"author":{"gitId":"-"},"content":" */"},{"lineNumber":447,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForInstituteName(String instituteName) {"},{"lineNumber":448,"author":{"gitId":"-"},"content":" return getValidityInfoForAllowedName(INSTITUTE_NAME_FIELD_NAME, INSTITUTE_NAME_MAX_LENGTH,"},{"lineNumber":449,"author":{"gitId":"-"},"content":" instituteName);"},{"lineNumber":450,"author":{"gitId":"-"},"content":" }"},{"lineNumber":451,"author":{"gitId":"-"},"content":""},{"lineNumber":452,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":453,"author":{"gitId":"-"},"content":" * Checks if {@code personName} is a non-null non-empty string no longer than the specified length"},{"lineNumber":454,"author":{"gitId":"-"},"content":" * {@code PERSON_NAME_MAX_LENGTH}, and also does not contain any invalid characters (| or %)."},{"lineNumber":455,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code personName} is not acceptable."},{"lineNumber":456,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code personName} is acceptable."},{"lineNumber":457,"author":{"gitId":"-"},"content":" */"},{"lineNumber":458,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForPersonName(String personName) {"},{"lineNumber":459,"author":{"gitId":"-"},"content":" return getValidityInfoForAllowedName(PERSON_NAME_FIELD_NAME, PERSON_NAME_MAX_LENGTH, personName);"},{"lineNumber":460,"author":{"gitId":"-"},"content":" }"},{"lineNumber":461,"author":{"gitId":"-"},"content":""},{"lineNumber":462,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":463,"author":{"gitId":"-"},"content":" * Checks if the given string is a non-null string contained in Java\u0027s list of"},{"lineNumber":464,"author":{"gitId":"-"},"content":" * regional time zone IDs."},{"lineNumber":465,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code timeZoneValue} is not acceptable."},{"lineNumber":466,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code timeZoneValue} is acceptable."},{"lineNumber":467,"author":{"gitId":"-"},"content":" */"},{"lineNumber":468,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForTimeZone(String timeZoneValue) {"},{"lineNumber":469,"author":{"gitId":"-"},"content":" assert timeZoneValue !\u003d null;"},{"lineNumber":470,"author":{"gitId":"-"},"content":" if (!ZoneId.getAvailableZoneIds().contains(timeZoneValue)) {"},{"lineNumber":471,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(TIME_ZONE_ERROR_MESSAGE,"},{"lineNumber":472,"author":{"gitId":"-"},"content":" timeZoneValue, TIME_ZONE_FIELD_NAME, REASON_UNAVAILABLE_AS_CHOICE);"},{"lineNumber":473,"author":{"gitId":"-"},"content":" }"},{"lineNumber":474,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":475,"author":{"gitId":"-"},"content":" }"},{"lineNumber":476,"author":{"gitId":"-"},"content":""},{"lineNumber":477,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":478,"author":{"gitId":"-"},"content":" * Checks if {@code role} is one of the recognized roles {@link #ROLE_ACCEPTED_VALUES}."},{"lineNumber":479,"author":{"gitId":"-"},"content":" *"},{"lineNumber":480,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code role} is not acceptable."},{"lineNumber":481,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code role} is acceptable."},{"lineNumber":482,"author":{"gitId":"-"},"content":" */"},{"lineNumber":483,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForRole(String role) {"},{"lineNumber":484,"author":{"gitId":"-"},"content":" assert role !\u003d null;"},{"lineNumber":485,"author":{"gitId":"-"},"content":""},{"lineNumber":486,"author":{"gitId":"-"},"content":" if (!ROLE_ACCEPTED_VALUES.contains(role)) {"},{"lineNumber":487,"author":{"gitId":"-"},"content":" return String.format(ROLE_ERROR_MESSAGE, role);"},{"lineNumber":488,"author":{"gitId":"-"},"content":" }"},{"lineNumber":489,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":490,"author":{"gitId":"-"},"content":" }"},{"lineNumber":491,"author":{"gitId":"-"},"content":""},{"lineNumber":492,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":493,"author":{"gitId":"-"},"content":" * Checks if the given name (including person name, institute name, course name, feedback session and team name)"},{"lineNumber":494,"author":{"gitId":"-"},"content":" * is a non-null non-empty string no longer than the specified length {@code maxLength},"},{"lineNumber":495,"author":{"gitId":"-"},"content":" * and also does not contain any invalid characters (| or %)."},{"lineNumber":496,"author":{"gitId":"-"},"content":" *"},{"lineNumber":497,"author":{"gitId":"-"},"content":" * @param fieldName"},{"lineNumber":498,"author":{"gitId":"-"},"content":" * A descriptive name of the field e.g., \"student name\", to be"},{"lineNumber":499,"author":{"gitId":"-"},"content":" * used in the return value to make the explanation more"},{"lineNumber":500,"author":{"gitId":"-"},"content":" * descriptive."},{"lineNumber":501,"author":{"gitId":"-"},"content":" * @param value"},{"lineNumber":502,"author":{"gitId":"-"},"content":" * The string to be checked."},{"lineNumber":503,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code value} is not acceptable."},{"lineNumber":504,"author":{"gitId":"-"},"content":" * Returns an empty string \"\" if the {@code value} is acceptable."},{"lineNumber":505,"author":{"gitId":"-"},"content":" */"},{"lineNumber":506,"author":{"gitId":"-"},"content":" static String getValidityInfoForAllowedName(String fieldName, int maxLength, String value) {"},{"lineNumber":507,"author":{"gitId":"-"},"content":""},{"lineNumber":508,"author":{"gitId":"-"},"content":" assert value !\u003d null : \"Non-null value expected for \" + fieldName;"},{"lineNumber":509,"author":{"gitId":"-"},"content":""},{"lineNumber":510,"author":{"gitId":"-"},"content":" if (value.isEmpty()) {"},{"lineNumber":511,"author":{"gitId":"-"},"content":" if (FEEDBACK_SESSION_NAME_FIELD_NAME.equals(fieldName)) {"},{"lineNumber":512,"author":{"gitId":"-"},"content":" return getPopulatedEmptyStringErrorMessage("},{"lineNumber":513,"author":{"gitId":"-"},"content":" SIZE_CAPPED_NON_EMPTY_STRING_ERROR_MESSAGE_EMPTY_STRING_FOR_SESSION_NAME,"},{"lineNumber":514,"author":{"gitId":"-"},"content":" fieldName, maxLength);"},{"lineNumber":515,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":516,"author":{"gitId":"-"},"content":" return getPopulatedEmptyStringErrorMessage(SIZE_CAPPED_NON_EMPTY_STRING_ERROR_MESSAGE_EMPTY_STRING,"},{"lineNumber":517,"author":{"gitId":"-"},"content":" fieldName, maxLength);"},{"lineNumber":518,"author":{"gitId":"-"},"content":" }"},{"lineNumber":519,"author":{"gitId":"-"},"content":" }"},{"lineNumber":520,"author":{"gitId":"-"},"content":" if (isUntrimmed(value)) {"},{"lineNumber":521,"author":{"gitId":"-"},"content":" return WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace(\"${fieldName}\", fieldName);"},{"lineNumber":522,"author":{"gitId":"-"},"content":" }"},{"lineNumber":523,"author":{"gitId":"-"},"content":" if (value.length() \u003e maxLength) {"},{"lineNumber":524,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(SIZE_CAPPED_NON_EMPTY_STRING_ERROR_MESSAGE, value,"},{"lineNumber":525,"author":{"gitId":"-"},"content":" fieldName, REASON_TOO_LONG, maxLength);"},{"lineNumber":526,"author":{"gitId":"-"},"content":" }"},{"lineNumber":527,"author":{"gitId":"-"},"content":" if (!Character.isLetterOrDigit(value.codePointAt(0))) {"},{"lineNumber":528,"author":{"gitId":"-"},"content":" boolean hasStartingBrace \u003d value.charAt(0) \u003d\u003d \u0027{\u0027 \u0026\u0026 value.contains(\"}\");"},{"lineNumber":529,"author":{"gitId":"-"},"content":" if (!hasStartingBrace) {"},{"lineNumber":530,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(INVALID_NAME_ERROR_MESSAGE, value,"},{"lineNumber":531,"author":{"gitId":"-"},"content":" fieldName, REASON_START_WITH_NON_ALPHANUMERIC_CHAR);"},{"lineNumber":532,"author":{"gitId":"-"},"content":" }"},{"lineNumber":533,"author":{"gitId":"-"},"content":" if (!StringHelper.isMatching(value.substring(1), REGEX_NAME)) {"},{"lineNumber":534,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(INVALID_NAME_ERROR_MESSAGE, value, fieldName,"},{"lineNumber":535,"author":{"gitId":"-"},"content":" REASON_CONTAINS_INVALID_CHAR);"},{"lineNumber":536,"author":{"gitId":"-"},"content":" }"},{"lineNumber":537,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":538,"author":{"gitId":"-"},"content":" }"},{"lineNumber":539,"author":{"gitId":"-"},"content":" if (!StringHelper.isMatching(value, REGEX_NAME)) {"},{"lineNumber":540,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(INVALID_NAME_ERROR_MESSAGE, value, fieldName,"},{"lineNumber":541,"author":{"gitId":"-"},"content":" REASON_CONTAINS_INVALID_CHAR);"},{"lineNumber":542,"author":{"gitId":"-"},"content":" }"},{"lineNumber":543,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":544,"author":{"gitId":"-"},"content":" }"},{"lineNumber":545,"author":{"gitId":"-"},"content":""},{"lineNumber":546,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":547,"author":{"gitId":"-"},"content":" * Checks if the notification title is a non-null non-empty string."},{"lineNumber":548,"author":{"gitId":"-"},"content":" *"},{"lineNumber":549,"author":{"gitId":"-"},"content":" * @param notificationTitle The title of the notification."},{"lineNumber":550,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code notificationTitle} is not acceptable."},{"lineNumber":551,"author":{"gitId":"-"},"content":" * Returns an empty string \"\" if the {@code notificationTitle} is acceptable."},{"lineNumber":552,"author":{"gitId":"-"},"content":" */"},{"lineNumber":553,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForNotificationTitle(String notificationTitle) {"},{"lineNumber":554,"author":{"gitId":"-"},"content":""},{"lineNumber":555,"author":{"gitId":"-"},"content":" assert notificationTitle !\u003d null : \"Non-null value expected for notification title\";"},{"lineNumber":556,"author":{"gitId":"-"},"content":""},{"lineNumber":557,"author":{"gitId":"-"},"content":" if (notificationTitle.isEmpty()) {"},{"lineNumber":558,"author":{"gitId":"-"},"content":" return getPopulatedEmptyStringErrorMessage(EMPTY_STRING_ERROR_INFO,"},{"lineNumber":559,"author":{"gitId":"-"},"content":" NOTIFICATION_TITLE_FIELD_NAME, NOTIFICATION_TITLE_MAX_LENGTH);"},{"lineNumber":560,"author":{"gitId":"-"},"content":" } else if (notificationTitle.length() \u003e NOTIFICATION_TITLE_MAX_LENGTH) {"},{"lineNumber":561,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(SIZE_CAPPED_NON_EMPTY_STRING_ERROR_MESSAGE, notificationTitle,"},{"lineNumber":562,"author":{"gitId":"-"},"content":" NOTIFICATION_TITLE_FIELD_NAME, REASON_TOO_LONG, NOTIFICATION_TITLE_MAX_LENGTH);"},{"lineNumber":563,"author":{"gitId":"-"},"content":" }"},{"lineNumber":564,"author":{"gitId":"-"},"content":""},{"lineNumber":565,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":566,"author":{"gitId":"-"},"content":" }"},{"lineNumber":567,"author":{"gitId":"-"},"content":""},{"lineNumber":568,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":569,"author":{"gitId":"-"},"content":" * Checks if the notification message is a non-null non-empty string."},{"lineNumber":570,"author":{"gitId":"-"},"content":" *"},{"lineNumber":571,"author":{"gitId":"-"},"content":" * @param notificationMessage The notification message."},{"lineNumber":572,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code notificationMessage} is not acceptable."},{"lineNumber":573,"author":{"gitId":"-"},"content":" * Returns an empty string \"\" if the {@code notificationMessage} is acceptable."},{"lineNumber":574,"author":{"gitId":"-"},"content":" */"},{"lineNumber":575,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForNotificationBody(String notificationMessage) {"},{"lineNumber":576,"author":{"gitId":"-"},"content":""},{"lineNumber":577,"author":{"gitId":"-"},"content":" assert notificationMessage !\u003d null : \"Non-null value expected for notification message\";"},{"lineNumber":578,"author":{"gitId":"-"},"content":""},{"lineNumber":579,"author":{"gitId":"-"},"content":" if (notificationMessage.isEmpty()) {"},{"lineNumber":580,"author":{"gitId":"-"},"content":" return getPopulatedEmptyStringErrorMessage(EMPTY_STRING_ERROR_INFO, NOTIFICATION_MESSAGE_FIELD_NAME, 0);"},{"lineNumber":581,"author":{"gitId":"-"},"content":" }"},{"lineNumber":582,"author":{"gitId":"-"},"content":""},{"lineNumber":583,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":584,"author":{"gitId":"-"},"content":" }"},{"lineNumber":585,"author":{"gitId":"-"},"content":""},{"lineNumber":586,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":587,"author":{"gitId":"-"},"content":" * Checks if {@code style} is one of the recognized notification style {@link #NOTIFICATION_STYLE_ACCEPTED_VALUES}."},{"lineNumber":588,"author":{"gitId":"-"},"content":" *"},{"lineNumber":589,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code style} is not acceptable."},{"lineNumber":590,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code style} is acceptable."},{"lineNumber":591,"author":{"gitId":"-"},"content":" */"},{"lineNumber":592,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForNotificationStyle(String style) {"},{"lineNumber":593,"author":{"gitId":"-"},"content":" assert style !\u003d null;"},{"lineNumber":594,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":595,"author":{"gitId":"-"},"content":" NotificationStyle.valueOf(style);"},{"lineNumber":596,"author":{"gitId":"-"},"content":" } catch (IllegalArgumentException e) {"},{"lineNumber":597,"author":{"gitId":"-"},"content":" return String.format(NOTIFICATION_STYLE_ERROR_MESSAGE, style);"},{"lineNumber":598,"author":{"gitId":"-"},"content":" }"},{"lineNumber":599,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":600,"author":{"gitId":"-"},"content":" }"},{"lineNumber":601,"author":{"gitId":"-"},"content":""},{"lineNumber":602,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":603,"author":{"gitId":"-"},"content":" * Checks if {@code targetUser} is one of the"},{"lineNumber":604,"author":{"gitId":"-"},"content":" * recognized notification target user groups {@link #NOTIFICATION_TARGET_USER_ACCEPTED_VALUES}."},{"lineNumber":605,"author":{"gitId":"-"},"content":" *"},{"lineNumber":606,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code targetUser} is not acceptable."},{"lineNumber":607,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code targetUser} is acceptable."},{"lineNumber":608,"author":{"gitId":"-"},"content":" */"},{"lineNumber":609,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForNotificationTargetUser(String targetUser) {"},{"lineNumber":610,"author":{"gitId":"-"},"content":" assert targetUser !\u003d null;"},{"lineNumber":611,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":612,"author":{"gitId":"-"},"content":" NotificationTargetUser.valueOf(targetUser);"},{"lineNumber":613,"author":{"gitId":"-"},"content":" } catch (IllegalArgumentException e) {"},{"lineNumber":614,"author":{"gitId":"-"},"content":" return String.format(NOTIFICATION_TARGET_USER_ERROR_MESSAGE, targetUser);"},{"lineNumber":615,"author":{"gitId":"-"},"content":" }"},{"lineNumber":616,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":617,"author":{"gitId":"-"},"content":" }"},{"lineNumber":618,"author":{"gitId":"-"},"content":""},{"lineNumber":619,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":620,"author":{"gitId":"-"},"content":" * Checks if the given string is a non-null string no longer than"},{"lineNumber":621,"author":{"gitId":"-"},"content":" * the specified length {@code maxLength}. However, this string can be empty."},{"lineNumber":622,"author":{"gitId":"-"},"content":" *"},{"lineNumber":623,"author":{"gitId":"-"},"content":" * @param fieldName"},{"lineNumber":624,"author":{"gitId":"-"},"content":" * A descriptive name of the field e.g., \"student name\", to be"},{"lineNumber":625,"author":{"gitId":"-"},"content":" * used in the return value to make the explanation more"},{"lineNumber":626,"author":{"gitId":"-"},"content":" * descriptive."},{"lineNumber":627,"author":{"gitId":"-"},"content":" * @param value"},{"lineNumber":628,"author":{"gitId":"-"},"content":" * The string to be checked."},{"lineNumber":629,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code value} is not acceptable."},{"lineNumber":630,"author":{"gitId":"-"},"content":" * Returns an empty string \"\" if the {@code value} is acceptable."},{"lineNumber":631,"author":{"gitId":"-"},"content":" */"},{"lineNumber":632,"author":{"gitId":"-"},"content":" static String getValidityInfoForSizeCappedPossiblyEmptyString(String fieldName, int maxLength, String value) {"},{"lineNumber":633,"author":{"gitId":"-"},"content":" assert value !\u003d null : \"Non-null value expected for \" + fieldName;"},{"lineNumber":634,"author":{"gitId":"-"},"content":""},{"lineNumber":635,"author":{"gitId":"-"},"content":" if (isUntrimmed(value)) {"},{"lineNumber":636,"author":{"gitId":"-"},"content":" return WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace(\"${fieldName}\", fieldName);"},{"lineNumber":637,"author":{"gitId":"-"},"content":" }"},{"lineNumber":638,"author":{"gitId":"-"},"content":" if (value.length() \u003e maxLength) {"},{"lineNumber":639,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(SIZE_CAPPED_POSSIBLY_EMPTY_STRING_ERROR_MESSAGE, value,"},{"lineNumber":640,"author":{"gitId":"-"},"content":" fieldName, REASON_TOO_LONG, maxLength);"},{"lineNumber":641,"author":{"gitId":"-"},"content":" }"},{"lineNumber":642,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":643,"author":{"gitId":"-"},"content":" }"},{"lineNumber":644,"author":{"gitId":"-"},"content":""},{"lineNumber":645,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":646,"author":{"gitId":"-"},"content":" * Checks if the {@code startTime} is valid to be used as a session start time."},{"lineNumber":647,"author":{"gitId":"-"},"content":" * Returns an empty string if it is valid, or an error message otherwise."},{"lineNumber":648,"author":{"gitId":"-"},"content":" *"},{"lineNumber":649,"author":{"gitId":"-"},"content":" * \u003cp\u003eThe {@code startTime} is valid if it is after 2 hours before now, before 12 months from now"},{"lineNumber":650,"author":{"gitId":"-"},"content":" * and at exact hour mark."},{"lineNumber":651,"author":{"gitId":"-"},"content":" */"},{"lineNumber":652,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForNewStartTime(Instant startTime, String timeZone) {"},{"lineNumber":653,"author":{"gitId":"-"},"content":" Instant twoHoursBeforeNow \u003d TimeHelper.getInstantHoursOffsetFromNow(-2);"},{"lineNumber":654,"author":{"gitId":"-"},"content":" String earlierThanThreeHoursBeforeNowError \u003d getInvalidityInfoForFirstTimeComparedToSecondTime("},{"lineNumber":655,"author":{"gitId":"-"},"content":" twoHoursBeforeNow, startTime, SESSION_NAME,"},{"lineNumber":656,"author":{"gitId":"-"},"content":" \"2 hours before now\", SESSION_START_TIME_FIELD_NAME,"},{"lineNumber":657,"author":{"gitId":"-"},"content":" (firstTime, secondTime) -\u003e firstTime.isBefore(secondTime) || firstTime.equals(secondTime),"},{"lineNumber":658,"author":{"gitId":"-"},"content":" \"The %s for this %s cannot be earlier than %s.\");"},{"lineNumber":659,"author":{"gitId":"-"},"content":""},{"lineNumber":660,"author":{"gitId":"-"},"content":" if (!earlierThanThreeHoursBeforeNowError.isEmpty()) {"},{"lineNumber":661,"author":{"gitId":"-"},"content":" return earlierThanThreeHoursBeforeNowError;"},{"lineNumber":662,"author":{"gitId":"-"},"content":" }"},{"lineNumber":663,"author":{"gitId":"-"},"content":""},{"lineNumber":664,"author":{"gitId":"-"},"content":" Instant twelveMonthsFromNow \u003d TimeHelper.getInstantMonthsOffsetFromNow(12, timeZone);"},{"lineNumber":665,"author":{"gitId":"-"},"content":" String laterThanTwelveMonthsFromNowError \u003d getInvalidityInfoForFirstTimeComparedToSecondTime("},{"lineNumber":666,"author":{"gitId":"-"},"content":" twelveMonthsFromNow, startTime, SESSION_NAME,"},{"lineNumber":667,"author":{"gitId":"-"},"content":" \"12 months from now\", SESSION_START_TIME_FIELD_NAME,"},{"lineNumber":668,"author":{"gitId":"-"},"content":" (firstTime, secondTime) -\u003e firstTime.isAfter(secondTime) || firstTime.equals(secondTime),"},{"lineNumber":669,"author":{"gitId":"-"},"content":" \"The %s for this %s cannot be later than %s.\");"},{"lineNumber":670,"author":{"gitId":"-"},"content":""},{"lineNumber":671,"author":{"gitId":"-"},"content":" if (!laterThanTwelveMonthsFromNowError.isEmpty()) {"},{"lineNumber":672,"author":{"gitId":"-"},"content":" return laterThanTwelveMonthsFromNowError;"},{"lineNumber":673,"author":{"gitId":"-"},"content":" }"},{"lineNumber":674,"author":{"gitId":"-"},"content":""},{"lineNumber":675,"author":{"gitId":"-"},"content":" String notExactHourError \u003d getInvalidityInfoForExactHourTime(startTime, timeZone, \"start time\");"},{"lineNumber":676,"author":{"gitId":"-"},"content":" if (!notExactHourError.isEmpty()) {"},{"lineNumber":677,"author":{"gitId":"-"},"content":" return notExactHourError;"},{"lineNumber":678,"author":{"gitId":"-"},"content":" }"},{"lineNumber":679,"author":{"gitId":"-"},"content":""},{"lineNumber":680,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":681,"author":{"gitId":"-"},"content":" }"},{"lineNumber":682,"author":{"gitId":"-"},"content":""},{"lineNumber":683,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":684,"author":{"gitId":"-"},"content":" * Checks if the {@code endTime} is valid to be used as a session end time."},{"lineNumber":685,"author":{"gitId":"-"},"content":" * Returns an empty string if it is valid, or an error message otherwise."},{"lineNumber":686,"author":{"gitId":"-"},"content":" *"},{"lineNumber":687,"author":{"gitId":"-"},"content":" * \u003cp\u003eThe {@code endTime} is valid if it is after 1 hour before now, before 12 months from now"},{"lineNumber":688,"author":{"gitId":"-"},"content":" * and at exact hour mark."},{"lineNumber":689,"author":{"gitId":"-"},"content":" */"},{"lineNumber":690,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForNewEndTime(Instant endTime, String timeZone) {"},{"lineNumber":691,"author":{"gitId":"-"},"content":" Instant oneHourBeforeNow \u003d TimeHelper.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":692,"author":{"gitId":"-"},"content":" String earlierThanThreeHoursBeforeNowError \u003d getInvalidityInfoForFirstTimeComparedToSecondTime("},{"lineNumber":693,"author":{"gitId":"-"},"content":" oneHourBeforeNow, endTime, SESSION_NAME,"},{"lineNumber":694,"author":{"gitId":"-"},"content":" \"1 hour before now\", SESSION_END_TIME_FIELD_NAME,"},{"lineNumber":695,"author":{"gitId":"-"},"content":" (firstTime, secondTime) -\u003e firstTime.isBefore(secondTime) || firstTime.equals(secondTime),"},{"lineNumber":696,"author":{"gitId":"-"},"content":" \"The %s for this %s cannot be earlier than %s.\");"},{"lineNumber":697,"author":{"gitId":"-"},"content":" if (!earlierThanThreeHoursBeforeNowError.isEmpty()) {"},{"lineNumber":698,"author":{"gitId":"-"},"content":" return earlierThanThreeHoursBeforeNowError;"},{"lineNumber":699,"author":{"gitId":"-"},"content":" }"},{"lineNumber":700,"author":{"gitId":"-"},"content":""},{"lineNumber":701,"author":{"gitId":"-"},"content":" Instant twelveMonthsFromNow \u003d TimeHelper.getInstantMonthsOffsetFromNow(12, timeZone);"},{"lineNumber":702,"author":{"gitId":"-"},"content":" String laterThanTwelveMonthsError \u003d getInvalidityInfoForFirstTimeComparedToSecondTime("},{"lineNumber":703,"author":{"gitId":"-"},"content":" twelveMonthsFromNow, endTime, SESSION_NAME,"},{"lineNumber":704,"author":{"gitId":"-"},"content":" \"12 months from now\", SESSION_END_TIME_FIELD_NAME,"},{"lineNumber":705,"author":{"gitId":"-"},"content":" (firstTime, secondTime) -\u003e firstTime.isAfter(secondTime) || firstTime.equals(secondTime),"},{"lineNumber":706,"author":{"gitId":"-"},"content":" \"The %s for this %s cannot be later than %s.\");"},{"lineNumber":707,"author":{"gitId":"-"},"content":" if (!laterThanTwelveMonthsError.isEmpty()) {"},{"lineNumber":708,"author":{"gitId":"-"},"content":" return laterThanTwelveMonthsError;"},{"lineNumber":709,"author":{"gitId":"-"},"content":" }"},{"lineNumber":710,"author":{"gitId":"-"},"content":""},{"lineNumber":711,"author":{"gitId":"-"},"content":" String notExactHourError \u003d getInvalidityInfoForExactHourTime(endTime, timeZone, \"end time\");"},{"lineNumber":712,"author":{"gitId":"-"},"content":" if (!notExactHourError.isEmpty()) {"},{"lineNumber":713,"author":{"gitId":"-"},"content":" return notExactHourError;"},{"lineNumber":714,"author":{"gitId":"-"},"content":" }"},{"lineNumber":715,"author":{"gitId":"-"},"content":""},{"lineNumber":716,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":717,"author":{"gitId":"-"},"content":" }"},{"lineNumber":718,"author":{"gitId":"-"},"content":""},{"lineNumber":719,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":720,"author":{"gitId":"-"},"content":" * Checks if Session Start Time is before Session End Time."},{"lineNumber":721,"author":{"gitId":"-"},"content":" * @return Error string if {@code sessionStart} is before {@code sessionEnd}"},{"lineNumber":722,"author":{"gitId":"-"},"content":" * Empty string if {@code sessionStart} is after {@code sessionEnd}"},{"lineNumber":723,"author":{"gitId":"-"},"content":" */"},{"lineNumber":724,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForTimeForSessionStartAndEnd(Instant sessionStart, Instant sessionEnd) {"},{"lineNumber":725,"author":{"gitId":"-"},"content":" return getInvalidityInfoForFirstTimeIsBeforeSecondTime("},{"lineNumber":726,"author":{"gitId":"-"},"content":" sessionStart, sessionEnd, SESSION_NAME, SESSION_START_TIME_FIELD_NAME, SESSION_END_TIME_FIELD_NAME);"},{"lineNumber":727,"author":{"gitId":"-"},"content":" }"},{"lineNumber":728,"author":{"gitId":"-"},"content":""},{"lineNumber":729,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":730,"author":{"gitId":"-"},"content":" * Checks if Session Visibility Start Time is before Session Start Time."},{"lineNumber":731,"author":{"gitId":"-"},"content":" * @return Error string if {@code visibilityStart} is before {@code sessionStart}"},{"lineNumber":732,"author":{"gitId":"-"},"content":" * Empty string if {@code visibilityStart} is after {@code sessionStart}"},{"lineNumber":733,"author":{"gitId":"-"},"content":" */"},{"lineNumber":734,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForTimeForVisibilityStartAndSessionStart("},{"lineNumber":735,"author":{"gitId":"-"},"content":" Instant visibilityStart, Instant sessionStart) {"},{"lineNumber":736,"author":{"gitId":"-"},"content":" return getInvalidityInfoForFirstTimeIsBeforeSecondTime(visibilityStart, sessionStart,"},{"lineNumber":737,"author":{"gitId":"-"},"content":" SESSION_NAME, SESSION_VISIBLE_TIME_FIELD_NAME, SESSION_START_TIME_FIELD_NAME);"},{"lineNumber":738,"author":{"gitId":"-"},"content":" }"},{"lineNumber":739,"author":{"gitId":"-"},"content":""},{"lineNumber":740,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":741,"author":{"gitId":"-"},"content":" * Checks if the {@code visibilityStart} is valid to be used as a session visible start time."},{"lineNumber":742,"author":{"gitId":"-"},"content":" * Returns an empty string if it is valid, or an error message otherwise."},{"lineNumber":743,"author":{"gitId":"-"},"content":" *"},{"lineNumber":744,"author":{"gitId":"-"},"content":" * \u003cp\u003eThe {@code visibilityStart} is valid if it is less than 30 days before {@code sessionStart}."},{"lineNumber":745,"author":{"gitId":"-"},"content":" */"},{"lineNumber":746,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForTimeForNewVisibilityStart(Instant visibilityStart, Instant sessionStart) {"},{"lineNumber":747,"author":{"gitId":"-"},"content":" Instant visibilityStartThirtyDaysBeforeSessionStart \u003d sessionStart.minus(Duration.ofDays(30));"},{"lineNumber":748,"author":{"gitId":"-"},"content":" String visibilityStartMoreThanThirtyDaysBeforeSessionStartError \u003d"},{"lineNumber":749,"author":{"gitId":"-"},"content":" getInvalidityInfoForFirstTimeComparedToSecondTime("},{"lineNumber":750,"author":{"gitId":"-"},"content":" visibilityStartThirtyDaysBeforeSessionStart, visibilityStart, SESSION_NAME,"},{"lineNumber":751,"author":{"gitId":"-"},"content":" \"30 days before start time\", SESSION_VISIBLE_TIME_FIELD_NAME,"},{"lineNumber":752,"author":{"gitId":"-"},"content":" (firstTime, secondTime) -\u003e firstTime.isBefore(secondTime) || firstTime.equals(secondTime),"},{"lineNumber":753,"author":{"gitId":"-"},"content":" \"The %s for this %s cannot be earlier than %s.\");"},{"lineNumber":754,"author":{"gitId":"-"},"content":" if (!visibilityStartMoreThanThirtyDaysBeforeSessionStartError.isEmpty()) {"},{"lineNumber":755,"author":{"gitId":"-"},"content":" return visibilityStartMoreThanThirtyDaysBeforeSessionStartError;"},{"lineNumber":756,"author":{"gitId":"-"},"content":" }"},{"lineNumber":757,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":758,"author":{"gitId":"-"},"content":" }"},{"lineNumber":759,"author":{"gitId":"-"},"content":""},{"lineNumber":760,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":761,"author":{"gitId":"-"},"content":" * Checks if Visibility Start Time is before Results Publish Time."},{"lineNumber":762,"author":{"gitId":"-"},"content":" * @return Error string if {@code visibilityStart} is before {@code resultsPublish}"},{"lineNumber":763,"author":{"gitId":"-"},"content":" * Empty string if {@code visibilityStart} is after {@code resultsPublish}"},{"lineNumber":764,"author":{"gitId":"-"},"content":" */"},{"lineNumber":765,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForTimeForVisibilityStartAndResultsPublish("},{"lineNumber":766,"author":{"gitId":"-"},"content":" Instant visibilityStart, Instant resultsPublish) {"},{"lineNumber":767,"author":{"gitId":"-"},"content":" return getInvalidityInfoForFirstTimeIsBeforeSecondTime(visibilityStart, resultsPublish,"},{"lineNumber":768,"author":{"gitId":"-"},"content":" SESSION_NAME, SESSION_VISIBLE_TIME_FIELD_NAME, RESULTS_VISIBLE_TIME_FIELD_NAME);"},{"lineNumber":769,"author":{"gitId":"-"},"content":" }"},{"lineNumber":770,"author":{"gitId":"-"},"content":""},{"lineNumber":771,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":772,"author":{"gitId":"-"},"content":" * Checks if the session end time is before all extended deadlines."},{"lineNumber":773,"author":{"gitId":"-"},"content":" * @return Error string if any deadline in {@code deadlines} is before {@code sessionEnd}, an empty one otherwise."},{"lineNumber":774,"author":{"gitId":"-"},"content":" */"},{"lineNumber":775,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForTimeForSessionEndAndExtendedDeadlines("},{"lineNumber":776,"author":{"gitId":"-"},"content":" Instant sessionEnd, Map\u003cString, Instant\u003e deadlines) {"},{"lineNumber":777,"author":{"gitId":"-"},"content":" return deadlines.entrySet()"},{"lineNumber":778,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":779,"author":{"gitId":"-"},"content":" .map(entry -\u003e getInvalidityInfoForFirstTimeIsStrictlyBeforeSecondTime(sessionEnd, entry.getValue(),"},{"lineNumber":780,"author":{"gitId":"-"},"content":" SESSION_NAME, SESSION_END_TIME_FIELD_NAME, EXTENDED_DEADLINES_FIELD_NAME))"},{"lineNumber":781,"author":{"gitId":"-"},"content":" .filter(invalidityInfo -\u003e !invalidityInfo.isEmpty())"},{"lineNumber":782,"author":{"gitId":"-"},"content":" .findFirst()"},{"lineNumber":783,"author":{"gitId":"-"},"content":" .orElse(\"\");"},{"lineNumber":784,"author":{"gitId":"-"},"content":" }"},{"lineNumber":785,"author":{"gitId":"-"},"content":""},{"lineNumber":786,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":787,"author":{"gitId":"-"},"content":" * Checks if the session end time is before all extended deadlines."},{"lineNumber":788,"author":{"gitId":"-"},"content":" * @return Error string if any deadline in {@code deadlines} is before {@code sessionEnd}, an empty one otherwise."},{"lineNumber":789,"author":{"gitId":"-"},"content":" */"},{"lineNumber":790,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForTimeForSessionEndAndExtendedDeadlines("},{"lineNumber":791,"author":{"gitId":"-"},"content":" Instant sessionEnd, List\u003cDeadlineExtension\u003e deadlineExtensions) {"},{"lineNumber":792,"author":{"gitId":"-"},"content":" for (DeadlineExtension de : deadlineExtensions) {"},{"lineNumber":793,"author":{"gitId":"-"},"content":" String err \u003d getInvalidityInfoForFirstTimeIsStrictlyBeforeSecondTime(sessionEnd, de.getEndTime(),"},{"lineNumber":794,"author":{"gitId":"-"},"content":" SESSION_NAME, SESSION_END_TIME_FIELD_NAME, EXTENDED_DEADLINES_FIELD_NAME);"},{"lineNumber":795,"author":{"gitId":"-"},"content":""},{"lineNumber":796,"author":{"gitId":"-"},"content":" if (!err.isEmpty()) {"},{"lineNumber":797,"author":{"gitId":"-"},"content":" return err;"},{"lineNumber":798,"author":{"gitId":"-"},"content":" }"},{"lineNumber":799,"author":{"gitId":"-"},"content":" }"},{"lineNumber":800,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":801,"author":{"gitId":"-"},"content":" }"},{"lineNumber":802,"author":{"gitId":"-"},"content":""},{"lineNumber":803,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":804,"author":{"gitId":"-"},"content":" * Checks if Notification Start Time is before Notification End Time."},{"lineNumber":805,"author":{"gitId":"-"},"content":" * @return Error string if {@code notificationStart} is before {@code notificationEnd}"},{"lineNumber":806,"author":{"gitId":"-"},"content":" * Empty string if {@code notificationStart} is after {@code notificationEnd}"},{"lineNumber":807,"author":{"gitId":"-"},"content":" */"},{"lineNumber":808,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForTimeForNotificationStartAndEnd("},{"lineNumber":809,"author":{"gitId":"-"},"content":" Instant notificationStart, Instant notificationExpiry) {"},{"lineNumber":810,"author":{"gitId":"-"},"content":" return getInvalidityInfoForFirstTimeIsBeforeSecondTime(notificationStart, notificationExpiry,"},{"lineNumber":811,"author":{"gitId":"-"},"content":" NOTIFICATION_NAME, NOTIFICATION_VISIBLE_TIME_FIELD_NAME, NOTIFICATION_EXPIRY_TIME_FIELD_NAME);"},{"lineNumber":812,"author":{"gitId":"-"},"content":" }"},{"lineNumber":813,"author":{"gitId":"-"},"content":""},{"lineNumber":814,"author":{"gitId":"-"},"content":" private static String getInvalidityInfoForFirstTimeIsBeforeSecondTime(Instant earlierTime, Instant laterTime,"},{"lineNumber":815,"author":{"gitId":"-"},"content":" String entityName, String earlierTimeFieldName, String laterTimeFieldName) {"},{"lineNumber":816,"author":{"gitId":"-"},"content":" return getInvalidityInfoForFirstTimeComparedToSecondTime(earlierTime, laterTime, entityName,"},{"lineNumber":817,"author":{"gitId":"-"},"content":" earlierTimeFieldName, laterTimeFieldName,"},{"lineNumber":818,"author":{"gitId":"-"},"content":" (firstTime, secondTime) -\u003e firstTime.isBefore(secondTime) || firstTime.equals(secondTime),"},{"lineNumber":819,"author":{"gitId":"-"},"content":" TIME_BEFORE_ERROR_MESSAGE);"},{"lineNumber":820,"author":{"gitId":"-"},"content":" }"},{"lineNumber":821,"author":{"gitId":"-"},"content":""},{"lineNumber":822,"author":{"gitId":"-"},"content":" private static String getInvalidityInfoForFirstTimeIsStrictlyBeforeSecondTime("},{"lineNumber":823,"author":{"gitId":"-"},"content":" Instant earlierTime, Instant laterTime, String entityName, String earlierTimeFieldName,"},{"lineNumber":824,"author":{"gitId":"-"},"content":" String laterTimeFieldName) {"},{"lineNumber":825,"author":{"gitId":"-"},"content":" return getInvalidityInfoForFirstTimeComparedToSecondTime(earlierTime, laterTime, entityName,"},{"lineNumber":826,"author":{"gitId":"-"},"content":" earlierTimeFieldName, laterTimeFieldName, Instant::isBefore,"},{"lineNumber":827,"author":{"gitId":"-"},"content":" TIME_BEFORE_OR_EQUAL_ERROR_MESSAGE);"},{"lineNumber":828,"author":{"gitId":"-"},"content":" }"},{"lineNumber":829,"author":{"gitId":"-"},"content":""},{"lineNumber":830,"author":{"gitId":"-"},"content":" private static String getInvalidityInfoForFirstTimeComparedToSecondTime(Instant earlierTime, Instant laterTime,"},{"lineNumber":831,"author":{"gitId":"-"},"content":" String entityName, String earlierTimeFieldName, String laterTimeFieldName,"},{"lineNumber":832,"author":{"gitId":"-"},"content":" BiPredicate\u003cInstant, Instant\u003e validityChecker,"},{"lineNumber":833,"author":{"gitId":"-"},"content":" String invalidityInfoTemplate) {"},{"lineNumber":834,"author":{"gitId":"-"},"content":""},{"lineNumber":835,"author":{"gitId":"-"},"content":" assert earlierTime !\u003d null;"},{"lineNumber":836,"author":{"gitId":"-"},"content":" assert laterTime !\u003d null;"},{"lineNumber":837,"author":{"gitId":"-"},"content":""},{"lineNumber":838,"author":{"gitId":"-"},"content":" if (TimeHelper.isSpecialTime(earlierTime) || TimeHelper.isSpecialTime(laterTime)) {"},{"lineNumber":839,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":840,"author":{"gitId":"-"},"content":" }"},{"lineNumber":841,"author":{"gitId":"-"},"content":""},{"lineNumber":842,"author":{"gitId":"-"},"content":" if (!validityChecker.test(earlierTime, laterTime)) {"},{"lineNumber":843,"author":{"gitId":"-"},"content":" return String.format(invalidityInfoTemplate, laterTimeFieldName, entityName, earlierTimeFieldName);"},{"lineNumber":844,"author":{"gitId":"-"},"content":" }"},{"lineNumber":845,"author":{"gitId":"-"},"content":""},{"lineNumber":846,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":847,"author":{"gitId":"-"},"content":" }"},{"lineNumber":848,"author":{"gitId":"-"},"content":""},{"lineNumber":849,"author":{"gitId":"-"},"content":" private static String getInvalidityInfoForExactHourTime(Instant time, String timeZone, String timeName) {"},{"lineNumber":850,"author":{"gitId":"-"},"content":" // Timezone offsets are usually a whole number of hours, but a few zones are offset by"},{"lineNumber":851,"author":{"gitId":"-"},"content":" // an additional 30 or 45 minutes, such as in India, South Australia and Nepal."},{"lineNumber":852,"author":{"gitId":"-"},"content":" boolean isExactHour \u003d LocalDateTime.ofInstant(time, ZoneId.of(timeZone)).getMinute() \u003d\u003d 0;"},{"lineNumber":853,"author":{"gitId":"-"},"content":" if (!isExactHour) {"},{"lineNumber":854,"author":{"gitId":"-"},"content":" return String.format(NOT_EXACT_HOUR_ERROR_MESSAGE, timeName);"},{"lineNumber":855,"author":{"gitId":"-"},"content":" }"},{"lineNumber":856,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":857,"author":{"gitId":"-"},"content":" }"},{"lineNumber":858,"author":{"gitId":"-"},"content":""},{"lineNumber":859,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":860,"author":{"gitId":"-"},"content":" * Checks if both the giver type and recipient type for the feedback question is valid."},{"lineNumber":861,"author":{"gitId":"-"},"content":" *"},{"lineNumber":862,"author":{"gitId":"-"},"content":" * @param giverType feedback question giver type to be checked."},{"lineNumber":863,"author":{"gitId":"-"},"content":" * @param recipientType feedback question recipient type to be checked."},{"lineNumber":864,"author":{"gitId":"-"},"content":" * @return Error string if either type is invalid, otherwise empty string."},{"lineNumber":865,"author":{"gitId":"-"},"content":" */"},{"lineNumber":866,"author":{"gitId":"-"},"content":" public static List\u003cString\u003e getValidityInfoForFeedbackParticipantType("},{"lineNumber":867,"author":{"gitId":"-"},"content":" FeedbackParticipantType giverType, FeedbackParticipantType recipientType) {"},{"lineNumber":868,"author":{"gitId":"-"},"content":""},{"lineNumber":869,"author":{"gitId":"-"},"content":" assert giverType !\u003d null;"},{"lineNumber":870,"author":{"gitId":"-"},"content":" assert recipientType !\u003d null;"},{"lineNumber":871,"author":{"gitId":"-"},"content":""},{"lineNumber":872,"author":{"gitId":"-"},"content":" List\u003cString\u003e errors \u003d new LinkedList\u003c\u003e();"},{"lineNumber":873,"author":{"gitId":"-"},"content":" if (!giverType.isValidGiver()) {"},{"lineNumber":874,"author":{"gitId":"-"},"content":" errors.add(String.format(PARTICIPANT_TYPE_ERROR_MESSAGE, giverType.toString(), GIVER_TYPE_NAME));"},{"lineNumber":875,"author":{"gitId":"-"},"content":" }"},{"lineNumber":876,"author":{"gitId":"-"},"content":" if (!recipientType.isValidRecipient()) {"},{"lineNumber":877,"author":{"gitId":"-"},"content":" errors.add(String.format(PARTICIPANT_TYPE_ERROR_MESSAGE, recipientType.toString(), RECIPIENT_TYPE_NAME));"},{"lineNumber":878,"author":{"gitId":"-"},"content":" }"},{"lineNumber":879,"author":{"gitId":"-"},"content":" if (giverType \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":880,"author":{"gitId":"-"},"content":" \u0026\u0026 (recipientType \u003d\u003d FeedbackParticipantType.OWN_TEAM"},{"lineNumber":881,"author":{"gitId":"-"},"content":" || recipientType \u003d\u003d FeedbackParticipantType.OWN_TEAM_MEMBERS)) {"},{"lineNumber":882,"author":{"gitId":"-"},"content":" String displayRecipientName \u003d recipientType \u003d\u003d FeedbackParticipantType.OWN_TEAM"},{"lineNumber":883,"author":{"gitId":"-"},"content":" ? \"Giver\u0027s team\" : \"Giver\u0027s team members\";"},{"lineNumber":884,"author":{"gitId":"-"},"content":" errors.add(String.format(PARTICIPANT_TYPE_TEAM_ERROR_MESSAGE,"},{"lineNumber":885,"author":{"gitId":"-"},"content":" displayRecipientName,"},{"lineNumber":886,"author":{"gitId":"-"},"content":" \"Teams in this course\"));"},{"lineNumber":887,"author":{"gitId":"-"},"content":" }"},{"lineNumber":888,"author":{"gitId":"-"},"content":""},{"lineNumber":889,"author":{"gitId":"-"},"content":" return errors;"},{"lineNumber":890,"author":{"gitId":"-"},"content":" }"},{"lineNumber":891,"author":{"gitId":"-"},"content":""},{"lineNumber":892,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":893,"author":{"gitId":"-"},"content":" * Checks if comment giver type is either instructor, student or team."},{"lineNumber":894,"author":{"gitId":"-"},"content":" *"},{"lineNumber":895,"author":{"gitId":"-"},"content":" * @param commentGiverType comment giver type to be checked."},{"lineNumber":896,"author":{"gitId":"-"},"content":" * @return Error string if type is invalid, otherwise empty string."},{"lineNumber":897,"author":{"gitId":"-"},"content":" */"},{"lineNumber":898,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForCommentGiverType(FeedbackParticipantType commentGiverType) {"},{"lineNumber":899,"author":{"gitId":"-"},"content":" assert commentGiverType !\u003d null;"},{"lineNumber":900,"author":{"gitId":"-"},"content":" if (!commentGiverType.equals(FeedbackParticipantType.STUDENTS)"},{"lineNumber":901,"author":{"gitId":"-"},"content":" \u0026\u0026 !commentGiverType.equals(FeedbackParticipantType.INSTRUCTORS)"},{"lineNumber":902,"author":{"gitId":"-"},"content":" \u0026\u0026 !commentGiverType.equals(FeedbackParticipantType.TEAMS)) {"},{"lineNumber":903,"author":{"gitId":"-"},"content":" return \"Invalid comment giver type: \" + commentGiverType;"},{"lineNumber":904,"author":{"gitId":"-"},"content":" }"},{"lineNumber":905,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":906,"author":{"gitId":"-"},"content":" }"},{"lineNumber":907,"author":{"gitId":"-"},"content":""},{"lineNumber":908,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":909,"author":{"gitId":"-"},"content":" * Checks if visibility of comment is following question when comment is from a feedback participant."},{"lineNumber":910,"author":{"gitId":"-"},"content":" *"},{"lineNumber":911,"author":{"gitId":"-"},"content":" * @param isCommentFromFeedbackParticipant true if comment is from feedback participant."},{"lineNumber":912,"author":{"gitId":"-"},"content":" * @param isVisibilityFollowingFeedbackQuestion true if visibility of comment follows question."},{"lineNumber":913,"author":{"gitId":"-"},"content":" * @return Error string if condition is not met, otherwise empty string."},{"lineNumber":914,"author":{"gitId":"-"},"content":" */"},{"lineNumber":915,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForVisibilityOfFeedbackParticipantComments("},{"lineNumber":916,"author":{"gitId":"-"},"content":" boolean isCommentFromFeedbackParticipant,"},{"lineNumber":917,"author":{"gitId":"-"},"content":" boolean isVisibilityFollowingFeedbackQuestion) {"},{"lineNumber":918,"author":{"gitId":"-"},"content":" if (isCommentFromFeedbackParticipant \u0026\u0026 !isVisibilityFollowingFeedbackQuestion) {"},{"lineNumber":919,"author":{"gitId":"-"},"content":" return \"Comment by feedback participant not following visibility setting of the question.\";"},{"lineNumber":920,"author":{"gitId":"-"},"content":" }"},{"lineNumber":921,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":922,"author":{"gitId":"-"},"content":" }"},{"lineNumber":923,"author":{"gitId":"-"},"content":""},{"lineNumber":924,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":925,"author":{"gitId":"-"},"content":" * Checks if all the given participant types are valid for the purpose of"},{"lineNumber":926,"author":{"gitId":"-"},"content":" * showing different fields of a feedback response."},{"lineNumber":927,"author":{"gitId":"-"},"content":" *"},{"lineNumber":928,"author":{"gitId":"-"},"content":" * @param showResponsesTo the list of participant types to whom responses can be shown"},{"lineNumber":929,"author":{"gitId":"-"},"content":" * @param showGiverNameTo the list of participant types to whom giver name can be shown"},{"lineNumber":930,"author":{"gitId":"-"},"content":" * @param showRecipientNameTo the list of participant types to whom recipient name can be shown"},{"lineNumber":931,"author":{"gitId":"-"},"content":" * @return Error string if any type in any list is invalid, otherwise empty string."},{"lineNumber":932,"author":{"gitId":"-"},"content":" */"},{"lineNumber":933,"author":{"gitId":"-"},"content":" public static List\u003cString\u003e getValidityInfoForFeedbackResponseVisibility("},{"lineNumber":934,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showResponsesTo,"},{"lineNumber":935,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showGiverNameTo,"},{"lineNumber":936,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showRecipientNameTo) {"},{"lineNumber":937,"author":{"gitId":"-"},"content":""},{"lineNumber":938,"author":{"gitId":"-"},"content":" assert showResponsesTo !\u003d null;"},{"lineNumber":939,"author":{"gitId":"-"},"content":" assert showGiverNameTo !\u003d null;"},{"lineNumber":940,"author":{"gitId":"-"},"content":" assert showRecipientNameTo !\u003d null;"},{"lineNumber":941,"author":{"gitId":"-"},"content":" assert !showResponsesTo.contains(null);"},{"lineNumber":942,"author":{"gitId":"-"},"content":" assert !showGiverNameTo.contains(null);"},{"lineNumber":943,"author":{"gitId":"-"},"content":" assert !showRecipientNameTo.contains(null);"},{"lineNumber":944,"author":{"gitId":"-"},"content":""},{"lineNumber":945,"author":{"gitId":"-"},"content":" List\u003cString\u003e errors \u003d new LinkedList\u003c\u003e();"},{"lineNumber":946,"author":{"gitId":"-"},"content":""},{"lineNumber":947,"author":{"gitId":"-"},"content":" for (FeedbackParticipantType type : showGiverNameTo) {"},{"lineNumber":948,"author":{"gitId":"-"},"content":" if (!type.isValidViewer()) {"},{"lineNumber":949,"author":{"gitId":"-"},"content":" errors.add(String.format(PARTICIPANT_TYPE_ERROR_MESSAGE,"},{"lineNumber":950,"author":{"gitId":"-"},"content":" type.toString(), VIEWER_TYPE_NAME));"},{"lineNumber":951,"author":{"gitId":"-"},"content":" }"},{"lineNumber":952,"author":{"gitId":"-"},"content":" if (!showResponsesTo.contains(type)) {"},{"lineNumber":953,"author":{"gitId":"-"},"content":" errors.add(\"Trying to show giver name to \""},{"lineNumber":954,"author":{"gitId":"-"},"content":" + type.toString()"},{"lineNumber":955,"author":{"gitId":"-"},"content":" + \" without showing response first.\");"},{"lineNumber":956,"author":{"gitId":"-"},"content":" }"},{"lineNumber":957,"author":{"gitId":"-"},"content":" }"},{"lineNumber":958,"author":{"gitId":"-"},"content":""},{"lineNumber":959,"author":{"gitId":"-"},"content":" for (FeedbackParticipantType type : showRecipientNameTo) {"},{"lineNumber":960,"author":{"gitId":"-"},"content":" if (!type.isValidViewer()) {"},{"lineNumber":961,"author":{"gitId":"-"},"content":" errors.add(String.format(PARTICIPANT_TYPE_ERROR_MESSAGE,"},{"lineNumber":962,"author":{"gitId":"-"},"content":" type.toString(), VIEWER_TYPE_NAME));"},{"lineNumber":963,"author":{"gitId":"-"},"content":" }"},{"lineNumber":964,"author":{"gitId":"-"},"content":" if (!showResponsesTo.contains(type)) {"},{"lineNumber":965,"author":{"gitId":"-"},"content":" errors.add(\"Trying to show recipient name to \""},{"lineNumber":966,"author":{"gitId":"-"},"content":" + type.toString()"},{"lineNumber":967,"author":{"gitId":"-"},"content":" + \" without showing response first.\");"},{"lineNumber":968,"author":{"gitId":"-"},"content":" }"},{"lineNumber":969,"author":{"gitId":"-"},"content":" }"},{"lineNumber":970,"author":{"gitId":"-"},"content":""},{"lineNumber":971,"author":{"gitId":"-"},"content":" for (FeedbackParticipantType type : showResponsesTo) {"},{"lineNumber":972,"author":{"gitId":"-"},"content":" if (!type.isValidViewer()) {"},{"lineNumber":973,"author":{"gitId":"-"},"content":" errors.add(String.format(PARTICIPANT_TYPE_ERROR_MESSAGE,"},{"lineNumber":974,"author":{"gitId":"-"},"content":" type.toString(), VIEWER_TYPE_NAME));"},{"lineNumber":975,"author":{"gitId":"-"},"content":" }"},{"lineNumber":976,"author":{"gitId":"-"},"content":" }"},{"lineNumber":977,"author":{"gitId":"-"},"content":""},{"lineNumber":978,"author":{"gitId":"-"},"content":" return errors;"},{"lineNumber":979,"author":{"gitId":"-"},"content":" }"},{"lineNumber":980,"author":{"gitId":"-"},"content":""},{"lineNumber":981,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":982,"author":{"gitId":"-"},"content":" * Checks if the given {@code value} has no HTML code."},{"lineNumber":983,"author":{"gitId":"-"},"content":" */"},{"lineNumber":984,"author":{"gitId":"-"},"content":" static String getValidityInfoForNonHtmlField(String fieldName, String value) {"},{"lineNumber":985,"author":{"gitId":"-"},"content":" String sanitizedValue \u003d SanitizationHelper.sanitizeForHtml(value);"},{"lineNumber":986,"author":{"gitId":"-"},"content":" //Fails if sanitized value is not same as value"},{"lineNumber":987,"author":{"gitId":"-"},"content":" return value.equals(sanitizedValue) ? \"\" : NON_HTML_FIELD_ERROR_MESSAGE.replace(\"${fieldName}\", fieldName);"},{"lineNumber":988,"author":{"gitId":"-"},"content":" }"},{"lineNumber":989,"author":{"gitId":"-"},"content":""},{"lineNumber":990,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":991,"author":{"gitId":"-"},"content":" * Checks if the given {@code value} is not null."},{"lineNumber":992,"author":{"gitId":"-"},"content":" */"},{"lineNumber":993,"author":{"gitId":"-"},"content":" public static String getValidityInfoForNonNullField(String fieldName, Object value) {"},{"lineNumber":994,"author":{"gitId":"-"},"content":" return value \u003d\u003d null ? NON_NULL_FIELD_ERROR_MESSAGE.replace(\"${fieldName}\", fieldName) : \"\";"},{"lineNumber":995,"author":{"gitId":"-"},"content":" }"},{"lineNumber":996,"author":{"gitId":"-"},"content":""},{"lineNumber":997,"author":{"gitId":"-"},"content":" private static boolean isUntrimmed(String value) {"},{"lineNumber":998,"author":{"gitId":"-"},"content":" return value.length() !\u003d value.trim().length();"},{"lineNumber":999,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1000,"author":{"gitId":"-"},"content":""},{"lineNumber":1001,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1002,"author":{"gitId":"-"},"content":" * Checks whether a given text input represents a format of a valid email address."},{"lineNumber":1003,"author":{"gitId":"-"},"content":" * @param email text input which needs the validation"},{"lineNumber":1004,"author":{"gitId":"-"},"content":" * @return true if it is a valid email address, else false."},{"lineNumber":1005,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1006,"author":{"gitId":"-"},"content":" private static boolean isValidEmailAddress(String email) {"},{"lineNumber":1007,"author":{"gitId":"-"},"content":" return StringHelper.isMatching(email, REGEX_EMAIL);"},{"lineNumber":1008,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1009,"author":{"gitId":"-"},"content":""},{"lineNumber":1010,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1011,"author":{"gitId":"-"},"content":" * Checks whether all the elements in a Collection are unique."},{"lineNumber":1012,"author":{"gitId":"-"},"content":" * @param elements The Collection of elements to be checked."},{"lineNumber":1013,"author":{"gitId":"-"},"content":" * @return true if all elements are unique, else false."},{"lineNumber":1014,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1015,"author":{"gitId":"-"},"content":" public static \u003cT\u003e boolean areElementsUnique(Collection\u003cT\u003e elements) {"},{"lineNumber":1016,"author":{"gitId":"-"},"content":" Set\u003cT\u003e uniqueElements \u003d new HashSet\u003c\u003e(elements);"},{"lineNumber":1017,"author":{"gitId":"-"},"content":" return uniqueElements.size() \u003d\u003d elements.size();"},{"lineNumber":1018,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1019,"author":{"gitId":"-"},"content":""},{"lineNumber":1020,"author":{"gitId":"-"},"content":" private static String getPopulatedErrorMessage("},{"lineNumber":1021,"author":{"gitId":"-"},"content":" String messageTemplate, String userInput, String fieldName, String errorReason, int maxLength) {"},{"lineNumber":1022,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(messageTemplate, userInput, fieldName, errorReason)"},{"lineNumber":1023,"author":{"gitId":"-"},"content":" .replace(\"${maxLength}\", String.valueOf(maxLength));"},{"lineNumber":1024,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1025,"author":{"gitId":"-"},"content":""},{"lineNumber":1026,"author":{"gitId":"-"},"content":" private static String getPopulatedErrorMessage("},{"lineNumber":1027,"author":{"gitId":"-"},"content":" String messageTemplate, String userInput, String fieldName, String errorReason) {"},{"lineNumber":1028,"author":{"gitId":"-"},"content":" return messageTemplate.replace(\"${userInput}\", userInput)"},{"lineNumber":1029,"author":{"gitId":"-"},"content":" .replace(\"${fieldName}\", fieldName)"},{"lineNumber":1030,"author":{"gitId":"-"},"content":" .replace(\"${reason}\", errorReason);"},{"lineNumber":1031,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1032,"author":{"gitId":"-"},"content":""},{"lineNumber":1033,"author":{"gitId":"-"},"content":" private static String getPopulatedEmptyStringErrorMessage(String messageTemplate,"},{"lineNumber":1034,"author":{"gitId":"-"},"content":" String fieldName, int maxLength) {"},{"lineNumber":1035,"author":{"gitId":"-"},"content":" return messageTemplate.replace(\"${fieldName}\", fieldName)"},{"lineNumber":1036,"author":{"gitId":"-"},"content":" .replace(\"${maxLength}\", String.valueOf(maxLength));"},{"lineNumber":1037,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1038,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":1,"-":1037}},{"path":"src/main/java/teammates/common/util/HibernateUtil.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.util;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import jakarta.persistence.TypedQuery;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaBuilder;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaDelete;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaQuery;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.hibernate.Session;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import org.hibernate.SessionFactory;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.hibernate.Transaction;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import org.hibernate.cfg.Configuration;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import org.hibernate.query.MutationQuery;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import org.hibernate.resource.transaction.spi.TransactionStatus;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.BaseEntity;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.ReadNotification;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.UsageStatistics;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.User;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackConstantSumQuestion;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackContributionQuestion;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackMcqQuestion;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackMsqQuestion;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackNumericalScaleQuestion;"},{"lineNumber":41,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackRankOptionsQuestion;"},{"lineNumber":42,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackRankRecipientsQuestion;"},{"lineNumber":43,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackRubricQuestion;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackTextQuestion;"},{"lineNumber":45,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackConstantSumResponse;"},{"lineNumber":46,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackContributionResponse;"},{"lineNumber":47,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackMcqResponse;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackMsqResponse;"},{"lineNumber":49,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackNumericalScaleResponse;"},{"lineNumber":50,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackRankOptionsResponse;"},{"lineNumber":51,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackRankRecipientsResponse;"},{"lineNumber":52,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackRubricResponse;"},{"lineNumber":53,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackTextResponse;"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":56,"author":{"gitId":"-"},"content":" * Utility class for Hibernate related methods."},{"lineNumber":57,"author":{"gitId":"-"},"content":" */"},{"lineNumber":58,"author":{"gitId":"-"},"content":"public final class HibernateUtil {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" private static SessionFactory sessionFactory;"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" private static final List\u003cClass\u003c? extends BaseEntity\u003e\u003e ANNOTATED_CLASSES \u003d List.of("},{"lineNumber":62,"author":{"gitId":"-"},"content":" AccountRequest.class,"},{"lineNumber":63,"author":{"gitId":"-"},"content":" Course.class,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" FeedbackSession.class,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" Account.class,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" Notification.class,"},{"lineNumber":67,"author":{"gitId":"-"},"content":" ReadNotification.class,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" User.class,"},{"lineNumber":69,"author":{"gitId":"-"},"content":" Instructor.class,"},{"lineNumber":70,"author":{"gitId":"-"},"content":" Student.class,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" UsageStatistics.class,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" Section.class,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" Team.class,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" FeedbackQuestion.class,"},{"lineNumber":75,"author":{"gitId":"-"},"content":" FeedbackConstantSumQuestion.class,"},{"lineNumber":76,"author":{"gitId":"-"},"content":" FeedbackContributionQuestion.class,"},{"lineNumber":77,"author":{"gitId":"-"},"content":" FeedbackMcqQuestion.class,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" FeedbackMsqQuestion.class,"},{"lineNumber":79,"author":{"gitId":"-"},"content":" FeedbackNumericalScaleQuestion.class,"},{"lineNumber":80,"author":{"gitId":"-"},"content":" FeedbackRankOptionsQuestion.class,"},{"lineNumber":81,"author":{"gitId":"-"},"content":" FeedbackRankRecipientsQuestion.class,"},{"lineNumber":82,"author":{"gitId":"-"},"content":" FeedbackRubricQuestion.class,"},{"lineNumber":83,"author":{"gitId":"-"},"content":" FeedbackTextQuestion.class,"},{"lineNumber":84,"author":{"gitId":"-"},"content":" DeadlineExtension.class,"},{"lineNumber":85,"author":{"gitId":"-"},"content":" FeedbackResponse.class,"},{"lineNumber":86,"author":{"gitId":"-"},"content":" FeedbackConstantSumResponse.class,"},{"lineNumber":87,"author":{"gitId":"-"},"content":" FeedbackContributionResponse.class,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" FeedbackMcqResponse.class,"},{"lineNumber":89,"author":{"gitId":"-"},"content":" FeedbackMsqResponse.class,"},{"lineNumber":90,"author":{"gitId":"-"},"content":" FeedbackNumericalScaleResponse.class,"},{"lineNumber":91,"author":{"gitId":"-"},"content":" FeedbackRankOptionsResponse.class,"},{"lineNumber":92,"author":{"gitId":"-"},"content":" FeedbackRankRecipientsResponse.class,"},{"lineNumber":93,"author":{"gitId":"-"},"content":" FeedbackRubricResponse.class,"},{"lineNumber":94,"author":{"gitId":"-"},"content":" FeedbackTextResponse.class,"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" FeedbackResponseComment.class,"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog.class);"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" private HibernateUtil() {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" // Utility class"},{"lineNumber":100,"author":{"gitId":"-"},"content":" // Intentional private constructor to prevent instantiation."},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":104,"author":{"gitId":"-"},"content":" * Builds a session factory if it does not already exist."},{"lineNumber":105,"author":{"gitId":"-"},"content":" */"},{"lineNumber":106,"author":{"gitId":"-"},"content":" public static void buildSessionFactory(String dbUrl, String username, String password) {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" synchronized (HibernateUtil.class) {"},{"lineNumber":108,"author":{"gitId":"-"},"content":" if (sessionFactory !\u003d null) {"},{"lineNumber":109,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" Configuration config \u003d new Configuration()"},{"lineNumber":114,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.dialect\", \"org.hibernate.dialect.PostgreSQLDialect\")"},{"lineNumber":115,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.connection.driver_class\", \"org.postgresql.Driver\")"},{"lineNumber":116,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.connection.provider_class\","},{"lineNumber":117,"author":{"gitId":"-"},"content":" \"org.hibernate.hikaricp.internal.HikariCPConnectionProvider\")"},{"lineNumber":118,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.connection.username\", username)"},{"lineNumber":119,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.connection.password\", password)"},{"lineNumber":120,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.connection.url\", dbUrl)"},{"lineNumber":121,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.hbm2ddl.auto\", \"validate\")"},{"lineNumber":122,"author":{"gitId":"-"},"content":" .setProperty(\"show_sql\", \"true\")"},{"lineNumber":123,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.current_session_context_class\", \"thread\")"},{"lineNumber":124,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.hikari.minimumIdle\", \"10\")"},{"lineNumber":125,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.hikari.maximumPoolSize\", \"30\")"},{"lineNumber":126,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.hikari.idleTimeout\", \"300000\")"},{"lineNumber":127,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.hikari.connectionTimeout\", \"30000\")"},{"lineNumber":128,"author":{"gitId":"-"},"content":" // Uncomment only during migration for optimized batch-insertion, batch-update, and batch-fetch."},{"lineNumber":129,"author":{"gitId":"-"},"content":" // .setProperty(\"hibernate.jdbc.batch_size\", \"50\")"},{"lineNumber":130,"author":{"gitId":"-"},"content":" // .setProperty(\"hibernate.order_updates\", \"true\")"},{"lineNumber":131,"author":{"gitId":"-"},"content":" // .setProperty(\"hibernate.batch_versioned_data\", \"true\")"},{"lineNumber":132,"author":{"gitId":"-"},"content":" // .setProperty(\"hibernate.jdbc.fetch_size\", \"50\")"},{"lineNumber":133,"author":{"gitId":"-"},"content":" .addPackage(\"teammates.storage.sqlentity\");"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" if (Config.IS_DEV_SERVER) {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" config.setProperty(\"hibernate.hbm2ddl.auto\", \"update\");"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" for (Class\u003c? extends BaseEntity\u003e cls : ANNOTATED_CLASSES) {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" config \u003d config.addAnnotatedClass(cls);"},{"lineNumber":141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":142,"author":{"gitId":"-"},"content":" config.setPhysicalNamingStrategy(new CamelCaseToUnderscoresNamingStrategy());"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" setSessionFactory(config.buildSessionFactory());"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":148,"author":{"gitId":"-"},"content":" * Returns the SessionFactory."},{"lineNumber":149,"author":{"gitId":"-"},"content":" */"},{"lineNumber":150,"author":{"gitId":"-"},"content":" private static SessionFactory getSessionFactory() {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" assert sessionFactory !\u003d null;"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":" return sessionFactory;"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":157,"author":{"gitId":"-"},"content":" * Returns the current hibernate session."},{"lineNumber":158,"author":{"gitId":"-"},"content":" * @see SessionFactory#getCurrentSession()"},{"lineNumber":159,"author":{"gitId":"-"},"content":" */"},{"lineNumber":160,"author":{"gitId":"-"},"content":" private static Session getCurrentSession() {"},{"lineNumber":161,"author":{"gitId":"-"},"content":" return getSessionFactory().getCurrentSession();"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":165,"author":{"gitId":"-"},"content":" * Returns a CriteriaBuilder object."},{"lineNumber":166,"author":{"gitId":"-"},"content":" * @see SessionFactory#getCriteriaBuilder()"},{"lineNumber":167,"author":{"gitId":"-"},"content":" */"},{"lineNumber":168,"author":{"gitId":"-"},"content":" public static CriteriaBuilder getCriteriaBuilder() {"},{"lineNumber":169,"author":{"gitId":"-"},"content":" return getCurrentSession().getCriteriaBuilder();"},{"lineNumber":170,"author":{"gitId":"-"},"content":" }"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":173,"author":{"gitId":"-"},"content":" * Returns a generic typed TypedQuery object."},{"lineNumber":174,"author":{"gitId":"-"},"content":" * @see Session#createQuery(CriteriaQuery)"},{"lineNumber":175,"author":{"gitId":"-"},"content":" */"},{"lineNumber":176,"author":{"gitId":"-"},"content":" public static \u003cT\u003e TypedQuery\u003cT\u003e createQuery(CriteriaQuery\u003cT\u003e cr) {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" return getCurrentSession().createQuery(cr);"},{"lineNumber":178,"author":{"gitId":"-"},"content":" }"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":181,"author":{"gitId":"-"},"content":" * Returns a MutationQuery object."},{"lineNumber":182,"author":{"gitId":"-"},"content":" * @see Session#createMutationQuery(CriteriaDelete)"},{"lineNumber":183,"author":{"gitId":"-"},"content":" */"},{"lineNumber":184,"author":{"gitId":"-"},"content":" public static \u003cT\u003e MutationQuery createMutationQuery(CriteriaDelete\u003cT\u003e cd) {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" return getCurrentSession().createMutationQuery(cd);"},{"lineNumber":186,"author":{"gitId":"-"},"content":" }"},{"lineNumber":187,"author":{"gitId":"-"},"content":""},{"lineNumber":188,"author":{"gitId":"-"},"content":" public static void setSessionFactory(SessionFactory sessionFactory) {"},{"lineNumber":189,"author":{"gitId":"-"},"content":" HibernateUtil.sessionFactory \u003d sessionFactory;"},{"lineNumber":190,"author":{"gitId":"-"},"content":" }"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":193,"author":{"gitId":"-"},"content":" * Start a resource transaction."},{"lineNumber":194,"author":{"gitId":"-"},"content":" * @see Transaction#begin()"},{"lineNumber":195,"author":{"gitId":"-"},"content":" */"},{"lineNumber":196,"author":{"gitId":"-"},"content":" public static void beginTransaction() {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" Transaction transaction \u003d getCurrentSession().getTransaction();"},{"lineNumber":198,"author":{"gitId":"-"},"content":" transaction.begin();"},{"lineNumber":199,"author":{"gitId":"-"},"content":" }"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":202,"author":{"gitId":"-"},"content":" * Roll back the current resource transaction if needed."},{"lineNumber":203,"author":{"gitId":"-"},"content":" * @see Transaction#rollback()"},{"lineNumber":204,"author":{"gitId":"-"},"content":" */"},{"lineNumber":205,"author":{"gitId":"-"},"content":" public static void rollbackTransaction() {"},{"lineNumber":206,"author":{"gitId":"-"},"content":" Session session \u003d getCurrentSession();"},{"lineNumber":207,"author":{"gitId":"-"},"content":" if (session.getTransaction().getStatus() \u003d\u003d TransactionStatus.ACTIVE"},{"lineNumber":208,"author":{"gitId":"-"},"content":" || session.getTransaction().getStatus() \u003d\u003d TransactionStatus.MARKED_ROLLBACK) {"},{"lineNumber":209,"author":{"gitId":"-"},"content":" session.getTransaction().rollback();"},{"lineNumber":210,"author":{"gitId":"-"},"content":" }"},{"lineNumber":211,"author":{"gitId":"-"},"content":" }"},{"lineNumber":212,"author":{"gitId":"-"},"content":""},{"lineNumber":213,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":214,"author":{"gitId":"-"},"content":" * Commit the current resource transaction, writing any unflushed changes to the database."},{"lineNumber":215,"author":{"gitId":"-"},"content":" * @see Transaction#commit()"},{"lineNumber":216,"author":{"gitId":"-"},"content":" */"},{"lineNumber":217,"author":{"gitId":"-"},"content":" public static void commitTransaction() {"},{"lineNumber":218,"author":{"gitId":"-"},"content":" Transaction transaction \u003d getCurrentSession().getTransaction();"},{"lineNumber":219,"author":{"gitId":"-"},"content":" transaction.commit();"},{"lineNumber":220,"author":{"gitId":"-"},"content":" }"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":223,"author":{"gitId":"-"},"content":" * Force this session to flush. Must be called at the end of a unit of work, before the transaction is committed."},{"lineNumber":224,"author":{"gitId":"-"},"content":" * @see Session#flush()"},{"lineNumber":225,"author":{"gitId":"-"},"content":" */"},{"lineNumber":226,"author":{"gitId":"-"},"content":" public static void flushSession() {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" getCurrentSession().flush();"},{"lineNumber":228,"author":{"gitId":"-"},"content":" }"},{"lineNumber":229,"author":{"gitId":"-"},"content":""},{"lineNumber":230,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":231,"author":{"gitId":"-"},"content":" * Force this session to clear. Usually called together with flush."},{"lineNumber":232,"author":{"gitId":"-"},"content":" * @see Session#clear()"},{"lineNumber":233,"author":{"gitId":"-"},"content":" */"},{"lineNumber":234,"author":{"gitId":"-"},"content":" public static void clearSession() {"},{"lineNumber":235,"author":{"gitId":"-"},"content":" getCurrentSession().clear();"},{"lineNumber":236,"author":{"gitId":"-"},"content":" }"},{"lineNumber":237,"author":{"gitId":"-"},"content":""},{"lineNumber":238,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":239,"author":{"gitId":"-"},"content":" * Return the persistent instance of the given entity class with the given identifier,"},{"lineNumber":240,"author":{"gitId":"-"},"content":" * or null if there is no such persistent instance."},{"lineNumber":241,"author":{"gitId":"-"},"content":" * @see Session#get(Class, Object)"},{"lineNumber":242,"author":{"gitId":"-"},"content":" */"},{"lineNumber":243,"author":{"gitId":"-"},"content":" public static \u003cT extends BaseEntity\u003e T get(Class\u003cT\u003e entityType, Object id) {"},{"lineNumber":244,"author":{"gitId":"-"},"content":" return getCurrentSession().get(entityType, id);"},{"lineNumber":245,"author":{"gitId":"-"},"content":" }"},{"lineNumber":246,"author":{"gitId":"-"},"content":""},{"lineNumber":247,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":248,"author":{"gitId":"-"},"content":" * Return the persistent instance of the given entity class with the given natural id,"},{"lineNumber":249,"author":{"gitId":"-"},"content":" * or null if there is no such persistent instance."},{"lineNumber":250,"author":{"gitId":"-"},"content":" * @see Session#get(Class, Object)"},{"lineNumber":251,"author":{"gitId":"-"},"content":" */"},{"lineNumber":252,"author":{"gitId":"-"},"content":" public static \u003cT extends BaseEntity\u003e T getBySimpleNaturalId(Class\u003cT\u003e entityType, Object id) {"},{"lineNumber":253,"author":{"gitId":"-"},"content":" return getCurrentSession().bySimpleNaturalId(entityType).load(id);"},{"lineNumber":254,"author":{"gitId":"-"},"content":" }"},{"lineNumber":255,"author":{"gitId":"-"},"content":""},{"lineNumber":256,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":257,"author":{"gitId":"-"},"content":" * Copy the state of the given object onto the persistent object with the same identifier."},{"lineNumber":258,"author":{"gitId":"-"},"content":" * @see Session#merge(E)"},{"lineNumber":259,"author":{"gitId":"-"},"content":" */"},{"lineNumber":260,"author":{"gitId":"-"},"content":" public static \u003cE\u003e E merge(E object) {"},{"lineNumber":261,"author":{"gitId":"-"},"content":" return getCurrentSession().merge(object);"},{"lineNumber":262,"author":{"gitId":"-"},"content":" }"},{"lineNumber":263,"author":{"gitId":"-"},"content":""},{"lineNumber":264,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":265,"author":{"gitId":"-"},"content":" * Make a transient instance persistent and mark it for later insertion in the database."},{"lineNumber":266,"author":{"gitId":"-"},"content":" * @see Session#persist(Object)"},{"lineNumber":267,"author":{"gitId":"-"},"content":" */"},{"lineNumber":268,"author":{"gitId":"-"},"content":" public static void persist(BaseEntity entity) {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" getCurrentSession().persist(entity);"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":273,"author":{"gitId":"-"},"content":" * Mark a persistence instance associated with this session for removal from the underlying database."},{"lineNumber":274,"author":{"gitId":"-"},"content":" * @see Session#remove(Object)"},{"lineNumber":275,"author":{"gitId":"-"},"content":" */"},{"lineNumber":276,"author":{"gitId":"-"},"content":" public static void remove(BaseEntity entity) {"},{"lineNumber":277,"author":{"gitId":"-"},"content":" getCurrentSession().remove(entity);"},{"lineNumber":278,"author":{"gitId":"-"},"content":" }"},{"lineNumber":279,"author":{"gitId":"-"},"content":""},{"lineNumber":280,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":281,"author":{"gitId":"-"},"content":" * Create and execute a {@code MutationQuery} for the given delete criteria tree."},{"lineNumber":282,"author":{"gitId":"-"},"content":" */"},{"lineNumber":283,"author":{"gitId":"-"},"content":" public static \u003cT\u003e void executeDelete(CriteriaDelete\u003cT\u003e cd) {"},{"lineNumber":284,"author":{"gitId":"-"},"content":" getCurrentSession().createMutationQuery(cd).executeUpdate();"},{"lineNumber":285,"author":{"gitId":"-"},"content":" }"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":288,"author":{"gitId":"dishenggg"},"content":" * Return a reference to the persistent instance with the given class and"},{"lineNumber":289,"author":{"gitId":"dishenggg"},"content":" * identifier,making the assumption that the instance is still persistent in the"},{"lineNumber":290,"author":{"gitId":"dishenggg"},"content":" * database."},{"lineNumber":291,"author":{"gitId":"dishenggg"},"content":" * @see Session#getReference(Class, Object)"},{"lineNumber":292,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":293,"author":{"gitId":"dishenggg"},"content":" public static \u003cT\u003e T getReference(Class\u003cT\u003e entityType, Object id) {"},{"lineNumber":294,"author":{"gitId":"-"},"content":" return getCurrentSession().getReference(entityType, id);"},{"lineNumber":295,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":296,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":297,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":12,"-":285}},{"path":"src/main/java/teammates/common/util/Templates.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.util;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":4,"author":{"gitId":"-"},"content":" * Contains utility methods for creating strings from given templates."},{"lineNumber":5,"author":{"gitId":"-"},"content":" */"},{"lineNumber":6,"author":{"gitId":"-"},"content":"public final class Templates {"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_SAMPLE_DATA \u003d FileHelper.readResourceFile(\"InstructorSampleData.json\");"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":" private Templates() {"},{"lineNumber":11,"author":{"gitId":"-"},"content":" // utility class"},{"lineNumber":12,"author":{"gitId":"-"},"content":" }"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":15,"author":{"gitId":"-"},"content":" * Populates the HTML templates by replacing variables in the template string"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * with the given value strings."},{"lineNumber":17,"author":{"gitId":"-"},"content":" * @param template The template html to be populated"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * @param keyValuePairs Array of a variable, even number of key-value pairs:"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * { \"key1\", \"val1\", \"key2\", \"val2\", ... }"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * @return The populated template"},{"lineNumber":21,"author":{"gitId":"-"},"content":" */"},{"lineNumber":22,"author":{"gitId":"-"},"content":" public static String populateTemplate(String template, String... keyValuePairs) {"},{"lineNumber":23,"author":{"gitId":"-"},"content":" assert keyValuePairs.length % 2 \u003d\u003d 0 : \"The number of elements in keyValuePairs passed in must be even\";"},{"lineNumber":24,"author":{"gitId":"-"},"content":" String populatedTemplate \u003d template;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c keyValuePairs.length; i +\u003d 2) {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" populatedTemplate \u003d populatedTemplate.replace(keyValuePairs[i], keyValuePairs[i + 1]);"},{"lineNumber":27,"author":{"gitId":"-"},"content":" }"},{"lineNumber":28,"author":{"gitId":"-"},"content":" return populatedTemplate;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":32,"author":{"gitId":"-"},"content":" * Collection of templates of emails to be sent by the system."},{"lineNumber":33,"author":{"gitId":"-"},"content":" */"},{"lineNumber":34,"author":{"gitId":"-"},"content":" public static class EmailTemplates {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" public static final String ADMIN_NEW_ACCOUNT_REQUEST_ALERT \u003d"},{"lineNumber":36,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"adminEmailTemplate-newAccountRequestAlert.html\");"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" public static final String INSTRUCTOR_NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT \u003d"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" FileHelper.readResourceFile(\"instructorEmailTemplate-newAccountRequestAcknowledgement.html\");"},{"lineNumber":39,"author":{"gitId":"-"},"content":" public static final String USER_COURSE_JOIN \u003d"},{"lineNumber":40,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplate-courseJoin.html\");"},{"lineNumber":41,"author":{"gitId":"-"},"content":" public static final String USER_COURSE_REGISTER \u003d"},{"lineNumber":42,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplate-userRegisterForCourse.html\");"},{"lineNumber":43,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_STUDENT_COURSE_JOIN \u003d"},{"lineNumber":44,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"studentEmailFragment-courseJoin.html\");"},{"lineNumber":45,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_STUDENT_COURSE_REJOIN_AFTER_GOOGLE_ID_RESET \u003d"},{"lineNumber":46,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"studentEmailFragment-googleIdReset.html\");"},{"lineNumber":47,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_STUDENT_COURSE_REJOIN_AFTER_REGKEY_RESET \u003d"},{"lineNumber":48,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"studentEmailFragment-registrationKeyReset.html\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_INSTRUCTOR_COPY_PREAMBLE \u003d"},{"lineNumber":50,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"instructorEmailFragment-instructorCopyPreamble.html\");"},{"lineNumber":51,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_INSTRUCTOR_COURSE_JOIN \u003d"},{"lineNumber":52,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"instructorEmailFragment-courseJoin.html\");"},{"lineNumber":53,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_INSTRUCTOR_COURSE_REJOIN_AFTER_GOOGLE_ID_RESET \u003d"},{"lineNumber":54,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"instructorEmailFragment-googleIdReset.html\");"},{"lineNumber":55,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_INSTRUCTOR_COURSE_REJOIN_AFTER_REGKEY_RESET \u003d"},{"lineNumber":56,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"instructorEmailFragment-registrationKeyReset.html\");"},{"lineNumber":57,"author":{"gitId":"-"},"content":" public static final String USER_FEEDBACK_SESSION \u003d"},{"lineNumber":58,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplate-feedbackSession.html\");"},{"lineNumber":59,"author":{"gitId":"-"},"content":" public static final String USER_FEEDBACK_SESSION_OPENING \u003d"},{"lineNumber":60,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplate-feedbackSessionOpening.html\");"},{"lineNumber":61,"author":{"gitId":"-"},"content":" public static final String USER_FEEDBACK_SESSION_PUBLISHED \u003d"},{"lineNumber":62,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplate-feedbackSessionPublished.html\");"},{"lineNumber":63,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_SESSION_LINKS_RECOVERY_ACCESS_LINKS_BY_SESSION \u003d"},{"lineNumber":64,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"sessionLinksRecoveryEmailTemplateFragment-sessionAccessLinksBySession.html\");"},{"lineNumber":65,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_SESSION_LINKS_RECOVERY_ACCESS_LINKS_BY_COURSE \u003d"},{"lineNumber":66,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"sessionLinksRecoveryEmailTemplateFragment-sessionAccessLinksByCourse.html\");"},{"lineNumber":67,"author":{"gitId":"-"},"content":" public static final String SESSION_LINKS_RECOVERY_ACCESS_LINKS \u003d"},{"lineNumber":68,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"sessionLinksRecoveryEmailTemplate-feedbackSessionAccessLinks.html\");"},{"lineNumber":69,"author":{"gitId":"-"},"content":" public static final String SESSION_LINKS_RECOVERY_ACCESS_LINKS_NONE \u003d"},{"lineNumber":70,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"sessionLinksRecoveryEmailTemplate-feedbackSessionAccessLinksNone.html\");"},{"lineNumber":71,"author":{"gitId":"-"},"content":" public static final String SESSION_LINKS_RECOVERY_EMAIL_NOT_FOUND \u003d"},{"lineNumber":72,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"sessionLinksRecoveryEmailTemplate-emailNotFound.html\");"},{"lineNumber":73,"author":{"gitId":"-"},"content":" public static final String USER_FEEDBACK_SESSION_UNPUBLISHED \u003d"},{"lineNumber":74,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplate-feedbackSessionUnpublished.html\");"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_SINGLE_FEEDBACK_SESSION_LINKS \u003d"},{"lineNumber":76,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplateFragment-feedbackSessionResendAllLinks.html\");"},{"lineNumber":77,"author":{"gitId":"-"},"content":" public static final String USER_FEEDBACK_SESSION_RESEND_ALL_LINKS \u003d"},{"lineNumber":78,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplate-feedbackSessionResendAllLinks.html\");"},{"lineNumber":79,"author":{"gitId":"-"},"content":" public static final String USER_REGKEY_REGENERATION_RESEND_ALL_COURSE_LINKS \u003d"},{"lineNumber":80,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplate-regenerateLinksResendAllCourseLinks.html\");"},{"lineNumber":81,"author":{"gitId":"-"},"content":" public static final String SEVERE_ERROR_LOG_LINE \u003d"},{"lineNumber":82,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"severeErrorLogLine.html\");"},{"lineNumber":83,"author":{"gitId":"-"},"content":" public static final String LOGIN_EMAIL \u003d"},{"lineNumber":84,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"loginEmail.html\");"},{"lineNumber":85,"author":{"gitId":"-"},"content":" public static final String NEW_INSTRUCTOR_ACCOUNT_WELCOME \u003d"},{"lineNumber":86,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"newInstructorAccountWelcome.html\");"},{"lineNumber":87,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_SESSION_ADDITIONAL_CONTACT_INFORMATION \u003d"},{"lineNumber":88,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailFragment-sessionAdditionalContactInformationFragment.html\");"},{"lineNumber":89,"author":{"gitId":"-"},"content":" public static final String OWNER_FEEDBACK_SESSION \u003d"},{"lineNumber":90,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"ownerEmailTemplate-feedbackSession.html\");"},{"lineNumber":91,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_OPENING_SOON_EDIT_DETAILS \u003d"},{"lineNumber":92,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"ownerEmailFragment-editDetails.html\");"},{"lineNumber":93,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_OPENING_SOON_JOIN_COURSE_BEFORE_EDIT_DETAILS \u003d"},{"lineNumber":94,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"ownerEmailFragment-joinCourseBeforeEditDetails.html\");"},{"lineNumber":95,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_CLOSED_VIEW_RESPONSES \u003d"},{"lineNumber":96,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"ownerEmailFragment-viewResponses.html\");"},{"lineNumber":97,"author":{"gitId":"-"},"content":" public static final String USER_DEADLINE_EXTENSION \u003d"},{"lineNumber":98,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplate-deadlineExtension.html\");"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":2,"-":99}},{"path":"src/main/java/teammates/common/util/TimeHelper.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.util;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Duration;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.OffsetDateTime;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.time.ZoneId;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.time.ZonedDateTime;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.time.format.DateTimeFormatter;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.time.format.DateTimeParseException;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":12,"author":{"gitId":"-"},"content":" * A helper class to hold time-related functions (e.g., converting dates to strings etc.)."},{"lineNumber":13,"author":{"gitId":"-"},"content":" *"},{"lineNumber":14,"author":{"gitId":"-"},"content":" * \u003cp\u003eTime zone is assumed as UTC unless specifically mentioned."},{"lineNumber":15,"author":{"gitId":"-"},"content":" */"},{"lineNumber":16,"author":{"gitId":"-"},"content":"public final class TimeHelper {"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":" private TimeHelper() {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" // utility class"},{"lineNumber":20,"author":{"gitId":"-"},"content":" }"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":23,"author":{"gitId":"-"},"content":" * Returns an Instant that represents the nearest hour before the given object."},{"lineNumber":24,"author":{"gitId":"-"},"content":" *"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * \u003cp\u003eThe time zone used is assumed to be the default timezone, namely UTC."},{"lineNumber":26,"author":{"gitId":"-"},"content":" */"},{"lineNumber":27,"author":{"gitId":"-"},"content":" public static Instant getInstantNearestHourBefore(Instant instant) {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" String nearestHourString \u003d formatInstant(instant, Const.DEFAULT_TIME_ZONE, \"yyyy-MM-dd\u0027T\u0027HH:00:00.00\u0027Z\u0027\");"},{"lineNumber":29,"author":{"gitId":"-"},"content":" return parseInstant(nearestHourString);"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" * Returns an Instant that represents the nearest quarter hour before the given object."},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" * \u003cp\u003eThe time zone used is assumed to be the default timezone, namely UTC."},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" public static Instant getInstantNearestQuarterHourBefore(Instant instant) {"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" ZonedDateTime zdt \u003d instant.atZone(ZoneId.of(Const.DEFAULT_TIME_ZONE));"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" int minutesPastQuarter \u003d zdt.getMinute() % 15;"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" ZonedDateTime nearestQuarterZdt \u003d zdt.minusMinutes(minutesPastQuarter).withSecond(0).withNano(0);"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" return nearestQuarterZdt.toInstant();"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":45,"author":{"gitId":"-"},"content":" * Returns an Instant that is offset by a number of days from now."},{"lineNumber":46,"author":{"gitId":"-"},"content":" *"},{"lineNumber":47,"author":{"gitId":"-"},"content":" * @param offsetInDays integer number of days to offset by"},{"lineNumber":48,"author":{"gitId":"-"},"content":" * @return an Instant offset by {@code offsetInDays} days"},{"lineNumber":49,"author":{"gitId":"-"},"content":" */"},{"lineNumber":50,"author":{"gitId":"-"},"content":" public static Instant getInstantDaysOffsetFromNow(long offsetInDays) {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" return Instant.now().plus(Duration.ofDays(offsetInDays));"},{"lineNumber":52,"author":{"gitId":"-"},"content":" }"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":55,"author":{"gitId":"-"},"content":" * Returns an Instant that is offset by a number of months from now."},{"lineNumber":56,"author":{"gitId":"-"},"content":" *"},{"lineNumber":57,"author":{"gitId":"-"},"content":" * @param offsetInMonths integer number of months to offset by"},{"lineNumber":58,"author":{"gitId":"-"},"content":" * @param timeZone string representing the time zone to compute local datetime"},{"lineNumber":59,"author":{"gitId":"-"},"content":" * @return an Instant offset by {@code offsetInMonths} days"},{"lineNumber":60,"author":{"gitId":"-"},"content":" */"},{"lineNumber":61,"author":{"gitId":"-"},"content":" public static Instant getInstantMonthsOffsetFromNow(long offsetInMonths, String timeZone) {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" Instant now \u003d Instant.now();"},{"lineNumber":63,"author":{"gitId":"-"},"content":" ZonedDateTime zdt \u003d now.atZone(ZoneId.of(timeZone));"},{"lineNumber":64,"author":{"gitId":"-"},"content":" ZonedDateTime offsetZdt \u003d zdt.plusMonths(offsetInMonths);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" return offsetZdt.toInstant();"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":69,"author":{"gitId":"-"},"content":" * Returns an Instant that is offset by a number of days before now."},{"lineNumber":70,"author":{"gitId":"-"},"content":" *"},{"lineNumber":71,"author":{"gitId":"-"},"content":" * @param offsetInDays integer number of days to offset by"},{"lineNumber":72,"author":{"gitId":"-"},"content":" * @return an Instant offset by {@code offsetInDays} days"},{"lineNumber":73,"author":{"gitId":"-"},"content":" */"},{"lineNumber":74,"author":{"gitId":"-"},"content":" public static Instant getInstantDaysOffsetBeforeNow(long offsetInDays) {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" return Instant.now().minus(Duration.ofDays(offsetInDays));"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":79,"author":{"gitId":"-"},"content":" * Returns an Instant that is offset by a number of hours from now."},{"lineNumber":80,"author":{"gitId":"-"},"content":" *"},{"lineNumber":81,"author":{"gitId":"-"},"content":" * @param offsetInHours integer number of hours to offset by"},{"lineNumber":82,"author":{"gitId":"-"},"content":" * @return an Instant offset by {@code offsetInHours} hours"},{"lineNumber":83,"author":{"gitId":"-"},"content":" */"},{"lineNumber":84,"author":{"gitId":"-"},"content":" public static Instant getInstantHoursOffsetFromNow(long offsetInHours) {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" return Instant.now().plus(Duration.ofHours(offsetInHours));"},{"lineNumber":86,"author":{"gitId":"-"},"content":" }"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":89,"author":{"gitId":"-"},"content":" * Formats a datetime stamp from an {@code instant} using a formatting pattern."},{"lineNumber":90,"author":{"gitId":"-"},"content":" *"},{"lineNumber":91,"author":{"gitId":"-"},"content":" * \u003cp\u003eNote: a formatting pattern containing \u0027a\u0027 (for the period; AM/PM) is treated differently at noon/midday."},{"lineNumber":92,"author":{"gitId":"-"},"content":" * Using that pattern with a datetime whose time falls on \"12:00 PM\" will cause it to be formatted as \"12:00 NOON\".\u003c/p\u003e"},{"lineNumber":93,"author":{"gitId":"-"},"content":" *"},{"lineNumber":94,"author":{"gitId":"-"},"content":" * @param instant the instant to be formatted"},{"lineNumber":95,"author":{"gitId":"-"},"content":" * @param timeZone the time zone to compute local datetime"},{"lineNumber":96,"author":{"gitId":"-"},"content":" * @param pattern formatting pattern, see Oracle docs for DateTimeFormatter for pattern table"},{"lineNumber":97,"author":{"gitId":"-"},"content":" * @return the formatted datetime stamp string"},{"lineNumber":98,"author":{"gitId":"-"},"content":" */"},{"lineNumber":99,"author":{"gitId":"-"},"content":" public static String formatInstant(Instant instant, String timeZone, String pattern) {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" if (instant \u003d\u003d null || timeZone \u003d\u003d null || pattern \u003d\u003d null) {"},{"lineNumber":101,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"-"},"content":" ZonedDateTime zonedDateTime \u003d instant.atZone(ZoneId.of(timeZone));"},{"lineNumber":104,"author":{"gitId":"-"},"content":" String processedPattern \u003d pattern;"},{"lineNumber":105,"author":{"gitId":"-"},"content":" if (zonedDateTime.getHour() \u003d\u003d 12 \u0026\u0026 zonedDateTime.getMinute() \u003d\u003d 0) {"},{"lineNumber":106,"author":{"gitId":"-"},"content":" processedPattern \u003d pattern.replace(\"a\", \"\u0027NOON\u0027\");"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":" DateTimeFormatter formatter \u003d DateTimeFormatter.ofPattern(processedPattern);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" return zonedDateTime.format(formatter);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":113,"author":{"gitId":"-"},"content":" * Gets an Instant which is adjusted for midnight time (23:59 and 00:00) at the specified time zone."},{"lineNumber":114,"author":{"gitId":"-"},"content":" * The direction of adjustment (23:59 to 00:00 or vice versa) is determined by {@code isForward} parameter."},{"lineNumber":115,"author":{"gitId":"-"},"content":" */"},{"lineNumber":116,"author":{"gitId":"-"},"content":" public static Instant getMidnightAdjustedInstantBasedOnZone(Instant instant, String timeZone, boolean isForward) {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" if (isSpecialTime(instant)) {"},{"lineNumber":118,"author":{"gitId":"-"},"content":" return instant;"},{"lineNumber":119,"author":{"gitId":"-"},"content":" }"},{"lineNumber":120,"author":{"gitId":"-"},"content":" ZonedDateTime zonedDateTime \u003d instant.atZone(ZoneId.of(timeZone));"},{"lineNumber":121,"author":{"gitId":"-"},"content":" if (isForward \u0026\u0026 zonedDateTime.getHour() \u003d\u003d 23 \u0026\u0026 zonedDateTime.getMinute() \u003d\u003d 59) {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" zonedDateTime \u003d zonedDateTime.plusMinutes(1L);"},{"lineNumber":123,"author":{"gitId":"-"},"content":" } else if (!isForward \u0026\u0026 zonedDateTime.getHour() \u003d\u003d 0 \u0026\u0026 zonedDateTime.getMinute() \u003d\u003d 0) {"},{"lineNumber":124,"author":{"gitId":"-"},"content":" zonedDateTime \u003d zonedDateTime.minusMinutes(1L);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" }"},{"lineNumber":126,"author":{"gitId":"-"},"content":" return zonedDateTime.toInstant();"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":130,"author":{"gitId":"-"},"content":" * Returns whether the given {@code instant} is being used as a special representation, signifying its face value"},{"lineNumber":131,"author":{"gitId":"-"},"content":" * should not be used without proper processing."},{"lineNumber":132,"author":{"gitId":"-"},"content":" *"},{"lineNumber":133,"author":{"gitId":"-"},"content":" * \u003cp\u003eA {@code null} instant is not a special time.\u003c/p\u003e"},{"lineNumber":134,"author":{"gitId":"-"},"content":" *"},{"lineNumber":135,"author":{"gitId":"-"},"content":" * @param instant the instant to test"},{"lineNumber":136,"author":{"gitId":"-"},"content":" * @return {@code true} if the given instant is used as a special representation, {@code false} otherwise"},{"lineNumber":137,"author":{"gitId":"-"},"content":" */"},{"lineNumber":138,"author":{"gitId":"-"},"content":" public static boolean isSpecialTime(Instant instant) {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" if (instant \u003d\u003d null) {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" return instant.equals(Const.TIME_REPRESENTS_FOLLOW_OPENING)"},{"lineNumber":144,"author":{"gitId":"-"},"content":" || instant.equals(Const.TIME_REPRESENTS_FOLLOW_VISIBLE)"},{"lineNumber":145,"author":{"gitId":"-"},"content":" || instant.equals(Const.TIME_REPRESENTS_LATER)"},{"lineNumber":146,"author":{"gitId":"-"},"content":" || instant.equals(Const.TIME_REPRESENTS_NOW);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":150,"author":{"gitId":"-"},"content":" * Parses an {@code Instant} object from a datetime string in the ISO 8601 format."},{"lineNumber":151,"author":{"gitId":"-"},"content":" *"},{"lineNumber":152,"author":{"gitId":"-"},"content":" * @return the parsed {@code Instant} object"},{"lineNumber":153,"author":{"gitId":"-"},"content":" * @throws AssertionError if there is a parsing error"},{"lineNumber":154,"author":{"gitId":"-"},"content":" * @see \u003ca href\u003d\"https://www.w3.org/TR/NOTE-datetime\"\u003ehttps://www.w3.org/TR/NOTE-datetime\u003c/a\u003e"},{"lineNumber":155,"author":{"gitId":"-"},"content":" */"},{"lineNumber":156,"author":{"gitId":"-"},"content":" public static Instant parseInstant(String dateTimeString) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" return OffsetDateTime.parse(dateTimeString).toInstant();"},{"lineNumber":159,"author":{"gitId":"-"},"content":" } catch (DateTimeParseException e) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" assert false : \"Date in String is in wrong format.\";"},{"lineNumber":161,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":12,"-":153}},{"path":"src/main/java/teammates/logic/api/LogsProcessor.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.logic.api;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.QueryLogsResults;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.GeneralLogEntry;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.LogEvent;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.QueryLogsParams;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.logic.external.GoogleCloudLoggingService;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.logic.external.LocalLoggingService;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.logic.external.LogService;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * Handles operations related to logs reading/writing."},{"lineNumber":19,"author":{"gitId":"-"},"content":" *"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * \u003cp\u003eNote that while this interface should support writing logs, most of the application/system logs"},{"lineNumber":21,"author":{"gitId":"-"},"content":" * should be written via the standard Logger class."},{"lineNumber":22,"author":{"gitId":"-"},"content":" */"},{"lineNumber":23,"author":{"gitId":"-"},"content":"public class LogsProcessor {"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" private static final LogsProcessor instance \u003d new LogsProcessor();"},{"lineNumber":26,"author":{"gitId":"-"},"content":" private final LogService service;"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" LogsProcessor() {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" if (Config.IS_DEV_SERVER) {"},{"lineNumber":30,"author":{"gitId":"-"},"content":" service \u003d new LocalLoggingService();"},{"lineNumber":31,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" service \u003d new GoogleCloudLoggingService();"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" public static LogsProcessor inst() {"},{"lineNumber":37,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" }"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":41,"author":{"gitId":"-"},"content":" * Queries and retrieves logs with given parameters."},{"lineNumber":42,"author":{"gitId":"-"},"content":" */"},{"lineNumber":43,"author":{"gitId":"-"},"content":" public QueryLogsResults queryLogs(QueryLogsParams queryLogsParams) {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return service.queryLogs(queryLogsParams);"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":48,"author":{"gitId":"-"},"content":" * Creates a feedback session log."},{"lineNumber":49,"author":{"gitId":"-"},"content":" */"},{"lineNumber":50,"author":{"gitId":"-"},"content":" public void createFeedbackSessionLog(String courseId, String email, String fsName, String fslType) {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" service.createFeedbackSessionLog(courseId, email, fsName, fslType);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" }"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" * Creates a feedback session log."},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" public void createFeedbackSessionLog(String courseId, UUID studentId, UUID fsId, String fslType) {"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" service.createFeedbackSessionLog(courseId, studentId, fsId, fslType);"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" * Gets the feedback session logs as filtered by the given parameters ordered by ascending timestamp."},{"lineNumber":63,"author":{"gitId":"-"},"content":" * @param email Can be null"},{"lineNumber":64,"author":{"gitId":"-"},"content":" */"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" public List\u003cFeedbackSessionLogEntry\u003e getOrderedFeedbackSessionLogs(String courseId, String email,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" long startTime, long endTime, String fsName) {"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" return service.getOrderedFeedbackSessionLogs(courseId, email, startTime, endTime, fsName);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" }"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":71,"author":{"gitId":"-"},"content":" * Gets the number of logs for the event type and extra filters."},{"lineNumber":72,"author":{"gitId":"-"},"content":" */"},{"lineNumber":73,"author":{"gitId":"-"},"content":" public int getNumberOfLogsForEvent(Instant startTime, Instant endTime, LogEvent logEvent, String extraFilters) {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" int total \u003d 0;"},{"lineNumber":75,"author":{"gitId":"-"},"content":" long logStartTime \u003d startTime.toEpochMilli();"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" while (true) {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" QueryLogsParams logsParams \u003d QueryLogsParams.builder(logStartTime, endTime.toEpochMilli())"},{"lineNumber":79,"author":{"gitId":"-"},"content":" .withLogEvent(logEvent.name())"},{"lineNumber":80,"author":{"gitId":"-"},"content":" .withExtraFilters(extraFilters)"},{"lineNumber":81,"author":{"gitId":"-"},"content":" .withOrder(\"asc\")"},{"lineNumber":82,"author":{"gitId":"-"},"content":" .withPageSize(300)"},{"lineNumber":83,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":84,"author":{"gitId":"-"},"content":" QueryLogsResults logFetchResults \u003d queryLogs(logsParams);"},{"lineNumber":85,"author":{"gitId":"-"},"content":" List\u003cGeneralLogEntry\u003e logs \u003d logFetchResults.getLogEntries();"},{"lineNumber":86,"author":{"gitId":"-"},"content":" total +\u003d logs.size();"},{"lineNumber":87,"author":{"gitId":"-"},"content":" if (logFetchResults.getHasNextPage()) {"},{"lineNumber":88,"author":{"gitId":"-"},"content":" logStartTime \u003d logs.get(logs.size() - 1).getTimestamp();"},{"lineNumber":89,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":90,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":91,"author":{"gitId":"-"},"content":" }"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":" return total;"},{"lineNumber":94,"author":{"gitId":"-"},"content":" }"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":10,"-":86}},{"path":"src/main/java/teammates/logic/api/TaskQueuer.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.logic.api;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.ParamsNames;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.TaskQueue;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.TaskWrapper;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.logic.external.GoogleCloudTasksService;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.logic.external.LocalTaskQueueService;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.logic.external.TaskQueueService;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.ui.request.FeedbackSessionRemindRequest;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.ui.request.SendEmailRequest;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * Allows for adding specific type of tasks to the task queue."},{"lineNumber":21,"author":{"gitId":"-"},"content":" */"},{"lineNumber":22,"author":{"gitId":"-"},"content":"public class TaskQueuer {"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" private static final TaskQueuer instance \u003d new TaskQueuer();"},{"lineNumber":27,"author":{"gitId":"-"},"content":" private final TaskQueueService service;"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" TaskQueuer() {"},{"lineNumber":30,"author":{"gitId":"-"},"content":" if (Config.IS_DEV_SERVER) {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" service \u003d new LocalTaskQueueService();"},{"lineNumber":32,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" service \u003d new GoogleCloudTasksService();"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" public static TaskQueuer inst() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" // The following methods are facades to the actual logic for adding tasks to the queue."},{"lineNumber":42,"author":{"gitId":"-"},"content":" // Using this method, the actual logic can still be black-boxed"},{"lineNumber":43,"author":{"gitId":"-"},"content":" // while at the same time allowing this API to be mocked during test."},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" private void addTask(String queueName, String workerUrl, Map\u003cString, String\u003e paramMap, Object requestBody) {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" addDeferredTask(queueName, workerUrl, paramMap, requestBody, 0);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" }"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" void addDeferredTask(String queueName, String workerUrl, Map\u003cString, String\u003e paramMap, Object requestBody,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" long countdownTime) {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" TaskWrapper task \u003d new TaskWrapper(queueName, workerUrl, paramMap, requestBody);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" service.addDeferredTask(task, countdownTime);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" // The following methods are the actual API methods to be used by the client classes"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":58,"author":{"gitId":"-"},"content":" * Schedules for feedback session reminders (i.e. student has not submitted responses yet)"},{"lineNumber":59,"author":{"gitId":"-"},"content":" * for the specified feedback session."},{"lineNumber":60,"author":{"gitId":"-"},"content":" *"},{"lineNumber":61,"author":{"gitId":"-"},"content":" * @param courseId the course ID of the feedback session"},{"lineNumber":62,"author":{"gitId":"-"},"content":" * @param feedbackSessionName the name of the feedback session"},{"lineNumber":63,"author":{"gitId":"-"},"content":" */"},{"lineNumber":64,"author":{"gitId":"-"},"content":" public void scheduleFeedbackSessionReminders(String courseId, String feedbackSessionName,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" String googleIdOfRequestingInstructor) {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e paramMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":67,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.INSTRUCTOR_ID, googleIdOfRequestingInstructor);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.FEEDBACK_SESSION_NAME, feedbackSessionName);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.COURSE_ID, courseId);"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" addTask(TaskQueue.FEEDBACK_SESSION_REMIND_EMAIL_QUEUE_NAME,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" TaskQueue.FEEDBACK_SESSION_REMIND_EMAIL_WORKER_URL, paramMap, null);"},{"lineNumber":73,"author":{"gitId":"-"},"content":" }"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":76,"author":{"gitId":"-"},"content":" * Schedules for feedback session reminders (i.e. student/instructor has not submitted responses yet)"},{"lineNumber":77,"author":{"gitId":"-"},"content":" * for the specified feedback session for the specified group of users."},{"lineNumber":78,"author":{"gitId":"-"},"content":" *"},{"lineNumber":79,"author":{"gitId":"-"},"content":" * @param courseId the course ID of the feedback session"},{"lineNumber":80,"author":{"gitId":"-"},"content":" * @param feedbackSessionName the name of the feedback session"},{"lineNumber":81,"author":{"gitId":"-"},"content":" * @param usersToRemind the group of users to send the reminders to"},{"lineNumber":82,"author":{"gitId":"-"},"content":" * @param requestingInstructorId the ID of the instructor who sends the reminder"},{"lineNumber":83,"author":{"gitId":"-"},"content":" * @param isSendingCopyToInstructor the indicator of whether to send an email copy to the requesting instructor"},{"lineNumber":84,"author":{"gitId":"-"},"content":" */"},{"lineNumber":85,"author":{"gitId":"-"},"content":" public void scheduleFeedbackSessionRemindersForParticularUsers(String courseId, String feedbackSessionName,"},{"lineNumber":86,"author":{"gitId":"-"},"content":" String[] usersToRemind,"},{"lineNumber":87,"author":{"gitId":"-"},"content":" String requestingInstructorId,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" boolean isSendingCopyToInstructor) {"},{"lineNumber":89,"author":{"gitId":"-"},"content":" FeedbackSessionRemindRequest remindRequest \u003d"},{"lineNumber":90,"author":{"gitId":"-"},"content":" new FeedbackSessionRemindRequest(courseId, feedbackSessionName, requestingInstructorId, usersToRemind,"},{"lineNumber":91,"author":{"gitId":"-"},"content":" isSendingCopyToInstructor);"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" addTask(TaskQueue.FEEDBACK_SESSION_REMIND_PARTICULAR_USERS_EMAIL_QUEUE_NAME,"},{"lineNumber":94,"author":{"gitId":"-"},"content":" TaskQueue.FEEDBACK_SESSION_REMIND_PARTICULAR_USERS_EMAIL_WORKER_URL, new HashMap\u003c\u003e(), remindRequest);"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":98,"author":{"gitId":"-"},"content":" * Schedules for feedback session published email to be sent."},{"lineNumber":99,"author":{"gitId":"-"},"content":" *"},{"lineNumber":100,"author":{"gitId":"-"},"content":" * @param courseId the course ID of the feedback session"},{"lineNumber":101,"author":{"gitId":"-"},"content":" * @param feedbackSessionName the name of the feedback session"},{"lineNumber":102,"author":{"gitId":"-"},"content":" */"},{"lineNumber":103,"author":{"gitId":"-"},"content":" public void scheduleFeedbackSessionPublishedEmail(String courseId, String feedbackSessionName) {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e paramMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":105,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.COURSE_ID, courseId);"},{"lineNumber":106,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.FEEDBACK_SESSION_NAME, feedbackSessionName);"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" addTask(TaskQueue.FEEDBACK_SESSION_PUBLISHED_EMAIL_QUEUE_NAME,"},{"lineNumber":109,"author":{"gitId":"-"},"content":" TaskQueue.FEEDBACK_SESSION_PUBLISHED_EMAIL_WORKER_URL, paramMap, null);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":113,"author":{"gitId":"-"},"content":" * Schedules for feedback session publication reminders"},{"lineNumber":114,"author":{"gitId":"-"},"content":" * for the specified feedback session for the specified group of users."},{"lineNumber":115,"author":{"gitId":"-"},"content":" *"},{"lineNumber":116,"author":{"gitId":"-"},"content":" * @param courseId the course ID of the feedback session"},{"lineNumber":117,"author":{"gitId":"-"},"content":" * @param feedbackSessionName the name of the feedback session"},{"lineNumber":118,"author":{"gitId":"-"},"content":" * @param usersToEmail the group of users to send the reminders to"},{"lineNumber":119,"author":{"gitId":"-"},"content":" * @param requestingInstructorId the ID of the instructor who sends the reminder"},{"lineNumber":120,"author":{"gitId":"-"},"content":" */"},{"lineNumber":121,"author":{"gitId":"-"},"content":" public void scheduleFeedbackSessionResendPublishedEmail(String courseId, String feedbackSessionName,"},{"lineNumber":122,"author":{"gitId":"-"},"content":" String[] usersToEmail, String requestingInstructorId) {"},{"lineNumber":123,"author":{"gitId":"-"},"content":" FeedbackSessionRemindRequest remindRequest \u003d"},{"lineNumber":124,"author":{"gitId":"-"},"content":" new FeedbackSessionRemindRequest(courseId, feedbackSessionName, requestingInstructorId, usersToEmail, true);"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" addTask(TaskQueue.FEEDBACK_SESSION_RESEND_PUBLISHED_EMAIL_QUEUE_NAME,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" TaskQueue.FEEDBACK_SESSION_RESEND_PUBLISHED_EMAIL_WORKER_URL, new HashMap\u003c\u003e(), remindRequest);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":131,"author":{"gitId":"-"},"content":" * Schedules for feedback session unpublished email to be sent."},{"lineNumber":132,"author":{"gitId":"-"},"content":" *"},{"lineNumber":133,"author":{"gitId":"-"},"content":" * @param courseId the course ID of the feedback session"},{"lineNumber":134,"author":{"gitId":"-"},"content":" * @param feedbackSessionName the name of the feedback session"},{"lineNumber":135,"author":{"gitId":"-"},"content":" */"},{"lineNumber":136,"author":{"gitId":"-"},"content":" public void scheduleFeedbackSessionUnpublishedEmail(String courseId, String feedbackSessionName) {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e paramMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":138,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.COURSE_ID, courseId);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.FEEDBACK_SESSION_NAME, feedbackSessionName);"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" addTask(TaskQueue.FEEDBACK_SESSION_UNPUBLISHED_EMAIL_QUEUE_NAME,"},{"lineNumber":142,"author":{"gitId":"-"},"content":" TaskQueue.FEEDBACK_SESSION_UNPUBLISHED_EMAIL_WORKER_URL, paramMap, null);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" }"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":146,"author":{"gitId":"-"},"content":" * Schedules for course registration to be sent to the specified instructor."},{"lineNumber":147,"author":{"gitId":"-"},"content":" *"},{"lineNumber":148,"author":{"gitId":"-"},"content":" * @param inviterGoogleId googleId of instructor or administrator who sends the invitation"},{"lineNumber":149,"author":{"gitId":"-"},"content":" * @param courseId the target course ID"},{"lineNumber":150,"author":{"gitId":"-"},"content":" * @param instructorEmail the email address of the invited instructor"},{"lineNumber":151,"author":{"gitId":"-"},"content":" */"},{"lineNumber":152,"author":{"gitId":"-"},"content":" public void scheduleCourseRegistrationInviteToInstructor(String inviterGoogleId,"},{"lineNumber":153,"author":{"gitId":"-"},"content":" String instructorEmail, String courseId, boolean isRejoining) {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e paramMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":155,"author":{"gitId":"-"},"content":" if (inviterGoogleId !\u003d null) {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.INVITER_ID, inviterGoogleId);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" }"},{"lineNumber":158,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.INSTRUCTOR_EMAIL, instructorEmail);"},{"lineNumber":159,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.COURSE_ID, courseId);"},{"lineNumber":160,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.IS_INSTRUCTOR_REJOINING, String.valueOf(isRejoining));"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"-"},"content":" addTask(TaskQueue.INSTRUCTOR_COURSE_JOIN_EMAIL_QUEUE_NAME,"},{"lineNumber":163,"author":{"gitId":"-"},"content":" TaskQueue.INSTRUCTOR_COURSE_JOIN_EMAIL_WORKER_URL, paramMap, null);"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":167,"author":{"gitId":"-"},"content":" * Schedules for course registration to be sent to the specified student."},{"lineNumber":168,"author":{"gitId":"-"},"content":" *"},{"lineNumber":169,"author":{"gitId":"-"},"content":" * @param courseId the target course ID"},{"lineNumber":170,"author":{"gitId":"-"},"content":" * @param studentEmail the email address of the student"},{"lineNumber":171,"author":{"gitId":"-"},"content":" */"},{"lineNumber":172,"author":{"gitId":"-"},"content":" public void scheduleCourseRegistrationInviteToStudent(String courseId, String studentEmail, boolean isRejoining) {"},{"lineNumber":173,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e paramMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":174,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.COURSE_ID, courseId);"},{"lineNumber":175,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.STUDENT_EMAIL, studentEmail);"},{"lineNumber":176,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.IS_STUDENT_REJOINING, String.valueOf(isRejoining));"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" addTask(TaskQueue.STUDENT_COURSE_JOIN_EMAIL_QUEUE_NAME,"},{"lineNumber":179,"author":{"gitId":"-"},"content":" TaskQueue.STUDENT_COURSE_JOIN_EMAIL_WORKER_URL, paramMap, null);"},{"lineNumber":180,"author":{"gitId":"-"},"content":" }"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":183,"author":{"gitId":"-"},"content":" * Schedules for the given list of emails to be sent."},{"lineNumber":184,"author":{"gitId":"-"},"content":" *"},{"lineNumber":185,"author":{"gitId":"-"},"content":" * @param emails the list of emails to be sent"},{"lineNumber":186,"author":{"gitId":"-"},"content":" */"},{"lineNumber":187,"author":{"gitId":"-"},"content":" public void scheduleEmailsForSending(List\u003cEmailWrapper\u003e emails) {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" if (emails.isEmpty()) {"},{"lineNumber":189,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":190,"author":{"gitId":"-"},"content":" }"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"-"},"content":" // Equally spread out the emails to be sent over 1 hour"},{"lineNumber":193,"author":{"gitId":"-"},"content":" // Sets interval to a maximum of 5 seconds if the interval is too large"},{"lineNumber":194,"author":{"gitId":"-"},"content":" int oneHourInMillis \u003d 60 * 60 * 1000;"},{"lineNumber":195,"author":{"gitId":"-"},"content":" int emailIntervalMillis \u003d Math.min(5000, oneHourInMillis / emails.size());"},{"lineNumber":196,"author":{"gitId":"-"},"content":""},{"lineNumber":197,"author":{"gitId":"-"},"content":" long numberOfEmailsSent \u003d 0L;"},{"lineNumber":198,"author":{"gitId":"-"},"content":" for (EmailWrapper email : emails) {"},{"lineNumber":199,"author":{"gitId":"-"},"content":" long emailDelayTimer \u003d numberOfEmailsSent * emailIntervalMillis;"},{"lineNumber":200,"author":{"gitId":"-"},"content":" scheduleEmailForSending(email, emailDelayTimer);"},{"lineNumber":201,"author":{"gitId":"-"},"content":" numberOfEmailsSent++;"},{"lineNumber":202,"author":{"gitId":"-"},"content":" }"},{"lineNumber":203,"author":{"gitId":"-"},"content":" }"},{"lineNumber":204,"author":{"gitId":"-"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":206,"author":{"gitId":"-"},"content":" * Schedules for the search indexing of the instructor identified by {@code courseId} and {@code email}."},{"lineNumber":207,"author":{"gitId":"-"},"content":" *"},{"lineNumber":208,"author":{"gitId":"-"},"content":" * @param courseId the course ID of the instructor"},{"lineNumber":209,"author":{"gitId":"-"},"content":" * @param email the email of the instructor"},{"lineNumber":210,"author":{"gitId":"-"},"content":" */"},{"lineNumber":211,"author":{"gitId":"-"},"content":" public void scheduleInstructorForSearchIndexing(String courseId, String email) {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e paramMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":213,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.COURSE_ID, courseId);"},{"lineNumber":214,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.INSTRUCTOR_EMAIL, email);"},{"lineNumber":215,"author":{"gitId":"-"},"content":""},{"lineNumber":216,"author":{"gitId":"-"},"content":" addTask(TaskQueue.SEARCH_INDEXING_QUEUE_NAME, TaskQueue.INSTRUCTOR_SEARCH_INDEXING_WORKER_URL,"},{"lineNumber":217,"author":{"gitId":"-"},"content":" paramMap, null);"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":221,"author":{"gitId":"domoberzin"},"content":" * Schedules for the search indexing of the account request identified by {@code id}."},{"lineNumber":222,"author":{"gitId":"-"},"content":" *"},{"lineNumber":223,"author":{"gitId":"domoberzin"},"content":" * @param id the id associated with the account request"},{"lineNumber":224,"author":{"gitId":"-"},"content":" */"},{"lineNumber":225,"author":{"gitId":"domoberzin"},"content":" public void scheduleAccountRequestForSearchIndexing(String id) {"},{"lineNumber":226,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e paramMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":227,"author":{"gitId":"domoberzin"},"content":" paramMap.put(ParamsNames.ACCOUNT_REQUEST_ID, id);"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" addTask(TaskQueue.SEARCH_INDEXING_QUEUE_NAME, TaskQueue.ACCOUNT_REQUEST_SEARCH_INDEXING_WORKER_URL,"},{"lineNumber":230,"author":{"gitId":"-"},"content":" paramMap, null);"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":234,"author":{"gitId":"-"},"content":" * Schedules for the search indexing of the student identified by {@code courseId} and {@code email}."},{"lineNumber":235,"author":{"gitId":"-"},"content":" *"},{"lineNumber":236,"author":{"gitId":"-"},"content":" * @param courseId the course ID of the student"},{"lineNumber":237,"author":{"gitId":"-"},"content":" * @param email the email of the student"},{"lineNumber":238,"author":{"gitId":"-"},"content":" */"},{"lineNumber":239,"author":{"gitId":"-"},"content":" public void scheduleStudentForSearchIndexing(String courseId, String email) {"},{"lineNumber":240,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e paramMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":241,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.COURSE_ID, courseId);"},{"lineNumber":242,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.STUDENT_EMAIL, email);"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" addTask(TaskQueue.SEARCH_INDEXING_QUEUE_NAME, TaskQueue.STUDENT_SEARCH_INDEXING_WORKER_URL,"},{"lineNumber":245,"author":{"gitId":"-"},"content":" paramMap, null);"},{"lineNumber":246,"author":{"gitId":"-"},"content":" }"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" private void scheduleEmailForSending(EmailWrapper email, long emailDelayTimer) {"},{"lineNumber":249,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":250,"author":{"gitId":"-"},"content":" SendEmailRequest request \u003d new SendEmailRequest(email);"},{"lineNumber":251,"author":{"gitId":"-"},"content":""},{"lineNumber":252,"author":{"gitId":"-"},"content":" addDeferredTask(TaskQueue.SEND_EMAIL_QUEUE_NAME, TaskQueue.SEND_EMAIL_WORKER_URL,"},{"lineNumber":253,"author":{"gitId":"-"},"content":" new HashMap\u003c\u003e(), request, emailDelayTimer);"},{"lineNumber":254,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" String emailSubject \u003d email.getSubject();"},{"lineNumber":256,"author":{"gitId":"-"},"content":" String emailSenderName \u003d email.getSenderName();"},{"lineNumber":257,"author":{"gitId":"-"},"content":" String emailSender \u003d email.getSenderEmail();"},{"lineNumber":258,"author":{"gitId":"-"},"content":" String emailReceiver \u003d email.getRecipient();"},{"lineNumber":259,"author":{"gitId":"-"},"content":" String emailReplyToAddress \u003d email.getReplyTo();"},{"lineNumber":260,"author":{"gitId":"-"},"content":""},{"lineNumber":261,"author":{"gitId":"-"},"content":" log.severe(\"Error when adding email to task queue: \" + e.getMessage() + \"\\n\""},{"lineNumber":262,"author":{"gitId":"-"},"content":" + \"Email sender: \" + emailSender + \"\\n\""},{"lineNumber":263,"author":{"gitId":"-"},"content":" + \"Email sender name: \" + emailSenderName + \"\\n\""},{"lineNumber":264,"author":{"gitId":"-"},"content":" + \"Email receiver: \" + emailReceiver + \"\\n\""},{"lineNumber":265,"author":{"gitId":"-"},"content":" + \"Email subject: \" + emailSubject + \"\\n\""},{"lineNumber":266,"author":{"gitId":"-"},"content":" + \"Email reply-to address: \" + emailReplyToAddress);"},{"lineNumber":267,"author":{"gitId":"-"},"content":" }"},{"lineNumber":268,"author":{"gitId":"-"},"content":" }"},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":4,"-":266}},{"path":"src/main/java/teammates/logic/external/GoogleCloudLoggingService.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.logic.external;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import com.google.api.gax.paging.Page;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import com.google.cloud.logging.LogEntry;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import com.google.cloud.logging.Logging;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import com.google.cloud.logging.Logging.EntryListOption;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import com.google.cloud.logging.Logging.SortingField;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import com.google.cloud.logging.Logging.SortingOrder;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import com.google.cloud.logging.LoggingOptions;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import com.google.cloud.logging.Payload;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import com.google.cloud.logging.Severity;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.QueryLogsResults;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionAuditLogDetails;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.GeneralLogEntry;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.LogDetails;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.LogEvent;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.LogSeverity;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.QueryLogsParams;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.SourceLocation;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":33,"author":{"gitId":"-"},"content":" * Holds functions for operations related to Google Cloud Logging."},{"lineNumber":34,"author":{"gitId":"-"},"content":" */"},{"lineNumber":35,"author":{"gitId":"-"},"content":"public class GoogleCloudLoggingService implements LogService {"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" private static final String RESOURCE_TYPE_GAE_APP \u003d \"gae_app\";"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" private static final String STDOUT_LOG_NAME \u003d \"stdout\";"},{"lineNumber":40,"author":{"gitId":"-"},"content":" private static final String STDERR_LOG_NAME \u003d \"stderr\";"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" private static final String ASCENDING_ORDER \u003d \"asc\";"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" private static final String TRACE_PREFIX \u003d String.format(\"projects/%s/traces/\", Config.APP_ID);"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":47,"author":{"gitId":"-"},"content":" public QueryLogsResults queryLogs(QueryLogsParams queryLogsParams) {"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" LogSearchParams logSearchParams \u003d LogSearchParams.from(queryLogsParams)"},{"lineNumber":50,"author":{"gitId":"-"},"content":" .addLogName(STDOUT_LOG_NAME)"},{"lineNumber":51,"author":{"gitId":"-"},"content":" .addLogName(STDERR_LOG_NAME)"},{"lineNumber":52,"author":{"gitId":"-"},"content":" .setResourceType(RESOURCE_TYPE_GAE_APP);"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" Page\u003cLogEntry\u003e logEntriesInPage \u003d getPageLogEntries(logSearchParams, queryLogsParams.getPageSize());"},{"lineNumber":55,"author":{"gitId":"-"},"content":" List\u003cGeneralLogEntry\u003e logEntries \u003d new ArrayList\u003c\u003e();"},{"lineNumber":56,"author":{"gitId":"-"},"content":" for (LogEntry entry : logEntriesInPage.getValues()) {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" Severity severity \u003d entry.getSeverity();"},{"lineNumber":58,"author":{"gitId":"-"},"content":" String trace \u003d entry.getTrace();"},{"lineNumber":59,"author":{"gitId":"-"},"content":" if (trace !\u003d null) {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" trace \u003d trace.replace(TRACE_PREFIX, \"\");"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":" String insertId \u003d entry.getInsertId();"},{"lineNumber":63,"author":{"gitId":"-"},"content":" com.google.cloud.logging.SourceLocation sourceLocation \u003d entry.getSourceLocation();"},{"lineNumber":64,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e resourceIdentifier \u003d entry.getResource().getLabels();"},{"lineNumber":65,"author":{"gitId":"-"},"content":" Payload\u003c?\u003e payload \u003d entry.getPayload();"},{"lineNumber":66,"author":{"gitId":"-"},"content":" long timestamp \u003d entry.getInstantTimestamp().toEpochMilli();"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" String file \u003d \"\";"},{"lineNumber":69,"author":{"gitId":"-"},"content":" Long line \u003d 0L;"},{"lineNumber":70,"author":{"gitId":"-"},"content":" String function \u003d \"\";"},{"lineNumber":71,"author":{"gitId":"-"},"content":" if (sourceLocation !\u003d null) {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" file \u003d sourceLocation.getFile();"},{"lineNumber":73,"author":{"gitId":"-"},"content":" line \u003d sourceLocation.getLine();"},{"lineNumber":74,"author":{"gitId":"-"},"content":" function \u003d sourceLocation.getFunction();"},{"lineNumber":75,"author":{"gitId":"-"},"content":" }"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" GeneralLogEntry logEntry \u003d new GeneralLogEntry(convertSeverity(severity), trace, insertId,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" resourceIdentifier, new SourceLocation(file, line, function), timestamp);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" if (payload.getType() \u003d\u003d Payload.Type.JSON) {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" Map\u003cString, Object\u003e jsonPayloadMap \u003d ((Payload.JsonPayload) payload).getDataAsMap();"},{"lineNumber":81,"author":{"gitId":"-"},"content":" logEntry.setDetails(JsonUtils.fromJson(JsonUtils.toCompactJson(jsonPayloadMap), LogDetails.class));"},{"lineNumber":82,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" String textPayloadMessage \u003d ((Payload.StringPayload) payload).getData();"},{"lineNumber":84,"author":{"gitId":"-"},"content":" logEntry.setMessage(textPayloadMessage);"},{"lineNumber":85,"author":{"gitId":"-"},"content":" }"},{"lineNumber":86,"author":{"gitId":"-"},"content":" logEntries.add(logEntry);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" }"},{"lineNumber":88,"author":{"gitId":"-"},"content":" boolean hasNextPage \u003d logEntriesInPage.getNextPageToken() !\u003d null;"},{"lineNumber":89,"author":{"gitId":"-"},"content":" return new QueryLogsResults(logEntries, hasNextPage);"},{"lineNumber":90,"author":{"gitId":"-"},"content":" }"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" private LogSeverity convertSeverity(Severity severity) {"},{"lineNumber":93,"author":{"gitId":"-"},"content":" if (severity \u003d\u003d Severity.ERROR) {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" return LogSeverity.ERROR;"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":" if (severity \u003d\u003d Severity.WARNING) {"},{"lineNumber":97,"author":{"gitId":"-"},"content":" return LogSeverity.WARNING;"},{"lineNumber":98,"author":{"gitId":"-"},"content":" }"},{"lineNumber":99,"author":{"gitId":"-"},"content":" if (severity \u003d\u003d Severity.INFO || severity \u003d\u003d Severity.NOTICE) {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" return LogSeverity.INFO;"},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":" if (severity \u003d\u003d Severity.CRITICAL || severity \u003d\u003d Severity.ALERT || severity \u003d\u003d Severity.EMERGENCY) {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" return LogSeverity.CRITICAL;"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":" if (severity \u003d\u003d Severity.DEBUG) {"},{"lineNumber":106,"author":{"gitId":"-"},"content":" return LogSeverity.DEBUG;"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":" return LogSeverity.DEFAULT;"},{"lineNumber":109,"author":{"gitId":"-"},"content":" }"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":112,"author":{"gitId":"-"},"content":" public void createFeedbackSessionLog(String courseId, String email, String fsName, String fslType) {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" // This method is not necessary for production usage because a feedback session log"},{"lineNumber":114,"author":{"gitId":"-"},"content":" // is already separately created through the standardized logging infrastructure."},{"lineNumber":115,"author":{"gitId":"-"},"content":" // However, this method is not removed as it is necessary to assist in local testing."},{"lineNumber":116,"author":{"gitId":"-"},"content":" }"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" public void createFeedbackSessionLog(String courseId, UUID studentId, UUID fsId, String fslType) {"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" // This method is not necessary for production usage because a feedback session log"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" // is already separately created through the standardized logging infrastructure."},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" // However, this method is not removed as it is necessary to assist in local testing."},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" public List\u003cFeedbackSessionLogEntry\u003e getOrderedFeedbackSessionLogs(String courseId, String email,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" long startTime, long endTime, String fsName) {"},{"lineNumber":128,"author":{"gitId":"-"},"content":" List\u003cString\u003e filters \u003d new ArrayList\u003c\u003e();"},{"lineNumber":129,"author":{"gitId":"-"},"content":" if (courseId !\u003d null) {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" filters.add(\"jsonPayload.courseId\u003d\\\"\" + courseId + \"\\\"\");"},{"lineNumber":131,"author":{"gitId":"-"},"content":" }"},{"lineNumber":132,"author":{"gitId":"-"},"content":" if (email !\u003d null) {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" filters.add(\"jsonPayload.studentEmail\u003d\\\"\" + email + \"\\\"\");"},{"lineNumber":134,"author":{"gitId":"-"},"content":" }"},{"lineNumber":135,"author":{"gitId":"-"},"content":" if (fsName !\u003d null) {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" filters.add(\"jsonPayload.feedbackSessionName\u003d\\\"\" + fsName + \"\\\"\");"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":" QueryLogsParams queryLogsParams \u003d QueryLogsParams.builder(startTime, endTime)"},{"lineNumber":139,"author":{"gitId":"-"},"content":" .withLogEvent(LogEvent.FEEDBACK_SESSION_AUDIT.name())"},{"lineNumber":140,"author":{"gitId":"-"},"content":" .withSeverityLevel(LogSeverity.INFO)"},{"lineNumber":141,"author":{"gitId":"-"},"content":" .withExtraFilters(String.join(\"\\n\", filters))"},{"lineNumber":142,"author":{"gitId":"dishenggg"},"content":" .withOrder(ASCENDING_ORDER)"},{"lineNumber":143,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":144,"author":{"gitId":"-"},"content":" LogSearchParams logSearchParams \u003d LogSearchParams.from(queryLogsParams)"},{"lineNumber":145,"author":{"gitId":"-"},"content":" .addLogName(STDOUT_LOG_NAME)"},{"lineNumber":146,"author":{"gitId":"-"},"content":" .setResourceType(RESOURCE_TYPE_GAE_APP);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" List\u003cLogEntry\u003e logEntries \u003d getAllLogEntries(logSearchParams);"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogEntry\u003e fsLogEntries \u003d new ArrayList\u003c\u003e();"},{"lineNumber":150,"author":{"gitId":"-"},"content":" for (LogEntry entry : logEntries) {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" long timestamp \u003d entry.getInstantTimestamp().toEpochMilli();"},{"lineNumber":152,"author":{"gitId":"-"},"content":" Payload\u003c?\u003e payload \u003d entry.getPayload();"},{"lineNumber":153,"author":{"gitId":"-"},"content":" FeedbackSessionAuditLogDetails details;"},{"lineNumber":154,"author":{"gitId":"-"},"content":" if (payload.getType() \u003d\u003d Payload.Type.JSON) {"},{"lineNumber":155,"author":{"gitId":"-"},"content":" Map\u003cString, Object\u003e jsonPayloadMap \u003d ((Payload.JsonPayload) payload).getDataAsMap();"},{"lineNumber":156,"author":{"gitId":"-"},"content":" LogDetails logDetails \u003d JsonUtils.fromJson(JsonUtils.toCompactJson(jsonPayloadMap), LogDetails.class);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" if (!(logDetails instanceof FeedbackSessionAuditLogDetails)) {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"-"},"content":" details \u003d (FeedbackSessionAuditLogDetails) logDetails;"},{"lineNumber":161,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"dishenggg"},"content":" UUID studentId \u003d details.getStudentId() !\u003d null ? UUID.fromString(details.getStudentId()) : null;"},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":" UUID fsId \u003d details.getFeedbackSessionId() !\u003d null ? UUID.fromString(details.getFeedbackSessionId()) : null;"},{"lineNumber":167,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogEntry fslEntry;"},{"lineNumber":168,"author":{"gitId":"dishenggg"},"content":" if (fsId !\u003d null \u0026\u0026 studentId !\u003d null) {"},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":" fslEntry \u003d new FeedbackSessionLogEntry(details.getCourseId(), studentId, fsId, details.getAccessType(),"},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" timestamp);"},{"lineNumber":171,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":" fslEntry \u003d new FeedbackSessionLogEntry(details.getCourseId(), details.getStudentEmail(),"},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":" details.getFeedbackSessionName(), details.getAccessType(), timestamp);"},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":175,"author":{"gitId":"-"},"content":" fsLogEntries.add(fslEntry);"},{"lineNumber":176,"author":{"gitId":"-"},"content":" }"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" return fsLogEntries;"},{"lineNumber":179,"author":{"gitId":"-"},"content":" }"},{"lineNumber":180,"author":{"gitId":"-"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":" private List\u003cLogEntry\u003e getAllLogEntries(LogSearchParams logSearchParams) {"},{"lineNumber":182,"author":{"gitId":"-"},"content":" Logging logging \u003d LoggingOptions.getDefaultInstance().getService();"},{"lineNumber":183,"author":{"gitId":"-"},"content":" List\u003cEntryListOption\u003e entryListOptions \u003d convertLogSearchParams(logSearchParams, 0);"},{"lineNumber":184,"author":{"gitId":"-"},"content":" Page\u003cLogEntry\u003e entries \u003d logging.listLogEntries(entryListOptions.toArray(new EntryListOption[] {}));"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" List\u003cLogEntry\u003e logEntries \u003d new ArrayList\u003c\u003e();"},{"lineNumber":187,"author":{"gitId":"-"},"content":" for (LogEntry entry : entries.iterateAll()) {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" logEntries.add(entry);"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":192,"author":{"gitId":"-"},"content":" logging.close();"},{"lineNumber":193,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":194,"author":{"gitId":"-"},"content":" // ignore exception when closing resource"},{"lineNumber":195,"author":{"gitId":"-"},"content":" }"},{"lineNumber":196,"author":{"gitId":"-"},"content":" return logEntries;"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" private Page\u003cLogEntry\u003e getPageLogEntries(LogSearchParams logSearchParams, int pageSize) {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" Logging logging \u003d LoggingOptions.getDefaultInstance().getService();"},{"lineNumber":201,"author":{"gitId":"-"},"content":" List\u003cEntryListOption\u003e entryListOptions \u003d convertLogSearchParams(logSearchParams, pageSize);"},{"lineNumber":202,"author":{"gitId":"-"},"content":" Page\u003cLogEntry\u003e entries \u003d logging.listLogEntries(entryListOptions.toArray(new EntryListOption[] {}));"},{"lineNumber":203,"author":{"gitId":"-"},"content":""},{"lineNumber":204,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" logging.close();"},{"lineNumber":206,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":207,"author":{"gitId":"-"},"content":" // ignore exception when closing resource"},{"lineNumber":208,"author":{"gitId":"-"},"content":" }"},{"lineNumber":209,"author":{"gitId":"-"},"content":" return entries;"},{"lineNumber":210,"author":{"gitId":"-"},"content":" }"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" private List\u003cEntryListOption\u003e convertLogSearchParams(LogSearchParams s, int pageSize) {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" LoggingOptions options \u003d LoggingOptions.getDefaultInstance();"},{"lineNumber":214,"author":{"gitId":"-"},"content":" QueryLogsParams q \u003d s.queryLogsParams;"},{"lineNumber":215,"author":{"gitId":"-"},"content":""},{"lineNumber":216,"author":{"gitId":"-"},"content":" List\u003cString\u003e logFilters \u003d new ArrayList\u003c\u003e();"},{"lineNumber":217,"author":{"gitId":"-"},"content":" logFilters.add(\"timestamp\u003e\\\"\" + Instant.ofEpochMilli(q.getStartTime()).toString() + \"\\\"\");"},{"lineNumber":218,"author":{"gitId":"-"},"content":" logFilters.add(\"timestamp\u003c\u003d\\\"\" + Instant.ofEpochMilli(q.getEndTime()).toString() + \"\\\"\");"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" if (!s.logName.isEmpty()) {"},{"lineNumber":221,"author":{"gitId":"-"},"content":" String logNameFilter \u003d s.logName.stream()"},{"lineNumber":222,"author":{"gitId":"-"},"content":" .map(str -\u003e \"\\\"projects/\" + options.getProjectId() + \"/logs/\" + str + \"\\\"\")"},{"lineNumber":223,"author":{"gitId":"-"},"content":" .collect(Collectors.joining(\" OR \"));"},{"lineNumber":224,"author":{"gitId":"-"},"content":" logFilters.add(\"logName\u003d(\" + logNameFilter + \")\");"},{"lineNumber":225,"author":{"gitId":"-"},"content":" }"},{"lineNumber":226,"author":{"gitId":"-"},"content":" if (s.resourceType !\u003d null) {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" logFilters.add(\"resource.type\u003d\\\"\" + s.resourceType + \"\\\"\");"},{"lineNumber":228,"author":{"gitId":"-"},"content":" }"},{"lineNumber":229,"author":{"gitId":"-"},"content":" if (q.getSeverity() !\u003d null) {"},{"lineNumber":230,"author":{"gitId":"-"},"content":" logFilters.add(\"severity\u003d\" + q.getSeverity());"},{"lineNumber":231,"author":{"gitId":"-"},"content":" } else if (q.getMinSeverity() !\u003d null \u0026\u0026 q.getSeverity() \u003d\u003d null) {"},{"lineNumber":232,"author":{"gitId":"-"},"content":" logFilters.add(\"severity\u003e\u003d\" + q.getMinSeverity());"},{"lineNumber":233,"author":{"gitId":"-"},"content":" }"},{"lineNumber":234,"author":{"gitId":"-"},"content":" if (q.getTraceId() !\u003d null) {"},{"lineNumber":235,"author":{"gitId":"-"},"content":" logFilters.add(\"trace\u003d\\\"\" + TRACE_PREFIX + q.getTraceId() + \"\\\"\");"},{"lineNumber":236,"author":{"gitId":"-"},"content":" }"},{"lineNumber":237,"author":{"gitId":"-"},"content":" if (q.getActionClass() !\u003d null) {"},{"lineNumber":238,"author":{"gitId":"-"},"content":" logFilters.add(\"jsonPayload.actionClass\u003d\\\"\" + q.getActionClass() + \"\\\"\");"},{"lineNumber":239,"author":{"gitId":"-"},"content":" }"},{"lineNumber":240,"author":{"gitId":"-"},"content":" if (q.getUserInfoParams() !\u003d null) {"},{"lineNumber":241,"author":{"gitId":"-"},"content":" if (q.getUserInfoParams().getGoogleId() !\u003d null) {"},{"lineNumber":242,"author":{"gitId":"-"},"content":" logFilters.add(\"jsonPayload.userInfo.googleId\u003d\\\"\" + q.getUserInfoParams().getGoogleId() + \"\\\"\");"},{"lineNumber":243,"author":{"gitId":"-"},"content":" }"},{"lineNumber":244,"author":{"gitId":"-"},"content":" if (q.getUserInfoParams().getRegkey() !\u003d null) {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" logFilters.add(\"jsonPayload.userInfo.regkey\u003d\\\"\" + q.getUserInfoParams().getRegkey() + \"\\\"\");"},{"lineNumber":246,"author":{"gitId":"-"},"content":" }"},{"lineNumber":247,"author":{"gitId":"-"},"content":" if (q.getUserInfoParams().getEmail() !\u003d null) {"},{"lineNumber":248,"author":{"gitId":"-"},"content":" logFilters.add(\"jsonPayload.userInfo.email\u003d\\\"\" + q.getUserInfoParams().getEmail() + \"\\\"\");"},{"lineNumber":249,"author":{"gitId":"-"},"content":" }"},{"lineNumber":250,"author":{"gitId":"-"},"content":" }"},{"lineNumber":251,"author":{"gitId":"-"},"content":" if (q.getLogEvent() !\u003d null) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" logFilters.add(\"jsonPayload.event\u003d\\\"\" + q.getLogEvent() + \"\\\"\");"},{"lineNumber":253,"author":{"gitId":"-"},"content":" }"},{"lineNumber":254,"author":{"gitId":"-"},"content":" if (q.getSourceLocation() !\u003d null \u0026\u0026 q.getSourceLocation().getFile() !\u003d null) {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" if (q.getSourceLocation().getFunction() \u003d\u003d null) {"},{"lineNumber":256,"author":{"gitId":"-"},"content":" logFilters.add(\"sourceLocation.file\u003d\\\"\" + q.getSourceLocation().getFile() + \"\\\"\");"},{"lineNumber":257,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" logFilters.add(\"sourceLocation.file\u003d\\\"\" + q.getSourceLocation().getFile()"},{"lineNumber":259,"author":{"gitId":"-"},"content":" + \"\\\" AND sourceLocation.function\u003d\\\"\" + q.getSourceLocation().getFunction() + \"\\\"\");"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":" }"},{"lineNumber":262,"author":{"gitId":"-"},"content":" if (q.getExceptionClass() !\u003d null) {"},{"lineNumber":263,"author":{"gitId":"-"},"content":" logFilters.add(\"jsonPayload.exceptionClass\u003d\\\"\" + q.getExceptionClass() + \"\\\"\");"},{"lineNumber":264,"author":{"gitId":"-"},"content":" }"},{"lineNumber":265,"author":{"gitId":"-"},"content":" if (q.getLatency() !\u003d null) {"},{"lineNumber":266,"author":{"gitId":"-"},"content":" logFilters.add(\"jsonPayload.responseTime\" + q.getLatency());"},{"lineNumber":267,"author":{"gitId":"-"},"content":" }"},{"lineNumber":268,"author":{"gitId":"-"},"content":" if (q.getStatus() !\u003d null) {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" logFilters.add(\"jsonPayload.responseStatus\u003d\" + q.getStatus());"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":" if (q.getVersion() !\u003d null) {"},{"lineNumber":272,"author":{"gitId":"-"},"content":" logFilters.add(\"jsonPayload.webVersion\u003d\\\"\" + q.getVersion() + \"\\\"\");"},{"lineNumber":273,"author":{"gitId":"-"},"content":" }"},{"lineNumber":274,"author":{"gitId":"-"},"content":" if (q.getExtraFilters() !\u003d null) {"},{"lineNumber":275,"author":{"gitId":"-"},"content":" logFilters.add(q.getExtraFilters());"},{"lineNumber":276,"author":{"gitId":"-"},"content":" }"},{"lineNumber":277,"author":{"gitId":"-"},"content":" String logFilter \u003d String.join(\"\\n\", logFilters);"},{"lineNumber":278,"author":{"gitId":"-"},"content":""},{"lineNumber":279,"author":{"gitId":"-"},"content":" List\u003cEntryListOption\u003e entryListOptions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":280,"author":{"gitId":"-"},"content":""},{"lineNumber":281,"author":{"gitId":"-"},"content":" entryListOptions.add(EntryListOption.filter(logFilter));"},{"lineNumber":282,"author":{"gitId":"-"},"content":""},{"lineNumber":283,"author":{"gitId":"-"},"content":" if (pageSize \u003e 0) {"},{"lineNumber":284,"author":{"gitId":"-"},"content":" entryListOptions.add(EntryListOption.pageSize(pageSize));"},{"lineNumber":285,"author":{"gitId":"-"},"content":" }"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"-"},"content":" if (q.getOrder() !\u003d null) {"},{"lineNumber":288,"author":{"gitId":"-"},"content":" if (ASCENDING_ORDER.equals(q.getOrder())) {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" entryListOptions.add(EntryListOption.sortOrder(SortingField.TIMESTAMP, SortingOrder.ASCENDING));"},{"lineNumber":290,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":291,"author":{"gitId":"-"},"content":" entryListOptions.add(EntryListOption.sortOrder(SortingField.TIMESTAMP, SortingOrder.DESCENDING));"},{"lineNumber":292,"author":{"gitId":"-"},"content":" }"},{"lineNumber":293,"author":{"gitId":"-"},"content":" }"},{"lineNumber":294,"author":{"gitId":"-"},"content":""},{"lineNumber":295,"author":{"gitId":"-"},"content":" return entryListOptions;"},{"lineNumber":296,"author":{"gitId":"-"},"content":" }"},{"lineNumber":297,"author":{"gitId":"-"},"content":""},{"lineNumber":298,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":299,"author":{"gitId":"-"},"content":" * Contains params to be used for the searching of logs."},{"lineNumber":300,"author":{"gitId":"-"},"content":" */"},{"lineNumber":301,"author":{"gitId":"-"},"content":" private static final class LogSearchParams {"},{"lineNumber":302,"author":{"gitId":"-"},"content":" private final List\u003cString\u003e logName \u003d new ArrayList\u003c\u003e();"},{"lineNumber":303,"author":{"gitId":"-"},"content":" private String resourceType;"},{"lineNumber":304,"author":{"gitId":"-"},"content":" private QueryLogsParams queryLogsParams;"},{"lineNumber":305,"author":{"gitId":"-"},"content":""},{"lineNumber":306,"author":{"gitId":"-"},"content":" static LogSearchParams from(QueryLogsParams queryLogsParams) {"},{"lineNumber":307,"author":{"gitId":"-"},"content":" return new LogSearchParams().setQueryLogsParams(queryLogsParams);"},{"lineNumber":308,"author":{"gitId":"-"},"content":" }"},{"lineNumber":309,"author":{"gitId":"-"},"content":""},{"lineNumber":310,"author":{"gitId":"-"},"content":" LogSearchParams addLogName(String logName) {"},{"lineNumber":311,"author":{"gitId":"-"},"content":" this.logName.add(logName);"},{"lineNumber":312,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":313,"author":{"gitId":"-"},"content":" }"},{"lineNumber":314,"author":{"gitId":"-"},"content":""},{"lineNumber":315,"author":{"gitId":"-"},"content":" LogSearchParams setResourceType(String resourceType) {"},{"lineNumber":316,"author":{"gitId":"-"},"content":" this.resourceType \u003d resourceType;"},{"lineNumber":317,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":318,"author":{"gitId":"-"},"content":" }"},{"lineNumber":319,"author":{"gitId":"-"},"content":""},{"lineNumber":320,"author":{"gitId":"-"},"content":" private LogSearchParams setQueryLogsParams(QueryLogsParams queryLogsParams) {"},{"lineNumber":321,"author":{"gitId":"-"},"content":" this.queryLogsParams \u003d queryLogsParams;"},{"lineNumber":322,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":323,"author":{"gitId":"-"},"content":" }"},{"lineNumber":324,"author":{"gitId":"-"},"content":" }"},{"lineNumber":325,"author":{"gitId":"-"},"content":""},{"lineNumber":326,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":19,"-":307}},{"path":"src/main/java/teammates/logic/external/LocalLoggingService.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.logic.external;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.lang.reflect.Type;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Collection;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.concurrent.ConcurrentHashMap;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import java.util.regex.Matcher;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import java.util.regex.Pattern;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"import org.apache.commons.math3.random.RandomDataGenerator;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"import com.google.common.reflect.TypeToken;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import com.google.gson.JsonParseException;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.QueryLogsResults;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.ExceptionLogDetails;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.GeneralLogEntry;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.LogDetails;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.LogEvent;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.QueryLogsParams;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.RequestLogDetails;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.RequestLogUser;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.common.util.FileHelper;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":33,"author":{"gitId":"-"},"content":" * Holds functions for operations related to logs reading/writing in local dev environment."},{"lineNumber":34,"author":{"gitId":"-"},"content":" *"},{"lineNumber":35,"author":{"gitId":"-"},"content":" * \u003cp\u003eThe current implementation uses an in-memory storage of logs to simulate the logs"},{"lineNumber":36,"author":{"gitId":"-"},"content":" * retention locally for feedback session logs only. It is not meant as a replacement but"},{"lineNumber":37,"author":{"gitId":"-"},"content":" * merely for testing purposes."},{"lineNumber":38,"author":{"gitId":"-"},"content":" */"},{"lineNumber":39,"author":{"gitId":"-"},"content":"public class LocalLoggingService implements LogService {"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" private static final Map\u003cString, List\u003cFeedbackSessionLogEntry\u003e\u003e FEEDBACK_SESSION_LOG_ENTRIES \u003d new ConcurrentHashMap\u003c\u003e();"},{"lineNumber":42,"author":{"gitId":"-"},"content":" private static final List\u003cGeneralLogEntry\u003e LOCAL_LOG_ENTRIES \u003d loadLocalLogEntries();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" private static final String ASCENDING_ORDER \u003d \"asc\";"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" private static List\u003cGeneralLogEntry\u003e loadLocalLogEntries() {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" // Timestamp of logs are randomly created to be within the last one hour"},{"lineNumber":47,"author":{"gitId":"-"},"content":" long currentTimestamp \u003d Instant.now().toEpochMilli();"},{"lineNumber":48,"author":{"gitId":"-"},"content":" long earliestTimestamp \u003d currentTimestamp - 60 * 60 * 1000;"},{"lineNumber":49,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" String jsonString \u003d FileHelper.readResourceFile(\"logsForLocalDev.json\");"},{"lineNumber":51,"author":{"gitId":"-"},"content":" Type type \u003d new TypeToken\u003cCollection\u003cGeneralLogEntry\u003e\u003e(){}.getType();"},{"lineNumber":52,"author":{"gitId":"-"},"content":" Collection\u003cGeneralLogEntry\u003e logEntriesCollection \u003d JsonUtils.fromJson(jsonString, type);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" return logEntriesCollection.stream()"},{"lineNumber":54,"author":{"gitId":"-"},"content":" .map(log -\u003e {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" long timestamp \u003d new RandomDataGenerator().nextLong(earliestTimestamp, currentTimestamp);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" GeneralLogEntry logEntryWithUpdatedTimestamp \u003d new GeneralLogEntry("},{"lineNumber":57,"author":{"gitId":"-"},"content":" log.getSeverity(), log.getTrace(), log.getInsertId(), log.getResourceIdentifier(),"},{"lineNumber":58,"author":{"gitId":"-"},"content":" log.getSourceLocation(), timestamp);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" logEntryWithUpdatedTimestamp.setDetails(log.getDetails());"},{"lineNumber":60,"author":{"gitId":"-"},"content":" logEntryWithUpdatedTimestamp.setMessage(log.getMessage());"},{"lineNumber":61,"author":{"gitId":"-"},"content":" return logEntryWithUpdatedTimestamp;"},{"lineNumber":62,"author":{"gitId":"-"},"content":" })"},{"lineNumber":63,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":64,"author":{"gitId":"-"},"content":" } catch (JsonParseException e) {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" return new ArrayList\u003c\u003e();"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":70,"author":{"gitId":"-"},"content":" public QueryLogsResults queryLogs(QueryLogsParams queryLogsParams) {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" // Page size is set as a small value to test loading of more logs"},{"lineNumber":72,"author":{"gitId":"-"},"content":" int pageSize \u003d 10;"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" List\u003cGeneralLogEntry\u003e result \u003d LOCAL_LOG_ENTRIES.stream()"},{"lineNumber":75,"author":{"gitId":"-"},"content":" .sorted((x, y) -\u003e {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" String order \u003d queryLogsParams.getOrder();"},{"lineNumber":77,"author":{"gitId":"-"},"content":" if (ASCENDING_ORDER.equals(order)) {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" return Long.compare(x.getTimestamp(), y.getTimestamp());"},{"lineNumber":79,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" return Long.compare(y.getTimestamp(), x.getTimestamp());"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":" })"},{"lineNumber":83,"author":{"gitId":"-"},"content":" .filter(log -\u003e queryLogsParams.getSeverity() \u003d\u003d null"},{"lineNumber":84,"author":{"gitId":"-"},"content":" || log.getSeverity().equals(queryLogsParams.getSeverity()))"},{"lineNumber":85,"author":{"gitId":"-"},"content":" .filter(log -\u003e queryLogsParams.getMinSeverity() \u003d\u003d null"},{"lineNumber":86,"author":{"gitId":"-"},"content":" || log.getSeverity().getSeverityLevel()"},{"lineNumber":87,"author":{"gitId":"-"},"content":" \u003e\u003d queryLogsParams.getMinSeverity().getSeverityLevel())"},{"lineNumber":88,"author":{"gitId":"-"},"content":" .filter(log -\u003e log.getTimestamp() \u003e queryLogsParams.getStartTime())"},{"lineNumber":89,"author":{"gitId":"-"},"content":" .filter(log -\u003e log.getTimestamp() \u003c\u003d queryLogsParams.getEndTime())"},{"lineNumber":90,"author":{"gitId":"-"},"content":" .filter(log -\u003e queryLogsParams.getTraceId() \u003d\u003d null"},{"lineNumber":91,"author":{"gitId":"-"},"content":" || queryLogsParams.getTraceId().equals(log.getTrace()))"},{"lineNumber":92,"author":{"gitId":"-"},"content":" .filter(log -\u003e queryLogsParams.getVersion() \u003d\u003d null"},{"lineNumber":93,"author":{"gitId":"-"},"content":" || queryLogsParams.getVersion().equals(log.getResourceIdentifier().get(\"version_id\")))"},{"lineNumber":94,"author":{"gitId":"-"},"content":" .filter(log -\u003e queryLogsParams.getSourceLocation().getFile() \u003d\u003d null"},{"lineNumber":95,"author":{"gitId":"-"},"content":" || log.getSourceLocation().getFile().equals(queryLogsParams.getSourceLocation().getFile()))"},{"lineNumber":96,"author":{"gitId":"-"},"content":" .filter(log -\u003e queryLogsParams.getSourceLocation().getFunction() \u003d\u003d null"},{"lineNumber":97,"author":{"gitId":"-"},"content":" || log.getSourceLocation().getFunction().equals(queryLogsParams.getSourceLocation().getFunction()))"},{"lineNumber":98,"author":{"gitId":"-"},"content":" .filter(log -\u003e isEventBasedFilterSatisfied(log, queryLogsParams))"},{"lineNumber":99,"author":{"gitId":"-"},"content":" .limit(pageSize)"},{"lineNumber":100,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" List\u003cGeneralLogEntry\u003e copiedResults \u003d deepCopyLogEntries(result);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" boolean hasNextPage \u003d copiedResults.size() \u003d\u003d pageSize;"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" return new QueryLogsResults(copiedResults, hasNextPage);"},{"lineNumber":106,"author":{"gitId":"-"},"content":" }"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" private boolean isEventBasedFilterSatisfied(GeneralLogEntry log, QueryLogsParams queryLogsParams) {"},{"lineNumber":109,"author":{"gitId":"-"},"content":" String actionClassFilter \u003d queryLogsParams.getActionClass();"},{"lineNumber":110,"author":{"gitId":"-"},"content":" String exceptionClassFilter \u003d queryLogsParams.getExceptionClass();"},{"lineNumber":111,"author":{"gitId":"-"},"content":" String logEventFilter \u003d queryLogsParams.getLogEvent();"},{"lineNumber":112,"author":{"gitId":"-"},"content":" String latencyFilter \u003d queryLogsParams.getLatency();"},{"lineNumber":113,"author":{"gitId":"-"},"content":" String statusFilter \u003d queryLogsParams.getStatus();"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" RequestLogUser userInfoFilter \u003d queryLogsParams.getUserInfoParams();"},{"lineNumber":116,"author":{"gitId":"-"},"content":" String regkeyFilter \u003d userInfoFilter.getRegkey();"},{"lineNumber":117,"author":{"gitId":"-"},"content":" String emailFilter \u003d userInfoFilter.getEmail();"},{"lineNumber":118,"author":{"gitId":"-"},"content":" String googleIdFilter \u003d userInfoFilter.getGoogleId();"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" if (actionClassFilter \u003d\u003d null \u0026\u0026 exceptionClassFilter \u003d\u003d null \u0026\u0026 logEventFilter \u003d\u003d null"},{"lineNumber":121,"author":{"gitId":"-"},"content":" \u0026\u0026 latencyFilter \u003d\u003d null \u0026\u0026 statusFilter \u003d\u003d null \u0026\u0026 regkeyFilter \u003d\u003d null"},{"lineNumber":122,"author":{"gitId":"-"},"content":" \u0026\u0026 emailFilter \u003d\u003d null \u0026\u0026 googleIdFilter \u003d\u003d null) {"},{"lineNumber":123,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":124,"author":{"gitId":"-"},"content":" }"},{"lineNumber":125,"author":{"gitId":"-"},"content":" LogDetails details \u003d log.getDetails();"},{"lineNumber":126,"author":{"gitId":"-"},"content":" if (details \u003d\u003d null) {"},{"lineNumber":127,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":" if (logEventFilter !\u003d null \u0026\u0026 !details.getEvent().name().equals(logEventFilter)) {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":131,"author":{"gitId":"-"},"content":" }"},{"lineNumber":132,"author":{"gitId":"-"},"content":" if (!isExceptionFilterSatisfied(details, exceptionClassFilter)) {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":134,"author":{"gitId":"-"},"content":" }"},{"lineNumber":135,"author":{"gitId":"-"},"content":" return isRequestFilterSatisfied(details, actionClassFilter, latencyFilter, statusFilter,"},{"lineNumber":136,"author":{"gitId":"-"},"content":" regkeyFilter, emailFilter, googleIdFilter);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" private boolean isExceptionFilterSatisfied(LogDetails details, String exceptionClassFilter) {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" if (exceptionClassFilter \u003d\u003d null) {"},{"lineNumber":141,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":142,"author":{"gitId":"-"},"content":" }"},{"lineNumber":143,"author":{"gitId":"-"},"content":" if (details.getEvent() !\u003d LogEvent.EXCEPTION_LOG) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":" ExceptionLogDetails exceptionDetails \u003d (ExceptionLogDetails) details;"},{"lineNumber":147,"author":{"gitId":"-"},"content":" return exceptionDetails.getExceptionClass().equals(exceptionClassFilter);"},{"lineNumber":148,"author":{"gitId":"-"},"content":" }"},{"lineNumber":149,"author":{"gitId":"-"},"content":""},{"lineNumber":150,"author":{"gitId":"-"},"content":" private boolean isRequestFilterSatisfied(LogDetails details, String actionClassFilter,"},{"lineNumber":151,"author":{"gitId":"-"},"content":" String latencyFilter, String statusFilter, String regkeyFilter, String emailFilter, String googleIdFilter) {"},{"lineNumber":152,"author":{"gitId":"-"},"content":" if (actionClassFilter \u003d\u003d null \u0026\u0026 latencyFilter \u003d\u003d null \u0026\u0026 statusFilter \u003d\u003d null"},{"lineNumber":153,"author":{"gitId":"-"},"content":" \u0026\u0026 regkeyFilter \u003d\u003d null \u0026\u0026 emailFilter \u003d\u003d null \u0026\u0026 googleIdFilter \u003d\u003d null) {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":155,"author":{"gitId":"-"},"content":" }"},{"lineNumber":156,"author":{"gitId":"-"},"content":" if (details.getEvent() !\u003d LogEvent.REQUEST_LOG) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":" RequestLogDetails requestDetails \u003d (RequestLogDetails) details;"},{"lineNumber":160,"author":{"gitId":"-"},"content":" if (actionClassFilter !\u003d null \u0026\u0026 !actionClassFilter.equals(requestDetails.getActionClass())) {"},{"lineNumber":161,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":" if (statusFilter !\u003d null \u0026\u0026 !statusFilter.equals(String.valueOf(requestDetails.getResponseStatus()))) {"},{"lineNumber":164,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":" if (latencyFilter !\u003d null) {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" Pattern p \u003d Pattern.compile(\"^(\u003e|\u003e\u003d|\u003c|\u003c\u003d) *(\\\\d+)$\");"},{"lineNumber":168,"author":{"gitId":"-"},"content":" Matcher m \u003d p.matcher(latencyFilter);"},{"lineNumber":169,"author":{"gitId":"-"},"content":" long logLatency \u003d ((RequestLogDetails) details).getResponseTime();"},{"lineNumber":170,"author":{"gitId":"-"},"content":" boolean isFilterSatisfied \u003d false;"},{"lineNumber":171,"author":{"gitId":"-"},"content":" if (m.matches()) {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" int time \u003d Integer.parseInt(m.group(2));"},{"lineNumber":173,"author":{"gitId":"-"},"content":" switch (m.group(1)) {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" case \"\u003e\":"},{"lineNumber":175,"author":{"gitId":"-"},"content":" isFilterSatisfied \u003d logLatency \u003e time;"},{"lineNumber":176,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":177,"author":{"gitId":"-"},"content":" case \"\u003e\u003d\":"},{"lineNumber":178,"author":{"gitId":"-"},"content":" isFilterSatisfied \u003d logLatency \u003e\u003d time;"},{"lineNumber":179,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":180,"author":{"gitId":"-"},"content":" case \"\u003c\":"},{"lineNumber":181,"author":{"gitId":"-"},"content":" isFilterSatisfied \u003d logLatency \u003c time;"},{"lineNumber":182,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":183,"author":{"gitId":"-"},"content":" case \"\u003c\u003d\":"},{"lineNumber":184,"author":{"gitId":"-"},"content":" isFilterSatisfied \u003d logLatency \u003c\u003d time;"},{"lineNumber":185,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":186,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":187,"author":{"gitId":"-"},"content":" assert false : \"Unreachable case\";"},{"lineNumber":188,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":" }"},{"lineNumber":191,"author":{"gitId":"-"},"content":" if (!isFilterSatisfied) {"},{"lineNumber":192,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":" }"},{"lineNumber":195,"author":{"gitId":"-"},"content":" RequestLogUser userInfo \u003d requestDetails.getUserInfo();"},{"lineNumber":196,"author":{"gitId":"-"},"content":" if (regkeyFilter !\u003d null \u0026\u0026 (userInfo \u003d\u003d null || !regkeyFilter.equals(userInfo.getRegkey()))) {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":198,"author":{"gitId":"-"},"content":" }"},{"lineNumber":199,"author":{"gitId":"-"},"content":" if (emailFilter !\u003d null \u0026\u0026 (userInfo \u003d\u003d null || !emailFilter.equals(userInfo.getEmail()))) {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":201,"author":{"gitId":"-"},"content":" }"},{"lineNumber":202,"author":{"gitId":"-"},"content":" return googleIdFilter \u003d\u003d null || userInfo !\u003d null \u0026\u0026 googleIdFilter.equals(userInfo.getGoogleId());"},{"lineNumber":203,"author":{"gitId":"-"},"content":" }"},{"lineNumber":204,"author":{"gitId":"-"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":206,"author":{"gitId":"-"},"content":" public void createFeedbackSessionLog(String courseId, String email, String fsName, String fslType) {"},{"lineNumber":207,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogEntry logEntry \u003d new FeedbackSessionLogEntry(courseId, email,"},{"lineNumber":208,"author":{"gitId":"dishenggg"},"content":" fsName, fslType, Instant.now().toEpochMilli());"},{"lineNumber":209,"author":{"gitId":"dishenggg"},"content":" FEEDBACK_SESSION_LOG_ENTRIES.computeIfAbsent(courseId, k -\u003e new ArrayList\u003c\u003e()).add(logEntry);"},{"lineNumber":210,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":211,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":212,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":213,"author":{"gitId":"dishenggg"},"content":" public void createFeedbackSessionLog(String courseId, UUID studentId, UUID fsId, String fslType) {"},{"lineNumber":214,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogEntry logEntry \u003d new FeedbackSessionLogEntry(courseId, studentId, fsId,"},{"lineNumber":215,"author":{"gitId":"-"},"content":" fslType, Instant.now().toEpochMilli());"},{"lineNumber":216,"author":{"gitId":"-"},"content":" FEEDBACK_SESSION_LOG_ENTRIES.computeIfAbsent(courseId, k -\u003e new ArrayList\u003c\u003e()).add(logEntry);"},{"lineNumber":217,"author":{"gitId":"-"},"content":" }"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":220,"author":{"gitId":"dishenggg"},"content":" public List\u003cFeedbackSessionLogEntry\u003e getOrderedFeedbackSessionLogs(String courseId, String email,"},{"lineNumber":221,"author":{"gitId":"-"},"content":" long startTime, long endTime, String fsName) {"},{"lineNumber":222,"author":{"gitId":"-"},"content":" return FEEDBACK_SESSION_LOG_ENTRIES"},{"lineNumber":223,"author":{"gitId":"-"},"content":" .getOrDefault(courseId, new ArrayList\u003c\u003e())"},{"lineNumber":224,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":225,"author":{"gitId":"-"},"content":" .filter(log -\u003e email \u003d\u003d null || log.getStudentEmail().equals(email))"},{"lineNumber":226,"author":{"gitId":"-"},"content":" .filter(log -\u003e fsName \u003d\u003d null || log.getFeedbackSessionName().equals(fsName))"},{"lineNumber":227,"author":{"gitId":"-"},"content":" .filter(log -\u003e log.getTimestamp() \u003e\u003d startTime)"},{"lineNumber":228,"author":{"gitId":"-"},"content":" .filter(log -\u003e log.getTimestamp() \u003c\u003d endTime)"},{"lineNumber":229,"author":{"gitId":"dishenggg"},"content":" .sorted()"},{"lineNumber":230,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" private List\u003cGeneralLogEntry\u003e deepCopyLogEntries(List\u003cGeneralLogEntry\u003e logEntries) {"},{"lineNumber":234,"author":{"gitId":"-"},"content":" List\u003cGeneralLogEntry\u003e result \u003d new ArrayList\u003c\u003e();"},{"lineNumber":235,"author":{"gitId":"-"},"content":" for (GeneralLogEntry logEntry : logEntries) {"},{"lineNumber":236,"author":{"gitId":"-"},"content":" GeneralLogEntry copiedEntry \u003d new GeneralLogEntry(logEntry.getSeverity(),"},{"lineNumber":237,"author":{"gitId":"-"},"content":" logEntry.getTrace(), logEntry.getInsertId(), logEntry.getResourceIdentifier(),"},{"lineNumber":238,"author":{"gitId":"-"},"content":" logEntry.getSourceLocation(), logEntry.getTimestamp());"},{"lineNumber":239,"author":{"gitId":"-"},"content":" copiedEntry.setDetails(JsonUtils.fromJson(JsonUtils.toCompactJson(logEntry.getDetails()), LogDetails.class));"},{"lineNumber":240,"author":{"gitId":"-"},"content":" copiedEntry.setMessage(logEntry.getMessage());"},{"lineNumber":241,"author":{"gitId":"-"},"content":" result.add(copiedEntry);"},{"lineNumber":242,"author":{"gitId":"-"},"content":" }"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" return result;"},{"lineNumber":245,"author":{"gitId":"-"},"content":" }"},{"lineNumber":246,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":11,"-":235}},{"path":"src/main/java/teammates/logic/external/LogService.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.logic.external;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.QueryLogsResults;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.QueryLogsParams;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * An interface used for logs operations such as reading/writing."},{"lineNumber":12,"author":{"gitId":"-"},"content":" */"},{"lineNumber":13,"author":{"gitId":"-"},"content":"public interface LogService {"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * Gets the list of logs satisfying the given criteria."},{"lineNumber":17,"author":{"gitId":"-"},"content":" */"},{"lineNumber":18,"author":{"gitId":"-"},"content":" QueryLogsResults queryLogs(QueryLogsParams queryLogsParams);"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":21,"author":{"gitId":"-"},"content":" * Creates a feedback session log."},{"lineNumber":22,"author":{"gitId":"-"},"content":" */"},{"lineNumber":23,"author":{"gitId":"-"},"content":" void createFeedbackSessionLog(String courseId, String email, String fsName, String fslType);"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" * Creates a feedback session log for migrated courses."},{"lineNumber":27,"author":{"gitId":"-"},"content":" */"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" void createFeedbackSessionLog(String courseId, UUID studentId, UUID fsId, String fslType);"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" * Gets the feedback session logs as filtered by the given parameters ordered by ascending timestamp."},{"lineNumber":32,"author":{"gitId":"-"},"content":" */"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntry\u003e getOrderedFeedbackSessionLogs(String courseId, String email,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" long startTime, long endTime, String fsName);"},{"lineNumber":35,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":6,"-":29}},{"path":"src/main/java/teammates/sqllogic/api/Logic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.api;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Set;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackQuestionRecipient;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.FeedbackResultFetchType;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationStyle;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationTargetUser;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.SqlSessionResultsBundle;"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EnrollException;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.exception.InstructorUpdateException;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.exception.StudentUpdateException;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.AccountRequestsLogic;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.AccountsLogic;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.CoursesLogic;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.DataBundleLogic;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.DeadlineExtensionsLogic;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.FeedbackQuestionsLogic;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.FeedbackResponseCommentsLogic;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.FeedbackResponsesLogic;"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":"import teammates.sqllogic.core.FeedbackSessionLogsLogic;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.FeedbackSessionsLogic;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.NotificationsLogic;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.UsageStatisticsLogic;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.UsersLogic;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":41,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":42,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":43,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":45,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":47,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":49,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":50,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":52,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.UsageStatistics;"},{"lineNumber":53,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.User;"},{"lineNumber":54,"author":{"gitId":"-"},"content":"import teammates.ui.request.FeedbackQuestionUpdateRequest;"},{"lineNumber":55,"author":{"gitId":"-"},"content":"import teammates.ui.request.FeedbackResponseCommentUpdateRequest;"},{"lineNumber":56,"author":{"gitId":"-"},"content":"import teammates.ui.request.InstructorCreateRequest;"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":59,"author":{"gitId":"-"},"content":" * Provides the business logic for production usage of the system."},{"lineNumber":60,"author":{"gitId":"-"},"content":" *"},{"lineNumber":61,"author":{"gitId":"-"},"content":" * \u003cp\u003eThis is a Facade class which simply forwards the method to internal classes."},{"lineNumber":62,"author":{"gitId":"-"},"content":" */"},{"lineNumber":63,"author":{"gitId":"-"},"content":"public class Logic {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" private static final Logic instance \u003d new Logic();"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" final AccountsLogic accountsLogic \u003d AccountsLogic.inst();"},{"lineNumber":67,"author":{"gitId":"-"},"content":" final AccountRequestsLogic accountRequestLogic \u003d AccountRequestsLogic.inst();"},{"lineNumber":68,"author":{"gitId":"-"},"content":" final CoursesLogic coursesLogic \u003d CoursesLogic.inst();"},{"lineNumber":69,"author":{"gitId":"-"},"content":" final DeadlineExtensionsLogic deadlineExtensionsLogic \u003d DeadlineExtensionsLogic.inst();"},{"lineNumber":70,"author":{"gitId":"-"},"content":" final FeedbackQuestionsLogic feedbackQuestionsLogic \u003d FeedbackQuestionsLogic.inst();"},{"lineNumber":71,"author":{"gitId":"-"},"content":" final FeedbackResponsesLogic feedbackResponsesLogic \u003d FeedbackResponsesLogic.inst();"},{"lineNumber":72,"author":{"gitId":"-"},"content":" final FeedbackResponseCommentsLogic feedbackResponseCommentsLogic \u003d FeedbackResponseCommentsLogic.inst();"},{"lineNumber":73,"author":{"gitId":"-"},"content":" final FeedbackSessionsLogic feedbackSessionsLogic \u003d FeedbackSessionsLogic.inst();"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" final FeedbackSessionLogsLogic feedbackSessionLogsLogic \u003d FeedbackSessionLogsLogic.inst();"},{"lineNumber":75,"author":{"gitId":"-"},"content":" final UsageStatisticsLogic usageStatisticsLogic \u003d UsageStatisticsLogic.inst();"},{"lineNumber":76,"author":{"gitId":"-"},"content":" final UsersLogic usersLogic \u003d UsersLogic.inst();"},{"lineNumber":77,"author":{"gitId":"-"},"content":" final NotificationsLogic notificationsLogic \u003d NotificationsLogic.inst();"},{"lineNumber":78,"author":{"gitId":"-"},"content":" final DataBundleLogic dataBundleLogic \u003d DataBundleLogic.inst();"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" Logic() {"},{"lineNumber":81,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":82,"author":{"gitId":"-"},"content":" }"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" public static Logic inst() {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" }"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":89,"author":{"gitId":"-"},"content":" * Creates an account request."},{"lineNumber":90,"author":{"gitId":"-"},"content":" *"},{"lineNumber":91,"author":{"gitId":"-"},"content":" * @return newly created account request."},{"lineNumber":92,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the account request details are invalid."},{"lineNumber":93,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the account request already exists."},{"lineNumber":94,"author":{"gitId":"-"},"content":" */"},{"lineNumber":95,"author":{"gitId":"-"},"content":" public AccountRequest createAccountRequest(String name, String email, String institute, AccountRequestStatus status,"},{"lineNumber":96,"author":{"gitId":"-"},"content":" String comments) throws InvalidParametersException {"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" return accountRequestLogic.createAccountRequest(name, email, institute, status, comments);"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":102,"author":{"gitId":"-"},"content":" * Gets the account request with the given {@code id}."},{"lineNumber":103,"author":{"gitId":"-"},"content":" *"},{"lineNumber":104,"author":{"gitId":"-"},"content":" * @return account request with the given {@code id}."},{"lineNumber":105,"author":{"gitId":"-"},"content":" */"},{"lineNumber":106,"author":{"gitId":"-"},"content":" public AccountRequest getAccountRequest(UUID id) {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" return accountRequestLogic.getAccountRequest(id);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" * Gets the account request with the given {@code id}."},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" * @return account request with the given {@code id}."},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" public AccountRequest getAccountRequestWithTransaction(UUID id) {"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" return accountRequestLogic.getAccountRequestWithTransaction(id);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" }"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":120,"author":{"gitId":"-"},"content":" * Creates a or gets an account request."},{"lineNumber":121,"author":{"gitId":"-"},"content":" *"},{"lineNumber":122,"author":{"gitId":"-"},"content":" * @return newly created account request."},{"lineNumber":123,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the account request details are invalid."},{"lineNumber":124,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the account request already exists."},{"lineNumber":125,"author":{"gitId":"-"},"content":" */"},{"lineNumber":126,"author":{"gitId":"-"},"content":" public AccountRequest createAccountRequestWithTransaction(String name, String email, String institute,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" AccountRequestStatus status, String comments) throws InvalidParametersException {"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" return accountRequestLogic.createOrGetAccountRequestWithTransaction(name, email, institute, status, comments);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" }"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" * Gets the account request with the associated {@code regkey}."},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":" * @return account request with the associated {@code regkey}."},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":" public AccountRequest getAccountRequestByRegistrationKey(String regkey) {"},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":" return accountRequestLogic.getAccountRequestByRegistrationKey(regkey);"},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":142,"author":{"gitId":"-"},"content":" * Updates the given account request."},{"lineNumber":143,"author":{"gitId":"-"},"content":" *"},{"lineNumber":144,"author":{"gitId":"-"},"content":" * @return the updated account request."},{"lineNumber":145,"author":{"gitId":"-"},"content":" */"},{"lineNumber":146,"author":{"gitId":"-"},"content":" public AccountRequest updateAccountRequest(AccountRequest accountRequest)"},{"lineNumber":147,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" return accountRequestLogic.updateAccountRequest(accountRequest);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" }"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":152,"author":{"gitId":"domoberzin"},"content":" * Updates the given account request."},{"lineNumber":153,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":154,"author":{"gitId":"domoberzin"},"content":" * @return the updated account request."},{"lineNumber":155,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":156,"author":{"gitId":"domoberzin"},"content":" public AccountRequest updateAccountRequestWithTransaction(AccountRequest accountRequest)"},{"lineNumber":157,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":158,"author":{"gitId":"domoberzin"},"content":" return accountRequestLogic.updateAccountRequestWithTransaction(accountRequest);"},{"lineNumber":159,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":160,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":162,"author":{"gitId":"dishenggg"},"content":" * Creates/Resets the account request with the given id"},{"lineNumber":163,"author":{"gitId":"-"},"content":" * such that it is not registered."},{"lineNumber":164,"author":{"gitId":"-"},"content":" *"},{"lineNumber":165,"author":{"gitId":"-"},"content":" * @return account request that is unregistered with the"},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":" * id."},{"lineNumber":167,"author":{"gitId":"-"},"content":" */"},{"lineNumber":168,"author":{"gitId":"dishenggg"},"content":" public AccountRequest resetAccountRequest(UUID id)"},{"lineNumber":169,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, InvalidParametersException {"},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" return accountRequestLogic.resetAccountRequest(id);"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":" * Deletes account request by id."},{"lineNumber":175,"author":{"gitId":"-"},"content":" *"},{"lineNumber":176,"author":{"gitId":"-"},"content":" * \u003cul\u003e"},{"lineNumber":177,"author":{"gitId":"-"},"content":" * \u003cli\u003eFails silently if no such account request.\u003c/li\u003e"},{"lineNumber":178,"author":{"gitId":"-"},"content":" * \u003c/ul\u003e"},{"lineNumber":179,"author":{"gitId":"-"},"content":" *"},{"lineNumber":180,"author":{"gitId":"-"},"content":" * \u003cp\u003ePreconditions:\u003c/p\u003e"},{"lineNumber":181,"author":{"gitId":"-"},"content":" * All parameters are non-null."},{"lineNumber":182,"author":{"gitId":"-"},"content":" */"},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":" public void deleteAccountRequest(UUID id) {"},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":" accountRequestLogic.deleteAccountRequest(id);"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":188,"author":{"gitId":"-"},"content":" * Gets all pending account requests."},{"lineNumber":189,"author":{"gitId":"-"},"content":" */"},{"lineNumber":190,"author":{"gitId":"-"},"content":" public List\u003cAccountRequest\u003e getPendingAccountRequests() {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" return accountRequestLogic.getPendingAccountRequests();"},{"lineNumber":192,"author":{"gitId":"-"},"content":" }"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" * Gets all pending account requests."},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccountRequest\u003e getAllAccountRequests() {"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" return accountRequestLogic.getAllAccountRequests();"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":200,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":201,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":202,"author":{"gitId":"domoberzin"},"content":" * Get a list of account requests associated with email provided."},{"lineNumber":203,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":204,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccountRequest\u003e getApprovedAccountRequestsForEmailWithTransaction(String email) {"},{"lineNumber":205,"author":{"gitId":"domoberzin"},"content":" return accountRequestLogic.getApprovedAccountRequestsForEmailWithTransaction(email);"},{"lineNumber":206,"author":{"gitId":"-"},"content":" }"},{"lineNumber":207,"author":{"gitId":"-"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":209,"author":{"gitId":"-"},"content":" * Gets an account."},{"lineNumber":210,"author":{"gitId":"-"},"content":" */"},{"lineNumber":211,"author":{"gitId":"-"},"content":" public Account getAccount(UUID id) {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" return accountsLogic.getAccount(id);"},{"lineNumber":213,"author":{"gitId":"-"},"content":" }"},{"lineNumber":214,"author":{"gitId":"-"},"content":""},{"lineNumber":215,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":216,"author":{"gitId":"-"},"content":" * Gets an account by googleId."},{"lineNumber":217,"author":{"gitId":"-"},"content":" */"},{"lineNumber":218,"author":{"gitId":"-"},"content":" public Account getAccountForGoogleId(String googleId) {"},{"lineNumber":219,"author":{"gitId":"-"},"content":" return accountsLogic.getAccountForGoogleId(googleId);"},{"lineNumber":220,"author":{"gitId":"-"},"content":" }"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":223,"author":{"gitId":"-"},"content":" * Get a list of accounts associated with email provided."},{"lineNumber":224,"author":{"gitId":"-"},"content":" */"},{"lineNumber":225,"author":{"gitId":"-"},"content":" public List\u003cAccount\u003e getAccountsForEmail(String email) {"},{"lineNumber":226,"author":{"gitId":"-"},"content":" return accountsLogic.getAccountsForEmail(email);"},{"lineNumber":227,"author":{"gitId":"-"},"content":" }"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":230,"author":{"gitId":"domoberzin"},"content":" * Get a list of accounts associated with email provided."},{"lineNumber":231,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":232,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccount\u003e getAccountsForEmailWithTransaction(String email) {"},{"lineNumber":233,"author":{"gitId":"domoberzin"},"content":" return accountsLogic.getAccountsForEmailWithTransaction(email);"},{"lineNumber":234,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":235,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":236,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":237,"author":{"gitId":"-"},"content":" * Creates an account."},{"lineNumber":238,"author":{"gitId":"-"},"content":" *"},{"lineNumber":239,"author":{"gitId":"-"},"content":" * @return the created account"},{"lineNumber":240,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the account is not valid"},{"lineNumber":241,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the account already exists in the database."},{"lineNumber":242,"author":{"gitId":"-"},"content":" */"},{"lineNumber":243,"author":{"gitId":"-"},"content":" public Account createAccount(Account account)"},{"lineNumber":244,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" return accountsLogic.createAccount(account);"},{"lineNumber":246,"author":{"gitId":"-"},"content":" }"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":249,"author":{"gitId":"domoberzin"},"content":" * Creates an account."},{"lineNumber":250,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":251,"author":{"gitId":"domoberzin"},"content":" * @return the created account"},{"lineNumber":252,"author":{"gitId":"domoberzin"},"content":" * @throws InvalidParametersException if the account is not valid"},{"lineNumber":253,"author":{"gitId":"domoberzin"},"content":" * @throws EntityAlreadyExistsException if the account already exists in the database."},{"lineNumber":254,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":255,"author":{"gitId":"domoberzin"},"content":" public Account createAccountWithTransaction(Account account)"},{"lineNumber":256,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":257,"author":{"gitId":"domoberzin"},"content":" return accountsLogic.createAccountWithTransaction(account);"},{"lineNumber":258,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":259,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":260,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":261,"author":{"gitId":"-"},"content":" * Deletes account by googleId."},{"lineNumber":262,"author":{"gitId":"-"},"content":" *"},{"lineNumber":263,"author":{"gitId":"-"},"content":" * \u003cul\u003e"},{"lineNumber":264,"author":{"gitId":"-"},"content":" * \u003cli\u003eFails silently if no such account.\u003c/li\u003e"},{"lineNumber":265,"author":{"gitId":"-"},"content":" * \u003c/ul\u003e"},{"lineNumber":266,"author":{"gitId":"-"},"content":" *"},{"lineNumber":267,"author":{"gitId":"-"},"content":" * \u003cp\u003ePreconditions:\u003c/p\u003e"},{"lineNumber":268,"author":{"gitId":"-"},"content":" * All parameters are non-null."},{"lineNumber":269,"author":{"gitId":"-"},"content":" */"},{"lineNumber":270,"author":{"gitId":"-"},"content":" public void deleteAccount(String googleId) {"},{"lineNumber":271,"author":{"gitId":"-"},"content":" accountsLogic.deleteAccount(googleId);"},{"lineNumber":272,"author":{"gitId":"-"},"content":" }"},{"lineNumber":273,"author":{"gitId":"-"},"content":""},{"lineNumber":274,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":275,"author":{"gitId":"-"},"content":" * Deletes account and all users by googleId."},{"lineNumber":276,"author":{"gitId":"-"},"content":" *"},{"lineNumber":277,"author":{"gitId":"-"},"content":" * \u003cul\u003e"},{"lineNumber":278,"author":{"gitId":"-"},"content":" * \u003cli\u003eFails silently if no such account.\u003c/li\u003e"},{"lineNumber":279,"author":{"gitId":"-"},"content":" * \u003c/ul\u003e"},{"lineNumber":280,"author":{"gitId":"-"},"content":" *"},{"lineNumber":281,"author":{"gitId":"-"},"content":" * \u003cp\u003ePreconditions:\u003c/p\u003e"},{"lineNumber":282,"author":{"gitId":"-"},"content":" * All parameters are non-null."},{"lineNumber":283,"author":{"gitId":"-"},"content":" */"},{"lineNumber":284,"author":{"gitId":"-"},"content":" public void deleteAccountCascade(String googleId) {"},{"lineNumber":285,"author":{"gitId":"-"},"content":" accountsLogic.deleteAccountCascade(googleId);"},{"lineNumber":286,"author":{"gitId":"-"},"content":" }"},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":289,"author":{"gitId":"-"},"content":" * Gets all students associated with a googleId."},{"lineNumber":290,"author":{"gitId":"-"},"content":" */"},{"lineNumber":291,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsByGoogleId(String googleId) {"},{"lineNumber":292,"author":{"gitId":"-"},"content":" return usersLogic.getStudentsByGoogleId(googleId);"},{"lineNumber":293,"author":{"gitId":"-"},"content":" }"},{"lineNumber":294,"author":{"gitId":"-"},"content":""},{"lineNumber":295,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":296,"author":{"gitId":"-"},"content":" * Gets a course by course id."},{"lineNumber":297,"author":{"gitId":"-"},"content":" * @param courseId courseId of the course."},{"lineNumber":298,"author":{"gitId":"-"},"content":" * @return the specified course."},{"lineNumber":299,"author":{"gitId":"-"},"content":" */"},{"lineNumber":300,"author":{"gitId":"-"},"content":" public Course getCourse(String courseId) {"},{"lineNumber":301,"author":{"gitId":"-"},"content":" return coursesLogic.getCourse(courseId);"},{"lineNumber":302,"author":{"gitId":"-"},"content":" }"},{"lineNumber":303,"author":{"gitId":"-"},"content":""},{"lineNumber":304,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":305,"author":{"gitId":"domoberzin"},"content":" * Gets a section from a course by section name."},{"lineNumber":306,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":307,"author":{"gitId":"domoberzin"},"content":" public Section getSection(String courseId, String section) {"},{"lineNumber":308,"author":{"gitId":"domoberzin"},"content":" return usersLogic.getSection(courseId, section);"},{"lineNumber":309,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":310,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":311,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":312,"author":{"gitId":"-"},"content":" * Gets courses associated with student."},{"lineNumber":313,"author":{"gitId":"-"},"content":" * Preconditions: \u003cbr\u003e"},{"lineNumber":314,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":315,"author":{"gitId":"-"},"content":" */"},{"lineNumber":316,"author":{"gitId":"-"},"content":" public List\u003cCourse\u003e getCoursesForStudentAccount(String googleId) {"},{"lineNumber":317,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":318,"author":{"gitId":"-"},"content":""},{"lineNumber":319,"author":{"gitId":"-"},"content":" return coursesLogic.getCoursesForStudentAccount(googleId);"},{"lineNumber":320,"author":{"gitId":"-"},"content":" }"},{"lineNumber":321,"author":{"gitId":"-"},"content":""},{"lineNumber":322,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":323,"author":{"gitId":"-"},"content":" * Gets courses associated with instructors."},{"lineNumber":324,"author":{"gitId":"-"},"content":" * Preconditions: \u003cbr\u003e"},{"lineNumber":325,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":326,"author":{"gitId":"-"},"content":" *"},{"lineNumber":327,"author":{"gitId":"-"},"content":" * @return Courses the given instructors is in except for courses in Recycle Bin."},{"lineNumber":328,"author":{"gitId":"-"},"content":" */"},{"lineNumber":329,"author":{"gitId":"-"},"content":" public List\u003cCourse\u003e getCoursesForInstructors(List\u003cInstructor\u003e instructorsList) {"},{"lineNumber":330,"author":{"gitId":"-"},"content":" assert instructorsList !\u003d null;"},{"lineNumber":331,"author":{"gitId":"-"},"content":""},{"lineNumber":332,"author":{"gitId":"-"},"content":" return coursesLogic.getCoursesForInstructors(instructorsList);"},{"lineNumber":333,"author":{"gitId":"-"},"content":" }"},{"lineNumber":334,"author":{"gitId":"-"},"content":""},{"lineNumber":335,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":336,"author":{"gitId":"-"},"content":" * Gets courses associated with instructors that are soft deleted."},{"lineNumber":337,"author":{"gitId":"-"},"content":" * Preconditions: \u003cbr\u003e"},{"lineNumber":338,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":339,"author":{"gitId":"-"},"content":" *"},{"lineNumber":340,"author":{"gitId":"-"},"content":" * @return Courses in Recycle Bin that the given instructors is in."},{"lineNumber":341,"author":{"gitId":"-"},"content":" */"},{"lineNumber":342,"author":{"gitId":"-"},"content":" public List\u003cCourse\u003e getSoftDeletedCoursesForInstructors(List\u003cInstructor\u003e instructorsList) {"},{"lineNumber":343,"author":{"gitId":"-"},"content":" assert instructorsList !\u003d null;"},{"lineNumber":344,"author":{"gitId":"-"},"content":""},{"lineNumber":345,"author":{"gitId":"-"},"content":" return coursesLogic.getSoftDeletedCoursesForInstructors(instructorsList);"},{"lineNumber":346,"author":{"gitId":"-"},"content":" }"},{"lineNumber":347,"author":{"gitId":"-"},"content":""},{"lineNumber":348,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":349,"author":{"gitId":"yuanxi1"},"content":" * Gets the institute of the course."},{"lineNumber":350,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":351,"author":{"gitId":"yuanxi1"},"content":" public String getCourseInstitute(String courseId) {"},{"lineNumber":352,"author":{"gitId":"yuanxi1"},"content":" return coursesLogic.getCourseInstitute(courseId);"},{"lineNumber":353,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":354,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":355,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":356,"author":{"gitId":"-"},"content":" * Creates a course."},{"lineNumber":357,"author":{"gitId":"-"},"content":" * @param course the course to create."},{"lineNumber":358,"author":{"gitId":"-"},"content":" * @return the created course."},{"lineNumber":359,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the course is not valid."},{"lineNumber":360,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the course already exists."},{"lineNumber":361,"author":{"gitId":"-"},"content":" */"},{"lineNumber":362,"author":{"gitId":"-"},"content":" public Course createCourse(Course course) throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":363,"author":{"gitId":"-"},"content":" return coursesLogic.createCourse(course);"},{"lineNumber":364,"author":{"gitId":"-"},"content":" }"},{"lineNumber":365,"author":{"gitId":"-"},"content":""},{"lineNumber":366,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":367,"author":{"gitId":"-"},"content":" * Deletes a course by course id."},{"lineNumber":368,"author":{"gitId":"-"},"content":" * @param courseId of course."},{"lineNumber":369,"author":{"gitId":"-"},"content":" */"},{"lineNumber":370,"author":{"gitId":"-"},"content":" public void deleteCourseCascade(String courseId) {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" coursesLogic.deleteCourseCascade(courseId);"},{"lineNumber":372,"author":{"gitId":"-"},"content":" }"},{"lineNumber":373,"author":{"gitId":"-"},"content":""},{"lineNumber":374,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":375,"author":{"gitId":"domoberzin"},"content":" * Updates a student by {@link Student}."},{"lineNumber":376,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":377,"author":{"gitId":"domoberzin"},"content":" * \u003cp\u003eIf email changed, update by recreating the student and cascade update all responses"},{"lineNumber":378,"author":{"gitId":"marquestye"},"content":" * and comments the student gives/receives."},{"lineNumber":379,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":380,"author":{"gitId":"domoberzin"},"content":" * \u003cp\u003eIf team changed, cascade delete all responses the student gives/receives within that team."},{"lineNumber":381,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":382,"author":{"gitId":"domoberzin"},"content":" * \u003cp\u003eIf section changed, cascade update all responses the student gives/receives."},{"lineNumber":383,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":384,"author":{"gitId":"domoberzin"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":385,"author":{"gitId":"marquestye"},"content":" * * Student parameter is non-null."},{"lineNumber":386,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":387,"author":{"gitId":"domoberzin"},"content":" * @return updated student"},{"lineNumber":388,"author":{"gitId":"domoberzin"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":389,"author":{"gitId":"domoberzin"},"content":" * @throws EntityDoesNotExistException if the student cannot be found"},{"lineNumber":390,"author":{"gitId":"domoberzin"},"content":" * @throws EntityAlreadyExistsException if the student cannot be updated"},{"lineNumber":391,"author":{"gitId":"domoberzin"},"content":" * by recreation because of an existent student"},{"lineNumber":392,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":393,"author":{"gitId":"domoberzin"},"content":" public Student updateStudentCascade(Student student)"},{"lineNumber":394,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException, EntityAlreadyExistsException {"},{"lineNumber":395,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":396,"author":{"gitId":"domoberzin"},"content":" assert student !\u003d null;"},{"lineNumber":397,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":398,"author":{"gitId":"domoberzin"},"content":" return usersLogic.updateStudentCascade(student);"},{"lineNumber":399,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":400,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":401,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":402,"author":{"gitId":"-"},"content":" * Moves a course to Recycle Bin by its given corresponding ID."},{"lineNumber":403,"author":{"gitId":"-"},"content":" * @return the deletion timestamp assigned to the course."},{"lineNumber":404,"author":{"gitId":"-"},"content":" */"},{"lineNumber":405,"author":{"gitId":"-"},"content":" public Course moveCourseToRecycleBin(String courseId) throws EntityDoesNotExistException {"},{"lineNumber":406,"author":{"gitId":"-"},"content":" return coursesLogic.moveCourseToRecycleBin(courseId);"},{"lineNumber":407,"author":{"gitId":"-"},"content":" }"},{"lineNumber":408,"author":{"gitId":"-"},"content":""},{"lineNumber":409,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":410,"author":{"gitId":"-"},"content":" * Restores a course and all data related to the course from Recycle Bin by"},{"lineNumber":411,"author":{"gitId":"-"},"content":" * its given corresponding ID."},{"lineNumber":412,"author":{"gitId":"-"},"content":" */"},{"lineNumber":413,"author":{"gitId":"-"},"content":" public void restoreCourseFromRecycleBin(String courseId) throws EntityDoesNotExistException {"},{"lineNumber":414,"author":{"gitId":"-"},"content":" coursesLogic.restoreCourseFromRecycleBin(courseId);"},{"lineNumber":415,"author":{"gitId":"-"},"content":" }"},{"lineNumber":416,"author":{"gitId":"-"},"content":""},{"lineNumber":417,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":418,"author":{"gitId":"-"},"content":" * Updates a course."},{"lineNumber":419,"author":{"gitId":"-"},"content":" *"},{"lineNumber":420,"author":{"gitId":"-"},"content":" * @return updated course"},{"lineNumber":421,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":422,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the course cannot be found"},{"lineNumber":423,"author":{"gitId":"-"},"content":" */"},{"lineNumber":424,"author":{"gitId":"-"},"content":" public Course updateCourse(String courseId, String name, String timezone)"},{"lineNumber":425,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":426,"author":{"gitId":"-"},"content":" return coursesLogic.updateCourse(courseId, name, timezone);"},{"lineNumber":427,"author":{"gitId":"-"},"content":" }"},{"lineNumber":428,"author":{"gitId":"-"},"content":""},{"lineNumber":429,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":430,"author":{"gitId":"-"},"content":" * Gets a list of section names for the given {@code courseId}."},{"lineNumber":431,"author":{"gitId":"-"},"content":" */"},{"lineNumber":432,"author":{"gitId":"-"},"content":" public List\u003cString\u003e getSectionNamesForCourse(String courseId)"},{"lineNumber":433,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":434,"author":{"gitId":"-"},"content":" return coursesLogic.getSectionNamesForCourse(courseId);"},{"lineNumber":435,"author":{"gitId":"-"},"content":" }"},{"lineNumber":436,"author":{"gitId":"-"},"content":""},{"lineNumber":437,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":438,"author":{"gitId":"-"},"content":" * Get section by {@code courseId} and {@code teamName}."},{"lineNumber":439,"author":{"gitId":"-"},"content":" */"},{"lineNumber":440,"author":{"gitId":"-"},"content":" public Section getSectionByCourseIdAndTeam(String courseId, String teamName) {"},{"lineNumber":441,"author":{"gitId":"-"},"content":" return coursesLogic.getSectionByCourseIdAndTeam(courseId, teamName);"},{"lineNumber":442,"author":{"gitId":"-"},"content":" }"},{"lineNumber":443,"author":{"gitId":"-"},"content":""},{"lineNumber":444,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":445,"author":{"gitId":"-"},"content":" * Creates a deadline extension."},{"lineNumber":446,"author":{"gitId":"-"},"content":" *"},{"lineNumber":447,"author":{"gitId":"-"},"content":" * @return created deadline extension"},{"lineNumber":448,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the deadline extension is not valid"},{"lineNumber":449,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the deadline extension already exist"},{"lineNumber":450,"author":{"gitId":"-"},"content":" */"},{"lineNumber":451,"author":{"gitId":"-"},"content":" public DeadlineExtension createDeadlineExtension(DeadlineExtension deadlineExtension)"},{"lineNumber":452,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":453,"author":{"gitId":"-"},"content":" return deadlineExtensionsLogic.createDeadlineExtension(deadlineExtension);"},{"lineNumber":454,"author":{"gitId":"-"},"content":" }"},{"lineNumber":455,"author":{"gitId":"-"},"content":""},{"lineNumber":456,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":457,"author":{"gitId":"-"},"content":" * Updates a deadline extension."},{"lineNumber":458,"author":{"gitId":"-"},"content":" *"},{"lineNumber":459,"author":{"gitId":"-"},"content":" * @return updated deadline extension"},{"lineNumber":460,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the deadline extension does not exist"},{"lineNumber":461,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the deadline extension is not valid"},{"lineNumber":462,"author":{"gitId":"-"},"content":" *"},{"lineNumber":463,"author":{"gitId":"-"},"content":" */"},{"lineNumber":464,"author":{"gitId":"-"},"content":" public DeadlineExtension updateDeadlineExtension(DeadlineExtension de)"},{"lineNumber":465,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":466,"author":{"gitId":"-"},"content":" return deadlineExtensionsLogic.updateDeadlineExtension(de);"},{"lineNumber":467,"author":{"gitId":"-"},"content":" }"},{"lineNumber":468,"author":{"gitId":"-"},"content":""},{"lineNumber":469,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":470,"author":{"gitId":"-"},"content":" * Deletes a deadline extension."},{"lineNumber":471,"author":{"gitId":"-"},"content":" */"},{"lineNumber":472,"author":{"gitId":"-"},"content":" public void deleteDeadlineExtension(DeadlineExtension de) {"},{"lineNumber":473,"author":{"gitId":"-"},"content":" deadlineExtensionsLogic.deleteDeadlineExtension(de);"},{"lineNumber":474,"author":{"gitId":"-"},"content":" }"},{"lineNumber":475,"author":{"gitId":"-"},"content":""},{"lineNumber":476,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":477,"author":{"gitId":"-"},"content":" * Fetch the deadline extension for a given user and session feedback."},{"lineNumber":478,"author":{"gitId":"-"},"content":" *"},{"lineNumber":479,"author":{"gitId":"-"},"content":" * @return deadline extension instant if exists, else the default end time instant"},{"lineNumber":480,"author":{"gitId":"-"},"content":" * for the session feedback."},{"lineNumber":481,"author":{"gitId":"-"},"content":" */"},{"lineNumber":482,"author":{"gitId":"-"},"content":" public Instant getDeadlineForUser(FeedbackSession session, User user) {"},{"lineNumber":483,"author":{"gitId":"-"},"content":" return deadlineExtensionsLogic.getDeadlineForUser(session, user);"},{"lineNumber":484,"author":{"gitId":"-"},"content":" }"},{"lineNumber":485,"author":{"gitId":"-"},"content":""},{"lineNumber":486,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":487,"author":{"gitId":"-"},"content":" * Fetch the deadline extension for a given user and session feedback."},{"lineNumber":488,"author":{"gitId":"-"},"content":" *"},{"lineNumber":489,"author":{"gitId":"-"},"content":" * @return deadline extension instant if exists, else return null since no deadline extensions."},{"lineNumber":490,"author":{"gitId":"-"},"content":" */"},{"lineNumber":491,"author":{"gitId":"-"},"content":" public Instant getExtendedDeadlineForUser(FeedbackSession session, User user) {"},{"lineNumber":492,"author":{"gitId":"-"},"content":" return deadlineExtensionsLogic.getExtendedDeadlineForUser(session, user);"},{"lineNumber":493,"author":{"gitId":"-"},"content":" }"},{"lineNumber":494,"author":{"gitId":"-"},"content":""},{"lineNumber":495,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":496,"author":{"gitId":"-"},"content":" * Gets a list of deadline extensions with endTime coming up soon"},{"lineNumber":497,"author":{"gitId":"-"},"content":" * and possibly need a closing email to be sent."},{"lineNumber":498,"author":{"gitId":"-"},"content":" */"},{"lineNumber":499,"author":{"gitId":"-"},"content":" public List\u003cDeadlineExtension\u003e getDeadlineExtensionsPossiblyNeedingClosingEmail() {"},{"lineNumber":500,"author":{"gitId":"-"},"content":" return deadlineExtensionsLogic.getDeadlineExtensionsPossiblyNeedingClosingEmail();"},{"lineNumber":501,"author":{"gitId":"-"},"content":" }"},{"lineNumber":502,"author":{"gitId":"-"},"content":""},{"lineNumber":503,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":504,"author":{"gitId":"-"},"content":" * Gets a feedback session."},{"lineNumber":505,"author":{"gitId":"-"},"content":" *"},{"lineNumber":506,"author":{"gitId":"-"},"content":" * @return null if not found."},{"lineNumber":507,"author":{"gitId":"-"},"content":" */"},{"lineNumber":508,"author":{"gitId":"-"},"content":" public FeedbackSession getFeedbackSession(UUID id) {"},{"lineNumber":509,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSession(id);"},{"lineNumber":510,"author":{"gitId":"-"},"content":" }"},{"lineNumber":511,"author":{"gitId":"-"},"content":""},{"lineNumber":512,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":513,"author":{"gitId":"-"},"content":" * Gets a feedback session for {@code feedbackSessionName} and {@code courseId}."},{"lineNumber":514,"author":{"gitId":"-"},"content":" *"},{"lineNumber":515,"author":{"gitId":"-"},"content":" * @return null if not found."},{"lineNumber":516,"author":{"gitId":"-"},"content":" */"},{"lineNumber":517,"author":{"gitId":"-"},"content":" public FeedbackSession getFeedbackSession(String feedbackSessionName, String courseId) {"},{"lineNumber":518,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":519,"author":{"gitId":"-"},"content":" }"},{"lineNumber":520,"author":{"gitId":"-"},"content":""},{"lineNumber":521,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":522,"author":{"gitId":"dishenggg"},"content":" * Gets a feedback session reference."},{"lineNumber":523,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":524,"author":{"gitId":"dishenggg"},"content":" * @return Returns a proxy for the feedback session."},{"lineNumber":525,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":526,"author":{"gitId":"dishenggg"},"content":" public FeedbackSession getFeedbackSessionReference(UUID id) {"},{"lineNumber":527,"author":{"gitId":"dishenggg"},"content":" return feedbackSessionsLogic.getFeedbackSessionReference(id);"},{"lineNumber":528,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":529,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":530,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":531,"author":{"gitId":"-"},"content":" * Gets a feedback session from the recycle bin."},{"lineNumber":532,"author":{"gitId":"-"},"content":" *"},{"lineNumber":533,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":534,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":535,"author":{"gitId":"-"},"content":" *"},{"lineNumber":536,"author":{"gitId":"-"},"content":" * @return null if not found."},{"lineNumber":537,"author":{"gitId":"-"},"content":" */"},{"lineNumber":538,"author":{"gitId":"-"},"content":" public FeedbackSession getFeedbackSessionFromRecycleBin(String feedbackSessionName, String courseId) {"},{"lineNumber":539,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":540,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":541,"author":{"gitId":"-"},"content":""},{"lineNumber":542,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSessionFromRecycleBin(feedbackSessionName, courseId);"},{"lineNumber":543,"author":{"gitId":"-"},"content":" }"},{"lineNumber":544,"author":{"gitId":"-"},"content":""},{"lineNumber":545,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":546,"author":{"gitId":"-"},"content":" * Returns a {@code List} of feedback sessions in the Recycle Bin for the instructors."},{"lineNumber":547,"author":{"gitId":"-"},"content":" * \u003cbr\u003e"},{"lineNumber":548,"author":{"gitId":"-"},"content":" * Omits sessions if the corresponding courses are archived or in Recycle Bin"},{"lineNumber":549,"author":{"gitId":"-"},"content":" */"},{"lineNumber":550,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getSoftDeletedFeedbackSessionsForInstructors("},{"lineNumber":551,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorList) {"},{"lineNumber":552,"author":{"gitId":"-"},"content":" assert instructorList !\u003d null;"},{"lineNumber":553,"author":{"gitId":"-"},"content":""},{"lineNumber":554,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getSoftDeletedFeedbackSessionsForInstructors(instructorList);"},{"lineNumber":555,"author":{"gitId":"-"},"content":" }"},{"lineNumber":556,"author":{"gitId":"-"},"content":""},{"lineNumber":557,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":558,"author":{"gitId":"-"},"content":" * Gets a list of feedback sessions for instructors."},{"lineNumber":559,"author":{"gitId":"-"},"content":" */"},{"lineNumber":560,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsForInstructors("},{"lineNumber":561,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorList) {"},{"lineNumber":562,"author":{"gitId":"-"},"content":" assert instructorList !\u003d null;"},{"lineNumber":563,"author":{"gitId":"-"},"content":""},{"lineNumber":564,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSessionsForInstructors(instructorList);"},{"lineNumber":565,"author":{"gitId":"-"},"content":" }"},{"lineNumber":566,"author":{"gitId":"-"},"content":""},{"lineNumber":567,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":568,"author":{"gitId":"-"},"content":" * Gets all and only the feedback sessions ongoing within a range of time."},{"lineNumber":569,"author":{"gitId":"-"},"content":" */"},{"lineNumber":570,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getOngoingSessions(Instant rangeStart, Instant rangeEnd) {"},{"lineNumber":571,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getOngoingSessions(rangeStart, rangeEnd);"},{"lineNumber":572,"author":{"gitId":"-"},"content":" }"},{"lineNumber":573,"author":{"gitId":"-"},"content":""},{"lineNumber":574,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":575,"author":{"gitId":"-"},"content":" * Gets a set of giver identifiers that has at least one response under a feedback session."},{"lineNumber":576,"author":{"gitId":"-"},"content":" */"},{"lineNumber":577,"author":{"gitId":"-"},"content":" public Set\u003cString\u003e getGiverSetThatAnsweredFeedbackSession(String feedbackSessionName, String courseId) {"},{"lineNumber":578,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":579,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":580,"author":{"gitId":"-"},"content":""},{"lineNumber":581,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getGiverSetThatAnsweredFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":582,"author":{"gitId":"-"},"content":" }"},{"lineNumber":583,"author":{"gitId":"-"},"content":""},{"lineNumber":584,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":585,"author":{"gitId":"-"},"content":" * Updates a feedback session."},{"lineNumber":586,"author":{"gitId":"-"},"content":" *"},{"lineNumber":587,"author":{"gitId":"-"},"content":" * @return returns the updated feedback session."},{"lineNumber":588,"author":{"gitId":"-"},"content":" */"},{"lineNumber":589,"author":{"gitId":"-"},"content":" public FeedbackSession updateFeedbackSession(FeedbackSession feedbackSession)"},{"lineNumber":590,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":591,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.updateFeedbackSession(feedbackSession);"},{"lineNumber":592,"author":{"gitId":"-"},"content":" }"},{"lineNumber":593,"author":{"gitId":"-"},"content":""},{"lineNumber":594,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":595,"author":{"gitId":"-"},"content":" * Returns a list of sessions that require automated emails to be sent as they are published."},{"lineNumber":596,"author":{"gitId":"-"},"content":" */"},{"lineNumber":597,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsWhichNeedAutomatedPublishedEmailsToBeSent() {"},{"lineNumber":598,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSessionsWhichNeedAutomatedPublishedEmailsToBeSent();"},{"lineNumber":599,"author":{"gitId":"-"},"content":" }"},{"lineNumber":600,"author":{"gitId":"-"},"content":""},{"lineNumber":601,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":602,"author":{"gitId":"-"},"content":" * Creates a feedback session."},{"lineNumber":603,"author":{"gitId":"-"},"content":" *"},{"lineNumber":604,"author":{"gitId":"-"},"content":" * @return returns the created feedback session."},{"lineNumber":605,"author":{"gitId":"-"},"content":" */"},{"lineNumber":606,"author":{"gitId":"-"},"content":" public FeedbackSession createFeedbackSession(FeedbackSession feedbackSession)"},{"lineNumber":607,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":608,"author":{"gitId":"-"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":609,"author":{"gitId":"-"},"content":" assert feedbackSession.getCourse() !\u003d null \u0026\u0026 feedbackSession.getCourse().getId() !\u003d null;"},{"lineNumber":610,"author":{"gitId":"-"},"content":""},{"lineNumber":611,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.createFeedbackSession(feedbackSession);"},{"lineNumber":612,"author":{"gitId":"-"},"content":" }"},{"lineNumber":613,"author":{"gitId":"-"},"content":""},{"lineNumber":614,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":615,"author":{"gitId":"-"},"content":" * Gets all feedback sessions of a course, except those that are soft-deleted."},{"lineNumber":616,"author":{"gitId":"-"},"content":" */"},{"lineNumber":617,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsForCourse(String courseId) {"},{"lineNumber":618,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSessionsForCourse(courseId);"},{"lineNumber":619,"author":{"gitId":"-"},"content":" }"},{"lineNumber":620,"author":{"gitId":"-"},"content":""},{"lineNumber":621,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":622,"author":{"gitId":"-"},"content":" * Creates a new feedback question."},{"lineNumber":623,"author":{"gitId":"-"},"content":" *"},{"lineNumber":624,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":625,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":626,"author":{"gitId":"-"},"content":" *"},{"lineNumber":627,"author":{"gitId":"-"},"content":" * @return the created question"},{"lineNumber":628,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the question is invalid"},{"lineNumber":629,"author":{"gitId":"marquestye"},"content":" * @throws EntityAlreadyExistsException if the question already exists"},{"lineNumber":630,"author":{"gitId":"-"},"content":" */"},{"lineNumber":631,"author":{"gitId":"marquestye"},"content":" public FeedbackQuestion createFeedbackQuestion(FeedbackQuestion feedbackQuestion)"},{"lineNumber":632,"author":{"gitId":"marquestye"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":633,"author":{"gitId":"-"},"content":" return feedbackQuestionsLogic.createFeedbackQuestion(feedbackQuestion);"},{"lineNumber":634,"author":{"gitId":"-"},"content":" }"},{"lineNumber":635,"author":{"gitId":"-"},"content":""},{"lineNumber":636,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":637,"author":{"gitId":"-"},"content":" * Publishes a feedback session."},{"lineNumber":638,"author":{"gitId":"-"},"content":" * @return the published feedback session"},{"lineNumber":639,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the feedback session cannot be found"},{"lineNumber":640,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if session is already published"},{"lineNumber":641,"author":{"gitId":"-"},"content":" */"},{"lineNumber":642,"author":{"gitId":"-"},"content":" public FeedbackSession publishFeedbackSession(String feedbackSessionName, String courseId)"},{"lineNumber":643,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, InvalidParametersException {"},{"lineNumber":644,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":645,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":646,"author":{"gitId":"-"},"content":""},{"lineNumber":647,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.publishFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":648,"author":{"gitId":"-"},"content":" }"},{"lineNumber":649,"author":{"gitId":"-"},"content":""},{"lineNumber":650,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":651,"author":{"gitId":"-"},"content":" * Checks whether a student has attempted a feedback session."},{"lineNumber":652,"author":{"gitId":"-"},"content":" *"},{"lineNumber":653,"author":{"gitId":"-"},"content":" * \u003cp\u003eIf there is no question for students, the feedback session is considered as attempted.\u003c/p\u003e"},{"lineNumber":654,"author":{"gitId":"-"},"content":" */"},{"lineNumber":655,"author":{"gitId":"-"},"content":" public boolean isFeedbackSessionAttemptedByStudent(FeedbackSession session, String userEmail, String userTeam) {"},{"lineNumber":656,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.isFeedbackSessionAttemptedByStudent(session, userEmail, userTeam);"},{"lineNumber":657,"author":{"gitId":"-"},"content":" }"},{"lineNumber":658,"author":{"gitId":"-"},"content":""},{"lineNumber":659,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":660,"author":{"gitId":"-"},"content":" * Checks whether an instructor has attempted a feedback session."},{"lineNumber":661,"author":{"gitId":"-"},"content":" *"},{"lineNumber":662,"author":{"gitId":"-"},"content":" * \u003cp\u003eIf there is no question for instructors, the feedback session is considered as attempted.\u003c/p\u003e"},{"lineNumber":663,"author":{"gitId":"-"},"content":" */"},{"lineNumber":664,"author":{"gitId":"-"},"content":" public boolean isFeedbackSessionAttemptedByInstructor(FeedbackSession session, String userEmail) {"},{"lineNumber":665,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.isFeedbackSessionAttemptedByInstructor(session, userEmail);"},{"lineNumber":666,"author":{"gitId":"-"},"content":" }"},{"lineNumber":667,"author":{"gitId":"-"},"content":""},{"lineNumber":668,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":669,"author":{"gitId":"-"},"content":" * Deletes a feedback session cascade to its associated questions, responses, deadline extensions and comments."},{"lineNumber":670,"author":{"gitId":"-"},"content":" *"},{"lineNumber":671,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":672,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":673,"author":{"gitId":"-"},"content":" */"},{"lineNumber":674,"author":{"gitId":"-"},"content":" public void deleteFeedbackSessionCascade(String feedbackSessionName, String courseId) {"},{"lineNumber":675,"author":{"gitId":"-"},"content":" feedbackSessionsLogic.deleteFeedbackSessionCascade(feedbackSessionName, courseId);"},{"lineNumber":676,"author":{"gitId":"-"},"content":" }"},{"lineNumber":677,"author":{"gitId":"-"},"content":""},{"lineNumber":678,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":679,"author":{"gitId":"-"},"content":" * Soft-deletes a specific session to Recycle Bin."},{"lineNumber":680,"author":{"gitId":"-"},"content":" */"},{"lineNumber":681,"author":{"gitId":"-"},"content":" public FeedbackSession moveFeedbackSessionToRecycleBin(String feedbackSessionName, String courseId)"},{"lineNumber":682,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":683,"author":{"gitId":"-"},"content":""},{"lineNumber":684,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":685,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":686,"author":{"gitId":"-"},"content":""},{"lineNumber":687,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.moveFeedbackSessionToRecycleBin(feedbackSessionName, courseId);"},{"lineNumber":688,"author":{"gitId":"-"},"content":" }"},{"lineNumber":689,"author":{"gitId":"-"},"content":""},{"lineNumber":690,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":691,"author":{"gitId":"-"},"content":" * Restores a specific session from Recycle Bin to feedback sessions table."},{"lineNumber":692,"author":{"gitId":"-"},"content":" */"},{"lineNumber":693,"author":{"gitId":"-"},"content":" public void restoreFeedbackSessionFromRecycleBin(String feedbackSessionName, String courseId)"},{"lineNumber":694,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":695,"author":{"gitId":"-"},"content":""},{"lineNumber":696,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":697,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":698,"author":{"gitId":"-"},"content":""},{"lineNumber":699,"author":{"gitId":"-"},"content":" feedbackSessionsLogic.restoreFeedbackSessionFromRecycleBin(feedbackSessionName, courseId);"},{"lineNumber":700,"author":{"gitId":"-"},"content":" }"},{"lineNumber":701,"author":{"gitId":"-"},"content":""},{"lineNumber":702,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":703,"author":{"gitId":"-"},"content":" * Unpublishes a feedback session."},{"lineNumber":704,"author":{"gitId":"-"},"content":" * @return the unpublished feedback session"},{"lineNumber":705,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the feedback session cannot be found"},{"lineNumber":706,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException"},{"lineNumber":707,"author":{"gitId":"-"},"content":" * if the feedback session is not ready to be unpublished."},{"lineNumber":708,"author":{"gitId":"-"},"content":" */"},{"lineNumber":709,"author":{"gitId":"-"},"content":" public FeedbackSession unpublishFeedbackSession(String feedbackSessionName, String courseId)"},{"lineNumber":710,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, InvalidParametersException {"},{"lineNumber":711,"author":{"gitId":"-"},"content":""},{"lineNumber":712,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":713,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":714,"author":{"gitId":"-"},"content":""},{"lineNumber":715,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.unpublishFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":716,"author":{"gitId":"-"},"content":" }"},{"lineNumber":717,"author":{"gitId":"-"},"content":""},{"lineNumber":718,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":719,"author":{"gitId":"-"},"content":" * After an update to feedback session\u0027s fields, may need to adjust the email status of the session."},{"lineNumber":720,"author":{"gitId":"-"},"content":" * @param session recently updated session."},{"lineNumber":721,"author":{"gitId":"-"},"content":" */"},{"lineNumber":722,"author":{"gitId":"-"},"content":" public void adjustFeedbackSessionEmailStatusAfterUpdate(FeedbackSession session) {"},{"lineNumber":723,"author":{"gitId":"-"},"content":" assert session !\u003d null;"},{"lineNumber":724,"author":{"gitId":"-"},"content":" feedbackSessionsLogic.adjustFeedbackSessionEmailStatusAfterUpdate(session);"},{"lineNumber":725,"author":{"gitId":"-"},"content":" }"},{"lineNumber":726,"author":{"gitId":"-"},"content":""},{"lineNumber":727,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":728,"author":{"gitId":"domoberzin"},"content":" * Gets the expected number of submissions for a feedback session."},{"lineNumber":729,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":730,"author":{"gitId":"domoberzin"},"content":" * \u003cbr\u003ePreconditions: \u003cbr\u003e"},{"lineNumber":731,"author":{"gitId":"domoberzin"},"content":" * * All parameters are non-null."},{"lineNumber":732,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":733,"author":{"gitId":"domoberzin"},"content":" public int getExpectedTotalSubmission(FeedbackSession fs) {"},{"lineNumber":734,"author":{"gitId":"domoberzin"},"content":" assert fs !\u003d null;"},{"lineNumber":735,"author":{"gitId":"domoberzin"},"content":" return feedbackSessionsLogic.getExpectedTotalSubmission(fs);"},{"lineNumber":736,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":737,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":738,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":739,"author":{"gitId":"domoberzin"},"content":" * Gets the actual number of submissions for a feedback session."},{"lineNumber":740,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":741,"author":{"gitId":"domoberzin"},"content":" * \u003cbr\u003ePreconditions: \u003cbr\u003e"},{"lineNumber":742,"author":{"gitId":"domoberzin"},"content":" * * All parameters are non-null."},{"lineNumber":743,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":744,"author":{"gitId":"domoberzin"},"content":" public int getActualTotalSubmission(FeedbackSession fs) {"},{"lineNumber":745,"author":{"gitId":"domoberzin"},"content":" assert fs !\u003d null;"},{"lineNumber":746,"author":{"gitId":"domoberzin"},"content":" return feedbackSessionsLogic.getActualTotalSubmission(fs);"},{"lineNumber":747,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":748,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":749,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":750,"author":{"gitId":"-"},"content":" * Get usage statistics within a time range."},{"lineNumber":751,"author":{"gitId":"-"},"content":" */"},{"lineNumber":752,"author":{"gitId":"-"},"content":" public List\u003cUsageStatistics\u003e getUsageStatisticsForTimeRange(Instant startTime, Instant endTime) {"},{"lineNumber":753,"author":{"gitId":"-"},"content":" return usageStatisticsLogic.getUsageStatisticsForTimeRange(startTime, endTime);"},{"lineNumber":754,"author":{"gitId":"-"},"content":" }"},{"lineNumber":755,"author":{"gitId":"-"},"content":""},{"lineNumber":756,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":757,"author":{"gitId":"-"},"content":" * Calculate usage statistics within a time range."},{"lineNumber":758,"author":{"gitId":"-"},"content":" */"},{"lineNumber":759,"author":{"gitId":"-"},"content":" public UsageStatistics calculateEntitiesStatisticsForTimeRange(Instant startTime, Instant endTime) {"},{"lineNumber":760,"author":{"gitId":"-"},"content":" return usageStatisticsLogic.calculateEntitiesStatisticsForTimeRange(startTime, endTime);"},{"lineNumber":761,"author":{"gitId":"-"},"content":" }"},{"lineNumber":762,"author":{"gitId":"-"},"content":""},{"lineNumber":763,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":764,"author":{"gitId":"-"},"content":" * Create usage statistics within a time range."},{"lineNumber":765,"author":{"gitId":"-"},"content":" */"},{"lineNumber":766,"author":{"gitId":"-"},"content":" public void createUsageStatistics(UsageStatistics attributes)"},{"lineNumber":767,"author":{"gitId":"-"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":768,"author":{"gitId":"-"},"content":" usageStatisticsLogic.createUsageStatistics(attributes);"},{"lineNumber":769,"author":{"gitId":"-"},"content":" }"},{"lineNumber":770,"author":{"gitId":"-"},"content":""},{"lineNumber":771,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":772,"author":{"gitId":"-"},"content":" * Creates a notification."},{"lineNumber":773,"author":{"gitId":"-"},"content":" *"},{"lineNumber":774,"author":{"gitId":"-"},"content":" * \u003cp\u003ePreconditions:\u003c/p\u003e"},{"lineNumber":775,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":776,"author":{"gitId":"-"},"content":" *"},{"lineNumber":777,"author":{"gitId":"-"},"content":" * @return created notification"},{"lineNumber":778,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the notification is not valid"},{"lineNumber":779,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the notification exists in the database"},{"lineNumber":780,"author":{"gitId":"-"},"content":" */"},{"lineNumber":781,"author":{"gitId":"-"},"content":" public Notification createNotification(Notification notification) throws"},{"lineNumber":782,"author":{"gitId":"-"},"content":" InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":783,"author":{"gitId":"-"},"content":" return notificationsLogic.createNotification(notification);"},{"lineNumber":784,"author":{"gitId":"-"},"content":" }"},{"lineNumber":785,"author":{"gitId":"-"},"content":""},{"lineNumber":786,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":787,"author":{"gitId":"-"},"content":" * Gets a notification by ID."},{"lineNumber":788,"author":{"gitId":"-"},"content":" *"},{"lineNumber":789,"author":{"gitId":"-"},"content":" * \u003cp\u003ePreconditions:\u003c/p\u003e"},{"lineNumber":790,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":791,"author":{"gitId":"-"},"content":" *"},{"lineNumber":792,"author":{"gitId":"-"},"content":" * @return Null if no match found."},{"lineNumber":793,"author":{"gitId":"-"},"content":" */"},{"lineNumber":794,"author":{"gitId":"-"},"content":" public Notification getNotification(UUID notificationId) {"},{"lineNumber":795,"author":{"gitId":"-"},"content":" return notificationsLogic.getNotification(notificationId);"},{"lineNumber":796,"author":{"gitId":"-"},"content":" }"},{"lineNumber":797,"author":{"gitId":"-"},"content":""},{"lineNumber":798,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":799,"author":{"gitId":"-"},"content":" * Updates a notification."},{"lineNumber":800,"author":{"gitId":"-"},"content":" *"},{"lineNumber":801,"author":{"gitId":"-"},"content":" * \u003cp\u003ePreconditions:\u003c/p\u003e"},{"lineNumber":802,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":803,"author":{"gitId":"-"},"content":" * @return updated notification"},{"lineNumber":804,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the notification is not valid"},{"lineNumber":805,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the notification does not exist in the database"},{"lineNumber":806,"author":{"gitId":"-"},"content":" */"},{"lineNumber":807,"author":{"gitId":"-"},"content":" public Notification updateNotification(UUID notificationId, Instant startTime, Instant endTime,"},{"lineNumber":808,"author":{"gitId":"-"},"content":" NotificationStyle style, NotificationTargetUser targetUser, String title,"},{"lineNumber":809,"author":{"gitId":"-"},"content":" String message) throws"},{"lineNumber":810,"author":{"gitId":"-"},"content":" InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":811,"author":{"gitId":"-"},"content":" return notificationsLogic.updateNotification(notificationId, startTime, endTime, style, targetUser, title, message);"},{"lineNumber":812,"author":{"gitId":"-"},"content":" }"},{"lineNumber":813,"author":{"gitId":"-"},"content":""},{"lineNumber":814,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":815,"author":{"gitId":"-"},"content":" * Deletes notification by ID."},{"lineNumber":816,"author":{"gitId":"-"},"content":" *"},{"lineNumber":817,"author":{"gitId":"-"},"content":" * \u003cul\u003e"},{"lineNumber":818,"author":{"gitId":"-"},"content":" * \u003cli\u003eFails silently if no such notification.\u003c/li\u003e"},{"lineNumber":819,"author":{"gitId":"-"},"content":" * \u003c/ul\u003e"},{"lineNumber":820,"author":{"gitId":"-"},"content":" *"},{"lineNumber":821,"author":{"gitId":"-"},"content":" * \u003cp\u003ePreconditions:\u003c/p\u003e"},{"lineNumber":822,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":823,"author":{"gitId":"-"},"content":" */"},{"lineNumber":824,"author":{"gitId":"-"},"content":" public void deleteNotification(UUID notificationId) {"},{"lineNumber":825,"author":{"gitId":"-"},"content":" notificationsLogic.deleteNotification(notificationId);"},{"lineNumber":826,"author":{"gitId":"-"},"content":" }"},{"lineNumber":827,"author":{"gitId":"-"},"content":""},{"lineNumber":828,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":829,"author":{"gitId":"-"},"content":" * Get a list of IDs of the read notifications of the account."},{"lineNumber":830,"author":{"gitId":"-"},"content":" */"},{"lineNumber":831,"author":{"gitId":"-"},"content":" public List\u003cUUID\u003e getReadNotificationsId(String id) {"},{"lineNumber":832,"author":{"gitId":"-"},"content":" return accountsLogic.getReadNotificationsId(id);"},{"lineNumber":833,"author":{"gitId":"-"},"content":" }"},{"lineNumber":834,"author":{"gitId":"-"},"content":""},{"lineNumber":835,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":836,"author":{"gitId":"-"},"content":" * Updates user read status for notification with ID {@code notificationId} and expiry time {@code endTime}."},{"lineNumber":837,"author":{"gitId":"-"},"content":" *"},{"lineNumber":838,"author":{"gitId":"-"},"content":" * \u003cp\u003ePreconditions:\u003c/p\u003e"},{"lineNumber":839,"author":{"gitId":"-"},"content":" * * All parameters are non-null. {@code endTime} must be after current moment."},{"lineNumber":840,"author":{"gitId":"-"},"content":" */"},{"lineNumber":841,"author":{"gitId":"-"},"content":" public List\u003cUUID\u003e updateReadNotifications(String id, UUID notificationId, Instant endTime)"},{"lineNumber":842,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":843,"author":{"gitId":"-"},"content":" return accountsLogic.updateReadNotifications(id, notificationId, endTime);"},{"lineNumber":844,"author":{"gitId":"-"},"content":" }"},{"lineNumber":845,"author":{"gitId":"-"},"content":""},{"lineNumber":846,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":847,"author":{"gitId":"-"},"content":" * Gets instructor associated with {@code id}."},{"lineNumber":848,"author":{"gitId":"-"},"content":" *"},{"lineNumber":849,"author":{"gitId":"-"},"content":" * @param id Id of Instructor."},{"lineNumber":850,"author":{"gitId":"-"},"content":" * @return Returns Instructor if found else null."},{"lineNumber":851,"author":{"gitId":"-"},"content":" */"},{"lineNumber":852,"author":{"gitId":"-"},"content":" public Instructor getInstructor(UUID id) {"},{"lineNumber":853,"author":{"gitId":"-"},"content":" return usersLogic.getInstructor(id);"},{"lineNumber":854,"author":{"gitId":"-"},"content":" }"},{"lineNumber":855,"author":{"gitId":"-"},"content":""},{"lineNumber":856,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":857,"author":{"gitId":"-"},"content":" * Gets instructor associated with {@code courseId} and {@code email}."},{"lineNumber":858,"author":{"gitId":"-"},"content":" */"},{"lineNumber":859,"author":{"gitId":"-"},"content":" public Instructor getInstructorForEmail(String courseId, String email) {"},{"lineNumber":860,"author":{"gitId":"-"},"content":" return usersLogic.getInstructorForEmail(courseId, email);"},{"lineNumber":861,"author":{"gitId":"-"},"content":" }"},{"lineNumber":862,"author":{"gitId":"-"},"content":""},{"lineNumber":863,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":864,"author":{"gitId":"-"},"content":" * Gets an instructor by associated {@code regkey}."},{"lineNumber":865,"author":{"gitId":"-"},"content":" */"},{"lineNumber":866,"author":{"gitId":"-"},"content":" public Instructor getInstructorByRegistrationKey(String regKey) {"},{"lineNumber":867,"author":{"gitId":"-"},"content":" return usersLogic.getInstructorByRegistrationKey(regKey);"},{"lineNumber":868,"author":{"gitId":"-"},"content":" }"},{"lineNumber":869,"author":{"gitId":"-"},"content":""},{"lineNumber":870,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":871,"author":{"gitId":"-"},"content":" * Gets an instructor by associated {@code googleId}."},{"lineNumber":872,"author":{"gitId":"-"},"content":" */"},{"lineNumber":873,"author":{"gitId":"-"},"content":" public Instructor getInstructorByGoogleId(String courseId, String googleId) {"},{"lineNumber":874,"author":{"gitId":"-"},"content":" return usersLogic.getInstructorByGoogleId(courseId, googleId);"},{"lineNumber":875,"author":{"gitId":"-"},"content":" }"},{"lineNumber":876,"author":{"gitId":"-"},"content":""},{"lineNumber":877,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":878,"author":{"gitId":"-"},"content":" * Gets list of instructors by {@code googleId}."},{"lineNumber":879,"author":{"gitId":"-"},"content":" */"},{"lineNumber":880,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getInstructorsForGoogleId(String googleId) {"},{"lineNumber":881,"author":{"gitId":"-"},"content":" return usersLogic.getInstructorsForGoogleId(googleId);"},{"lineNumber":882,"author":{"gitId":"-"},"content":" }"},{"lineNumber":883,"author":{"gitId":"-"},"content":""},{"lineNumber":884,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":885,"author":{"gitId":"-"},"content":" * Gets instructors by associated {@code courseId}."},{"lineNumber":886,"author":{"gitId":"-"},"content":" */"},{"lineNumber":887,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getInstructorsByCourse(String courseId) {"},{"lineNumber":888,"author":{"gitId":"-"},"content":" return usersLogic.getInstructorsForCourse(courseId);"},{"lineNumber":889,"author":{"gitId":"-"},"content":" }"},{"lineNumber":890,"author":{"gitId":"-"},"content":""},{"lineNumber":891,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":892,"author":{"gitId":"-"},"content":" * Creates an instructor."},{"lineNumber":893,"author":{"gitId":"-"},"content":" */"},{"lineNumber":894,"author":{"gitId":"-"},"content":" public Instructor createInstructor(Instructor instructor)"},{"lineNumber":895,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":896,"author":{"gitId":"-"},"content":" return usersLogic.createInstructor(instructor);"},{"lineNumber":897,"author":{"gitId":"-"},"content":" }"},{"lineNumber":898,"author":{"gitId":"-"},"content":""},{"lineNumber":899,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":900,"author":{"gitId":"-"},"content":" * Make the instructor join the course, i.e. associate the Google ID to the instructor.\u003cbr\u003e"},{"lineNumber":901,"author":{"gitId":"-"},"content":" * Creates an account for the instructor if no existing account is found."},{"lineNumber":902,"author":{"gitId":"-"},"content":" * Preconditions: \u003cbr\u003e"},{"lineNumber":903,"author":{"gitId":"-"},"content":" * * Parameters regkey and googleId are non-null."},{"lineNumber":904,"author":{"gitId":"-"},"content":" */"},{"lineNumber":905,"author":{"gitId":"-"},"content":" public Instructor joinCourseForInstructor(String regkey, String googleId)"},{"lineNumber":906,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException, EntityAlreadyExistsException {"},{"lineNumber":907,"author":{"gitId":"-"},"content":""},{"lineNumber":908,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":909,"author":{"gitId":"-"},"content":" assert regkey !\u003d null;"},{"lineNumber":910,"author":{"gitId":"-"},"content":""},{"lineNumber":911,"author":{"gitId":"-"},"content":" return accountsLogic.joinCourseForInstructor(regkey, googleId);"},{"lineNumber":912,"author":{"gitId":"-"},"content":" }"},{"lineNumber":913,"author":{"gitId":"-"},"content":""},{"lineNumber":914,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":915,"author":{"gitId":"-"},"content":" * Validates that the join course request is valid, then"},{"lineNumber":916,"author":{"gitId":"-"},"content":" * makes the instructor join the course, i.e. associate an account to the instructor with the given googleId."},{"lineNumber":917,"author":{"gitId":"-"},"content":" * Creates an account for the instructor if no existing account is found."},{"lineNumber":918,"author":{"gitId":"-"},"content":" * Preconditions:"},{"lineNumber":919,"author":{"gitId":"-"},"content":" * Parameters regkey and googleId are non-null."},{"lineNumber":920,"author":{"gitId":"-"},"content":" */"},{"lineNumber":921,"author":{"gitId":"-"},"content":" public Instructor joinCourseForInstructor(String googleId, Instructor instructor)"},{"lineNumber":922,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException, EntityDoesNotExistException {"},{"lineNumber":923,"author":{"gitId":"-"},"content":" if (googleId \u003d\u003d null) {"},{"lineNumber":924,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(\"Instructor\u0027s googleId cannot be null\");"},{"lineNumber":925,"author":{"gitId":"-"},"content":" }"},{"lineNumber":926,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":927,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(\"Instructor cannot be null\");"},{"lineNumber":928,"author":{"gitId":"-"},"content":" }"},{"lineNumber":929,"author":{"gitId":"-"},"content":""},{"lineNumber":930,"author":{"gitId":"-"},"content":" validateJoinCourseRequest(googleId, instructor);"},{"lineNumber":931,"author":{"gitId":"-"},"content":" return usersLogic.joinCourseForInstructor(googleId, instructor);"},{"lineNumber":932,"author":{"gitId":"-"},"content":" }"},{"lineNumber":933,"author":{"gitId":"-"},"content":""},{"lineNumber":934,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":935,"author":{"gitId":"-"},"content":" * Validates that the instructor can join the course it has as courseId field."},{"lineNumber":936,"author":{"gitId":"-"},"content":" *"},{"lineNumber":937,"author":{"gitId":"-"},"content":" * @return true if the instructor can join the course."},{"lineNumber":938,"author":{"gitId":"-"},"content":" * @throws Exception if the instructor cannot join the course."},{"lineNumber":939,"author":{"gitId":"-"},"content":" */"},{"lineNumber":940,"author":{"gitId":"-"},"content":" private boolean validateJoinCourseRequest(String googleId, Instructor instructor)"},{"lineNumber":941,"author":{"gitId":"-"},"content":" throws EntityAlreadyExistsException, EntityDoesNotExistException {"},{"lineNumber":942,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":943,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Instructor not found\");"},{"lineNumber":944,"author":{"gitId":"-"},"content":" }"},{"lineNumber":945,"author":{"gitId":"-"},"content":""},{"lineNumber":946,"author":{"gitId":"-"},"content":" // check course exists and has not been deleted"},{"lineNumber":947,"author":{"gitId":"-"},"content":" Course course \u003d getCourse(instructor.getCourseId());"},{"lineNumber":948,"author":{"gitId":"-"},"content":""},{"lineNumber":949,"author":{"gitId":"-"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":950,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Course with id \" + instructor.getCourseId() + \" does not exist\");"},{"lineNumber":951,"author":{"gitId":"-"},"content":" }"},{"lineNumber":952,"author":{"gitId":"-"},"content":" if (course.isCourseDeleted()) {"},{"lineNumber":953,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"The course you are trying to join has been deleted by an instructor\");"},{"lineNumber":954,"author":{"gitId":"-"},"content":" }"},{"lineNumber":955,"author":{"gitId":"-"},"content":""},{"lineNumber":956,"author":{"gitId":"-"},"content":" if (instructor.isRegistered()) {"},{"lineNumber":957,"author":{"gitId":"-"},"content":" throw new EntityAlreadyExistsException(\"Instructor has already joined course\");"},{"lineNumber":958,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":959,"author":{"gitId":"-"},"content":" // Check if this Google ID has already joined this course with courseId"},{"lineNumber":960,"author":{"gitId":"-"},"content":" Instructor existingInstructor \u003d"},{"lineNumber":961,"author":{"gitId":"-"},"content":" usersLogic.getInstructorByGoogleId(instructor.getCourseId(), googleId);"},{"lineNumber":962,"author":{"gitId":"-"},"content":" if (existingInstructor !\u003d null) {"},{"lineNumber":963,"author":{"gitId":"-"},"content":" throw new EntityAlreadyExistsException(\"Instructor has already joined course\");"},{"lineNumber":964,"author":{"gitId":"-"},"content":" }"},{"lineNumber":965,"author":{"gitId":"-"},"content":" }"},{"lineNumber":966,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":967,"author":{"gitId":"-"},"content":" }"},{"lineNumber":968,"author":{"gitId":"-"},"content":""},{"lineNumber":969,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":970,"author":{"gitId":"-"},"content":" * Searches instructors in the whole system. Used by admin only."},{"lineNumber":971,"author":{"gitId":"-"},"content":" *"},{"lineNumber":972,"author":{"gitId":"-"},"content":" * @return List of found instructors in the whole system. Null if no result found."},{"lineNumber":973,"author":{"gitId":"-"},"content":" */"},{"lineNumber":974,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e searchInstructorsInWholeSystem(String queryString)"},{"lineNumber":975,"author":{"gitId":"-"},"content":" throws SearchServiceException {"},{"lineNumber":976,"author":{"gitId":"-"},"content":" assert queryString !\u003d null;"},{"lineNumber":977,"author":{"gitId":"-"},"content":""},{"lineNumber":978,"author":{"gitId":"-"},"content":" return usersLogic.searchInstructorsInWholeSystem(queryString);"},{"lineNumber":979,"author":{"gitId":"-"},"content":" }"},{"lineNumber":980,"author":{"gitId":"-"},"content":""},{"lineNumber":981,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":982,"author":{"gitId":"-"},"content":" * Updates an instructor and cascades to responses and comments if needed."},{"lineNumber":983,"author":{"gitId":"-"},"content":" *"},{"lineNumber":984,"author":{"gitId":"-"},"content":" * @return updated instructor"},{"lineNumber":985,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the instructor update request is invalid"},{"lineNumber":986,"author":{"gitId":"-"},"content":" * @throws InstructorUpdateException if the update violates instructor validity"},{"lineNumber":987,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the instructor does not exist in the database"},{"lineNumber":988,"author":{"gitId":"-"},"content":" */"},{"lineNumber":989,"author":{"gitId":"-"},"content":" public Instructor updateInstructorCascade(String courseId, InstructorCreateRequest instructorRequest) throws"},{"lineNumber":990,"author":{"gitId":"-"},"content":" InvalidParametersException, InstructorUpdateException, EntityDoesNotExistException {"},{"lineNumber":991,"author":{"gitId":"-"},"content":" return usersLogic.updateInstructorCascade(courseId, instructorRequest);"},{"lineNumber":992,"author":{"gitId":"-"},"content":" }"},{"lineNumber":993,"author":{"gitId":"-"},"content":""},{"lineNumber":994,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":995,"author":{"gitId":"-"},"content":" * Checks if an instructor with {@code googleId} can create a course with {@code institute}."},{"lineNumber":996,"author":{"gitId":"-"},"content":" */"},{"lineNumber":997,"author":{"gitId":"-"},"content":" public boolean canInstructorCreateCourse(String googleId, String institute) {"},{"lineNumber":998,"author":{"gitId":"-"},"content":" return usersLogic.canInstructorCreateCourse(googleId, institute);"},{"lineNumber":999,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1000,"author":{"gitId":"-"},"content":""},{"lineNumber":1001,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1002,"author":{"gitId":"-"},"content":" * Gets student associated with {@code id}."},{"lineNumber":1003,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1004,"author":{"gitId":"-"},"content":" * @param id Id of Student."},{"lineNumber":1005,"author":{"gitId":"-"},"content":" * @return Returns Student if found else null."},{"lineNumber":1006,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1007,"author":{"gitId":"-"},"content":" public Student getStudent(UUID id) {"},{"lineNumber":1008,"author":{"gitId":"-"},"content":" return usersLogic.getStudent(id);"},{"lineNumber":1009,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1010,"author":{"gitId":"-"},"content":""},{"lineNumber":1011,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":1012,"author":{"gitId":"dishenggg"},"content":" * Gets student reference associated with {@code id}."},{"lineNumber":1013,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":1014,"author":{"gitId":"dishenggg"},"content":" * @param id Id of Student."},{"lineNumber":1015,"author":{"gitId":"dishenggg"},"content":" * @return Returns a proxy for the Student."},{"lineNumber":1016,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":1017,"author":{"gitId":"dishenggg"},"content":" public Student getStudentReference(UUID id) {"},{"lineNumber":1018,"author":{"gitId":"dishenggg"},"content":" return usersLogic.getStudentReference(id);"},{"lineNumber":1019,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":1020,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":1021,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1022,"author":{"gitId":"-"},"content":" * Gets student associated with {@code courseId} and {@code email}."},{"lineNumber":1023,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1024,"author":{"gitId":"-"},"content":" public Student getStudentForEmail(String courseId, String email) {"},{"lineNumber":1025,"author":{"gitId":"-"},"content":" return usersLogic.getStudentForEmail(courseId, email);"},{"lineNumber":1026,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1027,"author":{"gitId":"-"},"content":""},{"lineNumber":1028,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1029,"author":{"gitId":"-"},"content":" * Check if the students with the provided emails exist in the course."},{"lineNumber":1030,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1031,"author":{"gitId":"-"},"content":" public boolean verifyStudentsExistInCourse(String courseId, List\u003cString\u003e emails) {"},{"lineNumber":1032,"author":{"gitId":"-"},"content":" return usersLogic.verifyStudentsExistInCourse(courseId, emails);"},{"lineNumber":1033,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1034,"author":{"gitId":"-"},"content":""},{"lineNumber":1035,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1036,"author":{"gitId":"-"},"content":" * Check if the instructors with the provided emails exist in the course."},{"lineNumber":1037,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1038,"author":{"gitId":"-"},"content":" public boolean verifyInstructorsExistInCourse(String courseId, List\u003cString\u003e emails) {"},{"lineNumber":1039,"author":{"gitId":"-"},"content":" return usersLogic.verifyInstructorsExistInCourse(courseId, emails);"},{"lineNumber":1040,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1041,"author":{"gitId":"-"},"content":""},{"lineNumber":1042,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1043,"author":{"gitId":"-"},"content":" * Preconditions: \u003cbr\u003e"},{"lineNumber":1044,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1045,"author":{"gitId":"-"},"content":" * @return Empty list if none found."},{"lineNumber":1046,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1047,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsForCourse(String courseId) {"},{"lineNumber":1048,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":1049,"author":{"gitId":"-"},"content":" return usersLogic.getStudentsForCourse(courseId);"},{"lineNumber":1050,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1051,"author":{"gitId":"-"},"content":""},{"lineNumber":1052,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1053,"author":{"gitId":"-"},"content":" * Preconditions: \u003cbr\u003e"},{"lineNumber":1054,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1055,"author":{"gitId":"-"},"content":" * @return Empty list if none found."},{"lineNumber":1056,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1057,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getUnregisteredStudentsForCourse(String courseId) {"},{"lineNumber":1058,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":1059,"author":{"gitId":"-"},"content":" return usersLogic.getUnregisteredStudentsForCourse(courseId);"},{"lineNumber":1060,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1061,"author":{"gitId":"-"},"content":""},{"lineNumber":1062,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1063,"author":{"gitId":"-"},"content":" * Gets a student by associated {@code regkey}."},{"lineNumber":1064,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1065,"author":{"gitId":"-"},"content":" public Student getStudentByRegistrationKey(String regKey) {"},{"lineNumber":1066,"author":{"gitId":"-"},"content":" return usersLogic.getStudentByRegistrationKey(regKey);"},{"lineNumber":1067,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1068,"author":{"gitId":"-"},"content":""},{"lineNumber":1069,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1070,"author":{"gitId":"-"},"content":" * Gets a student by associated {@code googleId}."},{"lineNumber":1071,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1072,"author":{"gitId":"-"},"content":" public Student getStudentByGoogleId(String courseId, String googleId) {"},{"lineNumber":1073,"author":{"gitId":"-"},"content":" return usersLogic.getStudentByGoogleId(courseId, googleId);"},{"lineNumber":1074,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1075,"author":{"gitId":"-"},"content":""},{"lineNumber":1076,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1077,"author":{"gitId":"-"},"content":" * Gets students by associated {@code teamName} and {@code courseId}."},{"lineNumber":1078,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1079,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsByTeamName(String teamName, String courseId) {"},{"lineNumber":1080,"author":{"gitId":"-"},"content":" return usersLogic.getStudentsForTeam(teamName, courseId);"},{"lineNumber":1081,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1082,"author":{"gitId":"-"},"content":""},{"lineNumber":1083,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":1084,"author":{"gitId":"domoberzin"},"content":" * Gets a team by associated {@code courseId} and {@code sectionName}."},{"lineNumber":1085,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":1086,"author":{"gitId":"domoberzin"},"content":" public Section getSectionOrCreate(String courseId, String sectionName) {"},{"lineNumber":1087,"author":{"gitId":"domoberzin"},"content":" return usersLogic.getSectionOrCreate(courseId, sectionName);"},{"lineNumber":1088,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":1089,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1090,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":1091,"author":{"gitId":"domoberzin"},"content":" * Gets a team by associated {@code section} and {@code teamName}."},{"lineNumber":1092,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":1093,"author":{"gitId":"domoberzin"},"content":" public Team getTeamOrCreate(Section section, String teamName) {"},{"lineNumber":1094,"author":{"gitId":"domoberzin"},"content":" return usersLogic.getTeamOrCreate(section, teamName);"},{"lineNumber":1095,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":1096,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1097,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1098,"author":{"gitId":"-"},"content":" * Creates a student."},{"lineNumber":1099,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1100,"author":{"gitId":"-"},"content":" * @return the created student"},{"lineNumber":1101,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the student is not valid"},{"lineNumber":1102,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the student already exists in the database."},{"lineNumber":1103,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1104,"author":{"gitId":"-"},"content":" public Student createStudent(Student student) throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":1105,"author":{"gitId":"-"},"content":" return usersLogic.createStudent(student);"},{"lineNumber":1106,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1107,"author":{"gitId":"-"},"content":""},{"lineNumber":1108,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":1109,"author":{"gitId":"yuanxi1"},"content":" * Search for students. Preconditions: all parameters are non-null."},{"lineNumber":1110,"author":{"gitId":"yuanxi1"},"content":" * @param instructors a list of Instructors associated to a googleId,"},{"lineNumber":1111,"author":{"gitId":"yuanxi1"},"content":" * used for filtering of search result"},{"lineNumber":1112,"author":{"gitId":"yuanxi1"},"content":" * @return Null if no match found"},{"lineNumber":1113,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":1114,"author":{"gitId":"yuanxi1"},"content":" public List\u003cStudent\u003e searchStudents(String queryString, List\u003cInstructor\u003e instructors)"},{"lineNumber":1115,"author":{"gitId":"yuanxi1"},"content":" throws SearchServiceException {"},{"lineNumber":1116,"author":{"gitId":"yuanxi1"},"content":" assert queryString !\u003d null;"},{"lineNumber":1117,"author":{"gitId":"yuanxi1"},"content":" assert instructors !\u003d null;"},{"lineNumber":1118,"author":{"gitId":"yuanxi1"},"content":" return usersLogic.searchStudents(queryString, instructors);"},{"lineNumber":1119,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":1120,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":1121,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":1122,"author":{"gitId":"yuanxi1"},"content":" * This method should be used by admin only since the searching does not restrict the"},{"lineNumber":1123,"author":{"gitId":"yuanxi1"},"content":" * visibility according to the logged-in user\u0027s google ID. This is used by admin to"},{"lineNumber":1124,"author":{"gitId":"yuanxi1"},"content":" * search students in the whole system."},{"lineNumber":1125,"author":{"gitId":"yuanxi1"},"content":" * @return Null if no match found."},{"lineNumber":1126,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":1127,"author":{"gitId":"yuanxi1"},"content":" public List\u003cStudent\u003e searchStudentsInWholeSystem(String queryString)"},{"lineNumber":1128,"author":{"gitId":"yuanxi1"},"content":" throws SearchServiceException {"},{"lineNumber":1129,"author":{"gitId":"yuanxi1"},"content":" assert queryString !\u003d null;"},{"lineNumber":1130,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":1131,"author":{"gitId":"yuanxi1"},"content":" return usersLogic.searchStudentsInWholeSystem(queryString);"},{"lineNumber":1132,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":1133,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":1134,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1135,"author":{"gitId":"-"},"content":" * Deletes a student cascade its associated feedback responses, deadline"},{"lineNumber":1136,"author":{"gitId":"-"},"content":" * extensions and comments."},{"lineNumber":1137,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1138,"author":{"gitId":"-"},"content":" * \u003cp\u003eFails silently if the student does not exist."},{"lineNumber":1139,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1140,"author":{"gitId":"-"},"content":" * \u003cbr/\u003e"},{"lineNumber":1141,"author":{"gitId":"-"},"content":" * Preconditions: \u003cbr/\u003e"},{"lineNumber":1142,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1143,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1144,"author":{"gitId":"-"},"content":" public void deleteStudentCascade(String courseId, String studentEmail) {"},{"lineNumber":1145,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":1146,"author":{"gitId":"-"},"content":" assert studentEmail !\u003d null;"},{"lineNumber":1147,"author":{"gitId":"-"},"content":""},{"lineNumber":1148,"author":{"gitId":"-"},"content":" usersLogic.deleteStudentCascade(courseId, studentEmail);"},{"lineNumber":1149,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1150,"author":{"gitId":"-"},"content":""},{"lineNumber":1151,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1152,"author":{"gitId":"-"},"content":" * Deletes all the students in the course cascade their associated responses, deadline extensions and comments."},{"lineNumber":1153,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1154,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr\u003e"},{"lineNumber":1155,"author":{"gitId":"-"},"content":" * Parameter is non-null."},{"lineNumber":1156,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1157,"author":{"gitId":"-"},"content":" public void deleteStudentsInCourseCascade(String courseId) {"},{"lineNumber":1158,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":1159,"author":{"gitId":"-"},"content":""},{"lineNumber":1160,"author":{"gitId":"-"},"content":" usersLogic.deleteStudentsInCourseCascade(courseId);"},{"lineNumber":1161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1162,"author":{"gitId":"-"},"content":""},{"lineNumber":1163,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":1164,"author":{"gitId":"yuanxi1"},"content":" * Make the student join the course, i.e. associate the Google ID to the student.\u003cbr\u003e"},{"lineNumber":1165,"author":{"gitId":"yuanxi1"},"content":" * Create an account for the student if no existing account is found."},{"lineNumber":1166,"author":{"gitId":"yuanxi1"},"content":" * Preconditions: \u003cbr\u003e"},{"lineNumber":1167,"author":{"gitId":"yuanxi1"},"content":" * * All parameters are non-null."},{"lineNumber":1168,"author":{"gitId":"yuanxi1"},"content":" * @param key the registration key"},{"lineNumber":1169,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":1170,"author":{"gitId":"yuanxi1"},"content":" public Student joinCourseForStudent(String key, String googleId)"},{"lineNumber":1171,"author":{"gitId":"yuanxi1"},"content":" throws InvalidParametersException, EntityDoesNotExistException, EntityAlreadyExistsException {"},{"lineNumber":1172,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":1173,"author":{"gitId":"yuanxi1"},"content":" assert googleId !\u003d null;"},{"lineNumber":1174,"author":{"gitId":"yuanxi1"},"content":" assert key !\u003d null;"},{"lineNumber":1175,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":1176,"author":{"gitId":"yuanxi1"},"content":" return accountsLogic.joinCourseForStudent(key, googleId);"},{"lineNumber":1177,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":1178,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":1179,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":1180,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1181,"author":{"gitId":"-"},"content":" * Gets all instructors and students by associated {@code googleId}."},{"lineNumber":1182,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1183,"author":{"gitId":"-"},"content":" public List\u003cUser\u003e getAllUsersByGoogleId(String googleId) {"},{"lineNumber":1184,"author":{"gitId":"-"},"content":" return usersLogic.getAllUsersByGoogleId(googleId);"},{"lineNumber":1185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1186,"author":{"gitId":"-"},"content":""},{"lineNumber":1187,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1188,"author":{"gitId":"-"},"content":" * Deletes a user."},{"lineNumber":1189,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1190,"author":{"gitId":"-"},"content":" * \u003cp\u003eFails silently if the user does not exist.\u003c/p\u003e"},{"lineNumber":1191,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1192,"author":{"gitId":"-"},"content":" public \u003cT extends User\u003e void deleteUser(T user) {"},{"lineNumber":1193,"author":{"gitId":"-"},"content":" usersLogic.deleteUser(user);"},{"lineNumber":1194,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1195,"author":{"gitId":"-"},"content":""},{"lineNumber":1196,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1197,"author":{"gitId":"-"},"content":" * Deletes an instructor and cascades deletion to"},{"lineNumber":1198,"author":{"gitId":"-"},"content":" * associated feedback responses, deadline extensions and comments."},{"lineNumber":1199,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1200,"author":{"gitId":"-"},"content":" * \u003cp\u003eFails silently if the instructor does not exist."},{"lineNumber":1201,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1202,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":1203,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1204,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1205,"author":{"gitId":"-"},"content":" public void deleteInstructorCascade(String courseId, String email) {"},{"lineNumber":1206,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":1207,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":1208,"author":{"gitId":"-"},"content":""},{"lineNumber":1209,"author":{"gitId":"-"},"content":" usersLogic.deleteInstructorCascade(courseId, email);"},{"lineNumber":1210,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1211,"author":{"gitId":"-"},"content":""},{"lineNumber":1212,"author":{"gitId":"-"},"content":" public List\u003cNotification\u003e getAllNotifications() {"},{"lineNumber":1213,"author":{"gitId":"-"},"content":" return notificationsLogic.getAllNotifications();"},{"lineNumber":1214,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1215,"author":{"gitId":"-"},"content":""},{"lineNumber":1216,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1217,"author":{"gitId":"-"},"content":" * Resets the googleId associated with the instructor."},{"lineNumber":1218,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1219,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":1220,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1221,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1222,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException If instructor cannot be found with given email and courseId."},{"lineNumber":1223,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1224,"author":{"gitId":"-"},"content":" public void resetInstructorGoogleId(String email, String courseId, String googleId)"},{"lineNumber":1225,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":1226,"author":{"gitId":"-"},"content":" usersLogic.resetInstructorGoogleId(email, courseId, googleId);"},{"lineNumber":1227,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1228,"author":{"gitId":"-"},"content":""},{"lineNumber":1229,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1230,"author":{"gitId":"-"},"content":" * Resets the googleId associated with the student."},{"lineNumber":1231,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1232,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":1233,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1234,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1235,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException If student cannot be found with given email and courseId."},{"lineNumber":1236,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1237,"author":{"gitId":"-"},"content":" public void resetStudentGoogleId(String email, String courseId, String googleId)"},{"lineNumber":1238,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":1239,"author":{"gitId":"-"},"content":" usersLogic.resetStudentGoogleId(email, courseId, googleId);"},{"lineNumber":1240,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1241,"author":{"gitId":"-"},"content":""},{"lineNumber":1242,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1243,"author":{"gitId":"-"},"content":" * Regenerates the registration key for the instructor with email address {@code email} in course {@code courseId}."},{"lineNumber":1244,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1245,"author":{"gitId":"-"},"content":" * @return the instructor with the new registration key."},{"lineNumber":1246,"author":{"gitId":"-"},"content":" * @throws InstructorUpdateException if system was unable to generate a new registration key."},{"lineNumber":1247,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the instructor does not exist."},{"lineNumber":1248,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1249,"author":{"gitId":"-"},"content":" public Instructor regenerateInstructorRegistrationKey(String courseId, String email)"},{"lineNumber":1250,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, InstructorUpdateException {"},{"lineNumber":1251,"author":{"gitId":"-"},"content":""},{"lineNumber":1252,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":1253,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":1254,"author":{"gitId":"-"},"content":""},{"lineNumber":1255,"author":{"gitId":"-"},"content":" return usersLogic.regenerateInstructorRegistrationKey(courseId, email);"},{"lineNumber":1256,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1257,"author":{"gitId":"-"},"content":""},{"lineNumber":1258,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1259,"author":{"gitId":"-"},"content":" * Regenerates the registration key for the student with email address {@code email} in course {@code courseId}."},{"lineNumber":1260,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1261,"author":{"gitId":"-"},"content":" * @return the student with the new registration key."},{"lineNumber":1262,"author":{"gitId":"-"},"content":" * @throws StudentUpdateException if system was unable to generate a new registration key."},{"lineNumber":1263,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the student does not exist."},{"lineNumber":1264,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1265,"author":{"gitId":"-"},"content":" public Student regenerateStudentRegistrationKey(String courseId, String email)"},{"lineNumber":1266,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, StudentUpdateException {"},{"lineNumber":1267,"author":{"gitId":"-"},"content":""},{"lineNumber":1268,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":1269,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":1270,"author":{"gitId":"-"},"content":""},{"lineNumber":1271,"author":{"gitId":"-"},"content":" return usersLogic.regenerateStudentRegistrationKey(courseId, email);"},{"lineNumber":1272,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1273,"author":{"gitId":"-"},"content":""},{"lineNumber":1274,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1275,"author":{"gitId":"-"},"content":" * Updates the instructor being edited to ensure validity of instructors for the course."},{"lineNumber":1276,"author":{"gitId":"-"},"content":" * * Preconditions: \u003cbr\u003e"},{"lineNumber":1277,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1278,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1279,"author":{"gitId":"-"},"content":" * @see UsersLogic#updateToEnsureValidityOfInstructorsForTheCourse(String, Instructor)"},{"lineNumber":1280,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1281,"author":{"gitId":"-"},"content":" public void updateToEnsureValidityOfInstructorsForTheCourse(String courseId, Instructor instructorToEdit) {"},{"lineNumber":1282,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":1283,"author":{"gitId":"-"},"content":" assert instructorToEdit !\u003d null;"},{"lineNumber":1284,"author":{"gitId":"-"},"content":""},{"lineNumber":1285,"author":{"gitId":"-"},"content":" usersLogic.updateToEnsureValidityOfInstructorsForTheCourse(courseId, instructorToEdit);"},{"lineNumber":1286,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1287,"author":{"gitId":"-"},"content":""},{"lineNumber":1288,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1289,"author":{"gitId":"-"},"content":" * Returns active notification for general users and the specified {@code targetUser}."},{"lineNumber":1290,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1291,"author":{"gitId":"-"},"content":" public List\u003cNotification\u003e getActiveNotificationsByTargetUser(NotificationTargetUser targetUser) {"},{"lineNumber":1292,"author":{"gitId":"-"},"content":" return notificationsLogic.getActiveNotificationsByTargetUser(targetUser);"},{"lineNumber":1293,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1294,"author":{"gitId":"-"},"content":""},{"lineNumber":1295,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1296,"author":{"gitId":"-"},"content":" * Gets all questions for a feedback session.\u003cbr\u003e"},{"lineNumber":1297,"author":{"gitId":"-"},"content":" * Returns an empty list if they are no questions"},{"lineNumber":1298,"author":{"gitId":"-"},"content":" * for the session."},{"lineNumber":1299,"author":{"gitId":"-"},"content":" * Preconditions: \u003cbr\u003e"},{"lineNumber":1300,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1301,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1302,"author":{"gitId":"-"},"content":" public List\u003cFeedbackQuestion\u003e getFeedbackQuestionsForSession(FeedbackSession feedbackSession) {"},{"lineNumber":1303,"author":{"gitId":"-"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":1304,"author":{"gitId":"-"},"content":""},{"lineNumber":1305,"author":{"gitId":"-"},"content":" return feedbackQuestionsLogic.getFeedbackQuestionsForSession(feedbackSession);"},{"lineNumber":1306,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1307,"author":{"gitId":"-"},"content":""},{"lineNumber":1308,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1309,"author":{"gitId":"-"},"content":" * Gets a list of all questions for the given session that"},{"lineNumber":1310,"author":{"gitId":"-"},"content":" * students can view/submit."},{"lineNumber":1311,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1312,"author":{"gitId":"-"},"content":" public List\u003cFeedbackQuestion\u003e getFeedbackQuestionsForStudents(FeedbackSession feedbackSession) {"},{"lineNumber":1313,"author":{"gitId":"-"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":1314,"author":{"gitId":"-"},"content":""},{"lineNumber":1315,"author":{"gitId":"-"},"content":" return feedbackQuestionsLogic.getFeedbackQuestionsForStudents(feedbackSession);"},{"lineNumber":1316,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1317,"author":{"gitId":"-"},"content":""},{"lineNumber":1318,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1319,"author":{"gitId":"-"},"content":" * Gets a {@code List} of all questions for the given session that"},{"lineNumber":1320,"author":{"gitId":"-"},"content":" * instructor can view/submit."},{"lineNumber":1321,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1322,"author":{"gitId":"-"},"content":" public List\u003cFeedbackQuestion\u003e getFeedbackQuestionsForInstructors("},{"lineNumber":1323,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession, String instructorEmail) {"},{"lineNumber":1324,"author":{"gitId":"-"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":1325,"author":{"gitId":"-"},"content":""},{"lineNumber":1326,"author":{"gitId":"-"},"content":" return feedbackQuestionsLogic.getFeedbackQuestionsForInstructors(feedbackSession, instructorEmail);"},{"lineNumber":1327,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1328,"author":{"gitId":"-"},"content":""},{"lineNumber":1329,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1330,"author":{"gitId":"xenosf"},"content":" * Gets the session result for a feedback session."},{"lineNumber":1331,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":1332,"author":{"gitId":"xenosf"},"content":" * @see FeedbackResponsesLogic#getSessionResultsForCourse("},{"lineNumber":1333,"author":{"gitId":"xenosf"},"content":" * FeedbackSession, String, String, String, Section, FeedbackResultFetchType)"},{"lineNumber":1334,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1335,"author":{"gitId":"xenosf"},"content":" public SqlSessionResultsBundle getSessionResultsForCourse("},{"lineNumber":1336,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession, String courseId, String userEmail,"},{"lineNumber":1337,"author":{"gitId":"xenosf"},"content":" @Nullable UUID questionId, @Nullable String sectionName, @Nullable FeedbackResultFetchType fetchType) {"},{"lineNumber":1338,"author":{"gitId":"xenosf"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":1339,"author":{"gitId":"xenosf"},"content":" assert courseId !\u003d null;"},{"lineNumber":1340,"author":{"gitId":"xenosf"},"content":" assert userEmail !\u003d null;"},{"lineNumber":1341,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1342,"author":{"gitId":"xenosf"},"content":" return feedbackResponsesLogic.getSessionResultsForCourse("},{"lineNumber":1343,"author":{"gitId":"xenosf"},"content":" feedbackSession, courseId, userEmail, questionId, sectionName, fetchType);"},{"lineNumber":1344,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1345,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1346,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1347,"author":{"gitId":"xenosf"},"content":" * Gets the session result for a feedback session for the given user."},{"lineNumber":1348,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":1349,"author":{"gitId":"xenosf"},"content":" * @see FeedbackResponsesLogic#getSessionResultsForUser(FeedbackSession, String, String, boolean, String)"},{"lineNumber":1350,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1351,"author":{"gitId":"xenosf"},"content":" public SqlSessionResultsBundle getSessionResultsForUser("},{"lineNumber":1352,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession, String courseId, String userEmail, boolean isInstructor,"},{"lineNumber":1353,"author":{"gitId":"xenosf"},"content":" @Nullable UUID questionId, boolean isPreviewResults) {"},{"lineNumber":1354,"author":{"gitId":"xenosf"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":1355,"author":{"gitId":"xenosf"},"content":" assert courseId !\u003d null;"},{"lineNumber":1356,"author":{"gitId":"xenosf"},"content":" assert userEmail !\u003d null;"},{"lineNumber":1357,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1358,"author":{"gitId":"xenosf"},"content":" return feedbackResponsesLogic.getSessionResultsForUser("},{"lineNumber":1359,"author":{"gitId":"xenosf"},"content":" feedbackSession, courseId, userEmail, isInstructor, questionId, isPreviewResults);"},{"lineNumber":1360,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1361,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1362,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1363,"author":{"gitId":"-"},"content":" * Persists the given data bundle to the database."},{"lineNumber":1364,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1365,"author":{"gitId":"-"},"content":" public SqlDataBundle persistDataBundle(SqlDataBundle dataBundle)"},{"lineNumber":1366,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException, EntityDoesNotExistException {"},{"lineNumber":1367,"author":{"gitId":"-"},"content":" return dataBundleLogic.persistDataBundle(dataBundle);"},{"lineNumber":1368,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1369,"author":{"gitId":"-"},"content":""},{"lineNumber":1370,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1371,"author":{"gitId":"-"},"content":" * Puts searchable documents from the data bundle to the database."},{"lineNumber":1372,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1373,"author":{"gitId":"-"},"content":" * @see DataBundleLogic#putDocuments(DataBundle)"},{"lineNumber":1374,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1375,"author":{"gitId":"-"},"content":" public void putDocuments(SqlDataBundle dataBundle) throws SearchServiceException {"},{"lineNumber":1376,"author":{"gitId":"-"},"content":" dataBundleLogic.putDocuments(dataBundle);"},{"lineNumber":1377,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1378,"author":{"gitId":"-"},"content":""},{"lineNumber":1379,"author":{"gitId":"mingyuanc"},"content":" /**"},{"lineNumber":1380,"author":{"gitId":"mingyuanc"},"content":" * Puts searchable instructor to the database."},{"lineNumber":1381,"author":{"gitId":"mingyuanc"},"content":" */"},{"lineNumber":1382,"author":{"gitId":"mingyuanc"},"content":" public void putInstructorDocument(Instructor instructor) throws SearchServiceException {"},{"lineNumber":1383,"author":{"gitId":"mingyuanc"},"content":" usersLogic.putInstructorDocument(instructor);"},{"lineNumber":1384,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":1385,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":1386,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":1387,"author":{"gitId":"domoberzin"},"content":" * Creates or updates search document for the given account request."},{"lineNumber":1388,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":1389,"author":{"gitId":"domoberzin"},"content":" * @see AccountRequestsLogic#putDocument(AccountRequest)"},{"lineNumber":1390,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":1391,"author":{"gitId":"domoberzin"},"content":" public void putAccountRequestDocument(AccountRequest accountRequest) throws SearchServiceException {"},{"lineNumber":1392,"author":{"gitId":"domoberzin"},"content":" accountRequestLogic.putDocument(accountRequest);"},{"lineNumber":1393,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":1394,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1395,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1396,"author":{"gitId":"-"},"content":" * Removes the given data bundle from the database."},{"lineNumber":1397,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1398,"author":{"gitId":"-"},"content":" public void removeDataBundle(SqlDataBundle dataBundle) throws InvalidParametersException {"},{"lineNumber":1399,"author":{"gitId":"-"},"content":" dataBundleLogic.removeDataBundle(dataBundle);"},{"lineNumber":1400,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1401,"author":{"gitId":"-"},"content":""},{"lineNumber":1402,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1403,"author":{"gitId":"-"},"content":" * Populates fields that need dynamic generation in a question."},{"lineNumber":1404,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1405,"author":{"gitId":"-"},"content":" * \u003cp\u003eCurrently, only MCQ/MSQ needs to generate choices dynamically.\u003c/p\u003e"},{"lineNumber":1406,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1407,"author":{"gitId":"-"},"content":" * @param feedbackQuestion the question to populate"},{"lineNumber":1408,"author":{"gitId":"-"},"content":" * @param courseId the ID of the course"},{"lineNumber":1409,"author":{"gitId":"-"},"content":" * @param emailOfEntityDoingQuestion the email of the entity doing the question"},{"lineNumber":1410,"author":{"gitId":"-"},"content":" * @param teamOfEntityDoingQuestion the team of the entity doing the question. If the entity is an instructor,"},{"lineNumber":1411,"author":{"gitId":"-"},"content":" * it can be {@code null}."},{"lineNumber":1412,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1413,"author":{"gitId":"-"},"content":" public void populateFieldsToGenerateInQuestion(FeedbackQuestion feedbackQuestion,"},{"lineNumber":1414,"author":{"gitId":"-"},"content":" String courseId, String emailOfEntityDoingQuestion,"},{"lineNumber":1415,"author":{"gitId":"-"},"content":" String teamOfEntityDoingQuestion) {"},{"lineNumber":1416,"author":{"gitId":"-"},"content":" assert feedbackQuestion !\u003d null;"},{"lineNumber":1417,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":1418,"author":{"gitId":"-"},"content":" assert emailOfEntityDoingQuestion !\u003d null;"},{"lineNumber":1419,"author":{"gitId":"-"},"content":""},{"lineNumber":1420,"author":{"gitId":"-"},"content":" feedbackQuestionsLogic.populateFieldsToGenerateInQuestion("},{"lineNumber":1421,"author":{"gitId":"-"},"content":" feedbackQuestion, courseId, emailOfEntityDoingQuestion, teamOfEntityDoingQuestion);"},{"lineNumber":1422,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1423,"author":{"gitId":"-"},"content":""},{"lineNumber":1424,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1425,"author":{"gitId":"-"},"content":" * Gets a feedback question."},{"lineNumber":1426,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1427,"author":{"gitId":"-"},"content":" * @return null if not found."},{"lineNumber":1428,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1429,"author":{"gitId":"-"},"content":" public FeedbackQuestion getFeedbackQuestion(UUID id) {"},{"lineNumber":1430,"author":{"gitId":"-"},"content":" return feedbackQuestionsLogic.getFeedbackQuestion(id);"},{"lineNumber":1431,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1432,"author":{"gitId":"-"},"content":""},{"lineNumber":1433,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1434,"author":{"gitId":"-"},"content":" * Deletes a feedback question cascade its responses and comments."},{"lineNumber":1435,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1436,"author":{"gitId":"-"},"content":" * \u003cp\u003eSilently fail if question does not exist."},{"lineNumber":1437,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1438,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":1439,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1440,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1441,"author":{"gitId":"-"},"content":" public void deleteFeedbackQuestionCascade(UUID questionId) {"},{"lineNumber":1442,"author":{"gitId":"-"},"content":" feedbackQuestionsLogic.deleteFeedbackQuestionCascade(questionId);"},{"lineNumber":1443,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1444,"author":{"gitId":"-"},"content":""},{"lineNumber":1445,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1446,"author":{"gitId":"-"},"content":" * Gets the recipients of a feedback question for student."},{"lineNumber":1447,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1448,"author":{"gitId":"-"},"content":" * @see FeedbackQuestionsLogic#getRecipientsOfQuestion"},{"lineNumber":1449,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1450,"author":{"gitId":"-"},"content":" public Map\u003cString, FeedbackQuestionRecipient\u003e getRecipientsOfQuestion("},{"lineNumber":1451,"author":{"gitId":"-"},"content":" FeedbackQuestion question,"},{"lineNumber":1452,"author":{"gitId":"-"},"content":" @Nullable Instructor instructorGiver, @Nullable Student studentGiver) {"},{"lineNumber":1453,"author":{"gitId":"-"},"content":" assert question !\u003d null;"},{"lineNumber":1454,"author":{"gitId":"-"},"content":""},{"lineNumber":1455,"author":{"gitId":"-"},"content":" return feedbackQuestionsLogic.getRecipientsOfQuestion(question, instructorGiver, studentGiver, null);"},{"lineNumber":1456,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1457,"author":{"gitId":"-"},"content":""},{"lineNumber":1458,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1459,"author":{"gitId":"-"},"content":" * Gets a feedbackResponse or null if it does not exist."},{"lineNumber":1460,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1461,"author":{"gitId":"-"},"content":" public FeedbackResponse getFeedbackResponse(UUID frId) {"},{"lineNumber":1462,"author":{"gitId":"-"},"content":" return feedbackResponsesLogic.getFeedbackResponse(frId);"},{"lineNumber":1463,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1464,"author":{"gitId":"-"},"content":""},{"lineNumber":1465,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1466,"author":{"gitId":"-"},"content":" * Creates a feedback response."},{"lineNumber":1467,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1468,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":1469,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1470,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1471,"author":{"gitId":"-"},"content":" * @return created feedback response"},{"lineNumber":1472,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the response is not valid"},{"lineNumber":1473,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the response already exist"},{"lineNumber":1474,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1475,"author":{"gitId":"-"},"content":" public FeedbackResponse createFeedbackResponse(FeedbackResponse feedbackResponse)"},{"lineNumber":1476,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":1477,"author":{"gitId":"-"},"content":" assert feedbackResponse !\u003d null;"},{"lineNumber":1478,"author":{"gitId":"-"},"content":" return feedbackResponsesLogic.createFeedbackResponse(feedbackResponse);"},{"lineNumber":1479,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1480,"author":{"gitId":"-"},"content":""},{"lineNumber":1481,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1482,"author":{"gitId":"-"},"content":" * Deletes a feedback response and cascades its associated comments."},{"lineNumber":1483,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1484,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":1485,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1486,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1487,"author":{"gitId":"-"},"content":" public void deleteFeedbackResponsesAndCommentsCascade(FeedbackResponse feedbackResponse) {"},{"lineNumber":1488,"author":{"gitId":"-"},"content":" assert feedbackResponse !\u003d null;"},{"lineNumber":1489,"author":{"gitId":"-"},"content":" feedbackResponsesLogic.deleteFeedbackResponsesAndCommentsCascade(feedbackResponse);"},{"lineNumber":1490,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1491,"author":{"gitId":"-"},"content":""},{"lineNumber":1492,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1493,"author":{"gitId":"-"},"content":" * Get existing feedback responses from instructor for the given question."},{"lineNumber":1494,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1495,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesFromInstructorForQuestion("},{"lineNumber":1496,"author":{"gitId":"-"},"content":" FeedbackQuestion question, Instructor instructor) {"},{"lineNumber":1497,"author":{"gitId":"-"},"content":" return feedbackResponsesLogic.getFeedbackResponsesFromInstructorForQuestion("},{"lineNumber":1498,"author":{"gitId":"-"},"content":" question, instructor);"},{"lineNumber":1499,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1500,"author":{"gitId":"-"},"content":""},{"lineNumber":1501,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1502,"author":{"gitId":"-"},"content":" * Get existing feedback responses from student or his team for the given"},{"lineNumber":1503,"author":{"gitId":"-"},"content":" * question."},{"lineNumber":1504,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1505,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesFromStudentOrTeamForQuestion("},{"lineNumber":1506,"author":{"gitId":"-"},"content":" FeedbackQuestion question, Student student) {"},{"lineNumber":1507,"author":{"gitId":"-"},"content":" return feedbackResponsesLogic.getFeedbackResponsesFromStudentOrTeamForQuestion("},{"lineNumber":1508,"author":{"gitId":"-"},"content":" question, student);"},{"lineNumber":1509,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1510,"author":{"gitId":"-"},"content":""},{"lineNumber":1511,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1512,"author":{"gitId":"-"},"content":" * Gets an feedback response comment by feedback response comment id."},{"lineNumber":1513,"author":{"gitId":"-"},"content":" * @param id of feedback response comment."},{"lineNumber":1514,"author":{"gitId":"-"},"content":" * @return the specified feedback response comment."},{"lineNumber":1515,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1516,"author":{"gitId":"-"},"content":" public FeedbackResponseComment getFeedbackResponseComment(Long id) {"},{"lineNumber":1517,"author":{"gitId":"-"},"content":" return feedbackResponseCommentsLogic.getFeedbackResponseComment(id);"},{"lineNumber":1518,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1519,"author":{"gitId":"-"},"content":""},{"lineNumber":1520,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1521,"author":{"gitId":"-"},"content":" * Updates a feedback response comment."},{"lineNumber":1522,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the comment does not exist"},{"lineNumber":1523,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1524,"author":{"gitId":"-"},"content":" public FeedbackResponseComment updateFeedbackResponseComment(Long frcId,"},{"lineNumber":1525,"author":{"gitId":"-"},"content":" FeedbackResponseCommentUpdateRequest updateRequest, String updaterEmail)"},{"lineNumber":1526,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":1527,"author":{"gitId":"-"},"content":" return feedbackResponseCommentsLogic.updateFeedbackResponseComment(frcId, updateRequest, updaterEmail);"},{"lineNumber":1528,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1529,"author":{"gitId":"-"},"content":""},{"lineNumber":1530,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1531,"author":{"gitId":"-"},"content":" * Updates a feedback response and comments by {@link FeedbackResponse}."},{"lineNumber":1532,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1533,"author":{"gitId":"-"},"content":" * \u003cp\u003eCascade updates its associated feedback response comment"},{"lineNumber":1534,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1535,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":1536,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1537,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1538,"author":{"gitId":"-"},"content":" * @return updated feedback response"},{"lineNumber":1539,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":1540,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the comment cannot be found"},{"lineNumber":1541,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1542,"author":{"gitId":"-"},"content":" public FeedbackResponse updateFeedbackResponseCascade(FeedbackResponse feedbackResponse)"},{"lineNumber":1543,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":1544,"author":{"gitId":"-"},"content":" assert feedbackResponse !\u003d null;"},{"lineNumber":1545,"author":{"gitId":"-"},"content":""},{"lineNumber":1546,"author":{"gitId":"-"},"content":" return feedbackResponsesLogic.updateFeedbackResponseCascade(feedbackResponse);"},{"lineNumber":1547,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1548,"author":{"gitId":"-"},"content":""},{"lineNumber":1549,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1550,"author":{"gitId":"-"},"content":" * Checks whether there are responses for a question."},{"lineNumber":1551,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1552,"author":{"gitId":"-"},"content":" public boolean areThereResponsesForQuestion(UUID questionId) {"},{"lineNumber":1553,"author":{"gitId":"-"},"content":" return feedbackResponsesLogic.areThereResponsesForQuestion(questionId);"},{"lineNumber":1554,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1555,"author":{"gitId":"-"},"content":""},{"lineNumber":1556,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1557,"author":{"gitId":"-"},"content":" * Checks whether there are responses for a course."},{"lineNumber":1558,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1559,"author":{"gitId":"-"},"content":" public boolean hasResponsesForCourse(String courseId) {"},{"lineNumber":1560,"author":{"gitId":"-"},"content":" return feedbackResponsesLogic.hasResponsesForCourse(courseId);"},{"lineNumber":1561,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1562,"author":{"gitId":"-"},"content":""},{"lineNumber":1563,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1564,"author":{"gitId":"-"},"content":" * Gets the comment associated with the response."},{"lineNumber":1565,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1566,"author":{"gitId":"-"},"content":" public FeedbackResponseComment getFeedbackResponseCommentForResponseFromParticipant("},{"lineNumber":1567,"author":{"gitId":"-"},"content":" UUID feedbackResponseId) {"},{"lineNumber":1568,"author":{"gitId":"-"},"content":" return feedbackResponseCommentsLogic.getFeedbackResponseCommentForResponseFromParticipant(feedbackResponseId);"},{"lineNumber":1569,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1570,"author":{"gitId":"-"},"content":""},{"lineNumber":1571,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1572,"author":{"gitId":"-"},"content":" * Creates a feedback response comment."},{"lineNumber":1573,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the comment alreadty exists"},{"lineNumber":1574,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the comment is invalid"},{"lineNumber":1575,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1576,"author":{"gitId":"-"},"content":" public FeedbackResponseComment createFeedbackResponseComment(FeedbackResponseComment frc)"},{"lineNumber":1577,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":1578,"author":{"gitId":"-"},"content":" return feedbackResponseCommentsLogic.createFeedbackResponseComment(frc);"},{"lineNumber":1579,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1580,"author":{"gitId":"-"},"content":""},{"lineNumber":1581,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1582,"author":{"gitId":"-"},"content":" * Deletes a feedbackResponseComment."},{"lineNumber":1583,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1584,"author":{"gitId":"-"},"content":" public void deleteFeedbackResponseComment(Long frcId) {"},{"lineNumber":1585,"author":{"gitId":"-"},"content":" feedbackResponseCommentsLogic.deleteFeedbackResponseComment(frcId);"},{"lineNumber":1586,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1587,"author":{"gitId":"-"},"content":""},{"lineNumber":1588,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1589,"author":{"gitId":"domoberzin"},"content":" * Gets all feedback responses from a giver for a question."},{"lineNumber":1590,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":1591,"author":{"gitId":"domoberzin"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesFromGiverForCourse(String courseId, String giverEmail) {"},{"lineNumber":1592,"author":{"gitId":"domoberzin"},"content":" return feedbackResponsesLogic.getFeedbackResponsesFromGiverForCourse(courseId, giverEmail);"},{"lineNumber":1593,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":1594,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1595,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":1596,"author":{"gitId":"domoberzin"},"content":" * Gets all feedback responses for a recipient for a course."},{"lineNumber":1597,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":1598,"author":{"gitId":"domoberzin"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForRecipientForCourse(String courseId, String recipientEmail) {"},{"lineNumber":1599,"author":{"gitId":"domoberzin"},"content":" return feedbackResponsesLogic.getFeedbackResponsesForRecipientForCourse(courseId, recipientEmail);"},{"lineNumber":1600,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":1601,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1602,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":1603,"author":{"gitId":"domoberzin"},"content":" * Gets all feedback response comments for a feedback response."},{"lineNumber":1604,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":1605,"author":{"gitId":"domoberzin"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentsForResponse(UUID feedbackResponse) {"},{"lineNumber":1606,"author":{"gitId":"domoberzin"},"content":" return feedbackResponseCommentsLogic.getFeedbackResponseCommentsForResponse(feedbackResponse);"},{"lineNumber":1607,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":1608,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1609,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":1610,"author":{"gitId":"domoberzin"},"content":" * Validates sections for any limit violations and teams for any team name violations."},{"lineNumber":1611,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":1612,"author":{"gitId":"domoberzin"},"content":" * \u003cp\u003ePreconditions: \u003cbr\u003e"},{"lineNumber":1613,"author":{"gitId":"domoberzin"},"content":" * * All parameters are non-null."},{"lineNumber":1614,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":1615,"author":{"gitId":"domoberzin"},"content":" * @see StudentsLogic#validateSectionsAndTeams(List, String)"},{"lineNumber":1616,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":1617,"author":{"gitId":"domoberzin"},"content":" public void validateSectionsAndTeams("},{"lineNumber":1618,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e studentList, String courseId) throws EnrollException {"},{"lineNumber":1619,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1620,"author":{"gitId":"domoberzin"},"content":" assert studentList !\u003d null;"},{"lineNumber":1621,"author":{"gitId":"domoberzin"},"content":" assert courseId !\u003d null;"},{"lineNumber":1622,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1623,"author":{"gitId":"domoberzin"},"content":" usersLogic.validateSectionsAndTeams(studentList, courseId);"},{"lineNumber":1624,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":1625,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1626,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":1627,"author":{"gitId":"domoberzin"},"content":" * Updates a feedback question by {@code FeedbackQuestionUpdateRequest}."},{"lineNumber":1628,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1629,"author":{"gitId":"-"},"content":" * \u003cp\u003eCascade adjust the question number of questions in the same session."},{"lineNumber":1630,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1631,"author":{"gitId":"-"},"content":" * \u003cp\u003eCascade adjust the existing response of the question."},{"lineNumber":1632,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1633,"author":{"gitId":"-"},"content":" * \u003cbr/\u003e Preconditions: \u003cbr/\u003e"},{"lineNumber":1634,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1635,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1636,"author":{"gitId":"-"},"content":" * @return updated feedback question"},{"lineNumber":1637,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":1638,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the feedback question cannot be found"},{"lineNumber":1639,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1640,"author":{"gitId":"-"},"content":" public FeedbackQuestion updateFeedbackQuestionCascade(UUID questionId, FeedbackQuestionUpdateRequest updateRequest)"},{"lineNumber":1641,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":1642,"author":{"gitId":"-"},"content":" return feedbackQuestionsLogic.updateFeedbackQuestionCascade(questionId, updateRequest);"},{"lineNumber":1643,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1644,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1645,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1646,"author":{"gitId":"-"},"content":" * Returns a list of feedback sessions that need an \"Open\" email to be sent."},{"lineNumber":1647,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1648,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsWhichNeedOpenEmailsToBeSent() {"},{"lineNumber":1649,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSessionsWhichNeedOpenEmailsToBeSent();"},{"lineNumber":1650,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1651,"author":{"gitId":"-"},"content":""},{"lineNumber":1652,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1653,"author":{"gitId":"-"},"content":" * Returns a list of sessions that were closed within past hour."},{"lineNumber":1654,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1655,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsClosedWithinThePastHour() {"},{"lineNumber":1656,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSessionsClosedWithinThePastHour();"},{"lineNumber":1657,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1658,"author":{"gitId":"-"},"content":""},{"lineNumber":1659,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1660,"author":{"gitId":"xenosf"},"content":" * Creates or updates search document for the given student."},{"lineNumber":1661,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":1662,"author":{"gitId":"xenosf"},"content":" * @see UsersLogic#putStudentDocument(Student)"},{"lineNumber":1663,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1664,"author":{"gitId":"xenosf"},"content":" public void putStudentDocument(Student student) throws SearchServiceException {"},{"lineNumber":1665,"author":{"gitId":"xenosf"},"content":" usersLogic.putStudentDocument(student);"},{"lineNumber":1666,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1667,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1668,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":1669,"author":{"gitId":"domoberzin"},"content":" * This is used by admin to search account requests in the whole system."},{"lineNumber":1670,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":1671,"author":{"gitId":"domoberzin"},"content":" * @return A list of {@link AccountRequest} or {@code null} if no match found."},{"lineNumber":1672,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":1673,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccountRequest\u003e searchAccountRequestsInWholeSystem(String queryString)"},{"lineNumber":1674,"author":{"gitId":"domoberzin"},"content":" throws SearchServiceException {"},{"lineNumber":1675,"author":{"gitId":"domoberzin"},"content":" assert queryString !\u003d null;"},{"lineNumber":1676,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1677,"author":{"gitId":"domoberzin"},"content":" return accountRequestLogic.searchAccountRequestsInWholeSystem(queryString);"},{"lineNumber":1678,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":1679,"author":{"gitId":"-"},"content":""},{"lineNumber":1680,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1681,"author":{"gitId":"-"},"content":" * Returns a list of sessions that are going to close soon."},{"lineNumber":1682,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1683,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsClosingWithinTimeLimit() {"},{"lineNumber":1684,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSessionsClosingWithinTimeLimit();"},{"lineNumber":1685,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1686,"author":{"gitId":"-"},"content":""},{"lineNumber":1687,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1688,"author":{"gitId":"-"},"content":" * Returns a list of sessions that are going to open soon."},{"lineNumber":1689,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1690,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsOpeningWithinTimeLimit() {"},{"lineNumber":1691,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSessionsOpeningWithinTimeLimit();"},{"lineNumber":1692,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1693,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":1694,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":1695,"author":{"gitId":"dishenggg"},"content":" * Create feedback session logs."},{"lineNumber":1696,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":1697,"author":{"gitId":"dishenggg"},"content":" public void createFeedbackSessionLogs(List\u003cFeedbackSessionLog\u003e feedbackSessionLogs) {"},{"lineNumber":1698,"author":{"gitId":"dishenggg"},"content":" feedbackSessionLogsLogic.createFeedbackSessionLogs(feedbackSessionLogs);"},{"lineNumber":1699,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":1700,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":1701,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":1702,"author":{"gitId":"dishenggg"},"content":" * Gets the feedback session logs as filtered by the given parameters ordered by"},{"lineNumber":1703,"author":{"gitId":"dishenggg"},"content":" * ascending timestamp. Logs with the same timestamp will be ordered by the"},{"lineNumber":1704,"author":{"gitId":"dishenggg"},"content":" * student\u0027s email."},{"lineNumber":1705,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":1706,"author":{"gitId":"dishenggg"},"content":" * @param studentId Can be null"},{"lineNumber":1707,"author":{"gitId":"dishenggg"},"content":" * @param feedbackSessionId Can be null"},{"lineNumber":1708,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":1709,"author":{"gitId":"dishenggg"},"content":" public List\u003cFeedbackSessionLog\u003e getOrderedFeedbackSessionLogs(String courseId, UUID studentId,"},{"lineNumber":1710,"author":{"gitId":"dishenggg"},"content":" UUID feedbackSessionId, Instant startTime, Instant endTime) {"},{"lineNumber":1711,"author":{"gitId":"dishenggg"},"content":" return feedbackSessionLogsLogic.getOrderedFeedbackSessionLogs(courseId, studentId, feedbackSessionId, startTime,"},{"lineNumber":1712,"author":{"gitId":"dishenggg"},"content":" endTime);"},{"lineNumber":1713,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":1714,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":177,"yuanxi1":50,"marquestye":5,"xenosf":44,"dishenggg":59,"mingyuanc":7,"-":1372}},{"path":"src/main/java/teammates/sqllogic/api/SqlEmailGenerator.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.api;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.Collections;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.Set;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.ErrorLogEntry;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailType;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.util.RequestTracer;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.util.Templates;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.util.Templates.EmailTemplates;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.CoursesLogic;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.DeadlineExtensionsLogic;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.FeedbackSessionsLogic;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.UsersLogic;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":37,"author":{"gitId":"-"},"content":" * Handles operations related to generating emails to be sent from provided templates."},{"lineNumber":38,"author":{"gitId":"-"},"content":" *"},{"lineNumber":39,"author":{"gitId":"-"},"content":" * @see EmailTemplates"},{"lineNumber":40,"author":{"gitId":"-"},"content":" * @see EmailType"},{"lineNumber":41,"author":{"gitId":"-"},"content":" * @see EmailWrapper"},{"lineNumber":42,"author":{"gitId":"-"},"content":" */"},{"lineNumber":43,"author":{"gitId":"-"},"content":"public final class SqlEmailGenerator {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" // feedback action strings"},{"lineNumber":45,"author":{"gitId":"-"},"content":" private static final String FEEDBACK_ACTION_SUBMIT_EDIT_OR_VIEW \u003d \"submit, edit or view\";"},{"lineNumber":46,"author":{"gitId":"-"},"content":" private static final String FEEDBACK_ACTION_VIEW \u003d \"view\";"},{"lineNumber":47,"author":{"gitId":"-"},"content":" private static final String FEEDBACK_ACTION_SUBMIT_OR_UPDATE \u003d"},{"lineNumber":48,"author":{"gitId":"-"},"content":" \", in case you have not submitted yet or wish to update your submission. \";"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private static final String HTML_NO_ACTION_REQUIRED \u003d \"\u003cmark\u003eNo action is required if you have already submitted\u003c/mark\u003e\";"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" // status-related strings"},{"lineNumber":52,"author":{"gitId":"-"},"content":" private static final String FEEDBACK_STATUS_SESSION_OPEN \u003d \"is still open for submissions\""},{"lineNumber":53,"author":{"gitId":"-"},"content":" + FEEDBACK_ACTION_SUBMIT_OR_UPDATE + HTML_NO_ACTION_REQUIRED;"},{"lineNumber":54,"author":{"gitId":"-"},"content":" private static final String FEEDBACK_STATUS_SESSION_OPENING \u003d \"is now open\";"},{"lineNumber":55,"author":{"gitId":"-"},"content":" private static final String FEEDBACK_STATUS_SESSION_CLOSING \u003d \"is closing soon\""},{"lineNumber":56,"author":{"gitId":"-"},"content":" + FEEDBACK_ACTION_SUBMIT_OR_UPDATE + HTML_NO_ACTION_REQUIRED;"},{"lineNumber":57,"author":{"gitId":"-"},"content":" private static final String FEEDBACK_STATUS_SESSION_CLOSED \u003d \"is now closed for submission\";"},{"lineNumber":58,"author":{"gitId":"-"},"content":" private static final String FEEDBACK_STATUS_SESSION_OPENING_SOON \u003d \"is due to open soon\";"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" private static final String DATETIME_DISPLAY_FORMAT \u003d \"EEE, dd MMM yyyy, hh:mm a z\";"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" private static final long SESSION_LINK_RECOVERY_DURATION_IN_DAYS \u003d 90;"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" private static final SqlEmailGenerator instance \u003d new SqlEmailGenerator();"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" private final CoursesLogic coursesLogic \u003d CoursesLogic.inst();"},{"lineNumber":67,"author":{"gitId":"-"},"content":" private final DeadlineExtensionsLogic deLogic \u003d DeadlineExtensionsLogic.inst();"},{"lineNumber":68,"author":{"gitId":"-"},"content":" private final FeedbackSessionsLogic fsLogic \u003d FeedbackSessionsLogic.inst();"},{"lineNumber":69,"author":{"gitId":"-"},"content":" private final UsersLogic usersLogic \u003d UsersLogic.inst();"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" private SqlEmailGenerator() {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":73,"author":{"gitId":"-"},"content":" }"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" public static SqlEmailGenerator inst() {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":80,"author":{"gitId":"-"},"content":" * Generate Feedback Session Opening emails."},{"lineNumber":81,"author":{"gitId":"-"},"content":" */"},{"lineNumber":82,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateFeedbackSessionOpeningEmails(FeedbackSession session) {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" return generateFeedbackSessionOpeningOrClosingEmails(session, EmailType.FEEDBACK_OPENING);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" private List\u003cEmailWrapper\u003e generateFeedbackSessionOpeningOrClosingEmails("},{"lineNumber":87,"author":{"gitId":"-"},"content":" FeedbackSession session, EmailType emailType) {"},{"lineNumber":88,"author":{"gitId":"-"},"content":" Course course \u003d session.getCourse();"},{"lineNumber":89,"author":{"gitId":"-"},"content":" boolean isEmailNeededForStudents \u003d fsLogic.isFeedbackSessionForUserTypeToAnswer(session, false);"},{"lineNumber":90,"author":{"gitId":"-"},"content":" boolean isEmailNeededForInstructors \u003d fsLogic.isFeedbackSessionForUserTypeToAnswer(session, true);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorsToNotify \u003d isEmailNeededForStudents"},{"lineNumber":92,"author":{"gitId":"-"},"content":" ? usersLogic.getCoOwnersForCourse(course.getId())"},{"lineNumber":93,"author":{"gitId":"-"},"content":" : new ArrayList\u003c\u003e();"},{"lineNumber":94,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e students \u003d isEmailNeededForStudents"},{"lineNumber":95,"author":{"gitId":"-"},"content":" ? usersLogic.getStudentsForCourse(course.getId())"},{"lineNumber":96,"author":{"gitId":"-"},"content":" : new ArrayList\u003c\u003e();"},{"lineNumber":97,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors \u003d isEmailNeededForInstructors"},{"lineNumber":98,"author":{"gitId":"-"},"content":" ? usersLogic.getInstructorsForCourse(course.getId())"},{"lineNumber":99,"author":{"gitId":"-"},"content":" : new ArrayList\u003c\u003e();"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" if (emailType \u003d\u003d EmailType.FEEDBACK_CLOSING) {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" List\u003cDeadlineExtension\u003e deadlines \u003d session.getDeadlineExtensions();"},{"lineNumber":103,"author":{"gitId":"-"},"content":" Set\u003cUUID\u003e userIds \u003d deadlines.stream()"},{"lineNumber":104,"author":{"gitId":"-"},"content":" .map(d -\u003e d.getUser().getId())"},{"lineNumber":105,"author":{"gitId":"-"},"content":" .collect(Collectors.toSet());"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" // student."},{"lineNumber":108,"author":{"gitId":"-"},"content":" students \u003d students.stream()"},{"lineNumber":109,"author":{"gitId":"-"},"content":" .filter(x -\u003e !userIds.contains(x.getId()))"},{"lineNumber":110,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" // instructor."},{"lineNumber":113,"author":{"gitId":"-"},"content":" instructors \u003d instructors.stream()"},{"lineNumber":114,"author":{"gitId":"-"},"content":" .filter(x -\u003e !userIds.contains(x.getId()))"},{"lineNumber":115,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":116,"author":{"gitId":"-"},"content":" }"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" String status \u003d emailType \u003d\u003d EmailType.FEEDBACK_OPENING"},{"lineNumber":119,"author":{"gitId":"-"},"content":" ? FEEDBACK_STATUS_SESSION_OPENING"},{"lineNumber":120,"author":{"gitId":"-"},"content":" : FEEDBACK_STATUS_SESSION_CLOSING;"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" String template \u003d emailType \u003d\u003d EmailType.FEEDBACK_OPENING"},{"lineNumber":123,"author":{"gitId":"-"},"content":" ? EmailTemplates.USER_FEEDBACK_SESSION_OPENING.replace(\"${status}\", status)"},{"lineNumber":124,"author":{"gitId":"-"},"content":" : EmailTemplates.USER_FEEDBACK_SESSION.replace(\"${status}\", status);"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" return generateFeedbackSessionEmailBases(course, session, students, instructors, instructorsToNotify, template,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" emailType, FEEDBACK_ACTION_SUBMIT_EDIT_OR_VIEW);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":131,"author":{"gitId":"-"},"content":" * Generates the feedback session opening soon emails for the given {@code session}."},{"lineNumber":132,"author":{"gitId":"-"},"content":" *"},{"lineNumber":133,"author":{"gitId":"-"},"content":" * \u003cp\u003eThis is useful for e.g. in case the feedback session opening info was set wrongly."},{"lineNumber":134,"author":{"gitId":"-"},"content":" */"},{"lineNumber":135,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateFeedbackSessionOpeningSoonEmails(FeedbackSession session) {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" return generateFeedbackSessionOpeningSoonOrClosedEmails(session, EmailType.FEEDBACK_OPENING_SOON);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" private List\u003cEmailWrapper\u003e generateFeedbackSessionOpeningSoonOrClosedEmails("},{"lineNumber":140,"author":{"gitId":"-"},"content":" FeedbackSession session, EmailType emailType) {"},{"lineNumber":141,"author":{"gitId":"-"},"content":" Course course \u003d session.getCourse();"},{"lineNumber":142,"author":{"gitId":"-"},"content":" // Notify only course co-owners"},{"lineNumber":143,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e coOwners \u003d usersLogic.getCoOwnersForCourse(course.getId());"},{"lineNumber":144,"author":{"gitId":"-"},"content":" return coOwners.stream()"},{"lineNumber":145,"author":{"gitId":"-"},"content":" .map(coOwner -\u003e generateFeedbackSessionEmailBaseForCoowner(course, session, coOwner, emailType))"},{"lineNumber":146,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" private EmailWrapper generateFeedbackSessionEmailBaseForCoowner("},{"lineNumber":150,"author":{"gitId":"-"},"content":" Course course, FeedbackSession session, Instructor coOwner, EmailType emailType) {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" String additionalNotes;"},{"lineNumber":152,"author":{"gitId":"-"},"content":" String status;"},{"lineNumber":153,"author":{"gitId":"-"},"content":" if (emailType \u003d\u003d EmailType.FEEDBACK_OPENING_SOON) {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" String editUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.INSTRUCTOR_SESSION_EDIT_PAGE)"},{"lineNumber":155,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":156,"author":{"gitId":"-"},"content":" .withSessionName(session.getName())"},{"lineNumber":157,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":158,"author":{"gitId":"-"},"content":" // If instructor has not joined the course, populate additional notes with information to join course."},{"lineNumber":159,"author":{"gitId":"-"},"content":" if (coOwner.isRegistered()) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" additionalNotes \u003d fillUpEditFeedbackSessionDetailsFragment(editUrl);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" additionalNotes \u003d fillUpJoinCourseBeforeEditFeedbackSessionDetailsFragment(editUrl,"},{"lineNumber":163,"author":{"gitId":"-"},"content":" getInstructorCourseJoinUrl(coOwner));"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":" status \u003d FEEDBACK_STATUS_SESSION_OPENING_SOON;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" String reportUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.INSTRUCTOR_SESSION_REPORT_PAGE)"},{"lineNumber":168,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":169,"author":{"gitId":"-"},"content":" .withSessionName(session.getName())"},{"lineNumber":170,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":171,"author":{"gitId":"-"},"content":" additionalNotes \u003d fillUpViewResponsesDetailsFragment(reportUrl);"},{"lineNumber":172,"author":{"gitId":"-"},"content":" status \u003d FEEDBACK_STATUS_SESSION_CLOSED;"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" Instant startTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":176,"author":{"gitId":"-"},"content":" session.getStartTime(), session.getCourse().getTimeZone(), false);"},{"lineNumber":177,"author":{"gitId":"-"},"content":" Instant endTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":178,"author":{"gitId":"-"},"content":" session.getEndTime(), session.getCourse().getTimeZone(), false);"},{"lineNumber":179,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate(EmailTemplates.OWNER_FEEDBACK_SESSION,"},{"lineNumber":180,"author":{"gitId":"-"},"content":" \"${status}\", status,"},{"lineNumber":181,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(coOwner.getName()),"},{"lineNumber":182,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":183,"author":{"gitId":"-"},"content":" \"${courseId}\", SanitizationHelper.sanitizeForHtml(course.getId()),"},{"lineNumber":184,"author":{"gitId":"-"},"content":" \"${feedbackSessionName}\", SanitizationHelper.sanitizeForHtml(session.getName()),"},{"lineNumber":185,"author":{"gitId":"-"},"content":" \"${deadline}\", SanitizationHelper.sanitizeForHtml("},{"lineNumber":186,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(endTime, session.getCourse().getTimeZone(), DATETIME_DISPLAY_FORMAT)),"},{"lineNumber":187,"author":{"gitId":"-"},"content":" \"${sessionInstructions}\", session.getInstructionsString(),"},{"lineNumber":188,"author":{"gitId":"-"},"content":" \"${startTime}\", SanitizationHelper.sanitizeForHtml("},{"lineNumber":189,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(startTime, session.getCourse().getTimeZone(), DATETIME_DISPLAY_FORMAT)),"},{"lineNumber":190,"author":{"gitId":"-"},"content":" \"${additionalNotes}\", additionalNotes);"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(coOwner.getEmail());"},{"lineNumber":193,"author":{"gitId":"-"},"content":" email.setType(emailType);"},{"lineNumber":194,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), session.getName());"},{"lineNumber":195,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":196,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":200,"author":{"gitId":"-"},"content":" * Generates the fragment for instructions on how to edit details for feedback session at {@code editUrl}."},{"lineNumber":201,"author":{"gitId":"-"},"content":" */"},{"lineNumber":202,"author":{"gitId":"-"},"content":" private String fillUpEditFeedbackSessionDetailsFragment(String editUrl) {"},{"lineNumber":203,"author":{"gitId":"-"},"content":" return Templates.populateTemplate(EmailTemplates.FRAGMENT_OPENING_SOON_EDIT_DETAILS,"},{"lineNumber":204,"author":{"gitId":"-"},"content":" \"${sessionEditUrl}\", editUrl);"},{"lineNumber":205,"author":{"gitId":"-"},"content":" }"},{"lineNumber":206,"author":{"gitId":"-"},"content":""},{"lineNumber":207,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":208,"author":{"gitId":"-"},"content":" * Generates the fragment for instructions on how to view responses for feedback session at {@code reportUrl}."},{"lineNumber":209,"author":{"gitId":"-"},"content":" */"},{"lineNumber":210,"author":{"gitId":"-"},"content":" private String fillUpViewResponsesDetailsFragment(String reportUrl) {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" return Templates.populateTemplate(EmailTemplates.FRAGMENT_CLOSED_VIEW_RESPONSES,"},{"lineNumber":212,"author":{"gitId":"-"},"content":" \"${reportUrl}\", reportUrl);"},{"lineNumber":213,"author":{"gitId":"-"},"content":" }"},{"lineNumber":214,"author":{"gitId":"-"},"content":""},{"lineNumber":215,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":216,"author":{"gitId":"-"},"content":" * Generates the fragment for instructions on how to edit details for feedback session at {@code editUrl} and"},{"lineNumber":217,"author":{"gitId":"-"},"content":" * how to join the course at {@code joinUrl}."},{"lineNumber":218,"author":{"gitId":"-"},"content":" */"},{"lineNumber":219,"author":{"gitId":"-"},"content":" private String fillUpJoinCourseBeforeEditFeedbackSessionDetailsFragment(String editUrl, String joinUrl) {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" return Templates.populateTemplate(EmailTemplates.FRAGMENT_OPENING_SOON_JOIN_COURSE_BEFORE_EDIT_DETAILS,"},{"lineNumber":221,"author":{"gitId":"-"},"content":" \"${sessionEditUrl}\", editUrl,"},{"lineNumber":222,"author":{"gitId":"-"},"content":" \"${joinUrl}\", joinUrl"},{"lineNumber":223,"author":{"gitId":"-"},"content":" );"},{"lineNumber":224,"author":{"gitId":"-"},"content":" }"},{"lineNumber":225,"author":{"gitId":"-"},"content":""},{"lineNumber":226,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":227,"author":{"gitId":"-"},"content":" * Generates the feedback session reminder emails for the given {@code session} for {@code students}"},{"lineNumber":228,"author":{"gitId":"-"},"content":" * and {@code instructorsToRemind}. In addition, the emails will also be forwarded to {@code instructorsToNotify}."},{"lineNumber":229,"author":{"gitId":"-"},"content":" */"},{"lineNumber":230,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateFeedbackSessionReminderEmails("},{"lineNumber":231,"author":{"gitId":"-"},"content":" FeedbackSession session, List\u003cStudent\u003e students,"},{"lineNumber":232,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorsToRemind, Instructor instructorToNotify) {"},{"lineNumber":233,"author":{"gitId":"-"},"content":""},{"lineNumber":234,"author":{"gitId":"-"},"content":" Course course \u003d session.getCourse();"},{"lineNumber":235,"author":{"gitId":"-"},"content":" String template \u003d EmailTemplates.USER_FEEDBACK_SESSION.replace(\"${status}\", FEEDBACK_STATUS_SESSION_OPEN);"},{"lineNumber":236,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorToNotifyAsList \u003d new ArrayList\u003c\u003e();"},{"lineNumber":237,"author":{"gitId":"-"},"content":" if (instructorToNotify !\u003d null) {"},{"lineNumber":238,"author":{"gitId":"-"},"content":" instructorToNotifyAsList.add(instructorToNotify);"},{"lineNumber":239,"author":{"gitId":"-"},"content":" }"},{"lineNumber":240,"author":{"gitId":"-"},"content":""},{"lineNumber":241,"author":{"gitId":"-"},"content":" return generateFeedbackSessionEmailBases(course, session, students, instructorsToRemind, instructorToNotifyAsList,"},{"lineNumber":242,"author":{"gitId":"-"},"content":" template, EmailType.FEEDBACK_SESSION_REMINDER, FEEDBACK_ACTION_SUBMIT_EDIT_OR_VIEW);"},{"lineNumber":243,"author":{"gitId":"-"},"content":" }"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":246,"author":{"gitId":"-"},"content":" * Generates the email containing the summary of the feedback sessions"},{"lineNumber":247,"author":{"gitId":"-"},"content":" * email for the given {@code courseId} for {@code userEmail}."},{"lineNumber":248,"author":{"gitId":"-"},"content":" * @param courseId - ID of the course"},{"lineNumber":249,"author":{"gitId":"-"},"content":" * @param userEmail - Email of student to send feedback session summary to"},{"lineNumber":250,"author":{"gitId":"-"},"content":" * @param emailType - The email type which corresponds to the reason behind why the links are being resent"},{"lineNumber":251,"author":{"gitId":"-"},"content":" */"},{"lineNumber":252,"author":{"gitId":"-"},"content":" public EmailWrapper generateFeedbackSessionSummaryOfCourse("},{"lineNumber":253,"author":{"gitId":"-"},"content":" String courseId, String userEmail, EmailType emailType) {"},{"lineNumber":254,"author":{"gitId":"-"},"content":" assert emailType \u003d\u003d EmailType.STUDENT_EMAIL_CHANGED"},{"lineNumber":255,"author":{"gitId":"-"},"content":" || emailType \u003d\u003d EmailType.STUDENT_COURSE_LINKS_REGENERATED"},{"lineNumber":256,"author":{"gitId":"-"},"content":" || emailType \u003d\u003d EmailType.INSTRUCTOR_COURSE_LINKS_REGENERATED;"},{"lineNumber":257,"author":{"gitId":"-"},"content":""},{"lineNumber":258,"author":{"gitId":"-"},"content":" Course course \u003d coursesLogic.getCourse(courseId);"},{"lineNumber":259,"author":{"gitId":"-"},"content":" boolean isInstructor \u003d emailType \u003d\u003d EmailType.INSTRUCTOR_COURSE_LINKS_REGENERATED;"},{"lineNumber":260,"author":{"gitId":"-"},"content":" Student student \u003d usersLogic.getStudentForEmail(courseId, userEmail);"},{"lineNumber":261,"author":{"gitId":"-"},"content":" Instructor instructor \u003d null;"},{"lineNumber":262,"author":{"gitId":"-"},"content":" if (isInstructor) {"},{"lineNumber":263,"author":{"gitId":"-"},"content":" instructor \u003d usersLogic.getInstructorForEmail(courseId, userEmail);"},{"lineNumber":264,"author":{"gitId":"-"},"content":" }"},{"lineNumber":265,"author":{"gitId":"-"},"content":""},{"lineNumber":266,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e sessions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":267,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e fsInCourse \u003d fsLogic.getFeedbackSessionsForCourse(courseId);"},{"lineNumber":268,"author":{"gitId":"-"},"content":""},{"lineNumber":269,"author":{"gitId":"-"},"content":" for (FeedbackSession fs : fsInCourse) {"},{"lineNumber":270,"author":{"gitId":"-"},"content":" if (fs.isOpenEmailSent() || fs.isPublishedEmailSent()) {"},{"lineNumber":271,"author":{"gitId":"-"},"content":" sessions.add(fs);"},{"lineNumber":272,"author":{"gitId":"-"},"content":" }"},{"lineNumber":273,"author":{"gitId":"-"},"content":" }"},{"lineNumber":274,"author":{"gitId":"-"},"content":""},{"lineNumber":275,"author":{"gitId":"-"},"content":" StringBuilder linksFragmentValue \u003d new StringBuilder(1000);"},{"lineNumber":276,"author":{"gitId":"-"},"content":" String joinUrl \u003d Config.getFrontEndAppUrl("},{"lineNumber":277,"author":{"gitId":"-"},"content":" isInstructor ? instructor.getRegistrationUrl() : student.getRegistrationUrl()).toAbsoluteString();"},{"lineNumber":278,"author":{"gitId":"-"},"content":" boolean isYetToJoinCourse \u003d isInstructor ? isYetToJoinCourse(instructor) : isYetToJoinCourse(student);"},{"lineNumber":279,"author":{"gitId":"-"},"content":" String joinFragmentTemplate \u003d isInstructor"},{"lineNumber":280,"author":{"gitId":"-"},"content":" ? EmailTemplates.FRAGMENT_INSTRUCTOR_COURSE_REJOIN_AFTER_REGKEY_RESET"},{"lineNumber":281,"author":{"gitId":"-"},"content":" : emailType \u003d\u003d EmailType.STUDENT_EMAIL_CHANGED"},{"lineNumber":282,"author":{"gitId":"-"},"content":" ? EmailTemplates.FRAGMENT_STUDENT_COURSE_JOIN"},{"lineNumber":283,"author":{"gitId":"-"},"content":" : EmailTemplates.FRAGMENT_STUDENT_COURSE_REJOIN_AFTER_REGKEY_RESET;"},{"lineNumber":284,"author":{"gitId":"-"},"content":""},{"lineNumber":285,"author":{"gitId":"-"},"content":" String joinFragmentValue \u003d isYetToJoinCourse"},{"lineNumber":286,"author":{"gitId":"-"},"content":" ? Templates.populateTemplate(joinFragmentTemplate,"},{"lineNumber":287,"author":{"gitId":"-"},"content":" \"${joinUrl}\", joinUrl,"},{"lineNumber":288,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":289,"author":{"gitId":"-"},"content":" \"${coOwnersEmails}\", generateCoOwnersEmailsLine(course.getId()),"},{"lineNumber":290,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL)"},{"lineNumber":291,"author":{"gitId":"-"},"content":" : \"\";"},{"lineNumber":292,"author":{"gitId":"-"},"content":""},{"lineNumber":293,"author":{"gitId":"-"},"content":" for (FeedbackSession fs : sessions) {"},{"lineNumber":294,"author":{"gitId":"-"},"content":" String submitUrlHtml \u003d \"(Feedback session is not yet opened)\";"},{"lineNumber":295,"author":{"gitId":"-"},"content":" String reportUrlHtml \u003d \"(Feedback session is not yet published)\";"},{"lineNumber":296,"author":{"gitId":"-"},"content":""},{"lineNumber":297,"author":{"gitId":"-"},"content":" String userKey \u003d isInstructor ? instructor.getRegKey() : student.getRegKey();"},{"lineNumber":298,"author":{"gitId":"-"},"content":""},{"lineNumber":299,"author":{"gitId":"-"},"content":" if (fs.isOpened() || fs.isClosed()) {"},{"lineNumber":300,"author":{"gitId":"-"},"content":" String submitUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSION_SUBMISSION_PAGE)"},{"lineNumber":301,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":302,"author":{"gitId":"-"},"content":" .withSessionName(fs.getName())"},{"lineNumber":303,"author":{"gitId":"-"},"content":" .withRegistrationKey(userKey)"},{"lineNumber":304,"author":{"gitId":"-"},"content":" .withEntityType(isInstructor ? Const.EntityType.INSTRUCTOR : \"\")"},{"lineNumber":305,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":306,"author":{"gitId":"-"},"content":" submitUrlHtml \u003d \"\u003ca href\u003d\\\"\" + submitUrl + \"\\\"\u003e\" + submitUrl + \"\u003c/a\u003e\";"},{"lineNumber":307,"author":{"gitId":"-"},"content":" }"},{"lineNumber":308,"author":{"gitId":"-"},"content":""},{"lineNumber":309,"author":{"gitId":"-"},"content":" if (fs.isPublished()) {"},{"lineNumber":310,"author":{"gitId":"-"},"content":" String reportUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSION_RESULTS_PAGE)"},{"lineNumber":311,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":312,"author":{"gitId":"-"},"content":" .withSessionName(fs.getName())"},{"lineNumber":313,"author":{"gitId":"-"},"content":" .withRegistrationKey(userKey)"},{"lineNumber":314,"author":{"gitId":"-"},"content":" .withEntityType(isInstructor ? Const.EntityType.INSTRUCTOR : \"\")"},{"lineNumber":315,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":316,"author":{"gitId":"-"},"content":" reportUrlHtml \u003d \"\u003ca href\u003d\\\"\" + reportUrl + \"\\\"\u003e\" + reportUrl + \"\u003c/a\u003e\";"},{"lineNumber":317,"author":{"gitId":"-"},"content":" }"},{"lineNumber":318,"author":{"gitId":"-"},"content":""},{"lineNumber":319,"author":{"gitId":"-"},"content":" Instant endTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":320,"author":{"gitId":"-"},"content":" fs.getEndTime(), fs.getCourse().getTimeZone(), false);"},{"lineNumber":321,"author":{"gitId":"-"},"content":" linksFragmentValue.append(Templates.populateTemplate("},{"lineNumber":322,"author":{"gitId":"-"},"content":" EmailTemplates.FRAGMENT_SINGLE_FEEDBACK_SESSION_LINKS,"},{"lineNumber":323,"author":{"gitId":"-"},"content":" \"${feedbackSessionName}\", fs.getName(),"},{"lineNumber":324,"author":{"gitId":"-"},"content":" \"${deadline}\", TimeHelper.formatInstant(endTime, fs.getCourse().getTimeZone(), DATETIME_DISPLAY_FORMAT)"},{"lineNumber":325,"author":{"gitId":"-"},"content":" + (fs.isClosed() ? \" (Passed)\" : \"\"),"},{"lineNumber":326,"author":{"gitId":"-"},"content":" \"${submitUrl}\", submitUrlHtml,"},{"lineNumber":327,"author":{"gitId":"-"},"content":" \"${reportUrl}\", reportUrlHtml));"},{"lineNumber":328,"author":{"gitId":"-"},"content":" }"},{"lineNumber":329,"author":{"gitId":"-"},"content":""},{"lineNumber":330,"author":{"gitId":"-"},"content":" if (linksFragmentValue.length() \u003d\u003d 0) {"},{"lineNumber":331,"author":{"gitId":"-"},"content":" linksFragmentValue.append(\"No links found.\");"},{"lineNumber":332,"author":{"gitId":"-"},"content":" }"},{"lineNumber":333,"author":{"gitId":"-"},"content":""},{"lineNumber":334,"author":{"gitId":"-"},"content":" String additionalContactInformation \u003d getAdditionalContactInformationFragment(course, isInstructor);"},{"lineNumber":335,"author":{"gitId":"-"},"content":" String resendLinksTemplate \u003d emailType \u003d\u003d EmailType.STUDENT_EMAIL_CHANGED"},{"lineNumber":336,"author":{"gitId":"-"},"content":" ? Templates.EmailTemplates.USER_FEEDBACK_SESSION_RESEND_ALL_LINKS"},{"lineNumber":337,"author":{"gitId":"-"},"content":" : Templates.EmailTemplates.USER_REGKEY_REGENERATION_RESEND_ALL_COURSE_LINKS;"},{"lineNumber":338,"author":{"gitId":"-"},"content":""},{"lineNumber":339,"author":{"gitId":"-"},"content":" String userName \u003d isInstructor ? instructor.getName() : student.getName();"},{"lineNumber":340,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate(resendLinksTemplate,"},{"lineNumber":341,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(userName),"},{"lineNumber":342,"author":{"gitId":"-"},"content":" \"${userEmail}\", userEmail,"},{"lineNumber":343,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":344,"author":{"gitId":"-"},"content":" \"${courseId}\", course.getId(),"},{"lineNumber":345,"author":{"gitId":"-"},"content":" \"${joinFragment}\", joinFragmentValue,"},{"lineNumber":346,"author":{"gitId":"-"},"content":" \"${linksFragment}\", linksFragmentValue.toString(),"},{"lineNumber":347,"author":{"gitId":"-"},"content":" \"${additionalContactInformation}\", additionalContactInformation);"},{"lineNumber":348,"author":{"gitId":"-"},"content":""},{"lineNumber":349,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(userEmail);"},{"lineNumber":350,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":351,"author":{"gitId":"-"},"content":" email.setType(emailType);"},{"lineNumber":352,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), course.getId());"},{"lineNumber":353,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":354,"author":{"gitId":"-"},"content":" }"},{"lineNumber":355,"author":{"gitId":"-"},"content":""},{"lineNumber":356,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":357,"author":{"gitId":"-"},"content":" * Generates for the student an recovery email listing the links to submit/view responses for all feedback sessions"},{"lineNumber":358,"author":{"gitId":"-"},"content":" * under {@code recoveryEmailAddress} in the past 180 days. If no student with {@code recoveryEmailAddress} is"},{"lineNumber":359,"author":{"gitId":"-"},"content":" * found, generate an email stating that there is no such student in the system. If no feedback sessions are found,"},{"lineNumber":360,"author":{"gitId":"-"},"content":" * generate an email stating no feedback sessions found."},{"lineNumber":361,"author":{"gitId":"-"},"content":" */"},{"lineNumber":362,"author":{"gitId":"-"},"content":" public EmailWrapper generateSessionLinksRecoveryEmailForStudent(String recoveryEmailAddress,"},{"lineNumber":363,"author":{"gitId":"-"},"content":" String studentNameFromDatastore, Map\u003cCourseAttributes, StringBuilder\u003e dataStoreLinkFragmentMap) {"},{"lineNumber":364,"author":{"gitId":"-"},"content":""},{"lineNumber":365,"author":{"gitId":"-"},"content":" // Datastore attributes should be removed once migration is completed"},{"lineNumber":366,"author":{"gitId":"-"},"content":" String emptyName \u003d \"\";"},{"lineNumber":367,"author":{"gitId":"-"},"content":" boolean noDataStoreStudent \u003d studentNameFromDatastore.equals(emptyName); // student name cannot be empty"},{"lineNumber":368,"author":{"gitId":"-"},"content":""},{"lineNumber":369,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e studentsForEmail \u003d usersLogic.getAllStudentsForEmail(recoveryEmailAddress);"},{"lineNumber":370,"author":{"gitId":"-"},"content":""},{"lineNumber":371,"author":{"gitId":"-"},"content":" if (studentsForEmail.isEmpty() \u0026\u0026 noDataStoreStudent) {"},{"lineNumber":372,"author":{"gitId":"-"},"content":" return generateSessionLinksRecoveryEmailForNonExistentStudent(recoveryEmailAddress);"},{"lineNumber":373,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":374,"author":{"gitId":"-"},"content":" return generateSessionLinksRecoveryEmailForExistingStudent(recoveryEmailAddress, studentsForEmail,"},{"lineNumber":375,"author":{"gitId":"-"},"content":" studentNameFromDatastore, dataStoreLinkFragmentMap);"},{"lineNumber":376,"author":{"gitId":"-"},"content":" }"},{"lineNumber":377,"author":{"gitId":"-"},"content":" }"},{"lineNumber":378,"author":{"gitId":"-"},"content":""},{"lineNumber":379,"author":{"gitId":"-"},"content":" private EmailWrapper generateSessionLinksRecoveryEmailForNonExistentStudent(String recoveryEmailAddress) {"},{"lineNumber":380,"author":{"gitId":"-"},"content":" String recoveryUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSIONS_LINK_RECOVERY_PAGE).toAbsoluteString();"},{"lineNumber":381,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate("},{"lineNumber":382,"author":{"gitId":"-"},"content":" EmailTemplates.SESSION_LINKS_RECOVERY_EMAIL_NOT_FOUND,"},{"lineNumber":383,"author":{"gitId":"-"},"content":" \"${userEmail}\", SanitizationHelper.sanitizeForHtml(recoveryEmailAddress),"},{"lineNumber":384,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL,"},{"lineNumber":385,"author":{"gitId":"-"},"content":" \"${teammateHomePageLink}\", Config.getFrontEndAppUrl(\"/\").toAbsoluteString(),"},{"lineNumber":386,"author":{"gitId":"-"},"content":" \"${sessionsRecoveryLink}\", recoveryUrl);"},{"lineNumber":387,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(recoveryEmailAddress);"},{"lineNumber":388,"author":{"gitId":"-"},"content":" email.setType(EmailType.SESSION_LINKS_RECOVERY);"},{"lineNumber":389,"author":{"gitId":"-"},"content":" email.setSubjectFromType();"},{"lineNumber":390,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":391,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":392,"author":{"gitId":"-"},"content":" }"},{"lineNumber":393,"author":{"gitId":"-"},"content":""},{"lineNumber":394,"author":{"gitId":"-"},"content":" private EmailWrapper generateSessionLinksRecoveryEmailForExistingStudent(String recoveryEmailAddress,"},{"lineNumber":395,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e studentsForEmail, String studentNameFromDatastore,"},{"lineNumber":396,"author":{"gitId":"-"},"content":" Map\u003cCourseAttributes, StringBuilder\u003e dataStoreLinkFragmentMap) {"},{"lineNumber":397,"author":{"gitId":"-"},"content":" assert !studentsForEmail.isEmpty() || studentNameFromDatastore !\u003d null;"},{"lineNumber":398,"author":{"gitId":"-"},"content":" int firstStudentIdx \u003d 0;"},{"lineNumber":399,"author":{"gitId":"-"},"content":""},{"lineNumber":400,"author":{"gitId":"-"},"content":" Map\u003cCourse, StringBuilder\u003e linkFragmentsMap \u003d generateLinkFragmentsMap(studentsForEmail);"},{"lineNumber":401,"author":{"gitId":"-"},"content":""},{"lineNumber":402,"author":{"gitId":"-"},"content":" String emailBody;"},{"lineNumber":403,"author":{"gitId":"-"},"content":""},{"lineNumber":404,"author":{"gitId":"-"},"content":" String studentName;"},{"lineNumber":405,"author":{"gitId":"-"},"content":""},{"lineNumber":406,"author":{"gitId":"-"},"content":" if (studentsForEmail.isEmpty()) {"},{"lineNumber":407,"author":{"gitId":"-"},"content":" studentName \u003d studentNameFromDatastore;"},{"lineNumber":408,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":409,"author":{"gitId":"-"},"content":" studentName \u003d studentsForEmail.get(firstStudentIdx).getName();"},{"lineNumber":410,"author":{"gitId":"-"},"content":" }"},{"lineNumber":411,"author":{"gitId":"-"},"content":""},{"lineNumber":412,"author":{"gitId":"-"},"content":" var recoveryUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSIONS_LINK_RECOVERY_PAGE).toAbsoluteString();"},{"lineNumber":413,"author":{"gitId":"-"},"content":""},{"lineNumber":414,"author":{"gitId":"-"},"content":" if (linkFragmentsMap.isEmpty() \u0026\u0026 dataStoreLinkFragmentMap.isEmpty()) {"},{"lineNumber":415,"author":{"gitId":"-"},"content":" emailBody \u003d Templates.populateTemplate("},{"lineNumber":416,"author":{"gitId":"-"},"content":" EmailTemplates.SESSION_LINKS_RECOVERY_ACCESS_LINKS_NONE,"},{"lineNumber":417,"author":{"gitId":"-"},"content":" \"${teammateHomePageLink}\", Config.getFrontEndAppUrl(\"/\").toAbsoluteString(),"},{"lineNumber":418,"author":{"gitId":"-"},"content":" \"${userEmail}\", SanitizationHelper.sanitizeForHtml(recoveryEmailAddress),"},{"lineNumber":419,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL,"},{"lineNumber":420,"author":{"gitId":"-"},"content":" \"${sessionsRecoveryLink}\", recoveryUrl);"},{"lineNumber":421,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":422,"author":{"gitId":"-"},"content":" var courseFragments \u003d new StringBuilder(10000);"},{"lineNumber":423,"author":{"gitId":"-"},"content":" linkFragmentsMap.forEach((course, linksFragments) -\u003e {"},{"lineNumber":424,"author":{"gitId":"-"},"content":" String courseBody \u003d Templates.populateTemplate("},{"lineNumber":425,"author":{"gitId":"-"},"content":" EmailTemplates.FRAGMENT_SESSION_LINKS_RECOVERY_ACCESS_LINKS_BY_COURSE,"},{"lineNumber":426,"author":{"gitId":"-"},"content":" \"${sessionFragment}\", linksFragments.toString(),"},{"lineNumber":427,"author":{"gitId":"-"},"content":" \"${courseName}\", course.getName());"},{"lineNumber":428,"author":{"gitId":"-"},"content":" courseFragments.append(courseBody);"},{"lineNumber":429,"author":{"gitId":"-"},"content":" });"},{"lineNumber":430,"author":{"gitId":"-"},"content":""},{"lineNumber":431,"author":{"gitId":"-"},"content":" // To remove after migrating to postgres"},{"lineNumber":432,"author":{"gitId":"-"},"content":" dataStoreLinkFragmentMap.forEach((course, linksFragments) -\u003e {"},{"lineNumber":433,"author":{"gitId":"-"},"content":" String courseBody \u003d Templates.populateTemplate("},{"lineNumber":434,"author":{"gitId":"-"},"content":" EmailTemplates.FRAGMENT_SESSION_LINKS_RECOVERY_ACCESS_LINKS_BY_COURSE,"},{"lineNumber":435,"author":{"gitId":"-"},"content":" \"${sessionFragment}\", linksFragments.toString(),"},{"lineNumber":436,"author":{"gitId":"-"},"content":" \"${courseName}\", course.getName());"},{"lineNumber":437,"author":{"gitId":"-"},"content":" courseFragments.append(courseBody);"},{"lineNumber":438,"author":{"gitId":"-"},"content":" });"},{"lineNumber":439,"author":{"gitId":"-"},"content":" emailBody \u003d Templates.populateTemplate("},{"lineNumber":440,"author":{"gitId":"-"},"content":" EmailTemplates.SESSION_LINKS_RECOVERY_ACCESS_LINKS,"},{"lineNumber":441,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(studentName),"},{"lineNumber":442,"author":{"gitId":"-"},"content":" \"${linksFragment}\", courseFragments.toString(),"},{"lineNumber":443,"author":{"gitId":"-"},"content":" \"${userEmail}\", SanitizationHelper.sanitizeForHtml(recoveryEmailAddress),"},{"lineNumber":444,"author":{"gitId":"-"},"content":" \"${teammateHomePageLink}\", Config.getFrontEndAppUrl(\"/\").toAbsoluteString(),"},{"lineNumber":445,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL,"},{"lineNumber":446,"author":{"gitId":"-"},"content":" \"${sessionsRecoveryLink}\", recoveryUrl);"},{"lineNumber":447,"author":{"gitId":"-"},"content":" }"},{"lineNumber":448,"author":{"gitId":"-"},"content":""},{"lineNumber":449,"author":{"gitId":"-"},"content":" var email \u003d getEmptyEmailAddressedToEmail(recoveryEmailAddress);"},{"lineNumber":450,"author":{"gitId":"-"},"content":" email.setType(EmailType.SESSION_LINKS_RECOVERY);"},{"lineNumber":451,"author":{"gitId":"-"},"content":" email.setSubjectFromType();"},{"lineNumber":452,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":453,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":454,"author":{"gitId":"-"},"content":" }"},{"lineNumber":455,"author":{"gitId":"-"},"content":""},{"lineNumber":456,"author":{"gitId":"-"},"content":" private Map\u003cCourse, StringBuilder\u003e generateLinkFragmentsMap(List\u003cStudent\u003e studentsForEmail) {"},{"lineNumber":457,"author":{"gitId":"-"},"content":" Instant searchStartTime \u003d TimeHelper.getInstantDaysOffsetBeforeNow(SESSION_LINK_RECOVERY_DURATION_IN_DAYS);"},{"lineNumber":458,"author":{"gitId":"-"},"content":" Map\u003cCourse, StringBuilder\u003e linkFragmentsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":459,"author":{"gitId":"-"},"content":""},{"lineNumber":460,"author":{"gitId":"-"},"content":" for (var student : studentsForEmail) {"},{"lineNumber":461,"author":{"gitId":"-"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":462,"author":{"gitId":"-"},"content":" // Query students\u0027 courses first"},{"lineNumber":463,"author":{"gitId":"-"},"content":" // as a student will likely be in only a small number of courses."},{"lineNumber":464,"author":{"gitId":"-"},"content":" Course course \u003d student.getCourse();"},{"lineNumber":465,"author":{"gitId":"-"},"content":" String courseId \u003d course.getId();"},{"lineNumber":466,"author":{"gitId":"-"},"content":""},{"lineNumber":467,"author":{"gitId":"-"},"content":" StringBuilder linksFragmentValue;"},{"lineNumber":468,"author":{"gitId":"-"},"content":" if (linkFragmentsMap.containsKey(course)) {"},{"lineNumber":469,"author":{"gitId":"-"},"content":" linksFragmentValue \u003d linkFragmentsMap.get(course);"},{"lineNumber":470,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":471,"author":{"gitId":"-"},"content":" linksFragmentValue \u003d new StringBuilder(5000);"},{"lineNumber":472,"author":{"gitId":"-"},"content":" }"},{"lineNumber":473,"author":{"gitId":"-"},"content":""},{"lineNumber":474,"author":{"gitId":"-"},"content":" for (var session : fsLogic.getFeedbackSessionsForCourseStartingAfter(courseId, searchStartTime)) {"},{"lineNumber":475,"author":{"gitId":"-"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":476,"author":{"gitId":"-"},"content":" var submitUrlHtml \u003d \"\";"},{"lineNumber":477,"author":{"gitId":"-"},"content":" var reportUrlHtml \u003d \"\";"},{"lineNumber":478,"author":{"gitId":"-"},"content":""},{"lineNumber":479,"author":{"gitId":"-"},"content":" if (session.isOpened() || session.isClosed()) {"},{"lineNumber":480,"author":{"gitId":"-"},"content":" var submitUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSION_SUBMISSION_PAGE)"},{"lineNumber":481,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":482,"author":{"gitId":"-"},"content":" .withSessionName(session.getName())"},{"lineNumber":483,"author":{"gitId":"-"},"content":" .withRegistrationKey(student.getRegKey())"},{"lineNumber":484,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":485,"author":{"gitId":"-"},"content":" submitUrlHtml \u003d \"[\u003ca href\u003d\\\"\" + submitUrl + \"\\\"\u003esubmission link\u003c/a\u003e]\";"},{"lineNumber":486,"author":{"gitId":"-"},"content":" }"},{"lineNumber":487,"author":{"gitId":"-"},"content":""},{"lineNumber":488,"author":{"gitId":"-"},"content":" if (session.isPublished()) {"},{"lineNumber":489,"author":{"gitId":"-"},"content":" var reportUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSION_RESULTS_PAGE)"},{"lineNumber":490,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":491,"author":{"gitId":"-"},"content":" .withSessionName(session.getName())"},{"lineNumber":492,"author":{"gitId":"-"},"content":" .withRegistrationKey(student.getRegKey())"},{"lineNumber":493,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":494,"author":{"gitId":"-"},"content":" reportUrlHtml \u003d \"[\u003ca href\u003d\\\"\" + reportUrl + \"\\\"\u003eresult link\u003c/a\u003e]\";"},{"lineNumber":495,"author":{"gitId":"-"},"content":" }"},{"lineNumber":496,"author":{"gitId":"-"},"content":""},{"lineNumber":497,"author":{"gitId":"-"},"content":" if (submitUrlHtml.isEmpty() \u0026\u0026 reportUrlHtml.isEmpty()) {"},{"lineNumber":498,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":499,"author":{"gitId":"-"},"content":" }"},{"lineNumber":500,"author":{"gitId":"-"},"content":""},{"lineNumber":501,"author":{"gitId":"-"},"content":" linksFragmentValue.append(Templates.populateTemplate("},{"lineNumber":502,"author":{"gitId":"-"},"content":" EmailTemplates.FRAGMENT_SESSION_LINKS_RECOVERY_ACCESS_LINKS_BY_SESSION,"},{"lineNumber":503,"author":{"gitId":"-"},"content":" \"${sessionName}\", session.getName(),"},{"lineNumber":504,"author":{"gitId":"-"},"content":" \"${submitUrl}\", submitUrlHtml,"},{"lineNumber":505,"author":{"gitId":"-"},"content":" \"${reportUrl}\", reportUrlHtml));"},{"lineNumber":506,"author":{"gitId":"-"},"content":""},{"lineNumber":507,"author":{"gitId":"-"},"content":" linkFragmentsMap.putIfAbsent(course, linksFragmentValue);"},{"lineNumber":508,"author":{"gitId":"-"},"content":" }"},{"lineNumber":509,"author":{"gitId":"-"},"content":" }"},{"lineNumber":510,"author":{"gitId":"-"},"content":" return linkFragmentsMap;"},{"lineNumber":511,"author":{"gitId":"-"},"content":""},{"lineNumber":512,"author":{"gitId":"-"},"content":" }"},{"lineNumber":513,"author":{"gitId":"-"},"content":""},{"lineNumber":514,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":515,"author":{"gitId":"-"},"content":" * Generates the feedback session closing emails for the given {@code session}."},{"lineNumber":516,"author":{"gitId":"-"},"content":" *"},{"lineNumber":517,"author":{"gitId":"-"},"content":" * \u003cp\u003eStudents and instructors with deadline extensions are not notified."},{"lineNumber":518,"author":{"gitId":"-"},"content":" */"},{"lineNumber":519,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateFeedbackSessionClosingEmails(FeedbackSession session) {"},{"lineNumber":520,"author":{"gitId":"-"},"content":" return generateFeedbackSessionOpeningOrClosingEmails(session, EmailType.FEEDBACK_CLOSING);"},{"lineNumber":521,"author":{"gitId":"-"},"content":" }"},{"lineNumber":522,"author":{"gitId":"-"},"content":""},{"lineNumber":523,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":524,"author":{"gitId":"-"},"content":" * Generates the feedback session closed emails for the given {@code session}."},{"lineNumber":525,"author":{"gitId":"-"},"content":" */"},{"lineNumber":526,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateFeedbackSessionClosedEmails(FeedbackSession session) {"},{"lineNumber":527,"author":{"gitId":"-"},"content":" return generateFeedbackSessionOpeningSoonOrClosedEmails(session, EmailType.FEEDBACK_CLOSED);"},{"lineNumber":528,"author":{"gitId":"-"},"content":" }"},{"lineNumber":529,"author":{"gitId":"-"},"content":""},{"lineNumber":530,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":531,"author":{"gitId":"-"},"content":" * Generates the feedback session closing emails for users with deadline extensions."},{"lineNumber":532,"author":{"gitId":"-"},"content":" */"},{"lineNumber":533,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateFeedbackSessionClosingWithExtensionEmails("},{"lineNumber":534,"author":{"gitId":"-"},"content":" FeedbackSession session, List\u003cDeadlineExtension\u003e deadlineExtensions) {"},{"lineNumber":535,"author":{"gitId":"-"},"content":" Course course \u003d session.getCourse();"},{"lineNumber":536,"author":{"gitId":"-"},"content":""},{"lineNumber":537,"author":{"gitId":"-"},"content":" boolean isEmailNeededForStudents \u003d"},{"lineNumber":538,"author":{"gitId":"-"},"content":" !deadlineExtensions.isEmpty() \u0026\u0026 fsLogic.isFeedbackSessionForUserTypeToAnswer(session, false);"},{"lineNumber":539,"author":{"gitId":"-"},"content":" boolean isEmailNeededForInstructors \u003d"},{"lineNumber":540,"author":{"gitId":"-"},"content":" !deadlineExtensions.isEmpty() \u0026\u0026 fsLogic.isFeedbackSessionForUserTypeToAnswer(session, true);"},{"lineNumber":541,"author":{"gitId":"-"},"content":""},{"lineNumber":542,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e students \u003d new ArrayList\u003c\u003e();"},{"lineNumber":543,"author":{"gitId":"-"},"content":" if (isEmailNeededForStudents) {"},{"lineNumber":544,"author":{"gitId":"-"},"content":" for (DeadlineExtension de : deadlineExtensions) {"},{"lineNumber":545,"author":{"gitId":"-"},"content":" Student student \u003d usersLogic.getStudentForEmail(course.getId(), de.getUser().getEmail());"},{"lineNumber":546,"author":{"gitId":"-"},"content":" if (student !\u003d null) {"},{"lineNumber":547,"author":{"gitId":"-"},"content":" students.add(student);"},{"lineNumber":548,"author":{"gitId":"-"},"content":" }"},{"lineNumber":549,"author":{"gitId":"-"},"content":" }"},{"lineNumber":550,"author":{"gitId":"-"},"content":" }"},{"lineNumber":551,"author":{"gitId":"-"},"content":""},{"lineNumber":552,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors \u003d new ArrayList\u003c\u003e();"},{"lineNumber":553,"author":{"gitId":"-"},"content":" if (isEmailNeededForInstructors) {"},{"lineNumber":554,"author":{"gitId":"-"},"content":" for (DeadlineExtension de : deadlineExtensions) {"},{"lineNumber":555,"author":{"gitId":"-"},"content":" Instructor instructor \u003d"},{"lineNumber":556,"author":{"gitId":"-"},"content":" usersLogic.getInstructorForEmail(course.getId(), de.getUser().getEmail());"},{"lineNumber":557,"author":{"gitId":"-"},"content":" if (instructor !\u003d null) {"},{"lineNumber":558,"author":{"gitId":"-"},"content":" instructors.add(instructor);"},{"lineNumber":559,"author":{"gitId":"-"},"content":" }"},{"lineNumber":560,"author":{"gitId":"-"},"content":" }"},{"lineNumber":561,"author":{"gitId":"-"},"content":" }"},{"lineNumber":562,"author":{"gitId":"-"},"content":""},{"lineNumber":563,"author":{"gitId":"-"},"content":" String template \u003d EmailTemplates.USER_FEEDBACK_SESSION.replace(\"${status}\", FEEDBACK_STATUS_SESSION_CLOSING);"},{"lineNumber":564,"author":{"gitId":"-"},"content":" EmailType type \u003d EmailType.FEEDBACK_CLOSING;"},{"lineNumber":565,"author":{"gitId":"-"},"content":" String feedbackAction \u003d FEEDBACK_ACTION_SUBMIT_EDIT_OR_VIEW;"},{"lineNumber":566,"author":{"gitId":"-"},"content":" List\u003cEmailWrapper\u003e emails \u003d new ArrayList\u003c\u003e();"},{"lineNumber":567,"author":{"gitId":"-"},"content":" for (Student student : students) {"},{"lineNumber":568,"author":{"gitId":"-"},"content":" emails.addAll(generateFeedbackSessionEmailBases(course, session, Collections.singletonList(student),"},{"lineNumber":569,"author":{"gitId":"-"},"content":" Collections.emptyList(), Collections.emptyList(), template, type, feedbackAction));"},{"lineNumber":570,"author":{"gitId":"-"},"content":" }"},{"lineNumber":571,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructors) {"},{"lineNumber":572,"author":{"gitId":"-"},"content":" emails.addAll(generateFeedbackSessionEmailBases(course, session, Collections.emptyList(),"},{"lineNumber":573,"author":{"gitId":"-"},"content":" Collections.singletonList(instructor), Collections.emptyList(), template, type, feedbackAction));"},{"lineNumber":574,"author":{"gitId":"-"},"content":" }"},{"lineNumber":575,"author":{"gitId":"-"},"content":" return emails;"},{"lineNumber":576,"author":{"gitId":"-"},"content":" }"},{"lineNumber":577,"author":{"gitId":"-"},"content":""},{"lineNumber":578,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":579,"author":{"gitId":"-"},"content":" * Generates the feedback session published emails for the given {@code session}."},{"lineNumber":580,"author":{"gitId":"-"},"content":" */"},{"lineNumber":581,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateFeedbackSessionPublishedEmails(FeedbackSession session) {"},{"lineNumber":582,"author":{"gitId":"-"},"content":" return generateFeedbackSessionPublishedOrUnpublishedEmails(session, EmailType.FEEDBACK_PUBLISHED);"},{"lineNumber":583,"author":{"gitId":"-"},"content":" }"},{"lineNumber":584,"author":{"gitId":"-"},"content":""},{"lineNumber":585,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":586,"author":{"gitId":"-"},"content":" * Generates the feedback session published emails for the given {@code students} and"},{"lineNumber":587,"author":{"gitId":"-"},"content":" * {@code instructors} in {@code session}."},{"lineNumber":588,"author":{"gitId":"-"},"content":" */"},{"lineNumber":589,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateFeedbackSessionPublishedEmails(FeedbackSession session,"},{"lineNumber":590,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e students, List\u003cInstructor\u003e instructors,"},{"lineNumber":591,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorsToNotify) {"},{"lineNumber":592,"author":{"gitId":"-"},"content":" return generateFeedbackSessionPublishedOrUnpublishedEmails("},{"lineNumber":593,"author":{"gitId":"-"},"content":" session, students, instructors, instructorsToNotify, EmailType.FEEDBACK_PUBLISHED);"},{"lineNumber":594,"author":{"gitId":"-"},"content":" }"},{"lineNumber":595,"author":{"gitId":"-"},"content":""},{"lineNumber":596,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":597,"author":{"gitId":"-"},"content":" * Generates the feedback session unpublished emails for the given {@code session}."},{"lineNumber":598,"author":{"gitId":"-"},"content":" */"},{"lineNumber":599,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateFeedbackSessionUnpublishedEmails(FeedbackSession session) {"},{"lineNumber":600,"author":{"gitId":"-"},"content":" return generateFeedbackSessionPublishedOrUnpublishedEmails(session, EmailType.FEEDBACK_UNPUBLISHED);"},{"lineNumber":601,"author":{"gitId":"-"},"content":" }"},{"lineNumber":602,"author":{"gitId":"-"},"content":""},{"lineNumber":603,"author":{"gitId":"-"},"content":" private List\u003cEmailWrapper\u003e generateFeedbackSessionPublishedOrUnpublishedEmails("},{"lineNumber":604,"author":{"gitId":"-"},"content":" FeedbackSession session, EmailType emailType) {"},{"lineNumber":605,"author":{"gitId":"-"},"content":" boolean isEmailNeededForStudents \u003d fsLogic.isFeedbackSessionViewableToUserType(session, false);"},{"lineNumber":606,"author":{"gitId":"-"},"content":" boolean isEmailNeededForInstructors \u003d fsLogic.isFeedbackSessionViewableToUserType(session, true);"},{"lineNumber":607,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorsToNotify \u003d isEmailNeededForStudents"},{"lineNumber":608,"author":{"gitId":"-"},"content":" ? usersLogic.getCoOwnersForCourse(session.getCourse().getId())"},{"lineNumber":609,"author":{"gitId":"-"},"content":" : new ArrayList\u003c\u003e();"},{"lineNumber":610,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e students \u003d isEmailNeededForStudents"},{"lineNumber":611,"author":{"gitId":"-"},"content":" ? usersLogic.getStudentsForCourse(session.getCourse().getId())"},{"lineNumber":612,"author":{"gitId":"-"},"content":" : new ArrayList\u003c\u003e();"},{"lineNumber":613,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors \u003d isEmailNeededForInstructors"},{"lineNumber":614,"author":{"gitId":"-"},"content":" ? usersLogic.getInstructorsForCourse(session.getCourse().getId())"},{"lineNumber":615,"author":{"gitId":"-"},"content":" : new ArrayList\u003c\u003e();"},{"lineNumber":616,"author":{"gitId":"-"},"content":""},{"lineNumber":617,"author":{"gitId":"-"},"content":" return generateFeedbackSessionPublishedOrUnpublishedEmails("},{"lineNumber":618,"author":{"gitId":"-"},"content":" session, students, instructors, instructorsToNotify, emailType);"},{"lineNumber":619,"author":{"gitId":"-"},"content":" }"},{"lineNumber":620,"author":{"gitId":"-"},"content":""},{"lineNumber":621,"author":{"gitId":"-"},"content":" private List\u003cEmailWrapper\u003e generateFeedbackSessionPublishedOrUnpublishedEmails("},{"lineNumber":622,"author":{"gitId":"-"},"content":" FeedbackSession session, List\u003cStudent\u003e students,"},{"lineNumber":623,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors, List\u003cInstructor\u003e instructorsToNotify, EmailType emailType) {"},{"lineNumber":624,"author":{"gitId":"-"},"content":" Course course \u003d session.getCourse();"},{"lineNumber":625,"author":{"gitId":"-"},"content":" String template;"},{"lineNumber":626,"author":{"gitId":"-"},"content":" String action;"},{"lineNumber":627,"author":{"gitId":"-"},"content":" if (emailType \u003d\u003d EmailType.FEEDBACK_PUBLISHED) {"},{"lineNumber":628,"author":{"gitId":"-"},"content":" template \u003d EmailTemplates.USER_FEEDBACK_SESSION_PUBLISHED;"},{"lineNumber":629,"author":{"gitId":"-"},"content":" action \u003d FEEDBACK_ACTION_VIEW;"},{"lineNumber":630,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":631,"author":{"gitId":"-"},"content":" template \u003d EmailTemplates.USER_FEEDBACK_SESSION_UNPUBLISHED;"},{"lineNumber":632,"author":{"gitId":"-"},"content":" action \u003d FEEDBACK_ACTION_SUBMIT_EDIT_OR_VIEW;"},{"lineNumber":633,"author":{"gitId":"-"},"content":" }"},{"lineNumber":634,"author":{"gitId":"-"},"content":""},{"lineNumber":635,"author":{"gitId":"-"},"content":" return generateFeedbackSessionEmailBases(course, session, students, instructors, instructorsToNotify, template,"},{"lineNumber":636,"author":{"gitId":"-"},"content":" emailType, action);"},{"lineNumber":637,"author":{"gitId":"-"},"content":" }"},{"lineNumber":638,"author":{"gitId":"-"},"content":""},{"lineNumber":639,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":640,"author":{"gitId":"-"},"content":" * Generates deadline extension granted emails."},{"lineNumber":641,"author":{"gitId":"-"},"content":" */"},{"lineNumber":642,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateDeadlineGrantedEmails(Course course,"},{"lineNumber":643,"author":{"gitId":"-"},"content":" FeedbackSession session, Map\u003cString, Instant\u003e createdDeadlines, boolean areInstructors) {"},{"lineNumber":644,"author":{"gitId":"-"},"content":" return createdDeadlines.entrySet()"},{"lineNumber":645,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":646,"author":{"gitId":"-"},"content":" .map(entry -\u003e"},{"lineNumber":647,"author":{"gitId":"-"},"content":" generateDeadlineExtensionEmail(course, session,"},{"lineNumber":648,"author":{"gitId":"-"},"content":" session.getEndTime(), entry.getValue(), EmailType.DEADLINE_EXTENSION_GRANTED,"},{"lineNumber":649,"author":{"gitId":"-"},"content":" entry.getKey(), areInstructors))"},{"lineNumber":650,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":651,"author":{"gitId":"-"},"content":" }"},{"lineNumber":652,"author":{"gitId":"-"},"content":""},{"lineNumber":653,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":654,"author":{"gitId":"-"},"content":" * Generates deadline extension updated emails."},{"lineNumber":655,"author":{"gitId":"-"},"content":" */"},{"lineNumber":656,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateDeadlineUpdatedEmails(Course course, FeedbackSession session,"},{"lineNumber":657,"author":{"gitId":"-"},"content":" Map\u003cString, Instant\u003e updatedDeadlines, Map\u003cString, Instant\u003e oldDeadlines, boolean areInstructors) {"},{"lineNumber":658,"author":{"gitId":"-"},"content":" return updatedDeadlines.entrySet()"},{"lineNumber":659,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":660,"author":{"gitId":"-"},"content":" .map(entry -\u003e"},{"lineNumber":661,"author":{"gitId":"-"},"content":" generateDeadlineExtensionEmail(course, session,"},{"lineNumber":662,"author":{"gitId":"-"},"content":" oldDeadlines.get(entry.getKey()), entry.getValue(), EmailType.DEADLINE_EXTENSION_UPDATED,"},{"lineNumber":663,"author":{"gitId":"-"},"content":" entry.getKey(), areInstructors))"},{"lineNumber":664,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":665,"author":{"gitId":"-"},"content":" }"},{"lineNumber":666,"author":{"gitId":"-"},"content":""},{"lineNumber":667,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":668,"author":{"gitId":"-"},"content":" * Generates deadline extension revoked emails."},{"lineNumber":669,"author":{"gitId":"-"},"content":" */"},{"lineNumber":670,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateDeadlineRevokedEmails(Course course,"},{"lineNumber":671,"author":{"gitId":"-"},"content":" FeedbackSession session, Map\u003cString, Instant\u003e revokedDeadlines, boolean areInstructors) {"},{"lineNumber":672,"author":{"gitId":"-"},"content":" return revokedDeadlines.entrySet()"},{"lineNumber":673,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":674,"author":{"gitId":"-"},"content":" .map(entry -\u003e"},{"lineNumber":675,"author":{"gitId":"-"},"content":" generateDeadlineExtensionEmail(course, session,"},{"lineNumber":676,"author":{"gitId":"-"},"content":" entry.getValue(), session.getEndTime(), EmailType.DEADLINE_EXTENSION_REVOKED,"},{"lineNumber":677,"author":{"gitId":"-"},"content":" entry.getKey(), areInstructors))"},{"lineNumber":678,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":679,"author":{"gitId":"-"},"content":" }"},{"lineNumber":680,"author":{"gitId":"-"},"content":""},{"lineNumber":681,"author":{"gitId":"-"},"content":" private EmailWrapper generateDeadlineExtensionEmail("},{"lineNumber":682,"author":{"gitId":"-"},"content":" Course course, FeedbackSession session, Instant oldEndTime, Instant endTime,"},{"lineNumber":683,"author":{"gitId":"-"},"content":" EmailType emailType, String userEmail, boolean isInstructor) {"},{"lineNumber":684,"author":{"gitId":"-"},"content":" String status;"},{"lineNumber":685,"author":{"gitId":"-"},"content":""},{"lineNumber":686,"author":{"gitId":"-"},"content":" switch (emailType) {"},{"lineNumber":687,"author":{"gitId":"-"},"content":" case DEADLINE_EXTENSION_GRANTED:"},{"lineNumber":688,"author":{"gitId":"-"},"content":" status \u003d \"You have been granted a deadline extension for the following feedback session.\";"},{"lineNumber":689,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":690,"author":{"gitId":"-"},"content":" case DEADLINE_EXTENSION_UPDATED:"},{"lineNumber":691,"author":{"gitId":"-"},"content":" status \u003d \"Your deadline for the following feedback session has been updated.\";"},{"lineNumber":692,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":693,"author":{"gitId":"-"},"content":" case DEADLINE_EXTENSION_REVOKED:"},{"lineNumber":694,"author":{"gitId":"-"},"content":" status \u003d \"Your deadline extension for the following feedback session has been revoked.\";"},{"lineNumber":695,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":696,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":697,"author":{"gitId":"-"},"content":" throw new AssertionError(\"Invalid email type: \" + emailType);"},{"lineNumber":698,"author":{"gitId":"-"},"content":" }"},{"lineNumber":699,"author":{"gitId":"-"},"content":""},{"lineNumber":700,"author":{"gitId":"-"},"content":" String additionalContactInformation \u003d getAdditionalContactInformationFragment(course, isInstructor);"},{"lineNumber":701,"author":{"gitId":"-"},"content":" Instant oldEndTimeFormatted \u003d"},{"lineNumber":702,"author":{"gitId":"-"},"content":" TimeHelper.getMidnightAdjustedInstantBasedOnZone(oldEndTime, session.getCourse().getTimeZone(), false);"},{"lineNumber":703,"author":{"gitId":"-"},"content":" Instant newEndTimeFormatted \u003d"},{"lineNumber":704,"author":{"gitId":"-"},"content":" TimeHelper.getMidnightAdjustedInstantBasedOnZone(endTime, session.getCourse().getTimeZone(), false);"},{"lineNumber":705,"author":{"gitId":"-"},"content":" String template \u003d EmailTemplates.USER_DEADLINE_EXTENSION"},{"lineNumber":706,"author":{"gitId":"-"},"content":" .replace(\"${status}\", status)"},{"lineNumber":707,"author":{"gitId":"-"},"content":" .replace(\"${oldEndTime}\", SanitizationHelper.sanitizeForHtml("},{"lineNumber":708,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(oldEndTimeFormatted,"},{"lineNumber":709,"author":{"gitId":"-"},"content":" session.getCourse().getTimeZone(), DATETIME_DISPLAY_FORMAT)))"},{"lineNumber":710,"author":{"gitId":"-"},"content":" .replace(\"${newEndTime}\", SanitizationHelper.sanitizeForHtml("},{"lineNumber":711,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(newEndTimeFormatted,"},{"lineNumber":712,"author":{"gitId":"-"},"content":" session.getCourse().getTimeZone(), DATETIME_DISPLAY_FORMAT)));"},{"lineNumber":713,"author":{"gitId":"-"},"content":" String feedbackAction \u003d FEEDBACK_ACTION_SUBMIT_EDIT_OR_VIEW;"},{"lineNumber":714,"author":{"gitId":"-"},"content":""},{"lineNumber":715,"author":{"gitId":"-"},"content":" if (isInstructor) {"},{"lineNumber":716,"author":{"gitId":"-"},"content":" Instructor instructor \u003d usersLogic.getInstructorForEmail(course.getId(), userEmail);"},{"lineNumber":717,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":718,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":719,"author":{"gitId":"-"},"content":" }"},{"lineNumber":720,"author":{"gitId":"-"},"content":" return generateFeedbackSessionEmailBaseForInstructors("},{"lineNumber":721,"author":{"gitId":"-"},"content":" course, session, instructor, template, emailType, feedbackAction, additionalContactInformation);"},{"lineNumber":722,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":723,"author":{"gitId":"-"},"content":" Student student \u003d usersLogic.getStudentForEmail(course.getId(), userEmail);"},{"lineNumber":724,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":725,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":726,"author":{"gitId":"-"},"content":" }"},{"lineNumber":727,"author":{"gitId":"-"},"content":" return generateFeedbackSessionEmailBaseForStudents("},{"lineNumber":728,"author":{"gitId":"-"},"content":" course, session, student, template, emailType, feedbackAction, additionalContactInformation);"},{"lineNumber":729,"author":{"gitId":"-"},"content":" }"},{"lineNumber":730,"author":{"gitId":"-"},"content":" }"},{"lineNumber":731,"author":{"gitId":"-"},"content":""},{"lineNumber":732,"author":{"gitId":"-"},"content":" private List\u003cEmailWrapper\u003e generateFeedbackSessionEmailBases("},{"lineNumber":733,"author":{"gitId":"-"},"content":" Course course, FeedbackSession session, List\u003cStudent\u003e students,"},{"lineNumber":734,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors, List\u003cInstructor\u003e instructorsToNotify, String template,"},{"lineNumber":735,"author":{"gitId":"-"},"content":" EmailType type, String feedbackAction) {"},{"lineNumber":736,"author":{"gitId":"-"},"content":" StringBuilder studentAdditionalContactBuilder \u003d new StringBuilder();"},{"lineNumber":737,"author":{"gitId":"-"},"content":" StringBuilder instructorAdditionalContactBuilder \u003d new StringBuilder();"},{"lineNumber":738,"author":{"gitId":"-"},"content":" studentAdditionalContactBuilder.append(getAdditionalContactInformationFragment(course, false));"},{"lineNumber":739,"author":{"gitId":"-"},"content":" instructorAdditionalContactBuilder.append(getAdditionalContactInformationFragment(course, true));"},{"lineNumber":740,"author":{"gitId":"-"},"content":""},{"lineNumber":741,"author":{"gitId":"-"},"content":" List\u003cEmailWrapper\u003e emails \u003d new ArrayList\u003c\u003e();"},{"lineNumber":742,"author":{"gitId":"-"},"content":" for (Student student : students) {"},{"lineNumber":743,"author":{"gitId":"-"},"content":" emails.add(generateFeedbackSessionEmailBaseForStudents(course, session, student,"},{"lineNumber":744,"author":{"gitId":"-"},"content":" template, type, feedbackAction, studentAdditionalContactBuilder.toString()));"},{"lineNumber":745,"author":{"gitId":"-"},"content":" }"},{"lineNumber":746,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructors) {"},{"lineNumber":747,"author":{"gitId":"-"},"content":" emails.add(generateFeedbackSessionEmailBaseForInstructors(course, session, instructor,"},{"lineNumber":748,"author":{"gitId":"-"},"content":" template, type, feedbackAction, instructorAdditionalContactBuilder.toString()));"},{"lineNumber":749,"author":{"gitId":"-"},"content":" }"},{"lineNumber":750,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructorsToNotify) {"},{"lineNumber":751,"author":{"gitId":"-"},"content":" emails.add(generateFeedbackSessionEmailBaseForNotifiedInstructors(course, session, instructor,"},{"lineNumber":752,"author":{"gitId":"-"},"content":" template, type, feedbackAction, studentAdditionalContactBuilder.toString()));"},{"lineNumber":753,"author":{"gitId":"-"},"content":" }"},{"lineNumber":754,"author":{"gitId":"-"},"content":" return emails;"},{"lineNumber":755,"author":{"gitId":"-"},"content":" }"},{"lineNumber":756,"author":{"gitId":"-"},"content":""},{"lineNumber":757,"author":{"gitId":"-"},"content":" private EmailWrapper generateFeedbackSessionEmailBaseForStudents("},{"lineNumber":758,"author":{"gitId":"-"},"content":" Course course, FeedbackSession session, Student student, String template,"},{"lineNumber":759,"author":{"gitId":"-"},"content":" EmailType type, String feedbackAction, String additionalContactInformation) {"},{"lineNumber":760,"author":{"gitId":"-"},"content":" String submitUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSION_SUBMISSION_PAGE)"},{"lineNumber":761,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":762,"author":{"gitId":"-"},"content":" .withSessionName(session.getName())"},{"lineNumber":763,"author":{"gitId":"-"},"content":" .withRegistrationKey(student.getRegKey())"},{"lineNumber":764,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":765,"author":{"gitId":"-"},"content":""},{"lineNumber":766,"author":{"gitId":"-"},"content":" String reportUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSION_RESULTS_PAGE)"},{"lineNumber":767,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":768,"author":{"gitId":"-"},"content":" .withSessionName(session.getName())"},{"lineNumber":769,"author":{"gitId":"-"},"content":" .withRegistrationKey(student.getRegKey())"},{"lineNumber":770,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":771,"author":{"gitId":"-"},"content":""},{"lineNumber":772,"author":{"gitId":"-"},"content":" Instant deadline \u003d deLogic.getDeadlineForUser(session, student);"},{"lineNumber":773,"author":{"gitId":"-"},"content":""},{"lineNumber":774,"author":{"gitId":"-"},"content":" Instant endTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":775,"author":{"gitId":"-"},"content":" deadline, session.getCourse().getTimeZone(), false);"},{"lineNumber":776,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate(template,"},{"lineNumber":777,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(student.getName()),"},{"lineNumber":778,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":779,"author":{"gitId":"-"},"content":" \"${courseId}\", SanitizationHelper.sanitizeForHtml(course.getId()),"},{"lineNumber":780,"author":{"gitId":"-"},"content":" \"${feedbackSessionName}\", SanitizationHelper.sanitizeForHtml(session.getName()),"},{"lineNumber":781,"author":{"gitId":"-"},"content":" \"${deadline}\", SanitizationHelper.sanitizeForHtml("},{"lineNumber":782,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(endTime, session.getCourse().getTimeZone(), DATETIME_DISPLAY_FORMAT))"},{"lineNumber":783,"author":{"gitId":"-"},"content":" + (session.getEndTime().equals(deadline) ? \"\" : \" (after extension)\"),"},{"lineNumber":784,"author":{"gitId":"-"},"content":" \"${instructorPreamble}\", \"\","},{"lineNumber":785,"author":{"gitId":"-"},"content":" \"${sessionInstructions}\", session.getInstructionsString(),"},{"lineNumber":786,"author":{"gitId":"-"},"content":" \"${submitUrl}\", submitUrl,"},{"lineNumber":787,"author":{"gitId":"-"},"content":" \"${reportUrl}\", reportUrl,"},{"lineNumber":788,"author":{"gitId":"-"},"content":" \"${feedbackAction}\", feedbackAction,"},{"lineNumber":789,"author":{"gitId":"-"},"content":" \"${additionalContactInformation}\", additionalContactInformation);"},{"lineNumber":790,"author":{"gitId":"-"},"content":""},{"lineNumber":791,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(student.getEmail());"},{"lineNumber":792,"author":{"gitId":"-"},"content":" email.setType(type);"},{"lineNumber":793,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), session.getName());"},{"lineNumber":794,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":795,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":796,"author":{"gitId":"-"},"content":" }"},{"lineNumber":797,"author":{"gitId":"-"},"content":""},{"lineNumber":798,"author":{"gitId":"-"},"content":" private EmailWrapper generateFeedbackSessionEmailBaseForInstructors("},{"lineNumber":799,"author":{"gitId":"-"},"content":" Course course, FeedbackSession session, Instructor instructor,"},{"lineNumber":800,"author":{"gitId":"-"},"content":" String template, EmailType type, String feedbackAction, String additionalContactInformation) {"},{"lineNumber":801,"author":{"gitId":"-"},"content":" String submitUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSION_SUBMISSION_PAGE)"},{"lineNumber":802,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":803,"author":{"gitId":"-"},"content":" .withSessionName(session.getName())"},{"lineNumber":804,"author":{"gitId":"-"},"content":" .withRegistrationKey(instructor.getRegKey())"},{"lineNumber":805,"author":{"gitId":"-"},"content":" .withEntityType(Const.EntityType.INSTRUCTOR)"},{"lineNumber":806,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":807,"author":{"gitId":"-"},"content":""},{"lineNumber":808,"author":{"gitId":"-"},"content":" String reportUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSION_RESULTS_PAGE)"},{"lineNumber":809,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":810,"author":{"gitId":"-"},"content":" .withSessionName(session.getName())"},{"lineNumber":811,"author":{"gitId":"-"},"content":" .withRegistrationKey(instructor.getRegKey())"},{"lineNumber":812,"author":{"gitId":"-"},"content":" .withEntityType(Const.EntityType.INSTRUCTOR)"},{"lineNumber":813,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":814,"author":{"gitId":"-"},"content":""},{"lineNumber":815,"author":{"gitId":"-"},"content":" Instant deadline \u003d deLogic.getDeadlineForUser(session, instructor);"},{"lineNumber":816,"author":{"gitId":"-"},"content":""},{"lineNumber":817,"author":{"gitId":"-"},"content":" Instant endTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":818,"author":{"gitId":"-"},"content":" deadline, session.getCourse().getTimeZone(), false);"},{"lineNumber":819,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate(template,"},{"lineNumber":820,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(instructor.getName()),"},{"lineNumber":821,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":822,"author":{"gitId":"-"},"content":" \"${courseId}\", SanitizationHelper.sanitizeForHtml(course.getId()),"},{"lineNumber":823,"author":{"gitId":"-"},"content":" \"${feedbackSessionName}\", SanitizationHelper.sanitizeForHtml(session.getName()),"},{"lineNumber":824,"author":{"gitId":"-"},"content":" \"${deadline}\", SanitizationHelper.sanitizeForHtml("},{"lineNumber":825,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(endTime, session.getCourse().getTimeZone(), DATETIME_DISPLAY_FORMAT))"},{"lineNumber":826,"author":{"gitId":"-"},"content":" + (session.getEndTime().equals(deadline) ? \"\" : \" (after extension)\"),"},{"lineNumber":827,"author":{"gitId":"-"},"content":" \"${instructorPreamble}\", \"\","},{"lineNumber":828,"author":{"gitId":"-"},"content":" \"${sessionInstructions}\", session.getInstructionsString(),"},{"lineNumber":829,"author":{"gitId":"-"},"content":" \"${submitUrl}\", submitUrl,"},{"lineNumber":830,"author":{"gitId":"-"},"content":" \"${reportUrl}\", reportUrl,"},{"lineNumber":831,"author":{"gitId":"-"},"content":" \"${feedbackAction}\", feedbackAction,"},{"lineNumber":832,"author":{"gitId":"-"},"content":" \"${additionalContactInformation}\", additionalContactInformation);"},{"lineNumber":833,"author":{"gitId":"-"},"content":""},{"lineNumber":834,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(instructor.getEmail());"},{"lineNumber":835,"author":{"gitId":"-"},"content":" email.setType(type);"},{"lineNumber":836,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), session.getName());"},{"lineNumber":837,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":838,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":839,"author":{"gitId":"-"},"content":" }"},{"lineNumber":840,"author":{"gitId":"-"},"content":""},{"lineNumber":841,"author":{"gitId":"-"},"content":" private EmailWrapper generateFeedbackSessionEmailBaseForNotifiedInstructors("},{"lineNumber":842,"author":{"gitId":"-"},"content":" Course course, FeedbackSession session, Instructor instructor,"},{"lineNumber":843,"author":{"gitId":"-"},"content":" String template, EmailType type, String feedbackAction, String additionalContactInformation) {"},{"lineNumber":844,"author":{"gitId":"-"},"content":""},{"lineNumber":845,"author":{"gitId":"-"},"content":" Instant endTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":846,"author":{"gitId":"-"},"content":" session.getEndTime(), session.getCourse().getTimeZone(), false);"},{"lineNumber":847,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate(template,"},{"lineNumber":848,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(instructor.getName()),"},{"lineNumber":849,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":850,"author":{"gitId":"-"},"content":" \"${courseId}\", SanitizationHelper.sanitizeForHtml(course.getId()),"},{"lineNumber":851,"author":{"gitId":"-"},"content":" \"${feedbackSessionName}\", SanitizationHelper.sanitizeForHtml(session.getName()),"},{"lineNumber":852,"author":{"gitId":"-"},"content":" \"${deadline}\", SanitizationHelper.sanitizeForHtml("},{"lineNumber":853,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(endTime, session.getCourse().getTimeZone(), DATETIME_DISPLAY_FORMAT)),"},{"lineNumber":854,"author":{"gitId":"-"},"content":" \"${instructorPreamble}\", fillUpInstructorPreamble(course),"},{"lineNumber":855,"author":{"gitId":"-"},"content":" \"${sessionInstructions}\", session.getInstructionsString(),"},{"lineNumber":856,"author":{"gitId":"-"},"content":" \"${submitUrl}\", \"{in the actual email sent to the students, this will be the unique link}\","},{"lineNumber":857,"author":{"gitId":"-"},"content":" \"${reportUrl}\", \"{in the actual email sent to the students, this will be the unique link}\","},{"lineNumber":858,"author":{"gitId":"-"},"content":" \"${feedbackAction}\", feedbackAction,"},{"lineNumber":859,"author":{"gitId":"-"},"content":" \"${additionalContactInformation}\", additionalContactInformation);"},{"lineNumber":860,"author":{"gitId":"-"},"content":""},{"lineNumber":861,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(instructor.getEmail());"},{"lineNumber":862,"author":{"gitId":"-"},"content":" email.setType(type);"},{"lineNumber":863,"author":{"gitId":"-"},"content":" email.setIsCopy(true);"},{"lineNumber":864,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), session.getName());"},{"lineNumber":865,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":866,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":867,"author":{"gitId":"-"},"content":" }"},{"lineNumber":868,"author":{"gitId":"-"},"content":""},{"lineNumber":869,"author":{"gitId":"-"},"content":" private boolean isYetToJoinCourse(Student student) {"},{"lineNumber":870,"author":{"gitId":"-"},"content":" return student.getAccount() \u003d\u003d null || student.getAccount().getGoogleId().isEmpty();"},{"lineNumber":871,"author":{"gitId":"-"},"content":" }"},{"lineNumber":872,"author":{"gitId":"-"},"content":""},{"lineNumber":873,"author":{"gitId":"-"},"content":" private boolean isYetToJoinCourse(Instructor instructor) {"},{"lineNumber":874,"author":{"gitId":"-"},"content":" return instructor.getAccount() \u003d\u003d null || instructor.getAccount().getGoogleId().isEmpty();"},{"lineNumber":875,"author":{"gitId":"-"},"content":" }"},{"lineNumber":876,"author":{"gitId":"-"},"content":""},{"lineNumber":877,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":878,"author":{"gitId":"-"},"content":" * Generates the new instructor account join email for the given {@code instructor}."},{"lineNumber":879,"author":{"gitId":"-"},"content":" */"},{"lineNumber":880,"author":{"gitId":"-"},"content":" public EmailWrapper generateNewInstructorAccountJoinEmail("},{"lineNumber":881,"author":{"gitId":"-"},"content":" String instructorEmail, String instructorName, String joinUrl) {"},{"lineNumber":882,"author":{"gitId":"-"},"content":""},{"lineNumber":883,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate(EmailTemplates.NEW_INSTRUCTOR_ACCOUNT_WELCOME,"},{"lineNumber":884,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(instructorName),"},{"lineNumber":885,"author":{"gitId":"-"},"content":" \"${joinUrl}\", joinUrl);"},{"lineNumber":886,"author":{"gitId":"-"},"content":""},{"lineNumber":887,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(instructorEmail);"},{"lineNumber":888,"author":{"gitId":"-"},"content":" email.setBcc(Config.SUPPORT_EMAIL);"},{"lineNumber":889,"author":{"gitId":"-"},"content":" email.setType(EmailType.NEW_INSTRUCTOR_ACCOUNT);"},{"lineNumber":890,"author":{"gitId":"-"},"content":" email.setSubjectFromType(SanitizationHelper.sanitizeForHtml(instructorName));"},{"lineNumber":891,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":892,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":893,"author":{"gitId":"-"},"content":" }"},{"lineNumber":894,"author":{"gitId":"-"},"content":""},{"lineNumber":895,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":896,"author":{"gitId":"-"},"content":" * Generates the course join email for the given {@code student} in {@code course}."},{"lineNumber":897,"author":{"gitId":"-"},"content":" */"},{"lineNumber":898,"author":{"gitId":"-"},"content":" public EmailWrapper generateStudentCourseJoinEmail(Course course, Student student) {"},{"lineNumber":899,"author":{"gitId":"-"},"content":""},{"lineNumber":900,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate("},{"lineNumber":901,"author":{"gitId":"-"},"content":" fillUpStudentJoinFragment(student),"},{"lineNumber":902,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(student.getName()),"},{"lineNumber":903,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":904,"author":{"gitId":"-"},"content":" \"${coOwnersEmails}\", generateCoOwnersEmailsLine(course.getId()),"},{"lineNumber":905,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL);"},{"lineNumber":906,"author":{"gitId":"-"},"content":""},{"lineNumber":907,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(student.getEmail());"},{"lineNumber":908,"author":{"gitId":"-"},"content":" email.setType(EmailType.STUDENT_COURSE_JOIN);"},{"lineNumber":909,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), course.getId());"},{"lineNumber":910,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":911,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":912,"author":{"gitId":"-"},"content":" }"},{"lineNumber":913,"author":{"gitId":"-"},"content":""},{"lineNumber":914,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":915,"author":{"gitId":"-"},"content":" * Generates the course re-join email for the given {@code student} in {@code course}."},{"lineNumber":916,"author":{"gitId":"-"},"content":" */"},{"lineNumber":917,"author":{"gitId":"-"},"content":" public EmailWrapper generateStudentCourseRejoinEmailAfterGoogleIdReset("},{"lineNumber":918,"author":{"gitId":"-"},"content":" Course course, Student student) {"},{"lineNumber":919,"author":{"gitId":"-"},"content":""},{"lineNumber":920,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate("},{"lineNumber":921,"author":{"gitId":"-"},"content":" fillUpStudentRejoinAfterGoogleIdResetFragment(student),"},{"lineNumber":922,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(student.getName()),"},{"lineNumber":923,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":924,"author":{"gitId":"-"},"content":" \"${coOwnersEmails}\", generateCoOwnersEmailsLine(course.getId()),"},{"lineNumber":925,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL);"},{"lineNumber":926,"author":{"gitId":"-"},"content":""},{"lineNumber":927,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(student.getEmail());"},{"lineNumber":928,"author":{"gitId":"-"},"content":" email.setType(EmailType.STUDENT_COURSE_REJOIN_AFTER_GOOGLE_ID_RESET);"},{"lineNumber":929,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), course.getId());"},{"lineNumber":930,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":931,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":932,"author":{"gitId":"-"},"content":" }"},{"lineNumber":933,"author":{"gitId":"-"},"content":""},{"lineNumber":934,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":935,"author":{"gitId":"-"},"content":" * Generates the course join email for the given {@code instructor} in {@code course}."},{"lineNumber":936,"author":{"gitId":"-"},"content":" * Also specifies contact information of {@code inviter}."},{"lineNumber":937,"author":{"gitId":"-"},"content":" */"},{"lineNumber":938,"author":{"gitId":"-"},"content":" public EmailWrapper generateInstructorCourseJoinEmail(Account inviter,"},{"lineNumber":939,"author":{"gitId":"-"},"content":" Instructor instructor, Course course) {"},{"lineNumber":940,"author":{"gitId":"-"},"content":""},{"lineNumber":941,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate("},{"lineNumber":942,"author":{"gitId":"-"},"content":" fillUpInstructorJoinFragment(instructor),"},{"lineNumber":943,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(instructor.getName()),"},{"lineNumber":944,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":945,"author":{"gitId":"-"},"content":" \"${inviterName}\", SanitizationHelper.sanitizeForHtml(inviter.getName()),"},{"lineNumber":946,"author":{"gitId":"-"},"content":" \"${inviterEmail}\", SanitizationHelper.sanitizeForHtml(inviter.getEmail()),"},{"lineNumber":947,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL);"},{"lineNumber":948,"author":{"gitId":"-"},"content":""},{"lineNumber":949,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(instructor.getEmail());"},{"lineNumber":950,"author":{"gitId":"-"},"content":" email.setType(EmailType.INSTRUCTOR_COURSE_JOIN);"},{"lineNumber":951,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), course.getId());"},{"lineNumber":952,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":953,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":954,"author":{"gitId":"-"},"content":" }"},{"lineNumber":955,"author":{"gitId":"-"},"content":""},{"lineNumber":956,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":957,"author":{"gitId":"-"},"content":" * Generates the course re-join email for the given {@code instructor} in {@code course}."},{"lineNumber":958,"author":{"gitId":"-"},"content":" */"},{"lineNumber":959,"author":{"gitId":"-"},"content":" public EmailWrapper generateInstructorCourseRejoinEmailAfterGoogleIdReset("},{"lineNumber":960,"author":{"gitId":"-"},"content":" Instructor instructor, Course course) {"},{"lineNumber":961,"author":{"gitId":"-"},"content":""},{"lineNumber":962,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate("},{"lineNumber":963,"author":{"gitId":"-"},"content":" fillUpInstructorRejoinAfterGoogleIdResetFragment(instructor),"},{"lineNumber":964,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(instructor.getName()),"},{"lineNumber":965,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":966,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL);"},{"lineNumber":967,"author":{"gitId":"-"},"content":""},{"lineNumber":968,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(instructor.getEmail());"},{"lineNumber":969,"author":{"gitId":"-"},"content":" email.setType(EmailType.INSTRUCTOR_COURSE_REJOIN_AFTER_GOOGLE_ID_RESET);"},{"lineNumber":970,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), course.getId());"},{"lineNumber":971,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":972,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":973,"author":{"gitId":"-"},"content":" }"},{"lineNumber":974,"author":{"gitId":"-"},"content":""},{"lineNumber":975,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":976,"author":{"gitId":"-"},"content":" * Generates the email to alert the admin of the new {@code accountRequest}."},{"lineNumber":977,"author":{"gitId":"-"},"content":" */"},{"lineNumber":978,"author":{"gitId":"-"},"content":" public EmailWrapper generateNewAccountRequestAdminAlertEmail(AccountRequest accountRequest) {"},{"lineNumber":979,"author":{"gitId":"-"},"content":" String name \u003d accountRequest.getName();"},{"lineNumber":980,"author":{"gitId":"-"},"content":" String institute \u003d accountRequest.getInstitute();"},{"lineNumber":981,"author":{"gitId":"-"},"content":" String emailAddress \u003d accountRequest.getEmail();"},{"lineNumber":982,"author":{"gitId":"-"},"content":" String comments \u003d accountRequest.getComments();"},{"lineNumber":983,"author":{"gitId":"-"},"content":" if (comments \u003d\u003d null) {"},{"lineNumber":984,"author":{"gitId":"-"},"content":" comments \u003d \"\";"},{"lineNumber":985,"author":{"gitId":"-"},"content":" }"},{"lineNumber":986,"author":{"gitId":"-"},"content":" String adminAccountRequestsPageUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.ADMIN_HOME_PAGE).toAbsoluteString();"},{"lineNumber":987,"author":{"gitId":"-"},"content":" String[] templateKeyValuePairs \u003d new String[] {"},{"lineNumber":988,"author":{"gitId":"-"},"content":" \"${name}\", name,"},{"lineNumber":989,"author":{"gitId":"-"},"content":" \"${institute}\", institute,"},{"lineNumber":990,"author":{"gitId":"-"},"content":" \"${emailAddress}\", emailAddress,"},{"lineNumber":991,"author":{"gitId":"-"},"content":" \"${comments}\", comments,"},{"lineNumber":992,"author":{"gitId":"-"},"content":" \"${adminAccountRequestsPageUrl}\", adminAccountRequestsPageUrl,"},{"lineNumber":993,"author":{"gitId":"-"},"content":" };"},{"lineNumber":994,"author":{"gitId":"-"},"content":" String content \u003d Templates.populateTemplate(EmailTemplates.ADMIN_NEW_ACCOUNT_REQUEST_ALERT, templateKeyValuePairs);"},{"lineNumber":995,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(Config.SUPPORT_EMAIL);"},{"lineNumber":996,"author":{"gitId":"-"},"content":" email.setType(EmailType.NEW_ACCOUNT_REQUEST_ADMIN_ALERT);"},{"lineNumber":997,"author":{"gitId":"-"},"content":" email.setSubjectFromType();"},{"lineNumber":998,"author":{"gitId":"-"},"content":" email.setContent(content);"},{"lineNumber":999,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":1000,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1001,"author":{"gitId":"-"},"content":""},{"lineNumber":1002,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1003,"author":{"gitId":"xenosf"},"content":" * Generates the acknowledgement email to be sent to the person who submitted {@code accountRequest}."},{"lineNumber":1004,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1005,"author":{"gitId":"xenosf"},"content":" public EmailWrapper generateNewAccountRequestAcknowledgementEmail(AccountRequest accountRequest) {"},{"lineNumber":1006,"author":{"gitId":"xenosf"},"content":" String name \u003d SanitizationHelper.sanitizeForHtml(accountRequest.getName());"},{"lineNumber":1007,"author":{"gitId":"xenosf"},"content":" String institute \u003d SanitizationHelper.sanitizeForHtml(accountRequest.getInstitute());"},{"lineNumber":1008,"author":{"gitId":"xenosf"},"content":" String emailAddress \u003d SanitizationHelper.sanitizeForHtml(accountRequest.getEmail());"},{"lineNumber":1009,"author":{"gitId":"xenosf"},"content":" String comments \u003d SanitizationHelper.sanitizeForHtml(accountRequest.getComments());"},{"lineNumber":1010,"author":{"gitId":"xenosf"},"content":" if (comments \u003d\u003d null) {"},{"lineNumber":1011,"author":{"gitId":"xenosf"},"content":" comments \u003d \"\";"},{"lineNumber":1012,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1013,"author":{"gitId":"xenosf"},"content":" String[] templateKeyValuePairs \u003d new String[] {"},{"lineNumber":1014,"author":{"gitId":"xenosf"},"content":" \"${name}\", name,"},{"lineNumber":1015,"author":{"gitId":"xenosf"},"content":" \"${institute}\", institute,"},{"lineNumber":1016,"author":{"gitId":"xenosf"},"content":" \"${emailAddress}\", emailAddress,"},{"lineNumber":1017,"author":{"gitId":"xenosf"},"content":" \"${comments}\", comments,"},{"lineNumber":1018,"author":{"gitId":"xenosf"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL,"},{"lineNumber":1019,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":1020,"author":{"gitId":"xenosf"},"content":" String content \u003d Templates.populateTemplate("},{"lineNumber":1021,"author":{"gitId":"xenosf"},"content":" EmailTemplates.INSTRUCTOR_NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT, templateKeyValuePairs);"},{"lineNumber":1022,"author":{"gitId":"xenosf"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(emailAddress);"},{"lineNumber":1023,"author":{"gitId":"xenosf"},"content":" email.setType(EmailType.NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT);"},{"lineNumber":1024,"author":{"gitId":"xenosf"},"content":" email.setBcc(Config.SUPPORT_EMAIL);"},{"lineNumber":1025,"author":{"gitId":"xenosf"},"content":" email.setSubjectFromType();"},{"lineNumber":1026,"author":{"gitId":"xenosf"},"content":" email.setContent(content);"},{"lineNumber":1027,"author":{"gitId":"xenosf"},"content":" return email;"},{"lineNumber":1028,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1029,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1030,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1031,"author":{"gitId":"-"},"content":" * Generates the email to be sent to instructor when their account request has been rejected by admin."},{"lineNumber":1032,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1033,"author":{"gitId":"-"},"content":" public EmailWrapper generateAccountRequestRejectionEmail(AccountRequest accountRequest, String title, String content) {"},{"lineNumber":1034,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(accountRequest.getEmail());"},{"lineNumber":1035,"author":{"gitId":"-"},"content":" email.setType(EmailType.ACCOUNT_REQUEST_REJECTION);"},{"lineNumber":1036,"author":{"gitId":"-"},"content":" email.setBcc(Config.SUPPORT_EMAIL);"},{"lineNumber":1037,"author":{"gitId":"-"},"content":" email.setSubjectFromType(SanitizationHelper.sanitizeTitle(title));"},{"lineNumber":1038,"author":{"gitId":"-"},"content":" email.setContent(SanitizationHelper.sanitizeForRichText(content));"},{"lineNumber":1039,"author":{"gitId":"-"},"content":""},{"lineNumber":1040,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":1041,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1042,"author":{"gitId":"-"},"content":""},{"lineNumber":1043,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1044,"author":{"gitId":"-"},"content":" * Generates the course registered email for the user with the given details in {@code course}."},{"lineNumber":1045,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1046,"author":{"gitId":"-"},"content":" public EmailWrapper generateUserCourseRegisteredEmail("},{"lineNumber":1047,"author":{"gitId":"-"},"content":" String name, String emailAddress, String googleId, boolean isInstructor, Course course) {"},{"lineNumber":1048,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate(EmailTemplates.USER_COURSE_REGISTER,"},{"lineNumber":1049,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(name),"},{"lineNumber":1050,"author":{"gitId":"-"},"content":" \"${userType}\", isInstructor ? \"an instructor\" : \"a student\","},{"lineNumber":1051,"author":{"gitId":"-"},"content":" \"${courseId}\", SanitizationHelper.sanitizeForHtml(course.getId()),"},{"lineNumber":1052,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":1053,"author":{"gitId":"-"},"content":" \"${googleId}\", SanitizationHelper.sanitizeForHtml(googleId),"},{"lineNumber":1054,"author":{"gitId":"-"},"content":" \"${appUrl}\", isInstructor"},{"lineNumber":1055,"author":{"gitId":"-"},"content":" ? Config.getFrontEndAppUrl(Const.WebPageURIs.INSTRUCTOR_HOME_PAGE).toAbsoluteString()"},{"lineNumber":1056,"author":{"gitId":"-"},"content":" : Config.getFrontEndAppUrl(Const.WebPageURIs.STUDENT_HOME_PAGE).toAbsoluteString(),"},{"lineNumber":1057,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL);"},{"lineNumber":1058,"author":{"gitId":"-"},"content":""},{"lineNumber":1059,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(emailAddress);"},{"lineNumber":1060,"author":{"gitId":"-"},"content":" email.setType(EmailType.USER_COURSE_REGISTER);"},{"lineNumber":1061,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), course.getId());"},{"lineNumber":1062,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":1063,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":1064,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1065,"author":{"gitId":"-"},"content":""},{"lineNumber":1066,"author":{"gitId":"-"},"content":" private String fillUpStudentJoinFragment(Student student) {"},{"lineNumber":1067,"author":{"gitId":"-"},"content":" String joinUrl \u003d Config.getFrontEndAppUrl(student.getRegistrationUrl()).toAbsoluteString();"},{"lineNumber":1068,"author":{"gitId":"-"},"content":""},{"lineNumber":1069,"author":{"gitId":"-"},"content":" return Templates.populateTemplate(EmailTemplates.USER_COURSE_JOIN,"},{"lineNumber":1070,"author":{"gitId":"-"},"content":" \"${joinFragment}\", EmailTemplates.FRAGMENT_STUDENT_COURSE_JOIN,"},{"lineNumber":1071,"author":{"gitId":"-"},"content":" \"${joinUrl}\", joinUrl);"},{"lineNumber":1072,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1073,"author":{"gitId":"-"},"content":""},{"lineNumber":1074,"author":{"gitId":"-"},"content":" private String fillUpStudentRejoinAfterGoogleIdResetFragment(Student student) {"},{"lineNumber":1075,"author":{"gitId":"-"},"content":" String joinUrl \u003d Config.getFrontEndAppUrl(student.getRegistrationUrl()).toAbsoluteString();"},{"lineNumber":1076,"author":{"gitId":"-"},"content":""},{"lineNumber":1077,"author":{"gitId":"-"},"content":" return Templates.populateTemplate(EmailTemplates.USER_COURSE_JOIN,"},{"lineNumber":1078,"author":{"gitId":"-"},"content":" \"${joinFragment}\", EmailTemplates.FRAGMENT_STUDENT_COURSE_REJOIN_AFTER_GOOGLE_ID_RESET,"},{"lineNumber":1079,"author":{"gitId":"-"},"content":" \"${joinUrl}\", joinUrl,"},{"lineNumber":1080,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL);"},{"lineNumber":1081,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1082,"author":{"gitId":"-"},"content":""},{"lineNumber":1083,"author":{"gitId":"-"},"content":" private String getInstructorCourseJoinUrl(Instructor instructor) {"},{"lineNumber":1084,"author":{"gitId":"-"},"content":" return Config.getFrontEndAppUrl(instructor.getRegistrationUrl()).toAbsoluteString();"},{"lineNumber":1085,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1086,"author":{"gitId":"-"},"content":""},{"lineNumber":1087,"author":{"gitId":"-"},"content":" private String fillUpInstructorJoinFragment(Instructor instructor) {"},{"lineNumber":1088,"author":{"gitId":"-"},"content":" return Templates.populateTemplate(EmailTemplates.USER_COURSE_JOIN,"},{"lineNumber":1089,"author":{"gitId":"-"},"content":" \"${joinFragment}\", EmailTemplates.FRAGMENT_INSTRUCTOR_COURSE_JOIN,"},{"lineNumber":1090,"author":{"gitId":"-"},"content":" \"${joinUrl}\", getInstructorCourseJoinUrl(instructor));"},{"lineNumber":1091,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1092,"author":{"gitId":"-"},"content":""},{"lineNumber":1093,"author":{"gitId":"-"},"content":" private String fillUpInstructorRejoinAfterGoogleIdResetFragment(Instructor instructor) {"},{"lineNumber":1094,"author":{"gitId":"-"},"content":" String joinUrl \u003d Config.getFrontEndAppUrl(instructor.getRegistrationUrl()).toAbsoluteString();"},{"lineNumber":1095,"author":{"gitId":"-"},"content":""},{"lineNumber":1096,"author":{"gitId":"-"},"content":" return Templates.populateTemplate(EmailTemplates.USER_COURSE_JOIN,"},{"lineNumber":1097,"author":{"gitId":"-"},"content":" \"${joinFragment}\", EmailTemplates.FRAGMENT_INSTRUCTOR_COURSE_REJOIN_AFTER_GOOGLE_ID_RESET,"},{"lineNumber":1098,"author":{"gitId":"-"},"content":" \"${joinUrl}\", joinUrl,"},{"lineNumber":1099,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL);"},{"lineNumber":1100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1101,"author":{"gitId":"-"},"content":""},{"lineNumber":1102,"author":{"gitId":"-"},"content":" private String fillUpInstructorPreamble(Course course) {"},{"lineNumber":1103,"author":{"gitId":"-"},"content":" return Templates.populateTemplate(EmailTemplates.FRAGMENT_INSTRUCTOR_COPY_PREAMBLE,"},{"lineNumber":1104,"author":{"gitId":"-"},"content":" \"${courseId}\", SanitizationHelper.sanitizeForHtml(course.getId()),"},{"lineNumber":1105,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()));"},{"lineNumber":1106,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1107,"author":{"gitId":"-"},"content":""},{"lineNumber":1108,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1109,"author":{"gitId":"-"},"content":" * Generates the logs compilation email for the given {@code logs}."},{"lineNumber":1110,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1111,"author":{"gitId":"-"},"content":" public EmailWrapper generateCompiledLogsEmail(List\u003cErrorLogEntry\u003e logs) {"},{"lineNumber":1112,"author":{"gitId":"-"},"content":" StringBuilder emailBody \u003d new StringBuilder();"},{"lineNumber":1113,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c logs.size(); i++) {"},{"lineNumber":1114,"author":{"gitId":"-"},"content":" emailBody.append(generateSevereErrorLogLine(i, logs.get(i).getMessage(),"},{"lineNumber":1115,"author":{"gitId":"-"},"content":" logs.get(i).getSeverity(), logs.get(i).getTraceId()));"},{"lineNumber":1116,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1117,"author":{"gitId":"-"},"content":""},{"lineNumber":1118,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(Config.SUPPORT_EMAIL);"},{"lineNumber":1119,"author":{"gitId":"-"},"content":" email.setType(EmailType.SEVERE_LOGS_COMPILATION);"},{"lineNumber":1120,"author":{"gitId":"-"},"content":" email.setSubjectFromType(Config.APP_VERSION);"},{"lineNumber":1121,"author":{"gitId":"-"},"content":" email.setContent(emailBody.toString());"},{"lineNumber":1122,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":1123,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1124,"author":{"gitId":"-"},"content":""},{"lineNumber":1125,"author":{"gitId":"-"},"content":" private String generateSevereErrorLogLine(int index, String logMessage, String logLevel, String traceId) {"},{"lineNumber":1126,"author":{"gitId":"-"},"content":" return Templates.populateTemplate("},{"lineNumber":1127,"author":{"gitId":"-"},"content":" EmailTemplates.SEVERE_ERROR_LOG_LINE,"},{"lineNumber":1128,"author":{"gitId":"-"},"content":" \"${index}\", String.valueOf(index),"},{"lineNumber":1129,"author":{"gitId":"-"},"content":" \"${errorType}\", logLevel,"},{"lineNumber":1130,"author":{"gitId":"-"},"content":" \"${errorMessage}\", logMessage.replaceAll(\"\\n\", \"\\n\u003cbr\u003e\"),"},{"lineNumber":1131,"author":{"gitId":"-"},"content":" \"${traceId}\", traceId);"},{"lineNumber":1132,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1133,"author":{"gitId":"-"},"content":""},{"lineNumber":1134,"author":{"gitId":"-"},"content":" private EmailWrapper getEmptyEmailAddressedToEmail(String recipient) {"},{"lineNumber":1135,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d new EmailWrapper();"},{"lineNumber":1136,"author":{"gitId":"-"},"content":" email.setRecipient(recipient);"},{"lineNumber":1137,"author":{"gitId":"-"},"content":" email.setSenderEmail(Config.EMAIL_SENDEREMAIL);"},{"lineNumber":1138,"author":{"gitId":"-"},"content":" email.setSenderName(Config.EMAIL_SENDERNAME);"},{"lineNumber":1139,"author":{"gitId":"-"},"content":" email.setReplyTo(Config.EMAIL_REPLYTO);"},{"lineNumber":1140,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":1141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1142,"author":{"gitId":"-"},"content":""},{"lineNumber":1143,"author":{"gitId":"-"},"content":" private String generateCoOwnersEmailsLine(String courseId) {"},{"lineNumber":1144,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e coOwners \u003d usersLogic.getCoOwnersForCourse(courseId);"},{"lineNumber":1145,"author":{"gitId":"-"},"content":" if (coOwners.isEmpty()) {"},{"lineNumber":1146,"author":{"gitId":"-"},"content":" return \"(No contactable instructors found)\";"},{"lineNumber":1147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1148,"author":{"gitId":"-"},"content":" StringBuilder coOwnersEmailsLine \u003d new StringBuilder();"},{"lineNumber":1149,"author":{"gitId":"-"},"content":" for (Instructor coOwner : coOwners) {"},{"lineNumber":1150,"author":{"gitId":"-"},"content":" coOwnersEmailsLine"},{"lineNumber":1151,"author":{"gitId":"-"},"content":" .append(SanitizationHelper.sanitizeForHtml(coOwner.getName()))"},{"lineNumber":1152,"author":{"gitId":"-"},"content":" .append(\" (\")"},{"lineNumber":1153,"author":{"gitId":"-"},"content":" .append(coOwner.getEmail())"},{"lineNumber":1154,"author":{"gitId":"-"},"content":" .append(\"), \");"},{"lineNumber":1155,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1156,"author":{"gitId":"-"},"content":" return coOwnersEmailsLine.substring(0, coOwnersEmailsLine.length() - 2);"},{"lineNumber":1157,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1158,"author":{"gitId":"-"},"content":""},{"lineNumber":1159,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1160,"author":{"gitId":"-"},"content":" * Generates additional contact information for User Email Templates."},{"lineNumber":1161,"author":{"gitId":"-"},"content":" * @return The contact information after replacing the placeholders."},{"lineNumber":1162,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1163,"author":{"gitId":"-"},"content":" private String getAdditionalContactInformationFragment(Course course, boolean isInstructor) {"},{"lineNumber":1164,"author":{"gitId":"-"},"content":" String particulars \u003d isInstructor ? \"instructor data (e.g. wrong permission, misspelled name)\""},{"lineNumber":1165,"author":{"gitId":"-"},"content":" : \"team/student data (e.g. wrong team, misspelled name)\";"},{"lineNumber":1166,"author":{"gitId":"-"},"content":" return Templates.populateTemplate(EmailTemplates.FRAGMENT_SESSION_ADDITIONAL_CONTACT_INFORMATION,"},{"lineNumber":1167,"author":{"gitId":"-"},"content":" \"${particulars}\", particulars,"},{"lineNumber":1168,"author":{"gitId":"-"},"content":" \"${coOwnersEmails}\", generateCoOwnersEmailsLine(course.getId()),"},{"lineNumber":1169,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL);"},{"lineNumber":1170,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1171,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":28,"-":1143}},{"path":"src/main/java/teammates/sqllogic/core/AccountRequestsLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.AccountRequestsDb;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.AccountRequestSearchManager;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * Handles operations related to account requests."},{"lineNumber":17,"author":{"gitId":"-"},"content":" *"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * @see AccountRequest"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * @see AccountRequestsDb"},{"lineNumber":20,"author":{"gitId":"-"},"content":" */"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public final class AccountRequestsLogic {"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" private static final AccountRequestsLogic instance \u003d new AccountRequestsLogic();"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" private AccountRequestsDb accountRequestDb;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" private AccountRequestsLogic() {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" // prevent notification"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" public static AccountRequestsLogic inst() {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":36,"author":{"gitId":"-"},"content":" * Initialise dependencies for {@code AccountRequestLogic} object."},{"lineNumber":37,"author":{"gitId":"-"},"content":" */"},{"lineNumber":38,"author":{"gitId":"-"},"content":" public void initLogicDependencies(AccountRequestsDb accountRequestDb) {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.accountRequestDb \u003d accountRequestDb;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" private AccountRequestSearchManager getSearchManager() {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" return accountRequestDb.getSearchManager();"},{"lineNumber":44,"author":{"gitId":"-"},"content":" }"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":47,"author":{"gitId":"-"},"content":" * Creates or updates search document for the given account request."},{"lineNumber":48,"author":{"gitId":"-"},"content":" */"},{"lineNumber":49,"author":{"gitId":"-"},"content":" public void putDocument(AccountRequest accountRequest) throws SearchServiceException {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" getSearchManager().putDocument(accountRequest);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" }"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":54,"author":{"gitId":"-"},"content":" * Creates an account request."},{"lineNumber":55,"author":{"gitId":"-"},"content":" */"},{"lineNumber":56,"author":{"gitId":"-"},"content":" public AccountRequest createAccountRequest(AccountRequest accountRequest) throws InvalidParametersException {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" return accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":61,"author":{"gitId":"-"},"content":" * Creates an account request."},{"lineNumber":62,"author":{"gitId":"-"},"content":" */"},{"lineNumber":63,"author":{"gitId":"-"},"content":" public AccountRequest createAccountRequest(String name, String email, String institute, AccountRequestStatus status,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" String comments) throws InvalidParametersException {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" AccountRequest toCreate \u003d new AccountRequest(email, name, institute, status, comments);"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" return accountRequestDb.createAccountRequest(toCreate);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" }"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":71,"author":{"gitId":"-"},"content":" * Gets the account request associated with the {@code id}."},{"lineNumber":72,"author":{"gitId":"-"},"content":" */"},{"lineNumber":73,"author":{"gitId":"-"},"content":" public AccountRequest getAccountRequest(UUID id) {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" return accountRequestDb.getAccountRequest(id);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" }"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" * Gets the account request associated with the {@code id}."},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" public AccountRequest getAccountRequestWithTransaction(UUID id) {"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" AccountRequest request \u003d accountRequestDb.getAccountRequest(id);"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" return request;"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":88,"author":{"gitId":"-"},"content":" * Updates an account request."},{"lineNumber":89,"author":{"gitId":"-"},"content":" */"},{"lineNumber":90,"author":{"gitId":"-"},"content":" public AccountRequest updateAccountRequest(AccountRequest accountRequest)"},{"lineNumber":91,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" return accountRequestDb.updateAccountRequest(accountRequest);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" }"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" * Updates an account request."},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":" @SuppressWarnings(\"PMD\")"},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" public AccountRequest updateAccountRequestWithTransaction(AccountRequest accountRequest)"},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":" AccountRequest updatedRequest;"},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" updatedRequest \u003d accountRequestDb.updateAccountRequest(accountRequest);"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" } catch (InvalidParametersException ipe) {"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.rollbackTransaction();"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" throw new InvalidParametersException(ipe.getMessage());"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" return updatedRequest;"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" * Gets account request associated with the {@code regkey}."},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" public AccountRequest getAccountRequestByRegistrationKey(String regkey) {"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" return accountRequestDb.getAccountRequestByRegistrationKey(regkey);"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":124,"author":{"gitId":"-"},"content":" * Gets all pending account requests."},{"lineNumber":125,"author":{"gitId":"-"},"content":" */"},{"lineNumber":126,"author":{"gitId":"-"},"content":" public List\u003cAccountRequest\u003e getPendingAccountRequests() {"},{"lineNumber":127,"author":{"gitId":"-"},"content":" return accountRequestDb.getPendingAccountRequests();"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":" * Gets all account requests."},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccountRequest\u003e getAllAccountRequests() {"},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" return accountRequestDb.getAllAccountRequests();"},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":137,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":" * Get a list of account requests associated with email provided."},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":140,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccountRequest\u003e getApprovedAccountRequestsForEmailWithTransaction(String email) {"},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":" List\u003cAccountRequest\u003e accountRequests \u003d accountRequestDb.getApprovedAccountRequestsForEmail(email);"},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":" return accountRequests;"},{"lineNumber":145,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":" * Creates/resets the account request with the given id such that it is not registered."},{"lineNumber":149,"author":{"gitId":"-"},"content":" */"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":" public AccountRequest resetAccountRequest(UUID id)"},{"lineNumber":151,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, InvalidParametersException {"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":" AccountRequest accountRequest \u003d accountRequestDb.getAccountRequest(id);"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"-"},"content":" if (accountRequest \u003d\u003d null) {"},{"lineNumber":155,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Failed to reset since AccountRequest with \""},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" + \"the given id cannot be found.\");"},{"lineNumber":157,"author":{"gitId":"-"},"content":" }"},{"lineNumber":158,"author":{"gitId":"-"},"content":" accountRequest.setRegisteredAt(null);"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" return accountRequestDb.updateAccountRequest(accountRequest);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":164,"author":{"gitId":"dishenggg"},"content":" * Deletes account request associated with the {@code id}."},{"lineNumber":165,"author":{"gitId":"-"},"content":" *"},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":" * \u003cp\u003eFails silently if no account requests with the given id to delete can be found.\u003c/p\u003e"},{"lineNumber":167,"author":{"gitId":"-"},"content":" *"},{"lineNumber":168,"author":{"gitId":"-"},"content":" */"},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":" public void deleteAccountRequest(UUID id) {"},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" AccountRequest toDelete \u003d accountRequestDb.getAccountRequest(id);"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" accountRequestDb.deleteAccountRequest(toDelete);"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":" * Searches for account requests in the whole system."},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":" * @return A list of {@link AccountRequest} or {@code null} if no match found."},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccountRequest\u003e searchAccountRequestsInWholeSystem(String queryString)"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":" throws SearchServiceException {"},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":" return accountRequestDb.searchAccountRequestsInWholeSystem(queryString);"},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":184,"author":{"gitId":"-"},"content":""},{"lineNumber":185,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":186,"author":{"gitId":"-"},"content":" * Creates an or gets an account request."},{"lineNumber":187,"author":{"gitId":"-"},"content":" */"},{"lineNumber":188,"author":{"gitId":"-"},"content":" public AccountRequest createOrGetAccountRequestWithTransaction(String name, String email, String institute,"},{"lineNumber":189,"author":{"gitId":"-"},"content":" AccountRequestStatus status, String comments)"},{"lineNumber":190,"author":{"gitId":"-"},"content":" throws InvalidParametersException {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" AccountRequest toCreate \u003d new AccountRequest(email, name, institute, status, comments);"},{"lineNumber":192,"author":{"gitId":"-"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":193,"author":{"gitId":"-"},"content":" AccountRequest accountRequest;"},{"lineNumber":194,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":195,"author":{"gitId":"-"},"content":" accountRequest \u003d accountRequestDb.createAccountRequest(toCreate);"},{"lineNumber":196,"author":{"gitId":"-"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":197,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException ipe) {"},{"lineNumber":198,"author":{"gitId":"-"},"content":" HibernateUtil.rollbackTransaction();"},{"lineNumber":199,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(ipe);"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }"},{"lineNumber":201,"author":{"gitId":"-"},"content":" return accountRequest;"},{"lineNumber":202,"author":{"gitId":"-"},"content":" }"},{"lineNumber":203,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":60,"dishenggg":15,"-":128}},{"path":"src/main/java/teammates/sqllogic/core/AccountsLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.AccountsDb;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":14,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":15,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.ReadNotification;"},{"lineNumber":18,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.User;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * Handles operations related to accounts."},{"lineNumber":23,"author":{"gitId":"-"},"content":" *"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * @see Account"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * @see AccountsDb"},{"lineNumber":26,"author":{"gitId":"-"},"content":" */"},{"lineNumber":27,"author":{"gitId":"-"},"content":"public final class AccountsLogic {"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" private static final AccountsLogic instance \u003d new AccountsLogic();"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" private AccountsDb accountsDb;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private NotificationsLogic notificationsLogic;"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" private UsersLogic usersLogic;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"yuanxi1"},"content":" private CoursesLogic coursesLogic;"},{"lineNumber":38,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" private AccountsLogic() {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"yuanxi1"},"content":" void initLogicDependencies(AccountsDb accountsDb, NotificationsLogic notificationsLogic,"},{"lineNumber":44,"author":{"gitId":"yuanxi1"},"content":" UsersLogic usersLogic, CoursesLogic coursesLogic) {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" this.accountsDb \u003d accountsDb;"},{"lineNumber":46,"author":{"gitId":"-"},"content":" this.notificationsLogic \u003d notificationsLogic;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" this.usersLogic \u003d usersLogic;"},{"lineNumber":48,"author":{"gitId":"yuanxi1"},"content":" this.coursesLogic \u003d coursesLogic;"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" public static AccountsLogic inst() {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":56,"author":{"gitId":"-"},"content":" * Gets an account."},{"lineNumber":57,"author":{"gitId":"-"},"content":" */"},{"lineNumber":58,"author":{"gitId":"-"},"content":" public Account getAccount(UUID id) {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" assert id !\u003d null;"},{"lineNumber":60,"author":{"gitId":"-"},"content":" return accountsDb.getAccount(id);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":64,"author":{"gitId":"-"},"content":" * Gets an account by googleId."},{"lineNumber":65,"author":{"gitId":"-"},"content":" */"},{"lineNumber":66,"author":{"gitId":"-"},"content":" public Account getAccountForGoogleId(String googleId) {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" return accountsDb.getAccountByGoogleId(googleId);"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":73,"author":{"gitId":"-"},"content":" * Gets accounts associated with email."},{"lineNumber":74,"author":{"gitId":"-"},"content":" */"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public List\u003cAccount\u003e getAccountsForEmail(String email) {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" return accountsDb.getAccountsByEmail(email);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" }"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" * Gets accounts associated with email."},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccount\u003e getAccountsForEmailWithTransaction(String email) {"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" assert email !\u003d null;"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" List\u003cAccount\u003e accounts \u003d accountsDb.getAccountsByEmail(email);"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" return accounts;"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":95,"author":{"gitId":"-"},"content":" * Creates an account."},{"lineNumber":96,"author":{"gitId":"-"},"content":" *"},{"lineNumber":97,"author":{"gitId":"-"},"content":" * @return the created account"},{"lineNumber":98,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the account is not valid"},{"lineNumber":99,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the account already exists in the"},{"lineNumber":100,"author":{"gitId":"-"},"content":" * database."},{"lineNumber":101,"author":{"gitId":"-"},"content":" */"},{"lineNumber":102,"author":{"gitId":"-"},"content":" public Account createAccount(Account account)"},{"lineNumber":103,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" assert account !\u003d null;"},{"lineNumber":105,"author":{"gitId":"-"},"content":" return accountsDb.createAccount(account);"},{"lineNumber":106,"author":{"gitId":"-"},"content":" }"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" * Creates an account."},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" * @return the created account"},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" * @throws InvalidParametersException if the account is not valid"},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" * @throws EntityAlreadyExistsException if the account already exists in the"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" * database."},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" public Account createAccountWithTransaction(Account account)"},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":" assert account !\u003d null;"},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":" Account createdAccount \u003d accountsDb.createAccount(account);"},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" return createdAccount;"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":128,"author":{"gitId":"-"},"content":" * Deletes account associated with the {@code googleId}."},{"lineNumber":129,"author":{"gitId":"-"},"content":" *"},{"lineNumber":130,"author":{"gitId":"-"},"content":" * \u003cp\u003eFails silently if the account doesn\u0027t exist.\u003c/p\u003e"},{"lineNumber":131,"author":{"gitId":"-"},"content":" */"},{"lineNumber":132,"author":{"gitId":"-"},"content":" public void deleteAccount(String googleId) {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" Account account \u003d getAccountForGoogleId(googleId);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" accountsDb.deleteAccount(account);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":140,"author":{"gitId":"-"},"content":" * Deletes account and all users associated with the {@code googleId}."},{"lineNumber":141,"author":{"gitId":"-"},"content":" *"},{"lineNumber":142,"author":{"gitId":"-"},"content":" * \u003cp\u003eFails silently if the account doesn\u0027t exist.\u003c/p\u003e"},{"lineNumber":143,"author":{"gitId":"-"},"content":" */"},{"lineNumber":144,"author":{"gitId":"-"},"content":" public void deleteAccountCascade(String googleId) {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" List\u003cUser\u003e usersToDelete \u003d usersLogic.getAllUsersByGoogleId(googleId);"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" for (User user : usersToDelete) {"},{"lineNumber":150,"author":{"gitId":"-"},"content":" usersLogic.deleteUser(user);"},{"lineNumber":151,"author":{"gitId":"-"},"content":" }"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":" deleteAccount(googleId);"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":157,"author":{"gitId":"-"},"content":" * Updates the readNotifications of an account."},{"lineNumber":158,"author":{"gitId":"-"},"content":" *"},{"lineNumber":159,"author":{"gitId":"-"},"content":" * @param googleId google ID of the user who read the notification."},{"lineNumber":160,"author":{"gitId":"-"},"content":" * @param notificationId ID of notification to be marked as read."},{"lineNumber":161,"author":{"gitId":"-"},"content":" * @param endTime the expiry time of the notification, i.e. notification"},{"lineNumber":162,"author":{"gitId":"-"},"content":" * will not be shown after this time."},{"lineNumber":163,"author":{"gitId":"-"},"content":" * @return the account with updated read notifications."},{"lineNumber":164,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the notification has expired."},{"lineNumber":165,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if account or notification does not"},{"lineNumber":166,"author":{"gitId":"-"},"content":" * exist."},{"lineNumber":167,"author":{"gitId":"-"},"content":" */"},{"lineNumber":168,"author":{"gitId":"-"},"content":" public List\u003cUUID\u003e updateReadNotifications(String googleId, UUID notificationId, Instant endTime)"},{"lineNumber":169,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":170,"author":{"gitId":"-"},"content":" Account account \u003d accountsDb.getAccountByGoogleId(googleId);"},{"lineNumber":171,"author":{"gitId":"-"},"content":" if (account \u003d\u003d null) {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Trying to update the read notifications of a non-existent account.\");"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" Notification notification \u003d notificationsLogic.getNotification(notificationId);"},{"lineNumber":176,"author":{"gitId":"-"},"content":" if (notification \u003d\u003d null) {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Trying to mark as read a notification that does not exist.\");"},{"lineNumber":178,"author":{"gitId":"-"},"content":" }"},{"lineNumber":179,"author":{"gitId":"-"},"content":" if (endTime.isBefore(Instant.now())) {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(\"Trying to mark an expired notification as read.\");"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" ReadNotification readNotification \u003d new ReadNotification(account, notification);"},{"lineNumber":184,"author":{"gitId":"-"},"content":" account.addReadNotification(readNotification);"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" return account.getReadNotifications().stream()"},{"lineNumber":187,"author":{"gitId":"-"},"content":" .map(n -\u003e n.getNotification().getId())"},{"lineNumber":188,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":192,"author":{"gitId":"-"},"content":" * Gets ids of read notifications in an account."},{"lineNumber":193,"author":{"gitId":"-"},"content":" */"},{"lineNumber":194,"author":{"gitId":"-"},"content":" public List\u003cUUID\u003e getReadNotificationsId(String googleId) {"},{"lineNumber":195,"author":{"gitId":"-"},"content":" return accountsDb.getAccountByGoogleId(googleId).getReadNotifications().stream()"},{"lineNumber":196,"author":{"gitId":"-"},"content":" .map(n -\u003e n.getNotification().getId())"},{"lineNumber":197,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":198,"author":{"gitId":"-"},"content":" }"},{"lineNumber":199,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":200,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":201,"author":{"gitId":"yuanxi1"},"content":" * Joins the user as a student."},{"lineNumber":202,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":203,"author":{"gitId":"yuanxi1"},"content":" public Student joinCourseForStudent(String registrationKey, String googleId)"},{"lineNumber":204,"author":{"gitId":"yuanxi1"},"content":" throws InvalidParametersException, EntityDoesNotExistException, EntityAlreadyExistsException {"},{"lineNumber":205,"author":{"gitId":"yuanxi1"},"content":" Student student \u003d validateStudentJoinRequest(registrationKey, googleId);"},{"lineNumber":206,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":207,"author":{"gitId":"yuanxi1"},"content":" Account account \u003d accountsDb.getAccountByGoogleId(googleId);"},{"lineNumber":208,"author":{"gitId":"yuanxi1"},"content":" // Create an account if it doesn\u0027t exist"},{"lineNumber":209,"author":{"gitId":"yuanxi1"},"content":" if (account \u003d\u003d null) {"},{"lineNumber":210,"author":{"gitId":"yuanxi1"},"content":" account \u003d new Account(googleId, student.getName(), student.getEmail());"},{"lineNumber":211,"author":{"gitId":"yuanxi1"},"content":" createAccount(account);"},{"lineNumber":212,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":213,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":214,"author":{"gitId":"yuanxi1"},"content":" if (student.getAccount() \u003d\u003d null) {"},{"lineNumber":215,"author":{"gitId":"yuanxi1"},"content":" student.setAccount(account);"},{"lineNumber":216,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":217,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":218,"author":{"gitId":"yuanxi1"},"content":" return student;"},{"lineNumber":219,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":220,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":221,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":222,"author":{"gitId":"yuanxi1"},"content":" * Joins the user as an instructor."},{"lineNumber":223,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":224,"author":{"gitId":"yuanxi1"},"content":" public Instructor joinCourseForInstructor(String key, String googleId)"},{"lineNumber":225,"author":{"gitId":"yuanxi1"},"content":" throws InvalidParametersException, EntityDoesNotExistException, EntityAlreadyExistsException {"},{"lineNumber":226,"author":{"gitId":"yuanxi1"},"content":" Instructor instructor \u003d validateInstructorJoinRequest(key, googleId);"},{"lineNumber":227,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":228,"author":{"gitId":"yuanxi1"},"content":" Account account \u003d accountsDb.getAccountByGoogleId(googleId);"},{"lineNumber":229,"author":{"gitId":"yuanxi1"},"content":" if (account \u003d\u003d null) {"},{"lineNumber":230,"author":{"gitId":"yuanxi1"},"content":" try {"},{"lineNumber":231,"author":{"gitId":"yuanxi1"},"content":" account \u003d new Account(googleId, instructor.getName(), instructor.getEmail());"},{"lineNumber":232,"author":{"gitId":"yuanxi1"},"content":" createAccount(account);"},{"lineNumber":233,"author":{"gitId":"yuanxi1"},"content":" } catch (EntityAlreadyExistsException e) {"},{"lineNumber":234,"author":{"gitId":"yuanxi1"},"content":" assert false : \"Account already exists.\";"},{"lineNumber":235,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":236,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":237,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":238,"author":{"gitId":"yuanxi1"},"content":" instructor.setAccount(account);"},{"lineNumber":239,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":240,"author":{"gitId":"yuanxi1"},"content":" // Update the googleId of the student entity for the instructor which was created from sample data."},{"lineNumber":241,"author":{"gitId":"yuanxi1"},"content":" Student student \u003d usersLogic.getStudentForEmail(instructor.getCourseId(), instructor.getEmail());"},{"lineNumber":242,"author":{"gitId":"yuanxi1"},"content":" if (student !\u003d null) {"},{"lineNumber":243,"author":{"gitId":"yuanxi1"},"content":" student.setAccount(account);"},{"lineNumber":244,"author":{"gitId":"yuanxi1"},"content":" usersLogic.updateStudentCascade(student);"},{"lineNumber":245,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":246,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":247,"author":{"gitId":"yuanxi1"},"content":" return instructor;"},{"lineNumber":248,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":249,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":250,"author":{"gitId":"yuanxi1"},"content":" private Instructor validateInstructorJoinRequest(String registrationKey, String googleId)"},{"lineNumber":251,"author":{"gitId":"yuanxi1"},"content":" throws EntityDoesNotExistException, EntityAlreadyExistsException {"},{"lineNumber":252,"author":{"gitId":"yuanxi1"},"content":" Instructor instructorForKey \u003d usersLogic.getInstructorByRegistrationKey(registrationKey);"},{"lineNumber":253,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":254,"author":{"gitId":"yuanxi1"},"content":" if (instructorForKey \u003d\u003d null) {"},{"lineNumber":255,"author":{"gitId":"yuanxi1"},"content":" throw new EntityDoesNotExistException(\"No instructor with given registration key: \" + registrationKey);"},{"lineNumber":256,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":257,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":258,"author":{"gitId":"yuanxi1"},"content":" Course course \u003d coursesLogic.getCourse(instructorForKey.getCourseId());"},{"lineNumber":259,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":260,"author":{"gitId":"yuanxi1"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":261,"author":{"gitId":"yuanxi1"},"content":" throw new EntityDoesNotExistException(\"Course with id \" + instructorForKey.getCourseId() + \" does not exist\");"},{"lineNumber":262,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":263,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":264,"author":{"gitId":"yuanxi1"},"content":" if (course.isCourseDeleted()) {"},{"lineNumber":265,"author":{"gitId":"yuanxi1"},"content":" throw new EntityDoesNotExistException(\"The course you are trying to join has been deleted by an instructor\");"},{"lineNumber":266,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":267,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":268,"author":{"gitId":"yuanxi1"},"content":" if (instructorForKey.isRegistered()) {"},{"lineNumber":269,"author":{"gitId":"yuanxi1"},"content":" if (instructorForKey.getGoogleId().equals(googleId)) {"},{"lineNumber":270,"author":{"gitId":"yuanxi1"},"content":" Account existingAccount \u003d accountsDb.getAccountByGoogleId(googleId);"},{"lineNumber":271,"author":{"gitId":"yuanxi1"},"content":" if (existingAccount !\u003d null) {"},{"lineNumber":272,"author":{"gitId":"yuanxi1"},"content":" throw new EntityAlreadyExistsException(\"Instructor has already joined course\");"},{"lineNumber":273,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":274,"author":{"gitId":"yuanxi1"},"content":" } else {"},{"lineNumber":275,"author":{"gitId":"yuanxi1"},"content":" throw new EntityAlreadyExistsException(\"Instructor has already joined course\");"},{"lineNumber":276,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":277,"author":{"gitId":"yuanxi1"},"content":" } else {"},{"lineNumber":278,"author":{"gitId":"yuanxi1"},"content":" // Check if this Google ID has already joined this course"},{"lineNumber":279,"author":{"gitId":"yuanxi1"},"content":" Instructor existingInstructor \u003d"},{"lineNumber":280,"author":{"gitId":"yuanxi1"},"content":" usersLogic.getInstructorByGoogleId(instructorForKey.getCourseId(), googleId);"},{"lineNumber":281,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":282,"author":{"gitId":"yuanxi1"},"content":" if (existingInstructor !\u003d null) {"},{"lineNumber":283,"author":{"gitId":"yuanxi1"},"content":" throw new EntityAlreadyExistsException(\"Instructor has already joined course\");"},{"lineNumber":284,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":285,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":286,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":287,"author":{"gitId":"yuanxi1"},"content":" return instructorForKey;"},{"lineNumber":288,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":289,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":290,"author":{"gitId":"yuanxi1"},"content":" private Student validateStudentJoinRequest(String registrationKey, String googleId)"},{"lineNumber":291,"author":{"gitId":"yuanxi1"},"content":" throws EntityDoesNotExistException, EntityAlreadyExistsException {"},{"lineNumber":292,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":293,"author":{"gitId":"yuanxi1"},"content":" Student studentRole \u003d usersLogic.getStudentByRegistrationKey(registrationKey);"},{"lineNumber":294,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":295,"author":{"gitId":"yuanxi1"},"content":" if (studentRole \u003d\u003d null) {"},{"lineNumber":296,"author":{"gitId":"yuanxi1"},"content":" throw new EntityDoesNotExistException(\"No student with given registration key: \" + registrationKey);"},{"lineNumber":297,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":298,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":299,"author":{"gitId":"yuanxi1"},"content":" Course course \u003d coursesLogic.getCourse(studentRole.getCourseId());"},{"lineNumber":300,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":301,"author":{"gitId":"yuanxi1"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":302,"author":{"gitId":"yuanxi1"},"content":" throw new EntityDoesNotExistException(\"Course with id \" + studentRole.getCourseId() + \" does not exist\");"},{"lineNumber":303,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":304,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":305,"author":{"gitId":"yuanxi1"},"content":" if (course.isCourseDeleted()) {"},{"lineNumber":306,"author":{"gitId":"yuanxi1"},"content":" throw new EntityDoesNotExistException(\"The course you are trying to join has been deleted by an instructor\");"},{"lineNumber":307,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":308,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":309,"author":{"gitId":"yuanxi1"},"content":" if (studentRole.isRegistered()) {"},{"lineNumber":310,"author":{"gitId":"yuanxi1"},"content":" throw new EntityAlreadyExistsException(\"Student has already joined course\");"},{"lineNumber":311,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":312,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":313,"author":{"gitId":"yuanxi1"},"content":" // Check if this Google ID has already joined this course"},{"lineNumber":314,"author":{"gitId":"yuanxi1"},"content":" Student existingStudent \u003d"},{"lineNumber":315,"author":{"gitId":"yuanxi1"},"content":" usersLogic.getStudentByGoogleId(studentRole.getCourseId(), googleId);"},{"lineNumber":316,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":317,"author":{"gitId":"yuanxi1"},"content":" if (existingStudent !\u003d null) {"},{"lineNumber":318,"author":{"gitId":"yuanxi1"},"content":" throw new EntityAlreadyExistsException(\"Student has already joined course\");"},{"lineNumber":319,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":320,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":321,"author":{"gitId":"yuanxi1"},"content":" return studentRole;"},{"lineNumber":322,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":323,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":33,"yuanxi1":132,"-":158}},{"path":"src/main/java/teammates/sqllogic/core/CoursesLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static teammates.common.util.Const.ERROR_UPDATE_NON_EXISTENT;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Comparator;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.CoursesDb;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * Handles operations related to courses."},{"lineNumber":23,"author":{"gitId":"-"},"content":" *"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * @see Course"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * @see CoursesDb"},{"lineNumber":26,"author":{"gitId":"-"},"content":" */"},{"lineNumber":27,"author":{"gitId":"-"},"content":"public final class CoursesLogic {"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" private static final CoursesLogic instance \u003d new CoursesLogic();"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" private CoursesDb coursesDb;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private FeedbackSessionsLogic fsLogic;"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" private UsersLogic usersLogic;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" private CoursesLogic() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" public static CoursesLogic inst() {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" }"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" void initLogicDependencies(CoursesDb coursesDb, FeedbackSessionsLogic fsLogic, UsersLogic usersLogic) {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" this.coursesDb \u003d coursesDb;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" this.fsLogic \u003d fsLogic;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" this.usersLogic \u003d usersLogic;"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":52,"author":{"gitId":"-"},"content":" * Creates a course."},{"lineNumber":53,"author":{"gitId":"-"},"content":" *"},{"lineNumber":54,"author":{"gitId":"-"},"content":" * @return the created course"},{"lineNumber":55,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the course is not valid"},{"lineNumber":56,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the course already exists in the"},{"lineNumber":57,"author":{"gitId":"-"},"content":" * database."},{"lineNumber":58,"author":{"gitId":"-"},"content":" */"},{"lineNumber":59,"author":{"gitId":"-"},"content":" public Course createCourse(Course course) throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" return coursesDb.createCourse(course);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":64,"author":{"gitId":"-"},"content":" * Gets a course by course id."},{"lineNumber":65,"author":{"gitId":"-"},"content":" *"},{"lineNumber":66,"author":{"gitId":"-"},"content":" * @param courseId of course."},{"lineNumber":67,"author":{"gitId":"-"},"content":" * @return the specified course."},{"lineNumber":68,"author":{"gitId":"-"},"content":" */"},{"lineNumber":69,"author":{"gitId":"-"},"content":" public Course getCourse(String courseId) {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" return coursesDb.getCourse(courseId);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":74,"author":{"gitId":"-"},"content":" * Returns a list of {@link Course} for all courses a given student is enrolled in."},{"lineNumber":75,"author":{"gitId":"-"},"content":" *"},{"lineNumber":76,"author":{"gitId":"-"},"content":" * @param googleId The Google ID of the student"},{"lineNumber":77,"author":{"gitId":"-"},"content":" */"},{"lineNumber":78,"author":{"gitId":"-"},"content":" public List\u003cCourse\u003e getCoursesForStudentAccount(String googleId) {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e students \u003d usersLogic.getAllStudentsByGoogleId(googleId);"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" return students"},{"lineNumber":82,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":83,"author":{"gitId":"-"},"content":" .map(Student::getCourse)"},{"lineNumber":84,"author":{"gitId":"-"},"content":" .filter(course -\u003e !course.isCourseDeleted())"},{"lineNumber":85,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":86,"author":{"gitId":"-"},"content":" }"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":89,"author":{"gitId":"-"},"content":" * Returns a list of {@link Course} for all courses for a given list of instructors"},{"lineNumber":90,"author":{"gitId":"-"},"content":" * except for courses in Recycle Bin."},{"lineNumber":91,"author":{"gitId":"-"},"content":" */"},{"lineNumber":92,"author":{"gitId":"-"},"content":" public List\u003cCourse\u003e getCoursesForInstructors(List\u003cInstructor\u003e instructors) {"},{"lineNumber":93,"author":{"gitId":"-"},"content":" assert instructors !\u003d null;"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" return instructors"},{"lineNumber":96,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":97,"author":{"gitId":"-"},"content":" .map(Instructor::getCourse)"},{"lineNumber":98,"author":{"gitId":"-"},"content":" .filter(course -\u003e !course.isCourseDeleted())"},{"lineNumber":99,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":103,"author":{"gitId":"-"},"content":" * Returns a list of soft-deleted {@link Course} for a given list of instructors."},{"lineNumber":104,"author":{"gitId":"-"},"content":" */"},{"lineNumber":105,"author":{"gitId":"-"},"content":" public List\u003cCourse\u003e getSoftDeletedCoursesForInstructors(List\u003cInstructor\u003e instructors) {"},{"lineNumber":106,"author":{"gitId":"-"},"content":" assert instructors !\u003d null;"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" return instructors"},{"lineNumber":109,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":110,"author":{"gitId":"-"},"content":" .map(Instructor::getCourse)"},{"lineNumber":111,"author":{"gitId":"-"},"content":" .filter(course -\u003e course.isCourseDeleted())"},{"lineNumber":112,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":113,"author":{"gitId":"-"},"content":" }"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":116,"author":{"gitId":"-"},"content":" * Deletes a course and cascade its students, instructors, sessions, responses, deadline extensions and comments."},{"lineNumber":117,"author":{"gitId":"-"},"content":" * Fails silently if no such course."},{"lineNumber":118,"author":{"gitId":"-"},"content":" */"},{"lineNumber":119,"author":{"gitId":"-"},"content":" public void deleteCourseCascade(String courseId) {"},{"lineNumber":120,"author":{"gitId":"-"},"content":" Course course \u003d coursesDb.getCourse(courseId);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":123,"author":{"gitId":"-"},"content":" }"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" usersLogic.deleteStudentsInCourseCascade(courseId);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e feedbackSessions \u003d fsLogic.getFeedbackSessionsForCourse(courseId);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" feedbackSessions.forEach(feedbackSession -\u003e {"},{"lineNumber":128,"author":{"gitId":"-"},"content":" fsLogic.deleteFeedbackSessionCascade(feedbackSession.getName(), courseId);"},{"lineNumber":129,"author":{"gitId":"-"},"content":" });"},{"lineNumber":130,"author":{"gitId":"-"},"content":" coursesDb.deleteSectionsByCourseId(courseId);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors \u003d usersLogic.getInstructorsForCourse(courseId);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" instructors.forEach(instructor -\u003e {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" usersLogic.deleteInstructorCascade(courseId, instructor.getEmail());"},{"lineNumber":134,"author":{"gitId":"-"},"content":" });"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" coursesDb.deleteCourse(course);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":140,"author":{"gitId":"-"},"content":" * Moves a course to Recycle Bin by its given corresponding ID."},{"lineNumber":141,"author":{"gitId":"-"},"content":" *"},{"lineNumber":142,"author":{"gitId":"-"},"content":" * @return the time when the course is moved to the recycle bin."},{"lineNumber":143,"author":{"gitId":"-"},"content":" */"},{"lineNumber":144,"author":{"gitId":"-"},"content":" public Course moveCourseToRecycleBin(String courseId) throws EntityDoesNotExistException {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" Course course \u003d coursesDb.getCourse(courseId);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":147,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Trying to move a non-existent course to recycling bin.\");"},{"lineNumber":148,"author":{"gitId":"-"},"content":" }"},{"lineNumber":149,"author":{"gitId":"-"},"content":""},{"lineNumber":150,"author":{"gitId":"-"},"content":" Instant now \u003d Instant.now();"},{"lineNumber":151,"author":{"gitId":"-"},"content":" course.setDeletedAt(now);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" return course;"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":156,"author":{"gitId":"-"},"content":" * Restores a course from Recycle Bin by its given corresponding ID."},{"lineNumber":157,"author":{"gitId":"-"},"content":" */"},{"lineNumber":158,"author":{"gitId":"-"},"content":" public void restoreCourseFromRecycleBin(String courseId) throws EntityDoesNotExistException {"},{"lineNumber":159,"author":{"gitId":"-"},"content":" Course course \u003d coursesDb.getCourse(courseId);"},{"lineNumber":160,"author":{"gitId":"-"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":161,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Trying to restore a non-existent course from recycling bin.\");"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" course.setDeletedAt(null);"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":168,"author":{"gitId":"-"},"content":" * Updates a course."},{"lineNumber":169,"author":{"gitId":"-"},"content":" *"},{"lineNumber":170,"author":{"gitId":"-"},"content":" * @return updated course"},{"lineNumber":171,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":172,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the course cannot be found"},{"lineNumber":173,"author":{"gitId":"-"},"content":" */"},{"lineNumber":174,"author":{"gitId":"-"},"content":" public Course updateCourse(String courseId, String name, String timezone)"},{"lineNumber":175,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" Course course \u003d getCourse(courseId);"},{"lineNumber":177,"author":{"gitId":"-"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT + Course.class);"},{"lineNumber":179,"author":{"gitId":"-"},"content":" }"},{"lineNumber":180,"author":{"gitId":"-"},"content":" course.setName(name);"},{"lineNumber":181,"author":{"gitId":"-"},"content":" course.setTimeZone(timezone);"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" if (!course.isValid()) {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(course.getInvalidityInfo());"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" return course;"},{"lineNumber":188,"author":{"gitId":"-"},"content":" }"},{"lineNumber":189,"author":{"gitId":"-"},"content":""},{"lineNumber":190,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":191,"author":{"gitId":"-"},"content":" * Creates a section."},{"lineNumber":192,"author":{"gitId":"-"},"content":" */"},{"lineNumber":193,"author":{"gitId":"-"},"content":" public Section createSection(Section section) throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":194,"author":{"gitId":"-"},"content":" return coursesDb.createSection(section);"},{"lineNumber":195,"author":{"gitId":"-"},"content":" }"},{"lineNumber":196,"author":{"gitId":"-"},"content":""},{"lineNumber":197,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":198,"author":{"gitId":"-"},"content":" * Get section by {@code courseId} and {@code teamName}."},{"lineNumber":199,"author":{"gitId":"-"},"content":" */"},{"lineNumber":200,"author":{"gitId":"-"},"content":" public Section getSectionByCourseIdAndTeam(String courseId, String teamName) {"},{"lineNumber":201,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":202,"author":{"gitId":"-"},"content":" assert teamName !\u003d null;"},{"lineNumber":203,"author":{"gitId":"-"},"content":""},{"lineNumber":204,"author":{"gitId":"-"},"content":" return coursesDb.getSectionByCourseIdAndTeam(courseId, teamName);"},{"lineNumber":205,"author":{"gitId":"-"},"content":" }"},{"lineNumber":206,"author":{"gitId":"-"},"content":""},{"lineNumber":207,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":208,"author":{"gitId":"-"},"content":" * Gets a list of section names for the given {@code courseId}."},{"lineNumber":209,"author":{"gitId":"-"},"content":" */"},{"lineNumber":210,"author":{"gitId":"-"},"content":" public List\u003cString\u003e getSectionNamesForCourse(String courseId) throws EntityDoesNotExistException {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":212,"author":{"gitId":"-"},"content":" Course course \u003d getCourse(courseId);"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Trying to get section names for a non-existent course.\");"},{"lineNumber":216,"author":{"gitId":"-"},"content":" }"},{"lineNumber":217,"author":{"gitId":"-"},"content":""},{"lineNumber":218,"author":{"gitId":"-"},"content":" return course.getSections()"},{"lineNumber":219,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":220,"author":{"gitId":"-"},"content":" .map(section -\u003e section.getName())"},{"lineNumber":221,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":222,"author":{"gitId":"-"},"content":" }"},{"lineNumber":223,"author":{"gitId":"-"},"content":""},{"lineNumber":224,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":225,"author":{"gitId":"yuanxi1"},"content":" * Gets the institute of the course."},{"lineNumber":226,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":227,"author":{"gitId":"yuanxi1"},"content":" public String getCourseInstitute(String courseId) {"},{"lineNumber":228,"author":{"gitId":"yuanxi1"},"content":" Course course \u003d getCourse(courseId);"},{"lineNumber":229,"author":{"gitId":"yuanxi1"},"content":" assert course !\u003d null : \"Trying to getCourseInstitute for inexistent course with id \" + courseId;"},{"lineNumber":230,"author":{"gitId":"yuanxi1"},"content":" return course.getInstitute();"},{"lineNumber":231,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":232,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":234,"author":{"gitId":"-"},"content":" * Creates a team."},{"lineNumber":235,"author":{"gitId":"-"},"content":" */"},{"lineNumber":236,"author":{"gitId":"-"},"content":" public Team createTeam(Team team) throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":237,"author":{"gitId":"-"},"content":" return coursesDb.createTeam(team);"},{"lineNumber":238,"author":{"gitId":"-"},"content":" }"},{"lineNumber":239,"author":{"gitId":"-"},"content":""},{"lineNumber":240,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":241,"author":{"gitId":"-"},"content":" * Returns teams for a particular section."},{"lineNumber":242,"author":{"gitId":"-"},"content":" */"},{"lineNumber":243,"author":{"gitId":"-"},"content":" public List\u003cTeam\u003e getTeamsForSection(Section section) {"},{"lineNumber":244,"author":{"gitId":"-"},"content":" return coursesDb.getTeamsForSection(section);"},{"lineNumber":245,"author":{"gitId":"-"},"content":" }"},{"lineNumber":246,"author":{"gitId":"-"},"content":""},{"lineNumber":247,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":248,"author":{"gitId":"-"},"content":" * Returns teams for a course."},{"lineNumber":249,"author":{"gitId":"-"},"content":" */"},{"lineNumber":250,"author":{"gitId":"-"},"content":" public List\u003cTeam\u003e getTeamsForCourse(String courseId) {"},{"lineNumber":251,"author":{"gitId":"-"},"content":" return coursesDb.getTeamsForCourse(courseId);"},{"lineNumber":252,"author":{"gitId":"-"},"content":" }"},{"lineNumber":253,"author":{"gitId":"-"},"content":""},{"lineNumber":254,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":255,"author":{"gitId":"-"},"content":" * Sorts the courses list alphabetically by id."},{"lineNumber":256,"author":{"gitId":"-"},"content":" */"},{"lineNumber":257,"author":{"gitId":"-"},"content":" public static void sortById(List\u003cCourse\u003e courses) {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" courses.sort(Comparator.comparing(Course::getId));"},{"lineNumber":259,"author":{"gitId":"-"},"content":" }"},{"lineNumber":260,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"yuanxi1":9,"-":251}},{"path":"src/main/java/teammates/sqllogic/core/DataBundleLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Collection;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.ReadNotification;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.User;"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":33,"author":{"gitId":"-"},"content":" * Handles operations related to data bundles."},{"lineNumber":34,"author":{"gitId":"-"},"content":" *"},{"lineNumber":35,"author":{"gitId":"-"},"content":" * @see DataBundle"},{"lineNumber":36,"author":{"gitId":"-"},"content":" */"},{"lineNumber":37,"author":{"gitId":"-"},"content":"public final class DataBundleLogic {"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" private static final DataBundleLogic instance \u003d new DataBundleLogic();"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" private AccountsLogic accountsLogic;"},{"lineNumber":42,"author":{"gitId":"-"},"content":" private AccountRequestsLogic accountRequestsLogic;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" private CoursesLogic coursesLogic;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" private DeadlineExtensionsLogic deadlineExtensionsLogic;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" private FeedbackSessionsLogic fsLogic;"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" private FeedbackSessionLogsLogic fslLogic;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" private FeedbackQuestionsLogic fqLogic;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" private FeedbackResponsesLogic frLogic;"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private FeedbackResponseCommentsLogic frcLogic;"},{"lineNumber":50,"author":{"gitId":"-"},"content":" private NotificationsLogic notificationsLogic;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" private UsersLogic usersLogic;"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" private DataBundleLogic() {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" public static DataBundleLogic inst() {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":59,"author":{"gitId":"-"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" void initLogicDependencies(AccountsLogic accountsLogic, AccountRequestsLogic accountRequestsLogic,"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" CoursesLogic coursesLogic, DeadlineExtensionsLogic deadlineExtensionsLogic, FeedbackSessionsLogic fsLogic,"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogsLogic fslLogic, FeedbackQuestionsLogic fqLogic, FeedbackResponsesLogic frLogic,"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" FeedbackResponseCommentsLogic frcLogic, NotificationsLogic notificationsLogic, UsersLogic usersLogic) {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" this.accountsLogic \u003d accountsLogic;"},{"lineNumber":66,"author":{"gitId":"-"},"content":" this.accountRequestsLogic \u003d accountRequestsLogic;"},{"lineNumber":67,"author":{"gitId":"-"},"content":" this.coursesLogic \u003d coursesLogic;"},{"lineNumber":68,"author":{"gitId":"-"},"content":" this.deadlineExtensionsLogic \u003d deadlineExtensionsLogic;"},{"lineNumber":69,"author":{"gitId":"-"},"content":" this.fsLogic \u003d fsLogic;"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" this.fslLogic \u003d fslLogic;"},{"lineNumber":71,"author":{"gitId":"-"},"content":" this.fqLogic \u003d fqLogic;"},{"lineNumber":72,"author":{"gitId":"-"},"content":" this.frLogic \u003d frLogic;"},{"lineNumber":73,"author":{"gitId":"-"},"content":" this.frcLogic \u003d frcLogic;"},{"lineNumber":74,"author":{"gitId":"-"},"content":" this.notificationsLogic \u003d notificationsLogic;"},{"lineNumber":75,"author":{"gitId":"-"},"content":" this.usersLogic \u003d usersLogic;"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":79,"author":{"gitId":"-"},"content":" * Deserialize JSON into a data bundle."},{"lineNumber":80,"author":{"gitId":"-"},"content":" *"},{"lineNumber":81,"author":{"gitId":"-"},"content":" * \u003cp\u003eNOTE: apart from for Course, ids used in the jsonString may be any valid UUID"},{"lineNumber":82,"author":{"gitId":"-"},"content":" * and are used only to link entities together. They will be replaced by a random"},{"lineNumber":83,"author":{"gitId":"-"},"content":" * UUID when deserialized and hence do not need to be checked if they exist in the"},{"lineNumber":84,"author":{"gitId":"-"},"content":" * database previously.\u003c/p\u003e"},{"lineNumber":85,"author":{"gitId":"-"},"content":" *"},{"lineNumber":86,"author":{"gitId":"-"},"content":" * @param jsonString containing entities to persist at once to the database."},{"lineNumber":87,"author":{"gitId":"-"},"content":" * CourseID must be a valid UUID not currently in use."},{"lineNumber":88,"author":{"gitId":"-"},"content":" * For other entities, replaces the given ids with randomly generated UUIDs."},{"lineNumber":89,"author":{"gitId":"-"},"content":" * @return newly created DataBundle"},{"lineNumber":90,"author":{"gitId":"-"},"content":" */"},{"lineNumber":91,"author":{"gitId":"-"},"content":" public static SqlDataBundle deserializeDataBundle(String jsonString) {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" SqlDataBundle dataBundle \u003d JsonUtils.fromJson(jsonString, SqlDataBundle.class);"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" Collection\u003cAccount\u003e accounts \u003d dataBundle.accounts.values();"},{"lineNumber":95,"author":{"gitId":"-"},"content":" Collection\u003cAccountRequest\u003e accountRequests \u003d dataBundle.accountRequests.values();"},{"lineNumber":96,"author":{"gitId":"-"},"content":" Collection\u003cCourse\u003e courses \u003d dataBundle.courses.values();"},{"lineNumber":97,"author":{"gitId":"-"},"content":" Collection\u003cSection\u003e sections \u003d dataBundle.sections.values();"},{"lineNumber":98,"author":{"gitId":"-"},"content":" Collection\u003cTeam\u003e teams \u003d dataBundle.teams.values();"},{"lineNumber":99,"author":{"gitId":"-"},"content":" Collection\u003cInstructor\u003e instructors \u003d dataBundle.instructors.values();"},{"lineNumber":100,"author":{"gitId":"-"},"content":" Collection\u003cStudent\u003e students \u003d dataBundle.students.values();"},{"lineNumber":101,"author":{"gitId":"-"},"content":" Collection\u003cFeedbackSession\u003e sessions \u003d dataBundle.feedbackSessions.values();"},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" Collection\u003cFeedbackSessionLog\u003e sessionLogs \u003d dataBundle.feedbackSessionLogs.values();"},{"lineNumber":103,"author":{"gitId":"-"},"content":" Collection\u003cFeedbackQuestion\u003e questions \u003d dataBundle.feedbackQuestions.values();"},{"lineNumber":104,"author":{"gitId":"-"},"content":" Collection\u003cFeedbackResponse\u003e responses \u003d dataBundle.feedbackResponses.values();"},{"lineNumber":105,"author":{"gitId":"-"},"content":" Collection\u003cFeedbackResponseComment\u003e responseComments \u003d dataBundle.feedbackResponseComments.values();"},{"lineNumber":106,"author":{"gitId":"-"},"content":" Collection\u003cDeadlineExtension\u003e deadlineExtensions \u003d dataBundle.deadlineExtensions.values();"},{"lineNumber":107,"author":{"gitId":"-"},"content":" Collection\u003cNotification\u003e notifications \u003d dataBundle.notifications.values();"},{"lineNumber":108,"author":{"gitId":"-"},"content":" Collection\u003cReadNotification\u003e readNotifications \u003d dataBundle.readNotifications.values();"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" // Mapping of IDs or placeholder IDs to actual entity"},{"lineNumber":111,"author":{"gitId":"-"},"content":" Map\u003cString, Course\u003e coursesMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":112,"author":{"gitId":"-"},"content":" Map\u003cUUID, Section\u003e sectionsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":113,"author":{"gitId":"-"},"content":" Map\u003cUUID, Team\u003e teamsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":114,"author":{"gitId":"-"},"content":" Map\u003cUUID, FeedbackSession\u003e sessionsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":115,"author":{"gitId":"-"},"content":" Map\u003cUUID, FeedbackQuestion\u003e questionMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":116,"author":{"gitId":"-"},"content":" Map\u003cUUID, FeedbackResponse\u003e responseMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":117,"author":{"gitId":"-"},"content":" Map\u003cUUID, Account\u003e accountsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":118,"author":{"gitId":"-"},"content":" Map\u003cUUID, User\u003e usersMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":119,"author":{"gitId":"-"},"content":" Map\u003cUUID, Notification\u003e notificationsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":120,"author":{"gitId":"-"},"content":""},{"lineNumber":121,"author":{"gitId":"-"},"content":" // Replace any placeholder IDs with newly generated UUIDs"},{"lineNumber":122,"author":{"gitId":"-"},"content":" // Store mapping of placeholder ID to actual entity to keep track of"},{"lineNumber":123,"author":{"gitId":"-"},"content":" // associations between entities"},{"lineNumber":124,"author":{"gitId":"-"},"content":" for (AccountRequest accountRequest : accountRequests) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" accountRequest.setId(UUID.randomUUID());"},{"lineNumber":126,"author":{"gitId":"-"},"content":" accountRequest.generateNewRegistrationKey();"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" for (Course course : courses) {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" coursesMap.put(course.getId(), course);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" }"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" for (Section section : sections) {"},{"lineNumber":134,"author":{"gitId":"-"},"content":" UUID placeholderId \u003d section.getId();"},{"lineNumber":135,"author":{"gitId":"-"},"content":" section.setId(UUID.randomUUID());"},{"lineNumber":136,"author":{"gitId":"-"},"content":" sectionsMap.put(placeholderId, section);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" Course course \u003d coursesMap.get(section.getCourse().getId());"},{"lineNumber":138,"author":{"gitId":"-"},"content":" section.setCourse(course);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" }"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" for (Team team : teams) {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" UUID placeholderId \u003d team.getId();"},{"lineNumber":143,"author":{"gitId":"-"},"content":" team.setId(UUID.randomUUID());"},{"lineNumber":144,"author":{"gitId":"-"},"content":" teamsMap.put(placeholderId, team);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" Section section \u003d sectionsMap.get(team.getSection().getId());"},{"lineNumber":146,"author":{"gitId":"-"},"content":" team.setSection(section);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" for (FeedbackSession session : sessions) {"},{"lineNumber":150,"author":{"gitId":"-"},"content":" UUID placeholderId \u003d session.getId();"},{"lineNumber":151,"author":{"gitId":"-"},"content":" session.setId(UUID.randomUUID());"},{"lineNumber":152,"author":{"gitId":"-"},"content":" sessionsMap.put(placeholderId, session);"},{"lineNumber":153,"author":{"gitId":"-"},"content":" Course course \u003d coursesMap.get(session.getCourse().getId());"},{"lineNumber":154,"author":{"gitId":"-"},"content":" session.setCourse(course);"},{"lineNumber":155,"author":{"gitId":"-"},"content":" }"},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"-"},"content":" for (FeedbackQuestion question : questions) {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" UUID placeholderId \u003d question.getId();"},{"lineNumber":159,"author":{"gitId":"-"},"content":" question.setId(UUID.randomUUID());"},{"lineNumber":160,"author":{"gitId":"-"},"content":" questionMap.put(placeholderId, question);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d sessionsMap.get(question.getFeedbackSession().getId());"},{"lineNumber":162,"author":{"gitId":"-"},"content":" question.setFeedbackSession(fs);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" for (FeedbackResponse response : responses) {"},{"lineNumber":166,"author":{"gitId":"-"},"content":" UUID placeholderId \u003d response.getId();"},{"lineNumber":167,"author":{"gitId":"-"},"content":" response.setId(UUID.randomUUID());"},{"lineNumber":168,"author":{"gitId":"-"},"content":" responseMap.put(placeholderId, response);"},{"lineNumber":169,"author":{"gitId":"-"},"content":" FeedbackQuestion fq \u003d questionMap.get(response.getFeedbackQuestion().getId());"},{"lineNumber":170,"author":{"gitId":"-"},"content":" Section giverSection \u003d sectionsMap.get(response.getGiverSection().getId());"},{"lineNumber":171,"author":{"gitId":"-"},"content":" Section recipientSection \u003d response.getRecipientSection() !\u003d null"},{"lineNumber":172,"author":{"gitId":"-"},"content":" ? sectionsMap.get(response.getRecipientSection().getId()) : null;"},{"lineNumber":173,"author":{"gitId":"-"},"content":" response.setFeedbackQuestion(fq);"},{"lineNumber":174,"author":{"gitId":"-"},"content":" response.setGiverSection(giverSection);"},{"lineNumber":175,"author":{"gitId":"-"},"content":" response.setRecipientSection(recipientSection);"},{"lineNumber":176,"author":{"gitId":"-"},"content":" }"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" for (FeedbackResponseComment responseComment : responseComments) {"},{"lineNumber":179,"author":{"gitId":"-"},"content":" FeedbackResponse fr \u003d responseMap.get(responseComment.getFeedbackResponse().getId());"},{"lineNumber":180,"author":{"gitId":"-"},"content":" Section giverSection \u003d sectionsMap.get(responseComment.getGiverSection().getId());"},{"lineNumber":181,"author":{"gitId":"-"},"content":" Section recipientSection \u003d sectionsMap.get(responseComment.getRecipientSection().getId());"},{"lineNumber":182,"author":{"gitId":"-"},"content":" responseComment.setFeedbackResponse(fr);"},{"lineNumber":183,"author":{"gitId":"-"},"content":" responseComment.setGiverSection(giverSection);"},{"lineNumber":184,"author":{"gitId":"-"},"content":" responseComment.setRecipientSection(recipientSection);"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" for (Account account : accounts) {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" UUID placeholderId \u003d account.getId();"},{"lineNumber":189,"author":{"gitId":"-"},"content":" account.setId(UUID.randomUUID());"},{"lineNumber":190,"author":{"gitId":"-"},"content":" accountsMap.put(placeholderId, account);"},{"lineNumber":191,"author":{"gitId":"-"},"content":" }"},{"lineNumber":192,"author":{"gitId":"-"},"content":""},{"lineNumber":193,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructors) {"},{"lineNumber":194,"author":{"gitId":"-"},"content":" UUID placeholderId \u003d instructor.getId();"},{"lineNumber":195,"author":{"gitId":"-"},"content":" instructor.setId(UUID.randomUUID());"},{"lineNumber":196,"author":{"gitId":"-"},"content":" usersMap.put(placeholderId, instructor);"},{"lineNumber":197,"author":{"gitId":"-"},"content":" Course course \u003d coursesMap.get(instructor.getCourse().getId());"},{"lineNumber":198,"author":{"gitId":"-"},"content":" instructor.setCourse(course);"},{"lineNumber":199,"author":{"gitId":"-"},"content":" if (instructor.getAccount() !\u003d null) {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" Account account \u003d accountsMap.get(instructor.getAccount().getId());"},{"lineNumber":201,"author":{"gitId":"-"},"content":" instructor.setAccount(account);"},{"lineNumber":202,"author":{"gitId":"-"},"content":" }"},{"lineNumber":203,"author":{"gitId":"-"},"content":" instructor.generateNewRegistrationKey();"},{"lineNumber":204,"author":{"gitId":"-"},"content":" }"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" for (Student student : students) {"},{"lineNumber":207,"author":{"gitId":"-"},"content":" UUID placeholderId \u003d student.getId();"},{"lineNumber":208,"author":{"gitId":"-"},"content":" student.setId(UUID.randomUUID());"},{"lineNumber":209,"author":{"gitId":"-"},"content":" usersMap.put(placeholderId, student);"},{"lineNumber":210,"author":{"gitId":"-"},"content":" Course course \u003d coursesMap.get(student.getCourse().getId());"},{"lineNumber":211,"author":{"gitId":"-"},"content":" student.setCourse(course);"},{"lineNumber":212,"author":{"gitId":"-"},"content":" Team team \u003d teamsMap.get(student.getTeam().getId());"},{"lineNumber":213,"author":{"gitId":"-"},"content":" student.setTeam(team);"},{"lineNumber":214,"author":{"gitId":"-"},"content":" if (student.getAccount() !\u003d null) {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" Account account \u003d accountsMap.get(student.getAccount().getId());"},{"lineNumber":216,"author":{"gitId":"-"},"content":" student.setAccount(account);"},{"lineNumber":217,"author":{"gitId":"-"},"content":" }"},{"lineNumber":218,"author":{"gitId":"-"},"content":" student.generateNewRegistrationKey();"},{"lineNumber":219,"author":{"gitId":"-"},"content":" }"},{"lineNumber":220,"author":{"gitId":"-"},"content":""},{"lineNumber":221,"author":{"gitId":"dishenggg"},"content":" for (FeedbackSessionLog log : sessionLogs) {"},{"lineNumber":222,"author":{"gitId":"dishenggg"},"content":" log.setId(UUID.randomUUID());"},{"lineNumber":223,"author":{"gitId":"dishenggg"},"content":" FeedbackSession fs \u003d sessionsMap.get(log.getFeedbackSession().getId());"},{"lineNumber":224,"author":{"gitId":"dishenggg"},"content":" log.setFeedbackSession(fs);"},{"lineNumber":225,"author":{"gitId":"dishenggg"},"content":" Student student \u003d (Student) usersMap.get(log.getStudent().getId());"},{"lineNumber":226,"author":{"gitId":"dishenggg"},"content":" log.setStudent(student);"},{"lineNumber":227,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":228,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" for (Notification notification : notifications) {"},{"lineNumber":230,"author":{"gitId":"-"},"content":" UUID placeholderId \u003d notification.getId();"},{"lineNumber":231,"author":{"gitId":"-"},"content":" notification.setId(UUID.randomUUID());"},{"lineNumber":232,"author":{"gitId":"-"},"content":" notificationsMap.put(placeholderId, notification);"},{"lineNumber":233,"author":{"gitId":"-"},"content":" }"},{"lineNumber":234,"author":{"gitId":"-"},"content":""},{"lineNumber":235,"author":{"gitId":"-"},"content":" for (ReadNotification readNotification : readNotifications) {"},{"lineNumber":236,"author":{"gitId":"-"},"content":" readNotification.setId(UUID.randomUUID());"},{"lineNumber":237,"author":{"gitId":"-"},"content":" Account account \u003d accountsMap.get(readNotification.getAccount().getId());"},{"lineNumber":238,"author":{"gitId":"-"},"content":" readNotification.setAccount(account);"},{"lineNumber":239,"author":{"gitId":"-"},"content":" account.addReadNotification(readNotification);"},{"lineNumber":240,"author":{"gitId":"-"},"content":" Notification notification \u003d notificationsMap.get(readNotification.getNotification().getId());"},{"lineNumber":241,"author":{"gitId":"-"},"content":" readNotification.setNotification(notification);"},{"lineNumber":242,"author":{"gitId":"-"},"content":" }"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" for (DeadlineExtension deadlineExtension : deadlineExtensions) {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" deadlineExtension.setId(UUID.randomUUID());"},{"lineNumber":246,"author":{"gitId":"-"},"content":" FeedbackSession session \u003d sessionsMap.get(deadlineExtension.getFeedbackSession().getId());"},{"lineNumber":247,"author":{"gitId":"-"},"content":" deadlineExtension.setFeedbackSession(session);"},{"lineNumber":248,"author":{"gitId":"-"},"content":" User user \u003d usersMap.get(deadlineExtension.getUser().getId());"},{"lineNumber":249,"author":{"gitId":"-"},"content":" deadlineExtension.setUser(user);"},{"lineNumber":250,"author":{"gitId":"-"},"content":" }"},{"lineNumber":251,"author":{"gitId":"-"},"content":""},{"lineNumber":252,"author":{"gitId":"-"},"content":" return dataBundle;"},{"lineNumber":253,"author":{"gitId":"-"},"content":" }"},{"lineNumber":254,"author":{"gitId":"-"},"content":""},{"lineNumber":255,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":256,"author":{"gitId":"-"},"content":" * Persists data in the given {@link DataBundle} to the database."},{"lineNumber":257,"author":{"gitId":"-"},"content":" *"},{"lineNumber":258,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if invalid data is encountered."},{"lineNumber":259,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if an entity was not found."},{"lineNumber":260,"author":{"gitId":"-"},"content":" * (ReadNotification requires Account and Notification to be created)"},{"lineNumber":261,"author":{"gitId":"-"},"content":" */"},{"lineNumber":262,"author":{"gitId":"-"},"content":" public SqlDataBundle persistDataBundle(SqlDataBundle dataBundle)"},{"lineNumber":263,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException, EntityDoesNotExistException {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" if (dataBundle \u003d\u003d null) {"},{"lineNumber":265,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(\"Null data bundle\");"},{"lineNumber":266,"author":{"gitId":"-"},"content":" }"},{"lineNumber":267,"author":{"gitId":"-"},"content":""},{"lineNumber":268,"author":{"gitId":"yuanxi1"},"content":" linkEntities(dataBundle);"},{"lineNumber":269,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":" Collection\u003cAccount\u003e accounts \u003d dataBundle.accounts.values();"},{"lineNumber":271,"author":{"gitId":"-"},"content":" Collection\u003cAccountRequest\u003e accountRequests \u003d dataBundle.accountRequests.values();"},{"lineNumber":272,"author":{"gitId":"-"},"content":" Collection\u003cCourse\u003e courses \u003d dataBundle.courses.values();"},{"lineNumber":273,"author":{"gitId":"-"},"content":" Collection\u003cSection\u003e sections \u003d dataBundle.sections.values();"},{"lineNumber":274,"author":{"gitId":"-"},"content":" Collection\u003cTeam\u003e teams \u003d dataBundle.teams.values();"},{"lineNumber":275,"author":{"gitId":"-"},"content":" Collection\u003cInstructor\u003e instructors \u003d dataBundle.instructors.values();"},{"lineNumber":276,"author":{"gitId":"-"},"content":" Collection\u003cStudent\u003e students \u003d dataBundle.students.values();"},{"lineNumber":277,"author":{"gitId":"-"},"content":" Collection\u003cFeedbackSession\u003e sessions \u003d dataBundle.feedbackSessions.values();"},{"lineNumber":278,"author":{"gitId":"dishenggg"},"content":" Collection\u003cFeedbackSessionLog\u003e sessionLogs \u003d dataBundle.feedbackSessionLogs.values();"},{"lineNumber":279,"author":{"gitId":"-"},"content":" Collection\u003cFeedbackQuestion\u003e questions \u003d dataBundle.feedbackQuestions.values();"},{"lineNumber":280,"author":{"gitId":"-"},"content":" Collection\u003cFeedbackResponse\u003e responses \u003d dataBundle.feedbackResponses.values();"},{"lineNumber":281,"author":{"gitId":"-"},"content":" Collection\u003cFeedbackResponseComment\u003e responseComments \u003d dataBundle.feedbackResponseComments.values();"},{"lineNumber":282,"author":{"gitId":"-"},"content":" Collection\u003cDeadlineExtension\u003e deadlineExtensions \u003d dataBundle.deadlineExtensions.values();"},{"lineNumber":283,"author":{"gitId":"-"},"content":" Collection\u003cNotification\u003e notifications \u003d dataBundle.notifications.values();"},{"lineNumber":284,"author":{"gitId":"-"},"content":" Collection\u003cReadNotification\u003e readNotifications \u003d dataBundle.readNotifications.values();"},{"lineNumber":285,"author":{"gitId":"-"},"content":""},{"lineNumber":286,"author":{"gitId":"-"},"content":" for (AccountRequest accountRequest : accountRequests) {"},{"lineNumber":287,"author":{"gitId":"-"},"content":" accountRequestsLogic.createAccountRequest(accountRequest);"},{"lineNumber":288,"author":{"gitId":"-"},"content":" }"},{"lineNumber":289,"author":{"gitId":"-"},"content":""},{"lineNumber":290,"author":{"gitId":"-"},"content":" for (Notification notification : notifications) {"},{"lineNumber":291,"author":{"gitId":"-"},"content":" notificationsLogic.createNotification(notification);"},{"lineNumber":292,"author":{"gitId":"-"},"content":" }"},{"lineNumber":293,"author":{"gitId":"-"},"content":""},{"lineNumber":294,"author":{"gitId":"-"},"content":" for (Course course : courses) {"},{"lineNumber":295,"author":{"gitId":"-"},"content":" coursesLogic.createCourse(course);"},{"lineNumber":296,"author":{"gitId":"-"},"content":" }"},{"lineNumber":297,"author":{"gitId":"-"},"content":""},{"lineNumber":298,"author":{"gitId":"-"},"content":" for (Section section : sections) {"},{"lineNumber":299,"author":{"gitId":"-"},"content":" coursesLogic.createSection(section);"},{"lineNumber":300,"author":{"gitId":"-"},"content":" }"},{"lineNumber":301,"author":{"gitId":"-"},"content":""},{"lineNumber":302,"author":{"gitId":"-"},"content":" for (Team team : teams) {"},{"lineNumber":303,"author":{"gitId":"-"},"content":" coursesLogic.createTeam(team);"},{"lineNumber":304,"author":{"gitId":"-"},"content":" }"},{"lineNumber":305,"author":{"gitId":"-"},"content":""},{"lineNumber":306,"author":{"gitId":"-"},"content":" for (FeedbackSession session : sessions) {"},{"lineNumber":307,"author":{"gitId":"-"},"content":" fsLogic.createFeedbackSession(session);"},{"lineNumber":308,"author":{"gitId":"-"},"content":" }"},{"lineNumber":309,"author":{"gitId":"-"},"content":""},{"lineNumber":310,"author":{"gitId":"-"},"content":" for (FeedbackQuestion question : questions) {"},{"lineNumber":311,"author":{"gitId":"-"},"content":" fqLogic.createFeedbackQuestion(question);"},{"lineNumber":312,"author":{"gitId":"-"},"content":" }"},{"lineNumber":313,"author":{"gitId":"-"},"content":""},{"lineNumber":314,"author":{"gitId":"-"},"content":" for (FeedbackResponse response : responses) {"},{"lineNumber":315,"author":{"gitId":"-"},"content":" frLogic.createFeedbackResponse(response);"},{"lineNumber":316,"author":{"gitId":"-"},"content":" }"},{"lineNumber":317,"author":{"gitId":"-"},"content":""},{"lineNumber":318,"author":{"gitId":"-"},"content":" for (FeedbackResponseComment responseComment : responseComments) {"},{"lineNumber":319,"author":{"gitId":"-"},"content":" responseComment.setId(null);"},{"lineNumber":320,"author":{"gitId":"-"},"content":" frcLogic.createFeedbackResponseComment(responseComment);"},{"lineNumber":321,"author":{"gitId":"-"},"content":" }"},{"lineNumber":322,"author":{"gitId":"-"},"content":""},{"lineNumber":323,"author":{"gitId":"-"},"content":" for (Account account : accounts) {"},{"lineNumber":324,"author":{"gitId":"-"},"content":" accountsLogic.createAccount(account);"},{"lineNumber":325,"author":{"gitId":"-"},"content":" }"},{"lineNumber":326,"author":{"gitId":"-"},"content":""},{"lineNumber":327,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructors) {"},{"lineNumber":328,"author":{"gitId":"-"},"content":" usersLogic.createInstructor(instructor);"},{"lineNumber":329,"author":{"gitId":"-"},"content":" }"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" for (Student student : students) {"},{"lineNumber":332,"author":{"gitId":"-"},"content":" usersLogic.createStudent(student);"},{"lineNumber":333,"author":{"gitId":"-"},"content":" }"},{"lineNumber":334,"author":{"gitId":"-"},"content":""},{"lineNumber":335,"author":{"gitId":"dishenggg"},"content":" fslLogic.createFeedbackSessionLogs(new ArrayList\u003c\u003e(sessionLogs));"},{"lineNumber":336,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":337,"author":{"gitId":"-"},"content":" for (ReadNotification readNotification : readNotifications) {"},{"lineNumber":338,"author":{"gitId":"-"},"content":" accountsLogic.updateReadNotifications(readNotification.getAccount().getGoogleId(),"},{"lineNumber":339,"author":{"gitId":"-"},"content":" readNotification.getNotification().getId(), readNotification.getNotification().getEndTime());"},{"lineNumber":340,"author":{"gitId":"-"},"content":" }"},{"lineNumber":341,"author":{"gitId":"-"},"content":""},{"lineNumber":342,"author":{"gitId":"-"},"content":" for (DeadlineExtension deadlineExtension : deadlineExtensions) {"},{"lineNumber":343,"author":{"gitId":"-"},"content":" deadlineExtensionsLogic.createDeadlineExtension(deadlineExtension);"},{"lineNumber":344,"author":{"gitId":"-"},"content":" }"},{"lineNumber":345,"author":{"gitId":"-"},"content":""},{"lineNumber":346,"author":{"gitId":"-"},"content":" return dataBundle;"},{"lineNumber":347,"author":{"gitId":"-"},"content":" }"},{"lineNumber":348,"author":{"gitId":"-"},"content":""},{"lineNumber":349,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":350,"author":{"gitId":"-"},"content":" * Removes the items in the data bundle from the database."},{"lineNumber":351,"author":{"gitId":"-"},"content":" */"},{"lineNumber":352,"author":{"gitId":"-"},"content":" public void removeDataBundle(SqlDataBundle dataBundle) throws InvalidParametersException {"},{"lineNumber":353,"author":{"gitId":"-"},"content":" if (dataBundle \u003d\u003d null) {"},{"lineNumber":354,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(\"Data bundle is null\");"},{"lineNumber":355,"author":{"gitId":"-"},"content":" }"},{"lineNumber":356,"author":{"gitId":"-"},"content":""},{"lineNumber":357,"author":{"gitId":"yuanxi1"},"content":" linkEntities(dataBundle);"},{"lineNumber":358,"author":{"gitId":"-"},"content":" dataBundle.courses.values().forEach(course -\u003e {"},{"lineNumber":359,"author":{"gitId":"-"},"content":" coursesLogic.deleteCourseCascade(course.getId());"},{"lineNumber":360,"author":{"gitId":"-"},"content":" });"},{"lineNumber":361,"author":{"gitId":"-"},"content":" dataBundle.notifications.values().forEach(notification -\u003e {"},{"lineNumber":362,"author":{"gitId":"-"},"content":" notificationsLogic.deleteNotification(notification.getId());"},{"lineNumber":363,"author":{"gitId":"-"},"content":" });"},{"lineNumber":364,"author":{"gitId":"-"},"content":" dataBundle.accounts.values().forEach(account -\u003e {"},{"lineNumber":365,"author":{"gitId":"-"},"content":" accountsLogic.deleteAccount(account.getGoogleId());"},{"lineNumber":366,"author":{"gitId":"-"},"content":" });"},{"lineNumber":367,"author":{"gitId":"-"},"content":" dataBundle.accountRequests.values().forEach(accountRequest -\u003e {"},{"lineNumber":368,"author":{"gitId":"dishenggg"},"content":" accountRequestsLogic.deleteAccountRequest(accountRequest.getId());"},{"lineNumber":369,"author":{"gitId":"-"},"content":" });"},{"lineNumber":370,"author":{"gitId":"-"},"content":" }"},{"lineNumber":371,"author":{"gitId":"-"},"content":""},{"lineNumber":372,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":373,"author":{"gitId":"-"},"content":" * Creates document for entities that have document, i.e. searchable."},{"lineNumber":374,"author":{"gitId":"-"},"content":" */"},{"lineNumber":375,"author":{"gitId":"-"},"content":" public void putDocuments(SqlDataBundle dataBundle) throws SearchServiceException {"},{"lineNumber":376,"author":{"gitId":"-"},"content":" Map\u003cString, Student\u003e students \u003d dataBundle.students;"},{"lineNumber":377,"author":{"gitId":"-"},"content":" for (Student student : students.values()) {"},{"lineNumber":378,"author":{"gitId":"-"},"content":" usersLogic.putStudentDocument(student);"},{"lineNumber":379,"author":{"gitId":"-"},"content":" }"},{"lineNumber":380,"author":{"gitId":"-"},"content":""},{"lineNumber":381,"author":{"gitId":"-"},"content":" Map\u003cString, Instructor\u003e instructors \u003d dataBundle.instructors;"},{"lineNumber":382,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructors.values()) {"},{"lineNumber":383,"author":{"gitId":"-"},"content":" usersLogic.putInstructorDocument(instructor);"},{"lineNumber":384,"author":{"gitId":"-"},"content":" }"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"-"},"content":" Map\u003cString, AccountRequest\u003e accountRequests \u003d dataBundle.accountRequests;"},{"lineNumber":387,"author":{"gitId":"-"},"content":" for (AccountRequest accountRequest : accountRequests.values()) {"},{"lineNumber":388,"author":{"gitId":"-"},"content":" accountRequestsLogic.putDocument(accountRequest);"},{"lineNumber":389,"author":{"gitId":"-"},"content":" }"},{"lineNumber":390,"author":{"gitId":"-"},"content":" }"},{"lineNumber":391,"author":{"gitId":"-"},"content":""},{"lineNumber":392,"author":{"gitId":"yuanxi1"},"content":" private static void linkEntities(SqlDataBundle dataBundle) {"},{"lineNumber":393,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cAccount\u003e accounts \u003d dataBundle.accounts.values();"},{"lineNumber":394,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cCourse\u003e courses \u003d dataBundle.courses.values();"},{"lineNumber":395,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cSection\u003e sections \u003d dataBundle.sections.values();"},{"lineNumber":396,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cTeam\u003e teams \u003d dataBundle.teams.values();"},{"lineNumber":397,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cInstructor\u003e instructors \u003d dataBundle.instructors.values();"},{"lineNumber":398,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cStudent\u003e students \u003d dataBundle.students.values();"},{"lineNumber":399,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cFeedbackSession\u003e sessions \u003d dataBundle.feedbackSessions.values();"},{"lineNumber":400,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cFeedbackQuestion\u003e questions \u003d dataBundle.feedbackQuestions.values();"},{"lineNumber":401,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cFeedbackResponse\u003e responses \u003d dataBundle.feedbackResponses.values();"},{"lineNumber":402,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cFeedbackResponseComment\u003e responseComments \u003d dataBundle.feedbackResponseComments.values();"},{"lineNumber":403,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cDeadlineExtension\u003e deadlineExtensions \u003d dataBundle.deadlineExtensions.values();"},{"lineNumber":404,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cNotification\u003e notifications \u003d dataBundle.notifications.values();"},{"lineNumber":405,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cReadNotification\u003e readNotifications \u003d dataBundle.readNotifications.values();"},{"lineNumber":406,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":407,"author":{"gitId":"yuanxi1"},"content":" // Mapping of IDs or placeholder IDs to actual entity"},{"lineNumber":408,"author":{"gitId":"yuanxi1"},"content":" Map\u003cString, Course\u003e coursesMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":409,"author":{"gitId":"yuanxi1"},"content":" Map\u003cUUID, Section\u003e sectionsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":410,"author":{"gitId":"yuanxi1"},"content":" Map\u003cUUID, Team\u003e teamsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":411,"author":{"gitId":"yuanxi1"},"content":" Map\u003cUUID, FeedbackSession\u003e sessionsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":412,"author":{"gitId":"yuanxi1"},"content":" Map\u003cUUID, FeedbackQuestion\u003e questionMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":413,"author":{"gitId":"yuanxi1"},"content":" Map\u003cUUID, FeedbackResponse\u003e responseMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":414,"author":{"gitId":"yuanxi1"},"content":" Map\u003cUUID, Account\u003e accountsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":415,"author":{"gitId":"yuanxi1"},"content":" Map\u003cUUID, User\u003e usersMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":416,"author":{"gitId":"yuanxi1"},"content":" Map\u003cUUID, Notification\u003e notificationsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":417,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":418,"author":{"gitId":"yuanxi1"},"content":" for (Course course : courses) {"},{"lineNumber":419,"author":{"gitId":"yuanxi1"},"content":" coursesMap.put(course.getId(), course);"},{"lineNumber":420,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":421,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":422,"author":{"gitId":"yuanxi1"},"content":" for (Section section : sections) {"},{"lineNumber":423,"author":{"gitId":"yuanxi1"},"content":" sectionsMap.put(section.getId(), section);"},{"lineNumber":424,"author":{"gitId":"yuanxi1"},"content":" Course course \u003d coursesMap.get(section.getCourse().getId());"},{"lineNumber":425,"author":{"gitId":"yuanxi1"},"content":" section.setCourse(course);"},{"lineNumber":426,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":427,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":428,"author":{"gitId":"yuanxi1"},"content":" for (Team team : teams) {"},{"lineNumber":429,"author":{"gitId":"yuanxi1"},"content":" teamsMap.put(team.getId(), team);"},{"lineNumber":430,"author":{"gitId":"yuanxi1"},"content":" Section section \u003d sectionsMap.get(team.getSection().getId());"},{"lineNumber":431,"author":{"gitId":"yuanxi1"},"content":" team.setSection(section);"},{"lineNumber":432,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":433,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":434,"author":{"gitId":"yuanxi1"},"content":" for (FeedbackSession session : sessions) {"},{"lineNumber":435,"author":{"gitId":"yuanxi1"},"content":" sessionsMap.put(session.getId(), session);"},{"lineNumber":436,"author":{"gitId":"yuanxi1"},"content":" Course course \u003d coursesMap.get(session.getCourse().getId());"},{"lineNumber":437,"author":{"gitId":"yuanxi1"},"content":" session.setCourse(course);"},{"lineNumber":438,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":439,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":440,"author":{"gitId":"yuanxi1"},"content":" for (FeedbackQuestion question : questions) {"},{"lineNumber":441,"author":{"gitId":"yuanxi1"},"content":" questionMap.put(question.getId(), question);"},{"lineNumber":442,"author":{"gitId":"yuanxi1"},"content":" FeedbackSession fs \u003d sessionsMap.get(question.getFeedbackSession().getId());"},{"lineNumber":443,"author":{"gitId":"yuanxi1"},"content":" question.setFeedbackSession(fs);"},{"lineNumber":444,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":445,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":446,"author":{"gitId":"yuanxi1"},"content":" for (FeedbackResponse response : responses) {"},{"lineNumber":447,"author":{"gitId":"yuanxi1"},"content":" UUID placeholderId \u003d response.getId();"},{"lineNumber":448,"author":{"gitId":"yuanxi1"},"content":" responseMap.put(placeholderId, response);"},{"lineNumber":449,"author":{"gitId":"yuanxi1"},"content":" FeedbackQuestion fq \u003d questionMap.get(response.getFeedbackQuestion().getId());"},{"lineNumber":450,"author":{"gitId":"yuanxi1"},"content":" Section giverSection \u003d sectionsMap.get(response.getGiverSection().getId());"},{"lineNumber":451,"author":{"gitId":"yuanxi1"},"content":" Section recipientSection \u003d response.getRecipientSection() !\u003d null"},{"lineNumber":452,"author":{"gitId":"yuanxi1"},"content":" ? sectionsMap.get(response.getRecipientSection().getId()) : null;"},{"lineNumber":453,"author":{"gitId":"yuanxi1"},"content":" response.setFeedbackQuestion(fq);"},{"lineNumber":454,"author":{"gitId":"yuanxi1"},"content":" response.setGiverSection(giverSection);"},{"lineNumber":455,"author":{"gitId":"yuanxi1"},"content":" response.setRecipientSection(recipientSection);"},{"lineNumber":456,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":457,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":458,"author":{"gitId":"yuanxi1"},"content":" for (FeedbackResponseComment responseComment : responseComments) {"},{"lineNumber":459,"author":{"gitId":"yuanxi1"},"content":" FeedbackResponse fr \u003d responseMap.get(responseComment.getFeedbackResponse().getId());"},{"lineNumber":460,"author":{"gitId":"yuanxi1"},"content":" Section giverSection \u003d sectionsMap.get(responseComment.getGiverSection().getId());"},{"lineNumber":461,"author":{"gitId":"yuanxi1"},"content":" Section recipientSection \u003d sectionsMap.get(responseComment.getRecipientSection().getId());"},{"lineNumber":462,"author":{"gitId":"yuanxi1"},"content":" responseComment.setFeedbackResponse(fr);"},{"lineNumber":463,"author":{"gitId":"yuanxi1"},"content":" responseComment.setGiverSection(giverSection);"},{"lineNumber":464,"author":{"gitId":"yuanxi1"},"content":" responseComment.setRecipientSection(recipientSection);"},{"lineNumber":465,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":466,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":467,"author":{"gitId":"yuanxi1"},"content":" for (Account account : accounts) {"},{"lineNumber":468,"author":{"gitId":"yuanxi1"},"content":" accountsMap.put(account.getId(), account);"},{"lineNumber":469,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":470,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":471,"author":{"gitId":"yuanxi1"},"content":" for (Instructor instructor : instructors) {"},{"lineNumber":472,"author":{"gitId":"yuanxi1"},"content":" usersMap.put(instructor.getId(), instructor);"},{"lineNumber":473,"author":{"gitId":"yuanxi1"},"content":" Course course \u003d coursesMap.get(instructor.getCourse().getId());"},{"lineNumber":474,"author":{"gitId":"yuanxi1"},"content":" instructor.setCourse(course);"},{"lineNumber":475,"author":{"gitId":"yuanxi1"},"content":" if (instructor.getAccount() !\u003d null) {"},{"lineNumber":476,"author":{"gitId":"yuanxi1"},"content":" Account account \u003d accountsMap.get(instructor.getAccount().getId());"},{"lineNumber":477,"author":{"gitId":"yuanxi1"},"content":" instructor.setAccount(account);"},{"lineNumber":478,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":479,"author":{"gitId":"yuanxi1"},"content":" instructor.generateNewRegistrationKey();"},{"lineNumber":480,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":481,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":482,"author":{"gitId":"yuanxi1"},"content":" for (Student student : students) {"},{"lineNumber":483,"author":{"gitId":"yuanxi1"},"content":" usersMap.put(student.getId(), student);"},{"lineNumber":484,"author":{"gitId":"yuanxi1"},"content":" Course course \u003d coursesMap.get(student.getCourse().getId());"},{"lineNumber":485,"author":{"gitId":"yuanxi1"},"content":" student.setCourse(course);"},{"lineNumber":486,"author":{"gitId":"yuanxi1"},"content":" Team team \u003d teamsMap.get(student.getTeam().getId());"},{"lineNumber":487,"author":{"gitId":"yuanxi1"},"content":" student.setTeam(team);"},{"lineNumber":488,"author":{"gitId":"yuanxi1"},"content":" if (student.getAccount() !\u003d null) {"},{"lineNumber":489,"author":{"gitId":"yuanxi1"},"content":" Account account \u003d accountsMap.get(student.getAccount().getId());"},{"lineNumber":490,"author":{"gitId":"yuanxi1"},"content":" student.setAccount(account);"},{"lineNumber":491,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":492,"author":{"gitId":"yuanxi1"},"content":" student.generateNewRegistrationKey();"},{"lineNumber":493,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":494,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":495,"author":{"gitId":"yuanxi1"},"content":" for (Notification notification : notifications) {"},{"lineNumber":496,"author":{"gitId":"yuanxi1"},"content":" notificationsMap.put(notification.getId(), notification);"},{"lineNumber":497,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":498,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":499,"author":{"gitId":"yuanxi1"},"content":" for (ReadNotification readNotification : readNotifications) {"},{"lineNumber":500,"author":{"gitId":"yuanxi1"},"content":" Account account \u003d accountsMap.get(readNotification.getAccount().getId());"},{"lineNumber":501,"author":{"gitId":"yuanxi1"},"content":" readNotification.setAccount(account);"},{"lineNumber":502,"author":{"gitId":"yuanxi1"},"content":" Notification notification \u003d notificationsMap.get(readNotification.getNotification().getId());"},{"lineNumber":503,"author":{"gitId":"yuanxi1"},"content":" readNotification.setNotification(notification);"},{"lineNumber":504,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":505,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":506,"author":{"gitId":"yuanxi1"},"content":" for (DeadlineExtension deadlineExtension : deadlineExtensions) {"},{"lineNumber":507,"author":{"gitId":"yuanxi1"},"content":" FeedbackSession session \u003d sessionsMap.get(deadlineExtension.getFeedbackSession().getId());"},{"lineNumber":508,"author":{"gitId":"yuanxi1"},"content":" deadlineExtension.setFeedbackSession(session);"},{"lineNumber":509,"author":{"gitId":"yuanxi1"},"content":" User user \u003d usersMap.get(deadlineExtension.getUser().getId());"},{"lineNumber":510,"author":{"gitId":"yuanxi1"},"content":" deadlineExtension.setUser(user);"},{"lineNumber":511,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":512,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":513,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"yuanxi1":124,"dishenggg":20,"-":369}},{"path":"src/main/java/teammates/sqllogic/core/FeedbackQuestionsLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Collections;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.HashSet;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.Set;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackQuestionRecipient;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlCourseRoster;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackMcqQuestionDetails;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackMsqQuestionDetails;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionDetails;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionType;"},{"lineNumber":22,"author":{"gitId":"marquestye"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackQuestionsDb;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackMcqQuestion;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackMsqQuestion;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.ui.request.FeedbackQuestionUpdateRequest;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":37,"author":{"gitId":"-"},"content":" * Handles operations related to feedback questions."},{"lineNumber":38,"author":{"gitId":"-"},"content":" *"},{"lineNumber":39,"author":{"gitId":"-"},"content":" * @see FeedbackQuestion"},{"lineNumber":40,"author":{"gitId":"-"},"content":" * @see FeedbackQuestionsDb"},{"lineNumber":41,"author":{"gitId":"-"},"content":" */"},{"lineNumber":42,"author":{"gitId":"-"},"content":"public final class FeedbackQuestionsLogic {"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" static final String USER_NAME_FOR_SELF \u003d \"Myself\";"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" private static final FeedbackQuestionsLogic instance \u003d new FeedbackQuestionsLogic();"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private FeedbackQuestionsDb fqDb;"},{"lineNumber":50,"author":{"gitId":"-"},"content":" private CoursesLogic coursesLogic;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" private FeedbackResponsesLogic frLogic;"},{"lineNumber":52,"author":{"gitId":"-"},"content":" private UsersLogic usersLogic;"},{"lineNumber":53,"author":{"gitId":"-"},"content":" private FeedbackSessionsLogic feedbackSessionsLogic;"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" private FeedbackQuestionsLogic() {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" public static FeedbackQuestionsLogic inst() {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" void initLogicDependencies(FeedbackQuestionsDb fqDb, CoursesLogic coursesLogic, FeedbackResponsesLogic frLogic,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" UsersLogic usersLogic, FeedbackSessionsLogic feedbackSessionsLogic) {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" this.fqDb \u003d fqDb;"},{"lineNumber":66,"author":{"gitId":"-"},"content":" this.coursesLogic \u003d coursesLogic;"},{"lineNumber":67,"author":{"gitId":"-"},"content":" this.frLogic \u003d frLogic;"},{"lineNumber":68,"author":{"gitId":"-"},"content":" this.usersLogic \u003d usersLogic;"},{"lineNumber":69,"author":{"gitId":"-"},"content":" this.feedbackSessionsLogic \u003d feedbackSessionsLogic;"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":73,"author":{"gitId":"-"},"content":" * Creates a new feedback question."},{"lineNumber":74,"author":{"gitId":"-"},"content":" *"},{"lineNumber":75,"author":{"gitId":"-"},"content":" * @return the created question"},{"lineNumber":76,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the question is invalid"},{"lineNumber":77,"author":{"gitId":"marquestye"},"content":" * @throws EntityAlreadyExistsException if the question already exists"},{"lineNumber":78,"author":{"gitId":"-"},"content":" */"},{"lineNumber":79,"author":{"gitId":"marquestye"},"content":" public FeedbackQuestion createFeedbackQuestion(FeedbackQuestion feedbackQuestion)"},{"lineNumber":80,"author":{"gitId":"marquestye"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":81,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion createdQuestion \u003d fqDb.createFeedbackQuestion(feedbackQuestion);"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsBefore \u003d getFeedbackQuestionsForSession(feedbackQuestion.getFeedbackSession());"},{"lineNumber":84,"author":{"gitId":"marquestye"},"content":" questionsBefore.remove(createdQuestion);"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" adjustQuestionNumbers(questionsBefore.size() + 1, createdQuestion.getQuestionNumber(), questionsBefore);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" return createdQuestion;"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":91,"author":{"gitId":"-"},"content":" * Gets an feedback question by feedback question id."},{"lineNumber":92,"author":{"gitId":"-"},"content":" * @param id of feedback question."},{"lineNumber":93,"author":{"gitId":"-"},"content":" * @return the specified feedback question."},{"lineNumber":94,"author":{"gitId":"-"},"content":" */"},{"lineNumber":95,"author":{"gitId":"-"},"content":" public FeedbackQuestion getFeedbackQuestion(UUID id) {"},{"lineNumber":96,"author":{"gitId":"-"},"content":" return fqDb.getFeedbackQuestion(id);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" }"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":100,"author":{"gitId":"-"},"content":" * Gets a {@link List} of every FeedbackQuestion in the given session."},{"lineNumber":101,"author":{"gitId":"-"},"content":" */"},{"lineNumber":102,"author":{"gitId":"-"},"content":" public List\u003cFeedbackQuestion\u003e getFeedbackQuestionsForSession(FeedbackSession feedbackSession) {"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questions \u003d fqDb.getFeedbackQuestionsForSession(feedbackSession.getId());"},{"lineNumber":105,"author":{"gitId":"-"},"content":" questions.sort(null);"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" // check whether the question numbers are consistent"},{"lineNumber":108,"author":{"gitId":"-"},"content":" if (questions.size() \u003e 1 \u0026\u0026 !areQuestionNumbersConsistent(questions)) {"},{"lineNumber":109,"author":{"gitId":"-"},"content":" log.severe(feedbackSession.getCourse().getId() + \": \" + feedbackSession.getName()"},{"lineNumber":110,"author":{"gitId":"-"},"content":" + \" has invalid question numbers\");"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" return questions;"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":117,"author":{"gitId":"-"},"content":" * Checks if there are any questions for the given session that instructors can view/submit."},{"lineNumber":118,"author":{"gitId":"-"},"content":" */"},{"lineNumber":119,"author":{"gitId":"-"},"content":" public boolean hasFeedbackQuestionsForInstructors(List\u003cFeedbackQuestion\u003e fqs, boolean isCreator) {"},{"lineNumber":120,"author":{"gitId":"-"},"content":" boolean hasQuestions \u003d hasFeedbackQuestionsForGiverType(fqs, FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" if (hasQuestions) {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":123,"author":{"gitId":"-"},"content":" }"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" if (isCreator) {"},{"lineNumber":126,"author":{"gitId":"-"},"content":" hasQuestions \u003d hasFeedbackQuestionsForGiverType(fqs, FeedbackParticipantType.SELF);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" return hasQuestions;"},{"lineNumber":130,"author":{"gitId":"-"},"content":" }"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":133,"author":{"gitId":"-"},"content":" * Gets a {@code List} of all questions for the given session that instructors can view/submit."},{"lineNumber":134,"author":{"gitId":"-"},"content":" */"},{"lineNumber":135,"author":{"gitId":"-"},"content":" public List\u003cFeedbackQuestion\u003e getFeedbackQuestionsForInstructors("},{"lineNumber":136,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession, String userEmail) {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" questions.addAll("},{"lineNumber":140,"author":{"gitId":"-"},"content":" fqDb.getFeedbackQuestionsForGiverType("},{"lineNumber":141,"author":{"gitId":"-"},"content":" feedbackSession, FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" if (feedbackSession.getCreatorEmail().equals(userEmail)) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" questions.addAll("},{"lineNumber":145,"author":{"gitId":"-"},"content":" fqDb.getFeedbackQuestionsForGiverType("},{"lineNumber":146,"author":{"gitId":"-"},"content":" feedbackSession, FeedbackParticipantType.SELF));"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" return questions;"},{"lineNumber":150,"author":{"gitId":"-"},"content":" }"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":153,"author":{"gitId":"-"},"content":" * Gets a {@code List} of all questions for the given session that students can view/submit."},{"lineNumber":154,"author":{"gitId":"-"},"content":" */"},{"lineNumber":155,"author":{"gitId":"-"},"content":" public List\u003cFeedbackQuestion\u003e getFeedbackQuestionsForStudents(FeedbackSession feedbackSession) {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"-"},"content":" questions.addAll(fqDb.getFeedbackQuestionsForGiverType(feedbackSession, FeedbackParticipantType.STUDENTS));"},{"lineNumber":159,"author":{"gitId":"-"},"content":" questions.addAll(fqDb.getFeedbackQuestionsForGiverType(feedbackSession, FeedbackParticipantType.SELF));"},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":" questions.sort(null);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" return questions;"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":165,"author":{"gitId":"-"},"content":" * Updates a feedback question."},{"lineNumber":166,"author":{"gitId":"-"},"content":" *"},{"lineNumber":167,"author":{"gitId":"-"},"content":" * \u003cp\u003eCascade adjust the question number of questions in the same session."},{"lineNumber":168,"author":{"gitId":"-"},"content":" *"},{"lineNumber":169,"author":{"gitId":"-"},"content":" * \u003cp\u003eCascade adjust the existing response of the question."},{"lineNumber":170,"author":{"gitId":"-"},"content":" *"},{"lineNumber":171,"author":{"gitId":"-"},"content":" * @return updated feedback question"},{"lineNumber":172,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":173,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the feedback question cannot be found"},{"lineNumber":174,"author":{"gitId":"-"},"content":" */"},{"lineNumber":175,"author":{"gitId":"-"},"content":" public FeedbackQuestion updateFeedbackQuestionCascade(UUID questionId, FeedbackQuestionUpdateRequest updateRequest)"},{"lineNumber":176,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" FeedbackQuestion question \u003d fqDb.getFeedbackQuestion(questionId);"},{"lineNumber":178,"author":{"gitId":"-"},"content":" if (question \u003d\u003d null) {"},{"lineNumber":179,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Trying to update a feedback question that does not exist.\");"},{"lineNumber":180,"author":{"gitId":"-"},"content":" }"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" int oldQuestionNumber \u003d question.getQuestionNumber();"},{"lineNumber":183,"author":{"gitId":"-"},"content":" int newQuestionNumber \u003d updateRequest.getQuestionNumber();"},{"lineNumber":184,"author":{"gitId":"-"},"content":""},{"lineNumber":185,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e previousQuestionsInSession \u003d new ArrayList\u003c\u003e();"},{"lineNumber":186,"author":{"gitId":"-"},"content":" if (oldQuestionNumber !\u003d newQuestionNumber) {"},{"lineNumber":187,"author":{"gitId":"-"},"content":" // get questions in session before update"},{"lineNumber":188,"author":{"gitId":"-"},"content":" previousQuestionsInSession \u003d getFeedbackQuestionsForSession(question.getFeedbackSession());"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" // update question"},{"lineNumber":192,"author":{"gitId":"-"},"content":" question.setQuestionNumber(updateRequest.getQuestionNumber());"},{"lineNumber":193,"author":{"gitId":"-"},"content":" question.setDescription(updateRequest.getQuestionDescription());"},{"lineNumber":194,"author":{"gitId":"-"},"content":" question.setQuestionDetails(updateRequest.getQuestionDetails());"},{"lineNumber":195,"author":{"gitId":"-"},"content":" question.setGiverType(updateRequest.getGiverType());"},{"lineNumber":196,"author":{"gitId":"-"},"content":" question.setRecipientType(updateRequest.getRecipientType());"},{"lineNumber":197,"author":{"gitId":"-"},"content":" question.setNumOfEntitiesToGiveFeedbackTo(updateRequest.getNumberOfEntitiesToGiveFeedbackTo());"},{"lineNumber":198,"author":{"gitId":"-"},"content":" question.setShowResponsesTo(updateRequest.getShowResponsesTo());"},{"lineNumber":199,"author":{"gitId":"-"},"content":" question.setShowGiverNameTo(updateRequest.getShowGiverNameTo());"},{"lineNumber":200,"author":{"gitId":"-"},"content":" question.setShowRecipientNameTo(updateRequest.getShowRecipientNameTo());"},{"lineNumber":201,"author":{"gitId":"-"},"content":""},{"lineNumber":202,"author":{"gitId":"-"},"content":" // validate questions (giver \u0026 recipient)"},{"lineNumber":203,"author":{"gitId":"-"},"content":" String err \u003d question.getQuestionDetailsCopy().validateGiverRecipientVisibility(question);"},{"lineNumber":204,"author":{"gitId":"-"},"content":" if (!err.isEmpty()) {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(err);"},{"lineNumber":206,"author":{"gitId":"-"},"content":" }"},{"lineNumber":207,"author":{"gitId":"-"},"content":" // validate questions (question details)"},{"lineNumber":208,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails questionDetails \u003d question.getQuestionDetailsCopy();"},{"lineNumber":209,"author":{"gitId":"-"},"content":" List\u003cString\u003e questionDetailsErrors \u003d questionDetails.validateQuestionDetails();"},{"lineNumber":210,"author":{"gitId":"-"},"content":""},{"lineNumber":211,"author":{"gitId":"-"},"content":" if (!questionDetailsErrors.isEmpty()) {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(questionDetailsErrors.toString());"},{"lineNumber":213,"author":{"gitId":"-"},"content":" }"},{"lineNumber":214,"author":{"gitId":"-"},"content":""},{"lineNumber":215,"author":{"gitId":"-"},"content":" if (oldQuestionNumber !\u003d newQuestionNumber) {"},{"lineNumber":216,"author":{"gitId":"-"},"content":" // shift other feedback questions (generate an empty \"slot\")"},{"lineNumber":217,"author":{"gitId":"-"},"content":" adjustQuestionNumbers(oldQuestionNumber, newQuestionNumber, previousQuestionsInSession);"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" // adjust responses"},{"lineNumber":221,"author":{"gitId":"-"},"content":" if (question.areResponseDeletionsRequiredForChanges(updateRequest.getGiverType(),"},{"lineNumber":222,"author":{"gitId":"-"},"content":" updateRequest.getRecipientType(), updateRequest.getQuestionDetails())) {"},{"lineNumber":223,"author":{"gitId":"-"},"content":" frLogic.deleteFeedbackResponsesForQuestionCascade(question.getId());"},{"lineNumber":224,"author":{"gitId":"-"},"content":" }"},{"lineNumber":225,"author":{"gitId":"-"},"content":""},{"lineNumber":226,"author":{"gitId":"-"},"content":" return question;"},{"lineNumber":227,"author":{"gitId":"-"},"content":" }"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":230,"author":{"gitId":"-"},"content":" * Checks if there are any questions for the given session that students can view/submit."},{"lineNumber":231,"author":{"gitId":"-"},"content":" */"},{"lineNumber":232,"author":{"gitId":"-"},"content":" public boolean hasFeedbackQuestionsForStudents(List\u003cFeedbackQuestion\u003e fqs) {"},{"lineNumber":233,"author":{"gitId":"-"},"content":" return hasFeedbackQuestionsForGiverType(fqs, FeedbackParticipantType.STUDENTS)"},{"lineNumber":234,"author":{"gitId":"-"},"content":" || hasFeedbackQuestionsForGiverType(fqs, FeedbackParticipantType.TEAMS);"},{"lineNumber":235,"author":{"gitId":"-"},"content":" }"},{"lineNumber":236,"author":{"gitId":"-"},"content":""},{"lineNumber":237,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":238,"author":{"gitId":"-"},"content":" * Checks if there is any feedback questions in a session in a course for the given giver type."},{"lineNumber":239,"author":{"gitId":"-"},"content":" */"},{"lineNumber":240,"author":{"gitId":"-"},"content":" public boolean hasFeedbackQuestionsForGiverType("},{"lineNumber":241,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e feedbackQuestions, FeedbackParticipantType giverType) {"},{"lineNumber":242,"author":{"gitId":"-"},"content":" assert feedbackQuestions !\u003d null;"},{"lineNumber":243,"author":{"gitId":"-"},"content":" assert giverType !\u003d null;"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":" for (FeedbackQuestion fq : feedbackQuestions) {"},{"lineNumber":246,"author":{"gitId":"-"},"content":" if (fq.getGiverType() \u003d\u003d giverType) {"},{"lineNumber":247,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":248,"author":{"gitId":"-"},"content":" }"},{"lineNumber":249,"author":{"gitId":"-"},"content":" }"},{"lineNumber":250,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":251,"author":{"gitId":"-"},"content":" }"},{"lineNumber":252,"author":{"gitId":"-"},"content":""},{"lineNumber":253,"author":{"gitId":"-"},"content":" // TODO can be removed once we are sure that question numbers will be consistent"},{"lineNumber":254,"author":{"gitId":"-"},"content":" private boolean areQuestionNumbersConsistent(List\u003cFeedbackQuestion\u003e questions) {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" Set\u003cInteger\u003e questionNumbersInSession \u003d new HashSet\u003c\u003e();"},{"lineNumber":256,"author":{"gitId":"-"},"content":" for (FeedbackQuestion question : questions) {"},{"lineNumber":257,"author":{"gitId":"-"},"content":" if (!questionNumbersInSession.add(question.getQuestionNumber())) {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":259,"author":{"gitId":"-"},"content":" }"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":""},{"lineNumber":262,"author":{"gitId":"-"},"content":" for (int i \u003d 1; i \u003c\u003d questions.size(); i++) {"},{"lineNumber":263,"author":{"gitId":"-"},"content":" if (!questionNumbersInSession.contains(i)) {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":265,"author":{"gitId":"-"},"content":" }"},{"lineNumber":266,"author":{"gitId":"-"},"content":" }"},{"lineNumber":267,"author":{"gitId":"-"},"content":""},{"lineNumber":268,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":269,"author":{"gitId":"-"},"content":" }"},{"lineNumber":270,"author":{"gitId":"-"},"content":""},{"lineNumber":271,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":272,"author":{"gitId":"-"},"content":" * Adjust questions between the old and new number,"},{"lineNumber":273,"author":{"gitId":"-"},"content":" * if the new number is smaller, then shift up (increase qn#) all questions in between."},{"lineNumber":274,"author":{"gitId":"-"},"content":" * if the new number is bigger, then shift down(decrease qn#) all questions in between."},{"lineNumber":275,"author":{"gitId":"-"},"content":" */"},{"lineNumber":276,"author":{"gitId":"-"},"content":" private void adjustQuestionNumbers(int oldQuestionNumber, int newQuestionNumber, List\u003cFeedbackQuestion\u003e questions) {"},{"lineNumber":277,"author":{"gitId":"-"},"content":" if (oldQuestionNumber \u003e newQuestionNumber \u0026\u0026 oldQuestionNumber \u003e\u003d 1) {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" for (int i \u003d oldQuestionNumber - 1; i \u003e\u003d newQuestionNumber; i--) {"},{"lineNumber":279,"author":{"gitId":"-"},"content":" FeedbackQuestion question \u003d questions.get(i - 1);"},{"lineNumber":280,"author":{"gitId":"-"},"content":" question.setQuestionNumber(question.getQuestionNumber() + 1);"},{"lineNumber":281,"author":{"gitId":"-"},"content":" }"},{"lineNumber":282,"author":{"gitId":"-"},"content":" } else if (oldQuestionNumber \u003c newQuestionNumber \u0026\u0026 oldQuestionNumber \u003c questions.size()) {"},{"lineNumber":283,"author":{"gitId":"-"},"content":" for (int i \u003d oldQuestionNumber + 1; i \u003c\u003d newQuestionNumber; i++) {"},{"lineNumber":284,"author":{"gitId":"-"},"content":" FeedbackQuestion question \u003d questions.get(i - 1);"},{"lineNumber":285,"author":{"gitId":"-"},"content":" question.setQuestionNumber(question.getQuestionNumber() - 1);"},{"lineNumber":286,"author":{"gitId":"-"},"content":" }"},{"lineNumber":287,"author":{"gitId":"-"},"content":" }"},{"lineNumber":288,"author":{"gitId":"-"},"content":" }"},{"lineNumber":289,"author":{"gitId":"-"},"content":""},{"lineNumber":290,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":291,"author":{"gitId":"-"},"content":" * Populates fields that need dynamic generation in a question."},{"lineNumber":292,"author":{"gitId":"-"},"content":" *"},{"lineNumber":293,"author":{"gitId":"-"},"content":" * \u003cp\u003eCurrently, only MCQ/MSQ needs to generate choices dynamically.\u003c/p\u003e"},{"lineNumber":294,"author":{"gitId":"-"},"content":" *"},{"lineNumber":295,"author":{"gitId":"-"},"content":" * @param feedbackQuestion the question to populate"},{"lineNumber":296,"author":{"gitId":"-"},"content":" * @param courseId the ID of the course"},{"lineNumber":297,"author":{"gitId":"-"},"content":" * @param emailOfEntityDoingQuestion the email of the entity doing the question"},{"lineNumber":298,"author":{"gitId":"-"},"content":" * @param teamOfEntityDoingQuestion the team of the entity doing the question. If the entity is an instructor,"},{"lineNumber":299,"author":{"gitId":"-"},"content":" * it can be {@code null}."},{"lineNumber":300,"author":{"gitId":"-"},"content":" */"},{"lineNumber":301,"author":{"gitId":"-"},"content":" public void populateFieldsToGenerateInQuestion(FeedbackQuestion feedbackQuestion,"},{"lineNumber":302,"author":{"gitId":"-"},"content":" String courseId, String emailOfEntityDoingQuestion, String teamOfEntityDoingQuestion) {"},{"lineNumber":303,"author":{"gitId":"-"},"content":" List\u003cString\u003e optionList;"},{"lineNumber":304,"author":{"gitId":"-"},"content":""},{"lineNumber":305,"author":{"gitId":"-"},"content":" FeedbackParticipantType generateOptionsFor;"},{"lineNumber":306,"author":{"gitId":"-"},"content":" FeedbackQuestionType questionType \u003d feedbackQuestion.getQuestionDetailsCopy().getQuestionType();"},{"lineNumber":307,"author":{"gitId":"-"},"content":""},{"lineNumber":308,"author":{"gitId":"-"},"content":" if (questionType \u003d\u003d FeedbackQuestionType.MCQ) {"},{"lineNumber":309,"author":{"gitId":"-"},"content":" FeedbackMcqQuestionDetails feedbackMcqQuestionDetails \u003d"},{"lineNumber":310,"author":{"gitId":"-"},"content":" (FeedbackMcqQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":311,"author":{"gitId":"-"},"content":" optionList \u003d feedbackMcqQuestionDetails.getMcqChoices();"},{"lineNumber":312,"author":{"gitId":"-"},"content":" generateOptionsFor \u003d feedbackMcqQuestionDetails.getGenerateOptionsFor();"},{"lineNumber":313,"author":{"gitId":"-"},"content":" } else if (questionType \u003d\u003d FeedbackQuestionType.MSQ) {"},{"lineNumber":314,"author":{"gitId":"-"},"content":" FeedbackMsqQuestionDetails feedbackMsqQuestionDetails \u003d"},{"lineNumber":315,"author":{"gitId":"-"},"content":" (FeedbackMsqQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":316,"author":{"gitId":"-"},"content":" optionList \u003d feedbackMsqQuestionDetails.getMsqChoices();"},{"lineNumber":317,"author":{"gitId":"-"},"content":" generateOptionsFor \u003d feedbackMsqQuestionDetails.getGenerateOptionsFor();"},{"lineNumber":318,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":319,"author":{"gitId":"-"},"content":" // other question types"},{"lineNumber":320,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":321,"author":{"gitId":"-"},"content":" }"},{"lineNumber":322,"author":{"gitId":"-"},"content":""},{"lineNumber":323,"author":{"gitId":"-"},"content":" switch (generateOptionsFor) {"},{"lineNumber":324,"author":{"gitId":"-"},"content":" case NONE:"},{"lineNumber":325,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":326,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":327,"author":{"gitId":"-"},"content":" case STUDENTS_IN_SAME_SECTION:"},{"lineNumber":328,"author":{"gitId":"-"},"content":" case STUDENTS_EXCLUDING_SELF:"},{"lineNumber":329,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e studentList;"},{"lineNumber":330,"author":{"gitId":"-"},"content":" if (generateOptionsFor \u003d\u003d FeedbackParticipantType.STUDENTS_IN_SAME_SECTION) {"},{"lineNumber":331,"author":{"gitId":"-"},"content":" Student student \u003d"},{"lineNumber":332,"author":{"gitId":"-"},"content":" usersLogic.getStudentForEmail(courseId, emailOfEntityDoingQuestion);"},{"lineNumber":333,"author":{"gitId":"-"},"content":" studentList \u003d usersLogic.getStudentsForSection(student.getSectionName(), courseId);"},{"lineNumber":334,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":335,"author":{"gitId":"-"},"content":" studentList \u003d usersLogic.getStudentsForCourse(courseId);"},{"lineNumber":336,"author":{"gitId":"-"},"content":" }"},{"lineNumber":337,"author":{"gitId":"-"},"content":""},{"lineNumber":338,"author":{"gitId":"-"},"content":" if (generateOptionsFor \u003d\u003d FeedbackParticipantType.STUDENTS_EXCLUDING_SELF) {"},{"lineNumber":339,"author":{"gitId":"-"},"content":" studentList.removeIf(studentInList -\u003e studentInList.getEmail().equals(emailOfEntityDoingQuestion));"},{"lineNumber":340,"author":{"gitId":"-"},"content":" }"},{"lineNumber":341,"author":{"gitId":"-"},"content":""},{"lineNumber":342,"author":{"gitId":"-"},"content":" for (Student student : studentList) {"},{"lineNumber":343,"author":{"gitId":"dishenggg"},"content":" optionList.add(student.getName() + \" (\" + student.getTeam().getName() + \")\");"},{"lineNumber":344,"author":{"gitId":"-"},"content":" }"},{"lineNumber":345,"author":{"gitId":"-"},"content":""},{"lineNumber":346,"author":{"gitId":"-"},"content":" optionList.sort(null);"},{"lineNumber":347,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":348,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":349,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":350,"author":{"gitId":"-"},"content":" case TEAMS_EXCLUDING_SELF:"},{"lineNumber":351,"author":{"gitId":"-"},"content":" List\u003cString\u003e teams;"},{"lineNumber":352,"author":{"gitId":"-"},"content":" if (generateOptionsFor \u003d\u003d FeedbackParticipantType.TEAMS_IN_SAME_SECTION) {"},{"lineNumber":353,"author":{"gitId":"-"},"content":" Student student \u003d"},{"lineNumber":354,"author":{"gitId":"-"},"content":" usersLogic.getStudentForEmail(courseId, emailOfEntityDoingQuestion);"},{"lineNumber":355,"author":{"gitId":"-"},"content":" teams \u003d coursesLogic.getTeamsForSection(student.getSection())"},{"lineNumber":356,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":357,"author":{"gitId":"-"},"content":" .map(team -\u003e { return team.getName(); })"},{"lineNumber":358,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":359,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":360,"author":{"gitId":"-"},"content":" teams \u003d coursesLogic.getTeamsForCourse(courseId)"},{"lineNumber":361,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":362,"author":{"gitId":"-"},"content":" .map(team -\u003e { return team.getName(); })"},{"lineNumber":363,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":364,"author":{"gitId":"-"},"content":" }"},{"lineNumber":365,"author":{"gitId":"-"},"content":""},{"lineNumber":366,"author":{"gitId":"-"},"content":" if (generateOptionsFor \u003d\u003d FeedbackParticipantType.TEAMS_EXCLUDING_SELF) {"},{"lineNumber":367,"author":{"gitId":"-"},"content":" teams.removeIf(team -\u003e team.equals(teamOfEntityDoingQuestion));"},{"lineNumber":368,"author":{"gitId":"-"},"content":" }"},{"lineNumber":369,"author":{"gitId":"-"},"content":""},{"lineNumber":370,"author":{"gitId":"-"},"content":" for (String team : teams) {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" optionList.add(team);"},{"lineNumber":372,"author":{"gitId":"-"},"content":" }"},{"lineNumber":373,"author":{"gitId":"-"},"content":""},{"lineNumber":374,"author":{"gitId":"-"},"content":" optionList.sort(null);"},{"lineNumber":375,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":376,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS_INCLUDING_SELF:"},{"lineNumber":377,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":378,"author":{"gitId":"-"},"content":" if (teamOfEntityDoingQuestion !\u003d null) {"},{"lineNumber":379,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e teamMembers \u003d usersLogic.getStudentsForTeam(teamOfEntityDoingQuestion,"},{"lineNumber":380,"author":{"gitId":"-"},"content":" courseId);"},{"lineNumber":381,"author":{"gitId":"-"},"content":""},{"lineNumber":382,"author":{"gitId":"-"},"content":" if (generateOptionsFor \u003d\u003d FeedbackParticipantType.OWN_TEAM_MEMBERS) {"},{"lineNumber":383,"author":{"gitId":"-"},"content":" teamMembers.removeIf(teamMember -\u003e teamMember.getEmail().equals(emailOfEntityDoingQuestion));"},{"lineNumber":384,"author":{"gitId":"-"},"content":" }"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"-"},"content":" teamMembers.forEach(teamMember -\u003e optionList.add(teamMember.getName()));"},{"lineNumber":387,"author":{"gitId":"-"},"content":""},{"lineNumber":388,"author":{"gitId":"-"},"content":" optionList.sort(null);"},{"lineNumber":389,"author":{"gitId":"-"},"content":" }"},{"lineNumber":390,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":391,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":392,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorList \u003d"},{"lineNumber":393,"author":{"gitId":"-"},"content":" usersLogic.getInstructorsForCourse(courseId);"},{"lineNumber":394,"author":{"gitId":"-"},"content":""},{"lineNumber":395,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructorList) {"},{"lineNumber":396,"author":{"gitId":"-"},"content":" optionList.add(instructor.getName());"},{"lineNumber":397,"author":{"gitId":"-"},"content":" }"},{"lineNumber":398,"author":{"gitId":"-"},"content":""},{"lineNumber":399,"author":{"gitId":"-"},"content":" optionList.sort(null);"},{"lineNumber":400,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":401,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":402,"author":{"gitId":"-"},"content":" assert false : \"Trying to generate options for neither students, teams nor instructors\";"},{"lineNumber":403,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":404,"author":{"gitId":"-"},"content":" }"},{"lineNumber":405,"author":{"gitId":"-"},"content":""},{"lineNumber":406,"author":{"gitId":"-"},"content":" if (questionType \u003d\u003d FeedbackQuestionType.MCQ) {"},{"lineNumber":407,"author":{"gitId":"-"},"content":" FeedbackMcqQuestionDetails feedbackMcqQuestionDetails \u003d"},{"lineNumber":408,"author":{"gitId":"-"},"content":" (FeedbackMcqQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":409,"author":{"gitId":"-"},"content":" feedbackMcqQuestionDetails.setMcqChoices(optionList);"},{"lineNumber":410,"author":{"gitId":"-"},"content":" ((FeedbackMcqQuestion) feedbackQuestion).setFeedBackQuestionDetails(feedbackMcqQuestionDetails);"},{"lineNumber":411,"author":{"gitId":"-"},"content":" } else if (questionType \u003d\u003d FeedbackQuestionType.MSQ) {"},{"lineNumber":412,"author":{"gitId":"-"},"content":" FeedbackMsqQuestionDetails feedbackMsqQuestionDetails \u003d"},{"lineNumber":413,"author":{"gitId":"-"},"content":" (FeedbackMsqQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":414,"author":{"gitId":"-"},"content":" feedbackMsqQuestionDetails.setMsqChoices(optionList);"},{"lineNumber":415,"author":{"gitId":"-"},"content":" ((FeedbackMsqQuestion) feedbackQuestion).setFeedBackQuestionDetails(feedbackMsqQuestionDetails);"},{"lineNumber":416,"author":{"gitId":"-"},"content":" }"},{"lineNumber":417,"author":{"gitId":"-"},"content":" }"},{"lineNumber":418,"author":{"gitId":"-"},"content":""},{"lineNumber":419,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":420,"author":{"gitId":"-"},"content":" * Gets the recipients of a feedback question including recipient section and team."},{"lineNumber":421,"author":{"gitId":"-"},"content":" *"},{"lineNumber":422,"author":{"gitId":"-"},"content":" * @param question the feedback question"},{"lineNumber":423,"author":{"gitId":"-"},"content":" * @param instructorGiver can be null for student giver"},{"lineNumber":424,"author":{"gitId":"-"},"content":" * @param studentGiver can be null for instructor giver"},{"lineNumber":425,"author":{"gitId":"-"},"content":" * @param courseRoster if provided, the function can be completed without touching database"},{"lineNumber":426,"author":{"gitId":"-"},"content":" * @return a Map of {@code FeedbackQuestionRecipient} as the value and identifier as the key."},{"lineNumber":427,"author":{"gitId":"-"},"content":" */"},{"lineNumber":428,"author":{"gitId":"-"},"content":" public Map\u003cString, FeedbackQuestionRecipient\u003e getRecipientsOfQuestion("},{"lineNumber":429,"author":{"gitId":"-"},"content":" FeedbackQuestion question,"},{"lineNumber":430,"author":{"gitId":"-"},"content":" @Nullable Instructor instructorGiver, @Nullable Student studentGiver,"},{"lineNumber":431,"author":{"gitId":"-"},"content":" @Nullable SqlCourseRoster courseRoster) {"},{"lineNumber":432,"author":{"gitId":"-"},"content":" assert instructorGiver !\u003d null || studentGiver !\u003d null;"},{"lineNumber":433,"author":{"gitId":"-"},"content":""},{"lineNumber":434,"author":{"gitId":"-"},"content":" String courseId \u003d question.getCourseId();"},{"lineNumber":435,"author":{"gitId":"-"},"content":""},{"lineNumber":436,"author":{"gitId":"-"},"content":" Map\u003cString, FeedbackQuestionRecipient\u003e recipients \u003d new HashMap\u003c\u003e();"},{"lineNumber":437,"author":{"gitId":"-"},"content":""},{"lineNumber":438,"author":{"gitId":"-"},"content":" boolean isStudentGiver \u003d studentGiver !\u003d null;"},{"lineNumber":439,"author":{"gitId":"-"},"content":" boolean isInstructorGiver \u003d instructorGiver !\u003d null;"},{"lineNumber":440,"author":{"gitId":"-"},"content":""},{"lineNumber":441,"author":{"gitId":"-"},"content":" String giverEmail \u003d \"\";"},{"lineNumber":442,"author":{"gitId":"-"},"content":" String giverTeam \u003d \"\";"},{"lineNumber":443,"author":{"gitId":"-"},"content":" String giverSection \u003d \"\";"},{"lineNumber":444,"author":{"gitId":"-"},"content":" if (isStudentGiver) {"},{"lineNumber":445,"author":{"gitId":"-"},"content":" giverEmail \u003d studentGiver.getEmail();"},{"lineNumber":446,"author":{"gitId":"-"},"content":" giverTeam \u003d studentGiver.getTeamName();"},{"lineNumber":447,"author":{"gitId":"-"},"content":" giverSection \u003d studentGiver.getSectionName();"},{"lineNumber":448,"author":{"gitId":"-"},"content":" } else if (isInstructorGiver) {"},{"lineNumber":449,"author":{"gitId":"-"},"content":" giverEmail \u003d instructorGiver.getEmail();"},{"lineNumber":450,"author":{"gitId":"-"},"content":" giverTeam \u003d Const.USER_TEAM_FOR_INSTRUCTOR;"},{"lineNumber":451,"author":{"gitId":"-"},"content":" giverSection \u003d Const.DEFAULT_SECTION;"},{"lineNumber":452,"author":{"gitId":"-"},"content":" }"},{"lineNumber":453,"author":{"gitId":"-"},"content":""},{"lineNumber":454,"author":{"gitId":"-"},"content":" FeedbackParticipantType recipientType \u003d question.getRecipientType();"},{"lineNumber":455,"author":{"gitId":"-"},"content":" FeedbackParticipantType generateOptionsFor \u003d recipientType;"},{"lineNumber":456,"author":{"gitId":"-"},"content":""},{"lineNumber":457,"author":{"gitId":"-"},"content":" switch (recipientType) {"},{"lineNumber":458,"author":{"gitId":"-"},"content":" case SELF:"},{"lineNumber":459,"author":{"gitId":"-"},"content":" if (question.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS) {"},{"lineNumber":460,"author":{"gitId":"-"},"content":" recipients.put(giverTeam,"},{"lineNumber":461,"author":{"gitId":"-"},"content":" new FeedbackQuestionRecipient(giverTeam, giverTeam));"},{"lineNumber":462,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":463,"author":{"gitId":"-"},"content":" recipients.put(giverEmail,"},{"lineNumber":464,"author":{"gitId":"-"},"content":" new FeedbackQuestionRecipient(USER_NAME_FOR_SELF, giverEmail));"},{"lineNumber":465,"author":{"gitId":"-"},"content":" }"},{"lineNumber":466,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":467,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":468,"author":{"gitId":"-"},"content":" case STUDENTS_EXCLUDING_SELF:"},{"lineNumber":469,"author":{"gitId":"-"},"content":" case STUDENTS_IN_SAME_SECTION:"},{"lineNumber":470,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e studentList;"},{"lineNumber":471,"author":{"gitId":"-"},"content":" if (courseRoster \u003d\u003d null) {"},{"lineNumber":472,"author":{"gitId":"-"},"content":" if (generateOptionsFor \u003d\u003d FeedbackParticipantType.STUDENTS_IN_SAME_SECTION) {"},{"lineNumber":473,"author":{"gitId":"-"},"content":" studentList \u003d usersLogic.getStudentsForSection(giverSection, courseId);"},{"lineNumber":474,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":475,"author":{"gitId":"-"},"content":" studentList \u003d usersLogic.getStudentsForCourse(courseId);"},{"lineNumber":476,"author":{"gitId":"-"},"content":" }"},{"lineNumber":477,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":478,"author":{"gitId":"-"},"content":" if (generateOptionsFor \u003d\u003d FeedbackParticipantType.STUDENTS_IN_SAME_SECTION) {"},{"lineNumber":479,"author":{"gitId":"-"},"content":" final String finalGiverSection \u003d giverSection;"},{"lineNumber":480,"author":{"gitId":"-"},"content":" studentList \u003d courseRoster.getStudents().stream()"},{"lineNumber":481,"author":{"gitId":"-"},"content":" .filter(studentAttributes -\u003e studentAttributes.getSectionName()"},{"lineNumber":482,"author":{"gitId":"-"},"content":" .equals(finalGiverSection)).collect(Collectors.toList());"},{"lineNumber":483,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":484,"author":{"gitId":"-"},"content":" studentList \u003d courseRoster.getStudents();"},{"lineNumber":485,"author":{"gitId":"-"},"content":" }"},{"lineNumber":486,"author":{"gitId":"-"},"content":" }"},{"lineNumber":487,"author":{"gitId":"-"},"content":" for (Student student : studentList) {"},{"lineNumber":488,"author":{"gitId":"-"},"content":" if (isInstructorGiver \u0026\u0026 !instructorGiver.isAllowedForPrivilege("},{"lineNumber":489,"author":{"gitId":"-"},"content":" student.getSectionName(), question.getFeedbackSession().getName(),"},{"lineNumber":490,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_SUBMIT_SESSION_IN_SECTIONS)) {"},{"lineNumber":491,"author":{"gitId":"-"},"content":" // instructor can only see students in allowed sections for him/her"},{"lineNumber":492,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":493,"author":{"gitId":"-"},"content":" }"},{"lineNumber":494,"author":{"gitId":"-"},"content":" // Ensure student does not evaluate him/herself if it\u0027s STUDENTS_EXCLUDING_SELF or"},{"lineNumber":495,"author":{"gitId":"-"},"content":" // STUDENTS_IN_SAME_SECTION"},{"lineNumber":496,"author":{"gitId":"-"},"content":" if (giverEmail.equals(student.getEmail()) \u0026\u0026 generateOptionsFor !\u003d FeedbackParticipantType.STUDENTS) {"},{"lineNumber":497,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":498,"author":{"gitId":"-"},"content":" }"},{"lineNumber":499,"author":{"gitId":"-"},"content":" recipients.put(student.getEmail(), new FeedbackQuestionRecipient(student.getName(), student.getEmail(),"},{"lineNumber":500,"author":{"gitId":"-"},"content":" student.getSectionName(), student.getTeamName()));"},{"lineNumber":501,"author":{"gitId":"-"},"content":" }"},{"lineNumber":502,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":503,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":504,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorsInCourse;"},{"lineNumber":505,"author":{"gitId":"-"},"content":" if (courseRoster \u003d\u003d null) {"},{"lineNumber":506,"author":{"gitId":"-"},"content":" instructorsInCourse \u003d usersLogic.getInstructorsForCourse(courseId);"},{"lineNumber":507,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":508,"author":{"gitId":"-"},"content":" instructorsInCourse \u003d courseRoster.getInstructors();"},{"lineNumber":509,"author":{"gitId":"-"},"content":" }"},{"lineNumber":510,"author":{"gitId":"-"},"content":" for (Instructor instr : instructorsInCourse) {"},{"lineNumber":511,"author":{"gitId":"-"},"content":" // remove hidden instructors for students"},{"lineNumber":512,"author":{"gitId":"-"},"content":" if (isStudentGiver \u0026\u0026 !instr.isDisplayedToStudents()) {"},{"lineNumber":513,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":514,"author":{"gitId":"-"},"content":" }"},{"lineNumber":515,"author":{"gitId":"-"},"content":" // Ensure instructor does not evaluate himself"},{"lineNumber":516,"author":{"gitId":"-"},"content":" if (!giverEmail.equals(instr.getEmail())) {"},{"lineNumber":517,"author":{"gitId":"-"},"content":" recipients.put(instr.getEmail(),"},{"lineNumber":518,"author":{"gitId":"-"},"content":" new FeedbackQuestionRecipient(instr.getName(), instr.getEmail()));"},{"lineNumber":519,"author":{"gitId":"-"},"content":" }"},{"lineNumber":520,"author":{"gitId":"-"},"content":" }"},{"lineNumber":521,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":522,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":523,"author":{"gitId":"-"},"content":" case TEAMS_EXCLUDING_SELF:"},{"lineNumber":524,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":525,"author":{"gitId":"-"},"content":" Map\u003cString, List\u003cStudent\u003e\u003e teamToTeamMembersTable;"},{"lineNumber":526,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e teamStudents;"},{"lineNumber":527,"author":{"gitId":"-"},"content":" if (courseRoster \u003d\u003d null) {"},{"lineNumber":528,"author":{"gitId":"-"},"content":" if (generateOptionsFor \u003d\u003d FeedbackParticipantType.TEAMS_IN_SAME_SECTION) {"},{"lineNumber":529,"author":{"gitId":"-"},"content":" teamStudents \u003d usersLogic.getStudentsForSection(giverSection, courseId);"},{"lineNumber":530,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":531,"author":{"gitId":"-"},"content":" teamStudents \u003d usersLogic.getStudentsForCourse(courseId);"},{"lineNumber":532,"author":{"gitId":"-"},"content":" }"},{"lineNumber":533,"author":{"gitId":"-"},"content":" teamToTeamMembersTable \u003d SqlCourseRoster.buildTeamToMembersTable(teamStudents);"},{"lineNumber":534,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":535,"author":{"gitId":"-"},"content":" if (generateOptionsFor \u003d\u003d FeedbackParticipantType.TEAMS_IN_SAME_SECTION) {"},{"lineNumber":536,"author":{"gitId":"-"},"content":" final String finalGiverSection \u003d giverSection;"},{"lineNumber":537,"author":{"gitId":"-"},"content":" teamStudents \u003d courseRoster.getStudents().stream()"},{"lineNumber":538,"author":{"gitId":"-"},"content":" .filter(student -\u003e student.getSectionName().equals(finalGiverSection))"},{"lineNumber":539,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":540,"author":{"gitId":"-"},"content":" teamToTeamMembersTable \u003d SqlCourseRoster.buildTeamToMembersTable(teamStudents);"},{"lineNumber":541,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":542,"author":{"gitId":"-"},"content":" teamToTeamMembersTable \u003d courseRoster.getTeamToMembersTable();"},{"lineNumber":543,"author":{"gitId":"-"},"content":" }"},{"lineNumber":544,"author":{"gitId":"-"},"content":" }"},{"lineNumber":545,"author":{"gitId":"-"},"content":" for (Map.Entry\u003cString, List\u003cStudent\u003e\u003e team : teamToTeamMembersTable.entrySet()) {"},{"lineNumber":546,"author":{"gitId":"-"},"content":" if (isInstructorGiver \u0026\u0026 !instructorGiver.isAllowedForPrivilege("},{"lineNumber":547,"author":{"gitId":"-"},"content":" team.getValue().iterator().next().getSectionName(),"},{"lineNumber":548,"author":{"gitId":"-"},"content":" question.getFeedbackSession().getName(),"},{"lineNumber":549,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_SUBMIT_SESSION_IN_SECTIONS)) {"},{"lineNumber":550,"author":{"gitId":"-"},"content":" // instructor can only see teams in allowed sections for him/her"},{"lineNumber":551,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":552,"author":{"gitId":"-"},"content":" }"},{"lineNumber":553,"author":{"gitId":"-"},"content":" // Ensure student(\u0027s team) does not evaluate own team if it\u0027s TEAMS_EXCLUDING_SELF or"},{"lineNumber":554,"author":{"gitId":"-"},"content":" // TEAMS_IN_SAME_SECTION"},{"lineNumber":555,"author":{"gitId":"-"},"content":" if (giverTeam.equals(team.getKey()) \u0026\u0026 generateOptionsFor !\u003d FeedbackParticipantType.TEAMS) {"},{"lineNumber":556,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":557,"author":{"gitId":"-"},"content":" }"},{"lineNumber":558,"author":{"gitId":"-"},"content":" // recipientEmail doubles as team name in this case."},{"lineNumber":559,"author":{"gitId":"-"},"content":" recipients.put(team.getKey(), new FeedbackQuestionRecipient(team.getKey(), team.getKey()));"},{"lineNumber":560,"author":{"gitId":"-"},"content":" }"},{"lineNumber":561,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":562,"author":{"gitId":"-"},"content":" case OWN_TEAM:"},{"lineNumber":563,"author":{"gitId":"-"},"content":" recipients.put(giverTeam, new FeedbackQuestionRecipient(giverTeam, giverTeam));"},{"lineNumber":564,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":565,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":566,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e students;"},{"lineNumber":567,"author":{"gitId":"-"},"content":" if (courseRoster \u003d\u003d null) {"},{"lineNumber":568,"author":{"gitId":"-"},"content":" students \u003d usersLogic.getStudentsForTeam(giverTeam, courseId);"},{"lineNumber":569,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":570,"author":{"gitId":"-"},"content":" students \u003d courseRoster.getTeamToMembersTable().getOrDefault(giverTeam, Collections.emptyList());"},{"lineNumber":571,"author":{"gitId":"-"},"content":" }"},{"lineNumber":572,"author":{"gitId":"-"},"content":" for (Student student : students) {"},{"lineNumber":573,"author":{"gitId":"-"},"content":" if (!student.getEmail().equals(giverEmail)) {"},{"lineNumber":574,"author":{"gitId":"-"},"content":" recipients.put(student.getEmail(), new FeedbackQuestionRecipient(student.getName(), student.getEmail(),"},{"lineNumber":575,"author":{"gitId":"-"},"content":" student.getSectionName(), student.getTeamName()));"},{"lineNumber":576,"author":{"gitId":"-"},"content":" }"},{"lineNumber":577,"author":{"gitId":"-"},"content":" }"},{"lineNumber":578,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":579,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS_INCLUDING_SELF:"},{"lineNumber":580,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e teamMembers;"},{"lineNumber":581,"author":{"gitId":"-"},"content":" if (courseRoster \u003d\u003d null) {"},{"lineNumber":582,"author":{"gitId":"-"},"content":" teamMembers \u003d usersLogic.getStudentsForTeam(giverTeam, courseId);"},{"lineNumber":583,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":584,"author":{"gitId":"-"},"content":" teamMembers \u003d courseRoster.getTeamToMembersTable().getOrDefault(giverTeam, Collections.emptyList());"},{"lineNumber":585,"author":{"gitId":"-"},"content":" }"},{"lineNumber":586,"author":{"gitId":"-"},"content":" for (Student student : teamMembers) {"},{"lineNumber":587,"author":{"gitId":"-"},"content":" // accepts self feedback too"},{"lineNumber":588,"author":{"gitId":"-"},"content":" recipients.put(student.getEmail(), new FeedbackQuestionRecipient(student.getName(), student.getEmail(),"},{"lineNumber":589,"author":{"gitId":"-"},"content":" student.getSectionName(), student.getTeamName()));"},{"lineNumber":590,"author":{"gitId":"-"},"content":" }"},{"lineNumber":591,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":592,"author":{"gitId":"-"},"content":" case NONE:"},{"lineNumber":593,"author":{"gitId":"-"},"content":" recipients.put(Const.GENERAL_QUESTION,"},{"lineNumber":594,"author":{"gitId":"-"},"content":" new FeedbackQuestionRecipient(Const.GENERAL_QUESTION, Const.GENERAL_QUESTION));"},{"lineNumber":595,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":596,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":597,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":598,"author":{"gitId":"-"},"content":" }"},{"lineNumber":599,"author":{"gitId":"-"},"content":" return recipients;"},{"lineNumber":600,"author":{"gitId":"-"},"content":" }"},{"lineNumber":601,"author":{"gitId":"-"},"content":""},{"lineNumber":602,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":603,"author":{"gitId":"-"},"content":" * Returns true if a session has question in a specific giverType."},{"lineNumber":604,"author":{"gitId":"-"},"content":" */"},{"lineNumber":605,"author":{"gitId":"-"},"content":" public boolean sessionHasQuestionsForGiverType("},{"lineNumber":606,"author":{"gitId":"-"},"content":" String feedbackSessionName, String courseId, FeedbackParticipantType giverType) {"},{"lineNumber":607,"author":{"gitId":"-"},"content":" return fqDb.hasFeedbackQuestionsForGiverType(feedbackSessionName, courseId, giverType);"},{"lineNumber":608,"author":{"gitId":"-"},"content":" }"},{"lineNumber":609,"author":{"gitId":"-"},"content":""},{"lineNumber":610,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":611,"author":{"gitId":"-"},"content":" * Returns true if a session has question in either STUDENTS type or TEAMS type."},{"lineNumber":612,"author":{"gitId":"-"},"content":" */"},{"lineNumber":613,"author":{"gitId":"-"},"content":" public boolean sessionHasQuestionsForStudent(String feedbackSessionName, String courseId) {"},{"lineNumber":614,"author":{"gitId":"-"},"content":" return fqDb.hasFeedbackQuestionsForGiverType(feedbackSessionName, courseId, FeedbackParticipantType.STUDENTS)"},{"lineNumber":615,"author":{"gitId":"-"},"content":" || fqDb.hasFeedbackQuestionsForGiverType(feedbackSessionName, courseId, FeedbackParticipantType.TEAMS);"},{"lineNumber":616,"author":{"gitId":"-"},"content":" }"},{"lineNumber":617,"author":{"gitId":"-"},"content":""},{"lineNumber":618,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":619,"author":{"gitId":"-"},"content":" * Deletes a feedback question cascade its responses and comments."},{"lineNumber":620,"author":{"gitId":"-"},"content":" *"},{"lineNumber":621,"author":{"gitId":"-"},"content":" * \u003cp\u003eSilently fail if question does not exist."},{"lineNumber":622,"author":{"gitId":"-"},"content":" */"},{"lineNumber":623,"author":{"gitId":"-"},"content":" public void deleteFeedbackQuestionCascade(UUID feedbackQuestionId) {"},{"lineNumber":624,"author":{"gitId":"-"},"content":" fqDb.deleteFeedbackQuestion(feedbackQuestionId);"},{"lineNumber":625,"author":{"gitId":"-"},"content":" }"},{"lineNumber":626,"author":{"gitId":"-"},"content":""},{"lineNumber":627,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":628,"author":{"gitId":"-"},"content":" * Filters the feedback questions in a course, with specified question type."},{"lineNumber":629,"author":{"gitId":"-"},"content":" * @param courseId the course to search from"},{"lineNumber":630,"author":{"gitId":"-"},"content":" * @param questionType the question type to search on"},{"lineNumber":631,"author":{"gitId":"-"},"content":" * @return a list of filtered questions"},{"lineNumber":632,"author":{"gitId":"-"},"content":" */"},{"lineNumber":633,"author":{"gitId":"-"},"content":" public List\u003cFeedbackQuestion\u003e getFeedbackQuestionForCourseWithType("},{"lineNumber":634,"author":{"gitId":"-"},"content":" String courseId, FeedbackQuestionType questionType) {"},{"lineNumber":635,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e feedbackSessions \u003d feedbackSessionsLogic.getFeedbackSessionsForCourse(courseId);"},{"lineNumber":636,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e feedbackQuestions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":637,"author":{"gitId":"-"},"content":""},{"lineNumber":638,"author":{"gitId":"-"},"content":" for (FeedbackSession session : feedbackSessions) {"},{"lineNumber":639,"author":{"gitId":"-"},"content":" feedbackQuestions.addAll(getFeedbackQuestionsForSession(session));"},{"lineNumber":640,"author":{"gitId":"-"},"content":" }"},{"lineNumber":641,"author":{"gitId":"-"},"content":""},{"lineNumber":642,"author":{"gitId":"-"},"content":" return feedbackQuestions"},{"lineNumber":643,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":644,"author":{"gitId":"-"},"content":" .filter(q -\u003e q.getQuestionDetailsCopy().getQuestionType().equals(questionType))"},{"lineNumber":645,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":646,"author":{"gitId":"-"},"content":" }"},{"lineNumber":647,"author":{"gitId":"-"},"content":""},{"lineNumber":648,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":649,"author":{"gitId":"xenosf"},"content":" * Builds a complete giver to recipient map for a {@code relatedQuestion}."},{"lineNumber":650,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":651,"author":{"gitId":"xenosf"},"content":" * @param relatedQuestion The question to be considered"},{"lineNumber":652,"author":{"gitId":"xenosf"},"content":" * @param courseRoster the roster in the course"},{"lineNumber":653,"author":{"gitId":"xenosf"},"content":" * @return a map from giver to recipient for the question."},{"lineNumber":654,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":655,"author":{"gitId":"xenosf"},"content":" public Map\u003cString, Set\u003cString\u003e\u003e buildCompleteGiverRecipientMap("},{"lineNumber":656,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion relatedQuestion, SqlCourseRoster courseRoster) {"},{"lineNumber":657,"author":{"gitId":"xenosf"},"content":" Map\u003cString, Set\u003cString\u003e\u003e completeGiverRecipientMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":658,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":659,"author":{"gitId":"xenosf"},"content":" List\u003cString\u003e possibleGiverEmails \u003d getPossibleGivers(relatedQuestion, courseRoster);"},{"lineNumber":660,"author":{"gitId":"xenosf"},"content":" for (String possibleGiverEmail : possibleGiverEmails) {"},{"lineNumber":661,"author":{"gitId":"xenosf"},"content":" switch (relatedQuestion.getGiverType()) {"},{"lineNumber":662,"author":{"gitId":"xenosf"},"content":" case STUDENTS:"},{"lineNumber":663,"author":{"gitId":"xenosf"},"content":" Student studentGiver \u003d courseRoster.getStudentForEmail(possibleGiverEmail);"},{"lineNumber":664,"author":{"gitId":"xenosf"},"content":" completeGiverRecipientMap"},{"lineNumber":665,"author":{"gitId":"xenosf"},"content":" .computeIfAbsent(possibleGiverEmail, key -\u003e new HashSet\u003c\u003e())"},{"lineNumber":666,"author":{"gitId":"xenosf"},"content":" .addAll(getRecipientsOfQuestion("},{"lineNumber":667,"author":{"gitId":"xenosf"},"content":" relatedQuestion, null, studentGiver, courseRoster).keySet());"},{"lineNumber":668,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":669,"author":{"gitId":"xenosf"},"content":" case TEAMS:"},{"lineNumber":670,"author":{"gitId":"xenosf"},"content":" Student oneTeamMember \u003d"},{"lineNumber":671,"author":{"gitId":"xenosf"},"content":" courseRoster.getTeamToMembersTable().get(possibleGiverEmail).iterator().next();"},{"lineNumber":672,"author":{"gitId":"xenosf"},"content":" completeGiverRecipientMap"},{"lineNumber":673,"author":{"gitId":"xenosf"},"content":" .computeIfAbsent(possibleGiverEmail, key -\u003e new HashSet\u003c\u003e())"},{"lineNumber":674,"author":{"gitId":"xenosf"},"content":" .addAll(getRecipientsOfQuestion("},{"lineNumber":675,"author":{"gitId":"xenosf"},"content":" relatedQuestion, null, oneTeamMember, courseRoster).keySet());"},{"lineNumber":676,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":677,"author":{"gitId":"xenosf"},"content":" case INSTRUCTORS:"},{"lineNumber":678,"author":{"gitId":"xenosf"},"content":" case SELF:"},{"lineNumber":679,"author":{"gitId":"xenosf"},"content":" Instructor instructorGiver \u003d courseRoster.getInstructorForEmail(possibleGiverEmail);"},{"lineNumber":680,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":681,"author":{"gitId":"xenosf"},"content":" // only happens when a session creator quits their course"},{"lineNumber":682,"author":{"gitId":"xenosf"},"content":" if (instructorGiver \u003d\u003d null) {"},{"lineNumber":683,"author":{"gitId":"xenosf"},"content":" instructorGiver \u003d new Instructor("},{"lineNumber":684,"author":{"gitId":"xenosf"},"content":" relatedQuestion.getCourse(),"},{"lineNumber":685,"author":{"gitId":"xenosf"},"content":" USER_NAME_FOR_SELF,"},{"lineNumber":686,"author":{"gitId":"xenosf"},"content":" possibleGiverEmail,"},{"lineNumber":687,"author":{"gitId":"xenosf"},"content":" false,"},{"lineNumber":688,"author":{"gitId":"xenosf"},"content":" USER_NAME_FOR_SELF,"},{"lineNumber":689,"author":{"gitId":"xenosf"},"content":" null,"},{"lineNumber":690,"author":{"gitId":"xenosf"},"content":" null"},{"lineNumber":691,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":692,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":693,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":694,"author":{"gitId":"xenosf"},"content":" completeGiverRecipientMap"},{"lineNumber":695,"author":{"gitId":"xenosf"},"content":" .computeIfAbsent(possibleGiverEmail, key -\u003e new HashSet\u003c\u003e())"},{"lineNumber":696,"author":{"gitId":"xenosf"},"content":" .addAll(getRecipientsOfQuestion("},{"lineNumber":697,"author":{"gitId":"xenosf"},"content":" relatedQuestion, instructorGiver, null, courseRoster).keySet());"},{"lineNumber":698,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":699,"author":{"gitId":"xenosf"},"content":" default:"},{"lineNumber":700,"author":{"gitId":"xenosf"},"content":" log.severe(\"Invalid giver type specified\");"},{"lineNumber":701,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":702,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":703,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":704,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":705,"author":{"gitId":"xenosf"},"content":" return completeGiverRecipientMap;"},{"lineNumber":706,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":707,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":708,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":709,"author":{"gitId":"xenosf"},"content":" * Gets possible giver identifiers for a feedback question."},{"lineNumber":710,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":711,"author":{"gitId":"xenosf"},"content":" * @param fq the feedback question"},{"lineNumber":712,"author":{"gitId":"xenosf"},"content":" * @param courseRoster roster of all students and instructors"},{"lineNumber":713,"author":{"gitId":"xenosf"},"content":" * @return a list of giver identifier"},{"lineNumber":714,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":715,"author":{"gitId":"xenosf"},"content":" private List\u003cString\u003e getPossibleGivers("},{"lineNumber":716,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion fq, SqlCourseRoster courseRoster) {"},{"lineNumber":717,"author":{"gitId":"xenosf"},"content":" FeedbackParticipantType giverType \u003d fq.getGiverType();"},{"lineNumber":718,"author":{"gitId":"xenosf"},"content":" List\u003cString\u003e possibleGivers \u003d new ArrayList\u003c\u003e();"},{"lineNumber":719,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":720,"author":{"gitId":"xenosf"},"content":" switch (giverType) {"},{"lineNumber":721,"author":{"gitId":"xenosf"},"content":" case STUDENTS:"},{"lineNumber":722,"author":{"gitId":"xenosf"},"content":" possibleGivers \u003d courseRoster.getStudents()"},{"lineNumber":723,"author":{"gitId":"xenosf"},"content":" .stream()"},{"lineNumber":724,"author":{"gitId":"xenosf"},"content":" .map(Student::getEmail)"},{"lineNumber":725,"author":{"gitId":"xenosf"},"content":" .collect(Collectors.toList());"},{"lineNumber":726,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":727,"author":{"gitId":"xenosf"},"content":" case INSTRUCTORS:"},{"lineNumber":728,"author":{"gitId":"xenosf"},"content":" possibleGivers \u003d courseRoster.getInstructors()"},{"lineNumber":729,"author":{"gitId":"xenosf"},"content":" .stream()"},{"lineNumber":730,"author":{"gitId":"xenosf"},"content":" .map(Instructor::getEmail)"},{"lineNumber":731,"author":{"gitId":"xenosf"},"content":" .collect(Collectors.toList());"},{"lineNumber":732,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":733,"author":{"gitId":"xenosf"},"content":" case TEAMS:"},{"lineNumber":734,"author":{"gitId":"xenosf"},"content":" possibleGivers \u003d new ArrayList\u003c\u003e(courseRoster.getTeamToMembersTable().keySet());"},{"lineNumber":735,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":736,"author":{"gitId":"xenosf"},"content":" case SELF:"},{"lineNumber":737,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession \u003d"},{"lineNumber":738,"author":{"gitId":"xenosf"},"content":" feedbackSessionsLogic.getFeedbackSession(fq.getFeedbackSessionName(), fq.getCourseId());"},{"lineNumber":739,"author":{"gitId":"xenosf"},"content":" possibleGivers \u003d Collections.singletonList(feedbackSession.getCreatorEmail());"},{"lineNumber":740,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":741,"author":{"gitId":"xenosf"},"content":" default:"},{"lineNumber":742,"author":{"gitId":"xenosf"},"content":" log.severe(\"Invalid giver type specified\");"},{"lineNumber":743,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":744,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":745,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":746,"author":{"gitId":"xenosf"},"content":" return possibleGivers;"},{"lineNumber":747,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":748,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":749,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":6,"xenosf":101,"dishenggg":2,"-":640}},{"path":"src/main/java/teammates/sqllogic/core/FeedbackResponseCommentsLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import java.util.Set;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.SqlCourseRoster;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackResponseCommentsDb;"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.ui.request.FeedbackResponseCommentUpdateRequest;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * Handles operations related to feedback response comments."},{"lineNumber":23,"author":{"gitId":"-"},"content":" *"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * @see FeedbackResponseComment"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * @see FeedbackResponseCommentsDb"},{"lineNumber":26,"author":{"gitId":"-"},"content":" */"},{"lineNumber":27,"author":{"gitId":"-"},"content":"public final class FeedbackResponseCommentsLogic {"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" private static final FeedbackResponseCommentsLogic instance \u003d new FeedbackResponseCommentsLogic();"},{"lineNumber":30,"author":{"gitId":"-"},"content":" private FeedbackResponseCommentsDb frcDb;"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" private FeedbackResponseCommentsLogic() {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" public static FeedbackResponseCommentsLogic inst() {"},{"lineNumber":37,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" }"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":41,"author":{"gitId":"-"},"content":" * Initialize dependencies for {@code FeedbackResponseCommentsLogic}."},{"lineNumber":42,"author":{"gitId":"-"},"content":" */"},{"lineNumber":43,"author":{"gitId":"-"},"content":" void initLogicDependencies(FeedbackResponseCommentsDb frcDb) {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" this.frcDb \u003d frcDb;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":48,"author":{"gitId":"-"},"content":" * Gets an feedback response comment by feedback response comment id."},{"lineNumber":49,"author":{"gitId":"-"},"content":" * @param id of feedback response comment."},{"lineNumber":50,"author":{"gitId":"-"},"content":" * @return the specified feedback response comment."},{"lineNumber":51,"author":{"gitId":"-"},"content":" */"},{"lineNumber":52,"author":{"gitId":"-"},"content":" public FeedbackResponseComment getFeedbackResponseComment(Long id) {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" return frcDb.getFeedbackResponseComment(id);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" }"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" * Gets all feedback response comments for a response."},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentForResponse(UUID feedbackResponseId) {"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" return frcDb.getFeedbackResponseCommentsForResponse(feedbackResponseId);"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" * Gets all response comments for a response."},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentsForResponse(UUID feedbackResponseId) {"},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" assert feedbackResponseId !\u003d null;"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" return frcDb.getFeedbackResponseCommentsForResponse(feedbackResponseId);"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":73,"author":{"gitId":"-"},"content":" * Gets the comment associated with the response."},{"lineNumber":74,"author":{"gitId":"-"},"content":" */"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public FeedbackResponseComment getFeedbackResponseCommentForResponseFromParticipant("},{"lineNumber":76,"author":{"gitId":"-"},"content":" UUID feedbackResponseId) {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" return frcDb.getFeedbackResponseCommentForResponseFromParticipant(feedbackResponseId);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":81,"author":{"gitId":"-"},"content":" * Creates a feedback response comment."},{"lineNumber":82,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the comment alreadty exists"},{"lineNumber":83,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the comment is invalid"},{"lineNumber":84,"author":{"gitId":"-"},"content":" */"},{"lineNumber":85,"author":{"gitId":"-"},"content":" public FeedbackResponseComment createFeedbackResponseComment(FeedbackResponseComment frc)"},{"lineNumber":86,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" return frcDb.createFeedbackResponseComment(frc);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":91,"author":{"gitId":"-"},"content":" * Deletes a feedbackResponseComment."},{"lineNumber":92,"author":{"gitId":"-"},"content":" */"},{"lineNumber":93,"author":{"gitId":"-"},"content":" public void deleteFeedbackResponseComment(Long frcId) {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" frcDb.deleteFeedbackResponseComment(frcId);"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":98,"author":{"gitId":"-"},"content":" * Updates a feedback response comment by {@link FeedbackResponseComment}."},{"lineNumber":99,"author":{"gitId":"-"},"content":" *"},{"lineNumber":100,"author":{"gitId":"-"},"content":" * @return updated comment"},{"lineNumber":101,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":102,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the comment cannot be found"},{"lineNumber":103,"author":{"gitId":"-"},"content":" */"},{"lineNumber":104,"author":{"gitId":"-"},"content":" public FeedbackResponseComment updateFeedbackResponseComment(FeedbackResponseComment feedbackResponseComment)"},{"lineNumber":105,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" return frcDb.updateFeedbackResponseComment(feedbackResponseComment);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":111,"author":{"gitId":"-"},"content":" * Updates a feedback response comment."},{"lineNumber":112,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the comment does not exist"},{"lineNumber":113,"author":{"gitId":"-"},"content":" */"},{"lineNumber":114,"author":{"gitId":"-"},"content":" public FeedbackResponseComment updateFeedbackResponseComment(Long frcId,"},{"lineNumber":115,"author":{"gitId":"-"},"content":" FeedbackResponseCommentUpdateRequest updateRequest, String updaterEmail)"},{"lineNumber":116,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" FeedbackResponseComment comment \u003d frcDb.getFeedbackResponseComment(frcId);"},{"lineNumber":118,"author":{"gitId":"-"},"content":" if (comment \u003d\u003d null) {"},{"lineNumber":119,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Trying to update a feedback response comment that does not exist.\");"},{"lineNumber":120,"author":{"gitId":"-"},"content":" }"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" comment.setCommentText(updateRequest.getCommentText());"},{"lineNumber":123,"author":{"gitId":"-"},"content":" comment.setShowCommentTo(updateRequest.getShowCommentTo());"},{"lineNumber":124,"author":{"gitId":"-"},"content":" comment.setShowGiverNameTo(updateRequest.getShowGiverNameTo());"},{"lineNumber":125,"author":{"gitId":"-"},"content":" comment.setLastEditorEmail(updaterEmail);"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" return comment;"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":" * Updates all feedback response comments with new emails."},{"lineNumber":132,"author":{"gitId":"-"},"content":" */"},{"lineNumber":133,"author":{"gitId":"-"},"content":" public void updateFeedbackResponseCommentsEmails(String courseId, String oldEmail, String updatedEmail) {"},{"lineNumber":134,"author":{"gitId":"-"},"content":" frcDb.updateGiverEmailOfFeedbackResponseComments(courseId, oldEmail, updatedEmail);"},{"lineNumber":135,"author":{"gitId":"-"},"content":" frcDb.updateLastEditorEmailOfFeedbackResponseComments(courseId, oldEmail, updatedEmail);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" }"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":" * Updates all feedback response comments with new sections."},{"lineNumber":140,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":" public void updateFeedbackResponseCommentsForResponse(FeedbackResponse response)"},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackResponseComment\u003e comments \u003d getFeedbackResponseCommentForResponse(response.getId());"},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":" for (FeedbackResponseComment comment : comments) {"},{"lineNumber":145,"author":{"gitId":"domoberzin"},"content":" comment.setGiverSection(response.getGiverSection());"},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":" comment.setRecipientSection(response.getRecipientSection());"},{"lineNumber":147,"author":{"gitId":"domoberzin"},"content":" frcDb.updateFeedbackResponseComment(comment);"},{"lineNumber":148,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":149,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":150,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":151,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":152,"author":{"gitId":"xenosf"},"content":" * Gets all feedback response comments for session in a section."},{"lineNumber":153,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":154,"author":{"gitId":"xenosf"},"content":" * @param courseId the course ID of the feedback session"},{"lineNumber":155,"author":{"gitId":"xenosf"},"content":" * @param feedbackSessionName the feedback session name"},{"lineNumber":156,"author":{"gitId":"xenosf"},"content":" * @param sectionName if null, will retrieve all comments in the session"},{"lineNumber":157,"author":{"gitId":"xenosf"},"content":" * @return a list of feedback response comments"},{"lineNumber":158,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":159,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentForSessionInSection("},{"lineNumber":160,"author":{"gitId":"xenosf"},"content":" String courseId, String feedbackSessionName, @Nullable String sectionName) {"},{"lineNumber":161,"author":{"gitId":"xenosf"},"content":" if (sectionName \u003d\u003d null) {"},{"lineNumber":162,"author":{"gitId":"xenosf"},"content":" return frcDb.getFeedbackResponseCommentsForSession(courseId, feedbackSessionName);"},{"lineNumber":163,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":164,"author":{"gitId":"xenosf"},"content":" return frcDb.getFeedbackResponseCommentsForSessionInSection(courseId, feedbackSessionName, sectionName);"},{"lineNumber":165,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":166,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":167,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":168,"author":{"gitId":"xenosf"},"content":" * Gets all feedback response comments for a question in a section."},{"lineNumber":169,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":170,"author":{"gitId":"xenosf"},"content":" * @param questionId the ID of the question"},{"lineNumber":171,"author":{"gitId":"xenosf"},"content":" * @param sectionName if null, will retrieve all comments for the question"},{"lineNumber":172,"author":{"gitId":"xenosf"},"content":" * @return a list of feedback response comments"},{"lineNumber":173,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":174,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentForQuestionInSection("},{"lineNumber":175,"author":{"gitId":"xenosf"},"content":" UUID questionId, @Nullable String sectionName) {"},{"lineNumber":176,"author":{"gitId":"xenosf"},"content":" if (sectionName \u003d\u003d null) {"},{"lineNumber":177,"author":{"gitId":"xenosf"},"content":" return frcDb.getFeedbackResponseCommentsForQuestion(questionId);"},{"lineNumber":178,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":179,"author":{"gitId":"xenosf"},"content":" return frcDb.getFeedbackResponseCommentsForQuestionInSection(questionId, sectionName);"},{"lineNumber":180,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":181,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":182,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":183,"author":{"gitId":"xenosf"},"content":" * Verifies whether the comment is visible to certain user."},{"lineNumber":184,"author":{"gitId":"xenosf"},"content":" * @return true/false"},{"lineNumber":185,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":186,"author":{"gitId":"xenosf"},"content":" public boolean checkIsResponseCommentVisibleForUser(String userEmail, boolean isInstructor,"},{"lineNumber":187,"author":{"gitId":"xenosf"},"content":" Student student, Set\u003cString\u003e studentsEmailInTeam, FeedbackResponse response,"},{"lineNumber":188,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion relatedQuestion, FeedbackResponseComment relatedComment) {"},{"lineNumber":189,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":190,"author":{"gitId":"xenosf"},"content":" if (response \u003d\u003d null || relatedQuestion \u003d\u003d null) {"},{"lineNumber":191,"author":{"gitId":"xenosf"},"content":" return false;"},{"lineNumber":192,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":193,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":194,"author":{"gitId":"xenosf"},"content":" boolean isVisibilityFollowingFeedbackQuestion \u003d relatedComment.getIsVisibilityFollowingFeedbackQuestion();"},{"lineNumber":195,"author":{"gitId":"xenosf"},"content":" boolean isVisibleToGiver \u003d isVisibilityFollowingFeedbackQuestion"},{"lineNumber":196,"author":{"gitId":"xenosf"},"content":" || relatedComment.checkIsVisibleTo(FeedbackParticipantType.GIVER);"},{"lineNumber":197,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":198,"author":{"gitId":"xenosf"},"content":" boolean isVisibleToUser \u003d checkIsVisibleToUser(userEmail, response, relatedQuestion, relatedComment,"},{"lineNumber":199,"author":{"gitId":"xenosf"},"content":" isVisibleToGiver, isInstructor, !isInstructor);"},{"lineNumber":200,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":201,"author":{"gitId":"xenosf"},"content":" boolean isVisibleToUserTeam \u003d checkIsVisibleToUserTeam(student, studentsEmailInTeam, response,"},{"lineNumber":202,"author":{"gitId":"xenosf"},"content":" relatedQuestion, relatedComment, !isInstructor);"},{"lineNumber":203,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":204,"author":{"gitId":"xenosf"},"content":" return isVisibleToUser || isVisibleToUserTeam;"},{"lineNumber":205,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":206,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":207,"author":{"gitId":"xenosf"},"content":" private boolean checkIsVisibleToUserTeam(Student student, Set\u003cString\u003e studentsEmailInTeam,"},{"lineNumber":208,"author":{"gitId":"xenosf"},"content":" FeedbackResponse response, FeedbackQuestion relatedQuestion,"},{"lineNumber":209,"author":{"gitId":"xenosf"},"content":" FeedbackResponseComment relatedComment, boolean isUserStudent) {"},{"lineNumber":210,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":211,"author":{"gitId":"xenosf"},"content":" boolean isUserInResponseRecipientTeamAndRelatedResponseCommentVisibleToRecipients \u003d"},{"lineNumber":212,"author":{"gitId":"xenosf"},"content":" isUserStudent"},{"lineNumber":213,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 relatedQuestion.getRecipientType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 checkIsResponseCommentVisibleTo(relatedQuestion, relatedComment,"},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" FeedbackParticipantType.RECEIVER)"},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 response.getRecipient().equals(student.getTeamName());"},{"lineNumber":217,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":218,"author":{"gitId":"xenosf"},"content":" boolean isUserInResponseGiverTeamAndRelatedResponseCommentVisibleToGiversTeamMembers \u003d"},{"lineNumber":219,"author":{"gitId":"xenosf"},"content":" (relatedQuestion.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":220,"author":{"gitId":"xenosf"},"content":" || checkIsResponseCommentVisibleTo(relatedQuestion, relatedComment,"},{"lineNumber":221,"author":{"gitId":"xenosf"},"content":" FeedbackParticipantType.OWN_TEAM_MEMBERS))"},{"lineNumber":222,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 (studentsEmailInTeam.contains(response.getGiver())"},{"lineNumber":223,"author":{"gitId":"xenosf"},"content":" || isUserStudent \u0026\u0026 student.getTeamName().equals(response.getGiver()));"},{"lineNumber":224,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":225,"author":{"gitId":"xenosf"},"content":" boolean isUserInResponseRecipientTeamAndRelatedResponseCommentVisibleToRecipientsTeamMembers \u003d"},{"lineNumber":226,"author":{"gitId":"xenosf"},"content":" checkIsResponseCommentVisibleTo(relatedQuestion, relatedComment,"},{"lineNumber":227,"author":{"gitId":"xenosf"},"content":" FeedbackParticipantType.RECEIVER_TEAM_MEMBERS)"},{"lineNumber":228,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 studentsEmailInTeam.contains(response.getRecipient());"},{"lineNumber":229,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":230,"author":{"gitId":"xenosf"},"content":" return isUserInResponseRecipientTeamAndRelatedResponseCommentVisibleToRecipients"},{"lineNumber":231,"author":{"gitId":"xenosf"},"content":" || isUserInResponseGiverTeamAndRelatedResponseCommentVisibleToGiversTeamMembers"},{"lineNumber":232,"author":{"gitId":"xenosf"},"content":" || isUserInResponseRecipientTeamAndRelatedResponseCommentVisibleToRecipientsTeamMembers;"},{"lineNumber":233,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":234,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":235,"author":{"gitId":"xenosf"},"content":" private boolean checkIsVisibleToUser(String userEmail, FeedbackResponse response,"},{"lineNumber":236,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion relatedQuestion, FeedbackResponseComment relatedComment,"},{"lineNumber":237,"author":{"gitId":"xenosf"},"content":" boolean isVisibleToGiver, boolean isUserInstructor, boolean isUserStudent) {"},{"lineNumber":238,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":239,"author":{"gitId":"xenosf"},"content":" boolean isUserInstructorAndRelatedResponseCommentVisibleToInstructors \u003d"},{"lineNumber":240,"author":{"gitId":"xenosf"},"content":" isUserInstructor \u0026\u0026 checkIsResponseCommentVisibleTo(relatedQuestion, relatedComment,"},{"lineNumber":241,"author":{"gitId":"xenosf"},"content":" FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":242,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":243,"author":{"gitId":"xenosf"},"content":" boolean isUserResponseRecipientAndRelatedResponseCommentVisibleToRecipients \u003d"},{"lineNumber":244,"author":{"gitId":"xenosf"},"content":" response.getRecipient().equals(userEmail) \u0026\u0026 checkIsResponseCommentVisibleTo(relatedQuestion,"},{"lineNumber":245,"author":{"gitId":"xenosf"},"content":" relatedComment, FeedbackParticipantType.RECEIVER);"},{"lineNumber":246,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":247,"author":{"gitId":"xenosf"},"content":" boolean isUserResponseGiverAndRelatedResponseCommentVisibleToGivers \u003d"},{"lineNumber":248,"author":{"gitId":"xenosf"},"content":" response.getGiver().equals(userEmail) \u0026\u0026 isVisibleToGiver;"},{"lineNumber":249,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":250,"author":{"gitId":"xenosf"},"content":" boolean isUserRelatedResponseCommentGiver \u003d relatedComment.getGiver().equals(userEmail);"},{"lineNumber":251,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":252,"author":{"gitId":"xenosf"},"content":" boolean isUserStudentAndRelatedResponseCommentVisibleToStudents \u003d"},{"lineNumber":253,"author":{"gitId":"xenosf"},"content":" isUserStudent \u0026\u0026 checkIsResponseCommentVisibleTo(relatedQuestion,"},{"lineNumber":254,"author":{"gitId":"xenosf"},"content":" relatedComment, FeedbackParticipantType.STUDENTS);"},{"lineNumber":255,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":256,"author":{"gitId":"xenosf"},"content":" return isUserInstructorAndRelatedResponseCommentVisibleToInstructors"},{"lineNumber":257,"author":{"gitId":"xenosf"},"content":" || isUserResponseRecipientAndRelatedResponseCommentVisibleToRecipients"},{"lineNumber":258,"author":{"gitId":"xenosf"},"content":" || isUserResponseGiverAndRelatedResponseCommentVisibleToGivers"},{"lineNumber":259,"author":{"gitId":"xenosf"},"content":" || isUserRelatedResponseCommentGiver"},{"lineNumber":260,"author":{"gitId":"xenosf"},"content":" || isUserStudentAndRelatedResponseCommentVisibleToStudents;"},{"lineNumber":261,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":262,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":263,"author":{"gitId":"xenosf"},"content":" private boolean checkIsResponseCommentVisibleTo(FeedbackQuestion relatedQuestion,"},{"lineNumber":264,"author":{"gitId":"xenosf"},"content":" FeedbackResponseComment relatedComment,"},{"lineNumber":265,"author":{"gitId":"xenosf"},"content":" FeedbackParticipantType viewerType) {"},{"lineNumber":266,"author":{"gitId":"xenosf"},"content":" boolean isVisibilityFollowingFeedbackQuestion \u003d relatedComment.getIsVisibilityFollowingFeedbackQuestion();"},{"lineNumber":267,"author":{"gitId":"xenosf"},"content":" return isVisibilityFollowingFeedbackQuestion"},{"lineNumber":268,"author":{"gitId":"xenosf"},"content":" ? relatedQuestion.isResponseVisibleTo(viewerType)"},{"lineNumber":269,"author":{"gitId":"xenosf"},"content":" : relatedComment.checkIsVisibleTo(viewerType);"},{"lineNumber":270,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":271,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":272,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":273,"author":{"gitId":"xenosf"},"content":" * Returns true if the comment\u0027s giver name is visible to certain user."},{"lineNumber":274,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":275,"author":{"gitId":"xenosf"},"content":" public boolean checkIsNameVisibleToUser(FeedbackResponseComment comment, FeedbackResponse response,"},{"lineNumber":276,"author":{"gitId":"xenosf"},"content":" String userEmail, SqlCourseRoster roster) {"},{"lineNumber":277,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackParticipantType\u003e showNameTo \u003d comment.getShowGiverNameTo();"},{"lineNumber":278,"author":{"gitId":"xenosf"},"content":" //in the old ver, name is always visible"},{"lineNumber":279,"author":{"gitId":"xenosf"},"content":" if (showNameTo \u003d\u003d null || comment.getIsVisibilityFollowingFeedbackQuestion()) {"},{"lineNumber":280,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":281,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":282,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":283,"author":{"gitId":"xenosf"},"content":" //comment giver can always see"},{"lineNumber":284,"author":{"gitId":"xenosf"},"content":" if (userEmail.equals(comment.getGiver())) {"},{"lineNumber":285,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":286,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":287,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":288,"author":{"gitId":"xenosf"},"content":" return checkIsFeedbackParticipantNameVisibleToUser(response, userEmail, roster, showNameTo);"},{"lineNumber":289,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":290,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":291,"author":{"gitId":"xenosf"},"content":" private boolean checkIsFeedbackParticipantNameVisibleToUser(FeedbackResponse response,"},{"lineNumber":292,"author":{"gitId":"xenosf"},"content":" String userEmail, SqlCourseRoster roster, List\u003cFeedbackParticipantType\u003e showNameTo) {"},{"lineNumber":293,"author":{"gitId":"xenosf"},"content":" String responseGiverTeam \u003d \"giverTeam\";"},{"lineNumber":294,"author":{"gitId":"xenosf"},"content":" if (roster.getStudentForEmail(response.getGiver()) !\u003d null) {"},{"lineNumber":295,"author":{"gitId":"xenosf"},"content":" responseGiverTeam \u003d roster.getStudentForEmail(response.getGiver()).getTeamName();"},{"lineNumber":296,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":297,"author":{"gitId":"xenosf"},"content":" String responseRecipientTeam \u003d \"recipientTeam\";"},{"lineNumber":298,"author":{"gitId":"xenosf"},"content":" if (roster.getStudentForEmail(response.getRecipient()) !\u003d null) {"},{"lineNumber":299,"author":{"gitId":"xenosf"},"content":" responseRecipientTeam \u003d roster.getStudentForEmail(response.getRecipient()).getTeamName();"},{"lineNumber":300,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":301,"author":{"gitId":"xenosf"},"content":" String currentUserTeam \u003d \"currentUserTeam\";"},{"lineNumber":302,"author":{"gitId":"xenosf"},"content":" if (roster.getStudentForEmail(userEmail) !\u003d null) {"},{"lineNumber":303,"author":{"gitId":"xenosf"},"content":" currentUserTeam \u003d roster.getStudentForEmail(userEmail).getTeamName();"},{"lineNumber":304,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":305,"author":{"gitId":"xenosf"},"content":" for (FeedbackParticipantType type : showNameTo) {"},{"lineNumber":306,"author":{"gitId":"xenosf"},"content":" switch (type) {"},{"lineNumber":307,"author":{"gitId":"xenosf"},"content":" case INSTRUCTORS:"},{"lineNumber":308,"author":{"gitId":"xenosf"},"content":" if (roster.getInstructorForEmail(userEmail) !\u003d null) {"},{"lineNumber":309,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":310,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":311,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":312,"author":{"gitId":"xenosf"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":313,"author":{"gitId":"xenosf"},"content":" if (responseGiverTeam.equals(currentUserTeam)) {"},{"lineNumber":314,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":315,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":316,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":317,"author":{"gitId":"xenosf"},"content":" case RECEIVER:"},{"lineNumber":318,"author":{"gitId":"xenosf"},"content":" if (userEmail.equals(response.getRecipient())) {"},{"lineNumber":319,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":320,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":321,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":322,"author":{"gitId":"xenosf"},"content":" case RECEIVER_TEAM_MEMBERS:"},{"lineNumber":323,"author":{"gitId":"xenosf"},"content":" if (responseRecipientTeam.equals(currentUserTeam)) {"},{"lineNumber":324,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":325,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":326,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":327,"author":{"gitId":"xenosf"},"content":" case STUDENTS:"},{"lineNumber":328,"author":{"gitId":"xenosf"},"content":" if (roster.getStudentForEmail(userEmail) !\u003d null) {"},{"lineNumber":329,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":330,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":331,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":332,"author":{"gitId":"xenosf"},"content":" case GIVER:"},{"lineNumber":333,"author":{"gitId":"xenosf"},"content":" if (userEmail.equals(response.getGiver())) {"},{"lineNumber":334,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":335,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":336,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":337,"author":{"gitId":"xenosf"},"content":" default:"},{"lineNumber":338,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":339,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":340,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":341,"author":{"gitId":"xenosf"},"content":" return false;"},{"lineNumber":342,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":343,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":32,"xenosf":198,"-":113}},{"path":"src/main/java/teammates/sqllogic/core/FeedbackResponsesLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import java.util.Collections;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import java.util.HashMap;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import java.util.HashSet;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":"import java.util.Set;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.FeedbackResultFetchType;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlCourseRoster;"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.SqlSessionResultsBundle;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionType;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRankRecipientsResponseDetails;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const;"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.RequestTracer;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackResponsesDb;"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.responses.FeedbackMissingResponse;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackRankRecipientsResponse;"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" * Handles operations related to feedback responses."},{"lineNumber":40,"author":{"gitId":"-"},"content":" *"},{"lineNumber":41,"author":{"gitId":"-"},"content":" * @see FeedbackResponse"},{"lineNumber":42,"author":{"gitId":"-"},"content":" * @see FeedbackResponsesDb"},{"lineNumber":43,"author":{"gitId":"-"},"content":" */"},{"lineNumber":44,"author":{"gitId":"-"},"content":"public final class FeedbackResponsesLogic {"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" private static final FeedbackResponsesLogic instance \u003d new FeedbackResponsesLogic();"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" private FeedbackResponsesDb frDb;"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private UsersLogic usersLogic;"},{"lineNumber":50,"author":{"gitId":"-"},"content":" private FeedbackQuestionsLogic fqLogic;"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" private FeedbackResponseCommentsLogic frcLogic;"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" private FeedbackResponsesLogic() {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" public static FeedbackResponsesLogic inst() {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":59,"author":{"gitId":"-"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":62,"author":{"gitId":"-"},"content":" * Initialize dependencies for {@code FeedbackResponsesLogic}."},{"lineNumber":63,"author":{"gitId":"-"},"content":" */"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" void initLogicDependencies(FeedbackResponsesDb frDb,"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" UsersLogic usersLogic, FeedbackQuestionsLogic fqLogic, FeedbackResponseCommentsLogic frcLogic) {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" this.frDb \u003d frDb;"},{"lineNumber":67,"author":{"gitId":"-"},"content":" this.usersLogic \u003d usersLogic;"},{"lineNumber":68,"author":{"gitId":"-"},"content":" this.fqLogic \u003d fqLogic;"},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" this.frcLogic \u003d frcLogic;"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":73,"author":{"gitId":"-"},"content":" * Gets a feedbackResponse or null if it does not exist."},{"lineNumber":74,"author":{"gitId":"-"},"content":" */"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public FeedbackResponse getFeedbackResponse(UUID frId) {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" return frDb.getFeedbackResponse(frId);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":80,"author":{"gitId":"-"},"content":" * Returns true if the responses of the question are visible to students."},{"lineNumber":81,"author":{"gitId":"-"},"content":" */"},{"lineNumber":82,"author":{"gitId":"-"},"content":" public boolean isResponseOfFeedbackQuestionVisibleToStudent(FeedbackQuestion question) {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" if (question.isResponseVisibleTo(FeedbackParticipantType.STUDENTS)) {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" }"},{"lineNumber":86,"author":{"gitId":"-"},"content":" boolean isStudentRecipientType \u003d"},{"lineNumber":87,"author":{"gitId":"-"},"content":" question.getRecipientType().equals(FeedbackParticipantType.STUDENTS)"},{"lineNumber":88,"author":{"gitId":"-"},"content":" || question.getRecipientType().equals(FeedbackParticipantType.STUDENTS_EXCLUDING_SELF)"},{"lineNumber":89,"author":{"gitId":"-"},"content":" || question.getRecipientType().equals(FeedbackParticipantType.STUDENTS_IN_SAME_SECTION)"},{"lineNumber":90,"author":{"gitId":"-"},"content":" || question.getRecipientType().equals(FeedbackParticipantType.OWN_TEAM_MEMBERS)"},{"lineNumber":91,"author":{"gitId":"-"},"content":" || question.getRecipientType().equals(FeedbackParticipantType.OWN_TEAM_MEMBERS_INCLUDING_SELF)"},{"lineNumber":92,"author":{"gitId":"-"},"content":" || question.getRecipientType().equals(FeedbackParticipantType.GIVER)"},{"lineNumber":93,"author":{"gitId":"-"},"content":" \u0026\u0026 question.getGiverType().equals(FeedbackParticipantType.STUDENTS);"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" if ((isStudentRecipientType || question.getRecipientType().isTeam())"},{"lineNumber":96,"author":{"gitId":"-"},"content":" \u0026\u0026 question.isResponseVisibleTo(FeedbackParticipantType.RECEIVER)) {"},{"lineNumber":97,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":98,"author":{"gitId":"-"},"content":" }"},{"lineNumber":99,"author":{"gitId":"-"},"content":" if (question.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":100,"author":{"gitId":"-"},"content":" || question.isResponseVisibleTo(FeedbackParticipantType.OWN_TEAM_MEMBERS)) {"},{"lineNumber":101,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"-"},"content":" return question.isResponseVisibleTo(FeedbackParticipantType.RECEIVER_TEAM_MEMBERS);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":107,"author":{"gitId":"-"},"content":" * Returns true if the responses of the question are visible to instructors."},{"lineNumber":108,"author":{"gitId":"-"},"content":" */"},{"lineNumber":109,"author":{"gitId":"-"},"content":" public boolean isResponseOfFeedbackQuestionVisibleToInstructor(FeedbackQuestion question) {"},{"lineNumber":110,"author":{"gitId":"-"},"content":" return question.isResponseVisibleTo(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":114,"author":{"gitId":"-"},"content":" * Checks whether a giver has responded a session."},{"lineNumber":115,"author":{"gitId":"-"},"content":" */"},{"lineNumber":116,"author":{"gitId":"-"},"content":" public boolean hasGiverRespondedForSession(String giverIdentifier, List\u003cFeedbackQuestion\u003e questions) {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" assert questions !\u003d null;"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" for (FeedbackQuestion question : questions) {"},{"lineNumber":120,"author":{"gitId":"-"},"content":" boolean hasResponse \u003d question"},{"lineNumber":121,"author":{"gitId":"-"},"content":" .getFeedbackResponses()"},{"lineNumber":122,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":123,"author":{"gitId":"-"},"content":" .anyMatch(response -\u003e response.getGiver().equals(giverIdentifier));"},{"lineNumber":124,"author":{"gitId":"-"},"content":" if (hasResponse) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":126,"author":{"gitId":"-"},"content":" }"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":130,"author":{"gitId":"-"},"content":" }"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":133,"author":{"gitId":"-"},"content":" * Checks whether a giver has responded a session."},{"lineNumber":134,"author":{"gitId":"-"},"content":" */"},{"lineNumber":135,"author":{"gitId":"-"},"content":" public boolean hasGiverRespondedForSession(String giver, String feedbackSessionName, String courseId) {"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" return frDb.hasResponsesFromGiverInSession(giver, feedbackSessionName, courseId);"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":141,"author":{"gitId":"-"},"content":" * Creates a feedback response."},{"lineNumber":142,"author":{"gitId":"-"},"content":" * @return the created response"},{"lineNumber":143,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the response is not valid"},{"lineNumber":144,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the response already exist"},{"lineNumber":145,"author":{"gitId":"-"},"content":" */"},{"lineNumber":146,"author":{"gitId":"-"},"content":" public FeedbackResponse createFeedbackResponse(FeedbackResponse feedbackResponse)"},{"lineNumber":147,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" return frDb.createFeedbackResponse(feedbackResponse);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" }"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":152,"author":{"gitId":"-"},"content":" * Get existing feedback responses from instructor for the given question."},{"lineNumber":153,"author":{"gitId":"-"},"content":" */"},{"lineNumber":154,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesFromInstructorForQuestion("},{"lineNumber":155,"author":{"gitId":"-"},"content":" FeedbackQuestion question, Instructor instructor) {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" return frDb.getFeedbackResponsesFromGiverForQuestion("},{"lineNumber":157,"author":{"gitId":"-"},"content":" question.getId(), instructor.getEmail());"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":161,"author":{"gitId":"-"},"content":" * Get existing feedback responses from student or his team for the given"},{"lineNumber":162,"author":{"gitId":"-"},"content":" * question."},{"lineNumber":163,"author":{"gitId":"-"},"content":" */"},{"lineNumber":164,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesFromStudentOrTeamForQuestion("},{"lineNumber":165,"author":{"gitId":"-"},"content":" FeedbackQuestion question, Student student) {"},{"lineNumber":166,"author":{"gitId":"-"},"content":" if (question.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS) {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" return getFeedbackResponsesFromTeamForQuestion("},{"lineNumber":168,"author":{"gitId":"-"},"content":" question.getId(), question.getCourseId(), student.getTeamName(), null);"},{"lineNumber":169,"author":{"gitId":"-"},"content":" }"},{"lineNumber":170,"author":{"gitId":"-"},"content":" return frDb.getFeedbackResponsesFromGiverForQuestion(question.getId(), student.getEmail());"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" private List\u003cFeedbackResponse\u003e getFeedbackResponsesFromTeamForQuestion("},{"lineNumber":174,"author":{"gitId":"-"},"content":" UUID feedbackQuestionId, String courseId, String teamName, @Nullable SqlCourseRoster courseRoster) {"},{"lineNumber":175,"author":{"gitId":"-"},"content":""},{"lineNumber":176,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponse\u003e responses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":177,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e studentsInTeam \u003d courseRoster \u003d\u003d null"},{"lineNumber":178,"author":{"gitId":"-"},"content":" ? usersLogic.getStudentsForTeam(teamName, courseId) : courseRoster.getTeamToMembersTable().get(teamName);"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" for (Student student : studentsInTeam) {"},{"lineNumber":181,"author":{"gitId":"-"},"content":" responses.addAll(frDb.getFeedbackResponsesFromGiverForQuestion("},{"lineNumber":182,"author":{"gitId":"-"},"content":" feedbackQuestionId, student.getEmail()));"},{"lineNumber":183,"author":{"gitId":"-"},"content":" }"},{"lineNumber":184,"author":{"gitId":"-"},"content":""},{"lineNumber":185,"author":{"gitId":"-"},"content":" responses.addAll(frDb.getFeedbackResponsesFromGiverForQuestion("},{"lineNumber":186,"author":{"gitId":"-"},"content":" feedbackQuestionId, teamName));"},{"lineNumber":187,"author":{"gitId":"-"},"content":" return responses;"},{"lineNumber":188,"author":{"gitId":"-"},"content":" }"},{"lineNumber":189,"author":{"gitId":"-"},"content":""},{"lineNumber":190,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":191,"author":{"gitId":"-"},"content":" * Updates a non-null feedback response by {@link FeedbackResponse}."},{"lineNumber":192,"author":{"gitId":"-"},"content":" *"},{"lineNumber":193,"author":{"gitId":"-"},"content":" * \u003cp\u003eCascade updates its associated feedback response comment"},{"lineNumber":194,"author":{"gitId":"-"},"content":" * (e.g. associated response ID, giverSection and recipientSection)."},{"lineNumber":195,"author":{"gitId":"-"},"content":" *"},{"lineNumber":196,"author":{"gitId":"-"},"content":" * \u003cp\u003eIf the giver/recipient field is changed, the response is updated by recreating the response"},{"lineNumber":197,"author":{"gitId":"-"},"content":" * as question-giver-recipient is the primary key."},{"lineNumber":198,"author":{"gitId":"-"},"content":" *"},{"lineNumber":199,"author":{"gitId":"-"},"content":" * @return updated feedback response"},{"lineNumber":200,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":201,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the comment cannot be found"},{"lineNumber":202,"author":{"gitId":"-"},"content":" */"},{"lineNumber":203,"author":{"gitId":"-"},"content":" public FeedbackResponse updateFeedbackResponseCascade(FeedbackResponse feedbackResponse)"},{"lineNumber":204,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" FeedbackResponse oldResponse \u003d frDb.getFeedbackResponse(feedbackResponse.getId());"},{"lineNumber":207,"author":{"gitId":"-"},"content":" FeedbackResponse newResponse \u003d frDb.updateFeedbackResponse(feedbackResponse);"},{"lineNumber":208,"author":{"gitId":"-"},"content":""},{"lineNumber":209,"author":{"gitId":"-"},"content":" boolean isGiverSectionChanged \u003d !oldResponse.getGiverSection().equals(newResponse.getGiverSection());"},{"lineNumber":210,"author":{"gitId":"-"},"content":" boolean isRecipientSectionChanged \u003d !oldResponse.getRecipientSection().equals(newResponse.getRecipientSection());"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" if (isGiverSectionChanged || isRecipientSectionChanged) {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponseComment\u003e oldResponseComments \u003d"},{"lineNumber":214,"author":{"gitId":"-"},"content":" frcLogic.getFeedbackResponseCommentForResponse(oldResponse.getId());"},{"lineNumber":215,"author":{"gitId":"-"},"content":" for (FeedbackResponseComment oldResponseComment : oldResponseComments) {"},{"lineNumber":216,"author":{"gitId":"-"},"content":" if (isGiverSectionChanged) {"},{"lineNumber":217,"author":{"gitId":"-"},"content":" oldResponseComment.setGiverSection(newResponse.getGiverSection());"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" if (isRecipientSectionChanged) {"},{"lineNumber":221,"author":{"gitId":"-"},"content":" oldResponseComment.setRecipientSection(newResponse.getRecipientSection());"},{"lineNumber":222,"author":{"gitId":"-"},"content":" }"},{"lineNumber":223,"author":{"gitId":"-"},"content":""},{"lineNumber":224,"author":{"gitId":"-"},"content":" frcLogic.updateFeedbackResponseComment(oldResponseComment);"},{"lineNumber":225,"author":{"gitId":"-"},"content":" }"},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"-"},"content":" }"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" return newResponse;"},{"lineNumber":230,"author":{"gitId":"-"},"content":" }"},{"lineNumber":231,"author":{"gitId":"-"},"content":""},{"lineNumber":232,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":233,"author":{"gitId":"-"},"content":" * Deletes a feedback response cascade its associated feedback response comments."},{"lineNumber":234,"author":{"gitId":"-"},"content":" * Implicitly makes use of CascadeType.REMOVE."},{"lineNumber":235,"author":{"gitId":"-"},"content":" */"},{"lineNumber":236,"author":{"gitId":"-"},"content":" public void deleteFeedbackResponsesAndCommentsCascade(FeedbackResponse feedbackResponse) {"},{"lineNumber":237,"author":{"gitId":"-"},"content":" frDb.deleteFeedbackResponse(feedbackResponse);"},{"lineNumber":238,"author":{"gitId":"-"},"content":" }"},{"lineNumber":239,"author":{"gitId":"-"},"content":""},{"lineNumber":240,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":241,"author":{"gitId":"-"},"content":" * Deletes all feedback responses of a question cascade its associated comments."},{"lineNumber":242,"author":{"gitId":"-"},"content":" */"},{"lineNumber":243,"author":{"gitId":"-"},"content":" public void deleteFeedbackResponsesForQuestionCascade(UUID feedbackQuestionId) {"},{"lineNumber":244,"author":{"gitId":"-"},"content":" // delete all responses, comments of the question"},{"lineNumber":245,"author":{"gitId":"-"},"content":" frDb.deleteFeedbackResponsesForQuestionCascade(feedbackQuestionId);"},{"lineNumber":246,"author":{"gitId":"-"},"content":" }"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":249,"author":{"gitId":"-"},"content":" * Checks whether there are responses for a question."},{"lineNumber":250,"author":{"gitId":"-"},"content":" */"},{"lineNumber":251,"author":{"gitId":"-"},"content":" public boolean areThereResponsesForQuestion(UUID questionId) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" return frDb.areThereResponsesForQuestion(questionId);"},{"lineNumber":253,"author":{"gitId":"-"},"content":" }"},{"lineNumber":254,"author":{"gitId":"-"},"content":""},{"lineNumber":255,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":256,"author":{"gitId":"-"},"content":" * Checks whether there are responses for a course."},{"lineNumber":257,"author":{"gitId":"-"},"content":" */"},{"lineNumber":258,"author":{"gitId":"-"},"content":" public boolean hasResponsesForCourse(String courseId) {"},{"lineNumber":259,"author":{"gitId":"-"},"content":" return frDb.hasResponsesForCourse(courseId);"},{"lineNumber":260,"author":{"gitId":"-"},"content":""},{"lineNumber":261,"author":{"gitId":"-"},"content":" }"},{"lineNumber":262,"author":{"gitId":"-"},"content":""},{"lineNumber":263,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":264,"author":{"gitId":"-"},"content":" * Deletes all feedback responses involved an entity, cascade its associated comments."},{"lineNumber":265,"author":{"gitId":"-"},"content":" * Deletion will automatically be cascaded to each feedback response\u0027s comments,"},{"lineNumber":266,"author":{"gitId":"-"},"content":" * handled by Hibernate using the OnDelete annotation."},{"lineNumber":267,"author":{"gitId":"-"},"content":" */"},{"lineNumber":268,"author":{"gitId":"-"},"content":" public void deleteFeedbackResponsesForCourseCascade(String courseId, String entityEmail) {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" // delete responses from the entity"},{"lineNumber":270,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponse\u003e responsesFromStudent \u003d"},{"lineNumber":271,"author":{"gitId":"-"},"content":" getFeedbackResponsesFromGiverForCourse(courseId, entityEmail);"},{"lineNumber":272,"author":{"gitId":"-"},"content":" for (FeedbackResponse response : responsesFromStudent) {"},{"lineNumber":273,"author":{"gitId":"-"},"content":" frDb.deleteFeedbackResponse(response);"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" // delete responses to the entity"},{"lineNumber":277,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponse\u003e responsesToStudent \u003d"},{"lineNumber":278,"author":{"gitId":"-"},"content":" getFeedbackResponsesForRecipientForCourse(courseId, entityEmail);"},{"lineNumber":279,"author":{"gitId":"-"},"content":" for (FeedbackResponse response : responsesToStudent) {"},{"lineNumber":280,"author":{"gitId":"-"},"content":" frDb.deleteFeedbackResponse(response);"},{"lineNumber":281,"author":{"gitId":"-"},"content":" }"},{"lineNumber":282,"author":{"gitId":"-"},"content":" }"},{"lineNumber":283,"author":{"gitId":"-"},"content":""},{"lineNumber":284,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":285,"author":{"gitId":"-"},"content":" * Gets all responses given by a user for a course."},{"lineNumber":286,"author":{"gitId":"-"},"content":" */"},{"lineNumber":287,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesFromGiverForCourse("},{"lineNumber":288,"author":{"gitId":"-"},"content":" String courseId, String giver) {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":290,"author":{"gitId":"-"},"content":" assert giver !\u003d null;"},{"lineNumber":291,"author":{"gitId":"-"},"content":""},{"lineNumber":292,"author":{"gitId":"-"},"content":" return frDb.getFeedbackResponsesFromGiverForCourse(courseId, giver);"},{"lineNumber":293,"author":{"gitId":"-"},"content":" }"},{"lineNumber":294,"author":{"gitId":"-"},"content":""},{"lineNumber":295,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":296,"author":{"gitId":"-"},"content":" * Gets all responses received by a user for a course."},{"lineNumber":297,"author":{"gitId":"-"},"content":" */"},{"lineNumber":298,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForRecipientForCourse("},{"lineNumber":299,"author":{"gitId":"-"},"content":" String courseId, String recipient) {"},{"lineNumber":300,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":301,"author":{"gitId":"-"},"content":" assert recipient !\u003d null;"},{"lineNumber":302,"author":{"gitId":"-"},"content":""},{"lineNumber":303,"author":{"gitId":"-"},"content":" return frDb.getFeedbackResponsesForRecipientForCourse(courseId, recipient);"},{"lineNumber":304,"author":{"gitId":"-"},"content":" }"},{"lineNumber":305,"author":{"gitId":"-"},"content":""},{"lineNumber":306,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":307,"author":{"gitId":"-"},"content":" * Gets all responses given by a user for a question."},{"lineNumber":308,"author":{"gitId":"-"},"content":" */"},{"lineNumber":309,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesFromGiverForQuestion("},{"lineNumber":310,"author":{"gitId":"-"},"content":" UUID feedbackQuestionId, String giver) {"},{"lineNumber":311,"author":{"gitId":"-"},"content":" return frDb.getFeedbackResponsesFromGiverForQuestion(feedbackQuestionId, giver);"},{"lineNumber":312,"author":{"gitId":"-"},"content":" }"},{"lineNumber":313,"author":{"gitId":"-"},"content":""},{"lineNumber":314,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":315,"author":{"gitId":"xenosf"},"content":" * Gets all responses for a question."},{"lineNumber":316,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":317,"author":{"gitId":"domoberzin"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForQuestion(UUID feedbackQuestionId) {"},{"lineNumber":318,"author":{"gitId":"domoberzin"},"content":" return frDb.getResponsesForQuestion(feedbackQuestionId);"},{"lineNumber":319,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":320,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":321,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":322,"author":{"gitId":"-"},"content":" * Updates the relevant responses before the deletion of a student."},{"lineNumber":323,"author":{"gitId":"-"},"content":" * This method takes care of the following:"},{"lineNumber":324,"author":{"gitId":"-"},"content":" * Making existing responses of \u0027rank recipient question\u0027 consistent."},{"lineNumber":325,"author":{"gitId":"-"},"content":" */"},{"lineNumber":326,"author":{"gitId":"-"},"content":" public void updateRankRecipientQuestionResponsesAfterDeletingStudent(String courseId) {"},{"lineNumber":327,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e filteredQuestions \u003d"},{"lineNumber":328,"author":{"gitId":"-"},"content":" fqLogic.getFeedbackQuestionForCourseWithType(courseId, FeedbackQuestionType.RANK_RECIPIENTS);"},{"lineNumber":329,"author":{"gitId":"-"},"content":" SqlCourseRoster roster \u003d new SqlCourseRoster("},{"lineNumber":330,"author":{"gitId":"-"},"content":" usersLogic.getStudentsForCourse(courseId),"},{"lineNumber":331,"author":{"gitId":"-"},"content":" usersLogic.getInstructorsForCourse(courseId));"},{"lineNumber":332,"author":{"gitId":"-"},"content":""},{"lineNumber":333,"author":{"gitId":"-"},"content":" for (FeedbackQuestion question : filteredQuestions) {"},{"lineNumber":334,"author":{"gitId":"-"},"content":" makeRankRecipientQuestionResponsesConsistent(question, roster);"},{"lineNumber":335,"author":{"gitId":"-"},"content":" }"},{"lineNumber":336,"author":{"gitId":"-"},"content":" }"},{"lineNumber":337,"author":{"gitId":"-"},"content":""},{"lineNumber":338,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":339,"author":{"gitId":"-"},"content":" * Makes the rankings by one giver in the response to a \u0027rank recipient question\u0027 consistent, after deleting a"},{"lineNumber":340,"author":{"gitId":"-"},"content":" * student."},{"lineNumber":341,"author":{"gitId":"-"},"content":" * \u003cp\u003e"},{"lineNumber":342,"author":{"gitId":"-"},"content":" * Fails silently if the question type is not \u0027rank recipient question\u0027."},{"lineNumber":343,"author":{"gitId":"-"},"content":" * \u003c/p\u003e"},{"lineNumber":344,"author":{"gitId":"-"},"content":" */"},{"lineNumber":345,"author":{"gitId":"-"},"content":" private void makeRankRecipientQuestionResponsesConsistent("},{"lineNumber":346,"author":{"gitId":"-"},"content":" FeedbackQuestion question, SqlCourseRoster roster) {"},{"lineNumber":347,"author":{"gitId":"mingyuanc"},"content":" assert question.getQuestionDetailsCopy().getQuestionType()"},{"lineNumber":348,"author":{"gitId":"-"},"content":" .equals(FeedbackQuestionType.RANK_RECIPIENTS);"},{"lineNumber":349,"author":{"gitId":"-"},"content":""},{"lineNumber":350,"author":{"gitId":"-"},"content":" FeedbackParticipantType giverType \u003d question.getGiverType();"},{"lineNumber":351,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponse\u003e responses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":352,"author":{"gitId":"-"},"content":" int numberOfRecipients \u003d 0;"},{"lineNumber":353,"author":{"gitId":"-"},"content":""},{"lineNumber":354,"author":{"gitId":"-"},"content":" switch (giverType) {"},{"lineNumber":355,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":356,"author":{"gitId":"-"},"content":" case SELF:"},{"lineNumber":357,"author":{"gitId":"-"},"content":" for (Instructor instructor : roster.getInstructors()) {"},{"lineNumber":358,"author":{"gitId":"-"},"content":" numberOfRecipients \u003d"},{"lineNumber":359,"author":{"gitId":"-"},"content":" fqLogic.getRecipientsOfQuestion(question, instructor, null, roster).size();"},{"lineNumber":360,"author":{"gitId":"-"},"content":" responses \u003d getFeedbackResponsesFromGiverForQuestion(question.getId(), instructor.getEmail());"},{"lineNumber":361,"author":{"gitId":"-"},"content":" }"},{"lineNumber":362,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":363,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":364,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":365,"author":{"gitId":"-"},"content":" Student firstMemberOfTeam;"},{"lineNumber":366,"author":{"gitId":"-"},"content":" String team;"},{"lineNumber":367,"author":{"gitId":"-"},"content":" Map\u003cString, List\u003cStudent\u003e\u003e teams \u003d roster.getTeamToMembersTable();"},{"lineNumber":368,"author":{"gitId":"-"},"content":" for (Map.Entry\u003cString, List\u003cStudent\u003e\u003e entry : teams.entrySet()) {"},{"lineNumber":369,"author":{"gitId":"-"},"content":" team \u003d entry.getKey();"},{"lineNumber":370,"author":{"gitId":"-"},"content":" firstMemberOfTeam \u003d entry.getValue().get(0);"},{"lineNumber":371,"author":{"gitId":"-"},"content":" numberOfRecipients \u003d"},{"lineNumber":372,"author":{"gitId":"-"},"content":" fqLogic.getRecipientsOfQuestion(question, null, firstMemberOfTeam, roster).size();"},{"lineNumber":373,"author":{"gitId":"-"},"content":" responses \u003d"},{"lineNumber":374,"author":{"gitId":"-"},"content":" getFeedbackResponsesFromTeamForQuestion("},{"lineNumber":375,"author":{"gitId":"-"},"content":" question.getId(), question.getCourseId(), team, roster);"},{"lineNumber":376,"author":{"gitId":"-"},"content":" }"},{"lineNumber":377,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":378,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":379,"author":{"gitId":"-"},"content":" for (Student student : roster.getStudents()) {"},{"lineNumber":380,"author":{"gitId":"-"},"content":" numberOfRecipients \u003d"},{"lineNumber":381,"author":{"gitId":"-"},"content":" fqLogic.getRecipientsOfQuestion(question, null, student, roster).size();"},{"lineNumber":382,"author":{"gitId":"-"},"content":" responses \u003d getFeedbackResponsesFromGiverForQuestion(question.getId(), student.getEmail());"},{"lineNumber":383,"author":{"gitId":"-"},"content":" }"},{"lineNumber":384,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":385,"author":{"gitId":"-"},"content":" }"},{"lineNumber":386,"author":{"gitId":"-"},"content":""},{"lineNumber":387,"author":{"gitId":"-"},"content":" updateFeedbackResponsesForRankRecipientQuestions(responses, numberOfRecipients);"},{"lineNumber":388,"author":{"gitId":"-"},"content":" }"},{"lineNumber":389,"author":{"gitId":"-"},"content":""},{"lineNumber":390,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":391,"author":{"gitId":"-"},"content":" * Updates responses for \u0027rank recipient question\u0027, such that the ranks in the responses are consistent."},{"lineNumber":392,"author":{"gitId":"-"},"content":" * @param responses responses to one feedback question, from one giver"},{"lineNumber":393,"author":{"gitId":"-"},"content":" * @param maxRank the maximum rank in each response"},{"lineNumber":394,"author":{"gitId":"-"},"content":" */"},{"lineNumber":395,"author":{"gitId":"-"},"content":" private void updateFeedbackResponsesForRankRecipientQuestions("},{"lineNumber":396,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponse\u003e responses, int maxRank) {"},{"lineNumber":397,"author":{"gitId":"-"},"content":" if (maxRank \u003c\u003d 0) {"},{"lineNumber":398,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":399,"author":{"gitId":"-"},"content":" }"},{"lineNumber":400,"author":{"gitId":"-"},"content":""},{"lineNumber":401,"author":{"gitId":"-"},"content":" FeedbackRankRecipientsResponseDetails responseDetails;"},{"lineNumber":402,"author":{"gitId":"-"},"content":" boolean[] isRankUsed;"},{"lineNumber":403,"author":{"gitId":"-"},"content":" boolean isUpdateNeeded \u003d false;"},{"lineNumber":404,"author":{"gitId":"-"},"content":" int answer;"},{"lineNumber":405,"author":{"gitId":"-"},"content":" int maxUnusedRank \u003d 0;"},{"lineNumber":406,"author":{"gitId":"-"},"content":""},{"lineNumber":407,"author":{"gitId":"-"},"content":" // Checks whether update is needed."},{"lineNumber":408,"author":{"gitId":"-"},"content":" for (FeedbackResponse response : responses) {"},{"lineNumber":409,"author":{"gitId":"-"},"content":" if (!(response instanceof FeedbackRankRecipientsResponse)) {"},{"lineNumber":410,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":411,"author":{"gitId":"-"},"content":" }"},{"lineNumber":412,"author":{"gitId":"-"},"content":" responseDetails \u003d ((FeedbackRankRecipientsResponse) response).getAnswer();"},{"lineNumber":413,"author":{"gitId":"-"},"content":" answer \u003d responseDetails.getAnswer();"},{"lineNumber":414,"author":{"gitId":"-"},"content":" if (answer \u003e maxRank) {"},{"lineNumber":415,"author":{"gitId":"-"},"content":" isUpdateNeeded \u003d true;"},{"lineNumber":416,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":417,"author":{"gitId":"-"},"content":" }"},{"lineNumber":418,"author":{"gitId":"-"},"content":" }"},{"lineNumber":419,"author":{"gitId":"-"},"content":""},{"lineNumber":420,"author":{"gitId":"-"},"content":" // Updates repeatedly, until all responses are consistent."},{"lineNumber":421,"author":{"gitId":"-"},"content":" while (isUpdateNeeded) {"},{"lineNumber":422,"author":{"gitId":"-"},"content":" isUpdateNeeded \u003d false; // will be set to true again once invalid rank appears after update"},{"lineNumber":423,"author":{"gitId":"-"},"content":" isRankUsed \u003d new boolean[maxRank];"},{"lineNumber":424,"author":{"gitId":"-"},"content":""},{"lineNumber":425,"author":{"gitId":"-"},"content":" // Obtains the largest unused rank."},{"lineNumber":426,"author":{"gitId":"-"},"content":" for (FeedbackResponse response : responses) {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" if (!(response instanceof FeedbackRankRecipientsResponse)) {"},{"lineNumber":428,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":429,"author":{"gitId":"-"},"content":" }"},{"lineNumber":430,"author":{"gitId":"-"},"content":" responseDetails \u003d ((FeedbackRankRecipientsResponse) response).getAnswer();"},{"lineNumber":431,"author":{"gitId":"-"},"content":" answer \u003d responseDetails.getAnswer();"},{"lineNumber":432,"author":{"gitId":"-"},"content":" if (answer \u003c\u003d maxRank) {"},{"lineNumber":433,"author":{"gitId":"-"},"content":" isRankUsed[answer - 1] \u003d true;"},{"lineNumber":434,"author":{"gitId":"-"},"content":" }"},{"lineNumber":435,"author":{"gitId":"-"},"content":" }"},{"lineNumber":436,"author":{"gitId":"-"},"content":" for (int i \u003d maxRank - 1; i \u003e\u003d 0; i--) {"},{"lineNumber":437,"author":{"gitId":"-"},"content":" if (!isRankUsed[i]) {"},{"lineNumber":438,"author":{"gitId":"-"},"content":" maxUnusedRank \u003d i + 1;"},{"lineNumber":439,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":440,"author":{"gitId":"-"},"content":" }"},{"lineNumber":441,"author":{"gitId":"-"},"content":" }"},{"lineNumber":442,"author":{"gitId":"-"},"content":" assert maxUnusedRank \u003e 0; // if update is needed, there must be at least one unused rank"},{"lineNumber":443,"author":{"gitId":"-"},"content":""},{"lineNumber":444,"author":{"gitId":"-"},"content":" for (FeedbackResponse response : responses) {"},{"lineNumber":445,"author":{"gitId":"-"},"content":" if (response instanceof FeedbackRankRecipientsResponse) {"},{"lineNumber":446,"author":{"gitId":"-"},"content":" responseDetails \u003d ((FeedbackRankRecipientsResponse) response).getAnswer();"},{"lineNumber":447,"author":{"gitId":"-"},"content":" answer \u003d responseDetails.getAnswer();"},{"lineNumber":448,"author":{"gitId":"-"},"content":" if (answer \u003e maxUnusedRank) {"},{"lineNumber":449,"author":{"gitId":"-"},"content":" answer--;"},{"lineNumber":450,"author":{"gitId":"-"},"content":" responseDetails.setAnswer(answer);"},{"lineNumber":451,"author":{"gitId":"-"},"content":" }"},{"lineNumber":452,"author":{"gitId":"-"},"content":" if (answer \u003e maxRank) {"},{"lineNumber":453,"author":{"gitId":"-"},"content":" isUpdateNeeded \u003d true; // sets the flag to true if the updated rank is still invalid"},{"lineNumber":454,"author":{"gitId":"-"},"content":" }"},{"lineNumber":455,"author":{"gitId":"-"},"content":" }"},{"lineNumber":456,"author":{"gitId":"-"},"content":" }"},{"lineNumber":457,"author":{"gitId":"-"},"content":" }"},{"lineNumber":458,"author":{"gitId":"-"},"content":" }"},{"lineNumber":459,"author":{"gitId":"-"},"content":""},{"lineNumber":460,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":461,"author":{"gitId":"domoberzin"},"content":" * Updates responses for a student when his team changes."},{"lineNumber":462,"author":{"gitId":"domoberzin"},"content":" * \u003cp\u003e"},{"lineNumber":463,"author":{"gitId":"domoberzin"},"content":" * This is done by deleting responses that are no longer relevant to him in his new team."},{"lineNumber":464,"author":{"gitId":"domoberzin"},"content":" * \u003c/p\u003e"},{"lineNumber":465,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":466,"author":{"gitId":"domoberzin"},"content":" public void updateFeedbackResponsesForChangingTeam(Course course, String newEmail, Team newTeam, Team oldTeam)"},{"lineNumber":467,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":468,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":469,"author":{"gitId":"domoberzin"},"content":" FeedbackQuestion qn;"},{"lineNumber":470,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":471,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackResponse\u003e responsesFromUser \u003d"},{"lineNumber":472,"author":{"gitId":"domoberzin"},"content":" getFeedbackResponsesFromGiverForCourse(course.getId(), newEmail);"},{"lineNumber":473,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":474,"author":{"gitId":"domoberzin"},"content":" for (FeedbackResponse response : responsesFromUser) {"},{"lineNumber":475,"author":{"gitId":"domoberzin"},"content":" qn \u003d fqLogic.getFeedbackQuestion(response.getId());"},{"lineNumber":476,"author":{"gitId":"domoberzin"},"content":" if (qn !\u003d null \u0026\u0026 qn.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS) {"},{"lineNumber":477,"author":{"gitId":"domoberzin"},"content":" deleteFeedbackResponsesForQuestionCascade(qn.getId());"},{"lineNumber":478,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":479,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":480,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":481,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackResponse\u003e responsesToUser \u003d"},{"lineNumber":482,"author":{"gitId":"domoberzin"},"content":" getFeedbackResponsesForRecipientForCourse(course.getId(), newEmail);"},{"lineNumber":483,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":484,"author":{"gitId":"domoberzin"},"content":" for (FeedbackResponse response : responsesToUser) {"},{"lineNumber":485,"author":{"gitId":"domoberzin"},"content":" qn \u003d fqLogic.getFeedbackQuestion(response.getId());"},{"lineNumber":486,"author":{"gitId":"domoberzin"},"content":" if (qn !\u003d null \u0026\u0026 qn.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS) {"},{"lineNumber":487,"author":{"gitId":"domoberzin"},"content":" deleteFeedbackResponsesForQuestionCascade(qn.getId());"},{"lineNumber":488,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":489,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":490,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":491,"author":{"gitId":"domoberzin"},"content":" boolean isOldTeamEmpty \u003d usersLogic.getStudentsForTeam(oldTeam.getName(), course.getId()).isEmpty();"},{"lineNumber":492,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":493,"author":{"gitId":"domoberzin"},"content":" if (isOldTeamEmpty) {"},{"lineNumber":494,"author":{"gitId":"domoberzin"},"content":" deleteFeedbackResponsesForCourseCascade(course.getId(), oldTeam.getName());"},{"lineNumber":495,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":496,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":497,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":498,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":499,"author":{"gitId":"domoberzin"},"content":" * Updates responses for a student when his section changes."},{"lineNumber":500,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":501,"author":{"gitId":"domoberzin"},"content":" public void updateFeedbackResponsesForChangingSection(Course course, String newEmail, Section newSection)"},{"lineNumber":502,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":503,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":504,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackResponse\u003e responsesFromUser \u003d"},{"lineNumber":505,"author":{"gitId":"domoberzin"},"content":" getFeedbackResponsesFromGiverForCourse(course.getId(), newEmail);"},{"lineNumber":506,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":507,"author":{"gitId":"domoberzin"},"content":" for (FeedbackResponse response : responsesFromUser) {"},{"lineNumber":508,"author":{"gitId":"domoberzin"},"content":" response.setGiverSection(newSection);"},{"lineNumber":509,"author":{"gitId":"domoberzin"},"content":" frDb.updateFeedbackResponse(response);"},{"lineNumber":510,"author":{"gitId":"domoberzin"},"content":" frcLogic.updateFeedbackResponseCommentsForResponse(response);"},{"lineNumber":511,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":512,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":513,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackResponse\u003e responsesToUser \u003d"},{"lineNumber":514,"author":{"gitId":"domoberzin"},"content":" getFeedbackResponsesForRecipientForCourse(course.getId(), newEmail);"},{"lineNumber":515,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":516,"author":{"gitId":"domoberzin"},"content":" for (FeedbackResponse response : responsesToUser) {"},{"lineNumber":517,"author":{"gitId":"domoberzin"},"content":" response.setRecipientSection(newSection);"},{"lineNumber":518,"author":{"gitId":"domoberzin"},"content":" frDb.updateFeedbackResponse(response);"},{"lineNumber":519,"author":{"gitId":"domoberzin"},"content":" frcLogic.updateFeedbackResponseCommentsForResponse(response);"},{"lineNumber":520,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":521,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":522,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":523,"author":{"gitId":"marquestye"},"content":" /**"},{"lineNumber":524,"author":{"gitId":"marquestye"},"content":" * Updates a student\u0027s email in their given/received responses."},{"lineNumber":525,"author":{"gitId":"marquestye"},"content":" */"},{"lineNumber":526,"author":{"gitId":"marquestye"},"content":" public void updateFeedbackResponsesForChangingEmail(String courseId, String oldEmail, String newEmail)"},{"lineNumber":527,"author":{"gitId":"marquestye"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":528,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":529,"author":{"gitId":"marquestye"},"content":" List\u003cFeedbackResponse\u003e responsesFromUser \u003d"},{"lineNumber":530,"author":{"gitId":"marquestye"},"content":" getFeedbackResponsesFromGiverForCourse(courseId, oldEmail);"},{"lineNumber":531,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":532,"author":{"gitId":"marquestye"},"content":" for (FeedbackResponse response : responsesFromUser) {"},{"lineNumber":533,"author":{"gitId":"marquestye"},"content":" response.setGiver(newEmail);"},{"lineNumber":534,"author":{"gitId":"marquestye"},"content":" frDb.updateFeedbackResponse(response);"},{"lineNumber":535,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":536,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":537,"author":{"gitId":"marquestye"},"content":" List\u003cFeedbackResponse\u003e responsesToUser \u003d"},{"lineNumber":538,"author":{"gitId":"marquestye"},"content":" getFeedbackResponsesForRecipientForCourse(courseId, oldEmail);"},{"lineNumber":539,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":540,"author":{"gitId":"marquestye"},"content":" for (FeedbackResponse response : responsesToUser) {"},{"lineNumber":541,"author":{"gitId":"marquestye"},"content":" response.setRecipient(newEmail);"},{"lineNumber":542,"author":{"gitId":"marquestye"},"content":" frDb.updateFeedbackResponse(response);"},{"lineNumber":543,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":544,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":545,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":546,"author":{"gitId":"xenosf"},"content":" private List\u003cFeedbackQuestion\u003e getQuestionsForSession("},{"lineNumber":547,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession, @Nullable UUID questionId) {"},{"lineNumber":548,"author":{"gitId":"xenosf"},"content":" if (questionId \u003d\u003d null) {"},{"lineNumber":549,"author":{"gitId":"xenosf"},"content":" return fqLogic.getFeedbackQuestionsForSession(feedbackSession);"},{"lineNumber":550,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":551,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion fq \u003d fqLogic.getFeedbackQuestion(questionId);"},{"lineNumber":552,"author":{"gitId":"xenosf"},"content":" return fq \u003d\u003d null ? Collections.emptyList() : Collections.singletonList(fq);"},{"lineNumber":553,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":554,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":555,"author":{"gitId":"xenosf"},"content":" private SqlSessionResultsBundle buildResultsBundle("},{"lineNumber":556,"author":{"gitId":"xenosf"},"content":" boolean isCourseWide, FeedbackSession feedbackSession, String courseId, String sectionName, UUID questionId,"},{"lineNumber":557,"author":{"gitId":"xenosf"},"content":" boolean isInstructor, String userEmail, Instructor instructor, Student student,"},{"lineNumber":558,"author":{"gitId":"xenosf"},"content":" SqlCourseRoster roster, List\u003cFeedbackQuestion\u003e allQuestions,"},{"lineNumber":559,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e allResponses, boolean isPreviewResults) {"},{"lineNumber":560,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":561,"author":{"gitId":"xenosf"},"content":" Set\u003cFeedbackQuestion\u003e questionsNotVisibleToInstructors \u003d new HashSet\u003c\u003e();"},{"lineNumber":562,"author":{"gitId":"xenosf"},"content":" for (FeedbackQuestion qn : allQuestions) {"},{"lineNumber":563,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":564,"author":{"gitId":"xenosf"},"content":" // set questions that should not be visible to instructors if results are being previewed"},{"lineNumber":565,"author":{"gitId":"xenosf"},"content":" if (isPreviewResults \u0026\u0026 !checkCanInstructorsSeeQuestion(qn)) {"},{"lineNumber":566,"author":{"gitId":"xenosf"},"content":" questionsNotVisibleToInstructors.add(qn);"},{"lineNumber":567,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":568,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":569,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":570,"author":{"gitId":"xenosf"},"content":" // load comment(s)"},{"lineNumber":571,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e allComments;"},{"lineNumber":572,"author":{"gitId":"xenosf"},"content":" if (questionId \u003d\u003d null) {"},{"lineNumber":573,"author":{"gitId":"xenosf"},"content":" allComments \u003d frcLogic.getFeedbackResponseCommentForSessionInSection("},{"lineNumber":574,"author":{"gitId":"xenosf"},"content":" courseId, feedbackSession.getName(), sectionName);"},{"lineNumber":575,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":576,"author":{"gitId":"xenosf"},"content":" allComments \u003d frcLogic.getFeedbackResponseCommentForQuestionInSection(questionId, sectionName);"},{"lineNumber":577,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":578,"author":{"gitId":"xenosf"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":579,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":580,"author":{"gitId":"xenosf"},"content":" // related questions, responses, and comment"},{"lineNumber":581,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackQuestion\u003e relatedQuestions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":582,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e relatedResponses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":583,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackResponse, List\u003cFeedbackResponseComment\u003e\u003e relatedCommentsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":584,"author":{"gitId":"xenosf"},"content":" Set\u003cFeedbackQuestion\u003e relatedQuestionsNotVisibleForPreviewSet \u003d new HashSet\u003c\u003e();"},{"lineNumber":585,"author":{"gitId":"xenosf"},"content":" Set\u003cFeedbackQuestion\u003e relatedQuestionsWithCommentNotVisibleForPreview \u003d new HashSet\u003c\u003e();"},{"lineNumber":586,"author":{"gitId":"xenosf"},"content":" if (isCourseWide) {"},{"lineNumber":587,"author":{"gitId":"xenosf"},"content":" // all questions are related questions when viewing course-wide result"},{"lineNumber":588,"author":{"gitId":"xenosf"},"content":" for (FeedbackQuestion qn : allQuestions) {"},{"lineNumber":589,"author":{"gitId":"xenosf"},"content":" relatedQuestions.add(qn);"},{"lineNumber":590,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":591,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":592,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":593,"author":{"gitId":"xenosf"},"content":" Set\u003cString\u003e studentsEmailInTeam \u003d new HashSet\u003c\u003e();"},{"lineNumber":594,"author":{"gitId":"xenosf"},"content":" if (student !\u003d null) {"},{"lineNumber":595,"author":{"gitId":"xenosf"},"content":" for (Student studentInTeam"},{"lineNumber":596,"author":{"gitId":"mingyuanc"},"content":" : roster.getTeamToMembersTable().getOrDefault(student.getTeam().getName(), Collections.emptyList())) {"},{"lineNumber":597,"author":{"gitId":"xenosf"},"content":" studentsEmailInTeam.add(studentInTeam.getEmail());"},{"lineNumber":598,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":599,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":600,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":601,"author":{"gitId":"xenosf"},"content":" // visibility table for each response and comment"},{"lineNumber":602,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackResponse, Boolean\u003e responseGiverVisibilityTable \u003d new HashMap\u003c\u003e();"},{"lineNumber":603,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackResponse, Boolean\u003e responseRecipientVisibilityTable \u003d new HashMap\u003c\u003e();"},{"lineNumber":604,"author":{"gitId":"xenosf"},"content":" Map\u003cLong, Boolean\u003e commentVisibilityTable \u003d new HashMap\u003c\u003e();"},{"lineNumber":605,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":606,"author":{"gitId":"xenosf"},"content":" // build response"},{"lineNumber":607,"author":{"gitId":"xenosf"},"content":" for (FeedbackResponse response : allResponses) {"},{"lineNumber":608,"author":{"gitId":"xenosf"},"content":" if (isPreviewResults"},{"lineNumber":609,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 relatedQuestionsNotVisibleForPreviewSet.contains(response.getFeedbackQuestion())) {"},{"lineNumber":610,"author":{"gitId":"xenosf"},"content":" // corresponding question\u0027s responses will not be shown to previewer, ignore the response"},{"lineNumber":611,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":612,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":613,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion correspondingQuestion \u003d response.getFeedbackQuestion();"},{"lineNumber":614,"author":{"gitId":"xenosf"},"content":" if (correspondingQuestion \u003d\u003d null) {"},{"lineNumber":615,"author":{"gitId":"xenosf"},"content":" // orphan response without corresponding question, ignore it"},{"lineNumber":616,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":617,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":618,"author":{"gitId":"xenosf"},"content":" // check visibility of response"},{"lineNumber":619,"author":{"gitId":"xenosf"},"content":" boolean isVisibleResponse \u003d isResponseVisibleForUser("},{"lineNumber":620,"author":{"gitId":"xenosf"},"content":" userEmail, isInstructor, student, studentsEmailInTeam, response, correspondingQuestion, instructor);"},{"lineNumber":621,"author":{"gitId":"xenosf"},"content":" if (!isVisibleResponse) {"},{"lineNumber":622,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":623,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":624,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":625,"author":{"gitId":"xenosf"},"content":" // if previewing results and corresponding question should not be visible to instructors,"},{"lineNumber":626,"author":{"gitId":"xenosf"},"content":" // note down the question and do not add the response"},{"lineNumber":627,"author":{"gitId":"xenosf"},"content":" if (isPreviewResults \u0026\u0026 questionsNotVisibleToInstructors.contains(response.getFeedbackQuestion())) {"},{"lineNumber":628,"author":{"gitId":"xenosf"},"content":" relatedQuestionsNotVisibleForPreviewSet.add(response.getFeedbackQuestion());"},{"lineNumber":629,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":630,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":631,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":632,"author":{"gitId":"xenosf"},"content":" // if there are viewable responses, the corresponding question becomes related"},{"lineNumber":633,"author":{"gitId":"xenosf"},"content":" relatedQuestions.add(response.getFeedbackQuestion());"},{"lineNumber":634,"author":{"gitId":"xenosf"},"content":" relatedResponses.add(response);"},{"lineNumber":635,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":636,"author":{"gitId":"xenosf"},"content":" // generate giver/recipient name visibility table"},{"lineNumber":637,"author":{"gitId":"xenosf"},"content":" responseGiverVisibilityTable.put(response,"},{"lineNumber":638,"author":{"gitId":"xenosf"},"content":" isNameVisibleToUser(correspondingQuestion, response, userEmail, isInstructor, true, roster));"},{"lineNumber":639,"author":{"gitId":"xenosf"},"content":" responseRecipientVisibilityTable.put(response,"},{"lineNumber":640,"author":{"gitId":"xenosf"},"content":" isNameVisibleToUser(correspondingQuestion, response, userEmail, isInstructor, false, roster));"},{"lineNumber":641,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":642,"author":{"gitId":"xenosf"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":643,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":644,"author":{"gitId":"xenosf"},"content":" // build comment"},{"lineNumber":645,"author":{"gitId":"xenosf"},"content":" for (FeedbackResponseComment frc : allComments) {"},{"lineNumber":646,"author":{"gitId":"xenosf"},"content":" FeedbackResponse relatedResponse \u003d frc.getFeedbackResponse();"},{"lineNumber":647,"author":{"gitId":"xenosf"},"content":" // the comment needs to be relevant to the question and response"},{"lineNumber":648,"author":{"gitId":"xenosf"},"content":" if (relatedResponse \u003d\u003d null) {"},{"lineNumber":649,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":650,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":651,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion relatedQuestion \u003d relatedResponse.getFeedbackQuestion();"},{"lineNumber":652,"author":{"gitId":"xenosf"},"content":" if (relatedQuestion \u003d\u003d null) {"},{"lineNumber":653,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":654,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":655,"author":{"gitId":"xenosf"},"content":" // check visibility of comment"},{"lineNumber":656,"author":{"gitId":"xenosf"},"content":" boolean isVisibleResponseComment \u003d frcLogic.checkIsResponseCommentVisibleForUser("},{"lineNumber":657,"author":{"gitId":"xenosf"},"content":" userEmail, isInstructor, student, studentsEmailInTeam, relatedResponse, relatedQuestion, frc);"},{"lineNumber":658,"author":{"gitId":"xenosf"},"content":" if (!isVisibleResponseComment) {"},{"lineNumber":659,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":660,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":661,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":662,"author":{"gitId":"xenosf"},"content":" // if previewing results and the comment should not be visible to instructors,"},{"lineNumber":663,"author":{"gitId":"xenosf"},"content":" // note down the corresponding question and do not add the comment"},{"lineNumber":664,"author":{"gitId":"xenosf"},"content":" if (isPreviewResults \u0026\u0026 !checkCanInstructorsSeeComment(frc)) {"},{"lineNumber":665,"author":{"gitId":"xenosf"},"content":" relatedQuestionsWithCommentNotVisibleForPreview.add(frc.getFeedbackResponse().getFeedbackQuestion());"},{"lineNumber":666,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":667,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":668,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":669,"author":{"gitId":"xenosf"},"content":" relatedCommentsMap.computeIfAbsent(relatedResponse, key -\u003e new ArrayList\u003c\u003e()).add(frc);"},{"lineNumber":670,"author":{"gitId":"xenosf"},"content":" // generate comment giver name visibility table"},{"lineNumber":671,"author":{"gitId":"xenosf"},"content":" commentVisibilityTable.put(frc.getId(),"},{"lineNumber":672,"author":{"gitId":"xenosf"},"content":" frcLogic.checkIsNameVisibleToUser(frc, relatedResponse, userEmail, roster));"},{"lineNumber":673,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":674,"author":{"gitId":"xenosf"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":675,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":676,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e existingResponses \u003d new ArrayList\u003c\u003e(relatedResponses);"},{"lineNumber":677,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e missingResponses \u003d Collections.emptyList();"},{"lineNumber":678,"author":{"gitId":"xenosf"},"content":" if (isCourseWide) {"},{"lineNumber":679,"author":{"gitId":"xenosf"},"content":" missingResponses \u003d buildMissingResponses("},{"lineNumber":680,"author":{"gitId":"xenosf"},"content":" instructor, responseGiverVisibilityTable, responseRecipientVisibilityTable, relatedQuestions,"},{"lineNumber":681,"author":{"gitId":"xenosf"},"content":" existingResponses, roster, sectionName);"},{"lineNumber":682,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":683,"author":{"gitId":"xenosf"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":684,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":685,"author":{"gitId":"xenosf"},"content":" return new SqlSessionResultsBundle(relatedQuestions, relatedQuestionsNotVisibleForPreviewSet,"},{"lineNumber":686,"author":{"gitId":"xenosf"},"content":" relatedQuestionsWithCommentNotVisibleForPreview, existingResponses, missingResponses,"},{"lineNumber":687,"author":{"gitId":"xenosf"},"content":" responseGiverVisibilityTable, responseRecipientVisibilityTable, relatedCommentsMap,"},{"lineNumber":688,"author":{"gitId":"xenosf"},"content":" commentVisibilityTable, roster);"},{"lineNumber":689,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":690,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":691,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":692,"author":{"gitId":"xenosf"},"content":" * Gets the session result for a feedback session."},{"lineNumber":693,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":694,"author":{"gitId":"xenosf"},"content":" * @param feedbackSession the feedback session"},{"lineNumber":695,"author":{"gitId":"xenosf"},"content":" * @param courseId the ID of the course"},{"lineNumber":696,"author":{"gitId":"xenosf"},"content":" * @param instructorEmail the instructor viewing the feedback session"},{"lineNumber":697,"author":{"gitId":"xenosf"},"content":" * @param questionId if not null, will only return partial bundle for the question"},{"lineNumber":698,"author":{"gitId":"xenosf"},"content":" * @param sectionName if not null, will only return partial bundle for the section"},{"lineNumber":699,"author":{"gitId":"xenosf"},"content":" * @param fetchType if not null, will fetch responses by giver, receiver sections, or both"},{"lineNumber":700,"author":{"gitId":"xenosf"},"content":" * @return the session result bundle"},{"lineNumber":701,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":702,"author":{"gitId":"xenosf"},"content":" public SqlSessionResultsBundle getSessionResultsForCourse("},{"lineNumber":703,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession, String courseId, String instructorEmail,"},{"lineNumber":704,"author":{"gitId":"xenosf"},"content":" @Nullable UUID questionId, @Nullable String sectionName, @Nullable FeedbackResultFetchType fetchType) {"},{"lineNumber":705,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":706,"author":{"gitId":"xenosf"},"content":" SqlCourseRoster roster \u003d new SqlCourseRoster("},{"lineNumber":707,"author":{"gitId":"xenosf"},"content":" usersLogic.getStudentsForCourse(courseId),"},{"lineNumber":708,"author":{"gitId":"xenosf"},"content":" usersLogic.getInstructorsForCourse(courseId));"},{"lineNumber":709,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":710,"author":{"gitId":"xenosf"},"content":" // load question(s)"},{"lineNumber":711,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackQuestion\u003e allQuestions \u003d getQuestionsForSession(feedbackSession, questionId);"},{"lineNumber":712,"author":{"gitId":"xenosf"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":713,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":714,"author":{"gitId":"xenosf"},"content":" // load response(s)"},{"lineNumber":715,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e allResponses;"},{"lineNumber":716,"author":{"gitId":"xenosf"},"content":" // load all response for instructors and passively filter them later"},{"lineNumber":717,"author":{"gitId":"xenosf"},"content":" if (questionId \u003d\u003d null) {"},{"lineNumber":718,"author":{"gitId":"xenosf"},"content":" allResponses \u003d getFeedbackResponsesForSessionInSection(feedbackSession, courseId, sectionName, fetchType);"},{"lineNumber":719,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":720,"author":{"gitId":"xenosf"},"content":" allResponses \u003d getFeedbackResponsesForQuestionInSection(questionId, sectionName, fetchType);"},{"lineNumber":721,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":722,"author":{"gitId":"xenosf"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":723,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":724,"author":{"gitId":"xenosf"},"content":" // consider the current viewing user"},{"lineNumber":725,"author":{"gitId":"xenosf"},"content":" Instructor instructor \u003d usersLogic.getInstructorForEmail(courseId, instructorEmail);"},{"lineNumber":726,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":727,"author":{"gitId":"xenosf"},"content":" return buildResultsBundle(true, feedbackSession, courseId, sectionName, questionId, true, instructorEmail,"},{"lineNumber":728,"author":{"gitId":"xenosf"},"content":" instructor, null, roster, allQuestions, allResponses, false);"},{"lineNumber":729,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":730,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":731,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":732,"author":{"gitId":"xenosf"},"content":" * Gets the session result for a feedback session for the given user."},{"lineNumber":733,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":734,"author":{"gitId":"xenosf"},"content":" * @param feedbackSession the feedback session"},{"lineNumber":735,"author":{"gitId":"xenosf"},"content":" * @param courseId the ID of the course"},{"lineNumber":736,"author":{"gitId":"xenosf"},"content":" * @param userEmail the user viewing the feedback session"},{"lineNumber":737,"author":{"gitId":"xenosf"},"content":" * @param isInstructor true if the user is an instructor"},{"lineNumber":738,"author":{"gitId":"xenosf"},"content":" * @param questionId if not null, will only return partial bundle for the question"},{"lineNumber":739,"author":{"gitId":"xenosf"},"content":" * @param isPreviewResults true if getting session results for preview purpose"},{"lineNumber":740,"author":{"gitId":"xenosf"},"content":" * @return the session result bundle"},{"lineNumber":741,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":742,"author":{"gitId":"xenosf"},"content":" public SqlSessionResultsBundle getSessionResultsForUser("},{"lineNumber":743,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession, String courseId, String userEmail, boolean isInstructor,"},{"lineNumber":744,"author":{"gitId":"xenosf"},"content":" @Nullable UUID questionId, boolean isPreviewResults) {"},{"lineNumber":745,"author":{"gitId":"xenosf"},"content":" SqlCourseRoster roster \u003d new SqlCourseRoster("},{"lineNumber":746,"author":{"gitId":"xenosf"},"content":" usersLogic.getStudentsForCourse(courseId),"},{"lineNumber":747,"author":{"gitId":"xenosf"},"content":" usersLogic.getInstructorsForCourse(courseId));"},{"lineNumber":748,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":749,"author":{"gitId":"xenosf"},"content":" // load question(s)"},{"lineNumber":750,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackQuestion\u003e allQuestions \u003d getQuestionsForSession(feedbackSession, questionId);"},{"lineNumber":751,"author":{"gitId":"xenosf"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":752,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":753,"author":{"gitId":"xenosf"},"content":" // load response(s)"},{"lineNumber":754,"author":{"gitId":"xenosf"},"content":" Student student \u003d isInstructor ? null : usersLogic.getStudentForEmail(courseId, userEmail);"},{"lineNumber":755,"author":{"gitId":"xenosf"},"content":" Instructor instructor \u003d isInstructor ? usersLogic.getInstructorForEmail(courseId, userEmail) : null;"},{"lineNumber":756,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e allResponses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":757,"author":{"gitId":"xenosf"},"content":" for (FeedbackQuestion question : allQuestions) {"},{"lineNumber":758,"author":{"gitId":"xenosf"},"content":" // load viewable responses for students/instructors proactively"},{"lineNumber":759,"author":{"gitId":"xenosf"},"content":" // this is cost-effective as in most of time responses for the whole session will not be viewable to individuals"},{"lineNumber":760,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e viewableResponses \u003d isInstructor"},{"lineNumber":761,"author":{"gitId":"xenosf"},"content":" ? getFeedbackResponsesToOrFromInstructorForQuestion(question, instructor)"},{"lineNumber":762,"author":{"gitId":"xenosf"},"content":" : getViewableFeedbackResponsesForStudentForQuestion(question, student, roster);"},{"lineNumber":763,"author":{"gitId":"xenosf"},"content":" allResponses.addAll(viewableResponses);"},{"lineNumber":764,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":765,"author":{"gitId":"xenosf"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":766,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":767,"author":{"gitId":"xenosf"},"content":" return buildResultsBundle(false, feedbackSession, courseId, null, questionId, isInstructor, userEmail,"},{"lineNumber":768,"author":{"gitId":"xenosf"},"content":" instructor, student, roster, allQuestions, allResponses, isPreviewResults);"},{"lineNumber":769,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":770,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":771,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":772,"author":{"gitId":"xenosf"},"content":" * Builds viewable missing responses for the session for instructor."},{"lineNumber":773,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":774,"author":{"gitId":"xenosf"},"content":" * @param instructor the instructor"},{"lineNumber":775,"author":{"gitId":"xenosf"},"content":" * @param responseGiverVisibilityTable"},{"lineNumber":776,"author":{"gitId":"xenosf"},"content":" * the giver visibility table which will be updated with the visibility of missing responses"},{"lineNumber":777,"author":{"gitId":"xenosf"},"content":" * @param responseRecipientVisibilityTable"},{"lineNumber":778,"author":{"gitId":"xenosf"},"content":" * the recipient visibility table which will be updated with the visibility of missing responses"},{"lineNumber":779,"author":{"gitId":"xenosf"},"content":" * @param relatedQuestions the relevant questions"},{"lineNumber":780,"author":{"gitId":"xenosf"},"content":" * @param existingResponses existing responses"},{"lineNumber":781,"author":{"gitId":"xenosf"},"content":" * @param courseRoster the course roster"},{"lineNumber":782,"author":{"gitId":"xenosf"},"content":" * @param sectionName if not null, will only build missing responses for the section"},{"lineNumber":783,"author":{"gitId":"xenosf"},"content":" * @return a list of missing responses for the session."},{"lineNumber":784,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":785,"author":{"gitId":"xenosf"},"content":" private List\u003cFeedbackResponse\u003e buildMissingResponses("},{"lineNumber":786,"author":{"gitId":"xenosf"},"content":" Instructor instructor, Map\u003cFeedbackResponse, Boolean\u003e responseGiverVisibilityTable,"},{"lineNumber":787,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackResponse, Boolean\u003e responseRecipientVisibilityTable, List\u003cFeedbackQuestion\u003e relatedQuestions,"},{"lineNumber":788,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e existingResponses, SqlCourseRoster courseRoster, @Nullable String sectionName) {"},{"lineNumber":789,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":790,"author":{"gitId":"xenosf"},"content":" // first get all possible giver recipient pairs"},{"lineNumber":791,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackQuestion, Map\u003cString, Set\u003cString\u003e\u003e\u003e questionCompleteGiverRecipientMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":792,"author":{"gitId":"xenosf"},"content":" for (FeedbackQuestion feedbackQuestion : relatedQuestions) {"},{"lineNumber":793,"author":{"gitId":"xenosf"},"content":" if (feedbackQuestion.getQuestionDetailsCopy().shouldGenerateMissingResponses(feedbackQuestion)) {"},{"lineNumber":794,"author":{"gitId":"xenosf"},"content":" questionCompleteGiverRecipientMap.put(feedbackQuestion,"},{"lineNumber":795,"author":{"gitId":"xenosf"},"content":" fqLogic.buildCompleteGiverRecipientMap(feedbackQuestion, courseRoster));"},{"lineNumber":796,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":797,"author":{"gitId":"xenosf"},"content":" questionCompleteGiverRecipientMap.put(feedbackQuestion, new HashMap\u003c\u003e());"},{"lineNumber":798,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":799,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":800,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":801,"author":{"gitId":"xenosf"},"content":" // remove the existing responses in those pairs"},{"lineNumber":802,"author":{"gitId":"xenosf"},"content":" for (FeedbackResponse existingResponse : existingResponses) {"},{"lineNumber":803,"author":{"gitId":"xenosf"},"content":" Map\u003cString, Set\u003cString\u003e\u003e currGiverRecipientMap \u003d"},{"lineNumber":804,"author":{"gitId":"xenosf"},"content":" questionCompleteGiverRecipientMap.get(existingResponse.getFeedbackQuestion());"},{"lineNumber":805,"author":{"gitId":"xenosf"},"content":" if (!currGiverRecipientMap.containsKey(existingResponse.getGiver())) {"},{"lineNumber":806,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":807,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":808,"author":{"gitId":"xenosf"},"content":" currGiverRecipientMap.get(existingResponse.getGiver()).remove(existingResponse.getRecipient());"},{"lineNumber":809,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":810,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":811,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e missingResponses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":812,"author":{"gitId":"xenosf"},"content":" // build dummy responses"},{"lineNumber":813,"author":{"gitId":"xenosf"},"content":" for (Map.Entry\u003cFeedbackQuestion, Map\u003cString, Set\u003cString\u003e\u003e\u003e currGiverRecipientMapEntry"},{"lineNumber":814,"author":{"gitId":"xenosf"},"content":" : questionCompleteGiverRecipientMap.entrySet()) {"},{"lineNumber":815,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion correspondingQuestion \u003d currGiverRecipientMapEntry.getKey();"},{"lineNumber":816,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":817,"author":{"gitId":"xenosf"},"content":" for (Map.Entry\u003cString, Set\u003cString\u003e\u003e giverRecipientEntry"},{"lineNumber":818,"author":{"gitId":"xenosf"},"content":" : currGiverRecipientMapEntry.getValue().entrySet()) {"},{"lineNumber":819,"author":{"gitId":"xenosf"},"content":" // giver"},{"lineNumber":820,"author":{"gitId":"xenosf"},"content":" String giverIdentifier \u003d giverRecipientEntry.getKey();"},{"lineNumber":821,"author":{"gitId":"xenosf"},"content":" SqlCourseRoster.ParticipantInfo giverInfo \u003d courseRoster.getInfoForIdentifier(giverIdentifier);"},{"lineNumber":822,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":823,"author":{"gitId":"xenosf"},"content":" for (String recipientIdentifier : giverRecipientEntry.getValue()) {"},{"lineNumber":824,"author":{"gitId":"xenosf"},"content":" // recipient"},{"lineNumber":825,"author":{"gitId":"xenosf"},"content":" SqlCourseRoster.ParticipantInfo recipientInfo \u003d courseRoster.getInfoForIdentifier(recipientIdentifier);"},{"lineNumber":826,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":827,"author":{"gitId":"xenosf"},"content":" // skip responses not in current section"},{"lineNumber":828,"author":{"gitId":"xenosf"},"content":" if (sectionName !\u003d null"},{"lineNumber":829,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 !giverInfo.getSectionName().equals(sectionName)"},{"lineNumber":830,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 !recipientInfo.getSectionName().equals(sectionName)) {"},{"lineNumber":831,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":832,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":833,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":834,"author":{"gitId":"xenosf"},"content":" FeedbackResponse missingResponse \u003d new FeedbackMissingResponse("},{"lineNumber":835,"author":{"gitId":"xenosf"},"content":" correspondingQuestion,"},{"lineNumber":836,"author":{"gitId":"xenosf"},"content":" giverIdentifier, giverInfo.getSectionName(),"},{"lineNumber":837,"author":{"gitId":"xenosf"},"content":" recipientIdentifier, recipientInfo.getSectionName());"},{"lineNumber":838,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":839,"author":{"gitId":"xenosf"},"content":" // check visibility of the missing response"},{"lineNumber":840,"author":{"gitId":"xenosf"},"content":" boolean isVisibleResponse \u003d isResponseVisibleForUser("},{"lineNumber":841,"author":{"gitId":"xenosf"},"content":" instructor.getEmail(), true, null, Collections.emptySet(),"},{"lineNumber":842,"author":{"gitId":"xenosf"},"content":" missingResponse, correspondingQuestion, instructor);"},{"lineNumber":843,"author":{"gitId":"xenosf"},"content":" if (!isVisibleResponse) {"},{"lineNumber":844,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":845,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":846,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":847,"author":{"gitId":"xenosf"},"content":" // generate giver/recipient name visibility table"},{"lineNumber":848,"author":{"gitId":"xenosf"},"content":" responseGiverVisibilityTable.put(missingResponse,"},{"lineNumber":849,"author":{"gitId":"xenosf"},"content":" isNameVisibleToUser(correspondingQuestion, missingResponse,"},{"lineNumber":850,"author":{"gitId":"xenosf"},"content":" instructor.getEmail(), true, true, courseRoster));"},{"lineNumber":851,"author":{"gitId":"xenosf"},"content":" responseRecipientVisibilityTable.put(missingResponse,"},{"lineNumber":852,"author":{"gitId":"xenosf"},"content":" isNameVisibleToUser(correspondingQuestion, missingResponse,"},{"lineNumber":853,"author":{"gitId":"xenosf"},"content":" instructor.getEmail(), true, false, courseRoster));"},{"lineNumber":854,"author":{"gitId":"xenosf"},"content":" missingResponses.add(missingResponse);"},{"lineNumber":855,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":856,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":857,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":858,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":859,"author":{"gitId":"xenosf"},"content":" return missingResponses;"},{"lineNumber":860,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":861,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":862,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":863,"author":{"gitId":"xenosf"},"content":" * Checks whether the giver name of a response is visible to an user."},{"lineNumber":864,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":865,"author":{"gitId":"xenosf"},"content":" public boolean isNameVisibleToUser("},{"lineNumber":866,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question,"},{"lineNumber":867,"author":{"gitId":"xenosf"},"content":" FeedbackResponse response,"},{"lineNumber":868,"author":{"gitId":"xenosf"},"content":" String userEmail,"},{"lineNumber":869,"author":{"gitId":"xenosf"},"content":" boolean isInstructor, boolean isGiverName, SqlCourseRoster roster) {"},{"lineNumber":870,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":871,"author":{"gitId":"xenosf"},"content":" if (question \u003d\u003d null) {"},{"lineNumber":872,"author":{"gitId":"xenosf"},"content":" return false;"},{"lineNumber":873,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":874,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":875,"author":{"gitId":"xenosf"},"content":" // Early return if user is giver"},{"lineNumber":876,"author":{"gitId":"xenosf"},"content":" if (question.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS) {"},{"lineNumber":877,"author":{"gitId":"xenosf"},"content":" // if response is given by team, then anyone in the team can see the response"},{"lineNumber":878,"author":{"gitId":"xenosf"},"content":" if (roster.isStudentInTeam(userEmail, response.getGiver())) {"},{"lineNumber":879,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":880,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":881,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":882,"author":{"gitId":"xenosf"},"content":" if (response.getGiver().equals(userEmail)) {"},{"lineNumber":883,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":884,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":885,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":886,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":887,"author":{"gitId":"xenosf"},"content":" return isFeedbackParticipantNameVisibleToUser(question, response,"},{"lineNumber":888,"author":{"gitId":"xenosf"},"content":" userEmail, isInstructor, isGiverName, roster);"},{"lineNumber":889,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":890,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":891,"author":{"gitId":"xenosf"},"content":" private boolean isFeedbackParticipantNameVisibleToUser("},{"lineNumber":892,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question, FeedbackResponse response,"},{"lineNumber":893,"author":{"gitId":"xenosf"},"content":" String userEmail, boolean isInstructor, boolean isGiverName, SqlCourseRoster roster) {"},{"lineNumber":894,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackParticipantType\u003e showNameTo \u003d isGiverName"},{"lineNumber":895,"author":{"gitId":"xenosf"},"content":" ? question.getShowGiverNameTo()"},{"lineNumber":896,"author":{"gitId":"xenosf"},"content":" : question.getShowRecipientNameTo();"},{"lineNumber":897,"author":{"gitId":"xenosf"},"content":" for (FeedbackParticipantType type : showNameTo) {"},{"lineNumber":898,"author":{"gitId":"xenosf"},"content":" switch (type) {"},{"lineNumber":899,"author":{"gitId":"xenosf"},"content":" case INSTRUCTORS:"},{"lineNumber":900,"author":{"gitId":"xenosf"},"content":" if (roster.getInstructorForEmail(userEmail) !\u003d null \u0026\u0026 isInstructor) {"},{"lineNumber":901,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":902,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":903,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":904,"author":{"gitId":"xenosf"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":905,"author":{"gitId":"xenosf"},"content":" case OWN_TEAM_MEMBERS_INCLUDING_SELF:"},{"lineNumber":906,"author":{"gitId":"xenosf"},"content":" // Refers to Giver\u0027s Team Members"},{"lineNumber":907,"author":{"gitId":"xenosf"},"content":" if (roster.isStudentsInSameTeam(response.getGiver(), userEmail)) {"},{"lineNumber":908,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":909,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":910,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":911,"author":{"gitId":"xenosf"},"content":" case RECEIVER:"},{"lineNumber":912,"author":{"gitId":"xenosf"},"content":" // Response to team"},{"lineNumber":913,"author":{"gitId":"xenosf"},"content":" if (question.getRecipientType().isTeam()) {"},{"lineNumber":914,"author":{"gitId":"xenosf"},"content":" if (roster.isStudentInTeam(userEmail, response.getRecipient())) {"},{"lineNumber":915,"author":{"gitId":"xenosf"},"content":" // this is a team name"},{"lineNumber":916,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":917,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":918,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":919,"author":{"gitId":"xenosf"},"content":" // Response to individual"},{"lineNumber":920,"author":{"gitId":"xenosf"},"content":" } else if (response.getRecipient().equals(userEmail)) {"},{"lineNumber":921,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":922,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":923,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":924,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":925,"author":{"gitId":"xenosf"},"content":" case RECEIVER_TEAM_MEMBERS:"},{"lineNumber":926,"author":{"gitId":"xenosf"},"content":" // Response to team; recipient \u003d teamName"},{"lineNumber":927,"author":{"gitId":"xenosf"},"content":" if (question.getRecipientType().isTeam()) {"},{"lineNumber":928,"author":{"gitId":"xenosf"},"content":" if (roster.isStudentInTeam(userEmail, response.getRecipient())) {"},{"lineNumber":929,"author":{"gitId":"xenosf"},"content":" // this is a team name"},{"lineNumber":930,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":931,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":932,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":933,"author":{"gitId":"xenosf"},"content":" } else if (roster.isStudentsInSameTeam(response.getRecipient(), userEmail)) {"},{"lineNumber":934,"author":{"gitId":"xenosf"},"content":" // Response to individual"},{"lineNumber":935,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":936,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":937,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":938,"author":{"gitId":"xenosf"},"content":" case STUDENTS:"},{"lineNumber":939,"author":{"gitId":"xenosf"},"content":" if (roster.isStudentInCourse(userEmail)) {"},{"lineNumber":940,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":941,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":942,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":943,"author":{"gitId":"xenosf"},"content":" default:"},{"lineNumber":944,"author":{"gitId":"xenosf"},"content":" assert false : \"Invalid FeedbackParticipantType for showNameTo in \""},{"lineNumber":945,"author":{"gitId":"xenosf"},"content":" + \"FeedbackResponseLogic.isFeedbackParticipantNameVisibleToUser()\";"},{"lineNumber":946,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":947,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":948,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":949,"author":{"gitId":"xenosf"},"content":" return false;"},{"lineNumber":950,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":951,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":952,"author":{"gitId":"xenosf"},"content":" private boolean isResponseVisibleForUser("},{"lineNumber":953,"author":{"gitId":"xenosf"},"content":" String userEmail, boolean isInstructor, Student student,"},{"lineNumber":954,"author":{"gitId":"xenosf"},"content":" Set\u003cString\u003e studentsEmailInTeam, FeedbackResponse response,"},{"lineNumber":955,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion relatedQuestion, Instructor instructor) {"},{"lineNumber":956,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":957,"author":{"gitId":"xenosf"},"content":" boolean isVisibleResponse \u003d false;"},{"lineNumber":958,"author":{"gitId":"xenosf"},"content":" if (isInstructor \u0026\u0026 relatedQuestion.isResponseVisibleTo(FeedbackParticipantType.INSTRUCTORS)"},{"lineNumber":959,"author":{"gitId":"xenosf"},"content":" || response.getRecipient().equals(userEmail)"},{"lineNumber":960,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 relatedQuestion.isResponseVisibleTo(FeedbackParticipantType.RECEIVER)"},{"lineNumber":961,"author":{"gitId":"xenosf"},"content":" || response.getGiver().equals(userEmail)"},{"lineNumber":962,"author":{"gitId":"xenosf"},"content":" || !isInstructor \u0026\u0026 relatedQuestion.isResponseVisibleTo(FeedbackParticipantType.STUDENTS)) {"},{"lineNumber":963,"author":{"gitId":"xenosf"},"content":" isVisibleResponse \u003d true;"},{"lineNumber":964,"author":{"gitId":"xenosf"},"content":" } else if (studentsEmailInTeam !\u003d null \u0026\u0026 !isInstructor) {"},{"lineNumber":965,"author":{"gitId":"xenosf"},"content":" if ((relatedQuestion.getRecipientType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":966,"author":{"gitId":"xenosf"},"content":" || relatedQuestion.getRecipientType() \u003d\u003d FeedbackParticipantType.TEAMS_IN_SAME_SECTION"},{"lineNumber":967,"author":{"gitId":"xenosf"},"content":" || relatedQuestion.getRecipientType() \u003d\u003d FeedbackParticipantType.TEAMS_EXCLUDING_SELF)"},{"lineNumber":968,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 relatedQuestion.isResponseVisibleTo(FeedbackParticipantType.RECEIVER)"},{"lineNumber":969,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 response.getRecipient().equals(student.getTeamName())) {"},{"lineNumber":970,"author":{"gitId":"xenosf"},"content":" isVisibleResponse \u003d true;"},{"lineNumber":971,"author":{"gitId":"xenosf"},"content":" } else if (relatedQuestion.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":972,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 response.getGiver().equals(student.getTeamName())) {"},{"lineNumber":973,"author":{"gitId":"xenosf"},"content":" isVisibleResponse \u003d true;"},{"lineNumber":974,"author":{"gitId":"xenosf"},"content":" } else if (relatedQuestion.isResponseVisibleTo(FeedbackParticipantType.OWN_TEAM_MEMBERS)"},{"lineNumber":975,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 studentsEmailInTeam.contains(response.getGiver())) {"},{"lineNumber":976,"author":{"gitId":"xenosf"},"content":" isVisibleResponse \u003d true;"},{"lineNumber":977,"author":{"gitId":"xenosf"},"content":" } else if (relatedQuestion.isResponseVisibleTo(FeedbackParticipantType.RECEIVER_TEAM_MEMBERS)"},{"lineNumber":978,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 studentsEmailInTeam.contains(response.getRecipient())) {"},{"lineNumber":979,"author":{"gitId":"xenosf"},"content":" isVisibleResponse \u003d true;"},{"lineNumber":980,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":981,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":982,"author":{"gitId":"xenosf"},"content":" if (isVisibleResponse \u0026\u0026 instructor !\u003d null) {"},{"lineNumber":983,"author":{"gitId":"xenosf"},"content":" boolean isGiverSectionRestricted \u003d"},{"lineNumber":984,"author":{"gitId":"xenosf"},"content":" !instructor.isAllowedForPrivilege(response.getGiverSectionName(),"},{"lineNumber":985,"author":{"gitId":"xenosf"},"content":" response.getFeedbackQuestion().getFeedbackSession().getName(),"},{"lineNumber":986,"author":{"gitId":"xenosf"},"content":" Const.InstructorPermissions.CAN_VIEW_SESSION_IN_SECTIONS);"},{"lineNumber":987,"author":{"gitId":"xenosf"},"content":" // If instructors are not restricted to view the giver\u0027s section,"},{"lineNumber":988,"author":{"gitId":"xenosf"},"content":" // they are allowed to view responses to GENERAL, subject to visibility options"},{"lineNumber":989,"author":{"gitId":"xenosf"},"content":" boolean isRecipientSectionRestricted \u003d"},{"lineNumber":990,"author":{"gitId":"xenosf"},"content":" relatedQuestion.getRecipientType() !\u003d FeedbackParticipantType.NONE"},{"lineNumber":991,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 !instructor.isAllowedForPrivilege(response.getRecipientSectionName(),"},{"lineNumber":992,"author":{"gitId":"xenosf"},"content":" response.getFeedbackQuestion().getFeedbackSession().getName(),"},{"lineNumber":993,"author":{"gitId":"xenosf"},"content":" Const.InstructorPermissions.CAN_VIEW_SESSION_IN_SECTIONS);"},{"lineNumber":994,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":995,"author":{"gitId":"xenosf"},"content":" boolean isNotAllowedForInstructor \u003d isGiverSectionRestricted || isRecipientSectionRestricted;"},{"lineNumber":996,"author":{"gitId":"xenosf"},"content":" if (isNotAllowedForInstructor) {"},{"lineNumber":997,"author":{"gitId":"xenosf"},"content":" isVisibleResponse \u003d false;"},{"lineNumber":998,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":999,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1000,"author":{"gitId":"xenosf"},"content":" return isVisibleResponse;"},{"lineNumber":1001,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1002,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1003,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1004,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1005,"author":{"gitId":"xenosf"},"content":" * Gets all responses for a session."},{"lineNumber":1006,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1007,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e getFeedbackResponsesForSession("},{"lineNumber":1008,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession, String courseId) {"},{"lineNumber":1009,"author":{"gitId":"xenosf"},"content":" return frDb.getFeedbackResponsesForSession(feedbackSession, courseId);"},{"lineNumber":1010,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1011,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1012,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1013,"author":{"gitId":"xenosf"},"content":" * Gets all responses given to/from a section in a feedback session in a course."},{"lineNumber":1014,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":1015,"author":{"gitId":"xenosf"},"content":" * @param feedbackSession the session"},{"lineNumber":1016,"author":{"gitId":"xenosf"},"content":" * @param courseId the course ID of the session"},{"lineNumber":1017,"author":{"gitId":"xenosf"},"content":" * @param sectionName if null, will retrieve all responses in the session"},{"lineNumber":1018,"author":{"gitId":"xenosf"},"content":" * @param fetchType if not null, will retrieve responses by giver, receiver sections, or both"},{"lineNumber":1019,"author":{"gitId":"xenosf"},"content":" * @return a list of responses"},{"lineNumber":1020,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1021,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForSessionInSection("},{"lineNumber":1022,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession, String courseId, @Nullable String sectionName,"},{"lineNumber":1023,"author":{"gitId":"xenosf"},"content":" @Nullable FeedbackResultFetchType fetchType) {"},{"lineNumber":1024,"author":{"gitId":"xenosf"},"content":" if (sectionName \u003d\u003d null) {"},{"lineNumber":1025,"author":{"gitId":"xenosf"},"content":" return getFeedbackResponsesForSession(feedbackSession, courseId);"},{"lineNumber":1026,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1027,"author":{"gitId":"xenosf"},"content":" return frDb.getFeedbackResponsesForSessionInSection(feedbackSession, courseId, sectionName, fetchType);"},{"lineNumber":1028,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1029,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1030,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1031,"author":{"gitId":"xenosf"},"content":" * Gets all responses given to/from a section for a question."},{"lineNumber":1032,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":1033,"author":{"gitId":"xenosf"},"content":" * @param feedbackQuestionId the question UUID"},{"lineNumber":1034,"author":{"gitId":"xenosf"},"content":" * @param sectionName if null, will retrieve all responses for the question"},{"lineNumber":1035,"author":{"gitId":"xenosf"},"content":" * @return a list of responses"},{"lineNumber":1036,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1037,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForQuestionInSection("},{"lineNumber":1038,"author":{"gitId":"xenosf"},"content":" UUID feedbackQuestionId, @Nullable String sectionName, FeedbackResultFetchType fetchType) {"},{"lineNumber":1039,"author":{"gitId":"xenosf"},"content":" if (sectionName \u003d\u003d null) {"},{"lineNumber":1040,"author":{"gitId":"xenosf"},"content":" return getFeedbackResponsesForQuestion(feedbackQuestionId);"},{"lineNumber":1041,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1042,"author":{"gitId":"xenosf"},"content":" return frDb.getFeedbackResponsesForQuestionInSection(feedbackQuestionId, sectionName, fetchType);"},{"lineNumber":1043,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1044,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1045,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1046,"author":{"gitId":"xenosf"},"content":" * Returns feedback responses given/received by an instructor."},{"lineNumber":1047,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1048,"author":{"gitId":"xenosf"},"content":" private List\u003cFeedbackResponse\u003e getFeedbackResponsesToOrFromInstructorForQuestion("},{"lineNumber":1049,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question, Instructor instructor) {"},{"lineNumber":1050,"author":{"gitId":"xenosf"},"content":" Set\u003cFeedbackResponse\u003e viewableResponses \u003d new HashSet\u003c\u003e();"},{"lineNumber":1051,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1052,"author":{"gitId":"xenosf"},"content":" // Add responses that the instructor submitted him/herself"},{"lineNumber":1053,"author":{"gitId":"xenosf"},"content":" if (question.getGiverType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS) {"},{"lineNumber":1054,"author":{"gitId":"xenosf"},"content":" viewableResponses.addAll("},{"lineNumber":1055,"author":{"gitId":"xenosf"},"content":" getFeedbackResponsesFromGiverForQuestion(question.getId(), instructor.getEmail())"},{"lineNumber":1056,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":1057,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1058,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1059,"author":{"gitId":"xenosf"},"content":" // Add responses that user is a receiver of when response is visible to receiver or instructors"},{"lineNumber":1060,"author":{"gitId":"xenosf"},"content":" if (question.getRecipientType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":1061,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 (question.isResponseVisibleTo(FeedbackParticipantType.RECEIVER)"},{"lineNumber":1062,"author":{"gitId":"xenosf"},"content":" || question.isResponseVisibleTo(FeedbackParticipantType.INSTRUCTORS))) {"},{"lineNumber":1063,"author":{"gitId":"xenosf"},"content":" viewableResponses.addAll("},{"lineNumber":1064,"author":{"gitId":"xenosf"},"content":" getFeedbackResponsesForRecipientForQuestion(question.getId(), instructor.getEmail())"},{"lineNumber":1065,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":1066,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1067,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1068,"author":{"gitId":"xenosf"},"content":" return new ArrayList\u003c\u003e(viewableResponses);"},{"lineNumber":1069,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1070,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1071,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1072,"author":{"gitId":"xenosf"},"content":" * Returns viewable feedback responses for a student."},{"lineNumber":1073,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1074,"author":{"gitId":"xenosf"},"content":" private List\u003cFeedbackResponse\u003e getViewableFeedbackResponsesForStudentForQuestion("},{"lineNumber":1075,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question, Student student, SqlCourseRoster courseRoster) {"},{"lineNumber":1076,"author":{"gitId":"xenosf"},"content":" Set\u003cFeedbackResponse\u003e viewableResponses \u003d new HashSet\u003c\u003e();"},{"lineNumber":1077,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1078,"author":{"gitId":"xenosf"},"content":" // Add responses that the student submitted him/herself"},{"lineNumber":1079,"author":{"gitId":"xenosf"},"content":" if (question.getGiverType() !\u003d FeedbackParticipantType.INSTRUCTORS) {"},{"lineNumber":1080,"author":{"gitId":"xenosf"},"content":" viewableResponses.addAll("},{"lineNumber":1081,"author":{"gitId":"xenosf"},"content":" getFeedbackResponsesFromGiverForQuestion(question.getId(), student.getEmail())"},{"lineNumber":1082,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":1083,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1084,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1085,"author":{"gitId":"xenosf"},"content":" // Add responses that user is a receiver of when response is visible to receiver"},{"lineNumber":1086,"author":{"gitId":"xenosf"},"content":" if (question.getRecipientType() !\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":1087,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 question.isResponseVisibleTo(FeedbackParticipantType.RECEIVER)) {"},{"lineNumber":1088,"author":{"gitId":"xenosf"},"content":" viewableResponses.addAll("},{"lineNumber":1089,"author":{"gitId":"xenosf"},"content":" getFeedbackResponsesForRecipientForQuestion(question.getId(), student.getEmail())"},{"lineNumber":1090,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":1091,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1092,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1093,"author":{"gitId":"xenosf"},"content":" if (question.isResponseVisibleTo(FeedbackParticipantType.STUDENTS)) {"},{"lineNumber":1094,"author":{"gitId":"xenosf"},"content":" viewableResponses.addAll(getFeedbackResponsesForQuestion(question.getId()));"},{"lineNumber":1095,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1096,"author":{"gitId":"xenosf"},"content":" // Early return as STUDENTS covers all cases below."},{"lineNumber":1097,"author":{"gitId":"xenosf"},"content":" return new ArrayList\u003c\u003e(viewableResponses);"},{"lineNumber":1098,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1099,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1100,"author":{"gitId":"xenosf"},"content":" if (question.getRecipientType().isTeam()"},{"lineNumber":1101,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 question.isResponseVisibleTo(FeedbackParticipantType.RECEIVER)) {"},{"lineNumber":1102,"author":{"gitId":"xenosf"},"content":" viewableResponses.addAll("},{"lineNumber":1103,"author":{"gitId":"xenosf"},"content":" getFeedbackResponsesForRecipientForQuestion(question.getId(), student.getTeamName())"},{"lineNumber":1104,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":1105,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1106,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1107,"author":{"gitId":"xenosf"},"content":" if (question.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":1108,"author":{"gitId":"xenosf"},"content":" || question.isResponseVisibleTo(FeedbackParticipantType.OWN_TEAM_MEMBERS)) {"},{"lineNumber":1109,"author":{"gitId":"xenosf"},"content":" viewableResponses.addAll("},{"lineNumber":1110,"author":{"gitId":"xenosf"},"content":" getFeedbackResponsesFromTeamForQuestion("},{"lineNumber":1111,"author":{"gitId":"xenosf"},"content":" question.getId(), question.getCourseId(), student.getTeamName(), courseRoster));"},{"lineNumber":1112,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1113,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1114,"author":{"gitId":"xenosf"},"content":" if (question.isResponseVisibleTo(FeedbackParticipantType.RECEIVER_TEAM_MEMBERS)) {"},{"lineNumber":1115,"author":{"gitId":"xenosf"},"content":" for (Student studentInTeam : courseRoster.getTeamToMembersTable().get(student.getTeamName())) {"},{"lineNumber":1116,"author":{"gitId":"xenosf"},"content":" if (studentInTeam.getEmail().equals(student.getEmail())) {"},{"lineNumber":1117,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":1118,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1119,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e responses \u003d"},{"lineNumber":1120,"author":{"gitId":"xenosf"},"content":" getFeedbackResponsesForRecipientForQuestion(question.getId(), studentInTeam.getEmail());"},{"lineNumber":1121,"author":{"gitId":"xenosf"},"content":" viewableResponses.addAll(responses);"},{"lineNumber":1122,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1123,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1124,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1125,"author":{"gitId":"xenosf"},"content":" return new ArrayList\u003c\u003e(viewableResponses);"},{"lineNumber":1126,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1127,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1128,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1129,"author":{"gitId":"xenosf"},"content":" * Gets all responses received by a user for a question."},{"lineNumber":1130,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1131,"author":{"gitId":"xenosf"},"content":" private List\u003cFeedbackResponse\u003e getFeedbackResponsesForRecipientForQuestion("},{"lineNumber":1132,"author":{"gitId":"xenosf"},"content":" UUID feedbackQuestionId, String userEmail) {"},{"lineNumber":1133,"author":{"gitId":"xenosf"},"content":" return frDb.getFeedbackResponsesForRecipientForQuestion(feedbackQuestionId, userEmail);"},{"lineNumber":1134,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1135,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1136,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1137,"author":{"gitId":"xenosf"},"content":" * Checks whether instructors can see the question."},{"lineNumber":1138,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1139,"author":{"gitId":"xenosf"},"content":" boolean checkCanInstructorsSeeQuestion(FeedbackQuestion feedbackQuestion) {"},{"lineNumber":1140,"author":{"gitId":"xenosf"},"content":" boolean isResponseVisibleToInstructor \u003d"},{"lineNumber":1141,"author":{"gitId":"xenosf"},"content":" feedbackQuestion.getShowResponsesTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":1142,"author":{"gitId":"xenosf"},"content":" boolean isGiverVisibleToInstructor \u003d"},{"lineNumber":1143,"author":{"gitId":"xenosf"},"content":" feedbackQuestion.getShowGiverNameTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":1144,"author":{"gitId":"xenosf"},"content":" boolean isRecipientVisibleToInstructor \u003d"},{"lineNumber":1145,"author":{"gitId":"xenosf"},"content":" feedbackQuestion.getShowRecipientNameTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":1146,"author":{"gitId":"xenosf"},"content":" return isResponseVisibleToInstructor \u0026\u0026 isGiverVisibleToInstructor \u0026\u0026 isRecipientVisibleToInstructor;"},{"lineNumber":1147,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1148,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1149,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1150,"author":{"gitId":"xenosf"},"content":" * Checks whether instructors can see the comment."},{"lineNumber":1151,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1152,"author":{"gitId":"xenosf"},"content":" boolean checkCanInstructorsSeeComment(FeedbackResponseComment feedbackResponseComment) {"},{"lineNumber":1153,"author":{"gitId":"xenosf"},"content":" boolean isCommentVisibleToInstructor \u003d"},{"lineNumber":1154,"author":{"gitId":"xenosf"},"content":" feedbackResponseComment.getShowCommentTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":1155,"author":{"gitId":"xenosf"},"content":" boolean isGiverVisibleToInstructor \u003d"},{"lineNumber":1156,"author":{"gitId":"xenosf"},"content":" feedbackResponseComment.getShowGiverNameTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":1157,"author":{"gitId":"xenosf"},"content":" return isCommentVisibleToInstructor \u0026\u0026 isGiverVisibleToInstructor;"},{"lineNumber":1158,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1159,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1160,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":77,"marquestye":23,"xenosf":625,"mingyuanc":2,"-":433}},{"path":"src/main/java/teammates/sqllogic/core/FeedbackSessionLogsLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import org.hibernate.ObjectNotFoundException;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Logger;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlapi.FeedbackSessionLogsDb;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":" * Handles operations related to feedback sessions."},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":" * @see FeedbackSessionLog"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":" * @see FeedbackSessionLogsDb"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"public final class FeedbackSessionLogsLogic {"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" private static final FeedbackSessionLogsLogic instance \u003d new FeedbackSessionLogsLogic();"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":" private static final String ERROR_FAILED_TO_CREATE_LOG \u003d \"Failed to create session activity log\";"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" private FeedbackSessionLogsDb fslDb;"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" private FeedbackSessionLogsLogic() {"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" // prevent initialization"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" public static FeedbackSessionLogsLogic inst() {"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" return instance;"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" void initLogicDependencies(FeedbackSessionLogsDb fslDb) {"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" this.fslDb \u003d fslDb;"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" * Creates feedback session logs."},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" public void createFeedbackSessionLogs(List\u003cFeedbackSessionLog\u003e fsLogs) {"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" for (FeedbackSessionLog fsLog : fsLogs) {"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" try {"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" fslDb.createFeedbackSessionLog(fsLog);"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" } catch (ObjectNotFoundException e) {"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" log.severe(String.format(ERROR_FAILED_TO_CREATE_LOG), e);"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" * Gets the feedback session logs as filtered by the given parameters ordered by"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" * ascending timestamp. Logs with the same timestamp will be ordered by the"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" * student\u0027s email."},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" * @param studentId Can be null"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" * @param feedbackSessionId Can be null"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" public List\u003cFeedbackSessionLog\u003e getOrderedFeedbackSessionLogs(String courseId, UUID studentId,"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" UUID feedbackSessionId, Instant startTime, Instant endTime) {"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" return fslDb.getOrderedFeedbackSessionLogs(courseId, studentId, feedbackSessionId, startTime,"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" endTime);"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":67}},{"path":"src/main/java/teammates/sqllogic/core/FeedbackSessionsLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.HashSet;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.Set;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackSessionsDb;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * Handles operations related to feedback sessions."},{"lineNumber":25,"author":{"gitId":"-"},"content":" *"},{"lineNumber":26,"author":{"gitId":"-"},"content":" * @see FeedbackSession"},{"lineNumber":27,"author":{"gitId":"-"},"content":" * @see FeedbackSessionsDb"},{"lineNumber":28,"author":{"gitId":"-"},"content":" */"},{"lineNumber":29,"author":{"gitId":"-"},"content":"public final class FeedbackSessionsLogic {"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private static final String ERROR_NON_EXISTENT_FS_STRING_FORMAT \u003d \"Trying to %s a non-existent feedback session: \";"},{"lineNumber":34,"author":{"gitId":"-"},"content":" private static final String ERROR_NON_EXISTENT_FS_UPDATE \u003d String.format(ERROR_NON_EXISTENT_FS_STRING_FORMAT, \"update\");"},{"lineNumber":35,"author":{"gitId":"-"},"content":" private static final String ERROR_FS_ALREADY_PUBLISH \u003d \"Error publishing feedback session: \""},{"lineNumber":36,"author":{"gitId":"-"},"content":" + \"Session has already been published.\";"},{"lineNumber":37,"author":{"gitId":"-"},"content":" private static final String ERROR_FS_ALREADY_UNPUBLISH \u003d \"Error unpublishing feedback session: \""},{"lineNumber":38,"author":{"gitId":"-"},"content":" + \"Session has already been unpublished.\";"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" private static final int NUMBER_OF_HOURS_BEFORE_CLOSING_ALERT \u003d 24;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" private static final int NUMBER_OF_HOURS_BEFORE_OPENING_SOON_ALERT \u003d 24;"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" private static final FeedbackSessionsLogic instance \u003d new FeedbackSessionsLogic();"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" private FeedbackSessionsDb fsDb;"},{"lineNumber":46,"author":{"gitId":"-"},"content":" private FeedbackQuestionsLogic fqLogic;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" private FeedbackResponsesLogic frLogic;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" private CoursesLogic coursesLogic;"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" private UsersLogic usersLogic;"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" private FeedbackSessionsLogic() {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" public static FeedbackSessionsLogic inst() {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" void initLogicDependencies(FeedbackSessionsDb fsDb, CoursesLogic coursesLogic,"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" FeedbackResponsesLogic frLogic, FeedbackQuestionsLogic fqLogic, UsersLogic usersLogic) {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" this.fsDb \u003d fsDb;"},{"lineNumber":62,"author":{"gitId":"-"},"content":" this.frLogic \u003d frLogic;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" this.fqLogic \u003d fqLogic;"},{"lineNumber":64,"author":{"gitId":"-"},"content":" this.coursesLogic \u003d coursesLogic;"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" this.usersLogic \u003d usersLogic;"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":69,"author":{"gitId":"-"},"content":" * Gets a feedback session."},{"lineNumber":70,"author":{"gitId":"-"},"content":" *"},{"lineNumber":71,"author":{"gitId":"-"},"content":" * @return null if not found."},{"lineNumber":72,"author":{"gitId":"-"},"content":" */"},{"lineNumber":73,"author":{"gitId":"-"},"content":" public FeedbackSession getFeedbackSession(UUID id) {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" assert id !\u003d null;"},{"lineNumber":75,"author":{"gitId":"-"},"content":" return fsDb.getFeedbackSession(id);"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":79,"author":{"gitId":"-"},"content":" * Gets a feedback session for {@code feedbackSessionName} and {@code courseId}."},{"lineNumber":80,"author":{"gitId":"-"},"content":" *"},{"lineNumber":81,"author":{"gitId":"-"},"content":" * @return null if not found."},{"lineNumber":82,"author":{"gitId":"-"},"content":" */"},{"lineNumber":83,"author":{"gitId":"-"},"content":" public FeedbackSession getFeedbackSession(String feedbackSessionName, String courseId) {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" return fsDb.getFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":" * Gets a feedback session reference."},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":" * @return Returns a proxy for the feedback session."},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" public FeedbackSession getFeedbackSessionReference(UUID id) {"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" assert id !\u003d null;"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" return fsDb.getFeedbackSessionReference(id);"},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":101,"author":{"gitId":"-"},"content":" * Gets all feedback sessions of a course, except those that are soft-deleted."},{"lineNumber":102,"author":{"gitId":"-"},"content":" */"},{"lineNumber":103,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsForCourse(String courseId) {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" return fsDb.getFeedbackSessionEntitiesForCourse(courseId).stream()"},{"lineNumber":105,"author":{"gitId":"-"},"content":" .filter(fs -\u003e fs.getDeletedAt() \u003d\u003d null)"},{"lineNumber":106,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":110,"author":{"gitId":"-"},"content":" * Gets all feedback sessions of a course started after time, except those that are soft-deleted."},{"lineNumber":111,"author":{"gitId":"-"},"content":" */"},{"lineNumber":112,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsForCourseStartingAfter(String courseId, Instant after) {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" return fsDb.getFeedbackSessionEntitiesForCourseStartingAfter(courseId, after).stream()"},{"lineNumber":114,"author":{"gitId":"-"},"content":" .filter(session -\u003e session.getDeletedAt() \u003d\u003d null)"},{"lineNumber":115,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":116,"author":{"gitId":"-"},"content":" }"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":119,"author":{"gitId":"-"},"content":" * Gets a feedback session from the recycle bin."},{"lineNumber":120,"author":{"gitId":"-"},"content":" *"},{"lineNumber":121,"author":{"gitId":"-"},"content":" * @return null if not found."},{"lineNumber":122,"author":{"gitId":"-"},"content":" */"},{"lineNumber":123,"author":{"gitId":"-"},"content":" public FeedbackSession getFeedbackSessionFromRecycleBin(String feedbackSessionName, String courseId) {"},{"lineNumber":124,"author":{"gitId":"-"},"content":" return fsDb.getSoftDeletedFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" }"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":128,"author":{"gitId":"-"},"content":" * Gets a list of feedback sessions for instructors."},{"lineNumber":129,"author":{"gitId":"-"},"content":" */"},{"lineNumber":130,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsForInstructors("},{"lineNumber":131,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorList) {"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e courseNotDeletedInstructorList \u003d instructorList.stream()"},{"lineNumber":134,"author":{"gitId":"-"},"content":" .filter(instructor -\u003e coursesLogic.getCourse(instructor.getCourseId()).getDeletedAt() \u003d\u003d null)"},{"lineNumber":135,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e fsList \u003d new ArrayList\u003c\u003e();"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" for (Instructor instructor : courseNotDeletedInstructorList) {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" fsList.addAll(getFeedbackSessionsForCourse(instructor.getCourseId()));"},{"lineNumber":141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" return fsList;"},{"lineNumber":144,"author":{"gitId":"-"},"content":" }"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":147,"author":{"gitId":"-"},"content":" * Returns a {@code List} of feedback sessions in the Recycle Bin for the instructors."},{"lineNumber":148,"author":{"gitId":"-"},"content":" * \u003cbr\u003e"},{"lineNumber":149,"author":{"gitId":"-"},"content":" * Omits sessions if the corresponding courses are archived or in Recycle Bin"},{"lineNumber":150,"author":{"gitId":"-"},"content":" */"},{"lineNumber":151,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getSoftDeletedFeedbackSessionsForInstructors("},{"lineNumber":152,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorList) {"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e courseNotDeletedInstructorList \u003d instructorList.stream()"},{"lineNumber":155,"author":{"gitId":"-"},"content":" .filter(instructor -\u003e coursesLogic.getCourse(instructor.getCourseId()).getDeletedAt() \u003d\u003d null)"},{"lineNumber":156,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e fsList \u003d new ArrayList\u003c\u003e();"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" for (Instructor instructor : courseNotDeletedInstructorList) {"},{"lineNumber":161,"author":{"gitId":"-"},"content":" fsList.addAll(fsDb.getSoftDeletedFeedbackSessionsForCourse(instructor.getCourseId()));"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" return fsList;"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":168,"author":{"gitId":"-"},"content":" * Gets all and only the feedback sessions ongoing within a range of time."},{"lineNumber":169,"author":{"gitId":"-"},"content":" */"},{"lineNumber":170,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getOngoingSessions(Instant rangeStart, Instant rangeEnd) {"},{"lineNumber":171,"author":{"gitId":"-"},"content":" return fsDb.getOngoingSessions(rangeStart, rangeEnd);"},{"lineNumber":172,"author":{"gitId":"-"},"content":" }"},{"lineNumber":173,"author":{"gitId":"-"},"content":""},{"lineNumber":174,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":175,"author":{"gitId":"-"},"content":" * Gets a set of giver identifiers that has at least one response under a feedback session."},{"lineNumber":176,"author":{"gitId":"-"},"content":" */"},{"lineNumber":177,"author":{"gitId":"-"},"content":" public Set\u003cString\u003e getGiverSetThatAnsweredFeedbackSession(String feedbackSessionName, String courseId) {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":179,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":180,"author":{"gitId":"-"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession \u003d fsDb.getFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" Set\u003cString\u003e giverSet \u003d new HashSet\u003c\u003e();"},{"lineNumber":184,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":185,"author":{"gitId":"domoberzin"},"content":" fqLogic.getFeedbackQuestionsForSession(feedbackSession).forEach(question -\u003e {"},{"lineNumber":186,"author":{"gitId":"domoberzin"},"content":" frLogic.getFeedbackResponsesForQuestion(question.getId()).forEach(response -\u003e {"},{"lineNumber":187,"author":{"gitId":"-"},"content":" giverSet.add(response.getGiver());"},{"lineNumber":188,"author":{"gitId":"-"},"content":" });"},{"lineNumber":189,"author":{"gitId":"-"},"content":" });"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" return giverSet;"},{"lineNumber":192,"author":{"gitId":"-"},"content":" }"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" * Gets a set of giver identifiers that has at least one response under a feedback session."},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":" public Set\u003cString\u003e getGiverSetThatAnsweredFeedbackSession(FeedbackSession fs) {"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" assert fs !\u003d null;"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":200,"author":{"gitId":"domoberzin"},"content":" Set\u003cString\u003e giverSet \u003d new HashSet\u003c\u003e();"},{"lineNumber":201,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":202,"author":{"gitId":"domoberzin"},"content":" fqLogic.getFeedbackQuestionsForSession(fs).forEach(question -\u003e {"},{"lineNumber":203,"author":{"gitId":"domoberzin"},"content":" frLogic.getFeedbackResponsesForQuestion(question.getId()).forEach(response -\u003e {"},{"lineNumber":204,"author":{"gitId":"domoberzin"},"content":" giverSet.add(response.getGiver());"},{"lineNumber":205,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":206,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":207,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":208,"author":{"gitId":"domoberzin"},"content":" return giverSet;"},{"lineNumber":209,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":210,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":211,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":212,"author":{"gitId":"-"},"content":" * Creates a feedback session."},{"lineNumber":213,"author":{"gitId":"-"},"content":" *"},{"lineNumber":214,"author":{"gitId":"-"},"content":" * @return created feedback session"},{"lineNumber":215,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the session is not valid"},{"lineNumber":216,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the session already exist"},{"lineNumber":217,"author":{"gitId":"-"},"content":" */"},{"lineNumber":218,"author":{"gitId":"-"},"content":" public FeedbackSession createFeedbackSession(FeedbackSession session)"},{"lineNumber":219,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" assert session !\u003d null;"},{"lineNumber":221,"author":{"gitId":"-"},"content":" return fsDb.createFeedbackSession(session);"},{"lineNumber":222,"author":{"gitId":"-"},"content":" }"},{"lineNumber":223,"author":{"gitId":"-"},"content":""},{"lineNumber":224,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":225,"author":{"gitId":"-"},"content":" * Updates a feedback session."},{"lineNumber":226,"author":{"gitId":"-"},"content":" *"},{"lineNumber":227,"author":{"gitId":"-"},"content":" * @return updated feedback session"},{"lineNumber":228,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the feedback session does not exist"},{"lineNumber":229,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the new fields for feedback session are invalid"},{"lineNumber":230,"author":{"gitId":"-"},"content":" */"},{"lineNumber":231,"author":{"gitId":"-"},"content":" public FeedbackSession updateFeedbackSession(FeedbackSession session)"},{"lineNumber":232,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":233,"author":{"gitId":"-"},"content":" return fsDb.updateFeedbackSession(session);"},{"lineNumber":234,"author":{"gitId":"-"},"content":" }"},{"lineNumber":235,"author":{"gitId":"-"},"content":""},{"lineNumber":236,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":237,"author":{"gitId":"-"},"content":" * Unpublishes a feedback session."},{"lineNumber":238,"author":{"gitId":"-"},"content":" *"},{"lineNumber":239,"author":{"gitId":"-"},"content":" * @return the unpublished feedback session"},{"lineNumber":240,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if session is already unpublished"},{"lineNumber":241,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the feedback session cannot be found"},{"lineNumber":242,"author":{"gitId":"-"},"content":" */"},{"lineNumber":243,"author":{"gitId":"-"},"content":" public FeedbackSession unpublishFeedbackSession(String feedbackSessionName, String courseId)"},{"lineNumber":244,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, InvalidParametersException {"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" FeedbackSession sessionToUnpublish \u003d getFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" if (sessionToUnpublish \u003d\u003d null) {"},{"lineNumber":249,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(ERROR_NON_EXISTENT_FS_UPDATE + courseId + \"/\" + feedbackSessionName);"},{"lineNumber":250,"author":{"gitId":"-"},"content":" }"},{"lineNumber":251,"author":{"gitId":"-"},"content":" if (!sessionToUnpublish.isPublished()) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(ERROR_FS_ALREADY_UNPUBLISH);"},{"lineNumber":253,"author":{"gitId":"-"},"content":" }"},{"lineNumber":254,"author":{"gitId":"-"},"content":""},{"lineNumber":255,"author":{"gitId":"-"},"content":" sessionToUnpublish.setResultsVisibleFromTime(Const.TIME_REPRESENTS_LATER);"},{"lineNumber":256,"author":{"gitId":"-"},"content":""},{"lineNumber":257,"author":{"gitId":"-"},"content":" return sessionToUnpublish;"},{"lineNumber":258,"author":{"gitId":"-"},"content":" }"},{"lineNumber":259,"author":{"gitId":"-"},"content":""},{"lineNumber":260,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":261,"author":{"gitId":"-"},"content":" * Publishes a feedback session."},{"lineNumber":262,"author":{"gitId":"-"},"content":" *"},{"lineNumber":263,"author":{"gitId":"-"},"content":" * @return the published feedback session"},{"lineNumber":264,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if session is already published"},{"lineNumber":265,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the feedback session cannot be found"},{"lineNumber":266,"author":{"gitId":"-"},"content":" */"},{"lineNumber":267,"author":{"gitId":"-"},"content":" public FeedbackSession publishFeedbackSession(String feedbackSessionName, String courseId)"},{"lineNumber":268,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, InvalidParametersException {"},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":" FeedbackSession sessionToPublish \u003d getFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" if (sessionToPublish \u003d\u003d null) {"},{"lineNumber":273,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(ERROR_NON_EXISTENT_FS_UPDATE + courseId + \"/\" + feedbackSessionName);"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":" if (sessionToPublish.isPublished()) {"},{"lineNumber":276,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(ERROR_FS_ALREADY_PUBLISH);"},{"lineNumber":277,"author":{"gitId":"-"},"content":" }"},{"lineNumber":278,"author":{"gitId":"-"},"content":""},{"lineNumber":279,"author":{"gitId":"-"},"content":" sessionToPublish.setResultsVisibleFromTime(Instant.now());"},{"lineNumber":280,"author":{"gitId":"-"},"content":""},{"lineNumber":281,"author":{"gitId":"-"},"content":" return sessionToPublish;"},{"lineNumber":282,"author":{"gitId":"-"},"content":" }"},{"lineNumber":283,"author":{"gitId":"-"},"content":""},{"lineNumber":284,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":285,"author":{"gitId":"-"},"content":" * Deletes a feedback session cascade to its associated questions, responses, deadline extensions and comments."},{"lineNumber":286,"author":{"gitId":"-"},"content":" */"},{"lineNumber":287,"author":{"gitId":"-"},"content":" public void deleteFeedbackSessionCascade(String feedbackSessionName, String courseId) {"},{"lineNumber":288,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession \u003d fsDb.getFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":289,"author":{"gitId":"-"},"content":" fsDb.deleteFeedbackSession(feedbackSession);"},{"lineNumber":290,"author":{"gitId":"-"},"content":" }"},{"lineNumber":291,"author":{"gitId":"-"},"content":""},{"lineNumber":292,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":293,"author":{"gitId":"-"},"content":" * Soft-deletes a specific feedback session to Recycle Bin."},{"lineNumber":294,"author":{"gitId":"-"},"content":" * @return the feedback session"},{"lineNumber":295,"author":{"gitId":"-"},"content":" */"},{"lineNumber":296,"author":{"gitId":"-"},"content":" public FeedbackSession moveFeedbackSessionToRecycleBin(String feedbackSessionName, String courseId)"},{"lineNumber":297,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":298,"author":{"gitId":"-"},"content":""},{"lineNumber":299,"author":{"gitId":"-"},"content":" return fsDb.softDeleteFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":300,"author":{"gitId":"-"},"content":" }"},{"lineNumber":301,"author":{"gitId":"-"},"content":""},{"lineNumber":302,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":303,"author":{"gitId":"-"},"content":" * Restores a specific feedback session from Recycle Bin."},{"lineNumber":304,"author":{"gitId":"-"},"content":" */"},{"lineNumber":305,"author":{"gitId":"-"},"content":" public void restoreFeedbackSessionFromRecycleBin(String feedbackSessionName, String courseId)"},{"lineNumber":306,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":307,"author":{"gitId":"-"},"content":" fsDb.restoreDeletedFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":308,"author":{"gitId":"-"},"content":" }"},{"lineNumber":309,"author":{"gitId":"-"},"content":""},{"lineNumber":310,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":311,"author":{"gitId":"-"},"content":" * Returns true if there are any questions for the specified user type (students/instructors) to answer."},{"lineNumber":312,"author":{"gitId":"-"},"content":" */"},{"lineNumber":313,"author":{"gitId":"-"},"content":" public boolean isFeedbackSessionForUserTypeToAnswer(FeedbackSession session, boolean isInstructor) {"},{"lineNumber":314,"author":{"gitId":"-"},"content":" if (!session.isVisible()) {"},{"lineNumber":315,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":316,"author":{"gitId":"-"},"content":" }"},{"lineNumber":317,"author":{"gitId":"-"},"content":""},{"lineNumber":318,"author":{"gitId":"-"},"content":" return isInstructor"},{"lineNumber":319,"author":{"gitId":"-"},"content":" ? fqLogic.hasFeedbackQuestionsForInstructors(session.getFeedbackQuestions(), false)"},{"lineNumber":320,"author":{"gitId":"-"},"content":" : fqLogic.hasFeedbackQuestionsForStudents(session.getFeedbackQuestions());"},{"lineNumber":321,"author":{"gitId":"-"},"content":" }"},{"lineNumber":322,"author":{"gitId":"-"},"content":""},{"lineNumber":323,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":324,"author":{"gitId":"-"},"content":" * Returns true if the feedback session is viewable by the given user type (students/instructors)."},{"lineNumber":325,"author":{"gitId":"-"},"content":" */"},{"lineNumber":326,"author":{"gitId":"-"},"content":" public boolean isFeedbackSessionViewableToUserType(FeedbackSession session, boolean isInstructor) {"},{"lineNumber":327,"author":{"gitId":"-"},"content":" // Allow user to view the feedback session if there are questions for them"},{"lineNumber":328,"author":{"gitId":"-"},"content":" if (isFeedbackSessionForUserTypeToAnswer(session, isInstructor)) {"},{"lineNumber":329,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":330,"author":{"gitId":"-"},"content":" }"},{"lineNumber":331,"author":{"gitId":"-"},"content":""},{"lineNumber":332,"author":{"gitId":"-"},"content":" // Allow user to view the feedback session if there are any question whose responses are visible to the user"},{"lineNumber":333,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsWithVisibleResponses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":334,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsForUser \u003d session.getFeedbackQuestions();"},{"lineNumber":335,"author":{"gitId":"-"},"content":" for (FeedbackQuestion question : questionsForUser) {"},{"lineNumber":336,"author":{"gitId":"-"},"content":" if (!isInstructor \u0026\u0026 frLogic.isResponseOfFeedbackQuestionVisibleToStudent(question)"},{"lineNumber":337,"author":{"gitId":"-"},"content":" || isInstructor \u0026\u0026 frLogic.isResponseOfFeedbackQuestionVisibleToInstructor(question)) {"},{"lineNumber":338,"author":{"gitId":"-"},"content":" // We only need one question with visible responses for the entire session to be visible"},{"lineNumber":339,"author":{"gitId":"-"},"content":" questionsWithVisibleResponses.add(question);"},{"lineNumber":340,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":341,"author":{"gitId":"-"},"content":" }"},{"lineNumber":342,"author":{"gitId":"-"},"content":" }"},{"lineNumber":343,"author":{"gitId":"-"},"content":""},{"lineNumber":344,"author":{"gitId":"-"},"content":" return session.isVisible() \u0026\u0026 !questionsWithVisibleResponses.isEmpty();"},{"lineNumber":345,"author":{"gitId":"-"},"content":" }"},{"lineNumber":346,"author":{"gitId":"-"},"content":""},{"lineNumber":347,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":348,"author":{"gitId":"-"},"content":" * Checks whether a student has attempted a feedback session."},{"lineNumber":349,"author":{"gitId":"-"},"content":" *"},{"lineNumber":350,"author":{"gitId":"-"},"content":" * \u003cp\u003eIf feedback session consists of all team questions, session is attempted by student only"},{"lineNumber":351,"author":{"gitId":"-"},"content":" * if someone from the team has responded. If feedback session has some individual questions,"},{"lineNumber":352,"author":{"gitId":"-"},"content":" * session is attempted only if the student has responded to any of the individual questions"},{"lineNumber":353,"author":{"gitId":"-"},"content":" * (regardless of the completion status of the team questions).\u003c/p\u003e"},{"lineNumber":354,"author":{"gitId":"-"},"content":" */"},{"lineNumber":355,"author":{"gitId":"-"},"content":" public boolean isFeedbackSessionAttemptedByStudent(FeedbackSession session, String userEmail, String userTeam) {"},{"lineNumber":356,"author":{"gitId":"-"},"content":" assert session !\u003d null;"},{"lineNumber":357,"author":{"gitId":"-"},"content":" assert userEmail !\u003d null;"},{"lineNumber":358,"author":{"gitId":"-"},"content":" assert userTeam !\u003d null;"},{"lineNumber":359,"author":{"gitId":"-"},"content":""},{"lineNumber":360,"author":{"gitId":"-"},"content":" if (!fqLogic.hasFeedbackQuestionsForStudents(session.getFeedbackQuestions())) {"},{"lineNumber":361,"author":{"gitId":"-"},"content":" // if there are no questions for student, session is attempted"},{"lineNumber":362,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":363,"author":{"gitId":"-"},"content":" } else if (fqLogic.hasFeedbackQuestionsForGiverType("},{"lineNumber":364,"author":{"gitId":"-"},"content":" session.getFeedbackQuestions(), FeedbackParticipantType.STUDENTS)) {"},{"lineNumber":365,"author":{"gitId":"-"},"content":" // case where there are some individual questions"},{"lineNumber":366,"author":{"gitId":"-"},"content":" return frLogic.hasGiverRespondedForSession(userEmail, session.getFeedbackQuestions());"},{"lineNumber":367,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":368,"author":{"gitId":"-"},"content":" // case where all are team questions"},{"lineNumber":369,"author":{"gitId":"-"},"content":" return frLogic.hasGiverRespondedForSession(userTeam, session.getFeedbackQuestions());"},{"lineNumber":370,"author":{"gitId":"-"},"content":" }"},{"lineNumber":371,"author":{"gitId":"-"},"content":" }"},{"lineNumber":372,"author":{"gitId":"-"},"content":""},{"lineNumber":373,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":374,"author":{"gitId":"-"},"content":" * Checks whether an instructor has attempted a feedback session."},{"lineNumber":375,"author":{"gitId":"-"},"content":" *"},{"lineNumber":376,"author":{"gitId":"-"},"content":" * \u003cp\u003eIf there is no question for instructors, the feedback session is considered as attempted.\u003c/p\u003e"},{"lineNumber":377,"author":{"gitId":"-"},"content":" */"},{"lineNumber":378,"author":{"gitId":"-"},"content":" public boolean isFeedbackSessionAttemptedByInstructor(FeedbackSession session, String userEmail) {"},{"lineNumber":379,"author":{"gitId":"-"},"content":" assert session !\u003d null;"},{"lineNumber":380,"author":{"gitId":"-"},"content":" assert userEmail !\u003d null;"},{"lineNumber":381,"author":{"gitId":"-"},"content":""},{"lineNumber":382,"author":{"gitId":"-"},"content":" if (frLogic.hasGiverRespondedForSession(userEmail, session.getFeedbackQuestions())) {"},{"lineNumber":383,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":384,"author":{"gitId":"-"},"content":" }"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"-"},"content":" // if there is no question for instructor, session is attempted"},{"lineNumber":387,"author":{"gitId":"-"},"content":" return !fqLogic.hasFeedbackQuestionsForInstructors(session.getFeedbackQuestions(), session.isCreator(userEmail));"},{"lineNumber":388,"author":{"gitId":"-"},"content":" }"},{"lineNumber":389,"author":{"gitId":"-"},"content":""},{"lineNumber":390,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":391,"author":{"gitId":"-"},"content":" * After an update to feedback session\u0027s fields, may need to adjust the email status of the session."},{"lineNumber":392,"author":{"gitId":"-"},"content":" * @param session recently updated session."},{"lineNumber":393,"author":{"gitId":"-"},"content":" */"},{"lineNumber":394,"author":{"gitId":"-"},"content":" public void adjustFeedbackSessionEmailStatusAfterUpdate(FeedbackSession session) {"},{"lineNumber":395,"author":{"gitId":"-"},"content":" // reset isOpenEmailSent if the session has opened but is being un-opened"},{"lineNumber":396,"author":{"gitId":"-"},"content":" // now, or else leave it as sent if so."},{"lineNumber":397,"author":{"gitId":"-"},"content":" if (session.isOpenEmailSent()) {"},{"lineNumber":398,"author":{"gitId":"-"},"content":" session.setOpenEmailSent(session.isOpened());"},{"lineNumber":399,"author":{"gitId":"-"},"content":""},{"lineNumber":400,"author":{"gitId":"-"},"content":" // also reset isOpeningSoonEmailSent"},{"lineNumber":401,"author":{"gitId":"-"},"content":" session.setOpeningSoonEmailSent("},{"lineNumber":402,"author":{"gitId":"domoberzin"},"content":" session.isOpened() || session.isOpeningInHours(NUMBER_OF_HOURS_BEFORE_OPENING_SOON_ALERT));"},{"lineNumber":403,"author":{"gitId":"-"},"content":" }"},{"lineNumber":404,"author":{"gitId":"-"},"content":""},{"lineNumber":405,"author":{"gitId":"-"},"content":" // reset isClosedEmailSent if the session has closed but is being un-closed"},{"lineNumber":406,"author":{"gitId":"-"},"content":" // now, or else leave it as sent if so."},{"lineNumber":407,"author":{"gitId":"-"},"content":" if (session.isClosedEmailSent()) {"},{"lineNumber":408,"author":{"gitId":"-"},"content":" session.setClosedEmailSent(session.isClosed());"},{"lineNumber":409,"author":{"gitId":"-"},"content":""},{"lineNumber":410,"author":{"gitId":"-"},"content":" // also reset isClosingSoonEmailSent"},{"lineNumber":411,"author":{"gitId":"-"},"content":" session.setClosingSoonEmailSent("},{"lineNumber":412,"author":{"gitId":"domoberzin"},"content":" session.isClosed() || session.isClosedAfter(NUMBER_OF_HOURS_BEFORE_CLOSING_ALERT));"},{"lineNumber":413,"author":{"gitId":"-"},"content":" }"},{"lineNumber":414,"author":{"gitId":"-"},"content":""},{"lineNumber":415,"author":{"gitId":"-"},"content":" // reset isPublishedEmailSent if the session has been published but is"},{"lineNumber":416,"author":{"gitId":"-"},"content":" // going to be unpublished now, or else leave it as sent if so."},{"lineNumber":417,"author":{"gitId":"-"},"content":" if (session.isPublishedEmailSent()) {"},{"lineNumber":418,"author":{"gitId":"-"},"content":" session.setPublishedEmailSent(session.isPublished());"},{"lineNumber":419,"author":{"gitId":"-"},"content":" }"},{"lineNumber":420,"author":{"gitId":"-"},"content":" }"},{"lineNumber":421,"author":{"gitId":"-"},"content":""},{"lineNumber":422,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":423,"author":{"gitId":"-"},"content":" * Criteria: must be published, publishEmail must be enabled and"},{"lineNumber":424,"author":{"gitId":"-"},"content":" * resultsVisibleTime must be custom."},{"lineNumber":425,"author":{"gitId":"-"},"content":" *"},{"lineNumber":426,"author":{"gitId":"-"},"content":" * @return returns a list of sessions that require automated emails to be"},{"lineNumber":427,"author":{"gitId":"-"},"content":" * sent as they are published"},{"lineNumber":428,"author":{"gitId":"-"},"content":" */"},{"lineNumber":429,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsWhichNeedAutomatedPublishedEmailsToBeSent() {"},{"lineNumber":430,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e sessionsToSendEmailsFor \u003d new ArrayList\u003c\u003e();"},{"lineNumber":431,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e sessions \u003d fsDb.getFeedbackSessionsPossiblyNeedingPublishedEmail();"},{"lineNumber":432,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration: %d\", sessions.size()));"},{"lineNumber":433,"author":{"gitId":"-"},"content":""},{"lineNumber":434,"author":{"gitId":"-"},"content":" for (FeedbackSession session : sessions) {"},{"lineNumber":435,"author":{"gitId":"-"},"content":" // automated emails are required only for custom publish times"},{"lineNumber":436,"author":{"gitId":"-"},"content":" if (session.isPublished()"},{"lineNumber":437,"author":{"gitId":"-"},"content":" \u0026\u0026 !TimeHelper.isSpecialTime(session.getResultsVisibleFromTime())"},{"lineNumber":438,"author":{"gitId":"-"},"content":" \u0026\u0026 session.getCourse().getDeletedAt() \u003d\u003d null) {"},{"lineNumber":439,"author":{"gitId":"-"},"content":" sessionsToSendEmailsFor.add(session);"},{"lineNumber":440,"author":{"gitId":"-"},"content":" }"},{"lineNumber":441,"author":{"gitId":"-"},"content":" }"},{"lineNumber":442,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration after filtering: %d\","},{"lineNumber":443,"author":{"gitId":"-"},"content":" sessionsToSendEmailsFor.size()));"},{"lineNumber":444,"author":{"gitId":"-"},"content":" return sessionsToSendEmailsFor;"},{"lineNumber":445,"author":{"gitId":"-"},"content":" }"},{"lineNumber":446,"author":{"gitId":"-"},"content":""},{"lineNumber":447,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":448,"author":{"gitId":"-"},"content":" * Returns a list of sessions that are going to close within the next 24 hours."},{"lineNumber":449,"author":{"gitId":"-"},"content":" */"},{"lineNumber":450,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsClosingWithinTimeLimit() {"},{"lineNumber":451,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e requiredSessions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":452,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e sessions \u003d fsDb.getFeedbackSessionsPossiblyNeedingClosingSoonEmail();"},{"lineNumber":453,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration: %d\", sessions.size()));"},{"lineNumber":454,"author":{"gitId":"-"},"content":""},{"lineNumber":455,"author":{"gitId":"-"},"content":" for (FeedbackSession session : sessions) {"},{"lineNumber":456,"author":{"gitId":"-"},"content":" if (session.isClosingWithinTimeLimit(NUMBER_OF_HOURS_BEFORE_CLOSING_ALERT)"},{"lineNumber":457,"author":{"gitId":"-"},"content":" \u0026\u0026 session.getCourse().getDeletedAt() \u003d\u003d null) {"},{"lineNumber":458,"author":{"gitId":"-"},"content":" requiredSessions.add(session);"},{"lineNumber":459,"author":{"gitId":"-"},"content":" }"},{"lineNumber":460,"author":{"gitId":"-"},"content":" }"},{"lineNumber":461,"author":{"gitId":"-"},"content":""},{"lineNumber":462,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration after filtering: %d\","},{"lineNumber":463,"author":{"gitId":"-"},"content":" requiredSessions.size()));"},{"lineNumber":464,"author":{"gitId":"-"},"content":" return requiredSessions;"},{"lineNumber":465,"author":{"gitId":"-"},"content":" }"},{"lineNumber":466,"author":{"gitId":"-"},"content":""},{"lineNumber":467,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":468,"author":{"gitId":"-"},"content":" * Returns a list of sessions that are going to open in 24 hours."},{"lineNumber":469,"author":{"gitId":"-"},"content":" */"},{"lineNumber":470,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsOpeningWithinTimeLimit() {"},{"lineNumber":471,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e requiredSessions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":472,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e sessions \u003d fsDb.getFeedbackSessionsPossiblyNeedingOpeningSoonEmail();"},{"lineNumber":473,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration: %d\", sessions.size()));"},{"lineNumber":474,"author":{"gitId":"-"},"content":""},{"lineNumber":475,"author":{"gitId":"-"},"content":" for (FeedbackSession session : sessions) {"},{"lineNumber":476,"author":{"gitId":"-"},"content":" if (session.isOpeningWithinTimeLimit(NUMBER_OF_HOURS_BEFORE_OPENING_SOON_ALERT)"},{"lineNumber":477,"author":{"gitId":"-"},"content":" \u0026\u0026 session.getCourse().getDeletedAt() \u003d\u003d null) {"},{"lineNumber":478,"author":{"gitId":"-"},"content":" requiredSessions.add(session);"},{"lineNumber":479,"author":{"gitId":"-"},"content":" }"},{"lineNumber":480,"author":{"gitId":"-"},"content":" }"},{"lineNumber":481,"author":{"gitId":"-"},"content":""},{"lineNumber":482,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration after filtering: %d\","},{"lineNumber":483,"author":{"gitId":"-"},"content":" requiredSessions.size()));"},{"lineNumber":484,"author":{"gitId":"-"},"content":" return requiredSessions;"},{"lineNumber":485,"author":{"gitId":"-"},"content":" }"},{"lineNumber":486,"author":{"gitId":"-"},"content":""},{"lineNumber":487,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":488,"author":{"gitId":"-"},"content":" * Returns a list of sessions that were closed within past hour."},{"lineNumber":489,"author":{"gitId":"-"},"content":" */"},{"lineNumber":490,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsClosedWithinThePastHour() {"},{"lineNumber":491,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e requiredSessions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":492,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e sessions \u003d fsDb.getFeedbackSessionsPossiblyNeedingClosedEmail();"},{"lineNumber":493,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration: %d\", sessions.size()));"},{"lineNumber":494,"author":{"gitId":"-"},"content":""},{"lineNumber":495,"author":{"gitId":"-"},"content":" for (FeedbackSession session : sessions) {"},{"lineNumber":496,"author":{"gitId":"-"},"content":" // is session closed in the past 1 hour"},{"lineNumber":497,"author":{"gitId":"-"},"content":" if (session.isClosedWithinPastHour()"},{"lineNumber":498,"author":{"gitId":"-"},"content":" \u0026\u0026 session.getCourse().getDeletedAt() \u003d\u003d null) {"},{"lineNumber":499,"author":{"gitId":"-"},"content":" requiredSessions.add(session);"},{"lineNumber":500,"author":{"gitId":"-"},"content":" }"},{"lineNumber":501,"author":{"gitId":"-"},"content":" }"},{"lineNumber":502,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration after filtering: %d\","},{"lineNumber":503,"author":{"gitId":"-"},"content":" requiredSessions.size()));"},{"lineNumber":504,"author":{"gitId":"-"},"content":" return requiredSessions;"},{"lineNumber":505,"author":{"gitId":"-"},"content":" }"},{"lineNumber":506,"author":{"gitId":"-"},"content":""},{"lineNumber":507,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":508,"author":{"gitId":"-"},"content":" * Gets a list of undeleted feedback sessions which start within the last 2 hours"},{"lineNumber":509,"author":{"gitId":"-"},"content":" * and need an open email to be sent."},{"lineNumber":510,"author":{"gitId":"-"},"content":" */"},{"lineNumber":511,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsWhichNeedOpenEmailsToBeSent() {"},{"lineNumber":512,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e sessionsToSendEmailsFor \u003d new ArrayList\u003c\u003e();"},{"lineNumber":513,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e sessions \u003d fsDb.getFeedbackSessionsPossiblyNeedingOpenEmail();"},{"lineNumber":514,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration: %d\", sessions.size()));"},{"lineNumber":515,"author":{"gitId":"-"},"content":""},{"lineNumber":516,"author":{"gitId":"-"},"content":" for (FeedbackSession session : sessions) {"},{"lineNumber":517,"author":{"gitId":"-"},"content":" if (session.isOpened() \u0026\u0026 session.getCourse().getDeletedAt() \u003d\u003d null) {"},{"lineNumber":518,"author":{"gitId":"-"},"content":" sessionsToSendEmailsFor.add(session);"},{"lineNumber":519,"author":{"gitId":"-"},"content":" }"},{"lineNumber":520,"author":{"gitId":"-"},"content":" }"},{"lineNumber":521,"author":{"gitId":"-"},"content":""},{"lineNumber":522,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration after filtering: %d\","},{"lineNumber":523,"author":{"gitId":"-"},"content":" sessionsToSendEmailsFor.size()));"},{"lineNumber":524,"author":{"gitId":"-"},"content":" return sessionsToSendEmailsFor;"},{"lineNumber":525,"author":{"gitId":"-"},"content":" }"},{"lineNumber":526,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":527,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":528,"author":{"gitId":"domoberzin"},"content":" * Gets the expected number of submissions for a feedback session."},{"lineNumber":529,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":530,"author":{"gitId":"domoberzin"},"content":" public int getExpectedTotalSubmission(FeedbackSession fs) {"},{"lineNumber":531,"author":{"gitId":"domoberzin"},"content":" int expectedTotal \u003d 0;"},{"lineNumber":532,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackQuestion\u003e questions \u003d fqLogic.getFeedbackQuestionsForSession(fs);"},{"lineNumber":533,"author":{"gitId":"domoberzin"},"content":" if (fqLogic.hasFeedbackQuestionsForStudents(questions)) {"},{"lineNumber":534,"author":{"gitId":"domoberzin"},"content":" expectedTotal +\u003d usersLogic.getStudentsForCourse(fs.getCourse().getId()).size();"},{"lineNumber":535,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":536,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":537,"author":{"gitId":"domoberzin"},"content":" // Pre-flight check to ensure there are questions for instructors."},{"lineNumber":538,"author":{"gitId":"domoberzin"},"content":" if (!fqLogic.hasFeedbackQuestionsForInstructors(questions, true)) {"},{"lineNumber":539,"author":{"gitId":"domoberzin"},"content":" return expectedTotal;"},{"lineNumber":540,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":541,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":542,"author":{"gitId":"domoberzin"},"content":" List\u003cInstructor\u003e instructors \u003d usersLogic.getInstructorsForCourse(fs.getCourse().getId());"},{"lineNumber":543,"author":{"gitId":"domoberzin"},"content":" if (instructors.isEmpty()) {"},{"lineNumber":544,"author":{"gitId":"domoberzin"},"content":" return expectedTotal;"},{"lineNumber":545,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":546,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":547,"author":{"gitId":"domoberzin"},"content":" // Check presence of questions for instructors."},{"lineNumber":548,"author":{"gitId":"domoberzin"},"content":" if (fqLogic.hasFeedbackQuestionsForInstructors(fqLogic.getFeedbackQuestionsForSession(fs), false)) {"},{"lineNumber":549,"author":{"gitId":"domoberzin"},"content":" expectedTotal +\u003d instructors.size();"},{"lineNumber":550,"author":{"gitId":"domoberzin"},"content":" } else {"},{"lineNumber":551,"author":{"gitId":"domoberzin"},"content":" // No questions for instructors. There must be questions for creator."},{"lineNumber":552,"author":{"gitId":"domoberzin"},"content":" List\u003cInstructor\u003e creators \u003d instructors.stream()"},{"lineNumber":553,"author":{"gitId":"domoberzin"},"content":" .filter(instructor -\u003e fs.getCreatorEmail().equals(instructor.getEmail()))"},{"lineNumber":554,"author":{"gitId":"domoberzin"},"content":" .collect(Collectors.toList());"},{"lineNumber":555,"author":{"gitId":"domoberzin"},"content":" expectedTotal +\u003d creators.size();"},{"lineNumber":556,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":557,"author":{"gitId":"domoberzin"},"content":" return expectedTotal;"},{"lineNumber":558,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":559,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":560,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":561,"author":{"gitId":"domoberzin"},"content":" * Gets the actual number of submissions for a feedback session."},{"lineNumber":562,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":563,"author":{"gitId":"domoberzin"},"content":" public int getActualTotalSubmission(FeedbackSession fs) {"},{"lineNumber":564,"author":{"gitId":"domoberzin"},"content":" return getGiverSetThatAnsweredFeedbackSession(fs).size();"},{"lineNumber":565,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":566,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":65,"dishenggg":10,"-":491}},{"path":"src/main/java/teammates/sqllogic/core/LogicStarter.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import jakarta.servlet.ServletContextEvent;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import jakarta.servlet.ServletContextListener;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.AccountRequestsDb;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.AccountsDb;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.CoursesDb;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.DeadlineExtensionsDb;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackQuestionsDb;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackResponseCommentsDb;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackResponsesDb;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlapi.FeedbackSessionLogsDb;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackSessionsDb;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.NotificationsDb;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.UsageStatisticsDb;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.UsersDb;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":21,"author":{"gitId":"-"},"content":" * Setup in web.xml to register logic classes at application startup."},{"lineNumber":22,"author":{"gitId":"-"},"content":" */"},{"lineNumber":23,"author":{"gitId":"-"},"content":"public class LogicStarter implements ServletContextListener {"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":28,"author":{"gitId":"-"},"content":" * Registers dependencies between different logic classes."},{"lineNumber":29,"author":{"gitId":"-"},"content":" */"},{"lineNumber":30,"author":{"gitId":"-"},"content":" public static void initializeDependencies() {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" AccountsLogic accountsLogic \u003d AccountsLogic.inst();"},{"lineNumber":32,"author":{"gitId":"-"},"content":" AccountRequestsLogic accountRequestsLogic \u003d AccountRequestsLogic.inst();"},{"lineNumber":33,"author":{"gitId":"-"},"content":" CoursesLogic coursesLogic \u003d CoursesLogic.inst();"},{"lineNumber":34,"author":{"gitId":"-"},"content":" DataBundleLogic dataBundleLogic \u003d DataBundleLogic.inst();"},{"lineNumber":35,"author":{"gitId":"-"},"content":" DeadlineExtensionsLogic deadlineExtensionsLogic \u003d DeadlineExtensionsLogic.inst();"},{"lineNumber":36,"author":{"gitId":"-"},"content":" FeedbackSessionsLogic fsLogic \u003d FeedbackSessionsLogic.inst();"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogsLogic fslLogic \u003d FeedbackSessionLogsLogic.inst();"},{"lineNumber":38,"author":{"gitId":"-"},"content":" FeedbackResponsesLogic frLogic \u003d FeedbackResponsesLogic.inst();"},{"lineNumber":39,"author":{"gitId":"-"},"content":" FeedbackResponseCommentsLogic frcLogic \u003d FeedbackResponseCommentsLogic.inst();"},{"lineNumber":40,"author":{"gitId":"-"},"content":" FeedbackQuestionsLogic fqLogic \u003d FeedbackQuestionsLogic.inst();"},{"lineNumber":41,"author":{"gitId":"-"},"content":" NotificationsLogic notificationsLogic \u003d NotificationsLogic.inst();"},{"lineNumber":42,"author":{"gitId":"-"},"content":" UsageStatisticsLogic usageStatisticsLogic \u003d UsageStatisticsLogic.inst();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" UsersLogic usersLogic \u003d UsersLogic.inst();"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" accountRequestsLogic.initLogicDependencies(AccountRequestsDb.inst());"},{"lineNumber":46,"author":{"gitId":"yuanxi1"},"content":" accountsLogic.initLogicDependencies(AccountsDb.inst(), notificationsLogic, usersLogic, coursesLogic);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" coursesLogic.initLogicDependencies(CoursesDb.inst(), fsLogic, usersLogic);"},{"lineNumber":48,"author":{"gitId":"-"},"content":" dataBundleLogic.initLogicDependencies(accountsLogic, accountRequestsLogic, coursesLogic,"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" deadlineExtensionsLogic, fsLogic, fslLogic, fqLogic, frLogic, frcLogic,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" notificationsLogic, usersLogic);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" deadlineExtensionsLogic.initLogicDependencies(DeadlineExtensionsDb.inst(), fsLogic);"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" fsLogic.initLogicDependencies(FeedbackSessionsDb.inst(), coursesLogic, frLogic, fqLogic, usersLogic);"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" fslLogic.initLogicDependencies(FeedbackSessionLogsDb.inst());"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" frLogic.initLogicDependencies(FeedbackResponsesDb.inst(), usersLogic, fqLogic, frcLogic);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" frcLogic.initLogicDependencies(FeedbackResponseCommentsDb.inst());"},{"lineNumber":56,"author":{"gitId":"-"},"content":" fqLogic.initLogicDependencies(FeedbackQuestionsDb.inst(), coursesLogic, frLogic, usersLogic, fsLogic);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" notificationsLogic.initLogicDependencies(NotificationsDb.inst());"},{"lineNumber":58,"author":{"gitId":"-"},"content":" usageStatisticsLogic.initLogicDependencies(UsageStatisticsDb.inst());"},{"lineNumber":59,"author":{"gitId":"-"},"content":" usersLogic.initLogicDependencies(UsersDb.inst(), accountsLogic, frLogic, frcLogic, deadlineExtensionsLogic);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" log.info(\"Initialized dependencies between logic classes\");"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":64,"author":{"gitId":"-"},"content":" public void contextInitialized(ServletContextEvent event) {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" // Invoked by Jetty at application startup."},{"lineNumber":66,"author":{"gitId":"-"},"content":" initializeDependencies();"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":70,"author":{"gitId":"-"},"content":" public void contextDestroyed(ServletContextEvent event) {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" // Nothing to do"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":2,"yuanxi1":1,"dishenggg":4,"-":67}},{"path":"src/main/java/teammates/sqllogic/core/UsersLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"marquestye"},"content":"import static teammates.common.util.Const.ERROR_CREATE_ENTITY_ALREADY_EXISTS;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import static teammates.common.util.Const.ERROR_UPDATE_NON_EXISTENT;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.Comparator;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import java.util.StringJoiner;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPermissionRole;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPrivileges;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EnrollException;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.exception.InstructorUpdateException;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.exception.StudentUpdateException;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.util.RequestTracer;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.UsersDb;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.User;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.InstructorSearchManager;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.StudentSearchManager;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import teammates.ui.request.InstructorCreateRequest;"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":41,"author":{"gitId":"-"},"content":" * Handles operations related to user (instructor \u0026 student)."},{"lineNumber":42,"author":{"gitId":"-"},"content":" *"},{"lineNumber":43,"author":{"gitId":"-"},"content":" * @see User"},{"lineNumber":44,"author":{"gitId":"-"},"content":" * @see UsersDb"},{"lineNumber":45,"author":{"gitId":"-"},"content":" */"},{"lineNumber":46,"author":{"gitId":"-"},"content":"public final class UsersLogic {"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" static final String ERROR_INVALID_TEAM_NAME \u003d"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" \"Team \\\"%s\\\" is detected in both Section \\\"%s\\\" and Section \\\"%s\\\".\";"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" static final String ERROR_INVALID_TEAM_NAME_INSTRUCTION \u003d"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" \"Please use different team names in different sections.\";"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" static final String ERROR_ENROLL_EXCEED_SECTION_LIMIT \u003d"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" \"You are trying enroll more than %s students in section \\\"%s\\\".\";"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" static final String ERROR_ENROLL_EXCEED_SECTION_LIMIT_INSTRUCTION \u003d"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" \"To avoid performance problems, please do not enroll more than %s students in a single section.\";"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" private static final UsersLogic instance \u003d new UsersLogic();"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" private static final int MAX_KEY_REGENERATION_TRIES \u003d 10;"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" private UsersDb usersDb;"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" private AccountsLogic accountsLogic;"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" private FeedbackResponsesLogic feedbackResponsesLogic;"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" private FeedbackResponseCommentsLogic feedbackResponseCommentsLogic;"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" private DeadlineExtensionsLogic deadlineExtensionsLogic;"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" private UsersLogic() {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":73,"author":{"gitId":"-"},"content":" }"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" public static UsersLogic inst() {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" void initLogicDependencies(UsersDb usersDb, AccountsLogic accountsLogic, FeedbackResponsesLogic feedbackResponsesLogic,"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" FeedbackResponseCommentsLogic feedbackResponseCommentsLogic,"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" DeadlineExtensionsLogic deadlineExtensionsLogic) {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" this.usersDb \u003d usersDb;"},{"lineNumber":83,"author":{"gitId":"-"},"content":" this.accountsLogic \u003d accountsLogic;"},{"lineNumber":84,"author":{"gitId":"-"},"content":" this.feedbackResponsesLogic \u003d feedbackResponsesLogic;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" this.feedbackResponseCommentsLogic \u003d feedbackResponseCommentsLogic;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" this.deadlineExtensionsLogic \u003d deadlineExtensionsLogic;"},{"lineNumber":87,"author":{"gitId":"-"},"content":" }"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" private InstructorSearchManager getInstructorSearchManager() {"},{"lineNumber":90,"author":{"gitId":"-"},"content":" return usersDb.getInstructorSearchManager();"},{"lineNumber":91,"author":{"gitId":"-"},"content":" }"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" private StudentSearchManager getStudentSearchManager() {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" return usersDb.getStudentSearchManager();"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":98,"author":{"gitId":"-"},"content":" * Creates or updates search document for the given instructor."},{"lineNumber":99,"author":{"gitId":"-"},"content":" */"},{"lineNumber":100,"author":{"gitId":"-"},"content":" public void putInstructorDocument(Instructor instructor) throws SearchServiceException {"},{"lineNumber":101,"author":{"gitId":"-"},"content":" getInstructorSearchManager().putDocument(instructor);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":105,"author":{"gitId":"-"},"content":" * Creates or updates search document for the given student."},{"lineNumber":106,"author":{"gitId":"-"},"content":" */"},{"lineNumber":107,"author":{"gitId":"-"},"content":" public void putStudentDocument(Student student) throws SearchServiceException {"},{"lineNumber":108,"author":{"gitId":"-"},"content":" getStudentSearchManager().putDocument(student);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" }"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":112,"author":{"gitId":"-"},"content":" * Create an instructor."},{"lineNumber":113,"author":{"gitId":"-"},"content":" *"},{"lineNumber":114,"author":{"gitId":"-"},"content":" * @return the created instructor"},{"lineNumber":115,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the instructor is not valid"},{"lineNumber":116,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the instructor already exists in the"},{"lineNumber":117,"author":{"gitId":"-"},"content":" * database."},{"lineNumber":118,"author":{"gitId":"-"},"content":" */"},{"lineNumber":119,"author":{"gitId":"-"},"content":" public Instructor createInstructor(Instructor instructor)"},{"lineNumber":120,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":121,"author":{"gitId":"mingyuanc"},"content":" if (getInstructorForEmail(instructor.getCourseId(), instructor.getEmail()) !\u003d null) {"},{"lineNumber":122,"author":{"gitId":"mingyuanc"},"content":" throw new EntityAlreadyExistsException(\"Instructor already exists.\");"},{"lineNumber":123,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":124,"author":{"gitId":"-"},"content":" return usersDb.createInstructor(instructor);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" }"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":128,"author":{"gitId":"-"},"content":" * Updates an instructor and cascades to responses and comments if needed."},{"lineNumber":129,"author":{"gitId":"-"},"content":" *"},{"lineNumber":130,"author":{"gitId":"-"},"content":" * @return updated instructor"},{"lineNumber":131,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the instructor update request is invalid"},{"lineNumber":132,"author":{"gitId":"-"},"content":" * @throws InstructorUpdateException if the update violates instructor validity"},{"lineNumber":133,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the instructor does not exist in the database"},{"lineNumber":134,"author":{"gitId":"-"},"content":" */"},{"lineNumber":135,"author":{"gitId":"-"},"content":" public Instructor updateInstructorCascade(String courseId, InstructorCreateRequest instructorRequest) throws"},{"lineNumber":136,"author":{"gitId":"-"},"content":" InvalidParametersException, InstructorUpdateException, EntityDoesNotExistException {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" Instructor instructor;"},{"lineNumber":138,"author":{"gitId":"-"},"content":" String instructorId \u003d instructorRequest.getId();"},{"lineNumber":139,"author":{"gitId":"-"},"content":" if (instructorId \u003d\u003d null) {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" instructor \u003d getInstructorForEmail(courseId, instructorRequest.getEmail());"},{"lineNumber":141,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" instructor \u003d getInstructorByGoogleId(courseId, instructorId);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" }"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":146,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Trying to update an instructor that does not exist.\");"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" verifyAtLeastOneInstructorIsDisplayed("},{"lineNumber":150,"author":{"gitId":"-"},"content":" courseId, instructor.isDisplayedToStudents(), instructorRequest.getIsDisplayedToStudent());"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" String originalEmail \u003d instructor.getEmail();"},{"lineNumber":153,"author":{"gitId":"-"},"content":" boolean needsCascade \u003d false;"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" String newDisplayName \u003d instructorRequest.getDisplayName();"},{"lineNumber":156,"author":{"gitId":"-"},"content":" if (newDisplayName \u003d\u003d null || newDisplayName.isEmpty()) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" newDisplayName \u003d Const.DEFAULT_DISPLAY_NAME_FOR_INSTRUCTOR;"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" instructor.setName(SanitizationHelper.sanitizeName(instructorRequest.getName()));"},{"lineNumber":161,"author":{"gitId":"-"},"content":" instructor.setEmail(SanitizationHelper.sanitizeEmail(instructorRequest.getEmail()));"},{"lineNumber":162,"author":{"gitId":"-"},"content":" instructor.setRole(InstructorPermissionRole.getEnum(instructorRequest.getRoleName()));"},{"lineNumber":163,"author":{"gitId":"-"},"content":" instructor.setPrivileges(new InstructorPrivileges(instructorRequest.getRoleName()));"},{"lineNumber":164,"author":{"gitId":"-"},"content":" instructor.setDisplayName(SanitizationHelper.sanitizeName(newDisplayName));"},{"lineNumber":165,"author":{"gitId":"-"},"content":" instructor.setDisplayedToStudents(instructorRequest.getIsDisplayedToStudent());"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" String newEmail \u003d instructor.getEmail();"},{"lineNumber":168,"author":{"gitId":"-"},"content":""},{"lineNumber":169,"author":{"gitId":"-"},"content":" if (!originalEmail.equals(newEmail)) {"},{"lineNumber":170,"author":{"gitId":"-"},"content":" needsCascade \u003d true;"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" if (!instructor.isValid()) {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(instructor.getInvalidityInfo());"},{"lineNumber":175,"author":{"gitId":"-"},"content":" }"},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":" if (needsCascade) {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" // cascade responses"},{"lineNumber":179,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponse\u003e responsesFromUser \u003d"},{"lineNumber":180,"author":{"gitId":"-"},"content":" feedbackResponsesLogic.getFeedbackResponsesFromGiverForCourse(courseId, originalEmail);"},{"lineNumber":181,"author":{"gitId":"-"},"content":" for (FeedbackResponse responseFromUser : responsesFromUser) {"},{"lineNumber":182,"author":{"gitId":"-"},"content":" FeedbackQuestion question \u003d responseFromUser.getFeedbackQuestion();"},{"lineNumber":183,"author":{"gitId":"-"},"content":" if (question.getGiverType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":184,"author":{"gitId":"-"},"content":" || question.getGiverType() \u003d\u003d FeedbackParticipantType.SELF) {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" responseFromUser.setGiver(newEmail);"},{"lineNumber":186,"author":{"gitId":"-"},"content":" }"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponse\u003e responsesToUser \u003d"},{"lineNumber":189,"author":{"gitId":"-"},"content":" feedbackResponsesLogic.getFeedbackResponsesForRecipientForCourse(courseId, originalEmail);"},{"lineNumber":190,"author":{"gitId":"-"},"content":" for (FeedbackResponse responseToUser : responsesToUser) {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" FeedbackQuestion question \u003d responseToUser.getFeedbackQuestion();"},{"lineNumber":192,"author":{"gitId":"-"},"content":" if (question.getRecipientType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":193,"author":{"gitId":"-"},"content":" || question.getGiverType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":194,"author":{"gitId":"-"},"content":" \u0026\u0026 question.getRecipientType() \u003d\u003d FeedbackParticipantType.SELF) {"},{"lineNumber":195,"author":{"gitId":"-"},"content":" responseToUser.setRecipient(newEmail);"},{"lineNumber":196,"author":{"gitId":"-"},"content":" }"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }"},{"lineNumber":198,"author":{"gitId":"-"},"content":" // cascade comments"},{"lineNumber":199,"author":{"gitId":"-"},"content":" feedbackResponseCommentsLogic.updateFeedbackResponseCommentsEmails(courseId, originalEmail, newEmail);"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }"},{"lineNumber":201,"author":{"gitId":"-"},"content":""},{"lineNumber":202,"author":{"gitId":"-"},"content":" return instructor;"},{"lineNumber":203,"author":{"gitId":"-"},"content":" }"},{"lineNumber":204,"author":{"gitId":"-"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":206,"author":{"gitId":"-"},"content":" * Verifies that at least one instructor is displayed to studens."},{"lineNumber":207,"author":{"gitId":"-"},"content":" *"},{"lineNumber":208,"author":{"gitId":"-"},"content":" * @throws InstructorUpdateException if there is no instructor displayed to students."},{"lineNumber":209,"author":{"gitId":"-"},"content":" */"},{"lineNumber":210,"author":{"gitId":"-"},"content":" void verifyAtLeastOneInstructorIsDisplayed(String courseId, boolean isOriginalInstructorDisplayed,"},{"lineNumber":211,"author":{"gitId":"-"},"content":" boolean isEditedInstructorDisplayed)"},{"lineNumber":212,"author":{"gitId":"-"},"content":" throws InstructorUpdateException {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorsDisplayed \u003d usersDb.getInstructorsDisplayedToStudents(courseId);"},{"lineNumber":214,"author":{"gitId":"-"},"content":" boolean isEditedInstructorChangedToNonVisible \u003d isOriginalInstructorDisplayed \u0026\u0026 !isEditedInstructorDisplayed;"},{"lineNumber":215,"author":{"gitId":"-"},"content":" boolean isNoInstructorMadeVisible \u003d instructorsDisplayed.isEmpty() \u0026\u0026 !isEditedInstructorDisplayed;"},{"lineNumber":216,"author":{"gitId":"-"},"content":""},{"lineNumber":217,"author":{"gitId":"-"},"content":" if (isNoInstructorMadeVisible || instructorsDisplayed.size() \u003d\u003d 1 \u0026\u0026 isEditedInstructorChangedToNonVisible) {"},{"lineNumber":218,"author":{"gitId":"-"},"content":" throw new InstructorUpdateException(\"At least one instructor must be displayed to students\");"},{"lineNumber":219,"author":{"gitId":"-"},"content":" }"},{"lineNumber":220,"author":{"gitId":"-"},"content":" }"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":223,"author":{"gitId":"-"},"content":" * Creates a student."},{"lineNumber":224,"author":{"gitId":"-"},"content":" *"},{"lineNumber":225,"author":{"gitId":"-"},"content":" * @return the created student"},{"lineNumber":226,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the student is not valid"},{"lineNumber":227,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the student already exists in the"},{"lineNumber":228,"author":{"gitId":"-"},"content":" * database."},{"lineNumber":229,"author":{"gitId":"-"},"content":" */"},{"lineNumber":230,"author":{"gitId":"-"},"content":" public Student createStudent(Student student) throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":231,"author":{"gitId":"-"},"content":" return usersDb.createStudent(student);"},{"lineNumber":232,"author":{"gitId":"-"},"content":" }"},{"lineNumber":233,"author":{"gitId":"-"},"content":""},{"lineNumber":234,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":235,"author":{"gitId":"-"},"content":" * Gets instructor associated with {@code id}."},{"lineNumber":236,"author":{"gitId":"-"},"content":" *"},{"lineNumber":237,"author":{"gitId":"-"},"content":" * @param id Id of Instructor."},{"lineNumber":238,"author":{"gitId":"-"},"content":" * @return Returns Instructor if found else null."},{"lineNumber":239,"author":{"gitId":"-"},"content":" */"},{"lineNumber":240,"author":{"gitId":"-"},"content":" public Instructor getInstructor(UUID id) {"},{"lineNumber":241,"author":{"gitId":"-"},"content":" assert id !\u003d null;"},{"lineNumber":242,"author":{"gitId":"-"},"content":""},{"lineNumber":243,"author":{"gitId":"-"},"content":" return usersDb.getInstructor(id);"},{"lineNumber":244,"author":{"gitId":"-"},"content":" }"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":247,"author":{"gitId":"-"},"content":" * Gets the instructor with the specified email."},{"lineNumber":248,"author":{"gitId":"-"},"content":" */"},{"lineNumber":249,"author":{"gitId":"-"},"content":" public Instructor getInstructorForEmail(String courseId, String userEmail) {"},{"lineNumber":250,"author":{"gitId":"-"},"content":" return usersDb.getInstructorForEmail(courseId, userEmail);"},{"lineNumber":251,"author":{"gitId":"-"},"content":" }"},{"lineNumber":252,"author":{"gitId":"-"},"content":""},{"lineNumber":253,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":254,"author":{"gitId":"-"},"content":" * Gets instructors matching any of the specified emails."},{"lineNumber":255,"author":{"gitId":"-"},"content":" */"},{"lineNumber":256,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getInstructorsForEmails(String courseId, List\u003cString\u003e userEmails) {"},{"lineNumber":257,"author":{"gitId":"-"},"content":" return usersDb.getInstructorsForEmails(courseId, userEmails);"},{"lineNumber":258,"author":{"gitId":"-"},"content":" }"},{"lineNumber":259,"author":{"gitId":"-"},"content":""},{"lineNumber":260,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":261,"author":{"gitId":"-"},"content":" * Gets an instructor by associated {@code regkey}."},{"lineNumber":262,"author":{"gitId":"-"},"content":" */"},{"lineNumber":263,"author":{"gitId":"-"},"content":" public Instructor getInstructorByRegistrationKey(String regKey) {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" assert regKey !\u003d null;"},{"lineNumber":265,"author":{"gitId":"-"},"content":""},{"lineNumber":266,"author":{"gitId":"-"},"content":" return usersDb.getInstructorByRegKey(regKey);"},{"lineNumber":267,"author":{"gitId":"-"},"content":" }"},{"lineNumber":268,"author":{"gitId":"-"},"content":""},{"lineNumber":269,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":270,"author":{"gitId":"-"},"content":" * Gets an instructor by associated {@code googleId}."},{"lineNumber":271,"author":{"gitId":"-"},"content":" */"},{"lineNumber":272,"author":{"gitId":"-"},"content":" public Instructor getInstructorByGoogleId(String courseId, String googleId) {"},{"lineNumber":273,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":274,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" return usersDb.getInstructorByGoogleId(courseId, googleId);"},{"lineNumber":277,"author":{"gitId":"-"},"content":" }"},{"lineNumber":278,"author":{"gitId":"-"},"content":""},{"lineNumber":279,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":280,"author":{"gitId":"-"},"content":" * Searches instructors in the whole system. Used by admin only."},{"lineNumber":281,"author":{"gitId":"-"},"content":" *"},{"lineNumber":282,"author":{"gitId":"-"},"content":" * @return List of found instructors in the whole system. Null if no result found."},{"lineNumber":283,"author":{"gitId":"-"},"content":" */"},{"lineNumber":284,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e searchInstructorsInWholeSystem(String queryString)"},{"lineNumber":285,"author":{"gitId":"-"},"content":" throws SearchServiceException {"},{"lineNumber":286,"author":{"gitId":"-"},"content":" return usersDb.searchInstructorsInWholeSystem(queryString);"},{"lineNumber":287,"author":{"gitId":"-"},"content":" }"},{"lineNumber":288,"author":{"gitId":"-"},"content":""},{"lineNumber":289,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":290,"author":{"gitId":"-"},"content":" * Deletes an instructor or student."},{"lineNumber":291,"author":{"gitId":"-"},"content":" */"},{"lineNumber":292,"author":{"gitId":"-"},"content":" public \u003cT extends User\u003e void deleteUser(T user) {"},{"lineNumber":293,"author":{"gitId":"-"},"content":" usersDb.deleteUser(user);"},{"lineNumber":294,"author":{"gitId":"-"},"content":" }"},{"lineNumber":295,"author":{"gitId":"-"},"content":""},{"lineNumber":296,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":297,"author":{"gitId":"-"},"content":" * Deletes an instructor and cascades deletion to"},{"lineNumber":298,"author":{"gitId":"-"},"content":" * associated feedback responses, deadline extensions and comments."},{"lineNumber":299,"author":{"gitId":"-"},"content":" *"},{"lineNumber":300,"author":{"gitId":"-"},"content":" * \u003cp\u003eFails silently if the instructor does not exist."},{"lineNumber":301,"author":{"gitId":"-"},"content":" */"},{"lineNumber":302,"author":{"gitId":"-"},"content":" public void deleteInstructorCascade(String courseId, String email) {"},{"lineNumber":303,"author":{"gitId":"-"},"content":" Instructor instructor \u003d getInstructorForEmail(courseId, email);"},{"lineNumber":304,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":305,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":306,"author":{"gitId":"-"},"content":" }"},{"lineNumber":307,"author":{"gitId":"-"},"content":""},{"lineNumber":308,"author":{"gitId":"-"},"content":" feedbackResponsesLogic.deleteFeedbackResponsesForCourseCascade(courseId, email);"},{"lineNumber":309,"author":{"gitId":"-"},"content":" deadlineExtensionsLogic.deleteDeadlineExtensionsForUser(instructor);"},{"lineNumber":310,"author":{"gitId":"-"},"content":" deleteUser(instructor);"},{"lineNumber":311,"author":{"gitId":"-"},"content":" }"},{"lineNumber":312,"author":{"gitId":"-"},"content":""},{"lineNumber":313,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":314,"author":{"gitId":"-"},"content":" * Gets the list of instructors with co-owner privileges in a course."},{"lineNumber":315,"author":{"gitId":"-"},"content":" */"},{"lineNumber":316,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getCoOwnersForCourse(String courseId) {"},{"lineNumber":317,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors \u003d getInstructorsForCourse(courseId);"},{"lineNumber":318,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorsWithCoOwnerPrivileges \u003d new ArrayList\u003c\u003e();"},{"lineNumber":319,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructors) {"},{"lineNumber":320,"author":{"gitId":"-"},"content":" if (!instructor.hasCoownerPrivileges()) {"},{"lineNumber":321,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":322,"author":{"gitId":"-"},"content":" }"},{"lineNumber":323,"author":{"gitId":"-"},"content":" instructorsWithCoOwnerPrivileges.add(instructor);"},{"lineNumber":324,"author":{"gitId":"-"},"content":" }"},{"lineNumber":325,"author":{"gitId":"-"},"content":" return instructorsWithCoOwnerPrivileges;"},{"lineNumber":326,"author":{"gitId":"-"},"content":" }"},{"lineNumber":327,"author":{"gitId":"-"},"content":""},{"lineNumber":328,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":329,"author":{"gitId":"-"},"content":" * Gets a list of instructors for the specified course."},{"lineNumber":330,"author":{"gitId":"-"},"content":" */"},{"lineNumber":331,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getInstructorsForCourse(String courseId) {"},{"lineNumber":332,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorReturnList \u003d usersDb.getInstructorsForCourse(courseId);"},{"lineNumber":333,"author":{"gitId":"-"},"content":" sortByName(instructorReturnList);"},{"lineNumber":334,"author":{"gitId":"-"},"content":""},{"lineNumber":335,"author":{"gitId":"-"},"content":" return instructorReturnList;"},{"lineNumber":336,"author":{"gitId":"-"},"content":" }"},{"lineNumber":337,"author":{"gitId":"-"},"content":""},{"lineNumber":338,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":339,"author":{"gitId":"-"},"content":" * Check if the instructors with the provided emails exist in the course."},{"lineNumber":340,"author":{"gitId":"-"},"content":" */"},{"lineNumber":341,"author":{"gitId":"-"},"content":" public boolean verifyInstructorsExistInCourse(String courseId, List\u003cString\u003e emails) {"},{"lineNumber":342,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors \u003d usersDb.getInstructorsForEmails(courseId, emails);"},{"lineNumber":343,"author":{"gitId":"-"},"content":" Map\u003cString, User\u003e emailInstructorMap \u003d convertUserListToEmailUserMap(instructors);"},{"lineNumber":344,"author":{"gitId":"-"},"content":""},{"lineNumber":345,"author":{"gitId":"-"},"content":" for (String email : emails) {"},{"lineNumber":346,"author":{"gitId":"-"},"content":" if (!emailInstructorMap.containsKey(email)) {"},{"lineNumber":347,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":348,"author":{"gitId":"-"},"content":" }"},{"lineNumber":349,"author":{"gitId":"-"},"content":" }"},{"lineNumber":350,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":351,"author":{"gitId":"-"},"content":" }"},{"lineNumber":352,"author":{"gitId":"-"},"content":""},{"lineNumber":353,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":354,"author":{"gitId":"-"},"content":" * Gets all instructors associated with a googleId."},{"lineNumber":355,"author":{"gitId":"-"},"content":" */"},{"lineNumber":356,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getInstructorsForGoogleId(String googleId) {"},{"lineNumber":357,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":358,"author":{"gitId":"-"},"content":" return usersDb.getInstructorsForGoogleId(googleId);"},{"lineNumber":359,"author":{"gitId":"-"},"content":" }"},{"lineNumber":360,"author":{"gitId":"-"},"content":""},{"lineNumber":361,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":362,"author":{"gitId":"-"},"content":" * Make the instructor join the course, i.e. associate an account to the instructor with the given googleId."},{"lineNumber":363,"author":{"gitId":"-"},"content":" * Creates an account for the instructor if no existing account is found."},{"lineNumber":364,"author":{"gitId":"-"},"content":" * Preconditions:"},{"lineNumber":365,"author":{"gitId":"-"},"content":" * Parameters regkey and googleId are non-null."},{"lineNumber":366,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the instructor already exists in the database."},{"lineNumber":367,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the instructor parameters are not valid"},{"lineNumber":368,"author":{"gitId":"-"},"content":" */"},{"lineNumber":369,"author":{"gitId":"-"},"content":" public Instructor joinCourseForInstructor(String googleId, Instructor instructor)"},{"lineNumber":370,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" if (googleId \u003d\u003d null) {"},{"lineNumber":372,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(\"Instructor\u0027s googleId cannot be null\");"},{"lineNumber":373,"author":{"gitId":"-"},"content":" }"},{"lineNumber":374,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":375,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(\"Instructor cannot be null\");"},{"lineNumber":376,"author":{"gitId":"-"},"content":" }"},{"lineNumber":377,"author":{"gitId":"-"},"content":""},{"lineNumber":378,"author":{"gitId":"-"},"content":" // setting account for instructor sets it as registered"},{"lineNumber":379,"author":{"gitId":"-"},"content":" if (instructor.getAccount() \u003d\u003d null) {"},{"lineNumber":380,"author":{"gitId":"-"},"content":" Account dbAccount \u003d accountsLogic.getAccountForGoogleId(googleId);"},{"lineNumber":381,"author":{"gitId":"-"},"content":" if (dbAccount !\u003d null) {"},{"lineNumber":382,"author":{"gitId":"-"},"content":" instructor.setAccount(dbAccount);"},{"lineNumber":383,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":384,"author":{"gitId":"-"},"content":" Account account \u003d new Account(googleId, instructor.getName(), instructor.getEmail());"},{"lineNumber":385,"author":{"gitId":"-"},"content":" instructor.setAccount(account);"},{"lineNumber":386,"author":{"gitId":"-"},"content":" accountsLogic.createAccount(account);"},{"lineNumber":387,"author":{"gitId":"-"},"content":" }"},{"lineNumber":388,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":389,"author":{"gitId":"-"},"content":" instructor.setGoogleId(googleId);"},{"lineNumber":390,"author":{"gitId":"-"},"content":" }"},{"lineNumber":391,"author":{"gitId":"-"},"content":" usersDb.updateUser(instructor);"},{"lineNumber":392,"author":{"gitId":"-"},"content":""},{"lineNumber":393,"author":{"gitId":"-"},"content":" // Update the googleId of the student entity for the instructor which was created from sample data."},{"lineNumber":394,"author":{"gitId":"-"},"content":" Student student \u003d getStudentForEmail(instructor.getCourseId(), instructor.getEmail());"},{"lineNumber":395,"author":{"gitId":"-"},"content":" if (student !\u003d null) {"},{"lineNumber":396,"author":{"gitId":"-"},"content":" if (student.getAccount() \u003d\u003d null) {"},{"lineNumber":397,"author":{"gitId":"-"},"content":" Account account \u003d new Account(googleId, student.getName(), student.getEmail());"},{"lineNumber":398,"author":{"gitId":"-"},"content":" student.setAccount(account);"},{"lineNumber":399,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":400,"author":{"gitId":"-"},"content":" student.getAccount().setGoogleId(googleId);"},{"lineNumber":401,"author":{"gitId":"-"},"content":" }"},{"lineNumber":402,"author":{"gitId":"-"},"content":" usersDb.updateUser(student);"},{"lineNumber":403,"author":{"gitId":"-"},"content":" }"},{"lineNumber":404,"author":{"gitId":"-"},"content":""},{"lineNumber":405,"author":{"gitId":"-"},"content":" return instructor;"},{"lineNumber":406,"author":{"gitId":"-"},"content":" }"},{"lineNumber":407,"author":{"gitId":"-"},"content":""},{"lineNumber":408,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":409,"author":{"gitId":"-"},"content":" * Regenerates the registration key for the instructor with email address {@code email} in course {@code courseId}."},{"lineNumber":410,"author":{"gitId":"-"},"content":" *"},{"lineNumber":411,"author":{"gitId":"-"},"content":" * @return the instructor with the new registration key."},{"lineNumber":412,"author":{"gitId":"-"},"content":" * @throws InstructorUpdateException if system was unable to generate a new registration key."},{"lineNumber":413,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the instructor does not exist."},{"lineNumber":414,"author":{"gitId":"-"},"content":" */"},{"lineNumber":415,"author":{"gitId":"-"},"content":" public Instructor regenerateInstructorRegistrationKey(String courseId, String email)"},{"lineNumber":416,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, InstructorUpdateException {"},{"lineNumber":417,"author":{"gitId":"-"},"content":" Instructor instructor \u003d getInstructorForEmail(courseId, email);"},{"lineNumber":418,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":419,"author":{"gitId":"-"},"content":" String errorMessage \u003d String.format("},{"lineNumber":420,"author":{"gitId":"-"},"content":" \"The instructor with the email %s could not be found for the course with ID [%s].\", email, courseId);"},{"lineNumber":421,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(errorMessage);"},{"lineNumber":422,"author":{"gitId":"-"},"content":" }"},{"lineNumber":423,"author":{"gitId":"-"},"content":""},{"lineNumber":424,"author":{"gitId":"-"},"content":" String oldKey \u003d instructor.getRegKey();"},{"lineNumber":425,"author":{"gitId":"-"},"content":" int numTries \u003d 0;"},{"lineNumber":426,"author":{"gitId":"-"},"content":" while (numTries \u003c MAX_KEY_REGENERATION_TRIES) {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" instructor.generateNewRegistrationKey();"},{"lineNumber":428,"author":{"gitId":"-"},"content":" if (!instructor.getRegKey().equals(oldKey)) {"},{"lineNumber":429,"author":{"gitId":"-"},"content":" return instructor;"},{"lineNumber":430,"author":{"gitId":"-"},"content":" }"},{"lineNumber":431,"author":{"gitId":"-"},"content":" numTries++;"},{"lineNumber":432,"author":{"gitId":"-"},"content":" }"},{"lineNumber":433,"author":{"gitId":"-"},"content":""},{"lineNumber":434,"author":{"gitId":"-"},"content":" throw new InstructorUpdateException(\"Could not regenerate a new course registration key for the instructor.\");"},{"lineNumber":435,"author":{"gitId":"-"},"content":" }"},{"lineNumber":436,"author":{"gitId":"-"},"content":""},{"lineNumber":437,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":438,"author":{"gitId":"-"},"content":" * Regenerates the registration key for the student with email address {@code email} in course {@code courseId}."},{"lineNumber":439,"author":{"gitId":"-"},"content":" *"},{"lineNumber":440,"author":{"gitId":"-"},"content":" * @return the student with the new registration key."},{"lineNumber":441,"author":{"gitId":"-"},"content":" * @throws StudentUpdateException if system was unable to generate a new registration key."},{"lineNumber":442,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the student does not exist."},{"lineNumber":443,"author":{"gitId":"-"},"content":" */"},{"lineNumber":444,"author":{"gitId":"-"},"content":" public Student regenerateStudentRegistrationKey(String courseId, String email)"},{"lineNumber":445,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, StudentUpdateException {"},{"lineNumber":446,"author":{"gitId":"-"},"content":" Student student \u003d getStudentForEmail(courseId, email);"},{"lineNumber":447,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":448,"author":{"gitId":"-"},"content":" String errorMessage \u003d String.format("},{"lineNumber":449,"author":{"gitId":"-"},"content":" \"The student with the email %s could not be found for the course with ID [%s].\", email, courseId);"},{"lineNumber":450,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(errorMessage);"},{"lineNumber":451,"author":{"gitId":"-"},"content":" }"},{"lineNumber":452,"author":{"gitId":"-"},"content":""},{"lineNumber":453,"author":{"gitId":"-"},"content":" String oldKey \u003d student.getRegKey();"},{"lineNumber":454,"author":{"gitId":"-"},"content":" int numTries \u003d 0;"},{"lineNumber":455,"author":{"gitId":"-"},"content":" while (numTries \u003c MAX_KEY_REGENERATION_TRIES) {"},{"lineNumber":456,"author":{"gitId":"-"},"content":" student.generateNewRegistrationKey();"},{"lineNumber":457,"author":{"gitId":"-"},"content":" if (!student.getRegKey().equals(oldKey)) {"},{"lineNumber":458,"author":{"gitId":"-"},"content":" return student;"},{"lineNumber":459,"author":{"gitId":"-"},"content":" }"},{"lineNumber":460,"author":{"gitId":"-"},"content":" numTries++;"},{"lineNumber":461,"author":{"gitId":"-"},"content":" }"},{"lineNumber":462,"author":{"gitId":"-"},"content":""},{"lineNumber":463,"author":{"gitId":"-"},"content":" throw new StudentUpdateException(\"Could not regenerate a new course registration key for the student.\");"},{"lineNumber":464,"author":{"gitId":"-"},"content":" }"},{"lineNumber":465,"author":{"gitId":"-"},"content":""},{"lineNumber":466,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":467,"author":{"gitId":"-"},"content":" * Returns true if the user associated with the googleId is an instructor in any course in the system."},{"lineNumber":468,"author":{"gitId":"-"},"content":" */"},{"lineNumber":469,"author":{"gitId":"-"},"content":" public boolean isInstructorInAnyCourse(String googleId) {"},{"lineNumber":470,"author":{"gitId":"-"},"content":" return !usersDb.getAllInstructorsByGoogleId(googleId).isEmpty();"},{"lineNumber":471,"author":{"gitId":"-"},"content":" }"},{"lineNumber":472,"author":{"gitId":"-"},"content":""},{"lineNumber":473,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":474,"author":{"gitId":"-"},"content":" * Gets student associated with {@code id}."},{"lineNumber":475,"author":{"gitId":"-"},"content":" *"},{"lineNumber":476,"author":{"gitId":"-"},"content":" * @param id Id of Student."},{"lineNumber":477,"author":{"gitId":"-"},"content":" * @return Returns Student if found else null."},{"lineNumber":478,"author":{"gitId":"-"},"content":" */"},{"lineNumber":479,"author":{"gitId":"-"},"content":" public Student getStudent(UUID id) {"},{"lineNumber":480,"author":{"gitId":"-"},"content":" assert id !\u003d null;"},{"lineNumber":481,"author":{"gitId":"-"},"content":""},{"lineNumber":482,"author":{"gitId":"-"},"content":" return usersDb.getStudent(id);"},{"lineNumber":483,"author":{"gitId":"-"},"content":" }"},{"lineNumber":484,"author":{"gitId":"-"},"content":""},{"lineNumber":485,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":486,"author":{"gitId":"dishenggg"},"content":" * Gets student reference associated with {@code id}."},{"lineNumber":487,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":488,"author":{"gitId":"dishenggg"},"content":" * @param id Id of Student."},{"lineNumber":489,"author":{"gitId":"dishenggg"},"content":" * @return Returns a proxy for the Student."},{"lineNumber":490,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":491,"author":{"gitId":"dishenggg"},"content":" public Student getStudentReference(UUID id) {"},{"lineNumber":492,"author":{"gitId":"dishenggg"},"content":" assert id !\u003d null;"},{"lineNumber":493,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":494,"author":{"gitId":"dishenggg"},"content":" return usersDb.getStudentReference(id);"},{"lineNumber":495,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":496,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":497,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":498,"author":{"gitId":"-"},"content":" * Gets the student with the specified email."},{"lineNumber":499,"author":{"gitId":"-"},"content":" */"},{"lineNumber":500,"author":{"gitId":"-"},"content":" public Student getStudentForEmail(String courseId, String userEmail) {"},{"lineNumber":501,"author":{"gitId":"-"},"content":" return usersDb.getStudentForEmail(courseId, userEmail);"},{"lineNumber":502,"author":{"gitId":"-"},"content":" }"},{"lineNumber":503,"author":{"gitId":"-"},"content":""},{"lineNumber":504,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":505,"author":{"gitId":"-"},"content":" * Check if the students with the provided emails exist in the course."},{"lineNumber":506,"author":{"gitId":"-"},"content":" */"},{"lineNumber":507,"author":{"gitId":"-"},"content":" public boolean verifyStudentsExistInCourse(String courseId, List\u003cString\u003e emails) {"},{"lineNumber":508,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e students \u003d usersDb.getStudentsForEmails(courseId, emails);"},{"lineNumber":509,"author":{"gitId":"-"},"content":" Map\u003cString, User\u003e emailStudentMap \u003d convertUserListToEmailUserMap(students);"},{"lineNumber":510,"author":{"gitId":"-"},"content":""},{"lineNumber":511,"author":{"gitId":"-"},"content":" for (String email : emails) {"},{"lineNumber":512,"author":{"gitId":"-"},"content":" if (!emailStudentMap.containsKey(email)) {"},{"lineNumber":513,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":514,"author":{"gitId":"-"},"content":" }"},{"lineNumber":515,"author":{"gitId":"-"},"content":" }"},{"lineNumber":516,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":517,"author":{"gitId":"-"},"content":" }"},{"lineNumber":518,"author":{"gitId":"-"},"content":""},{"lineNumber":519,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":520,"author":{"gitId":"-"},"content":" * Gets a list of students with the specified email."},{"lineNumber":521,"author":{"gitId":"-"},"content":" */"},{"lineNumber":522,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getAllStudentsForEmail(String email) {"},{"lineNumber":523,"author":{"gitId":"-"},"content":" return usersDb.getAllStudentsForEmail(email);"},{"lineNumber":524,"author":{"gitId":"-"},"content":" }"},{"lineNumber":525,"author":{"gitId":"-"},"content":""},{"lineNumber":526,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":527,"author":{"gitId":"-"},"content":" * Gets all students associated with a googleId."},{"lineNumber":528,"author":{"gitId":"-"},"content":" */"},{"lineNumber":529,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getAllStudentsByGoogleId(String googleId) {"},{"lineNumber":530,"author":{"gitId":"-"},"content":" return usersDb.getAllStudentsByGoogleId(googleId);"},{"lineNumber":531,"author":{"gitId":"-"},"content":" }"},{"lineNumber":532,"author":{"gitId":"-"},"content":""},{"lineNumber":533,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":534,"author":{"gitId":"-"},"content":" * Gets a list of students for the specified course."},{"lineNumber":535,"author":{"gitId":"-"},"content":" */"},{"lineNumber":536,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsForCourse(String courseId) {"},{"lineNumber":537,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e studentReturnList \u003d usersDb.getStudentsForCourse(courseId);"},{"lineNumber":538,"author":{"gitId":"-"},"content":" sortByName(studentReturnList);"},{"lineNumber":539,"author":{"gitId":"-"},"content":""},{"lineNumber":540,"author":{"gitId":"-"},"content":" return studentReturnList;"},{"lineNumber":541,"author":{"gitId":"-"},"content":" }"},{"lineNumber":542,"author":{"gitId":"-"},"content":""},{"lineNumber":543,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":544,"author":{"gitId":"-"},"content":" * Gets a list of unregistered students for the specified course."},{"lineNumber":545,"author":{"gitId":"-"},"content":" */"},{"lineNumber":546,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getUnregisteredStudentsForCourse(String courseId) {"},{"lineNumber":547,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e students \u003d getStudentsForCourse(courseId);"},{"lineNumber":548,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e unregisteredStudents \u003d new ArrayList\u003c\u003e();"},{"lineNumber":549,"author":{"gitId":"-"},"content":""},{"lineNumber":550,"author":{"gitId":"-"},"content":" for (Student s : students) {"},{"lineNumber":551,"author":{"gitId":"-"},"content":" if (s.getAccount() \u003d\u003d null) {"},{"lineNumber":552,"author":{"gitId":"-"},"content":" unregisteredStudents.add(s);"},{"lineNumber":553,"author":{"gitId":"-"},"content":" }"},{"lineNumber":554,"author":{"gitId":"-"},"content":" }"},{"lineNumber":555,"author":{"gitId":"-"},"content":""},{"lineNumber":556,"author":{"gitId":"-"},"content":" return unregisteredStudents;"},{"lineNumber":557,"author":{"gitId":"-"},"content":" }"},{"lineNumber":558,"author":{"gitId":"-"},"content":""},{"lineNumber":559,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":560,"author":{"gitId":"yuanxi1"},"content":" * Searches for students."},{"lineNumber":561,"author":{"gitId":"yuanxi1"},"content":" *"},{"lineNumber":562,"author":{"gitId":"yuanxi1"},"content":" * @param instructors the constraint that restricts the search result"},{"lineNumber":563,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":564,"author":{"gitId":"yuanxi1"},"content":" public List\u003cStudent\u003e searchStudents(String queryString, List\u003cInstructor\u003e instructors)"},{"lineNumber":565,"author":{"gitId":"yuanxi1"},"content":" throws SearchServiceException {"},{"lineNumber":566,"author":{"gitId":"yuanxi1"},"content":" return usersDb.searchStudents(queryString, instructors);"},{"lineNumber":567,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":568,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":569,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":570,"author":{"gitId":"yuanxi1"},"content":" * This method should be used by admin only since the searching does not restrict the"},{"lineNumber":571,"author":{"gitId":"yuanxi1"},"content":" * visibility according to the logged-in user\u0027s google ID. This is used by admin to"},{"lineNumber":572,"author":{"gitId":"yuanxi1"},"content":" * search students in the whole system."},{"lineNumber":573,"author":{"gitId":"yuanxi1"},"content":" * @return null if no result found"},{"lineNumber":574,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":575,"author":{"gitId":"yuanxi1"},"content":" public List\u003cStudent\u003e searchStudentsInWholeSystem(String queryString)"},{"lineNumber":576,"author":{"gitId":"yuanxi1"},"content":" throws SearchServiceException {"},{"lineNumber":577,"author":{"gitId":"yuanxi1"},"content":" return usersDb.searchStudentsInWholeSystem(queryString);"},{"lineNumber":578,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":579,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":580,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":581,"author":{"gitId":"-"},"content":" * Gets all students of a section."},{"lineNumber":582,"author":{"gitId":"-"},"content":" */"},{"lineNumber":583,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsForSection(String sectionName, String courseId) {"},{"lineNumber":584,"author":{"gitId":"-"},"content":" return usersDb.getStudentsForSection(sectionName, courseId);"},{"lineNumber":585,"author":{"gitId":"-"},"content":" }"},{"lineNumber":586,"author":{"gitId":"-"},"content":""},{"lineNumber":587,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":588,"author":{"gitId":"-"},"content":" * Gets all students of a team."},{"lineNumber":589,"author":{"gitId":"-"},"content":" */"},{"lineNumber":590,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsForTeam(String teamName, String courseId) {"},{"lineNumber":591,"author":{"gitId":"-"},"content":" return usersDb.getStudentsForTeam(teamName, courseId);"},{"lineNumber":592,"author":{"gitId":"-"},"content":" }"},{"lineNumber":593,"author":{"gitId":"-"},"content":""},{"lineNumber":594,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":595,"author":{"gitId":"-"},"content":" * Gets a student by associated {@code regkey}."},{"lineNumber":596,"author":{"gitId":"-"},"content":" */"},{"lineNumber":597,"author":{"gitId":"-"},"content":" public Student getStudentByRegistrationKey(String regKey) {"},{"lineNumber":598,"author":{"gitId":"-"},"content":" assert regKey !\u003d null;"},{"lineNumber":599,"author":{"gitId":"-"},"content":""},{"lineNumber":600,"author":{"gitId":"-"},"content":" return usersDb.getStudentByRegKey(regKey);"},{"lineNumber":601,"author":{"gitId":"-"},"content":" }"},{"lineNumber":602,"author":{"gitId":"-"},"content":""},{"lineNumber":603,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":604,"author":{"gitId":"-"},"content":" * Gets a student by associated {@code googleId}."},{"lineNumber":605,"author":{"gitId":"-"},"content":" */"},{"lineNumber":606,"author":{"gitId":"-"},"content":" public Student getStudentByGoogleId(String courseId, String googleId) {"},{"lineNumber":607,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":608,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":609,"author":{"gitId":"-"},"content":""},{"lineNumber":610,"author":{"gitId":"-"},"content":" return usersDb.getStudentByGoogleId(courseId, googleId);"},{"lineNumber":611,"author":{"gitId":"-"},"content":" }"},{"lineNumber":612,"author":{"gitId":"-"},"content":""},{"lineNumber":613,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":614,"author":{"gitId":"-"},"content":" * Gets all students associated with a googleId."},{"lineNumber":615,"author":{"gitId":"-"},"content":" */"},{"lineNumber":616,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsByGoogleId(String googleId) {"},{"lineNumber":617,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":618,"author":{"gitId":"-"},"content":""},{"lineNumber":619,"author":{"gitId":"-"},"content":" return usersDb.getStudentsByGoogleId(googleId);"},{"lineNumber":620,"author":{"gitId":"-"},"content":" }"},{"lineNumber":621,"author":{"gitId":"-"},"content":""},{"lineNumber":622,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":623,"author":{"gitId":"-"},"content":" * Returns true if the user associated with the googleId is a student in any"},{"lineNumber":624,"author":{"gitId":"-"},"content":" * course in the system."},{"lineNumber":625,"author":{"gitId":"-"},"content":" */"},{"lineNumber":626,"author":{"gitId":"-"},"content":" public boolean isStudentInAnyCourse(String googleId) {"},{"lineNumber":627,"author":{"gitId":"-"},"content":" return !usersDb.getAllStudentsByGoogleId(googleId).isEmpty();"},{"lineNumber":628,"author":{"gitId":"-"},"content":" }"},{"lineNumber":629,"author":{"gitId":"-"},"content":""},{"lineNumber":630,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":631,"author":{"gitId":"-"},"content":" * Gets all instructors and students by {@code googleId}."},{"lineNumber":632,"author":{"gitId":"-"},"content":" */"},{"lineNumber":633,"author":{"gitId":"-"},"content":" public List\u003cUser\u003e getAllUsersByGoogleId(String googleId) {"},{"lineNumber":634,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":635,"author":{"gitId":"-"},"content":""},{"lineNumber":636,"author":{"gitId":"-"},"content":" return usersDb.getAllUsersByGoogleId(googleId);"},{"lineNumber":637,"author":{"gitId":"-"},"content":" }"},{"lineNumber":638,"author":{"gitId":"-"},"content":""},{"lineNumber":639,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":640,"author":{"gitId":"domoberzin"},"content":" * Gets the section with the name in a particular course."},{"lineNumber":641,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":642,"author":{"gitId":"domoberzin"},"content":" public Section getSection(String courseId, String sectionName) {"},{"lineNumber":643,"author":{"gitId":"domoberzin"},"content":" return usersDb.getSection(courseId, sectionName);"},{"lineNumber":644,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":645,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":646,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":647,"author":{"gitId":"domoberzin"},"content":" * Gets the section with the name in a particular course, otherwise creates a new section."},{"lineNumber":648,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":649,"author":{"gitId":"domoberzin"},"content":" public Section getSectionOrCreate(String courseId, String sectionName) {"},{"lineNumber":650,"author":{"gitId":"domoberzin"},"content":" return usersDb.getSectionOrCreate(courseId, sectionName);"},{"lineNumber":651,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":652,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":653,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":654,"author":{"gitId":"domoberzin"},"content":" * Gets the team with the name in a particular session, otherwise creates a new team."},{"lineNumber":655,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":656,"author":{"gitId":"domoberzin"},"content":" public Team getTeamOrCreate(Section section, String teamName) {"},{"lineNumber":657,"author":{"gitId":"domoberzin"},"content":" return usersDb.getTeamOrCreate(section, teamName);"},{"lineNumber":658,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":659,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":660,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":661,"author":{"gitId":"-"},"content":" * Checks if there are any other registered instructors that can modify instructors."},{"lineNumber":662,"author":{"gitId":"-"},"content":" * If there are none, the instructor currently being edited will be granted the privilege"},{"lineNumber":663,"author":{"gitId":"-"},"content":" * of modifying instructors automatically."},{"lineNumber":664,"author":{"gitId":"-"},"content":" *"},{"lineNumber":665,"author":{"gitId":"-"},"content":" * @param courseId Id of the course."},{"lineNumber":666,"author":{"gitId":"-"},"content":" * @param instructorToEdit Instructor that will be edited."},{"lineNumber":667,"author":{"gitId":"-"},"content":" * This may be modified within the method."},{"lineNumber":668,"author":{"gitId":"-"},"content":" */"},{"lineNumber":669,"author":{"gitId":"-"},"content":" public void updateToEnsureValidityOfInstructorsForTheCourse(String courseId, Instructor instructorToEdit) {"},{"lineNumber":670,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors \u003d getInstructorsForCourse(courseId);"},{"lineNumber":671,"author":{"gitId":"-"},"content":" int numOfInstrCanModifyInstructor \u003d 0;"},{"lineNumber":672,"author":{"gitId":"-"},"content":" Instructor instrWithModifyInstructorPrivilege \u003d null;"},{"lineNumber":673,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructors) {"},{"lineNumber":674,"author":{"gitId":"-"},"content":" if (instructor.isAllowedForPrivilege(Const.InstructorPermissions.CAN_MODIFY_INSTRUCTOR)) {"},{"lineNumber":675,"author":{"gitId":"-"},"content":" numOfInstrCanModifyInstructor++;"},{"lineNumber":676,"author":{"gitId":"-"},"content":" instrWithModifyInstructorPrivilege \u003d instructor;"},{"lineNumber":677,"author":{"gitId":"-"},"content":" }"},{"lineNumber":678,"author":{"gitId":"-"},"content":" }"},{"lineNumber":679,"author":{"gitId":"-"},"content":" boolean isLastRegInstructorWithPrivilege \u003d numOfInstrCanModifyInstructor \u003c\u003d 1"},{"lineNumber":680,"author":{"gitId":"-"},"content":" \u0026\u0026 instrWithModifyInstructorPrivilege !\u003d null"},{"lineNumber":681,"author":{"gitId":"-"},"content":" \u0026\u0026 (!instrWithModifyInstructorPrivilege.isRegistered()"},{"lineNumber":682,"author":{"gitId":"-"},"content":" || instrWithModifyInstructorPrivilege.getGoogleId()"},{"lineNumber":683,"author":{"gitId":"-"},"content":" .equals(instructorToEdit.getGoogleId()));"},{"lineNumber":684,"author":{"gitId":"-"},"content":" if (isLastRegInstructorWithPrivilege) {"},{"lineNumber":685,"author":{"gitId":"-"},"content":" instructorToEdit.getPrivileges().updatePrivilege(Const.InstructorPermissions.CAN_MODIFY_INSTRUCTOR, true);"},{"lineNumber":686,"author":{"gitId":"-"},"content":" }"},{"lineNumber":687,"author":{"gitId":"-"},"content":" }"},{"lineNumber":688,"author":{"gitId":"-"},"content":""},{"lineNumber":689,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":690,"author":{"gitId":"-"},"content":" * Deletes a student along with its associated feedback responses, deadline extensions and comments."},{"lineNumber":691,"author":{"gitId":"-"},"content":" *"},{"lineNumber":692,"author":{"gitId":"-"},"content":" * \u003cp\u003eFails silently if the student does not exist."},{"lineNumber":693,"author":{"gitId":"-"},"content":" */"},{"lineNumber":694,"author":{"gitId":"-"},"content":" public void deleteStudentCascade(String courseId, String studentEmail) {"},{"lineNumber":695,"author":{"gitId":"-"},"content":" Student student \u003d getStudentForEmail(courseId, studentEmail);"},{"lineNumber":696,"author":{"gitId":"-"},"content":""},{"lineNumber":697,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":698,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":699,"author":{"gitId":"-"},"content":" }"},{"lineNumber":700,"author":{"gitId":"-"},"content":""},{"lineNumber":701,"author":{"gitId":"-"},"content":" feedbackResponsesLogic"},{"lineNumber":702,"author":{"gitId":"-"},"content":" .deleteFeedbackResponsesForCourseCascade(courseId, studentEmail);"},{"lineNumber":703,"author":{"gitId":"-"},"content":""},{"lineNumber":704,"author":{"gitId":"-"},"content":" if (usersDb.getStudentCountForTeam(student.getTeamName(), student.getCourseId()) \u003d\u003d 1) {"},{"lineNumber":705,"author":{"gitId":"-"},"content":" // the student is the only student in the team, delete responses related to the team"},{"lineNumber":706,"author":{"gitId":"-"},"content":" feedbackResponsesLogic"},{"lineNumber":707,"author":{"gitId":"-"},"content":" .deleteFeedbackResponsesForCourseCascade("},{"lineNumber":708,"author":{"gitId":"-"},"content":" student.getCourse().getId(), student.getTeamName());"},{"lineNumber":709,"author":{"gitId":"-"},"content":" }"},{"lineNumber":710,"author":{"gitId":"-"},"content":""},{"lineNumber":711,"author":{"gitId":"-"},"content":" deadlineExtensionsLogic.deleteDeadlineExtensionsForUser(student);"},{"lineNumber":712,"author":{"gitId":"-"},"content":" deleteUser(student);"},{"lineNumber":713,"author":{"gitId":"-"},"content":" feedbackResponsesLogic.updateRankRecipientQuestionResponsesAfterDeletingStudent(courseId);"},{"lineNumber":714,"author":{"gitId":"-"},"content":" }"},{"lineNumber":715,"author":{"gitId":"-"},"content":""},{"lineNumber":716,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":717,"author":{"gitId":"-"},"content":" * Deletes students in the course cascade their associated responses, deadline extensions, and comments."},{"lineNumber":718,"author":{"gitId":"-"},"content":" */"},{"lineNumber":719,"author":{"gitId":"-"},"content":" public void deleteStudentsInCourseCascade(String courseId) {"},{"lineNumber":720,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e studentsInCourse \u003d getStudentsForCourse(courseId);"},{"lineNumber":721,"author":{"gitId":"-"},"content":""},{"lineNumber":722,"author":{"gitId":"-"},"content":" for (Student student : studentsInCourse) {"},{"lineNumber":723,"author":{"gitId":"-"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":724,"author":{"gitId":"-"},"content":" deleteStudentCascade(courseId, student.getEmail());"},{"lineNumber":725,"author":{"gitId":"-"},"content":" }"},{"lineNumber":726,"author":{"gitId":"-"},"content":" }"},{"lineNumber":727,"author":{"gitId":"-"},"content":""},{"lineNumber":728,"author":{"gitId":"marquestye"},"content":" private boolean isEmailChanged(String originalEmail, String newEmail) {"},{"lineNumber":729,"author":{"gitId":"marquestye"},"content":" return newEmail !\u003d null \u0026\u0026 !originalEmail.equals(newEmail);"},{"lineNumber":730,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":731,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":732,"author":{"gitId":"domoberzin"},"content":" private boolean isTeamChanged(Team originalTeam, Team newTeam) {"},{"lineNumber":733,"author":{"gitId":"domoberzin"},"content":" return newTeam !\u003d null \u0026\u0026 originalTeam !\u003d null"},{"lineNumber":734,"author":{"gitId":"domoberzin"},"content":" \u0026\u0026 !originalTeam.equals(newTeam);"},{"lineNumber":735,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":736,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":737,"author":{"gitId":"domoberzin"},"content":" private boolean isSectionChanged(Section originalSection, Section newSection) {"},{"lineNumber":738,"author":{"gitId":"domoberzin"},"content":" return newSection !\u003d null \u0026\u0026 originalSection !\u003d null"},{"lineNumber":739,"author":{"gitId":"domoberzin"},"content":" \u0026\u0026 !originalSection.equals(newSection);"},{"lineNumber":740,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":741,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":742,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":743,"author":{"gitId":"domoberzin"},"content":" * Updates a student by {@link Student}."},{"lineNumber":744,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":745,"author":{"gitId":"marquestye"},"content":" * \u003cp\u003eIf email changed, update by recreating the student and cascade update all responses"},{"lineNumber":746,"author":{"gitId":"marquestye"},"content":" * and comments the student gives/receives."},{"lineNumber":747,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":748,"author":{"gitId":"domoberzin"},"content":" * \u003cp\u003eIf team changed, cascade delete all responses the student gives/receives within that team."},{"lineNumber":749,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":750,"author":{"gitId":"domoberzin"},"content":" * \u003cp\u003eIf section changed, cascade update all responses the student gives/receives."},{"lineNumber":751,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":752,"author":{"gitId":"domoberzin"},"content":" * @return updated student"},{"lineNumber":753,"author":{"gitId":"domoberzin"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":754,"author":{"gitId":"domoberzin"},"content":" * @throws EntityDoesNotExistException if the student cannot be found"},{"lineNumber":755,"author":{"gitId":"domoberzin"},"content":" * @throws EntityAlreadyExistsException if the student cannot be updated"},{"lineNumber":756,"author":{"gitId":"domoberzin"},"content":" * by recreation because of an existent student"},{"lineNumber":757,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":758,"author":{"gitId":"domoberzin"},"content":" public Student updateStudentCascade(Student student)"},{"lineNumber":759,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException, EntityAlreadyExistsException {"},{"lineNumber":760,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":761,"author":{"gitId":"marquestye"},"content":" String courseId \u003d student.getCourseId();"},{"lineNumber":762,"author":{"gitId":"marquestye"},"content":" Student originalStudent \u003d getStudent(student.getId());"},{"lineNumber":763,"author":{"gitId":"marquestye"},"content":" String originalEmail \u003d originalStudent.getEmail();"},{"lineNumber":764,"author":{"gitId":"marquestye"},"content":" boolean changedEmail \u003d isEmailChanged(originalEmail, student.getEmail());"},{"lineNumber":765,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":766,"author":{"gitId":"marquestye"},"content":" // check for email conflict"},{"lineNumber":767,"author":{"gitId":"marquestye"},"content":" Student s \u003d usersDb.getStudentForEmail(courseId, student.getEmail());"},{"lineNumber":768,"author":{"gitId":"marquestye"},"content":" if (changedEmail \u0026\u0026 s !\u003d null) {"},{"lineNumber":769,"author":{"gitId":"marquestye"},"content":" String errorMessage \u003d String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, s.toString());"},{"lineNumber":770,"author":{"gitId":"marquestye"},"content":" throw new EntityAlreadyExistsException(errorMessage);"},{"lineNumber":771,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":772,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":773,"author":{"gitId":"domoberzin"},"content":" Team originalTeam \u003d originalStudent.getTeam();"},{"lineNumber":774,"author":{"gitId":"domoberzin"},"content":" Section originalSection \u003d originalStudent.getSection();"},{"lineNumber":775,"author":{"gitId":"domoberzin"},"content":" boolean changedTeam \u003d isTeamChanged(originalTeam, student.getTeam());"},{"lineNumber":776,"author":{"gitId":"domoberzin"},"content":" boolean changedSection \u003d isSectionChanged(originalSection, student.getSection());"},{"lineNumber":777,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":778,"author":{"gitId":"marquestye"},"content":" // update student"},{"lineNumber":779,"author":{"gitId":"marquestye"},"content":" usersDb.checkBeforeUpdateStudent(student);"},{"lineNumber":780,"author":{"gitId":"domoberzin"},"content":" originalStudent.setName(student.getName());"},{"lineNumber":781,"author":{"gitId":"domoberzin"},"content":" originalStudent.setTeam(student.getTeam());"},{"lineNumber":782,"author":{"gitId":"domoberzin"},"content":" originalStudent.setEmail(student.getEmail());"},{"lineNumber":783,"author":{"gitId":"domoberzin"},"content":" originalStudent.setComments(student.getComments());"},{"lineNumber":784,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":785,"author":{"gitId":"marquestye"},"content":" // cascade email changes to responses and comments"},{"lineNumber":786,"author":{"gitId":"marquestye"},"content":" if (changedEmail) {"},{"lineNumber":787,"author":{"gitId":"marquestye"},"content":" feedbackResponsesLogic.updateFeedbackResponsesForChangingEmail(courseId, originalEmail, student.getEmail());"},{"lineNumber":788,"author":{"gitId":"marquestye"},"content":" feedbackResponseCommentsLogic.updateFeedbackResponseCommentsEmails(courseId, originalEmail, student.getEmail());"},{"lineNumber":789,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":790,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":791,"author":{"gitId":"domoberzin"},"content":" // adjust submissions if moving to a different team"},{"lineNumber":792,"author":{"gitId":"domoberzin"},"content":" if (changedTeam) {"},{"lineNumber":793,"author":{"gitId":"marquestye"},"content":" feedbackResponsesLogic.updateFeedbackResponsesForChangingTeam(student.getCourse(), student.getEmail(),"},{"lineNumber":794,"author":{"gitId":"marquestye"},"content":" student.getTeam(), originalTeam);"},{"lineNumber":795,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":796,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":797,"author":{"gitId":"domoberzin"},"content":" // update the new section name in responses"},{"lineNumber":798,"author":{"gitId":"domoberzin"},"content":" if (changedSection) {"},{"lineNumber":799,"author":{"gitId":"domoberzin"},"content":" feedbackResponsesLogic.updateFeedbackResponsesForChangingSection("},{"lineNumber":800,"author":{"gitId":"marquestye"},"content":" student.getCourse(), student.getEmail(), student.getSection());"},{"lineNumber":801,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":802,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":803,"author":{"gitId":"marquestye"},"content":" return originalStudent;"},{"lineNumber":804,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":805,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":806,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":807,"author":{"gitId":"-"},"content":" * Resets the googleId associated with the instructor."},{"lineNumber":808,"author":{"gitId":"-"},"content":" */"},{"lineNumber":809,"author":{"gitId":"-"},"content":" public void resetInstructorGoogleId(String email, String courseId, String googleId)"},{"lineNumber":810,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":811,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":812,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":813,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":814,"author":{"gitId":"-"},"content":""},{"lineNumber":815,"author":{"gitId":"-"},"content":" Instructor instructor \u003d getInstructorForEmail(courseId, email);"},{"lineNumber":816,"author":{"gitId":"-"},"content":""},{"lineNumber":817,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":818,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT"},{"lineNumber":819,"author":{"gitId":"-"},"content":" + \"Instructor [courseId\u003d\" + courseId + \", email\u003d\" + email + \"]\");"},{"lineNumber":820,"author":{"gitId":"-"},"content":" }"},{"lineNumber":821,"author":{"gitId":"-"},"content":""},{"lineNumber":822,"author":{"gitId":"-"},"content":" instructor.setAccount(null);"},{"lineNumber":823,"author":{"gitId":"-"},"content":""},{"lineNumber":824,"author":{"gitId":"-"},"content":" if (usersDb.getAllUsersByGoogleId(googleId).isEmpty()) {"},{"lineNumber":825,"author":{"gitId":"-"},"content":" accountsLogic.deleteAccountCascade(googleId);"},{"lineNumber":826,"author":{"gitId":"-"},"content":" }"},{"lineNumber":827,"author":{"gitId":"-"},"content":" }"},{"lineNumber":828,"author":{"gitId":"-"},"content":""},{"lineNumber":829,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":830,"author":{"gitId":"domoberzin"},"content":" * Validates sections for any limit violations and teams for any team name violations."},{"lineNumber":831,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":832,"author":{"gitId":"domoberzin"},"content":" public void validateSectionsAndTeams("},{"lineNumber":833,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e studentList, String courseId) throws EnrollException {"},{"lineNumber":834,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":835,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e mergedList \u003d getMergedList(studentList, courseId);"},{"lineNumber":836,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":837,"author":{"gitId":"domoberzin"},"content":" if (mergedList.size() \u003c 2) { // no conflicts"},{"lineNumber":838,"author":{"gitId":"domoberzin"},"content":" return;"},{"lineNumber":839,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":840,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":841,"author":{"gitId":"domoberzin"},"content":" String errorMessage \u003d getSectionInvalidityInfo(mergedList) + getTeamInvalidityInfo(mergedList);"},{"lineNumber":842,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":843,"author":{"gitId":"domoberzin"},"content":" if (!errorMessage.isEmpty()) {"},{"lineNumber":844,"author":{"gitId":"domoberzin"},"content":" throw new EnrollException(errorMessage);"},{"lineNumber":845,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":846,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":847,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":848,"author":{"gitId":"domoberzin"},"content":" private List\u003cStudent\u003e getMergedList(List\u003cStudent\u003e studentList, String courseId) {"},{"lineNumber":849,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":850,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e mergedList \u003d new ArrayList\u003c\u003e();"},{"lineNumber":851,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e studentsInCourse \u003d getStudentsForCourse(courseId);"},{"lineNumber":852,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":853,"author":{"gitId":"domoberzin"},"content":" for (Student student : studentList) {"},{"lineNumber":854,"author":{"gitId":"domoberzin"},"content":" mergedList.add(student);"},{"lineNumber":855,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":856,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":857,"author":{"gitId":"domoberzin"},"content":" for (Student student : studentsInCourse) {"},{"lineNumber":858,"author":{"gitId":"domoberzin"},"content":" if (!isInEnrollList(student, mergedList)) {"},{"lineNumber":859,"author":{"gitId":"domoberzin"},"content":" mergedList.add(student);"},{"lineNumber":860,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":861,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":862,"author":{"gitId":"domoberzin"},"content":" return mergedList;"},{"lineNumber":863,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":864,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":865,"author":{"gitId":"domoberzin"},"content":" private String getSectionInvalidityInfo(List\u003cStudent\u003e mergedList) {"},{"lineNumber":866,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":867,"author":{"gitId":"domoberzin"},"content":" mergedList.sort(Comparator.comparing((Student student) -\u003e student.getSectionName())"},{"lineNumber":868,"author":{"gitId":"domoberzin"},"content":" .thenComparing(student -\u003e student.getTeamName())"},{"lineNumber":869,"author":{"gitId":"domoberzin"},"content":" .thenComparing(student -\u003e student.getName()));"},{"lineNumber":870,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":871,"author":{"gitId":"domoberzin"},"content":" List\u003cString\u003e invalidSectionList \u003d new ArrayList\u003c\u003e();"},{"lineNumber":872,"author":{"gitId":"domoberzin"},"content":" int studentsCount \u003d 1;"},{"lineNumber":873,"author":{"gitId":"domoberzin"},"content":" for (int i \u003d 1; i \u003c mergedList.size(); i++) {"},{"lineNumber":874,"author":{"gitId":"domoberzin"},"content":" Student currentStudent \u003d mergedList.get(i);"},{"lineNumber":875,"author":{"gitId":"domoberzin"},"content":" Student previousStudent \u003d mergedList.get(i - 1);"},{"lineNumber":876,"author":{"gitId":"domoberzin"},"content":" if (currentStudent.getSectionName().equals(previousStudent.getSectionName())) {"},{"lineNumber":877,"author":{"gitId":"domoberzin"},"content":" studentsCount++;"},{"lineNumber":878,"author":{"gitId":"domoberzin"},"content":" } else {"},{"lineNumber":879,"author":{"gitId":"domoberzin"},"content":" if (studentsCount \u003e Const.SECTION_SIZE_LIMIT) {"},{"lineNumber":880,"author":{"gitId":"domoberzin"},"content":" invalidSectionList.add(previousStudent.getSectionName());"},{"lineNumber":881,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":882,"author":{"gitId":"domoberzin"},"content":" studentsCount \u003d 1;"},{"lineNumber":883,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":884,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":885,"author":{"gitId":"domoberzin"},"content":" if (i \u003d\u003d mergedList.size() - 1 \u0026\u0026 studentsCount \u003e Const.SECTION_SIZE_LIMIT) {"},{"lineNumber":886,"author":{"gitId":"domoberzin"},"content":" invalidSectionList.add(currentStudent.getSectionName());"},{"lineNumber":887,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":888,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":889,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":890,"author":{"gitId":"domoberzin"},"content":" StringJoiner errorMessage \u003d new StringJoiner(\" \");"},{"lineNumber":891,"author":{"gitId":"domoberzin"},"content":" for (String section : invalidSectionList) {"},{"lineNumber":892,"author":{"gitId":"domoberzin"},"content":" errorMessage.add(String.format("},{"lineNumber":893,"author":{"gitId":"domoberzin"},"content":" ERROR_ENROLL_EXCEED_SECTION_LIMIT,"},{"lineNumber":894,"author":{"gitId":"domoberzin"},"content":" Const.SECTION_SIZE_LIMIT, section));"},{"lineNumber":895,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":896,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":897,"author":{"gitId":"domoberzin"},"content":" if (!invalidSectionList.isEmpty()) {"},{"lineNumber":898,"author":{"gitId":"domoberzin"},"content":" errorMessage.add(String.format("},{"lineNumber":899,"author":{"gitId":"domoberzin"},"content":" ERROR_ENROLL_EXCEED_SECTION_LIMIT_INSTRUCTION,"},{"lineNumber":900,"author":{"gitId":"domoberzin"},"content":" Const.SECTION_SIZE_LIMIT));"},{"lineNumber":901,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":902,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":903,"author":{"gitId":"domoberzin"},"content":" return errorMessage.toString();"},{"lineNumber":904,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":905,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":906,"author":{"gitId":"domoberzin"},"content":" private String getTeamInvalidityInfo(List\u003cStudent\u003e mergedList) {"},{"lineNumber":907,"author":{"gitId":"domoberzin"},"content":" StringJoiner errorMessage \u003d new StringJoiner(\" \");"},{"lineNumber":908,"author":{"gitId":"domoberzin"},"content":" mergedList.sort(Comparator.comparing((Student student) -\u003e student.getTeamName())"},{"lineNumber":909,"author":{"gitId":"domoberzin"},"content":" .thenComparing(student -\u003e student.getName()));"},{"lineNumber":910,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":911,"author":{"gitId":"domoberzin"},"content":" List\u003cString\u003e invalidTeamList \u003d new ArrayList\u003c\u003e();"},{"lineNumber":912,"author":{"gitId":"domoberzin"},"content":" for (int i \u003d 1; i \u003c mergedList.size(); i++) {"},{"lineNumber":913,"author":{"gitId":"domoberzin"},"content":" Student currentStudent \u003d mergedList.get(i);"},{"lineNumber":914,"author":{"gitId":"domoberzin"},"content":" Student previousStudent \u003d mergedList.get(i - 1);"},{"lineNumber":915,"author":{"gitId":"domoberzin"},"content":" if (currentStudent.getTeamName().equals(previousStudent.getTeamName())"},{"lineNumber":916,"author":{"gitId":"domoberzin"},"content":" \u0026\u0026 !currentStudent.getSectionName().equals(previousStudent.getSectionName())"},{"lineNumber":917,"author":{"gitId":"domoberzin"},"content":" \u0026\u0026 !invalidTeamList.contains(currentStudent.getTeamName())) {"},{"lineNumber":918,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":919,"author":{"gitId":"domoberzin"},"content":" errorMessage.add(String.format(ERROR_INVALID_TEAM_NAME,"},{"lineNumber":920,"author":{"gitId":"domoberzin"},"content":" currentStudent.getTeamName(),"},{"lineNumber":921,"author":{"gitId":"domoberzin"},"content":" previousStudent.getSectionName(),"},{"lineNumber":922,"author":{"gitId":"domoberzin"},"content":" currentStudent.getSectionName()));"},{"lineNumber":923,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":924,"author":{"gitId":"domoberzin"},"content":" invalidTeamList.add(currentStudent.getTeamName());"},{"lineNumber":925,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":926,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":927,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":928,"author":{"gitId":"domoberzin"},"content":" if (!invalidTeamList.isEmpty()) {"},{"lineNumber":929,"author":{"gitId":"domoberzin"},"content":" errorMessage.add(ERROR_INVALID_TEAM_NAME_INSTRUCTION);"},{"lineNumber":930,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":931,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":932,"author":{"gitId":"domoberzin"},"content":" return errorMessage.toString();"},{"lineNumber":933,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":934,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":935,"author":{"gitId":"domoberzin"},"content":" private boolean isInEnrollList(Student student,"},{"lineNumber":936,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e studentInfoList) {"},{"lineNumber":937,"author":{"gitId":"domoberzin"},"content":" for (Student studentInfo : studentInfoList) {"},{"lineNumber":938,"author":{"gitId":"domoberzin"},"content":" if (studentInfo.getEmail().equalsIgnoreCase(student.getEmail())) {"},{"lineNumber":939,"author":{"gitId":"domoberzin"},"content":" return true;"},{"lineNumber":940,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":941,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":942,"author":{"gitId":"domoberzin"},"content":" return false;"},{"lineNumber":943,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":944,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":945,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":946,"author":{"gitId":"-"},"content":" * Resets the googleId associated with the student."},{"lineNumber":947,"author":{"gitId":"-"},"content":" */"},{"lineNumber":948,"author":{"gitId":"-"},"content":" public void resetStudentGoogleId(String email, String courseId, String googleId)"},{"lineNumber":949,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":950,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":951,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":952,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":953,"author":{"gitId":"-"},"content":""},{"lineNumber":954,"author":{"gitId":"-"},"content":" Student student \u003d getStudentForEmail(courseId, email);"},{"lineNumber":955,"author":{"gitId":"-"},"content":""},{"lineNumber":956,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":957,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT"},{"lineNumber":958,"author":{"gitId":"-"},"content":" + \"Student [courseId\u003d\" + courseId + \", email\u003d\" + email + \"]\");"},{"lineNumber":959,"author":{"gitId":"-"},"content":" }"},{"lineNumber":960,"author":{"gitId":"-"},"content":""},{"lineNumber":961,"author":{"gitId":"-"},"content":" student.setAccount(null);"},{"lineNumber":962,"author":{"gitId":"-"},"content":""},{"lineNumber":963,"author":{"gitId":"-"},"content":" if (usersDb.getAllUsersByGoogleId(googleId).isEmpty()) {"},{"lineNumber":964,"author":{"gitId":"-"},"content":" accountsLogic.deleteAccountCascade(googleId);"},{"lineNumber":965,"author":{"gitId":"-"},"content":" }"},{"lineNumber":966,"author":{"gitId":"-"},"content":" }"},{"lineNumber":967,"author":{"gitId":"-"},"content":""},{"lineNumber":968,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":969,"author":{"gitId":"-"},"content":" * Sorts the instructors list alphabetically by name."},{"lineNumber":970,"author":{"gitId":"-"},"content":" */"},{"lineNumber":971,"author":{"gitId":"-"},"content":" public static \u003cT extends User\u003e void sortByName(List\u003cT\u003e users) {"},{"lineNumber":972,"author":{"gitId":"-"},"content":" users.sort(Comparator.comparing(user -\u003e user.getName().toLowerCase()));"},{"lineNumber":973,"author":{"gitId":"-"},"content":" }"},{"lineNumber":974,"author":{"gitId":"-"},"content":""},{"lineNumber":975,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":976,"author":{"gitId":"-"},"content":" * Checks if an instructor with {@code googleId} can create a course with"},{"lineNumber":977,"author":{"gitId":"-"},"content":" * {@code institute}"},{"lineNumber":978,"author":{"gitId":"-"},"content":" * (ie. has an existing course(s) with the same {@code institute})."},{"lineNumber":979,"author":{"gitId":"-"},"content":" */"},{"lineNumber":980,"author":{"gitId":"-"},"content":" public boolean canInstructorCreateCourse(String googleId, String institute) {"},{"lineNumber":981,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":982,"author":{"gitId":"-"},"content":" assert institute !\u003d null;"},{"lineNumber":983,"author":{"gitId":"-"},"content":""},{"lineNumber":984,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e existingInstructors \u003d getInstructorsForGoogleId(googleId);"},{"lineNumber":985,"author":{"gitId":"-"},"content":" return existingInstructors"},{"lineNumber":986,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":987,"author":{"gitId":"-"},"content":" .filter(Instructor::hasCoownerPrivileges)"},{"lineNumber":988,"author":{"gitId":"-"},"content":" .map(instructor -\u003e instructor.getCourse())"},{"lineNumber":989,"author":{"gitId":"-"},"content":" .anyMatch(course -\u003e institute.equals(course.getInstitute()));"},{"lineNumber":990,"author":{"gitId":"-"},"content":" }"},{"lineNumber":991,"author":{"gitId":"-"},"content":""},{"lineNumber":992,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":993,"author":{"gitId":"-"},"content":" * Utility function to convert user list to email-user map for faster email lookup."},{"lineNumber":994,"author":{"gitId":"-"},"content":" *"},{"lineNumber":995,"author":{"gitId":"-"},"content":" * @param users users list which contains users with unique email addresses"},{"lineNumber":996,"author":{"gitId":"-"},"content":" * @return email-user map for faster email lookup"},{"lineNumber":997,"author":{"gitId":"-"},"content":" */"},{"lineNumber":998,"author":{"gitId":"-"},"content":" private Map\u003cString, User\u003e convertUserListToEmailUserMap(List\u003c? extends User\u003e users) {"},{"lineNumber":999,"author":{"gitId":"-"},"content":" Map\u003cString, User\u003e emailUserMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":1000,"author":{"gitId":"-"},"content":" users.forEach(u -\u003e emailUserMap.put(u.getEmail(), u));"},{"lineNumber":1001,"author":{"gitId":"-"},"content":""},{"lineNumber":1002,"author":{"gitId":"-"},"content":" return emailUserMap;"},{"lineNumber":1003,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1004,"author":{"gitId":"-"},"content":""},{"lineNumber":1005,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":201,"yuanxi1":21,"marquestye":30,"mingyuanc":3,"dishenggg":12,"-":738}},{"path":"src/main/java/teammates/storage/sqlapi/AccountRequestsDb.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static teammates.common.util.Const.ERROR_UPDATE_NON_EXISTENT;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import java.util.ArrayList;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import java.util.Collections;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import java.util.UUID;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import jakarta.persistence.TypedQuery;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaBuilder;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaQuery;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Root;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.AccountRequestSearchManager;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.SearchManagerFactory;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"-"},"content":" * Generates CRUD operations for AccountRequest."},{"lineNumber":27,"author":{"gitId":"-"},"content":" *"},{"lineNumber":28,"author":{"gitId":"-"},"content":" * @see AccountRequest"},{"lineNumber":29,"author":{"gitId":"-"},"content":" */"},{"lineNumber":30,"author":{"gitId":"-"},"content":"public final class AccountRequestsDb extends EntitiesDb {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" private static final AccountRequestsDb instance \u003d new AccountRequestsDb();"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private AccountRequestsDb() {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" // prevent instantiation"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" public static AccountRequestsDb inst() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" public AccountRequestSearchManager getSearchManager() {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" return SearchManagerFactory.getAccountRequestSearchManager();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" }"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":46,"author":{"gitId":"-"},"content":" * Creates an AccountRequest in the database."},{"lineNumber":47,"author":{"gitId":"-"},"content":" */"},{"lineNumber":48,"author":{"gitId":"-"},"content":" public AccountRequest createAccountRequest(AccountRequest accountRequest) throws InvalidParametersException {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" assert accountRequest !\u003d null;"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" if (!accountRequest.isValid()) {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(accountRequest.getInvalidityInfo());"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":" persist(accountRequest);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" return accountRequest;"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":59,"author":{"gitId":"-"},"content":" * Get AccountRequest by {@code id} from the database."},{"lineNumber":60,"author":{"gitId":"-"},"content":" */"},{"lineNumber":61,"author":{"gitId":"-"},"content":" public AccountRequest getAccountRequest(UUID id) {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" assert id !\u003d null;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" return HibernateUtil.get(AccountRequest.class, id);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" }"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":67,"author":{"gitId":"-"},"content":" * Get all Account Requests with {@code status} of \u0027pending\u0027."},{"lineNumber":68,"author":{"gitId":"-"},"content":" */"},{"lineNumber":69,"author":{"gitId":"-"},"content":" public List\u003cAccountRequest\u003e getPendingAccountRequests() {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":71,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cAccountRequest\u003e cr \u003d cb.createQuery(AccountRequest.class);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" Root\u003cAccountRequest\u003e root \u003d cr.from(AccountRequest.class);"},{"lineNumber":73,"author":{"gitId":"-"},"content":" cr.select(root)"},{"lineNumber":74,"author":{"gitId":"-"},"content":" .where(cb.equal(root.get(\"status\"), AccountRequestStatus.PENDING))"},{"lineNumber":75,"author":{"gitId":"-"},"content":" .orderBy(cb.desc(root.get(\"createdAt\")));"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" TypedQuery\u003cAccountRequest\u003e query \u003d HibernateUtil.createQuery(cr);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" return query.getResultList();"},{"lineNumber":79,"author":{"gitId":"-"},"content":" }"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" * Get all Account Requests."},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccountRequest\u003e getAllAccountRequests() {"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":" CriteriaQuery\u003cAccountRequest\u003e cr \u003d cb.createQuery(AccountRequest.class);"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" Root\u003cAccountRequest\u003e root \u003d cr.from(AccountRequest.class);"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" cr.select(root);"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" TypedQuery\u003cAccountRequest\u003e query \u003d HibernateUtil.createQuery(cr);"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" return query.getResultList();"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" * Get all Account Requests for a given {@code email}."},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccountRequest\u003e getApprovedAccountRequestsForEmail(String email) {"},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" CriteriaQuery\u003cAccountRequest\u003e cr \u003d cb.createQuery(AccountRequest.class);"},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":" Root\u003cAccountRequest\u003e root \u003d cr.from(AccountRequest.class);"},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" cr.select(root).where(cb.and(cb.equal(root.get(\"email\"), email),"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" cb.equal(root.get(\"status\"), AccountRequestStatus.APPROVED)));"},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" TypedQuery\u003cAccountRequest\u003e query \u003d HibernateUtil.createQuery(cr);"},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" return query.getResultList();"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":109,"author":{"gitId":"-"},"content":" * Get AccountRequest by {@code registrationKey} from database."},{"lineNumber":110,"author":{"gitId":"-"},"content":" */"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":" public AccountRequest getAccountRequestByRegistrationKey(String registrationKey) {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":113,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cAccountRequest\u003e cr \u003d cb.createQuery(AccountRequest.class);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" Root\u003cAccountRequest\u003e root \u003d cr.from(AccountRequest.class);"},{"lineNumber":115,"author":{"gitId":"-"},"content":" cr.select(root).where(cb.equal(root.get(\"registrationKey\"), registrationKey));"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" TypedQuery\u003cAccountRequest\u003e query \u003d HibernateUtil.createQuery(cr);"},{"lineNumber":118,"author":{"gitId":"-"},"content":" return query.getResultStream().findFirst().orElse(null);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" }"},{"lineNumber":120,"author":{"gitId":"-"},"content":""},{"lineNumber":121,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":122,"author":{"gitId":"-"},"content":" * Get AccountRequest with {@code createdTime} within the times {@code startTime} and {@code endTime}."},{"lineNumber":123,"author":{"gitId":"-"},"content":" */"},{"lineNumber":124,"author":{"gitId":"-"},"content":" public List\u003cAccountRequest\u003e getAccountRequests(Instant startTime, Instant endTime) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":126,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cAccountRequest\u003e cr \u003d cb.createQuery(AccountRequest.class);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" Root\u003cAccountRequest\u003e root \u003d cr.from(AccountRequest.class);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" cr.select(root).where(cb.and(cb.greaterThanOrEqualTo(root.get(\"createdAt\"), startTime),"},{"lineNumber":129,"author":{"gitId":"-"},"content":" cb.lessThanOrEqualTo(root.get(\"createdAt\"), endTime)));"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" TypedQuery\u003cAccountRequest\u003e query \u003d HibernateUtil.createQuery(cr);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" return query.getResultList();"},{"lineNumber":133,"author":{"gitId":"-"},"content":" }"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":136,"author":{"gitId":"-"},"content":" * Updates or creates (if does not exist) the AccountRequest in the database."},{"lineNumber":137,"author":{"gitId":"-"},"content":" */"},{"lineNumber":138,"author":{"gitId":"-"},"content":" public AccountRequest updateAccountRequest(AccountRequest accountRequest)"},{"lineNumber":139,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" assert accountRequest !\u003d null;"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" if (!accountRequest.isValid()) {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(accountRequest.getInvalidityInfo());"},{"lineNumber":144,"author":{"gitId":"-"},"content":" }"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" if (getAccountRequest(accountRequest.getId()) \u003d\u003d null) {"},{"lineNumber":147,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException("},{"lineNumber":148,"author":{"gitId":"-"},"content":" String.format(ERROR_UPDATE_NON_EXISTENT, accountRequest.toString()));"},{"lineNumber":149,"author":{"gitId":"-"},"content":" }"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" merge(accountRequest);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" return accountRequest;"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":156,"author":{"gitId":"-"},"content":" * Deletes an AccountRequest."},{"lineNumber":157,"author":{"gitId":"-"},"content":" */"},{"lineNumber":158,"author":{"gitId":"-"},"content":" public void deleteAccountRequest(AccountRequest accountRequest) {"},{"lineNumber":159,"author":{"gitId":"-"},"content":" if (accountRequest !\u003d null) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" delete(accountRequest);"},{"lineNumber":161,"author":{"gitId":"domoberzin"},"content":" deleteDocumentByAccountRequestId(accountRequest.getId());"},{"lineNumber":162,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":163,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":164,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":165,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":" * Removes search document for the given account request."},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":" public void deleteDocumentByAccountRequestId(UUID accountRequestId) {"},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" if (getSearchManager() !\u003d null) {"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" getSearchManager().deleteDocuments("},{"lineNumber":171,"author":{"gitId":"-"},"content":" Collections.singletonList(accountRequestId.toString()));"},{"lineNumber":172,"author":{"gitId":"-"},"content":" }"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":" * Searches all account requests in the system."},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":" * \u003cp\u003eThis is used by admin to search account requests in the whole system."},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccountRequest\u003e searchAccountRequestsInWholeSystem(String queryString)"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":" throws SearchServiceException {"},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":" if (queryString.trim().isEmpty()) {"},{"lineNumber":184,"author":{"gitId":"domoberzin"},"content":" return new ArrayList\u003c\u003e();"},{"lineNumber":185,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":186,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":187,"author":{"gitId":"domoberzin"},"content":" return getSearchManager().searchAccountRequests(queryString);"},{"lineNumber":188,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":189,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":56,"dishenggg":1,"-":132}},{"path":"src/main/java/teammates/storage/sqlapi/FeedbackQuestionsDb.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"marquestye"},"content":"import static teammates.common.util.Const.ERROR_CREATE_ENTITY_ALREADY_EXISTS;"},{"lineNumber":4,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaBuilder;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaQuery;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Join;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Root;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":14,"author":{"gitId":"marquestye"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":15,"author":{"gitId":"marquestye"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * Handles CRUD operations for feedback questions."},{"lineNumber":23,"author":{"gitId":"-"},"content":" *"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * @see FeedbackQuestion"},{"lineNumber":25,"author":{"gitId":"-"},"content":" */"},{"lineNumber":26,"author":{"gitId":"-"},"content":"public final class FeedbackQuestionsDb extends EntitiesDb {"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" private static final FeedbackQuestionsDb instance \u003d new FeedbackQuestionsDb();"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" private FeedbackQuestionsDb() {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":32,"author":{"gitId":"-"},"content":" }"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" public static FeedbackQuestionsDb inst() {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" }"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":39,"author":{"gitId":"-"},"content":" * Creates a new feedback question."},{"lineNumber":40,"author":{"gitId":"-"},"content":" *"},{"lineNumber":41,"author":{"gitId":"-"},"content":" * @return the created question"},{"lineNumber":42,"author":{"gitId":"marquestye"},"content":" * @throws InvalidParametersException if the question is invalid"},{"lineNumber":43,"author":{"gitId":"marquestye"},"content":" * @throws EntityAlreadyExistsException if the question already exists"},{"lineNumber":44,"author":{"gitId":"-"},"content":" */"},{"lineNumber":45,"author":{"gitId":"marquestye"},"content":" public FeedbackQuestion createFeedbackQuestion(FeedbackQuestion feedbackQuestion)"},{"lineNumber":46,"author":{"gitId":"marquestye"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":47,"author":{"gitId":"marquestye"},"content":" assert feedbackQuestion !\u003d null;"},{"lineNumber":48,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":49,"author":{"gitId":"marquestye"},"content":" if (!feedbackQuestion.isValid()) {"},{"lineNumber":50,"author":{"gitId":"marquestye"},"content":" throw new InvalidParametersException(feedbackQuestion.getInvalidityInfo());"},{"lineNumber":51,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":52,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":53,"author":{"gitId":"marquestye"},"content":" if (getFeedbackQuestion(feedbackQuestion.getId()) !\u003d null) {"},{"lineNumber":54,"author":{"gitId":"marquestye"},"content":" String errorMessage \u003d String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, feedbackQuestion.toString());"},{"lineNumber":55,"author":{"gitId":"marquestye"},"content":" throw new EntityAlreadyExistsException(errorMessage);"},{"lineNumber":56,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":57,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" persist(feedbackQuestion);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" return feedbackQuestion;"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":63,"author":{"gitId":"-"},"content":" * Gets a feedback question."},{"lineNumber":64,"author":{"gitId":"-"},"content":" *"},{"lineNumber":65,"author":{"gitId":"-"},"content":" * @return null if not found"},{"lineNumber":66,"author":{"gitId":"-"},"content":" */"},{"lineNumber":67,"author":{"gitId":"-"},"content":" public FeedbackQuestion getFeedbackQuestion(UUID fqId) {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" assert fqId !\u003d null;"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" return HibernateUtil.get(FeedbackQuestion.class, fqId);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":74,"author":{"gitId":"-"},"content":" * Gets all feedback questions of a session."},{"lineNumber":75,"author":{"gitId":"-"},"content":" */"},{"lineNumber":76,"author":{"gitId":"-"},"content":" public List\u003cFeedbackQuestion\u003e getFeedbackQuestionsForSession(UUID fdId) {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":78,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackQuestion\u003e cq \u003d cb.createQuery(FeedbackQuestion.class);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" Root\u003cFeedbackQuestion\u003e fqRoot \u003d cq.from(FeedbackQuestion.class);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fqJoin \u003d fqRoot.join(\"feedbackSession\");"},{"lineNumber":81,"author":{"gitId":"-"},"content":" cq.select(fqRoot).where(cb.equal(fqJoin.get(\"id\"), fdId));"},{"lineNumber":82,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":83,"author":{"gitId":"-"},"content":" }"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":86,"author":{"gitId":"-"},"content":" * Gets a list of feedback questions by {@code feedbackSession} and {@code giverType}."},{"lineNumber":87,"author":{"gitId":"-"},"content":" *"},{"lineNumber":88,"author":{"gitId":"-"},"content":" * @return null if not found"},{"lineNumber":89,"author":{"gitId":"-"},"content":" */"},{"lineNumber":90,"author":{"gitId":"-"},"content":" public List\u003cFeedbackQuestion\u003e getFeedbackQuestionsForGiverType("},{"lineNumber":91,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession, FeedbackParticipantType giverType) {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":93,"author":{"gitId":"-"},"content":" assert giverType !\u003d null;"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":96,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackQuestion\u003e cq \u003d cb.createQuery(FeedbackQuestion.class);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" Root\u003cFeedbackQuestion\u003e root \u003d cq.from(FeedbackQuestion.class);"},{"lineNumber":98,"author":{"gitId":"-"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fqJoin \u003d root.join(\"feedbackSession\");"},{"lineNumber":99,"author":{"gitId":"-"},"content":" cq.select(root)"},{"lineNumber":100,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":101,"author":{"gitId":"-"},"content":" cb.equal(fqJoin.get(\"id\"), feedbackSession.getId()),"},{"lineNumber":102,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"giverType\"), giverType)));"},{"lineNumber":103,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":107,"author":{"gitId":"-"},"content":" * Deletes a feedback question."},{"lineNumber":108,"author":{"gitId":"-"},"content":" */"},{"lineNumber":109,"author":{"gitId":"-"},"content":" public void deleteFeedbackQuestion(UUID fqId) {"},{"lineNumber":110,"author":{"gitId":"-"},"content":" assert fqId !\u003d null;"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" FeedbackQuestion fq \u003d getFeedbackQuestion(fqId);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" if (fq !\u003d null) {"},{"lineNumber":114,"author":{"gitId":"-"},"content":" delete(fq);"},{"lineNumber":115,"author":{"gitId":"-"},"content":" }"},{"lineNumber":116,"author":{"gitId":"-"},"content":" }"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":119,"author":{"gitId":"-"},"content":" * Checks if there is any feedback questions in a session in a course for the given giver type."},{"lineNumber":120,"author":{"gitId":"-"},"content":" */"},{"lineNumber":121,"author":{"gitId":"-"},"content":" public boolean hasFeedbackQuestionsForGiverType("},{"lineNumber":122,"author":{"gitId":"-"},"content":" String feedbackSessionName, String courseId, FeedbackParticipantType giverType) {"},{"lineNumber":123,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":124,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackQuestion\u003e cq \u003d cb.createQuery(FeedbackQuestion.class);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" Root\u003cFeedbackQuestion\u003e root \u003d cq.from(FeedbackQuestion.class);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d root.join(\"feedbackSession\");"},{"lineNumber":127,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e courseJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" cq.select(root)"},{"lineNumber":130,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":131,"author":{"gitId":"-"},"content":" cb.equal(courseJoin.get(\"id\"), courseId),"},{"lineNumber":132,"author":{"gitId":"-"},"content":" cb.equal(fsJoin.get(\"name\"), feedbackSessionName),"},{"lineNumber":133,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"giverType\"), giverType)));"},{"lineNumber":134,"author":{"gitId":"-"},"content":" return !HibernateUtil.createQuery(cq).getResultList().isEmpty();"},{"lineNumber":135,"author":{"gitId":"-"},"content":" }"},{"lineNumber":136,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":19,"-":117}},{"path":"src/main/java/teammates/storage/sqlapi/FeedbackResponseCommentsDb.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static teammates.common.util.Const.ERROR_CREATE_ENTITY_ALREADY_EXISTS;"},{"lineNumber":4,"author":{"gitId":"mingyuanc"},"content":"import static teammates.common.util.Const.ERROR_UPDATE_NON_EXISTENT;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaBuilder;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaQuery;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Join;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Root;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":15,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"-"},"content":" * Handles CRUD operations for feedbackResponseComments."},{"lineNumber":27,"author":{"gitId":"-"},"content":" *"},{"lineNumber":28,"author":{"gitId":"-"},"content":" * @see FeedbackResponseComment"},{"lineNumber":29,"author":{"gitId":"-"},"content":" */"},{"lineNumber":30,"author":{"gitId":"-"},"content":"public final class FeedbackResponseCommentsDb extends EntitiesDb {"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" private static final FeedbackResponseCommentsDb instance \u003d new FeedbackResponseCommentsDb();"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" private FeedbackResponseCommentsDb() {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":36,"author":{"gitId":"-"},"content":" }"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" public static FeedbackResponseCommentsDb inst() {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":43,"author":{"gitId":"-"},"content":" * Gets a feedbackResponseComment or null if it does not exist."},{"lineNumber":44,"author":{"gitId":"-"},"content":" */"},{"lineNumber":45,"author":{"gitId":"-"},"content":" public FeedbackResponseComment getFeedbackResponseComment(Long frId) {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" assert frId !\u003d null;"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" return HibernateUtil.get(FeedbackResponseComment.class, frId);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":52,"author":{"gitId":"-"},"content":" * Creates a feedbackResponseComment."},{"lineNumber":53,"author":{"gitId":"-"},"content":" */"},{"lineNumber":54,"author":{"gitId":"-"},"content":" public FeedbackResponseComment createFeedbackResponseComment(FeedbackResponseComment feedbackResponseComment)"},{"lineNumber":55,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" assert feedbackResponseComment !\u003d null;"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" if (!feedbackResponseComment.isValid()) {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(feedbackResponseComment.getInvalidityInfo());"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" if (feedbackResponseComment.getId() !\u003d null"},{"lineNumber":63,"author":{"gitId":"-"},"content":" \u0026\u0026 getFeedbackResponseComment(feedbackResponseComment.getId()) !\u003d null) {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" throw new EntityAlreadyExistsException("},{"lineNumber":65,"author":{"gitId":"-"},"content":" String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, feedbackResponseComment.toString()));"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" persist(feedbackResponseComment);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" return feedbackResponseComment;"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":73,"author":{"gitId":"-"},"content":" * Deletes a feedbackResponseComment."},{"lineNumber":74,"author":{"gitId":"-"},"content":" */"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public void deleteFeedbackResponseComment(Long frcId) {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" assert frcId !\u003d null;"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" FeedbackResponseComment frc \u003d getFeedbackResponseComment(frcId);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" if (frc !\u003d null) {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" delete(frc);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":" }"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" * Gets all feedback response comments for a response."},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentsForResponse(UUID feedbackResponseId) {"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" assert feedbackResponseId !\u003d null;"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" CriteriaQuery\u003cFeedbackResponseComment\u003e cq \u003d cb.createQuery(FeedbackResponseComment.class);"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" Root\u003cFeedbackResponseComment\u003e root \u003d cq.from(FeedbackResponseComment.class);"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":" Join\u003cFeedbackResponseComment, FeedbackResponse\u003e frJoin \u003d root.join(\"feedbackResponse\");"},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":" cq.select(root)"},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" .where(cb.and("},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" cb.equal(frJoin.get(\"id\"), feedbackResponseId)));"},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":102,"author":{"gitId":"-"},"content":" * Gets the comment associated with the feedback response."},{"lineNumber":103,"author":{"gitId":"-"},"content":" */"},{"lineNumber":104,"author":{"gitId":"-"},"content":" public FeedbackResponseComment getFeedbackResponseCommentForResponseFromParticipant("},{"lineNumber":105,"author":{"gitId":"-"},"content":" UUID feedbackResponseId) {"},{"lineNumber":106,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":107,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackResponseComment\u003e cq \u003d cb.createQuery(FeedbackResponseComment.class);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponseComment\u003e root \u003d cq.from(FeedbackResponseComment.class);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponseComment, FeedbackResponse\u003e frJoin \u003d root.join(\"feedbackResponse\");"},{"lineNumber":110,"author":{"gitId":"-"},"content":" cq.select(root)"},{"lineNumber":111,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":112,"author":{"gitId":"-"},"content":" cb.equal(frJoin.get(\"id\"), feedbackResponseId)));"},{"lineNumber":113,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cq).getResultStream().findFirst().orElse(null);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":117,"author":{"gitId":"-"},"content":" * Updates the giver email for all of the giver\u0027s comments in a course."},{"lineNumber":118,"author":{"gitId":"-"},"content":" */"},{"lineNumber":119,"author":{"gitId":"-"},"content":" public void updateGiverEmailOfFeedbackResponseComments(String courseId, String oldEmail, String updatedEmail) {"},{"lineNumber":120,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":121,"author":{"gitId":"-"},"content":" assert oldEmail !\u003d null;"},{"lineNumber":122,"author":{"gitId":"-"},"content":" assert updatedEmail !\u003d null;"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" if (oldEmail.equals(updatedEmail)) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":126,"author":{"gitId":"-"},"content":" }"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponseComment\u003e responseComments \u003d"},{"lineNumber":129,"author":{"gitId":"-"},"content":" getFeedbackResponseCommentEntitiesForGiverInCourse(courseId, oldEmail);"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" for (FeedbackResponseComment responseComment : responseComments) {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" responseComment.setGiver(updatedEmail);"},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" merge(responseComment);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" }"},{"lineNumber":135,"author":{"gitId":"-"},"content":" }"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":" * Updates the last editor to a new one for all comments in a course."},{"lineNumber":139,"author":{"gitId":"-"},"content":" */"},{"lineNumber":140,"author":{"gitId":"-"},"content":" public void updateLastEditorEmailOfFeedbackResponseComments(String courseId, String oldEmail, String updatedEmail) {"},{"lineNumber":141,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":142,"author":{"gitId":"-"},"content":" assert oldEmail !\u003d null;"},{"lineNumber":143,"author":{"gitId":"-"},"content":" assert updatedEmail !\u003d null;"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" if (oldEmail.equals(updatedEmail)) {"},{"lineNumber":146,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponseComment\u003e responseComments \u003d"},{"lineNumber":150,"author":{"gitId":"-"},"content":" getFeedbackResponseCommentEntitiesForLastEditorInCourse(courseId, oldEmail);"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" for (FeedbackResponseComment responseComment : responseComments) {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" responseComment.setLastEditorEmail(updatedEmail);"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":" }"},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"-"},"content":" private List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentEntitiesForGiverInCourse("},{"lineNumber":158,"author":{"gitId":"-"},"content":" String courseId, String giver) {"},{"lineNumber":159,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":160,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackResponseComment\u003e cq \u003d cb.createQuery(FeedbackResponseComment.class);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponseComment\u003e root \u003d cq.from(FeedbackResponseComment.class);"},{"lineNumber":162,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponseComment, FeedbackResponse\u003e frJoin \u003d root.join(\"feedbackResponse\");"},{"lineNumber":163,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d frJoin.join(\"feedbackQuestion\");"},{"lineNumber":164,"author":{"gitId":"-"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":165,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e cJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" cq.select(root)"},{"lineNumber":168,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":169,"author":{"gitId":"-"},"content":" cb.equal(cJoin.get(\"id\"), courseId),"},{"lineNumber":170,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"giver\"), giver)));"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" private List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentEntitiesForLastEditorInCourse("},{"lineNumber":176,"author":{"gitId":"-"},"content":" String courseId, String lastEditorEmail) {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":178,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackResponseComment\u003e cq \u003d cb.createQuery(FeedbackResponseComment.class);"},{"lineNumber":179,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponseComment\u003e root \u003d cq.from(FeedbackResponseComment.class);"},{"lineNumber":180,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponseComment, FeedbackResponse\u003e frJoin \u003d root.join(\"feedbackResponse\");"},{"lineNumber":181,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d frJoin.join(\"feedbackQuestion\");"},{"lineNumber":182,"author":{"gitId":"-"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":183,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e cJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":184,"author":{"gitId":"-"},"content":""},{"lineNumber":185,"author":{"gitId":"-"},"content":" cq.select(root)"},{"lineNumber":186,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":187,"author":{"gitId":"-"},"content":" cb.equal(cJoin.get(\"id\"), courseId),"},{"lineNumber":188,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"lastEditorEmail\"), lastEditorEmail)));"},{"lineNumber":189,"author":{"gitId":"-"},"content":""},{"lineNumber":190,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":191,"author":{"gitId":"-"},"content":" }"},{"lineNumber":192,"author":{"gitId":"-"},"content":""},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" * Updates the feedback response comment."},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":196,"author":{"gitId":"mingyuanc"},"content":" public FeedbackResponseComment updateFeedbackResponseComment(FeedbackResponseComment feedbackResponseComment)"},{"lineNumber":197,"author":{"gitId":"mingyuanc"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" assert feedbackResponseComment !\u003d null;"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":200,"author":{"gitId":"mingyuanc"},"content":" if (!feedbackResponseComment.isValid()) {"},{"lineNumber":201,"author":{"gitId":"mingyuanc"},"content":" throw new InvalidParametersException(feedbackResponseComment.getInvalidityInfo());"},{"lineNumber":202,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":203,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":204,"author":{"gitId":"mingyuanc"},"content":" if (getFeedbackResponseComment(feedbackResponseComment.getId()) \u003d\u003d null) {"},{"lineNumber":205,"author":{"gitId":"mingyuanc"},"content":" throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT);"},{"lineNumber":206,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":207,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" return merge(feedbackResponseComment);"},{"lineNumber":209,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":210,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":211,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":212,"author":{"gitId":"xenosf"},"content":" * Gets all comments in a feedback session of a course."},{"lineNumber":213,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentsForSession("},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" String courseId, String feedbackSessionName) {"},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" assert courseId !\u003d null;"},{"lineNumber":217,"author":{"gitId":"xenosf"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":218,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":219,"author":{"gitId":"xenosf"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":220,"author":{"gitId":"xenosf"},"content":" CriteriaQuery\u003cFeedbackResponseComment\u003e cq \u003d cb.createQuery(FeedbackResponseComment.class);"},{"lineNumber":221,"author":{"gitId":"xenosf"},"content":" Root\u003cFeedbackResponseComment\u003e root \u003d cq.from(FeedbackResponseComment.class);"},{"lineNumber":222,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponseComment, FeedbackResponse\u003e frJoin \u003d root.join(\"feedbackResponse\");"},{"lineNumber":223,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d frJoin.join(\"feedbackQuestion\");"},{"lineNumber":224,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":225,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackSession, Course\u003e cJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":226,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":227,"author":{"gitId":"xenosf"},"content":" cq.select(root)"},{"lineNumber":228,"author":{"gitId":"xenosf"},"content":" .where(cb.and("},{"lineNumber":229,"author":{"gitId":"xenosf"},"content":" cb.equal(cJoin.get(\"id\"), courseId),"},{"lineNumber":230,"author":{"gitId":"xenosf"},"content":" cb.equal(fsJoin.get(\"name\"), feedbackSessionName)"},{"lineNumber":231,"author":{"gitId":"xenosf"},"content":" ));"},{"lineNumber":232,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":233,"author":{"gitId":"xenosf"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":234,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":235,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":236,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":237,"author":{"gitId":"xenosf"},"content":" * Gets all comments of a feedback question of a course."},{"lineNumber":238,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":239,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentsForQuestion(UUID questionId) {"},{"lineNumber":240,"author":{"gitId":"xenosf"},"content":" assert questionId !\u003d null;"},{"lineNumber":241,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":242,"author":{"gitId":"xenosf"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":243,"author":{"gitId":"xenosf"},"content":" CriteriaQuery\u003cFeedbackResponseComment\u003e cq \u003d cb.createQuery(FeedbackResponseComment.class);"},{"lineNumber":244,"author":{"gitId":"xenosf"},"content":" Root\u003cFeedbackResponseComment\u003e root \u003d cq.from(FeedbackResponseComment.class);"},{"lineNumber":245,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponseComment, FeedbackResponse\u003e frJoin \u003d root.join(\"feedbackResponse\");"},{"lineNumber":246,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d frJoin.join(\"feedbackQuestion\");"},{"lineNumber":247,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":248,"author":{"gitId":"xenosf"},"content":" cq.select(root)"},{"lineNumber":249,"author":{"gitId":"xenosf"},"content":" .where(cb.and("},{"lineNumber":250,"author":{"gitId":"xenosf"},"content":" cb.equal(fqJoin.get(\"id\"), questionId)));"},{"lineNumber":251,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":252,"author":{"gitId":"xenosf"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":253,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":254,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":255,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":256,"author":{"gitId":"xenosf"},"content":" * Gets all comments in the given session where the giver or recipient is in the given section."},{"lineNumber":257,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":258,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentsForSessionInSection("},{"lineNumber":259,"author":{"gitId":"xenosf"},"content":" String courseId, String feedbackSessionName, String sectionName) {"},{"lineNumber":260,"author":{"gitId":"xenosf"},"content":" assert courseId !\u003d null;"},{"lineNumber":261,"author":{"gitId":"xenosf"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":262,"author":{"gitId":"xenosf"},"content":" assert sectionName !\u003d null;"},{"lineNumber":263,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":264,"author":{"gitId":"xenosf"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":265,"author":{"gitId":"xenosf"},"content":" CriteriaQuery\u003cFeedbackResponseComment\u003e cq \u003d cb.createQuery(FeedbackResponseComment.class);"},{"lineNumber":266,"author":{"gitId":"xenosf"},"content":" Root\u003cFeedbackResponseComment\u003e root \u003d cq.from(FeedbackResponseComment.class);"},{"lineNumber":267,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponseComment, FeedbackResponse\u003e frJoin \u003d root.join(\"feedbackResponse\");"},{"lineNumber":268,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d frJoin.join(\"feedbackQuestion\");"},{"lineNumber":269,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":270,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackSession, Course\u003e cJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":271,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":272,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponseComment, Section\u003e giverJoin \u003d root.join(\"giverSection\");"},{"lineNumber":273,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponseComment, Section\u003e recipientJoin \u003d root.join(\"recipientSection\");"},{"lineNumber":274,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":275,"author":{"gitId":"xenosf"},"content":" cq.select(root)"},{"lineNumber":276,"author":{"gitId":"xenosf"},"content":" .where(cb.and("},{"lineNumber":277,"author":{"gitId":"xenosf"},"content":" cb.equal(cJoin.get(\"id\"), courseId),"},{"lineNumber":278,"author":{"gitId":"xenosf"},"content":" cb.equal(fsJoin.get(\"name\"), feedbackSessionName),"},{"lineNumber":279,"author":{"gitId":"xenosf"},"content":" cb.or("},{"lineNumber":280,"author":{"gitId":"xenosf"},"content":" cb.equal(giverJoin.get(\"name\"), sectionName),"},{"lineNumber":281,"author":{"gitId":"xenosf"},"content":" cb.equal(recipientJoin.get(\"name\"), sectionName))"},{"lineNumber":282,"author":{"gitId":"xenosf"},"content":" ));"},{"lineNumber":283,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":284,"author":{"gitId":"xenosf"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":285,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":286,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":287,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":288,"author":{"gitId":"xenosf"},"content":" * Gets all comments for a question where the giver or recipient is in the given section."},{"lineNumber":289,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":290,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentsForQuestionInSection("},{"lineNumber":291,"author":{"gitId":"xenosf"},"content":" UUID questionId, String sectionName) {"},{"lineNumber":292,"author":{"gitId":"xenosf"},"content":" assert questionId !\u003d null;"},{"lineNumber":293,"author":{"gitId":"xenosf"},"content":" assert sectionName !\u003d null;"},{"lineNumber":294,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":295,"author":{"gitId":"xenosf"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":296,"author":{"gitId":"xenosf"},"content":" CriteriaQuery\u003cFeedbackResponseComment\u003e cq \u003d cb.createQuery(FeedbackResponseComment.class);"},{"lineNumber":297,"author":{"gitId":"xenosf"},"content":" Root\u003cFeedbackResponseComment\u003e root \u003d cq.from(FeedbackResponseComment.class);"},{"lineNumber":298,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponseComment, FeedbackResponse\u003e frJoin \u003d root.join(\"feedbackResponse\");"},{"lineNumber":299,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d frJoin.join(\"feedbackQuestion\");"},{"lineNumber":300,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":301,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponseComment, Section\u003e giverJoin \u003d root.join(\"giverSection\");"},{"lineNumber":302,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponseComment, Section\u003e recipientJoin \u003d root.join(\"recipientSection\");"},{"lineNumber":303,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":304,"author":{"gitId":"xenosf"},"content":" cq.select(root)"},{"lineNumber":305,"author":{"gitId":"xenosf"},"content":" .where(cb.and("},{"lineNumber":306,"author":{"gitId":"xenosf"},"content":" cb.equal(fqJoin.get(\"id\"), questionId),"},{"lineNumber":307,"author":{"gitId":"xenosf"},"content":" cb.or("},{"lineNumber":308,"author":{"gitId":"xenosf"},"content":" cb.equal(giverJoin.get(\"name\"), sectionName),"},{"lineNumber":309,"author":{"gitId":"xenosf"},"content":" cb.equal(recipientJoin.get(\"name\"), sectionName))"},{"lineNumber":310,"author":{"gitId":"xenosf"},"content":" ));"},{"lineNumber":311,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":312,"author":{"gitId":"xenosf"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":313,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":314,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":315,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":26,"xenosf":105,"mingyuanc":12,"-":172}},{"path":"src/main/java/teammates/storage/sqlapi/FeedbackResponsesDb.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static teammates.common.util.Const.ERROR_CREATE_ENTITY_ALREADY_EXISTS;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import static teammates.common.util.Const.ERROR_UPDATE_NON_EXISTENT;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaBuilder;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaDelete;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaQuery;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Join;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Predicate;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Root;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Subquery;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.FeedbackResultFetchType;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":29,"author":{"gitId":"-"},"content":" * Handles CRUD operations for feedbackResponses."},{"lineNumber":30,"author":{"gitId":"-"},"content":" *"},{"lineNumber":31,"author":{"gitId":"-"},"content":" * @see FeedbackResponse"},{"lineNumber":32,"author":{"gitId":"-"},"content":" */"},{"lineNumber":33,"author":{"gitId":"-"},"content":"public final class FeedbackResponsesDb extends EntitiesDb {"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" private static final FeedbackResponsesDb instance \u003d new FeedbackResponsesDb();"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" private FeedbackResponsesDb() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" public static FeedbackResponsesDb inst() {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" }"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":46,"author":{"gitId":"-"},"content":" * Gets a feedbackResponse or null if it does not exist."},{"lineNumber":47,"author":{"gitId":"-"},"content":" */"},{"lineNumber":48,"author":{"gitId":"-"},"content":" public FeedbackResponse getFeedbackResponse(UUID frId) {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" assert frId !\u003d null;"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" return HibernateUtil.get(FeedbackResponse.class, frId);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" }"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":55,"author":{"gitId":"-"},"content":" * Gets all responses given by a user in a course."},{"lineNumber":56,"author":{"gitId":"-"},"content":" */"},{"lineNumber":57,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesFromGiverForCourse("},{"lineNumber":58,"author":{"gitId":"-"},"content":" String courseId, String giver) {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":60,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cr \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponse\u003e frRoot \u003d cr.from(FeedbackResponse.class);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d frRoot.join(\"feedbackQuestion\");"},{"lineNumber":63,"author":{"gitId":"-"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":64,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e cJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" cr.select(frRoot)"},{"lineNumber":67,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":68,"author":{"gitId":"-"},"content":" cb.equal(cJoin.get(\"id\"), courseId),"},{"lineNumber":69,"author":{"gitId":"-"},"content":" cb.equal(frRoot.get(\"giver\"), giver)));"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":75,"author":{"gitId":"-"},"content":" * Gets all responses given to a user in a course."},{"lineNumber":76,"author":{"gitId":"-"},"content":" */"},{"lineNumber":77,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForRecipientForCourse(String courseId, String recipient) {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":79,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cr \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponse\u003e frRoot \u003d cr.from(FeedbackResponse.class);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d frRoot.join(\"feedbackQuestion\");"},{"lineNumber":82,"author":{"gitId":"-"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":83,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e cJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" cr.select(frRoot)"},{"lineNumber":86,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":87,"author":{"gitId":"-"},"content":" cb.equal(cJoin.get(\"id\"), courseId),"},{"lineNumber":88,"author":{"gitId":"-"},"content":" cb.equal(frRoot.get(\"recipient\"), recipient)));"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":91,"author":{"gitId":"-"},"content":" }"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":94,"author":{"gitId":"-"},"content":" * Creates a feedbackResponse."},{"lineNumber":95,"author":{"gitId":"-"},"content":" */"},{"lineNumber":96,"author":{"gitId":"-"},"content":" public FeedbackResponse createFeedbackResponse(FeedbackResponse feedbackResponse)"},{"lineNumber":97,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" assert feedbackResponse !\u003d null;"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" if (!feedbackResponse.isValid()) {"},{"lineNumber":101,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(feedbackResponse.getInvalidityInfo());"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" if (getFeedbackResponse(feedbackResponse.getId()) !\u003d null) {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" throw new EntityAlreadyExistsException("},{"lineNumber":106,"author":{"gitId":"-"},"content":" String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, feedbackResponse.toString()));"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" persist(feedbackResponse);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" return feedbackResponse;"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":114,"author":{"gitId":"-"},"content":" * Deletes a feedbackResponse."},{"lineNumber":115,"author":{"gitId":"-"},"content":" */"},{"lineNumber":116,"author":{"gitId":"-"},"content":" public void deleteFeedbackResponse(FeedbackResponse feedbackResponse) {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" if (feedbackResponse !\u003d null) {"},{"lineNumber":118,"author":{"gitId":"-"},"content":" delete(feedbackResponse);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" }"},{"lineNumber":120,"author":{"gitId":"-"},"content":" }"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":123,"author":{"gitId":"-"},"content":" * Gets the feedback responses for a feedback question."},{"lineNumber":124,"author":{"gitId":"-"},"content":" * @param feedbackQuestionId the Id of the feedback question."},{"lineNumber":125,"author":{"gitId":"-"},"content":" * @param giverEmail the email of the response giver."},{"lineNumber":126,"author":{"gitId":"-"},"content":" */"},{"lineNumber":127,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesFromGiverForQuestion("},{"lineNumber":128,"author":{"gitId":"-"},"content":" UUID feedbackQuestionId, String giverEmail) {"},{"lineNumber":129,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":130,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cq \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponse\u003e root \u003d cq.from(FeedbackResponse.class);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e frJoin \u003d root.join(\"feedbackQuestion\");"},{"lineNumber":133,"author":{"gitId":"-"},"content":" cq.select(root)"},{"lineNumber":134,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":135,"author":{"gitId":"-"},"content":" cb.equal(frJoin.get(\"id\"), feedbackQuestionId),"},{"lineNumber":136,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"giver\"), giverEmail)));"},{"lineNumber":137,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":141,"author":{"gitId":"-"},"content":" * Deletes all feedback responses of a question cascade its associated comments."},{"lineNumber":142,"author":{"gitId":"-"},"content":" */"},{"lineNumber":143,"author":{"gitId":"-"},"content":" public void deleteFeedbackResponsesForQuestionCascade(UUID feedbackQuestionId) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":145,"author":{"gitId":"-"},"content":" CriteriaDelete\u003cFeedbackResponse\u003e cd \u003d cb.createCriteriaDelete(FeedbackResponse.class);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponse\u003e frRoot \u003d cd.from(FeedbackResponse.class);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" Subquery\u003cUUID\u003e subquery \u003d cd.subquery(UUID.class);"},{"lineNumber":148,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponse\u003e subqueryRoot \u003d subquery.from(FeedbackResponse.class);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e sqJoin \u003d subqueryRoot.join(\"feedbackQuestion\");"},{"lineNumber":150,"author":{"gitId":"-"},"content":" subquery.select(subqueryRoot.get(\"id\"));"},{"lineNumber":151,"author":{"gitId":"-"},"content":" subquery.where(cb.equal(sqJoin.get(\"id\"), feedbackQuestionId));"},{"lineNumber":152,"author":{"gitId":"-"},"content":" cd.where(cb.in(frRoot.get(\"id\")).value(subquery));"},{"lineNumber":153,"author":{"gitId":"-"},"content":" HibernateUtil.createMutationQuery(cd).executeUpdate();"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":157,"author":{"gitId":"-"},"content":" * Checks whether there are responses for a question."},{"lineNumber":158,"author":{"gitId":"-"},"content":" */"},{"lineNumber":159,"author":{"gitId":"-"},"content":" public boolean areThereResponsesForQuestion(UUID questionId) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":161,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cq \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":162,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponse\u003e root \u003d cq.from(FeedbackResponse.class);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d root.join(\"feedbackQuestion\");"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" cq.select(root)"},{"lineNumber":166,"author":{"gitId":"-"},"content":" .where(cb.equal(fqJoin.get(\"id\"), questionId));"},{"lineNumber":167,"author":{"gitId":"-"},"content":" return !HibernateUtil.createQuery(cq).getResultList().isEmpty();"},{"lineNumber":168,"author":{"gitId":"-"},"content":" }"},{"lineNumber":169,"author":{"gitId":"-"},"content":""},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":171,"author":{"gitId":"xenosf"},"content":" * Get responses for a question."},{"lineNumber":172,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":" public List\u003cFeedbackResponse\u003e getResponsesForQuestion(UUID questionId) {"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cq \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":" Root\u003cFeedbackResponse\u003e root \u003d cq.from(FeedbackResponse.class);"},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d root.join(\"feedbackQuestion\");"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" cq.select(root)"},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" .where(cb.equal(fqJoin.get(\"id\"), questionId));"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":184,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":185,"author":{"gitId":"-"},"content":" * Checks whether a user has responses in a session."},{"lineNumber":186,"author":{"gitId":"-"},"content":" */"},{"lineNumber":187,"author":{"gitId":"-"},"content":" public boolean hasResponsesFromGiverInSession("},{"lineNumber":188,"author":{"gitId":"-"},"content":" String giver, String feedbackSessionName, String courseId) {"},{"lineNumber":189,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":190,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cq \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":191,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponse\u003e root \u003d cq.from(FeedbackResponse.class);"},{"lineNumber":192,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d root.join(\"feedbackQuestion\");"},{"lineNumber":193,"author":{"gitId":"-"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":194,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e courseJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":195,"author":{"gitId":"-"},"content":""},{"lineNumber":196,"author":{"gitId":"-"},"content":" cq.select(root)"},{"lineNumber":197,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":198,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"giver\"), giver),"},{"lineNumber":199,"author":{"gitId":"-"},"content":" cb.equal(fsJoin.get(\"name\"), feedbackSessionName),"},{"lineNumber":200,"author":{"gitId":"-"},"content":" cb.equal(courseJoin.get(\"id\"), courseId)));"},{"lineNumber":201,"author":{"gitId":"-"},"content":""},{"lineNumber":202,"author":{"gitId":"-"},"content":" return !HibernateUtil.createQuery(cq).getResultList().isEmpty();"},{"lineNumber":203,"author":{"gitId":"-"},"content":" }"},{"lineNumber":204,"author":{"gitId":"-"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":206,"author":{"gitId":"-"},"content":" * Checks whether there are responses for a course."},{"lineNumber":207,"author":{"gitId":"-"},"content":" */"},{"lineNumber":208,"author":{"gitId":"-"},"content":" public boolean hasResponsesForCourse(String courseId) {"},{"lineNumber":209,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":210,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cq \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":211,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponse\u003e root \u003d cq.from(FeedbackResponse.class);"},{"lineNumber":212,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d root.join(\"feedbackQuestion\");"},{"lineNumber":213,"author":{"gitId":"-"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":214,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e courseJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":215,"author":{"gitId":"-"},"content":""},{"lineNumber":216,"author":{"gitId":"-"},"content":" cq.select(root)"},{"lineNumber":217,"author":{"gitId":"-"},"content":" .where(cb.equal(courseJoin.get(\"id\"), courseId));"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":" return !HibernateUtil.createQuery(cq).getResultList().isEmpty();"},{"lineNumber":220,"author":{"gitId":"-"},"content":" }"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":223,"author":{"gitId":"domoberzin"},"content":" * Updates a feedbackResponse."},{"lineNumber":224,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":225,"author":{"gitId":"domoberzin"},"content":" * @throws EntityDoesNotExistException if the feedbackResponse does not exist"},{"lineNumber":226,"author":{"gitId":"domoberzin"},"content":" * @throws InvalidParametersException if the feedbackResponse is not valid"},{"lineNumber":227,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":228,"author":{"gitId":"domoberzin"},"content":" public FeedbackResponse updateFeedbackResponse(FeedbackResponse feedbackResponse)"},{"lineNumber":229,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":230,"author":{"gitId":"domoberzin"},"content":" assert feedbackResponse !\u003d null;"},{"lineNumber":231,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":232,"author":{"gitId":"domoberzin"},"content":" if (!feedbackResponse.isValid()) {"},{"lineNumber":233,"author":{"gitId":"domoberzin"},"content":" throw new InvalidParametersException(feedbackResponse.getInvalidityInfo());"},{"lineNumber":234,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":235,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":236,"author":{"gitId":"domoberzin"},"content":" if (getFeedbackResponse(feedbackResponse.getId()) \u003d\u003d null) {"},{"lineNumber":237,"author":{"gitId":"domoberzin"},"content":" throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT);"},{"lineNumber":238,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":239,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":240,"author":{"gitId":"domoberzin"},"content":" return merge(feedbackResponse);"},{"lineNumber":241,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":242,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":243,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":244,"author":{"gitId":"xenosf"},"content":" * Gets all responses received by a user for a question."},{"lineNumber":245,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":246,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForRecipientForQuestion("},{"lineNumber":247,"author":{"gitId":"xenosf"},"content":" UUID questionId, String recipient) {"},{"lineNumber":248,"author":{"gitId":"xenosf"},"content":" assert questionId !\u003d null;"},{"lineNumber":249,"author":{"gitId":"xenosf"},"content":" assert recipient !\u003d null;"},{"lineNumber":250,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":251,"author":{"gitId":"xenosf"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":252,"author":{"gitId":"xenosf"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cq \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":253,"author":{"gitId":"xenosf"},"content":" Root\u003cFeedbackResponse\u003e root \u003d cq.from(FeedbackResponse.class);"},{"lineNumber":254,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d root.join(\"feedbackQuestion\");"},{"lineNumber":255,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":256,"author":{"gitId":"xenosf"},"content":" cq.select(root)"},{"lineNumber":257,"author":{"gitId":"xenosf"},"content":" .where(cb.and("},{"lineNumber":258,"author":{"gitId":"xenosf"},"content":" cb.equal(fqJoin.get(\"id\"), questionId),"},{"lineNumber":259,"author":{"gitId":"xenosf"},"content":" cb.equal(root.get(\"recipient\"), recipient)"},{"lineNumber":260,"author":{"gitId":"xenosf"},"content":" ));"},{"lineNumber":261,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":262,"author":{"gitId":"xenosf"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":263,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":264,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":265,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":266,"author":{"gitId":"xenosf"},"content":" * Gets all responses given to/from a section in a feedback session in a course."},{"lineNumber":267,"author":{"gitId":"xenosf"},"content":" * Optionally, retrieves by either giver, receiver sections, or both."},{"lineNumber":268,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":269,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForSessionInSection("},{"lineNumber":270,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession, String courseId, String sectionName, FeedbackResultFetchType fetchType) {"},{"lineNumber":271,"author":{"gitId":"xenosf"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":272,"author":{"gitId":"xenosf"},"content":" assert courseId !\u003d null;"},{"lineNumber":273,"author":{"gitId":"xenosf"},"content":" assert sectionName !\u003d null;"},{"lineNumber":274,"author":{"gitId":"xenosf"},"content":" assert fetchType !\u003d null;"},{"lineNumber":275,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":276,"author":{"gitId":"xenosf"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":277,"author":{"gitId":"xenosf"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cq \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":278,"author":{"gitId":"xenosf"},"content":" Root\u003cFeedbackResponse\u003e root \u003d cq.from(FeedbackResponse.class);"},{"lineNumber":279,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d root.join(\"feedbackQuestion\");"},{"lineNumber":280,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":281,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackSession, Course\u003e cJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":282,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":283,"author":{"gitId":"xenosf"},"content":" // unless specified by fetchType, do not filter by giver/recipient section"},{"lineNumber":284,"author":{"gitId":"xenosf"},"content":" Predicate giverSectionFilter \u003d cb.isTrue(cb.literal(true));"},{"lineNumber":285,"author":{"gitId":"xenosf"},"content":" Predicate recipientSectionFilter \u003d cb.isTrue(cb.literal(true));"},{"lineNumber":286,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, Section\u003e giverJoin \u003d root.join(\"giverSection\");"},{"lineNumber":287,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, Section\u003e recipientJoin \u003d root.join(\"recipientSection\");"},{"lineNumber":288,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":289,"author":{"gitId":"xenosf"},"content":" if (fetchType.shouldFetchByGiver()) {"},{"lineNumber":290,"author":{"gitId":"xenosf"},"content":" giverSectionFilter \u003d cb.equal(giverJoin.get(\"name\"), sectionName);"},{"lineNumber":291,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":292,"author":{"gitId":"xenosf"},"content":" if (fetchType.shouldFetchByReceiver()) {"},{"lineNumber":293,"author":{"gitId":"xenosf"},"content":" recipientSectionFilter \u003d cb.equal(recipientJoin.get(\"name\"), sectionName);"},{"lineNumber":294,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":295,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":296,"author":{"gitId":"xenosf"},"content":" cq.select(root)"},{"lineNumber":297,"author":{"gitId":"xenosf"},"content":" .where(cb.and("},{"lineNumber":298,"author":{"gitId":"xenosf"},"content":" cb.equal(fsJoin.get(\"id\"), feedbackSession.getId()),"},{"lineNumber":299,"author":{"gitId":"xenosf"},"content":" cb.equal(cJoin.get(\"id\"), courseId),"},{"lineNumber":300,"author":{"gitId":"xenosf"},"content":" giverSectionFilter,"},{"lineNumber":301,"author":{"gitId":"xenosf"},"content":" recipientSectionFilter"},{"lineNumber":302,"author":{"gitId":"xenosf"},"content":" ));"},{"lineNumber":303,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":304,"author":{"gitId":"xenosf"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":305,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":306,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":307,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":308,"author":{"gitId":"xenosf"},"content":" * Gets all feedback responses of a question in a specific section."},{"lineNumber":309,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":310,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForQuestionInSection("},{"lineNumber":311,"author":{"gitId":"xenosf"},"content":" UUID questionId, String sectionName, FeedbackResultFetchType fetchType) {"},{"lineNumber":312,"author":{"gitId":"xenosf"},"content":" assert questionId !\u003d null;"},{"lineNumber":313,"author":{"gitId":"xenosf"},"content":" assert sectionName !\u003d null;"},{"lineNumber":314,"author":{"gitId":"xenosf"},"content":" assert fetchType !\u003d null;"},{"lineNumber":315,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":316,"author":{"gitId":"xenosf"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":317,"author":{"gitId":"xenosf"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cq \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":318,"author":{"gitId":"xenosf"},"content":" Root\u003cFeedbackResponse\u003e root \u003d cq.from(FeedbackResponse.class);"},{"lineNumber":319,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d root.join(\"feedbackQuestion\");"},{"lineNumber":320,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":321,"author":{"gitId":"xenosf"},"content":" // unless specified by fetchType, do not filter by giver/recipient section"},{"lineNumber":322,"author":{"gitId":"xenosf"},"content":" Predicate giverSectionFilter \u003d cb.isTrue(cb.literal(true));"},{"lineNumber":323,"author":{"gitId":"xenosf"},"content":" Predicate recipientSectionFilter \u003d cb.isTrue(cb.literal(true));"},{"lineNumber":324,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, Section\u003e giverJoin \u003d root.join(\"giverSection\");"},{"lineNumber":325,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, Section\u003e recipientJoin \u003d root.join(\"recipientSection\");"},{"lineNumber":326,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":327,"author":{"gitId":"xenosf"},"content":" if (fetchType.shouldFetchByGiver()) {"},{"lineNumber":328,"author":{"gitId":"xenosf"},"content":" giverSectionFilter \u003d cb.equal(giverJoin.get(\"name\"), sectionName);"},{"lineNumber":329,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":330,"author":{"gitId":"xenosf"},"content":" if (fetchType.shouldFetchByReceiver()) {"},{"lineNumber":331,"author":{"gitId":"xenosf"},"content":" recipientSectionFilter \u003d cb.equal(recipientJoin.get(\"name\"), sectionName);"},{"lineNumber":332,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":333,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":334,"author":{"gitId":"xenosf"},"content":" cq.select(root)"},{"lineNumber":335,"author":{"gitId":"xenosf"},"content":" .where(cb.and("},{"lineNumber":336,"author":{"gitId":"xenosf"},"content":" cb.equal(fqJoin.get(\"id\"), questionId),"},{"lineNumber":337,"author":{"gitId":"xenosf"},"content":" giverSectionFilter,"},{"lineNumber":338,"author":{"gitId":"xenosf"},"content":" recipientSectionFilter"},{"lineNumber":339,"author":{"gitId":"xenosf"},"content":" ));"},{"lineNumber":340,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":341,"author":{"gitId":"xenosf"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":342,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":343,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":344,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":345,"author":{"gitId":"xenosf"},"content":" * Gets all responses of a feedback session in a course."},{"lineNumber":346,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":347,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForSession("},{"lineNumber":348,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession, String courseId) {"},{"lineNumber":349,"author":{"gitId":"xenosf"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":350,"author":{"gitId":"xenosf"},"content":" assert courseId !\u003d null;"},{"lineNumber":351,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":352,"author":{"gitId":"xenosf"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":353,"author":{"gitId":"xenosf"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cq \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":354,"author":{"gitId":"xenosf"},"content":" Root\u003cFeedbackResponse\u003e root \u003d cq.from(FeedbackResponse.class);"},{"lineNumber":355,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d root.join(\"feedbackQuestion\");"},{"lineNumber":356,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":357,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackSession, Course\u003e cJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":358,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":359,"author":{"gitId":"xenosf"},"content":" cq.select(root)"},{"lineNumber":360,"author":{"gitId":"xenosf"},"content":" .where(cb.and("},{"lineNumber":361,"author":{"gitId":"xenosf"},"content":" cb.equal(fsJoin.get(\"id\"), feedbackSession.getId()),"},{"lineNumber":362,"author":{"gitId":"xenosf"},"content":" cb.equal(cJoin.get(\"id\"), courseId)"},{"lineNumber":363,"author":{"gitId":"xenosf"},"content":" ));"},{"lineNumber":364,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":365,"author":{"gitId":"xenosf"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":366,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":367,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":368,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":37,"xenosf":127,"-":204}},{"path":"src/main/java/teammates/storage/sqlapi/FeedbackSessionLogsDb.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.criteria.CriteriaBuilder;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.criteria.CriteriaQuery;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.criteria.Join;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.criteria.Predicate;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.criteria.Root;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":" * Handles CRUD operations for feedback session logs."},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" * @see FeedbackSessionLog"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":"public final class FeedbackSessionLogsDb extends EntitiesDb {"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" private static final FeedbackSessionLogsDb instance \u003d new FeedbackSessionLogsDb();"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" private FeedbackSessionLogsDb() {"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" // prevent initialization"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" public static FeedbackSessionLogsDb inst() {"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" return instance;"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" * Gets the feedback session logs as filtered by the given parameters ordered by"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" * ascending timestamp. Logs with the same timestamp will be ordered by the"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" * student\u0027s email."},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" * @param studentId Can be null"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" * @param feedbackSessionId Can be null"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" public List\u003cFeedbackSessionLog\u003e getOrderedFeedbackSessionLogs(String courseId, UUID studentId,"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" UUID feedbackSessionId, Instant startTime, Instant endTime) {"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" assert courseId !\u003d null;"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" assert startTime !\u003d null;"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" assert endTime !\u003d null;"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" CriteriaQuery\u003cFeedbackSessionLog\u003e cr \u003d cb.createQuery(FeedbackSessionLog.class);"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" Root\u003cFeedbackSessionLog\u003e root \u003d cr.from(FeedbackSessionLog.class);"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" Join\u003cFeedbackSessionLog, FeedbackSession\u003e feedbackSessionJoin \u003d root.join(\"feedbackSession\");"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" Join\u003cFeedbackSessionLog, Student\u003e studentJoin \u003d root.join(\"student\");"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" List\u003cPredicate\u003e predicates \u003d new ArrayList\u003c\u003e();"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" if (studentId !\u003d null) {"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" predicates.add(cb.equal(studentJoin.get(\"id\"), studentId));"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" if (feedbackSessionId !\u003d null) {"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" predicates.add(cb.equal(feedbackSessionJoin.get(\"id\"), feedbackSessionId));"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" predicates.add(cb.equal(feedbackSessionJoin.get(\"course\").get(\"id\"), courseId));"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" predicates.add(cb.greaterThanOrEqualTo(root.get(\"timestamp\"), startTime));"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" predicates.add(cb.lessThan(root.get(\"timestamp\"), endTime));"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" cr.select(root).where(predicates.toArray(new Predicate[0])).orderBy(cb.asc(root.get(\"timestamp\")),"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" cb.asc(studentJoin.get(\"email\")));"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" * Creates feedback session logs."},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" public FeedbackSessionLog createFeedbackSessionLog(FeedbackSessionLog log) {"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" assert log !\u003d null;"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" persist(log);"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" return log;"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":81,"-":5}},{"path":"src/main/java/teammates/storage/sqlapi/FeedbackSessionsDb.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static teammates.common.util.Const.ERROR_CREATE_ENTITY_ALREADY_EXISTS;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import static teammates.common.util.Const.ERROR_UPDATE_NON_EXISTENT;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaBuilder;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaQuery;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Join;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Root;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * Handles CRUD operations for feedback sessions."},{"lineNumber":26,"author":{"gitId":"-"},"content":" *"},{"lineNumber":27,"author":{"gitId":"-"},"content":" * @see FeedbackSession"},{"lineNumber":28,"author":{"gitId":"-"},"content":" */"},{"lineNumber":29,"author":{"gitId":"-"},"content":"public final class FeedbackSessionsDb extends EntitiesDb {"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" private static final FeedbackSessionsDb instance \u003d new FeedbackSessionsDb();"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private FeedbackSessionsDb() {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" public static FeedbackSessionsDb inst() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":42,"author":{"gitId":"-"},"content":" * Gets a feedback session."},{"lineNumber":43,"author":{"gitId":"-"},"content":" *"},{"lineNumber":44,"author":{"gitId":"-"},"content":" * @return null if not found"},{"lineNumber":45,"author":{"gitId":"-"},"content":" */"},{"lineNumber":46,"author":{"gitId":"-"},"content":" public FeedbackSession getFeedbackSession(UUID fsId) {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" assert fsId !\u003d null;"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" return HibernateUtil.get(FeedbackSession.class, fsId);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" }"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":53,"author":{"gitId":"-"},"content":" * Gets a feedback session for {@code feedbackSessionName} and {@code courseId}."},{"lineNumber":54,"author":{"gitId":"-"},"content":" *"},{"lineNumber":55,"author":{"gitId":"-"},"content":" * @return null if not found"},{"lineNumber":56,"author":{"gitId":"-"},"content":" */"},{"lineNumber":57,"author":{"gitId":"-"},"content":" public FeedbackSession getFeedbackSession(String feedbackSessionName, String courseId) {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":59,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cq \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e fsRoot \u003d cq.from(FeedbackSession.class);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e fsJoin \u003d fsRoot.join(\"course\");"},{"lineNumber":62,"author":{"gitId":"-"},"content":" cq.select(fsRoot).where(cb.and("},{"lineNumber":63,"author":{"gitId":"-"},"content":" cb.equal(fsRoot.get(\"name\"), feedbackSessionName),"},{"lineNumber":64,"author":{"gitId":"-"},"content":" cb.equal(fsJoin.get(\"id\"), courseId)));"},{"lineNumber":65,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cq).getResultStream().findFirst().orElse(null);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" * Gets a feedback session reference."},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" * @return Returns a proxy for the feedback session."},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" public FeedbackSession getFeedbackSessionReference(UUID id) {"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" assert id !\u003d null;"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" return HibernateUtil.getReference(FeedbackSession.class, id);"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":80,"author":{"gitId":"-"},"content":" * Gets a soft-deleted feedback session."},{"lineNumber":81,"author":{"gitId":"-"},"content":" *"},{"lineNumber":82,"author":{"gitId":"-"},"content":" * @return null if not found or not soft-deleted."},{"lineNumber":83,"author":{"gitId":"-"},"content":" */"},{"lineNumber":84,"author":{"gitId":"-"},"content":" public FeedbackSession getSoftDeletedFeedbackSession(String feedbackSessionName, String courseId) {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession \u003d getFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" if (feedbackSession !\u003d null \u0026\u0026 feedbackSession.getDeletedAt() \u003d\u003d null) {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" log.info(feedbackSessionName + \"/\" + courseId + \" is not soft-deleted!\");"},{"lineNumber":92,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":93,"author":{"gitId":"-"},"content":" }"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" return feedbackSession;"},{"lineNumber":96,"author":{"gitId":"-"},"content":" }"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":99,"author":{"gitId":"-"},"content":" * Gets soft-deleted feedback sessions for course."},{"lineNumber":100,"author":{"gitId":"-"},"content":" */"},{"lineNumber":101,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getSoftDeletedFeedbackSessionsForCourse(String courseId) {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":103,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cq \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e fsRoot \u003d cq.from(FeedbackSession.class);"},{"lineNumber":105,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e fsJoin \u003d fsRoot.join(\"course\");"},{"lineNumber":106,"author":{"gitId":"-"},"content":" cq.select(fsRoot).where(cb.and("},{"lineNumber":107,"author":{"gitId":"-"},"content":" cb.isNotNull(fsRoot.get(\"deletedAt\")),"},{"lineNumber":108,"author":{"gitId":"-"},"content":" cb.equal(fsJoin.get(\"id\"), courseId)));"},{"lineNumber":109,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":113,"author":{"gitId":"-"},"content":" * Gets all and only the feedback sessions ongoing within a range of time."},{"lineNumber":114,"author":{"gitId":"-"},"content":" */"},{"lineNumber":115,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getOngoingSessions(Instant rangeStart, Instant rangeEnd) {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" assert rangeStart !\u003d null;"},{"lineNumber":117,"author":{"gitId":"-"},"content":" assert rangeEnd !\u003d null;"},{"lineNumber":118,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":119,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cr \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e root \u003d cr.from(FeedbackSession.class);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" cr.select(root)"},{"lineNumber":122,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":123,"author":{"gitId":"-"},"content":" cb.greaterThan(root.get(\"endTime\"), rangeStart),"},{"lineNumber":124,"author":{"gitId":"-"},"content":" cb.lessThan(root.get(\"startTime\"), rangeEnd)));"},{"lineNumber":125,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":126,"author":{"gitId":"-"},"content":" }"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":129,"author":{"gitId":"-"},"content":" * Restores a specific soft deleted feedback session."},{"lineNumber":130,"author":{"gitId":"-"},"content":" */"},{"lineNumber":131,"author":{"gitId":"-"},"content":" public void restoreDeletedFeedbackSession(String feedbackSessionName, String courseId)"},{"lineNumber":132,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":134,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" FeedbackSession sessionEntity \u003d getFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" if (sessionEntity \u003d\u003d null) {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" sessionEntity.setDeletedAt(null);"},{"lineNumber":143,"author":{"gitId":"dishenggg"},"content":" merge(sessionEntity);"},{"lineNumber":144,"author":{"gitId":"-"},"content":" }"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":147,"author":{"gitId":"-"},"content":" * Creates a feedback session."},{"lineNumber":148,"author":{"gitId":"-"},"content":" */"},{"lineNumber":149,"author":{"gitId":"-"},"content":" public FeedbackSession createFeedbackSession(FeedbackSession session)"},{"lineNumber":150,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" assert session !\u003d null;"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":" if (!session.isValid()) {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(session.getInvalidityInfo());"},{"lineNumber":155,"author":{"gitId":"-"},"content":" }"},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"-"},"content":" if (getFeedbackSession(session.getId()) !\u003d null) {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" throw new EntityAlreadyExistsException(String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, session.toString()));"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" persist(session);"},{"lineNumber":162,"author":{"gitId":"-"},"content":" return session;"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":166,"author":{"gitId":"-"},"content":" * Saves an updated {@code FeedbackSession} to the db."},{"lineNumber":167,"author":{"gitId":"-"},"content":" *"},{"lineNumber":168,"author":{"gitId":"-"},"content":" * @return updated feedback session"},{"lineNumber":169,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":170,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the feedback session cannot be found"},{"lineNumber":171,"author":{"gitId":"-"},"content":" */"},{"lineNumber":172,"author":{"gitId":"-"},"content":" public FeedbackSession updateFeedbackSession(FeedbackSession feedbackSession)"},{"lineNumber":173,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":175,"author":{"gitId":"-"},"content":""},{"lineNumber":176,"author":{"gitId":"-"},"content":" if (!feedbackSession.isValid()) {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(feedbackSession.getInvalidityInfo());"},{"lineNumber":178,"author":{"gitId":"-"},"content":" }"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" if (getFeedbackSession(feedbackSession.getId()) \u003d\u003d null) {"},{"lineNumber":181,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT);"},{"lineNumber":182,"author":{"gitId":"-"},"content":" }"},{"lineNumber":183,"author":{"gitId":"-"},"content":""},{"lineNumber":184,"author":{"gitId":"-"},"content":" return merge(feedbackSession);"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":188,"author":{"gitId":"-"},"content":" * Deletes a feedback session."},{"lineNumber":189,"author":{"gitId":"-"},"content":" */"},{"lineNumber":190,"author":{"gitId":"-"},"content":" public void deleteFeedbackSession(FeedbackSession feedbackSession) {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" if (feedbackSession !\u003d null) {"},{"lineNumber":192,"author":{"gitId":"-"},"content":" delete(feedbackSession);"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":" }"},{"lineNumber":195,"author":{"gitId":"-"},"content":""},{"lineNumber":196,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":197,"author":{"gitId":"-"},"content":" * Soft-deletes a specific feedback session by its name and course id."},{"lineNumber":198,"author":{"gitId":"-"},"content":" *"},{"lineNumber":199,"author":{"gitId":"-"},"content":" * @return the feedback session."},{"lineNumber":200,"author":{"gitId":"-"},"content":" */"},{"lineNumber":201,"author":{"gitId":"-"},"content":" public FeedbackSession softDeleteFeedbackSession(String feedbackSessionName, String courseId)"},{"lineNumber":202,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":203,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":204,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSessionEntity \u003d getFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":207,"author":{"gitId":"-"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" if (feedbackSessionEntity \u003d\u003d null) {"},{"lineNumber":209,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT);"},{"lineNumber":210,"author":{"gitId":"-"},"content":" }"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" feedbackSessionEntity.setDeletedAt(Instant.now());"},{"lineNumber":213,"author":{"gitId":"-"},"content":" merge(feedbackSessionEntity);"},{"lineNumber":214,"author":{"gitId":"-"},"content":""},{"lineNumber":215,"author":{"gitId":"-"},"content":" return feedbackSessionEntity;"},{"lineNumber":216,"author":{"gitId":"-"},"content":" }"},{"lineNumber":217,"author":{"gitId":"-"},"content":""},{"lineNumber":218,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":219,"author":{"gitId":"-"},"content":" * Gets feedback sessions for a given {@code courseId}."},{"lineNumber":220,"author":{"gitId":"-"},"content":" */"},{"lineNumber":221,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionEntitiesForCourse(String courseId) {"},{"lineNumber":222,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":223,"author":{"gitId":"-"},"content":""},{"lineNumber":224,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":225,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cq \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":226,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e root \u003d cq.from(FeedbackSession.class);"},{"lineNumber":227,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e courseJoin \u003d root.join(\"course\");"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" cq.select(root).where(cb.equal(courseJoin.get(\"id\"), courseId));"},{"lineNumber":230,"author":{"gitId":"-"},"content":""},{"lineNumber":231,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":232,"author":{"gitId":"-"},"content":" }"},{"lineNumber":233,"author":{"gitId":"-"},"content":""},{"lineNumber":234,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":235,"author":{"gitId":"-"},"content":" * Gets feedback sessions for a given {@code courseId} that start after {@code after}."},{"lineNumber":236,"author":{"gitId":"-"},"content":" */"},{"lineNumber":237,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionEntitiesForCourseStartingAfter(String courseId, Instant after) {"},{"lineNumber":238,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":239,"author":{"gitId":"-"},"content":" assert after !\u003d null;"},{"lineNumber":240,"author":{"gitId":"-"},"content":""},{"lineNumber":241,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":242,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cr \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":243,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e root \u003d cr.from(FeedbackSession.class);"},{"lineNumber":244,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e courseJoin \u003d root.join(\"course\");"},{"lineNumber":245,"author":{"gitId":"-"},"content":" cr.select(root)"},{"lineNumber":246,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":247,"author":{"gitId":"-"},"content":" cb.greaterThanOrEqualTo(root.get(\"startTime\"), after),"},{"lineNumber":248,"author":{"gitId":"-"},"content":" cb.equal(courseJoin.get(\"id\"), courseId)));"},{"lineNumber":249,"author":{"gitId":"-"},"content":""},{"lineNumber":250,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":251,"author":{"gitId":"-"},"content":" }"},{"lineNumber":252,"author":{"gitId":"-"},"content":""},{"lineNumber":253,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":254,"author":{"gitId":"-"},"content":" * Gets a list of undeleted feedback sessions which open in the future"},{"lineNumber":255,"author":{"gitId":"-"},"content":" * and possibly need a opening soon email to be sent."},{"lineNumber":256,"author":{"gitId":"-"},"content":" */"},{"lineNumber":257,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsPossiblyNeedingOpeningSoonEmail() {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" return getFeedbackSessionEntitiesPossiblyNeedingOpeningSoonEmail().stream()"},{"lineNumber":259,"author":{"gitId":"-"},"content":" .filter(session -\u003e session.getDeletedAt() \u003d\u003d null)"},{"lineNumber":260,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":261,"author":{"gitId":"-"},"content":" }"},{"lineNumber":262,"author":{"gitId":"-"},"content":""},{"lineNumber":263,"author":{"gitId":"-"},"content":" private List\u003cFeedbackSession\u003e getFeedbackSessionEntitiesPossiblyNeedingOpeningSoonEmail() {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":265,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cr \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":266,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e root \u003d cr.from(FeedbackSession.class);"},{"lineNumber":267,"author":{"gitId":"-"},"content":""},{"lineNumber":268,"author":{"gitId":"-"},"content":" cr.select(root)"},{"lineNumber":269,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":270,"author":{"gitId":"-"},"content":" cb.greaterThan(root.get(\"startTime\"), TimeHelper.getInstantDaysOffsetFromNow(-2)),"},{"lineNumber":271,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"isOpeningSoonEmailSent\"), false)));"},{"lineNumber":272,"author":{"gitId":"-"},"content":""},{"lineNumber":273,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":277,"author":{"gitId":"-"},"content":" * Gets a list of undeleted feedback sessions which end in the future (2 hour ago onward)"},{"lineNumber":278,"author":{"gitId":"-"},"content":" * and possibly need a closing soon email to be sent."},{"lineNumber":279,"author":{"gitId":"-"},"content":" */"},{"lineNumber":280,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsPossiblyNeedingClosingSoonEmail() {"},{"lineNumber":281,"author":{"gitId":"-"},"content":" return getFeedbackSessionEntitiesPossiblyNeedingClosingSoonEmail().stream()"},{"lineNumber":282,"author":{"gitId":"-"},"content":" .filter(session -\u003e session.getDeletedAt() \u003d\u003d null)"},{"lineNumber":283,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":284,"author":{"gitId":"-"},"content":" }"},{"lineNumber":285,"author":{"gitId":"-"},"content":""},{"lineNumber":286,"author":{"gitId":"-"},"content":" private List\u003cFeedbackSession\u003e getFeedbackSessionEntitiesPossiblyNeedingClosingSoonEmail() {"},{"lineNumber":287,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":288,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cr \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":289,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e root \u003d cr.from(FeedbackSession.class);"},{"lineNumber":290,"author":{"gitId":"-"},"content":""},{"lineNumber":291,"author":{"gitId":"-"},"content":" cr.select(root)"},{"lineNumber":292,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":293,"author":{"gitId":"-"},"content":" cb.greaterThan(root.get(\"endTime\"), TimeHelper.getInstantDaysOffsetFromNow(-2)),"},{"lineNumber":294,"author":{"gitId":"-"},"content":" cb.and("},{"lineNumber":295,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"isClosingSoonEmailSent\"), false),"},{"lineNumber":296,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"isClosingEmailEnabled\"), true))"},{"lineNumber":297,"author":{"gitId":"-"},"content":" ));"},{"lineNumber":298,"author":{"gitId":"-"},"content":""},{"lineNumber":299,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":300,"author":{"gitId":"-"},"content":" }"},{"lineNumber":301,"author":{"gitId":"-"},"content":""},{"lineNumber":302,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":303,"author":{"gitId":"-"},"content":" * Gets a list of undeleted feedback sessions which end in the future (2 hour ago onward)"},{"lineNumber":304,"author":{"gitId":"-"},"content":" * and possibly need a closed email to be sent."},{"lineNumber":305,"author":{"gitId":"-"},"content":" */"},{"lineNumber":306,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsPossiblyNeedingClosedEmail() {"},{"lineNumber":307,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":308,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cr \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":309,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e root \u003d cr.from(FeedbackSession.class);"},{"lineNumber":310,"author":{"gitId":"-"},"content":""},{"lineNumber":311,"author":{"gitId":"-"},"content":" cr.select(root)"},{"lineNumber":312,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":313,"author":{"gitId":"-"},"content":" cb.greaterThan(root.get(\"endTime\"), TimeHelper.getInstantDaysOffsetFromNow(-2)),"},{"lineNumber":314,"author":{"gitId":"-"},"content":" cb.isFalse(root.get(\"isClosedEmailSent\")),"},{"lineNumber":315,"author":{"gitId":"-"},"content":" cb.isTrue(root.get(\"isClosingEmailEnabled\")),"},{"lineNumber":316,"author":{"gitId":"-"},"content":" cb.isNull(root.get(\"deletedAt\"))"},{"lineNumber":317,"author":{"gitId":"-"},"content":" ));"},{"lineNumber":318,"author":{"gitId":"-"},"content":""},{"lineNumber":319,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":320,"author":{"gitId":"-"},"content":" }"},{"lineNumber":321,"author":{"gitId":"-"},"content":""},{"lineNumber":322,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":323,"author":{"gitId":"-"},"content":" * Gets a list of undeleted published feedback sessions which possibly need a published email"},{"lineNumber":324,"author":{"gitId":"-"},"content":" * to be sent."},{"lineNumber":325,"author":{"gitId":"-"},"content":" */"},{"lineNumber":326,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsPossiblyNeedingPublishedEmail() {"},{"lineNumber":327,"author":{"gitId":"-"},"content":" return getFeedbackSessionEntitiesPossiblyNeedingPublishedEmail().stream()"},{"lineNumber":328,"author":{"gitId":"-"},"content":" .filter(session -\u003e session.getDeletedAt() \u003d\u003d null)"},{"lineNumber":329,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":330,"author":{"gitId":"-"},"content":" }"},{"lineNumber":331,"author":{"gitId":"-"},"content":""},{"lineNumber":332,"author":{"gitId":"-"},"content":" private List\u003cFeedbackSession\u003e getFeedbackSessionEntitiesPossiblyNeedingPublishedEmail() {"},{"lineNumber":333,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":334,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cr \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":335,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e root \u003d cr.from(FeedbackSession.class);"},{"lineNumber":336,"author":{"gitId":"-"},"content":""},{"lineNumber":337,"author":{"gitId":"-"},"content":" cr.select(root)"},{"lineNumber":338,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":339,"author":{"gitId":"-"},"content":" cb.greaterThan(root.get(\"resultsVisibleFromTime\"), TimeHelper.getInstantDaysOffsetFromNow(-2)),"},{"lineNumber":340,"author":{"gitId":"-"},"content":" cb.and("},{"lineNumber":341,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"isPublishedEmailSent\"), false),"},{"lineNumber":342,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"isPublishedEmailEnabled\"), true))"},{"lineNumber":343,"author":{"gitId":"-"},"content":" ));"},{"lineNumber":344,"author":{"gitId":"-"},"content":""},{"lineNumber":345,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":346,"author":{"gitId":"-"},"content":" }"},{"lineNumber":347,"author":{"gitId":"-"},"content":""},{"lineNumber":348,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":349,"author":{"gitId":"-"},"content":" * Gets a list of undeleted feedback sessions which start within the last 2 days"},{"lineNumber":350,"author":{"gitId":"-"},"content":" * and possibly need an open email to be sent."},{"lineNumber":351,"author":{"gitId":"-"},"content":" */"},{"lineNumber":352,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsPossiblyNeedingOpenEmail() {"},{"lineNumber":353,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":354,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cr \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":355,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e root \u003d cr.from(FeedbackSession.class);"},{"lineNumber":356,"author":{"gitId":"-"},"content":""},{"lineNumber":357,"author":{"gitId":"-"},"content":" cr.select(root)"},{"lineNumber":358,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":359,"author":{"gitId":"-"},"content":" cb.greaterThan(root.get(\"startTime\"), TimeHelper.getInstantDaysOffsetFromNow(-2)),"},{"lineNumber":360,"author":{"gitId":"-"},"content":" cb.isFalse(root.get(\"isOpenEmailSent\")),"},{"lineNumber":361,"author":{"gitId":"-"},"content":" cb.isNull(root.get(\"deletedAt\"))"},{"lineNumber":362,"author":{"gitId":"-"},"content":" ));"},{"lineNumber":363,"author":{"gitId":"-"},"content":""},{"lineNumber":364,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":365,"author":{"gitId":"-"},"content":" }"},{"lineNumber":366,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":12,"-":354}},{"path":"src/main/java/teammates/storage/sqlapi/UsersDb.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import static teammates.common.util.Const.ERROR_UPDATE_NON_EXISTENT;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaBuilder;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaQuery;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Join;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Predicate;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Root;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.User;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.InstructorSearchManager;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.SearchManagerFactory;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.StudentSearchManager;"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":33,"author":{"gitId":"-"},"content":" * Handles CRUD operations for users."},{"lineNumber":34,"author":{"gitId":"-"},"content":" *"},{"lineNumber":35,"author":{"gitId":"-"},"content":" * @see User"},{"lineNumber":36,"author":{"gitId":"-"},"content":" */"},{"lineNumber":37,"author":{"gitId":"-"},"content":"public final class UsersDb extends EntitiesDb {"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" private static final UsersDb instance \u003d new UsersDb();"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" private UsersDb() {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":43,"author":{"gitId":"-"},"content":" }"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" public static UsersDb inst() {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" }"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" public InstructorSearchManager getInstructorSearchManager() {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" return SearchManagerFactory.getInstructorSearchManager();"},{"lineNumber":51,"author":{"gitId":"-"},"content":" }"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" public StudentSearchManager getStudentSearchManager() {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" return SearchManagerFactory.getStudentSearchManager();"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":58,"author":{"gitId":"-"},"content":" * Creates an instructor."},{"lineNumber":59,"author":{"gitId":"-"},"content":" */"},{"lineNumber":60,"author":{"gitId":"-"},"content":" public Instructor createInstructor(Instructor instructor)"},{"lineNumber":61,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" assert instructor !\u003d null;"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" if (!instructor.isValid()) {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(instructor.getInvalidityInfo());"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" persist(instructor);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" return instructor;"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":73,"author":{"gitId":"-"},"content":" * Creates a student."},{"lineNumber":74,"author":{"gitId":"-"},"content":" */"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public Student createStudent(Student student)"},{"lineNumber":76,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" assert student !\u003d null;"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" if (!student.isValid()) {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(student.getInvalidityInfo());"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" persist(student);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" return student;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" }"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":88,"author":{"gitId":"-"},"content":" * Gets an instructor by its {@code id}."},{"lineNumber":89,"author":{"gitId":"-"},"content":" */"},{"lineNumber":90,"author":{"gitId":"-"},"content":" public Instructor getInstructor(UUID id) {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" assert id !\u003d null;"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" return HibernateUtil.get(Instructor.class, id);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" }"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":97,"author":{"gitId":"-"},"content":" * Gets an instructor by {@code regKey}."},{"lineNumber":98,"author":{"gitId":"-"},"content":" */"},{"lineNumber":99,"author":{"gitId":"-"},"content":" public Instructor getInstructorByRegKey(String regKey) {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":101,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cInstructor\u003e cr \u003d cb.createQuery(Instructor.class);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" Root\u003cInstructor\u003e instructorRoot \u003d cr.from(Instructor.class);"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" cr.select(instructorRoot).where(cb.equal(instructorRoot.get(\"regKey\"), regKey));"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultStream().findFirst().orElse(null);"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":110,"author":{"gitId":"-"},"content":" * Gets an instructor by {@code googleId}."},{"lineNumber":111,"author":{"gitId":"-"},"content":" */"},{"lineNumber":112,"author":{"gitId":"-"},"content":" public Instructor getInstructorByGoogleId(String courseId, String googleId) {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":114,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cInstructor\u003e cr \u003d cb.createQuery(Instructor.class);"},{"lineNumber":115,"author":{"gitId":"-"},"content":" Root\u003cInstructor\u003e instructorRoot \u003d cr.from(Instructor.class);"},{"lineNumber":116,"author":{"gitId":"-"},"content":" Join\u003cInstructor, Account\u003e accountsJoin \u003d instructorRoot.join(\"account\");"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" cr.select(instructorRoot).where(cb.and("},{"lineNumber":119,"author":{"gitId":"-"},"content":" cb.equal(instructorRoot.get(\"courseId\"), courseId),"},{"lineNumber":120,"author":{"gitId":"-"},"content":" cb.equal(accountsJoin.get(\"googleId\"), googleId)));"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultStream().findFirst().orElse(null);"},{"lineNumber":123,"author":{"gitId":"-"},"content":" }"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":126,"author":{"gitId":"-"},"content":" * Gets all instructors that will be displayed to students of a course."},{"lineNumber":127,"author":{"gitId":"-"},"content":" */"},{"lineNumber":128,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getInstructorsDisplayedToStudents(String courseId) {"},{"lineNumber":129,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":130,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cInstructor\u003e cr \u003d cb.createQuery(Instructor.class);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" Root\u003cInstructor\u003e instructorRoot \u003d cr.from(Instructor.class);"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" cr.select(instructorRoot).where(cb.and("},{"lineNumber":134,"author":{"gitId":"-"},"content":" cb.equal(instructorRoot.get(\"courseId\"), courseId),"},{"lineNumber":135,"author":{"gitId":"-"},"content":" cb.equal(instructorRoot.get(\"isDisplayedToStudents\"), true)));"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":141,"author":{"gitId":"-"},"content":" * Gets a student by its {@code id}."},{"lineNumber":142,"author":{"gitId":"-"},"content":" */"},{"lineNumber":143,"author":{"gitId":"-"},"content":" public Student getStudent(UUID id) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" assert id !\u003d null;"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" return HibernateUtil.get(Student.class, id);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":" * Gets a student reference by its {@code id}."},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":" public Student getStudentReference(UUID id) {"},{"lineNumber":153,"author":{"gitId":"dishenggg"},"content":" assert id !\u003d null;"},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":" return HibernateUtil.getReference(Student.class, id);"},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":158,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":159,"author":{"gitId":"-"},"content":" * Gets a student by {@code regKey}."},{"lineNumber":160,"author":{"gitId":"-"},"content":" */"},{"lineNumber":161,"author":{"gitId":"-"},"content":" public Student getStudentByRegKey(String regKey) {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":163,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":164,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" cr.select(studentRoot).where(cb.equal(studentRoot.get(\"regKey\"), regKey));"},{"lineNumber":167,"author":{"gitId":"-"},"content":""},{"lineNumber":168,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultStream().findFirst().orElse(null);"},{"lineNumber":169,"author":{"gitId":"-"},"content":" }"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":172,"author":{"gitId":"-"},"content":" * Gets a student by {@code googleId}."},{"lineNumber":173,"author":{"gitId":"-"},"content":" */"},{"lineNumber":174,"author":{"gitId":"-"},"content":" public Student getStudentByGoogleId(String courseId, String googleId) {"},{"lineNumber":175,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":176,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":177,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":178,"author":{"gitId":"-"},"content":" Join\u003cStudent, Account\u003e accountsJoin \u003d studentRoot.join(\"account\");"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" cr.select(studentRoot).where(cb.and("},{"lineNumber":181,"author":{"gitId":"-"},"content":" cb.equal(studentRoot.get(\"courseId\"), courseId),"},{"lineNumber":182,"author":{"gitId":"-"},"content":" cb.equal(accountsJoin.get(\"googleId\"), googleId)));"},{"lineNumber":183,"author":{"gitId":"-"},"content":""},{"lineNumber":184,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultStream().findFirst().orElse(null);"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":188,"author":{"gitId":"-"},"content":" * Gets all students by {@code googleId}."},{"lineNumber":189,"author":{"gitId":"-"},"content":" */"},{"lineNumber":190,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsByGoogleId(String googleId) {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":192,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":193,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":194,"author":{"gitId":"-"},"content":" Join\u003cStudent, Account\u003e accountsJoin \u003d studentRoot.join(\"account\");"},{"lineNumber":195,"author":{"gitId":"-"},"content":""},{"lineNumber":196,"author":{"gitId":"-"},"content":" cr.select(studentRoot).where(cb.equal(accountsJoin.get(\"googleId\"), googleId));"},{"lineNumber":197,"author":{"gitId":"-"},"content":""},{"lineNumber":198,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":199,"author":{"gitId":"-"},"content":" }"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":202,"author":{"gitId":"-"},"content":" * Gets a list of students by {@code teamName} and {@code courseId}."},{"lineNumber":203,"author":{"gitId":"-"},"content":" */"},{"lineNumber":204,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsByTeamName(String teamName, String courseId) {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":206,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":207,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":208,"author":{"gitId":"-"},"content":""},{"lineNumber":209,"author":{"gitId":"-"},"content":" studentRoot.alias(\"student\");"},{"lineNumber":210,"author":{"gitId":"-"},"content":""},{"lineNumber":211,"author":{"gitId":"-"},"content":" Join\u003cStudent, Team\u003e teamsJoin \u003d studentRoot.join(\"team\");"},{"lineNumber":212,"author":{"gitId":"-"},"content":""},{"lineNumber":213,"author":{"gitId":"-"},"content":" cr.select(studentRoot).where(cb.and("},{"lineNumber":214,"author":{"gitId":"-"},"content":" cb.equal(studentRoot.get(\"courseId\"), courseId),"},{"lineNumber":215,"author":{"gitId":"-"},"content":" cb.equal(teamsJoin.get(\"name\"), teamName)));"},{"lineNumber":216,"author":{"gitId":"-"},"content":""},{"lineNumber":217,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":221,"author":{"gitId":"-"},"content":" * Gets all instructors and students by {@code googleId}."},{"lineNumber":222,"author":{"gitId":"-"},"content":" */"},{"lineNumber":223,"author":{"gitId":"-"},"content":" public List\u003cUser\u003e getAllUsersByGoogleId(String googleId) {"},{"lineNumber":224,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":225,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cUser\u003e usersCr \u003d cb.createQuery(User.class);"},{"lineNumber":226,"author":{"gitId":"-"},"content":" Root\u003cUser\u003e usersRoot \u003d usersCr.from(User.class);"},{"lineNumber":227,"author":{"gitId":"-"},"content":" Join\u003cUser, Account\u003e accountsJoin \u003d usersRoot.join(\"account\");"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" usersCr.select(usersRoot).where(cb.equal(accountsJoin.get(\"googleId\"), googleId));"},{"lineNumber":230,"author":{"gitId":"-"},"content":""},{"lineNumber":231,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(usersCr).getResultList();"},{"lineNumber":232,"author":{"gitId":"-"},"content":" }"},{"lineNumber":233,"author":{"gitId":"-"},"content":""},{"lineNumber":234,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":235,"author":{"gitId":"-"},"content":" * Gets all instructors by {@code googleId}."},{"lineNumber":236,"author":{"gitId":"-"},"content":" */"},{"lineNumber":237,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getAllInstructorsByGoogleId(String googleId) {"},{"lineNumber":238,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":239,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cInstructor\u003e instructorsCr \u003d cb.createQuery(Instructor.class);"},{"lineNumber":240,"author":{"gitId":"-"},"content":" Root\u003cInstructor\u003e instructorsRoot \u003d instructorsCr.from(Instructor.class);"},{"lineNumber":241,"author":{"gitId":"-"},"content":" Join\u003cInstructor, Account\u003e accountsJoin \u003d instructorsRoot.join(\"account\");"},{"lineNumber":242,"author":{"gitId":"-"},"content":""},{"lineNumber":243,"author":{"gitId":"-"},"content":" instructorsCr.select(instructorsRoot).where(cb.equal(accountsJoin.get(\"googleId\"), googleId));"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(instructorsCr).getResultList();"},{"lineNumber":246,"author":{"gitId":"-"},"content":" }"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":249,"author":{"gitId":"-"},"content":" * Gets all students by {@code googleId}."},{"lineNumber":250,"author":{"gitId":"-"},"content":" */"},{"lineNumber":251,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getAllStudentsByGoogleId(String googleId) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":253,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e studentsCr \u003d cb.createQuery(Student.class);"},{"lineNumber":254,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentsRoot \u003d studentsCr.from(Student.class);"},{"lineNumber":255,"author":{"gitId":"-"},"content":" Join\u003cStudent, Account\u003e accountsJoin \u003d studentsRoot.join(\"account\");"},{"lineNumber":256,"author":{"gitId":"-"},"content":""},{"lineNumber":257,"author":{"gitId":"-"},"content":" studentsCr.select(studentsRoot).where(cb.equal(accountsJoin.get(\"googleId\"), googleId));"},{"lineNumber":258,"author":{"gitId":"-"},"content":""},{"lineNumber":259,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(studentsCr).getResultList();"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":""},{"lineNumber":262,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":263,"author":{"gitId":"-"},"content":" * Gets all instructors."},{"lineNumber":264,"author":{"gitId":"-"},"content":" */"},{"lineNumber":265,"author":{"gitId":"-"},"content":" public \u003cT extends User\u003e T updateUser(T user) {"},{"lineNumber":266,"author":{"gitId":"-"},"content":" assert user !\u003d null;"},{"lineNumber":267,"author":{"gitId":"-"},"content":""},{"lineNumber":268,"author":{"gitId":"-"},"content":" return merge(user);"},{"lineNumber":269,"author":{"gitId":"-"},"content":" }"},{"lineNumber":270,"author":{"gitId":"-"},"content":""},{"lineNumber":271,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":272,"author":{"gitId":"-"},"content":" * Searches all instructors in the system."},{"lineNumber":273,"author":{"gitId":"-"},"content":" *"},{"lineNumber":274,"author":{"gitId":"-"},"content":" * \u003cp\u003eThis method should be used by admin only since the searching does not"},{"lineNumber":275,"author":{"gitId":"-"},"content":" * restrict the visibility according to the logged-in user\u0027s google ID. This"},{"lineNumber":276,"author":{"gitId":"-"},"content":" * is used by admin to search instructors in the whole system."},{"lineNumber":277,"author":{"gitId":"-"},"content":" */"},{"lineNumber":278,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e searchInstructorsInWholeSystem(String queryString)"},{"lineNumber":279,"author":{"gitId":"-"},"content":" throws SearchServiceException {"},{"lineNumber":280,"author":{"gitId":"-"},"content":" if (queryString.trim().isEmpty()) {"},{"lineNumber":281,"author":{"gitId":"-"},"content":" return new ArrayList\u003c\u003e();"},{"lineNumber":282,"author":{"gitId":"-"},"content":" }"},{"lineNumber":283,"author":{"gitId":"-"},"content":""},{"lineNumber":284,"author":{"gitId":"-"},"content":" return getInstructorSearchManager().searchInstructors(queryString);"},{"lineNumber":285,"author":{"gitId":"-"},"content":" }"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":288,"author":{"gitId":"yuanxi1"},"content":" * Searches for students."},{"lineNumber":289,"author":{"gitId":"yuanxi1"},"content":" *"},{"lineNumber":290,"author":{"gitId":"yuanxi1"},"content":" * @param instructors the constraint that restricts the search result"},{"lineNumber":291,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":292,"author":{"gitId":"yuanxi1"},"content":" public List\u003cStudent\u003e searchStudents(String queryString, List\u003cInstructor\u003e instructors)"},{"lineNumber":293,"author":{"gitId":"yuanxi1"},"content":" throws SearchServiceException {"},{"lineNumber":294,"author":{"gitId":"yuanxi1"},"content":" if (queryString.trim().isEmpty()) {"},{"lineNumber":295,"author":{"gitId":"yuanxi1"},"content":" return new ArrayList\u003c\u003e();"},{"lineNumber":296,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":297,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":298,"author":{"gitId":"yuanxi1"},"content":" return getStudentSearchManager().searchStudents(queryString, instructors);"},{"lineNumber":299,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":300,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":301,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":302,"author":{"gitId":"yuanxi1"},"content":" * Searches all students in the system."},{"lineNumber":303,"author":{"gitId":"yuanxi1"},"content":" *"},{"lineNumber":304,"author":{"gitId":"yuanxi1"},"content":" * \u003cp\u003eThis method should be used by admin only since the searching does not restrict the"},{"lineNumber":305,"author":{"gitId":"yuanxi1"},"content":" * visibility according to the logged-in user\u0027s google ID. This is used by admin to"},{"lineNumber":306,"author":{"gitId":"yuanxi1"},"content":" * search instructors in the whole system."},{"lineNumber":307,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":308,"author":{"gitId":"yuanxi1"},"content":" public List\u003cStudent\u003e searchStudentsInWholeSystem(String queryString)"},{"lineNumber":309,"author":{"gitId":"yuanxi1"},"content":" throws SearchServiceException {"},{"lineNumber":310,"author":{"gitId":"yuanxi1"},"content":" if (queryString.trim().isEmpty()) {"},{"lineNumber":311,"author":{"gitId":"yuanxi1"},"content":" return new ArrayList\u003c\u003e();"},{"lineNumber":312,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":313,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":314,"author":{"gitId":"yuanxi1"},"content":" return getStudentSearchManager().searchStudents(queryString, null);"},{"lineNumber":315,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":316,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":317,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":318,"author":{"gitId":"-"},"content":" * Deletes a user."},{"lineNumber":319,"author":{"gitId":"-"},"content":" */"},{"lineNumber":320,"author":{"gitId":"-"},"content":" public \u003cT extends User\u003e void deleteUser(T user) {"},{"lineNumber":321,"author":{"gitId":"-"},"content":" if (user !\u003d null) {"},{"lineNumber":322,"author":{"gitId":"-"},"content":" delete(user);"},{"lineNumber":323,"author":{"gitId":"-"},"content":" }"},{"lineNumber":324,"author":{"gitId":"-"},"content":" }"},{"lineNumber":325,"author":{"gitId":"-"},"content":""},{"lineNumber":326,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":327,"author":{"gitId":"-"},"content":" * Gets the number of instructors created within a specified time range."},{"lineNumber":328,"author":{"gitId":"-"},"content":" */"},{"lineNumber":329,"author":{"gitId":"-"},"content":" public long getNumInstructorsByTimeRange(Instant startTime, Instant endTime) {"},{"lineNumber":330,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":331,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cLong\u003e cr \u003d cb.createQuery(Long.class);"},{"lineNumber":332,"author":{"gitId":"-"},"content":" Root\u003cInstructor\u003e root \u003d cr.from(Instructor.class);"},{"lineNumber":333,"author":{"gitId":"-"},"content":""},{"lineNumber":334,"author":{"gitId":"-"},"content":" cr.select(cb.count(root.get(\"id\"))).where(cb.and("},{"lineNumber":335,"author":{"gitId":"-"},"content":" cb.greaterThanOrEqualTo(root.get(\"createdAt\"), startTime),"},{"lineNumber":336,"author":{"gitId":"-"},"content":" cb.lessThan(root.get(\"createdAt\"), endTime)));"},{"lineNumber":337,"author":{"gitId":"-"},"content":""},{"lineNumber":338,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getSingleResult();"},{"lineNumber":339,"author":{"gitId":"-"},"content":" }"},{"lineNumber":340,"author":{"gitId":"-"},"content":""},{"lineNumber":341,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":342,"author":{"gitId":"-"},"content":" * Gets the number of students created within a specified time range."},{"lineNumber":343,"author":{"gitId":"-"},"content":" */"},{"lineNumber":344,"author":{"gitId":"-"},"content":" public long getNumStudentsByTimeRange(Instant startTime, Instant endTime) {"},{"lineNumber":345,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":346,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cLong\u003e cr \u003d cb.createQuery(Long.class);"},{"lineNumber":347,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e root \u003d cr.from(Student.class);"},{"lineNumber":348,"author":{"gitId":"-"},"content":""},{"lineNumber":349,"author":{"gitId":"-"},"content":" cr.select(cb.count(root.get(\"id\"))).where(cb.and("},{"lineNumber":350,"author":{"gitId":"-"},"content":" cb.greaterThanOrEqualTo(root.get(\"createdAt\"), startTime),"},{"lineNumber":351,"author":{"gitId":"-"},"content":" cb.lessThan(root.get(\"createdAt\"), endTime)));"},{"lineNumber":352,"author":{"gitId":"-"},"content":""},{"lineNumber":353,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getSingleResult();"},{"lineNumber":354,"author":{"gitId":"-"},"content":" }"},{"lineNumber":355,"author":{"gitId":"-"},"content":""},{"lineNumber":356,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":357,"author":{"gitId":"-"},"content":" * Gets the list of instructors for the specified {@code courseId}."},{"lineNumber":358,"author":{"gitId":"-"},"content":" */"},{"lineNumber":359,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getInstructorsForCourse(String courseId) {"},{"lineNumber":360,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":361,"author":{"gitId":"-"},"content":""},{"lineNumber":362,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":363,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cInstructor\u003e cr \u003d cb.createQuery(Instructor.class);"},{"lineNumber":364,"author":{"gitId":"-"},"content":" Root\u003cInstructor\u003e root \u003d cr.from(Instructor.class);"},{"lineNumber":365,"author":{"gitId":"-"},"content":""},{"lineNumber":366,"author":{"gitId":"-"},"content":" cr.select(root).where(cb.equal(root.get(\"courseId\"), courseId));"},{"lineNumber":367,"author":{"gitId":"-"},"content":""},{"lineNumber":368,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":369,"author":{"gitId":"-"},"content":" }"},{"lineNumber":370,"author":{"gitId":"-"},"content":""},{"lineNumber":371,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":372,"author":{"gitId":"-"},"content":" * Gets the list of students for the specified {@code courseId}."},{"lineNumber":373,"author":{"gitId":"-"},"content":" */"},{"lineNumber":374,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsForCourse(String courseId) {"},{"lineNumber":375,"author":{"gitId":"-"},"content":" assert courseId !\u003d null \u0026\u0026 !courseId.isEmpty();"},{"lineNumber":376,"author":{"gitId":"-"},"content":""},{"lineNumber":377,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":378,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":379,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e root \u003d cr.from(Student.class);"},{"lineNumber":380,"author":{"gitId":"-"},"content":""},{"lineNumber":381,"author":{"gitId":"-"},"content":" cr.select(root).where(cb.equal(root.get(\"courseId\"), courseId));"},{"lineNumber":382,"author":{"gitId":"-"},"content":""},{"lineNumber":383,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":384,"author":{"gitId":"-"},"content":" }"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":387,"author":{"gitId":"-"},"content":" * Gets the list of students for the specified {@code courseId} in batches with {@code batchSize}."},{"lineNumber":388,"author":{"gitId":"-"},"content":" */"},{"lineNumber":389,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsForCourse(String courseId, int batchSize) {"},{"lineNumber":390,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":391,"author":{"gitId":"-"},"content":""},{"lineNumber":392,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":393,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":394,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e root \u003d cr.from(Student.class);"},{"lineNumber":395,"author":{"gitId":"-"},"content":""},{"lineNumber":396,"author":{"gitId":"-"},"content":" cr.select(root).where(cb.equal(root.get(\"courseId\"), courseId));"},{"lineNumber":397,"author":{"gitId":"-"},"content":""},{"lineNumber":398,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).setMaxResults(batchSize).getResultList();"},{"lineNumber":399,"author":{"gitId":"-"},"content":" }"},{"lineNumber":400,"author":{"gitId":"-"},"content":""},{"lineNumber":401,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":402,"author":{"gitId":"-"},"content":" * Gets the instructor with the specified {@code userEmail}."},{"lineNumber":403,"author":{"gitId":"-"},"content":" */"},{"lineNumber":404,"author":{"gitId":"-"},"content":" public Instructor getInstructorForEmail(String courseId, String userEmail) {"},{"lineNumber":405,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":406,"author":{"gitId":"-"},"content":" assert userEmail !\u003d null;"},{"lineNumber":407,"author":{"gitId":"-"},"content":""},{"lineNumber":408,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":409,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cInstructor\u003e cr \u003d cb.createQuery(Instructor.class);"},{"lineNumber":410,"author":{"gitId":"-"},"content":" Root\u003cInstructor\u003e instructorRoot \u003d cr.from(Instructor.class);"},{"lineNumber":411,"author":{"gitId":"-"},"content":""},{"lineNumber":412,"author":{"gitId":"-"},"content":" cr.select(instructorRoot)"},{"lineNumber":413,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":414,"author":{"gitId":"-"},"content":" cb.equal(instructorRoot.get(\"courseId\"), courseId),"},{"lineNumber":415,"author":{"gitId":"-"},"content":" cb.equal(instructorRoot.get(\"email\"), userEmail)));"},{"lineNumber":416,"author":{"gitId":"-"},"content":""},{"lineNumber":417,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultStream().findFirst().orElse(null);"},{"lineNumber":418,"author":{"gitId":"-"},"content":" }"},{"lineNumber":419,"author":{"gitId":"-"},"content":""},{"lineNumber":420,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":421,"author":{"gitId":"-"},"content":" * Gets instructors with the specified {@code userEmail}."},{"lineNumber":422,"author":{"gitId":"-"},"content":" */"},{"lineNumber":423,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getInstructorsForEmails(String courseId, List\u003cString\u003e userEmails) {"},{"lineNumber":424,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":425,"author":{"gitId":"-"},"content":" assert userEmails !\u003d null;"},{"lineNumber":426,"author":{"gitId":"-"},"content":""},{"lineNumber":427,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":428,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cInstructor\u003e cr \u003d cb.createQuery(Instructor.class);"},{"lineNumber":429,"author":{"gitId":"-"},"content":" Root\u003cInstructor\u003e instructorRoot \u003d cr.from(Instructor.class);"},{"lineNumber":430,"author":{"gitId":"-"},"content":""},{"lineNumber":431,"author":{"gitId":"-"},"content":" List\u003cPredicate\u003e predicates \u003d new ArrayList\u003c\u003e();"},{"lineNumber":432,"author":{"gitId":"-"},"content":" for (String userEmail : userEmails) {"},{"lineNumber":433,"author":{"gitId":"-"},"content":" predicates.add(cb.equal(instructorRoot.get(\"email\"), userEmail));"},{"lineNumber":434,"author":{"gitId":"-"},"content":" }"},{"lineNumber":435,"author":{"gitId":"-"},"content":""},{"lineNumber":436,"author":{"gitId":"-"},"content":" cr.select(instructorRoot)"},{"lineNumber":437,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":438,"author":{"gitId":"-"},"content":" cb.equal(instructorRoot.get(\"courseId\"), courseId),"},{"lineNumber":439,"author":{"gitId":"-"},"content":" cb.or(predicates.toArray(new Predicate[0]))));"},{"lineNumber":440,"author":{"gitId":"-"},"content":""},{"lineNumber":441,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":442,"author":{"gitId":"-"},"content":" }"},{"lineNumber":443,"author":{"gitId":"-"},"content":""},{"lineNumber":444,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":445,"author":{"gitId":"-"},"content":" * Gets the student with the specified {@code userEmail}."},{"lineNumber":446,"author":{"gitId":"-"},"content":" */"},{"lineNumber":447,"author":{"gitId":"-"},"content":" public Student getStudentForEmail(String courseId, String userEmail) {"},{"lineNumber":448,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":449,"author":{"gitId":"-"},"content":" assert userEmail !\u003d null;"},{"lineNumber":450,"author":{"gitId":"-"},"content":""},{"lineNumber":451,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":452,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":453,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":454,"author":{"gitId":"-"},"content":""},{"lineNumber":455,"author":{"gitId":"-"},"content":" cr.select(studentRoot)"},{"lineNumber":456,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":457,"author":{"gitId":"-"},"content":" cb.equal(studentRoot.get(\"courseId\"), courseId),"},{"lineNumber":458,"author":{"gitId":"-"},"content":" cb.equal(studentRoot.get(\"email\"), userEmail)));"},{"lineNumber":459,"author":{"gitId":"-"},"content":""},{"lineNumber":460,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultStream().findFirst().orElse(null);"},{"lineNumber":461,"author":{"gitId":"-"},"content":" }"},{"lineNumber":462,"author":{"gitId":"-"},"content":""},{"lineNumber":463,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":464,"author":{"gitId":"-"},"content":" * Gets students with the specified {@code userEmail}."},{"lineNumber":465,"author":{"gitId":"-"},"content":" */"},{"lineNumber":466,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsForEmails(String courseId, List\u003cString\u003e userEmails) {"},{"lineNumber":467,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":468,"author":{"gitId":"-"},"content":" assert userEmails !\u003d null;"},{"lineNumber":469,"author":{"gitId":"-"},"content":""},{"lineNumber":470,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":471,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":472,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":473,"author":{"gitId":"-"},"content":""},{"lineNumber":474,"author":{"gitId":"-"},"content":" List\u003cPredicate\u003e predicates \u003d new ArrayList\u003c\u003e();"},{"lineNumber":475,"author":{"gitId":"-"},"content":" for (String userEmail : userEmails) {"},{"lineNumber":476,"author":{"gitId":"-"},"content":" predicates.add(cb.equal(studentRoot.get(\"email\"), userEmail));"},{"lineNumber":477,"author":{"gitId":"-"},"content":" }"},{"lineNumber":478,"author":{"gitId":"-"},"content":""},{"lineNumber":479,"author":{"gitId":"-"},"content":" cr.select(studentRoot)"},{"lineNumber":480,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":481,"author":{"gitId":"-"},"content":" cb.equal(studentRoot.get(\"courseId\"), courseId),"},{"lineNumber":482,"author":{"gitId":"-"},"content":" cb.or(predicates.toArray(new Predicate[0]))));"},{"lineNumber":483,"author":{"gitId":"-"},"content":""},{"lineNumber":484,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":485,"author":{"gitId":"-"},"content":" }"},{"lineNumber":486,"author":{"gitId":"-"},"content":""},{"lineNumber":487,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":488,"author":{"gitId":"-"},"content":" * Gets list of students by email."},{"lineNumber":489,"author":{"gitId":"-"},"content":" */"},{"lineNumber":490,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getAllStudentsForEmail(String email) {"},{"lineNumber":491,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":492,"author":{"gitId":"-"},"content":""},{"lineNumber":493,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":494,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":495,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":496,"author":{"gitId":"-"},"content":""},{"lineNumber":497,"author":{"gitId":"-"},"content":" cr.select(studentRoot)"},{"lineNumber":498,"author":{"gitId":"-"},"content":" .where(cb.equal(studentRoot.get(\"email\"), email));"},{"lineNumber":499,"author":{"gitId":"-"},"content":""},{"lineNumber":500,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":501,"author":{"gitId":"-"},"content":" }"},{"lineNumber":502,"author":{"gitId":"-"},"content":""},{"lineNumber":503,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":504,"author":{"gitId":"-"},"content":" * Gets all instructors associated with a googleId."},{"lineNumber":505,"author":{"gitId":"-"},"content":" */"},{"lineNumber":506,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getInstructorsForGoogleId(String googleId) {"},{"lineNumber":507,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":508,"author":{"gitId":"-"},"content":""},{"lineNumber":509,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":510,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cInstructor\u003e cr \u003d cb.createQuery(Instructor.class);"},{"lineNumber":511,"author":{"gitId":"-"},"content":" Root\u003cInstructor\u003e instructorRoot \u003d cr.from(Instructor.class);"},{"lineNumber":512,"author":{"gitId":"-"},"content":" Join\u003cInstructor, Account\u003e accountsJoin \u003d instructorRoot.join(\"account\");"},{"lineNumber":513,"author":{"gitId":"-"},"content":""},{"lineNumber":514,"author":{"gitId":"-"},"content":" cr.select(instructorRoot).where(cb.equal(accountsJoin.get(\"googleId\"), googleId));"},{"lineNumber":515,"author":{"gitId":"-"},"content":""},{"lineNumber":516,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":517,"author":{"gitId":"-"},"content":" }"},{"lineNumber":518,"author":{"gitId":"-"},"content":""},{"lineNumber":519,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":520,"author":{"gitId":"-"},"content":" * Gets all students of a section of a course."},{"lineNumber":521,"author":{"gitId":"-"},"content":" */"},{"lineNumber":522,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsForSection(String sectionName, String courseId) {"},{"lineNumber":523,"author":{"gitId":"-"},"content":" assert sectionName !\u003d null;"},{"lineNumber":524,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":525,"author":{"gitId":"-"},"content":""},{"lineNumber":526,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":527,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":528,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":529,"author":{"gitId":"-"},"content":" Join\u003cStudent, Course\u003e courseJoin \u003d studentRoot.join(\"course\");"},{"lineNumber":530,"author":{"gitId":"-"},"content":" Join\u003cStudent, Team\u003e teamsJoin \u003d studentRoot.join(\"team\");"},{"lineNumber":531,"author":{"gitId":"-"},"content":" Join\u003cTeam, Section\u003e sectionJoin \u003d teamsJoin.join(\"section\");"},{"lineNumber":532,"author":{"gitId":"-"},"content":""},{"lineNumber":533,"author":{"gitId":"-"},"content":" cr.select(studentRoot)"},{"lineNumber":534,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":535,"author":{"gitId":"-"},"content":" cb.equal(courseJoin.get(\"id\"), courseId),"},{"lineNumber":536,"author":{"gitId":"-"},"content":" cb.equal(sectionJoin.get(\"name\"), sectionName)));"},{"lineNumber":537,"author":{"gitId":"-"},"content":""},{"lineNumber":538,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":539,"author":{"gitId":"-"},"content":" }"},{"lineNumber":540,"author":{"gitId":"-"},"content":""},{"lineNumber":541,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":542,"author":{"gitId":"-"},"content":" * Gets all students of a team of a course."},{"lineNumber":543,"author":{"gitId":"-"},"content":" */"},{"lineNumber":544,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsForTeam(String teamName, String courseId) {"},{"lineNumber":545,"author":{"gitId":"-"},"content":" assert teamName !\u003d null;"},{"lineNumber":546,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":547,"author":{"gitId":"-"},"content":""},{"lineNumber":548,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":549,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":550,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":551,"author":{"gitId":"-"},"content":" Join\u003cStudent, Course\u003e courseJoin \u003d studentRoot.join(\"course\");"},{"lineNumber":552,"author":{"gitId":"-"},"content":" Join\u003cStudent, Team\u003e teamsJoin \u003d studentRoot.join(\"team\");"},{"lineNumber":553,"author":{"gitId":"-"},"content":""},{"lineNumber":554,"author":{"gitId":"-"},"content":" cr.select(studentRoot)"},{"lineNumber":555,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":556,"author":{"gitId":"-"},"content":" cb.equal(courseJoin.get(\"id\"), courseId),"},{"lineNumber":557,"author":{"gitId":"-"},"content":" cb.equal(teamsJoin.get(\"name\"), teamName)));"},{"lineNumber":558,"author":{"gitId":"-"},"content":""},{"lineNumber":559,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":560,"author":{"gitId":"-"},"content":" }"},{"lineNumber":561,"author":{"gitId":"-"},"content":""},{"lineNumber":562,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":563,"author":{"gitId":"-"},"content":" * Gets count of students of a team of a course."},{"lineNumber":564,"author":{"gitId":"-"},"content":" */"},{"lineNumber":565,"author":{"gitId":"-"},"content":" public long getStudentCountForTeam(String teamName, String courseId) {"},{"lineNumber":566,"author":{"gitId":"-"},"content":" assert teamName !\u003d null;"},{"lineNumber":567,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":568,"author":{"gitId":"-"},"content":""},{"lineNumber":569,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":570,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cLong\u003e cr \u003d cb.createQuery(Long.class);"},{"lineNumber":571,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":572,"author":{"gitId":"-"},"content":" Join\u003cStudent, Course\u003e courseJoin \u003d studentRoot.join(\"course\");"},{"lineNumber":573,"author":{"gitId":"-"},"content":" Join\u003cStudent, Team\u003e teamsJoin \u003d studentRoot.join(\"team\");"},{"lineNumber":574,"author":{"gitId":"-"},"content":""},{"lineNumber":575,"author":{"gitId":"-"},"content":" cr.select(cb.count(studentRoot.get(\"id\")))"},{"lineNumber":576,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":577,"author":{"gitId":"-"},"content":" cb.equal(courseJoin.get(\"id\"), courseId),"},{"lineNumber":578,"author":{"gitId":"-"},"content":" cb.equal(teamsJoin.get(\"name\"), teamName)));"},{"lineNumber":579,"author":{"gitId":"-"},"content":""},{"lineNumber":580,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getSingleResult();"},{"lineNumber":581,"author":{"gitId":"-"},"content":" }"},{"lineNumber":582,"author":{"gitId":"-"},"content":""},{"lineNumber":583,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":584,"author":{"gitId":"domoberzin"},"content":" * Gets the section with the specified {@code sectionName} and {@code courseId}."},{"lineNumber":585,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":586,"author":{"gitId":"domoberzin"},"content":" public Section getSection(String courseId, String sectionName) {"},{"lineNumber":587,"author":{"gitId":"domoberzin"},"content":" assert sectionName !\u003d null;"},{"lineNumber":588,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":589,"author":{"gitId":"domoberzin"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":590,"author":{"gitId":"domoberzin"},"content":" CriteriaQuery\u003cSection\u003e cr \u003d cb.createQuery(Section.class);"},{"lineNumber":591,"author":{"gitId":"domoberzin"},"content":" Root\u003cSection\u003e sectionRoot \u003d cr.from(Section.class);"},{"lineNumber":592,"author":{"gitId":"domoberzin"},"content":" Join\u003cSection, Course\u003e courseJoin \u003d sectionRoot.join(\"course\");"},{"lineNumber":593,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":594,"author":{"gitId":"domoberzin"},"content":" cr.select(sectionRoot)"},{"lineNumber":595,"author":{"gitId":"domoberzin"},"content":" .where(cb.and("},{"lineNumber":596,"author":{"gitId":"domoberzin"},"content":" cb.equal(courseJoin.get(\"id\"), courseId),"},{"lineNumber":597,"author":{"gitId":"domoberzin"},"content":" cb.equal(sectionRoot.get(\"name\"), sectionName)));"},{"lineNumber":598,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":599,"author":{"gitId":"domoberzin"},"content":" return HibernateUtil.createQuery(cr).getResultStream().findFirst().orElse(null);"},{"lineNumber":600,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":601,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":602,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":603,"author":{"gitId":"domoberzin"},"content":" * Gets a section by its {@code courseId} and {@code sectionName}."},{"lineNumber":604,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":605,"author":{"gitId":"domoberzin"},"content":" public Section getSectionOrCreate(String courseId, String sectionName) {"},{"lineNumber":606,"author":{"gitId":"domoberzin"},"content":" assert courseId !\u003d null;"},{"lineNumber":607,"author":{"gitId":"domoberzin"},"content":" assert sectionName !\u003d null;"},{"lineNumber":608,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":609,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getSection(courseId, sectionName);"},{"lineNumber":610,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":611,"author":{"gitId":"domoberzin"},"content":" if (section \u003d\u003d null) {"},{"lineNumber":612,"author":{"gitId":"domoberzin"},"content":" Course course \u003d CoursesDb.inst().getCourse(courseId);"},{"lineNumber":613,"author":{"gitId":"domoberzin"},"content":" section \u003d new Section(course, sectionName);"},{"lineNumber":614,"author":{"gitId":"domoberzin"},"content":" persist(section);"},{"lineNumber":615,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":616,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":617,"author":{"gitId":"domoberzin"},"content":" return section;"},{"lineNumber":618,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":619,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":620,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":621,"author":{"gitId":"domoberzin"},"content":" * Gets a team by its {@code section} and {@code teamName}."},{"lineNumber":622,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":623,"author":{"gitId":"domoberzin"},"content":" public Team getTeam(Section section, String teamName) {"},{"lineNumber":624,"author":{"gitId":"domoberzin"},"content":" assert teamName !\u003d null;"},{"lineNumber":625,"author":{"gitId":"domoberzin"},"content":" assert section !\u003d null;"},{"lineNumber":626,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":627,"author":{"gitId":"domoberzin"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":628,"author":{"gitId":"domoberzin"},"content":" CriteriaQuery\u003cTeam\u003e cr \u003d cb.createQuery(Team.class);"},{"lineNumber":629,"author":{"gitId":"domoberzin"},"content":" Root\u003cTeam\u003e teamRoot \u003d cr.from(Team.class);"},{"lineNumber":630,"author":{"gitId":"domoberzin"},"content":" Join\u003cTeam, Section\u003e sectionJoin \u003d teamRoot.join(\"section\");"},{"lineNumber":631,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":632,"author":{"gitId":"domoberzin"},"content":" cr.select(teamRoot)"},{"lineNumber":633,"author":{"gitId":"domoberzin"},"content":" .where(cb.and("},{"lineNumber":634,"author":{"gitId":"domoberzin"},"content":" cb.equal(sectionJoin.get(\"id\"), section.getId()),"},{"lineNumber":635,"author":{"gitId":"domoberzin"},"content":" cb.equal(teamRoot.get(\"name\"), teamName)));"},{"lineNumber":636,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":637,"author":{"gitId":"domoberzin"},"content":" return HibernateUtil.createQuery(cr).getResultStream().findFirst().orElse(null);"},{"lineNumber":638,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":639,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":640,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":641,"author":{"gitId":"domoberzin"},"content":" * Gets a team by its {@code section} and {@code teamName}."},{"lineNumber":642,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":643,"author":{"gitId":"domoberzin"},"content":" public Team getTeamOrCreate(Section section, String teamName) {"},{"lineNumber":644,"author":{"gitId":"domoberzin"},"content":" assert teamName !\u003d null;"},{"lineNumber":645,"author":{"gitId":"domoberzin"},"content":" assert section !\u003d null;"},{"lineNumber":646,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":647,"author":{"gitId":"domoberzin"},"content":" Team team \u003d getTeam(section, teamName);"},{"lineNumber":648,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":649,"author":{"gitId":"domoberzin"},"content":" if (team \u003d\u003d null) {"},{"lineNumber":650,"author":{"gitId":"domoberzin"},"content":" team \u003d new Team(section, teamName);"},{"lineNumber":651,"author":{"gitId":"domoberzin"},"content":" persist(team);"},{"lineNumber":652,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":653,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":654,"author":{"gitId":"domoberzin"},"content":" return team;"},{"lineNumber":655,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":656,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":657,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":658,"author":{"gitId":"domoberzin"},"content":" * Updates a student."},{"lineNumber":659,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":660,"author":{"gitId":"domoberzin"},"content":" public Student updateStudent(Student student)"},{"lineNumber":661,"author":{"gitId":"domoberzin"},"content":" throws EntityDoesNotExistException, InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":662,"author":{"gitId":"marquestye"},"content":" checkBeforeUpdateStudent(student);"},{"lineNumber":663,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":664,"author":{"gitId":"marquestye"},"content":" return merge(student);"},{"lineNumber":665,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":666,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":667,"author":{"gitId":"marquestye"},"content":" /**"},{"lineNumber":668,"author":{"gitId":"marquestye"},"content":" * Performs checks on student without updating."},{"lineNumber":669,"author":{"gitId":"marquestye"},"content":" */"},{"lineNumber":670,"author":{"gitId":"marquestye"},"content":" public void checkBeforeUpdateStudent(Student student)"},{"lineNumber":671,"author":{"gitId":"marquestye"},"content":" throws EntityDoesNotExistException, InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":672,"author":{"gitId":"domoberzin"},"content":" assert student !\u003d null;"},{"lineNumber":673,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":674,"author":{"gitId":"domoberzin"},"content":" if (!student.isValid()) {"},{"lineNumber":675,"author":{"gitId":"domoberzin"},"content":" throw new InvalidParametersException(student.getInvalidityInfo());"},{"lineNumber":676,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":677,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":678,"author":{"gitId":"domoberzin"},"content":" if (getStudent(student.getId()) \u003d\u003d null) {"},{"lineNumber":679,"author":{"gitId":"domoberzin"},"content":" throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT);"},{"lineNumber":680,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":681,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":682,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":683,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":93,"yuanxi1":30,"marquestye":10,"dishenggg":9,"-":541}},{"path":"src/main/java/teammates/storage/sqlentity/FeedbackQuestion.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlentity;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Objects;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.persistence.CascadeType;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import jakarta.persistence.Column;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import jakarta.persistence.Convert;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.persistence.Entity;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import jakarta.persistence.EnumType;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import jakarta.persistence.Enumerated;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import jakarta.persistence.Id;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import jakarta.persistence.Inheritance;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import jakarta.persistence.InheritanceType;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import jakarta.persistence.JoinColumn;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import jakarta.persistence.ManyToOne;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import jakarta.persistence.OneToMany;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import jakarta.persistence.Table;"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":"import org.hibernate.annotations.UpdateTimestamp;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionDetails;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackConstantSumQuestion;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackContributionQuestion;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackMcqQuestion;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackMsqQuestion;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackNumericalScaleQuestion;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackRankOptionsQuestion;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackRankRecipientsQuestion;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackRubricQuestion;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackTextQuestion;"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":39,"author":{"gitId":"-"},"content":" * Represents a feedback question."},{"lineNumber":40,"author":{"gitId":"-"},"content":" */"},{"lineNumber":41,"author":{"gitId":"-"},"content":"@Entity"},{"lineNumber":42,"author":{"gitId":"-"},"content":"@Table(name \u003d \"FeedbackQuestions\")"},{"lineNumber":43,"author":{"gitId":"-"},"content":"@Inheritance(strategy \u003d InheritanceType.SINGLE_TABLE)"},{"lineNumber":44,"author":{"gitId":"-"},"content":"public abstract class FeedbackQuestion extends BaseEntity implements Comparable\u003cFeedbackQuestion\u003e {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" @Id"},{"lineNumber":46,"author":{"gitId":"-"},"content":" private UUID id;"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" @ManyToOne"},{"lineNumber":49,"author":{"gitId":"-"},"content":" @JoinColumn(name \u003d \"sessionId\")"},{"lineNumber":50,"author":{"gitId":"-"},"content":" private FeedbackSession feedbackSession;"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" @OneToMany(mappedBy \u003d \"feedbackQuestion\", cascade \u003d CascadeType.REMOVE)"},{"lineNumber":53,"author":{"gitId":"-"},"content":" private List\u003cFeedbackResponse\u003e feedbackResponses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":56,"author":{"gitId":"-"},"content":" private Integer questionNumber;"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" @Column(nullable \u003d true)"},{"lineNumber":59,"author":{"gitId":"-"},"content":" private String description;"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":62,"author":{"gitId":"-"},"content":" @Enumerated(EnumType.STRING)"},{"lineNumber":63,"author":{"gitId":"-"},"content":" private FeedbackParticipantType giverType;"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":66,"author":{"gitId":"-"},"content":" @Enumerated(EnumType.STRING)"},{"lineNumber":67,"author":{"gitId":"-"},"content":" private FeedbackParticipantType recipientType;"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":70,"author":{"gitId":"-"},"content":" private Integer numOfEntitiesToGiveFeedbackTo;"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":73,"author":{"gitId":"-"},"content":" @Convert(converter \u003d FeedbackParticipantTypeListConverter.class)"},{"lineNumber":74,"author":{"gitId":"-"},"content":" private List\u003cFeedbackParticipantType\u003e showResponsesTo;"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":77,"author":{"gitId":"-"},"content":" @Convert(converter \u003d FeedbackParticipantTypeListConverter.class)"},{"lineNumber":78,"author":{"gitId":"-"},"content":" private List\u003cFeedbackParticipantType\u003e showGiverNameTo;"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":81,"author":{"gitId":"-"},"content":" @Convert(converter \u003d FeedbackParticipantTypeListConverter.class)"},{"lineNumber":82,"author":{"gitId":"-"},"content":" private List\u003cFeedbackParticipantType\u003e showRecipientNameTo;"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" @UpdateTimestamp"},{"lineNumber":85,"author":{"gitId":"-"},"content":" @Column"},{"lineNumber":86,"author":{"gitId":"-"},"content":" private Instant updatedAt;"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" protected FeedbackQuestion() {"},{"lineNumber":89,"author":{"gitId":"-"},"content":" // required by Hibernate"},{"lineNumber":90,"author":{"gitId":"-"},"content":" }"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" public FeedbackQuestion("},{"lineNumber":93,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession, Integer questionNumber,"},{"lineNumber":94,"author":{"gitId":"-"},"content":" String description, FeedbackParticipantType giverType, FeedbackParticipantType recipientType,"},{"lineNumber":95,"author":{"gitId":"-"},"content":" Integer numOfEntitiesToGiveFeedbackTo, List\u003cFeedbackParticipantType\u003e showResponsesTo,"},{"lineNumber":96,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showGiverNameTo, List\u003cFeedbackParticipantType\u003e showRecipientNameTo"},{"lineNumber":97,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" this.setId(UUID.randomUUID());"},{"lineNumber":99,"author":{"gitId":"-"},"content":" this.setFeedbackSession(feedbackSession);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" this.setQuestionNumber(questionNumber);"},{"lineNumber":101,"author":{"gitId":"-"},"content":" this.setDescription(description);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" this.setGiverType(giverType);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" this.setRecipientType(recipientType);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" this.setNumOfEntitiesToGiveFeedbackTo(numOfEntitiesToGiveFeedbackTo);"},{"lineNumber":105,"author":{"gitId":"-"},"content":" this.setShowResponsesTo(showResponsesTo);"},{"lineNumber":106,"author":{"gitId":"-"},"content":" this.setShowGiverNameTo(showGiverNameTo);"},{"lineNumber":107,"author":{"gitId":"-"},"content":" this.setShowRecipientNameTo(showRecipientNameTo);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":111,"author":{"gitId":"-"},"content":" * Gets a copy of the question details of the feedback question."},{"lineNumber":112,"author":{"gitId":"-"},"content":" */"},{"lineNumber":113,"author":{"gitId":"-"},"content":" public abstract FeedbackQuestionDetails getQuestionDetailsCopy();"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":116,"author":{"gitId":"-"},"content":" * Make a copy of the FeedbackQuestion."},{"lineNumber":117,"author":{"gitId":"-"},"content":" */"},{"lineNumber":118,"author":{"gitId":"-"},"content":" public abstract FeedbackQuestion makeDeepCopy(FeedbackSession newFeedbackSession);"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":121,"author":{"gitId":"-"},"content":" * Creates a feedback question according to its {@code FeedbackQuestionType}."},{"lineNumber":122,"author":{"gitId":"-"},"content":" */"},{"lineNumber":123,"author":{"gitId":"-"},"content":" public static FeedbackQuestion makeQuestion("},{"lineNumber":124,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession, Integer questionNumber,"},{"lineNumber":125,"author":{"gitId":"-"},"content":" String description, FeedbackParticipantType giverType, FeedbackParticipantType recipientType,"},{"lineNumber":126,"author":{"gitId":"-"},"content":" Integer numOfEntitiesToGiveFeedbackTo, List\u003cFeedbackParticipantType\u003e showResponsesTo,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showGiverNameTo, List\u003cFeedbackParticipantType\u003e showRecipientNameTo,"},{"lineNumber":128,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails feedbackQuestionDetails"},{"lineNumber":129,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" FeedbackQuestion feedbackQuestion \u003d null;"},{"lineNumber":131,"author":{"gitId":"-"},"content":" switch (feedbackQuestionDetails.getQuestionType()) {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" case TEXT:"},{"lineNumber":133,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d new FeedbackTextQuestion("},{"lineNumber":134,"author":{"gitId":"-"},"content":" feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":135,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo,"},{"lineNumber":136,"author":{"gitId":"-"},"content":" feedbackQuestionDetails"},{"lineNumber":137,"author":{"gitId":"-"},"content":" );"},{"lineNumber":138,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":139,"author":{"gitId":"-"},"content":" case MCQ:"},{"lineNumber":140,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d new FeedbackMcqQuestion("},{"lineNumber":141,"author":{"gitId":"-"},"content":" feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":142,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo,"},{"lineNumber":143,"author":{"gitId":"-"},"content":" feedbackQuestionDetails"},{"lineNumber":144,"author":{"gitId":"-"},"content":" );"},{"lineNumber":145,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":146,"author":{"gitId":"-"},"content":" case MSQ:"},{"lineNumber":147,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d new FeedbackMsqQuestion("},{"lineNumber":148,"author":{"gitId":"-"},"content":" feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":149,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo,"},{"lineNumber":150,"author":{"gitId":"-"},"content":" feedbackQuestionDetails"},{"lineNumber":151,"author":{"gitId":"-"},"content":" );"},{"lineNumber":152,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":153,"author":{"gitId":"-"},"content":" case NUMSCALE:"},{"lineNumber":154,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d new FeedbackNumericalScaleQuestion("},{"lineNumber":155,"author":{"gitId":"-"},"content":" feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":156,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo,"},{"lineNumber":157,"author":{"gitId":"-"},"content":" feedbackQuestionDetails"},{"lineNumber":158,"author":{"gitId":"-"},"content":" );"},{"lineNumber":159,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":160,"author":{"gitId":"-"},"content":" case CONSTSUM:"},{"lineNumber":161,"author":{"gitId":"-"},"content":" case CONSTSUM_OPTIONS:"},{"lineNumber":162,"author":{"gitId":"-"},"content":" case CONSTSUM_RECIPIENTS:"},{"lineNumber":163,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d new FeedbackConstantSumQuestion("},{"lineNumber":164,"author":{"gitId":"-"},"content":" feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":165,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo,"},{"lineNumber":166,"author":{"gitId":"-"},"content":" feedbackQuestionDetails"},{"lineNumber":167,"author":{"gitId":"-"},"content":" );"},{"lineNumber":168,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":169,"author":{"gitId":"-"},"content":" case CONTRIB:"},{"lineNumber":170,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d new FeedbackContributionQuestion("},{"lineNumber":171,"author":{"gitId":"-"},"content":" feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":172,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo,"},{"lineNumber":173,"author":{"gitId":"-"},"content":" feedbackQuestionDetails"},{"lineNumber":174,"author":{"gitId":"-"},"content":" );"},{"lineNumber":175,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":176,"author":{"gitId":"-"},"content":" case RUBRIC:"},{"lineNumber":177,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d new FeedbackRubricQuestion("},{"lineNumber":178,"author":{"gitId":"-"},"content":" feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":179,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo,"},{"lineNumber":180,"author":{"gitId":"-"},"content":" feedbackQuestionDetails"},{"lineNumber":181,"author":{"gitId":"-"},"content":" );"},{"lineNumber":182,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":183,"author":{"gitId":"-"},"content":" case RANK_OPTIONS:"},{"lineNumber":184,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d new FeedbackRankOptionsQuestion("},{"lineNumber":185,"author":{"gitId":"-"},"content":" feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":186,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo,"},{"lineNumber":187,"author":{"gitId":"-"},"content":" feedbackQuestionDetails"},{"lineNumber":188,"author":{"gitId":"-"},"content":" );"},{"lineNumber":189,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":190,"author":{"gitId":"-"},"content":" case RANK_RECIPIENTS:"},{"lineNumber":191,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d new FeedbackRankRecipientsQuestion("},{"lineNumber":192,"author":{"gitId":"-"},"content":" feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":193,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo,"},{"lineNumber":194,"author":{"gitId":"-"},"content":" feedbackQuestionDetails"},{"lineNumber":195,"author":{"gitId":"-"},"content":" );"},{"lineNumber":196,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }"},{"lineNumber":198,"author":{"gitId":"-"},"content":" return feedbackQuestion;"},{"lineNumber":199,"author":{"gitId":"-"},"content":" }"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":202,"author":{"gitId":"-"},"content":" public List\u003cString\u003e getInvalidityInfo() {"},{"lineNumber":203,"author":{"gitId":"-"},"content":" List\u003cString\u003e errors \u003d new ArrayList\u003c\u003e();"},{"lineNumber":204,"author":{"gitId":"-"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" errors.addAll(FieldValidator.getValidityInfoForFeedbackParticipantType(giverType, recipientType));"},{"lineNumber":206,"author":{"gitId":"-"},"content":""},{"lineNumber":207,"author":{"gitId":"-"},"content":" errors.addAll(FieldValidator.getValidityInfoForFeedbackResponseVisibility(showResponsesTo,"},{"lineNumber":208,"author":{"gitId":"-"},"content":" showGiverNameTo,"},{"lineNumber":209,"author":{"gitId":"-"},"content":" showRecipientNameTo));"},{"lineNumber":210,"author":{"gitId":"-"},"content":""},{"lineNumber":211,"author":{"gitId":"-"},"content":" return errors;"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":215,"author":{"gitId":"-"},"content":" * Checks if updating this question to the question will"},{"lineNumber":216,"author":{"gitId":"-"},"content":" * require the responses to be deleted for consistency."},{"lineNumber":217,"author":{"gitId":"-"},"content":" * Does not check if any responses exist."},{"lineNumber":218,"author":{"gitId":"-"},"content":" */"},{"lineNumber":219,"author":{"gitId":"-"},"content":" public boolean areResponseDeletionsRequiredForChanges(FeedbackParticipantType giverType,"},{"lineNumber":220,"author":{"gitId":"-"},"content":" FeedbackParticipantType recipientType,"},{"lineNumber":221,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails questionDetails) {"},{"lineNumber":222,"author":{"gitId":"-"},"content":" if (!giverType.equals(this.giverType)"},{"lineNumber":223,"author":{"gitId":"-"},"content":" || !recipientType.equals(this.recipientType)) {"},{"lineNumber":224,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":225,"author":{"gitId":"-"},"content":" }"},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"-"},"content":" return this.getQuestionDetailsCopy().shouldChangesRequireResponseDeletion(questionDetails);"},{"lineNumber":228,"author":{"gitId":"-"},"content":" }"},{"lineNumber":229,"author":{"gitId":"-"},"content":""},{"lineNumber":230,"author":{"gitId":"-"},"content":" public UUID getId() {"},{"lineNumber":231,"author":{"gitId":"-"},"content":" return id;"},{"lineNumber":232,"author":{"gitId":"-"},"content":" }"},{"lineNumber":233,"author":{"gitId":"-"},"content":""},{"lineNumber":234,"author":{"gitId":"-"},"content":" public void setId(UUID id) {"},{"lineNumber":235,"author":{"gitId":"-"},"content":" this.id \u003d id;"},{"lineNumber":236,"author":{"gitId":"-"},"content":" }"},{"lineNumber":237,"author":{"gitId":"-"},"content":""},{"lineNumber":238,"author":{"gitId":"-"},"content":" public FeedbackSession getFeedbackSession() {"},{"lineNumber":239,"author":{"gitId":"-"},"content":" return feedbackSession;"},{"lineNumber":240,"author":{"gitId":"-"},"content":" }"},{"lineNumber":241,"author":{"gitId":"-"},"content":""},{"lineNumber":242,"author":{"gitId":"xenosf"},"content":" public String getFeedbackSessionName() {"},{"lineNumber":243,"author":{"gitId":"xenosf"},"content":" return feedbackSession.getName();"},{"lineNumber":244,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":245,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" public void setFeedbackSession(FeedbackSession feedbackSession) {"},{"lineNumber":247,"author":{"gitId":"-"},"content":" this.feedbackSession \u003d feedbackSession;"},{"lineNumber":248,"author":{"gitId":"-"},"content":" }"},{"lineNumber":249,"author":{"gitId":"-"},"content":""},{"lineNumber":250,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponses() {"},{"lineNumber":251,"author":{"gitId":"-"},"content":" return feedbackResponses;"},{"lineNumber":252,"author":{"gitId":"-"},"content":" }"},{"lineNumber":253,"author":{"gitId":"-"},"content":""},{"lineNumber":254,"author":{"gitId":"-"},"content":" public void setFeedbackResponses(List\u003cFeedbackResponse\u003e feedbackResponses) {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" this.feedbackResponses \u003d feedbackResponses;"},{"lineNumber":256,"author":{"gitId":"-"},"content":" }"},{"lineNumber":257,"author":{"gitId":"-"},"content":""},{"lineNumber":258,"author":{"gitId":"-"},"content":" public Integer getQuestionNumber() {"},{"lineNumber":259,"author":{"gitId":"-"},"content":" return questionNumber;"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":""},{"lineNumber":262,"author":{"gitId":"-"},"content":" public void setQuestionNumber(Integer questionNumber) {"},{"lineNumber":263,"author":{"gitId":"-"},"content":" this.questionNumber \u003d questionNumber;"},{"lineNumber":264,"author":{"gitId":"-"},"content":" }"},{"lineNumber":265,"author":{"gitId":"-"},"content":""},{"lineNumber":266,"author":{"gitId":"-"},"content":" public String getDescription() {"},{"lineNumber":267,"author":{"gitId":"-"},"content":" return description;"},{"lineNumber":268,"author":{"gitId":"-"},"content":" }"},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":" public void setDescription(String description) {"},{"lineNumber":271,"author":{"gitId":"-"},"content":" this.description \u003d description;"},{"lineNumber":272,"author":{"gitId":"-"},"content":" }"},{"lineNumber":273,"author":{"gitId":"-"},"content":""},{"lineNumber":274,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":275,"author":{"gitId":"-"},"content":" * Set the question details of the question."},{"lineNumber":276,"author":{"gitId":"-"},"content":" */"},{"lineNumber":277,"author":{"gitId":"-"},"content":" public abstract void setQuestionDetails(FeedbackQuestionDetails questionDetails);"},{"lineNumber":278,"author":{"gitId":"-"},"content":""},{"lineNumber":279,"author":{"gitId":"-"},"content":" public FeedbackParticipantType getGiverType() {"},{"lineNumber":280,"author":{"gitId":"-"},"content":" return giverType;"},{"lineNumber":281,"author":{"gitId":"-"},"content":" }"},{"lineNumber":282,"author":{"gitId":"-"},"content":""},{"lineNumber":283,"author":{"gitId":"-"},"content":" public void setGiverType(FeedbackParticipantType giverType) {"},{"lineNumber":284,"author":{"gitId":"-"},"content":" this.giverType \u003d giverType;"},{"lineNumber":285,"author":{"gitId":"-"},"content":" }"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"-"},"content":" public FeedbackParticipantType getRecipientType() {"},{"lineNumber":288,"author":{"gitId":"-"},"content":" return recipientType;"},{"lineNumber":289,"author":{"gitId":"-"},"content":" }"},{"lineNumber":290,"author":{"gitId":"-"},"content":""},{"lineNumber":291,"author":{"gitId":"-"},"content":" public void setRecipientType(FeedbackParticipantType recipientType) {"},{"lineNumber":292,"author":{"gitId":"-"},"content":" this.recipientType \u003d recipientType;"},{"lineNumber":293,"author":{"gitId":"-"},"content":" }"},{"lineNumber":294,"author":{"gitId":"-"},"content":""},{"lineNumber":295,"author":{"gitId":"-"},"content":" public Integer getNumOfEntitiesToGiveFeedbackTo() {"},{"lineNumber":296,"author":{"gitId":"-"},"content":" return numOfEntitiesToGiveFeedbackTo;"},{"lineNumber":297,"author":{"gitId":"-"},"content":" }"},{"lineNumber":298,"author":{"gitId":"-"},"content":""},{"lineNumber":299,"author":{"gitId":"-"},"content":" public void setNumOfEntitiesToGiveFeedbackTo(Integer numOfEntitiesToGiveFeedbackTo) {"},{"lineNumber":300,"author":{"gitId":"-"},"content":" this.numOfEntitiesToGiveFeedbackTo \u003d numOfEntitiesToGiveFeedbackTo;"},{"lineNumber":301,"author":{"gitId":"-"},"content":" }"},{"lineNumber":302,"author":{"gitId":"-"},"content":""},{"lineNumber":303,"author":{"gitId":"-"},"content":" public List\u003cFeedbackParticipantType\u003e getShowResponsesTo() {"},{"lineNumber":304,"author":{"gitId":"-"},"content":" return showResponsesTo;"},{"lineNumber":305,"author":{"gitId":"-"},"content":" }"},{"lineNumber":306,"author":{"gitId":"-"},"content":""},{"lineNumber":307,"author":{"gitId":"-"},"content":" public void setShowResponsesTo(List\u003cFeedbackParticipantType\u003e showResponsesTo) {"},{"lineNumber":308,"author":{"gitId":"-"},"content":" this.showResponsesTo \u003d showResponsesTo;"},{"lineNumber":309,"author":{"gitId":"-"},"content":" }"},{"lineNumber":310,"author":{"gitId":"-"},"content":""},{"lineNumber":311,"author":{"gitId":"-"},"content":" public List\u003cFeedbackParticipantType\u003e getShowGiverNameTo() {"},{"lineNumber":312,"author":{"gitId":"-"},"content":" return showGiverNameTo;"},{"lineNumber":313,"author":{"gitId":"-"},"content":" }"},{"lineNumber":314,"author":{"gitId":"-"},"content":""},{"lineNumber":315,"author":{"gitId":"-"},"content":" public void setShowGiverNameTo(List\u003cFeedbackParticipantType\u003e showGiverNameTo) {"},{"lineNumber":316,"author":{"gitId":"-"},"content":" this.showGiverNameTo \u003d showGiverNameTo;"},{"lineNumber":317,"author":{"gitId":"-"},"content":" }"},{"lineNumber":318,"author":{"gitId":"-"},"content":""},{"lineNumber":319,"author":{"gitId":"-"},"content":" public List\u003cFeedbackParticipantType\u003e getShowRecipientNameTo() {"},{"lineNumber":320,"author":{"gitId":"-"},"content":" return showRecipientNameTo;"},{"lineNumber":321,"author":{"gitId":"-"},"content":" }"},{"lineNumber":322,"author":{"gitId":"-"},"content":""},{"lineNumber":323,"author":{"gitId":"-"},"content":" public void setShowRecipientNameTo(List\u003cFeedbackParticipantType\u003e showRecipientNameTo) {"},{"lineNumber":324,"author":{"gitId":"-"},"content":" this.showRecipientNameTo \u003d showRecipientNameTo;"},{"lineNumber":325,"author":{"gitId":"-"},"content":" }"},{"lineNumber":326,"author":{"gitId":"-"},"content":""},{"lineNumber":327,"author":{"gitId":"-"},"content":" public Instant getUpdatedAt() {"},{"lineNumber":328,"author":{"gitId":"-"},"content":" return updatedAt;"},{"lineNumber":329,"author":{"gitId":"-"},"content":" }"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" public void setUpdatedAt(Instant updatedAt) {"},{"lineNumber":332,"author":{"gitId":"-"},"content":" this.updatedAt \u003d updatedAt;"},{"lineNumber":333,"author":{"gitId":"-"},"content":" }"},{"lineNumber":334,"author":{"gitId":"-"},"content":""},{"lineNumber":335,"author":{"gitId":"xenosf"},"content":" public Course getCourse() {"},{"lineNumber":336,"author":{"gitId":"xenosf"},"content":" return this.feedbackSession.getCourse();"},{"lineNumber":337,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":338,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":339,"author":{"gitId":"-"},"content":" public String getCourseId() {"},{"lineNumber":340,"author":{"gitId":"-"},"content":" return this.feedbackSession.getCourse().getId();"},{"lineNumber":341,"author":{"gitId":"-"},"content":" }"},{"lineNumber":342,"author":{"gitId":"-"},"content":""},{"lineNumber":343,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":344,"author":{"gitId":"-"},"content":" public String toString() {"},{"lineNumber":345,"author":{"gitId":"-"},"content":" return \"Question [id\u003d\" + id + \", questionNumber\u003d\" + questionNumber + \", description\u003d\" + description"},{"lineNumber":346,"author":{"gitId":"-"},"content":" + \", giverType\u003d\" + giverType + \", recipientType\u003d\" + recipientType"},{"lineNumber":347,"author":{"gitId":"-"},"content":" + \", numOfEntitiesToGiveFeedbackTo\u003d\" + numOfEntitiesToGiveFeedbackTo + \", showResponsesTo\u003d\""},{"lineNumber":348,"author":{"gitId":"-"},"content":" + showResponsesTo + \", showGiverNameTo\u003d\" + showGiverNameTo + \", showRecipientNameTo\u003d\""},{"lineNumber":349,"author":{"gitId":"-"},"content":" + showRecipientNameTo + \", isClosingEmailEnabled\u003d\" + \", createdAt\u003d\" + getCreatedAt() + \", updatedAt\u003d\""},{"lineNumber":350,"author":{"gitId":"-"},"content":" + updatedAt + \"]\";"},{"lineNumber":351,"author":{"gitId":"-"},"content":" }"},{"lineNumber":352,"author":{"gitId":"-"},"content":""},{"lineNumber":353,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":354,"author":{"gitId":"-"},"content":" public int compareTo(FeedbackQuestion o) {"},{"lineNumber":355,"author":{"gitId":"-"},"content":" if (o \u003d\u003d null) {"},{"lineNumber":356,"author":{"gitId":"-"},"content":" return 1;"},{"lineNumber":357,"author":{"gitId":"-"},"content":" }"},{"lineNumber":358,"author":{"gitId":"-"},"content":""},{"lineNumber":359,"author":{"gitId":"-"},"content":" if (!this.questionNumber.equals(o.questionNumber)) {"},{"lineNumber":360,"author":{"gitId":"-"},"content":" return Integer.compare(this.questionNumber, o.questionNumber);"},{"lineNumber":361,"author":{"gitId":"-"},"content":" }"},{"lineNumber":362,"author":{"gitId":"-"},"content":" // Although question numbers ought to be unique in a feedback session,"},{"lineNumber":363,"author":{"gitId":"-"},"content":" // eventual consistency can result in duplicate questions numbers."},{"lineNumber":364,"author":{"gitId":"-"},"content":" // Therefore, to ensure that the question order is always consistent to the user,"},{"lineNumber":365,"author":{"gitId":"-"},"content":" // compare feedbackQuestionId, which is guaranteed to be unique,"},{"lineNumber":366,"author":{"gitId":"-"},"content":" // when the questionNumbers are the same."},{"lineNumber":367,"author":{"gitId":"-"},"content":" return this.id.compareTo(o.id);"},{"lineNumber":368,"author":{"gitId":"-"},"content":" }"},{"lineNumber":369,"author":{"gitId":"-"},"content":""},{"lineNumber":370,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":371,"author":{"gitId":"-"},"content":" public int hashCode() {"},{"lineNumber":372,"author":{"gitId":"-"},"content":" // FeedbackQuestion ID uniquely identifies a FeedbackQuestion."},{"lineNumber":373,"author":{"gitId":"-"},"content":" return this.getId().hashCode();"},{"lineNumber":374,"author":{"gitId":"-"},"content":" }"},{"lineNumber":375,"author":{"gitId":"-"},"content":""},{"lineNumber":376,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":377,"author":{"gitId":"-"},"content":" public boolean equals(Object other) {"},{"lineNumber":378,"author":{"gitId":"-"},"content":" if (other \u003d\u003d null) {"},{"lineNumber":379,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":380,"author":{"gitId":"-"},"content":" } else if (this \u003d\u003d other) {"},{"lineNumber":381,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":382,"author":{"gitId":"-"},"content":" } else if (this.getClass() \u003d\u003d other.getClass()) {"},{"lineNumber":383,"author":{"gitId":"-"},"content":" FeedbackQuestion otherQuestion \u003d (FeedbackQuestion) other;"},{"lineNumber":384,"author":{"gitId":"-"},"content":" return Objects.equals(this.getId(), otherQuestion.getId());"},{"lineNumber":385,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":386,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":387,"author":{"gitId":"-"},"content":" }"},{"lineNumber":388,"author":{"gitId":"-"},"content":" }"},{"lineNumber":389,"author":{"gitId":"-"},"content":""},{"lineNumber":390,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":391,"author":{"gitId":"-"},"content":" * Returns true if the response is visible to the given participant type."},{"lineNumber":392,"author":{"gitId":"-"},"content":" */"},{"lineNumber":393,"author":{"gitId":"-"},"content":" public boolean isResponseVisibleTo(FeedbackParticipantType userType) {"},{"lineNumber":394,"author":{"gitId":"-"},"content":" return showResponsesTo.contains(userType);"},{"lineNumber":395,"author":{"gitId":"-"},"content":" }"},{"lineNumber":396,"author":{"gitId":"-"},"content":"}"},{"lineNumber":397,"author":{"gitId":"-"},"content":""}],"authorContributionMap":{"xenosf":8,"-":389}},{"path":"src/main/java/teammates/storage/sqlentity/FeedbackResponse.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlentity;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Objects;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.persistence.CascadeType;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import jakarta.persistence.Column;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import jakarta.persistence.Entity;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.persistence.Id;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import jakarta.persistence.Inheritance;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import jakarta.persistence.InheritanceType;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import jakarta.persistence.JoinColumn;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import jakarta.persistence.ManyToOne;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import jakarta.persistence.OneToMany;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import jakarta.persistence.Table;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"import org.hibernate.annotations.UpdateTimestamp;"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackResponseDetails;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackConstantSumResponse;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackContributionResponse;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackMcqResponse;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackMsqResponse;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackNumericalScaleResponse;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackRankOptionsResponse;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackRankRecipientsResponse;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackRubricResponse;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackTextResponse;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":34,"author":{"gitId":"-"},"content":" * Represents a Feedback Response."},{"lineNumber":35,"author":{"gitId":"-"},"content":" */"},{"lineNumber":36,"author":{"gitId":"-"},"content":"@Entity"},{"lineNumber":37,"author":{"gitId":"-"},"content":"@Table(name \u003d \"FeedbackResponses\")"},{"lineNumber":38,"author":{"gitId":"-"},"content":"@Inheritance(strategy \u003d InheritanceType.SINGLE_TABLE)"},{"lineNumber":39,"author":{"gitId":"-"},"content":"public abstract class FeedbackResponse extends BaseEntity {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" @Id"},{"lineNumber":41,"author":{"gitId":"-"},"content":" private UUID id;"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" @ManyToOne"},{"lineNumber":44,"author":{"gitId":"-"},"content":" @JoinColumn(name \u003d \"questionId\")"},{"lineNumber":45,"author":{"gitId":"-"},"content":" private FeedbackQuestion feedbackQuestion;"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" @OneToMany(mappedBy \u003d \"feedbackResponse\", cascade \u003d CascadeType.REMOVE)"},{"lineNumber":48,"author":{"gitId":"-"},"content":" private List\u003cFeedbackResponseComment\u003e feedbackResponseComments \u003d new ArrayList\u003c\u003e();"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":51,"author":{"gitId":"-"},"content":" private String giver;"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" @ManyToOne"},{"lineNumber":54,"author":{"gitId":"-"},"content":" @JoinColumn(name \u003d \"giverSectionId\")"},{"lineNumber":55,"author":{"gitId":"-"},"content":" private Section giverSection;"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":58,"author":{"gitId":"-"},"content":" private String recipient;"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" @ManyToOne"},{"lineNumber":61,"author":{"gitId":"-"},"content":" @JoinColumn(name \u003d \"recipientSectionId\")"},{"lineNumber":62,"author":{"gitId":"-"},"content":" private Section recipientSection;"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" @UpdateTimestamp"},{"lineNumber":65,"author":{"gitId":"-"},"content":" private Instant updatedAt;"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" protected FeedbackResponse() {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" // required by Hibernate"},{"lineNumber":69,"author":{"gitId":"-"},"content":" }"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" public FeedbackResponse("},{"lineNumber":72,"author":{"gitId":"-"},"content":" FeedbackQuestion feedbackQuestion, String giver,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" Section giverSection, String recipient, Section recipientSection"},{"lineNumber":74,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" this.setId(UUID.randomUUID());"},{"lineNumber":76,"author":{"gitId":"-"},"content":" this.setFeedbackQuestion(feedbackQuestion);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" this.setGiver(giver);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" this.setGiverSection(giverSection);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" this.setRecipient(recipient);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" this.setRecipientSection(recipientSection);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":84,"author":{"gitId":"-"},"content":" * Creates a feedback response according to its {@code FeedbackQuestionType}."},{"lineNumber":85,"author":{"gitId":"-"},"content":" */"},{"lineNumber":86,"author":{"gitId":"-"},"content":" public static FeedbackResponse makeResponse("},{"lineNumber":87,"author":{"gitId":"-"},"content":" FeedbackQuestion feedbackQuestion, String giver,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" Section giverSection, String receiver, Section receiverSection,"},{"lineNumber":89,"author":{"gitId":"-"},"content":" FeedbackResponseDetails responseDetails"},{"lineNumber":90,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" FeedbackResponse feedbackResponse \u003d null;"},{"lineNumber":92,"author":{"gitId":"-"},"content":" switch (responseDetails.getQuestionType()) {"},{"lineNumber":93,"author":{"gitId":"-"},"content":" case TEXT:"},{"lineNumber":94,"author":{"gitId":"-"},"content":" feedbackResponse \u003d new FeedbackTextResponse("},{"lineNumber":95,"author":{"gitId":"-"},"content":" feedbackQuestion, giver, giverSection, receiver, receiverSection, responseDetails"},{"lineNumber":96,"author":{"gitId":"-"},"content":" );"},{"lineNumber":97,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":98,"author":{"gitId":"-"},"content":" case MCQ:"},{"lineNumber":99,"author":{"gitId":"-"},"content":" feedbackResponse \u003d new FeedbackMcqResponse("},{"lineNumber":100,"author":{"gitId":"-"},"content":" feedbackQuestion, giver, giverSection, receiver, receiverSection, responseDetails"},{"lineNumber":101,"author":{"gitId":"-"},"content":" );"},{"lineNumber":102,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":103,"author":{"gitId":"-"},"content":" case MSQ:"},{"lineNumber":104,"author":{"gitId":"-"},"content":" feedbackResponse \u003d new FeedbackMsqResponse("},{"lineNumber":105,"author":{"gitId":"-"},"content":" feedbackQuestion, giver, giverSection, receiver, receiverSection, responseDetails"},{"lineNumber":106,"author":{"gitId":"-"},"content":" );"},{"lineNumber":107,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":108,"author":{"gitId":"-"},"content":" case NUMSCALE:"},{"lineNumber":109,"author":{"gitId":"-"},"content":" feedbackResponse \u003d new FeedbackNumericalScaleResponse("},{"lineNumber":110,"author":{"gitId":"-"},"content":" feedbackQuestion, giver, giverSection, receiver, receiverSection, responseDetails"},{"lineNumber":111,"author":{"gitId":"-"},"content":" );"},{"lineNumber":112,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":113,"author":{"gitId":"-"},"content":" case CONSTSUM:"},{"lineNumber":114,"author":{"gitId":"-"},"content":" case CONSTSUM_OPTIONS:"},{"lineNumber":115,"author":{"gitId":"-"},"content":" case CONSTSUM_RECIPIENTS:"},{"lineNumber":116,"author":{"gitId":"-"},"content":" feedbackResponse \u003d new FeedbackConstantSumResponse("},{"lineNumber":117,"author":{"gitId":"-"},"content":" feedbackQuestion, giver, giverSection, receiver, receiverSection, responseDetails"},{"lineNumber":118,"author":{"gitId":"-"},"content":" );"},{"lineNumber":119,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":120,"author":{"gitId":"-"},"content":" case CONTRIB:"},{"lineNumber":121,"author":{"gitId":"-"},"content":" feedbackResponse \u003d new FeedbackContributionResponse("},{"lineNumber":122,"author":{"gitId":"-"},"content":" feedbackQuestion, giver, giverSection, receiver, receiverSection, responseDetails"},{"lineNumber":123,"author":{"gitId":"-"},"content":" );"},{"lineNumber":124,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":125,"author":{"gitId":"-"},"content":" case RUBRIC:"},{"lineNumber":126,"author":{"gitId":"-"},"content":" feedbackResponse \u003d new FeedbackRubricResponse("},{"lineNumber":127,"author":{"gitId":"-"},"content":" feedbackQuestion, giver, giverSection, receiver, receiverSection, responseDetails"},{"lineNumber":128,"author":{"gitId":"-"},"content":" );"},{"lineNumber":129,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":130,"author":{"gitId":"-"},"content":" case RANK_OPTIONS:"},{"lineNumber":131,"author":{"gitId":"-"},"content":" feedbackResponse \u003d new FeedbackRankOptionsResponse("},{"lineNumber":132,"author":{"gitId":"-"},"content":" feedbackQuestion, giver, giverSection, receiver, receiverSection, responseDetails"},{"lineNumber":133,"author":{"gitId":"-"},"content":" );"},{"lineNumber":134,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":135,"author":{"gitId":"-"},"content":" case RANK_RECIPIENTS:"},{"lineNumber":136,"author":{"gitId":"-"},"content":" feedbackResponse \u003d new FeedbackRankRecipientsResponse("},{"lineNumber":137,"author":{"gitId":"-"},"content":" feedbackQuestion, giver, giverSection, receiver, receiverSection, responseDetails"},{"lineNumber":138,"author":{"gitId":"-"},"content":" );"},{"lineNumber":139,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":" return feedbackResponse;"},{"lineNumber":142,"author":{"gitId":"-"},"content":" }"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":145,"author":{"gitId":"-"},"content":" * Update a feedback response according to its {@code FeedbackQuestionType}."},{"lineNumber":146,"author":{"gitId":"-"},"content":" */"},{"lineNumber":147,"author":{"gitId":"-"},"content":" public static FeedbackResponse updateResponse("},{"lineNumber":148,"author":{"gitId":"-"},"content":" FeedbackResponse originalFeedbackResponse,"},{"lineNumber":149,"author":{"gitId":"-"},"content":" FeedbackQuestion feedbackQuestion, String giver,"},{"lineNumber":150,"author":{"gitId":"-"},"content":" Section giverSection, String receiver, Section receiverSection,"},{"lineNumber":151,"author":{"gitId":"-"},"content":" FeedbackResponseDetails responseDetails"},{"lineNumber":152,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" FeedbackResponse updatedFeedbackResponse \u003d makeResponse("},{"lineNumber":154,"author":{"gitId":"-"},"content":" feedbackQuestion,"},{"lineNumber":155,"author":{"gitId":"-"},"content":" giver,"},{"lineNumber":156,"author":{"gitId":"-"},"content":" giverSection,"},{"lineNumber":157,"author":{"gitId":"-"},"content":" receiver,"},{"lineNumber":158,"author":{"gitId":"-"},"content":" receiverSection,"},{"lineNumber":159,"author":{"gitId":"-"},"content":" responseDetails"},{"lineNumber":160,"author":{"gitId":"-"},"content":" );"},{"lineNumber":161,"author":{"gitId":"-"},"content":" updatedFeedbackResponse.setCreatedAt(originalFeedbackResponse.getCreatedAt());"},{"lineNumber":162,"author":{"gitId":"-"},"content":" updatedFeedbackResponse.setId(originalFeedbackResponse.getId());"},{"lineNumber":163,"author":{"gitId":"-"},"content":" return updatedFeedbackResponse;"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":167,"author":{"gitId":"-"},"content":" * Gets a copy of the question details of the feedback question."},{"lineNumber":168,"author":{"gitId":"-"},"content":" */"},{"lineNumber":169,"author":{"gitId":"-"},"content":" public abstract FeedbackResponseDetails getFeedbackResponseDetailsCopy();"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" public UUID getId() {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" return id;"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" public void setId(UUID id) {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" this.id \u003d id;"},{"lineNumber":177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" public FeedbackQuestion getFeedbackQuestion() {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" return feedbackQuestion;"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" public void setFeedbackQuestion(FeedbackQuestion feedbackQuestion) {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" this.feedbackQuestion \u003d feedbackQuestion;"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseComments() {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" return feedbackResponseComments;"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" public void setFeedbackResponseComments(List\u003cFeedbackResponseComment\u003e feedbackResponseComments) {"},{"lineNumber":192,"author":{"gitId":"-"},"content":" this.feedbackResponseComments \u003d feedbackResponseComments;"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"-"},"content":" public String getGiver() {"},{"lineNumber":196,"author":{"gitId":"-"},"content":" return giver;"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" public void setGiver(String giver) {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" this.giver \u003d giver;"},{"lineNumber":201,"author":{"gitId":"-"},"content":" }"},{"lineNumber":202,"author":{"gitId":"-"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":" public Section getGiverSection() {"},{"lineNumber":204,"author":{"gitId":"-"},"content":" return giverSection;"},{"lineNumber":205,"author":{"gitId":"-"},"content":" }"},{"lineNumber":206,"author":{"gitId":"-"},"content":""},{"lineNumber":207,"author":{"gitId":"xenosf"},"content":" public String getGiverSectionName() {"},{"lineNumber":208,"author":{"gitId":"xenosf"},"content":" return giverSection.getName();"},{"lineNumber":209,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":210,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":211,"author":{"gitId":"-"},"content":" public void setGiverSection(Section giverSection) {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" this.giverSection \u003d giverSection;"},{"lineNumber":213,"author":{"gitId":"-"},"content":" }"},{"lineNumber":214,"author":{"gitId":"-"},"content":""},{"lineNumber":215,"author":{"gitId":"-"},"content":" public String getRecipient() {"},{"lineNumber":216,"author":{"gitId":"-"},"content":" return recipient;"},{"lineNumber":217,"author":{"gitId":"-"},"content":" }"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":" public void setRecipient(String recipient) {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" this.recipient \u003d recipient;"},{"lineNumber":221,"author":{"gitId":"-"},"content":" }"},{"lineNumber":222,"author":{"gitId":"-"},"content":""},{"lineNumber":223,"author":{"gitId":"-"},"content":" public Section getRecipientSection() {"},{"lineNumber":224,"author":{"gitId":"-"},"content":" return recipientSection;"},{"lineNumber":225,"author":{"gitId":"-"},"content":" }"},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"xenosf"},"content":" public String getRecipientSectionName() {"},{"lineNumber":228,"author":{"gitId":"xenosf"},"content":" return recipientSection.getName();"},{"lineNumber":229,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":230,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":231,"author":{"gitId":"-"},"content":" public void setRecipientSection(Section recipientSection) {"},{"lineNumber":232,"author":{"gitId":"-"},"content":" this.recipientSection \u003d recipientSection;"},{"lineNumber":233,"author":{"gitId":"-"},"content":" }"},{"lineNumber":234,"author":{"gitId":"-"},"content":""},{"lineNumber":235,"author":{"gitId":"-"},"content":" public Instant getUpdatedAt() {"},{"lineNumber":236,"author":{"gitId":"-"},"content":" return updatedAt;"},{"lineNumber":237,"author":{"gitId":"-"},"content":" }"},{"lineNumber":238,"author":{"gitId":"-"},"content":""},{"lineNumber":239,"author":{"gitId":"-"},"content":" public void setUpdatedAt(Instant updatedAt) {"},{"lineNumber":240,"author":{"gitId":"-"},"content":" this.updatedAt \u003d updatedAt;"},{"lineNumber":241,"author":{"gitId":"-"},"content":" }"},{"lineNumber":242,"author":{"gitId":"-"},"content":""},{"lineNumber":243,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":244,"author":{"gitId":"-"},"content":" public List\u003cString\u003e getInvalidityInfo() {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" return new ArrayList\u003c\u003e();"},{"lineNumber":246,"author":{"gitId":"-"},"content":" }"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":249,"author":{"gitId":"-"},"content":" public String toString() {"},{"lineNumber":250,"author":{"gitId":"-"},"content":" return \"FeedbackResponse [id\u003d\" + id + \", giver\u003d\" + giver + \", recipient\u003d\" + recipient"},{"lineNumber":251,"author":{"gitId":"-"},"content":" + \", createdAt\u003d\" + getCreatedAt() + \", updatedAt\u003d\" + updatedAt + \"]\";"},{"lineNumber":252,"author":{"gitId":"-"},"content":" }"},{"lineNumber":253,"author":{"gitId":"-"},"content":""},{"lineNumber":254,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":255,"author":{"gitId":"-"},"content":" public int hashCode() {"},{"lineNumber":256,"author":{"gitId":"-"},"content":" return this.getId().hashCode();"},{"lineNumber":257,"author":{"gitId":"-"},"content":" }"},{"lineNumber":258,"author":{"gitId":"-"},"content":""},{"lineNumber":259,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":260,"author":{"gitId":"-"},"content":" public boolean equals(Object other) {"},{"lineNumber":261,"author":{"gitId":"-"},"content":" if (other \u003d\u003d null) {"},{"lineNumber":262,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":263,"author":{"gitId":"-"},"content":" } else if (this \u003d\u003d other) {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":265,"author":{"gitId":"-"},"content":" } else if (this.getClass() \u003d\u003d other.getClass()) {"},{"lineNumber":266,"author":{"gitId":"-"},"content":" FeedbackResponse otherResponse \u003d (FeedbackResponse) other;"},{"lineNumber":267,"author":{"gitId":"-"},"content":" return Objects.equals(this.getId(), otherResponse.getId());"},{"lineNumber":268,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":" }"},{"lineNumber":272,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":8,"-":264}},{"path":"src/main/java/teammates/storage/sqlentity/FeedbackResponseComment.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlentity;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Objects;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import jakarta.persistence.Column;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.persistence.Convert;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import jakarta.persistence.Entity;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import jakarta.persistence.GeneratedValue;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.persistence.Id;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import jakarta.persistence.JoinColumn;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import jakarta.persistence.ManyToOne;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import jakarta.persistence.Table;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"import org.hibernate.annotations.OnDelete;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import org.hibernate.annotations.OnDeleteAction;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import org.hibernate.annotations.UpdateTimestamp;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"-"},"content":" * Represents a feedback response comment."},{"lineNumber":27,"author":{"gitId":"-"},"content":" */"},{"lineNumber":28,"author":{"gitId":"-"},"content":"@Entity"},{"lineNumber":29,"author":{"gitId":"-"},"content":"@Table(name \u003d \"FeedbackResponseComments\")"},{"lineNumber":30,"author":{"gitId":"-"},"content":"public class FeedbackResponseComment extends BaseEntity {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" @Id"},{"lineNumber":32,"author":{"gitId":"-"},"content":" @GeneratedValue"},{"lineNumber":33,"author":{"gitId":"-"},"content":" private Long id;"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" @ManyToOne"},{"lineNumber":36,"author":{"gitId":"-"},"content":" @OnDelete(action \u003d OnDeleteAction.CASCADE)"},{"lineNumber":37,"author":{"gitId":"-"},"content":" @JoinColumn(name \u003d \"responseId\")"},{"lineNumber":38,"author":{"gitId":"-"},"content":" private FeedbackResponse feedbackResponse;"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":41,"author":{"gitId":"-"},"content":" private String giver;"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":44,"author":{"gitId":"-"},"content":" @Convert(converter \u003d FeedbackParticipantTypeConverter.class)"},{"lineNumber":45,"author":{"gitId":"-"},"content":" private FeedbackParticipantType giverType;"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" @ManyToOne"},{"lineNumber":48,"author":{"gitId":"-"},"content":" @JoinColumn(name \u003d \"giverSectionId\")"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private Section giverSection;"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" @ManyToOne"},{"lineNumber":52,"author":{"gitId":"-"},"content":" @JoinColumn(name \u003d \"recipientSectionId\")"},{"lineNumber":53,"author":{"gitId":"-"},"content":" private Section recipientSection;"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":56,"author":{"gitId":"-"},"content":" private String commentText;"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":59,"author":{"gitId":"-"},"content":" private boolean isVisibilityFollowingFeedbackQuestion;"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":62,"author":{"gitId":"-"},"content":" private boolean isCommentFromFeedbackParticipant;"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":65,"author":{"gitId":"-"},"content":" @Convert(converter \u003d FeedbackParticipantTypeListConverter.class)"},{"lineNumber":66,"author":{"gitId":"-"},"content":" private List\u003cFeedbackParticipantType\u003e showCommentTo;"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":69,"author":{"gitId":"-"},"content":" @Convert(converter \u003d FeedbackParticipantTypeListConverter.class)"},{"lineNumber":70,"author":{"gitId":"-"},"content":" private List\u003cFeedbackParticipantType\u003e showGiverNameTo;"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" @UpdateTimestamp"},{"lineNumber":73,"author":{"gitId":"-"},"content":" private Instant updatedAt;"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":76,"author":{"gitId":"-"},"content":" private String lastEditorEmail;"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" protected FeedbackResponseComment() {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" // required by Hibernate"},{"lineNumber":80,"author":{"gitId":"-"},"content":" }"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" public FeedbackResponseComment("},{"lineNumber":83,"author":{"gitId":"-"},"content":" FeedbackResponse feedbackResponse, String giver, FeedbackParticipantType giverType,"},{"lineNumber":84,"author":{"gitId":"-"},"content":" Section giverSection, Section recipientSection, String commentText,"},{"lineNumber":85,"author":{"gitId":"-"},"content":" boolean isVisibilityFollowingFeedbackQuestion, boolean isCommentFromFeedbackParticipant,"},{"lineNumber":86,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showCommentTo, List\u003cFeedbackParticipantType\u003e showGiverNameTo,"},{"lineNumber":87,"author":{"gitId":"-"},"content":" String lastEditorEmail"},{"lineNumber":88,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":89,"author":{"gitId":"-"},"content":" this.setFeedbackResponse(feedbackResponse);"},{"lineNumber":90,"author":{"gitId":"-"},"content":" this.setGiver(giver);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" this.setGiverType(giverType);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" this.setGiverSection(giverSection);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" this.setRecipientSection(recipientSection);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" this.setCommentText(commentText);"},{"lineNumber":95,"author":{"gitId":"-"},"content":" this.setIsVisibilityFollowingFeedbackQuestion(isVisibilityFollowingFeedbackQuestion);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" this.setIsCommentFromFeedbackParticipant(isCommentFromFeedbackParticipant);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" this.setShowCommentTo(showCommentTo);"},{"lineNumber":98,"author":{"gitId":"-"},"content":" this.setShowGiverNameTo(showGiverNameTo);"},{"lineNumber":99,"author":{"gitId":"-"},"content":" this.setLastEditorEmail(lastEditorEmail);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" public Long getId() {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" return id;"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" public void setId(Long id) {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" this.id \u003d id;"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" public FeedbackResponse getFeedbackResponse() {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" return feedbackResponse;"},{"lineNumber":112,"author":{"gitId":"-"},"content":" }"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" public void setFeedbackResponse(FeedbackResponse feedbackResponse) {"},{"lineNumber":115,"author":{"gitId":"-"},"content":" this.feedbackResponse \u003d feedbackResponse;"},{"lineNumber":116,"author":{"gitId":"-"},"content":" }"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" public String getGiver() {"},{"lineNumber":119,"author":{"gitId":"-"},"content":" return giver;"},{"lineNumber":120,"author":{"gitId":"-"},"content":" }"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" public void setGiver(String giver) {"},{"lineNumber":123,"author":{"gitId":"-"},"content":" this.giver \u003d giver;"},{"lineNumber":124,"author":{"gitId":"-"},"content":" }"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" public FeedbackParticipantType getGiverType() {"},{"lineNumber":127,"author":{"gitId":"-"},"content":" return giverType;"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" public void setGiverType(FeedbackParticipantType giverType) {"},{"lineNumber":131,"author":{"gitId":"-"},"content":" this.giverType \u003d giverType;"},{"lineNumber":132,"author":{"gitId":"-"},"content":" }"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" public Section getGiverSection() {"},{"lineNumber":135,"author":{"gitId":"-"},"content":" return giverSection;"},{"lineNumber":136,"author":{"gitId":"-"},"content":" }"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" public void setGiverSection(Section giverSection) {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" this.giverSection \u003d giverSection;"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" public Section getRecipientSection() {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" return recipientSection;"},{"lineNumber":144,"author":{"gitId":"-"},"content":" }"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" public void setRecipientSection(Section recipientSection) {"},{"lineNumber":147,"author":{"gitId":"-"},"content":" this.recipientSection \u003d recipientSection;"},{"lineNumber":148,"author":{"gitId":"-"},"content":" }"},{"lineNumber":149,"author":{"gitId":"-"},"content":""},{"lineNumber":150,"author":{"gitId":"-"},"content":" public String getCommentText() {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" return commentText;"},{"lineNumber":152,"author":{"gitId":"-"},"content":" }"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"-"},"content":" public void setCommentText(String commentText) {"},{"lineNumber":155,"author":{"gitId":"-"},"content":" this.commentText \u003d commentText;"},{"lineNumber":156,"author":{"gitId":"-"},"content":" }"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"-"},"content":" public boolean getIsVisibilityFollowingFeedbackQuestion() {"},{"lineNumber":159,"author":{"gitId":"-"},"content":" return this.isVisibilityFollowingFeedbackQuestion;"},{"lineNumber":160,"author":{"gitId":"-"},"content":" }"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"-"},"content":" public void setIsVisibilityFollowingFeedbackQuestion(boolean isVisibilityFollowingFeedbackQuestion) {"},{"lineNumber":163,"author":{"gitId":"-"},"content":" this.isVisibilityFollowingFeedbackQuestion \u003d isVisibilityFollowingFeedbackQuestion;"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" public boolean getIsCommentFromFeedbackParticipant() {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" return this.isCommentFromFeedbackParticipant;"},{"lineNumber":168,"author":{"gitId":"-"},"content":" }"},{"lineNumber":169,"author":{"gitId":"-"},"content":""},{"lineNumber":170,"author":{"gitId":"-"},"content":" public void setIsCommentFromFeedbackParticipant(boolean isCommentFromFeedbackParticipant) {"},{"lineNumber":171,"author":{"gitId":"-"},"content":" this.isCommentFromFeedbackParticipant \u003d isCommentFromFeedbackParticipant;"},{"lineNumber":172,"author":{"gitId":"-"},"content":" }"},{"lineNumber":173,"author":{"gitId":"-"},"content":""},{"lineNumber":174,"author":{"gitId":"-"},"content":" public List\u003cFeedbackParticipantType\u003e getShowCommentTo() {"},{"lineNumber":175,"author":{"gitId":"-"},"content":" return showCommentTo;"},{"lineNumber":176,"author":{"gitId":"-"},"content":" }"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" public void setShowCommentTo(List\u003cFeedbackParticipantType\u003e showCommentTo) {"},{"lineNumber":179,"author":{"gitId":"-"},"content":" this.showCommentTo \u003d showCommentTo;"},{"lineNumber":180,"author":{"gitId":"-"},"content":" }"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" public List\u003cFeedbackParticipantType\u003e getShowGiverNameTo() {"},{"lineNumber":183,"author":{"gitId":"-"},"content":" return showGiverNameTo;"},{"lineNumber":184,"author":{"gitId":"-"},"content":" }"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" public void setShowGiverNameTo(List\u003cFeedbackParticipantType\u003e showGiverNameTo) {"},{"lineNumber":187,"author":{"gitId":"-"},"content":" this.showGiverNameTo \u003d showGiverNameTo;"},{"lineNumber":188,"author":{"gitId":"-"},"content":" }"},{"lineNumber":189,"author":{"gitId":"-"},"content":""},{"lineNumber":190,"author":{"gitId":"-"},"content":" public Instant getUpdatedAt() {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" return updatedAt;"},{"lineNumber":192,"author":{"gitId":"-"},"content":" }"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"-"},"content":" public void setUpdatedAt(Instant updatedAt) {"},{"lineNumber":195,"author":{"gitId":"-"},"content":" this.updatedAt \u003d updatedAt;"},{"lineNumber":196,"author":{"gitId":"-"},"content":" }"},{"lineNumber":197,"author":{"gitId":"-"},"content":""},{"lineNumber":198,"author":{"gitId":"-"},"content":" public String getLastEditorEmail() {"},{"lineNumber":199,"author":{"gitId":"-"},"content":" return lastEditorEmail;"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }"},{"lineNumber":201,"author":{"gitId":"-"},"content":""},{"lineNumber":202,"author":{"gitId":"-"},"content":" public void setLastEditorEmail(String lastEditorEmail) {"},{"lineNumber":203,"author":{"gitId":"-"},"content":" this.lastEditorEmail \u003d lastEditorEmail;"},{"lineNumber":204,"author":{"gitId":"-"},"content":" }"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":207,"author":{"gitId":"-"},"content":" * Formats the entity before persisting in database."},{"lineNumber":208,"author":{"gitId":"-"},"content":" * TODO: Override when BaseEntity adds abstract sanitizeForSaving"},{"lineNumber":209,"author":{"gitId":"-"},"content":" */"},{"lineNumber":210,"author":{"gitId":"-"},"content":" public void sanitizeForSaving() {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" this.commentText \u003d SanitizationHelper.sanitizeForRichText(this.commentText);"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" * Returns true if the response comment is visible to the given participant type."},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":217,"author":{"gitId":"xenosf"},"content":" public boolean checkIsVisibleTo(FeedbackParticipantType viewerType) {"},{"lineNumber":218,"author":{"gitId":"xenosf"},"content":" return showCommentTo.contains(viewerType);"},{"lineNumber":219,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":220,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":221,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":222,"author":{"gitId":"-"},"content":" public List\u003cString\u003e getInvalidityInfo() {"},{"lineNumber":223,"author":{"gitId":"-"},"content":" List\u003cString\u003e errors \u003d new ArrayList\u003c\u003e();"},{"lineNumber":224,"author":{"gitId":"-"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForCommentGiverType(giverType), errors);"},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForVisibilityOfFeedbackParticipantComments("},{"lineNumber":228,"author":{"gitId":"-"},"content":" isCommentFromFeedbackParticipant, isVisibilityFollowingFeedbackQuestion), errors);"},{"lineNumber":229,"author":{"gitId":"-"},"content":""},{"lineNumber":230,"author":{"gitId":"-"},"content":" return errors;"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":234,"author":{"gitId":"-"},"content":" public String toString() {"},{"lineNumber":235,"author":{"gitId":"-"},"content":" return \"FeedbackResponse [id\u003d\" + id + \", giver\u003d\" + giver + \", commentText\u003d\" + commentText"},{"lineNumber":236,"author":{"gitId":"-"},"content":" + \", isVisibilityFollowingFeedbackQuestion\u003d\" + isVisibilityFollowingFeedbackQuestion"},{"lineNumber":237,"author":{"gitId":"-"},"content":" + \", isCommentFromFeedbackParticipant\u003d\" + isCommentFromFeedbackParticipant"},{"lineNumber":238,"author":{"gitId":"-"},"content":" + \", lastEditorEmail\u003d\" + lastEditorEmail + \", createdAt\u003d\" + getCreatedAt()"},{"lineNumber":239,"author":{"gitId":"-"},"content":" + \", updatedAt\u003d\" + updatedAt + \"]\";"},{"lineNumber":240,"author":{"gitId":"-"},"content":" }"},{"lineNumber":241,"author":{"gitId":"-"},"content":""},{"lineNumber":242,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":243,"author":{"gitId":"-"},"content":" public int hashCode() {"},{"lineNumber":244,"author":{"gitId":"-"},"content":" return this.getId().hashCode();"},{"lineNumber":245,"author":{"gitId":"-"},"content":" }"},{"lineNumber":246,"author":{"gitId":"-"},"content":""},{"lineNumber":247,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":248,"author":{"gitId":"-"},"content":" public boolean equals(Object other) {"},{"lineNumber":249,"author":{"gitId":"-"},"content":" if (other \u003d\u003d null) {"},{"lineNumber":250,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":251,"author":{"gitId":"-"},"content":" } else if (this \u003d\u003d other) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":253,"author":{"gitId":"-"},"content":" } else if (this.getClass() \u003d\u003d other.getClass()) {"},{"lineNumber":254,"author":{"gitId":"-"},"content":" FeedbackResponseComment otherResponse \u003d (FeedbackResponseComment) other;"},{"lineNumber":255,"author":{"gitId":"-"},"content":" return Objects.equals(this.getId(), otherResponse.getId());"},{"lineNumber":256,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":257,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":258,"author":{"gitId":"-"},"content":" }"},{"lineNumber":259,"author":{"gitId":"-"},"content":" }"},{"lineNumber":260,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":7,"-":253}},{"path":"src/main/java/teammates/storage/sqlentity/FeedbackSessionLog.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.storage.sqlentity;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import java.util.Objects;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.Column;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.Entity;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.EnumType;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.Enumerated;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.Id;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.JoinColumn;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.ManyToOne;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.Table;"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"import org.hibernate.annotations.NotFound;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import org.hibernate.annotations.NotFoundAction;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import org.hibernate.annotations.OnDelete;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import org.hibernate.annotations.OnDeleteAction;"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" * Represents a feedback session log."},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":"@Entity"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":"@Table(name \u003d \"FeedbackSessionLogs\")"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":"public class FeedbackSessionLog extends BaseEntity {"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" @Id"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" private UUID id;"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" @ManyToOne"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" @JoinColumn(name \u003d \"studentId\")"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" @NotFound(action \u003d NotFoundAction.IGNORE)"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" @OnDelete(action \u003d OnDeleteAction.CASCADE)"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" private Student student;"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" @ManyToOne"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" @JoinColumn(name \u003d \"sessionId\")"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" @NotFound(action \u003d NotFoundAction.IGNORE)"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" @OnDelete(action \u003d OnDeleteAction.CASCADE)"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" private FeedbackSession feedbackSession;"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" @Column(nullable \u003d false)"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" @Enumerated(EnumType.STRING)"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" private FeedbackSessionLogType feedbackSessionLogType;"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" @Column(nullable \u003d false)"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" private Instant timestamp;"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" protected FeedbackSessionLog() {"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" // required by Hibernate"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" public FeedbackSessionLog(Student student, FeedbackSession feedbackSession,"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType feedbackSessionLogType, Instant timestamp) {"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" this.setId(UUID.randomUUID());"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" this.student \u003d student;"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" this.feedbackSession \u003d feedbackSession;"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionLogType \u003d feedbackSessionLogType;"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" this.timestamp \u003d timestamp;"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" public UUID getId() {"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" return id;"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" public void setId(UUID id) {"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" this.id \u003d id;"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" public Student getStudent() {"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" return student;"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" public void setStudent(Student student) {"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" this.student \u003d student;"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" public FeedbackSession getFeedbackSession() {"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" return feedbackSession;"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":" public void setFeedbackSession(FeedbackSession feedbackSession) {"},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" this.feedbackSession \u003d feedbackSession;"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" public FeedbackSessionLogType getFeedbackSessionLogType() {"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":" return feedbackSessionLogType;"},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" public void setFeedbackSessionLogType(FeedbackSessionLogType feedbackSessionLogType) {"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionLogType \u003d feedbackSessionLogType;"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" public Instant getTimestamp() {"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" return timestamp;"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" public void setTimestamp(Instant timestamp) {"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":" this.timestamp \u003d timestamp;"},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":" public String toString() {"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" return \"FeedbackSessionLog [id\u003d\" + id + \", student\u003d\" + student + \", feedbackSession\u003d\" + feedbackSession"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":" + \", feedbackSessionLogType\u003d\" + feedbackSessionLogType.getLabel() + \", timestamp\u003d\" + timestamp + \"]\";"},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" public int hashCode() {"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":" return this.getId().hashCode();"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" public boolean equals(Object other) {"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" if (other \u003d\u003d null) {"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" return false;"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" } else if (this \u003d\u003d other) {"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" return true;"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" } else if (this.getClass() \u003d\u003d other.getClass()) {"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog otherFeedbackSessionLog \u003d (FeedbackSessionLog) other;"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" return Objects.equals(this.getId(), otherFeedbackSessionLog.getId());"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" return false;"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" public List\u003cString\u003e getInvalidityInfo() {"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" return new ArrayList\u003c\u003e();"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":128,"-":7}},{"path":"src/main/java/teammates/storage/sqlentity/Student.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlentity;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import jakarta.persistence.Column;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import jakarta.persistence.Entity;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import jakarta.persistence.Table;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * Represents a Student."},{"lineNumber":17,"author":{"gitId":"-"},"content":" */"},{"lineNumber":18,"author":{"gitId":"-"},"content":"@Entity"},{"lineNumber":19,"author":{"gitId":"-"},"content":"@Table(name \u003d \"Students\")"},{"lineNumber":20,"author":{"gitId":"-"},"content":"public class Student extends User {"},{"lineNumber":21,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":22,"author":{"gitId":"-"},"content":" private String comments;"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" protected Student() {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" // required by Hibernate"},{"lineNumber":26,"author":{"gitId":"-"},"content":" }"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" public Student(Course course, String name, String email, String comments) {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" super(course, name, email);"},{"lineNumber":30,"author":{"gitId":"-"},"content":" this.setComments(comments);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" }"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" public Student(Course course, String name, String email, String comments, Team team) {"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" super(course, name, email);"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" this.setComments(comments);"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" this.setTeam(team);"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" * Gets the comments of the student."},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":42,"author":{"gitId":"-"},"content":" public String getComments() {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" return comments;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" }"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" * Sets the comments of the student."},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":49,"author":{"gitId":"-"},"content":" public void setComments(String comments) {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" this.comments \u003d SanitizationHelper.sanitizeTextField(comments);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" }"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":54,"author":{"gitId":"-"},"content":" public String getTeamName() {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" return getTeam().getName();"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":59,"author":{"gitId":"-"},"content":" public String getSectionName() {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" return this.getTeam().getSection().getName();"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":64,"author":{"gitId":"-"},"content":" public Section getSection() {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" return this.getTeam().getSection();"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":69,"author":{"gitId":"-"},"content":" public String toString() {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" return \"Student [id\u003d\" + super.getId() + \", comments\u003d\" + comments"},{"lineNumber":71,"author":{"gitId":"-"},"content":" + \", createdAt\u003d\" + super.getCreatedAt() + \", updatedAt\u003d\" + super.getUpdatedAt() + \"]\";"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public List\u003cString\u003e getInvalidityInfo() {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" assert comments !\u003d null;"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" List\u003cString\u003e errors \u003d new ArrayList\u003c\u003e();"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForEmail(super.getEmail()), errors);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForStudentRoleComments(comments), errors);"},{"lineNumber":82,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForPersonName(super.getName()), errors);"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" return errors;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" }"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" public String getRegistrationUrl() {"},{"lineNumber":88,"author":{"gitId":"-"},"content":" return Config.getFrontEndAppUrl(Const.WebPageURIs.JOIN_PAGE)"},{"lineNumber":89,"author":{"gitId":"-"},"content":" .withRegistrationKey(getRegKey())"},{"lineNumber":90,"author":{"gitId":"-"},"content":" .withEntityType(Const.EntityType.STUDENT)"},{"lineNumber":91,"author":{"gitId":"-"},"content":" .toString();"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":12,"-":81}},{"path":"src/main/java/teammates/storage/sqlentity/questions/FeedbackMsqQuestion.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlentity.questions;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import jakarta.persistence.Column;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import jakarta.persistence.Convert;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import jakarta.persistence.Converter;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.persistence.Entity;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackMsqQuestionDetails;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionDetails;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * Represents an msq question."},{"lineNumber":19,"author":{"gitId":"-"},"content":" */"},{"lineNumber":20,"author":{"gitId":"-"},"content":"@Entity"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public class FeedbackMsqQuestion extends FeedbackQuestion {"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false, columnDefinition \u003d \"TEXT\")"},{"lineNumber":24,"author":{"gitId":"-"},"content":" @Convert(converter \u003d FeedbackMsqQuestionDetailsConverter.class)"},{"lineNumber":25,"author":{"gitId":"-"},"content":" private FeedbackMsqQuestionDetails questionDetails;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" protected FeedbackMsqQuestion() {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" // required by Hibernate"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" public FeedbackMsqQuestion("},{"lineNumber":32,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession, Integer questionNumber,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" String description, FeedbackParticipantType giverType, FeedbackParticipantType recipientType,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" Integer numOfEntitiesToGiveFeedbackTo, List\u003cFeedbackParticipantType\u003e showResponsesTo,"},{"lineNumber":35,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showGiverNameTo, List\u003cFeedbackParticipantType\u003e showRecipientNameTo,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails feedbackQuestionDetails"},{"lineNumber":37,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" super(feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":39,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo);"},{"lineNumber":40,"author":{"gitId":"-"},"content":" setFeedBackQuestionDetails((FeedbackMsqQuestionDetails) feedbackQuestionDetails);"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":44,"author":{"gitId":"-"},"content":" public FeedbackQuestionDetails getQuestionDetailsCopy() {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" return questionDetails.getDeepCopy();"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":49,"author":{"gitId":"-"},"content":" public FeedbackMsqQuestion makeDeepCopy(FeedbackSession newFeedbackSession) {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" return new FeedbackMsqQuestion("},{"lineNumber":51,"author":{"gitId":"-"},"content":" newFeedbackSession, this.getQuestionNumber(), this.getDescription(), this.getGiverType(),"},{"lineNumber":52,"author":{"gitId":"-"},"content":" this.getRecipientType(), this.getNumOfEntitiesToGiveFeedbackTo(), new ArrayList\u003c\u003e(this.getShowResponsesTo()),"},{"lineNumber":53,"author":{"gitId":"-"},"content":" new ArrayList\u003c\u003e(this.getShowGiverNameTo()), new ArrayList\u003c\u003e(this.getShowRecipientNameTo()),"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" this.questionDetails.getDeepCopy()"},{"lineNumber":55,"author":{"gitId":"-"},"content":" );"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":59,"author":{"gitId":"-"},"content":" public void setQuestionDetails(FeedbackQuestionDetails questionDetails) {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" this.questionDetails \u003d (FeedbackMsqQuestionDetails) questionDetails;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":64,"author":{"gitId":"-"},"content":" public String toString() {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" return \"FeedbackMsqQuestion [id\u003d\" + super.getId()"},{"lineNumber":66,"author":{"gitId":"-"},"content":" + \", createdAt\u003d\" + super.getCreatedAt() + \", updatedAt\u003d\" + super.getUpdatedAt() + \"]\";"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" public void setFeedBackQuestionDetails(FeedbackMsqQuestionDetails questionDetails) {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" this.questionDetails \u003d questionDetails;"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" public FeedbackMsqQuestionDetails getFeedbackQuestionDetails() {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" return questionDetails;"},{"lineNumber":75,"author":{"gitId":"-"},"content":" }"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":78,"author":{"gitId":"-"},"content":" * Converter for FeedbackMsqQuestion specific attributes."},{"lineNumber":79,"author":{"gitId":"-"},"content":" */"},{"lineNumber":80,"author":{"gitId":"-"},"content":" @Converter"},{"lineNumber":81,"author":{"gitId":"-"},"content":" public static class FeedbackMsqQuestionDetailsConverter"},{"lineNumber":82,"author":{"gitId":"-"},"content":" extends FeedbackQuestionDetailsConverter {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" }"},{"lineNumber":84,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":1,"-":83}},{"path":"src/main/java/teammates/storage/sqlentity/questions/FeedbackRankOptionsQuestion.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlentity.questions;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import jakarta.persistence.Column;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import jakarta.persistence.Convert;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import jakarta.persistence.Converter;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.persistence.Entity;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionDetails;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRankOptionsQuestionDetails;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * Represents a rank options question."},{"lineNumber":19,"author":{"gitId":"-"},"content":" */"},{"lineNumber":20,"author":{"gitId":"-"},"content":"@Entity"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public class FeedbackRankOptionsQuestion extends FeedbackQuestion {"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false, columnDefinition \u003d \"TEXT\")"},{"lineNumber":24,"author":{"gitId":"-"},"content":" @Convert(converter \u003d FeedbackRankOptionsQuestionDetailsConverter.class)"},{"lineNumber":25,"author":{"gitId":"-"},"content":" private FeedbackRankOptionsQuestionDetails questionDetails;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" protected FeedbackRankOptionsQuestion() {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" // required by Hibernate"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" public FeedbackRankOptionsQuestion("},{"lineNumber":32,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession, Integer questionNumber,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" String description, FeedbackParticipantType giverType, FeedbackParticipantType recipientType,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" Integer numOfEntitiesToGiveFeedbackTo, List\u003cFeedbackParticipantType\u003e showResponsesTo,"},{"lineNumber":35,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showGiverNameTo, List\u003cFeedbackParticipantType\u003e showRecipientNameTo,"},{"lineNumber":36,"author":{"gitId":"mingyuanc"},"content":" FeedbackQuestionDetails feedbackQuestionDetails) {"},{"lineNumber":37,"author":{"gitId":"-"},"content":" super(feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":38,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" setFeedBackQuestionDetails((FeedbackRankOptionsQuestionDetails) feedbackQuestionDetails);"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":43,"author":{"gitId":"-"},"content":" public FeedbackQuestionDetails getQuestionDetailsCopy() {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return questionDetails.getDeepCopy();"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":48,"author":{"gitId":"-"},"content":" public FeedbackRankOptionsQuestion makeDeepCopy(FeedbackSession newFeedbackSession) {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" return new FeedbackRankOptionsQuestion("},{"lineNumber":50,"author":{"gitId":"-"},"content":" newFeedbackSession, this.getQuestionNumber(), this.getDescription(), this.getGiverType(),"},{"lineNumber":51,"author":{"gitId":"-"},"content":" this.getRecipientType(), this.getNumOfEntitiesToGiveFeedbackTo(),"},{"lineNumber":52,"author":{"gitId":"-"},"content":" new ArrayList\u003c\u003e(this.getShowResponsesTo()), new ArrayList\u003c\u003e(this.getShowGiverNameTo()),"},{"lineNumber":53,"author":{"gitId":"-"},"content":" new ArrayList\u003c\u003e(this.getShowRecipientNameTo()),"},{"lineNumber":54,"author":{"gitId":"mingyuanc"},"content":" this.questionDetails.getDeepCopy());"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":58,"author":{"gitId":"-"},"content":" public void setQuestionDetails(FeedbackQuestionDetails questionDetails) {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" this.questionDetails \u003d (FeedbackRankOptionsQuestionDetails) questionDetails;"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":63,"author":{"gitId":"-"},"content":" public String toString() {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" return \"FeedbackRankOptionsQuestion [id\u003d\" + super.getId()"},{"lineNumber":65,"author":{"gitId":"-"},"content":" + \", createdAt\u003d\" + super.getCreatedAt() + \", updatedAt\u003d\" + super.getUpdatedAt() + \"]\";"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" public void setFeedBackQuestionDetails(FeedbackRankOptionsQuestionDetails questionDetails) {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" this.questionDetails \u003d questionDetails;"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" public FeedbackRankOptionsQuestionDetails getFeedbackQuestionDetails() {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" return questionDetails;"},{"lineNumber":74,"author":{"gitId":"-"},"content":" }"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":77,"author":{"gitId":"-"},"content":" * Converter for FeedbackRankOptionsQuestion specific attributes."},{"lineNumber":78,"author":{"gitId":"-"},"content":" */"},{"lineNumber":79,"author":{"gitId":"-"},"content":" @Converter"},{"lineNumber":80,"author":{"gitId":"-"},"content":" public static class FeedbackRankOptionsQuestionDetailsConverter"},{"lineNumber":81,"author":{"gitId":"-"},"content":" extends FeedbackQuestionDetailsConverter {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" }"},{"lineNumber":83,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"mingyuanc":2,"-":81}},{"path":"src/main/java/teammates/storage/sqlentity/responses/FeedbackMissingResponse.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.storage.sqlentity.responses;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.questions.FeedbackTextResponseDetails;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":" * Represents a missing response."},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"public class FeedbackMissingResponse extends FeedbackTextResponse {"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" private String giverSectionName;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" private String recipientSectionName;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":" protected FeedbackMissingResponse() {"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" // required by Hibernate"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":" public FeedbackMissingResponse("},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion feedbackQuestion, String giver,"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" String giverSectionName, String recipient, String recipientSectionName"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" ) {"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" super(feedbackQuestion, giver, null, recipient, null, new FeedbackTextResponseDetails(Const.MISSING_RESPONSE_TEXT));"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" this.giverSectionName \u003d giverSectionName;"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" this.recipientSectionName \u003d recipientSectionName;"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" public String getGiverSectionName() {"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" return giverSectionName;"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" public String getRecipientSectionName() {"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" return recipientSectionName;"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":37}},{"path":"src/main/java/teammates/storage/sqlsearch/SearchManager.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlsearch;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.io.IOException;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.net.SocketTimeoutException;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Collections;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.apache.commons.lang.StringUtils;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.apache.solr.client.solrj.SolrQuery;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import org.apache.solr.client.solrj.SolrServerException;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import org.apache.solr.client.solrj.impl.HttpSolrClient;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import org.apache.solr.client.solrj.response.QueryResponse;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import org.apache.solr.common.SolrDocument;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import org.apache.solr.common.SolrInputDocument;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.util.StringHelper;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.BaseEntity;"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":27,"author":{"gitId":"-"},"content":" * Acts as a proxy to search service."},{"lineNumber":28,"author":{"gitId":"-"},"content":" *"},{"lineNumber":29,"author":{"gitId":"-"},"content":" * @param \u003cT\u003e Type of entity to be returned"},{"lineNumber":30,"author":{"gitId":"-"},"content":" */"},{"lineNumber":31,"author":{"gitId":"-"},"content":"abstract class SearchManager\u003cT extends BaseEntity\u003e {"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" private static final String ERROR_DELETE_DOCUMENT \u003d \"Failed to delete document(s) %s in Solr. Root cause: %s \";"},{"lineNumber":36,"author":{"gitId":"-"},"content":" private static final String ERROR_SEARCH_DOCUMENT \u003d \"Failed to search for document(s) %s from Solr. Root cause: %s \";"},{"lineNumber":37,"author":{"gitId":"-"},"content":" private static final String ERROR_SEARCH_NOT_IMPLEMENTED \u003d \"Search service is not implemented\";"},{"lineNumber":38,"author":{"gitId":"-"},"content":" private static final String ERROR_PUT_DOCUMENT \u003d \"Failed to put document %s into Solr. Root cause: %s \";"},{"lineNumber":39,"author":{"gitId":"-"},"content":" private static final String ERROR_RESET_COLLECTION \u003d \"Failed to reset collections. Root cause: %s \";"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" private static final int START_INDEX \u003d 0;"},{"lineNumber":42,"author":{"gitId":"-"},"content":" private static final int NUM_OF_RESULTS \u003d Const.SEARCH_QUERY_SIZE_LIMIT;"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" private final HttpSolrClient client;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" private final boolean isResetAllowed;"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" SearchManager(String searchServiceHost, boolean isResetAllowed) {"},{"lineNumber":48,"author":{"gitId":"-"},"content":" this.isResetAllowed \u003d Config.IS_DEV_SERVER \u0026\u0026 isResetAllowed;"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" if (StringHelper.isEmpty(searchServiceHost)) {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" this.client \u003d null;"},{"lineNumber":52,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" this.client \u003d new HttpSolrClient.Builder(searchServiceHost)"},{"lineNumber":54,"author":{"gitId":"-"},"content":" .withConnectionTimeout(2000) // timeout for connecting to Solr server"},{"lineNumber":55,"author":{"gitId":"-"},"content":" .withSocketTimeout(5000) // timeout for reading data"},{"lineNumber":56,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" SolrQuery getBasicQuery(String queryString) {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" SolrQuery query \u003d new SolrQuery();"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" String cleanQueryString \u003d cleanSpecialChars(queryString);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" query.setQuery(cleanQueryString);"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" query.setStart(START_INDEX);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" query.setRows(NUM_OF_RESULTS);"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" return query;"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" QueryResponse performQuery(SolrQuery query) throws SearchServiceException {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" if (client \u003d\u003d null) {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" throw new SearchServiceException(\"Full-text search is not available.\", HttpStatus.SC_NOT_IMPLEMENTED);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" }"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" return client.query(getCollectionName(), query);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" } catch (SolrServerException e) {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" Throwable rootCause \u003d e.getRootCause();"},{"lineNumber":81,"author":{"gitId":"-"},"content":" log.severe(String.format(ERROR_SEARCH_DOCUMENT, query.getQuery(), rootCause), e);"},{"lineNumber":82,"author":{"gitId":"-"},"content":" if (rootCause instanceof SocketTimeoutException) {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" throw new SearchServiceException(\"A timeout was reached while processing your request. \""},{"lineNumber":84,"author":{"gitId":"-"},"content":" + \"Please try again later.\", e, HttpStatus.SC_GATEWAY_TIMEOUT);"},{"lineNumber":85,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":86,"author":{"gitId":"-"},"content":" throw new SearchServiceException(\"An error has occurred while performing search. \""},{"lineNumber":87,"author":{"gitId":"-"},"content":" + \"Please try again later.\", e, HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":90,"author":{"gitId":"-"},"content":" log.severe(String.format(ERROR_SEARCH_DOCUMENT, query.getQuery(), e.getCause()), e);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" throw new SearchServiceException(\"An error has occurred while performing search. \""},{"lineNumber":92,"author":{"gitId":"-"},"content":" + \"Please try again later.\", e, HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" }"},{"lineNumber":94,"author":{"gitId":"-"},"content":" }"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" abstract String getCollectionName();"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" abstract SearchDocument\u003cT\u003e createDocument(T entity);"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":101,"author":{"gitId":"-"},"content":" * Creates or updates search document for the given entity."},{"lineNumber":102,"author":{"gitId":"-"},"content":" */"},{"lineNumber":103,"author":{"gitId":"-"},"content":" public void putDocument(T entity) throws SearchServiceException {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" if (client \u003d\u003d null) {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" log.warning(ERROR_SEARCH_NOT_IMPLEMENTED);"},{"lineNumber":106,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" if (entity \u003d\u003d null) {"},{"lineNumber":110,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" Map\u003cString, Object\u003e searchableFields \u003d createDocument(entity).getSearchableFields();"},{"lineNumber":114,"author":{"gitId":"-"},"content":" SolrInputDocument document \u003d new SolrInputDocument();"},{"lineNumber":115,"author":{"gitId":"-"},"content":" searchableFields.forEach((key, value) -\u003e document.addField(key, value));"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":118,"author":{"gitId":"-"},"content":" client.add(getCollectionName(), Collections.singleton(document));"},{"lineNumber":119,"author":{"gitId":"-"},"content":" client.commit(getCollectionName());"},{"lineNumber":120,"author":{"gitId":"-"},"content":" } catch (SolrServerException e) {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" log.severe(String.format(ERROR_PUT_DOCUMENT, document, e.getRootCause()), e);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" throw new SearchServiceException(e, HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":123,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":124,"author":{"gitId":"-"},"content":" log.severe(String.format(ERROR_PUT_DOCUMENT, document, e.getCause()), e);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" throw new SearchServiceException(e, HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" }"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":130,"author":{"gitId":"-"},"content":" * Removes search documents based on the given keys."},{"lineNumber":131,"author":{"gitId":"-"},"content":" */"},{"lineNumber":132,"author":{"gitId":"-"},"content":" public void deleteDocuments(List\u003cString\u003e keys) {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" if (client \u003d\u003d null) {"},{"lineNumber":134,"author":{"gitId":"-"},"content":" log.warning(ERROR_SEARCH_NOT_IMPLEMENTED);"},{"lineNumber":135,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":136,"author":{"gitId":"-"},"content":" }"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" if (keys.isEmpty()) {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" client.deleteById(getCollectionName(), keys);"},{"lineNumber":144,"author":{"gitId":"-"},"content":" client.commit(getCollectionName());"},{"lineNumber":145,"author":{"gitId":"-"},"content":" } catch (SolrServerException e) {"},{"lineNumber":146,"author":{"gitId":"-"},"content":" log.severe(String.format(ERROR_DELETE_DOCUMENT, keys, e.getRootCause()), e);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" log.severe(String.format(ERROR_DELETE_DOCUMENT, keys, e.getCause()), e);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" }"},{"lineNumber":150,"author":{"gitId":"-"},"content":" }"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":153,"author":{"gitId":"-"},"content":" * Resets the data for all collections if, and only if called during component"},{"lineNumber":154,"author":{"gitId":"-"},"content":" * tests."},{"lineNumber":155,"author":{"gitId":"-"},"content":" */"},{"lineNumber":156,"author":{"gitId":"-"},"content":" public void resetCollections() {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" if (client \u003d\u003d null || !isResetAllowed) {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" client.deleteByQuery(getCollectionName(), \"*:*\");"},{"lineNumber":163,"author":{"gitId":"-"},"content":" client.commit(getCollectionName());"},{"lineNumber":164,"author":{"gitId":"-"},"content":" } catch (SolrServerException e) {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" log.severe(String.format(ERROR_RESET_COLLECTION, e.getRootCause()), e);"},{"lineNumber":166,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" log.severe(String.format(ERROR_RESET_COLLECTION, e.getCause()), e);"},{"lineNumber":168,"author":{"gitId":"-"},"content":" }"},{"lineNumber":169,"author":{"gitId":"-"},"content":" }"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" private String cleanSpecialChars(String queryString) {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" String htmlTagStripPattern \u003d \"\u003c[^\u003e]*\u003e\";"},{"lineNumber":173,"author":{"gitId":"-"},"content":""},{"lineNumber":174,"author":{"gitId":"-"},"content":" // Solr special characters: + - \u0026\u0026 || ! ( ) { } [ ] ^ \" ~ * ? : \\ /"},{"lineNumber":175,"author":{"gitId":"-"},"content":" String res \u003d queryString.replaceAll(htmlTagStripPattern, \"\")"},{"lineNumber":176,"author":{"gitId":"-"},"content":" .replace(\"\\\\\", \"\\\\\\\\\")"},{"lineNumber":177,"author":{"gitId":"-"},"content":" .replace(\"+\", \"\\\\+\")"},{"lineNumber":178,"author":{"gitId":"-"},"content":" .replace(\"-\", \"\\\\-\")"},{"lineNumber":179,"author":{"gitId":"-"},"content":" .replace(\"\u0026\u0026\", \"\\\\\u0026\u0026\")"},{"lineNumber":180,"author":{"gitId":"-"},"content":" .replace(\"||\", \"\\\\||\")"},{"lineNumber":181,"author":{"gitId":"-"},"content":" .replace(\"!\", \"\\\\!\")"},{"lineNumber":182,"author":{"gitId":"-"},"content":" .replace(\"(\", \"\\\\(\")"},{"lineNumber":183,"author":{"gitId":"-"},"content":" .replace(\")\", \"\\\\)\")"},{"lineNumber":184,"author":{"gitId":"-"},"content":" .replace(\"{\", \"\\\\{\")"},{"lineNumber":185,"author":{"gitId":"-"},"content":" .replace(\"}\", \"\\\\}\")"},{"lineNumber":186,"author":{"gitId":"-"},"content":" .replace(\"[\", \"\\\\[\")"},{"lineNumber":187,"author":{"gitId":"-"},"content":" .replace(\"]\", \"\\\\]\")"},{"lineNumber":188,"author":{"gitId":"-"},"content":" .replace(\"^\", \"\\\\^\")"},{"lineNumber":189,"author":{"gitId":"-"},"content":" .replace(\"~\", \"\\\\~\")"},{"lineNumber":190,"author":{"gitId":"-"},"content":" .replace(\"?\", \"\\\\?\")"},{"lineNumber":191,"author":{"gitId":"-"},"content":" .replace(\":\", \"\\\\:\")"},{"lineNumber":192,"author":{"gitId":"-"},"content":" .replace(\"/\", \"\\\\/\");"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"-"},"content":" // imbalanced double quotes are invalid"},{"lineNumber":195,"author":{"gitId":"-"},"content":" int count \u003d StringUtils.countMatches(res, \"\\\"\");"},{"lineNumber":196,"author":{"gitId":"-"},"content":" if (count % 2 \u003d\u003d 1) {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" res \u003d res.replace(\"\\\"\", \"\");"},{"lineNumber":198,"author":{"gitId":"-"},"content":" }"},{"lineNumber":199,"author":{"gitId":"-"},"content":""},{"lineNumber":200,"author":{"gitId":"-"},"content":" // use exact match only when there\u0027s email-like input"},{"lineNumber":201,"author":{"gitId":"-"},"content":" if (res.contains(\"@\") \u0026\u0026 count \u003d\u003d 0) {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" return \"\\\"\" + res + \"\\\"\";"},{"lineNumber":203,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":204,"author":{"gitId":"-"},"content":" return res;"},{"lineNumber":205,"author":{"gitId":"-"},"content":" }"},{"lineNumber":206,"author":{"gitId":"-"},"content":" }"},{"lineNumber":207,"author":{"gitId":"-"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" abstract T getEntityFromDocument(SolrDocument document);"},{"lineNumber":209,"author":{"gitId":"-"},"content":""},{"lineNumber":210,"author":{"gitId":"-"},"content":" abstract void sortResult(List\u003cT\u003e result);"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" List\u003cT\u003e convertDocumentToEntities(List\u003cSolrDocument\u003e documents) {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" if (documents \u003d\u003d null) {"},{"lineNumber":214,"author":{"gitId":"-"},"content":" return new ArrayList\u003c\u003e();"},{"lineNumber":215,"author":{"gitId":"-"},"content":" }"},{"lineNumber":216,"author":{"gitId":"-"},"content":""},{"lineNumber":217,"author":{"gitId":"-"},"content":" List\u003cT\u003e result \u003d new ArrayList\u003c\u003e();"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":" for (SolrDocument document : documents) {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" T entity \u003d getEntityFromDocument(document);"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"-"},"content":" // Entity will be null if document corresponds to entity in datastore"},{"lineNumber":223,"author":{"gitId":"-"},"content":" if (entity \u003d\u003d null) {"},{"lineNumber":224,"author":{"gitId":"-"},"content":" // search engine out of sync as SearchManager may fail to delete documents"},{"lineNumber":225,"author":{"gitId":"-"},"content":" // the chance is low and it is generally not a big problem"},{"lineNumber":226,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":227,"author":{"gitId":"domoberzin"},"content":" // these lines below are commented out as they interfere with the dual db search,"},{"lineNumber":228,"author":{"gitId":"domoberzin"},"content":" // and cause unwanted deletions, please refer to the following PR for more details"},{"lineNumber":229,"author":{"gitId":"domoberzin"},"content":" // [PR](https://github.com/TEAMMATES/teammates/pull/12838)"},{"lineNumber":230,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":231,"author":{"gitId":"domoberzin"},"content":" // String id \u003d (String) document.getFirstValue(\"id\");"},{"lineNumber":232,"author":{"gitId":"domoberzin"},"content":" // deleteDocuments(Collections.singletonList(id));"},{"lineNumber":233,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":234,"author":{"gitId":"-"},"content":" }"},{"lineNumber":235,"author":{"gitId":"-"},"content":" result.add(entity);"},{"lineNumber":236,"author":{"gitId":"-"},"content":" }"},{"lineNumber":237,"author":{"gitId":"-"},"content":" sortResult(result);"},{"lineNumber":238,"author":{"gitId":"-"},"content":""},{"lineNumber":239,"author":{"gitId":"-"},"content":" return result;"},{"lineNumber":240,"author":{"gitId":"-"},"content":" }"},{"lineNumber":241,"author":{"gitId":"-"},"content":""},{"lineNumber":242,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":7,"-":235}},{"path":"src/main/java/teammates/ui/constants/ApiConst.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.constants;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import com.fasterxml.jackson.annotation.JsonValue;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":9,"author":{"gitId":"-"},"content":" * Special constants used by the back-end."},{"lineNumber":10,"author":{"gitId":"-"},"content":" */"},{"lineNumber":11,"author":{"gitId":"-"},"content":"public enum ApiConst {"},{"lineNumber":12,"author":{"gitId":"-"},"content":" // CHECKSTYLE.OFF:JavadocVariable"},{"lineNumber":13,"author":{"gitId":"-"},"content":" COURSE_ID_MAX_LENGTH(FieldValidator.COURSE_ID_MAX_LENGTH),"},{"lineNumber":14,"author":{"gitId":"-"},"content":" COURSE_NAME_MAX_LENGTH(FieldValidator.COURSE_NAME_MAX_LENGTH),"},{"lineNumber":15,"author":{"gitId":"-"},"content":" STUDENT_NAME_MAX_LENGTH(FieldValidator.PERSON_NAME_MAX_LENGTH),"},{"lineNumber":16,"author":{"gitId":"-"},"content":" SECTION_NAME_MAX_LENGTH(FieldValidator.SECTION_NAME_MAX_LENGTH),"},{"lineNumber":17,"author":{"gitId":"-"},"content":" TEAM_NAME_MAX_LENGTH(FieldValidator.TEAM_NAME_MAX_LENGTH),"},{"lineNumber":18,"author":{"gitId":"-"},"content":" EMAIL_MAX_LENGTH(FieldValidator.EMAIL_MAX_LENGTH),"},{"lineNumber":19,"author":{"gitId":"-"},"content":" FEEDBACK_SESSION_NAME_MAX_LENGTH(FieldValidator.FEEDBACK_SESSION_NAME_MAX_LENGTH),"},{"lineNumber":20,"author":{"gitId":"-"},"content":" NOTIFICATION_TITLE_MAX_LENGTH(FieldValidator.NOTIFICATION_TITLE_MAX_LENGTH),"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" CONTRIBUTION_POINT_NOT_SUBMITTED(Const.POINTS_NOT_SUBMITTED),"},{"lineNumber":23,"author":{"gitId":"-"},"content":" CONTRIBUTION_POINT_NOT_INITIALIZED(Const.INT_UNINITIALIZED),"},{"lineNumber":24,"author":{"gitId":"-"},"content":" CONTRIBUTION_POINT_NOT_SURE(Const.POINTS_NOT_SURE),"},{"lineNumber":25,"author":{"gitId":"-"},"content":" CONTRIBUTION_POINT_EQUAL_SHARE(Const.POINTS_EQUAL_SHARE),"},{"lineNumber":26,"author":{"gitId":"-"},"content":" NUMERICAL_SCALE_ANSWER_NOT_SUBMITTED(Const.POINTS_NOT_SUBMITTED),"},{"lineNumber":27,"author":{"gitId":"-"},"content":" RANK_OPTIONS_ANSWER_NOT_SUBMITTED(Const.POINTS_NOT_SUBMITTED),"},{"lineNumber":28,"author":{"gitId":"-"},"content":" RANK_RECIPIENTS_ANSWER_NOT_SUBMITTED(Const.POINTS_NOT_SUBMITTED),"},{"lineNumber":29,"author":{"gitId":"-"},"content":" NO_VALUE(Const.POINTS_NO_VALUE),"},{"lineNumber":30,"author":{"gitId":"-"},"content":" LOGS_RETENTION_PERIOD(Const.LOGS_RETENTION_PERIOD.toDays()),"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" SEARCH_QUERY_SIZE_LIMIT(Const.SEARCH_QUERY_SIZE_LIMIT),"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" STUDENT_ACTIVITY_LOGS_UPDATE_INTERVAL(Const.STUDENT_ACTIVITY_LOGS_UPDATE_INTERVAL.toMinutes());"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" // CHECKSTYLE.ON:JavadocVariable"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" private final Object value;"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" ApiConst(Object value) {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.value \u003d value;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" @JsonValue"},{"lineNumber":43,"author":{"gitId":"-"},"content":" public Object getValue() {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return value;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":3,"-":44}},{"path":"src/main/java/teammates/ui/constants/ApiStringConst.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.ui.constants;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import com.fasterxml.jackson.annotation.JsonValue;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":" * Special constants used by the back-end."},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"public enum ApiStringConst {"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":" // CHECKSTYLE.OFF:JavadocVariable"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" EMAIL_REGEX(escapeRegex(FieldValidator.REGEX_EMAIL));"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" // CHECKSTYLE.ON:JavadocVariable"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":" private final Object value;"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" ApiStringConst(Object value) {"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":" this.value \u003d value;"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" @JsonValue"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" public Object getValue() {"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" return value;"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" * Escape regex pattern strings to ensure the pattern remains valid when converted to JS."},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" private static String escapeRegex(String regexStr) {"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" String escapedRegexStr \u003d regexStr;"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" // Double escape backslashes"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" escapedRegexStr \u003d escapedRegexStr.replace(\"\\\\\", \"\\\\\\\\\");"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" // Replace possessive zero or more times quantifier *+ that the email pattern uses"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" // with greedy zero or more times quantifier *"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" // as possessive quantifiers are not supported in JavaScript"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" escapedRegexStr \u003d escapedRegexStr.replace(\"*+\", \"*\");"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" return escapedRegexStr;"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":40}},{"path":"src/main/java/teammates/ui/constants/ResourceEndpoints.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.constants;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import com.fasterxml.jackson.annotation.JsonValue;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.ResourceURIs;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":8,"author":{"gitId":"-"},"content":" * API endpoints for resources."},{"lineNumber":9,"author":{"gitId":"-"},"content":" */"},{"lineNumber":10,"author":{"gitId":"-"},"content":"public enum ResourceEndpoints {"},{"lineNumber":11,"author":{"gitId":"-"},"content":" //CHECKSTYLE.OFF:JavadocVariable"},{"lineNumber":12,"author":{"gitId":"-"},"content":" ERROR_REPORT(ResourceURIs.ERROR_REPORT),"},{"lineNumber":13,"author":{"gitId":"-"},"content":" AUTH(ResourceURIs.AUTH),"},{"lineNumber":14,"author":{"gitId":"-"},"content":" AUTH_REGKEY(ResourceURIs.AUTH_REGKEY),"},{"lineNumber":15,"author":{"gitId":"-"},"content":" ACCOUNT(ResourceURIs.ACCOUNT),"},{"lineNumber":16,"author":{"gitId":"-"},"content":" ACCOUNT_RESET(ResourceURIs.ACCOUNT_RESET),"},{"lineNumber":17,"author":{"gitId":"-"},"content":" ACCOUNT_REQUEST(ResourceURIs.ACCOUNT_REQUEST),"},{"lineNumber":18,"author":{"gitId":"-"},"content":" ACCOUNT_REQUESTS(ResourceURIs.ACCOUNT_REQUESTS),"},{"lineNumber":19,"author":{"gitId":"-"},"content":" ACCOUNT_REQUEST_RESET(ResourceURIs.ACCOUNT_REQUEST_RESET),"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" ACCOUNT_REQUEST_REJECT(ResourceURIs.ACCOUNT_REQUEST_REJECTION),"},{"lineNumber":21,"author":{"gitId":"-"},"content":" ACCOUNTS(ResourceURIs.ACCOUNTS),"},{"lineNumber":22,"author":{"gitId":"-"},"content":" RESPONSE_COMMENT(ResourceURIs.RESPONSE_COMMENT),"},{"lineNumber":23,"author":{"gitId":"-"},"content":" COURSE(ResourceURIs.COURSE),"},{"lineNumber":24,"author":{"gitId":"-"},"content":" COURSE_ARCHIVE(ResourceURIs.COURSE_ARCHIVE),"},{"lineNumber":25,"author":{"gitId":"-"},"content":" BIN_COURSE(ResourceURIs.BIN_COURSE),"},{"lineNumber":26,"author":{"gitId":"-"},"content":" COURSE_SECTIONS(ResourceURIs.COURSE_SECTIONS),"},{"lineNumber":27,"author":{"gitId":"-"},"content":" COURSES(ResourceURIs.COURSES),"},{"lineNumber":28,"author":{"gitId":"-"},"content":" INSTRUCTORS(ResourceURIs.INSTRUCTORS),"},{"lineNumber":29,"author":{"gitId":"-"},"content":" INSTRUCTOR(ResourceURIs.INSTRUCTOR),"},{"lineNumber":30,"author":{"gitId":"-"},"content":" INSTRUCTOR_PRIVILEGE(ResourceURIs.INSTRUCTOR_PRIVILEGE),"},{"lineNumber":31,"author":{"gitId":"-"},"content":" INSTRUCTOR_KEY(ResourceURIs.INSTRUCTOR_KEY),"},{"lineNumber":32,"author":{"gitId":"-"},"content":" RESULT(ResourceURIs.RESULT),"},{"lineNumber":33,"author":{"gitId":"-"},"content":" STUDENTS(ResourceURIs.STUDENTS),"},{"lineNumber":34,"author":{"gitId":"-"},"content":" STUDENT(ResourceURIs.STUDENT),"},{"lineNumber":35,"author":{"gitId":"-"},"content":" STUDENT_KEY(ResourceURIs.STUDENT_KEY),"},{"lineNumber":36,"author":{"gitId":"-"},"content":" SESSIONS_ONGOING(ResourceURIs.SESSIONS_ONGOING),"},{"lineNumber":37,"author":{"gitId":"-"},"content":" SESSION(ResourceURIs.SESSION),"},{"lineNumber":38,"author":{"gitId":"-"},"content":" SESSION_LOGS(ResourceURIs.SESSION_LOGS),"},{"lineNumber":39,"author":{"gitId":"-"},"content":" SESSION_PUBLISH(ResourceURIs.SESSION_PUBLISH),"},{"lineNumber":40,"author":{"gitId":"-"},"content":" SESSION_REMIND_SUBMISSION(ResourceURIs.SESSION_REMIND_SUBMISSION),"},{"lineNumber":41,"author":{"gitId":"-"},"content":" SESSION_REMIND_RESULT(ResourceURIs.SESSION_REMIND_RESULT),"},{"lineNumber":42,"author":{"gitId":"-"},"content":" SESSION_STATS(ResourceURIs.SESSION_STATS),"},{"lineNumber":43,"author":{"gitId":"-"},"content":" SESSION_SUBMITTED_GIVER_SET(ResourceURIs.SESSION_SUBMITTED_GIVER_SET),"},{"lineNumber":44,"author":{"gitId":"-"},"content":" SESSIONS(ResourceURIs.SESSIONS),"},{"lineNumber":45,"author":{"gitId":"-"},"content":" BIN_SESSION(ResourceURIs.BIN_SESSION),"},{"lineNumber":46,"author":{"gitId":"-"},"content":" QUESTIONS(ResourceURIs.QUESTIONS),"},{"lineNumber":47,"author":{"gitId":"-"},"content":" QUESTION(ResourceURIs.QUESTION),"},{"lineNumber":48,"author":{"gitId":"-"},"content":" QUESTION_RECIPIENTS(ResourceURIs.QUESTION_RECIPIENTS),"},{"lineNumber":49,"author":{"gitId":"-"},"content":" RESPONSES(ResourceURIs.RESPONSES),"},{"lineNumber":50,"author":{"gitId":"-"},"content":" HAS_RESPONSES(ResourceURIs.HAS_RESPONSES),"},{"lineNumber":51,"author":{"gitId":"-"},"content":" NOTIFICATION(ResourceURIs.NOTIFICATION),"},{"lineNumber":52,"author":{"gitId":"-"},"content":" NOTIFICATIONS(ResourceURIs.NOTIFICATIONS),"},{"lineNumber":53,"author":{"gitId":"-"},"content":" NOTIFICATION_READ(ResourceURIs.NOTIFICATION_READ),"},{"lineNumber":54,"author":{"gitId":"-"},"content":" JOIN(ResourceURIs.JOIN),"},{"lineNumber":55,"author":{"gitId":"-"},"content":" JOIN_REMIND(ResourceURIs.JOIN_REMIND),"},{"lineNumber":56,"author":{"gitId":"-"},"content":" TIMEZONE(ResourceURIs.TIMEZONE),"},{"lineNumber":57,"author":{"gitId":"-"},"content":" SESSION_LINKS_RECOVERY(ResourceURIs.SESSION_LINKS_RECOVERY),"},{"lineNumber":58,"author":{"gitId":"-"},"content":" EMAIL(ResourceURIs.EMAIL),"},{"lineNumber":59,"author":{"gitId":"-"},"content":" SEARCH_ACCOUNT_REQUESTS(ResourceURIs.SEARCH_ACCOUNT_REQUESTS),"},{"lineNumber":60,"author":{"gitId":"-"},"content":" SEARCH_INSTRUCTORS(ResourceURIs.SEARCH_INSTRUCTORS),"},{"lineNumber":61,"author":{"gitId":"-"},"content":" SEARCH_STUDENTS(ResourceURIs.SEARCH_STUDENTS),"},{"lineNumber":62,"author":{"gitId":"-"},"content":" LOGS(ResourceURIs.LOGS),"},{"lineNumber":63,"author":{"gitId":"-"},"content":" USAGE_STATISTICS(ResourceURIs.USAGE_STATISTICS),"},{"lineNumber":64,"author":{"gitId":"-"},"content":" ACTION_CLASS(ResourceURIs.ACTION_CLASS),"},{"lineNumber":65,"author":{"gitId":"-"},"content":" LOGIN_EMAIL(ResourceURIs.LOGIN_EMAIL);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" //CHECKSTYLE.ON:JavadocVariable"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" private final String url;"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" ResourceEndpoints(String s) {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" this.url \u003d s;"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" @JsonValue"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public String getUrl() {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" return url;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":1,"-":77}},{"path":"src/main/java/teammates/ui/output/CourseData.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.output;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPermissionSet;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":10,"author":{"gitId":"-"},"content":" * The API output format of a course."},{"lineNumber":11,"author":{"gitId":"-"},"content":" */"},{"lineNumber":12,"author":{"gitId":"-"},"content":"public class CourseData extends ApiOutput {"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":" private final String courseId;"},{"lineNumber":15,"author":{"gitId":"-"},"content":" private final String courseName;"},{"lineNumber":16,"author":{"gitId":"-"},"content":" private final String timeZone;"},{"lineNumber":17,"author":{"gitId":"-"},"content":" private final String institute;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" @Nullable"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":" private final Boolean isMigrated;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" private long creationTimestamp;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" private long deletionTimestamp;"},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":23,"author":{"gitId":"-"},"content":" private InstructorPermissionSet privileges;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" public CourseData(CourseAttributes courseAttributes) {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" this.courseId \u003d courseAttributes.getId();"},{"lineNumber":27,"author":{"gitId":"-"},"content":" this.courseName \u003d courseAttributes.getName();"},{"lineNumber":28,"author":{"gitId":"-"},"content":" this.timeZone \u003d courseAttributes.getTimeZone();"},{"lineNumber":29,"author":{"gitId":"-"},"content":" this.institute \u003d courseAttributes.getInstitute();"},{"lineNumber":30,"author":{"gitId":"-"},"content":" this.creationTimestamp \u003d courseAttributes.getCreatedAt().toEpochMilli();"},{"lineNumber":31,"author":{"gitId":"-"},"content":" if (courseAttributes.getDeletedAt() !\u003d null) {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" this.deletionTimestamp \u003d courseAttributes.getDeletedAt().toEpochMilli();"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" this.isMigrated \u003d false;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" public CourseData(Course course) {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" this.courseId \u003d course.getId();"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.courseName \u003d course.getName();"},{"lineNumber":40,"author":{"gitId":"-"},"content":" this.timeZone \u003d course.getTimeZone();"},{"lineNumber":41,"author":{"gitId":"-"},"content":" this.institute \u003d course.getInstitute();"},{"lineNumber":42,"author":{"gitId":"-"},"content":" this.creationTimestamp \u003d course.getCreatedAt().toEpochMilli();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" if (course.getDeletedAt() !\u003d null) {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" this.deletionTimestamp \u003d course.getDeletedAt().toEpochMilli();"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" this.isMigrated \u003d true;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" }"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" public String getCourseId() {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" return courseId;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" }"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" public String getCourseName() {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" return courseName;"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" public String getInstitute() {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" return institute;"},{"lineNumber":59,"author":{"gitId":"-"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" public String getTimeZone() {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" return timeZone;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" public long getCreationTimestamp() {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" return creationTimestamp;"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" public long getDeletionTimestamp() {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" return deletionTimestamp;"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" public Boolean getIsMigrated() {"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" return isMigrated;"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" public InstructorPermissionSet getPrivileges() {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" return privileges;"},{"lineNumber":79,"author":{"gitId":"-"},"content":" }"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" public void setCreationTimestamp(long creationTimestamp) {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" this.creationTimestamp \u003d creationTimestamp;"},{"lineNumber":83,"author":{"gitId":"-"},"content":" }"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" public void setDeletionTimestamp(long deletionTimestamp) {"},{"lineNumber":86,"author":{"gitId":"-"},"content":" this.deletionTimestamp \u003d deletionTimestamp;"},{"lineNumber":87,"author":{"gitId":"-"},"content":" }"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" public void setPrivileges(InstructorPermissionSet privileges) {"},{"lineNumber":90,"author":{"gitId":"-"},"content":" this.privileges \u003d privileges;"},{"lineNumber":91,"author":{"gitId":"-"},"content":" }"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":94,"author":{"gitId":"-"},"content":" * Hides some attributes to student."},{"lineNumber":95,"author":{"gitId":"-"},"content":" */"},{"lineNumber":96,"author":{"gitId":"-"},"content":" public void hideInformationForStudent() {"},{"lineNumber":97,"author":{"gitId":"-"},"content":" setDeletionTimestamp(0);"},{"lineNumber":98,"author":{"gitId":"-"},"content":" }"},{"lineNumber":99,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":8,"-":91}},{"path":"src/main/java/teammates/ui/output/FeedbackSessionData.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.output;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPermissionSet;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":21,"author":{"gitId":"-"},"content":" * The API output format of {@link FeedbackSessionAttributes}."},{"lineNumber":22,"author":{"gitId":"-"},"content":" */"},{"lineNumber":23,"author":{"gitId":"-"},"content":"public class FeedbackSessionData extends ApiOutput {"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":" @Nullable"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" private final UUID feedbackSessionId;"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" private final String courseId;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" private final String timeZone;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" private final String feedbackSessionName;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" private final String instructions;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private final Long submissionStartTimestamp;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" private final Long submissionEndTimestamp;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":36,"author":{"gitId":"-"},"content":" private Long submissionEndWithExtensionTimestamp;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":38,"author":{"gitId":"-"},"content":" private Long sessionVisibleFromTimestamp;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":40,"author":{"gitId":"-"},"content":" private Long resultVisibleFromTimestamp;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" private Long gracePeriod;"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" private SessionVisibleSetting sessionVisibleSetting;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":45,"author":{"gitId":"-"},"content":" private Long customSessionVisibleTimestamp;"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" private ResponseVisibleSetting responseVisibleSetting;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private Long customResponseVisibleTimestamp;"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" private FeedbackSessionSubmissionStatus submissionStatus;"},{"lineNumber":52,"author":{"gitId":"-"},"content":" private FeedbackSessionPublishStatus publishStatus;"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" private Boolean isClosingEmailEnabled;"},{"lineNumber":55,"author":{"gitId":"-"},"content":" private Boolean isPublishedEmailEnabled;"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" private long createdAtTimestamp;"},{"lineNumber":58,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":59,"author":{"gitId":"-"},"content":" private final Long deletedAtTimestamp;"},{"lineNumber":60,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":61,"author":{"gitId":"-"},"content":" private InstructorPermissionSet privileges;"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" private Map\u003cString, Long\u003e studentDeadlines;"},{"lineNumber":64,"author":{"gitId":"-"},"content":" private Map\u003cString, Long\u003e instructorDeadlines;"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" public FeedbackSessionData(FeedbackSessionAttributes feedbackSessionAttributes) {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" String timeZone \u003d feedbackSessionAttributes.getTimeZone();"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionId \u003d null;"},{"lineNumber":69,"author":{"gitId":"-"},"content":" this.courseId \u003d feedbackSessionAttributes.getCourseId();"},{"lineNumber":70,"author":{"gitId":"-"},"content":" this.timeZone \u003d timeZone;"},{"lineNumber":71,"author":{"gitId":"-"},"content":" this.feedbackSessionName \u003d feedbackSessionAttributes.getFeedbackSessionName();"},{"lineNumber":72,"author":{"gitId":"-"},"content":" this.instructions \u003d feedbackSessionAttributes.getInstructions();"},{"lineNumber":73,"author":{"gitId":"-"},"content":" this.submissionStartTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":74,"author":{"gitId":"-"},"content":" feedbackSessionAttributes.getStartTime(), timeZone, true).toEpochMilli();"},{"lineNumber":75,"author":{"gitId":"-"},"content":" this.submissionEndTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":76,"author":{"gitId":"-"},"content":" feedbackSessionAttributes.getEndTime(), timeZone, true).toEpochMilli();"},{"lineNumber":77,"author":{"gitId":"-"},"content":" this.submissionEndWithExtensionTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":78,"author":{"gitId":"-"},"content":" feedbackSessionAttributes.getDeadline(), timeZone, true).toEpochMilli();"},{"lineNumber":79,"author":{"gitId":"-"},"content":" this.gracePeriod \u003d feedbackSessionAttributes.getGracePeriodMinutes();"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" Instant sessionVisibleTime \u003d feedbackSessionAttributes.getSessionVisibleFromTime();"},{"lineNumber":82,"author":{"gitId":"-"},"content":" this.sessionVisibleFromTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":83,"author":{"gitId":"-"},"content":" sessionVisibleTime, timeZone, true).toEpochMilli();"},{"lineNumber":84,"author":{"gitId":"-"},"content":" if (sessionVisibleTime.equals(Const.TIME_REPRESENTS_FOLLOW_OPENING)) {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" this.sessionVisibleSetting \u003d SessionVisibleSetting.AT_OPEN;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" this.sessionVisibleSetting \u003d SessionVisibleSetting.CUSTOM;"},{"lineNumber":88,"author":{"gitId":"-"},"content":" this.customSessionVisibleTimestamp \u003d this.sessionVisibleFromTimestamp;"},{"lineNumber":89,"author":{"gitId":"-"},"content":" }"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" Instant responseVisibleTime \u003d feedbackSessionAttributes.getResultsVisibleFromTime();"},{"lineNumber":92,"author":{"gitId":"-"},"content":" this.resultVisibleFromTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":93,"author":{"gitId":"-"},"content":" responseVisibleTime, timeZone, true).toEpochMilli();"},{"lineNumber":94,"author":{"gitId":"-"},"content":" if (responseVisibleTime.equals(Const.TIME_REPRESENTS_FOLLOW_VISIBLE)) {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" this.responseVisibleSetting \u003d ResponseVisibleSetting.AT_VISIBLE;"},{"lineNumber":96,"author":{"gitId":"-"},"content":" } else if (responseVisibleTime.equals(Const.TIME_REPRESENTS_LATER)) {"},{"lineNumber":97,"author":{"gitId":"-"},"content":" this.responseVisibleSetting \u003d ResponseVisibleSetting.LATER;"},{"lineNumber":98,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" this.responseVisibleSetting \u003d ResponseVisibleSetting.CUSTOM;"},{"lineNumber":100,"author":{"gitId":"-"},"content":" this.customResponseVisibleTimestamp \u003d this.resultVisibleFromTimestamp;"},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" if (!feedbackSessionAttributes.isVisible()) {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.NOT_VISIBLE;"},{"lineNumber":105,"author":{"gitId":"-"},"content":" }"},{"lineNumber":106,"author":{"gitId":"-"},"content":" if (feedbackSessionAttributes.isVisible() \u0026\u0026 !feedbackSessionAttributes.isOpened()) {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.VISIBLE_NOT_OPEN;"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":" if (feedbackSessionAttributes.isOpened()) {"},{"lineNumber":110,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.OPEN;"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":" if (feedbackSessionAttributes.isInGracePeriod()) {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.GRACE_PERIOD;"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":" if (feedbackSessionAttributes.isClosed()) {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.CLOSED;"},{"lineNumber":117,"author":{"gitId":"-"},"content":" }"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" if (feedbackSessionAttributes.isPublished()) {"},{"lineNumber":120,"author":{"gitId":"-"},"content":" this.publishStatus \u003d FeedbackSessionPublishStatus.PUBLISHED;"},{"lineNumber":121,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" this.publishStatus \u003d FeedbackSessionPublishStatus.NOT_PUBLISHED;"},{"lineNumber":123,"author":{"gitId":"-"},"content":" }"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" this.isClosingEmailEnabled \u003d feedbackSessionAttributes.isClosingEmailEnabled();"},{"lineNumber":126,"author":{"gitId":"-"},"content":" this.isPublishedEmailEnabled \u003d feedbackSessionAttributes.isPublishedEmailEnabled();"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" this.createdAtTimestamp \u003d feedbackSessionAttributes.getCreatedTime().toEpochMilli();"},{"lineNumber":129,"author":{"gitId":"-"},"content":" if (feedbackSessionAttributes.getDeletedTime() \u003d\u003d null) {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" this.deletedAtTimestamp \u003d null;"},{"lineNumber":131,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" this.deletedAtTimestamp \u003d feedbackSessionAttributes.getDeletedTime().toEpochMilli();"},{"lineNumber":133,"author":{"gitId":"-"},"content":" }"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" String userEmail \u003d feedbackSessionAttributes.getUserEmail();"},{"lineNumber":136,"author":{"gitId":"-"},"content":" this.studentDeadlines \u003d feedbackSessionAttributes.getStudentDeadlines()"},{"lineNumber":137,"author":{"gitId":"-"},"content":" .entrySet()"},{"lineNumber":138,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":139,"author":{"gitId":"-"},"content":" .filter(entry -\u003e userEmail \u003d\u003d null || userEmail.equals(entry.getKey()))"},{"lineNumber":140,"author":{"gitId":"-"},"content":" .collect(Collectors.toMap(Map.Entry::getKey, entry -\u003e"},{"lineNumber":141,"author":{"gitId":"-"},"content":" TimeHelper.getMidnightAdjustedInstantBasedOnZone(entry.getValue(), timeZone, true)"},{"lineNumber":142,"author":{"gitId":"-"},"content":" .toEpochMilli()));"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" this.instructorDeadlines \u003d feedbackSessionAttributes.getInstructorDeadlines()"},{"lineNumber":145,"author":{"gitId":"-"},"content":" .entrySet()"},{"lineNumber":146,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":147,"author":{"gitId":"-"},"content":" .filter(entry -\u003e userEmail \u003d\u003d null || userEmail.equals(entry.getKey()))"},{"lineNumber":148,"author":{"gitId":"-"},"content":" .collect(Collectors.toMap(Map.Entry::getKey, entry -\u003e"},{"lineNumber":149,"author":{"gitId":"-"},"content":" TimeHelper.getMidnightAdjustedInstantBasedOnZone(entry.getValue(), timeZone, true)"},{"lineNumber":150,"author":{"gitId":"-"},"content":" .toEpochMilli()));"},{"lineNumber":151,"author":{"gitId":"-"},"content":" }"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":" public FeedbackSessionData(FeedbackSession feedbackSession) {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":155,"author":{"gitId":"-"},"content":" assert feedbackSession.getCourse() !\u003d null;"},{"lineNumber":156,"author":{"gitId":"-"},"content":" String timeZone \u003d feedbackSession.getCourse().getTimeZone();"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionId \u003d feedbackSession.getId();"},{"lineNumber":158,"author":{"gitId":"-"},"content":" this.courseId \u003d feedbackSession.getCourse().getId();"},{"lineNumber":159,"author":{"gitId":"-"},"content":" this.timeZone \u003d timeZone;"},{"lineNumber":160,"author":{"gitId":"-"},"content":" this.feedbackSessionName \u003d feedbackSession.getName();"},{"lineNumber":161,"author":{"gitId":"-"},"content":" this.instructions \u003d feedbackSession.getInstructions();"},{"lineNumber":162,"author":{"gitId":"-"},"content":" this.submissionStartTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":163,"author":{"gitId":"-"},"content":" feedbackSession.getStartTime(), timeZone, true).toEpochMilli();"},{"lineNumber":164,"author":{"gitId":"-"},"content":" this.submissionEndTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":165,"author":{"gitId":"-"},"content":" feedbackSession.getEndTime(), timeZone, true).toEpochMilli();"},{"lineNumber":166,"author":{"gitId":"-"},"content":" // If no deadline extension time is provided, then the end time with extension is assumed to be"},{"lineNumber":167,"author":{"gitId":"-"},"content":" // just the end time."},{"lineNumber":168,"author":{"gitId":"-"},"content":" this.submissionEndWithExtensionTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":169,"author":{"gitId":"-"},"content":" feedbackSession.getEndTime(), timeZone, true).toEpochMilli();"},{"lineNumber":170,"author":{"gitId":"-"},"content":" this.gracePeriod \u003d feedbackSession.getGracePeriod().toMinutes();"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" Instant sessionVisibleTime \u003d feedbackSession.getSessionVisibleFromTime();"},{"lineNumber":173,"author":{"gitId":"-"},"content":" this.sessionVisibleFromTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":174,"author":{"gitId":"-"},"content":" sessionVisibleTime, timeZone, true).toEpochMilli();"},{"lineNumber":175,"author":{"gitId":"-"},"content":" if (sessionVisibleTime.equals(Const.TIME_REPRESENTS_FOLLOW_OPENING)) {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" this.sessionVisibleSetting \u003d SessionVisibleSetting.AT_OPEN;"},{"lineNumber":177,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" this.sessionVisibleSetting \u003d SessionVisibleSetting.CUSTOM;"},{"lineNumber":179,"author":{"gitId":"-"},"content":" this.customSessionVisibleTimestamp \u003d this.sessionVisibleFromTimestamp;"},{"lineNumber":180,"author":{"gitId":"-"},"content":" }"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" Instant responseVisibleTime \u003d feedbackSession.getResultsVisibleFromTime();"},{"lineNumber":183,"author":{"gitId":"-"},"content":" this.resultVisibleFromTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":184,"author":{"gitId":"-"},"content":" responseVisibleTime, timeZone, true).toEpochMilli();"},{"lineNumber":185,"author":{"gitId":"-"},"content":" if (responseVisibleTime.equals(Const.TIME_REPRESENTS_FOLLOW_VISIBLE)) {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" this.responseVisibleSetting \u003d ResponseVisibleSetting.AT_VISIBLE;"},{"lineNumber":187,"author":{"gitId":"-"},"content":" } else if (responseVisibleTime.equals(Const.TIME_REPRESENTS_LATER)) {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" this.responseVisibleSetting \u003d ResponseVisibleSetting.LATER;"},{"lineNumber":189,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" this.responseVisibleSetting \u003d ResponseVisibleSetting.CUSTOM;"},{"lineNumber":191,"author":{"gitId":"-"},"content":" this.customResponseVisibleTimestamp \u003d this.resultVisibleFromTimestamp;"},{"lineNumber":192,"author":{"gitId":"-"},"content":" }"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"-"},"content":" if (!feedbackSession.isVisible()) {"},{"lineNumber":195,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.NOT_VISIBLE;"},{"lineNumber":196,"author":{"gitId":"-"},"content":" } else if (feedbackSession.isVisible() \u0026\u0026 !feedbackSession.isOpened()"},{"lineNumber":197,"author":{"gitId":"-"},"content":" \u0026\u0026 !feedbackSession.isClosed()) {"},{"lineNumber":198,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.VISIBLE_NOT_OPEN;"},{"lineNumber":199,"author":{"gitId":"-"},"content":" } else if (feedbackSession.isInGracePeriod()) {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.GRACE_PERIOD;"},{"lineNumber":201,"author":{"gitId":"-"},"content":" } else if (feedbackSession.isOpened()) {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.OPEN;"},{"lineNumber":203,"author":{"gitId":"-"},"content":" } else if (feedbackSession.isClosed()) {"},{"lineNumber":204,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.CLOSED;"},{"lineNumber":205,"author":{"gitId":"-"},"content":" }"},{"lineNumber":206,"author":{"gitId":"-"},"content":""},{"lineNumber":207,"author":{"gitId":"-"},"content":" if (feedbackSession.isPublished()) {"},{"lineNumber":208,"author":{"gitId":"-"},"content":" this.publishStatus \u003d FeedbackSessionPublishStatus.PUBLISHED;"},{"lineNumber":209,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" this.publishStatus \u003d FeedbackSessionPublishStatus.NOT_PUBLISHED;"},{"lineNumber":211,"author":{"gitId":"-"},"content":" }"},{"lineNumber":212,"author":{"gitId":"-"},"content":""},{"lineNumber":213,"author":{"gitId":"-"},"content":" this.isClosingEmailEnabled \u003d feedbackSession.isClosingEmailEnabled();"},{"lineNumber":214,"author":{"gitId":"-"},"content":" this.isPublishedEmailEnabled \u003d feedbackSession.isPublishedEmailEnabled();"},{"lineNumber":215,"author":{"gitId":"-"},"content":""},{"lineNumber":216,"author":{"gitId":"-"},"content":" this.createdAtTimestamp \u003d feedbackSession.getCreatedAt().toEpochMilli();"},{"lineNumber":217,"author":{"gitId":"-"},"content":" if (feedbackSession.getDeletedAt() \u003d\u003d null) {"},{"lineNumber":218,"author":{"gitId":"-"},"content":" this.deletedAtTimestamp \u003d null;"},{"lineNumber":219,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" this.deletedAtTimestamp \u003d feedbackSession.getDeletedAt().toEpochMilli();"},{"lineNumber":221,"author":{"gitId":"-"},"content":" }"},{"lineNumber":222,"author":{"gitId":"-"},"content":""},{"lineNumber":223,"author":{"gitId":"-"},"content":" this.studentDeadlines \u003d new HashMap\u003c\u003e();"},{"lineNumber":224,"author":{"gitId":"-"},"content":" this.instructorDeadlines \u003d new HashMap\u003c\u003e();"},{"lineNumber":225,"author":{"gitId":"-"},"content":""},{"lineNumber":226,"author":{"gitId":"-"},"content":" // place deadline extensions into appropriate student and instructor deadline maps"},{"lineNumber":227,"author":{"gitId":"-"},"content":" for (DeadlineExtension de : feedbackSession.getDeadlineExtensions()) {"},{"lineNumber":228,"author":{"gitId":"-"},"content":" if (de.getUser() instanceof Student) {"},{"lineNumber":229,"author":{"gitId":"-"},"content":" this.studentDeadlines.put(de.getUser().getEmail(),"},{"lineNumber":230,"author":{"gitId":"-"},"content":" TimeHelper.getMidnightAdjustedInstantBasedOnZone(de.getEndTime(), timeZone, true).toEpochMilli());"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":" if (de.getUser() instanceof Instructor) {"},{"lineNumber":233,"author":{"gitId":"-"},"content":" this.instructorDeadlines.put(de.getUser().getEmail(),"},{"lineNumber":234,"author":{"gitId":"-"},"content":" TimeHelper.getMidnightAdjustedInstantBasedOnZone(de.getEndTime(), timeZone, true).toEpochMilli());"},{"lineNumber":235,"author":{"gitId":"-"},"content":" }"},{"lineNumber":236,"author":{"gitId":"-"},"content":" }"},{"lineNumber":237,"author":{"gitId":"-"},"content":" }"},{"lineNumber":238,"author":{"gitId":"-"},"content":""},{"lineNumber":239,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":240,"author":{"gitId":"-"},"content":" * Constructs FeedbackSessionData for a given user deadline."},{"lineNumber":241,"author":{"gitId":"-"},"content":" */"},{"lineNumber":242,"author":{"gitId":"-"},"content":" public FeedbackSessionData(FeedbackSession feedbackSession, Instant extendedDeadline) {"},{"lineNumber":243,"author":{"gitId":"-"},"content":" this(feedbackSession);"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":" this.submissionEndWithExtensionTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":246,"author":{"gitId":"-"},"content":" extendedDeadline, timeZone, true).toEpochMilli();"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" if (!feedbackSession.isVisible()) {"},{"lineNumber":249,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.NOT_VISIBLE;"},{"lineNumber":250,"author":{"gitId":"-"},"content":" } else if (feedbackSession.isVisible() \u0026\u0026 !feedbackSession.isOpenedGivenExtendedDeadline(extendedDeadline)"},{"lineNumber":251,"author":{"gitId":"-"},"content":" \u0026\u0026 !feedbackSession.isClosedGivenExtendedDeadline(extendedDeadline)) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.VISIBLE_NOT_OPEN;"},{"lineNumber":253,"author":{"gitId":"-"},"content":" } else if (feedbackSession.isInGracePeriodGivenExtendedDeadline(extendedDeadline)) {"},{"lineNumber":254,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.GRACE_PERIOD;"},{"lineNumber":255,"author":{"gitId":"-"},"content":" } else if (feedbackSession.isOpenedGivenExtendedDeadline(extendedDeadline)) {"},{"lineNumber":256,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.OPEN;"},{"lineNumber":257,"author":{"gitId":"-"},"content":" } else if (feedbackSession.isClosedGivenExtendedDeadline(extendedDeadline)) {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.CLOSED;"},{"lineNumber":259,"author":{"gitId":"-"},"content":" }"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":""},{"lineNumber":262,"author":{"gitId":"dishenggg"},"content":" public UUID getFeedbackSessionId() {"},{"lineNumber":263,"author":{"gitId":"dishenggg"},"content":" return feedbackSessionId;"},{"lineNumber":264,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":265,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":266,"author":{"gitId":"-"},"content":" public String getCourseId() {"},{"lineNumber":267,"author":{"gitId":"-"},"content":" return courseId;"},{"lineNumber":268,"author":{"gitId":"-"},"content":" }"},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":" public String getTimeZone() {"},{"lineNumber":271,"author":{"gitId":"-"},"content":" return timeZone;"},{"lineNumber":272,"author":{"gitId":"-"},"content":" }"},{"lineNumber":273,"author":{"gitId":"-"},"content":""},{"lineNumber":274,"author":{"gitId":"-"},"content":" public String getFeedbackSessionName() {"},{"lineNumber":275,"author":{"gitId":"-"},"content":" return feedbackSessionName;"},{"lineNumber":276,"author":{"gitId":"-"},"content":" }"},{"lineNumber":277,"author":{"gitId":"-"},"content":""},{"lineNumber":278,"author":{"gitId":"-"},"content":" public String getInstructions() {"},{"lineNumber":279,"author":{"gitId":"-"},"content":" return instructions;"},{"lineNumber":280,"author":{"gitId":"-"},"content":" }"},{"lineNumber":281,"author":{"gitId":"-"},"content":""},{"lineNumber":282,"author":{"gitId":"-"},"content":" public long getSubmissionStartTimestamp() {"},{"lineNumber":283,"author":{"gitId":"-"},"content":" return submissionStartTimestamp;"},{"lineNumber":284,"author":{"gitId":"-"},"content":" }"},{"lineNumber":285,"author":{"gitId":"-"},"content":""},{"lineNumber":286,"author":{"gitId":"-"},"content":" public long getSubmissionEndTimestamp() {"},{"lineNumber":287,"author":{"gitId":"-"},"content":" return submissionEndTimestamp;"},{"lineNumber":288,"author":{"gitId":"-"},"content":" }"},{"lineNumber":289,"author":{"gitId":"-"},"content":""},{"lineNumber":290,"author":{"gitId":"-"},"content":" public long getSubmissionEndWithExtensionTimestamp() {"},{"lineNumber":291,"author":{"gitId":"-"},"content":" return submissionEndWithExtensionTimestamp;"},{"lineNumber":292,"author":{"gitId":"-"},"content":" }"},{"lineNumber":293,"author":{"gitId":"-"},"content":""},{"lineNumber":294,"author":{"gitId":"-"},"content":" public Long getSessionVisibleFromTimestamp() {"},{"lineNumber":295,"author":{"gitId":"-"},"content":" return sessionVisibleFromTimestamp;"},{"lineNumber":296,"author":{"gitId":"-"},"content":" }"},{"lineNumber":297,"author":{"gitId":"-"},"content":""},{"lineNumber":298,"author":{"gitId":"-"},"content":" public Long getResultVisibleFromTimestamp() {"},{"lineNumber":299,"author":{"gitId":"-"},"content":" return resultVisibleFromTimestamp;"},{"lineNumber":300,"author":{"gitId":"-"},"content":" }"},{"lineNumber":301,"author":{"gitId":"-"},"content":""},{"lineNumber":302,"author":{"gitId":"-"},"content":" public Long getGracePeriod() {"},{"lineNumber":303,"author":{"gitId":"-"},"content":" return gracePeriod;"},{"lineNumber":304,"author":{"gitId":"-"},"content":" }"},{"lineNumber":305,"author":{"gitId":"-"},"content":""},{"lineNumber":306,"author":{"gitId":"-"},"content":" public SessionVisibleSetting getSessionVisibleSetting() {"},{"lineNumber":307,"author":{"gitId":"-"},"content":" return sessionVisibleSetting;"},{"lineNumber":308,"author":{"gitId":"-"},"content":" }"},{"lineNumber":309,"author":{"gitId":"-"},"content":""},{"lineNumber":310,"author":{"gitId":"-"},"content":" public Long getCustomSessionVisibleTimestamp() {"},{"lineNumber":311,"author":{"gitId":"-"},"content":" return customSessionVisibleTimestamp;"},{"lineNumber":312,"author":{"gitId":"-"},"content":" }"},{"lineNumber":313,"author":{"gitId":"-"},"content":""},{"lineNumber":314,"author":{"gitId":"-"},"content":" public ResponseVisibleSetting getResponseVisibleSetting() {"},{"lineNumber":315,"author":{"gitId":"-"},"content":" return responseVisibleSetting;"},{"lineNumber":316,"author":{"gitId":"-"},"content":" }"},{"lineNumber":317,"author":{"gitId":"-"},"content":""},{"lineNumber":318,"author":{"gitId":"-"},"content":" public Long getCustomResponseVisibleTimestamp() {"},{"lineNumber":319,"author":{"gitId":"-"},"content":" return customResponseVisibleTimestamp;"},{"lineNumber":320,"author":{"gitId":"-"},"content":" }"},{"lineNumber":321,"author":{"gitId":"-"},"content":""},{"lineNumber":322,"author":{"gitId":"-"},"content":" public FeedbackSessionSubmissionStatus getSubmissionStatus() {"},{"lineNumber":323,"author":{"gitId":"-"},"content":" return submissionStatus;"},{"lineNumber":324,"author":{"gitId":"-"},"content":" }"},{"lineNumber":325,"author":{"gitId":"-"},"content":""},{"lineNumber":326,"author":{"gitId":"-"},"content":" public FeedbackSessionPublishStatus getPublishStatus() {"},{"lineNumber":327,"author":{"gitId":"-"},"content":" return publishStatus;"},{"lineNumber":328,"author":{"gitId":"-"},"content":" }"},{"lineNumber":329,"author":{"gitId":"-"},"content":""},{"lineNumber":330,"author":{"gitId":"-"},"content":" public Boolean getIsClosingEmailEnabled() {"},{"lineNumber":331,"author":{"gitId":"-"},"content":" return isClosingEmailEnabled;"},{"lineNumber":332,"author":{"gitId":"-"},"content":" }"},{"lineNumber":333,"author":{"gitId":"-"},"content":""},{"lineNumber":334,"author":{"gitId":"-"},"content":" public Boolean getIsPublishedEmailEnabled() {"},{"lineNumber":335,"author":{"gitId":"-"},"content":" return isPublishedEmailEnabled;"},{"lineNumber":336,"author":{"gitId":"-"},"content":" }"},{"lineNumber":337,"author":{"gitId":"-"},"content":""},{"lineNumber":338,"author":{"gitId":"-"},"content":" public Map\u003cString, Long\u003e getStudentDeadlines() {"},{"lineNumber":339,"author":{"gitId":"-"},"content":" return studentDeadlines;"},{"lineNumber":340,"author":{"gitId":"-"},"content":" }"},{"lineNumber":341,"author":{"gitId":"-"},"content":""},{"lineNumber":342,"author":{"gitId":"-"},"content":" public Map\u003cString, Long\u003e getInstructorDeadlines() {"},{"lineNumber":343,"author":{"gitId":"-"},"content":" return instructorDeadlines;"},{"lineNumber":344,"author":{"gitId":"-"},"content":" }"},{"lineNumber":345,"author":{"gitId":"-"},"content":""},{"lineNumber":346,"author":{"gitId":"-"},"content":" public void setSessionVisibleFromTimestamp(Long sessionVisibleFromTimestamp) {"},{"lineNumber":347,"author":{"gitId":"-"},"content":" this.sessionVisibleFromTimestamp \u003d sessionVisibleFromTimestamp;"},{"lineNumber":348,"author":{"gitId":"-"},"content":" }"},{"lineNumber":349,"author":{"gitId":"-"},"content":""},{"lineNumber":350,"author":{"gitId":"-"},"content":" public void setResultVisibleFromTimestamp(Long resultVisibleFromTimestamp) {"},{"lineNumber":351,"author":{"gitId":"-"},"content":" this.resultVisibleFromTimestamp \u003d resultVisibleFromTimestamp;"},{"lineNumber":352,"author":{"gitId":"-"},"content":" }"},{"lineNumber":353,"author":{"gitId":"-"},"content":""},{"lineNumber":354,"author":{"gitId":"-"},"content":" public void setGracePeriod(Long gracePeriod) {"},{"lineNumber":355,"author":{"gitId":"-"},"content":" this.gracePeriod \u003d gracePeriod;"},{"lineNumber":356,"author":{"gitId":"-"},"content":" }"},{"lineNumber":357,"author":{"gitId":"-"},"content":""},{"lineNumber":358,"author":{"gitId":"-"},"content":" public void setSessionVisibleSetting(SessionVisibleSetting sessionVisibleSetting) {"},{"lineNumber":359,"author":{"gitId":"-"},"content":" this.sessionVisibleSetting \u003d sessionVisibleSetting;"},{"lineNumber":360,"author":{"gitId":"-"},"content":" }"},{"lineNumber":361,"author":{"gitId":"-"},"content":""},{"lineNumber":362,"author":{"gitId":"-"},"content":" public void setCustomSessionVisibleTimestamp(Long customSessionVisibleTimestamp) {"},{"lineNumber":363,"author":{"gitId":"-"},"content":" this.customSessionVisibleTimestamp \u003d customSessionVisibleTimestamp;"},{"lineNumber":364,"author":{"gitId":"-"},"content":" }"},{"lineNumber":365,"author":{"gitId":"-"},"content":""},{"lineNumber":366,"author":{"gitId":"-"},"content":" public void setResponseVisibleSetting(ResponseVisibleSetting responseVisibleSetting) {"},{"lineNumber":367,"author":{"gitId":"-"},"content":" this.responseVisibleSetting \u003d responseVisibleSetting;"},{"lineNumber":368,"author":{"gitId":"-"},"content":" }"},{"lineNumber":369,"author":{"gitId":"-"},"content":""},{"lineNumber":370,"author":{"gitId":"-"},"content":" public void setCustomResponseVisibleTimestamp(Long customResponseVisibleTimestamp) {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" this.customResponseVisibleTimestamp \u003d customResponseVisibleTimestamp;"},{"lineNumber":372,"author":{"gitId":"-"},"content":" }"},{"lineNumber":373,"author":{"gitId":"-"},"content":""},{"lineNumber":374,"author":{"gitId":"-"},"content":" public void setPublishStatus(FeedbackSessionPublishStatus publishStatus) {"},{"lineNumber":375,"author":{"gitId":"-"},"content":" this.publishStatus \u003d publishStatus;"},{"lineNumber":376,"author":{"gitId":"-"},"content":" }"},{"lineNumber":377,"author":{"gitId":"-"},"content":""},{"lineNumber":378,"author":{"gitId":"-"},"content":" public void setClosingEmailEnabled(Boolean closingEmailEnabled) {"},{"lineNumber":379,"author":{"gitId":"-"},"content":" isClosingEmailEnabled \u003d closingEmailEnabled;"},{"lineNumber":380,"author":{"gitId":"-"},"content":" }"},{"lineNumber":381,"author":{"gitId":"-"},"content":""},{"lineNumber":382,"author":{"gitId":"-"},"content":" public void setPublishedEmailEnabled(Boolean publishedEmailEnabled) {"},{"lineNumber":383,"author":{"gitId":"-"},"content":" isPublishedEmailEnabled \u003d publishedEmailEnabled;"},{"lineNumber":384,"author":{"gitId":"-"},"content":" }"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"-"},"content":" public long getCreatedAtTimestamp() {"},{"lineNumber":387,"author":{"gitId":"-"},"content":" return createdAtTimestamp;"},{"lineNumber":388,"author":{"gitId":"-"},"content":" }"},{"lineNumber":389,"author":{"gitId":"-"},"content":""},{"lineNumber":390,"author":{"gitId":"-"},"content":" public void setCreatedAtTimestamp(long timestamp) {"},{"lineNumber":391,"author":{"gitId":"-"},"content":" createdAtTimestamp \u003d timestamp;"},{"lineNumber":392,"author":{"gitId":"-"},"content":" }"},{"lineNumber":393,"author":{"gitId":"-"},"content":""},{"lineNumber":394,"author":{"gitId":"-"},"content":" public Long getDeletedAtTimestamp() {"},{"lineNumber":395,"author":{"gitId":"-"},"content":" return deletedAtTimestamp;"},{"lineNumber":396,"author":{"gitId":"-"},"content":" }"},{"lineNumber":397,"author":{"gitId":"-"},"content":""},{"lineNumber":398,"author":{"gitId":"-"},"content":" public InstructorPermissionSet getPrivileges() {"},{"lineNumber":399,"author":{"gitId":"-"},"content":" return privileges;"},{"lineNumber":400,"author":{"gitId":"-"},"content":" }"},{"lineNumber":401,"author":{"gitId":"-"},"content":""},{"lineNumber":402,"author":{"gitId":"-"},"content":" public void setPrivileges(InstructorPermissionSet privileges) {"},{"lineNumber":403,"author":{"gitId":"-"},"content":" this.privileges \u003d privileges;"},{"lineNumber":404,"author":{"gitId":"-"},"content":" }"},{"lineNumber":405,"author":{"gitId":"-"},"content":""},{"lineNumber":406,"author":{"gitId":"-"},"content":" public void setStudentDeadlines(Map\u003cString, Long\u003e studentDeadlines) {"},{"lineNumber":407,"author":{"gitId":"-"},"content":" this.studentDeadlines \u003d studentDeadlines;"},{"lineNumber":408,"author":{"gitId":"-"},"content":" }"},{"lineNumber":409,"author":{"gitId":"-"},"content":""},{"lineNumber":410,"author":{"gitId":"-"},"content":" public void setInstructorDeadlines(Map\u003cString, Long\u003e instructorDeadlines) {"},{"lineNumber":411,"author":{"gitId":"-"},"content":" this.instructorDeadlines \u003d instructorDeadlines;"},{"lineNumber":412,"author":{"gitId":"-"},"content":" }"},{"lineNumber":413,"author":{"gitId":"-"},"content":""},{"lineNumber":414,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":415,"author":{"gitId":"-"},"content":" * Hides some attributes to student."},{"lineNumber":416,"author":{"gitId":"-"},"content":" */"},{"lineNumber":417,"author":{"gitId":"-"},"content":" public void hideInformationForStudent() {"},{"lineNumber":418,"author":{"gitId":"-"},"content":" hideInformationForStudentAndInstructor();"},{"lineNumber":419,"author":{"gitId":"-"},"content":" hideSessionVisibilityTimestamps();"},{"lineNumber":420,"author":{"gitId":"-"},"content":" instructorDeadlines.clear();"},{"lineNumber":421,"author":{"gitId":"-"},"content":" }"},{"lineNumber":422,"author":{"gitId":"-"},"content":""},{"lineNumber":423,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":424,"author":{"gitId":"-"},"content":" * Hides some attributes to student."},{"lineNumber":425,"author":{"gitId":"-"},"content":" */"},{"lineNumber":426,"author":{"gitId":"-"},"content":" public void hideInformationForStudent(String studentEmail) {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" hideInformationForStudentAndInstructor();"},{"lineNumber":428,"author":{"gitId":"-"},"content":" hideSessionVisibilityTimestamps();"},{"lineNumber":429,"author":{"gitId":"-"},"content":" studentDeadlines.keySet().removeIf(email -\u003e !(email.equals(studentEmail)));"},{"lineNumber":430,"author":{"gitId":"-"},"content":" instructorDeadlines.clear();"},{"lineNumber":431,"author":{"gitId":"-"},"content":" }"},{"lineNumber":432,"author":{"gitId":"-"},"content":""},{"lineNumber":433,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":434,"author":{"gitId":"-"},"content":" * Hides some attributes to instructor without appropriate privilege."},{"lineNumber":435,"author":{"gitId":"-"},"content":" */"},{"lineNumber":436,"author":{"gitId":"-"},"content":" public void hideInformationForInstructor() {"},{"lineNumber":437,"author":{"gitId":"-"},"content":" hideInformationForStudentAndInstructor();"},{"lineNumber":438,"author":{"gitId":"-"},"content":" studentDeadlines.clear();"},{"lineNumber":439,"author":{"gitId":"-"},"content":" }"},{"lineNumber":440,"author":{"gitId":"-"},"content":""},{"lineNumber":441,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":442,"author":{"gitId":"-"},"content":" * Hides some attributes to instructor without appropriate privilege."},{"lineNumber":443,"author":{"gitId":"-"},"content":" */"},{"lineNumber":444,"author":{"gitId":"-"},"content":" public void hideInformationForInstructor(String instructorEmail) {"},{"lineNumber":445,"author":{"gitId":"-"},"content":" hideInformationForStudentAndInstructor();"},{"lineNumber":446,"author":{"gitId":"-"},"content":" instructorDeadlines.keySet().removeIf(email -\u003e !(email.equals(instructorEmail)));"},{"lineNumber":447,"author":{"gitId":"-"},"content":" studentDeadlines.clear();"},{"lineNumber":448,"author":{"gitId":"-"},"content":" }"},{"lineNumber":449,"author":{"gitId":"-"},"content":""},{"lineNumber":450,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":451,"author":{"gitId":"-"},"content":" * Hides some attributes for instructor who is submitting feedback session."},{"lineNumber":452,"author":{"gitId":"-"},"content":" */"},{"lineNumber":453,"author":{"gitId":"-"},"content":" public void hideInformationForInstructorSubmission() {"},{"lineNumber":454,"author":{"gitId":"-"},"content":" hideInformationForInstructor();"},{"lineNumber":455,"author":{"gitId":"-"},"content":" hideSessionVisibilityTimestamps();"},{"lineNumber":456,"author":{"gitId":"-"},"content":" }"},{"lineNumber":457,"author":{"gitId":"-"},"content":""},{"lineNumber":458,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":459,"author":{"gitId":"-"},"content":" * Hides some attributes for instructor who is submitting feedback session."},{"lineNumber":460,"author":{"gitId":"-"},"content":" */"},{"lineNumber":461,"author":{"gitId":"-"},"content":" public void hideInformationForInstructorSubmission(String userEmail) {"},{"lineNumber":462,"author":{"gitId":"-"},"content":" hideInformationForInstructor(userEmail);"},{"lineNumber":463,"author":{"gitId":"-"},"content":" hideSessionVisibilityTimestamps();"},{"lineNumber":464,"author":{"gitId":"-"},"content":" }"},{"lineNumber":465,"author":{"gitId":"-"},"content":""},{"lineNumber":466,"author":{"gitId":"-"},"content":" private void hideSessionVisibilityTimestamps() {"},{"lineNumber":467,"author":{"gitId":"-"},"content":" setSessionVisibleFromTimestamp(null);"},{"lineNumber":468,"author":{"gitId":"-"},"content":" setResultVisibleFromTimestamp(null);"},{"lineNumber":469,"author":{"gitId":"-"},"content":" setSessionVisibleSetting(null);"},{"lineNumber":470,"author":{"gitId":"-"},"content":" setCustomSessionVisibleTimestamp(null);"},{"lineNumber":471,"author":{"gitId":"-"},"content":" setResponseVisibleSetting(null);"},{"lineNumber":472,"author":{"gitId":"-"},"content":" setCustomResponseVisibleTimestamp(null);"},{"lineNumber":473,"author":{"gitId":"-"},"content":" }"},{"lineNumber":474,"author":{"gitId":"-"},"content":""},{"lineNumber":475,"author":{"gitId":"-"},"content":" private void hideInformationForStudentAndInstructor() {"},{"lineNumber":476,"author":{"gitId":"-"},"content":" setClosingEmailEnabled(null);"},{"lineNumber":477,"author":{"gitId":"-"},"content":" setPublishedEmailEnabled(null);"},{"lineNumber":478,"author":{"gitId":"-"},"content":" setGracePeriod(null);"},{"lineNumber":479,"author":{"gitId":"-"},"content":" setCreatedAtTimestamp(0);"},{"lineNumber":480,"author":{"gitId":"-"},"content":" }"},{"lineNumber":481,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":11,"-":470}},{"path":"src/main/java/teammates/ui/output/FeedbackSessionLogData.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.output;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":15,"author":{"gitId":"-"},"content":" * The response log of a single feedback session."},{"lineNumber":16,"author":{"gitId":"-"},"content":" */"},{"lineNumber":17,"author":{"gitId":"-"},"content":"public class FeedbackSessionLogData {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" private final FeedbackSessionData feedbackSessionData;"},{"lineNumber":19,"author":{"gitId":"-"},"content":" private final List\u003cFeedbackSessionLogEntryData\u003e feedbackSessionLogEntries;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":" // Remove generic types after migration is done (i.e. can just use FeedbackSession, Student, FeedbackSessionLog)"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" public \u003cS, T, U\u003e FeedbackSessionLogData(S feedbackSession, List\u003cU\u003e logEntries,"},{"lineNumber":23,"author":{"gitId":"-"},"content":" Map\u003cString, T\u003e studentsMap) {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" if (feedbackSession instanceof FeedbackSessionAttributes) {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes fs \u003d (FeedbackSessionAttributes) feedbackSession;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" FeedbackSessionData fsData \u003d new FeedbackSessionData(fs);"},{"lineNumber":27,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogEntryData\u003e fsLogEntryDatas \u003d logEntries.stream()"},{"lineNumber":28,"author":{"gitId":"-"},"content":" .map(log -\u003e {"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" if (log instanceof FeedbackSessionLogEntry) {"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogEntry convertedLog \u003d (FeedbackSessionLogEntry) log;"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" T student \u003d studentsMap.get(convertedLog.getStudentEmail());"},{"lineNumber":32,"author":{"gitId":"-"},"content":" if (student instanceof StudentAttributes) {"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" return new FeedbackSessionLogEntryData(convertedLog, (StudentAttributes) student);"},{"lineNumber":34,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" throw new IllegalArgumentException(\"Invalid student type\");"},{"lineNumber":36,"author":{"gitId":"-"},"content":" }"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" throw new IllegalArgumentException(\"Invalid log type\");"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":" })"},{"lineNumber":41,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":42,"author":{"gitId":"-"},"content":" this.feedbackSessionData \u003d fsData;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" this.feedbackSessionLogEntries \u003d fsLogEntryDatas;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" } else if (feedbackSession instanceof FeedbackSession) {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d (FeedbackSession) feedbackSession;"},{"lineNumber":46,"author":{"gitId":"-"},"content":" FeedbackSessionData fsData \u003d new FeedbackSessionData(fs);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogEntryData\u003e fsLogEntryDatas \u003d logEntries.stream()"},{"lineNumber":48,"author":{"gitId":"-"},"content":" .map(log -\u003e {"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" if (log instanceof FeedbackSessionLog) {"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog convertedLog \u003d (FeedbackSessionLog) log;"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" T student \u003d studentsMap.get(convertedLog.getStudent().getEmail());"},{"lineNumber":52,"author":{"gitId":"-"},"content":" if (student instanceof Student) {"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" return new FeedbackSessionLogEntryData(convertedLog, (Student) student);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" throw new IllegalArgumentException(\"Invalid student type\");"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" throw new IllegalArgumentException(\"Invalid log type\");"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":" })"},{"lineNumber":61,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":62,"author":{"gitId":"-"},"content":" this.feedbackSessionData \u003d fsData;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" this.feedbackSessionLogEntries \u003d fsLogEntryDatas;"},{"lineNumber":64,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" throw new IllegalArgumentException(\"Invalid feedback session type\");"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" public FeedbackSessionData getFeedbackSessionData() {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" return feedbackSessionData;"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":74,"author":{"gitId":"-"},"content":" * Returns all feedback session log entries."},{"lineNumber":75,"author":{"gitId":"-"},"content":" */"},{"lineNumber":76,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSessionLogEntryData\u003e getFeedbackSessionLogEntries() {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" return feedbackSessionLogEntries;"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }"},{"lineNumber":79,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":17,"-":62}},{"path":"src/main/java/teammates/ui/output/FeedbackSessionLogEntryData.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.output;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":10,"author":{"gitId":"-"},"content":" * The session log of a student for a single feedback session."},{"lineNumber":11,"author":{"gitId":"-"},"content":" */"},{"lineNumber":12,"author":{"gitId":"-"},"content":"public class FeedbackSessionLogEntryData {"},{"lineNumber":13,"author":{"gitId":"-"},"content":" private final StudentData studentData;"},{"lineNumber":14,"author":{"gitId":"-"},"content":" private final FeedbackSessionLogType feedbackSessionLogType;"},{"lineNumber":15,"author":{"gitId":"-"},"content":" private final long timestamp;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":" public FeedbackSessionLogEntryData(FeedbackSessionLogEntry logEntry, StudentAttributes student) {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" StudentData studentData \u003d new StudentData(student);"},{"lineNumber":19,"author":{"gitId":"-"},"content":" FeedbackSessionLogType logType \u003d FeedbackSessionLogType.valueOfLabel(logEntry.getFeedbackSessionLogType());"},{"lineNumber":20,"author":{"gitId":"-"},"content":" long timestamp \u003d logEntry.getTimestamp();"},{"lineNumber":21,"author":{"gitId":"-"},"content":" this.studentData \u003d studentData;"},{"lineNumber":22,"author":{"gitId":"-"},"content":" this.feedbackSessionLogType \u003d logType;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" this.timestamp \u003d timestamp;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" }"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" public FeedbackSessionLogEntryData(FeedbackSessionLog logEntry, Student student) {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" StudentData studentData \u003d new StudentData(student);"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType logType \u003d logEntry.getFeedbackSessionLogType();"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" long timestamp \u003d logEntry.getTimestamp().toEpochMilli();"},{"lineNumber":30,"author":{"gitId":"-"},"content":" this.studentData \u003d studentData;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" this.feedbackSessionLogType \u003d logType;"},{"lineNumber":32,"author":{"gitId":"-"},"content":" this.timestamp \u003d timestamp;"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" public StudentData getStudentData() {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" return studentData;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" }"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" public FeedbackSessionLogType getFeedbackSessionLogType() {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" return feedbackSessionLogType;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" public long getTimestamp() {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return timestamp;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":4,"-":42}},{"path":"src/main/java/teammates/ui/output/FeedbackSessionLogsData.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.output;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":8,"author":{"gitId":"-"},"content":" * The API output format for logs on all feedback sessions in a course."},{"lineNumber":9,"author":{"gitId":"-"},"content":" */"},{"lineNumber":10,"author":{"gitId":"-"},"content":"public class FeedbackSessionLogsData extends ApiOutput {"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":" private final List\u003cFeedbackSessionLogData\u003e feedbackSessionLogs;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":" // Remove generic types after migration is done (i.e. can just use FeedbackSession and Student, FeedbackSessionLog)"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":" public \u003cS, T, U\u003e FeedbackSessionLogsData(Map\u003cString, List\u003cU\u003e\u003e groupedEntries,"},{"lineNumber":16,"author":{"gitId":"-"},"content":" Map\u003cString, S\u003e studentsMap, Map\u003cString, T\u003e sessionsMap) {"},{"lineNumber":17,"author":{"gitId":"-"},"content":" this.feedbackSessionLogs \u003d groupedEntries.entrySet().stream()"},{"lineNumber":18,"author":{"gitId":"-"},"content":" .map(entry -\u003e {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" T feedbackSession \u003d sessionsMap.get(entry.getKey());"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":" List\u003cU\u003e logEntries \u003d entry.getValue();"},{"lineNumber":21,"author":{"gitId":"-"},"content":" return new FeedbackSessionLogData(feedbackSession, logEntries, studentsMap);"},{"lineNumber":22,"author":{"gitId":"-"},"content":" })"},{"lineNumber":23,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":24,"author":{"gitId":"-"},"content":" }"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSessionLogData\u003e getFeedbackSessionLogs() {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" return feedbackSessionLogs;"},{"lineNumber":28,"author":{"gitId":"-"},"content":" }"},{"lineNumber":29,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":3,"-":26}},{"path":"src/main/java/teammates/ui/output/NotificationData.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.output;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import org.threeten.bp.Instant;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationStyle;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationTargetUser;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.NotificationAttributes;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * The API output format of a notification."},{"lineNumber":12,"author":{"gitId":"-"},"content":" */"},{"lineNumber":13,"author":{"gitId":"-"},"content":"public class NotificationData extends ApiOutput {"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":" private String notificationId;"},{"lineNumber":16,"author":{"gitId":"-"},"content":" private long startTimestamp;"},{"lineNumber":17,"author":{"gitId":"-"},"content":" private long endTimestamp;"},{"lineNumber":18,"author":{"gitId":"-"},"content":" private long createdAt;"},{"lineNumber":19,"author":{"gitId":"-"},"content":" private NotificationStyle style;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" private NotificationTargetUser targetUser;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" private String title;"},{"lineNumber":22,"author":{"gitId":"-"},"content":" private String message;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" private boolean shown;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" public NotificationData(NotificationAttributes notificationAttributes) {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" this.notificationId \u003d notificationAttributes.getNotificationId();"},{"lineNumber":27,"author":{"gitId":"-"},"content":" this.startTimestamp \u003d notificationAttributes.getStartTime().toEpochMilli();"},{"lineNumber":28,"author":{"gitId":"-"},"content":" this.endTimestamp \u003d notificationAttributes.getEndTime().toEpochMilli();"},{"lineNumber":29,"author":{"gitId":"-"},"content":" this.createdAt \u003d notificationAttributes.getCreatedAt().toEpochMilli();"},{"lineNumber":30,"author":{"gitId":"-"},"content":" this.style \u003d notificationAttributes.getStyle();"},{"lineNumber":31,"author":{"gitId":"-"},"content":" this.targetUser \u003d notificationAttributes.getTargetUser();"},{"lineNumber":32,"author":{"gitId":"-"},"content":" this.title \u003d notificationAttributes.getTitle();"},{"lineNumber":33,"author":{"gitId":"-"},"content":" this.message \u003d notificationAttributes.getMessage();"},{"lineNumber":34,"author":{"gitId":"-"},"content":" this.shown \u003d notificationAttributes.isShown();"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" public NotificationData(Notification notification) {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" this.notificationId \u003d notification.getId().toString();"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.startTimestamp \u003d notification.getStartTime().toEpochMilli();"},{"lineNumber":40,"author":{"gitId":"-"},"content":" this.endTimestamp \u003d notification.getEndTime().toEpochMilli();"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" this.createdAt \u003d notification.getCreatedAt() \u003d\u003d null"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" ? Instant.now().toEpochMilli() : notification.getCreatedAt().toEpochMilli();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" this.style \u003d notification.getStyle();"},{"lineNumber":44,"author":{"gitId":"-"},"content":" this.targetUser \u003d notification.getTargetUser();"},{"lineNumber":45,"author":{"gitId":"-"},"content":" this.title \u003d notification.getTitle();"},{"lineNumber":46,"author":{"gitId":"-"},"content":" this.message \u003d notification.getMessage();"},{"lineNumber":47,"author":{"gitId":"-"},"content":" this.shown \u003d notification.isShown();"},{"lineNumber":48,"author":{"gitId":"-"},"content":" }"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" public String getNotificationId() {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" return this.notificationId;"},{"lineNumber":52,"author":{"gitId":"-"},"content":" }"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" public long getStartTimestamp() {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" return this.startTimestamp;"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" public long getEndTimestamp() {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" return this.endTimestamp;"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" public long getCreatedAt() {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" return this.createdAt;"},{"lineNumber":64,"author":{"gitId":"-"},"content":" }"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" public NotificationStyle getStyle() {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" return this.style;"},{"lineNumber":68,"author":{"gitId":"-"},"content":" }"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" public NotificationTargetUser getTargetUser() {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" return this.targetUser;"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" public String getTitle() {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" return this.title;"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" public String getMessage() {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" return this.message;"},{"lineNumber":80,"author":{"gitId":"-"},"content":" }"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" public boolean isShown() {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" return this.shown;"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":4,"-":81}},{"path":"src/main/java/teammates/ui/output/SessionResultsData.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.output;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Collections;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.LinkedList;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.Queue;"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"import java.util.Set;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.CourseRoster;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SessionResultsBundle;"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.SqlCourseRoster;"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.SqlSessionResultsBundle;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseAttributes;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseCommentAttributes;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionDetails;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackResponseDetails;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.common.util.StringHelper;"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":36,"author":{"gitId":"-"},"content":" * API output format for session results, including statistics."},{"lineNumber":37,"author":{"gitId":"-"},"content":" */"},{"lineNumber":38,"author":{"gitId":"-"},"content":"public class SessionResultsData extends ApiOutput {"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" private static final String REGEX_ANONYMOUS_PARTICIPANT_HASH \u003d \"[0-9]{1,10}\";"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" final List\u003cQuestionOutput\u003e questions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" SessionResultsData() {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" // use factory method instead"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":49,"author":{"gitId":"-"},"content":" * Factory method to construct API output for instructor."},{"lineNumber":50,"author":{"gitId":"-"},"content":" */"},{"lineNumber":51,"author":{"gitId":"-"},"content":" public static SessionResultsData initForInstructor(SessionResultsBundle bundle) {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" SessionResultsData sessionResultsData \u003d new SessionResultsData();"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" Map\u003cString, List\u003cFeedbackResponseAttributes\u003e\u003e questionsWithResponses \u003d"},{"lineNumber":55,"author":{"gitId":"-"},"content":" bundle.getQuestionResponseMap();"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" questionsWithResponses.forEach((questionId, responses) -\u003e {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes question \u003d bundle.getQuestionsMap().get(questionId);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails questionDetails \u003d question.getQuestionDetailsCopy();"},{"lineNumber":60,"author":{"gitId":"-"},"content":" QuestionOutput qnOutput \u003d new QuestionOutput(question,"},{"lineNumber":61,"author":{"gitId":"-"},"content":" questionDetails.getQuestionResultStatisticsJson(question, null, bundle), false, false);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" // put normal responses"},{"lineNumber":63,"author":{"gitId":"-"},"content":" List\u003cResponseOutput\u003e allResponses \u003d buildResponsesForInstructor(responses, bundle, false);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" qnOutput.allResponses.addAll(allResponses);"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" // put missing responses"},{"lineNumber":67,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponseAttributes\u003e missingResponses \u003d bundle.getQuestionMissingResponseMap().get(questionId);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" qnOutput.allResponses.addAll(buildResponsesForInstructor(missingResponses, bundle, true));"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" sessionResultsData.questions.add(qnOutput);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" });"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" return sessionResultsData;"},{"lineNumber":74,"author":{"gitId":"-"},"content":" }"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":" * Factory method to construct API output for instructor."},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":" public static SessionResultsData initForInstructor(SqlSessionResultsBundle bundle) {"},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" SessionResultsData sessionResultsData \u003d new SessionResultsData();"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackQuestion, List\u003cFeedbackResponse\u003e\u003e questionsWithResponses \u003d"},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" bundle.getQuestionResponseMap();"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":" questionsWithResponses.forEach((question, responses) -\u003e {"},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":" FeedbackQuestionDetails questionDetails \u003d question.getQuestionDetailsCopy();"},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":" QuestionOutput qnOutput \u003d new QuestionOutput(question,"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" questionDetails.getQuestionResultStatisticsJson(question, null, bundle), false, false);"},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":" // put normal responses"},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" List\u003cResponseOutput\u003e allResponses \u003d buildResponsesForInstructor(responses, bundle, false);"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":" qnOutput.allResponses.addAll(allResponses);"},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":93,"author":{"gitId":"xenosf"},"content":" // put missing responses"},{"lineNumber":94,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e missingResponses \u003d bundle.getQuestionMissingResponseMap().get(question);"},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":" qnOutput.allResponses.addAll(buildResponsesForInstructor(missingResponses, bundle, true));"},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" sessionResultsData.questions.add(qnOutput);"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":100,"author":{"gitId":"xenosf"},"content":" return sessionResultsData;"},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":102,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":104,"author":{"gitId":"-"},"content":" * Factory method to construct API output for student."},{"lineNumber":105,"author":{"gitId":"-"},"content":" */"},{"lineNumber":106,"author":{"gitId":"-"},"content":" public static SessionResultsData initForStudent(SessionResultsBundle bundle, StudentAttributes student) {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" SessionResultsData sessionResultsData \u003d new SessionResultsData();"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" Map\u003cString, List\u003cFeedbackResponseAttributes\u003e\u003e questionsWithResponses \u003d"},{"lineNumber":110,"author":{"gitId":"-"},"content":" bundle.getQuestionResponseMap();"},{"lineNumber":111,"author":{"gitId":"-"},"content":" questionsWithResponses.forEach((questionId, responses) -\u003e {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes question \u003d bundle.getQuestionsMap().get(questionId);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails questionDetails \u003d question.getQuestionDetailsCopy();"},{"lineNumber":114,"author":{"gitId":"-"},"content":" // check if question has comments (on any responses) not visible for preview"},{"lineNumber":115,"author":{"gitId":"-"},"content":" boolean hasCommentNotVisibleForPreview \u003d bundle.getQuestionsWithCommentNotVisibleForPreview()"},{"lineNumber":116,"author":{"gitId":"-"},"content":" .contains(questionId);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" QuestionOutput qnOutput \u003d new QuestionOutput(question,"},{"lineNumber":118,"author":{"gitId":"-"},"content":" questionDetails.getQuestionResultStatisticsJson(question, student.getEmail(), bundle),"},{"lineNumber":119,"author":{"gitId":"-"},"content":" false, hasCommentNotVisibleForPreview);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" Map\u003cString, List\u003cResponseOutput\u003e\u003e otherResponsesMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" qnOutput.getFeedbackQuestion().hideInformationForStudent();"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" if (questionDetails.isIndividualResponsesShownToStudents()) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" for (FeedbackResponseAttributes response : responses) {"},{"lineNumber":126,"author":{"gitId":"-"},"content":" boolean isUserInstructor \u003d Const.USER_TEAM_FOR_INSTRUCTOR.equals(student.getTeam());"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" boolean isUserGiver \u003d student.getEmail().equals(response.getGiver())"},{"lineNumber":129,"author":{"gitId":"-"},"content":" \u0026\u0026 (isUserInstructor \u0026\u0026 question.getGiverType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":130,"author":{"gitId":"-"},"content":" || !isUserInstructor \u0026\u0026 question.getGiverType() !\u003d FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" boolean isUserRecipient \u003d student.getEmail().equals(response.getRecipient())"},{"lineNumber":132,"author":{"gitId":"-"},"content":" \u0026\u0026 (isUserInstructor \u0026\u0026 question.getRecipientType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":133,"author":{"gitId":"-"},"content":" || !isUserInstructor \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" ResponseOutput responseOutput \u003d buildSingleResponseForStudent(response, bundle, student);"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" if (isUserRecipient) {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" qnOutput.responsesToSelf.add(responseOutput);"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" if (isUserGiver) {"},{"lineNumber":141,"author":{"gitId":"-"},"content":" qnOutput.responsesFromSelf.add(responseOutput);"},{"lineNumber":142,"author":{"gitId":"-"},"content":" }"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" if (!isUserRecipient \u0026\u0026 !isUserGiver) {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" // we don\u0027t need care about the keys of the map here"},{"lineNumber":146,"author":{"gitId":"-"},"content":" // as only the values of the map will be used"},{"lineNumber":147,"author":{"gitId":"-"},"content":" otherResponsesMap.computeIfAbsent(response.getRecipient(), k -\u003e new ArrayList\u003c\u003e())"},{"lineNumber":148,"author":{"gitId":"-"},"content":" .add(responseOutput);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" }"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" qnOutput.allResponses.add(responseOutput);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" }"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":" qnOutput.otherResponses.addAll(otherResponsesMap.values());"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" sessionResultsData.questions.add(qnOutput);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" });"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" Map\u003cString, FeedbackQuestionAttributes\u003e questionsWithResponsesNotVisibleForPreview \u003d"},{"lineNumber":160,"author":{"gitId":"-"},"content":" bundle.getQuestionsNotVisibleForPreviewMap();"},{"lineNumber":161,"author":{"gitId":"-"},"content":" questionsWithResponsesNotVisibleForPreview.forEach((questionId, question) -\u003e {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" QuestionOutput qnOutput \u003d new QuestionOutput(question, \"\", true, false);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" sessionResultsData.questions.add(qnOutput);"},{"lineNumber":164,"author":{"gitId":"-"},"content":" });"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" return sessionResultsData;"},{"lineNumber":167,"author":{"gitId":"-"},"content":" }"},{"lineNumber":168,"author":{"gitId":"-"},"content":""},{"lineNumber":169,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":170,"author":{"gitId":"xenosf"},"content":" * Factory method to construct API output for student."},{"lineNumber":171,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":172,"author":{"gitId":"xenosf"},"content":" public static SessionResultsData initForStudent(SqlSessionResultsBundle bundle, Student student) {"},{"lineNumber":173,"author":{"gitId":"xenosf"},"content":" SessionResultsData sessionResultsData \u003d new SessionResultsData();"},{"lineNumber":174,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":175,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackQuestion, List\u003cFeedbackResponse\u003e\u003e questionsWithResponses \u003d"},{"lineNumber":176,"author":{"gitId":"xenosf"},"content":" bundle.getQuestionResponseMap();"},{"lineNumber":177,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":178,"author":{"gitId":"xenosf"},"content":" questionsWithResponses.forEach((question, responses) -\u003e {"},{"lineNumber":179,"author":{"gitId":"xenosf"},"content":" FeedbackQuestionDetails questionDetails \u003d question.getQuestionDetailsCopy();"},{"lineNumber":180,"author":{"gitId":"xenosf"},"content":" // check if question has comments (on any responses) not visible for preview"},{"lineNumber":181,"author":{"gitId":"xenosf"},"content":" boolean hasCommentNotVisibleForPreview \u003d bundle.getQuestionsWithCommentNotVisibleForPreviewSet()"},{"lineNumber":182,"author":{"gitId":"xenosf"},"content":" .contains(question);"},{"lineNumber":183,"author":{"gitId":"xenosf"},"content":" QuestionOutput qnOutput \u003d new QuestionOutput(question,"},{"lineNumber":184,"author":{"gitId":"xenosf"},"content":" questionDetails.getQuestionResultStatisticsJson(question, student.getEmail(), bundle),"},{"lineNumber":185,"author":{"gitId":"xenosf"},"content":" false, hasCommentNotVisibleForPreview);"},{"lineNumber":186,"author":{"gitId":"xenosf"},"content":" Map\u003cString, List\u003cResponseOutput\u003e\u003e otherResponsesMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":187,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":188,"author":{"gitId":"xenosf"},"content":" qnOutput.getFeedbackQuestion().hideInformationForStudent();"},{"lineNumber":189,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":190,"author":{"gitId":"xenosf"},"content":" if (questionDetails.isIndividualResponsesShownToStudents()) {"},{"lineNumber":191,"author":{"gitId":"xenosf"},"content":" for (FeedbackResponse response : responses) {"},{"lineNumber":192,"author":{"gitId":"xenosf"},"content":" boolean isUserInstructor \u003d Const.USER_TEAM_FOR_INSTRUCTOR.equals(student.getTeamName());"},{"lineNumber":193,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":194,"author":{"gitId":"xenosf"},"content":" boolean isUserGiver \u003d student.getEmail().equals(response.getGiver())"},{"lineNumber":195,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 (isUserInstructor \u0026\u0026 question.getGiverType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":196,"author":{"gitId":"xenosf"},"content":" || !isUserInstructor \u0026\u0026 question.getGiverType() !\u003d FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":197,"author":{"gitId":"xenosf"},"content":" boolean isUserRecipient \u003d student.getEmail().equals(response.getRecipient())"},{"lineNumber":198,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 (isUserInstructor \u0026\u0026 question.getRecipientType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":199,"author":{"gitId":"xenosf"},"content":" || !isUserInstructor \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":200,"author":{"gitId":"xenosf"},"content":" ResponseOutput responseOutput \u003d buildSingleResponseForStudent(response, bundle, student);"},{"lineNumber":201,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":202,"author":{"gitId":"xenosf"},"content":" if (isUserRecipient) {"},{"lineNumber":203,"author":{"gitId":"xenosf"},"content":" qnOutput.responsesToSelf.add(responseOutput);"},{"lineNumber":204,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":205,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":206,"author":{"gitId":"xenosf"},"content":" if (isUserGiver) {"},{"lineNumber":207,"author":{"gitId":"xenosf"},"content":" qnOutput.responsesFromSelf.add(responseOutput);"},{"lineNumber":208,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":209,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":210,"author":{"gitId":"xenosf"},"content":" if (!isUserRecipient \u0026\u0026 !isUserGiver) {"},{"lineNumber":211,"author":{"gitId":"xenosf"},"content":" // we don\u0027t need care about the keys of the map here"},{"lineNumber":212,"author":{"gitId":"xenosf"},"content":" // as only the values of the map will be used"},{"lineNumber":213,"author":{"gitId":"xenosf"},"content":" otherResponsesMap.computeIfAbsent(response.getRecipient(), k -\u003e new ArrayList\u003c\u003e())"},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" .add(responseOutput);"},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":217,"author":{"gitId":"xenosf"},"content":" qnOutput.allResponses.add(responseOutput);"},{"lineNumber":218,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":219,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":220,"author":{"gitId":"xenosf"},"content":" qnOutput.otherResponses.addAll(otherResponsesMap.values());"},{"lineNumber":221,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":222,"author":{"gitId":"xenosf"},"content":" sessionResultsData.questions.add(qnOutput);"},{"lineNumber":223,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":224,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":225,"author":{"gitId":"xenosf"},"content":" Set\u003cFeedbackQuestion\u003e questionsWithResponsesNotVisibleForPreview \u003d"},{"lineNumber":226,"author":{"gitId":"xenosf"},"content":" bundle.getQuestionsNotVisibleForPreviewSet();"},{"lineNumber":227,"author":{"gitId":"xenosf"},"content":" questionsWithResponsesNotVisibleForPreview.forEach(question -\u003e {"},{"lineNumber":228,"author":{"gitId":"xenosf"},"content":" QuestionOutput qnOutput \u003d new QuestionOutput(question, \"\", true, false);"},{"lineNumber":229,"author":{"gitId":"xenosf"},"content":" sessionResultsData.questions.add(qnOutput);"},{"lineNumber":230,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":231,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":232,"author":{"gitId":"xenosf"},"content":" return sessionResultsData;"},{"lineNumber":233,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":234,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":235,"author":{"gitId":"-"},"content":" private static ResponseOutput buildSingleResponseForStudent("},{"lineNumber":236,"author":{"gitId":"-"},"content":" FeedbackResponseAttributes response, SessionResultsBundle bundle, StudentAttributes student) {"},{"lineNumber":237,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes question \u003d bundle.getQuestionsMap().get(response.getFeedbackQuestionId());"},{"lineNumber":238,"author":{"gitId":"-"},"content":" boolean isUserInstructor \u003d Const.USER_TEAM_FOR_INSTRUCTOR.equals(student.getTeam());"},{"lineNumber":239,"author":{"gitId":"-"},"content":""},{"lineNumber":240,"author":{"gitId":"-"},"content":" // process giver"},{"lineNumber":241,"author":{"gitId":"-"},"content":" boolean isUserGiver \u003d student.getEmail().equals(response.getGiver())"},{"lineNumber":242,"author":{"gitId":"-"},"content":" \u0026\u0026 (isUserInstructor \u0026\u0026 question.getGiverType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":243,"author":{"gitId":"-"},"content":" || !isUserInstructor \u0026\u0026 question.getGiverType() !\u003d FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":244,"author":{"gitId":"-"},"content":" boolean isUserTeamGiver \u003d question.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":245,"author":{"gitId":"-"},"content":" \u0026\u0026 student.getTeam().equals(response.getGiver());"},{"lineNumber":246,"author":{"gitId":"-"},"content":" String giverName;"},{"lineNumber":247,"author":{"gitId":"-"},"content":" String giverTeam \u003d \"\";"},{"lineNumber":248,"author":{"gitId":"-"},"content":" if (isUserTeamGiver) {"},{"lineNumber":249,"author":{"gitId":"-"},"content":" giverName \u003d String.format(\"Your Team (%s)\", response.getGiver());"},{"lineNumber":250,"author":{"gitId":"-"},"content":" giverTeam \u003d response.getGiver();"},{"lineNumber":251,"author":{"gitId":"-"},"content":" } else if (isUserGiver) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" giverName \u003d \"You\";"},{"lineNumber":253,"author":{"gitId":"-"},"content":" giverTeam \u003d student.getTeam();"},{"lineNumber":254,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" // we don\u0027t want student to figure out who is who by using the hash"},{"lineNumber":256,"author":{"gitId":"-"},"content":" giverName \u003d removeAnonymousHash(getGiverNameOfResponse(response, bundle));"},{"lineNumber":257,"author":{"gitId":"-"},"content":" }"},{"lineNumber":258,"author":{"gitId":"-"},"content":""},{"lineNumber":259,"author":{"gitId":"-"},"content":" // process recipient"},{"lineNumber":260,"author":{"gitId":"-"},"content":" boolean isUserRecipient \u003d student.getEmail().equals(response.getRecipient())"},{"lineNumber":261,"author":{"gitId":"-"},"content":" \u0026\u0026 (isUserInstructor \u0026\u0026 question.getRecipientType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":262,"author":{"gitId":"-"},"content":" || !isUserInstructor \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":263,"author":{"gitId":"-"},"content":" boolean isUserTeamRecipient \u003d (question.getRecipientType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":264,"author":{"gitId":"-"},"content":" || question.getRecipientType() \u003d\u003d FeedbackParticipantType.TEAMS_IN_SAME_SECTION)"},{"lineNumber":265,"author":{"gitId":"-"},"content":" \u0026\u0026 student.getTeam().equals(response.getRecipient());"},{"lineNumber":266,"author":{"gitId":"-"},"content":" String recipientName;"},{"lineNumber":267,"author":{"gitId":"-"},"content":" String recipientTeam \u003d \"\";"},{"lineNumber":268,"author":{"gitId":"-"},"content":" if (isUserRecipient) {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" recipientName \u003d \"You\";"},{"lineNumber":270,"author":{"gitId":"-"},"content":" recipientTeam \u003d student.getTeam();"},{"lineNumber":271,"author":{"gitId":"-"},"content":" } else if (isUserTeamRecipient) {"},{"lineNumber":272,"author":{"gitId":"-"},"content":" recipientName \u003d String.format(\"Your Team (%s)\", response.getRecipient());"},{"lineNumber":273,"author":{"gitId":"-"},"content":" recipientTeam \u003d response.getRecipient();"},{"lineNumber":274,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":275,"author":{"gitId":"-"},"content":" // we don\u0027t want student to figure out who is who by using the hash"},{"lineNumber":276,"author":{"gitId":"-"},"content":" recipientName \u003d removeAnonymousHash(getRecipientNameOfResponse(response, bundle));"},{"lineNumber":277,"author":{"gitId":"-"},"content":" if (!recipientName.contains(Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT)) {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" recipientTeam \u003d bundle.getRoster().getInfoForIdentifier(response.getRecipient()).getTeamName();"},{"lineNumber":279,"author":{"gitId":"-"},"content":" }"},{"lineNumber":280,"author":{"gitId":"-"},"content":" }"},{"lineNumber":281,"author":{"gitId":"-"},"content":""},{"lineNumber":282,"author":{"gitId":"-"},"content":" // process comments"},{"lineNumber":283,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponseCommentAttributes\u003e feedbackResponseComments \u003d"},{"lineNumber":284,"author":{"gitId":"-"},"content":" bundle.getResponseCommentsMap().getOrDefault(response.getId(), Collections.emptyList());"},{"lineNumber":285,"author":{"gitId":"-"},"content":" Queue\u003cCommentOutput\u003e comments \u003d buildComments(feedbackResponseComments, bundle);"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"-"},"content":" return ResponseOutput.builder()"},{"lineNumber":288,"author":{"gitId":"-"},"content":" .withResponseId(response.getId())"},{"lineNumber":289,"author":{"gitId":"-"},"content":" .withGiver(giverName)"},{"lineNumber":290,"author":{"gitId":"-"},"content":" .withGiverTeam(giverTeam)"},{"lineNumber":291,"author":{"gitId":"-"},"content":" .withGiverEmail(null)"},{"lineNumber":292,"author":{"gitId":"-"},"content":" .withRelatedGiverEmail(null)"},{"lineNumber":293,"author":{"gitId":"xenosf"},"content":" .withGiverSectionName(response.getGiverSection())"},{"lineNumber":294,"author":{"gitId":"xenosf"},"content":" .withRecipient(recipientName)"},{"lineNumber":295,"author":{"gitId":"xenosf"},"content":" .withRecipientTeam(recipientTeam)"},{"lineNumber":296,"author":{"gitId":"xenosf"},"content":" .withRecipientEmail(null)"},{"lineNumber":297,"author":{"gitId":"xenosf"},"content":" .withRecipientSectionName(response.getRecipientSection())"},{"lineNumber":298,"author":{"gitId":"xenosf"},"content":" .withResponseDetails(response.getResponseDetailsCopy())"},{"lineNumber":299,"author":{"gitId":"xenosf"},"content":" .withParticipantComment(comments.poll())"},{"lineNumber":300,"author":{"gitId":"xenosf"},"content":" .withInstructorComments(new ArrayList\u003c\u003e(comments))"},{"lineNumber":301,"author":{"gitId":"xenosf"},"content":" .build();"},{"lineNumber":302,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":303,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":304,"author":{"gitId":"xenosf"},"content":" private static ResponseOutput buildSingleResponseForStudent("},{"lineNumber":305,"author":{"gitId":"xenosf"},"content":" FeedbackResponse response, SqlSessionResultsBundle bundle, Student student) {"},{"lineNumber":306,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question \u003d response.getFeedbackQuestion();"},{"lineNumber":307,"author":{"gitId":"xenosf"},"content":" boolean isUserInstructor \u003d Const.USER_TEAM_FOR_INSTRUCTOR.equals(student.getTeamName());"},{"lineNumber":308,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":309,"author":{"gitId":"xenosf"},"content":" // process giver"},{"lineNumber":310,"author":{"gitId":"xenosf"},"content":" boolean isUserGiver \u003d student.getEmail().equals(response.getGiver())"},{"lineNumber":311,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 (isUserInstructor \u0026\u0026 question.getGiverType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":312,"author":{"gitId":"xenosf"},"content":" || !isUserInstructor \u0026\u0026 question.getGiverType() !\u003d FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":313,"author":{"gitId":"xenosf"},"content":" boolean isUserTeamGiver \u003d question.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":314,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 student.getTeamName().equals(response.getGiver());"},{"lineNumber":315,"author":{"gitId":"xenosf"},"content":" String giverName;"},{"lineNumber":316,"author":{"gitId":"xenosf"},"content":" String giverTeam \u003d \"\";"},{"lineNumber":317,"author":{"gitId":"xenosf"},"content":" if (isUserTeamGiver) {"},{"lineNumber":318,"author":{"gitId":"xenosf"},"content":" giverName \u003d String.format(\"Your Team (%s)\", response.getGiver());"},{"lineNumber":319,"author":{"gitId":"xenosf"},"content":" giverTeam \u003d response.getGiver();"},{"lineNumber":320,"author":{"gitId":"xenosf"},"content":" } else if (isUserGiver) {"},{"lineNumber":321,"author":{"gitId":"xenosf"},"content":" giverName \u003d \"You\";"},{"lineNumber":322,"author":{"gitId":"xenosf"},"content":" giverTeam \u003d student.getTeamName();"},{"lineNumber":323,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":324,"author":{"gitId":"xenosf"},"content":" // we don\u0027t want student to figure out who is who by using the hash"},{"lineNumber":325,"author":{"gitId":"xenosf"},"content":" giverName \u003d removeAnonymousHash(getGiverNameOfResponse(response, bundle));"},{"lineNumber":326,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":327,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":328,"author":{"gitId":"xenosf"},"content":" // process recipient"},{"lineNumber":329,"author":{"gitId":"xenosf"},"content":" boolean isUserRecipient \u003d student.getEmail().equals(response.getRecipient())"},{"lineNumber":330,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 (isUserInstructor \u0026\u0026 question.getRecipientType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":331,"author":{"gitId":"xenosf"},"content":" || !isUserInstructor \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":332,"author":{"gitId":"xenosf"},"content":" boolean isUserTeamRecipient \u003d (question.getRecipientType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":333,"author":{"gitId":"xenosf"},"content":" || question.getRecipientType() \u003d\u003d FeedbackParticipantType.TEAMS_IN_SAME_SECTION)"},{"lineNumber":334,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 student.getTeamName().equals(response.getRecipient());"},{"lineNumber":335,"author":{"gitId":"xenosf"},"content":" String recipientName;"},{"lineNumber":336,"author":{"gitId":"xenosf"},"content":" String recipientTeam \u003d \"\";"},{"lineNumber":337,"author":{"gitId":"xenosf"},"content":" if (isUserRecipient) {"},{"lineNumber":338,"author":{"gitId":"xenosf"},"content":" recipientName \u003d \"You\";"},{"lineNumber":339,"author":{"gitId":"xenosf"},"content":" recipientTeam \u003d student.getTeamName();"},{"lineNumber":340,"author":{"gitId":"xenosf"},"content":" } else if (isUserTeamRecipient) {"},{"lineNumber":341,"author":{"gitId":"xenosf"},"content":" recipientName \u003d String.format(\"Your Team (%s)\", response.getRecipient());"},{"lineNumber":342,"author":{"gitId":"xenosf"},"content":" recipientTeam \u003d response.getRecipient();"},{"lineNumber":343,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":344,"author":{"gitId":"xenosf"},"content":" // we don\u0027t want student to figure out who is who by using the hash"},{"lineNumber":345,"author":{"gitId":"xenosf"},"content":" recipientName \u003d removeAnonymousHash(getRecipientNameOfResponse(response, bundle));"},{"lineNumber":346,"author":{"gitId":"xenosf"},"content":" if (!recipientName.contains(Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT)) {"},{"lineNumber":347,"author":{"gitId":"xenosf"},"content":" recipientTeam \u003d bundle.getRoster().getInfoForIdentifier(response.getRecipient()).getTeamName();"},{"lineNumber":348,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":349,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":350,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":351,"author":{"gitId":"xenosf"},"content":" // process comments"},{"lineNumber":352,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e feedbackResponseComments \u003d"},{"lineNumber":353,"author":{"gitId":"xenosf"},"content":" bundle.getResponseCommentsMap().getOrDefault(response, Collections.emptyList());"},{"lineNumber":354,"author":{"gitId":"xenosf"},"content":" Queue\u003cCommentOutput\u003e comments \u003d buildComments(feedbackResponseComments, bundle);"},{"lineNumber":355,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":356,"author":{"gitId":"xenosf"},"content":" return ResponseOutput.builder()"},{"lineNumber":357,"author":{"gitId":"xenosf"},"content":" .withResponse(response)"},{"lineNumber":358,"author":{"gitId":"xenosf"},"content":" .withGiver(giverName)"},{"lineNumber":359,"author":{"gitId":"xenosf"},"content":" .withGiverTeam(giverTeam)"},{"lineNumber":360,"author":{"gitId":"xenosf"},"content":" .withGiverEmail(null)"},{"lineNumber":361,"author":{"gitId":"xenosf"},"content":" .withRelatedGiverEmail(null)"},{"lineNumber":362,"author":{"gitId":"-"},"content":" .withGiverSection(response.getGiverSection())"},{"lineNumber":363,"author":{"gitId":"-"},"content":" .withRecipient(recipientName)"},{"lineNumber":364,"author":{"gitId":"-"},"content":" .withRecipientTeam(recipientTeam)"},{"lineNumber":365,"author":{"gitId":"-"},"content":" .withRecipientEmail(null)"},{"lineNumber":366,"author":{"gitId":"-"},"content":" .withRecipientSection(response.getRecipientSection())"},{"lineNumber":367,"author":{"gitId":"xenosf"},"content":" .withResponseDetails(response.getFeedbackResponseDetailsCopy())"},{"lineNumber":368,"author":{"gitId":"-"},"content":" .withParticipantComment(comments.poll())"},{"lineNumber":369,"author":{"gitId":"-"},"content":" .withInstructorComments(new ArrayList\u003c\u003e(comments))"},{"lineNumber":370,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":371,"author":{"gitId":"-"},"content":" }"},{"lineNumber":372,"author":{"gitId":"-"},"content":""},{"lineNumber":373,"author":{"gitId":"-"},"content":" private static String removeAnonymousHash(String identifier) {"},{"lineNumber":374,"author":{"gitId":"-"},"content":" return identifier.replaceAll(Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT + \" (student|instructor|team) \""},{"lineNumber":375,"author":{"gitId":"-"},"content":" + REGEX_ANONYMOUS_PARTICIPANT_HASH, Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT + \" $1\");"},{"lineNumber":376,"author":{"gitId":"-"},"content":" }"},{"lineNumber":377,"author":{"gitId":"-"},"content":""},{"lineNumber":378,"author":{"gitId":"-"},"content":" private static List\u003cResponseOutput\u003e buildResponsesForInstructor("},{"lineNumber":379,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponseAttributes\u003e responses, SessionResultsBundle bundle, boolean areMissingResponses) {"},{"lineNumber":380,"author":{"gitId":"-"},"content":" List\u003cResponseOutput\u003e output \u003d new ArrayList\u003c\u003e();"},{"lineNumber":381,"author":{"gitId":"-"},"content":""},{"lineNumber":382,"author":{"gitId":"-"},"content":" for (FeedbackResponseAttributes response : responses) {"},{"lineNumber":383,"author":{"gitId":"-"},"content":" output.add(buildSingleResponseForInstructor(response, bundle, areMissingResponses));"},{"lineNumber":384,"author":{"gitId":"-"},"content":" }"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"-"},"content":" return output;"},{"lineNumber":387,"author":{"gitId":"-"},"content":" }"},{"lineNumber":388,"author":{"gitId":"-"},"content":""},{"lineNumber":389,"author":{"gitId":"xenosf"},"content":" private static List\u003cResponseOutput\u003e buildResponsesForInstructor("},{"lineNumber":390,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e responses, SqlSessionResultsBundle bundle, boolean areMissingResponses) {"},{"lineNumber":391,"author":{"gitId":"xenosf"},"content":" List\u003cResponseOutput\u003e output \u003d new ArrayList\u003c\u003e();"},{"lineNumber":392,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":393,"author":{"gitId":"xenosf"},"content":" for (FeedbackResponse response : responses) {"},{"lineNumber":394,"author":{"gitId":"xenosf"},"content":" output.add(buildSingleResponseForInstructor(response, bundle, areMissingResponses));"},{"lineNumber":395,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":396,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":397,"author":{"gitId":"xenosf"},"content":" return output;"},{"lineNumber":398,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":399,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":400,"author":{"gitId":"-"},"content":" private static ResponseOutput buildSingleResponseForInstructor("},{"lineNumber":401,"author":{"gitId":"-"},"content":" FeedbackResponseAttributes response, SessionResultsBundle bundle, boolean isMissingResponse) {"},{"lineNumber":402,"author":{"gitId":"-"},"content":" // process giver"},{"lineNumber":403,"author":{"gitId":"-"},"content":" String giverEmail \u003d null;"},{"lineNumber":404,"author":{"gitId":"-"},"content":" String relatedGiverEmail \u003d null;"},{"lineNumber":405,"author":{"gitId":"-"},"content":" if (bundle.isResponseGiverVisible(response)) {"},{"lineNumber":406,"author":{"gitId":"-"},"content":" giverEmail \u003d response.getGiver();"},{"lineNumber":407,"author":{"gitId":"-"},"content":" relatedGiverEmail \u003d response.getGiver();"},{"lineNumber":408,"author":{"gitId":"-"},"content":""},{"lineNumber":409,"author":{"gitId":"-"},"content":" if (bundle.getRoster().isTeamInCourse(giverEmail)) {"},{"lineNumber":410,"author":{"gitId":"-"},"content":" // remove recipient email as it is a team name"},{"lineNumber":411,"author":{"gitId":"-"},"content":" relatedGiverEmail \u003d"},{"lineNumber":412,"author":{"gitId":"-"},"content":" bundle.getRoster().getTeamToMembersTable().get(giverEmail).iterator().next().getEmail();"},{"lineNumber":413,"author":{"gitId":"-"},"content":" giverEmail \u003d null;"},{"lineNumber":414,"author":{"gitId":"-"},"content":" }"},{"lineNumber":415,"author":{"gitId":"-"},"content":" }"},{"lineNumber":416,"author":{"gitId":"-"},"content":" String giverName \u003d getGiverNameOfResponse(response, bundle);"},{"lineNumber":417,"author":{"gitId":"-"},"content":" String giverTeam \u003d bundle.getRoster().getInfoForIdentifier(response.getGiver()).getTeamName();"},{"lineNumber":418,"author":{"gitId":"-"},"content":" String giverSection \u003d response.getGiverSection();"},{"lineNumber":419,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes question \u003d bundle.getQuestionsMap().get(response.getFeedbackQuestionId());"},{"lineNumber":420,"author":{"gitId":"-"},"content":" if (question.getGiverType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS) {"},{"lineNumber":421,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d bundle.getRoster().getInstructorForEmail(response.getGiver());"},{"lineNumber":422,"author":{"gitId":"-"},"content":" giverName \u003d instructor.getName();"},{"lineNumber":423,"author":{"gitId":"-"},"content":" giverTeam \u003d Const.USER_TEAM_FOR_INSTRUCTOR;"},{"lineNumber":424,"author":{"gitId":"-"},"content":" giverSection \u003d Const.DEFAULT_SECTION;"},{"lineNumber":425,"author":{"gitId":"-"},"content":" }"},{"lineNumber":426,"author":{"gitId":"-"},"content":""},{"lineNumber":427,"author":{"gitId":"-"},"content":" // process recipient"},{"lineNumber":428,"author":{"gitId":"-"},"content":" String recipientEmail \u003d null;"},{"lineNumber":429,"author":{"gitId":"-"},"content":" String recipientName \u003d getRecipientNameOfResponse(response, bundle);"},{"lineNumber":430,"author":{"gitId":"-"},"content":" String recipientTeam \u003d"},{"lineNumber":431,"author":{"gitId":"-"},"content":" bundle.getRoster().getInfoForIdentifier(response.getRecipient()).getTeamName();"},{"lineNumber":432,"author":{"gitId":"-"},"content":" String recipientSection \u003d response.getRecipientSection();"},{"lineNumber":433,"author":{"gitId":"-"},"content":" if (question.getRecipientType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS) {"},{"lineNumber":434,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d bundle.getRoster().getInstructorForEmail(response.getRecipient());"},{"lineNumber":435,"author":{"gitId":"-"},"content":" recipientName \u003d instructor.getName();"},{"lineNumber":436,"author":{"gitId":"-"},"content":" recipientTeam \u003d Const.USER_TEAM_FOR_INSTRUCTOR;"},{"lineNumber":437,"author":{"gitId":"-"},"content":" recipientSection \u003d Const.DEFAULT_SECTION;"},{"lineNumber":438,"author":{"gitId":"-"},"content":" }"},{"lineNumber":439,"author":{"gitId":"-"},"content":" if (bundle.isResponseRecipientVisible(response)) {"},{"lineNumber":440,"author":{"gitId":"-"},"content":" recipientEmail \u003d response.getRecipient();"},{"lineNumber":441,"author":{"gitId":"-"},"content":""},{"lineNumber":442,"author":{"gitId":"-"},"content":" if (bundle.getRoster().isTeamInCourse(recipientEmail)) {"},{"lineNumber":443,"author":{"gitId":"-"},"content":" // remove recipient email as it is a team name"},{"lineNumber":444,"author":{"gitId":"-"},"content":" recipientEmail \u003d null;"},{"lineNumber":445,"author":{"gitId":"-"},"content":" } else if (Const.GENERAL_QUESTION.equals(recipientEmail)) {"},{"lineNumber":446,"author":{"gitId":"-"},"content":" // general recipient does not have email"},{"lineNumber":447,"author":{"gitId":"-"},"content":" recipientEmail \u003d null;"},{"lineNumber":448,"author":{"gitId":"-"},"content":" }"},{"lineNumber":449,"author":{"gitId":"-"},"content":" }"},{"lineNumber":450,"author":{"gitId":"-"},"content":""},{"lineNumber":451,"author":{"gitId":"-"},"content":" // process comments"},{"lineNumber":452,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponseCommentAttributes\u003e feedbackResponseComments \u003d"},{"lineNumber":453,"author":{"gitId":"-"},"content":" bundle.getResponseCommentsMap().getOrDefault(response.getId(), Collections.emptyList());"},{"lineNumber":454,"author":{"gitId":"-"},"content":" Queue\u003cCommentOutput\u003e comments \u003d buildComments(feedbackResponseComments, bundle);"},{"lineNumber":455,"author":{"gitId":"-"},"content":""},{"lineNumber":456,"author":{"gitId":"-"},"content":" return ResponseOutput.builder()"},{"lineNumber":457,"author":{"gitId":"-"},"content":" .withIsMissingResponse(isMissingResponse)"},{"lineNumber":458,"author":{"gitId":"-"},"content":" .withResponseId(response.getId())"},{"lineNumber":459,"author":{"gitId":"-"},"content":" .withGiver(giverName)"},{"lineNumber":460,"author":{"gitId":"-"},"content":" .withGiverTeam(giverTeam)"},{"lineNumber":461,"author":{"gitId":"-"},"content":" .withGiverEmail(giverEmail)"},{"lineNumber":462,"author":{"gitId":"-"},"content":" .withRelatedGiverEmail(relatedGiverEmail)"},{"lineNumber":463,"author":{"gitId":"xenosf"},"content":" .withGiverSectionName(giverSection)"},{"lineNumber":464,"author":{"gitId":"-"},"content":" .withRecipient(recipientName)"},{"lineNumber":465,"author":{"gitId":"-"},"content":" .withRecipientTeam(recipientTeam)"},{"lineNumber":466,"author":{"gitId":"-"},"content":" .withRecipientEmail(recipientEmail)"},{"lineNumber":467,"author":{"gitId":"xenosf"},"content":" .withRecipientSectionName(recipientSection)"},{"lineNumber":468,"author":{"gitId":"-"},"content":" .withResponseDetails(response.getResponseDetailsCopy())"},{"lineNumber":469,"author":{"gitId":"-"},"content":" .withParticipantComment(comments.poll())"},{"lineNumber":470,"author":{"gitId":"-"},"content":" .withInstructorComments(new ArrayList\u003c\u003e(comments))"},{"lineNumber":471,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":472,"author":{"gitId":"-"},"content":" }"},{"lineNumber":473,"author":{"gitId":"-"},"content":""},{"lineNumber":474,"author":{"gitId":"xenosf"},"content":" private static ResponseOutput buildSingleResponseForInstructor("},{"lineNumber":475,"author":{"gitId":"xenosf"},"content":" FeedbackResponse response, SqlSessionResultsBundle bundle, boolean isMissingResponse) {"},{"lineNumber":476,"author":{"gitId":"xenosf"},"content":" // process giver"},{"lineNumber":477,"author":{"gitId":"xenosf"},"content":" String giverEmail \u003d null;"},{"lineNumber":478,"author":{"gitId":"xenosf"},"content":" String relatedGiverEmail \u003d null;"},{"lineNumber":479,"author":{"gitId":"xenosf"},"content":" if (bundle.isResponseGiverVisible(response)) {"},{"lineNumber":480,"author":{"gitId":"xenosf"},"content":" giverEmail \u003d response.getGiver();"},{"lineNumber":481,"author":{"gitId":"xenosf"},"content":" relatedGiverEmail \u003d response.getGiver();"},{"lineNumber":482,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":483,"author":{"gitId":"xenosf"},"content":" if (bundle.getRoster().isTeamInCourse(giverEmail)) {"},{"lineNumber":484,"author":{"gitId":"xenosf"},"content":" // remove recipient email as it is a team name"},{"lineNumber":485,"author":{"gitId":"xenosf"},"content":" relatedGiverEmail \u003d"},{"lineNumber":486,"author":{"gitId":"xenosf"},"content":" bundle.getRoster().getTeamToMembersTable().get(giverEmail).iterator().next().getEmail();"},{"lineNumber":487,"author":{"gitId":"xenosf"},"content":" giverEmail \u003d null;"},{"lineNumber":488,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":489,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":490,"author":{"gitId":"xenosf"},"content":" String giverName \u003d getGiverNameOfResponse(response, bundle);"},{"lineNumber":491,"author":{"gitId":"xenosf"},"content":" String giverTeam \u003d bundle.getRoster().getInfoForIdentifier(response.getGiver()).getTeamName();"},{"lineNumber":492,"author":{"gitId":"xenosf"},"content":" String giverSectionName \u003d response.getGiverSectionName();"},{"lineNumber":493,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question \u003d response.getFeedbackQuestion();"},{"lineNumber":494,"author":{"gitId":"xenosf"},"content":" if (question.getGiverType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS) {"},{"lineNumber":495,"author":{"gitId":"xenosf"},"content":" Instructor instructor \u003d bundle.getRoster().getInstructorForEmail(response.getGiver());"},{"lineNumber":496,"author":{"gitId":"xenosf"},"content":" giverName \u003d instructor.getName();"},{"lineNumber":497,"author":{"gitId":"xenosf"},"content":" giverTeam \u003d Const.USER_TEAM_FOR_INSTRUCTOR;"},{"lineNumber":498,"author":{"gitId":"xenosf"},"content":" giverSectionName \u003d Const.DEFAULT_SECTION;"},{"lineNumber":499,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":500,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":501,"author":{"gitId":"xenosf"},"content":" // process recipient"},{"lineNumber":502,"author":{"gitId":"xenosf"},"content":" String recipientEmail \u003d null;"},{"lineNumber":503,"author":{"gitId":"xenosf"},"content":" String recipientName \u003d getRecipientNameOfResponse(response, bundle);"},{"lineNumber":504,"author":{"gitId":"xenosf"},"content":" String recipientTeam \u003d"},{"lineNumber":505,"author":{"gitId":"xenosf"},"content":" bundle.getRoster().getInfoForIdentifier(response.getRecipient()).getTeamName();"},{"lineNumber":506,"author":{"gitId":"xenosf"},"content":" String recipientSectionName \u003d response.getRecipientSectionName();"},{"lineNumber":507,"author":{"gitId":"xenosf"},"content":" if (question.getRecipientType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS) {"},{"lineNumber":508,"author":{"gitId":"xenosf"},"content":" Instructor instructor \u003d bundle.getRoster().getInstructorForEmail(response.getRecipient());"},{"lineNumber":509,"author":{"gitId":"xenosf"},"content":" recipientName \u003d instructor.getName();"},{"lineNumber":510,"author":{"gitId":"xenosf"},"content":" recipientTeam \u003d Const.USER_TEAM_FOR_INSTRUCTOR;"},{"lineNumber":511,"author":{"gitId":"xenosf"},"content":" recipientSectionName \u003d Const.DEFAULT_SECTION;"},{"lineNumber":512,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":513,"author":{"gitId":"xenosf"},"content":" if (bundle.isResponseRecipientVisible(response)) {"},{"lineNumber":514,"author":{"gitId":"xenosf"},"content":" recipientEmail \u003d response.getRecipient();"},{"lineNumber":515,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":516,"author":{"gitId":"xenosf"},"content":" if (bundle.getRoster().isTeamInCourse(recipientEmail)) {"},{"lineNumber":517,"author":{"gitId":"xenosf"},"content":" // remove recipient email as it is a team name"},{"lineNumber":518,"author":{"gitId":"xenosf"},"content":" recipientEmail \u003d null;"},{"lineNumber":519,"author":{"gitId":"xenosf"},"content":" } else if (Const.GENERAL_QUESTION.equals(recipientEmail)) {"},{"lineNumber":520,"author":{"gitId":"xenosf"},"content":" // general recipient does not have email"},{"lineNumber":521,"author":{"gitId":"xenosf"},"content":" recipientEmail \u003d null;"},{"lineNumber":522,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":523,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":524,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":525,"author":{"gitId":"xenosf"},"content":" // process comments"},{"lineNumber":526,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e feedbackResponseComments \u003d"},{"lineNumber":527,"author":{"gitId":"xenosf"},"content":" bundle.getResponseCommentsMap().getOrDefault(response, Collections.emptyList());"},{"lineNumber":528,"author":{"gitId":"xenosf"},"content":" Queue\u003cCommentOutput\u003e comments \u003d buildComments(feedbackResponseComments, bundle);"},{"lineNumber":529,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":530,"author":{"gitId":"xenosf"},"content":" return ResponseOutput.builder()"},{"lineNumber":531,"author":{"gitId":"xenosf"},"content":" .withIsMissingResponse(isMissingResponse)"},{"lineNumber":532,"author":{"gitId":"xenosf"},"content":" .withResponse(response)"},{"lineNumber":533,"author":{"gitId":"xenosf"},"content":" .withGiver(giverName)"},{"lineNumber":534,"author":{"gitId":"xenosf"},"content":" .withGiverTeam(giverTeam)"},{"lineNumber":535,"author":{"gitId":"xenosf"},"content":" .withGiverEmail(giverEmail)"},{"lineNumber":536,"author":{"gitId":"xenosf"},"content":" .withRelatedGiverEmail(relatedGiverEmail)"},{"lineNumber":537,"author":{"gitId":"xenosf"},"content":" .withGiverSectionName(giverSectionName)"},{"lineNumber":538,"author":{"gitId":"xenosf"},"content":" .withRecipient(recipientName)"},{"lineNumber":539,"author":{"gitId":"xenosf"},"content":" .withRecipientTeam(recipientTeam)"},{"lineNumber":540,"author":{"gitId":"xenosf"},"content":" .withRecipientEmail(recipientEmail)"},{"lineNumber":541,"author":{"gitId":"xenosf"},"content":" .withRecipientSectionName(recipientSectionName)"},{"lineNumber":542,"author":{"gitId":"xenosf"},"content":" .withResponseDetails(response.getFeedbackResponseDetailsCopy())"},{"lineNumber":543,"author":{"gitId":"xenosf"},"content":" .withParticipantComment(comments.poll())"},{"lineNumber":544,"author":{"gitId":"xenosf"},"content":" .withInstructorComments(new ArrayList\u003c\u003e(comments))"},{"lineNumber":545,"author":{"gitId":"xenosf"},"content":" .build();"},{"lineNumber":546,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":547,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":548,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":549,"author":{"gitId":"-"},"content":" * Gets giver name of a response from the bundle."},{"lineNumber":550,"author":{"gitId":"-"},"content":" *"},{"lineNumber":551,"author":{"gitId":"-"},"content":" * \u003cp\u003eAnonymized the name if necessary."},{"lineNumber":552,"author":{"gitId":"-"},"content":" */"},{"lineNumber":553,"author":{"gitId":"-"},"content":" private static String getGiverNameOfResponse(FeedbackResponseAttributes response, SessionResultsBundle bundle) {"},{"lineNumber":554,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes question \u003d bundle.getQuestionsMap().get(response.getFeedbackQuestionId());"},{"lineNumber":555,"author":{"gitId":"-"},"content":" FeedbackParticipantType participantType \u003d question.getGiverType();"},{"lineNumber":556,"author":{"gitId":"-"},"content":""},{"lineNumber":557,"author":{"gitId":"-"},"content":" CourseRoster.ParticipantInfo userInfo \u003d bundle.getRoster().getInfoForIdentifier(response.getGiver());"},{"lineNumber":558,"author":{"gitId":"-"},"content":" String name \u003d userInfo.getName();"},{"lineNumber":559,"author":{"gitId":"-"},"content":""},{"lineNumber":560,"author":{"gitId":"-"},"content":" if (!bundle.isResponseGiverVisible(response)) {"},{"lineNumber":561,"author":{"gitId":"-"},"content":" name \u003d SessionResultsBundle.getAnonName(participantType, name);"},{"lineNumber":562,"author":{"gitId":"-"},"content":" }"},{"lineNumber":563,"author":{"gitId":"-"},"content":""},{"lineNumber":564,"author":{"gitId":"-"},"content":" return name;"},{"lineNumber":565,"author":{"gitId":"-"},"content":" }"},{"lineNumber":566,"author":{"gitId":"-"},"content":""},{"lineNumber":567,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":568,"author":{"gitId":"xenosf"},"content":" * Gets giver name of a response from the bundle."},{"lineNumber":569,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":570,"author":{"gitId":"xenosf"},"content":" * \u003cp\u003eAnonymized the name if necessary."},{"lineNumber":571,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":572,"author":{"gitId":"xenosf"},"content":" private static String getGiverNameOfResponse(FeedbackResponse response, SqlSessionResultsBundle bundle) {"},{"lineNumber":573,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question \u003d response.getFeedbackQuestion();"},{"lineNumber":574,"author":{"gitId":"xenosf"},"content":" FeedbackParticipantType participantType \u003d question.getGiverType();"},{"lineNumber":575,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":576,"author":{"gitId":"xenosf"},"content":" SqlCourseRoster.ParticipantInfo userInfo \u003d bundle.getRoster().getInfoForIdentifier(response.getGiver());"},{"lineNumber":577,"author":{"gitId":"xenosf"},"content":" String name \u003d userInfo.getName();"},{"lineNumber":578,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":579,"author":{"gitId":"xenosf"},"content":" if (!bundle.isResponseGiverVisible(response)) {"},{"lineNumber":580,"author":{"gitId":"xenosf"},"content":" name \u003d SessionResultsBundle.getAnonName(participantType, name);"},{"lineNumber":581,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":582,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":583,"author":{"gitId":"xenosf"},"content":" return name;"},{"lineNumber":584,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":585,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":586,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":587,"author":{"gitId":"-"},"content":" * Gets recipient name of a response from the bundle."},{"lineNumber":588,"author":{"gitId":"-"},"content":" *"},{"lineNumber":589,"author":{"gitId":"-"},"content":" * \u003cp\u003eAnonymized the name if necessary."},{"lineNumber":590,"author":{"gitId":"-"},"content":" */"},{"lineNumber":591,"author":{"gitId":"-"},"content":" private static String getRecipientNameOfResponse(FeedbackResponseAttributes response, SessionResultsBundle bundle) {"},{"lineNumber":592,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes question \u003d bundle.getQuestionsMap().get(response.getFeedbackQuestionId());"},{"lineNumber":593,"author":{"gitId":"-"},"content":" FeedbackParticipantType participantType \u003d question.getRecipientType();"},{"lineNumber":594,"author":{"gitId":"-"},"content":" if (participantType \u003d\u003d FeedbackParticipantType.SELF) {"},{"lineNumber":595,"author":{"gitId":"-"},"content":" // recipient type for self-feedback is the same as the giver type"},{"lineNumber":596,"author":{"gitId":"-"},"content":" participantType \u003d question.getGiverType();"},{"lineNumber":597,"author":{"gitId":"-"},"content":" }"},{"lineNumber":598,"author":{"gitId":"-"},"content":""},{"lineNumber":599,"author":{"gitId":"-"},"content":" CourseRoster.ParticipantInfo userInfo \u003d bundle.getRoster().getInfoForIdentifier(response.getRecipient());"},{"lineNumber":600,"author":{"gitId":"-"},"content":" String name \u003d userInfo.getName();"},{"lineNumber":601,"author":{"gitId":"-"},"content":" if (Const.GENERAL_QUESTION.equals(response.getRecipient())) {"},{"lineNumber":602,"author":{"gitId":"-"},"content":" // for general question"},{"lineNumber":603,"author":{"gitId":"-"},"content":" name \u003d Const.USER_NOBODY_TEXT;"},{"lineNumber":604,"author":{"gitId":"-"},"content":" }"},{"lineNumber":605,"author":{"gitId":"-"},"content":" if (!bundle.isResponseRecipientVisible(response)) {"},{"lineNumber":606,"author":{"gitId":"-"},"content":" name \u003d SessionResultsBundle.getAnonName(participantType, name);"},{"lineNumber":607,"author":{"gitId":"-"},"content":" }"},{"lineNumber":608,"author":{"gitId":"-"},"content":""},{"lineNumber":609,"author":{"gitId":"-"},"content":" return name;"},{"lineNumber":610,"author":{"gitId":"-"},"content":" }"},{"lineNumber":611,"author":{"gitId":"-"},"content":""},{"lineNumber":612,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":613,"author":{"gitId":"xenosf"},"content":" * Gets recipient name of a response from the bundle."},{"lineNumber":614,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":615,"author":{"gitId":"xenosf"},"content":" * \u003cp\u003eAnonymized the name if necessary."},{"lineNumber":616,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":617,"author":{"gitId":"xenosf"},"content":" private static String getRecipientNameOfResponse(FeedbackResponse response, SqlSessionResultsBundle bundle) {"},{"lineNumber":618,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question \u003d response.getFeedbackQuestion();"},{"lineNumber":619,"author":{"gitId":"xenosf"},"content":" FeedbackParticipantType participantType \u003d question.getRecipientType();"},{"lineNumber":620,"author":{"gitId":"xenosf"},"content":" if (participantType \u003d\u003d FeedbackParticipantType.SELF) {"},{"lineNumber":621,"author":{"gitId":"xenosf"},"content":" // recipient type for self-feedback is the same as the giver type"},{"lineNumber":622,"author":{"gitId":"xenosf"},"content":" participantType \u003d question.getGiverType();"},{"lineNumber":623,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":624,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":625,"author":{"gitId":"xenosf"},"content":" SqlCourseRoster.ParticipantInfo userInfo \u003d bundle.getRoster().getInfoForIdentifier(response.getRecipient());"},{"lineNumber":626,"author":{"gitId":"xenosf"},"content":" String name \u003d userInfo.getName();"},{"lineNumber":627,"author":{"gitId":"xenosf"},"content":" if (Const.GENERAL_QUESTION.equals(response.getRecipient())) {"},{"lineNumber":628,"author":{"gitId":"xenosf"},"content":" // for general question"},{"lineNumber":629,"author":{"gitId":"xenosf"},"content":" name \u003d Const.USER_NOBODY_TEXT;"},{"lineNumber":630,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":631,"author":{"gitId":"xenosf"},"content":" if (!bundle.isResponseRecipientVisible(response)) {"},{"lineNumber":632,"author":{"gitId":"xenosf"},"content":" name \u003d SessionResultsBundle.getAnonName(participantType, name);"},{"lineNumber":633,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":634,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":635,"author":{"gitId":"xenosf"},"content":" return name;"},{"lineNumber":636,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":637,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":638,"author":{"gitId":"-"},"content":" private static Queue\u003cCommentOutput\u003e buildComments(List\u003cFeedbackResponseCommentAttributes\u003e feedbackResponseComments,"},{"lineNumber":639,"author":{"gitId":"-"},"content":" SessionResultsBundle bundle) {"},{"lineNumber":640,"author":{"gitId":"-"},"content":" LinkedList\u003cCommentOutput\u003e outputs \u003d new LinkedList\u003c\u003e();"},{"lineNumber":641,"author":{"gitId":"-"},"content":""},{"lineNumber":642,"author":{"gitId":"-"},"content":" CommentOutput participantComment \u003d null;"},{"lineNumber":643,"author":{"gitId":"-"},"content":" for (FeedbackResponseCommentAttributes comment : feedbackResponseComments) {"},{"lineNumber":644,"author":{"gitId":"-"},"content":" if (comment.isCommentFromFeedbackParticipant()) {"},{"lineNumber":645,"author":{"gitId":"-"},"content":" // participant comment will not need these fields"},{"lineNumber":646,"author":{"gitId":"-"},"content":" participantComment \u003d CommentOutput.builder(comment)"},{"lineNumber":647,"author":{"gitId":"-"},"content":" .withCommentGiver(null)"},{"lineNumber":648,"author":{"gitId":"-"},"content":" .withCommentGiverName(null)"},{"lineNumber":649,"author":{"gitId":"-"},"content":" .withLastEditorEmail(null)"},{"lineNumber":650,"author":{"gitId":"-"},"content":" .withLastEditorName(null)"},{"lineNumber":651,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":652,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":653,"author":{"gitId":"-"},"content":" String giverEmail \u003d Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT;"},{"lineNumber":654,"author":{"gitId":"-"},"content":" String giverName \u003d Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT;"},{"lineNumber":655,"author":{"gitId":"-"},"content":" String lastEditorEmail \u003d Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT;"},{"lineNumber":656,"author":{"gitId":"-"},"content":" String lastEditorName \u003d Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT;"},{"lineNumber":657,"author":{"gitId":"-"},"content":" if (bundle.isCommentGiverVisible(comment)) {"},{"lineNumber":658,"author":{"gitId":"-"},"content":" giverEmail \u003d comment.getCommentGiver();"},{"lineNumber":659,"author":{"gitId":"-"},"content":" giverName \u003d bundle.getRoster().getInfoForIdentifier(comment.getCommentGiver()).getName();"},{"lineNumber":660,"author":{"gitId":"-"},"content":" lastEditorEmail \u003d comment.getLastEditorEmail();"},{"lineNumber":661,"author":{"gitId":"-"},"content":" lastEditorName \u003d bundle.getRoster().getInfoForIdentifier(comment.getLastEditorEmail()).getName();"},{"lineNumber":662,"author":{"gitId":"-"},"content":" }"},{"lineNumber":663,"author":{"gitId":"-"},"content":" outputs.add(CommentOutput.builder(comment)"},{"lineNumber":664,"author":{"gitId":"-"},"content":" .withCommentGiver(giverEmail)"},{"lineNumber":665,"author":{"gitId":"-"},"content":" .withCommentGiverName(giverName)"},{"lineNumber":666,"author":{"gitId":"-"},"content":" .withLastEditorEmail(lastEditorEmail)"},{"lineNumber":667,"author":{"gitId":"-"},"content":" .withLastEditorName(lastEditorName)"},{"lineNumber":668,"author":{"gitId":"-"},"content":" .build());"},{"lineNumber":669,"author":{"gitId":"-"},"content":" }"},{"lineNumber":670,"author":{"gitId":"-"},"content":" }"},{"lineNumber":671,"author":{"gitId":"-"},"content":" outputs.addFirst(participantComment);"},{"lineNumber":672,"author":{"gitId":"-"},"content":""},{"lineNumber":673,"author":{"gitId":"-"},"content":" return outputs;"},{"lineNumber":674,"author":{"gitId":"-"},"content":" }"},{"lineNumber":675,"author":{"gitId":"-"},"content":""},{"lineNumber":676,"author":{"gitId":"xenosf"},"content":" private static Queue\u003cCommentOutput\u003e buildComments(List\u003cFeedbackResponseComment\u003e feedbackResponseComments,"},{"lineNumber":677,"author":{"gitId":"xenosf"},"content":" SqlSessionResultsBundle bundle) {"},{"lineNumber":678,"author":{"gitId":"xenosf"},"content":" LinkedList\u003cCommentOutput\u003e outputs \u003d new LinkedList\u003c\u003e();"},{"lineNumber":679,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":680,"author":{"gitId":"xenosf"},"content":" CommentOutput participantComment \u003d null;"},{"lineNumber":681,"author":{"gitId":"xenosf"},"content":" for (FeedbackResponseComment comment : feedbackResponseComments) {"},{"lineNumber":682,"author":{"gitId":"xenosf"},"content":" if (comment.getIsCommentFromFeedbackParticipant()) {"},{"lineNumber":683,"author":{"gitId":"xenosf"},"content":" // participant comment will not need these fields"},{"lineNumber":684,"author":{"gitId":"xenosf"},"content":" participantComment \u003d CommentOutput.builder(comment)"},{"lineNumber":685,"author":{"gitId":"xenosf"},"content":" .withCommentGiver(null)"},{"lineNumber":686,"author":{"gitId":"xenosf"},"content":" .withCommentGiverName(null)"},{"lineNumber":687,"author":{"gitId":"xenosf"},"content":" .withLastEditorEmail(null)"},{"lineNumber":688,"author":{"gitId":"xenosf"},"content":" .withLastEditorName(null)"},{"lineNumber":689,"author":{"gitId":"xenosf"},"content":" .build();"},{"lineNumber":690,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":691,"author":{"gitId":"xenosf"},"content":" String giverEmail \u003d Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT;"},{"lineNumber":692,"author":{"gitId":"xenosf"},"content":" String giverName \u003d Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT;"},{"lineNumber":693,"author":{"gitId":"xenosf"},"content":" String lastEditorEmail \u003d Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT;"},{"lineNumber":694,"author":{"gitId":"xenosf"},"content":" String lastEditorName \u003d Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT;"},{"lineNumber":695,"author":{"gitId":"xenosf"},"content":" if (bundle.isCommentGiverVisible(comment)) {"},{"lineNumber":696,"author":{"gitId":"xenosf"},"content":" giverEmail \u003d comment.getGiver();"},{"lineNumber":697,"author":{"gitId":"xenosf"},"content":" giverName \u003d bundle.getRoster().getInfoForIdentifier(comment.getGiver()).getName();"},{"lineNumber":698,"author":{"gitId":"xenosf"},"content":" lastEditorEmail \u003d comment.getLastEditorEmail();"},{"lineNumber":699,"author":{"gitId":"xenosf"},"content":" lastEditorName \u003d bundle.getRoster().getInfoForIdentifier(comment.getLastEditorEmail()).getName();"},{"lineNumber":700,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":701,"author":{"gitId":"xenosf"},"content":" outputs.add(CommentOutput.builder(comment)"},{"lineNumber":702,"author":{"gitId":"xenosf"},"content":" .withCommentGiver(giverEmail)"},{"lineNumber":703,"author":{"gitId":"xenosf"},"content":" .withCommentGiverName(giverName)"},{"lineNumber":704,"author":{"gitId":"xenosf"},"content":" .withLastEditorEmail(lastEditorEmail)"},{"lineNumber":705,"author":{"gitId":"xenosf"},"content":" .withLastEditorName(lastEditorName)"},{"lineNumber":706,"author":{"gitId":"xenosf"},"content":" .build());"},{"lineNumber":707,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":708,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":709,"author":{"gitId":"xenosf"},"content":" outputs.addFirst(participantComment);"},{"lineNumber":710,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":711,"author":{"gitId":"xenosf"},"content":" return outputs;"},{"lineNumber":712,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":713,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":714,"author":{"gitId":"-"},"content":" public List\u003cQuestionOutput\u003e getQuestions() {"},{"lineNumber":715,"author":{"gitId":"-"},"content":" return questions;"},{"lineNumber":716,"author":{"gitId":"-"},"content":" }"},{"lineNumber":717,"author":{"gitId":"-"},"content":""},{"lineNumber":718,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":719,"author":{"gitId":"-"},"content":" * API output format for questions in session results."},{"lineNumber":720,"author":{"gitId":"-"},"content":" */"},{"lineNumber":721,"author":{"gitId":"-"},"content":" public static final class QuestionOutput {"},{"lineNumber":722,"author":{"gitId":"-"},"content":""},{"lineNumber":723,"author":{"gitId":"-"},"content":" private final FeedbackQuestionData feedbackQuestion;"},{"lineNumber":724,"author":{"gitId":"-"},"content":" private final String questionStatistics;"},{"lineNumber":725,"author":{"gitId":"-"},"content":""},{"lineNumber":726,"author":{"gitId":"-"},"content":" private final List\u003cResponseOutput\u003e allResponses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":727,"author":{"gitId":"-"},"content":" private final boolean hasResponseButNotVisibleForPreview;"},{"lineNumber":728,"author":{"gitId":"-"},"content":" private final boolean hasCommentNotVisibleForPreview;"},{"lineNumber":729,"author":{"gitId":"-"},"content":""},{"lineNumber":730,"author":{"gitId":"-"},"content":" // For student view only"},{"lineNumber":731,"author":{"gitId":"-"},"content":" private final List\u003cResponseOutput\u003e responsesToSelf \u003d new ArrayList\u003c\u003e();"},{"lineNumber":732,"author":{"gitId":"-"},"content":" private final List\u003cResponseOutput\u003e responsesFromSelf \u003d new ArrayList\u003c\u003e();"},{"lineNumber":733,"author":{"gitId":"-"},"content":" private final List\u003cList\u003cResponseOutput\u003e\u003e otherResponses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":734,"author":{"gitId":"-"},"content":""},{"lineNumber":735,"author":{"gitId":"-"},"content":" private QuestionOutput(FeedbackQuestionAttributes feedbackQuestionAttributes, String questionStatistics,"},{"lineNumber":736,"author":{"gitId":"-"},"content":" boolean hasResponseButNotVisibleForPreview, boolean hasCommentNotVisibleForPreview) {"},{"lineNumber":737,"author":{"gitId":"-"},"content":" this.feedbackQuestion \u003d new FeedbackQuestionData(feedbackQuestionAttributes);"},{"lineNumber":738,"author":{"gitId":"-"},"content":" this.questionStatistics \u003d questionStatistics;"},{"lineNumber":739,"author":{"gitId":"-"},"content":" this.hasResponseButNotVisibleForPreview \u003d hasResponseButNotVisibleForPreview;"},{"lineNumber":740,"author":{"gitId":"-"},"content":" this.hasCommentNotVisibleForPreview \u003d hasCommentNotVisibleForPreview;"},{"lineNumber":741,"author":{"gitId":"-"},"content":" }"},{"lineNumber":742,"author":{"gitId":"-"},"content":""},{"lineNumber":743,"author":{"gitId":"xenosf"},"content":" private QuestionOutput(FeedbackQuestion feedbackQuestion, String questionStatistics,"},{"lineNumber":744,"author":{"gitId":"xenosf"},"content":" boolean hasResponseButNotVisibleForPreview, boolean hasCommentNotVisibleForPreview) {"},{"lineNumber":745,"author":{"gitId":"xenosf"},"content":" this.feedbackQuestion \u003d new FeedbackQuestionData(feedbackQuestion);"},{"lineNumber":746,"author":{"gitId":"xenosf"},"content":" this.questionStatistics \u003d questionStatistics;"},{"lineNumber":747,"author":{"gitId":"xenosf"},"content":" this.hasResponseButNotVisibleForPreview \u003d hasResponseButNotVisibleForPreview;"},{"lineNumber":748,"author":{"gitId":"xenosf"},"content":" this.hasCommentNotVisibleForPreview \u003d hasCommentNotVisibleForPreview;"},{"lineNumber":749,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":750,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":751,"author":{"gitId":"-"},"content":" public FeedbackQuestionData getFeedbackQuestion() {"},{"lineNumber":752,"author":{"gitId":"-"},"content":" return feedbackQuestion;"},{"lineNumber":753,"author":{"gitId":"-"},"content":" }"},{"lineNumber":754,"author":{"gitId":"-"},"content":""},{"lineNumber":755,"author":{"gitId":"-"},"content":" public String getQuestionStatistics() {"},{"lineNumber":756,"author":{"gitId":"-"},"content":" return questionStatistics;"},{"lineNumber":757,"author":{"gitId":"-"},"content":" }"},{"lineNumber":758,"author":{"gitId":"-"},"content":""},{"lineNumber":759,"author":{"gitId":"-"},"content":" public List\u003cResponseOutput\u003e getAllResponses() {"},{"lineNumber":760,"author":{"gitId":"-"},"content":" return allResponses;"},{"lineNumber":761,"author":{"gitId":"-"},"content":" }"},{"lineNumber":762,"author":{"gitId":"-"},"content":""},{"lineNumber":763,"author":{"gitId":"-"},"content":" public boolean getHasResponseButNotVisibleForPreview() {"},{"lineNumber":764,"author":{"gitId":"-"},"content":" return hasResponseButNotVisibleForPreview;"},{"lineNumber":765,"author":{"gitId":"-"},"content":" }"},{"lineNumber":766,"author":{"gitId":"-"},"content":""},{"lineNumber":767,"author":{"gitId":"-"},"content":" public boolean getHasCommentNotVisibleForPreview() {"},{"lineNumber":768,"author":{"gitId":"-"},"content":" return hasCommentNotVisibleForPreview;"},{"lineNumber":769,"author":{"gitId":"-"},"content":" }"},{"lineNumber":770,"author":{"gitId":"-"},"content":""},{"lineNumber":771,"author":{"gitId":"-"},"content":" public List\u003cResponseOutput\u003e getResponsesFromSelf() {"},{"lineNumber":772,"author":{"gitId":"-"},"content":" return responsesFromSelf;"},{"lineNumber":773,"author":{"gitId":"-"},"content":" }"},{"lineNumber":774,"author":{"gitId":"-"},"content":""},{"lineNumber":775,"author":{"gitId":"-"},"content":" public List\u003cResponseOutput\u003e getResponsesToSelf() {"},{"lineNumber":776,"author":{"gitId":"-"},"content":" return responsesToSelf;"},{"lineNumber":777,"author":{"gitId":"-"},"content":" }"},{"lineNumber":778,"author":{"gitId":"-"},"content":""},{"lineNumber":779,"author":{"gitId":"-"},"content":" public List\u003cList\u003cResponseOutput\u003e\u003e getOtherResponses() {"},{"lineNumber":780,"author":{"gitId":"-"},"content":" return otherResponses;"},{"lineNumber":781,"author":{"gitId":"-"},"content":" }"},{"lineNumber":782,"author":{"gitId":"-"},"content":""},{"lineNumber":783,"author":{"gitId":"-"},"content":" }"},{"lineNumber":784,"author":{"gitId":"-"},"content":""},{"lineNumber":785,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":786,"author":{"gitId":"-"},"content":" * API output format for question responses."},{"lineNumber":787,"author":{"gitId":"-"},"content":" */"},{"lineNumber":788,"author":{"gitId":"-"},"content":" public static final class ResponseOutput {"},{"lineNumber":789,"author":{"gitId":"-"},"content":""},{"lineNumber":790,"author":{"gitId":"-"},"content":" private boolean isMissingResponse;"},{"lineNumber":791,"author":{"gitId":"-"},"content":""},{"lineNumber":792,"author":{"gitId":"-"},"content":" private String responseId;"},{"lineNumber":793,"author":{"gitId":"-"},"content":""},{"lineNumber":794,"author":{"gitId":"-"},"content":" private String giver;"},{"lineNumber":795,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":796,"author":{"gitId":"-"},"content":" * Depending on the question giver type, {@code giverIdentifier} may contain the giver\u0027s email, any team member\u0027s"},{"lineNumber":797,"author":{"gitId":"-"},"content":" * email or null."},{"lineNumber":798,"author":{"gitId":"-"},"content":" */"},{"lineNumber":799,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":800,"author":{"gitId":"-"},"content":" private String relatedGiverEmail;"},{"lineNumber":801,"author":{"gitId":"-"},"content":" private String giverTeam;"},{"lineNumber":802,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":803,"author":{"gitId":"-"},"content":" private String giverEmail;"},{"lineNumber":804,"author":{"gitId":"-"},"content":" private String giverSection;"},{"lineNumber":805,"author":{"gitId":"-"},"content":" private String recipient;"},{"lineNumber":806,"author":{"gitId":"-"},"content":" private String recipientTeam;"},{"lineNumber":807,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":808,"author":{"gitId":"-"},"content":" private String recipientEmail;"},{"lineNumber":809,"author":{"gitId":"-"},"content":" private String recipientSection;"},{"lineNumber":810,"author":{"gitId":"-"},"content":" private FeedbackResponseDetails responseDetails;"},{"lineNumber":811,"author":{"gitId":"-"},"content":""},{"lineNumber":812,"author":{"gitId":"-"},"content":" // comments"},{"lineNumber":813,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":814,"author":{"gitId":"-"},"content":" private CommentOutput participantComment;"},{"lineNumber":815,"author":{"gitId":"-"},"content":" private List\u003cCommentOutput\u003e instructorComments;"},{"lineNumber":816,"author":{"gitId":"-"},"content":""},{"lineNumber":817,"author":{"gitId":"-"},"content":" private ResponseOutput() {"},{"lineNumber":818,"author":{"gitId":"-"},"content":" // use builder instead"},{"lineNumber":819,"author":{"gitId":"-"},"content":" }"},{"lineNumber":820,"author":{"gitId":"-"},"content":""},{"lineNumber":821,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":822,"author":{"gitId":"-"},"content":" * Returns a builder for {@link ResponseOutput}."},{"lineNumber":823,"author":{"gitId":"-"},"content":" */"},{"lineNumber":824,"author":{"gitId":"-"},"content":" static Builder builder() {"},{"lineNumber":825,"author":{"gitId":"-"},"content":" return new Builder();"},{"lineNumber":826,"author":{"gitId":"-"},"content":" }"},{"lineNumber":827,"author":{"gitId":"-"},"content":""},{"lineNumber":828,"author":{"gitId":"-"},"content":" public boolean isMissingResponse() {"},{"lineNumber":829,"author":{"gitId":"-"},"content":" return isMissingResponse;"},{"lineNumber":830,"author":{"gitId":"-"},"content":" }"},{"lineNumber":831,"author":{"gitId":"-"},"content":""},{"lineNumber":832,"author":{"gitId":"-"},"content":" public String getResponseId() {"},{"lineNumber":833,"author":{"gitId":"-"},"content":" return responseId;"},{"lineNumber":834,"author":{"gitId":"-"},"content":" }"},{"lineNumber":835,"author":{"gitId":"-"},"content":""},{"lineNumber":836,"author":{"gitId":"-"},"content":" public String getGiver() {"},{"lineNumber":837,"author":{"gitId":"-"},"content":" return giver;"},{"lineNumber":838,"author":{"gitId":"-"},"content":" }"},{"lineNumber":839,"author":{"gitId":"-"},"content":""},{"lineNumber":840,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":841,"author":{"gitId":"-"},"content":" public String getGiverEmail() {"},{"lineNumber":842,"author":{"gitId":"-"},"content":" return giverEmail;"},{"lineNumber":843,"author":{"gitId":"-"},"content":" }"},{"lineNumber":844,"author":{"gitId":"-"},"content":""},{"lineNumber":845,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":846,"author":{"gitId":"-"},"content":" public String getRelatedGiverEmail() {"},{"lineNumber":847,"author":{"gitId":"-"},"content":" return relatedGiverEmail;"},{"lineNumber":848,"author":{"gitId":"-"},"content":" }"},{"lineNumber":849,"author":{"gitId":"-"},"content":""},{"lineNumber":850,"author":{"gitId":"-"},"content":" public String getGiverTeam() {"},{"lineNumber":851,"author":{"gitId":"-"},"content":" return giverTeam;"},{"lineNumber":852,"author":{"gitId":"-"},"content":" }"},{"lineNumber":853,"author":{"gitId":"-"},"content":""},{"lineNumber":854,"author":{"gitId":"-"},"content":" public String getGiverSection() {"},{"lineNumber":855,"author":{"gitId":"-"},"content":" return giverSection;"},{"lineNumber":856,"author":{"gitId":"-"},"content":" }"},{"lineNumber":857,"author":{"gitId":"-"},"content":""},{"lineNumber":858,"author":{"gitId":"-"},"content":" public String getRecipient() {"},{"lineNumber":859,"author":{"gitId":"-"},"content":" return recipient;"},{"lineNumber":860,"author":{"gitId":"-"},"content":" }"},{"lineNumber":861,"author":{"gitId":"-"},"content":""},{"lineNumber":862,"author":{"gitId":"-"},"content":" public String getRecipientTeam() {"},{"lineNumber":863,"author":{"gitId":"-"},"content":" return recipientTeam;"},{"lineNumber":864,"author":{"gitId":"-"},"content":" }"},{"lineNumber":865,"author":{"gitId":"-"},"content":""},{"lineNumber":866,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":867,"author":{"gitId":"-"},"content":" public String getRecipientEmail() {"},{"lineNumber":868,"author":{"gitId":"-"},"content":" return recipientEmail;"},{"lineNumber":869,"author":{"gitId":"-"},"content":" }"},{"lineNumber":870,"author":{"gitId":"-"},"content":""},{"lineNumber":871,"author":{"gitId":"-"},"content":" public String getRecipientSection() {"},{"lineNumber":872,"author":{"gitId":"-"},"content":" return recipientSection;"},{"lineNumber":873,"author":{"gitId":"-"},"content":" }"},{"lineNumber":874,"author":{"gitId":"-"},"content":""},{"lineNumber":875,"author":{"gitId":"-"},"content":" public FeedbackResponseDetails getResponseDetails() {"},{"lineNumber":876,"author":{"gitId":"-"},"content":" return responseDetails;"},{"lineNumber":877,"author":{"gitId":"-"},"content":" }"},{"lineNumber":878,"author":{"gitId":"-"},"content":""},{"lineNumber":879,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":880,"author":{"gitId":"-"},"content":" public CommentOutput getParticipantComment() {"},{"lineNumber":881,"author":{"gitId":"-"},"content":" return participantComment;"},{"lineNumber":882,"author":{"gitId":"-"},"content":" }"},{"lineNumber":883,"author":{"gitId":"-"},"content":""},{"lineNumber":884,"author":{"gitId":"-"},"content":" public List\u003cCommentOutput\u003e getInstructorComments() {"},{"lineNumber":885,"author":{"gitId":"-"},"content":" return instructorComments;"},{"lineNumber":886,"author":{"gitId":"-"},"content":" }"},{"lineNumber":887,"author":{"gitId":"-"},"content":""},{"lineNumber":888,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":889,"author":{"gitId":"-"},"content":" * Builder class for {@link ResponseOutput}."},{"lineNumber":890,"author":{"gitId":"-"},"content":" */"},{"lineNumber":891,"author":{"gitId":"-"},"content":" public static final class Builder {"},{"lineNumber":892,"author":{"gitId":"-"},"content":" private final ResponseOutput responseOutput;"},{"lineNumber":893,"author":{"gitId":"-"},"content":""},{"lineNumber":894,"author":{"gitId":"-"},"content":" private Builder() {"},{"lineNumber":895,"author":{"gitId":"-"},"content":" responseOutput \u003d new ResponseOutput();"},{"lineNumber":896,"author":{"gitId":"-"},"content":" }"},{"lineNumber":897,"author":{"gitId":"-"},"content":""},{"lineNumber":898,"author":{"gitId":"-"},"content":" Builder withIsMissingResponse(boolean isMissingResponse) {"},{"lineNumber":899,"author":{"gitId":"-"},"content":" responseOutput.isMissingResponse \u003d isMissingResponse;"},{"lineNumber":900,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":901,"author":{"gitId":"-"},"content":" }"},{"lineNumber":902,"author":{"gitId":"-"},"content":""},{"lineNumber":903,"author":{"gitId":"-"},"content":" Builder withResponseId(String responseId) {"},{"lineNumber":904,"author":{"gitId":"-"},"content":" responseOutput.responseId \u003d StringHelper.encrypt(responseId);"},{"lineNumber":905,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":906,"author":{"gitId":"-"},"content":" }"},{"lineNumber":907,"author":{"gitId":"-"},"content":""},{"lineNumber":908,"author":{"gitId":"xenosf"},"content":" Builder withResponse(FeedbackResponse response) {"},{"lineNumber":909,"author":{"gitId":"xenosf"},"content":" responseOutput.responseId \u003d StringHelper.encrypt(response.getId().toString());"},{"lineNumber":910,"author":{"gitId":"xenosf"},"content":" return this;"},{"lineNumber":911,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":912,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":913,"author":{"gitId":"-"},"content":" Builder withGiver(String giverName) {"},{"lineNumber":914,"author":{"gitId":"-"},"content":" responseOutput.giver \u003d giverName;"},{"lineNumber":915,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":916,"author":{"gitId":"-"},"content":" }"},{"lineNumber":917,"author":{"gitId":"-"},"content":""},{"lineNumber":918,"author":{"gitId":"-"},"content":" Builder withRelatedGiverEmail(@Nullable String relatedGiverEmail) {"},{"lineNumber":919,"author":{"gitId":"-"},"content":" responseOutput.relatedGiverEmail \u003d relatedGiverEmail;"},{"lineNumber":920,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":921,"author":{"gitId":"-"},"content":" }"},{"lineNumber":922,"author":{"gitId":"-"},"content":""},{"lineNumber":923,"author":{"gitId":"-"},"content":" Builder withGiverTeam(String giverTeam) {"},{"lineNumber":924,"author":{"gitId":"-"},"content":" responseOutput.giverTeam \u003d giverTeam;"},{"lineNumber":925,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":926,"author":{"gitId":"-"},"content":" }"},{"lineNumber":927,"author":{"gitId":"-"},"content":""},{"lineNumber":928,"author":{"gitId":"-"},"content":" Builder withGiverEmail(@Nullable String giverEmail) {"},{"lineNumber":929,"author":{"gitId":"-"},"content":" responseOutput.giverEmail \u003d giverEmail;"},{"lineNumber":930,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":931,"author":{"gitId":"-"},"content":" }"},{"lineNumber":932,"author":{"gitId":"-"},"content":""},{"lineNumber":933,"author":{"gitId":"xenosf"},"content":" Builder withGiverSectionName(String giverSection) {"},{"lineNumber":934,"author":{"gitId":"-"},"content":" responseOutput.giverSection \u003d giverSection;"},{"lineNumber":935,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":936,"author":{"gitId":"-"},"content":" }"},{"lineNumber":937,"author":{"gitId":"-"},"content":""},{"lineNumber":938,"author":{"gitId":"xenosf"},"content":" Builder withGiverSection(Section giverSection) {"},{"lineNumber":939,"author":{"gitId":"xenosf"},"content":" responseOutput.giverSection \u003d giverSection.getName();"},{"lineNumber":940,"author":{"gitId":"xenosf"},"content":" return this;"},{"lineNumber":941,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":942,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":943,"author":{"gitId":"-"},"content":" Builder withRecipient(String recipientName) {"},{"lineNumber":944,"author":{"gitId":"-"},"content":" responseOutput.recipient \u003d recipientName;"},{"lineNumber":945,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":946,"author":{"gitId":"-"},"content":" }"},{"lineNumber":947,"author":{"gitId":"-"},"content":""},{"lineNumber":948,"author":{"gitId":"-"},"content":" Builder withRecipientTeam(String recipientTeam) {"},{"lineNumber":949,"author":{"gitId":"-"},"content":" responseOutput.recipientTeam \u003d recipientTeam;"},{"lineNumber":950,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":951,"author":{"gitId":"-"},"content":" }"},{"lineNumber":952,"author":{"gitId":"-"},"content":""},{"lineNumber":953,"author":{"gitId":"-"},"content":" Builder withRecipientEmail(@Nullable String recipientEmail) {"},{"lineNumber":954,"author":{"gitId":"-"},"content":" responseOutput.recipientEmail \u003d recipientEmail;"},{"lineNumber":955,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":956,"author":{"gitId":"-"},"content":" }"},{"lineNumber":957,"author":{"gitId":"-"},"content":""},{"lineNumber":958,"author":{"gitId":"xenosf"},"content":" Builder withRecipientSectionName(String recipientSection) {"},{"lineNumber":959,"author":{"gitId":"-"},"content":" responseOutput.recipientSection \u003d recipientSection;"},{"lineNumber":960,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":961,"author":{"gitId":"-"},"content":" }"},{"lineNumber":962,"author":{"gitId":"-"},"content":""},{"lineNumber":963,"author":{"gitId":"xenosf"},"content":" Builder withRecipientSection(Section recipientSection) {"},{"lineNumber":964,"author":{"gitId":"xenosf"},"content":" responseOutput.recipientSection \u003d recipientSection.getName();"},{"lineNumber":965,"author":{"gitId":"xenosf"},"content":" return this;"},{"lineNumber":966,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":967,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":968,"author":{"gitId":"-"},"content":" Builder withResponseDetails(FeedbackResponseDetails responseDetails) {"},{"lineNumber":969,"author":{"gitId":"-"},"content":" responseOutput.responseDetails \u003d responseDetails;"},{"lineNumber":970,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":971,"author":{"gitId":"-"},"content":" }"},{"lineNumber":972,"author":{"gitId":"-"},"content":""},{"lineNumber":973,"author":{"gitId":"-"},"content":" Builder withParticipantComment(@Nullable CommentOutput participantComment) {"},{"lineNumber":974,"author":{"gitId":"-"},"content":" responseOutput.participantComment \u003d participantComment;"},{"lineNumber":975,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":976,"author":{"gitId":"-"},"content":" }"},{"lineNumber":977,"author":{"gitId":"-"},"content":""},{"lineNumber":978,"author":{"gitId":"-"},"content":" Builder withInstructorComments(List\u003cCommentOutput\u003e instructorComments) {"},{"lineNumber":979,"author":{"gitId":"-"},"content":" responseOutput.instructorComments \u003d instructorComments;"},{"lineNumber":980,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":981,"author":{"gitId":"-"},"content":" }"},{"lineNumber":982,"author":{"gitId":"-"},"content":""},{"lineNumber":983,"author":{"gitId":"-"},"content":" ResponseOutput build() {"},{"lineNumber":984,"author":{"gitId":"-"},"content":" return responseOutput;"},{"lineNumber":985,"author":{"gitId":"-"},"content":" }"},{"lineNumber":986,"author":{"gitId":"-"},"content":" }"},{"lineNumber":987,"author":{"gitId":"-"},"content":" }"},{"lineNumber":988,"author":{"gitId":"-"},"content":""},{"lineNumber":989,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":990,"author":{"gitId":"-"},"content":" * API output format for response comments."},{"lineNumber":991,"author":{"gitId":"-"},"content":" */"},{"lineNumber":992,"author":{"gitId":"-"},"content":" public static final class CommentOutput extends FeedbackResponseCommentData {"},{"lineNumber":993,"author":{"gitId":"-"},"content":""},{"lineNumber":994,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":995,"author":{"gitId":"-"},"content":" private String commentGiverName;"},{"lineNumber":996,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":997,"author":{"gitId":"-"},"content":" private String lastEditorName;"},{"lineNumber":998,"author":{"gitId":"-"},"content":""},{"lineNumber":999,"author":{"gitId":"xenosf"},"content":" private CommentOutput(FeedbackResponseCommentAttributes frca) {"},{"lineNumber":1000,"author":{"gitId":"xenosf"},"content":" // use builder instead"},{"lineNumber":1001,"author":{"gitId":"xenosf"},"content":" super(frca);"},{"lineNumber":1002,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1003,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1004,"author":{"gitId":"xenosf"},"content":" private CommentOutput(FeedbackResponseComment frc) {"},{"lineNumber":1005,"author":{"gitId":"-"},"content":" // use builder instead"},{"lineNumber":1006,"author":{"gitId":"-"},"content":" super(frc);"},{"lineNumber":1007,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1008,"author":{"gitId":"-"},"content":""},{"lineNumber":1009,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1010,"author":{"gitId":"-"},"content":" * Returns a builder for {@link CommentOutput}."},{"lineNumber":1011,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1012,"author":{"gitId":"xenosf"},"content":" static Builder builder(FeedbackResponseCommentAttributes frca) {"},{"lineNumber":1013,"author":{"gitId":"xenosf"},"content":" return new Builder(frca);"},{"lineNumber":1014,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1015,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1016,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1017,"author":{"gitId":"xenosf"},"content":" * Returns a builder for {@link CommentOutput}."},{"lineNumber":1018,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1019,"author":{"gitId":"xenosf"},"content":" static Builder builder(FeedbackResponseComment frc) {"},{"lineNumber":1020,"author":{"gitId":"-"},"content":" return new Builder(frc);"},{"lineNumber":1021,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1022,"author":{"gitId":"-"},"content":""},{"lineNumber":1023,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":1024,"author":{"gitId":"-"},"content":" public String getCommentGiverName() {"},{"lineNumber":1025,"author":{"gitId":"-"},"content":" return commentGiverName;"},{"lineNumber":1026,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1027,"author":{"gitId":"-"},"content":""},{"lineNumber":1028,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":1029,"author":{"gitId":"-"},"content":" public String getLastEditorName() {"},{"lineNumber":1030,"author":{"gitId":"-"},"content":" return lastEditorName;"},{"lineNumber":1031,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1032,"author":{"gitId":"-"},"content":""},{"lineNumber":1033,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1034,"author":{"gitId":"-"},"content":" * Builder class for {@link CommentOutput}."},{"lineNumber":1035,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1036,"author":{"gitId":"-"},"content":" public static final class Builder {"},{"lineNumber":1037,"author":{"gitId":"-"},"content":" private final CommentOutput commentOutput;"},{"lineNumber":1038,"author":{"gitId":"-"},"content":""},{"lineNumber":1039,"author":{"gitId":"xenosf"},"content":" private Builder(FeedbackResponseCommentAttributes frca) {"},{"lineNumber":1040,"author":{"gitId":"xenosf"},"content":" commentOutput \u003d new CommentOutput(frca);"},{"lineNumber":1041,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1042,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1043,"author":{"gitId":"xenosf"},"content":" private Builder(FeedbackResponseComment frc) {"},{"lineNumber":1044,"author":{"gitId":"-"},"content":" commentOutput \u003d new CommentOutput(frc);"},{"lineNumber":1045,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1046,"author":{"gitId":"-"},"content":""},{"lineNumber":1047,"author":{"gitId":"-"},"content":" Builder withCommentGiver(@Nullable String commentGiver) {"},{"lineNumber":1048,"author":{"gitId":"-"},"content":" commentOutput.commentGiver \u003d commentGiver;"},{"lineNumber":1049,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":1050,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1051,"author":{"gitId":"-"},"content":""},{"lineNumber":1052,"author":{"gitId":"-"},"content":" Builder withCommentGiverName(@Nullable String commentGiverName) {"},{"lineNumber":1053,"author":{"gitId":"-"},"content":" commentOutput.commentGiverName \u003d commentGiverName;"},{"lineNumber":1054,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":1055,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1056,"author":{"gitId":"-"},"content":""},{"lineNumber":1057,"author":{"gitId":"-"},"content":" Builder withLastEditorEmail(@Nullable String lastEditorEmail) {"},{"lineNumber":1058,"author":{"gitId":"-"},"content":" commentOutput.lastEditorEmail \u003d lastEditorEmail;"},{"lineNumber":1059,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":1060,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1061,"author":{"gitId":"-"},"content":""},{"lineNumber":1062,"author":{"gitId":"-"},"content":" Builder withLastEditorName(@Nullable String lastEditorName) {"},{"lineNumber":1063,"author":{"gitId":"-"},"content":" commentOutput.lastEditorName \u003d lastEditorName;"},{"lineNumber":1064,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":1065,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1066,"author":{"gitId":"-"},"content":""},{"lineNumber":1067,"author":{"gitId":"-"},"content":" CommentOutput build() {"},{"lineNumber":1068,"author":{"gitId":"-"},"content":" return commentOutput;"},{"lineNumber":1069,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1070,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1071,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1072,"author":{"gitId":"-"},"content":""},{"lineNumber":1073,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":386,"-":687}},{"path":"src/main/java/teammates/ui/output/StudentData.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.output;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * The API output format of {@link StudentAttributes}."},{"lineNumber":12,"author":{"gitId":"-"},"content":" */"},{"lineNumber":13,"author":{"gitId":"-"},"content":"public class StudentData extends ApiOutput {"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":" @Nullable"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":" private final UUID studentId;"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":" private final String email;"},{"lineNumber":19,"author":{"gitId":"-"},"content":" private final String courseId;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" private final String name;"},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":23,"author":{"gitId":"-"},"content":" private String googleId;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":25,"author":{"gitId":"-"},"content":" private String comments;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":27,"author":{"gitId":"-"},"content":" private String key;"},{"lineNumber":28,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":29,"author":{"gitId":"-"},"content":" private String institute;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":31,"author":{"gitId":"-"},"content":" private JoinState joinState;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private final String teamName;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" private final String sectionName;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" public StudentData(StudentAttributes studentAttributes) {"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" this.studentId \u003d null;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" this.email \u003d studentAttributes.getEmail();"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.courseId \u003d studentAttributes.getCourse();"},{"lineNumber":40,"author":{"gitId":"-"},"content":" this.name \u003d studentAttributes.getName();"},{"lineNumber":41,"author":{"gitId":"-"},"content":" this.joinState \u003d studentAttributes.isRegistered() ? JoinState.JOINED : JoinState.NOT_JOINED;"},{"lineNumber":42,"author":{"gitId":"-"},"content":" this.comments \u003d studentAttributes.getComments();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" this.teamName \u003d studentAttributes.getTeam();"},{"lineNumber":44,"author":{"gitId":"-"},"content":" this.sectionName \u003d studentAttributes.getSection();"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" public StudentData(Student student) {"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" this.studentId \u003d student.getId();"},{"lineNumber":49,"author":{"gitId":"-"},"content":" this.email \u003d student.getEmail();"},{"lineNumber":50,"author":{"gitId":"-"},"content":" this.courseId \u003d student.getCourseId();"},{"lineNumber":51,"author":{"gitId":"-"},"content":" this.name \u003d student.getName();"},{"lineNumber":52,"author":{"gitId":"-"},"content":" this.joinState \u003d student.isRegistered() ? JoinState.JOINED : JoinState.NOT_JOINED;"},{"lineNumber":53,"author":{"gitId":"-"},"content":" this.comments \u003d student.getComments();"},{"lineNumber":54,"author":{"gitId":"-"},"content":" this.teamName \u003d student.getTeamName();"},{"lineNumber":55,"author":{"gitId":"-"},"content":" this.sectionName \u003d student.getSectionName();"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" public UUID getStudentId() {"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" return studentId;"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" public String getEmail() {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":64,"author":{"gitId":"-"},"content":" }"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" public String getCourseId() {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" return courseId;"},{"lineNumber":68,"author":{"gitId":"-"},"content":" }"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" public String getName() {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" return name;"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" public String getGoogleId() {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" return googleId;"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" public String getComments() {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" return comments;"},{"lineNumber":80,"author":{"gitId":"-"},"content":" }"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" public JoinState getJoinState() {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" return joinState;"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" public String getTeamName() {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" return teamName;"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" public String getSectionName() {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" return sectionName;"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" public String getKey() {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" return key;"},{"lineNumber":96,"author":{"gitId":"-"},"content":" }"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" public String getInstitute() {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" return institute;"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" public void setGoogleId(String googleId) {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" this.googleId \u003d googleId;"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" public void setComments(String comments) {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" this.comments \u003d comments;"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" public void setJoinState(JoinState joinState) {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" this.joinState \u003d joinState;"},{"lineNumber":112,"author":{"gitId":"-"},"content":" }"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" public void setKey(String key) {"},{"lineNumber":115,"author":{"gitId":"-"},"content":" this.key \u003d key;"},{"lineNumber":116,"author":{"gitId":"-"},"content":" }"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" public void setInstitute(String institute) {"},{"lineNumber":119,"author":{"gitId":"-"},"content":" this.institute \u003d institute;"},{"lineNumber":120,"author":{"gitId":"-"},"content":" }"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":123,"author":{"gitId":"-"},"content":" * Hides some attributes to student."},{"lineNumber":124,"author":{"gitId":"-"},"content":" */"},{"lineNumber":125,"author":{"gitId":"-"},"content":" public void hideInformationForStudent() {"},{"lineNumber":126,"author":{"gitId":"-"},"content":" setComments(null);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" setJoinState(null);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":131,"author":{"gitId":"-"},"content":" * Adds additional information only for search result for admin."},{"lineNumber":132,"author":{"gitId":"-"},"content":" * @param key The registration key"},{"lineNumber":133,"author":{"gitId":"-"},"content":" * @param institute The institute of the student"},{"lineNumber":134,"author":{"gitId":"-"},"content":" * @param googleId The googleId of the student"},{"lineNumber":135,"author":{"gitId":"-"},"content":" */"},{"lineNumber":136,"author":{"gitId":"-"},"content":" public void addAdditionalInformationForAdminSearch(String key, String institute, String googleId) {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" this.setKey(key);"},{"lineNumber":138,"author":{"gitId":"-"},"content":" this.setInstitute(institute);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" this.setGoogleId(googleId);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":11,"-":130}},{"path":"src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.ui.request;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import java.util.Objects;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":" * The request reasonBody for rejecting an account request."},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":"public class AccountRequestRejectionRequest extends BasicRequest {"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" @Nullable"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":" private String reasonTitle;"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" @Nullable"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" private String reasonBody;"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":" public AccountRequestRejectionRequest(String reasonTitle, String reasonBody) {"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" this.reasonTitle \u003d SanitizationHelper.sanitizeTitle(reasonTitle);"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" this.reasonBody \u003d SanitizationHelper.sanitizeForRichText(reasonBody);"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" public void validate() throws InvalidHttpRequestBodyException {"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" if (reasonBody \u003d\u003d null || reasonTitle \u003d\u003d null) {"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" assertTrue(Objects.equals(reasonBody, reasonTitle),"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" \"Both reason body and title need to be null to reject silently\");"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" public String getReasonTitle() {"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" return this.reasonTitle;"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" public String getReasonBody() {"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" return this.reasonBody;"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" * Returns true if both reason body and title are non-null."},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" public boolean checkHasReason() {"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" return this.reasonBody !\u003d null \u0026\u0026 this.reasonTitle !\u003d null;"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":45,"-":1}},{"path":"src/main/java/teammates/ui/request/AccountRequestUpdateRequest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.ui.request;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":" * The create request for an account request update request."},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"public class AccountRequestUpdateRequest extends BasicRequest {"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":" private String name;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":" private String email;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":" private String institute;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" private AccountRequestStatus status;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" @Nullable"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" private String comments;"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" public AccountRequestUpdateRequest(String name, String email, String institute, AccountRequestStatus status,"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" String comments) {"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" this.name \u003d SanitizationHelper.sanitizeName(name);"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" this.email \u003d SanitizationHelper.sanitizeEmail(email);"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" this.institute \u003d SanitizationHelper.sanitizeName(institute);"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" this.status \u003d status;"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" if (comments !\u003d null) {"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" this.comments \u003d SanitizationHelper.sanitizeTextField(comments);"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" public void validate() throws InvalidHttpRequestBodyException {"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" assertTrue(name !\u003d null, \"name cannot be null\");"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" assertTrue(email !\u003d null, \"email cannot be null\");"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" assertTrue(institute !\u003d null, \"institute cannot be null\");"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" assertTrue(status !\u003d null, \"status cannot be null\");"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" assertTrue(status \u003d\u003d AccountRequestStatus.APPROVED"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" || status \u003d\u003d AccountRequestStatus.REJECTED"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" || status \u003d\u003d AccountRequestStatus.PENDING"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" || status \u003d\u003d AccountRequestStatus.REGISTERED,"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" \"status must be one of the following: APPROVED, REJECTED, PENDING, REGISTERED\");"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" public String getName() {"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" return this.name;"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" public String getEmail() {"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" return this.email;"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" public String getInstitute() {"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" return this.institute;"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" public AccountRequestStatus getStatus() {"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" return this.status;"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" public String getComments() {"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" return this.comments;"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":62,"-":1}},{"path":"src/main/java/teammates/ui/webapi/AccountRequestSearchIndexingWorkerAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.ParamsNames;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":12,"author":{"gitId":"-"},"content":" * Task queue worker action: performs account request search indexing."},{"lineNumber":13,"author":{"gitId":"-"},"content":" */"},{"lineNumber":14,"author":{"gitId":"-"},"content":"public class AccountRequestSearchIndexingWorkerAction extends AdminOnlyAction {"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":17,"author":{"gitId":"-"},"content":" public ActionResult execute() {"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" String id \u003d getNonNullRequestParamValue(ParamsNames.ACCOUNT_REQUEST_ID);"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" UUID accountRequestId;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" accountRequestId \u003d UUID.fromString(id);"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" } catch (IllegalArgumentException e) {"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" throw new InvalidHttpParameterException(e.getMessage(), e);"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" AccountRequest accRequest \u003d sqlLogic.getAccountRequest(accountRequestId);"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" sqlLogic.putAccountRequestDocument(accRequest);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" // Set an arbitrary retry code outside of the range 200-299 to trigger automatic retry"},{"lineNumber":33,"author":{"gitId":"-"},"content":" return new JsonResult(\"Failure\", HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" return new JsonResult(\"Successful\");"},{"lineNumber":37,"author":{"gitId":"-"},"content":" }"},{"lineNumber":38,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":13,"-":25}},{"path":"src/main/java/teammates/ui/webapi/ActionFactory.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import jakarta.servlet.http.HttpServletRequest;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpDelete;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpGet;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpPost;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpPut;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.CronJobURIs;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.ResourceURIs;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.TaskQueue;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * Generates the matching {@link Action} for a given URI and request method."},{"lineNumber":20,"author":{"gitId":"-"},"content":" */"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public final class ActionFactory {"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" static final Map\u003cString, Map\u003cString, Class\u003c? extends Action\u003e\u003e\u003e ACTION_MAPPINGS \u003d new HashMap\u003c\u003e();"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" private static final String GET \u003d HttpGet.METHOD_NAME;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" private static final String POST \u003d HttpPost.METHOD_NAME;"},{"lineNumber":27,"author":{"gitId":"-"},"content":" private static final String PUT \u003d HttpPut.METHOD_NAME;"},{"lineNumber":28,"author":{"gitId":"-"},"content":" private static final String DELETE \u003d HttpDelete.METHOD_NAME;"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" static {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" map(ResourceURIs.DATABUNDLE, POST, PutDataBundleAction.class);"},{"lineNumber":32,"author":{"gitId":"-"},"content":" // Even though this is a DELETE action, PUT is used as DELETE does not allow usage of response body"},{"lineNumber":33,"author":{"gitId":"-"},"content":" map(ResourceURIs.DATABUNDLE, PUT, DeleteDataBundleAction.class);"},{"lineNumber":34,"author":{"gitId":"-"},"content":" map(ResourceURIs.SQL_DATABUNDLE, POST, PutSqlDataBundleAction.class);"},{"lineNumber":35,"author":{"gitId":"-"},"content":" // Even though this is a DELETE action, PUT is used as DELETE does not allow usage of response body"},{"lineNumber":36,"author":{"gitId":"-"},"content":" map(ResourceURIs.SQL_DATABUNDLE, PUT, DeleteSqlDataBundleAction.class);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" map(ResourceURIs.DATABUNDLE_DOCUMENTS, PUT, PutDataBundleDocumentsAction.class);"},{"lineNumber":38,"author":{"gitId":"-"},"content":" map(ResourceURIs.EXCEPTION, GET, AdminExceptionTestAction.class);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" // Even though this is a GET action, POST is used in order to get extra protection from CSRF"},{"lineNumber":40,"author":{"gitId":"-"},"content":" map(ResourceURIs.USER_COOKIE, POST, GetUserCookieAction.class);"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" map(ResourceURIs.ERROR_REPORT, POST, SendErrorReportAction.class);"},{"lineNumber":43,"author":{"gitId":"-"},"content":" map(ResourceURIs.TIMEZONE, GET, GetTimeZonesAction.class);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" map(ResourceURIs.AUTH, GET, GetAuthInfoAction.class);"},{"lineNumber":45,"author":{"gitId":"-"},"content":" map(ResourceURIs.AUTH_REGKEY, GET, GetRegkeyValidityAction.class);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNT, GET, GetAccountAction.class);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNT, POST, CreateAccountAction.class);"},{"lineNumber":48,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNT, DELETE, DeleteAccountAction.class);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNT_RESET, PUT, ResetAccountAction.class);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNT_REQUEST, GET, GetAccountRequestAction.class);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNT_REQUEST, POST, CreateAccountRequestAction.class);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNT_REQUEST, DELETE, DeleteAccountRequestAction.class);"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" map(ResourceURIs.ACCOUNT_REQUEST, PUT, UpdateAccountRequestAction.class);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNT_REQUESTS, GET, GetAccountRequestsAction.class);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNT_REQUEST_RESET, PUT, ResetAccountRequestAction.class);"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" map(ResourceURIs.ACCOUNT_REQUEST_REJECTION, POST, RejectAccountRequestAction.class);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNTS, GET, GetAccountsAction.class);"},{"lineNumber":58,"author":{"gitId":"-"},"content":" map(ResourceURIs.COURSE, GET, GetCourseAction.class);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" map(ResourceURIs.COURSE, DELETE, DeleteCourseAction.class);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" map(ResourceURIs.COURSE, POST, CreateCourseAction.class);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" map(ResourceURIs.COURSE, PUT, UpdateCourseAction.class);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" map(ResourceURIs.COURSE_ARCHIVE, PUT, ArchiveCourseAction.class);"},{"lineNumber":63,"author":{"gitId":"-"},"content":" map(ResourceURIs.DEADLINE_EXTENSION, GET, GetDeadlineExtensionAction.class);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" map(ResourceURIs.BIN_COURSE, PUT, BinCourseAction.class);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" map(ResourceURIs.BIN_COURSE, DELETE, RestoreCourseAction.class);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" map(ResourceURIs.COURSES, GET, GetCoursesAction.class);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" map(ResourceURIs.COURSE_SECTIONS, GET, GetCourseSectionNamesAction.class);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" map(ResourceURIs.INSTRUCTORS, GET, GetInstructorsAction.class);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" map(ResourceURIs.INSTRUCTOR, GET, GetInstructorAction.class);"},{"lineNumber":70,"author":{"gitId":"-"},"content":" map(ResourceURIs.INSTRUCTOR, DELETE, DeleteInstructorAction.class);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" map(ResourceURIs.INSTRUCTOR_PRIVILEGE, GET, GetInstructorPrivilegeAction.class);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" map(ResourceURIs.INSTRUCTOR_PRIVILEGE, PUT, UpdateInstructorPrivilegeAction.class);"},{"lineNumber":73,"author":{"gitId":"-"},"content":" map(ResourceURIs.RESPONSE_COMMENT, POST, CreateFeedbackResponseCommentAction.class);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" map(ResourceURIs.RESPONSE_COMMENT, GET, GetFeedbackResponseCommentAction.class);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" map(ResourceURIs.RESPONSE_COMMENT, PUT, UpdateFeedbackResponseCommentAction.class);"},{"lineNumber":76,"author":{"gitId":"-"},"content":" map(ResourceURIs.RESPONSE_COMMENT, DELETE, DeleteFeedbackResponseCommentAction.class);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" map(ResourceURIs.RESULT, GET, GetSessionResultsAction.class);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" map(ResourceURIs.LOGIN_EMAIL, POST, SendLoginEmailAction.class);"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" //STUDENTS APIs"},{"lineNumber":81,"author":{"gitId":"-"},"content":" map(ResourceURIs.STUDENTS, GET, GetStudentsAction.class);"},{"lineNumber":82,"author":{"gitId":"-"},"content":" map(ResourceURIs.STUDENTS, PUT, EnrollStudentsAction.class);"},{"lineNumber":83,"author":{"gitId":"-"},"content":" map(ResourceURIs.STUDENTS, DELETE, DeleteStudentsAction.class);"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" //STUDENT APIs"},{"lineNumber":86,"author":{"gitId":"-"},"content":" map(ResourceURIs.STUDENT, DELETE, DeleteStudentAction.class);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" map(ResourceURIs.STUDENT, GET, GetStudentAction.class);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" map(ResourceURIs.STUDENT, PUT, UpdateStudentAction.class);"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" // NOTIFICATION APIs"},{"lineNumber":91,"author":{"gitId":"-"},"content":" map(ResourceURIs.NOTIFICATION, GET, GetNotificationAction.class);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" map(ResourceURIs.NOTIFICATION, POST, CreateNotificationAction.class);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" map(ResourceURIs.NOTIFICATION, PUT, UpdateNotificationAction.class);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" map(ResourceURIs.NOTIFICATION, DELETE, DeleteNotificationAction.class);"},{"lineNumber":95,"author":{"gitId":"-"},"content":" map(ResourceURIs.NOTIFICATION_READ, POST, MarkNotificationAsReadAction.class);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" map(ResourceURIs.NOTIFICATION_READ, GET, GetReadNotificationsAction.class);"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" // NOTIFICATIONS APIs"},{"lineNumber":99,"author":{"gitId":"-"},"content":" map(ResourceURIs.NOTIFICATIONS, GET, GetNotificationsAction.class);"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" //SEARCH APIs"},{"lineNumber":102,"author":{"gitId":"-"},"content":" map(ResourceURIs.SEARCH_INSTRUCTORS, GET, SearchInstructorsAction.class);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" map(ResourceURIs.SEARCH_STUDENTS, GET, SearchStudentsAction.class);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" map(ResourceURIs.SEARCH_ACCOUNT_REQUESTS, GET, SearchAccountRequestsAction.class);"},{"lineNumber":105,"author":{"gitId":"-"},"content":" map(ResourceURIs.EMAIL, GET, GenerateEmailAction.class);"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSIONS_ONGOING, GET, GetOngoingSessionsAction.class);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION_STATS, GET, GetSessionResponseStatsAction.class);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION, GET, GetFeedbackSessionAction.class);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION, PUT, UpdateFeedbackSessionAction.class);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION, POST, CreateFeedbackSessionAction.class);"},{"lineNumber":112,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION, DELETE, DeleteFeedbackSessionAction.class);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION_PUBLISH, POST, PublishFeedbackSessionAction.class);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION_PUBLISH, DELETE, UnpublishFeedbackSessionAction.class);"},{"lineNumber":115,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION_SUBMITTED_GIVER_SET, GET, GetFeedbackSessionSubmittedGiverSetAction.class);"},{"lineNumber":116,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION_REMIND_SUBMISSION, POST, RemindFeedbackSessionSubmissionAction.class);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION_REMIND_RESULT, POST, RemindFeedbackSessionResultAction.class);"},{"lineNumber":118,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSIONS, GET, GetFeedbackSessionsAction.class);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" map(ResourceURIs.BIN_SESSION, PUT, BinFeedbackSessionAction.class);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" map(ResourceURIs.BIN_SESSION, DELETE, RestoreFeedbackSessionAction.class);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" map(ResourceURIs.INSTRUCTOR_KEY, POST, RegenerateInstructorKeyAction.class);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" map(ResourceURIs.STUDENT_KEY, POST, RegenerateStudentKeyAction.class);"},{"lineNumber":123,"author":{"gitId":"-"},"content":" map(ResourceURIs.QUESTIONS, GET, GetFeedbackQuestionsAction.class);"},{"lineNumber":124,"author":{"gitId":"-"},"content":" map(ResourceURIs.QUESTION, POST, CreateFeedbackQuestionAction.class);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" map(ResourceURIs.QUESTION, PUT, UpdateFeedbackQuestionAction.class);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" map(ResourceURIs.QUESTION, DELETE, DeleteFeedbackQuestionAction.class);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" map(ResourceURIs.QUESTION_RECIPIENTS, GET, GetFeedbackQuestionRecipientsAction.class);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" map(ResourceURIs.RESPONSES, GET, GetFeedbackResponsesAction.class);"},{"lineNumber":129,"author":{"gitId":"-"},"content":" map(ResourceURIs.RESPONSES, PUT, SubmitFeedbackResponsesAction.class);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" map(ResourceURIs.HAS_RESPONSES, GET, GetHasResponsesAction.class);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION_LINKS_RECOVERY, POST, SessionLinksRecoveryAction.class);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" map(ResourceURIs.JOIN, GET, GetCourseJoinStatusAction.class);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" map(ResourceURIs.JOIN, PUT, JoinCourseAction.class);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" map(ResourceURIs.JOIN_REMIND, POST, SendJoinReminderEmailAction.class);"},{"lineNumber":135,"author":{"gitId":"-"},"content":" map(ResourceURIs.INSTRUCTOR, PUT, UpdateInstructorAction.class);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" map(ResourceURIs.INSTRUCTOR, POST, CreateInstructorAction.class);"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" // Logging and tracking"},{"lineNumber":139,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION_LOGS, POST, CreateFeedbackSessionLogAction.class);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION_LOGS, GET, GetFeedbackSessionLogsAction.class);"},{"lineNumber":141,"author":{"gitId":"-"},"content":" map(ResourceURIs.LOGS, GET, QueryLogsAction.class);"},{"lineNumber":142,"author":{"gitId":"-"},"content":" map(ResourceURIs.USAGE_STATISTICS, GET, GetUsageStatisticsAction.class);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACTION_CLASS, GET, GetActionClassesAction.class);"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" // Cron jobs; use GET request"},{"lineNumber":146,"author":{"gitId":"-"},"content":" // Reference: https://cloud.google.com/appengine/docs/standard/scheduling-jobs-with-cron-yaml"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" map(CronJobURIs.AUTOMATED_LOG_COMPILATION, GET, CompileLogsAction.class);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" map(CronJobURIs.AUTOMATED_DATASTORE_BACKUP, GET, DatastoreBackupAction.class);"},{"lineNumber":150,"author":{"gitId":"-"},"content":" map(CronJobURIs.AUTOMATED_FEEDBACK_OPENING_REMINDERS, GET, FeedbackSessionOpeningRemindersAction.class);"},{"lineNumber":151,"author":{"gitId":"-"},"content":" map(CronJobURIs.AUTOMATED_FEEDBACK_CLOSED_REMINDERS, GET, FeedbackSessionClosedRemindersAction.class);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" map(CronJobURIs.AUTOMATED_FEEDBACK_CLOSING_REMINDERS, GET, FeedbackSessionClosingRemindersAction.class);"},{"lineNumber":153,"author":{"gitId":"-"},"content":" map(CronJobURIs.AUTOMATED_FEEDBACK_PUBLISHED_REMINDERS, GET, FeedbackSessionPublishedRemindersAction.class);"},{"lineNumber":154,"author":{"gitId":"-"},"content":" map(CronJobURIs.AUTOMATED_FEEDBACK_OPENING_SOON_REMINDERS, GET,"},{"lineNumber":155,"author":{"gitId":"-"},"content":" FeedbackSessionOpeningSoonRemindersAction.class);"},{"lineNumber":156,"author":{"gitId":"-"},"content":" map(CronJobURIs.AUTOMATED_USAGE_STATISTICS_COLLECTION, GET, CalculateUsageStatisticsAction.class);"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":" map(CronJobURIs.AUTOMATED_FEEDBACK_SESSION_LOGS_PROCESSING, GET, UpdateFeedbackSessionLogsAction.class);"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" // Task queue workers; use POST request"},{"lineNumber":160,"author":{"gitId":"-"},"content":" // Reference: https://cloud.google.com/tasks/docs/creating-appengine-tasks"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"-"},"content":" map(TaskQueue.FEEDBACK_SESSION_PUBLISHED_EMAIL_WORKER_URL, POST, FeedbackSessionPublishedEmailWorkerAction.class);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" map(TaskQueue.FEEDBACK_SESSION_RESEND_PUBLISHED_EMAIL_WORKER_URL, POST,"},{"lineNumber":164,"author":{"gitId":"-"},"content":" FeedbackSessionResendPublishedEmailWorkerAction.class);"},{"lineNumber":165,"author":{"gitId":"-"},"content":" map(TaskQueue.FEEDBACK_SESSION_REMIND_EMAIL_WORKER_URL, POST, FeedbackSessionRemindEmailWorkerAction.class);"},{"lineNumber":166,"author":{"gitId":"-"},"content":" map(TaskQueue.FEEDBACK_SESSION_REMIND_PARTICULAR_USERS_EMAIL_WORKER_URL, POST,"},{"lineNumber":167,"author":{"gitId":"-"},"content":" FeedbackSessionRemindParticularUsersEmailWorkerAction.class);"},{"lineNumber":168,"author":{"gitId":"-"},"content":" map(TaskQueue.FEEDBACK_SESSION_UNPUBLISHED_EMAIL_WORKER_URL, POST,"},{"lineNumber":169,"author":{"gitId":"-"},"content":" FeedbackSessionUnpublishedEmailWorkerAction.class);"},{"lineNumber":170,"author":{"gitId":"-"},"content":" map(TaskQueue.INSTRUCTOR_COURSE_JOIN_EMAIL_WORKER_URL, POST, InstructorCourseJoinEmailWorkerAction.class);"},{"lineNumber":171,"author":{"gitId":"-"},"content":" map(TaskQueue.SEND_EMAIL_WORKER_URL, POST, SendEmailWorkerAction.class);"},{"lineNumber":172,"author":{"gitId":"-"},"content":" map(TaskQueue.STUDENT_COURSE_JOIN_EMAIL_WORKER_URL, POST, StudentCourseJoinEmailWorkerAction.class);"},{"lineNumber":173,"author":{"gitId":"-"},"content":" map(TaskQueue.ACCOUNT_REQUEST_SEARCH_INDEXING_WORKER_URL, POST, AccountRequestSearchIndexingWorkerAction.class);"},{"lineNumber":174,"author":{"gitId":"-"},"content":" map(TaskQueue.INSTRUCTOR_SEARCH_INDEXING_WORKER_URL, POST, InstructorSearchIndexingWorkerAction.class);"},{"lineNumber":175,"author":{"gitId":"-"},"content":" map(TaskQueue.STUDENT_SEARCH_INDEXING_WORKER_URL, POST, StudentSearchIndexingWorkerAction.class);"},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" private ActionFactory() {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" private static void map(String uri, String method, Class\u003c? extends Action\u003e actionClass) {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" ACTION_MAPPINGS.computeIfAbsent(uri, k -\u003e new HashMap\u003c\u003e()).put(method, actionClass);"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":188,"author":{"gitId":"-"},"content":" * Returns the matching {@link Action} object for the URI and method in {@code req}."},{"lineNumber":189,"author":{"gitId":"-"},"content":" */"},{"lineNumber":190,"author":{"gitId":"-"},"content":" public static Action getAction(HttpServletRequest req, String method) throws ActionMappingException {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" String uri \u003d req.getRequestURI();"},{"lineNumber":192,"author":{"gitId":"-"},"content":" if (uri.contains(\";\")) {"},{"lineNumber":193,"author":{"gitId":"-"},"content":" uri \u003d uri.split(\";\")[0];"},{"lineNumber":194,"author":{"gitId":"-"},"content":" }"},{"lineNumber":195,"author":{"gitId":"-"},"content":" return getAction(uri, method);"},{"lineNumber":196,"author":{"gitId":"-"},"content":" }"},{"lineNumber":197,"author":{"gitId":"-"},"content":""},{"lineNumber":198,"author":{"gitId":"-"},"content":" private static Action getAction(String uri, String method) throws ActionMappingException {"},{"lineNumber":199,"author":{"gitId":"-"},"content":" if (!ACTION_MAPPINGS.containsKey(uri)) {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" throw new ActionMappingException(\"Resource with URI \" + uri + \" is not found.\", HttpStatus.SC_NOT_FOUND);"},{"lineNumber":201,"author":{"gitId":"-"},"content":" }"},{"lineNumber":202,"author":{"gitId":"-"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":" Class\u003c? extends Action\u003e controllerClass \u003d"},{"lineNumber":204,"author":{"gitId":"-"},"content":" ACTION_MAPPINGS.getOrDefault(uri, new HashMap\u003c\u003e()).get(method);"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" if (controllerClass \u003d\u003d null) {"},{"lineNumber":207,"author":{"gitId":"-"},"content":" throw new ActionMappingException(\"Method [\" + method + \"] is not allowed for URI \" + uri + \".\","},{"lineNumber":208,"author":{"gitId":"-"},"content":" HttpStatus.SC_METHOD_NOT_ALLOWED);"},{"lineNumber":209,"author":{"gitId":"-"},"content":" }"},{"lineNumber":210,"author":{"gitId":"-"},"content":""},{"lineNumber":211,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" return controllerClass.getDeclaredConstructor().newInstance();"},{"lineNumber":213,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":214,"author":{"gitId":"-"},"content":" assert false : \"Could not create the action for \" + uri;"},{"lineNumber":215,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":216,"author":{"gitId":"-"},"content":" }"},{"lineNumber":217,"author":{"gitId":"-"},"content":" }"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":1,"xenosf":1,"dishenggg":1,"-":216}},{"path":"src/main/java/teammates/ui/webapi/BasicFeedbackSubmissionAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.StringHelper;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * The basic action for feedback submission."},{"lineNumber":18,"author":{"gitId":"-"},"content":" */"},{"lineNumber":19,"author":{"gitId":"-"},"content":"abstract class BasicFeedbackSubmissionAction extends Action {"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * Checks whether instructors can see the question."},{"lineNumber":23,"author":{"gitId":"-"},"content":" */"},{"lineNumber":24,"author":{"gitId":"-"},"content":" boolean canInstructorSeeQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" boolean isGiverVisibleToInstructor \u003d"},{"lineNumber":26,"author":{"gitId":"-"},"content":" feedbackQuestion.getShowGiverNameTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":27,"author":{"gitId":"-"},"content":" boolean isRecipientVisibleToInstructor \u003d"},{"lineNumber":28,"author":{"gitId":"-"},"content":" feedbackQuestion.getShowRecipientNameTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":29,"author":{"gitId":"-"},"content":" boolean isResponseVisibleToInstructor \u003d"},{"lineNumber":30,"author":{"gitId":"-"},"content":" feedbackQuestion.getShowResponsesTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" return isResponseVisibleToInstructor \u0026\u0026 isGiverVisibleToInstructor \u0026\u0026 isRecipientVisibleToInstructor;"},{"lineNumber":32,"author":{"gitId":"-"},"content":" }"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":35,"author":{"gitId":"-"},"content":" * Checks whether instructors can see the question."},{"lineNumber":36,"author":{"gitId":"-"},"content":" */"},{"lineNumber":37,"author":{"gitId":"-"},"content":" boolean canInstructorSeeQuestion(FeedbackQuestion feedbackQuestion) {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" boolean isGiverVisibleToInstructor \u003d"},{"lineNumber":39,"author":{"gitId":"-"},"content":" feedbackQuestion.getShowGiverNameTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":40,"author":{"gitId":"-"},"content":" boolean isRecipientVisibleToInstructor \u003d"},{"lineNumber":41,"author":{"gitId":"-"},"content":" feedbackQuestion.getShowRecipientNameTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":42,"author":{"gitId":"-"},"content":" boolean isResponseVisibleToInstructor \u003d"},{"lineNumber":43,"author":{"gitId":"-"},"content":" feedbackQuestion.getShowResponsesTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return isResponseVisibleToInstructor \u0026\u0026 isGiverVisibleToInstructor \u0026\u0026 isRecipientVisibleToInstructor;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":48,"author":{"gitId":"-"},"content":" * Verifies that instructor can see the moderated question in moderation request."},{"lineNumber":49,"author":{"gitId":"-"},"content":" */"},{"lineNumber":50,"author":{"gitId":"-"},"content":" void verifyInstructorCanSeeQuestionIfInModeration(FeedbackQuestionAttributes feedbackQuestion)"},{"lineNumber":51,"author":{"gitId":"-"},"content":" throws UnauthorizedAccessException {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson) \u0026\u0026 !canInstructorSeeQuestion(feedbackQuestion)) {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" // should not moderate question which instructors cannot see"},{"lineNumber":56,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"The question is not applicable for moderation\", true);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":61,"author":{"gitId":"-"},"content":" * Verifies that instructor can see the moderated question in moderation request."},{"lineNumber":62,"author":{"gitId":"-"},"content":" */"},{"lineNumber":63,"author":{"gitId":"-"},"content":" void verifyInstructorCanSeeQuestionIfInModeration(FeedbackQuestion feedbackQuestion)"},{"lineNumber":64,"author":{"gitId":"-"},"content":" throws UnauthorizedAccessException {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson) \u0026\u0026 !canInstructorSeeQuestion(feedbackQuestion)) {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" // should not moderate question which instructors cannot see"},{"lineNumber":69,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"The question is not applicable for moderation\", true);"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":74,"author":{"gitId":"-"},"content":" * Gets the student involved in the submission process."},{"lineNumber":75,"author":{"gitId":"-"},"content":" */"},{"lineNumber":76,"author":{"gitId":"-"},"content":" StudentAttributes getStudentOfCourseFromRequest(String courseId) {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson)) {"},{"lineNumber":81,"author":{"gitId":"-"},"content":" return logic.getStudentForEmail(courseId, moderatedPerson);"},{"lineNumber":82,"author":{"gitId":"-"},"content":" } else if (!StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" return logic.getStudentForEmail(courseId, previewAsPerson);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" return getPossiblyUnregisteredStudent(courseId);"},{"lineNumber":86,"author":{"gitId":"-"},"content":" }"},{"lineNumber":87,"author":{"gitId":"-"},"content":" }"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":90,"author":{"gitId":"-"},"content":" * Gets the student involved in the submission process."},{"lineNumber":91,"author":{"gitId":"-"},"content":" */"},{"lineNumber":92,"author":{"gitId":"-"},"content":" Student getSqlStudentOfCourseFromRequest(String courseId) {"},{"lineNumber":93,"author":{"gitId":"-"},"content":" // TODO: Rename method to remove Sql after migration."},{"lineNumber":94,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":95,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson)) {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" return sqlLogic.getStudentForEmail(courseId, moderatedPerson);"},{"lineNumber":99,"author":{"gitId":"-"},"content":" } else if (!StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" return sqlLogic.getStudentForEmail(courseId, previewAsPerson);"},{"lineNumber":101,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" return getPossiblyUnregisteredSqlStudent(courseId);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" }"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":107,"author":{"gitId":"-"},"content":" * Checks the access control for student feedback submission."},{"lineNumber":108,"author":{"gitId":"-"},"content":" */"},{"lineNumber":109,"author":{"gitId":"-"},"content":" void checkAccessControlForStudentFeedbackSubmission("},{"lineNumber":110,"author":{"gitId":"-"},"content":" StudentAttributes student, FeedbackSessionAttributes feedbackSession) throws UnauthorizedAccessException {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Trying to access system using a non-existent student entity\");"},{"lineNumber":113,"author":{"gitId":"-"},"content":" }"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":116,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson)) {"},{"lineNumber":119,"author":{"gitId":"-"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":121,"author":{"gitId":"-"},"content":" logic.getInstructorForGoogleId(feedbackSession.getCourseId(), userInfo.getId()), feedbackSession,"},{"lineNumber":122,"author":{"gitId":"-"},"content":" student.getSection(),"},{"lineNumber":123,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_MODIFY_SESSION_COMMENT_IN_SECTIONS);"},{"lineNumber":124,"author":{"gitId":"-"},"content":" } else if (!StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" checkAccessControlForPreview(feedbackSession, false);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":127,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(student, feedbackSession);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" verifyMatchingGoogleId(student.getGoogleId());"},{"lineNumber":129,"author":{"gitId":"-"},"content":" }"},{"lineNumber":130,"author":{"gitId":"-"},"content":" }"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":133,"author":{"gitId":"-"},"content":" * Checks the access control for student feedback submission."},{"lineNumber":134,"author":{"gitId":"-"},"content":" */"},{"lineNumber":135,"author":{"gitId":"-"},"content":" void checkAccessControlForStudentFeedbackSubmission(Student student, FeedbackSession feedbackSession)"},{"lineNumber":136,"author":{"gitId":"-"},"content":" throws UnauthorizedAccessException {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":138,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Trying to access system using a non-existent student entity\");"},{"lineNumber":139,"author":{"gitId":"-"},"content":" }"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":142,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson)) {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":147,"author":{"gitId":"-"},"content":" sqlLogic.getInstructorByGoogleId(feedbackSession.getCourse().getId(), userInfo.getId()), feedbackSession,"},{"lineNumber":148,"author":{"gitId":"-"},"content":" student.getSectionName(),"},{"lineNumber":149,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_MODIFY_SESSION_COMMENT_IN_SECTIONS);"},{"lineNumber":150,"author":{"gitId":"-"},"content":" } else if (!StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":153,"author":{"gitId":"-"},"content":" sqlLogic.getInstructorByGoogleId(feedbackSession.getCourse().getId(), userInfo.getId()), feedbackSession,"},{"lineNumber":154,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":155,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(student, feedbackSession);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" if (student.getAccount() !\u003d null) {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" if (userInfo \u003d\u003d null) {"},{"lineNumber":159,"author":{"gitId":"-"},"content":" // Student is associated with an account; even if registration key is passed, do not allow access"},{"lineNumber":160,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Login is required to access this feedback session\");"},{"lineNumber":161,"author":{"gitId":"-"},"content":" } else if (!userInfo.id.equals(student.getAccount().getGoogleId())) {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" // Logged in student is not the same as the student registered for the given key, do not allow access"},{"lineNumber":163,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"You are not authorized to access this feedback session\");"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":" }"},{"lineNumber":167,"author":{"gitId":"-"},"content":" }"},{"lineNumber":168,"author":{"gitId":"-"},"content":""},{"lineNumber":169,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":170,"author":{"gitId":"-"},"content":" * Checks the access control for student feedback result."},{"lineNumber":171,"author":{"gitId":"-"},"content":" */"},{"lineNumber":172,"author":{"gitId":"-"},"content":" void checkAccessControlForStudentFeedbackResult("},{"lineNumber":173,"author":{"gitId":"-"},"content":" StudentAttributes student, FeedbackSessionAttributes feedbackSession) throws UnauthorizedAccessException {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":175,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Trying to access system using a non-existent student entity\");"},{"lineNumber":176,"author":{"gitId":"-"},"content":" }"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" if (StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":181,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(student, feedbackSession);"},{"lineNumber":182,"author":{"gitId":"-"},"content":" verifyMatchingGoogleId(student.getGoogleId());"},{"lineNumber":183,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" checkAccessControlForPreview(feedbackSession, false);"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":" }"},{"lineNumber":187,"author":{"gitId":"-"},"content":""},{"lineNumber":188,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":189,"author":{"gitId":"xenosf"},"content":" * Checks the access control for student feedback result."},{"lineNumber":190,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":191,"author":{"gitId":"xenosf"},"content":" void checkAccessControlForStudentFeedbackResult("},{"lineNumber":192,"author":{"gitId":"xenosf"},"content":" Student student, FeedbackSession feedbackSession) throws UnauthorizedAccessException {"},{"lineNumber":193,"author":{"gitId":"xenosf"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":194,"author":{"gitId":"xenosf"},"content":" throw new UnauthorizedAccessException(\"Trying to access system using a non-existent student entity\");"},{"lineNumber":195,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":196,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":197,"author":{"gitId":"xenosf"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":198,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":199,"author":{"gitId":"xenosf"},"content":" if (StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":200,"author":{"gitId":"xenosf"},"content":" gateKeeper.verifyAccessible(student, feedbackSession);"},{"lineNumber":201,"author":{"gitId":"xenosf"},"content":" verifyMatchingGoogleId(student.getGoogleId());"},{"lineNumber":202,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":203,"author":{"gitId":"xenosf"},"content":" checkAccessControlForPreview(feedbackSession, false);"},{"lineNumber":204,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":205,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":206,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":207,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":208,"author":{"gitId":"-"},"content":" * Gets the instructor involved in the submission process."},{"lineNumber":209,"author":{"gitId":"-"},"content":" */"},{"lineNumber":210,"author":{"gitId":"-"},"content":" InstructorAttributes getInstructorOfCourseFromRequest(String courseId) {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":212,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson)) {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" return logic.getInstructorForEmail(courseId, moderatedPerson);"},{"lineNumber":216,"author":{"gitId":"-"},"content":" } else if (!StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":217,"author":{"gitId":"-"},"content":" return logic.getInstructorForEmail(courseId, previewAsPerson);"},{"lineNumber":218,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":219,"author":{"gitId":"-"},"content":" return getPossiblyUnregisteredInstructor(courseId);"},{"lineNumber":220,"author":{"gitId":"-"},"content":" }"},{"lineNumber":221,"author":{"gitId":"-"},"content":" }"},{"lineNumber":222,"author":{"gitId":"-"},"content":""},{"lineNumber":223,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":224,"author":{"gitId":"-"},"content":" * Gets the instructor involved in the submission process."},{"lineNumber":225,"author":{"gitId":"-"},"content":" */"},{"lineNumber":226,"author":{"gitId":"-"},"content":" Instructor getSqlInstructorOfCourseFromRequest(String courseId) {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":228,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":229,"author":{"gitId":"-"},"content":""},{"lineNumber":230,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson)) {"},{"lineNumber":231,"author":{"gitId":"-"},"content":" return sqlLogic.getInstructorForEmail(courseId, moderatedPerson);"},{"lineNumber":232,"author":{"gitId":"-"},"content":" } else if (!StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":233,"author":{"gitId":"-"},"content":" return sqlLogic.getInstructorForEmail(courseId, previewAsPerson);"},{"lineNumber":234,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":235,"author":{"gitId":"-"},"content":" return getPossiblyUnregisteredSqlInstructor(courseId);"},{"lineNumber":236,"author":{"gitId":"-"},"content":" }"},{"lineNumber":237,"author":{"gitId":"-"},"content":" }"},{"lineNumber":238,"author":{"gitId":"-"},"content":""},{"lineNumber":239,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":240,"author":{"gitId":"-"},"content":" * Checks the access control for instructor feedback submission."},{"lineNumber":241,"author":{"gitId":"-"},"content":" */"},{"lineNumber":242,"author":{"gitId":"-"},"content":" void checkAccessControlForInstructorFeedbackSubmission("},{"lineNumber":243,"author":{"gitId":"-"},"content":" InstructorAttributes instructor, FeedbackSessionAttributes feedbackSession) throws UnauthorizedAccessException {"},{"lineNumber":244,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Trying to access system using a non-existent instructor entity\");"},{"lineNumber":246,"author":{"gitId":"-"},"content":" }"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":249,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":250,"author":{"gitId":"-"},"content":""},{"lineNumber":251,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson)) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":253,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(logic.getInstructorForGoogleId(feedbackSession.getCourseId(), userInfo.getId()),"},{"lineNumber":254,"author":{"gitId":"-"},"content":" feedbackSession, Const.InstructorPermissions.CAN_MODIFY_SESSION_COMMENT_IN_SECTIONS);"},{"lineNumber":255,"author":{"gitId":"-"},"content":" } else if (!StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":256,"author":{"gitId":"-"},"content":" checkAccessControlForPreview(feedbackSession, true);"},{"lineNumber":257,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" gateKeeper.verifySessionSubmissionPrivilegeForInstructor(feedbackSession, instructor);"},{"lineNumber":259,"author":{"gitId":"-"},"content":" verifyMatchingGoogleId(instructor.getGoogleId());"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":" }"},{"lineNumber":262,"author":{"gitId":"-"},"content":""},{"lineNumber":263,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":264,"author":{"gitId":"-"},"content":" * Checks the access control for instructor feedback submission."},{"lineNumber":265,"author":{"gitId":"-"},"content":" */"},{"lineNumber":266,"author":{"gitId":"-"},"content":" void checkAccessControlForInstructorFeedbackSubmission("},{"lineNumber":267,"author":{"gitId":"-"},"content":" Instructor instructor, FeedbackSession feedbackSession) throws UnauthorizedAccessException {"},{"lineNumber":268,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Trying to access system using a non-existent instructor entity\");"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":273,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":274,"author":{"gitId":"-"},"content":""},{"lineNumber":275,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson)) {"},{"lineNumber":276,"author":{"gitId":"-"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":277,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":278,"author":{"gitId":"-"},"content":" sqlLogic.getInstructorByGoogleId(feedbackSession.getCourse().getId(), userInfo.getId()),"},{"lineNumber":279,"author":{"gitId":"-"},"content":" feedbackSession, Const.InstructorPermissions.CAN_MODIFY_SESSION_COMMENT_IN_SECTIONS);"},{"lineNumber":280,"author":{"gitId":"-"},"content":" } else if (!StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":281,"author":{"gitId":"-"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":282,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":283,"author":{"gitId":"-"},"content":" sqlLogic.getInstructorByGoogleId(feedbackSession.getCourse().getId(), userInfo.getId()),"},{"lineNumber":284,"author":{"gitId":"-"},"content":" feedbackSession, Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":285,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":286,"author":{"gitId":"-"},"content":" gateKeeper.verifySessionSubmissionPrivilegeForInstructor(feedbackSession, instructor);"},{"lineNumber":287,"author":{"gitId":"-"},"content":" if (instructor.getAccount() !\u003d null) {"},{"lineNumber":288,"author":{"gitId":"-"},"content":" if (userInfo \u003d\u003d null) {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" // Instructor is associated to an account; even if registration key is passed, do not allow access"},{"lineNumber":290,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Login is required to access this feedback session\");"},{"lineNumber":291,"author":{"gitId":"-"},"content":" } else if (!userInfo.id.equals(instructor.getAccount().getGoogleId())) {"},{"lineNumber":292,"author":{"gitId":"-"},"content":" // Logged in instructor is not the same as the instructor registered for the given key,"},{"lineNumber":293,"author":{"gitId":"-"},"content":" // do not allow access"},{"lineNumber":294,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"You are not authorized to access this feedback session\");"},{"lineNumber":295,"author":{"gitId":"-"},"content":" }"},{"lineNumber":296,"author":{"gitId":"-"},"content":" }"},{"lineNumber":297,"author":{"gitId":"-"},"content":" }"},{"lineNumber":298,"author":{"gitId":"-"},"content":" }"},{"lineNumber":299,"author":{"gitId":"-"},"content":""},{"lineNumber":300,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":301,"author":{"gitId":"-"},"content":" * Checks the access control for instructor feedback result."},{"lineNumber":302,"author":{"gitId":"-"},"content":" */"},{"lineNumber":303,"author":{"gitId":"-"},"content":" void checkAccessControlForInstructorFeedbackResult("},{"lineNumber":304,"author":{"gitId":"-"},"content":" InstructorAttributes instructor, FeedbackSessionAttributes feedbackSession) throws UnauthorizedAccessException {"},{"lineNumber":305,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":306,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Trying to access system using a non-existent instructor entity\");"},{"lineNumber":307,"author":{"gitId":"-"},"content":" }"},{"lineNumber":308,"author":{"gitId":"-"},"content":""},{"lineNumber":309,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":310,"author":{"gitId":"-"},"content":""},{"lineNumber":311,"author":{"gitId":"-"},"content":" if (StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":312,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, feedbackSession,"},{"lineNumber":313,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_VIEW_SESSION_IN_SECTIONS);"},{"lineNumber":314,"author":{"gitId":"-"},"content":" verifyMatchingGoogleId(instructor.getGoogleId());"},{"lineNumber":315,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":316,"author":{"gitId":"-"},"content":" checkAccessControlForPreview(feedbackSession, true);"},{"lineNumber":317,"author":{"gitId":"-"},"content":" }"},{"lineNumber":318,"author":{"gitId":"-"},"content":" }"},{"lineNumber":319,"author":{"gitId":"-"},"content":""},{"lineNumber":320,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":321,"author":{"gitId":"-"},"content":" * Checks the access control for instructor feedback result."},{"lineNumber":322,"author":{"gitId":"-"},"content":" */"},{"lineNumber":323,"author":{"gitId":"-"},"content":" void checkAccessControlForInstructorFeedbackResult("},{"lineNumber":324,"author":{"gitId":"-"},"content":" Instructor instructor, FeedbackSession feedbackSession) throws UnauthorizedAccessException {"},{"lineNumber":325,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":326,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Trying to access system using a non-existent instructor entity\");"},{"lineNumber":327,"author":{"gitId":"-"},"content":" }"},{"lineNumber":328,"author":{"gitId":"-"},"content":""},{"lineNumber":329,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" if (StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":332,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, feedbackSession,"},{"lineNumber":333,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_VIEW_SESSION_IN_SECTIONS);"},{"lineNumber":334,"author":{"gitId":"-"},"content":" verifyMatchingGoogleId(instructor.getGoogleId());"},{"lineNumber":335,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":336,"author":{"gitId":"-"},"content":" checkAccessControlForPreview(feedbackSession, true);"},{"lineNumber":337,"author":{"gitId":"-"},"content":" }"},{"lineNumber":338,"author":{"gitId":"-"},"content":" }"},{"lineNumber":339,"author":{"gitId":"-"},"content":""},{"lineNumber":340,"author":{"gitId":"-"},"content":" private void verifyMatchingGoogleId(String googleId) throws UnauthorizedAccessException {"},{"lineNumber":341,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(googleId)) {"},{"lineNumber":342,"author":{"gitId":"-"},"content":" if (userInfo \u003d\u003d null) {"},{"lineNumber":343,"author":{"gitId":"-"},"content":" // Student/Instructor is associated to a google ID; even if registration key is passed, do not allow access"},{"lineNumber":344,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Login is required to access this feedback session\");"},{"lineNumber":345,"author":{"gitId":"-"},"content":" } else if (!userInfo.id.equals(googleId)) {"},{"lineNumber":346,"author":{"gitId":"-"},"content":" // Logged in student/instructor is not the same as the student/instructor registered for the given key,"},{"lineNumber":347,"author":{"gitId":"-"},"content":" // do not allow access"},{"lineNumber":348,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"You are not authorized to access this feedback session\");"},{"lineNumber":349,"author":{"gitId":"-"},"content":" }"},{"lineNumber":350,"author":{"gitId":"-"},"content":" }"},{"lineNumber":351,"author":{"gitId":"-"},"content":" }"},{"lineNumber":352,"author":{"gitId":"-"},"content":""},{"lineNumber":353,"author":{"gitId":"-"},"content":" private void checkAccessControlForPreview(FeedbackSessionAttributes feedbackSession, boolean isInstructor)"},{"lineNumber":354,"author":{"gitId":"-"},"content":" throws UnauthorizedAccessException {"},{"lineNumber":355,"author":{"gitId":"-"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":356,"author":{"gitId":"-"},"content":" if (isInstructor) {"},{"lineNumber":357,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":358,"author":{"gitId":"-"},"content":" logic.getInstructorForGoogleId(feedbackSession.getCourseId(), userInfo.getId()), feedbackSession,"},{"lineNumber":359,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":360,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":361,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":362,"author":{"gitId":"-"},"content":" logic.getInstructorForGoogleId(feedbackSession.getCourseId(), userInfo.getId()), feedbackSession,"},{"lineNumber":363,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":364,"author":{"gitId":"-"},"content":" }"},{"lineNumber":365,"author":{"gitId":"-"},"content":" }"},{"lineNumber":366,"author":{"gitId":"-"},"content":""},{"lineNumber":367,"author":{"gitId":"xenosf"},"content":" private void checkAccessControlForPreview(FeedbackSession feedbackSession, boolean isInstructor)"},{"lineNumber":368,"author":{"gitId":"xenosf"},"content":" throws UnauthorizedAccessException {"},{"lineNumber":369,"author":{"gitId":"xenosf"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":370,"author":{"gitId":"xenosf"},"content":" if (isInstructor) {"},{"lineNumber":371,"author":{"gitId":"xenosf"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":372,"author":{"gitId":"xenosf"},"content":" sqlLogic.getInstructorByGoogleId(feedbackSession.getCourse().getId(), userInfo.getId()), feedbackSession,"},{"lineNumber":373,"author":{"gitId":"xenosf"},"content":" Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":374,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":375,"author":{"gitId":"xenosf"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":376,"author":{"gitId":"xenosf"},"content":" sqlLogic.getInstructorByGoogleId(feedbackSession.getCourse().getId(), userInfo.getId()), feedbackSession,"},{"lineNumber":377,"author":{"gitId":"xenosf"},"content":" Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":378,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":379,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":380,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":381,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":382,"author":{"gitId":"-"},"content":" * Verifies that it is not a preview request."},{"lineNumber":383,"author":{"gitId":"-"},"content":" */"},{"lineNumber":384,"author":{"gitId":"-"},"content":" void verifyNotPreview() throws UnauthorizedAccessException {"},{"lineNumber":385,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":386,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":387,"author":{"gitId":"-"},"content":" // should not view response under preview mode"},{"lineNumber":388,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"You are not allowed to see responses when previewing\", true);"},{"lineNumber":389,"author":{"gitId":"-"},"content":" }"},{"lineNumber":390,"author":{"gitId":"-"},"content":" }"},{"lineNumber":391,"author":{"gitId":"-"},"content":""},{"lineNumber":392,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":393,"author":{"gitId":"-"},"content":" * Verifies that the session is open for submission."},{"lineNumber":394,"author":{"gitId":"-"},"content":" *"},{"lineNumber":395,"author":{"gitId":"-"},"content":" * \u003cp\u003eIf it is moderation request, omit the check."},{"lineNumber":396,"author":{"gitId":"-"},"content":" */"},{"lineNumber":397,"author":{"gitId":"-"},"content":" void verifySessionOpenExceptForModeration(FeedbackSessionAttributes feedbackSession) throws UnauthorizedAccessException {"},{"lineNumber":398,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":399,"author":{"gitId":"-"},"content":""},{"lineNumber":400,"author":{"gitId":"-"},"content":" if (StringHelper.isEmpty(moderatedPerson) \u0026\u0026 !(feedbackSession.isOpened() || feedbackSession.isInGracePeriod())) {"},{"lineNumber":401,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"The feedback session is not available for submission\", true);"},{"lineNumber":402,"author":{"gitId":"-"},"content":" }"},{"lineNumber":403,"author":{"gitId":"-"},"content":" }"},{"lineNumber":404,"author":{"gitId":"-"},"content":""},{"lineNumber":405,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":406,"author":{"gitId":"-"},"content":" * Verifies that the session is open for submission."},{"lineNumber":407,"author":{"gitId":"-"},"content":" *"},{"lineNumber":408,"author":{"gitId":"-"},"content":" * \u003cp\u003eIf it is moderation request, omit the check."},{"lineNumber":409,"author":{"gitId":"-"},"content":" */"},{"lineNumber":410,"author":{"gitId":"-"},"content":" void verifySessionOpenExceptForModeration(FeedbackSession feedbackSession) throws UnauthorizedAccessException {"},{"lineNumber":411,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":412,"author":{"gitId":"-"},"content":""},{"lineNumber":413,"author":{"gitId":"-"},"content":" if (StringHelper.isEmpty(moderatedPerson) \u0026\u0026 !(feedbackSession.isOpened() || feedbackSession.isInGracePeriod())) {"},{"lineNumber":414,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"The feedback session is not available for submission\", true);"},{"lineNumber":415,"author":{"gitId":"-"},"content":" }"},{"lineNumber":416,"author":{"gitId":"-"},"content":" }"},{"lineNumber":417,"author":{"gitId":"-"},"content":""},{"lineNumber":418,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":419,"author":{"gitId":"-"},"content":" * Gets the section of a recipient."},{"lineNumber":420,"author":{"gitId":"-"},"content":" */"},{"lineNumber":421,"author":{"gitId":"-"},"content":" @SuppressWarnings(\"PMD.ImplicitSwitchFallThrough\") // false positive"},{"lineNumber":422,"author":{"gitId":"-"},"content":" Section getRecipientSection("},{"lineNumber":423,"author":{"gitId":"-"},"content":" String courseId, FeedbackParticipantType giverType, FeedbackParticipantType recipientType,"},{"lineNumber":424,"author":{"gitId":"-"},"content":" String recipientIdentifier) {"},{"lineNumber":425,"author":{"gitId":"-"},"content":""},{"lineNumber":426,"author":{"gitId":"-"},"content":" switch (recipientType) {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" case SELF:"},{"lineNumber":428,"author":{"gitId":"-"},"content":" switch (giverType) {"},{"lineNumber":429,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":430,"author":{"gitId":"-"},"content":" case SELF:"},{"lineNumber":431,"author":{"gitId":"-"},"content":" return Const.DEFAULT_SQL_SECTION;"},{"lineNumber":432,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":433,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":434,"author":{"gitId":"-"},"content":" Section section \u003d sqlLogic.getSectionByCourseIdAndTeam(courseId, recipientIdentifier);"},{"lineNumber":435,"author":{"gitId":"-"},"content":" return section \u003d\u003d null ? Const.DEFAULT_SQL_SECTION : section;"},{"lineNumber":436,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":437,"author":{"gitId":"-"},"content":" case STUDENTS_IN_SAME_SECTION:"},{"lineNumber":438,"author":{"gitId":"-"},"content":" Student student \u003d sqlLogic.getStudentForEmail(courseId, recipientIdentifier);"},{"lineNumber":439,"author":{"gitId":"-"},"content":" return student \u003d\u003d null ? Const.DEFAULT_SQL_SECTION : student.getSection();"},{"lineNumber":440,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":441,"author":{"gitId":"-"},"content":" assert false : \"Invalid giver type \" + giverType + \" for recipient type \" + recipientType;"},{"lineNumber":442,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":443,"author":{"gitId":"-"},"content":" }"},{"lineNumber":444,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":445,"author":{"gitId":"-"},"content":" case NONE:"},{"lineNumber":446,"author":{"gitId":"-"},"content":" return Const.DEFAULT_SQL_SECTION;"},{"lineNumber":447,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":448,"author":{"gitId":"-"},"content":" case TEAMS_EXCLUDING_SELF:"},{"lineNumber":449,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":450,"author":{"gitId":"-"},"content":" case OWN_TEAM:"},{"lineNumber":451,"author":{"gitId":"-"},"content":" Section section \u003d sqlLogic.getSectionByCourseIdAndTeam(courseId, recipientIdentifier);"},{"lineNumber":452,"author":{"gitId":"-"},"content":" return section \u003d\u003d null ? Const.DEFAULT_SQL_SECTION : section;"},{"lineNumber":453,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":454,"author":{"gitId":"-"},"content":" case STUDENTS_EXCLUDING_SELF:"},{"lineNumber":455,"author":{"gitId":"-"},"content":" case STUDENTS_IN_SAME_SECTION:"},{"lineNumber":456,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":457,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS_INCLUDING_SELF:"},{"lineNumber":458,"author":{"gitId":"-"},"content":" Student student \u003d sqlLogic.getStudentForEmail(courseId, recipientIdentifier);"},{"lineNumber":459,"author":{"gitId":"-"},"content":" return student \u003d\u003d null ? Const.DEFAULT_SQL_SECTION : student.getSection();"},{"lineNumber":460,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":461,"author":{"gitId":"-"},"content":" assert false : \"Unknown recipient type \" + recipientType;"},{"lineNumber":462,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":463,"author":{"gitId":"-"},"content":" }"},{"lineNumber":464,"author":{"gitId":"-"},"content":" }"},{"lineNumber":465,"author":{"gitId":"-"},"content":""},{"lineNumber":466,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":467,"author":{"gitId":"-"},"content":" * Gets the section of a recipient."},{"lineNumber":468,"author":{"gitId":"-"},"content":" */"},{"lineNumber":469,"author":{"gitId":"-"},"content":" @SuppressWarnings(\"PMD.ImplicitSwitchFallThrough\") // false positive"},{"lineNumber":470,"author":{"gitId":"-"},"content":" String getDatastoreRecipientSection("},{"lineNumber":471,"author":{"gitId":"-"},"content":" String courseId, FeedbackParticipantType giverType, FeedbackParticipantType recipientType,"},{"lineNumber":472,"author":{"gitId":"-"},"content":" String recipientIdentifier) {"},{"lineNumber":473,"author":{"gitId":"-"},"content":" switch (recipientType) {"},{"lineNumber":474,"author":{"gitId":"-"},"content":" case SELF:"},{"lineNumber":475,"author":{"gitId":"-"},"content":" switch (giverType) {"},{"lineNumber":476,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":477,"author":{"gitId":"-"},"content":" case SELF:"},{"lineNumber":478,"author":{"gitId":"-"},"content":" return Const.DEFAULT_SECTION;"},{"lineNumber":479,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":480,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":481,"author":{"gitId":"-"},"content":" return logic.getSectionForTeam(courseId, recipientIdentifier);"},{"lineNumber":482,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":483,"author":{"gitId":"-"},"content":" case STUDENTS_IN_SAME_SECTION:"},{"lineNumber":484,"author":{"gitId":"-"},"content":" StudentAttributes student \u003d logic.getStudentForEmail(courseId, recipientIdentifier);"},{"lineNumber":485,"author":{"gitId":"-"},"content":" return student \u003d\u003d null ? Const.DEFAULT_SECTION : student.getSection();"},{"lineNumber":486,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":487,"author":{"gitId":"-"},"content":" assert false : \"Invalid giver type \" + giverType + \" for recipient type \" + recipientType;"},{"lineNumber":488,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":489,"author":{"gitId":"-"},"content":" }"},{"lineNumber":490,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":491,"author":{"gitId":"-"},"content":" case NONE:"},{"lineNumber":492,"author":{"gitId":"-"},"content":" return Const.DEFAULT_SECTION;"},{"lineNumber":493,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":494,"author":{"gitId":"-"},"content":" case TEAMS_EXCLUDING_SELF:"},{"lineNumber":495,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":496,"author":{"gitId":"-"},"content":" case OWN_TEAM:"},{"lineNumber":497,"author":{"gitId":"-"},"content":" return logic.getSectionForTeam(courseId, recipientIdentifier);"},{"lineNumber":498,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":499,"author":{"gitId":"-"},"content":" case STUDENTS_EXCLUDING_SELF:"},{"lineNumber":500,"author":{"gitId":"-"},"content":" case STUDENTS_IN_SAME_SECTION:"},{"lineNumber":501,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":502,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS_INCLUDING_SELF:"},{"lineNumber":503,"author":{"gitId":"-"},"content":" StudentAttributes student \u003d logic.getStudentForEmail(courseId, recipientIdentifier);"},{"lineNumber":504,"author":{"gitId":"-"},"content":" return student \u003d\u003d null ? Const.DEFAULT_SECTION : student.getSection();"},{"lineNumber":505,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":506,"author":{"gitId":"-"},"content":" assert false : \"Unknown recipient type \" + recipientType;"},{"lineNumber":507,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":508,"author":{"gitId":"-"},"content":" }"},{"lineNumber":509,"author":{"gitId":"-"},"content":" }"},{"lineNumber":510,"author":{"gitId":"-"},"content":""},{"lineNumber":511,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":33,"-":478}},{"path":"src/main/java/teammates/ui/webapi/CreateAccountAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.time.ZoneId;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.ZonedDateTime;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.time.temporal.ChronoUnit;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.regex.Pattern;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.DataBundle;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.util.StringHelper;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.util.Templates;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":30,"author":{"gitId":"-"},"content":" * Creates a new instructor account with sample courses."},{"lineNumber":31,"author":{"gitId":"-"},"content":" */"},{"lineNumber":32,"author":{"gitId":"-"},"content":"public class CreateAccountAction extends Action {"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":37,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":42,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" // Any user can create instructor account as long as the registration key is valid."},{"lineNumber":44,"author":{"gitId":"-"},"content":" }"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":47,"author":{"gitId":"-"},"content":" public JsonResult execute() throws InvalidHttpRequestBodyException, InvalidOperationException {"},{"lineNumber":48,"author":{"gitId":"-"},"content":" String registrationKey \u003d getNonNullRequestParamValue(Const.ParamsNames.REGKEY);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" String timezone \u003d getRequestParamValue(Const.ParamsNames.TIMEZONE);"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" if (timezone \u003d\u003d null || !FieldValidator.getInvalidityInfoForTimeZone(timezone).isEmpty()) {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" // Use default timezone instead"},{"lineNumber":53,"author":{"gitId":"-"},"content":" timezone \u003d Const.DEFAULT_TIME_ZONE;"},{"lineNumber":54,"author":{"gitId":"-"},"content":" }"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d sqlLogic.getAccountRequestByRegistrationKey(registrationKey);"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" if (accountRequest \u003d\u003d null) {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(\"Account request with registration key \""},{"lineNumber":60,"author":{"gitId":"-"},"content":" + registrationKey + \" could not be found\");"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" if (accountRequest.getRegisteredAt() !\u003d null) {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(\"The registration key \" + registrationKey + \" has already been used.\");"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" String instructorEmail \u003d accountRequest.getEmail();"},{"lineNumber":68,"author":{"gitId":"-"},"content":" String instructorName \u003d accountRequest.getName();"},{"lineNumber":69,"author":{"gitId":"-"},"content":" String instructorInstitution \u003d accountRequest.getInstitute();"},{"lineNumber":70,"author":{"gitId":"-"},"content":" String courseId;"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" courseId \u003d importDemoData(instructorEmail, instructorName, instructorInstitution, timezone);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException ipe) {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" // There should not be any invalid parameter here"},{"lineNumber":76,"author":{"gitId":"-"},"content":" log.severe(\"Unexpected error\", ipe);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" return new JsonResult(ipe.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" List\u003cInstructorAttributes\u003e instructorList \u003d logic.getInstructorsForCourse(courseId);"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" assert !instructorList.isEmpty();"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" logic.joinCourseForInstructor(instructorList.get(0).getKey(), userInfo.id);"},{"lineNumber":86,"author":{"gitId":"-"},"content":" } catch (EntityDoesNotExistException | EntityAlreadyExistsException | InvalidParametersException e) {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" // EntityDoesNotExistException should not be thrown as all entities should exist in demo course."},{"lineNumber":88,"author":{"gitId":"-"},"content":" // EntityAlreadyExistsException should not be thrown as updated entities should not have"},{"lineNumber":89,"author":{"gitId":"-"},"content":" // conflict with generated entities in new demo course."},{"lineNumber":90,"author":{"gitId":"-"},"content":" // InvalidParametersException should not be thrown as as there should not be any invalid parameters."},{"lineNumber":91,"author":{"gitId":"-"},"content":" log.severe(\"Unexpected error\", e);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" return new JsonResult(e.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" }"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":96,"author":{"gitId":"-"},"content":" setAccountRequestAsRegistered(accountRequest);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" } catch (EntityDoesNotExistException | InvalidParametersException e) {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" // EntityDoesNotExistException should not be thrown as existence of account request has been validated before."},{"lineNumber":99,"author":{"gitId":"-"},"content":" // InvalidParametersException should not be thrown as there should not be any invalid parameters."},{"lineNumber":100,"author":{"gitId":"-"},"content":" log.severe(\"Unexpected error\", e);"},{"lineNumber":101,"author":{"gitId":"-"},"content":" return new JsonResult(e.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" return new JsonResult(\"Account successfully created\", HttpStatus.SC_OK);"},{"lineNumber":105,"author":{"gitId":"-"},"content":" }"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":108,"author":{"gitId":"-"},"content":" * Abstracts the logic of updating an account request to be registered."},{"lineNumber":109,"author":{"gitId":"-"},"content":" *"},{"lineNumber":110,"author":{"gitId":"-"},"content":" * @return the updated account request"},{"lineNumber":111,"author":{"gitId":"-"},"content":" */"},{"lineNumber":112,"author":{"gitId":"-"},"content":" private AccountRequest setAccountRequestAsRegistered(AccountRequest accountRequest)"},{"lineNumber":113,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" accountRequest.setStatus(AccountRequestStatus.REGISTERED);"},{"lineNumber":115,"author":{"gitId":"-"},"content":" accountRequest.setRegisteredAt(Instant.now());"},{"lineNumber":116,"author":{"gitId":"-"},"content":" sqlLogic.updateAccountRequest(accountRequest);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" return accountRequest;"},{"lineNumber":118,"author":{"gitId":"-"},"content":" }"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" private static String getDateString(Instant instant) {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" return TimeHelper.formatInstant(instant, Const.DEFAULT_TIME_ZONE, \"yyyy-MM-dd\");"},{"lineNumber":122,"author":{"gitId":"-"},"content":" }"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":125,"author":{"gitId":"-"},"content":" * Imports demo course for the new instructor."},{"lineNumber":126,"author":{"gitId":"-"},"content":" *"},{"lineNumber":127,"author":{"gitId":"-"},"content":" * @return the ID of demo course"},{"lineNumber":128,"author":{"gitId":"-"},"content":" */"},{"lineNumber":129,"author":{"gitId":"-"},"content":" private String importDemoData(String instructorEmail, String instructorName, String instructorInstitute, String timezone)"},{"lineNumber":130,"author":{"gitId":"-"},"content":" throws InvalidParametersException {"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":" String courseId \u003d generateDemoCourseId(instructorEmail);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" Instant now \u003d Instant.now();"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" // Used for start time + visible time for all sessions"},{"lineNumber":136,"author":{"gitId":"-"},"content":" String dateString1 \u003d getDateString(now.minus(7, ChronoUnit.DAYS));"},{"lineNumber":137,"author":{"gitId":"-"},"content":" // Used for end time for sessions already past"},{"lineNumber":138,"author":{"gitId":"-"},"content":" String dateString2 \u003d getDateString(now.minus(3, ChronoUnit.DAYS));"},{"lineNumber":139,"author":{"gitId":"-"},"content":" // Used for result visible time for sessions already past"},{"lineNumber":140,"author":{"gitId":"-"},"content":" String dateString3 \u003d getDateString(now.minus(2, ChronoUnit.DAYS));"},{"lineNumber":141,"author":{"gitId":"-"},"content":" // Used for end time for session still ongoing"},{"lineNumber":142,"author":{"gitId":"-"},"content":" String dateString4 \u003d getDateString(now.plus(3, ChronoUnit.DAYS));"},{"lineNumber":143,"author":{"gitId":"-"},"content":" // Used for timestamp of comments"},{"lineNumber":144,"author":{"gitId":"-"},"content":" String dateString5 \u003d getDateString(now);"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" String dataBundleString \u003d Templates.populateTemplate(Templates.INSTRUCTOR_SAMPLE_DATA,"},{"lineNumber":147,"author":{"gitId":"-"},"content":" // replace email"},{"lineNumber":148,"author":{"gitId":"-"},"content":" \"teammates.demo.instructor@demo.course\", instructorEmail,"},{"lineNumber":149,"author":{"gitId":"-"},"content":" // replace name"},{"lineNumber":150,"author":{"gitId":"-"},"content":" \"Demo_Instructor\", instructorName,"},{"lineNumber":151,"author":{"gitId":"-"},"content":" // replace course"},{"lineNumber":152,"author":{"gitId":"-"},"content":" \"demo.course\", courseId,"},{"lineNumber":153,"author":{"gitId":"-"},"content":" // replace institute"},{"lineNumber":154,"author":{"gitId":"-"},"content":" \"demo.institute\", instructorInstitute,"},{"lineNumber":155,"author":{"gitId":"-"},"content":" // replace timezone"},{"lineNumber":156,"author":{"gitId":"-"},"content":" \"demo.timezone\", timezone,"},{"lineNumber":157,"author":{"gitId":"-"},"content":" // replace dates"},{"lineNumber":158,"author":{"gitId":"-"},"content":" \"demo.date1\", dateString1,"},{"lineNumber":159,"author":{"gitId":"-"},"content":" \"demo.date2\", dateString2,"},{"lineNumber":160,"author":{"gitId":"-"},"content":" \"demo.date3\", dateString3,"},{"lineNumber":161,"author":{"gitId":"-"},"content":" \"demo.date4\", dateString4,"},{"lineNumber":162,"author":{"gitId":"-"},"content":" \"demo.date5\", dateString5);"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" if (!Const.DEFAULT_TIME_ZONE.equals(timezone)) {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" dataBundleString \u003d replaceAdjustedTimeAndTimezone(dataBundleString, timezone);"},{"lineNumber":166,"author":{"gitId":"-"},"content":" }"},{"lineNumber":167,"author":{"gitId":"-"},"content":""},{"lineNumber":168,"author":{"gitId":"-"},"content":" DataBundle data \u003d JsonUtils.fromJson(dataBundleString, DataBundle.class);"},{"lineNumber":169,"author":{"gitId":"-"},"content":""},{"lineNumber":170,"author":{"gitId":"-"},"content":" logic.persistDataBundle(data);"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" List\u003cStudentAttributes\u003e students \u003d logic.getStudentsForCourse(courseId);"},{"lineNumber":173,"author":{"gitId":"-"},"content":" List\u003cInstructorAttributes\u003e instructors \u003d logic.getInstructorsForCourse(courseId);"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" for (StudentAttributes student : students) {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" taskQueuer.scheduleStudentForSearchIndexing(student.getCourse(), student.getEmail());"},{"lineNumber":177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" for (InstructorAttributes instructor : instructors) {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" taskQueuer.scheduleInstructorForSearchIndexing(instructor.getCourseId(), instructor.getEmail());"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" return courseId;"},{"lineNumber":184,"author":{"gitId":"-"},"content":" }"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" // Strategy to Generate New Demo Course Id:"},{"lineNumber":187,"author":{"gitId":"-"},"content":" // a. keep the part of email before \"@\""},{"lineNumber":188,"author":{"gitId":"-"},"content":" // replace \"@\" with \".\""},{"lineNumber":189,"author":{"gitId":"-"},"content":" // replace email host with their first 3 chars. eg, gmail.com -\u003e gma"},{"lineNumber":190,"author":{"gitId":"-"},"content":" // append \"-demo\""},{"lineNumber":191,"author":{"gitId":"-"},"content":" // to sum up: lebron@gmail.com -\u003e lebron.gma-demo"},{"lineNumber":192,"author":{"gitId":"-"},"content":" //"},{"lineNumber":193,"author":{"gitId":"-"},"content":" // b. if the generated courseId already exists, create another one by appending a integer to the previous courseId."},{"lineNumber":194,"author":{"gitId":"-"},"content":" // if the newly generate id still exists, increment the id, until we find a feasible one"},{"lineNumber":195,"author":{"gitId":"-"},"content":" // eg."},{"lineNumber":196,"author":{"gitId":"-"},"content":" // lebron@gmail.com -\u003e lebron.gma-demo // already exists!"},{"lineNumber":197,"author":{"gitId":"-"},"content":" // lebron@gmail.com -\u003e lebron.gma-demo0 // already exists!"},{"lineNumber":198,"author":{"gitId":"-"},"content":" // lebron@gmail.com -\u003e lebron.gma-demo1 // already exists!"},{"lineNumber":199,"author":{"gitId":"-"},"content":" // ..."},{"lineNumber":200,"author":{"gitId":"-"},"content":" // lebron@gmail.com -\u003e lebron.gma-demo99 // already exists!"},{"lineNumber":201,"author":{"gitId":"-"},"content":" // lebron@gmail.com -\u003e lebron.gma-demo100 // found! a feasible id"},{"lineNumber":202,"author":{"gitId":"-"},"content":" //"},{"lineNumber":203,"author":{"gitId":"-"},"content":" // c. in any cases(a or b), if generated Id is longer than FieldValidator.COURSE_ID_MAX_LENGTH, shorten the part"},{"lineNumber":204,"author":{"gitId":"-"},"content":" // before \"@\" of the initial input email, by continuously removing its last character"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":207,"author":{"gitId":"-"},"content":" * Generate a course ID for demo course, and if the generated id already exists, try another one."},{"lineNumber":208,"author":{"gitId":"-"},"content":" *"},{"lineNumber":209,"author":{"gitId":"-"},"content":" * @param instructorEmail is the instructor email."},{"lineNumber":210,"author":{"gitId":"-"},"content":" * @return generated course id"},{"lineNumber":211,"author":{"gitId":"-"},"content":" */"},{"lineNumber":212,"author":{"gitId":"-"},"content":" private String generateDemoCourseId(String instructorEmail) {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" String proposedCourseId \u003d generateNextDemoCourseId(instructorEmail, FieldValidator.COURSE_ID_MAX_LENGTH);"},{"lineNumber":214,"author":{"gitId":"-"},"content":" while (logic.getCourse(proposedCourseId) !\u003d null) {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" proposedCourseId \u003d generateNextDemoCourseId(proposedCourseId, FieldValidator.COURSE_ID_MAX_LENGTH);"},{"lineNumber":216,"author":{"gitId":"-"},"content":" }"},{"lineNumber":217,"author":{"gitId":"-"},"content":" return proposedCourseId;"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":221,"author":{"gitId":"-"},"content":" * Generate a course ID for demo course from a given email."},{"lineNumber":222,"author":{"gitId":"-"},"content":" *"},{"lineNumber":223,"author":{"gitId":"-"},"content":" * @param instructorEmail is the instructor email."},{"lineNumber":224,"author":{"gitId":"-"},"content":" * @return the first proposed course id. eg.lebron@gmail.com -\u003e lebron.gma-demo"},{"lineNumber":225,"author":{"gitId":"-"},"content":" */"},{"lineNumber":226,"author":{"gitId":"-"},"content":" private String getDemoCourseIdRoot(String instructorEmail) {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" String[] emailSplit \u003d instructorEmail.split(\"@\");"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" String username \u003d emailSplit[0];"},{"lineNumber":230,"author":{"gitId":"-"},"content":" String host \u003d emailSplit[1];"},{"lineNumber":231,"author":{"gitId":"-"},"content":""},{"lineNumber":232,"author":{"gitId":"-"},"content":" String head \u003d StringHelper.replaceIllegalChars(username, FieldValidator.REGEX_COURSE_ID, \u0027_\u0027);"},{"lineNumber":233,"author":{"gitId":"-"},"content":" String hostAbbreviation \u003d host.substring(0, Math.min(host.length(), 3));"},{"lineNumber":234,"author":{"gitId":"-"},"content":""},{"lineNumber":235,"author":{"gitId":"-"},"content":" return head + \".\" + hostAbbreviation + \"-demo\";"},{"lineNumber":236,"author":{"gitId":"-"},"content":" }"},{"lineNumber":237,"author":{"gitId":"-"},"content":""},{"lineNumber":238,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":239,"author":{"gitId":"-"},"content":" * Generate a course ID for demo course from a given email or a generated course Id."},{"lineNumber":240,"author":{"gitId":"-"},"content":" *"},{"lineNumber":241,"author":{"gitId":"-"},"content":" * \u003cp\u003eHere we check the input string is an email or course Id and handle them accordingly;"},{"lineNumber":242,"author":{"gitId":"-"},"content":" * check the resulting course id, and if bigger than maximumIdLength, cut it so that it equals maximumIdLength."},{"lineNumber":243,"author":{"gitId":"-"},"content":" *"},{"lineNumber":244,"author":{"gitId":"-"},"content":" * @param instructorEmailOrProposedCourseId is the instructor email or a proposed course id that already exists."},{"lineNumber":245,"author":{"gitId":"-"},"content":" * @param maximumIdLength is the maximum resulting id length allowed, above which we will cut the part before \"@\""},{"lineNumber":246,"author":{"gitId":"-"},"content":" * @return the proposed course id, e.g.:"},{"lineNumber":247,"author":{"gitId":"-"},"content":" * \u003cul\u003e"},{"lineNumber":248,"author":{"gitId":"-"},"content":" * \u003cli\u003elebron@gmail.com -\u003e lebron.gma-demo\u003c/li\u003e"},{"lineNumber":249,"author":{"gitId":"-"},"content":" * \u003cli\u003elebron.gma-demo -\u003e lebron.gma-demo0\u003c/li\u003e"},{"lineNumber":250,"author":{"gitId":"-"},"content":" * \u003cli\u003elebron.gma-demo0 -\u003e lebron.gma-demo1\u003c/li\u003e"},{"lineNumber":251,"author":{"gitId":"-"},"content":" * \u003cli\u003e012345678901234567890123456789.gma-demo9 -\u003e 01234567890123456789012345678.gma-demo10 (being cut)\u003c/li\u003e"},{"lineNumber":252,"author":{"gitId":"-"},"content":" * \u003c/ul\u003e"},{"lineNumber":253,"author":{"gitId":"-"},"content":" */"},{"lineNumber":254,"author":{"gitId":"-"},"content":" public String generateNextDemoCourseId(String instructorEmailOrProposedCourseId, int maximumIdLength) {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" boolean isFirstCourseId \u003d instructorEmailOrProposedCourseId.contains(\"@\");"},{"lineNumber":256,"author":{"gitId":"-"},"content":" if (isFirstCourseId) {"},{"lineNumber":257,"author":{"gitId":"-"},"content":" return StringHelper.truncateHead(getDemoCourseIdRoot(instructorEmailOrProposedCourseId), maximumIdLength);"},{"lineNumber":258,"author":{"gitId":"-"},"content":" }"},{"lineNumber":259,"author":{"gitId":"-"},"content":""},{"lineNumber":260,"author":{"gitId":"-"},"content":" boolean isFirstTimeDuplicate \u003d instructorEmailOrProposedCourseId.endsWith(\"-demo\");"},{"lineNumber":261,"author":{"gitId":"-"},"content":" if (isFirstTimeDuplicate) {"},{"lineNumber":262,"author":{"gitId":"-"},"content":" return StringHelper.truncateHead(instructorEmailOrProposedCourseId + \"0\", maximumIdLength);"},{"lineNumber":263,"author":{"gitId":"-"},"content":" }"},{"lineNumber":264,"author":{"gitId":"-"},"content":""},{"lineNumber":265,"author":{"gitId":"-"},"content":" int lastIndexOfDemo \u003d instructorEmailOrProposedCourseId.lastIndexOf(\"-demo\");"},{"lineNumber":266,"author":{"gitId":"-"},"content":" String root \u003d instructorEmailOrProposedCourseId.substring(0, lastIndexOfDemo);"},{"lineNumber":267,"author":{"gitId":"-"},"content":" int previousDedupSuffix \u003d Integer.parseInt(instructorEmailOrProposedCourseId.substring(lastIndexOfDemo + 5));"},{"lineNumber":268,"author":{"gitId":"-"},"content":""},{"lineNumber":269,"author":{"gitId":"-"},"content":" return StringHelper.truncateHead(root + \"-demo\" + (previousDedupSuffix + 1), maximumIdLength);"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":273,"author":{"gitId":"-"},"content":" * Replace time and timezone based on users timezone."},{"lineNumber":274,"author":{"gitId":"-"},"content":" * Strings representing instant are adjusted so that they represent the same date and time but in the users timezone."},{"lineNumber":275,"author":{"gitId":"-"},"content":" * Timezone is changed to users timezone."},{"lineNumber":276,"author":{"gitId":"-"},"content":" */"},{"lineNumber":277,"author":{"gitId":"-"},"content":" private String replaceAdjustedTimeAndTimezone(String template, String timezoneString) {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" // timezoneString should have been validated in #execute() method already"},{"lineNumber":279,"author":{"gitId":"-"},"content":" assert ZoneId.getAvailableZoneIds().contains(timezoneString);"},{"lineNumber":280,"author":{"gitId":"-"},"content":""},{"lineNumber":281,"author":{"gitId":"-"},"content":" String pattern \u003d \"\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}Z\"; // regex for instant"},{"lineNumber":282,"author":{"gitId":"-"},"content":" ZoneId timezone \u003d ZoneId.of(timezoneString);"},{"lineNumber":283,"author":{"gitId":"-"},"content":""},{"lineNumber":284,"author":{"gitId":"-"},"content":" // replace instant with instant adjusted for user\u0027s timezone"},{"lineNumber":285,"author":{"gitId":"-"},"content":" return Pattern.compile(pattern).matcher(template).replaceAll(timestampMatch -\u003e {"},{"lineNumber":286,"author":{"gitId":"-"},"content":" String timestamp \u003d timestampMatch.group();"},{"lineNumber":287,"author":{"gitId":"-"},"content":" Instant instant \u003d Instant.parse(timestamp);"},{"lineNumber":288,"author":{"gitId":"-"},"content":""},{"lineNumber":289,"author":{"gitId":"-"},"content":" if (TimeHelper.isSpecialTime(instant)) {"},{"lineNumber":290,"author":{"gitId":"-"},"content":" return timestamp;"},{"lineNumber":291,"author":{"gitId":"-"},"content":" }"},{"lineNumber":292,"author":{"gitId":"-"},"content":""},{"lineNumber":293,"author":{"gitId":"-"},"content":" return ZonedDateTime.ofInstant(instant, ZoneId.of(Const.DEFAULT_TIME_ZONE))"},{"lineNumber":294,"author":{"gitId":"-"},"content":" .withZoneSameLocal(timezone).toInstant().toString();"},{"lineNumber":295,"author":{"gitId":"-"},"content":" });"},{"lineNumber":296,"author":{"gitId":"-"},"content":" }"},{"lineNumber":297,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":2,"-":295}},{"path":"src/main/java/teammates/ui/webapi/CreateAccountRequestAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.ui.output.AccountRequestData;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.ui.request.AccountCreateRequest;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":12,"author":{"gitId":"-"},"content":" * Creates a new account request."},{"lineNumber":13,"author":{"gitId":"-"},"content":" */"},{"lineNumber":14,"author":{"gitId":"-"},"content":"public class CreateAccountRequestAction extends Action {"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":17,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" return AuthType.PUBLIC;"},{"lineNumber":19,"author":{"gitId":"-"},"content":" }"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":22,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":23,"author":{"gitId":"-"},"content":" // Nothing needs to be done here because anybody should be able to create an account request."},{"lineNumber":24,"author":{"gitId":"-"},"content":" }"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":27,"author":{"gitId":"-"},"content":" public boolean isTransactionNeeded() {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":32,"author":{"gitId":"-"},"content":" public JsonResult execute()"},{"lineNumber":33,"author":{"gitId":"-"},"content":" throws InvalidHttpRequestBodyException, InvalidOperationException {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" AccountCreateRequest createRequest \u003d getAndValidateRequestBody(AccountCreateRequest.class);"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" String instructorName \u003d createRequest.getInstructorName().trim();"},{"lineNumber":37,"author":{"gitId":"-"},"content":" String instructorEmail \u003d createRequest.getInstructorEmail().trim();"},{"lineNumber":38,"author":{"gitId":"-"},"content":" String instructorInstitution \u003d createRequest.getInstructorInstitution().trim();"},{"lineNumber":39,"author":{"gitId":"-"},"content":" String comments \u003d createRequest.getInstructorComments();"},{"lineNumber":40,"author":{"gitId":"-"},"content":" if (comments !\u003d null) {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" comments \u003d comments.trim();"},{"lineNumber":42,"author":{"gitId":"-"},"content":" }"},{"lineNumber":43,"author":{"gitId":"-"},"content":" AccountRequest accountRequest;"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" accountRequest \u003d sqlLogic.createAccountRequestWithTransaction(instructorName, instructorEmail,"},{"lineNumber":47,"author":{"gitId":"-"},"content":" instructorInstitution, AccountRequestStatus.PENDING, comments);"},{"lineNumber":48,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException ipe) {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(ipe);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" }"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" taskQueuer.scheduleAccountRequestForSearchIndexing(accountRequest.getId().toString());"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" assert accountRequest !\u003d null;"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" if (userInfo \u003d\u003d null || !userInfo.isAdmin) {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" EmailWrapper adminAlertEmail \u003d sqlEmailGenerator.generateNewAccountRequestAdminAlertEmail(accountRequest);"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" EmailWrapper userAcknowledgementEmail \u003d sqlEmailGenerator"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" .generateNewAccountRequestAcknowledgementEmail(accountRequest);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" emailSender.sendEmail(adminAlertEmail);"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" emailSender.sendEmail(userAcknowledgementEmail);"},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" AccountRequestData output \u003d new AccountRequestData(accountRequest);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" return new JsonResult(output);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":1,"xenosf":5,"-":62}},{"path":"src/main/java/teammates/ui/webapi/CreateFeedbackQuestionAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionDetails;"},{"lineNumber":8,"author":{"gitId":"marquestye"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackQuestionData;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.ui.request.FeedbackQuestionCreateRequest;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * Creates a feedback question."},{"lineNumber":19,"author":{"gitId":"-"},"content":" */"},{"lineNumber":20,"author":{"gitId":"-"},"content":"public class CreateFeedbackQuestionAction extends Action {"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":23,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":30,"author":{"gitId":"-"},"content":" String feedbackSessionName \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" InstructorAttributes instructorDetailForCourse \u003d logic.getInstructorForGoogleId(courseId, userInfo.getId());"},{"lineNumber":32,"author":{"gitId":"-"},"content":" if (!isCourseMigrated(courseId)) {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructorDetailForCourse,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" getNonNullFeedbackSession(feedbackSessionName, courseId),"},{"lineNumber":35,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":36,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" }"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" // TODO: Remove sql from variable name after migration"},{"lineNumber":40,"author":{"gitId":"-"},"content":" Instructor sqlInstructorDetailForCourse \u003d sqlLogic.getInstructorByGoogleId(courseId, userInfo.getId());"},{"lineNumber":41,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(sqlInstructorDetailForCourse,"},{"lineNumber":42,"author":{"gitId":"-"},"content":" getNonNullSqlFeedbackSession(feedbackSessionName, courseId),"},{"lineNumber":43,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" }"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":47,"author":{"gitId":"marquestye"},"content":" public JsonResult execute() throws InvalidHttpRequestBodyException, InvalidOperationException {"},{"lineNumber":48,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" String feedbackSessionName \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" FeedbackQuestionCreateRequest request \u003d getAndValidateRequestBody(FeedbackQuestionCreateRequest.class);"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" if (!isCourseMigrated(courseId)) {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" return executeWithDataStore(courseId, feedbackSessionName, request);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" }"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" FeedbackQuestion feedbackQuestion \u003d FeedbackQuestion.makeQuestion("},{"lineNumber":57,"author":{"gitId":"-"},"content":" getNonNullSqlFeedbackSession(feedbackSessionName, courseId),"},{"lineNumber":58,"author":{"gitId":"-"},"content":" request.getQuestionNumber(),"},{"lineNumber":59,"author":{"gitId":"-"},"content":" request.getQuestionDescription(),"},{"lineNumber":60,"author":{"gitId":"-"},"content":" request.getGiverType(),"},{"lineNumber":61,"author":{"gitId":"-"},"content":" request.getRecipientType(),"},{"lineNumber":62,"author":{"gitId":"-"},"content":" request.getNumberOfEntitiesToGiveFeedbackTo(),"},{"lineNumber":63,"author":{"gitId":"-"},"content":" request.getShowResponsesTo(),"},{"lineNumber":64,"author":{"gitId":"-"},"content":" request.getShowGiverNameTo(),"},{"lineNumber":65,"author":{"gitId":"-"},"content":" request.getShowRecipientNameTo(),"},{"lineNumber":66,"author":{"gitId":"-"},"content":" request.getQuestionDetails()"},{"lineNumber":67,"author":{"gitId":"-"},"content":" );"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" // validate questions (giver \u0026 recipient)"},{"lineNumber":71,"author":{"gitId":"-"},"content":" String err \u003d feedbackQuestion.getQuestionDetailsCopy().validateGiverRecipientVisibility(feedbackQuestion);"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" if (!err.isEmpty()) {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(err);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" }"},{"lineNumber":76,"author":{"gitId":"-"},"content":" // validate questions (question details)"},{"lineNumber":77,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails questionDetails \u003d feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":78,"author":{"gitId":"-"},"content":" List\u003cString\u003e questionDetailsErrors \u003d questionDetails.validateQuestionDetails();"},{"lineNumber":79,"author":{"gitId":"-"},"content":" if (!questionDetailsErrors.isEmpty()) {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(questionDetailsErrors.toString());"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d sqlLogic.createFeedbackQuestion(feedbackQuestion);"},{"lineNumber":83,"author":{"gitId":"-"},"content":" return new JsonResult(new FeedbackQuestionData(feedbackQuestion));"},{"lineNumber":84,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException ex) {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(ex);"},{"lineNumber":86,"author":{"gitId":"marquestye"},"content":" } catch (EntityAlreadyExistsException e) {"},{"lineNumber":87,"author":{"gitId":"marquestye"},"content":" throw new InvalidOperationException(e);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":" }"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" private JsonResult executeWithDataStore(String courseId, String feedbackSessionName,"},{"lineNumber":92,"author":{"gitId":"-"},"content":" FeedbackQuestionCreateRequest request) throws InvalidHttpRequestBodyException {"},{"lineNumber":93,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes attributes \u003d FeedbackQuestionAttributes.builder()"},{"lineNumber":94,"author":{"gitId":"-"},"content":" .withCourseId(courseId)"},{"lineNumber":95,"author":{"gitId":"-"},"content":" .withFeedbackSessionName(feedbackSessionName)"},{"lineNumber":96,"author":{"gitId":"-"},"content":" .withGiverType(request.getGiverType())"},{"lineNumber":97,"author":{"gitId":"-"},"content":" .withRecipientType(request.getRecipientType())"},{"lineNumber":98,"author":{"gitId":"-"},"content":" .withQuestionNumber(request.getQuestionNumber())"},{"lineNumber":99,"author":{"gitId":"-"},"content":" .withNumberOfEntitiesToGiveFeedbackTo(request.getNumberOfEntitiesToGiveFeedbackTo())"},{"lineNumber":100,"author":{"gitId":"-"},"content":" .withShowResponsesTo(request.getShowResponsesTo())"},{"lineNumber":101,"author":{"gitId":"-"},"content":" .withShowGiverNameTo(request.getShowGiverNameTo())"},{"lineNumber":102,"author":{"gitId":"-"},"content":" .withShowRecipientNameTo(request.getShowRecipientNameTo())"},{"lineNumber":103,"author":{"gitId":"-"},"content":" .withQuestionDetails(request.getQuestionDetails())"},{"lineNumber":104,"author":{"gitId":"-"},"content":" .withQuestionDescription(request.getQuestionDescription())"},{"lineNumber":105,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" // validate questions (giver \u0026 recipient)"},{"lineNumber":108,"author":{"gitId":"-"},"content":" String err \u003d attributes.getQuestionDetailsCopy().validateGiverRecipientVisibility(attributes);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" if (!err.isEmpty()) {"},{"lineNumber":110,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(err);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":" // validate questions (question details)"},{"lineNumber":113,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails questionDetails \u003d attributes.getQuestionDetailsCopy();"},{"lineNumber":114,"author":{"gitId":"-"},"content":" List\u003cString\u003e questionDetailsErrors \u003d questionDetails.validateQuestionDetails();"},{"lineNumber":115,"author":{"gitId":"-"},"content":" if (!questionDetailsErrors.isEmpty()) {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(String.join(\"\\n\", questionDetailsErrors));"},{"lineNumber":117,"author":{"gitId":"-"},"content":" }"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":120,"author":{"gitId":"-"},"content":" attributes \u003d logic.createFeedbackQuestion(attributes);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(e);"},{"lineNumber":123,"author":{"gitId":"-"},"content":" }"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" return new JsonResult(new FeedbackQuestionData(attributes));"},{"lineNumber":126,"author":{"gitId":"-"},"content":" }"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":4,"-":124}},{"path":"src/main/java/teammates/ui/webapi/CreateFeedbackSessionAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPermissionSet;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionData;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.ui.request.FeedbackSessionCreateRequest;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"-"},"content":" * Create a feedback session."},{"lineNumber":27,"author":{"gitId":"-"},"content":" */"},{"lineNumber":28,"author":{"gitId":"-"},"content":"public class CreateFeedbackSessionAction extends Action {"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":33,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" Instructor instructor \u003d sqlLogic.getInstructorByGoogleId(courseId, userInfo.getId());"},{"lineNumber":43,"author":{"gitId":"-"},"content":" Course course \u003d sqlLogic.getCourse(courseId);"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, course, Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d logic.getInstructorForGoogleId(courseId, userInfo.getId());"},{"lineNumber":48,"author":{"gitId":"-"},"content":" CourseAttributes course \u003d logic.getCourse(courseId);"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, course, Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" }"},{"lineNumber":52,"author":{"gitId":"-"},"content":" }"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":55,"author":{"gitId":"-"},"content":" public JsonResult execute() throws InvalidHttpRequestBodyException, InvalidOperationException {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" FeedbackSessionCreateRequest createRequest \u003d"},{"lineNumber":58,"author":{"gitId":"-"},"content":" getAndValidateRequestBody(FeedbackSessionCreateRequest.class);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" String feedbackSessionName \u003d SanitizationHelper.sanitizeTitle(createRequest.getFeedbackSessionName());"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" Course course \u003d sqlLogic.getCourse(courseId);"},{"lineNumber":63,"author":{"gitId":"-"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Failed to find course with the given course id.\");"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":" Instructor instructor \u003d sqlLogic.getInstructorByGoogleId(courseId, userInfo.getId());"},{"lineNumber":67,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Failed to find instructor with the given courseId and googleId.\");"},{"lineNumber":69,"author":{"gitId":"-"},"content":" }"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" String timeZone \u003d course.getTimeZone();"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" Instant startTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":74,"author":{"gitId":"-"},"content":" createRequest.getSubmissionStartTime(), timeZone, true);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" String startTimeError \u003d FieldValidator.getInvalidityInfoForNewStartTime(startTime, timeZone);"},{"lineNumber":76,"author":{"gitId":"-"},"content":" if (!startTimeError.isEmpty()) {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(\"Invalid submission opening time: \" + startTimeError);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }"},{"lineNumber":79,"author":{"gitId":"-"},"content":" Instant endTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":80,"author":{"gitId":"-"},"content":" createRequest.getSubmissionEndTime(), timeZone, true);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" String endTimeError \u003d FieldValidator.getInvalidityInfoForNewEndTime(endTime, timeZone);"},{"lineNumber":82,"author":{"gitId":"-"},"content":" if (!endTimeError.isEmpty()) {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(\"Invalid submission closing time: \" + endTimeError);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":" Instant sessionVisibleTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":86,"author":{"gitId":"-"},"content":" createRequest.getSessionVisibleFromTime(), timeZone, true);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" String visibilityStartAndSessionStartTimeError \u003d"},{"lineNumber":88,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForNewVisibilityStart(sessionVisibleTime, startTime);"},{"lineNumber":89,"author":{"gitId":"-"},"content":" if (!visibilityStartAndSessionStartTimeError.isEmpty()) {"},{"lineNumber":90,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(\"Invalid session visible time: \""},{"lineNumber":91,"author":{"gitId":"-"},"content":" + visibilityStartAndSessionStartTimeError);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":" Instant resultsVisibleTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":94,"author":{"gitId":"-"},"content":" createRequest.getResultsVisibleFromTime(), timeZone, true);"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession \u003d new FeedbackSession("},{"lineNumber":97,"author":{"gitId":"-"},"content":" feedbackSessionName,"},{"lineNumber":98,"author":{"gitId":"-"},"content":" course,"},{"lineNumber":99,"author":{"gitId":"-"},"content":" instructor.getEmail(),"},{"lineNumber":100,"author":{"gitId":"-"},"content":" createRequest.getInstructions(),"},{"lineNumber":101,"author":{"gitId":"-"},"content":" startTime,"},{"lineNumber":102,"author":{"gitId":"-"},"content":" endTime,"},{"lineNumber":103,"author":{"gitId":"-"},"content":" sessionVisibleTime,"},{"lineNumber":104,"author":{"gitId":"-"},"content":" resultsVisibleTime,"},{"lineNumber":105,"author":{"gitId":"-"},"content":" createRequest.getGracePeriod(),"},{"lineNumber":106,"author":{"gitId":"-"},"content":" true,"},{"lineNumber":107,"author":{"gitId":"-"},"content":" createRequest.isClosingEmailEnabled(),"},{"lineNumber":108,"author":{"gitId":"-"},"content":" createRequest.isPublishedEmailEnabled()"},{"lineNumber":109,"author":{"gitId":"-"},"content":" );"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" feedbackSession \u003d sqlLogic.createFeedbackSession(feedbackSession);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" } catch (EntityAlreadyExistsException e) {"},{"lineNumber":114,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(\"A session named \" + feedbackSessionName"},{"lineNumber":115,"author":{"gitId":"-"},"content":" + \" exists already in the course \" + course.getName()"},{"lineNumber":116,"author":{"gitId":"-"},"content":" + \" (Course ID: \" + courseId + \")\", e);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":118,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(e);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" }"},{"lineNumber":120,"author":{"gitId":"-"},"content":""},{"lineNumber":121,"author":{"gitId":"-"},"content":" if (createRequest.getToCopyCourseId() !\u003d null) {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" createCopiedFeedbackQuestions(createRequest.getToCopyCourseId(), courseId,"},{"lineNumber":123,"author":{"gitId":"-"},"content":" feedbackSessionName, createRequest.getToCopySessionName());"},{"lineNumber":124,"author":{"gitId":"-"},"content":" }"},{"lineNumber":125,"author":{"gitId":"-"},"content":" FeedbackSessionData output \u003d new FeedbackSessionData(feedbackSession);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" InstructorPermissionSet privilege \u003d constructInstructorPrivileges(instructor, feedbackSessionName);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" output.setPrivileges(privilege);"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" return new JsonResult(output);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":131,"author":{"gitId":"-"},"content":" CourseAttributes course \u003d logic.getCourse(courseId);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" String timeZone \u003d course.getTimeZone();"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" Instant startTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":135,"author":{"gitId":"-"},"content":" createRequest.getSubmissionStartTime(), timeZone, true);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" String startTimeError \u003d FieldValidator.getInvalidityInfoForNewStartTime(startTime, timeZone);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" if (!startTimeError.isEmpty()) {"},{"lineNumber":138,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(\"Invalid submission opening time: \" + startTimeError);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" }"},{"lineNumber":140,"author":{"gitId":"-"},"content":" Instant endTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":141,"author":{"gitId":"-"},"content":" createRequest.getSubmissionEndTime(), timeZone, true);"},{"lineNumber":142,"author":{"gitId":"-"},"content":" String endTimeError \u003d FieldValidator.getInvalidityInfoForNewEndTime(endTime, timeZone);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" if (!endTimeError.isEmpty()) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(\"Invalid submission closing time: \" + endTimeError);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":" Instant sessionVisibleTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":147,"author":{"gitId":"-"},"content":" createRequest.getSessionVisibleFromTime(), timeZone, true);"},{"lineNumber":148,"author":{"gitId":"-"},"content":" String visibilityStartAndSessionStartTimeError \u003d"},{"lineNumber":149,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForNewVisibilityStart(sessionVisibleTime, startTime);"},{"lineNumber":150,"author":{"gitId":"-"},"content":" if (!visibilityStartAndSessionStartTimeError.isEmpty()) {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(\"Invalid session visible time: \""},{"lineNumber":152,"author":{"gitId":"-"},"content":" + visibilityStartAndSessionStartTimeError);"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":" Instant resultsVisibleTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":155,"author":{"gitId":"-"},"content":" createRequest.getResultsVisibleFromTime(), timeZone, true);"},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d logic.getInstructorForGoogleId(courseId, userInfo.getId());"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes fs \u003d"},{"lineNumber":160,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes"},{"lineNumber":161,"author":{"gitId":"-"},"content":" .builder(feedbackSessionName, course.getId())"},{"lineNumber":162,"author":{"gitId":"-"},"content":" .withCreatorEmail(instructor.getEmail())"},{"lineNumber":163,"author":{"gitId":"-"},"content":" .withTimeZone(course.getTimeZone())"},{"lineNumber":164,"author":{"gitId":"-"},"content":" .withInstructions(createRequest.getInstructions())"},{"lineNumber":165,"author":{"gitId":"-"},"content":" .withStartTime(startTime)"},{"lineNumber":166,"author":{"gitId":"-"},"content":" .withEndTime(endTime)"},{"lineNumber":167,"author":{"gitId":"-"},"content":" .withGracePeriod(createRequest.getGracePeriod())"},{"lineNumber":168,"author":{"gitId":"-"},"content":" .withSessionVisibleFromTime(sessionVisibleTime)"},{"lineNumber":169,"author":{"gitId":"-"},"content":" .withResultsVisibleFromTime(resultsVisibleTime)"},{"lineNumber":170,"author":{"gitId":"-"},"content":" .withIsClosingEmailEnabled(createRequest.isClosingEmailEnabled())"},{"lineNumber":171,"author":{"gitId":"-"},"content":" .withIsPublishedEmailEnabled(createRequest.isPublishedEmailEnabled())"},{"lineNumber":172,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":173,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" logic.createFeedbackSession(fs);"},{"lineNumber":175,"author":{"gitId":"-"},"content":" } catch (EntityAlreadyExistsException e) {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(\"A session named \" + feedbackSessionName"},{"lineNumber":177,"author":{"gitId":"-"},"content":" + \" exists already in the course \" + course.getName()"},{"lineNumber":178,"author":{"gitId":"-"},"content":" + \" (Course ID: \" + courseId + \")\", e);"},{"lineNumber":179,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(e);"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" if (createRequest.getToCopyCourseId() !\u003d null) {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" createFeedbackQuestions(createRequest.getToCopyCourseId(), courseId, feedbackSessionName,"},{"lineNumber":185,"author":{"gitId":"-"},"content":" createRequest.getToCopySessionName());"},{"lineNumber":186,"author":{"gitId":"-"},"content":" }"},{"lineNumber":187,"author":{"gitId":"-"},"content":" fs \u003d getNonNullFeedbackSession(fs.getFeedbackSessionName(), fs.getCourseId());"},{"lineNumber":188,"author":{"gitId":"-"},"content":" FeedbackSessionData output \u003d new FeedbackSessionData(fs);"},{"lineNumber":189,"author":{"gitId":"-"},"content":" InstructorPermissionSet privilege \u003d constructInstructorPrivileges(instructor, feedbackSessionName);"},{"lineNumber":190,"author":{"gitId":"-"},"content":" output.setPrivileges(privilege);"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"-"},"content":" return new JsonResult(output);"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":" }"},{"lineNumber":195,"author":{"gitId":"-"},"content":""},{"lineNumber":196,"author":{"gitId":"-"},"content":" private void createCopiedFeedbackQuestions(String oldCourseId, String newCourseId,"},{"lineNumber":197,"author":{"gitId":"-"},"content":" String newFeedbackSessionName, String oldFeedbackSessionName) {"},{"lineNumber":198,"author":{"gitId":"-"},"content":" FeedbackSession oldFeedbackSession \u003d sqlLogic.getFeedbackSession(oldFeedbackSessionName, oldCourseId);"},{"lineNumber":199,"author":{"gitId":"-"},"content":" FeedbackSession newFeedbackSession \u003d sqlLogic.getFeedbackSession(newFeedbackSessionName, newCourseId);"},{"lineNumber":200,"author":{"gitId":"-"},"content":" sqlLogic.getFeedbackQuestionsForSession(oldFeedbackSession).forEach(question -\u003e {"},{"lineNumber":201,"author":{"gitId":"-"},"content":" FeedbackQuestion feedbackQuestion \u003d question.makeDeepCopy(newFeedbackSession);"},{"lineNumber":202,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":203,"author":{"gitId":"-"},"content":" sqlLogic.createFeedbackQuestion(feedbackQuestion);"},{"lineNumber":204,"author":{"gitId":"marquestye"},"content":" } catch (InvalidParametersException | EntityAlreadyExistsException e) {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" log.severe(\"Error when copying feedback question: \" + e.getMessage());"},{"lineNumber":206,"author":{"gitId":"-"},"content":" }"},{"lineNumber":207,"author":{"gitId":"-"},"content":" });"},{"lineNumber":208,"author":{"gitId":"-"},"content":" }"},{"lineNumber":209,"author":{"gitId":"-"},"content":""},{"lineNumber":210,"author":{"gitId":"-"},"content":" private void createFeedbackQuestions(String copyCourseId, String newCourseId, String feedbackSessionName,"},{"lineNumber":211,"author":{"gitId":"-"},"content":" String oldSessionName) {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" logic.getFeedbackQuestionsForSession(oldSessionName, copyCourseId).forEach(question -\u003e {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes attributes \u003d FeedbackQuestionAttributes.builder()"},{"lineNumber":214,"author":{"gitId":"-"},"content":" .withCourseId(newCourseId)"},{"lineNumber":215,"author":{"gitId":"-"},"content":" .withFeedbackSessionName(feedbackSessionName)"},{"lineNumber":216,"author":{"gitId":"-"},"content":" .withGiverType(question.getGiverType())"},{"lineNumber":217,"author":{"gitId":"-"},"content":" .withRecipientType(question.getRecipientType())"},{"lineNumber":218,"author":{"gitId":"-"},"content":" .withQuestionNumber(question.getQuestionNumber())"},{"lineNumber":219,"author":{"gitId":"-"},"content":" .withNumberOfEntitiesToGiveFeedbackTo(question.getNumberOfEntitiesToGiveFeedbackTo())"},{"lineNumber":220,"author":{"gitId":"-"},"content":" .withShowResponsesTo(question.getShowResponsesTo())"},{"lineNumber":221,"author":{"gitId":"-"},"content":" .withShowGiverNameTo(question.getShowGiverNameTo())"},{"lineNumber":222,"author":{"gitId":"-"},"content":" .withShowRecipientNameTo(question.getShowRecipientNameTo())"},{"lineNumber":223,"author":{"gitId":"-"},"content":" .withQuestionDetails(question.getQuestionDetails())"},{"lineNumber":224,"author":{"gitId":"-"},"content":" .withQuestionDescription(question.getQuestionDescription())"},{"lineNumber":225,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":228,"author":{"gitId":"-"},"content":" logic.createFeedbackQuestion(attributes);"},{"lineNumber":229,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":230,"author":{"gitId":"-"},"content":" log.severe(\"Error when copying feedback question: \" + e.getMessage());"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":" });"},{"lineNumber":233,"author":{"gitId":"-"},"content":" }"},{"lineNumber":234,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":1,"-":233}},{"path":"src/main/java/teammates/ui/webapi/CreateFeedbackSessionLogAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionAuditLogDetails;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * Action: creates a feedback session log for the purposes of tracking and auditing."},{"lineNumber":12,"author":{"gitId":"-"},"content":" */"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"public class CreateFeedbackSessionLogAction extends Action {"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":18,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" return AuthType.PUBLIC;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" }"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":23,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" // No specific access control restrictions on creating feedback session logs"},{"lineNumber":25,"author":{"gitId":"-"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"-"},"content":" public JsonResult execute() {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" String fslType \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE);"},{"lineNumber":30,"author":{"gitId":"-"},"content":" FeedbackSessionLogType convertedFslType \u003d FeedbackSessionLogType.valueOfLabel(fslType);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" if (convertedFslType \u003d\u003d null) {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Invalid log type\");"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":36,"author":{"gitId":"-"},"content":" String fsName \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" String studentEmail \u003d getNonNullRequestParamValue(Const.ParamsNames.STUDENT_EMAIL);"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" // Skip rigorous validations to avoid incurring extra db reads and to keep the endpoint"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" // light"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" FeedbackSessionAuditLogDetails details \u003d new FeedbackSessionAuditLogDetails();"},{"lineNumber":42,"author":{"gitId":"-"},"content":" details.setCourseId(courseId);"},{"lineNumber":43,"author":{"gitId":"-"},"content":" details.setFeedbackSessionName(fsName);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" details.setStudentEmail(studentEmail);"},{"lineNumber":45,"author":{"gitId":"-"},"content":" details.setAccessType(fslType);"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" UUID studentId \u003d getUuidRequestParamValue(Const.ParamsNames.STUDENT_SQL_ID);"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" UUID fsId \u003d getUuidRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_ID);"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" details.setStudentId(studentId.toString());"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" details.setFeedbackSessionId(fsId.toString());"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" // Necessary to assist local testing. For production usage, this will be a no-op."},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" logsProcessor.createFeedbackSessionLog(courseId, studentId, fsId, fslType);"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" // Necessary to assist local testing. For production usage, this will be a no-op."},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" logsProcessor.createFeedbackSessionLog(courseId, studentEmail, fsName, fslType);"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" log.event(\"Feedback session audit event: \" + fslType, details);"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" return new JsonResult(\"Successful\");"},{"lineNumber":64,"author":{"gitId":"-"},"content":" }"},{"lineNumber":65,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":19,"-":46}},{"path":"src/main/java/teammates/ui/webapi/CreateInstructorAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.datatransfer.InstructorPermissionRole;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPrivileges;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":10,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":11,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.ui.output.InstructorData;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.ui.request.InstructorCreateRequest;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * Action: adds another instructor to a course that already exists."},{"lineNumber":18,"author":{"gitId":"-"},"content":" */"},{"lineNumber":19,"author":{"gitId":"mingyuanc"},"content":"public class CreateInstructorAction extends Action {"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":22,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":23,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" }"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":27,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" if (userInfo.isAdmin) {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" if (!userInfo.isInstructor) {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Instructor privilege is required to access this resource.\");"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"mingyuanc"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":39,"author":{"gitId":"mingyuanc"},"content":" Instructor instructor \u003d sqlLogic.getInstructorByGoogleId(courseId, userInfo.id);"},{"lineNumber":40,"author":{"gitId":"mingyuanc"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":41,"author":{"gitId":"mingyuanc"},"content":" instructor, sqlLogic.getCourse(courseId), Const.InstructorPermissions.CAN_MODIFY_INSTRUCTOR);"},{"lineNumber":42,"author":{"gitId":"mingyuanc"},"content":" } else {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d logic.getInstructorForGoogleId(courseId, userInfo.id);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":45,"author":{"gitId":"-"},"content":" instructor, logic.getCourse(courseId), Const.InstructorPermissions.CAN_MODIFY_INSTRUCTOR);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":" }"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":50,"author":{"gitId":"-"},"content":" public JsonResult execute() throws InvalidHttpRequestBodyException, InvalidOperationException {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" InstructorCreateRequest instructorRequest \u003d getAndValidateRequestBody(InstructorCreateRequest.class);"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":55,"author":{"gitId":"mingyuanc"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":56,"author":{"gitId":"mingyuanc"},"content":" return executeWithSql(courseId, instructorRequest);"},{"lineNumber":57,"author":{"gitId":"mingyuanc"},"content":" } else {"},{"lineNumber":58,"author":{"gitId":"mingyuanc"},"content":" return executeWithDataStore(courseId, instructorRequest);"},{"lineNumber":59,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":" } catch (EntityAlreadyExistsException e) {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" throw new InvalidOperationException("},{"lineNumber":62,"author":{"gitId":"-"},"content":" \"An instructor with the same email address already exists in the course.\", e);"},{"lineNumber":63,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(e);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":67,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":68,"author":{"gitId":"mingyuanc"},"content":" /**"},{"lineNumber":69,"author":{"gitId":"mingyuanc"},"content":" * Executes the action using SQL storage."},{"lineNumber":70,"author":{"gitId":"mingyuanc"},"content":" *"},{"lineNumber":71,"author":{"gitId":"mingyuanc"},"content":" * @param courseId Id of the course the instructor is being added"},{"lineNumber":72,"author":{"gitId":"mingyuanc"},"content":" * to."},{"lineNumber":73,"author":{"gitId":"mingyuanc"},"content":" * @param instructorRequest Request body containing the instructor\u0027s info."},{"lineNumber":74,"author":{"gitId":"mingyuanc"},"content":" * @return The Json result of the created Instructor"},{"lineNumber":75,"author":{"gitId":"mingyuanc"},"content":" * @throws InvalidParametersException If a parameter is invalid"},{"lineNumber":76,"author":{"gitId":"mingyuanc"},"content":" * @throws EntityAlreadyExistsException If there is a conflict at the email"},{"lineNumber":77,"author":{"gitId":"mingyuanc"},"content":" * field"},{"lineNumber":78,"author":{"gitId":"mingyuanc"},"content":" */"},{"lineNumber":79,"author":{"gitId":"mingyuanc"},"content":" private JsonResult executeWithSql(String courseId, InstructorCreateRequest instructorRequest)"},{"lineNumber":80,"author":{"gitId":"mingyuanc"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":81,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":82,"author":{"gitId":"mingyuanc"},"content":" Instructor instructorToAdd \u003d createInstructorWithBasicAttributesSql(courseId,"},{"lineNumber":83,"author":{"gitId":"mingyuanc"},"content":" SanitizationHelper.sanitizeName(instructorRequest.getName()),"},{"lineNumber":84,"author":{"gitId":"mingyuanc"},"content":" SanitizationHelper.sanitizeEmail(instructorRequest.getEmail()), instructorRequest.getRoleName(),"},{"lineNumber":85,"author":{"gitId":"mingyuanc"},"content":" instructorRequest.getIsDisplayedToStudent(),"},{"lineNumber":86,"author":{"gitId":"mingyuanc"},"content":" SanitizationHelper.sanitizeName(instructorRequest.getDisplayName()));"},{"lineNumber":87,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":88,"author":{"gitId":"mingyuanc"},"content":" Instructor createdInstructor \u003d sqlLogic.createInstructor(instructorToAdd);"},{"lineNumber":89,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":90,"author":{"gitId":"mingyuanc"},"content":" taskQueuer.scheduleCourseRegistrationInviteToInstructor("},{"lineNumber":91,"author":{"gitId":"mingyuanc"},"content":" this.userInfo.id, instructorToAdd.getEmail(), courseId, false);"},{"lineNumber":92,"author":{"gitId":"mingyuanc"},"content":" taskQueuer.scheduleInstructorForSearchIndexing(createdInstructor.getCourseId(), createdInstructor.getEmail());"},{"lineNumber":93,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":94,"author":{"gitId":"mingyuanc"},"content":" return new JsonResult(new InstructorData(createdInstructor));"},{"lineNumber":95,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":96,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":97,"author":{"gitId":"mingyuanc"},"content":" /**"},{"lineNumber":98,"author":{"gitId":"mingyuanc"},"content":" * Executes the action using Datastore storage."},{"lineNumber":99,"author":{"gitId":"mingyuanc"},"content":" *"},{"lineNumber":100,"author":{"gitId":"mingyuanc"},"content":" * @param courseId Id of the course the instructor is being added"},{"lineNumber":101,"author":{"gitId":"mingyuanc"},"content":" * to."},{"lineNumber":102,"author":{"gitId":"mingyuanc"},"content":" * @param instructorRequest Request body containing the instructor\u0027s info."},{"lineNumber":103,"author":{"gitId":"mingyuanc"},"content":" * @return The Json result of the created Instructor"},{"lineNumber":104,"author":{"gitId":"mingyuanc"},"content":" * @throws InvalidParametersException If a parameter is invalid"},{"lineNumber":105,"author":{"gitId":"mingyuanc"},"content":" * @throws EntityAlreadyExistsException If there is a conflict at the email"},{"lineNumber":106,"author":{"gitId":"mingyuanc"},"content":" * field"},{"lineNumber":107,"author":{"gitId":"mingyuanc"},"content":" */"},{"lineNumber":108,"author":{"gitId":"mingyuanc"},"content":" private JsonResult executeWithDataStore(String courseId, InstructorCreateRequest instructorRequest)"},{"lineNumber":109,"author":{"gitId":"mingyuanc"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":110,"author":{"gitId":"-"},"content":" InstructorAttributes instructorToAdd \u003d createInstructorWithBasicAttributes(courseId,"},{"lineNumber":111,"author":{"gitId":"-"},"content":" instructorRequest.getName(), instructorRequest.getEmail(), instructorRequest.getRoleName(),"},{"lineNumber":112,"author":{"gitId":"-"},"content":" instructorRequest.getIsDisplayedToStudent(), instructorRequest.getDisplayName());"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" InstructorAttributes createdInstructor \u003d logic.createInstructor(instructorToAdd);"},{"lineNumber":115,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" taskQueuer.scheduleCourseRegistrationInviteToInstructor("},{"lineNumber":117,"author":{"gitId":"-"},"content":" userInfo.id, instructorToAdd.getEmail(), instructorToAdd.getCourseId(), false);"},{"lineNumber":118,"author":{"gitId":"-"},"content":" taskQueuer.scheduleInstructorForSearchIndexing(createdInstructor.getCourseId(), createdInstructor.getEmail());"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" return new JsonResult(new InstructorData(createdInstructor));"},{"lineNumber":121,"author":{"gitId":"-"},"content":" }"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"mingyuanc"},"content":" /**"},{"lineNumber":124,"author":{"gitId":"mingyuanc"},"content":" * Creates a new instructor with basic information."},{"lineNumber":125,"author":{"gitId":"mingyuanc"},"content":" * This consists of everything apart from custom privileges."},{"lineNumber":126,"author":{"gitId":"mingyuanc"},"content":" *"},{"lineNumber":127,"author":{"gitId":"mingyuanc"},"content":" * @param courseId Id of the course the instructor is being added"},{"lineNumber":128,"author":{"gitId":"mingyuanc"},"content":" * to."},{"lineNumber":129,"author":{"gitId":"mingyuanc"},"content":" * @param instructorName Name of the instructor."},{"lineNumber":130,"author":{"gitId":"mingyuanc"},"content":" * @param instructorEmail Email of the instructor."},{"lineNumber":131,"author":{"gitId":"mingyuanc"},"content":" * @param instructorRole Role of the instructor."},{"lineNumber":132,"author":{"gitId":"mingyuanc"},"content":" * @param isDisplayedToStudents Whether the instructor should be visible to"},{"lineNumber":133,"author":{"gitId":"mingyuanc"},"content":" * students."},{"lineNumber":134,"author":{"gitId":"mingyuanc"},"content":" * @param displayedName Name to be visible to students."},{"lineNumber":135,"author":{"gitId":"mingyuanc"},"content":" * Should not be {@code null} even if"},{"lineNumber":136,"author":{"gitId":"mingyuanc"},"content":" * {@code isDisplayedToStudents} is false."},{"lineNumber":137,"author":{"gitId":"mingyuanc"},"content":" * @return An instructor with basic info, excluding custom privileges"},{"lineNumber":138,"author":{"gitId":"mingyuanc"},"content":" */"},{"lineNumber":139,"author":{"gitId":"mingyuanc"},"content":" private Instructor createInstructorWithBasicAttributesSql(String courseId, String instructorName,"},{"lineNumber":140,"author":{"gitId":"mingyuanc"},"content":" String instructorEmail, String instructorRole,"},{"lineNumber":141,"author":{"gitId":"mingyuanc"},"content":" boolean isDisplayedToStudents, String displayedName) {"},{"lineNumber":142,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":143,"author":{"gitId":"mingyuanc"},"content":" String instrName \u003d SanitizationHelper.sanitizeName(instructorName);"},{"lineNumber":144,"author":{"gitId":"mingyuanc"},"content":" String instrEmail \u003d SanitizationHelper.sanitizeEmail(instructorEmail);"},{"lineNumber":145,"author":{"gitId":"mingyuanc"},"content":" String instrRole \u003d SanitizationHelper.sanitizeName(instructorRole);"},{"lineNumber":146,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":147,"author":{"gitId":"mingyuanc"},"content":" String instrDisplayedName \u003d displayedName;"},{"lineNumber":148,"author":{"gitId":"mingyuanc"},"content":" if (displayedName \u003d\u003d null || displayedName.isEmpty()) {"},{"lineNumber":149,"author":{"gitId":"mingyuanc"},"content":" instrDisplayedName \u003d Const.DEFAULT_DISPLAY_NAME_FOR_INSTRUCTOR;"},{"lineNumber":150,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":151,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":152,"author":{"gitId":"mingyuanc"},"content":" InstructorPrivileges privileges \u003d new InstructorPrivileges(instrRole);"},{"lineNumber":153,"author":{"gitId":"mingyuanc"},"content":" InstructorPermissionRole role \u003d InstructorPermissionRole.getEnum(instrRole);"},{"lineNumber":154,"author":{"gitId":"mingyuanc"},"content":" Course course \u003d sqlLogic.getCourse(courseId);"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"mingyuanc"},"content":" return new Instructor(course, instrName, instrEmail, isDisplayedToStudents, instrDisplayedName, role,"},{"lineNumber":157,"author":{"gitId":"mingyuanc"},"content":" privileges);"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":161,"author":{"gitId":"-"},"content":" * Creates a new instructor with basic information."},{"lineNumber":162,"author":{"gitId":"-"},"content":" * This consists of everything apart from custom privileges."},{"lineNumber":163,"author":{"gitId":"-"},"content":" *"},{"lineNumber":164,"author":{"gitId":"mingyuanc"},"content":" * @param courseId Id of the course the instructor is being added"},{"lineNumber":165,"author":{"gitId":"mingyuanc"},"content":" * to."},{"lineNumber":166,"author":{"gitId":"-"},"content":" * @param instructorName Name of the instructor."},{"lineNumber":167,"author":{"gitId":"-"},"content":" * @param instructorEmail Email of the instructor."},{"lineNumber":168,"author":{"gitId":"-"},"content":" * @param instructorRole Role of the instructor."},{"lineNumber":169,"author":{"gitId":"mingyuanc"},"content":" * @param isDisplayedToStudents Whether the instructor should be visible to"},{"lineNumber":170,"author":{"gitId":"mingyuanc"},"content":" * students."},{"lineNumber":171,"author":{"gitId":"-"},"content":" * @param displayedName Name to be visible to students."},{"lineNumber":172,"author":{"gitId":"mingyuanc"},"content":" * Should not be {@code null} even if"},{"lineNumber":173,"author":{"gitId":"mingyuanc"},"content":" * {@code isDisplayedToStudents} is false."},{"lineNumber":174,"author":{"gitId":"-"},"content":" * @return An instructor with basic info, excluding custom privileges"},{"lineNumber":175,"author":{"gitId":"-"},"content":" */"},{"lineNumber":176,"author":{"gitId":"-"},"content":" private InstructorAttributes createInstructorWithBasicAttributes(String courseId, String instructorName,"},{"lineNumber":177,"author":{"gitId":"-"},"content":" String instructorEmail, String instructorRole,"},{"lineNumber":178,"author":{"gitId":"-"},"content":" boolean isDisplayedToStudents, String displayedName) {"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" String instrName \u003d SanitizationHelper.sanitizeName(instructorName);"},{"lineNumber":181,"author":{"gitId":"-"},"content":" String instrEmail \u003d SanitizationHelper.sanitizeEmail(instructorEmail);"},{"lineNumber":182,"author":{"gitId":"-"},"content":" String instrRole \u003d SanitizationHelper.sanitizeName(instructorRole);"},{"lineNumber":183,"author":{"gitId":"-"},"content":""},{"lineNumber":184,"author":{"gitId":"-"},"content":" String instrDisplayedName \u003d displayedName;"},{"lineNumber":185,"author":{"gitId":"-"},"content":" if (displayedName \u003d\u003d null || displayedName.isEmpty()) {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" instrDisplayedName \u003d Const.DEFAULT_DISPLAY_NAME_FOR_INSTRUCTOR;"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":" instrDisplayedName \u003d SanitizationHelper.sanitizeName(instrDisplayedName);"},{"lineNumber":190,"author":{"gitId":"-"},"content":" InstructorPrivileges privileges \u003d new InstructorPrivileges(instructorRole);"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"-"},"content":" return InstructorAttributes.builder(courseId, instrEmail)"},{"lineNumber":193,"author":{"gitId":"-"},"content":" .withName(instrName)"},{"lineNumber":194,"author":{"gitId":"-"},"content":" .withRole(instrRole)"},{"lineNumber":195,"author":{"gitId":"-"},"content":" .withIsDisplayedToStudents(isDisplayedToStudents)"},{"lineNumber":196,"author":{"gitId":"-"},"content":" .withDisplayedName(instrDisplayedName)"},{"lineNumber":197,"author":{"gitId":"-"},"content":" .withPrivileges(privileges)"},{"lineNumber":198,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":199,"author":{"gitId":"-"},"content":" }"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"mingyuanc":99,"-":102}},{"path":"src/main/java/teammates/ui/webapi/DeleteAccountRequestAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":9,"author":{"gitId":"-"},"content":" * Deletes an existing account request."},{"lineNumber":10,"author":{"gitId":"-"},"content":" */"},{"lineNumber":11,"author":{"gitId":"-"},"content":"class DeleteAccountRequestAction extends AdminOnlyAction {"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":14,"author":{"gitId":"-"},"content":" public JsonResult execute() throws InvalidOperationException {"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":" UUID id \u003d getUuidRequestParamValue(Const.ParamsNames.ACCOUNT_REQUEST_ID);"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":" AccountRequest toDelete \u003d sqlLogic.getAccountRequest(id);"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":" if (toDelete !\u003d null \u0026\u0026 toDelete.getRegisteredAt() !\u003d null) {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" // instructor is already registered and cannot be deleted"},{"lineNumber":21,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(\"Account request of a registered instructor cannot be deleted.\");"},{"lineNumber":22,"author":{"gitId":"-"},"content":" }"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":" sqlLogic.deleteAccountRequest(id);"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" return new JsonResult(\"Account request successfully deleted.\");"},{"lineNumber":27,"author":{"gitId":"-"},"content":" }"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":5,"-":24}},{"path":"src/main/java/teammates/ui/webapi/EnrollStudentsAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.Set;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.EnrollException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.util.RequestTracer;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.ui.output.EnrollStudentsData;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.ui.output.StudentData;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.ui.output.StudentsData;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.ui.request.StudentsEnrollRequest;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":28,"author":{"gitId":"-"},"content":" * Enroll a list of students."},{"lineNumber":29,"author":{"gitId":"-"},"content":" *"},{"lineNumber":30,"author":{"gitId":"-"},"content":" * \u003cp\u003eCreate the students who are not in the course."},{"lineNumber":31,"author":{"gitId":"-"},"content":" *"},{"lineNumber":32,"author":{"gitId":"-"},"content":" * \u003cp\u003eUpdate the students who are already existed."},{"lineNumber":33,"author":{"gitId":"-"},"content":" *"},{"lineNumber":34,"author":{"gitId":"-"},"content":" * \u003cp\u003eReturn all students who are successfully enrolled."},{"lineNumber":35,"author":{"gitId":"-"},"content":" */"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":"public class EnrollStudentsAction extends Action {"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":39,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":44,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" if (!userInfo.isInstructor) {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Instructor privilege is required to access this resource.\");"},{"lineNumber":47,"author":{"gitId":"-"},"content":" }"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" if (!isCourseMigrated(courseId)) {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d logic.getInstructorForGoogleId(courseId, userInfo.id);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":53,"author":{"gitId":"-"},"content":" instructor, logic.getCourse(courseId), Const.InstructorPermissions.CAN_MODIFY_STUDENT);"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" return;"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" Instructor instructor \u003d sqlLogic.getInstructorByGoogleId(courseId, userInfo.id);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" instructor, sqlLogic.getCourse(courseId), Const.InstructorPermissions.CAN_MODIFY_STUDENT);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":64,"author":{"gitId":"-"},"content":" public JsonResult execute() throws InvalidHttpRequestBodyException, InvalidOperationException {"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" StudentsEnrollRequest enrollRequests \u003d getAndValidateRequestBody(StudentsEnrollRequest.class);"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":" List\u003cStudentsEnrollRequest.StudentEnrollRequest\u003e studentEnrollRequests \u003d enrollRequests.getStudentEnrollRequests();"},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" Course course \u003d sqlLogic.getCourse(courseId);"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" boolean isCourseMigrated \u003d isCourseMigrated(courseId);"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" if (isCourseMigrated) {"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e studentsToEnroll \u003d new ArrayList\u003c\u003e();"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" studentEnrollRequests.forEach(studentEnrollRequest -\u003e {"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" Section section \u003d new Section(course, studentEnrollRequest.getSection());"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" Team team \u003d new Team(section, studentEnrollRequest.getTeam());"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" studentsToEnroll.add(new Student("},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" course, studentEnrollRequest.getName(),"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" studentEnrollRequest.getEmail(), studentEnrollRequest.getComments(), team));"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" sqlLogic.validateSectionsAndTeams(studentsToEnroll, courseId);"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" } catch (EnrollException e) {"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" throw new InvalidOperationException(e);"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e enrolledStudents \u003d new ArrayList\u003c\u003e();"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" List\u003cEnrollStudentsData.EnrollErrorResults\u003e failToEnrollStudents \u003d new ArrayList\u003c\u003e();"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" Set\u003cString\u003e existingStudentsEmail;"},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e existingStudents \u003d sqlLogic.getStudentsForCourse(courseId);"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" existingStudentsEmail \u003d"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":" existingStudents.stream().map(Student::getEmail).collect(Collectors.toSet());"},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" for (StudentsEnrollRequest.StudentEnrollRequest enrollRequest : studentEnrollRequests) {"},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":" if (existingStudentsEmail.contains(enrollRequest.getEmail())) {"},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":" // The student has been enrolled in the course."},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":" Section section \u003d sqlLogic.getSectionOrCreate(courseId, enrollRequest.getSection());"},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" Team team \u003d sqlLogic.getTeamOrCreate(section, enrollRequest.getTeam());"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" Student newStudent \u003d new Student("},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":" course, enrollRequest.getName(),"},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" enrollRequest.getEmail(), enrollRequest.getComments(), team);"},{"lineNumber":105,"author":{"gitId":"marquestye"},"content":" newStudent.setId(sqlLogic.getStudentForEmail(courseId, enrollRequest.getEmail()).getId());"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" Student updatedStudent \u003d sqlLogic.updateStudentCascade(newStudent);"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" taskQueuer.scheduleStudentForSearchIndexing("},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" updatedStudent.getCourseId(), updatedStudent.getEmail());"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" enrolledStudents.add(updatedStudent);"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" } catch (InvalidParametersException | EntityDoesNotExistException"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" | EntityAlreadyExistsException exception) {"},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" // Unsuccessfully enrolled students will not be returned."},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" failToEnrollStudents.add(new EnrollStudentsData.EnrollErrorResults(enrollRequest.getEmail(),"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" exception.getMessage()));"},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" } else {"},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":" // The student is new."},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" Section section \u003d sqlLogic.getSectionOrCreate(courseId, enrollRequest.getSection());"},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" Team team \u003d sqlLogic.getTeamOrCreate(section, enrollRequest.getTeam());"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":" Student newStudent \u003d new Student("},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" course, enrollRequest.getName(),"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":" enrollRequest.getEmail(), enrollRequest.getComments(), team);"},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" newStudent \u003d sqlLogic.createStudent(newStudent);"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" taskQueuer.scheduleStudentForSearchIndexing("},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" newStudent.getCourseId(), newStudent.getEmail());"},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" enrolledStudents.add(newStudent);"},{"lineNumber":128,"author":{"gitId":"domoberzin"},"content":" } catch (InvalidParametersException | EntityAlreadyExistsException exception) {"},{"lineNumber":129,"author":{"gitId":"domoberzin"},"content":" // Unsuccessfully enrolled students will not be returned."},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":" failToEnrollStudents.add(new EnrollStudentsData.EnrollErrorResults(enrollRequest.getEmail(),"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":" exception.getMessage()));"},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" List\u003cStudentData\u003e studentDataList \u003d enrolledStudents"},{"lineNumber":137,"author":{"gitId":"domoberzin"},"content":" .stream()"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":" .map(StudentData::new)"},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":" .collect(Collectors.toList());"},{"lineNumber":140,"author":{"gitId":"domoberzin"},"content":" StudentsData data \u003d new StudentsData();"},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":" data.setStudents(studentDataList);"},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":" return new JsonResult(new EnrollStudentsData(data, failToEnrollStudents));"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":" } else {"},{"lineNumber":147,"author":{"gitId":"-"},"content":" List\u003cStudentAttributes\u003e studentsToEnroll \u003d new ArrayList\u003c\u003e();"},{"lineNumber":148,"author":{"gitId":"-"},"content":" enrollRequests.getStudentEnrollRequests().forEach(studentEnrollRequest -\u003e {"},{"lineNumber":149,"author":{"gitId":"-"},"content":" studentsToEnroll.add(StudentAttributes.builder(courseId, studentEnrollRequest.getEmail())"},{"lineNumber":150,"author":{"gitId":"-"},"content":" .withName(studentEnrollRequest.getName())"},{"lineNumber":151,"author":{"gitId":"-"},"content":" .withSectionName(studentEnrollRequest.getSection())"},{"lineNumber":152,"author":{"gitId":"-"},"content":" .withTeamName(studentEnrollRequest.getTeam())"},{"lineNumber":153,"author":{"gitId":"-"},"content":" .withComment(studentEnrollRequest.getComments())"},{"lineNumber":154,"author":{"gitId":"-"},"content":" .build());"},{"lineNumber":155,"author":{"gitId":"-"},"content":" });"},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" logic.validateSectionsAndTeams(studentsToEnroll, courseId);"},{"lineNumber":159,"author":{"gitId":"-"},"content":" } catch (EnrollException e) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(e);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" List\u003cStudentAttributes\u003e enrolledStudents \u003d new ArrayList\u003c\u003e();"},{"lineNumber":164,"author":{"gitId":"-"},"content":" List\u003cEnrollStudentsData.EnrollErrorResults\u003e failToEnrollStudents \u003d new ArrayList\u003c\u003e();"},{"lineNumber":165,"author":{"gitId":"domoberzin"},"content":" Set\u003cString\u003e existingStudentsEmail;"},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" List\u003cStudentAttributes\u003e existingStudents \u003d logic.getStudentsForCourse(courseId);"},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":" existingStudentsEmail \u003d"},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" existingStudents.stream().map(StudentAttributes::getEmail).collect(Collectors.toSet());"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" for (StudentAttributes student : studentsToEnroll) {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":173,"author":{"gitId":"-"},"content":" if (existingStudentsEmail.contains(student.getEmail())) {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" // The student has been enrolled in the course."},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" StudentAttributes.UpdateOptions updateOptions \u003d"},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" StudentAttributes.updateOptionsBuilder(courseId, student.getEmail())"},{"lineNumber":178,"author":{"gitId":"-"},"content":" .withName(student.getName())"},{"lineNumber":179,"author":{"gitId":"-"},"content":" .withSectionName(student.getSection())"},{"lineNumber":180,"author":{"gitId":"-"},"content":" .withTeamName(student.getTeam())"},{"lineNumber":181,"author":{"gitId":"-"},"content":" .withComment(student.getComments())"},{"lineNumber":182,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":183,"author":{"gitId":"-"},"content":" StudentAttributes updatedStudent \u003d logic.updateStudentCascade(updateOptions);"},{"lineNumber":184,"author":{"gitId":"domoberzin"},"content":" taskQueuer.scheduleStudentForSearchIndexing("},{"lineNumber":185,"author":{"gitId":"domoberzin"},"content":" updatedStudent.getCourse(), updatedStudent.getEmail());"},{"lineNumber":186,"author":{"gitId":"-"},"content":" enrolledStudents.add(updatedStudent);"},{"lineNumber":187,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException | EntityDoesNotExistException"},{"lineNumber":188,"author":{"gitId":"-"},"content":" | EntityAlreadyExistsException exception) {"},{"lineNumber":189,"author":{"gitId":"-"},"content":" // Unsuccessfully enrolled students will not be returned."},{"lineNumber":190,"author":{"gitId":"-"},"content":" failToEnrollStudents.add(new EnrollStudentsData.EnrollErrorResults(student.getEmail(),"},{"lineNumber":191,"author":{"gitId":"-"},"content":" exception.getMessage()));"},{"lineNumber":192,"author":{"gitId":"-"},"content":" }"},{"lineNumber":193,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":194,"author":{"gitId":"-"},"content":" // The student is new."},{"lineNumber":195,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":" StudentAttributes studentAttributes \u003d StudentAttributes.builder(courseId, student.getEmail())"},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":" .withName(student.getName())"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" .withSectionName(student.getSection())"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":" .withTeamName(student.getTeam())"},{"lineNumber":200,"author":{"gitId":"domoberzin"},"content":" .withComment(student.getComments())"},{"lineNumber":201,"author":{"gitId":"domoberzin"},"content":" .build();"},{"lineNumber":202,"author":{"gitId":"domoberzin"},"content":" StudentAttributes newStudent \u003d logic.createStudent(studentAttributes);"},{"lineNumber":203,"author":{"gitId":"-"},"content":" taskQueuer.scheduleStudentForSearchIndexing(newStudent.getCourse(), newStudent.getEmail());"},{"lineNumber":204,"author":{"gitId":"-"},"content":" enrolledStudents.add(newStudent);"},{"lineNumber":205,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException | EntityAlreadyExistsException exception) {"},{"lineNumber":206,"author":{"gitId":"-"},"content":" // Unsuccessfully enrolled students will not be returned."},{"lineNumber":207,"author":{"gitId":"-"},"content":" failToEnrollStudents.add(new EnrollStudentsData.EnrollErrorResults(student.getEmail(),"},{"lineNumber":208,"author":{"gitId":"-"},"content":" exception.getMessage()));"},{"lineNumber":209,"author":{"gitId":"-"},"content":" }"},{"lineNumber":210,"author":{"gitId":"-"},"content":" }"},{"lineNumber":211,"author":{"gitId":"-"},"content":" }"},{"lineNumber":212,"author":{"gitId":"-"},"content":""},{"lineNumber":213,"author":{"gitId":"-"},"content":" List\u003cStudentData\u003e studentDataList \u003d enrolledStudents"},{"lineNumber":214,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":215,"author":{"gitId":"-"},"content":" .map(StudentData::new)"},{"lineNumber":216,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":217,"author":{"gitId":"-"},"content":" StudentsData data \u003d new StudentsData();"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":" data.setStudents(studentDataList);"},{"lineNumber":220,"author":{"gitId":"-"},"content":""},{"lineNumber":221,"author":{"gitId":"-"},"content":" return new JsonResult(new EnrollStudentsData(data, failToEnrollStudents));"},{"lineNumber":222,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":223,"author":{"gitId":"-"},"content":" }"},{"lineNumber":224,"author":{"gitId":"-"},"content":" }"},{"lineNumber":225,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":108,"marquestye":1,"-":116}},{"path":"src/main/java/teammates/ui/webapi/GetCourseJoinStatusAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountRequestAttributes;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.ui.output.JoinStatus;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * Get the join status of a course."},{"lineNumber":14,"author":{"gitId":"-"},"content":" */"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"public class GetCourseJoinStatusAction extends Action {"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":18,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" }"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":23,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" // Any user can use a join link as long as its parameters are valid"},{"lineNumber":25,"author":{"gitId":"-"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"-"},"content":" public JsonResult execute() {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" String regkey \u003d getNonNullRequestParamValue(Const.ParamsNames.REGKEY);"},{"lineNumber":30,"author":{"gitId":"-"},"content":" String entityType \u003d getNonNullRequestParamValue(Const.ParamsNames.ENTITY_TYPE);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" String isCreatingAccount \u003d getRequestParamValue(Const.ParamsNames.IS_CREATING_ACCOUNT);"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" switch (entityType) {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" case Const.EntityType.STUDENT:"},{"lineNumber":35,"author":{"gitId":"-"},"content":" return getStudentJoinStatus(regkey);"},{"lineNumber":36,"author":{"gitId":"-"},"content":" case Const.EntityType.INSTRUCTOR:"},{"lineNumber":37,"author":{"gitId":"-"},"content":" return getInstructorJoinStatus(regkey, \"true\".equals(isCreatingAccount));"},{"lineNumber":38,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":39,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Error: invalid entity type\");"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" private JsonResult getStudentJoinStatus(String regkey) {"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" StudentAttributes studentAttributes \u003d logic.getStudentForRegistrationKey(regkey);"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" if (studentAttributes !\u003d null \u0026\u0026 !isCourseMigrated(studentAttributes.getCourse())) {"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" return getJoinStatusResult(studentAttributes.isRegistered());"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" Student student \u003d sqlLogic.getStudentByRegistrationKey(regkey);"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(\"No student with given registration key: \" + regkey);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":" return getJoinStatusResult(student.isRegistered());"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" private JsonResult getInstructorJoinStatus(String regkey, boolean isCreatingAccount) {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" if (isCreatingAccount) {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" AccountRequestAttributes accountRequest \u003d logic.getAccountRequestForRegistrationKey(regkey);"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" AccountRequest sqlAccountRequest \u003d sqlLogic.getAccountRequestByRegistrationKey(regkey);"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" if (accountRequest \u003d\u003d null \u0026\u0026 sqlAccountRequest \u003d\u003d null) {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(\"No account request with given registration key: \" + regkey);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" if (sqlAccountRequest !\u003d null) {"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" return getJoinStatusResult(sqlAccountRequest.getRegisteredAt() !\u003d null);"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" if (accountRequest !\u003d null) {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" return getJoinStatusResult(accountRequest.getRegisteredAt() !\u003d null);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":" }"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" InstructorAttributes instructorAttributes \u003d logic.getInstructorForRegistrationKey(regkey);"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" if (instructorAttributes !\u003d null \u0026\u0026 !isCourseMigrated(instructorAttributes.getCourseId())) {"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" return getJoinStatusResult(instructorAttributes.isRegistered());"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" Instructor instructor \u003d sqlLogic.getInstructorByRegistrationKey(regkey);"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(\"No instructor with given registration key: \" + regkey);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":" return getJoinStatusResult(instructor.isRegistered());"},{"lineNumber":86,"author":{"gitId":"-"},"content":" }"},{"lineNumber":87,"author":{"gitId":"-"},"content":" }"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" private JsonResult getJoinStatusResult(boolean hasJoined) {"},{"lineNumber":90,"author":{"gitId":"-"},"content":" JoinStatus result \u003d new JoinStatus(hasJoined);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" return new JsonResult(result);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":24,"-":69}},{"path":"src/main/java/teammates/ui/webapi/GetFeedbackSessionLogsAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.LinkedHashMap;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionLogsData;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":28,"author":{"gitId":"-"},"content":" * Action: gets the feedback session logs of feedback sessions of a course."},{"lineNumber":29,"author":{"gitId":"-"},"content":" */"},{"lineNumber":30,"author":{"gitId":"-"},"content":"public class GetFeedbackSessionLogsAction extends Action {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":32,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":37,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" if (!userInfo.isInstructor) {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Instructor privilege is required to access this resource.\");"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" Course course \u003d sqlLogic.getCourse(courseId);"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":48,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(\"Course is not found\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" Instructor instructor \u003d sqlLogic.getInstructorByGoogleId(courseId, userInfo.getId());"},{"lineNumber":52,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, course, Const.InstructorPermissions.CAN_MODIFY_STUDENT);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, course, Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, course, Const.InstructorPermissions.CAN_MODIFY_INSTRUCTOR);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" CourseAttributes courseAttributes \u003d logic.getCourse(courseId);"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" if (courseAttributes \u003d\u003d null) {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(\"Course is not found\");"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d logic.getInstructorForGoogleId(courseId, userInfo.getId());"},{"lineNumber":63,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, courseAttributes, Const.InstructorPermissions.CAN_MODIFY_STUDENT);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, courseAttributes, Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, courseAttributes, Const.InstructorPermissions.CAN_MODIFY_INSTRUCTOR);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":70,"author":{"gitId":"-"},"content":" public JsonResult execute() {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" String fslTypes \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogType\u003e convertedFslTypes \u003d new ArrayList\u003c\u003e();"},{"lineNumber":73,"author":{"gitId":"-"},"content":" if (fslTypes !\u003d null) {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" // Multiple log types are separated by a comma e.g access,submission"},{"lineNumber":75,"author":{"gitId":"-"},"content":" for (String fslType : fslTypes.split(\",\")) {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" FeedbackSessionLogType convertedFslType \u003d FeedbackSessionLogType.valueOfLabel(fslType);"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" if (convertedFslType \u003d\u003d null) {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Invalid log type\");"},{"lineNumber":80,"author":{"gitId":"-"},"content":" }"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" convertedFslTypes.add(convertedFslType);"},{"lineNumber":83,"author":{"gitId":"-"},"content":" }"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" String startTimeStr \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" String endTimeStr \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" long startTime;"},{"lineNumber":89,"author":{"gitId":"-"},"content":" long endTime;"},{"lineNumber":90,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" startTime \u003d Long.parseLong(startTimeStr);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" endTime \u003d Long.parseLong(endTimeStr);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" } catch (NumberFormatException e) {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Invalid start or end time\", e);"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":" // TODO: we might want to impose limits on the time range from startTime to endTime"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" if (endTime \u003c startTime) {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"The end time should be after the start time.\");"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" if (!isCourseMigrated(courseId)) {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" long earliestSearchTime \u003d TimeHelper.getInstantDaysOffsetBeforeNow(Const.LOGS_RETENTION_PERIOD.toDays())"},{"lineNumber":106,"author":{"gitId":"-"},"content":" .toEpochMilli();"},{"lineNumber":107,"author":{"gitId":"-"},"content":" if (startTime \u003c earliestSearchTime) {"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" throw new InvalidHttpParameterException(\"The earliest date you can search for is \""},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":" + Const.LOGS_RETENTION_PERIOD.toDays() + \" days before today.\");"},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":" UUID studentId \u003d null;"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" UUID feedbackSessionId \u003d null;"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" String studentIdString \u003d getRequestParamValue(Const.ParamsNames.STUDENT_SQL_ID);"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" String feedbackSessionIdString \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_ID);"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" if (studentIdString !\u003d null) {"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" studentId \u003d getUuidFromString(Const.ParamsNames.STUDENT_SQL_ID, studentIdString);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" }"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" if (feedbackSessionIdString !\u003d null) {"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" feedbackSessionId \u003d getUuidFromString(Const.ParamsNames.FEEDBACK_SESSION_ID, feedbackSessionIdString);"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" if (sqlLogic.getCourse(courseId) \u003d\u003d null) {"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":" throw new EntityNotFoundException(\"Course not found\");"},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" if (studentId !\u003d null \u0026\u0026 sqlLogic.getStudent(studentId) \u003d\u003d null) {"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" throw new EntityNotFoundException(\"Student not found\");"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":" if (feedbackSessionId !\u003d null \u0026\u0026 sqlLogic.getFeedbackSession(feedbackSessionId) \u003d\u003d null) {"},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" throw new EntityNotFoundException(\"Feedback session not found\");"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e fsLogEntries \u003d sqlLogic.getOrderedFeedbackSessionLogs(courseId, studentId,"},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":" feedbackSessionId, Instant.ofEpochMilli(startTime), Instant.ofEpochMilli(endTime));"},{"lineNumber":141,"author":{"gitId":"-"},"content":" Map\u003cString, Student\u003e studentsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":142,"author":{"gitId":"-"},"content":" Map\u003cString, FeedbackSession\u003e sessionsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":143,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e feedbackSessions \u003d sqlLogic.getFeedbackSessionsForCourse(courseId);"},{"lineNumber":144,"author":{"gitId":"-"},"content":" feedbackSessions.forEach(fs -\u003e sessionsMap.put(fs.getName(), fs));"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" fsLogEntries \u003d fsLogEntries.stream().filter(logEntry -\u003e {"},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType logType \u003d logEntry.getFeedbackSessionLogType();"},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":" if (logType \u003d\u003d null || fslTypes !\u003d null \u0026\u0026 !convertedFslTypes.contains(logType)) {"},{"lineNumber":149,"author":{"gitId":"-"},"content":" // If the feedback session log type retrieved from the log is invalid"},{"lineNumber":150,"author":{"gitId":"-"},"content":" // or not the type being queried, ignore the log"},{"lineNumber":151,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":152,"author":{"gitId":"-"},"content":" }"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":" if (!studentsMap.containsKey(logEntry.getStudent().getEmail())) {"},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":" Student student \u003d sqlLogic.getStudent(logEntry.getStudent().getId());"},{"lineNumber":156,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" // If the student email retrieved from the log is invalid, ignore the log"},{"lineNumber":158,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":" studentsMap.put(student.getEmail(), student);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":" // If the feedback session retrieved from the log is invalid, ignore the log"},{"lineNumber":163,"author":{"gitId":"dishenggg"},"content":" return sessionsMap.containsKey(logEntry.getFeedbackSession().getName());"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }).collect(Collectors.toList());"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":" Map\u003cString, List\u003cFeedbackSessionLog\u003e\u003e groupedEntries \u003d groupFeedbackSessionLogs(fsLogEntries);"},{"lineNumber":167,"author":{"gitId":"-"},"content":" feedbackSessions.forEach(fs -\u003e groupedEntries.putIfAbsent(fs.getName(), new ArrayList\u003c\u003e()));"},{"lineNumber":168,"author":{"gitId":"-"},"content":""},{"lineNumber":169,"author":{"gitId":"-"},"content":" FeedbackSessionLogsData fslData \u003d new FeedbackSessionLogsData(groupedEntries, studentsMap, sessionsMap);"},{"lineNumber":170,"author":{"gitId":"-"},"content":" return new JsonResult(fslData);"},{"lineNumber":171,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":" if (logic.getCourse(courseId) \u003d\u003d null) {"},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":" throw new EntityNotFoundException(\"Course not found\");"},{"lineNumber":174,"author":{"gitId":"-"},"content":" }"},{"lineNumber":175,"author":{"gitId":"-"},"content":""},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":" String email \u003d getRequestParamValue(Const.ParamsNames.STUDENT_EMAIL);"},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":" if (email !\u003d null \u0026\u0026 logic.getStudentForEmail(courseId, email) \u003d\u003d null) {"},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":" throw new EntityNotFoundException(\"Student not found\");"},{"lineNumber":179,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":180,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":181,"author":{"gitId":"dishenggg"},"content":" String feedbackSessionName \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME);"},{"lineNumber":182,"author":{"gitId":"dishenggg"},"content":" if (feedbackSessionName !\u003d null \u0026\u0026 logic.getFeedbackSession(feedbackSessionName, courseId) \u003d\u003d null) {"},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":" throw new EntityNotFoundException(\"Feedback session not found\");"},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":185,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":186,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntry\u003e fsLogEntries \u003d"},{"lineNumber":187,"author":{"gitId":"dishenggg"},"content":" logsProcessor.getOrderedFeedbackSessionLogs(courseId, email, startTime, endTime, feedbackSessionName);"},{"lineNumber":188,"author":{"gitId":"-"},"content":" Map\u003cString, StudentAttributes\u003e studentsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":189,"author":{"gitId":"-"},"content":" Map\u003cString, FeedbackSessionAttributes\u003e sessionsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":190,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionAttributes\u003e feedbackSessions \u003d logic.getFeedbackSessionsForCourse(courseId);"},{"lineNumber":191,"author":{"gitId":"-"},"content":" feedbackSessions.forEach(fs -\u003e sessionsMap.put(fs.getFeedbackSessionName(), fs));"},{"lineNumber":192,"author":{"gitId":"-"},"content":""},{"lineNumber":193,"author":{"gitId":"-"},"content":" fsLogEntries \u003d fsLogEntries.stream().filter(logEntry -\u003e {"},{"lineNumber":194,"author":{"gitId":"-"},"content":" String logType \u003d logEntry.getFeedbackSessionLogType();"},{"lineNumber":195,"author":{"gitId":"-"},"content":" FeedbackSessionLogType convertedLogType \u003d FeedbackSessionLogType.valueOfLabel(logType);"},{"lineNumber":196,"author":{"gitId":"-"},"content":" if (convertedLogType \u003d\u003d null || fslTypes !\u003d null \u0026\u0026 !convertedFslTypes.contains(convertedLogType)) {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" // If the feedback session log type retrieved from the log is invalid"},{"lineNumber":198,"author":{"gitId":"-"},"content":" // or not the type being queried, ignore the log"},{"lineNumber":199,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }"},{"lineNumber":201,"author":{"gitId":"-"},"content":""},{"lineNumber":202,"author":{"gitId":"-"},"content":" if (!studentsMap.containsKey(logEntry.getStudentEmail())) {"},{"lineNumber":203,"author":{"gitId":"-"},"content":" StudentAttributes student \u003d logic.getStudentForEmail(courseId, logEntry.getStudentEmail());"},{"lineNumber":204,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" // If the student email retrieved from the log is invalid, ignore the log"},{"lineNumber":206,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":207,"author":{"gitId":"-"},"content":" }"},{"lineNumber":208,"author":{"gitId":"-"},"content":" studentsMap.put(logEntry.getStudentEmail(), student);"},{"lineNumber":209,"author":{"gitId":"-"},"content":" }"},{"lineNumber":210,"author":{"gitId":"-"},"content":" // If the feedback session retrieved from the log is invalid, ignore the log"},{"lineNumber":211,"author":{"gitId":"-"},"content":" return sessionsMap.containsKey(logEntry.getFeedbackSessionName());"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }).collect(Collectors.toList());"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" Map\u003cString, List\u003cFeedbackSessionLogEntry\u003e\u003e groupedEntries \u003d"},{"lineNumber":215,"author":{"gitId":"-"},"content":" groupFeedbackSessionLogEntries(fsLogEntries);"},{"lineNumber":216,"author":{"gitId":"-"},"content":" feedbackSessions.forEach(fs -\u003e groupedEntries.putIfAbsent(fs.getFeedbackSessionName(), new ArrayList\u003c\u003e()));"},{"lineNumber":217,"author":{"gitId":"-"},"content":""},{"lineNumber":218,"author":{"gitId":"-"},"content":" FeedbackSessionLogsData fslData \u003d new FeedbackSessionLogsData(groupedEntries, studentsMap, sessionsMap);"},{"lineNumber":219,"author":{"gitId":"-"},"content":" return new JsonResult(fslData);"},{"lineNumber":220,"author":{"gitId":"-"},"content":" }"},{"lineNumber":221,"author":{"gitId":"-"},"content":" }"},{"lineNumber":222,"author":{"gitId":"-"},"content":""},{"lineNumber":223,"author":{"gitId":"-"},"content":" private Map\u003cString, List\u003cFeedbackSessionLogEntry\u003e\u003e groupFeedbackSessionLogEntries("},{"lineNumber":224,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogEntry\u003e fsLogEntries) {"},{"lineNumber":225,"author":{"gitId":"-"},"content":" Map\u003cString, List\u003cFeedbackSessionLogEntry\u003e\u003e groupedEntries \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":226,"author":{"gitId":"-"},"content":" for (FeedbackSessionLogEntry fsLogEntry : fsLogEntries) {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" String fsName \u003d fsLogEntry.getFeedbackSessionName();"},{"lineNumber":228,"author":{"gitId":"-"},"content":" groupedEntries.computeIfAbsent(fsName, k -\u003e new ArrayList\u003c\u003e()).add(fsLogEntry);"},{"lineNumber":229,"author":{"gitId":"-"},"content":" }"},{"lineNumber":230,"author":{"gitId":"-"},"content":" return groupedEntries;"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":233,"author":{"gitId":"dishenggg"},"content":" private Map\u003cString, List\u003cFeedbackSessionLog\u003e\u003e groupFeedbackSessionLogs("},{"lineNumber":234,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e fsLogEntries) {"},{"lineNumber":235,"author":{"gitId":"dishenggg"},"content":" Map\u003cString, List\u003cFeedbackSessionLog\u003e\u003e groupedEntries \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":236,"author":{"gitId":"dishenggg"},"content":" for (FeedbackSessionLog fsLogEntry : fsLogEntries) {"},{"lineNumber":237,"author":{"gitId":"dishenggg"},"content":" String fsName \u003d fsLogEntry.getFeedbackSession().getName();"},{"lineNumber":238,"author":{"gitId":"dishenggg"},"content":" groupedEntries.computeIfAbsent(fsName, k -\u003e new ArrayList\u003c\u003e()).add(fsLogEntry);"},{"lineNumber":239,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":240,"author":{"gitId":"dishenggg"},"content":" return groupedEntries;"},{"lineNumber":241,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":242,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":65,"-":177}},{"path":"src/main/java/teammates/ui/webapi/GetSessionResponseStatsAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionStatsData;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * Action: gets the response stats (submitted / total) of a feedback session."},{"lineNumber":12,"author":{"gitId":"-"},"content":" */"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"public class GetSessionResponseStatsAction extends Action {"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":16,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":17,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":18,"author":{"gitId":"-"},"content":" }"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":21,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" if (userInfo.isAdmin) {"},{"lineNumber":23,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" }"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":27,"author":{"gitId":"-"},"content":" String feedbackSessionName \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME);"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" FeedbackSession fs \u003d getNonNullSqlFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" Instructor instructor \u003d sqlLogic.getInstructorByGoogleId(courseId, userInfo.getId());"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" gateKeeper.verifyAccessible(instructor, fs);"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" } else {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes fsa \u003d getNonNullFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":34,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d logic.getInstructorForGoogleId(courseId, userInfo.getId());"},{"lineNumber":35,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, fsa);"},{"lineNumber":36,"author":{"gitId":"-"},"content":" }"},{"lineNumber":37,"author":{"gitId":"-"},"content":" }"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":40,"author":{"gitId":"-"},"content":" public JsonResult execute() {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":42,"author":{"gitId":"-"},"content":" String feedbackSessionName \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME);"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" FeedbackSession fsa \u003d getNonNullSqlFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" int expectedTotal \u003d sqlLogic.getExpectedTotalSubmission(fsa);"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" int actualTotal \u003d sqlLogic.getActualTotalSubmission(fsa);"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" FeedbackSessionStatsData output \u003d new FeedbackSessionStatsData(actualTotal, expectedTotal);"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" return new JsonResult(output);"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" } else {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes fsa \u003d getNonNullFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" int expectedTotal \u003d logic.getExpectedTotalSubmission(fsa);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" int actualTotal \u003d logic.getActualTotalSubmission(fsa);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" FeedbackSessionStatsData output \u003d new FeedbackSessionStatsData(actualTotal, expectedTotal);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" return new JsonResult(output);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":15,"-":44}},{"path":"src/main/java/teammates/ui/webapi/GetSessionResultsAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackResultFetchType;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SessionResultsBundle;"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.SqlSessionResultsBundle;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.StringHelper;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":16,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.ui.output.SessionResultsData;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.ui.request.Intent;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":21,"author":{"gitId":"-"},"content":" * Gets feedback session results including statistics where necessary."},{"lineNumber":22,"author":{"gitId":"-"},"content":" */"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":"public class GetSessionResultsAction extends BasicFeedbackSubmissionAction {"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":26,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" return AuthType.PUBLIC;"},{"lineNumber":28,"author":{"gitId":"-"},"content":" }"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":31,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":33,"author":{"gitId":"-"},"content":" String feedbackSessionName \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME);"},{"lineNumber":34,"author":{"gitId":"-"},"content":" Intent intent \u003d Intent.valueOf(getNonNullRequestParamValue(Const.ParamsNames.INTENT));"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" boolean isPreviewResults \u003d !StringHelper.isEmpty(previewAsPerson);"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" checkSpecificAccessControlSql(courseId, feedbackSessionName, intent, isPreviewResults);"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" checkSpecificAccessControlDatastore(courseId, feedbackSessionName, intent, isPreviewResults);"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" private void checkSpecificAccessControlDatastore("},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" String courseId, String feedbackSessionName, Intent intent, boolean isPreviewResults)"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" throws UnauthorizedAccessException {"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" FeedbackSessionAttributes feedbackSession \u003d getNonNullFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" switch (intent) {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" case FULL_DETAIL:"},{"lineNumber":52,"author":{"gitId":"-"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d logic.getInstructorForGoogleId(courseId, userInfo.getId());"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" gateKeeper.verifyAccessible(instructor, feedbackSession);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":56,"author":{"gitId":"-"},"content":" case INSTRUCTOR_RESULT:"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" if (!isPreviewResults \u0026\u0026 !feedbackSession.isPublished()) {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"This feedback session is not yet published.\", true);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":" instructor \u003d getInstructorOfCourseFromRequest(courseId);"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" checkAccessControlForInstructorFeedbackResult(instructor, feedbackSession);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" case STUDENT_RESULT:"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" if (!isPreviewResults \u0026\u0026 !feedbackSession.isPublished()) {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"This feedback session is not yet published.\", true);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":" StudentAttributes student \u003d getStudentOfCourseFromRequest(courseId);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" checkAccessControlForStudentFeedbackResult(student, feedbackSession);"},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":" case INSTRUCTOR_SUBMISSION:"},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" case STUDENT_SUBMISSION:"},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" throw new InvalidHttpParameterException(\"Invalid intent for this action\");"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":" default:"},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" throw new InvalidHttpParameterException(\"Unknown intent \" + intent);"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" private void checkSpecificAccessControlSql("},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":" String courseId, String feedbackSessionName, Intent intent, boolean isPreviewResults)"},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" throws UnauthorizedAccessException {"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession \u003d getNonNullSqlFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" switch (intent) {"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":" case FULL_DETAIL:"},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":" Instructor instructor \u003d sqlLogic.getInstructorByGoogleId(courseId, userInfo.getId());"},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":" gateKeeper.verifyAccessible(instructor, feedbackSession);"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":" case INSTRUCTOR_RESULT:"},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" if (!isPreviewResults \u0026\u0026 !feedbackSession.isPublished()) {"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":" throw new UnauthorizedAccessException(\"This feedback session is not yet published.\", true);"},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":" instructor \u003d getSqlInstructorOfCourseFromRequest(courseId);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" checkAccessControlForInstructorFeedbackResult(instructor, feedbackSession);"},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":" case STUDENT_RESULT:"},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" if (!isPreviewResults \u0026\u0026 !feedbackSession.isPublished()) {"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" throw new UnauthorizedAccessException(\"This feedback session is not yet published.\", true);"},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":" Student student \u003d getSqlStudentOfCourseFromRequest(courseId);"},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":" checkAccessControlForStudentFeedbackResult(student, feedbackSession);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":103,"author":{"gitId":"-"},"content":" case INSTRUCTOR_SUBMISSION:"},{"lineNumber":104,"author":{"gitId":"-"},"content":" case STUDENT_SUBMISSION:"},{"lineNumber":105,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Invalid intent for this action\");"},{"lineNumber":106,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":107,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Unknown intent \" + intent);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":" }"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":112,"author":{"gitId":"-"},"content":" public JsonResult execute() {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" String feedbackSessionName \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME);"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" // Allow additional filter by question ID and section name"},{"lineNumber":117,"author":{"gitId":"-"},"content":" String questionId \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_QUESTION_ID);"},{"lineNumber":118,"author":{"gitId":"-"},"content":" String selectedSection \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_RESULTS_GROUPBYSECTION);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" FeedbackResultFetchType fetchType \u003d FeedbackResultFetchType.parseFetchType("},{"lineNumber":120,"author":{"gitId":"-"},"content":" getRequestParamValue(Const.ParamsNames.FEEDBACK_RESULTS_SECTION_BY_GIVER_RECEIVER));"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":123,"author":{"gitId":"-"},"content":" boolean isPreviewResults \u003d !StringHelper.isEmpty(previewAsPerson);"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"xenosf"},"content":" Intent intent \u003d Intent.valueOf(getNonNullRequestParamValue(Const.ParamsNames.INTENT));"},{"lineNumber":126,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":127,"author":{"gitId":"xenosf"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":128,"author":{"gitId":"xenosf"},"content":" if (questionId !\u003d null) {"},{"lineNumber":129,"author":{"gitId":"xenosf"},"content":" UUID questionUuid \u003d getUuidRequestParamValue(Const.ParamsNames.FEEDBACK_QUESTION_ID);"},{"lineNumber":130,"author":{"gitId":"mingyuanc"},"content":" return executeWithSql(courseId, feedbackSessionName, questionUuid,"},{"lineNumber":131,"author":{"gitId":"xenosf"},"content":" selectedSection, fetchType, intent, isPreviewResults);"},{"lineNumber":132,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":133,"author":{"gitId":"xenosf"},"content":" return executeWithSql(courseId, feedbackSessionName, null, selectedSection,"},{"lineNumber":134,"author":{"gitId":"xenosf"},"content":" fetchType, intent, isPreviewResults);"},{"lineNumber":135,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":136,"author":{"gitId":"xenosf"},"content":" return executeWithDatastore(courseId, feedbackSessionName, questionId, selectedSection,"},{"lineNumber":137,"author":{"gitId":"xenosf"},"content":" fetchType, intent, isPreviewResults);"},{"lineNumber":138,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":139,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":140,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":141,"author":{"gitId":"xenosf"},"content":" private JsonResult executeWithDatastore("},{"lineNumber":142,"author":{"gitId":"xenosf"},"content":" String courseId, String feedbackSessionName, String questionId, String selectedSection,"},{"lineNumber":143,"author":{"gitId":"xenosf"},"content":" FeedbackResultFetchType fetchType, Intent intent, boolean isPreviewResults) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" InstructorAttributes instructor;"},{"lineNumber":145,"author":{"gitId":"-"},"content":" StudentAttributes student;"},{"lineNumber":146,"author":{"gitId":"xenosf"},"content":" SessionResultsBundle bundle;"},{"lineNumber":147,"author":{"gitId":"-"},"content":" switch (intent) {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" case FULL_DETAIL:"},{"lineNumber":149,"author":{"gitId":"-"},"content":" instructor \u003d logic.getInstructorForGoogleId(courseId, userInfo.id);"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" bundle \u003d logic.getSessionResultsForCourse(feedbackSessionName, courseId, instructor.getEmail(),"},{"lineNumber":152,"author":{"gitId":"-"},"content":" questionId, selectedSection, fetchType);"},{"lineNumber":153,"author":{"gitId":"-"},"content":" return new JsonResult(SessionResultsData.initForInstructor(bundle));"},{"lineNumber":154,"author":{"gitId":"-"},"content":" case INSTRUCTOR_RESULT:"},{"lineNumber":155,"author":{"gitId":"-"},"content":" // Section name filter is not applicable here"},{"lineNumber":156,"author":{"gitId":"-"},"content":" instructor \u003d getInstructorOfCourseFromRequest(courseId);"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"-"},"content":" bundle \u003d logic.getSessionResultsForUser(feedbackSessionName, courseId, instructor.getEmail(),"},{"lineNumber":159,"author":{"gitId":"-"},"content":" true, questionId, isPreviewResults);"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" // Build a fake student object, as the results will be displayed as if they are displayed to a student"},{"lineNumber":162,"author":{"gitId":"-"},"content":" student \u003d StudentAttributes.builder(instructor.getCourseId(), instructor.getEmail())"},{"lineNumber":163,"author":{"gitId":"-"},"content":" .withTeamName(Const.USER_TEAM_FOR_INSTRUCTOR)"},{"lineNumber":164,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" return new JsonResult(SessionResultsData.initForStudent(bundle, student));"},{"lineNumber":167,"author":{"gitId":"-"},"content":" case STUDENT_RESULT:"},{"lineNumber":168,"author":{"gitId":"-"},"content":" // Section name filter is not applicable here"},{"lineNumber":169,"author":{"gitId":"-"},"content":" student \u003d getStudentOfCourseFromRequest(courseId);"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" bundle \u003d logic.getSessionResultsForUser(feedbackSessionName, courseId, student.getEmail(),"},{"lineNumber":172,"author":{"gitId":"-"},"content":" false, questionId, isPreviewResults);"},{"lineNumber":173,"author":{"gitId":"-"},"content":""},{"lineNumber":174,"author":{"gitId":"-"},"content":" return new JsonResult(SessionResultsData.initForStudent(bundle, student));"},{"lineNumber":175,"author":{"gitId":"-"},"content":" case INSTRUCTOR_SUBMISSION:"},{"lineNumber":176,"author":{"gitId":"-"},"content":" case STUDENT_SUBMISSION:"},{"lineNumber":177,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Invalid intent for this action\");"},{"lineNumber":178,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":179,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Unknown intent \" + intent);"},{"lineNumber":180,"author":{"gitId":"-"},"content":" }"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"xenosf"},"content":" private JsonResult executeWithSql("},{"lineNumber":184,"author":{"gitId":"xenosf"},"content":" String courseId, String feedbackSessionName, UUID questionUuid, String selectedSection,"},{"lineNumber":185,"author":{"gitId":"xenosf"},"content":" FeedbackResultFetchType fetchType, Intent intent, boolean isPreviewResults) {"},{"lineNumber":186,"author":{"gitId":"xenosf"},"content":" Instructor instructor;"},{"lineNumber":187,"author":{"gitId":"xenosf"},"content":" Student student;"},{"lineNumber":188,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession \u003d getNonNullSqlFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":189,"author":{"gitId":"xenosf"},"content":" SqlSessionResultsBundle bundle;"},{"lineNumber":190,"author":{"gitId":"xenosf"},"content":" switch (intent) {"},{"lineNumber":191,"author":{"gitId":"xenosf"},"content":" case FULL_DETAIL:"},{"lineNumber":192,"author":{"gitId":"xenosf"},"content":" instructor \u003d getSqlInstructorOfCourseFromRequest(courseId);"},{"lineNumber":193,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":194,"author":{"gitId":"xenosf"},"content":" bundle \u003d sqlLogic.getSessionResultsForCourse(feedbackSession, courseId, instructor.getEmail(),"},{"lineNumber":195,"author":{"gitId":"xenosf"},"content":" questionUuid, selectedSection, fetchType);"},{"lineNumber":196,"author":{"gitId":"xenosf"},"content":" return new JsonResult(SessionResultsData.initForInstructor(bundle));"},{"lineNumber":197,"author":{"gitId":"xenosf"},"content":" case INSTRUCTOR_RESULT:"},{"lineNumber":198,"author":{"gitId":"xenosf"},"content":" // Section name filter is not applicable here"},{"lineNumber":199,"author":{"gitId":"mingyuanc"},"content":" instructor \u003d getSqlInstructorOfCourseFromRequest(courseId);"},{"lineNumber":200,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":201,"author":{"gitId":"xenosf"},"content":" bundle \u003d sqlLogic.getSessionResultsForUser(feedbackSession, courseId, instructor.getEmail(),"},{"lineNumber":202,"author":{"gitId":"xenosf"},"content":" true, questionUuid, isPreviewResults);"},{"lineNumber":203,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":204,"author":{"gitId":"xenosf"},"content":" // Build a fake student object, as the results will be displayed as if they are displayed to a student"},{"lineNumber":205,"author":{"gitId":"xenosf"},"content":" student \u003d new Student(instructor.getCourse(), instructor.getName(), instructor.getEmail(), \"\");"},{"lineNumber":206,"author":{"gitId":"mingyuanc"},"content":" student.setTeam(new Team(null, Const.USER_TEAM_FOR_INSTRUCTOR));"},{"lineNumber":207,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":208,"author":{"gitId":"xenosf"},"content":" return new JsonResult(SessionResultsData.initForStudent(bundle, student));"},{"lineNumber":209,"author":{"gitId":"xenosf"},"content":" case STUDENT_RESULT:"},{"lineNumber":210,"author":{"gitId":"xenosf"},"content":" // Section name filter is not applicable here"},{"lineNumber":211,"author":{"gitId":"xenosf"},"content":" student \u003d getSqlStudentOfCourseFromRequest(courseId);"},{"lineNumber":212,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":213,"author":{"gitId":"xenosf"},"content":" bundle \u003d sqlLogic.getSessionResultsForUser(feedbackSession, courseId, student.getEmail(),"},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" false, questionUuid, isPreviewResults);"},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" return new JsonResult(SessionResultsData.initForStudent(bundle, student));"},{"lineNumber":217,"author":{"gitId":"xenosf"},"content":" case INSTRUCTOR_SUBMISSION:"},{"lineNumber":218,"author":{"gitId":"xenosf"},"content":" case STUDENT_SUBMISSION:"},{"lineNumber":219,"author":{"gitId":"xenosf"},"content":" throw new InvalidHttpParameterException(\"Invalid intent for this action\");"},{"lineNumber":220,"author":{"gitId":"xenosf"},"content":" default:"},{"lineNumber":221,"author":{"gitId":"xenosf"},"content":" throw new InvalidHttpParameterException(\"Unknown intent \" + intent);"},{"lineNumber":222,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":223,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":224,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":114,"mingyuanc":4,"-":107}},{"path":"src/main/java/teammates/ui/webapi/InstructorSearchIndexingWorkerAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.ParamsNames;"},{"lineNumber":8,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * Task queue worker action: performs instructor search indexing."},{"lineNumber":12,"author":{"gitId":"-"},"content":" */"},{"lineNumber":13,"author":{"gitId":"-"},"content":"public class InstructorSearchIndexingWorkerAction extends AdminOnlyAction {"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":16,"author":{"gitId":"-"},"content":" public ActionResult execute() {"},{"lineNumber":17,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(ParamsNames.COURSE_ID);"},{"lineNumber":18,"author":{"gitId":"-"},"content":" String email \u003d getNonNullRequestParamValue(ParamsNames.INSTRUCTOR_EMAIL);"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"mingyuanc"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":21,"author":{"gitId":"mingyuanc"},"content":" return executeWithSql(courseId, email);"},{"lineNumber":22,"author":{"gitId":"mingyuanc"},"content":" } else {"},{"lineNumber":23,"author":{"gitId":"mingyuanc"},"content":" return executeWithDataStore(courseId, email);"},{"lineNumber":24,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":25,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":26,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":27,"author":{"gitId":"mingyuanc"},"content":" private JsonResult executeWithSql(String courseId, String email) {"},{"lineNumber":28,"author":{"gitId":"mingyuanc"},"content":" Instructor instructor \u003d sqlLogic.getInstructorForEmail(courseId, email);"},{"lineNumber":29,"author":{"gitId":"mingyuanc"},"content":" try {"},{"lineNumber":30,"author":{"gitId":"mingyuanc"},"content":" sqlLogic.putInstructorDocument(instructor);"},{"lineNumber":31,"author":{"gitId":"mingyuanc"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":32,"author":{"gitId":"mingyuanc"},"content":" // Set an arbitrary retry code outside the range 200-299 to trigger automatic retry"},{"lineNumber":33,"author":{"gitId":"mingyuanc"},"content":" return new JsonResult(\"Failure\", HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":34,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":35,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":36,"author":{"gitId":"mingyuanc"},"content":" return new JsonResult(\"Successful\");"},{"lineNumber":37,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":38,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":39,"author":{"gitId":"mingyuanc"},"content":" private JsonResult executeWithDataStore(String courseId, String email) {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d logic.getInstructorForEmail(courseId, email);"},{"lineNumber":41,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" logic.putInstructorDocument(instructor);"},{"lineNumber":43,"author":{"gitId":"-"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" // Set an arbitrary retry code outside of the range 200-299 to trigger automatic retry"},{"lineNumber":45,"author":{"gitId":"-"},"content":" return new JsonResult(\"Failure\", HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" return new JsonResult(\"Successful\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"mingyuanc":21,"-":29}},{"path":"src/main/java/teammates/ui/webapi/JoinCourseAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"yuanxi1"},"content":"import java.util.Optional;"},{"lineNumber":4,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":16,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":17,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":18,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":21,"author":{"gitId":"-"},"content":" * Action: joins a course for a student/instructor."},{"lineNumber":22,"author":{"gitId":"-"},"content":" */"},{"lineNumber":23,"author":{"gitId":"yuanxi1"},"content":"public class JoinCourseAction extends Action {"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":33,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" // Any user can use a join link as long as its parameters are valid"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"-"},"content":" public JsonResult execute() throws InvalidOperationException {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" String regKey \u003d getNonNullRequestParamValue(Const.ParamsNames.REGKEY);"},{"lineNumber":40,"author":{"gitId":"-"},"content":" String entityType \u003d getNonNullRequestParamValue(Const.ParamsNames.ENTITY_TYPE);"},{"lineNumber":41,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":42,"author":{"gitId":"yuanxi1"},"content":" String courseId \u003d getCourseId(regKey, entityType);"},{"lineNumber":43,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":44,"author":{"gitId":"yuanxi1"},"content":" // courseId is null when the registration key does not exist, this case is handled in the AccountsLogic."},{"lineNumber":45,"author":{"gitId":"yuanxi1"},"content":" // Hence default to not migrated. Getting the courseId in the action layer is not needed once migration is done."},{"lineNumber":46,"author":{"gitId":"yuanxi1"},"content":" if (courseId \u003d\u003d null || !isCourseMigrated(courseId)) {"},{"lineNumber":47,"author":{"gitId":"yuanxi1"},"content":" switch (entityType) {"},{"lineNumber":48,"author":{"gitId":"yuanxi1"},"content":" case Const.EntityType.STUDENT:"},{"lineNumber":49,"author":{"gitId":"yuanxi1"},"content":" return joinCourseForStudentDatastore(regKey);"},{"lineNumber":50,"author":{"gitId":"yuanxi1"},"content":" case Const.EntityType.INSTRUCTOR:"},{"lineNumber":51,"author":{"gitId":"yuanxi1"},"content":" return joinCourseForInstructorDatastore(regKey);"},{"lineNumber":52,"author":{"gitId":"yuanxi1"},"content":" default:"},{"lineNumber":53,"author":{"gitId":"yuanxi1"},"content":" throw new InvalidHttpParameterException(\"Error: invalid entity type\");"},{"lineNumber":54,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":55,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":56,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" switch (entityType) {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" case Const.EntityType.STUDENT:"},{"lineNumber":59,"author":{"gitId":"-"},"content":" return joinCourseForStudent(regKey);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" case Const.EntityType.INSTRUCTOR:"},{"lineNumber":61,"author":{"gitId":"-"},"content":" return joinCourseForInstructor(regKey);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":63,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Error: invalid entity type\");"},{"lineNumber":64,"author":{"gitId":"-"},"content":" }"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" private JsonResult joinCourseForStudent(String regkey) throws InvalidOperationException {"},{"lineNumber":68,"author":{"gitId":"yuanxi1"},"content":" Student student;"},{"lineNumber":69,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":70,"author":{"gitId":"yuanxi1"},"content":" try {"},{"lineNumber":71,"author":{"gitId":"yuanxi1"},"content":" student \u003d sqlLogic.joinCourseForStudent(regkey, userInfo.id);"},{"lineNumber":72,"author":{"gitId":"yuanxi1"},"content":" } catch (EntityDoesNotExistException ednee) {"},{"lineNumber":73,"author":{"gitId":"yuanxi1"},"content":" throw new EntityNotFoundException(ednee);"},{"lineNumber":74,"author":{"gitId":"yuanxi1"},"content":" } catch (EntityAlreadyExistsException eaee) {"},{"lineNumber":75,"author":{"gitId":"yuanxi1"},"content":" throw new InvalidOperationException(eaee);"},{"lineNumber":76,"author":{"gitId":"yuanxi1"},"content":" } catch (InvalidParametersException ipe) {"},{"lineNumber":77,"author":{"gitId":"yuanxi1"},"content":" // There should not be any invalid parameter here"},{"lineNumber":78,"author":{"gitId":"yuanxi1"},"content":" log.severe(\"Unexpected error\", ipe);"},{"lineNumber":79,"author":{"gitId":"yuanxi1"},"content":" return new JsonResult(ipe.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR);"},{"lineNumber":80,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":81,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":82,"author":{"gitId":"yuanxi1"},"content":" sendJoinEmail(student.getCourseId(), student.getName(), student.getEmail(), false);"},{"lineNumber":83,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":84,"author":{"gitId":"yuanxi1"},"content":" return new JsonResult(\"Student successfully joined course\");"},{"lineNumber":85,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":86,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":87,"author":{"gitId":"yuanxi1"},"content":" private JsonResult joinCourseForInstructor(String regkey) throws InvalidOperationException {"},{"lineNumber":88,"author":{"gitId":"yuanxi1"},"content":" Instructor instructor;"},{"lineNumber":89,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":90,"author":{"gitId":"yuanxi1"},"content":" try {"},{"lineNumber":91,"author":{"gitId":"yuanxi1"},"content":" instructor \u003d sqlLogic.joinCourseForInstructor(regkey, userInfo.id);"},{"lineNumber":92,"author":{"gitId":"yuanxi1"},"content":" } catch (EntityDoesNotExistException ednee) {"},{"lineNumber":93,"author":{"gitId":"yuanxi1"},"content":" throw new EntityNotFoundException(ednee);"},{"lineNumber":94,"author":{"gitId":"yuanxi1"},"content":" } catch (EntityAlreadyExistsException eaee) {"},{"lineNumber":95,"author":{"gitId":"yuanxi1"},"content":" throw new InvalidOperationException(eaee);"},{"lineNumber":96,"author":{"gitId":"yuanxi1"},"content":" } catch (InvalidParametersException ipe) {"},{"lineNumber":97,"author":{"gitId":"yuanxi1"},"content":" // There should not be any invalid parameter here"},{"lineNumber":98,"author":{"gitId":"yuanxi1"},"content":" log.severe(\"Unexpected error\", ipe);"},{"lineNumber":99,"author":{"gitId":"yuanxi1"},"content":" return new JsonResult(ipe.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR);"},{"lineNumber":100,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":101,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":102,"author":{"gitId":"yuanxi1"},"content":" sendJoinEmail(instructor.getCourseId(), instructor.getName(), instructor.getEmail(), true);"},{"lineNumber":103,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":104,"author":{"gitId":"yuanxi1"},"content":" return new JsonResult(\"Instructor successfully joined course\");"},{"lineNumber":105,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":106,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":107,"author":{"gitId":"yuanxi1"},"content":" private JsonResult joinCourseForStudentDatastore(String regkey) throws InvalidOperationException {"},{"lineNumber":108,"author":{"gitId":"-"},"content":" StudentAttributes student;"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" student \u003d logic.joinCourseForStudent(regkey, userInfo.id);"},{"lineNumber":112,"author":{"gitId":"-"},"content":" } catch (EntityDoesNotExistException ednee) {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(ednee);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" } catch (EntityAlreadyExistsException eaee) {"},{"lineNumber":115,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(eaee);"},{"lineNumber":116,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException ipe) {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" // There should not be any invalid parameter here"},{"lineNumber":118,"author":{"gitId":"-"},"content":" log.severe(\"Unexpected error\", ipe);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" return new JsonResult(ipe.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" }"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"yuanxi1"},"content":" sendJoinEmailDatastore(student.getCourse(), student.getName(), student.getEmail(), false);"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" return new JsonResult(\"Student successfully joined course\");"},{"lineNumber":125,"author":{"gitId":"-"},"content":" }"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"yuanxi1"},"content":" private JsonResult joinCourseForInstructorDatastore(String regkey) throws InvalidOperationException {"},{"lineNumber":128,"author":{"gitId":"-"},"content":" InstructorAttributes instructor;"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":131,"author":{"gitId":"-"},"content":" instructor \u003d logic.joinCourseForInstructor(regkey, userInfo.id);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" } catch (EntityDoesNotExistException ednee) {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(ednee);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" } catch (EntityAlreadyExistsException eaee) {"},{"lineNumber":135,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(eaee);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException ipe) {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" // There should not be any invalid parameter here"},{"lineNumber":138,"author":{"gitId":"-"},"content":" log.severe(\"Unexpected error\", ipe);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" return new JsonResult(ipe.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"yuanxi1"},"content":" sendJoinEmailDatastore(instructor.getCourseId(), instructor.getName(), instructor.getEmail(), true);"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" return new JsonResult(\"Instructor successfully joined course\");"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"yuanxi1"},"content":" private void sendJoinEmailDatastore(String courseId, String userName, String userEmail, boolean isInstructor) {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" CourseAttributes course \u003d logic.getCourse(courseId);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d emailGenerator.generateUserCourseRegisteredEmail("},{"lineNumber":150,"author":{"gitId":"-"},"content":" userName, userEmail, userInfo.id, isInstructor, course);"},{"lineNumber":151,"author":{"gitId":"-"},"content":" emailSender.sendEmail(email);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" }"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"yuanxi1"},"content":" private void sendJoinEmail(String courseId, String userName, String userEmail, boolean isInstructor) {"},{"lineNumber":155,"author":{"gitId":"yuanxi1"},"content":" Course course \u003d sqlLogic.getCourse(courseId);"},{"lineNumber":156,"author":{"gitId":"yuanxi1"},"content":" EmailWrapper email \u003d sqlEmailGenerator.generateUserCourseRegisteredEmail("},{"lineNumber":157,"author":{"gitId":"yuanxi1"},"content":" userName, userEmail, userInfo.id, isInstructor, course);"},{"lineNumber":158,"author":{"gitId":"yuanxi1"},"content":" emailSender.sendEmail(email);"},{"lineNumber":159,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":160,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":161,"author":{"gitId":"yuanxi1"},"content":" private String getCourseId(String regKey, String entityType) {"},{"lineNumber":162,"author":{"gitId":"yuanxi1"},"content":" String courseIdSql;"},{"lineNumber":163,"author":{"gitId":"yuanxi1"},"content":" String courseIdDatastore;"},{"lineNumber":164,"author":{"gitId":"yuanxi1"},"content":" switch (entityType) {"},{"lineNumber":165,"author":{"gitId":"yuanxi1"},"content":" case Const.EntityType.STUDENT:"},{"lineNumber":166,"author":{"gitId":"yuanxi1"},"content":" courseIdSql \u003d Optional.ofNullable(sqlLogic.getStudentByRegistrationKey(regKey))"},{"lineNumber":167,"author":{"gitId":"yuanxi1"},"content":" .map(Student::getCourseId)"},{"lineNumber":168,"author":{"gitId":"yuanxi1"},"content":" .orElse(null);"},{"lineNumber":169,"author":{"gitId":"yuanxi1"},"content":" courseIdDatastore \u003d Optional.ofNullable(logic.getStudentForRegistrationKey(regKey))"},{"lineNumber":170,"author":{"gitId":"yuanxi1"},"content":" .map(StudentAttributes::getCourse)"},{"lineNumber":171,"author":{"gitId":"yuanxi1"},"content":" .orElse(null);"},{"lineNumber":172,"author":{"gitId":"yuanxi1"},"content":" break;"},{"lineNumber":173,"author":{"gitId":"yuanxi1"},"content":" case Const.EntityType.INSTRUCTOR:"},{"lineNumber":174,"author":{"gitId":"yuanxi1"},"content":" courseIdSql \u003d Optional.ofNullable(sqlLogic.getInstructorByRegistrationKey(regKey))"},{"lineNumber":175,"author":{"gitId":"yuanxi1"},"content":" .map(Instructor::getCourseId)"},{"lineNumber":176,"author":{"gitId":"yuanxi1"},"content":" .orElse(null);"},{"lineNumber":177,"author":{"gitId":"yuanxi1"},"content":" courseIdDatastore \u003d Optional.ofNullable(logic.getInstructorForRegistrationKey(regKey))"},{"lineNumber":178,"author":{"gitId":"yuanxi1"},"content":" .map(InstructorAttributes::getCourseId)"},{"lineNumber":179,"author":{"gitId":"yuanxi1"},"content":" .orElse(null);"},{"lineNumber":180,"author":{"gitId":"yuanxi1"},"content":" break;"},{"lineNumber":181,"author":{"gitId":"yuanxi1"},"content":" default:"},{"lineNumber":182,"author":{"gitId":"yuanxi1"},"content":" throw new InvalidHttpParameterException(\"Error: invalid entity type\");"},{"lineNumber":183,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":184,"author":{"gitId":"yuanxi1"},"content":" return courseIdDatastore !\u003d null ? courseIdDatastore : courseIdSql;"},{"lineNumber":185,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"yuanxi1":98,"-":88}},{"path":"src/main/java/teammates/ui/webapi/PutDataBundleDocumentsAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.DataBundle;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * Puts searchable documents from the data bundle into the DB."},{"lineNumber":14,"author":{"gitId":"-"},"content":" */"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"public class PutDataBundleDocumentsAction extends Action {"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":18,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" return AuthType.ALL_ACCESS;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" }"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":23,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" if (!Config.IS_DEV_SERVER) {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Admin privilege is required to access this resource.\");"},{"lineNumber":26,"author":{"gitId":"-"},"content":" }"},{"lineNumber":27,"author":{"gitId":"-"},"content":" }"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" public JsonResult execute() throws InvalidHttpRequestBodyException {"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" String type \u003d getNonNullRequestParamValue(\"databundletype\");"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" switch (type) {"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" case \"sql\":"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" return putSqlDataBundleDocuments();"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" case \"datastore\":"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" return putDataBundleDocuments();"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" default:"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" throw new InvalidHttpParameterException(\"Error: invalid data bundle type\");"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" private JsonResult putSqlDataBundleDocuments() throws InvalidHttpRequestBodyException {"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" SqlDataBundle sqlDataBundle \u003d JsonUtils.fromJson(getRequestBody(), SqlDataBundle.class);"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" try {"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" sqlLogic.putDocuments(sqlDataBundle);"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" return new JsonResult(\"Failed to add data bundle documents.\", HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" return new JsonResult(\"Data bundle documents successfully added.\");"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" private JsonResult putDataBundleDocuments() throws InvalidHttpRequestBodyException {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" DataBundle dataBundle \u003d JsonUtils.fromJson(getRequestBody(), DataBundle.class);"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" logic.putDocuments(dataBundle);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" return new JsonResult(\"Failed to add data bundle documents.\", HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":" return new JsonResult(\"Data bundle documents successfully added.\");"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":29,"-":35}},{"path":"src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":"import teammates.ui.output.AccountRequestData;"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":"import teammates.ui.request.AccountRequestRejectionRequest;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" * Rejects an account request."},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":"public class RejectAccountRequestAction extends AdminOnlyAction {"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" public boolean isTransactionNeeded() {"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" return false;"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" public JsonResult execute() throws InvalidOperationException, InvalidHttpRequestBodyException {"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" String id \u003d getNonNullRequestParamValue(Const.ParamsNames.ACCOUNT_REQUEST_ID);"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" UUID accountRequestId \u003d getUuidFromString(Const.ParamsNames.ACCOUNT_REQUEST_ID, id);"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d sqlLogic.getAccountRequestWithTransaction(accountRequestId);"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" if (accountRequest \u003d\u003d null) {"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" String errorMessage \u003d String.format(Const.ACCOUNT_REQUEST_NOT_FOUND, accountRequestId.toString());"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" throw new EntityNotFoundException(errorMessage);"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest accountRequestRejectionRequest \u003d"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" getAndValidateRequestBody(AccountRequestRejectionRequest.class);"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" AccountRequestStatus initialStatus \u003d accountRequest.getStatus();"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" try {"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" accountRequest.setStatus(AccountRequestStatus.REJECTED);"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d sqlLogic.updateAccountRequestWithTransaction(accountRequest);"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" if (accountRequestRejectionRequest.checkHasReason()"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 initialStatus !\u003d AccountRequestStatus.REJECTED) {"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" EmailWrapper email \u003d sqlEmailGenerator.generateAccountRequestRejectionEmail(accountRequest,"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" accountRequestRejectionRequest.getReasonTitle(), accountRequestRejectionRequest.getReasonBody());"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" emailSender.sendEmail(email);"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" taskQueuer.scheduleAccountRequestForSearchIndexing(accountRequest.getId().toString());"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" throw new InvalidHttpRequestBodyException(e);"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" } catch (EntityDoesNotExistException e) {"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" throw new EntityNotFoundException(e);"},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" return new JsonResult(new AccountRequestData(accountRequest));"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"domoberzin":9,"xenosf":50}},{"path":"src/main/java/teammates/ui/webapi/ResetAccountRequestAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.ui.output.JoinLinkData;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * Action: resets an account request."},{"lineNumber":17,"author":{"gitId":"-"},"content":" */"},{"lineNumber":18,"author":{"gitId":"-"},"content":"class ResetAccountRequestAction extends AdminOnlyAction {"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":23,"author":{"gitId":"-"},"content":" public JsonResult execute() throws InvalidOperationException {"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":" UUID id \u003d getUuidRequestParamValue(Const.ParamsNames.ACCOUNT_REQUEST_ID);"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" AccountRequest accountRequest \u003d sqlLogic.getAccountRequest(id);"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" if (accountRequest \u003d\u003d null) {"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" throw new EntityNotFoundException(\"Account request with id: \" + id.toString() + \" does not exist.\");"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":" if (accountRequest.getRegisteredAt() \u003d\u003d null) {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(\"Unable to reset account request as instructor is still unregistered.\");"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" accountRequest \u003d sqlLogic.resetAccountRequest(id);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException | EntityDoesNotExistException ue) {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" // InvalidParametersException and EntityDoesNotExistException should not be thrown as"},{"lineNumber":39,"author":{"gitId":"-"},"content":" // validity of params has been verified when fetching entity."},{"lineNumber":40,"author":{"gitId":"-"},"content":" log.severe(\"Unexpected error\", ue);"},{"lineNumber":41,"author":{"gitId":"-"},"content":" return new JsonResult(ue.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR);"},{"lineNumber":42,"author":{"gitId":"-"},"content":" }"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" String joinLink \u003d accountRequest.getRegistrationUrl();"},{"lineNumber":45,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d emailGenerator.generateNewInstructorAccountJoinEmail("},{"lineNumber":46,"author":{"gitId":"-"},"content":" accountRequest.getEmail(), accountRequest.getName(), joinLink);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" emailSender.sendEmail(email);"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" JoinLinkData output \u003d new JoinLinkData(joinLink);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" return new JsonResult(output);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" }"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":6,"-":47}},{"path":"src/main/java/teammates/ui/webapi/SearchAccountRequestsAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountRequestAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.ui.output.AccountRequestData;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.ui.output.AccountRequestsData;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"-"},"content":" * Searches for account requests."},{"lineNumber":15,"author":{"gitId":"-"},"content":" */"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"public class SearchAccountRequestsAction extends AdminOnlyAction {"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":19,"author":{"gitId":"-"},"content":" public JsonResult execute() {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" String searchKey \u003d getNonNullRequestParamValue(Const.ParamsNames.SEARCH_KEY);"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" List\u003cAccountRequest\u003e accountRequests;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" accountRequests \u003d sqlLogic.searchAccountRequestsInWholeSystem(searchKey);"},{"lineNumber":25,"author":{"gitId":"-"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" return new JsonResult(e.getMessage(), e.getStatusCode());"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" List\u003cAccountRequestAttributes\u003e requestsDatastore;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" requestsDatastore \u003d logic.searchAccountRequestsInWholeSystem(searchKey);"},{"lineNumber":32,"author":{"gitId":"-"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" return new JsonResult(e.getMessage(), e.getStatusCode());"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" List\u003cAccountRequestData\u003e accountRequestDataList \u003d new ArrayList\u003c\u003e();"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" for (AccountRequest accountRequest : accountRequests) {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" AccountRequestData accountRequestData \u003d new AccountRequestData(accountRequest);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" accountRequestDataList.add(accountRequestData);"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" for (AccountRequestAttributes request : requestsDatastore) {"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" if (accountRequestDataList.stream().noneMatch(data -\u003e data.getEmail().equals(request.getEmail()))) {"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" AccountRequestData accountRequestData \u003d new AccountRequestData(request);"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" accountRequestDataList.add(accountRequestData);"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" AccountRequestsData accountRequestsData \u003d new AccountRequestsData();"},{"lineNumber":50,"author":{"gitId":"-"},"content":" accountRequestsData.setAccountRequests(accountRequestDataList);"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" return new JsonResult(accountRequestsData);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":17,"-":37}},{"path":"src/main/java/teammates/ui/webapi/SearchInstructorsAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.ui.output.InstructorData;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.ui.output.InstructorsData;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"-"},"content":" * Searches for instructors."},{"lineNumber":15,"author":{"gitId":"-"},"content":" */"},{"lineNumber":16,"author":{"gitId":"-"},"content":"public class SearchInstructorsAction extends AdminOnlyAction {"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":19,"author":{"gitId":"-"},"content":" public JsonResult execute() {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" // Search for sql db"},{"lineNumber":21,"author":{"gitId":"-"},"content":" String searchKey \u003d getNonNullRequestParamValue(Const.ParamsNames.SEARCH_KEY);"},{"lineNumber":22,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" instructors \u003d sqlLogic.searchInstructorsInWholeSystem(searchKey);"},{"lineNumber":25,"author":{"gitId":"-"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" return new JsonResult(e.getMessage(), e.getStatusCode());"},{"lineNumber":27,"author":{"gitId":"-"},"content":" }"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" // Search for datastore"},{"lineNumber":30,"author":{"gitId":"-"},"content":" List\u003cInstructorAttributes\u003e instructorsDatastore;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" instructorsDatastore \u003d logic.searchInstructorsInWholeSystem(searchKey);"},{"lineNumber":33,"author":{"gitId":"-"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" return new JsonResult(e.getMessage(), e.getStatusCode());"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" List\u003cInstructorData\u003e instructorDataList \u003d new ArrayList\u003c\u003e();"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" // Add instructors from sql db"},{"lineNumber":40,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructors) {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" InstructorData instructorData \u003d new InstructorData(instructor);"},{"lineNumber":42,"author":{"gitId":"-"},"content":" instructorData.addAdditionalInformationForAdminSearch("},{"lineNumber":43,"author":{"gitId":"-"},"content":" instructor.getRegKey(),"},{"lineNumber":44,"author":{"gitId":"-"},"content":" sqlLogic.getCourse(instructor.getCourseId()).getInstitute(),"},{"lineNumber":45,"author":{"gitId":"-"},"content":" instructor.getGoogleId());"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" instructorDataList.add(instructorData);"},{"lineNumber":48,"author":{"gitId":"-"},"content":" }"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" // Add instructors from datastore"},{"lineNumber":51,"author":{"gitId":"-"},"content":" for (InstructorAttributes instructor : instructorsDatastore) {"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" InstructorData instructorData \u003d new InstructorData(instructor);"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" if (isCourseMigrated(instructorData.getCourseId())) {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" instructorData.addAdditionalInformationForAdminSearch("},{"lineNumber":60,"author":{"gitId":"-"},"content":" instructor.getKey(),"},{"lineNumber":61,"author":{"gitId":"-"},"content":" logic.getCourseInstitute(instructor.getCourseId()),"},{"lineNumber":62,"author":{"gitId":"-"},"content":" instructor.getGoogleId());"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" instructorDataList.add(instructorData);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" InstructorsData instructorsData \u003d new InstructorsData();"},{"lineNumber":68,"author":{"gitId":"-"},"content":" instructorsData.setInstructors(instructorDataList);"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" return new JsonResult(instructorsData);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":1,"-":71}},{"path":"src/main/java/teammates/ui/webapi/SearchStudentsAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":10,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":11,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.ui.output.StudentData;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.ui.output.StudentsData;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * Action for searching for students."},{"lineNumber":17,"author":{"gitId":"-"},"content":" */"},{"lineNumber":18,"author":{"gitId":"yuanxi1"},"content":"public class SearchStudentsAction extends Action {"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":21,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" }"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":26,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" // Only instructors and admins can search for student"},{"lineNumber":28,"author":{"gitId":"-"},"content":" if (!userInfo.isInstructor \u0026\u0026 !userInfo.isAdmin) {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Instructor or Admin privilege is required to access this resource.\");"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":" }"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":34,"author":{"gitId":"-"},"content":" public JsonResult execute() {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" String searchKey \u003d getNonNullRequestParamValue(Const.ParamsNames.SEARCH_KEY);"},{"lineNumber":36,"author":{"gitId":"-"},"content":" String entity \u003d getNonNullRequestParamValue(Const.ParamsNames.ENTITY_TYPE);"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"yuanxi1"},"content":" List\u003cStudent\u003e students;"},{"lineNumber":39,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":40,"author":{"gitId":"yuanxi1"},"content":" try {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" if (userInfo.isInstructor \u0026\u0026 Const.EntityType.INSTRUCTOR.equals(entity)) {"},{"lineNumber":42,"author":{"gitId":"yuanxi1"},"content":" List\u003cInstructor\u003e instructors \u003d sqlLogic.getInstructorsForGoogleId(userInfo.id);"},{"lineNumber":43,"author":{"gitId":"yuanxi1"},"content":" students \u003d sqlLogic.searchStudents(searchKey, instructors);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" } else if (userInfo.isAdmin \u0026\u0026 Const.EntityType.ADMIN.equals(entity)) {"},{"lineNumber":45,"author":{"gitId":"yuanxi1"},"content":" students \u003d sqlLogic.searchStudentsInWholeSystem(searchKey);"},{"lineNumber":46,"author":{"gitId":"yuanxi1"},"content":" } else {"},{"lineNumber":47,"author":{"gitId":"yuanxi1"},"content":" throw new InvalidHttpParameterException(\"Invalid entity type for search\");"},{"lineNumber":48,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":49,"author":{"gitId":"yuanxi1"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":50,"author":{"gitId":"yuanxi1"},"content":" return new JsonResult(e.getMessage(), e.getStatusCode());"},{"lineNumber":51,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":52,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":53,"author":{"gitId":"yuanxi1"},"content":" // Search in datastore. For more information on dual db support, see this [PR](https://github.com/TEAMMATES/teammates/pull/12728/files)"},{"lineNumber":54,"author":{"gitId":"yuanxi1"},"content":" List\u003cStudentAttributes\u003e studentsDatastore;"},{"lineNumber":55,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" if (userInfo.isInstructor \u0026\u0026 Const.EntityType.INSTRUCTOR.equals(entity)) {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" List\u003cInstructorAttributes\u003e instructors \u003d logic.getInstructorsForGoogleId(userInfo.id);"},{"lineNumber":58,"author":{"gitId":"yuanxi1"},"content":" studentsDatastore \u003d logic.searchStudents(searchKey, instructors);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" } else if (userInfo.isAdmin \u0026\u0026 Const.EntityType.ADMIN.equals(entity)) {"},{"lineNumber":60,"author":{"gitId":"yuanxi1"},"content":" studentsDatastore \u003d logic.searchStudentsInWholeSystem(searchKey);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Invalid entity type for search\");"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"-"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" return new JsonResult(e.getMessage(), e.getStatusCode());"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" List\u003cStudentData\u003e studentDataList \u003d new ArrayList\u003c\u003e();"},{"lineNumber":69,"author":{"gitId":"yuanxi1"},"content":" // Add students from sql database"},{"lineNumber":70,"author":{"gitId":"yuanxi1"},"content":" for (Student s : students) {"},{"lineNumber":71,"author":{"gitId":"yuanxi1"},"content":" StudentData studentData \u003d new StudentData(s);"},{"lineNumber":72,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" if (userInfo.isAdmin \u0026\u0026 Const.EntityType.ADMIN.equals(entity)) {"},{"lineNumber":74,"author":{"gitId":"yuanxi1"},"content":" studentData.addAdditionalInformationForAdminSearch("},{"lineNumber":75,"author":{"gitId":"yuanxi1"},"content":" s.getRegKey(),"},{"lineNumber":76,"author":{"gitId":"yuanxi1"},"content":" sqlLogic.getCourseInstitute(s.getCourseId()),"},{"lineNumber":77,"author":{"gitId":"yuanxi1"},"content":" s.getGoogleId()"},{"lineNumber":78,"author":{"gitId":"yuanxi1"},"content":" );"},{"lineNumber":79,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":80,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":81,"author":{"gitId":"yuanxi1"},"content":" studentDataList.add(studentData);"},{"lineNumber":82,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":83,"author":{"gitId":"yuanxi1"},"content":" // Add students from datastore"},{"lineNumber":84,"author":{"gitId":"yuanxi1"},"content":" for (StudentAttributes s : studentsDatastore) {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" StudentData studentData \u003d new StudentData(s);"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" if (isCourseMigrated(studentData.getCourseId())) {"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" continue;"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" if (userInfo.isAdmin \u0026\u0026 Const.EntityType.ADMIN.equals(entity)) {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" studentData.addAdditionalInformationForAdminSearch("},{"lineNumber":93,"author":{"gitId":"-"},"content":" s.getKey(),"},{"lineNumber":94,"author":{"gitId":"-"},"content":" logic.getCourseInstitute(s.getCourse()),"},{"lineNumber":95,"author":{"gitId":"-"},"content":" s.getGoogleId()"},{"lineNumber":96,"author":{"gitId":"-"},"content":" );"},{"lineNumber":97,"author":{"gitId":"-"},"content":" }"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" studentDataList.add(studentData);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":" StudentsData studentsData \u003d new StudentsData();"},{"lineNumber":102,"author":{"gitId":"-"},"content":" studentsData.setStudents(studentDataList);"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" return new JsonResult(studentsData);"},{"lineNumber":105,"author":{"gitId":"-"},"content":" }"},{"lineNumber":106,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":4,"yuanxi1":35,"-":67}},{"path":"src/main/java/teammates/ui/webapi/StudentSearchIndexingWorkerAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.ParamsNames;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * Task queue worker action: performs student search indexing."},{"lineNumber":12,"author":{"gitId":"-"},"content":" */"},{"lineNumber":13,"author":{"gitId":"-"},"content":"public class StudentSearchIndexingWorkerAction extends AdminOnlyAction {"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":16,"author":{"gitId":"-"},"content":" public ActionResult execute() {"},{"lineNumber":17,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(ParamsNames.COURSE_ID);"},{"lineNumber":18,"author":{"gitId":"-"},"content":" String email \u003d getNonNullRequestParamValue(ParamsNames.STUDENT_EMAIL);"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" return executeWithSql(courseId, email);"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" return executeWithDataStore(courseId, email);"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" private ActionResult executeWithDataStore(String courseId, String email) {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" StudentAttributes student \u003d logic.getStudentForEmail(courseId, email);"},{"lineNumber":30,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" logic.putStudentDocument(student);"},{"lineNumber":32,"author":{"gitId":"-"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" // Set an arbitrary retry code outside of the range 200-299 to trigger automatic retry"},{"lineNumber":34,"author":{"gitId":"-"},"content":" return new JsonResult(\"Failure\", HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" return new JsonResult(\"Successful\");"},{"lineNumber":38,"author":{"gitId":"-"},"content":" }"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" private ActionResult executeWithSql(String courseId, String email) {"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" Student student \u003d sqlLogic.getStudentForEmail(courseId, email);"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" try {"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" sqlLogic.putStudentDocument(student);"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" // Set an arbitrary retry code outside of the range 200-299 to trigger automatic retry"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" return new JsonResult(\"Failure\", HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" return new JsonResult(\"Successful\");"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":51,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":22,"-":29}},{"path":"src/main/java/teammates/ui/webapi/UpdateAccountRequestAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.output.AccountRequestData;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.request.AccountRequestUpdateRequest;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" * Updates an account request."},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"public class UpdateAccountRequestAction extends AdminOnlyAction {"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" public boolean isTransactionNeeded() {"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" return false;"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" public JsonResult execute() throws InvalidOperationException, InvalidHttpRequestBodyException {"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" String id \u003d getNonNullRequestParamValue(Const.ParamsNames.ACCOUNT_REQUEST_ID);"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" UUID accountRequestId \u003d getUuidFromString(Const.ParamsNames.ACCOUNT_REQUEST_ID, id);"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d sqlLogic.getAccountRequestWithTransaction(accountRequestId);"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" if (accountRequest \u003d\u003d null) {"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" String errorMessage \u003d String.format(Const.ACCOUNT_REQUEST_NOT_FOUND, accountRequestId.toString());"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" throw new EntityNotFoundException(errorMessage);"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" AccountRequestUpdateRequest accountRequestUpdateRequest \u003d"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" getAndValidateRequestBody(AccountRequestUpdateRequest.class);"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" if (accountRequestUpdateRequest.getStatus() \u003d\u003d AccountRequestStatus.APPROVED"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" \u0026\u0026 (accountRequest.getStatus() \u003d\u003d AccountRequestStatus.PENDING"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" || accountRequest.getStatus() \u003d\u003d AccountRequestStatus.REJECTED)) {"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" if (!sqlLogic.getAccountsForEmailWithTransaction(accountRequest.getEmail()).isEmpty()) {"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" throw new InvalidOperationException(String.format(\"An account with email %s already exists. \""},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" + \"Please reject or delete the account request instead.\","},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" accountRequest.getEmail()));"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" if (!sqlLogic.getApprovedAccountRequestsForEmailWithTransaction(accountRequest.getEmail()).isEmpty()) {"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" throw new InvalidOperationException(String.format("},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" \"An account request with email %s has already been approved. \""},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" + \"Please reject or delete the account request instead.\","},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" accountRequest.getEmail()));"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" // should not need to update other fields for an approval"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" accountRequest.setStatus(accountRequestUpdateRequest.getStatus());"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d sqlLogic.updateAccountRequestWithTransaction(accountRequest);"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" EmailWrapper email \u003d sqlEmailGenerator.generateNewInstructorAccountJoinEmail("},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" accountRequest.getEmail(), accountRequest.getName(), accountRequest.getRegistrationUrl());"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" taskQueuer.scheduleAccountRequestForSearchIndexing(accountRequest.getId().toString());"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" emailSender.sendEmail(email);"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":" throw new InvalidHttpRequestBodyException(e);"},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" } catch (EntityDoesNotExistException e) {"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":" throw new EntityNotFoundException(e);"},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" } else {"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" accountRequest.setName(accountRequestUpdateRequest.getName());"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" accountRequest.setEmail(accountRequestUpdateRequest.getEmail());"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" accountRequest.setInstitute(accountRequestUpdateRequest.getInstitute());"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" accountRequest.setStatus(accountRequest.getStatus());"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" accountRequest.setComments(accountRequestUpdateRequest.getComments());"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d sqlLogic.updateAccountRequestWithTransaction(accountRequest);"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" taskQueuer.scheduleAccountRequestForSearchIndexing(accountRequest.getId().toString());"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" throw new InvalidHttpRequestBodyException(e);"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" } catch (EntityDoesNotExistException e) {"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" throw new EntityNotFoundException(e);"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":" return new JsonResult(new AccountRequestData(accountRequest));"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":85,"xenosf":1,"-":2}},{"path":"src/main/java/teammates/ui/webapi/UpdateFeedbackSessionLogsAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.time.temporal.ChronoUnit;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import java.util.HashMap;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import java.util.Map;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Const;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":" * Process feedback session logs from GCP in the past defined time period and"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" * store in the database."},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":"public class UpdateFeedbackSessionLogsAction extends AdminOnlyAction {"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" static final long COLLECTION_TIME_PERIOD \u003d Const.STUDENT_ACTIVITY_LOGS_UPDATE_INTERVAL.toMinutes();"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" static final long SPAM_FILTER \u003d Const.STUDENT_ACTIVITY_LOGS_FILTER_WINDOW.toMillis();"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" public JsonResult execute() {"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e filteredLogs \u003d new ArrayList\u003c\u003e();"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" Instant endTime \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.now());"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" Instant startTime \u003d endTime.minus(COLLECTION_TIME_PERIOD, ChronoUnit.MINUTES);"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntry\u003e logEntries \u003d logsProcessor.getOrderedFeedbackSessionLogs(null, null,"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" startTime.toEpochMilli(), endTime.toEpochMilli(), null);"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" Map\u003cUUID, Map\u003cString, Map\u003cUUID, Map\u003cString, Long\u003e\u003e\u003e\u003e lastSavedTimestamps \u003d new HashMap\u003c\u003e();"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" Map\u003cString, Boolean\u003e isCourseMigratedMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" for (FeedbackSessionLogEntry logEntry : logEntries) {"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" isCourseMigratedMap.computeIfAbsent(logEntry.getCourseId(), k -\u003e {"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" CourseAttributes course \u003d logic.getCourse(logEntry.getCourseId());"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" return course \u003d\u003d null || course.isMigrated();"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" });"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" if (!isCourseMigratedMap.get(logEntry.getCourseId())) {"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" continue;"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" String courseId \u003d logEntry.getCourseId();"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" UUID studentId \u003d logEntry.getStudentId();"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" UUID fbSessionId \u003d logEntry.getFeedbackSessionId();"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" String type \u003d logEntry.getFeedbackSessionLogType();"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" Long timestamp \u003d logEntry.getTimestamp();"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" lastSavedTimestamps.computeIfAbsent(studentId, k -\u003e new HashMap\u003c\u003e());"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" lastSavedTimestamps.get(studentId).computeIfAbsent(courseId, k -\u003e new HashMap\u003c\u003e());"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" lastSavedTimestamps.get(studentId).get(courseId).computeIfAbsent(fbSessionId, k -\u003e new HashMap\u003c\u003e());"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" Long lastSaved \u003d lastSavedTimestamps.get(studentId).get(courseId).get(fbSessionId).getOrDefault(type, 0L);"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" if (Math.abs(timestamp - lastSaved) \u003e SPAM_FILTER) {"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" lastSavedTimestamps.get(studentId).get(courseId).get(fbSessionId).put(type, timestamp);"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" Student student \u003d sqlLogic.getStudentReference(studentId);"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d sqlLogic.getFeedbackSessionReference(fbSessionId);"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog fslEntity \u003d new FeedbackSessionLog(student, feedbackSession,"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.valueOfLabel(type), Instant.ofEpochMilli(timestamp));"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" filteredLogs.add(fslEntity);"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" sqlLogic.createFeedbackSessionLogs(filteredLogs);"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" return new JsonResult(\"Successful\");"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":77}},{"path":"src/main/java/teammates/ui/webapi/UpdateStudentAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.Arrays;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.exception.EnrollException;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailSendingStatus;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailType;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":15,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":16,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":17,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":18,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":19,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.ui.request.StudentUpdateRequest;"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * Action: Edits details of a student in a course."},{"lineNumber":25,"author":{"gitId":"-"},"content":" */"},{"lineNumber":26,"author":{"gitId":"marquestye"},"content":"public class UpdateStudentAction extends Action {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" static final String STUDENT_NOT_FOUND_FOR_EDIT \u003d \"The student you tried to edit does not exist. \""},{"lineNumber":28,"author":{"gitId":"-"},"content":" + \"If the student was created during the last few minutes, \""},{"lineNumber":29,"author":{"gitId":"-"},"content":" + \"try again in a few more minutes as the student may still be being saved.\";"},{"lineNumber":30,"author":{"gitId":"-"},"content":" private static final String SUCCESSFUL_UPDATE \u003d \"Student has been updated\";"},{"lineNumber":31,"author":{"gitId":"-"},"content":" private static final String SUCCESSFUL_UPDATE_WITH_EMAIL \u003d SUCCESSFUL_UPDATE + \" and email sent\";"},{"lineNumber":32,"author":{"gitId":"-"},"content":" private static final String SUCCESSFUL_UPDATE_BUT_EMAIL_FAILED \u003d SUCCESSFUL_UPDATE + \" but email failed to send\";"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":35,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" }"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":40,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" if (!userInfo.isInstructor) {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Instructor privilege is required to access this resource.\");"},{"lineNumber":43,"author":{"gitId":"-"},"content":" }"},{"lineNumber":44,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"marquestye"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":47,"author":{"gitId":"marquestye"},"content":" Instructor instructor \u003d sqlLogic.getInstructorByGoogleId(courseId, userInfo.getId());"},{"lineNumber":48,"author":{"gitId":"marquestye"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":49,"author":{"gitId":"marquestye"},"content":" instructor, sqlLogic.getCourse(courseId), Const.InstructorPermissions.CAN_MODIFY_STUDENT);"},{"lineNumber":50,"author":{"gitId":"marquestye"},"content":" } else {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d logic.getInstructorForGoogleId(courseId, userInfo.id);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":53,"author":{"gitId":"-"},"content":" instructor, logic.getCourse(courseId), Const.InstructorPermissions.CAN_MODIFY_STUDENT);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" }"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":58,"author":{"gitId":"-"},"content":" public JsonResult execute() throws InvalidHttpRequestBodyException, InvalidOperationException {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" String studentEmail \u003d getNonNullRequestParamValue(Const.ParamsNames.STUDENT_EMAIL);"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"marquestye"},"content":" if (!isCourseMigrated(courseId)) {"},{"lineNumber":63,"author":{"gitId":"marquestye"},"content":" return executeWithDatastore(courseId, studentEmail);"},{"lineNumber":64,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":65,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":66,"author":{"gitId":"marquestye"},"content":" Student existingStudent \u003d sqlLogic.getStudentForEmail(courseId, studentEmail);"},{"lineNumber":67,"author":{"gitId":"marquestye"},"content":" if (existingStudent \u003d\u003d null) {"},{"lineNumber":68,"author":{"gitId":"marquestye"},"content":" throw new EntityNotFoundException(STUDENT_NOT_FOUND_FOR_EDIT);"},{"lineNumber":69,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":70,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":71,"author":{"gitId":"marquestye"},"content":" StudentUpdateRequest updateRequest \u003d getAndValidateRequestBody(StudentUpdateRequest.class);"},{"lineNumber":72,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":73,"author":{"gitId":"marquestye"},"content":" Course course \u003d sqlLogic.getCourse(courseId);"},{"lineNumber":74,"author":{"gitId":"marquestye"},"content":" Section section \u003d sqlLogic.getSectionOrCreate(courseId, updateRequest.getSection());"},{"lineNumber":75,"author":{"gitId":"marquestye"},"content":" Team team \u003d sqlLogic.getTeamOrCreate(section, updateRequest.getTeam());"},{"lineNumber":76,"author":{"gitId":"marquestye"},"content":" Student studentToUpdate \u003d new Student(course, updateRequest.getName(), updateRequest.getEmail(),"},{"lineNumber":77,"author":{"gitId":"marquestye"},"content":" updateRequest.getComments(), team);"},{"lineNumber":78,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":79,"author":{"gitId":"marquestye"},"content":" try {"},{"lineNumber":80,"author":{"gitId":"marquestye"},"content":" //we swap out email before we validate"},{"lineNumber":81,"author":{"gitId":"marquestye"},"content":" //TODO: this is duct tape at the moment, need to refactor how we do the validation"},{"lineNumber":82,"author":{"gitId":"marquestye"},"content":" String newEmail \u003d studentToUpdate.getEmail();"},{"lineNumber":83,"author":{"gitId":"marquestye"},"content":" studentToUpdate.setEmail(existingStudent.getEmail());"},{"lineNumber":84,"author":{"gitId":"marquestye"},"content":" sqlLogic.validateSectionsAndTeams(Arrays.asList(studentToUpdate), courseId);"},{"lineNumber":85,"author":{"gitId":"marquestye"},"content":" studentToUpdate.setEmail(newEmail);"},{"lineNumber":86,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":87,"author":{"gitId":"marquestye"},"content":" studentToUpdate.setId(existingStudent.getId());"},{"lineNumber":88,"author":{"gitId":"marquestye"},"content":" Student updatedStudent \u003d sqlLogic.updateStudentCascade(studentToUpdate);"},{"lineNumber":89,"author":{"gitId":"marquestye"},"content":" taskQueuer.scheduleStudentForSearchIndexing(courseId, updatedStudent.getEmail());"},{"lineNumber":90,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":91,"author":{"gitId":"marquestye"},"content":" if (!studentEmail.equals(updateRequest.getEmail()) \u0026\u0026 updateRequest.getIsSessionSummarySendEmail()) {"},{"lineNumber":92,"author":{"gitId":"marquestye"},"content":" boolean emailSent \u003d sendEmail(courseId, updateRequest.getEmail());"},{"lineNumber":93,"author":{"gitId":"marquestye"},"content":" String statusMessage \u003d emailSent ? SUCCESSFUL_UPDATE_WITH_EMAIL"},{"lineNumber":94,"author":{"gitId":"marquestye"},"content":" : SUCCESSFUL_UPDATE_BUT_EMAIL_FAILED;"},{"lineNumber":95,"author":{"gitId":"marquestye"},"content":" return new JsonResult(statusMessage);"},{"lineNumber":96,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":97,"author":{"gitId":"marquestye"},"content":" } catch (EnrollException e) {"},{"lineNumber":98,"author":{"gitId":"marquestye"},"content":" throw new InvalidOperationException(e);"},{"lineNumber":99,"author":{"gitId":"marquestye"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":100,"author":{"gitId":"marquestye"},"content":" throw new InvalidHttpRequestBodyException(e);"},{"lineNumber":101,"author":{"gitId":"marquestye"},"content":" } catch (EntityDoesNotExistException ednee) {"},{"lineNumber":102,"author":{"gitId":"marquestye"},"content":" throw new EntityNotFoundException(ednee);"},{"lineNumber":103,"author":{"gitId":"marquestye"},"content":" } catch (EntityAlreadyExistsException e) {"},{"lineNumber":104,"author":{"gitId":"marquestye"},"content":" throw new InvalidOperationException(\"Trying to update to an email that is already in use\", e);"},{"lineNumber":105,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":106,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":107,"author":{"gitId":"marquestye"},"content":" return new JsonResult(SUCCESSFUL_UPDATE);"},{"lineNumber":108,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":109,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":110,"author":{"gitId":"marquestye"},"content":" private JsonResult executeWithDatastore(String courseId, String studentEmail)"},{"lineNumber":111,"author":{"gitId":"marquestye"},"content":" throws InvalidHttpRequestBodyException, InvalidOperationException {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" StudentAttributes student \u003d logic.getStudentForEmail(courseId, studentEmail);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":114,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(STUDENT_NOT_FOUND_FOR_EDIT);"},{"lineNumber":115,"author":{"gitId":"-"},"content":" }"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" StudentUpdateRequest updateRequest \u003d getAndValidateRequestBody(StudentUpdateRequest.class);"},{"lineNumber":118,"author":{"gitId":"-"},"content":" StudentAttributes studentToUpdate \u003d StudentAttributes.builder(courseId, updateRequest.getEmail())"},{"lineNumber":119,"author":{"gitId":"-"},"content":" .withName(updateRequest.getName())"},{"lineNumber":120,"author":{"gitId":"-"},"content":" .withSectionName(updateRequest.getSection())"},{"lineNumber":121,"author":{"gitId":"-"},"content":" .withTeamName(updateRequest.getTeam())"},{"lineNumber":122,"author":{"gitId":"-"},"content":" .withComment(updateRequest.getComments())"},{"lineNumber":123,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":126,"author":{"gitId":"-"},"content":" //we swap out email before we validate"},{"lineNumber":127,"author":{"gitId":"-"},"content":" //TODO: this is duct tape at the moment, need to refactor how we do the validation"},{"lineNumber":128,"author":{"gitId":"-"},"content":" String newEmail \u003d studentToUpdate.getEmail();"},{"lineNumber":129,"author":{"gitId":"-"},"content":" studentToUpdate.setEmail(student.getEmail());"},{"lineNumber":130,"author":{"gitId":"-"},"content":" logic.validateSectionsAndTeams(Arrays.asList(studentToUpdate), student.getCourse());"},{"lineNumber":131,"author":{"gitId":"-"},"content":" studentToUpdate.setEmail(newEmail);"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" StudentAttributes updatedStudent \u003d logic.updateStudentCascade("},{"lineNumber":134,"author":{"gitId":"-"},"content":" StudentAttributes.updateOptionsBuilder(courseId, studentEmail)"},{"lineNumber":135,"author":{"gitId":"-"},"content":" .withName(updateRequest.getName())"},{"lineNumber":136,"author":{"gitId":"-"},"content":" .withNewEmail(updateRequest.getEmail())"},{"lineNumber":137,"author":{"gitId":"-"},"content":" .withTeamName(updateRequest.getTeam())"},{"lineNumber":138,"author":{"gitId":"-"},"content":" .withSectionName(updateRequest.getSection())"},{"lineNumber":139,"author":{"gitId":"-"},"content":" .withComment(updateRequest.getComments())"},{"lineNumber":140,"author":{"gitId":"-"},"content":" .build());"},{"lineNumber":141,"author":{"gitId":"-"},"content":" taskQueuer.scheduleStudentForSearchIndexing(updatedStudent.getCourse(), updatedStudent.getEmail());"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" if (!student.getEmail().equals(updateRequest.getEmail())) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" logic.resetStudentGoogleId(updateRequest.getEmail(), courseId);"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" if (updateRequest.getIsSessionSummarySendEmail()) {"},{"lineNumber":147,"author":{"gitId":"-"},"content":" boolean emailSent \u003d sendEmail(courseId, updateRequest.getEmail());"},{"lineNumber":148,"author":{"gitId":"-"},"content":" String statusMessage \u003d emailSent ? SUCCESSFUL_UPDATE_WITH_EMAIL"},{"lineNumber":149,"author":{"gitId":"-"},"content":" : SUCCESSFUL_UPDATE_BUT_EMAIL_FAILED;"},{"lineNumber":150,"author":{"gitId":"-"},"content":" return new JsonResult(statusMessage);"},{"lineNumber":151,"author":{"gitId":"-"},"content":" }"},{"lineNumber":152,"author":{"gitId":"-"},"content":" }"},{"lineNumber":153,"author":{"gitId":"-"},"content":" } catch (EnrollException e) {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(e);"},{"lineNumber":155,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(e);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" } catch (EntityDoesNotExistException ednee) {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(ednee);"},{"lineNumber":159,"author":{"gitId":"-"},"content":" } catch (EntityAlreadyExistsException e) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(\"Trying to update to an email that is already in use\", e);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" return new JsonResult(SUCCESSFUL_UPDATE);"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":167,"author":{"gitId":"-"},"content":" * Sends the feedback session summary as an email."},{"lineNumber":168,"author":{"gitId":"-"},"content":" *"},{"lineNumber":169,"author":{"gitId":"-"},"content":" * @return The true if email was sent successfully or false otherwise."},{"lineNumber":170,"author":{"gitId":"-"},"content":" */"},{"lineNumber":171,"author":{"gitId":"-"},"content":" private boolean sendEmail(String courseId, String studentEmail) {"},{"lineNumber":172,"author":{"gitId":"marquestye"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":173,"author":{"gitId":"marquestye"},"content":" EmailWrapper email \u003d sqlEmailGenerator.generateFeedbackSessionSummaryOfCourse("},{"lineNumber":174,"author":{"gitId":"marquestye"},"content":" courseId, studentEmail, EmailType.STUDENT_EMAIL_CHANGED);"},{"lineNumber":175,"author":{"gitId":"marquestye"},"content":" EmailSendingStatus status \u003d emailSender.sendEmail(email);"},{"lineNumber":176,"author":{"gitId":"marquestye"},"content":" return status.isSuccess();"},{"lineNumber":177,"author":{"gitId":"marquestye"},"content":" } else {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d emailGenerator.generateFeedbackSessionSummaryOfCourse("},{"lineNumber":179,"author":{"gitId":"-"},"content":" courseId, studentEmail, EmailType.STUDENT_EMAIL_CHANGED);"},{"lineNumber":180,"author":{"gitId":"-"},"content":" EmailSendingStatus status \u003d emailSender.sendEmail(email);"},{"lineNumber":181,"author":{"gitId":"-"},"content":" return status.isSuccess();"},{"lineNumber":182,"author":{"gitId":"-"},"content":" }"},{"lineNumber":183,"author":{"gitId":"-"},"content":" }"},{"lineNumber":184,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":185,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":68,"-":117}},{"path":"src/main/resources/instructorEmailTemplate-newAccountRequestAcknowledgement.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"\u003cp\u003eHello, ${name}\u003c/p\u003e"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":" Thank you for submitting an account request. This is what you have submitted:"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"\u003cdiv\u003e"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":" \u003ctable style\u003d\"max-width:600px;border:1px solid black;\"\u003e"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" Full Name"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" ${name}"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" Country \u0026 Institute"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" ${institute}"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" Email Address"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" ${emailAddress}"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" Comments"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" ${comments}"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" \u003c/table\u003e"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":"\u003c/div\u003e"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" Your request will be reviewed within 24 hours. We will send another email once your request has been accepted."},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" If you have any additional queries, please feel free to contact us at ${supportEmail}."},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" Regards,\u003cbr\u003e"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" TEAMMATES Team."},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"}],"authorContributionMap":{"xenosf":65}},{"path":"src/test/java/teammates/common/datatransfer/SqlSessionResultsBundleTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.common.datatransfer;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import java.util.HashMap;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import java.util.HashSet;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import java.util.Map;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":"import org.testng.annotations.Test;"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":" * SUT: {@link SqlSessionResultsBundle}."},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":"public class SqlSessionResultsBundleTest extends BaseTestCase {"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" public void testGetQuestionResponseMap() {"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" SqlDataBundle responseBundle \u003d loadSqlDataBundle(\"/SqlFeedbackSessionResultsBundleTest.json\");"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" List\u003cString\u003e allExpectedResponses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" allExpectedResponses.add(responseBundle.feedbackResponses.get(\"response1ForQ1\").toString());"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" allExpectedResponses.add(responseBundle.feedbackResponses.get(\"response2ForQ1\").toString());"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" SqlSessionResultsBundle bundle \u003d"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" new SqlSessionResultsBundle("},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.feedbackQuestions.values()),"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(),"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(),"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.feedbackResponses.values()),"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(),"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" new SqlCourseRoster(new ArrayList\u003c\u003e(responseBundle.students.values()),"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.instructors.values()))"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" ______TS(\"Test question having responses\");"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion fq \u003d responseBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e allResponses \u003d bundle.getQuestionResponseMap().get(fq);"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" assertEquals(2, allResponses.size());"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" List\u003cString\u003e allResponsesString \u003d new ArrayList\u003c\u003e();"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" allResponsesString.add(allResponses.get(0).toString());"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" allResponsesString.add(allResponses.get(1).toString());"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" assertEquals(allExpectedResponses, allResponsesString);"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":" ______TS(\"Test question having no responses\");"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" fq \u003d responseBundle.feedbackQuestions.get(\"qn4InSession1InCourse1\");"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" allResponses \u003d bundle.getQuestionResponseMap().get(fq);"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" assertEquals(0, allResponses.size());"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" public void testGetQuestionMissingResponseMap() {"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" SqlDataBundle responseBundle \u003d loadSqlDataBundle(\"/SqlFeedbackSessionResultsBundleTest.json\");"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":" List\u003cString\u003e expectedMissingResponses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":" expectedMissingResponses.add(responseBundle.feedbackResponses.get(\"response1ForQ1\").toString());"},{"lineNumber":67,"author":{"gitId":"xenosf"},"content":" expectedMissingResponses.add(responseBundle.feedbackResponses.get(\"response2ForQ1\").toString());"},{"lineNumber":68,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":" SqlSessionResultsBundle bundle \u003d"},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":" new SqlSessionResultsBundle("},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.feedbackQuestions.values()),"},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(),"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(),"},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(),"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.feedbackResponses.values()),"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" new SqlCourseRoster(new ArrayList\u003c\u003e(responseBundle.students.values()),"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.instructors.values()))"},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":" ______TS(\"Test question having missing responses\");"},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion fq \u003d responseBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e missingResponses \u003d bundle.getQuestionMissingResponseMap().get(fq);"},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":" assertEquals(2, missingResponses.size());"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" List\u003cString\u003e missingResponsesString \u003d new ArrayList\u003c\u003e();"},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":" missingResponsesString.add(missingResponses.get(0).toString());"},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" missingResponsesString.add(missingResponses.get(1).toString());"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":" assertEquals(expectedMissingResponses, missingResponsesString);"},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":93,"author":{"gitId":"xenosf"},"content":" ______TS(\"Test question having no missing responses\");"},{"lineNumber":94,"author":{"gitId":"xenosf"},"content":" fq \u003d responseBundle.feedbackQuestions.get(\"qn4InSession1InCourse1\");"},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":" missingResponses \u003d bundle.getQuestionMissingResponseMap().get(fq);"},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":" assertEquals(0, missingResponses.size());"},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":100,"author":{"gitId":"xenosf"},"content":" public void testIsResponseGiverRecipientVisible_typicalCase_shouldReturnCorrectValues() {"},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":102,"author":{"gitId":"xenosf"},"content":" SqlDataBundle responseBundle \u003d loadSqlDataBundle(\"/SqlFeedbackSessionResultsBundleTest.json\");"},{"lineNumber":103,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":104,"author":{"gitId":"xenosf"},"content":" FeedbackSession session1Course1 \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":105,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":106,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question1ForS1C1 \u003d getTypicalFeedbackQuestionForSession(session1Course1);"},{"lineNumber":107,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question2ForS1C1 \u003d getTypicalFeedbackQuestionForSession(session1Course1);"},{"lineNumber":108,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":109,"author":{"gitId":"xenosf"},"content":" FeedbackResponse response1ForQ1S1C1 \u003d getTypicalFeedbackResponseForQuestion(question1ForS1C1);"},{"lineNumber":110,"author":{"gitId":"xenosf"},"content":" FeedbackResponse response2ForQ1S1C1 \u003d getTypicalFeedbackResponseForQuestion(question1ForS1C1);"},{"lineNumber":111,"author":{"gitId":"xenosf"},"content":" FeedbackResponse response1ForQ2S1C1 \u003d getTypicalFeedbackResponseForQuestion(question2ForS1C1);"},{"lineNumber":112,"author":{"gitId":"xenosf"},"content":" FeedbackResponse response2ForQ2S1C1 \u003d getTypicalFeedbackResponseForQuestion(question2ForS1C1);"},{"lineNumber":113,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":114,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackResponse, Boolean\u003e responseGiverVisibilityTable \u003d new HashMap\u003c\u003e();"},{"lineNumber":115,"author":{"gitId":"xenosf"},"content":" responseGiverVisibilityTable.put(response1ForQ1S1C1, true);"},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" responseGiverVisibilityTable.put(response2ForQ1S1C1, false);"},{"lineNumber":117,"author":{"gitId":"xenosf"},"content":" responseGiverVisibilityTable.put(response1ForQ2S1C1, true);"},{"lineNumber":118,"author":{"gitId":"xenosf"},"content":" responseGiverVisibilityTable.put(response2ForQ2S1C1, false);"},{"lineNumber":119,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":120,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackResponse, Boolean\u003e responseRecipientVisibilityTable \u003d new HashMap\u003c\u003e();"},{"lineNumber":121,"author":{"gitId":"xenosf"},"content":" responseRecipientVisibilityTable.put(response1ForQ1S1C1, false);"},{"lineNumber":122,"author":{"gitId":"xenosf"},"content":" responseRecipientVisibilityTable.put(response2ForQ1S1C1, true);"},{"lineNumber":123,"author":{"gitId":"xenosf"},"content":" responseRecipientVisibilityTable.put(response1ForQ2S1C1, true);"},{"lineNumber":124,"author":{"gitId":"xenosf"},"content":" responseRecipientVisibilityTable.put(response2ForQ2S1C1, false);"},{"lineNumber":125,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":126,"author":{"gitId":"xenosf"},"content":" SqlSessionResultsBundle bundle \u003d"},{"lineNumber":127,"author":{"gitId":"xenosf"},"content":" new SqlSessionResultsBundle("},{"lineNumber":128,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.feedbackQuestions.values()),"},{"lineNumber":129,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(),"},{"lineNumber":130,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(),"},{"lineNumber":131,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.feedbackResponses.values()),"},{"lineNumber":132,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(),"},{"lineNumber":133,"author":{"gitId":"xenosf"},"content":" responseGiverVisibilityTable,"},{"lineNumber":134,"author":{"gitId":"xenosf"},"content":" responseRecipientVisibilityTable,"},{"lineNumber":135,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":136,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":137,"author":{"gitId":"xenosf"},"content":" new SqlCourseRoster(new ArrayList\u003c\u003e(responseBundle.students.values()),"},{"lineNumber":138,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.instructors.values()))"},{"lineNumber":139,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":140,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":141,"author":{"gitId":"xenosf"},"content":" for (Map.Entry\u003cFeedbackResponse, Boolean\u003e visibilityEntry : responseGiverVisibilityTable.entrySet()) {"},{"lineNumber":142,"author":{"gitId":"xenosf"},"content":" assertEquals(visibilityEntry.getValue(),"},{"lineNumber":143,"author":{"gitId":"xenosf"},"content":" bundle.isResponseGiverVisible(visibilityEntry.getKey()));"},{"lineNumber":144,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":145,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":146,"author":{"gitId":"xenosf"},"content":" for (Map.Entry\u003cFeedbackResponse, Boolean\u003e visibilityEntry : responseRecipientVisibilityTable.entrySet()) {"},{"lineNumber":147,"author":{"gitId":"xenosf"},"content":" assertEquals(visibilityEntry.getValue(),"},{"lineNumber":148,"author":{"gitId":"xenosf"},"content":" bundle.isResponseRecipientVisible(visibilityEntry.getKey()));"},{"lineNumber":149,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":150,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":151,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":152,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":153,"author":{"gitId":"xenosf"},"content":" public void testIsCommentGiverVisible_typicalCase_shouldReturnCorrectValues() {"},{"lineNumber":154,"author":{"gitId":"xenosf"},"content":" SqlDataBundle responseBundle \u003d loadSqlDataBundle(\"/SqlFeedbackSessionResultsBundleTest.json\");"},{"lineNumber":155,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":156,"author":{"gitId":"xenosf"},"content":" Map\u003cLong, Boolean\u003e commentGiverVisibilityTable \u003d new HashMap\u003c\u003e();"},{"lineNumber":157,"author":{"gitId":"xenosf"},"content":" commentGiverVisibilityTable.put(1L, true);"},{"lineNumber":158,"author":{"gitId":"xenosf"},"content":" commentGiverVisibilityTable.put(2L, false);"},{"lineNumber":159,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":160,"author":{"gitId":"xenosf"},"content":" SqlSessionResultsBundle bundle \u003d"},{"lineNumber":161,"author":{"gitId":"xenosf"},"content":" new SqlSessionResultsBundle("},{"lineNumber":162,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.feedbackQuestions.values()),"},{"lineNumber":163,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(),"},{"lineNumber":164,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(),"},{"lineNumber":165,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.feedbackResponses.values()),"},{"lineNumber":166,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(),"},{"lineNumber":167,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":168,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":169,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":170,"author":{"gitId":"xenosf"},"content":" commentGiverVisibilityTable,"},{"lineNumber":171,"author":{"gitId":"xenosf"},"content":" new SqlCourseRoster(new ArrayList\u003c\u003e(responseBundle.students.values()),"},{"lineNumber":172,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.instructors.values()))"},{"lineNumber":173,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":174,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":175,"author":{"gitId":"xenosf"},"content":" // Manually add comment IDs as loadSqlDataBundle does not add comment IDs"},{"lineNumber":176,"author":{"gitId":"xenosf"},"content":" FeedbackResponseComment comment1 \u003d responseBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ1\");"},{"lineNumber":177,"author":{"gitId":"xenosf"},"content":" FeedbackResponseComment comment2 \u003d responseBundle.feedbackResponseComments.get(\"comment2ToResponse1ForQ1\");"},{"lineNumber":178,"author":{"gitId":"xenosf"},"content":" comment1.setId(1L);"},{"lineNumber":179,"author":{"gitId":"xenosf"},"content":" comment2.setId(2L);"},{"lineNumber":180,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":181,"author":{"gitId":"xenosf"},"content":" assertTrue(bundle.isCommentGiverVisible(comment1));"},{"lineNumber":182,"author":{"gitId":"xenosf"},"content":" assertFalse(bundle.isCommentGiverVisible(comment2));"},{"lineNumber":183,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":184,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":185,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":186,"author":{"gitId":"xenosf"},"content":" public void testGetAnonName_typicalCase_shouldGenerateCorrectly() {"},{"lineNumber":187,"author":{"gitId":"xenosf"},"content":" String anonName \u003d SqlSessionResultsBundle.getAnonName(FeedbackParticipantType.STUDENTS, \"\");"},{"lineNumber":188,"author":{"gitId":"xenosf"},"content":" assertTrue(anonName.startsWith(Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT));"},{"lineNumber":189,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":190,"author":{"gitId":"xenosf"},"content":" anonName \u003d SqlSessionResultsBundle.getAnonName(FeedbackParticipantType.STUDENTS, \"test@gmail.com\");"},{"lineNumber":191,"author":{"gitId":"xenosf"},"content":" assertTrue(anonName.startsWith(Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT));"},{"lineNumber":192,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":193,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":193}},{"path":"src/test/java/teammates/common/util/FieldValidatorTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.util;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Duration;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.temporal.ChronoUnit;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"-"},"content":" * SUT: {@link FieldValidator}."},{"lineNumber":15,"author":{"gitId":"-"},"content":" */"},{"lineNumber":16,"author":{"gitId":"-"},"content":"public class FieldValidatorTest extends BaseTestCase {"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":19,"author":{"gitId":"-"},"content":" public void testGetValidityInfoForNonHtmlField_cleanInput_returnEmptyString() {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" String clean \u003d \"Valid clean input with no special HTML characters\";"},{"lineNumber":21,"author":{"gitId":"-"},"content":" String testFieldName \u003d \"Inconsequential test field name\";"},{"lineNumber":22,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getValidityInfoForNonHtmlField(testFieldName, clean);"},{"lineNumber":23,"author":{"gitId":"-"},"content":" assertEquals(\"Valid clean input with no special HTML characters should return empty string\", \"\","},{"lineNumber":24,"author":{"gitId":"-"},"content":" actual);"},{"lineNumber":25,"author":{"gitId":"-"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":28,"author":{"gitId":"-"},"content":" public void testGetValidityInfoForNonHtmlField_sanitizedInput_returnEmptyString() {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" String sanitizedInput \u003d \"Valid sanitized input \u0026lt; \u0026gt; \u0026quot; \u0026#x2f; \u0026#39; \u0026amp;\";"},{"lineNumber":30,"author":{"gitId":"-"},"content":" String testFieldName \u003d \"Inconsequential test field name\";"},{"lineNumber":31,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getValidityInfoForNonHtmlField(testFieldName, sanitizedInput);"},{"lineNumber":32,"author":{"gitId":"-"},"content":" assertEquals(\"Valid sanitized input should return empty string\", \"\", actual);"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":36,"author":{"gitId":"-"},"content":" public void testGetValidityInfoForNonHtmlField_unsanitizedInput_returnErrorString() {"},{"lineNumber":37,"author":{"gitId":"-"},"content":" String unsanitizedInput \u003d \"Invalid unsanitized input \u003c\u003e\\\"/\u0027\u0026\";"},{"lineNumber":38,"author":{"gitId":"-"},"content":" String testFieldName \u003d \"Inconsequential test field name\";"},{"lineNumber":39,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getValidityInfoForNonHtmlField(testFieldName, unsanitizedInput);"},{"lineNumber":40,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid unsanitized input should return error string\","},{"lineNumber":41,"author":{"gitId":"-"},"content":" \"The provided Inconsequential test field name is not acceptable to TEAMMATES as it \""},{"lineNumber":42,"author":{"gitId":"-"},"content":" + \"cannot contain the following special html characters in brackets: (\u003c \u003e \\\" / \u0027 \u0026)\","},{"lineNumber":43,"author":{"gitId":"-"},"content":" actual);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" }"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":47,"author":{"gitId":"-"},"content":" public void testGetValidityInfoForSizeCappedPossiblyEmptyString() {"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" String typicalFieldName \u003d \"my field\";"},{"lineNumber":50,"author":{"gitId":"-"},"content":" int maxLength \u003d 50;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" assertEquals(\"valid: typical value\","},{"lineNumber":52,"author":{"gitId":"-"},"content":" \"\","},{"lineNumber":53,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForSizeCappedPossiblyEmptyString("},{"lineNumber":54,"author":{"gitId":"-"},"content":" typicalFieldName,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" maxLength,"},{"lineNumber":56,"author":{"gitId":"-"},"content":" \"Dr. Amy-B s/o O\u0027br, \u0026 2nd \\t \\n (alias \u0027JB\u0027)\"));"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" assertEquals(\"valid: max length\","},{"lineNumber":59,"author":{"gitId":"-"},"content":" \"\","},{"lineNumber":60,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForSizeCappedPossiblyEmptyString("},{"lineNumber":61,"author":{"gitId":"-"},"content":" typicalFieldName,"},{"lineNumber":62,"author":{"gitId":"-"},"content":" maxLength,"},{"lineNumber":63,"author":{"gitId":"-"},"content":" StringHelperExtension.generateStringOfLength(maxLength)));"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" String emptyValue \u003d \"\";"},{"lineNumber":66,"author":{"gitId":"-"},"content":" assertEquals(\"valid: empty\","},{"lineNumber":67,"author":{"gitId":"-"},"content":" \"\","},{"lineNumber":68,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForSizeCappedPossiblyEmptyString("},{"lineNumber":69,"author":{"gitId":"-"},"content":" typicalFieldName,"},{"lineNumber":70,"author":{"gitId":"-"},"content":" maxLength,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" emptyValue));"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" String untrimmedValue \u003d \" abc \";"},{"lineNumber":74,"author":{"gitId":"-"},"content":" assertEquals(\"invalid: untrimmed\","},{"lineNumber":75,"author":{"gitId":"-"},"content":" \"The provided my field is not acceptable to TEAMMATES as it contains only whitespace or \""},{"lineNumber":76,"author":{"gitId":"-"},"content":" + \"contains extra spaces at the beginning or at the end of the text.\","},{"lineNumber":77,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForSizeCappedPossiblyEmptyString(typicalFieldName, maxLength,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" untrimmedValue));"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" String tooLongName \u003d StringHelperExtension.generateStringOfLength(maxLength + 1);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" assertEquals(\"invalid: too long\","},{"lineNumber":82,"author":{"gitId":"-"},"content":" \"\\\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\" is not acceptable to TEAMMATES \""},{"lineNumber":83,"author":{"gitId":"-"},"content":" + \"as a/an my field because it is too long. The value of a/an my field should be no \""},{"lineNumber":84,"author":{"gitId":"-"},"content":" + \"longer than 50 characters.\","},{"lineNumber":85,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForSizeCappedPossiblyEmptyString(typicalFieldName, maxLength,"},{"lineNumber":86,"author":{"gitId":"-"},"content":" tooLongName));"},{"lineNumber":87,"author":{"gitId":"-"},"content":" }"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":90,"author":{"gitId":"-"},"content":" public void testGetValidityInfoForAllowedName() {"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" ______TS(\"null value\");"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" String typicalFieldName \u003d \"name field\";"},{"lineNumber":95,"author":{"gitId":"-"},"content":" int typicalLength \u003d 25;"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" assertThrows(AssertionError.class, () -\u003e"},{"lineNumber":98,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName(typicalFieldName, typicalLength, null));"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" ______TS(\"typical success case\");"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" int maxLength \u003d 50;"},{"lineNumber":103,"author":{"gitId":"-"},"content":" assertEquals(\"valid: typical length with valid characters\","},{"lineNumber":104,"author":{"gitId":"-"},"content":" \"\","},{"lineNumber":105,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName("},{"lineNumber":106,"author":{"gitId":"-"},"content":" typicalFieldName,"},{"lineNumber":107,"author":{"gitId":"-"},"content":" maxLength,"},{"lineNumber":108,"author":{"gitId":"-"},"content":" \"Ýàn-B. s/o O\u0027br, \u00262\\t\\n(~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\"));"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" ______TS(\"failure: invalid characters\");"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" String nameContainInvalidChars \u003d \"Dr. Amy-Bén s/o O\u0027\u0026|% 2\\t\\n (~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\";"},{"lineNumber":113,"author":{"gitId":"-"},"content":" assertEquals(\"invalid: typical length with invalid characters\","},{"lineNumber":114,"author":{"gitId":"-"},"content":" \"\\\"Dr. Amy-Bén s/o O\u0027\u0026|% 2\\t\\n (~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\\\" is \""},{"lineNumber":115,"author":{"gitId":"-"},"content":" + \"not acceptable to TEAMMATES as a/an name field because it contains invalid \""},{"lineNumber":116,"author":{"gitId":"-"},"content":" + \"characters. A/An name field must start with an alphanumeric character, and cannot \""},{"lineNumber":117,"author":{"gitId":"-"},"content":" + \"contain any vertical bar (|) or percent sign (%).\","},{"lineNumber":118,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName(typicalFieldName, maxLength,"},{"lineNumber":119,"author":{"gitId":"-"},"content":" nameContainInvalidChars));"},{"lineNumber":120,"author":{"gitId":"-"},"content":""},{"lineNumber":121,"author":{"gitId":"-"},"content":" ______TS(\"failure: starts with non-alphanumeric character\");"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" String nameStartedWithNonAlphaNumChar \u003d \"!Amy-Bén s/o O\u0027\u0026|% 2\\t\\n (~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\";"},{"lineNumber":124,"author":{"gitId":"-"},"content":" assertEquals(\"invalid: typical length with invalid characters\","},{"lineNumber":125,"author":{"gitId":"-"},"content":" \"\\\"!Amy-Bén s/o O\u0027\u0026|% 2\\t\\n (~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\\\" is not \""},{"lineNumber":126,"author":{"gitId":"-"},"content":" + \"acceptable to TEAMMATES as a/an name field because it starts with a \""},{"lineNumber":127,"author":{"gitId":"-"},"content":" + \"non-alphanumeric character. A/An name field must start with an alphanumeric \""},{"lineNumber":128,"author":{"gitId":"-"},"content":" + \"character, and cannot contain any vertical bar (|) or percent sign (%).\","},{"lineNumber":129,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName(typicalFieldName, maxLength,"},{"lineNumber":130,"author":{"gitId":"-"},"content":" nameStartedWithNonAlphaNumChar));"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":" ______TS(\"failure: starts with curly braces but contains invalid char\");"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" String nameStartedWithBracesButHasInvalidChar \u003d \"{Amy} -Bén s/o O\u0027\u0026|% 2\\t\\n (~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\";"},{"lineNumber":135,"author":{"gitId":"-"},"content":" assertEquals(\"invalid: typical length with invalid characters\","},{"lineNumber":136,"author":{"gitId":"-"},"content":" \"\\\"{Amy} -Bén s/o O\u0027\u0026|% 2\\t\\n (~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\\\" is not \""},{"lineNumber":137,"author":{"gitId":"-"},"content":" + \"acceptable to TEAMMATES as a/an name field because it contains invalid \""},{"lineNumber":138,"author":{"gitId":"-"},"content":" + \"characters. A/An name field must start with an alphanumeric character, and cannot \""},{"lineNumber":139,"author":{"gitId":"-"},"content":" + \"contain any vertical bar (|) or percent sign (%).\","},{"lineNumber":140,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName(typicalFieldName, maxLength,"},{"lineNumber":141,"author":{"gitId":"-"},"content":" nameStartedWithBracesButHasInvalidChar));"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" ______TS(\"failure: starts with opening curly bracket but dose not have closing bracket\");"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" String nameStartedWithCurlyBracketButHasNoEnd \u003d \"{Amy -Bén s/o O\u0027\u0026|% 2\\t\\n (~!@#$^*+_\u003d{[]\\\\:;\\\"\u003c\u003e?)\";"},{"lineNumber":146,"author":{"gitId":"-"},"content":" assertEquals(\"invalid: typical length started with non-alphanumeric character\","},{"lineNumber":147,"author":{"gitId":"-"},"content":" \"\\\"{Amy -Bén s/o O\u0027\u0026|% 2\\t\\n (~!@#$^*+_\u003d{[]\\\\:;\\\"\u003c\u003e?)\\\" is not \""},{"lineNumber":148,"author":{"gitId":"-"},"content":" + \"acceptable to TEAMMATES as a/an name field because it starts with a \""},{"lineNumber":149,"author":{"gitId":"-"},"content":" + \"non-alphanumeric character. A/An name field must start with an alphanumeric \""},{"lineNumber":150,"author":{"gitId":"-"},"content":" + \"character, and cannot contain any vertical bar (|) or percent sign (%).\","},{"lineNumber":151,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName(typicalFieldName, maxLength,"},{"lineNumber":152,"author":{"gitId":"-"},"content":" nameStartedWithCurlyBracketButHasNoEnd));"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"-"},"content":" ______TS(\"success: with opening and closing curly braces\");"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" assertEquals(\"valid: max length\","},{"lineNumber":157,"author":{"gitId":"-"},"content":" \"\","},{"lineNumber":158,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName("},{"lineNumber":159,"author":{"gitId":"-"},"content":" typicalFieldName,"},{"lineNumber":160,"author":{"gitId":"-"},"content":" maxLength,"},{"lineNumber":161,"author":{"gitId":"-"},"content":" \"{last name} first name\"));"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" ______TS(\"success: max length\");"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" assertEquals(\"valid: max length\","},{"lineNumber":166,"author":{"gitId":"-"},"content":" \"\","},{"lineNumber":167,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName("},{"lineNumber":168,"author":{"gitId":"-"},"content":" typicalFieldName,"},{"lineNumber":169,"author":{"gitId":"-"},"content":" maxLength,"},{"lineNumber":170,"author":{"gitId":"-"},"content":" StringHelperExtension.generateStringOfLength(maxLength)));"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" ______TS(\"failure: too long\");"},{"lineNumber":173,"author":{"gitId":"-"},"content":""},{"lineNumber":174,"author":{"gitId":"-"},"content":" String tooLongName \u003d StringHelperExtension.generateStringOfLength(maxLength + 1);"},{"lineNumber":175,"author":{"gitId":"-"},"content":" assertEquals(\"invalid: too long\","},{"lineNumber":176,"author":{"gitId":"-"},"content":" \"\\\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\" is not acceptable to TEAMMATES \""},{"lineNumber":177,"author":{"gitId":"-"},"content":" + \"as a/an name field because it is too long. The value of a/an name field should \""},{"lineNumber":178,"author":{"gitId":"-"},"content":" + \"be no longer than 50 characters. It should not be empty.\","},{"lineNumber":179,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName(typicalFieldName, maxLength, tooLongName));"},{"lineNumber":180,"author":{"gitId":"-"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":" ______TS(\"failure: empty string\");"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" String emptyValue \u003d \"\";"},{"lineNumber":184,"author":{"gitId":"-"},"content":" assertEquals(\"invalid: empty\","},{"lineNumber":185,"author":{"gitId":"-"},"content":" \"The field \u0027name field\u0027 is empty. The value of a/an name field should be no longer \""},{"lineNumber":186,"author":{"gitId":"-"},"content":" + \"than 50 characters. It should not be empty.\","},{"lineNumber":187,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName(typicalFieldName, maxLength, emptyValue));"},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":" ______TS(\"failure: untrimmed value\");"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" String untrimmedValue \u003d \" abc \";"},{"lineNumber":192,"author":{"gitId":"-"},"content":" assertEquals(\"invalid: untrimmed\","},{"lineNumber":193,"author":{"gitId":"-"},"content":" \"The provided name field is not acceptable to TEAMMATES as it contains only whitespace \""},{"lineNumber":194,"author":{"gitId":"-"},"content":" + \"or contains extra spaces at the beginning or at the end of the text.\","},{"lineNumber":195,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName(typicalFieldName, maxLength, untrimmedValue));"},{"lineNumber":196,"author":{"gitId":"-"},"content":" }"},{"lineNumber":197,"author":{"gitId":"-"},"content":""},{"lineNumber":198,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":199,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForPersonName_invalid_returnSpecificErrorString() {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" String invalidPersonName \u003d \"\";"},{"lineNumber":201,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getInvalidityInfoForPersonName(invalidPersonName);"},{"lineNumber":202,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid person name (empty) should return error message that is specific to person name\","},{"lineNumber":203,"author":{"gitId":"-"},"content":" \"The field \u0027person name\u0027 is empty. The value of a/an person name should be no longer \""},{"lineNumber":204,"author":{"gitId":"-"},"content":" + \"than 100 characters. It should not be empty.\","},{"lineNumber":205,"author":{"gitId":"-"},"content":" actual);"},{"lineNumber":206,"author":{"gitId":"-"},"content":" }"},{"lineNumber":207,"author":{"gitId":"-"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":209,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForInstituteName_invalid_returnSpecificErrorString() {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" String invalidInstituteName \u003d StringHelperExtension.generateStringOfLength("},{"lineNumber":211,"author":{"gitId":"-"},"content":" FieldValidator.INSTITUTE_NAME_MAX_LENGTH + 1);"},{"lineNumber":212,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getInvalidityInfoForInstituteName(invalidInstituteName);"},{"lineNumber":213,"author":{"gitId":"xenosf"},"content":" String expectedTemplate \u003d \"\\\"%s\\\" is not \""},{"lineNumber":214,"author":{"gitId":"-"},"content":" + \"acceptable to TEAMMATES as a/an institute name because it is too long. The value \""},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" + \"of a/an institute name should be no longer than 128 characters. It should not be empty.\";"},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" String expected \u003d String.format(expectedTemplate, invalidInstituteName);"},{"lineNumber":217,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid institute name (too long) should return error message that is specific to institute name\","},{"lineNumber":218,"author":{"gitId":"xenosf"},"content":" expected, actual);"},{"lineNumber":219,"author":{"gitId":"-"},"content":" }"},{"lineNumber":220,"author":{"gitId":"-"},"content":""},{"lineNumber":221,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":222,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTeamName_invalid_returnSpecificErrorString() {"},{"lineNumber":223,"author":{"gitId":"-"},"content":" String invalidTeamName \u003d \"\";"},{"lineNumber":224,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getInvalidityInfoForTeamName(invalidTeamName);"},{"lineNumber":225,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid team name (empty) should return error message that is specific to team name\","},{"lineNumber":226,"author":{"gitId":"-"},"content":" \"The field \u0027team name\u0027 is empty. The value of a/an team name should be no longer \""},{"lineNumber":227,"author":{"gitId":"-"},"content":" + \"than 60 characters. It should not be empty.\","},{"lineNumber":228,"author":{"gitId":"-"},"content":" actual);"},{"lineNumber":229,"author":{"gitId":"-"},"content":" }"},{"lineNumber":230,"author":{"gitId":"-"},"content":""},{"lineNumber":231,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":232,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForSectionName_invalid_returnSpecificErrorString() {"},{"lineNumber":233,"author":{"gitId":"-"},"content":" String invalidSectionName \u003d \"Percent Symbol % Section\";"},{"lineNumber":234,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getInvalidityInfoForSectionName(invalidSectionName);"},{"lineNumber":235,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid section name (invalid char) should return error string that is specific to section name\","},{"lineNumber":236,"author":{"gitId":"-"},"content":" \"\\\"Percent Symbol % Section\\\" is not acceptable to TEAMMATES as a/an section name \""},{"lineNumber":237,"author":{"gitId":"-"},"content":" + \"because it contains invalid characters. A/An section name must start with an \""},{"lineNumber":238,"author":{"gitId":"-"},"content":" + \"alphanumeric character, and cannot contain any vertical bar (|) or percent sign (%).\","},{"lineNumber":239,"author":{"gitId":"-"},"content":" actual);"},{"lineNumber":240,"author":{"gitId":"-"},"content":" }"},{"lineNumber":241,"author":{"gitId":"-"},"content":""},{"lineNumber":242,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":243,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForCourseName_invalid_returnSpecificErrorString() {"},{"lineNumber":244,"author":{"gitId":"-"},"content":" String invalidCourseName \u003d \"Vertical Bar | Course\";"},{"lineNumber":245,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getInvalidityInfoForCourseName(invalidCourseName);"},{"lineNumber":246,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid course name (invalid char) should return error string that is specific to course name\","},{"lineNumber":247,"author":{"gitId":"-"},"content":" \"\\\"Vertical Bar | Course\\\" is not acceptable to TEAMMATES as a/an course name because \""},{"lineNumber":248,"author":{"gitId":"-"},"content":" + \"it contains invalid characters. A/An course name must start with an alphanumeric \""},{"lineNumber":249,"author":{"gitId":"-"},"content":" + \"character, and cannot contain any vertical bar (|) or percent sign (%).\","},{"lineNumber":250,"author":{"gitId":"-"},"content":" actual);"},{"lineNumber":251,"author":{"gitId":"-"},"content":" }"},{"lineNumber":252,"author":{"gitId":"-"},"content":""},{"lineNumber":253,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":254,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForFeedbackSessionName_invalid_returnSpecificErrorString() {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" String invalidSessionName \u003d StringHelperExtension.generateStringOfLength("},{"lineNumber":256,"author":{"gitId":"-"},"content":" FieldValidator.FEEDBACK_SESSION_NAME_MAX_LENGTH + 1);"},{"lineNumber":257,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getInvalidityInfoForFeedbackSessionName(invalidSessionName);"},{"lineNumber":258,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid feedback session name (too long) should return error message specific to feedback \""},{"lineNumber":259,"author":{"gitId":"-"},"content":" + \"session name\","},{"lineNumber":260,"author":{"gitId":"-"},"content":" \"\\\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\" \""},{"lineNumber":261,"author":{"gitId":"-"},"content":" + \"is not acceptable to TEAMMATES as a/an feedback session name because it is too long. \""},{"lineNumber":262,"author":{"gitId":"-"},"content":" + \"The value of a/an feedback session name should be no longer than 64 characters. \""},{"lineNumber":263,"author":{"gitId":"-"},"content":" + \"It should not be empty.\","},{"lineNumber":264,"author":{"gitId":"-"},"content":" actual);"},{"lineNumber":265,"author":{"gitId":"-"},"content":" }"},{"lineNumber":266,"author":{"gitId":"-"},"content":""},{"lineNumber":267,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":268,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForRole_null_throwException() {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" assertThrows(AssertionError.class, () -\u003e FieldValidator.getInvalidityInfoForRole(null));"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":273,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForRole_valid_returnEmptyString() {"},{"lineNumber":274,"author":{"gitId":"-"},"content":" String validRole \u003d Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_COOWNER;"},{"lineNumber":275,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getInvalidityInfoForRole(validRole);"},{"lineNumber":276,"author":{"gitId":"-"},"content":" assertEquals(\"Valid role should return empty string\", \"\", actual);"},{"lineNumber":277,"author":{"gitId":"-"},"content":" }"},{"lineNumber":278,"author":{"gitId":"-"},"content":""},{"lineNumber":279,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":280,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForRole_invalid_returnErrorString() {"},{"lineNumber":281,"author":{"gitId":"-"},"content":" String invalidRole \u003d \"student leader\";"},{"lineNumber":282,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getInvalidityInfoForRole(invalidRole);"},{"lineNumber":283,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid role should return appropriate error string\","},{"lineNumber":284,"author":{"gitId":"-"},"content":" String.format(FieldValidator.ROLE_ERROR_MESSAGE, invalidRole),"},{"lineNumber":285,"author":{"gitId":"-"},"content":" actual);"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"-"},"content":" invalidRole \u003d \"\u003cscript\u003e alert(\u0027hi!\u0027); \u003c/script\u003e\";"},{"lineNumber":288,"author":{"gitId":"-"},"content":" actual \u003d FieldValidator.getInvalidityInfoForRole(invalidRole);"},{"lineNumber":289,"author":{"gitId":"-"},"content":" assertEquals(\"Unsanitized, invalid role should return appropriate error string\","},{"lineNumber":290,"author":{"gitId":"-"},"content":" String.format(FieldValidator.ROLE_ERROR_MESSAGE, invalidRole), actual);"},{"lineNumber":291,"author":{"gitId":"-"},"content":" }"},{"lineNumber":292,"author":{"gitId":"-"},"content":""},{"lineNumber":293,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":294,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForGoogleId_null_throwException() {"},{"lineNumber":295,"author":{"gitId":"-"},"content":" assertThrows(AssertionError.class, () -\u003e FieldValidator.getInvalidityInfoForGoogleId(null));"},{"lineNumber":296,"author":{"gitId":"-"},"content":" }"},{"lineNumber":297,"author":{"gitId":"-"},"content":""},{"lineNumber":298,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":299,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForGoogleId_valid_returnEmptyString() {"},{"lineNumber":300,"author":{"gitId":"-"},"content":" String typicalId \u003d \"valid9.Goo-gle.id_\";"},{"lineNumber":301,"author":{"gitId":"-"},"content":" assertEquals(\"Valid Google ID (typical) should return empty string\", \"\","},{"lineNumber":302,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(typicalId));"},{"lineNumber":303,"author":{"gitId":"-"},"content":""},{"lineNumber":304,"author":{"gitId":"-"},"content":" String shortId \u003d \"e\";"},{"lineNumber":305,"author":{"gitId":"-"},"content":" assertEquals(\"Valid Google ID (short) should return empty string\", \"\","},{"lineNumber":306,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(shortId));"},{"lineNumber":307,"author":{"gitId":"-"},"content":""},{"lineNumber":308,"author":{"gitId":"-"},"content":" String emailAsId \u003d \"someone@yahoo.com\";"},{"lineNumber":309,"author":{"gitId":"-"},"content":" assertEquals(\"Valid Google ID (typical email) should return empty string\", \"\","},{"lineNumber":310,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(emailAsId));"},{"lineNumber":311,"author":{"gitId":"-"},"content":""},{"lineNumber":312,"author":{"gitId":"-"},"content":" String shortEmailAsId \u003d \"e@y.c\";"},{"lineNumber":313,"author":{"gitId":"-"},"content":" assertEquals(\"Valid Google ID (short email) should return empty string\", \"\","},{"lineNumber":314,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(shortEmailAsId));"},{"lineNumber":315,"author":{"gitId":"-"},"content":""},{"lineNumber":316,"author":{"gitId":"-"},"content":" String maxLengthId \u003d StringHelperExtension.generateStringOfLength(FieldValidator.GOOGLE_ID_MAX_LENGTH);"},{"lineNumber":317,"author":{"gitId":"-"},"content":" assertEquals(\"Valid Google ID (max length) should return empty string\", \"\","},{"lineNumber":318,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(maxLengthId));"},{"lineNumber":319,"author":{"gitId":"-"},"content":" }"},{"lineNumber":320,"author":{"gitId":"-"},"content":""},{"lineNumber":321,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":322,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForGoogleId_invalid_returnErrorString() {"},{"lineNumber":323,"author":{"gitId":"-"},"content":" String emptyId \u003d \"\";"},{"lineNumber":324,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Google ID (empty) should return appropriate error message\","},{"lineNumber":325,"author":{"gitId":"-"},"content":" \"The field \u0027Google ID\u0027 is empty. A Google ID must be a valid id \""},{"lineNumber":326,"author":{"gitId":"-"},"content":" + \"already registered with Google. It cannot be longer than \""},{"lineNumber":327,"author":{"gitId":"-"},"content":" + \"254 characters, cannot be empty and cannot contain spaces.\","},{"lineNumber":328,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(emptyId));"},{"lineNumber":329,"author":{"gitId":"-"},"content":""},{"lineNumber":330,"author":{"gitId":"-"},"content":" String whitespaceId \u003d \" \";"},{"lineNumber":331,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Google ID (contains whitespaces only) should return appropriate error message\","},{"lineNumber":332,"author":{"gitId":"-"},"content":" FieldValidator.WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace("},{"lineNumber":333,"author":{"gitId":"-"},"content":" \"${fieldName}\", FieldValidator.GOOGLE_ID_FIELD_NAME),"},{"lineNumber":334,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(whitespaceId));"},{"lineNumber":335,"author":{"gitId":"-"},"content":""},{"lineNumber":336,"author":{"gitId":"-"},"content":" String untrimmedId \u003d \" googleIdWithSpacesAround \";"},{"lineNumber":337,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Google ID (leading/trailing whitespaces) should return appropriate error message\","},{"lineNumber":338,"author":{"gitId":"-"},"content":" FieldValidator.WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace("},{"lineNumber":339,"author":{"gitId":"-"},"content":" \"${fieldName}\", FieldValidator.GOOGLE_ID_FIELD_NAME),"},{"lineNumber":340,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(untrimmedId));"},{"lineNumber":341,"author":{"gitId":"-"},"content":""},{"lineNumber":342,"author":{"gitId":"-"},"content":" String tooLongId \u003d StringHelperExtension.generateStringOfLength(FieldValidator.GOOGLE_ID_MAX_LENGTH + 1);"},{"lineNumber":343,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Google ID (too long) should return appropriate error message\","},{"lineNumber":344,"author":{"gitId":"-"},"content":" \"\\\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\""},{"lineNumber":345,"author":{"gitId":"-"},"content":" + \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\""},{"lineNumber":346,"author":{"gitId":"-"},"content":" + \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\""},{"lineNumber":347,"author":{"gitId":"-"},"content":" + \"aaaaaaaa\\\" is not acceptable to TEAMMATES as a/an Google ID because it is too \""},{"lineNumber":348,"author":{"gitId":"-"},"content":" + \"long. A Google ID must be a valid id already registered with Google. It cannot \""},{"lineNumber":349,"author":{"gitId":"-"},"content":" + \"be longer than 254 characters, cannot be empty and cannot contain spaces.\","},{"lineNumber":350,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(tooLongId));"},{"lineNumber":351,"author":{"gitId":"-"},"content":""},{"lineNumber":352,"author":{"gitId":"-"},"content":" String idWithSpaces \u003d \"invalid google id with spaces\";"},{"lineNumber":353,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Google ID (with spaces) should return appropriate error message\","},{"lineNumber":354,"author":{"gitId":"-"},"content":" \"\\\"invalid google id with spaces\\\" is not acceptable to TEAMMATES as a/an Google ID \""},{"lineNumber":355,"author":{"gitId":"-"},"content":" + \"because it is not in the correct format. A Google ID must be a valid id already \""},{"lineNumber":356,"author":{"gitId":"-"},"content":" + \"registered with Google. It cannot be longer than 254 characters, cannot be empty \""},{"lineNumber":357,"author":{"gitId":"-"},"content":" + \"and cannot contain spaces.\","},{"lineNumber":358,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(idWithSpaces));"},{"lineNumber":359,"author":{"gitId":"-"},"content":""},{"lineNumber":360,"author":{"gitId":"-"},"content":" String idWithInvalidHtmlChar \u003d \"invalid google id with HTML/\u003c special characters\";"},{"lineNumber":361,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Google ID (contains HTML characters) should return appropriate error message\","},{"lineNumber":362,"author":{"gitId":"-"},"content":" \"\\\"invalid google id with HTML/\u003c special characters\\\" is not acceptable to \""},{"lineNumber":363,"author":{"gitId":"-"},"content":" + \"TEAMMATES as a/an Google ID because it is not in the correct format. A Google ID \""},{"lineNumber":364,"author":{"gitId":"-"},"content":" + \"must be a valid id already registered with Google. It cannot be longer than 254 \""},{"lineNumber":365,"author":{"gitId":"-"},"content":" + \"characters, cannot be empty and cannot contain spaces.\","},{"lineNumber":366,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(idWithInvalidHtmlChar));"},{"lineNumber":367,"author":{"gitId":"-"},"content":" }"},{"lineNumber":368,"author":{"gitId":"-"},"content":""},{"lineNumber":369,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":370,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForEmail_null_throwException() {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" assertThrows(AssertionError.class, () -\u003e FieldValidator.getInvalidityInfoForEmail(null));"},{"lineNumber":372,"author":{"gitId":"-"},"content":" }"},{"lineNumber":373,"author":{"gitId":"-"},"content":""},{"lineNumber":374,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":375,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForEmail_valid_returnEmptyString() {"},{"lineNumber":376,"author":{"gitId":"-"},"content":" String typicalEmail \u003d \"someone@yahoo.com\";"},{"lineNumber":377,"author":{"gitId":"-"},"content":" assertEquals(\"Valid email (typical) should return empty string\", \"\","},{"lineNumber":378,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(typicalEmail));"},{"lineNumber":379,"author":{"gitId":"-"},"content":""},{"lineNumber":380,"author":{"gitId":"-"},"content":" String shortEmail \u003d \"e@y.c\";"},{"lineNumber":381,"author":{"gitId":"-"},"content":" assertEquals(\"Valid email (short) should return empty string\", \"\","},{"lineNumber":382,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(shortEmail));"},{"lineNumber":383,"author":{"gitId":"-"},"content":""},{"lineNumber":384,"author":{"gitId":"-"},"content":" String maxLengthEmail \u003d StringHelperExtension.generateStringOfLength(FieldValidator.EMAIL_MAX_LENGTH - 6) + \"@c.gov\";"},{"lineNumber":385,"author":{"gitId":"-"},"content":" assertEquals(\"Valid email (max-length) should return empty string\", \"\","},{"lineNumber":386,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(maxLengthEmail));"},{"lineNumber":387,"author":{"gitId":"-"},"content":" }"},{"lineNumber":388,"author":{"gitId":"-"},"content":""},{"lineNumber":389,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":390,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForEmail_invalid_returnErrorString() {"},{"lineNumber":391,"author":{"gitId":"-"},"content":" String emptyEmail \u003d \"\";"},{"lineNumber":392,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid email (empty) should return appropriate error string\","},{"lineNumber":393,"author":{"gitId":"-"},"content":" \"The field \u0027email\u0027 is empty. An email address contains some text followed by one \""},{"lineNumber":394,"author":{"gitId":"-"},"content":" + \"\u0027@\u0027 sign followed by some more text, and should end with a top level domain address like \""},{"lineNumber":395,"author":{"gitId":"-"},"content":" + \".com. It cannot be longer than 254 characters, cannot be empty and cannot contain spaces.\","},{"lineNumber":396,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(emptyEmail));"},{"lineNumber":397,"author":{"gitId":"-"},"content":""},{"lineNumber":398,"author":{"gitId":"-"},"content":" String untrimmedEmail \u003d \" untrimmed@email.com \";"},{"lineNumber":399,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid email (leading/trailing spaces) should return appropriate error string\","},{"lineNumber":400,"author":{"gitId":"-"},"content":" FieldValidator.WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace("},{"lineNumber":401,"author":{"gitId":"-"},"content":" \"${fieldName}\", FieldValidator.EMAIL_FIELD_NAME),"},{"lineNumber":402,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(untrimmedEmail));"},{"lineNumber":403,"author":{"gitId":"-"},"content":""},{"lineNumber":404,"author":{"gitId":"-"},"content":" String whitespaceEmail \u003d \" \";"},{"lineNumber":405,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid email (only whitespaces) should return appropriate error string\","},{"lineNumber":406,"author":{"gitId":"-"},"content":" FieldValidator.WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace("},{"lineNumber":407,"author":{"gitId":"-"},"content":" \"${fieldName}\", FieldValidator.EMAIL_FIELD_NAME),"},{"lineNumber":408,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(whitespaceEmail));"},{"lineNumber":409,"author":{"gitId":"-"},"content":""},{"lineNumber":410,"author":{"gitId":"-"},"content":" String tooLongEmail \u003d StringHelperExtension.generateStringOfLength(FieldValidator.EMAIL_MAX_LENGTH + 1) + \"@c.gov\";"},{"lineNumber":411,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid email (too long) should return appropriate error string\","},{"lineNumber":412,"author":{"gitId":"-"},"content":" \"\\\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\""},{"lineNumber":413,"author":{"gitId":"-"},"content":" + \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\""},{"lineNumber":414,"author":{"gitId":"-"},"content":" + \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\""},{"lineNumber":415,"author":{"gitId":"-"},"content":" + \"aaaaaaaa@c.gov\\\" is not acceptable to TEAMMATES as a/an email because it is too \""},{"lineNumber":416,"author":{"gitId":"-"},"content":" + \"long. An email address contains some text followed by one \u0027@\u0027 sign followed by \""},{"lineNumber":417,"author":{"gitId":"-"},"content":" + \"some more text, and should end with a top level domain address like .com. \""},{"lineNumber":418,"author":{"gitId":"-"},"content":" + \"It cannot be longer than 254 characters, cannot be empty and \""},{"lineNumber":419,"author":{"gitId":"-"},"content":" + \"cannot contain spaces.\","},{"lineNumber":420,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(tooLongEmail));"},{"lineNumber":421,"author":{"gitId":"-"},"content":""},{"lineNumber":422,"author":{"gitId":"-"},"content":" String emailWithSpaceAfterAtSymbol \u003d \"woMAN@com. sg\";"},{"lineNumber":423,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid email (space character after \u0027@\u0027) should return appropriate error string\","},{"lineNumber":424,"author":{"gitId":"-"},"content":" \"\\\"woMAN@com. sg\\\" is not acceptable to TEAMMATES as a/an email because it is not in \""},{"lineNumber":425,"author":{"gitId":"-"},"content":" + \"the correct format. An email address contains some text followed by one \u0027@\u0027 sign \""},{"lineNumber":426,"author":{"gitId":"-"},"content":" + \"followed by some more text, and should end with a top level domain address like .com. \""},{"lineNumber":427,"author":{"gitId":"-"},"content":" + \"It cannot be longer than 254 characters, cannot be \""},{"lineNumber":428,"author":{"gitId":"-"},"content":" + \"empty and cannot contain spaces.\","},{"lineNumber":429,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(emailWithSpaceAfterAtSymbol));"},{"lineNumber":430,"author":{"gitId":"-"},"content":""},{"lineNumber":431,"author":{"gitId":"-"},"content":" String emailWithSpaceBeforeAtSymbol \u003d \"man woman@com.sg\";"},{"lineNumber":432,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid email (space character before \u0027@\u0027) should return appropriate error string\","},{"lineNumber":433,"author":{"gitId":"-"},"content":" \"\\\"man woman@com.sg\\\" is not acceptable to TEAMMATES as a/an email because it \""},{"lineNumber":434,"author":{"gitId":"-"},"content":" + \"is not in the correct format. An email address contains some text followed by \""},{"lineNumber":435,"author":{"gitId":"-"},"content":" + \"one \u0027@\u0027 sign followed by some more text, and should end with a top level domain address \""},{"lineNumber":436,"author":{"gitId":"-"},"content":" + \"like .com. It cannot be longer than 254 \""},{"lineNumber":437,"author":{"gitId":"-"},"content":" + \"characters, cannot be empty and cannot contain spaces.\","},{"lineNumber":438,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(emailWithSpaceBeforeAtSymbol));"},{"lineNumber":439,"author":{"gitId":"-"},"content":""},{"lineNumber":440,"author":{"gitId":"-"},"content":" String emailWithMultipleAtSymbol \u003d \"man@woman@com.lk\";"},{"lineNumber":441,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid email (multiple \u0027@\u0027 characters) should return appropriate error string\","},{"lineNumber":442,"author":{"gitId":"-"},"content":" \"\\\"man@woman@com.lk\\\" is not acceptable to TEAMMATES as a/an email because it is not \""},{"lineNumber":443,"author":{"gitId":"-"},"content":" + \"in the correct format. An email address contains some text followed by one \u0027@\u0027 \""},{"lineNumber":444,"author":{"gitId":"-"},"content":" + \"sign followed by some more text, and should end with a top level domain address like .com. \""},{"lineNumber":445,"author":{"gitId":"-"},"content":" + \"It cannot be longer than 254 characters, \""},{"lineNumber":446,"author":{"gitId":"-"},"content":" + \"cannot be empty and cannot contain spaces.\","},{"lineNumber":447,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(emailWithMultipleAtSymbol));"},{"lineNumber":448,"author":{"gitId":"-"},"content":" }"},{"lineNumber":449,"author":{"gitId":"-"},"content":""},{"lineNumber":450,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":451,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForCourseId_null_throwException() {"},{"lineNumber":452,"author":{"gitId":"-"},"content":" assertThrows(AssertionError.class, () -\u003e FieldValidator.getInvalidityInfoForCourseId(null));"},{"lineNumber":453,"author":{"gitId":"-"},"content":" }"},{"lineNumber":454,"author":{"gitId":"-"},"content":""},{"lineNumber":455,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":456,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForCourseId_valid_returnEmptyString() {"},{"lineNumber":457,"author":{"gitId":"-"},"content":" String typicalCourseId \u003d \"cs1101-sem1.2_\";"},{"lineNumber":458,"author":{"gitId":"-"},"content":" assertEquals(\"Valid Course ID (typical) should return empty string\", \"\","},{"lineNumber":459,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForCourseId(typicalCourseId));"},{"lineNumber":460,"author":{"gitId":"-"},"content":""},{"lineNumber":461,"author":{"gitId":"-"},"content":" String shortCourseId \u003d \"c\";"},{"lineNumber":462,"author":{"gitId":"-"},"content":" assertEquals(\"Valid Course ID (short) should return empty string\", \"\","},{"lineNumber":463,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForCourseId(shortCourseId));"},{"lineNumber":464,"author":{"gitId":"-"},"content":""},{"lineNumber":465,"author":{"gitId":"-"},"content":" String maxLengthCourseId \u003d StringHelperExtension.generateStringOfLength("},{"lineNumber":466,"author":{"gitId":"-"},"content":" FieldValidator.COURSE_ID_MAX_LENGTH);"},{"lineNumber":467,"author":{"gitId":"-"},"content":" assertEquals(\"Valid Course ID (max length) should return empty string\", \"\","},{"lineNumber":468,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForCourseId(maxLengthCourseId));"},{"lineNumber":469,"author":{"gitId":"-"},"content":" }"},{"lineNumber":470,"author":{"gitId":"-"},"content":""},{"lineNumber":471,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":472,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForCourseId_invalid_returnErrorString() {"},{"lineNumber":473,"author":{"gitId":"-"},"content":" String emptyCourseId \u003d \"\";"},{"lineNumber":474,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Course ID (empty) should return appropriate error string\","},{"lineNumber":475,"author":{"gitId":"-"},"content":" \"The field \u0027course ID\u0027 is empty. A course ID can contain letters, numbers, \""},{"lineNumber":476,"author":{"gitId":"-"},"content":" + \"fullstops, hyphens, underscores, and dollar signs. It cannot be \""},{"lineNumber":477,"author":{"gitId":"-"},"content":" + \"longer than 64 characters, cannot be empty and cannot contain spaces.\","},{"lineNumber":478,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForCourseId(emptyCourseId));"},{"lineNumber":479,"author":{"gitId":"-"},"content":""},{"lineNumber":480,"author":{"gitId":"-"},"content":" String untrimmedCourseId \u003d \" $cs1101-sem1.2_ \";"},{"lineNumber":481,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Course ID (untrimmed) should return appropriate error string\","},{"lineNumber":482,"author":{"gitId":"-"},"content":" FieldValidator.WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace("},{"lineNumber":483,"author":{"gitId":"-"},"content":" \"${fieldName}\", FieldValidator.COURSE_ID_FIELD_NAME),"},{"lineNumber":484,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForCourseId(untrimmedCourseId));"},{"lineNumber":485,"author":{"gitId":"-"},"content":""},{"lineNumber":486,"author":{"gitId":"-"},"content":" String whitespaceOnlyCourseId \u003d \" \";"},{"lineNumber":487,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Course ID (whitespace only) should return appropriate error string\","},{"lineNumber":488,"author":{"gitId":"-"},"content":" FieldValidator.WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace("},{"lineNumber":489,"author":{"gitId":"-"},"content":" \"${fieldName}\", FieldValidator.COURSE_ID_FIELD_NAME),"},{"lineNumber":490,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForCourseId(whitespaceOnlyCourseId));"},{"lineNumber":491,"author":{"gitId":"-"},"content":""},{"lineNumber":492,"author":{"gitId":"-"},"content":" String tooLongCourseId \u003d StringHelperExtension.generateStringOfLength("},{"lineNumber":493,"author":{"gitId":"-"},"content":" FieldValidator.COURSE_ID_MAX_LENGTH + 1);"},{"lineNumber":494,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Course ID (too long) should return appropriate error string\","},{"lineNumber":495,"author":{"gitId":"-"},"content":" \"\\\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\" \""},{"lineNumber":496,"author":{"gitId":"-"},"content":" + \"is not acceptable to TEAMMATES as a/an course ID because it is too long. \""},{"lineNumber":497,"author":{"gitId":"-"},"content":" + \"A course ID can contain letters, numbers, fullstops, hyphens, underscores, \""},{"lineNumber":498,"author":{"gitId":"-"},"content":" + \"and dollar signs. It cannot be longer than 64 characters, \""},{"lineNumber":499,"author":{"gitId":"-"},"content":" + \"cannot be empty and cannot contain spaces.\","},{"lineNumber":500,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForCourseId(tooLongCourseId));"},{"lineNumber":501,"author":{"gitId":"-"},"content":""},{"lineNumber":502,"author":{"gitId":"-"},"content":" String courseIdWithSpaces \u003d \"my course id with spaces\";"},{"lineNumber":503,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Course ID (contains spaces) should return appropriate error string\","},{"lineNumber":504,"author":{"gitId":"-"},"content":" \"\\\"my course id with spaces\\\" is not acceptable to TEAMMATES as a/an course ID because \""},{"lineNumber":505,"author":{"gitId":"-"},"content":" + \"it is not in the correct format. A course ID can contain letters, numbers, \""},{"lineNumber":506,"author":{"gitId":"-"},"content":" + \"fullstops, hyphens, underscores, and dollar signs. It cannot be longer than 64 \""},{"lineNumber":507,"author":{"gitId":"-"},"content":" + \"characters, cannot be empty and cannot contain spaces.\","},{"lineNumber":508,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForCourseId(courseIdWithSpaces));"},{"lineNumber":509,"author":{"gitId":"-"},"content":""},{"lineNumber":510,"author":{"gitId":"-"},"content":" String courseIdWithInvalidChar \u003d \"cour@s*hy#\";"},{"lineNumber":511,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Course ID (invalid char) should return appropriate error string\","},{"lineNumber":512,"author":{"gitId":"-"},"content":" \"\\\"cour@s*hy#\\\" is not acceptable to TEAMMATES as a/an course ID because it is not in \""},{"lineNumber":513,"author":{"gitId":"-"},"content":" + \"the correct format. A course ID can contain letters, numbers, fullstops, \""},{"lineNumber":514,"author":{"gitId":"-"},"content":" + \"hyphens, underscores, and dollar signs. It cannot be longer than 64 characters, \""},{"lineNumber":515,"author":{"gitId":"-"},"content":" + \"cannot be empty and cannot contain spaces.\","},{"lineNumber":516,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForCourseId(courseIdWithInvalidChar));"},{"lineNumber":517,"author":{"gitId":"-"},"content":" }"},{"lineNumber":518,"author":{"gitId":"-"},"content":""},{"lineNumber":519,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":520,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNewStartTime_valid_returnEmptyString() {"},{"lineNumber":521,"author":{"gitId":"-"},"content":" Instant earliestSessionStart \u003d TimeHelperExtension"},{"lineNumber":522,"author":{"gitId":"-"},"content":" .getInstantHoursOffsetFromNow(-1)"},{"lineNumber":523,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS);"},{"lineNumber":524,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForNewStartTime(earliestSessionStart, Const.DEFAULT_TIME_ZONE));"},{"lineNumber":525,"author":{"gitId":"-"},"content":""},{"lineNumber":526,"author":{"gitId":"-"},"content":" Instant latestSessionStart \u003d TimeHelperExtension"},{"lineNumber":527,"author":{"gitId":"-"},"content":" .getInstantDaysOffsetFromNow(90)"},{"lineNumber":528,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS);"},{"lineNumber":529,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForNewStartTime(latestSessionStart, Const.DEFAULT_TIME_ZONE));"},{"lineNumber":530,"author":{"gitId":"-"},"content":" }"},{"lineNumber":531,"author":{"gitId":"-"},"content":""},{"lineNumber":532,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":533,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNewStartTime_invalid_returnErrorString() {"},{"lineNumber":534,"author":{"gitId":"-"},"content":" Instant threeHoursBeforeNowRounded \u003d TimeHelperExtension"},{"lineNumber":535,"author":{"gitId":"-"},"content":" .getInstantHoursOffsetFromNow(-3)"},{"lineNumber":536,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS);"},{"lineNumber":537,"author":{"gitId":"-"},"content":" assertEquals(\"The start time for this feedback session cannot be earlier than 2 hours before now.\","},{"lineNumber":538,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNewStartTime(threeHoursBeforeNowRounded, Const.DEFAULT_TIME_ZONE));"},{"lineNumber":539,"author":{"gitId":"-"},"content":""},{"lineNumber":540,"author":{"gitId":"-"},"content":" Instant thirteenMonthsFromNow \u003d TimeHelperExtension"},{"lineNumber":541,"author":{"gitId":"-"},"content":" .getInstantMonthsOffsetFromNow(13, Const.DEFAULT_TIME_ZONE)"},{"lineNumber":542,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS);"},{"lineNumber":543,"author":{"gitId":"-"},"content":" assertEquals(\"The start time for this feedback session cannot be later than 12 months from now.\","},{"lineNumber":544,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNewStartTime(thirteenMonthsFromNow, Const.DEFAULT_TIME_ZONE));"},{"lineNumber":545,"author":{"gitId":"-"},"content":""},{"lineNumber":546,"author":{"gitId":"-"},"content":" Instant notAtHourMark \u003d TimeHelperExtension"},{"lineNumber":547,"author":{"gitId":"-"},"content":" .getInstantHoursOffsetFromNow(1)"},{"lineNumber":548,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS)"},{"lineNumber":549,"author":{"gitId":"-"},"content":" .plus(Duration.ofMinutes(30));"},{"lineNumber":550,"author":{"gitId":"-"},"content":" assertEquals(\"The start time for this feedback session must be at exact hour mark.\","},{"lineNumber":551,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNewStartTime(notAtHourMark, Const.DEFAULT_TIME_ZONE));"},{"lineNumber":552,"author":{"gitId":"-"},"content":" }"},{"lineNumber":553,"author":{"gitId":"-"},"content":""},{"lineNumber":554,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":555,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNewEndTime_valid_returnEmptyString() {"},{"lineNumber":556,"author":{"gitId":"-"},"content":" Instant earliestSessionEnd \u003d TimeHelperExtension"},{"lineNumber":557,"author":{"gitId":"-"},"content":" .getInstantHoursOffsetFromNow(0)"},{"lineNumber":558,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS);"},{"lineNumber":559,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForNewEndTime(earliestSessionEnd, Const.DEFAULT_TIME_ZONE));"},{"lineNumber":560,"author":{"gitId":"-"},"content":""},{"lineNumber":561,"author":{"gitId":"-"},"content":" Instant latestSessionEnd \u003d TimeHelperExtension"},{"lineNumber":562,"author":{"gitId":"-"},"content":" .getInstantDaysOffsetFromNow(180)"},{"lineNumber":563,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS);"},{"lineNumber":564,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForNewEndTime(latestSessionEnd, Const.DEFAULT_TIME_ZONE));"},{"lineNumber":565,"author":{"gitId":"-"},"content":" }"},{"lineNumber":566,"author":{"gitId":"-"},"content":""},{"lineNumber":567,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":568,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNewEndTime_invalid_returnErrorString() {"},{"lineNumber":569,"author":{"gitId":"-"},"content":" Instant twoHoursBeforeNowRounded \u003d TimeHelperExtension"},{"lineNumber":570,"author":{"gitId":"-"},"content":" .getInstantHoursOffsetFromNow(-2)"},{"lineNumber":571,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS);"},{"lineNumber":572,"author":{"gitId":"-"},"content":" assertEquals(\"The end time for this feedback session cannot be earlier than 1 hour before now.\","},{"lineNumber":573,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNewEndTime(twoHoursBeforeNowRounded, Const.DEFAULT_TIME_ZONE));"},{"lineNumber":574,"author":{"gitId":"-"},"content":""},{"lineNumber":575,"author":{"gitId":"-"},"content":" Instant thirteenMonthsFromNow \u003d TimeHelperExtension"},{"lineNumber":576,"author":{"gitId":"-"},"content":" .getInstantMonthsOffsetFromNow(13, Const.DEFAULT_TIME_ZONE)"},{"lineNumber":577,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS);"},{"lineNumber":578,"author":{"gitId":"-"},"content":" assertEquals(\"The end time for this feedback session cannot be later than 12 months from now.\","},{"lineNumber":579,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNewEndTime(thirteenMonthsFromNow,"},{"lineNumber":580,"author":{"gitId":"-"},"content":" Const.DEFAULT_TIME_ZONE));"},{"lineNumber":581,"author":{"gitId":"-"},"content":""},{"lineNumber":582,"author":{"gitId":"-"},"content":" Instant notAtHourMark \u003d TimeHelperExtension"},{"lineNumber":583,"author":{"gitId":"-"},"content":" .getInstantHoursOffsetFromNow(1)"},{"lineNumber":584,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS)"},{"lineNumber":585,"author":{"gitId":"-"},"content":" .plus(Duration.ofMinutes(30));"},{"lineNumber":586,"author":{"gitId":"-"},"content":" assertEquals(\"The end time for this feedback session must be at exact hour mark.\","},{"lineNumber":587,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNewEndTime(notAtHourMark, Const.DEFAULT_TIME_ZONE));"},{"lineNumber":588,"author":{"gitId":"-"},"content":" }"},{"lineNumber":589,"author":{"gitId":"-"},"content":""},{"lineNumber":590,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":591,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForSessionStartAndEnd_valid_returnEmptyString() {"},{"lineNumber":592,"author":{"gitId":"-"},"content":" Instant sessionStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":593,"author":{"gitId":"-"},"content":" Instant sessionEnd \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(1);"},{"lineNumber":594,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForTimeForSessionStartAndEnd(sessionStart, sessionEnd));"},{"lineNumber":595,"author":{"gitId":"-"},"content":" }"},{"lineNumber":596,"author":{"gitId":"-"},"content":""},{"lineNumber":597,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":598,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForSessionStartAndEnd_invalid_returnErrorString() {"},{"lineNumber":599,"author":{"gitId":"-"},"content":" Instant sessionStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(1);"},{"lineNumber":600,"author":{"gitId":"-"},"content":" Instant sessionEnd \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":601,"author":{"gitId":"-"},"content":" assertEquals(\"The end time for this feedback session cannot be earlier than the start time.\","},{"lineNumber":602,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForSessionStartAndEnd(sessionStart, sessionEnd));"},{"lineNumber":603,"author":{"gitId":"-"},"content":" }"},{"lineNumber":604,"author":{"gitId":"-"},"content":""},{"lineNumber":605,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":606,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForVisibilityStartAndSessionStart_valid_returnEmptyString() {"},{"lineNumber":607,"author":{"gitId":"-"},"content":" Instant visibilityStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":608,"author":{"gitId":"-"},"content":" Instant sessionStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(1);"},{"lineNumber":609,"author":{"gitId":"-"},"content":" assertEquals(\"\","},{"lineNumber":610,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForVisibilityStartAndSessionStart("},{"lineNumber":611,"author":{"gitId":"-"},"content":" visibilityStart, sessionStart));"},{"lineNumber":612,"author":{"gitId":"-"},"content":" }"},{"lineNumber":613,"author":{"gitId":"-"},"content":""},{"lineNumber":614,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":615,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForVisibilityStartAndSessionStart_invalid_returnErrorString() {"},{"lineNumber":616,"author":{"gitId":"-"},"content":" Instant visibilityStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(1);"},{"lineNumber":617,"author":{"gitId":"-"},"content":" Instant sessionStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":618,"author":{"gitId":"-"},"content":" assertEquals(\"The start time for this feedback session cannot be earlier than the time when the \""},{"lineNumber":619,"author":{"gitId":"-"},"content":" + \"session will be visible.\","},{"lineNumber":620,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForVisibilityStartAndSessionStart("},{"lineNumber":621,"author":{"gitId":"-"},"content":" visibilityStart, sessionStart));"},{"lineNumber":622,"author":{"gitId":"-"},"content":" }"},{"lineNumber":623,"author":{"gitId":"-"},"content":""},{"lineNumber":624,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":625,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForNewVisibilityStart_valid_returnEmptyString() {"},{"lineNumber":626,"author":{"gitId":"-"},"content":" Instant sessionStart \u003d TimeHelperExtension.getInstantDaysOffsetFromNow(1);"},{"lineNumber":627,"author":{"gitId":"-"},"content":" Instant visibilityStart \u003d sessionStart.plus(Duration.ofDays(29));"},{"lineNumber":628,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForTimeForNewVisibilityStart("},{"lineNumber":629,"author":{"gitId":"-"},"content":" visibilityStart, sessionStart));"},{"lineNumber":630,"author":{"gitId":"-"},"content":" }"},{"lineNumber":631,"author":{"gitId":"-"},"content":""},{"lineNumber":632,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":633,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForNewVisibilityStart_invalid_returnErrorString() {"},{"lineNumber":634,"author":{"gitId":"-"},"content":" Instant sessionStart \u003d TimeHelperExtension.getInstantDaysOffsetFromNow(1);"},{"lineNumber":635,"author":{"gitId":"-"},"content":" Instant thirtyOneDaysBeforeSessionStart \u003d TimeHelperExtension.getInstantDaysOffsetFromNow(-31);"},{"lineNumber":636,"author":{"gitId":"-"},"content":" assertEquals(\"The time when the session will be visible for this feedback session cannot be \""},{"lineNumber":637,"author":{"gitId":"-"},"content":" + \"earlier than 30 days before start time.\","},{"lineNumber":638,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForNewVisibilityStart("},{"lineNumber":639,"author":{"gitId":"-"},"content":" thirtyOneDaysBeforeSessionStart, sessionStart));"},{"lineNumber":640,"author":{"gitId":"-"},"content":" }"},{"lineNumber":641,"author":{"gitId":"-"},"content":""},{"lineNumber":642,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":643,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForVisibilityStartAndResultsPublish_valid_returnEmptyString() {"},{"lineNumber":644,"author":{"gitId":"-"},"content":" Instant visibilityStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":645,"author":{"gitId":"-"},"content":" Instant resultsPublish \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(1);"},{"lineNumber":646,"author":{"gitId":"-"},"content":" assertEquals(\"\","},{"lineNumber":647,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForVisibilityStartAndResultsPublish("},{"lineNumber":648,"author":{"gitId":"-"},"content":" visibilityStart, resultsPublish));"},{"lineNumber":649,"author":{"gitId":"-"},"content":" }"},{"lineNumber":650,"author":{"gitId":"-"},"content":""},{"lineNumber":651,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":652,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForVisibilityStartAndResultsPublish_invalid_returnErrorString() {"},{"lineNumber":653,"author":{"gitId":"-"},"content":" Instant visibilityStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(1);"},{"lineNumber":654,"author":{"gitId":"-"},"content":" Instant resultsPublish \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":655,"author":{"gitId":"-"},"content":" assertEquals(\"The time when the results will be visible for this feedback session cannot be \""},{"lineNumber":656,"author":{"gitId":"-"},"content":" + \"earlier than the time when the session will be visible.\","},{"lineNumber":657,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForVisibilityStartAndResultsPublish("},{"lineNumber":658,"author":{"gitId":"-"},"content":" visibilityStart, resultsPublish));"},{"lineNumber":659,"author":{"gitId":"-"},"content":" }"},{"lineNumber":660,"author":{"gitId":"-"},"content":""},{"lineNumber":661,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":662,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForSessionEndAndExtendedDeadlines_valid_returnEmptyString() {"},{"lineNumber":663,"author":{"gitId":"-"},"content":" Instant sessionEnd \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":664,"author":{"gitId":"-"},"content":" Map\u003cString, Instant\u003e extendedDeadlines \u003d new HashMap\u003c\u003e();"},{"lineNumber":665,"author":{"gitId":"-"},"content":" extendedDeadlines.put(\"participant@email.com\", TimeHelperExtension.getInstantHoursOffsetFromNow(1));"},{"lineNumber":666,"author":{"gitId":"-"},"content":" assertEquals(\"\","},{"lineNumber":667,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForSessionEndAndExtendedDeadlines("},{"lineNumber":668,"author":{"gitId":"-"},"content":" sessionEnd, extendedDeadlines));"},{"lineNumber":669,"author":{"gitId":"-"},"content":" }"},{"lineNumber":670,"author":{"gitId":"-"},"content":""},{"lineNumber":671,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":672,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForSessionEndAndExtendedDeadlines_invalid_returnErrorString() {"},{"lineNumber":673,"author":{"gitId":"-"},"content":" ______TS(\"extended deadline earlier than the end time\");"},{"lineNumber":674,"author":{"gitId":"-"},"content":" Instant sessionEnd \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(1);"},{"lineNumber":675,"author":{"gitId":"-"},"content":" Map\u003cString, Instant\u003e extendedDeadlines \u003d new HashMap\u003c\u003e();"},{"lineNumber":676,"author":{"gitId":"-"},"content":" extendedDeadlines.put(\"participant@email.com\", TimeHelperExtension.getInstantHoursOffsetFromNow(-1));"},{"lineNumber":677,"author":{"gitId":"-"},"content":" assertEquals(\"The extended deadlines for this feedback session cannot be earlier than or at the same time as \""},{"lineNumber":678,"author":{"gitId":"-"},"content":" + \"the end time.\","},{"lineNumber":679,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForSessionEndAndExtendedDeadlines("},{"lineNumber":680,"author":{"gitId":"-"},"content":" sessionEnd, extendedDeadlines));"},{"lineNumber":681,"author":{"gitId":"-"},"content":""},{"lineNumber":682,"author":{"gitId":"-"},"content":" ______TS(\"extended deadline at the same time as the end time\");"},{"lineNumber":683,"author":{"gitId":"-"},"content":" extendedDeadlines.put(\"participant@email.com\", sessionEnd);"},{"lineNumber":684,"author":{"gitId":"-"},"content":" assertEquals(\"The extended deadlines for this feedback session cannot be earlier than or at the same time as \""},{"lineNumber":685,"author":{"gitId":"-"},"content":" + \"the end time.\","},{"lineNumber":686,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForSessionEndAndExtendedDeadlines("},{"lineNumber":687,"author":{"gitId":"-"},"content":" sessionEnd, extendedDeadlines));"},{"lineNumber":688,"author":{"gitId":"-"},"content":" }"},{"lineNumber":689,"author":{"gitId":"-"},"content":""},{"lineNumber":690,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":691,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForNotificationStartAndEnd_valid_returnEmptyString() {"},{"lineNumber":692,"author":{"gitId":"-"},"content":" Instant notificationStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":693,"author":{"gitId":"-"},"content":" Instant notificationEnd \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(1);"},{"lineNumber":694,"author":{"gitId":"-"},"content":""},{"lineNumber":695,"author":{"gitId":"-"},"content":" assertEquals(\"\","},{"lineNumber":696,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForNotificationStartAndEnd("},{"lineNumber":697,"author":{"gitId":"-"},"content":" notificationStart, notificationEnd));"},{"lineNumber":698,"author":{"gitId":"-"},"content":" }"},{"lineNumber":699,"author":{"gitId":"-"},"content":""},{"lineNumber":700,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":701,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForNotificationStartAndEnd_inValid_returnErrorString() {"},{"lineNumber":702,"author":{"gitId":"-"},"content":" Instant notificationStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(1);"},{"lineNumber":703,"author":{"gitId":"-"},"content":" Instant notificationEnd \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":704,"author":{"gitId":"-"},"content":""},{"lineNumber":705,"author":{"gitId":"-"},"content":" assertEquals(\"The time when the notification will expire for this notification cannot be earlier \""},{"lineNumber":706,"author":{"gitId":"-"},"content":" + \"than the time when the notification will be visible.\","},{"lineNumber":707,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForNotificationStartAndEnd("},{"lineNumber":708,"author":{"gitId":"-"},"content":" notificationStart, notificationEnd));"},{"lineNumber":709,"author":{"gitId":"-"},"content":" }"},{"lineNumber":710,"author":{"gitId":"-"},"content":""},{"lineNumber":711,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":712,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNotificationTitle_valid_returnEmptyString() {"},{"lineNumber":713,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForNotificationTitle(\"valid title\"));"},{"lineNumber":714,"author":{"gitId":"-"},"content":" }"},{"lineNumber":715,"author":{"gitId":"-"},"content":""},{"lineNumber":716,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":717,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNotificationTitle_inValid_returnErrorString() {"},{"lineNumber":718,"author":{"gitId":"-"},"content":" ______TS(\"Empty notification title\");"},{"lineNumber":719,"author":{"gitId":"-"},"content":" assertEquals(\"The field \u0027notification title\u0027 is empty.\","},{"lineNumber":720,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNotificationTitle(\"\"));"},{"lineNumber":721,"author":{"gitId":"-"},"content":""},{"lineNumber":722,"author":{"gitId":"-"},"content":" ______TS(\"Notification title exceeds maximum length\");"},{"lineNumber":723,"author":{"gitId":"-"},"content":" String invalidNotificationTitle \u003d StringHelperExtension.generateStringOfLength("},{"lineNumber":724,"author":{"gitId":"-"},"content":" FieldValidator.NOTIFICATION_TITLE_MAX_LENGTH + 1);"},{"lineNumber":725,"author":{"gitId":"-"},"content":" assertEquals(\"\\\"\" + invalidNotificationTitle + \"\\\" is not acceptable to TEAMMATES as a/an \""},{"lineNumber":726,"author":{"gitId":"-"},"content":" + \"notification title because it is too long. \""},{"lineNumber":727,"author":{"gitId":"-"},"content":" + \"The value of a/an notification title should be no longer than \""},{"lineNumber":728,"author":{"gitId":"-"},"content":" + FieldValidator.NOTIFICATION_TITLE_MAX_LENGTH"},{"lineNumber":729,"author":{"gitId":"-"},"content":" + \" characters. It should not be empty.\","},{"lineNumber":730,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNotificationTitle(invalidNotificationTitle));"},{"lineNumber":731,"author":{"gitId":"-"},"content":" }"},{"lineNumber":732,"author":{"gitId":"-"},"content":""},{"lineNumber":733,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":734,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNotificationBody_valid_returnEmptyString() {"},{"lineNumber":735,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForNotificationBody(\"valid body\"));"},{"lineNumber":736,"author":{"gitId":"-"},"content":" }"},{"lineNumber":737,"author":{"gitId":"-"},"content":""},{"lineNumber":738,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":739,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNotificationBody_inValid_returnErrorString() {"},{"lineNumber":740,"author":{"gitId":"-"},"content":" assertEquals(\"The field \u0027notification message\u0027 is empty.\","},{"lineNumber":741,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNotificationBody(\"\"));"},{"lineNumber":742,"author":{"gitId":"-"},"content":" }"},{"lineNumber":743,"author":{"gitId":"-"},"content":""},{"lineNumber":744,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":745,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNotificationStyle_valid_returnEmptyString() {"},{"lineNumber":746,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForNotificationStyle(\"SUCCESS\"));"},{"lineNumber":747,"author":{"gitId":"-"},"content":" }"},{"lineNumber":748,"author":{"gitId":"-"},"content":""},{"lineNumber":749,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":750,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNotificationStyle_inValid_returnErrorString() {"},{"lineNumber":751,"author":{"gitId":"-"},"content":" String invalidStyle \u003d \"invalid style\";"},{"lineNumber":752,"author":{"gitId":"-"},"content":" assertEquals(\"\\\"\" + invalidStyle + \"\\\" is not an accepted notification style to TEAMMATES. \","},{"lineNumber":753,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNotificationStyle(invalidStyle));"},{"lineNumber":754,"author":{"gitId":"-"},"content":" }"},{"lineNumber":755,"author":{"gitId":"-"},"content":""},{"lineNumber":756,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":757,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNotificationTargetUser_valid_returnEmptyString() {"},{"lineNumber":758,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForNotificationTargetUser(\"GENERAL\"));"},{"lineNumber":759,"author":{"gitId":"-"},"content":" }"},{"lineNumber":760,"author":{"gitId":"-"},"content":""},{"lineNumber":761,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":762,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNotificationTargetUser_inValid_returnErrorString() {"},{"lineNumber":763,"author":{"gitId":"-"},"content":" String invalidUser \u003d \"invalid user\";"},{"lineNumber":764,"author":{"gitId":"-"},"content":" assertEquals(\"\\\"\" + invalidUser + \"\\\" is not an accepted notification target user to TEAMMATES. \","},{"lineNumber":765,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNotificationTargetUser(invalidUser));"},{"lineNumber":766,"author":{"gitId":"-"},"content":" }"},{"lineNumber":767,"author":{"gitId":"-"},"content":""},{"lineNumber":768,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":769,"author":{"gitId":"-"},"content":" public void testRegexName() {"},{"lineNumber":770,"author":{"gitId":"-"},"content":" ______TS(\"success: typical name\");"},{"lineNumber":771,"author":{"gitId":"-"},"content":" String name \u003d \"Benny Charlés\";"},{"lineNumber":772,"author":{"gitId":"-"},"content":" assertTrue(StringHelper.isMatching(name, FieldValidator.REGEX_NAME));"},{"lineNumber":773,"author":{"gitId":"-"},"content":""},{"lineNumber":774,"author":{"gitId":"-"},"content":" ______TS(\"success: name begins with accented characters\");"},{"lineNumber":775,"author":{"gitId":"-"},"content":" name \u003d \"Ýàn-B. s/o O\u0027br, \u00262(~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\";"},{"lineNumber":776,"author":{"gitId":"-"},"content":" assertTrue(StringHelper.isMatching(name, FieldValidator.REGEX_NAME));"},{"lineNumber":777,"author":{"gitId":"-"},"content":""},{"lineNumber":778,"author":{"gitId":"-"},"content":" ______TS(\"failure: name begins with non-alphanumeric character\");"},{"lineNumber":779,"author":{"gitId":"-"},"content":" name \u003d \"~Amy-Ben. s/o O\u0027br, \u00262(~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\";"},{"lineNumber":780,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(name, FieldValidator.REGEX_NAME));"},{"lineNumber":781,"author":{"gitId":"-"},"content":""},{"lineNumber":782,"author":{"gitId":"-"},"content":" ______TS(\"failure: name contains invalid character\");"},{"lineNumber":783,"author":{"gitId":"-"},"content":" name \u003d \"Amy-B. s/o O\u0027br, %|\u00262(~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\";"},{"lineNumber":784,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(name, FieldValidator.REGEX_NAME));"},{"lineNumber":785,"author":{"gitId":"-"},"content":" }"},{"lineNumber":786,"author":{"gitId":"-"},"content":""},{"lineNumber":787,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":788,"author":{"gitId":"-"},"content":" public void testRegexEmail() {"},{"lineNumber":789,"author":{"gitId":"-"},"content":" ______TS(\"success: typical email\");"},{"lineNumber":790,"author":{"gitId":"-"},"content":" String email \u003d \"john@email.com\";"},{"lineNumber":791,"author":{"gitId":"-"},"content":" assertTrue(StringHelper.isMatching(email, FieldValidator.REGEX_EMAIL));"},{"lineNumber":792,"author":{"gitId":"-"},"content":""},{"lineNumber":793,"author":{"gitId":"-"},"content":" ______TS(\"failure: no top level domain\");"},{"lineNumber":794,"author":{"gitId":"-"},"content":" email \u003d \"a@e\";"},{"lineNumber":795,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(email, FieldValidator.REGEX_EMAIL));"},{"lineNumber":796,"author":{"gitId":"-"},"content":""},{"lineNumber":797,"author":{"gitId":"-"},"content":" ______TS(\"success: minimum allowed email format\");"},{"lineNumber":798,"author":{"gitId":"-"},"content":" email \u003d \"a@e.c\";"},{"lineNumber":799,"author":{"gitId":"-"},"content":" assertTrue(StringHelper.isMatching(email, FieldValidator.REGEX_EMAIL));"},{"lineNumber":800,"author":{"gitId":"-"},"content":""},{"lineNumber":801,"author":{"gitId":"-"},"content":" ______TS(\"success: all allowed special characters\");"},{"lineNumber":802,"author":{"gitId":"-"},"content":" email \u003d \"a!#$%\u0026\u0027*/\u003d?^_`{}~@e.c\";"},{"lineNumber":803,"author":{"gitId":"-"},"content":" assertTrue(StringHelper.isMatching(email, FieldValidator.REGEX_EMAIL));"},{"lineNumber":804,"author":{"gitId":"-"},"content":""},{"lineNumber":805,"author":{"gitId":"-"},"content":" ______TS(\"failure: invalid starting character\");"},{"lineNumber":806,"author":{"gitId":"-"},"content":" email \u003d \"$john@email.com\";"},{"lineNumber":807,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(email, FieldValidator.REGEX_EMAIL));"},{"lineNumber":808,"author":{"gitId":"-"},"content":""},{"lineNumber":809,"author":{"gitId":"-"},"content":" ______TS(\"failure: two consecutive dots in local part\");"},{"lineNumber":810,"author":{"gitId":"-"},"content":" email \u003d \"john..dot@email.com\";"},{"lineNumber":811,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(email, FieldValidator.REGEX_EMAIL));"},{"lineNumber":812,"author":{"gitId":"-"},"content":""},{"lineNumber":813,"author":{"gitId":"-"},"content":" ______TS(\"failure: invalid characters in domain part\");"},{"lineNumber":814,"author":{"gitId":"-"},"content":" email \u003d \"john@e\u0026email.com\";"},{"lineNumber":815,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(email, FieldValidator.REGEX_EMAIL));"},{"lineNumber":816,"author":{"gitId":"-"},"content":""},{"lineNumber":817,"author":{"gitId":"-"},"content":" ______TS(\"failure: invalid ending character in domain part\");"},{"lineNumber":818,"author":{"gitId":"-"},"content":" email \u003d \"john@email.com3\";"},{"lineNumber":819,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(email, FieldValidator.REGEX_EMAIL));"},{"lineNumber":820,"author":{"gitId":"-"},"content":" }"},{"lineNumber":821,"author":{"gitId":"-"},"content":""},{"lineNumber":822,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":823,"author":{"gitId":"-"},"content":" public void testRegexCourseId() {"},{"lineNumber":824,"author":{"gitId":"-"},"content":" ______TS(\"success: typical course ID\");"},{"lineNumber":825,"author":{"gitId":"-"},"content":" String courseId \u003d \"CS101\";"},{"lineNumber":826,"author":{"gitId":"-"},"content":" assertTrue(StringHelper.isMatching(courseId, FieldValidator.REGEX_COURSE_ID));"},{"lineNumber":827,"author":{"gitId":"-"},"content":""},{"lineNumber":828,"author":{"gitId":"-"},"content":" ______TS(\"success: course ID with all accepted symbols\");"},{"lineNumber":829,"author":{"gitId":"-"},"content":" courseId \u003d \"CS101-B.$\";"},{"lineNumber":830,"author":{"gitId":"-"},"content":" assertTrue(StringHelper.isMatching(courseId, FieldValidator.REGEX_COURSE_ID));"},{"lineNumber":831,"author":{"gitId":"-"},"content":""},{"lineNumber":832,"author":{"gitId":"-"},"content":" ______TS(\"failure: contains invalid character\");"},{"lineNumber":833,"author":{"gitId":"-"},"content":" courseId \u003d \"CS101+B\";"},{"lineNumber":834,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(courseId, FieldValidator.REGEX_COURSE_ID));"},{"lineNumber":835,"author":{"gitId":"-"},"content":" }"},{"lineNumber":836,"author":{"gitId":"-"},"content":""},{"lineNumber":837,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":838,"author":{"gitId":"-"},"content":" public void testRegexGoogleIdNonEmail() {"},{"lineNumber":839,"author":{"gitId":"-"},"content":" ______TS(\"success: typical google id\");"},{"lineNumber":840,"author":{"gitId":"-"},"content":" String googleId \u003d \"teammates.instr\";"},{"lineNumber":841,"author":{"gitId":"-"},"content":" assertTrue(StringHelper.isMatching(googleId, FieldValidator.REGEX_GOOGLE_ID_NON_EMAIL));"},{"lineNumber":842,"author":{"gitId":"-"},"content":""},{"lineNumber":843,"author":{"gitId":"-"},"content":" ______TS(\"success: google id with all accepted characters\");"},{"lineNumber":844,"author":{"gitId":"-"},"content":" googleId \u003d \"teammates.new_instr-3\";"},{"lineNumber":845,"author":{"gitId":"-"},"content":" assertTrue(StringHelper.isMatching(googleId, FieldValidator.REGEX_GOOGLE_ID_NON_EMAIL));"},{"lineNumber":846,"author":{"gitId":"-"},"content":""},{"lineNumber":847,"author":{"gitId":"-"},"content":" ______TS(\"failure: is email\");"},{"lineNumber":848,"author":{"gitId":"-"},"content":" googleId \u003d \"teammates.instr@email.com\";"},{"lineNumber":849,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(googleId, FieldValidator.REGEX_GOOGLE_ID_NON_EMAIL));"},{"lineNumber":850,"author":{"gitId":"-"},"content":""},{"lineNumber":851,"author":{"gitId":"-"},"content":" ______TS(\"failure: contains invalid character\");"},{"lineNumber":852,"author":{"gitId":"-"},"content":" googleId \u003d \"teammates.$instr\";"},{"lineNumber":853,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(googleId, FieldValidator.REGEX_GOOGLE_ID_NON_EMAIL));"},{"lineNumber":854,"author":{"gitId":"-"},"content":" }"},{"lineNumber":855,"author":{"gitId":"-"},"content":""},{"lineNumber":856,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":4,"-":852}},{"path":"src/test/java/teammates/common/util/TimeHelperTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.util;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Duration;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.LocalDateTime;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.time.Month;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.time.OffsetDateTime;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.time.ZoneId;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.time.ZonedDateTime;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.time.temporal.ChronoUnit;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * SUT: {@link TimeHelper}."},{"lineNumber":18,"author":{"gitId":"-"},"content":" */"},{"lineNumber":19,"author":{"gitId":"-"},"content":"public class TimeHelperTest extends BaseTestCase {"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" private static final String DATETIME_DISPLAY_FORMAT \u003d \"EEE, dd MMM yyyy, hh:mm a z\";"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":24,"author":{"gitId":"-"},"content":" public void testEndOfYearDates() {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" LocalDateTime date \u003d LocalDateTime.of(2015, Month.DECEMBER, 30, 12, 0);"},{"lineNumber":26,"author":{"gitId":"-"},"content":" assertEquals(\"Wed, 30 Dec 2015, 12:00 NOON UTC\", TimeHelper.formatInstant("},{"lineNumber":27,"author":{"gitId":"-"},"content":" date.atZone(ZoneId.of(\"UTC\")).toInstant(), \"UTC\", DATETIME_DISPLAY_FORMAT));"},{"lineNumber":28,"author":{"gitId":"-"},"content":" }"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":31,"author":{"gitId":"-"},"content":" public void testFormatDateTimeForDisplay() {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" String zoneId \u003d \"UTC\";"},{"lineNumber":33,"author":{"gitId":"-"},"content":" Instant instant \u003d LocalDateTime.of(2015, Month.NOVEMBER, 30, 12, 0).atZone(ZoneId.of(zoneId)).toInstant();"},{"lineNumber":34,"author":{"gitId":"-"},"content":" assertEquals(\"Mon, 30 Nov 2015, 12:00 NOON UTC\", TimeHelper.formatInstant(instant, zoneId, DATETIME_DISPLAY_FORMAT));"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" zoneId \u003d \"Asia/Singapore\";"},{"lineNumber":37,"author":{"gitId":"-"},"content":" instant \u003d LocalDateTime.of(2015, Month.NOVEMBER, 30, 16, 0).atZone(ZoneId.of(zoneId)).toInstant();"},{"lineNumber":38,"author":{"gitId":"-"},"content":" assertEquals(\"Mon, 30 Nov 2015, 04:00 PM SGT\", TimeHelper.formatInstant(instant, zoneId, DATETIME_DISPLAY_FORMAT));"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" instant \u003d LocalDateTime.of(2015, Month.NOVEMBER, 30, 4, 0).atZone(ZoneId.of(zoneId)).toInstant();"},{"lineNumber":41,"author":{"gitId":"-"},"content":" assertEquals(\"Mon, 30 Nov 2015, 04:00 AM SGT\", TimeHelper.formatInstant(instant, zoneId, DATETIME_DISPLAY_FORMAT));"},{"lineNumber":42,"author":{"gitId":"-"},"content":" }"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":45,"author":{"gitId":"-"},"content":" public void testGetMidnightAdjustedInstantBasedOnZone() {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" String zoneId \u003d \"UTC\";"},{"lineNumber":47,"author":{"gitId":"-"},"content":" Instant instantAt0000 \u003d LocalDateTime.of(2015, Month.NOVEMBER, 30, 0, 0).atZone(ZoneId.of(zoneId)).toInstant();"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" Instant backwardAdjusted \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone(instantAt0000, zoneId, false);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" assertEquals(\"Sun, 29 Nov 2015, 11:59 PM UTC\","},{"lineNumber":51,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(backwardAdjusted, zoneId, DATETIME_DISPLAY_FORMAT));"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" Instant forwardAdjusted \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone(instantAt0000, zoneId, true);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" assertEquals(\"Mon, 30 Nov 2015, 12:00 AM UTC\","},{"lineNumber":55,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(forwardAdjusted, zoneId, DATETIME_DISPLAY_FORMAT));"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" Instant instantAt2359 \u003d LocalDateTime.of(2015, Month.NOVEMBER, 29, 23, 59).atZone(ZoneId.of(zoneId)).toInstant();"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" backwardAdjusted \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone(instantAt2359, zoneId, false);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" assertEquals(\"Sun, 29 Nov 2015, 11:59 PM UTC\","},{"lineNumber":61,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(backwardAdjusted, zoneId, DATETIME_DISPLAY_FORMAT));"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" forwardAdjusted \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone(instantAt2359, zoneId, true);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" assertEquals(\"Mon, 30 Nov 2015, 12:00 AM UTC\","},{"lineNumber":65,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(forwardAdjusted, zoneId, DATETIME_DISPLAY_FORMAT));"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" String wrongTimeZone \u003d \"Asia/Singapore\";"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" backwardAdjusted \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone(instantAt0000, wrongTimeZone, false);"},{"lineNumber":70,"author":{"gitId":"-"},"content":" assertEquals(\"Mon, 30 Nov 2015, 12:00 AM UTC\","},{"lineNumber":71,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(backwardAdjusted, zoneId, DATETIME_DISPLAY_FORMAT));"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" forwardAdjusted \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone(instantAt2359, wrongTimeZone, true);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" assertEquals(\"Sun, 29 Nov 2015, 11:59 PM UTC\","},{"lineNumber":75,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(forwardAdjusted, zoneId, DATETIME_DISPLAY_FORMAT));"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":79,"author":{"gitId":"-"},"content":" public void testGetInstantNearestHourBefore() {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" Instant expected \u003d Instant.parse(\"2020-12-31T16:00:00Z\");"},{"lineNumber":81,"author":{"gitId":"-"},"content":" Instant actual \u003d TimeHelper.getInstantNearestHourBefore(Instant.parse(\"2020-12-31T16:00:00Z\"));"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" actual \u003d TimeHelper.getInstantNearestHourBefore(Instant.parse(\"2020-12-31T16:10:00Z\"));"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" actual \u003d TimeHelper.getInstantNearestHourBefore(OffsetDateTime.parse(\"2021-01-01T00:30:00+08:00\").toInstant());"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" actual \u003d TimeHelper.getInstantNearestHourBefore(OffsetDateTime.parse(\"2020-12-31T12:59:00-04:00\").toInstant());"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" }"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":99,"author":{"gitId":"-"},"content":" public void testGetInstantDaysOffsetFromNow() {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" // Comparison using second precision is sufficient"},{"lineNumber":101,"author":{"gitId":"-"},"content":" Instant expected \u003d Instant.now().truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" Instant actual \u003d TimeHelper.getInstantDaysOffsetFromNow(0).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" expected \u003d Instant.now().plus(Duration.ofDays(365)).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":106,"author":{"gitId":"-"},"content":" actual \u003d TimeHelper.getInstantDaysOffsetFromNow(365).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":107,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":111,"author":{"gitId":"-"},"content":" public void testGetInstantDaysOffsetBeforeNow() {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" // Comparison using second precision is sufficient"},{"lineNumber":113,"author":{"gitId":"-"},"content":" Instant expected \u003d Instant.now().truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" Instant actual \u003d TimeHelper.getInstantDaysOffsetBeforeNow(0).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":115,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" expected \u003d Instant.now().minus(Duration.ofDays(365)).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":118,"author":{"gitId":"-"},"content":" actual \u003d TimeHelper.getInstantDaysOffsetBeforeNow(365).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" }"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":123,"author":{"gitId":"-"},"content":" public void testGetInstantHoursOffsetFromNow() {"},{"lineNumber":124,"author":{"gitId":"-"},"content":" // Comparison using second precision is sufficient"},{"lineNumber":125,"author":{"gitId":"-"},"content":" Instant expected \u003d Instant.now().truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" Instant actual \u003d TimeHelper.getInstantHoursOffsetFromNow(0).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" expected \u003d Instant.now().plus(Duration.ofHours(60)).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" actual \u003d TimeHelper.getInstantHoursOffsetFromNow(60).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" }"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":135,"author":{"gitId":"-"},"content":" public void testGetInstantMonthsOffsetFromNow() {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" Instant expected \u003d Instant.now().truncatedTo(ChronoUnit.DAYS);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" Instant actual \u003d TimeHelper.getInstantMonthsOffsetFromNow(0, Const.DEFAULT_TIME_ZONE)"},{"lineNumber":138,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.DAYS);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" Instant now \u003d Instant.now();"},{"lineNumber":142,"author":{"gitId":"-"},"content":" ZonedDateTime zdt \u003d now.atZone(ZoneId.of(Const.DEFAULT_TIME_ZONE));"},{"lineNumber":143,"author":{"gitId":"-"},"content":" ZonedDateTime offsetZdt \u003d zdt.plusMonths(12);"},{"lineNumber":144,"author":{"gitId":"-"},"content":" expected \u003d offsetZdt.toInstant().truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" actual \u003d TimeHelper.getInstantMonthsOffsetFromNow(12, Const.DEFAULT_TIME_ZONE).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":" public void getInstantNearestQuarterHourBefore() {"},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":" Instant expectedQ1 \u003d Instant.parse(\"2020-12-31T16:00:00Z\");"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":" Instant actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:00:00Z\"));"},{"lineNumber":153,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ1, actual);"},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:09:30Z\"));"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":158,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ1, actual);"},{"lineNumber":159,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:14:59Z\"));"},{"lineNumber":161,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":162,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ1, actual);"},{"lineNumber":163,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":164,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper"},{"lineNumber":165,"author":{"gitId":"dishenggg"},"content":" .getInstantNearestQuarterHourBefore(OffsetDateTime.parse(\"2021-01-01T00:10:00+08:00\").toInstant());"},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":167,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ1, actual);"},{"lineNumber":168,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper"},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" .getInstantNearestQuarterHourBefore(OffsetDateTime.parse(\"2020-12-31T12:09:00-04:00\").toInstant());"},{"lineNumber":171,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ1, actual);"},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":" Instant expectedQ2 \u003d Instant.parse(\"2020-12-31T16:15:00Z\");"},{"lineNumber":175,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:15:00Z\"));"},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ2, actual);"},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":179,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:19:30Z\"));"},{"lineNumber":180,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":181,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ2, actual);"},{"lineNumber":182,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:29:59Z\"));"},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":185,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ2, actual);"},{"lineNumber":186,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":187,"author":{"gitId":"dishenggg"},"content":" Instant expectedQ3 \u003d Instant.parse(\"2020-12-31T16:30:00Z\");"},{"lineNumber":188,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:30:00Z\"));"},{"lineNumber":189,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":190,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ3, actual);"},{"lineNumber":191,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":192,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:39:30Z\"));"},{"lineNumber":193,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":194,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ3, actual);"},{"lineNumber":195,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":196,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:44:59Z\"));"},{"lineNumber":197,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":198,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ3, actual);"},{"lineNumber":199,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":200,"author":{"gitId":"dishenggg"},"content":" Instant expectedQ4 \u003d Instant.parse(\"2020-12-31T16:45:00Z\");"},{"lineNumber":201,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:45:00Z\"));"},{"lineNumber":202,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":203,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ4, actual);"},{"lineNumber":204,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":205,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:49:30Z\"));"},{"lineNumber":206,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":207,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ4, actual);"},{"lineNumber":208,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":209,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:59:59Z\"));"},{"lineNumber":210,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":211,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ4, actual);"},{"lineNumber":212,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":64,"-":149}},{"path":"src/test/java/teammates/logic/api/MockLogsProcessor.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.logic.api;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.QueryLogsResults;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.GeneralLogEntry;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.LogDetails;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.LogSeverity;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.QueryLogsParams;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.SourceLocation;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * Allows mocking of {@link LogsProcessor}."},{"lineNumber":18,"author":{"gitId":"-"},"content":" */"},{"lineNumber":19,"author":{"gitId":"-"},"content":"public class MockLogsProcessor extends LogsProcessor {"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" private List\u003cFeedbackSessionLogEntry\u003e feedbackSessionLogs \u003d new ArrayList\u003c\u003e();"},{"lineNumber":22,"author":{"gitId":"-"},"content":" private List\u003cGeneralLogEntry\u003e generalLogs \u003d new ArrayList\u003c\u003e();"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * Simulates insertion of feedback session logs."},{"lineNumber":26,"author":{"gitId":"-"},"content":" */"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" public void insertFeedbackSessionLog(String courseId, String studentEmail, String feedbackSessionName,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" String fslType, long timestamp) {"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" feedbackSessionLogs"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" .add(new FeedbackSessionLogEntry(courseId, studentEmail, feedbackSessionName, fslType, timestamp));"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" * Simulates insertion of feedback session logs."},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" public void insertFeedbackSessionLog(String courseId, UUID studentId, UUID feedbackSessionId,"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" String fslType, long timestamp) {"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" feedbackSessionLogs"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" .add(new FeedbackSessionLogEntry(courseId, studentId, feedbackSessionId, fslType, timestamp));"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":43,"author":{"gitId":"-"},"content":" * Simulates insertion of general INFO logs."},{"lineNumber":44,"author":{"gitId":"-"},"content":" */"},{"lineNumber":45,"author":{"gitId":"-"},"content":" public void insertInfoLog(String trace, String insertId, SourceLocation sourceLocation,"},{"lineNumber":46,"author":{"gitId":"-"},"content":" long timestamp, String textPayloadMessage, LogDetails logDetails) {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" insertGeneralLog(LogSeverity.INFO, trace, insertId,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" sourceLocation, timestamp, textPayloadMessage, logDetails);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":52,"author":{"gitId":"-"},"content":" * Simulates insertion of general WARNING logs."},{"lineNumber":53,"author":{"gitId":"-"},"content":" */"},{"lineNumber":54,"author":{"gitId":"-"},"content":" public void insertWarningLog(String trace, String insertId, SourceLocation sourceLocation,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" long timestamp, String textPayloadMessage, LogDetails logDetails) {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" insertGeneralLog(LogSeverity.WARNING, trace, insertId,"},{"lineNumber":57,"author":{"gitId":"-"},"content":" sourceLocation, timestamp, textPayloadMessage, logDetails);"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":61,"author":{"gitId":"-"},"content":" * Simulates insertion of general ERROR logs."},{"lineNumber":62,"author":{"gitId":"-"},"content":" */"},{"lineNumber":63,"author":{"gitId":"-"},"content":" public void insertErrorLog(String trace, String insertId, SourceLocation sourceLocation,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" long timestamp, String textPayloadMessage, LogDetails logDetails) {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" insertGeneralLog(LogSeverity.ERROR, trace, insertId,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" sourceLocation, timestamp, textPayloadMessage, logDetails);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" private void insertGeneralLog(LogSeverity severity, String trace, String insertId,"},{"lineNumber":70,"author":{"gitId":"-"},"content":" SourceLocation sourceLocation, long timestamp, String textPayloadMessage,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" LogDetails logDetails) {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" GeneralLogEntry logEntry \u003d new GeneralLogEntry(severity, trace, insertId, new HashMap\u003c\u003e(), sourceLocation,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" timestamp);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" logEntry.setMessage(textPayloadMessage);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" logEntry.setDetails(logDetails);"},{"lineNumber":76,"author":{"gitId":"-"},"content":" generalLogs.add(logEntry);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":80,"author":{"gitId":"-"},"content":" public QueryLogsResults queryLogs(QueryLogsParams queryLogsParams) {"},{"lineNumber":81,"author":{"gitId":"-"},"content":" List\u003cGeneralLogEntry\u003e queryResults \u003d new ArrayList\u003c\u003e();"},{"lineNumber":82,"author":{"gitId":"-"},"content":" if (queryLogsParams.getSeverity() !\u003d null) {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" generalLogs.forEach(entry -\u003e {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" if (queryLogsParams.getSeverity().equals(entry.getSeverity())"},{"lineNumber":85,"author":{"gitId":"-"},"content":" \u0026\u0026 entry.getTimestamp() \u003e\u003d queryLogsParams.getStartTime()"},{"lineNumber":86,"author":{"gitId":"-"},"content":" \u0026\u0026 entry.getTimestamp() \u003c\u003d queryLogsParams.getEndTime()) {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" queryResults.add(entry);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":" });"},{"lineNumber":90,"author":{"gitId":"-"},"content":" } else if (queryLogsParams.getMinSeverity() !\u003d null) {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" generalLogs.forEach(entry -\u003e {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" if (queryLogsParams.getMinSeverity().getSeverityLevel()"},{"lineNumber":93,"author":{"gitId":"-"},"content":" \u003c\u003d entry.getSeverity().getSeverityLevel()"},{"lineNumber":94,"author":{"gitId":"-"},"content":" \u0026\u0026 entry.getTimestamp() \u003e\u003d queryLogsParams.getStartTime()"},{"lineNumber":95,"author":{"gitId":"-"},"content":" \u0026\u0026 entry.getTimestamp() \u003c\u003d queryLogsParams.getEndTime()) {"},{"lineNumber":96,"author":{"gitId":"-"},"content":" queryResults.add(entry);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" }"},{"lineNumber":98,"author":{"gitId":"-"},"content":" });"},{"lineNumber":99,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" generalLogs.forEach(entry -\u003e {"},{"lineNumber":101,"author":{"gitId":"-"},"content":" if (entry.getTimestamp() \u003e\u003d queryLogsParams.getStartTime()"},{"lineNumber":102,"author":{"gitId":"-"},"content":" \u0026\u0026 entry.getTimestamp() \u003c\u003d queryLogsParams.getEndTime()) {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" queryResults.add(entry);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":" });"},{"lineNumber":106,"author":{"gitId":"-"},"content":" }"},{"lineNumber":107,"author":{"gitId":"-"},"content":" return new QueryLogsResults(queryResults, false);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":" public void createFeedbackSessionLog(String courseId, UUID studentId, UUID fsId, String fslType) {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" // No-op"},{"lineNumber":113,"author":{"gitId":"-"},"content":" }"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" public List\u003cFeedbackSessionLogEntry\u003e getOrderedFeedbackSessionLogs(String courseId, String email,"},{"lineNumber":117,"author":{"gitId":"-"},"content":" long startTime, long endTime, String fsName) {"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" feedbackSessionLogs.sort((x, y) -\u003e x.compareTo(y));"},{"lineNumber":119,"author":{"gitId":"-"},"content":" return feedbackSessionLogs;"},{"lineNumber":120,"author":{"gitId":"-"},"content":" }"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":16,"-":106}},{"path":"src/test/java/teammates/logic/api/MockUserProvision.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.logic.api;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.UserInfo;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.UserInfoCookie;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":7,"author":{"gitId":"-"},"content":" * Allows mocking of the {@link UserProvision} API used in production."},{"lineNumber":8,"author":{"gitId":"-"},"content":" *"},{"lineNumber":9,"author":{"gitId":"-"},"content":" * \u003cp\u003eInstead of getting user information from the authentication service,"},{"lineNumber":10,"author":{"gitId":"-"},"content":" * the API will return pre-determined information instead."},{"lineNumber":11,"author":{"gitId":"-"},"content":" */"},{"lineNumber":12,"author":{"gitId":"-"},"content":"public class MockUserProvision extends UserProvision {"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":" private UserInfo mockUser \u003d new UserInfo(\"user.id\");"},{"lineNumber":15,"author":{"gitId":"-"},"content":" private boolean isLoggedIn;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":" private UserInfo loginUser(String userId, boolean isAdmin) {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" isLoggedIn \u003d true;"},{"lineNumber":19,"author":{"gitId":"-"},"content":" mockUser.id \u003d userId;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" mockUser.isAdmin \u003d isAdmin;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" return getCurrentUser(null);"},{"lineNumber":22,"author":{"gitId":"-"},"content":" }"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * Adds a logged-in user without admin rights."},{"lineNumber":26,"author":{"gitId":"-"},"content":" *"},{"lineNumber":27,"author":{"gitId":"-"},"content":" * @return The user info after login process"},{"lineNumber":28,"author":{"gitId":"-"},"content":" */"},{"lineNumber":29,"author":{"gitId":"-"},"content":" public UserInfo loginUser(String userId) {"},{"lineNumber":30,"author":{"gitId":"-"},"content":" return loginUser(userId, false);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" }"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" private UserInfo loginUserWithTransaction(String userId, boolean isAdmin) {"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" isLoggedIn \u003d true;"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" mockUser.id \u003d userId;"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" mockUser.isAdmin \u003d isAdmin;"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" return getCurrentUserWithTransaction(null);"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" * Adds a logged-in user without admin rights."},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" * @return The user info after login process"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" public UserInfo loginUserWithTransaction(String userId) {"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" return loginUserWithTransaction(userId, false);"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":50,"author":{"gitId":"-"},"content":" * Adds a logged-in user as an admin."},{"lineNumber":51,"author":{"gitId":"-"},"content":" *"},{"lineNumber":52,"author":{"gitId":"-"},"content":" * @return The user info after login process"},{"lineNumber":53,"author":{"gitId":"-"},"content":" */"},{"lineNumber":54,"author":{"gitId":"-"},"content":" public UserInfo loginAsAdmin(String userId) {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" return loginUser(userId, true);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" * Adds a logged-in user as an admin."},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" * @return The user info after login process"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" public UserInfo loginAsAdminWithTransaction(String userId) {"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" return loginUserWithTransaction(userId, true);"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":68,"author":{"gitId":"-"},"content":" * Removes the logged-in user information."},{"lineNumber":69,"author":{"gitId":"-"},"content":" */"},{"lineNumber":70,"author":{"gitId":"-"},"content":" public void logoutUser() {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" isLoggedIn \u003d false;"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public UserInfo getCurrentLoggedInUser(UserInfoCookie uic) {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" return isLoggedIn ? mockUser : null;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":25,"-":54}},{"path":"src/test/java/teammates/sqllogic/api/SqlEmailGeneratorTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.api;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.io.IOException;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailType;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.test.EmailChecker;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * SUT: {@link SqlEmailGenerator}."},{"lineNumber":17,"author":{"gitId":"-"},"content":" */"},{"lineNumber":18,"author":{"gitId":"-"},"content":"public class SqlEmailGeneratorTest extends BaseTestCase {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" private final SqlEmailGenerator sqlEmailGenerator \u003d SqlEmailGenerator.inst();"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":22,"author":{"gitId":"-"},"content":" void testGenerateNewAccountRequestAdminAlertEmail_withComments_generatesSuccessfully() throws IOException {"},{"lineNumber":23,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d new AccountRequest(\"chosen-one@jedi.org\", \"Anakin Skywalker\", \"Jedi Order\","},{"lineNumber":24,"author":{"gitId":"-"},"content":" AccountRequestStatus.PENDING,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \"I don\u0027t like sand. It\u0027s coarse and rough and irritating... and it gets everywhere.\");"},{"lineNumber":26,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d sqlEmailGenerator.generateNewAccountRequestAdminAlertEmail(accountRequest);"},{"lineNumber":27,"author":{"gitId":"-"},"content":" verifyEmail(email, Config.SUPPORT_EMAIL, EmailType.NEW_ACCOUNT_REQUEST_ADMIN_ALERT,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" \"TEAMMATES (Action Needed): New Account Request Received\","},{"lineNumber":29,"author":{"gitId":"-"},"content":" \"/adminNewAccountRequestAlertEmailWithComments.html\");"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":33,"author":{"gitId":"-"},"content":" void testGenerateNewAccountRequestAdminAlertEmail_withNoComments_generatesSuccessfully() throws IOException {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d new AccountRequest(\"maul@sith.org\", \"Maul\", \"Sith Order\","},{"lineNumber":35,"author":{"gitId":"-"},"content":" AccountRequestStatus.PENDING, null);"},{"lineNumber":36,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d sqlEmailGenerator.generateNewAccountRequestAdminAlertEmail(accountRequest);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" verifyEmail(email, Config.SUPPORT_EMAIL, EmailType.NEW_ACCOUNT_REQUEST_ADMIN_ALERT,"},{"lineNumber":38,"author":{"gitId":"-"},"content":" \"TEAMMATES (Action Needed): New Account Request Received\","},{"lineNumber":39,"author":{"gitId":"-"},"content":" \"/adminNewAccountRequestAlertEmailWithNoComments.html\");"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" void testGenerateNewAccountRequestAcknowledgementEmail_withComments_generatesSuccessfully() throws IOException {"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" AccountRequest accountRequest \u003d new AccountRequest(\"darth-vader@sith.org\", \"Darth Vader\", \"Sith Order\","},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" AccountRequestStatus.PENDING,"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" \"I Am Your Father\");"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" EmailWrapper email \u003d sqlEmailGenerator.generateNewAccountRequestAcknowledgementEmail(accountRequest);"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" verifyEmail(email, \"darth-vader@sith.org\", EmailType.NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT,"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" \"TEAMMATES: Acknowledgement of Instructor Account Request\","},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" Config.SUPPORT_EMAIL,"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" \"/instructorNewAccountRequestAcknowledgementEmailWithComments.html\");"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":" void testGenerateNewAccountRequestAcknowledgementEmail_withNoComments_generatesSuccessfully() throws IOException {"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" AccountRequest accountRequest \u003d new AccountRequest(\"maul@sith.org\", \"Maul\", \"Sith Order\","},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" AccountRequestStatus.PENDING, null);"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" EmailWrapper email \u003d sqlEmailGenerator.generateNewAccountRequestAcknowledgementEmail(accountRequest);"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" verifyEmail(email, \"maul@sith.org\", EmailType.NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT,"},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" \"TEAMMATES: Acknowledgement of Instructor Account Request\","},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" Config.SUPPORT_EMAIL,"},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" \"/instructorNewAccountRequestAcknowledgementEmailWithNoComments.html\");"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":66,"author":{"gitId":"-"},"content":" void testGenerateAccountRequestRejectionEmail_withDefaultReason_generatesSuccessfully() throws IOException {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d new AccountRequest(\"maul@sith.org\", \"Maul\", \"Sith Order\","},{"lineNumber":68,"author":{"gitId":"-"},"content":" AccountRequestStatus.PENDING, null);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" String title \u003d \"We are Unable to Create an Account for you\";"},{"lineNumber":70,"author":{"gitId":"-"},"content":" String content \u003d new StringBuilder()"},{"lineNumber":71,"author":{"gitId":"-"},"content":" .append(\"\u003cp\u003eHi, Maul\u003c/p\u003e\\n\")"},{"lineNumber":72,"author":{"gitId":"-"},"content":" .append(\"\u003cp\u003eThanks for your interest in using TEAMMATES. \")"},{"lineNumber":73,"author":{"gitId":"-"},"content":" .append(\"We are unable to create a TEAMMATES instructor account for you.\u003c/p\u003e\\n\\n\")"},{"lineNumber":74,"author":{"gitId":"-"},"content":" .append(\"\u003cp\u003e\\n\")"},{"lineNumber":75,"author":{"gitId":"-"},"content":" .append(\" \u003cstrong\u003eReason:\u003c/strong\u003e The email address you provided \")"},{"lineNumber":76,"author":{"gitId":"-"},"content":" .append(\"is not an \u0027official\u0027 email address provided by your institution.\u003cbr /\u003e\\n\")"},{"lineNumber":77,"author":{"gitId":"-"},"content":" .append(\" \u003cstrong\u003eRemedy:\u003c/strong\u003e \")"},{"lineNumber":78,"author":{"gitId":"-"},"content":" .append(\"Please re-submit an account request with your \u0027official\u0027 institution email address.\\n\")"},{"lineNumber":79,"author":{"gitId":"-"},"content":" .append(\"\u003c/p\u003e\\n\\n\")"},{"lineNumber":80,"author":{"gitId":"-"},"content":" .append(\"\u003cp\u003eIf you need further clarification or would like to appeal this decision, \")"},{"lineNumber":81,"author":{"gitId":"-"},"content":" .append(\"please feel free to contact us at teammates@comp.nus.edu.sg.\u003c/p\u003e\\n\")"},{"lineNumber":82,"author":{"gitId":"-"},"content":" .append(\"\u003cp\u003eRegards,\u003cbr /\u003eTEAMMATES Team.\u003c/p\u003e\\n\")"},{"lineNumber":83,"author":{"gitId":"-"},"content":" .toString();"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d sqlEmailGenerator.generateAccountRequestRejectionEmail(accountRequest, title, content);"},{"lineNumber":86,"author":{"gitId":"-"},"content":" verifyEmail(email, \"maul@sith.org\", EmailType.ACCOUNT_REQUEST_REJECTION,"},{"lineNumber":87,"author":{"gitId":"-"},"content":" \"TEAMMATES: \" + title,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" Config.SUPPORT_EMAIL,"},{"lineNumber":89,"author":{"gitId":"-"},"content":" \"/instructorAccountRequestRejectionEmail.html\");"},{"lineNumber":90,"author":{"gitId":"-"},"content":" }"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" private void verifyEmail(EmailWrapper email, String expectedRecipientEmailAddress, EmailType expectedEmailType,"},{"lineNumber":93,"author":{"gitId":"-"},"content":" String expectedSubject, String expectedEmailContentFilePathname) throws IOException {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" assertEquals(expectedRecipientEmailAddress, email.getRecipient());"},{"lineNumber":95,"author":{"gitId":"-"},"content":" assertEquals(Config.EMAIL_SENDEREMAIL, email.getSenderEmail());"},{"lineNumber":96,"author":{"gitId":"-"},"content":" assertEquals(Config.EMAIL_SENDERNAME, email.getSenderName());"},{"lineNumber":97,"author":{"gitId":"-"},"content":" assertEquals(Config.EMAIL_REPLYTO, email.getReplyTo());"},{"lineNumber":98,"author":{"gitId":"-"},"content":" assertEquals(expectedEmailType, email.getType());"},{"lineNumber":99,"author":{"gitId":"-"},"content":" assertEquals(expectedSubject, email.getSubject());"},{"lineNumber":100,"author":{"gitId":"-"},"content":" String emailContent \u003d email.getContent();"},{"lineNumber":101,"author":{"gitId":"-"},"content":" EmailChecker.verifyEmailContent(emailContent, expectedEmailContentFilePathname);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" verifyEmailContentHasNoPlaceholders(emailContent);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" }"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"xenosf"},"content":" private void verifyEmail(EmailWrapper email, String expectedRecipientEmailAddress, EmailType expectedEmailType,"},{"lineNumber":106,"author":{"gitId":"xenosf"},"content":" String expectedSubject, String expectedBcc, String expectedEmailContentFilePathname) throws IOException {"},{"lineNumber":107,"author":{"gitId":"xenosf"},"content":" assertEquals(expectedRecipientEmailAddress, email.getRecipient());"},{"lineNumber":108,"author":{"gitId":"xenosf"},"content":" assertEquals(Config.EMAIL_SENDEREMAIL, email.getSenderEmail());"},{"lineNumber":109,"author":{"gitId":"xenosf"},"content":" assertEquals(Config.EMAIL_SENDERNAME, email.getSenderName());"},{"lineNumber":110,"author":{"gitId":"xenosf"},"content":" assertEquals(Config.EMAIL_REPLYTO, email.getReplyTo());"},{"lineNumber":111,"author":{"gitId":"xenosf"},"content":" assertEquals(expectedEmailType, email.getType());"},{"lineNumber":112,"author":{"gitId":"xenosf"},"content":" assertEquals(expectedSubject, email.getSubject());"},{"lineNumber":113,"author":{"gitId":"xenosf"},"content":" assertEquals(expectedBcc, email.getBcc());"},{"lineNumber":114,"author":{"gitId":"xenosf"},"content":" String emailContent \u003d email.getContent();"},{"lineNumber":115,"author":{"gitId":"xenosf"},"content":" EmailChecker.verifyEmailContent(emailContent, expectedEmailContentFilePathname);"},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" verifyEmailContentHasNoPlaceholders(emailContent);"},{"lineNumber":117,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":118,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" private void verifyEmailContentHasNoPlaceholders(String emailContent) {"},{"lineNumber":120,"author":{"gitId":"-"},"content":" assertFalse(emailContent.contains(\"${\"));"},{"lineNumber":121,"author":{"gitId":"-"},"content":" }"},{"lineNumber":122,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":37,"-":85}},{"path":"src/test/java/teammates/sqllogic/core/AccountRequestsLogicTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import static org.mockito.ArgumentMatchers.any;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import static org.mockito.ArgumentMatchers.nullable;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.mock;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import static org.mockito.Mockito.times;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.verify;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.when;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.AccountRequestsDb;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * SUT: {@link AccountRequestsLogic}."},{"lineNumber":25,"author":{"gitId":"-"},"content":" */"},{"lineNumber":26,"author":{"gitId":"-"},"content":"public class AccountRequestsLogicTest extends BaseTestCase {"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" private AccountRequestsLogic accountRequestsLogic \u003d AccountRequestsLogic.inst();"},{"lineNumber":29,"author":{"gitId":"-"},"content":" private AccountRequestsDb accountRequestsDb;"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":32,"author":{"gitId":"-"},"content":" public void setUpMethod() {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" accountRequestsDb \u003d mock(AccountRequestsDb.class);"},{"lineNumber":34,"author":{"gitId":"-"},"content":" accountRequestsLogic.initLogicDependencies(accountRequestsDb);"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" public void testCreateAccountRequest_typicalRequest_success() throws Exception {"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" AccountRequest accountRequest \u003d getTypicalAccountRequest();"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.createAccountRequest(accountRequest)).thenReturn(accountRequest);"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" AccountRequest createdAccountRequest \u003d accountRequestsLogic.createAccountRequest(accountRequest);"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest, createdAccountRequest);"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).createAccountRequest(accountRequest);"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" public void testCreateAccountRequest_requestAlreadyExists_success() throws Exception {"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" AccountRequest accountRequest1 \u003d getTypicalAccountRequest();"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" AccountRequest accountRequest2 \u003d getTypicalAccountRequest();"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.createAccountRequest(accountRequest1))"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" .thenReturn(accountRequest1);"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.createAccountRequest(accountRequest2))"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" .thenReturn(accountRequest2);"},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" accountRequestsLogic.createAccountRequest(accountRequest1);"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" accountRequestsLogic.createAccountRequest(accountRequest2);"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).createAccountRequest(accountRequest1);"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).createAccountRequest(accountRequest2);"},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" public void testCreateAccountRequest_invalidParams_failure() throws Exception {"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" AccountRequest invalidEmailAccountRequest \u003d getTypicalAccountRequest();"},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":" invalidEmailAccountRequest.setEmail(\"invalid email\");"},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.createAccountRequest(invalidEmailAccountRequest))"},{"lineNumber":67,"author":{"gitId":"xenosf"},"content":" .thenThrow(new InvalidParametersException(\"test exception\"));"},{"lineNumber":68,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":" assertThrows(InvalidParametersException.class, () -\u003e {"},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":" accountRequestsLogic.createAccountRequest(invalidEmailAccountRequest);"},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).createAccountRequest(invalidEmailAccountRequest);"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" public void testUpdateAccountRequest_typicalRequest_success()"},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" AccountRequest ar \u003d getTypicalAccountRequest();"},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.updateAccountRequest(ar)).thenReturn(ar);"},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" AccountRequest updatedAr \u003d accountRequestsLogic.updateAccountRequest(ar);"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":" assertEquals(ar, updatedAr);"},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).updateAccountRequest(ar);"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":" public void testUpdateAccountRequest_requestNotFound_failure()"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":" AccountRequest arNotFound \u003d getTypicalAccountRequest();"},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.updateAccountRequest(arNotFound)).thenThrow(new EntityDoesNotExistException(\"test message\"));"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":" assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":93,"author":{"gitId":"xenosf"},"content":" () -\u003e accountRequestsLogic.updateAccountRequest(arNotFound));"},{"lineNumber":94,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).updateAccountRequest(any(AccountRequest.class));"},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" public void testDeleteAccountRequest_typicalRequest_success() {"},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" AccountRequest ar \u003d getTypicalAccountRequest();"},{"lineNumber":100,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.getAccountRequest(ar.getId())).thenReturn(ar);"},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":" accountRequestsLogic.deleteAccountRequest(ar.getId());"},{"lineNumber":102,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":103,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).deleteAccountRequest(any(AccountRequest.class));"},{"lineNumber":104,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":105,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":106,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":107,"author":{"gitId":"xenosf"},"content":" public void testDeleteAccountRequest_nonexistentRequest_shouldSilentlyDelete() {"},{"lineNumber":108,"author":{"gitId":"xenosf"},"content":" UUID nonexistentUuid \u003d UUID.fromString(\"00000000-0000-4000-8000-000000000100\");"},{"lineNumber":109,"author":{"gitId":"xenosf"},"content":" accountRequestsLogic.deleteAccountRequest(nonexistentUuid);"},{"lineNumber":110,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":111,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).deleteAccountRequest(nullable(AccountRequest.class));"},{"lineNumber":112,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":113,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":114,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":115,"author":{"gitId":"xenosf"},"content":" public void testGetAccountRequestByRegistrationKey_typicalRequest_success() {"},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" AccountRequest ar \u003d getTypicalAccountRequest();"},{"lineNumber":117,"author":{"gitId":"xenosf"},"content":" String regkey \u003d \"regkey\";"},{"lineNumber":118,"author":{"gitId":"xenosf"},"content":" ar.setRegistrationKey(regkey);"},{"lineNumber":119,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.getAccountRequestByRegistrationKey(regkey)).thenReturn(ar);"},{"lineNumber":120,"author":{"gitId":"xenosf"},"content":" AccountRequest actualAr \u003d"},{"lineNumber":121,"author":{"gitId":"xenosf"},"content":" accountRequestsLogic.getAccountRequestByRegistrationKey(ar.getRegistrationKey());"},{"lineNumber":122,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":123,"author":{"gitId":"xenosf"},"content":" assertEquals(ar, actualAr);"},{"lineNumber":124,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).getAccountRequestByRegistrationKey(regkey);"},{"lineNumber":125,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":126,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":127,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":128,"author":{"gitId":"xenosf"},"content":" public void testGetAccountRequestByRegistrationKey_nonexistentRequest_shouldReturnNull() throws Exception {"},{"lineNumber":129,"author":{"gitId":"xenosf"},"content":" String nonexistentRegkey \u003d \"not_exist\";"},{"lineNumber":130,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.getAccountRequestByRegistrationKey(nonexistentRegkey)).thenReturn(null);"},{"lineNumber":131,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":132,"author":{"gitId":"xenosf"},"content":" assertNull(accountRequestsLogic.getAccountRequestByRegistrationKey(nonexistentRegkey));"},{"lineNumber":133,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).getAccountRequestByRegistrationKey(nonexistentRegkey);"},{"lineNumber":134,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":135,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":136,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":137,"author":{"gitId":"xenosf"},"content":" public void testResetAccountRequest_typicalRequest_success()"},{"lineNumber":138,"author":{"gitId":"xenosf"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":139,"author":{"gitId":"xenosf"},"content":" AccountRequest accountRequest \u003d getTypicalAccountRequest();"},{"lineNumber":140,"author":{"gitId":"xenosf"},"content":" accountRequest.setRegisteredAt(Const.TIME_REPRESENTS_NOW);"},{"lineNumber":141,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.getAccountRequest(accountRequest.getId()))"},{"lineNumber":142,"author":{"gitId":"xenosf"},"content":" .thenReturn(accountRequest);"},{"lineNumber":143,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.updateAccountRequest(accountRequest)).thenReturn(accountRequest);"},{"lineNumber":144,"author":{"gitId":"xenosf"},"content":" accountRequest \u003d accountRequestsLogic.resetAccountRequest(accountRequest.getId());"},{"lineNumber":145,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":146,"author":{"gitId":"xenosf"},"content":" assertNull(accountRequest.getRegisteredAt());"},{"lineNumber":147,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).getAccountRequest(accountRequest.getId());"},{"lineNumber":148,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":149,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":150,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":151,"author":{"gitId":"xenosf"},"content":" public void testResetAccountRequest_nonexistentRequest_failure()"},{"lineNumber":152,"author":{"gitId":"xenosf"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":153,"author":{"gitId":"xenosf"},"content":" AccountRequest accountRequest \u003d getTypicalAccountRequest();"},{"lineNumber":154,"author":{"gitId":"xenosf"},"content":" accountRequest.setRegisteredAt(Const.TIME_REPRESENTS_NOW);"},{"lineNumber":155,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.getAccountRequest(accountRequest.getId()))"},{"lineNumber":156,"author":{"gitId":"xenosf"},"content":" .thenReturn(null);"},{"lineNumber":157,"author":{"gitId":"xenosf"},"content":" assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":158,"author":{"gitId":"xenosf"},"content":" () -\u003e accountRequestsLogic.resetAccountRequest(accountRequest.getId()));"},{"lineNumber":159,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).getAccountRequest(accountRequest.getId());"},{"lineNumber":160,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(0)).updateAccountRequest(nullable(AccountRequest.class));"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":164,"author":{"gitId":"-"},"content":" public void testGetAccountRequest_nonExistentAccountRequest_returnsNull() {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" UUID id \u003d UUID.randomUUID();"},{"lineNumber":166,"author":{"gitId":"-"},"content":" when(accountRequestsDb.getAccountRequest(id)).thenReturn(null);"},{"lineNumber":167,"author":{"gitId":"-"},"content":" AccountRequest actualAccountRequest \u003d accountRequestsLogic.getAccountRequest(id);"},{"lineNumber":168,"author":{"gitId":"-"},"content":" verify(accountRequestsDb).getAccountRequest(id);"},{"lineNumber":169,"author":{"gitId":"-"},"content":" assertNull(actualAccountRequest);"},{"lineNumber":170,"author":{"gitId":"-"},"content":" }"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":173,"author":{"gitId":"-"},"content":" public void testGetAccountRequest_existingAccountRequest_getsSuccessfully() {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" AccountRequest expectedAccountRequest \u003d"},{"lineNumber":175,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":176,"author":{"gitId":"-"},"content":" UUID id \u003d expectedAccountRequest.getId();"},{"lineNumber":177,"author":{"gitId":"-"},"content":" when(accountRequestsDb.getAccountRequest(id)).thenReturn(expectedAccountRequest);"},{"lineNumber":178,"author":{"gitId":"-"},"content":" AccountRequest actualAccountRequest \u003d accountRequestsLogic.getAccountRequest(id);"},{"lineNumber":179,"author":{"gitId":"-"},"content":" verify(accountRequestsDb).getAccountRequest(id);"},{"lineNumber":180,"author":{"gitId":"-"},"content":" assertEquals(expectedAccountRequest, actualAccountRequest);"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":132,"-":50}},{"path":"src/test/java/teammates/sqllogic/core/AccountsLogicTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.mock;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.times;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.verify;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.when;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.AccountsDb;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.ReadNotification;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.User;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"-"},"content":" * SUT: {@link AccountsLogic}."},{"lineNumber":27,"author":{"gitId":"-"},"content":" */"},{"lineNumber":28,"author":{"gitId":"-"},"content":"public class AccountsLogicTest extends BaseTestCase {"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" private AccountsLogic accountsLogic \u003d AccountsLogic.inst();"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" private AccountsDb accountsDb;"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" private NotificationsLogic notificationsLogic;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" private UsersLogic usersLogic;"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"yuanxi1"},"content":" private CoursesLogic coursesLogic;"},{"lineNumber":39,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":41,"author":{"gitId":"-"},"content":" public void setUpMethod() {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" accountsDb \u003d mock(AccountsDb.class);"},{"lineNumber":43,"author":{"gitId":"-"},"content":" notificationsLogic \u003d mock(NotificationsLogic.class);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" usersLogic \u003d mock(UsersLogic.class);"},{"lineNumber":45,"author":{"gitId":"yuanxi1"},"content":" accountsLogic.initLogicDependencies(accountsDb, notificationsLogic, usersLogic, coursesLogic);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":49,"author":{"gitId":"-"},"content":" public void testDeleteAccount_accountExists_success() {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" Account account \u003d getTypicalAccount();"},{"lineNumber":51,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" when(accountsLogic.getAccountForGoogleId(googleId)).thenReturn(account);"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" accountsLogic.deleteAccount(googleId);"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" verify(accountsDb, times(1)).deleteAccount(account);"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":61,"author":{"gitId":"-"},"content":" public void testDeleteAccountCascade_googleIdExists_success() {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" Account account \u003d getTypicalAccount();"},{"lineNumber":63,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":64,"author":{"gitId":"-"},"content":" List\u003cUser\u003e users \u003d new ArrayList\u003c\u003e();"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c 2; ++i) {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" users.add(getTypicalInstructor());"},{"lineNumber":68,"author":{"gitId":"-"},"content":" users.add(getTypicalStudent());"},{"lineNumber":69,"author":{"gitId":"-"},"content":" }"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" when(usersLogic.getAllUsersByGoogleId(googleId)).thenReturn(users);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" when(accountsLogic.getAccountForGoogleId(googleId)).thenReturn(account);"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" accountsLogic.deleteAccountCascade(googleId);"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" for (User user : users) {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" verify(usersLogic, times(1)).deleteUser(user);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }"},{"lineNumber":79,"author":{"gitId":"-"},"content":" verify(accountsDb, times(1)).deleteAccount(account);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" }"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":83,"author":{"gitId":"-"},"content":" public void testUpdateReadNotifications_shouldReturnCorrectReadNotificationId_success()"},{"lineNumber":84,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" Account account \u003d getTypicalAccount();"},{"lineNumber":86,"author":{"gitId":"-"},"content":" Notification notification \u003d getTypicalNotificationWithId();"},{"lineNumber":87,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":88,"author":{"gitId":"-"},"content":" UUID notificationId \u003d notification.getId();"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" when(accountsDb.getAccountByGoogleId(googleId)).thenReturn(account);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" when(notificationsLogic.getNotification(notificationId)).thenReturn(notification);"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" List\u003cUUID\u003e readNotificationIds \u003d accountsLogic.updateReadNotifications(googleId, notificationId,"},{"lineNumber":94,"author":{"gitId":"-"},"content":" notification.getEndTime());"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" verify(accountsDb, times(1)).getAccountByGoogleId(googleId);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" verify(notificationsLogic, times(1)).getNotification(notificationId);"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" assertEquals(1, readNotificationIds.size());"},{"lineNumber":100,"author":{"gitId":"-"},"content":" assertEquals(notificationId, readNotificationIds.get(0));"},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":104,"author":{"gitId":"-"},"content":" public void testUpdateReadNotifications_shouldAddReadNotificationToAccount_success()"},{"lineNumber":105,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":106,"author":{"gitId":"-"},"content":" Account account \u003d getTypicalAccount();"},{"lineNumber":107,"author":{"gitId":"-"},"content":" Notification notification \u003d getTypicalNotificationWithId();"},{"lineNumber":108,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":109,"author":{"gitId":"-"},"content":" UUID notificationId \u003d notification.getId();"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" when(accountsDb.getAccountByGoogleId(googleId)).thenReturn(account);"},{"lineNumber":112,"author":{"gitId":"-"},"content":" when(notificationsLogic.getNotification(notificationId)).thenReturn(notification);"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" accountsLogic.updateReadNotifications(googleId, notificationId, notification.getEndTime());"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" verify(accountsDb, times(1)).getAccountByGoogleId(googleId);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" verify(notificationsLogic, times(1)).getNotification(notificationId);"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" List\u003cReadNotification\u003e accountReadNotifications \u003d account.getReadNotifications();"},{"lineNumber":120,"author":{"gitId":"-"},"content":" assertEquals(1, accountReadNotifications.size());"},{"lineNumber":121,"author":{"gitId":"-"},"content":" ReadNotification readNotification \u003d accountReadNotifications.get(0);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" assertSame(account, readNotification.getAccount());"},{"lineNumber":123,"author":{"gitId":"-"},"content":" assertSame(notification, readNotification.getNotification());"},{"lineNumber":124,"author":{"gitId":"-"},"content":" }"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":127,"author":{"gitId":"-"},"content":" public void testUpdateReadNotifications_accountDoesNotExist_throwEntityDoesNotExistException() {"},{"lineNumber":128,"author":{"gitId":"-"},"content":" Account account \u003d getTypicalAccount();"},{"lineNumber":129,"author":{"gitId":"-"},"content":" Notification notification \u003d getTypicalNotificationWithId();"},{"lineNumber":130,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":131,"author":{"gitId":"-"},"content":" UUID notificationId \u003d notification.getId();"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" when(accountsDb.getAccountByGoogleId(googleId)).thenReturn(null);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" when(notificationsLogic.getNotification(notificationId)).thenReturn(notification);"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" EntityDoesNotExistException ex \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":137,"author":{"gitId":"-"},"content":" () -\u003e accountsLogic.updateReadNotifications(googleId, notificationId, notification.getEndTime()));"},{"lineNumber":138,"author":{"gitId":"-"},"content":" assertEquals(\"Trying to update the read notifications of a non-existent account.\", ex.getMessage());"},{"lineNumber":139,"author":{"gitId":"-"},"content":" }"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":142,"author":{"gitId":"-"},"content":" public void testUpdateReadNotifications_notificationDoesNotExist_throwEntityDoesNotExistException() {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" Account account \u003d getTypicalAccount();"},{"lineNumber":144,"author":{"gitId":"-"},"content":" Notification notification \u003d getTypicalNotificationWithId();"},{"lineNumber":145,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":146,"author":{"gitId":"-"},"content":" UUID notificationId \u003d notification.getId();"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" when(accountsDb.getAccountByGoogleId(googleId)).thenReturn(account);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" when(notificationsLogic.getNotification(notificationId)).thenReturn(null);"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" EntityDoesNotExistException ex \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":152,"author":{"gitId":"-"},"content":" () -\u003e accountsLogic.updateReadNotifications(googleId, notificationId, notification.getEndTime()));"},{"lineNumber":153,"author":{"gitId":"-"},"content":" assertEquals(\"Trying to mark as read a notification that does not exist.\", ex.getMessage());"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":157,"author":{"gitId":"-"},"content":" public void testUpdateReadNotifications_markExpiredNotificationAsRead_throwInvalidParametersException() {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" Account account \u003d getTypicalAccount();"},{"lineNumber":159,"author":{"gitId":"-"},"content":" Notification notification \u003d getTypicalNotificationWithId();"},{"lineNumber":160,"author":{"gitId":"-"},"content":" notification.setEndTime(Instant.parse(\"2012-01-01T00:00:00Z\"));"},{"lineNumber":161,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":162,"author":{"gitId":"-"},"content":" UUID notificationId \u003d notification.getId();"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" when(accountsDb.getAccountByGoogleId(googleId)).thenReturn(account);"},{"lineNumber":165,"author":{"gitId":"-"},"content":" when(notificationsLogic.getNotification(notificationId)).thenReturn(notification);"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" InvalidParametersException ex \u003d assertThrows(InvalidParametersException.class,"},{"lineNumber":168,"author":{"gitId":"-"},"content":" () -\u003e accountsLogic.updateReadNotifications(googleId, notificationId, notification.getEndTime()));"},{"lineNumber":169,"author":{"gitId":"-"},"content":" assertEquals(\"Trying to mark an expired notification as read.\", ex.getMessage());"},{"lineNumber":170,"author":{"gitId":"-"},"content":" }"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":173,"author":{"gitId":"-"},"content":" public void testGetReadNotificationsId_doesNotHaveReadNotifications_success() {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" Account account \u003d getTypicalAccount();"},{"lineNumber":175,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":176,"author":{"gitId":"-"},"content":" when(accountsDb.getAccountByGoogleId(googleId)).thenReturn(account);"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" List\u003cUUID\u003e readNotifications \u003d accountsLogic.getReadNotificationsId(googleId);"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" assertEquals(0, readNotifications.size());"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":184,"author":{"gitId":"-"},"content":" public void testGetReadNotificationsId_hasReadNotifications_success() {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" Account account \u003d getTypicalAccount();"},{"lineNumber":186,"author":{"gitId":"-"},"content":" List\u003cReadNotification\u003e readNotifications \u003d new ArrayList\u003c\u003e();"},{"lineNumber":187,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c 10; i++) {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" Notification notification \u003d getTypicalNotificationWithId();"},{"lineNumber":189,"author":{"gitId":"-"},"content":" ReadNotification readNotification \u003d new ReadNotification(account, notification);"},{"lineNumber":190,"author":{"gitId":"-"},"content":" readNotifications.add(readNotification);"},{"lineNumber":191,"author":{"gitId":"-"},"content":" }"},{"lineNumber":192,"author":{"gitId":"-"},"content":" account.setReadNotifications(readNotifications);"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":195,"author":{"gitId":"-"},"content":" when(accountsDb.getAccountByGoogleId(googleId)).thenReturn(account);"},{"lineNumber":196,"author":{"gitId":"-"},"content":""},{"lineNumber":197,"author":{"gitId":"-"},"content":" List\u003cUUID\u003e actualReadNotifications \u003d accountsLogic.getReadNotificationsId(googleId);"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" assertEquals(10, actualReadNotifications.size());"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c 10; i++) {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" assertEquals(readNotifications.get(i).getNotification().getId(),"},{"lineNumber":203,"author":{"gitId":"-"},"content":" actualReadNotifications.get(i));"},{"lineNumber":204,"author":{"gitId":"-"},"content":" }"},{"lineNumber":205,"author":{"gitId":"-"},"content":" }"},{"lineNumber":206,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"yuanxi1":3,"-":203}},{"path":"src/test/java/teammates/sqllogic/core/CoursesLogicTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.mock;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.times;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.verify;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.when;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import static teammates.common.util.Const.ERROR_CREATE_ENTITY_ALREADY_EXISTS;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import static teammates.common.util.Const.ERROR_UPDATE_NON_EXISTENT;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import java.time.Duration;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.CoursesDb;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":30,"author":{"gitId":"-"},"content":" * SUT: {@code CoursesLogic}."},{"lineNumber":31,"author":{"gitId":"-"},"content":" */"},{"lineNumber":32,"author":{"gitId":"-"},"content":"public class CoursesLogicTest extends BaseTestCase {"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" private CoursesLogic coursesLogic \u003d CoursesLogic.inst();"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" private UsersLogic usersLogic;"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" private FeedbackSessionsLogic fsLogic;"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" private CoursesDb coursesDb;"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":43,"author":{"gitId":"-"},"content":" public void setUp() {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" coursesDb \u003d mock(CoursesDb.class);"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" fsLogic \u003d mock(FeedbackSessionsLogic.class);"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" usersLogic \u003d mock(UsersLogic.class);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" coursesLogic.initLogicDependencies(coursesDb, fsLogic, usersLogic);"},{"lineNumber":48,"author":{"gitId":"-"},"content":" }"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":51,"author":{"gitId":"-"},"content":" public void testMoveCourseToRecycleBin_shouldReturnBinnedCourse_success()"},{"lineNumber":52,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":54,"author":{"gitId":"-"},"content":" String courseId \u003d course.getId();"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(course);"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" Course binnedCourse \u003d coursesLogic.moveCourseToRecycleBin(courseId);"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" verify(coursesDb, times(1)).getCourse(courseId);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" assertNotNull(binnedCourse);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" }"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":65,"author":{"gitId":"-"},"content":" public void testMoveCourseToRecycleBin_courseDoesNotExist_throwEntityDoesNotExistException() {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" String courseId \u003d getTypicalCourse().getId();"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(null);"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" EntityDoesNotExistException ex \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" () -\u003e coursesLogic.moveCourseToRecycleBin(courseId));"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" assertEquals(\"Trying to move a non-existent course to recycling bin.\", ex.getMessage());"},{"lineNumber":74,"author":{"gitId":"-"},"content":" }"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":77,"author":{"gitId":"-"},"content":" public void testRestoreCourseFromRecycleBin_shouldSetDeletedAtToNull_success()"},{"lineNumber":78,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":80,"author":{"gitId":"-"},"content":" String courseId \u003d course.getId();"},{"lineNumber":81,"author":{"gitId":"-"},"content":" course.setDeletedAt(Instant.parse(\"2021-01-01T00:00:00Z\"));"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(course);"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" coursesLogic.restoreCourseFromRecycleBin(courseId);"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" verify(coursesDb, times(1)).getCourse(courseId);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" assertNull(course.getDeletedAt());"},{"lineNumber":89,"author":{"gitId":"-"},"content":" }"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":92,"author":{"gitId":"-"},"content":" public void testRestoreCourseFromRecycleBin_courseDoesNotExist_throwEntityDoesNotExistException() {"},{"lineNumber":93,"author":{"gitId":"-"},"content":" String courseId \u003d getTypicalCourse().getId();"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(null);"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" EntityDoesNotExistException ex \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":98,"author":{"gitId":"-"},"content":" () -\u003e coursesLogic.restoreCourseFromRecycleBin(courseId));"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" assertEquals(\"Trying to restore a non-existent course from recycling bin.\", ex.getMessage());"},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":104,"author":{"gitId":"-"},"content":" public void testGetSectionNamesForCourse_shouldReturnListOfSectionNames_success() throws EntityDoesNotExistException {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":106,"author":{"gitId":"-"},"content":" String courseId \u003d course.getId();"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" Section s1 \u003d getTypicalSection();"},{"lineNumber":109,"author":{"gitId":"-"},"content":" s1.setName(\"test-sectionName1\");"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" Section s2 \u003d getTypicalSection();"},{"lineNumber":112,"author":{"gitId":"-"},"content":" s2.setName(\"test-sectionName2\");"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" List\u003cSection\u003e sections \u003d new ArrayList\u003c\u003e();"},{"lineNumber":115,"author":{"gitId":"-"},"content":" sections.add(s1);"},{"lineNumber":116,"author":{"gitId":"-"},"content":" sections.add(s2);"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" course.setSections(sections);"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(course);"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" List\u003cString\u003e sectionNames \u003d coursesLogic.getSectionNamesForCourse(courseId);"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" verify(coursesDb, times(1)).getCourse(courseId);"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" List\u003cString\u003e expectedSectionNames \u003d List.of(\"test-sectionName1\", \"test-sectionName2\");"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" assertEquals(expectedSectionNames, sectionNames);"},{"lineNumber":129,"author":{"gitId":"-"},"content":" }"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":132,"author":{"gitId":"-"},"content":" public void testGetSectionNamesForCourse_courseDoesNotExist_throwEntityDoesNotExistException()"},{"lineNumber":133,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":134,"author":{"gitId":"-"},"content":" String courseId \u003d getTypicalCourse().getId();"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(null);"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" EntityDoesNotExistException ex \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":139,"author":{"gitId":"-"},"content":" () -\u003e coursesLogic.getSectionNamesForCourse(courseId));"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" assertEquals(\"Trying to get section names for a non-existent course.\", ex.getMessage());"},{"lineNumber":142,"author":{"gitId":"-"},"content":" }"},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":145,"author":{"gitId":"domoberzin"},"content":" public void testCreateCourse_shouldReturnCreatedCourse_success()"},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":147,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":148,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":149,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.createCourse(course)).thenReturn(course);"},{"lineNumber":150,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":151,"author":{"gitId":"domoberzin"},"content":" Course createdCourse \u003d coursesLogic.createCourse(course);"},{"lineNumber":152,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":153,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).createCourse(course);"},{"lineNumber":154,"author":{"gitId":"domoberzin"},"content":" assertNotNull(createdCourse);"},{"lineNumber":155,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":156,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":157,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":158,"author":{"gitId":"domoberzin"},"content":" public void testCreateDuplicateCourse_throwEntityAlreadyExistsException()"},{"lineNumber":159,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":160,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":161,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":162,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.createCourse(course))"},{"lineNumber":163,"author":{"gitId":"domoberzin"},"content":" .thenThrow(new EntityAlreadyExistsException("},{"lineNumber":164,"author":{"gitId":"domoberzin"},"content":" String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, course.toString())));"},{"lineNumber":165,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":" EntityAlreadyExistsException ex \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" () -\u003e coursesLogic.createCourse(course));"},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" assertEquals(String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, course.toString()), ex.getMessage());"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":171,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":172,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":" public void testGetCourse_shouldReturnCourse_success() {"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d course.getId();"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(course);"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" Course returnedCourse \u003d coursesLogic.getCourse(courseId);"},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).getCourse(courseId);"},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":" assertNotNull(returnedCourse);"},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":184,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":185,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":186,"author":{"gitId":"domoberzin"},"content":" public void testDeleteCourseCascade_shouldDeleteCourse_success() {"},{"lineNumber":187,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":188,"author":{"gitId":"domoberzin"},"content":" List\u003cInstructor\u003e instructors \u003d new ArrayList\u003c\u003e();"},{"lineNumber":189,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackSession\u003e feedbackSessions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":190,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":191,"author":{"gitId":"domoberzin"},"content":" FeedbackSession fs \u003d new FeedbackSession(\"test-fs\", course, \"test@email.com\","},{"lineNumber":192,"author":{"gitId":"domoberzin"},"content":" \"test\", Instant.now(), Instant.now(), Instant.now(), Instant.now(), Duration.ofSeconds(60),"},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":" false, false, false);"},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" feedbackSessions.add(fs);"},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" instructors.add(getTypicalInstructor());"},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":" when(fsLogic.getFeedbackSessionsForCourse(course.getId())).thenReturn(feedbackSessions);"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" when(usersLogic.getInstructorsForCourse(course.getId())).thenReturn(instructors);"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getCourse(course.getId())).thenReturn(course);"},{"lineNumber":200,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":201,"author":{"gitId":"domoberzin"},"content":" coursesLogic.deleteCourseCascade(course.getId());"},{"lineNumber":202,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":203,"author":{"gitId":"domoberzin"},"content":" verify(usersLogic, times(1)).deleteStudentsInCourseCascade(course.getId());"},{"lineNumber":204,"author":{"gitId":"domoberzin"},"content":" verify(usersLogic, times(1)).getInstructorsForCourse(course.getId());"},{"lineNumber":205,"author":{"gitId":"domoberzin"},"content":" verify(usersLogic, times(1)).deleteInstructorCascade(course.getId(), instructors.get(0).getEmail());"},{"lineNumber":206,"author":{"gitId":"domoberzin"},"content":" verify(fsLogic, times(1)).deleteFeedbackSessionCascade(fs.getName(), course.getId());"},{"lineNumber":207,"author":{"gitId":"domoberzin"},"content":" verify(fsLogic, times(1)).getFeedbackSessionsForCourse(course.getId());"},{"lineNumber":208,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).deleteCourse(course);"},{"lineNumber":209,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).deleteSectionsByCourseId(course.getId());"},{"lineNumber":210,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":211,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":212,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":213,"author":{"gitId":"domoberzin"},"content":" public void testUpdateCourse_shouldReturnUpdatedCourse_success()"},{"lineNumber":214,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":215,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":216,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d course.getId();"},{"lineNumber":217,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":218,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(course);"},{"lineNumber":219,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":220,"author":{"gitId":"domoberzin"},"content":" Course updatedCourse \u003d coursesLogic.updateCourse(courseId, \"Test Course 1\", \"Asia/India\");"},{"lineNumber":221,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":222,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).getCourse(courseId);"},{"lineNumber":223,"author":{"gitId":"domoberzin"},"content":" assertNotNull(updatedCourse);"},{"lineNumber":224,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"Test Course 1\", updatedCourse.getName());"},{"lineNumber":225,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"Asia/India\", updatedCourse.getTimeZone());"},{"lineNumber":226,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":227,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":228,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":229,"author":{"gitId":"domoberzin"},"content":" public void testUpdateCourse_throwEntityDoesNotExistException()"},{"lineNumber":230,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":231,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":232,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d course.getId();"},{"lineNumber":233,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":234,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(null);"},{"lineNumber":235,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":236,"author":{"gitId":"domoberzin"},"content":" EntityDoesNotExistException ex \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":237,"author":{"gitId":"domoberzin"},"content":" () -\u003e coursesLogic.updateCourse(courseId, course.getName(), \"Asia/Singapore\"));"},{"lineNumber":238,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":239,"author":{"gitId":"domoberzin"},"content":" assertEquals(ERROR_UPDATE_NON_EXISTENT + Course.class, ex.getMessage());"},{"lineNumber":240,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":241,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":242,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":243,"author":{"gitId":"domoberzin"},"content":" public void testUpdateCourse_throwInvalidParametersException()"},{"lineNumber":244,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":245,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":246,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d course.getId();"},{"lineNumber":247,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":248,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(course);"},{"lineNumber":249,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":250,"author":{"gitId":"domoberzin"},"content":" InvalidParametersException ex \u003d assertThrows(InvalidParametersException.class,"},{"lineNumber":251,"author":{"gitId":"domoberzin"},"content":" () -\u003e coursesLogic.updateCourse(courseId, \"\", \"Asia/Singapore\"));"},{"lineNumber":252,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":253,"author":{"gitId":"domoberzin"},"content":" String expectedMessage \u003d \"The field \u0027course name\u0027 is empty.\""},{"lineNumber":254,"author":{"gitId":"domoberzin"},"content":" + \" The value of a/an course name should be no longer than 80 characters.\""},{"lineNumber":255,"author":{"gitId":"domoberzin"},"content":" + \" It should not be empty.\";"},{"lineNumber":256,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":257,"author":{"gitId":"domoberzin"},"content":" assertEquals(expectedMessage, ex.getMessage());"},{"lineNumber":258,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":259,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":260,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":261,"author":{"gitId":"domoberzin"},"content":" public void testCreateSection_shouldReturnCreatedSection_success()"},{"lineNumber":262,"author":{"gitId":"domoberzin"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":263,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":264,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":265,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.createSection(section)).thenReturn(section);"},{"lineNumber":266,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":267,"author":{"gitId":"domoberzin"},"content":" Section createdSection \u003d coursesLogic.createSection(section);"},{"lineNumber":268,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":269,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).createSection(section);"},{"lineNumber":270,"author":{"gitId":"domoberzin"},"content":" assertNotNull(createdSection);"},{"lineNumber":271,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":272,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":273,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":274,"author":{"gitId":"domoberzin"},"content":" public void testCreateDuplicateSection_throwEntityAlreadyExistsException()"},{"lineNumber":275,"author":{"gitId":"domoberzin"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":276,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":277,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":278,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.createSection(section))"},{"lineNumber":279,"author":{"gitId":"domoberzin"},"content":" .thenThrow(new EntityAlreadyExistsException("},{"lineNumber":280,"author":{"gitId":"domoberzin"},"content":" String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, section.toString())));"},{"lineNumber":281,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":282,"author":{"gitId":"domoberzin"},"content":" EntityAlreadyExistsException ex \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":283,"author":{"gitId":"domoberzin"},"content":" () -\u003e coursesLogic.createSection(section));"},{"lineNumber":284,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":285,"author":{"gitId":"domoberzin"},"content":" assertEquals(String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, section.toString()), ex.getMessage());"},{"lineNumber":286,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":287,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":288,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":289,"author":{"gitId":"domoberzin"},"content":" public void testCreateSectionInvalidName_throwInvalidParametersException()"},{"lineNumber":290,"author":{"gitId":"domoberzin"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":291,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":292,"author":{"gitId":"domoberzin"},"content":" section.setName(null);"},{"lineNumber":293,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":294,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.createSection(section)).thenThrow(new InvalidParametersException(section.getInvalidityInfo()));"},{"lineNumber":295,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":296,"author":{"gitId":"domoberzin"},"content":" InvalidParametersException ex \u003d assertThrows(InvalidParametersException.class,"},{"lineNumber":297,"author":{"gitId":"domoberzin"},"content":" () -\u003e coursesLogic.createSection(section));"},{"lineNumber":298,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":299,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"The provided section name is not acceptable to TEAMMATES as it cannot be empty.\", ex.getMessage());"},{"lineNumber":300,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":301,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":302,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":303,"author":{"gitId":"domoberzin"},"content":" public void testGetSectionByCourseIdAndTeam_shouldReturnSection_success() {"},{"lineNumber":304,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":305,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d section.getCourse().getId();"},{"lineNumber":306,"author":{"gitId":"domoberzin"},"content":" String teamName \u003d section.getName();"},{"lineNumber":307,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":308,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getSectionByCourseIdAndTeam(courseId, teamName)).thenReturn(section);"},{"lineNumber":309,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":310,"author":{"gitId":"domoberzin"},"content":" Section returnedSection \u003d coursesLogic.getSectionByCourseIdAndTeam(courseId, teamName);"},{"lineNumber":311,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":312,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).getSectionByCourseIdAndTeam(courseId, teamName);"},{"lineNumber":313,"author":{"gitId":"domoberzin"},"content":" assertNotNull(returnedSection);"},{"lineNumber":314,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":315,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":316,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":317,"author":{"gitId":"domoberzin"},"content":" public void testGetSectionByCourseIdAndTeam_sectionDoesNotExist_returnNull() {"},{"lineNumber":318,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d getTypicalCourse().getId();"},{"lineNumber":319,"author":{"gitId":"domoberzin"},"content":" String teamName \u003d getTypicalSection().getName();"},{"lineNumber":320,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":321,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getSectionByCourseIdAndTeam(courseId, teamName)).thenReturn(null);"},{"lineNumber":322,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":323,"author":{"gitId":"domoberzin"},"content":" Section returnedSection \u003d coursesLogic.getSectionByCourseIdAndTeam(courseId, teamName);"},{"lineNumber":324,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":325,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).getSectionByCourseIdAndTeam(courseId, teamName);"},{"lineNumber":326,"author":{"gitId":"domoberzin"},"content":" assertNull(returnedSection);"},{"lineNumber":327,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":328,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":329,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":330,"author":{"gitId":"domoberzin"},"content":" public void testGetCourseInstitute_shouldReturnInstitute_success() {"},{"lineNumber":331,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":332,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d course.getId();"},{"lineNumber":333,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":334,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(course);"},{"lineNumber":335,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":336,"author":{"gitId":"domoberzin"},"content":" String institute \u003d coursesLogic.getCourseInstitute(courseId);"},{"lineNumber":337,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":338,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).getCourse(courseId);"},{"lineNumber":339,"author":{"gitId":"domoberzin"},"content":" assertNotNull(institute);"},{"lineNumber":340,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":341,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":342,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":343,"author":{"gitId":"domoberzin"},"content":" public void testGetCourseInstituteNonExistentCourse_throwAssertionError() {"},{"lineNumber":344,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":345,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d course.getId();"},{"lineNumber":346,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":347,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(null);"},{"lineNumber":348,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":349,"author":{"gitId":"domoberzin"},"content":" AssertionError ex \u003d assertThrows(AssertionError.class,"},{"lineNumber":350,"author":{"gitId":"domoberzin"},"content":" () -\u003e coursesLogic.getCourseInstitute(courseId));"},{"lineNumber":351,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":352,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"Trying to getCourseInstitute for inexistent course with id \" + courseId, ex.getMessage());"},{"lineNumber":353,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":354,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":355,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":356,"author":{"gitId":"domoberzin"},"content":" public void testCreateTeam_shouldReturnCreatedTeam_success()"},{"lineNumber":357,"author":{"gitId":"domoberzin"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":358,"author":{"gitId":"domoberzin"},"content":" Team team \u003d getTypicalTeam();"},{"lineNumber":359,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":360,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.createTeam(team)).thenReturn(team);"},{"lineNumber":361,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":362,"author":{"gitId":"domoberzin"},"content":" Team createdTeam \u003d coursesLogic.createTeam(team);"},{"lineNumber":363,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":364,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).createTeam(team);"},{"lineNumber":365,"author":{"gitId":"domoberzin"},"content":" assertNotNull(createdTeam);"},{"lineNumber":366,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":367,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":368,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":369,"author":{"gitId":"domoberzin"},"content":" public void testCreateDuplicateTeam_throwEntityAlreadyExistsException()"},{"lineNumber":370,"author":{"gitId":"domoberzin"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":371,"author":{"gitId":"domoberzin"},"content":" Team team \u003d getTypicalTeam();"},{"lineNumber":372,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":373,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.createTeam(team)).thenThrow("},{"lineNumber":374,"author":{"gitId":"domoberzin"},"content":" new EntityAlreadyExistsException("},{"lineNumber":375,"author":{"gitId":"domoberzin"},"content":" String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, team.toString())));"},{"lineNumber":376,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":377,"author":{"gitId":"domoberzin"},"content":" EntityAlreadyExistsException ex \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":378,"author":{"gitId":"domoberzin"},"content":" () -\u003e coursesLogic.createTeam(team));"},{"lineNumber":379,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":380,"author":{"gitId":"domoberzin"},"content":" assertEquals(String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, team.toString()), ex.getMessage());"},{"lineNumber":381,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":382,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":383,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":384,"author":{"gitId":"domoberzin"},"content":" public void testCreateTeamInvalidName_throwInvalidParametersException()"},{"lineNumber":385,"author":{"gitId":"domoberzin"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":386,"author":{"gitId":"domoberzin"},"content":" Team team \u003d getTypicalTeam();"},{"lineNumber":387,"author":{"gitId":"domoberzin"},"content":" team.setName(null);"},{"lineNumber":388,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":389,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.createTeam(team)).thenThrow(new InvalidParametersException(team.getInvalidityInfo()));"},{"lineNumber":390,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":391,"author":{"gitId":"domoberzin"},"content":" InvalidParametersException ex \u003d assertThrows(InvalidParametersException.class,"},{"lineNumber":392,"author":{"gitId":"domoberzin"},"content":" () -\u003e coursesLogic.createTeam(team));"},{"lineNumber":393,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":394,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"The provided team name is not acceptable to TEAMMATES as it cannot be empty.\", ex.getMessage());"},{"lineNumber":395,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":396,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":397,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":398,"author":{"gitId":"domoberzin"},"content":" public void testGetTeamsForSection_shouldReturnListOfTeams_success() {"},{"lineNumber":399,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":400,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":401,"author":{"gitId":"domoberzin"},"content":" Team t1 \u003d getTypicalTeam();"},{"lineNumber":402,"author":{"gitId":"domoberzin"},"content":" t1.setName(\"test-teamName1\");"},{"lineNumber":403,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":404,"author":{"gitId":"domoberzin"},"content":" Team t2 \u003d getTypicalTeam();"},{"lineNumber":405,"author":{"gitId":"domoberzin"},"content":" t2.setName(\"test-teamName2\");"},{"lineNumber":406,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":407,"author":{"gitId":"domoberzin"},"content":" List\u003cTeam\u003e teams \u003d new ArrayList\u003c\u003e();"},{"lineNumber":408,"author":{"gitId":"domoberzin"},"content":" teams.add(t1);"},{"lineNumber":409,"author":{"gitId":"domoberzin"},"content":" teams.add(t2);"},{"lineNumber":410,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":411,"author":{"gitId":"domoberzin"},"content":" section.setTeams(teams);"},{"lineNumber":412,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":413,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getTeamsForSection(section)).thenReturn(teams);"},{"lineNumber":414,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":415,"author":{"gitId":"domoberzin"},"content":" List\u003cTeam\u003e returnedTeams \u003d coursesLogic.getTeamsForSection(section);"},{"lineNumber":416,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":417,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).getTeamsForSection(section);"},{"lineNumber":418,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":419,"author":{"gitId":"domoberzin"},"content":" List\u003cTeam\u003e expectedTeams \u003d List.of(t1, t2);"},{"lineNumber":420,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":421,"author":{"gitId":"domoberzin"},"content":" assertEquals(expectedTeams, returnedTeams);"},{"lineNumber":422,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":423,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":424,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":425,"author":{"gitId":"domoberzin"},"content":" public void testGetTeamsForCourse_shouldReturnListOfTeams_success() {"},{"lineNumber":426,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":427,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":428,"author":{"gitId":"domoberzin"},"content":" Team t1 \u003d getTypicalTeam();"},{"lineNumber":429,"author":{"gitId":"domoberzin"},"content":" t1.setName(\"test-teamName1\");"},{"lineNumber":430,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":431,"author":{"gitId":"domoberzin"},"content":" Team t2 \u003d getTypicalTeam();"},{"lineNumber":432,"author":{"gitId":"domoberzin"},"content":" t2.setName(\"test-teamName2\");"},{"lineNumber":433,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":434,"author":{"gitId":"domoberzin"},"content":" List\u003cTeam\u003e teams \u003d new ArrayList\u003c\u003e();"},{"lineNumber":435,"author":{"gitId":"domoberzin"},"content":" teams.add(t1);"},{"lineNumber":436,"author":{"gitId":"domoberzin"},"content":" teams.add(t2);"},{"lineNumber":437,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":438,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getTeamsForCourse(course.getId())).thenReturn(teams);"},{"lineNumber":439,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":440,"author":{"gitId":"domoberzin"},"content":" List\u003cTeam\u003e returnedTeams \u003d coursesLogic.getTeamsForCourse(course.getId());"},{"lineNumber":441,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":442,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).getTeamsForCourse(course.getId());"},{"lineNumber":443,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":444,"author":{"gitId":"domoberzin"},"content":" List\u003cTeam\u003e expectedTeams \u003d List.of(t1, t2);"},{"lineNumber":445,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":446,"author":{"gitId":"domoberzin"},"content":" assertEquals(expectedTeams, returnedTeams);"},{"lineNumber":447,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":448,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":319,"-":129}},{"path":"src/test/java/teammates/sqllogic/core/FeedbackQuestionsLogicTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.mock;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.when;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlCourseRoster;"},{"lineNumber":15,"author":{"gitId":"marquestye"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackQuestionsDb;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * SUT: {@link FeedbackQuestionsLogic}."},{"lineNumber":26,"author":{"gitId":"-"},"content":" */"},{"lineNumber":27,"author":{"gitId":"-"},"content":"public class FeedbackQuestionsLogicTest extends BaseTestCase {"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" private FeedbackQuestionsLogic fqLogic \u003d FeedbackQuestionsLogic.inst();"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" private FeedbackQuestionsDb fqDb;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private UsersLogic usersLogic;"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":36,"author":{"gitId":"-"},"content":" public void setUpMethod() {"},{"lineNumber":37,"author":{"gitId":"-"},"content":" fqDb \u003d mock(FeedbackQuestionsDb.class);"},{"lineNumber":38,"author":{"gitId":"-"},"content":" CoursesLogic coursesLogic \u003d mock(CoursesLogic.class);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" usersLogic \u003d mock(UsersLogic.class);"},{"lineNumber":40,"author":{"gitId":"-"},"content":" FeedbackResponsesLogic frLogic \u003d mock(FeedbackResponsesLogic.class);"},{"lineNumber":41,"author":{"gitId":"-"},"content":" FeedbackSessionsLogic feedbackSessionsLogic \u003d mock(FeedbackSessionsLogic.class);"},{"lineNumber":42,"author":{"gitId":"-"},"content":" fqLogic.initLogicDependencies(fqDb, coursesLogic, frLogic, usersLogic, feedbackSessionsLogic);"},{"lineNumber":43,"author":{"gitId":"-"},"content":" }"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":46,"author":{"gitId":"-"},"content":" public void testGetFeedbackQuestionsForSession_questionNumbersInOrder_success() {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":48,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questions \u003d createQuestionList(fs, 5);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" fs.setId(UUID.randomUUID());"},{"lineNumber":52,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForSession(fs.getId())).thenReturn(questions);"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e actualQuestions \u003d fqLogic.getFeedbackQuestionsForSession(fs);"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" assertEquals(questions.size(), actualQuestions.size());"},{"lineNumber":57,"author":{"gitId":"-"},"content":" assertTrue(questions.containsAll(actualQuestions));"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":61,"author":{"gitId":"-"},"content":" public void testGetFeedbackQuestionsForSession_questionNumbersOutOfOrder_success() {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":63,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" FeedbackQuestion fq3 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" FeedbackQuestion fq4 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" FeedbackQuestion fq5 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" fq1.setQuestionNumber(1);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" fq2.setQuestionNumber(2);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" fq3.setQuestionNumber(3);"},{"lineNumber":73,"author":{"gitId":"-"},"content":" fq4.setQuestionNumber(4);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" fq5.setQuestionNumber(5);"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questions \u003d new ArrayList\u003c\u003e(List.of(fq2, fq4, fq3, fq1, fq5));"},{"lineNumber":77,"author":{"gitId":"-"},"content":" fs.setId(UUID.randomUUID());"},{"lineNumber":78,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForSession(fs.getId())).thenReturn(questions);"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e actualQuestions \u003d fqLogic.getFeedbackQuestionsForSession(fs);"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" assertEquals(questions.size(), actualQuestions.size());"},{"lineNumber":83,"author":{"gitId":"-"},"content":" assertTrue(questions.containsAll(actualQuestions));"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":87,"author":{"gitId":"-"},"content":" public void testCreateFeedbackQuestion_questionNumbersAreConsistent_canCreateFeedbackQuestion()"},{"lineNumber":88,"author":{"gitId":"marquestye"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":89,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":90,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" FeedbackQuestion newQuestion \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" newQuestion.setQuestionNumber(5);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsBefore \u003d createQuestionList(fs, 4);"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" fs.setId(UUID.randomUUID());"},{"lineNumber":97,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForSession(fs.getId())).thenReturn(questionsBefore);"},{"lineNumber":98,"author":{"gitId":"-"},"content":" when(fqDb.createFeedbackQuestion(newQuestion)).thenReturn(newQuestion);"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" FeedbackQuestion createdQuestion \u003d fqLogic.createFeedbackQuestion(newQuestion);"},{"lineNumber":101,"author":{"gitId":"-"},"content":" assertEquals(newQuestion, createdQuestion);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":105,"author":{"gitId":"-"},"content":" public void testCreateFeedbackQuestion_questionNumbersAreInconsistent_canCreateFeedbackQuestion()"},{"lineNumber":106,"author":{"gitId":"marquestye"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":108,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" FeedbackQuestion fq3 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":112,"author":{"gitId":"-"},"content":" FeedbackQuestion fq4 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" FeedbackQuestion fq5 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" fq1.setQuestionNumber(2);"},{"lineNumber":115,"author":{"gitId":"-"},"content":" fq2.setQuestionNumber(3);"},{"lineNumber":116,"author":{"gitId":"-"},"content":" fq3.setQuestionNumber(4);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" fq4.setQuestionNumber(5);"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsBefore \u003d new ArrayList\u003c\u003e(List.of(fq1, fq2, fq3, fq4));"},{"lineNumber":120,"author":{"gitId":"-"},"content":" fs.setId(UUID.randomUUID());"},{"lineNumber":121,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForSession(fs.getId())).thenReturn(questionsBefore);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" when(fqDb.createFeedbackQuestion(fq5)).thenReturn(fq5);"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" FeedbackQuestion createdQuestion \u003d fqLogic.createFeedbackQuestion(fq5);"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" assertEquals(fq5, createdQuestion);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" @Test(enabled \u003d false)"},{"lineNumber":130,"author":{"gitId":"-"},"content":" public void testCreateFeedbackQuestion_oldQuestionNumberLargerThanNewQuestionNumber_adjustQuestionNumberCorrectly()"},{"lineNumber":131,"author":{"gitId":"marquestye"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":133,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":135,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" FeedbackQuestion fq3 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" FeedbackQuestion fq4 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":138,"author":{"gitId":"-"},"content":" FeedbackQuestion fq5 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" fq1.setQuestionNumber(2);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" fq2.setQuestionNumber(3);"},{"lineNumber":141,"author":{"gitId":"-"},"content":" fq3.setQuestionNumber(4);"},{"lineNumber":142,"author":{"gitId":"-"},"content":" fq4.setQuestionNumber(5);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" fq5.setQuestionNumber(1);"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsBefore \u003d new ArrayList\u003c\u003e(List.of(fq1, fq2, fq3, fq4));"},{"lineNumber":146,"author":{"gitId":"-"},"content":" fs.setId(UUID.randomUUID());"},{"lineNumber":147,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForSession(fs.getId())).thenReturn(questionsBefore);"},{"lineNumber":148,"author":{"gitId":"-"},"content":" when(fqDb.createFeedbackQuestion(fq5)).thenReturn(fq5);"},{"lineNumber":149,"author":{"gitId":"-"},"content":""},{"lineNumber":150,"author":{"gitId":"-"},"content":" fqLogic.createFeedbackQuestion(fq5);"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" assertEquals(1, fq1.getQuestionNumber().intValue());"},{"lineNumber":153,"author":{"gitId":"-"},"content":" assertEquals(2, fq2.getQuestionNumber().intValue());"},{"lineNumber":154,"author":{"gitId":"-"},"content":" assertEquals(3, fq3.getQuestionNumber().intValue());"},{"lineNumber":155,"author":{"gitId":"-"},"content":" assertEquals(4, fq4.getQuestionNumber().intValue());"},{"lineNumber":156,"author":{"gitId":"-"},"content":" }"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"-"},"content":" @Test(enabled \u003d false)"},{"lineNumber":159,"author":{"gitId":"-"},"content":" public void testCreateFeedbackQuestion_oldQuestionNumberSmallerThanNewQuestionNumber_adjustQuestionNumberCorrectly()"},{"lineNumber":160,"author":{"gitId":"marquestye"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":161,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":162,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":164,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":165,"author":{"gitId":"-"},"content":" FeedbackQuestion fq3 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":166,"author":{"gitId":"-"},"content":" FeedbackQuestion fq4 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":167,"author":{"gitId":"-"},"content":" FeedbackQuestion fq5 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":168,"author":{"gitId":"-"},"content":" fq1.setQuestionNumber(0);"},{"lineNumber":169,"author":{"gitId":"-"},"content":" fq2.setQuestionNumber(1);"},{"lineNumber":170,"author":{"gitId":"-"},"content":" fq3.setQuestionNumber(2);"},{"lineNumber":171,"author":{"gitId":"-"},"content":" fq4.setQuestionNumber(3);"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsBefore \u003d new ArrayList\u003c\u003e(List.of(fq1, fq2, fq3, fq4));"},{"lineNumber":174,"author":{"gitId":"-"},"content":" fs.setId(UUID.randomUUID());"},{"lineNumber":175,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForSession(fs.getId())).thenReturn(questionsBefore);"},{"lineNumber":176,"author":{"gitId":"-"},"content":" when(fqDb.createFeedbackQuestion(fq5)).thenReturn(fq5);"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" fqLogic.createFeedbackQuestion(fq5);"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" assertEquals(1, fq1.getQuestionNumber().intValue());"},{"lineNumber":181,"author":{"gitId":"-"},"content":" assertEquals(2, fq2.getQuestionNumber().intValue());"},{"lineNumber":182,"author":{"gitId":"-"},"content":" assertEquals(3, fq3.getQuestionNumber().intValue());"},{"lineNumber":183,"author":{"gitId":"-"},"content":" assertEquals(4, fq4.getQuestionNumber().intValue());"},{"lineNumber":184,"author":{"gitId":"-"},"content":" }"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":187,"author":{"gitId":"-"},"content":" public void testGetFeedbackQuestionsForStudents_success() {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":189,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":190,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":191,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":192,"author":{"gitId":"-"},"content":" FeedbackQuestion fq3 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":193,"author":{"gitId":"-"},"content":" FeedbackQuestion fq4 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsSelf \u003d List.of(fq1, fq2);"},{"lineNumber":196,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsStudent \u003d List.of(fq3, fq4);"},{"lineNumber":197,"author":{"gitId":"-"},"content":""},{"lineNumber":198,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e expectedQuestions \u003d List.of(fq1, fq2, fq3, fq4);"},{"lineNumber":199,"author":{"gitId":"-"},"content":""},{"lineNumber":200,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForGiverType(fs, FeedbackParticipantType.SELF)).thenReturn(questionsSelf);"},{"lineNumber":201,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForGiverType(fs, FeedbackParticipantType.STUDENTS)).thenReturn(questionsStudent);"},{"lineNumber":202,"author":{"gitId":"-"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e actualQuestions \u003d fqLogic.getFeedbackQuestionsForStudents(fs);"},{"lineNumber":204,"author":{"gitId":"-"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestions.size(), actualQuestions.size());"},{"lineNumber":206,"author":{"gitId":"-"},"content":" assertTrue(actualQuestions.containsAll(actualQuestions));"},{"lineNumber":207,"author":{"gitId":"-"},"content":" }"},{"lineNumber":208,"author":{"gitId":"-"},"content":""},{"lineNumber":209,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":210,"author":{"gitId":"-"},"content":" public void testGetFeedbackQuestionsForInstructors_instructorIsCreator_success() {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":212,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":213,"author":{"gitId":"-"},"content":" fs.setCreatorEmail(\"instr1@teammates.tmt\");"},{"lineNumber":214,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":215,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":216,"author":{"gitId":"-"},"content":" FeedbackQuestion fq3 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":217,"author":{"gitId":"-"},"content":" FeedbackQuestion fq4 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsInstructors \u003d List.of(fq1, fq2);"},{"lineNumber":220,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsSelf \u003d List.of(fq3, fq4);"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForGiverType(fs, FeedbackParticipantType.INSTRUCTORS))"},{"lineNumber":223,"author":{"gitId":"-"},"content":" .thenReturn(questionsInstructors);"},{"lineNumber":224,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForGiverType(fs, FeedbackParticipantType.SELF)).thenReturn(questionsSelf);"},{"lineNumber":225,"author":{"gitId":"-"},"content":""},{"lineNumber":226,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e expectedQuestions \u003d List.of(fq1, fq2, fq3, fq4);"},{"lineNumber":227,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e actualQuestions \u003d fqLogic.getFeedbackQuestionsForInstructors(fs, \"instr1@teammates.tmt\");"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestions.size(), actualQuestions.size());"},{"lineNumber":230,"author":{"gitId":"-"},"content":" assertTrue(actualQuestions.containsAll(actualQuestions));"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":234,"author":{"gitId":"-"},"content":" public void testGetFeedbackQuestionsForInstructors_instructorIsNotCreator_success() {"},{"lineNumber":235,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":236,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":237,"author":{"gitId":"-"},"content":" fs.setCreatorEmail(\"instr1@teammates.tmt\");"},{"lineNumber":238,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":239,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":240,"author":{"gitId":"-"},"content":" FeedbackQuestion fq3 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":241,"author":{"gitId":"-"},"content":" FeedbackQuestion fq4 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":242,"author":{"gitId":"-"},"content":""},{"lineNumber":243,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsInstructors \u003d List.of(fq1, fq2);"},{"lineNumber":244,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsSelf \u003d List.of(fq3, fq4);"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForGiverType(fs, FeedbackParticipantType.INSTRUCTORS))"},{"lineNumber":247,"author":{"gitId":"-"},"content":" .thenReturn(questionsInstructors);"},{"lineNumber":248,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForGiverType(fs, FeedbackParticipantType.SELF)).thenReturn(questionsSelf);"},{"lineNumber":249,"author":{"gitId":"-"},"content":""},{"lineNumber":250,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e expectedQuestions \u003d List.of(fq1, fq2);"},{"lineNumber":251,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e actualQuestions \u003d fqLogic.getFeedbackQuestionsForInstructors(fs, \"instr2@teammates.tmt\");"},{"lineNumber":252,"author":{"gitId":"-"},"content":""},{"lineNumber":253,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestions.size(), actualQuestions.size());"},{"lineNumber":254,"author":{"gitId":"-"},"content":" assertTrue(actualQuestions.containsAll(actualQuestions));"},{"lineNumber":255,"author":{"gitId":"-"},"content":" }"},{"lineNumber":256,"author":{"gitId":"-"},"content":""},{"lineNumber":257,"author":{"gitId":"-"},"content":" @Test(enabled \u003d false)"},{"lineNumber":258,"author":{"gitId":"-"},"content":" public void testGetRecipientsOfQuestion_giverTypeStudents() {"},{"lineNumber":259,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":260,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":261,"author":{"gitId":"-"},"content":" FeedbackQuestion fq \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":262,"author":{"gitId":"-"},"content":""},{"lineNumber":263,"author":{"gitId":"-"},"content":" Student s1 \u003d getTypicalStudent();"},{"lineNumber":264,"author":{"gitId":"-"},"content":" Student s2 \u003d getTypicalStudent();"},{"lineNumber":265,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e studentsInCourse \u003d List.of(s1, s2);"},{"lineNumber":266,"author":{"gitId":"-"},"content":""},{"lineNumber":267,"author":{"gitId":"-"},"content":" SqlCourseRoster courseRoster \u003d new SqlCourseRoster(studentsInCourse, null);"},{"lineNumber":268,"author":{"gitId":"-"},"content":""},{"lineNumber":269,"author":{"gitId":"-"},"content":" when(usersLogic.getStudentsForCourse(\"course-1\")).thenReturn(studentsInCourse);"},{"lineNumber":270,"author":{"gitId":"-"},"content":""},{"lineNumber":271,"author":{"gitId":"-"},"content":" ______TS(\"response to students except self\");"},{"lineNumber":272,"author":{"gitId":"-"},"content":" assertEquals(fqLogic.getRecipientsOfQuestion(fq, null, s2, null).size(), studentsInCourse.size() - 1);"},{"lineNumber":273,"author":{"gitId":"-"},"content":" assertEquals(fqLogic.getRecipientsOfQuestion(fq, null, s2, courseRoster).size(), studentsInCourse.size() - 1);"},{"lineNumber":274,"author":{"gitId":"-"},"content":""},{"lineNumber":275,"author":{"gitId":"-"},"content":" }"},{"lineNumber":276,"author":{"gitId":"-"},"content":""},{"lineNumber":277,"author":{"gitId":"-"},"content":" private List\u003cFeedbackQuestion\u003e createQuestionList(FeedbackSession fs, int numOfQuestions) {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":279,"author":{"gitId":"-"},"content":" for (int i \u003d 1; i \u003c\u003d numOfQuestions; i++) {"},{"lineNumber":280,"author":{"gitId":"-"},"content":" FeedbackQuestion fq \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":281,"author":{"gitId":"-"},"content":" fq.setQuestionNumber(i);"},{"lineNumber":282,"author":{"gitId":"-"},"content":" questions.add(fq);"},{"lineNumber":283,"author":{"gitId":"-"},"content":" }"},{"lineNumber":284,"author":{"gitId":"-"},"content":" return questions;"},{"lineNumber":285,"author":{"gitId":"-"},"content":" }"},{"lineNumber":286,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":5,"-":281}},{"path":"src/test/java/teammates/sqllogic/core/FeedbackResponseCommentsLogicTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"mingyuanc"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":3,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.Mockito.mock;"},{"lineNumber":4,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.Mockito.times;"},{"lineNumber":5,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.Mockito.verify;"},{"lineNumber":6,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.Mockito.when;"},{"lineNumber":7,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":8,"author":{"gitId":"mingyuanc"},"content":"import java.util.ArrayList;"},{"lineNumber":9,"author":{"gitId":"mingyuanc"},"content":"import java.util.List;"},{"lineNumber":10,"author":{"gitId":"mingyuanc"},"content":"import java.util.UUID;"},{"lineNumber":11,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":12,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":13,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.Test;"},{"lineNumber":14,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":15,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":16,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":17,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":18,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":19,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlapi.FeedbackResponseCommentsDb;"},{"lineNumber":20,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":21,"author":{"gitId":"mingyuanc"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":22,"author":{"gitId":"mingyuanc"},"content":"import teammates.ui.output.CommentVisibilityType;"},{"lineNumber":23,"author":{"gitId":"mingyuanc"},"content":"import teammates.ui.request.FeedbackResponseCommentUpdateRequest;"},{"lineNumber":24,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":25,"author":{"gitId":"mingyuanc"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"mingyuanc"},"content":" * SUT: {@link FeedbackResponseCommentsLogic}."},{"lineNumber":27,"author":{"gitId":"mingyuanc"},"content":" */"},{"lineNumber":28,"author":{"gitId":"mingyuanc"},"content":"public class FeedbackResponseCommentsLogicTest extends BaseTestCase {"},{"lineNumber":29,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":30,"author":{"gitId":"mingyuanc"},"content":" private static final Long TYPICAL_ID \u003d 100L;"},{"lineNumber":31,"author":{"gitId":"mingyuanc"},"content":" private static final Long NOT_TYPICAL_ID \u003d 101L;"},{"lineNumber":32,"author":{"gitId":"mingyuanc"},"content":" private static final UUID TYPICAL_UUID \u003d UUID.randomUUID();"},{"lineNumber":33,"author":{"gitId":"mingyuanc"},"content":" private FeedbackResponseCommentsLogic frcLogic \u003d FeedbackResponseCommentsLogic.inst();"},{"lineNumber":34,"author":{"gitId":"mingyuanc"},"content":" private FeedbackResponseCommentsDb frcDb;"},{"lineNumber":35,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":36,"author":{"gitId":"mingyuanc"},"content":" @BeforeMethod"},{"lineNumber":37,"author":{"gitId":"mingyuanc"},"content":" public void setUpMethod() {"},{"lineNumber":38,"author":{"gitId":"mingyuanc"},"content":" frcDb \u003d mock(FeedbackResponseCommentsDb.class);"},{"lineNumber":39,"author":{"gitId":"mingyuanc"},"content":" frcLogic.initLogicDependencies(frcDb);"},{"lineNumber":40,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":41,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":42,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":43,"author":{"gitId":"mingyuanc"},"content":" public void testGetComment_commentAlreadyExists_success() {"},{"lineNumber":44,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":45,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":46,"author":{"gitId":"mingyuanc"},"content":" when(frcDb.getFeedbackResponseComment(comment.getId())).thenReturn(comment);"},{"lineNumber":47,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":48,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment commentFetched \u003d frcLogic.getFeedbackResponseComment(TYPICAL_ID);"},{"lineNumber":49,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":50,"author":{"gitId":"mingyuanc"},"content":" assertEquals(comment, commentFetched);"},{"lineNumber":51,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":52,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":53,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":54,"author":{"gitId":"mingyuanc"},"content":" public void testGetCommentForResponse_commentAlreadyExists_success() {"},{"lineNumber":55,"author":{"gitId":"mingyuanc"},"content":" List\u003cFeedbackResponseComment\u003e expectedReturn \u003d new ArrayList\u003c\u003e();"},{"lineNumber":56,"author":{"gitId":"mingyuanc"},"content":" expectedReturn.add(getTypicalResponseComment(TYPICAL_ID));"},{"lineNumber":57,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":58,"author":{"gitId":"mingyuanc"},"content":" when(frcDb.getFeedbackResponseCommentsForResponse(TYPICAL_UUID)).thenReturn(expectedReturn);"},{"lineNumber":59,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":60,"author":{"gitId":"mingyuanc"},"content":" List\u003cFeedbackResponseComment\u003e fetchedReturn \u003d frcLogic.getFeedbackResponseCommentsForResponse(TYPICAL_UUID);"},{"lineNumber":61,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":62,"author":{"gitId":"mingyuanc"},"content":" assertEquals(expectedReturn, fetchedReturn);"},{"lineNumber":63,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":64,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":65,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":66,"author":{"gitId":"mingyuanc"},"content":" public void testGetCommentForResponseFromParticipant_commentAlreadyExists_success() {"},{"lineNumber":67,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":68,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":69,"author":{"gitId":"mingyuanc"},"content":" when(frcDb.getFeedbackResponseCommentForResponseFromParticipant(TYPICAL_UUID)).thenReturn(comment);"},{"lineNumber":70,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":71,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment commentFetched \u003d frcLogic"},{"lineNumber":72,"author":{"gitId":"mingyuanc"},"content":" .getFeedbackResponseCommentForResponseFromParticipant(TYPICAL_UUID);"},{"lineNumber":73,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":74,"author":{"gitId":"mingyuanc"},"content":" assertEquals(comment, commentFetched);"},{"lineNumber":75,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":76,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":77,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":78,"author":{"gitId":"mingyuanc"},"content":" public void testGetComment_commentDoesNotExist_returnsNull() {"},{"lineNumber":79,"author":{"gitId":"mingyuanc"},"content":" when(frcDb.getFeedbackResponseComment(NOT_TYPICAL_ID)).thenReturn(null);"},{"lineNumber":80,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":81,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment commentFetched \u003d frcLogic.getFeedbackResponseComment(NOT_TYPICAL_ID);"},{"lineNumber":82,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":83,"author":{"gitId":"mingyuanc"},"content":" verify(frcDb, times(1)).getFeedbackResponseComment(NOT_TYPICAL_ID);"},{"lineNumber":84,"author":{"gitId":"mingyuanc"},"content":" assertNull(commentFetched);"},{"lineNumber":85,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":86,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":87,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":88,"author":{"gitId":"mingyuanc"},"content":" public void testCreateComment_commentDoesNotExist_success()"},{"lineNumber":89,"author":{"gitId":"mingyuanc"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":90,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":91,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":92,"author":{"gitId":"mingyuanc"},"content":" frcLogic.createFeedbackResponseComment(comment);"},{"lineNumber":93,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":94,"author":{"gitId":"mingyuanc"},"content":" verify(frcDb, times(1)).createFeedbackResponseComment(comment);"},{"lineNumber":95,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":96,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":97,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":98,"author":{"gitId":"mingyuanc"},"content":" public void testCreateComment_commentAlreadyExists_throwsEntityAlreadyExistsException()"},{"lineNumber":99,"author":{"gitId":"mingyuanc"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":100,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":101,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":102,"author":{"gitId":"mingyuanc"},"content":" when(frcDb.createFeedbackResponseComment(comment)).thenThrow(EntityAlreadyExistsException.class);"},{"lineNumber":103,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":104,"author":{"gitId":"mingyuanc"},"content":" assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":105,"author":{"gitId":"mingyuanc"},"content":" () -\u003e frcLogic.createFeedbackResponseComment(comment));"},{"lineNumber":106,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":107,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":108,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":109,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":110,"author":{"gitId":"mingyuanc"},"content":" public void testDeleteComment_commentExists_success() {"},{"lineNumber":111,"author":{"gitId":"mingyuanc"},"content":" frcLogic.deleteFeedbackResponseComment(TYPICAL_ID);"},{"lineNumber":112,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":113,"author":{"gitId":"mingyuanc"},"content":" verify(frcDb, times(1)).deleteFeedbackResponseComment(TYPICAL_ID);"},{"lineNumber":114,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":115,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":116,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":117,"author":{"gitId":"mingyuanc"},"content":" public void testUpdateCommentEmails_success() {"},{"lineNumber":118,"author":{"gitId":"mingyuanc"},"content":" String courseId \u003d \"Course_id\";"},{"lineNumber":119,"author":{"gitId":"mingyuanc"},"content":" String oldEmail \u003d \"oldEmail@gmail.com\";"},{"lineNumber":120,"author":{"gitId":"mingyuanc"},"content":" String newEmail \u003d \"newEmail@gmail.com\";"},{"lineNumber":121,"author":{"gitId":"mingyuanc"},"content":" frcLogic.updateFeedbackResponseCommentsEmails(courseId, oldEmail, newEmail);"},{"lineNumber":122,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":123,"author":{"gitId":"mingyuanc"},"content":" verify(frcDb, times(1)).updateGiverEmailOfFeedbackResponseComments(courseId, oldEmail, newEmail);"},{"lineNumber":124,"author":{"gitId":"mingyuanc"},"content":" verify(frcDb, times(1)).updateLastEditorEmailOfFeedbackResponseComments(courseId, oldEmail, newEmail);"},{"lineNumber":125,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":126,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":127,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":128,"author":{"gitId":"mingyuanc"},"content":" public void testUpdateComment_entityAlreadyExists_success()"},{"lineNumber":129,"author":{"gitId":"mingyuanc"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":130,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":131,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":132,"author":{"gitId":"mingyuanc"},"content":" when(frcDb.getFeedbackResponseComment(comment.getId())).thenReturn(comment);"},{"lineNumber":133,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":134,"author":{"gitId":"mingyuanc"},"content":" String updatedCommentText \u003d \"Update\";"},{"lineNumber":135,"author":{"gitId":"mingyuanc"},"content":" String lastEditorEmail \u003d \"me@gmail.com\";"},{"lineNumber":136,"author":{"gitId":"mingyuanc"},"content":" List\u003cCommentVisibilityType\u003e showCommentTo \u003d new ArrayList\u003c\u003e();"},{"lineNumber":137,"author":{"gitId":"mingyuanc"},"content":" showCommentTo.add(CommentVisibilityType.STUDENTS);"},{"lineNumber":138,"author":{"gitId":"mingyuanc"},"content":" showCommentTo.add(CommentVisibilityType.INSTRUCTORS);"},{"lineNumber":139,"author":{"gitId":"mingyuanc"},"content":" List\u003cCommentVisibilityType\u003e showGiverNameTo \u003d new ArrayList\u003c\u003e();"},{"lineNumber":140,"author":{"gitId":"mingyuanc"},"content":" showGiverNameTo.add(CommentVisibilityType.INSTRUCTORS);"},{"lineNumber":141,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":142,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseCommentUpdateRequest updateRequest \u003d new FeedbackResponseCommentUpdateRequest("},{"lineNumber":143,"author":{"gitId":"mingyuanc"},"content":" updatedCommentText, showCommentTo, showGiverNameTo);"},{"lineNumber":144,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment updatedComment \u003d frcLogic.updateFeedbackResponseComment(TYPICAL_ID, updateRequest,"},{"lineNumber":145,"author":{"gitId":"mingyuanc"},"content":" lastEditorEmail);"},{"lineNumber":146,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":147,"author":{"gitId":"mingyuanc"},"content":" verify(frcDb, times(1)).getFeedbackResponseComment(TYPICAL_ID);"},{"lineNumber":148,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":149,"author":{"gitId":"mingyuanc"},"content":" List\u003cFeedbackParticipantType\u003e expectedShowCommentTo \u003d new ArrayList\u003c\u003e();"},{"lineNumber":150,"author":{"gitId":"mingyuanc"},"content":" expectedShowCommentTo.add(FeedbackParticipantType.STUDENTS);"},{"lineNumber":151,"author":{"gitId":"mingyuanc"},"content":" expectedShowCommentTo.add(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":152,"author":{"gitId":"mingyuanc"},"content":" List\u003cFeedbackParticipantType\u003e expectedShowGiverNameTo \u003d new ArrayList\u003c\u003e();"},{"lineNumber":153,"author":{"gitId":"mingyuanc"},"content":" expectedShowGiverNameTo.add(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":154,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":155,"author":{"gitId":"mingyuanc"},"content":" assertEquals(TYPICAL_ID, updatedComment.getId());"},{"lineNumber":156,"author":{"gitId":"mingyuanc"},"content":" assertEquals(updatedCommentText, updatedComment.getCommentText());"},{"lineNumber":157,"author":{"gitId":"mingyuanc"},"content":" assertEquals(expectedShowCommentTo, updatedComment.getShowCommentTo());"},{"lineNumber":158,"author":{"gitId":"mingyuanc"},"content":" assertEquals(expectedShowGiverNameTo, updatedComment.getShowGiverNameTo());"},{"lineNumber":159,"author":{"gitId":"mingyuanc"},"content":" assertEquals(lastEditorEmail, updatedComment.getLastEditorEmail());"},{"lineNumber":160,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":161,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":162,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":163,"author":{"gitId":"mingyuanc"},"content":" public void testUpdateComment_entityDoesNotExist() {"},{"lineNumber":164,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":165,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":166,"author":{"gitId":"mingyuanc"},"content":" when(frcDb.getFeedbackResponseComment(comment.getId())).thenReturn(comment);"},{"lineNumber":167,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":168,"author":{"gitId":"mingyuanc"},"content":" long nonExistentId \u003d 101L;"},{"lineNumber":169,"author":{"gitId":"mingyuanc"},"content":" String updatedCommentText \u003d \"Update\";"},{"lineNumber":170,"author":{"gitId":"mingyuanc"},"content":" String lastEditorEmail \u003d \"me@gmail.com\";"},{"lineNumber":171,"author":{"gitId":"mingyuanc"},"content":" List\u003cCommentVisibilityType\u003e showCommentTo \u003d new ArrayList\u003c\u003e();"},{"lineNumber":172,"author":{"gitId":"mingyuanc"},"content":" showCommentTo.add(CommentVisibilityType.STUDENTS);"},{"lineNumber":173,"author":{"gitId":"mingyuanc"},"content":" showCommentTo.add(CommentVisibilityType.INSTRUCTORS);"},{"lineNumber":174,"author":{"gitId":"mingyuanc"},"content":" List\u003cCommentVisibilityType\u003e showGiverNameTo \u003d new ArrayList\u003c\u003e();"},{"lineNumber":175,"author":{"gitId":"mingyuanc"},"content":" showGiverNameTo.add(CommentVisibilityType.INSTRUCTORS);"},{"lineNumber":176,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":177,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseCommentUpdateRequest updateRequest \u003d new FeedbackResponseCommentUpdateRequest("},{"lineNumber":178,"author":{"gitId":"mingyuanc"},"content":" updatedCommentText, showCommentTo, showGiverNameTo);"},{"lineNumber":179,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":180,"author":{"gitId":"mingyuanc"},"content":" EntityDoesNotExistException ex \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":181,"author":{"gitId":"mingyuanc"},"content":" () -\u003e frcLogic.updateFeedbackResponseComment(nonExistentId, updateRequest, lastEditorEmail));"},{"lineNumber":182,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":183,"author":{"gitId":"mingyuanc"},"content":" assertEquals(\"Trying to update a feedback response comment that does not exist.\", ex.getMessage());"},{"lineNumber":184,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":185,"author":{"gitId":"mingyuanc"},"content":"}"}],"authorContributionMap":{"mingyuanc":185}},{"path":"src/test/java/teammates/sqlui/webapi/GetFeedbackSessionLogsActionTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.sqlui.webapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.when;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.InstructorPrivileges;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Const;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.output.FeedbackSessionLogData;"},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.output.FeedbackSessionLogEntryData;"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.output.FeedbackSessionLogsData;"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.webapi.GetFeedbackSessionLogsAction;"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link GetFeedbackSessionLogsAction}."},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":"public class GetFeedbackSessionLogsActionTest extends BaseActionTest\u003cGetFeedbackSessionLogsAction\u003e {"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" private Course course;"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" private Student student1;"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" private Student student2;"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" private FeedbackSession fs1;"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" private long startTime;"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" private long endTime;"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" private String googleId \u003d \"google-id\";"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" String getActionUri() {"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" return Const.ResourceURIs.SESSION_LOGS;"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" String getRequestMethod() {"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" return GET;"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" @BeforeMethod"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" void setUp() {"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" FeedbackSession fs2;"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" endTime \u003d Instant.now().toEpochMilli();"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" startTime \u003d endTime - (Const.LOGS_RETENTION_PERIOD.toDays() - 1) * 24 * 60 * 60 * 1000;"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" course \u003d getTypicalCourse();"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" student1 \u003d getTypicalStudent();"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" student1.setEmail(\"student1@teammates.tmt\");"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" student1.setTeam(getTypicalTeam());"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" student2 \u003d getTypicalStudent();"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" student2.setEmail(\"student2@teammates.tmt\");"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" student2.setTeam(getTypicalTeam());"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" fs1 \u003d getTypicalFeedbackSessionForCourse(course);"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" fs1.setName(\"fs1\");"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" fs1.setCreatedAt(Instant.now());"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" fs2 \u003d getTypicalFeedbackSessionForCourse(course);"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" fs2.setName(\"fs2\");"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" fs2.setCreatedAt(Instant.now());"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getCourse(course.getId())).thenReturn(course);"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getFeedbackSession(fs1.getId())).thenReturn(fs1);"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getStudent(student1.getId())).thenReturn(student1);"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getStudent(student2.getId())).thenReturn(student2);"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSession\u003e feedbackSessions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" feedbackSessions.add(fs1);"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" feedbackSessions.add(fs2);"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getFeedbackSessionsForCourse(course.getId())).thenReturn(feedbackSessions);"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student1Session1Log1 \u003d new FeedbackSessionLog(student1, fs1, FeedbackSessionLogType.ACCESS,"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" Instant.ofEpochMilli(startTime));"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student1Session2Log1 \u003d new FeedbackSessionLog(student1, fs2, FeedbackSessionLogType.ACCESS,"},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" Instant.ofEpochMilli(startTime + 1000));"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student1Session2Log2 \u003d new FeedbackSessionLog(student1, fs2,"},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.SUBMISSION, Instant.ofEpochMilli(startTime + 2000));"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student2Session1Log1 \u003d new FeedbackSessionLog(student2, fs1, FeedbackSessionLogType.ACCESS,"},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" Instant.ofEpochMilli(startTime + 3000));"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student2Session1Log2 \u003d new FeedbackSessionLog(student2, fs1,"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.SUBMISSION, Instant.ofEpochMilli(startTime + 4000));"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e allLogsInCourse \u003d new ArrayList\u003c\u003e();"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" allLogsInCourse.add(student1Session1Log1);"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":" allLogsInCourse.add(student1Session2Log1);"},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":" allLogsInCourse.add(student1Session2Log2);"},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" allLogsInCourse.add(student2Session1Log1);"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":" allLogsInCourse.add(student2Session1Log2);"},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getOrderedFeedbackSessionLogs(course.getId(), null, null, Instant.ofEpochMilli(startTime),"},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":" Instant.ofEpochMilli(endTime))).thenReturn(allLogsInCourse);"},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e student1Logs \u003d new ArrayList\u003c\u003e();"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" student1Logs.add(student1Session1Log1);"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":" student1Logs.add(student1Session2Log1);"},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" student1Logs.add(student1Session2Log2);"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getOrderedFeedbackSessionLogs(course.getId(), student1.getId(), null,"},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":" Instant.ofEpochMilli(startTime), Instant.ofEpochMilli(endTime))).thenReturn(student1Logs);"},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e fs1Logs \u003d new ArrayList\u003c\u003e();"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" fs1Logs.add(student1Session1Log1);"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" fs1Logs.add(student2Session1Log1);"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" fs1Logs.add(student2Session1Log2);"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getOrderedFeedbackSessionLogs(course.getId(), null, fs1.getId(),"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" Instant.ofEpochMilli(startTime), Instant.ofEpochMilli(endTime))).thenReturn(fs1Logs);"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e student1Fs1Logs \u003d new ArrayList\u003c\u003e();"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" student1Fs1Logs.add(student1Session1Log1);"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getOrderedFeedbackSessionLogs(course.getId(), student1.getId(), fs1.getId(),"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" Instant.ofEpochMilli(startTime), Instant.ofEpochMilli(endTime))).thenReturn(student1Fs1Logs);"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":" protected void testExecute() {"},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":" JsonResult actionOutput;"},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: not enough parameters\");"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure("},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId());"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure("},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime));"},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure("},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime));"},{"lineNumber":141,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":142,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: invalid course id\");"},{"lineNumber":143,"author":{"gitId":"dishenggg"},"content":" String[] paramsInvalid1 \u003d {"},{"lineNumber":144,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, \"fake-course-id\","},{"lineNumber":145,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student1.getId().toString(),"},{"lineNumber":146,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":" verifyEntityNotFound(paramsInvalid1);"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: invalid student id\");"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":" String[] paramsInvalid2 \u003d {"},{"lineNumber":153,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, \"00000000-0000-0000-0000-000000000000\","},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":158,"author":{"gitId":"dishenggg"},"content":" verifyEntityNotFound(paramsInvalid2);"},{"lineNumber":159,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: invalid start or end times\");"},{"lineNumber":161,"author":{"gitId":"dishenggg"},"content":" String[] paramsInvalid3 \u003d {"},{"lineNumber":162,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":163,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, \"abc\","},{"lineNumber":164,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":165,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure(paramsInvalid3);"},{"lineNumber":167,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":168,"author":{"gitId":"dishenggg"},"content":" String[] paramsInvalid4 \u003d {"},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":171,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, \" \","},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure(paramsInvalid4);"},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":175,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: should group by feedback session\");"},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":" String[] paramsSuccessful1 \u003d {"},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":179,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":180,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":181,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":182,"author":{"gitId":"dishenggg"},"content":" actionOutput \u003d getJsonResult(getAction(paramsSuccessful1));"},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogsData fslData \u003d (FeedbackSessionLogsData) actionOutput.getOutput();"},{"lineNumber":185,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogData\u003e fsLogs \u003d fslData.getFeedbackSessionLogs();"},{"lineNumber":186,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":187,"author":{"gitId":"dishenggg"},"content":" // Course has 2 feedback sessions"},{"lineNumber":188,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.size(), 2);"},{"lineNumber":189,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":190,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntryData\u003e fsLogEntries1 \u003d fsLogs.get(0).getFeedbackSessionLogEntries();"},{"lineNumber":191,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntryData\u003e fsLogEntries2 \u003d fsLogs.get(1).getFeedbackSessionLogEntries();"},{"lineNumber":192,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":193,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.size(), 3);"},{"lineNumber":194,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getStudentData().getEmail(), student1.getEmail());"},{"lineNumber":195,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":196,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(1).getStudentData().getEmail(), student2.getEmail());"},{"lineNumber":197,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":198,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(2).getStudentData().getEmail(), student2.getEmail());"},{"lineNumber":199,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(2).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":200,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":201,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.size(), 2);"},{"lineNumber":202,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(0).getStudentData().getEmail(), student1.getEmail());"},{"lineNumber":203,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":204,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(1).getStudentData().getEmail(), student1.getEmail());"},{"lineNumber":205,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":206,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":207,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: should accept optional student id\");"},{"lineNumber":208,"author":{"gitId":"dishenggg"},"content":" String[] paramsSuccessful2 \u003d {"},{"lineNumber":209,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":210,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student1.getId().toString(),"},{"lineNumber":211,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":212,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":213,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":214,"author":{"gitId":"dishenggg"},"content":" actionOutput \u003d getJsonResult(getAction(paramsSuccessful2));"},{"lineNumber":215,"author":{"gitId":"dishenggg"},"content":" fslData \u003d (FeedbackSessionLogsData) actionOutput.getOutput();"},{"lineNumber":216,"author":{"gitId":"dishenggg"},"content":" fsLogs \u003d fslData.getFeedbackSessionLogs();"},{"lineNumber":217,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":218,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.size(), 2);"},{"lineNumber":219,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":220,"author":{"gitId":"dishenggg"},"content":" fsLogEntries1 \u003d fsLogs.get(0).getFeedbackSessionLogEntries();"},{"lineNumber":221,"author":{"gitId":"dishenggg"},"content":" fsLogEntries2 \u003d fsLogs.get(1).getFeedbackSessionLogEntries();"},{"lineNumber":222,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":223,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.size(), 1);"},{"lineNumber":224,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getStudentData().getEmail(), student1.getEmail());"},{"lineNumber":225,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":226,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":227,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.size(), 2);"},{"lineNumber":228,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(0).getStudentData().getEmail(), student1.getEmail());"},{"lineNumber":229,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":230,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(1).getStudentData().getEmail(), student1.getEmail());"},{"lineNumber":231,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":232,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":233,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: should accept optional feedback session\");"},{"lineNumber":234,"author":{"gitId":"dishenggg"},"content":" String[] paramsSuccessful3 \u003d {"},{"lineNumber":235,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":236,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fs1.getId().toString(),"},{"lineNumber":237,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":238,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":239,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":240,"author":{"gitId":"dishenggg"},"content":" actionOutput \u003d getJsonResult(getAction(paramsSuccessful3));"},{"lineNumber":241,"author":{"gitId":"dishenggg"},"content":" fslData \u003d (FeedbackSessionLogsData) actionOutput.getOutput();"},{"lineNumber":242,"author":{"gitId":"dishenggg"},"content":" fsLogs \u003d fslData.getFeedbackSessionLogs();"},{"lineNumber":243,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":244,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.size(), 2);"},{"lineNumber":245,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(1).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":246,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":247,"author":{"gitId":"dishenggg"},"content":" fsLogEntries1 \u003d fsLogs.get(0).getFeedbackSessionLogEntries();"},{"lineNumber":248,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":249,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.size(), 3);"},{"lineNumber":250,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getStudentData().getEmail(), student1.getEmail());"},{"lineNumber":251,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":252,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(1).getStudentData().getEmail(), student2.getEmail());"},{"lineNumber":253,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":254,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(2).getStudentData().getEmail(), student2.getEmail());"},{"lineNumber":255,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(2).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":256,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":257,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: should accept all optional params\");"},{"lineNumber":258,"author":{"gitId":"dishenggg"},"content":" String[] paramsSuccessful4 \u003d {"},{"lineNumber":259,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":260,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student1.getId().toString(),"},{"lineNumber":261,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fs1.getId().toString(),"},{"lineNumber":262,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":263,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":264,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":265,"author":{"gitId":"dishenggg"},"content":" actionOutput \u003d getJsonResult(getAction(paramsSuccessful4));"},{"lineNumber":266,"author":{"gitId":"dishenggg"},"content":" fslData \u003d (FeedbackSessionLogsData) actionOutput.getOutput();"},{"lineNumber":267,"author":{"gitId":"dishenggg"},"content":" fsLogs \u003d fslData.getFeedbackSessionLogs();"},{"lineNumber":268,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":269,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.size(), 2);"},{"lineNumber":270,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(1).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":271,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":272,"author":{"gitId":"dishenggg"},"content":" fsLogEntries1 \u003d fsLogs.get(0).getFeedbackSessionLogEntries();"},{"lineNumber":273,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":274,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.size(), 1);"},{"lineNumber":275,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getStudentData().getEmail(), student1.getEmail());"},{"lineNumber":276,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":277,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":278,"author":{"gitId":"dishenggg"},"content":" // TODO: if we restrict the range from start to end time, it should be tested"},{"lineNumber":279,"author":{"gitId":"dishenggg"},"content":" // here as well"},{"lineNumber":280,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":281,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":282,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":283,"author":{"gitId":"dishenggg"},"content":" void testSpecificAccessControl_instructorWithInvalidPermission_cannotAccess() {"},{"lineNumber":284,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":285,"author":{"gitId":"dishenggg"},"content":" Instructor instructor \u003d new Instructor(course, \"name\", \"instructoremail@tm.tmt\","},{"lineNumber":286,"author":{"gitId":"dishenggg"},"content":" false, \"\", null, new InstructorPrivileges());"},{"lineNumber":287,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":288,"author":{"gitId":"dishenggg"},"content":" loginAsInstructor(googleId);"},{"lineNumber":289,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getCourse(course.getId())).thenReturn(course);"},{"lineNumber":290,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getInstructorByGoogleId(course.getId(), googleId)).thenReturn(instructor);"},{"lineNumber":291,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":292,"author":{"gitId":"dishenggg"},"content":" String[] params \u003d {"},{"lineNumber":293,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":294,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":295,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":296,"author":{"gitId":"dishenggg"},"content":" verifyCannotAccess(params);"},{"lineNumber":297,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":298,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":299,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":300,"author":{"gitId":"dishenggg"},"content":" void testSpecificAccessControl_instructorWithPermission_canAccess() {"},{"lineNumber":301,"author":{"gitId":"dishenggg"},"content":" InstructorPrivileges instructorPrivileges \u003d new InstructorPrivileges();"},{"lineNumber":302,"author":{"gitId":"dishenggg"},"content":" instructorPrivileges.updatePrivilege(Const.InstructorPermissions.CAN_MODIFY_SESSION, true);"},{"lineNumber":303,"author":{"gitId":"dishenggg"},"content":" instructorPrivileges.updatePrivilege(Const.InstructorPermissions.CAN_MODIFY_STUDENT, true);"},{"lineNumber":304,"author":{"gitId":"dishenggg"},"content":" instructorPrivileges.updatePrivilege(Const.InstructorPermissions.CAN_MODIFY_INSTRUCTOR, true);"},{"lineNumber":305,"author":{"gitId":"dishenggg"},"content":" Instructor instructor \u003d new Instructor(course, \"name\", \"instructoremail@tm.tmt\","},{"lineNumber":306,"author":{"gitId":"dishenggg"},"content":" false, \"\", null, instructorPrivileges);"},{"lineNumber":307,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":308,"author":{"gitId":"dishenggg"},"content":" loginAsInstructor(googleId);"},{"lineNumber":309,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getCourse(course.getId())).thenReturn(course);"},{"lineNumber":310,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getInstructorByGoogleId(course.getId(), googleId)).thenReturn(instructor);"},{"lineNumber":311,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":312,"author":{"gitId":"dishenggg"},"content":" String[] params \u003d {"},{"lineNumber":313,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":314,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":315,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":316,"author":{"gitId":"dishenggg"},"content":" verifyCanAccess(params);"},{"lineNumber":317,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":318,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":319,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":320,"author":{"gitId":"dishenggg"},"content":" void testSpecificAccessControl_notInstructor_cannotAccess() {"},{"lineNumber":321,"author":{"gitId":"dishenggg"},"content":" String[] params \u003d {"},{"lineNumber":322,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":323,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":324,"author":{"gitId":"dishenggg"},"content":" loginAsStudent(googleId);"},{"lineNumber":325,"author":{"gitId":"dishenggg"},"content":" verifyCannotAccess(params);"},{"lineNumber":326,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":327,"author":{"gitId":"dishenggg"},"content":" logoutUser();"},{"lineNumber":328,"author":{"gitId":"dishenggg"},"content":" verifyCannotAccess(params);"},{"lineNumber":329,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":330,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":330}},{"path":"src/test/java/teammates/sqlui/webapi/UpdateFeedbackSessionLogsActionTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.sqlui.webapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.ArgumentMatchers.argThat;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.reset;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.verify;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.when;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import java.time.temporal.ChronoUnit;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Const;"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.webapi.UpdateFeedbackSessionLogsAction;"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link UpdateFeedbackSessionLogsAction}."},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":"public class UpdateFeedbackSessionLogsActionTest"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" extends BaseActionTest\u003cUpdateFeedbackSessionLogsAction\u003e {"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" static final long COLLECTION_TIME_PERIOD \u003d Const.STUDENT_ACTIVITY_LOGS_UPDATE_INTERVAL.toMinutes();"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" static final long SPAM_FILTER \u003d Const.STUDENT_ACTIVITY_LOGS_FILTER_WINDOW.toMillis();"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" Student student1;"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" Student student2;"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" Course course1;"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" Course course2;"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" FeedbackSession session1InCourse1;"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" FeedbackSession session2InCourse1;"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" FeedbackSession session1InCourse2;"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" Instant endTime;"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" Instant startTime;"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" protected String getActionUri() {"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" return Const.CronJobURIs.AUTOMATED_FEEDBACK_SESSION_LOGS_PROCESSING;"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" String getRequestMethod() {"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" return GET;"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" @BeforeMethod"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" void setUp() {"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" endTime \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.now());"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" startTime \u003d endTime.minus(COLLECTION_TIME_PERIOD, ChronoUnit.MINUTES);"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" course1 \u003d getTypicalCourse();"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" course1.setId(\"course1\");"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" course2 \u003d getTypicalCourse();"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" course2.setId(\"course2\");"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" student1 \u003d getTypicalStudent();"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" student1.setEmail(\"student1@teammates.tmt\");"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" student1.setId(UUID.randomUUID());"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" student2 \u003d getTypicalStudent();"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" student2.setEmail(\"student2@teammates.tmt\");"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" student2.setId(UUID.randomUUID());"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" session1InCourse1 \u003d getTypicalFeedbackSessionForCourse(course1);"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.setName(\"session1\");"},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.setId(UUID.randomUUID());"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" session2InCourse1 \u003d getTypicalFeedbackSessionForCourse(course1);"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" session2InCourse1.setName(\"session2\");"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":" session2InCourse1.setId(UUID.randomUUID());"},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" session1InCourse2 \u003d getTypicalFeedbackSessionForCourse(course2);"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":" session1InCourse2.setName(\"session1\");"},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" session1InCourse2.setId(UUID.randomUUID());"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" reset(mockLogic);"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getStudentReference(student1.getId())).thenReturn(student1);"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getStudentReference(student2.getId())).thenReturn(student2);"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getFeedbackSessionReference(session1InCourse1.getId())).thenReturn(session1InCourse1);"},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getFeedbackSessionReference(session2InCourse1.getId())).thenReturn(session2InCourse1);"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getFeedbackSessionReference(session1InCourse2.getId())).thenReturn(session1InCourse2);"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.getOrderedFeedbackSessionLogs(\"\", \"\", 0, 0, \"\").clear();"},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":" public void testExecute_noRecentLogs_noLogsCreated()"},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":" UpdateFeedbackSessionLogsAction action \u003d getAction();"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" action.execute();"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" verify(mockLogic).createFeedbackSessionLogs(argThat(filteredLogs -\u003e filteredLogs.isEmpty()));"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":" public void testExecute_recentLogsNoSpam_allLogsCreated()"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" // Different Types"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(100).toEpochMilli());"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.SUBMISSION.getLabel(), startTime.plusSeconds(100).toEpochMilli());"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.VIEW_RESULT.getLabel(), startTime.plusSeconds(100).toEpochMilli());"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" // Different feedback sessions"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(200).toEpochMilli());"},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session2InCourse1.getId(),"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(200).toEpochMilli());"},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":" // Different Student"},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(300).toEpochMilli());"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student2.getId(), session1InCourse1.getId(),"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(300).toEpochMilli());"},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" // Different course"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(400).toEpochMilli());"},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course2.getId(), student1.getId(), session1InCourse2.getId(),"},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(400).toEpochMilli());"},{"lineNumber":141,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":142,"author":{"gitId":"dishenggg"},"content":" // Gap is larger than spam filter"},{"lineNumber":143,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":144,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.toEpochMilli());"},{"lineNumber":145,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":146,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusMillis(SPAM_FILTER + 1).toEpochMilli());"},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":" UpdateFeedbackSessionLogsAction action \u003d getAction();"},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":" action.execute();"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":" // method returns all logs regardless of params"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntry\u003e expected \u003d mockLogsProcessor.getOrderedFeedbackSessionLogs(\"\", \"\", 0, 0, \"\");"},{"lineNumber":153,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":" verify(mockLogic).createFeedbackSessionLogs(argThat(filteredLogs -\u003e isEqual(expected, filteredLogs)));"},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":158,"author":{"gitId":"dishenggg"},"content":" public void testExecute_recentLogsWithSpam_someLogsCreated()"},{"lineNumber":159,"author":{"gitId":"dishenggg"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":" // Gap is smaller than spam filter"},{"lineNumber":161,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":162,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.toEpochMilli());"},{"lineNumber":163,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":164,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusMillis(SPAM_FILTER - 2).toEpochMilli());"},{"lineNumber":165,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":" // Filters multiple logs within one spam window"},{"lineNumber":167,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":168,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusMillis(SPAM_FILTER - 1).toEpochMilli());"},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" // Correctly adds new log after filtering"},{"lineNumber":171,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusMillis(SPAM_FILTER + 1).toEpochMilli());"},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":" // Filters out spam in the new window"},{"lineNumber":175,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusMillis(SPAM_FILTER + 2).toEpochMilli());"},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":" UpdateFeedbackSessionLogsAction action \u003d getAction();"},{"lineNumber":179,"author":{"gitId":"dishenggg"},"content":" action.execute();"},{"lineNumber":180,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":181,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntry\u003e expected \u003d new ArrayList\u003c\u003e();"},{"lineNumber":182,"author":{"gitId":"dishenggg"},"content":" expected.add(new FeedbackSessionLogEntry(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.toEpochMilli()));"},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":" expected.add(new FeedbackSessionLogEntry(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":185,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusMillis(SPAM_FILTER + 1).toEpochMilli()));"},{"lineNumber":186,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":187,"author":{"gitId":"dishenggg"},"content":" verify(mockLogic).createFeedbackSessionLogs(argThat(filteredLogs -\u003e isEqual(expected, filteredLogs)));"},{"lineNumber":188,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":189,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":190,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":191,"author":{"gitId":"dishenggg"},"content":" public void testSpecificAccessControl_isAdmin_canAccess() {"},{"lineNumber":192,"author":{"gitId":"dishenggg"},"content":" loginAsAdmin();"},{"lineNumber":193,"author":{"gitId":"dishenggg"},"content":" verifyCanAccess();"},{"lineNumber":194,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":195,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":196,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":197,"author":{"gitId":"dishenggg"},"content":" public void testSpecificAccessControl_isInstructor_cannotAccess() {"},{"lineNumber":198,"author":{"gitId":"dishenggg"},"content":" loginAsInstructor(\"user-id\");"},{"lineNumber":199,"author":{"gitId":"dishenggg"},"content":" verifyCannotAccess();"},{"lineNumber":200,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":201,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":202,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":203,"author":{"gitId":"dishenggg"},"content":" public void testSpecificAccessControl_isStudent_cannotAccess() {"},{"lineNumber":204,"author":{"gitId":"dishenggg"},"content":" loginAsStudent(\"user-id\");"},{"lineNumber":205,"author":{"gitId":"dishenggg"},"content":" verifyCannotAccess();"},{"lineNumber":206,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":207,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":208,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":209,"author":{"gitId":"dishenggg"},"content":" public void testSpecificAccessControl_loggedOut_cannotAccess() {"},{"lineNumber":210,"author":{"gitId":"dishenggg"},"content":" logoutUser();"},{"lineNumber":211,"author":{"gitId":"dishenggg"},"content":" verifyCannotAccess();"},{"lineNumber":212,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":213,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":214,"author":{"gitId":"dishenggg"},"content":" private Boolean isEqual(List\u003cFeedbackSessionLogEntry\u003e expected, List\u003cFeedbackSessionLog\u003e actual) {"},{"lineNumber":215,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":216,"author":{"gitId":"dishenggg"},"content":" assertEquals(expected.size(), actual.size());"},{"lineNumber":217,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":218,"author":{"gitId":"dishenggg"},"content":" for (int i \u003d 0; i \u003c expected.size(); i++) {"},{"lineNumber":219,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogEntry expectedEntry \u003d expected.get(i);"},{"lineNumber":220,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog actualLog \u003d actual.get(i);"},{"lineNumber":221,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":222,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedEntry.getStudentId(), actualLog.getStudent().getId());"},{"lineNumber":223,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":224,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedEntry.getFeedbackSessionId(), actualLog.getFeedbackSession().getId());"},{"lineNumber":225,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":226,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedEntry.getFeedbackSessionLogType(), actualLog.getFeedbackSessionLogType().getLabel());"},{"lineNumber":227,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":228,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedEntry.getTimestamp(), actualLog.getTimestamp().toEpochMilli());"},{"lineNumber":229,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":230,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":231,"author":{"gitId":"dishenggg"},"content":" return true;"},{"lineNumber":232,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":233,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":232,"-":1}},{"path":"src/test/java/teammates/storage/sqlapi/FeedbackQuestionsDbTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"marquestye"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":3,"author":{"gitId":"marquestye"},"content":"import static org.mockito.ArgumentMatchers.any;"},{"lineNumber":4,"author":{"gitId":"marquestye"},"content":"import static org.mockito.Mockito.mockStatic;"},{"lineNumber":5,"author":{"gitId":"marquestye"},"content":"import static org.mockito.Mockito.never;"},{"lineNumber":6,"author":{"gitId":"marquestye"},"content":"import static org.mockito.Mockito.spy;"},{"lineNumber":7,"author":{"gitId":"marquestye"},"content":"import static org.mockito.Mockito.times;"},{"lineNumber":8,"author":{"gitId":"marquestye"},"content":"import static teammates.common.util.Const.ERROR_CREATE_ENTITY_ALREADY_EXISTS;"},{"lineNumber":9,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":10,"author":{"gitId":"marquestye"},"content":"import java.util.List;"},{"lineNumber":11,"author":{"gitId":"marquestye"},"content":"import java.util.UUID;"},{"lineNumber":12,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":13,"author":{"gitId":"marquestye"},"content":"import org.mockito.MockedStatic;"},{"lineNumber":14,"author":{"gitId":"marquestye"},"content":"import org.testng.annotations.AfterMethod;"},{"lineNumber":15,"author":{"gitId":"marquestye"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":16,"author":{"gitId":"marquestye"},"content":"import org.testng.annotations.Test;"},{"lineNumber":17,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":18,"author":{"gitId":"marquestye"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":19,"author":{"gitId":"marquestye"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":20,"author":{"gitId":"marquestye"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":21,"author":{"gitId":"marquestye"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":22,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":23,"author":{"gitId":"marquestye"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":24,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":25,"author":{"gitId":"marquestye"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"marquestye"},"content":" * SUT: {@link FeedbackQuestionsDb}."},{"lineNumber":27,"author":{"gitId":"marquestye"},"content":" */"},{"lineNumber":28,"author":{"gitId":"marquestye"},"content":"public class FeedbackQuestionsDbTest extends BaseTestCase {"},{"lineNumber":29,"author":{"gitId":"marquestye"},"content":" private FeedbackQuestionsDb feedbackQuestionsDb;"},{"lineNumber":30,"author":{"gitId":"marquestye"},"content":" private MockedStatic\u003cHibernateUtil\u003e mockHibernateUtil;"},{"lineNumber":31,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":32,"author":{"gitId":"marquestye"},"content":" @BeforeMethod"},{"lineNumber":33,"author":{"gitId":"marquestye"},"content":" public void setUpMethod() {"},{"lineNumber":34,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil \u003d mockStatic(HibernateUtil.class);"},{"lineNumber":35,"author":{"gitId":"marquestye"},"content":" feedbackQuestionsDb \u003d spy(FeedbackQuestionsDb.class);"},{"lineNumber":36,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":37,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":38,"author":{"gitId":"marquestye"},"content":" @AfterMethod"},{"lineNumber":39,"author":{"gitId":"marquestye"},"content":" public void teardownMethod() {"},{"lineNumber":40,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.close();"},{"lineNumber":41,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":42,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":43,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":44,"author":{"gitId":"marquestye"},"content":" public void testCreateFeedbackQuestion_success() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":45,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion feedbackQuestion \u003d getFeedbackQuestion();"},{"lineNumber":46,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":47,"author":{"gitId":"marquestye"},"content":" feedbackQuestionsDb.createFeedbackQuestion(feedbackQuestion);"},{"lineNumber":48,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":49,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.persist(feedbackQuestion), times(1));"},{"lineNumber":50,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":51,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":52,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":53,"author":{"gitId":"marquestye"},"content":" public void testCreateFeedbackQuestion_questionAlreadyExists_throwsEntityAlreadyExistsException() {"},{"lineNumber":54,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion feedbackQuestion \u003d getFeedbackQuestion();"},{"lineNumber":55,"author":{"gitId":"marquestye"},"content":" UUID fqid \u003d feedbackQuestion.getId();"},{"lineNumber":56,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":57,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackQuestion.class, fqid)).thenReturn(feedbackQuestion);"},{"lineNumber":58,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":59,"author":{"gitId":"marquestye"},"content":" EntityAlreadyExistsException eaee \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":60,"author":{"gitId":"marquestye"},"content":" () -\u003e feedbackQuestionsDb.createFeedbackQuestion(feedbackQuestion));"},{"lineNumber":61,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":62,"author":{"gitId":"marquestye"},"content":" assertEquals(String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, feedbackQuestion.toString()), eaee.getMessage());"},{"lineNumber":63,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.persist(feedbackQuestion), never());"},{"lineNumber":64,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":65,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":66,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":67,"author":{"gitId":"marquestye"},"content":" public void testCreateFeedbackQuestion_invalidQuestion_throwsInvalidParametersException() {"},{"lineNumber":68,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion feedbackQuestion \u003d getFeedbackQuestion();"},{"lineNumber":69,"author":{"gitId":"marquestye"},"content":" feedbackQuestion.setGiverType(FeedbackParticipantType.NONE);"},{"lineNumber":70,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":71,"author":{"gitId":"marquestye"},"content":" InvalidParametersException ipe \u003d assertThrows(InvalidParametersException.class,"},{"lineNumber":72,"author":{"gitId":"marquestye"},"content":" () -\u003e feedbackQuestionsDb.createFeedbackQuestion(feedbackQuestion));"},{"lineNumber":73,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":74,"author":{"gitId":"marquestye"},"content":" assertEquals(feedbackQuestion.getInvalidityInfo(), List.of(ipe.getMessage()));"},{"lineNumber":75,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.persist(feedbackQuestion), never());"},{"lineNumber":76,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":77,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":78,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":79,"author":{"gitId":"marquestye"},"content":" public void testGetFeedbackQuestion_success() {"},{"lineNumber":80,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion feedbackQuestion \u003d getFeedbackQuestion();"},{"lineNumber":81,"author":{"gitId":"marquestye"},"content":" UUID fqid \u003d feedbackQuestion.getId();"},{"lineNumber":82,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":83,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackQuestion.class, fqid)).thenReturn(feedbackQuestion);"},{"lineNumber":84,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":85,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion retrievedSession \u003d feedbackQuestionsDb.getFeedbackQuestion(fqid);"},{"lineNumber":86,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":87,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.get(FeedbackQuestion.class, fqid), times(1));"},{"lineNumber":88,"author":{"gitId":"marquestye"},"content":" assertEquals(feedbackQuestion, retrievedSession);"},{"lineNumber":89,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":90,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":91,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":92,"author":{"gitId":"marquestye"},"content":" public void testGetFeedbackQuestion_questionDoesNotExist_returnNull() {"},{"lineNumber":93,"author":{"gitId":"marquestye"},"content":" UUID fqid \u003d UUID.randomUUID();"},{"lineNumber":94,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":95,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackQuestion.class, fqid)).thenReturn(null);"},{"lineNumber":96,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":97,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion retrievedSession \u003d feedbackQuestionsDb.getFeedbackQuestion(fqid);"},{"lineNumber":98,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":99,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.get(FeedbackQuestion.class, fqid), times(1));"},{"lineNumber":100,"author":{"gitId":"marquestye"},"content":" assertNull(retrievedSession);"},{"lineNumber":101,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":102,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":103,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":104,"author":{"gitId":"marquestye"},"content":" public void testDeleteFeedbackQuestion_success() {"},{"lineNumber":105,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion feedbackQuestion \u003d getFeedbackQuestion();"},{"lineNumber":106,"author":{"gitId":"marquestye"},"content":" UUID fqid \u003d feedbackQuestion.getId();"},{"lineNumber":107,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":108,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackQuestion.class, fqid)).thenReturn(feedbackQuestion);"},{"lineNumber":109,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":110,"author":{"gitId":"marquestye"},"content":" feedbackQuestionsDb.deleteFeedbackQuestion(fqid);"},{"lineNumber":111,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":112,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.remove(feedbackQuestion), times(1));"},{"lineNumber":113,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":114,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":115,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":116,"author":{"gitId":"marquestye"},"content":" public void testDeleteFeedbackQuestion_questionDoesNotExist_nothingHappens() {"},{"lineNumber":117,"author":{"gitId":"marquestye"},"content":" UUID fqid \u003d UUID.randomUUID();"},{"lineNumber":118,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":119,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackQuestion.class, fqid)).thenReturn(null);"},{"lineNumber":120,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":121,"author":{"gitId":"marquestye"},"content":" feedbackQuestionsDb.deleteFeedbackQuestion(fqid);"},{"lineNumber":122,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":123,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.remove(any()), never());"},{"lineNumber":124,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":125,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":126,"author":{"gitId":"marquestye"},"content":" private FeedbackQuestion getFeedbackQuestion() {"},{"lineNumber":127,"author":{"gitId":"marquestye"},"content":" return getTypicalFeedbackQuestionForSession(getTypicalFeedbackSessionForCourse(getTypicalCourse()));"},{"lineNumber":128,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":129,"author":{"gitId":"marquestye"},"content":"}"}],"authorContributionMap":{"marquestye":129}},{"path":"src/test/java/teammates/storage/sqlapi/FeedbackResponseCommentsDbTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"mingyuanc"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":3,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.ArgumentMatchers.anyLong;"},{"lineNumber":4,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.Mockito.doReturn;"},{"lineNumber":5,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.Mockito.mockStatic;"},{"lineNumber":6,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.Mockito.never;"},{"lineNumber":7,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.Mockito.spy;"},{"lineNumber":8,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.Mockito.times;"},{"lineNumber":9,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":10,"author":{"gitId":"mingyuanc"},"content":"import org.mockito.MockedStatic;"},{"lineNumber":11,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.AfterMethod;"},{"lineNumber":12,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":13,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.Test;"},{"lineNumber":14,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":15,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":16,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":17,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":18,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":19,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":20,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":21,"author":{"gitId":"mingyuanc"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":22,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":23,"author":{"gitId":"mingyuanc"},"content":"/**"},{"lineNumber":24,"author":{"gitId":"mingyuanc"},"content":" * SUT: {@code FeedbackResponseCommentsDb}."},{"lineNumber":25,"author":{"gitId":"mingyuanc"},"content":" */"},{"lineNumber":26,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":27,"author":{"gitId":"mingyuanc"},"content":"public class FeedbackResponseCommentsDbTest extends BaseTestCase {"},{"lineNumber":28,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":29,"author":{"gitId":"mingyuanc"},"content":" private static final Long TYPICAL_ID \u003d 100L;"},{"lineNumber":30,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":31,"author":{"gitId":"mingyuanc"},"content":" private static final Long NOT_TYPICAL_ID \u003d 101L;"},{"lineNumber":32,"author":{"gitId":"mingyuanc"},"content":" private FeedbackResponseCommentsDb feedbackResponseCommentsDb;"},{"lineNumber":33,"author":{"gitId":"mingyuanc"},"content":" private MockedStatic\u003cHibernateUtil\u003e mockHibernateUtil;"},{"lineNumber":34,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":35,"author":{"gitId":"mingyuanc"},"content":" @BeforeMethod"},{"lineNumber":36,"author":{"gitId":"mingyuanc"},"content":" public void setUpMethod() {"},{"lineNumber":37,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil \u003d mockStatic(HibernateUtil.class);"},{"lineNumber":38,"author":{"gitId":"mingyuanc"},"content":" feedbackResponseCommentsDb \u003d spy(FeedbackResponseCommentsDb.class);"},{"lineNumber":39,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":40,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":41,"author":{"gitId":"mingyuanc"},"content":" @AfterMethod"},{"lineNumber":42,"author":{"gitId":"mingyuanc"},"content":" public void teardownMethod() {"},{"lineNumber":43,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.close();"},{"lineNumber":44,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":45,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":46,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":47,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":48,"author":{"gitId":"mingyuanc"},"content":" public void testCreateComment_commentDoesNotExist_success()"},{"lineNumber":49,"author":{"gitId":"mingyuanc"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":50,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":51,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":52,"author":{"gitId":"mingyuanc"},"content":" feedbackResponseCommentsDb.createFeedbackResponseComment(comment);"},{"lineNumber":53,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":54,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.persist(comment));"},{"lineNumber":55,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":56,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":57,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":58,"author":{"gitId":"mingyuanc"},"content":" public void testCreateComment_commentAlreadyExists_throwsEntityAlreadyExistsException() {"},{"lineNumber":59,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":60,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":61,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackResponseComment.class, TYPICAL_ID)).thenReturn(comment);"},{"lineNumber":62,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":63,"author":{"gitId":"mingyuanc"},"content":" EntityAlreadyExistsException ex \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":64,"author":{"gitId":"mingyuanc"},"content":" () -\u003e feedbackResponseCommentsDb.createFeedbackResponseComment(comment));"},{"lineNumber":65,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":66,"author":{"gitId":"mingyuanc"},"content":" assertEquals(\"Trying to create an entity that exists: \" + comment.toString(), ex.getMessage());"},{"lineNumber":67,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.persist(comment), never());"},{"lineNumber":68,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":69,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":70,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":71,"author":{"gitId":"mingyuanc"},"content":" public void testGetComment_commentAlreadyExists_success() {"},{"lineNumber":72,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":73,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":74,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackResponseComment.class, TYPICAL_ID)).thenReturn(comment);"},{"lineNumber":75,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":76,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment commentFetched \u003d feedbackResponseCommentsDb.getFeedbackResponseComment(TYPICAL_ID);"},{"lineNumber":77,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":78,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackResponseComment.class, TYPICAL_ID)).thenReturn(comment);"},{"lineNumber":79,"author":{"gitId":"mingyuanc"},"content":" assertEquals(comment, commentFetched);"},{"lineNumber":80,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":81,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":82,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":83,"author":{"gitId":"mingyuanc"},"content":" public void testGetComment_commentDoesNotExist_returnsNull() {"},{"lineNumber":84,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackResponseComment.class, NOT_TYPICAL_ID)).thenReturn(null);"},{"lineNumber":85,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":86,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment commentFetched \u003d feedbackResponseCommentsDb.getFeedbackResponseComment(NOT_TYPICAL_ID);"},{"lineNumber":87,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":88,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.get(FeedbackResponseComment.class, NOT_TYPICAL_ID), times(1));"},{"lineNumber":89,"author":{"gitId":"mingyuanc"},"content":" assertNull(commentFetched);"},{"lineNumber":90,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":91,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":92,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":93,"author":{"gitId":"mingyuanc"},"content":" public void testDeleteComment_commentExists_success() {"},{"lineNumber":94,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":95,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":96,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackResponseComment.class, TYPICAL_ID)).thenReturn(comment);"},{"lineNumber":97,"author":{"gitId":"mingyuanc"},"content":" feedbackResponseCommentsDb.deleteFeedbackResponseComment(TYPICAL_ID);"},{"lineNumber":98,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":99,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.remove(comment));"},{"lineNumber":100,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":101,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":102,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":103,"author":{"gitId":"mingyuanc"},"content":" public void testUpdateComment_commentInvalid_throwsInvalidParametersException() {"},{"lineNumber":104,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":105,"author":{"gitId":"mingyuanc"},"content":" comment.setGiverType(FeedbackParticipantType.SELF);"},{"lineNumber":106,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":107,"author":{"gitId":"mingyuanc"},"content":" assertThrows(InvalidParametersException.class,"},{"lineNumber":108,"author":{"gitId":"mingyuanc"},"content":" () -\u003e feedbackResponseCommentsDb.updateFeedbackResponseComment(comment));"},{"lineNumber":109,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":110,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(comment), never());"},{"lineNumber":111,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":112,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":113,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":114,"author":{"gitId":"mingyuanc"},"content":" public void testUpdateComment_commentDoesNotExist_throwsEntityDoesNotExistException() {"},{"lineNumber":115,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(NOT_TYPICAL_ID);"},{"lineNumber":116,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":117,"author":{"gitId":"mingyuanc"},"content":" assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":118,"author":{"gitId":"mingyuanc"},"content":" () -\u003e feedbackResponseCommentsDb.updateFeedbackResponseComment(comment));"},{"lineNumber":119,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":120,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(comment), never());"},{"lineNumber":121,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":122,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":123,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":124,"author":{"gitId":"mingyuanc"},"content":" public void testUpdateCourse_success() throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":125,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":126,"author":{"gitId":"mingyuanc"},"content":" comment.setCommentText(\"Placeholder Text\");"},{"lineNumber":127,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":128,"author":{"gitId":"mingyuanc"},"content":" doReturn(comment).when(feedbackResponseCommentsDb).getFeedbackResponseComment(anyLong());"},{"lineNumber":129,"author":{"gitId":"mingyuanc"},"content":" feedbackResponseCommentsDb.updateFeedbackResponseComment(comment);"},{"lineNumber":130,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":131,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(comment));"},{"lineNumber":132,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":133,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":134,"author":{"gitId":"mingyuanc"},"content":"}"}],"authorContributionMap":{"mingyuanc":134}},{"path":"src/test/java/teammates/storage/sqlapi/FeedbackSessionLogsDbTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.mockStatic;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import org.mockito.MockedStatic;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.AfterMethod;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" * SUT: {@code FeedbackSessionLogsDb}."},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":"public class FeedbackSessionLogsDbTest extends BaseTestCase {"},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" private FeedbackSessionLogsDb feedbackSessionLogsDb \u003d FeedbackSessionLogsDb.inst();"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":" private MockedStatic\u003cHibernateUtil\u003e mockHibernateUtil;"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" @BeforeMethod"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" public void setUpMethod() {"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil \u003d mockStatic(HibernateUtil.class);"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" @AfterMethod"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" public void teardownMethod() {"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.close();"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" public void testCreateFeedbackSessionLog_success() {"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog logToAdd \u003d new FeedbackSessionLog(getTypicalStudent(),"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" getTypicalFeedbackSessionForCourse(getTypicalCourse()), FeedbackSessionLogType.ACCESS,"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" Instant.parse(\"2011-01-01T00:00:00Z\"));"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" feedbackSessionLogsDb.createFeedbackSessionLog(logToAdd);"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.persist(logToAdd));"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":46}},{"path":"src/test/java/teammates/storage/sqlapi/FeedbackSessionsDbTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.ArgumentMatchers.any;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.doReturn;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.mockStatic;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.never;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.spy;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.times;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import org.mockito.MockedStatic;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.AfterMethod;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.TimeHelperExtension;"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" * SUT: {@code FeedbackSessionsDb}."},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":"public class FeedbackSessionsDbTest extends BaseTestCase {"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" private FeedbackSessionsDb feedbackSessionsDb;"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" private MockedStatic\u003cHibernateUtil\u003e mockHibernateUtil;"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" @BeforeMethod"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" public void setUpMethod() {"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil \u003d mockStatic(HibernateUtil.class);"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" feedbackSessionsDb \u003d spy(FeedbackSessionsDb.class);"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" @AfterMethod"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" public void teardownMethod() {"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.close();"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" public void testCreateSession_sessionDoesNotExist_success()"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" feedbackSessionsDb.createFeedbackSession(feedbackSession);"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.persist(feedbackSession), times(1));"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" public void testCreateSession_duplicateSession_throwsEntityAlreadyExistsException()"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" UUID uuid \u003d feedbackSession.getId();"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" doReturn(feedbackSession).when(feedbackSessionsDb).getFeedbackSession(uuid);"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" () -\u003e feedbackSessionsDb.createFeedbackSession(feedbackSession));"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.persist(feedbackSession), never());"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" public void testCreateSession_invalidParams_throwsInvalidParametersException()"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" feedbackSession.setName(\"\");"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" assertThrows(InvalidParametersException.class, () -\u003e feedbackSessionsDb.createFeedbackSession(feedbackSession));"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.persist(feedbackSession), never());"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" public void testCreateSession_nullParams_throwsAssertionError()"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" assertThrows(AssertionError.class, () -\u003e feedbackSessionsDb.createFeedbackSession(null));"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" public void testGetFeedbackSession_sessionExists_success() {"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" UUID uuid \u003d feedbackSession.getId();"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackSession.class, uuid)).thenReturn(feedbackSession);"},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" FeedbackSession sessionFetched \u003d feedbackSessionsDb.getFeedbackSession(uuid);"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.get(FeedbackSession.class, uuid), times(1));"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":" assertEquals(feedbackSession, sessionFetched);"},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" public void testGetFeedbackSession_sessionDoesNotExists_returnNull() {"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" UUID randomUuid \u003d UUID.randomUUID();"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackSession.class, randomUuid)).thenReturn(null);"},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" FeedbackSession sessionFetched \u003d feedbackSessionsDb.getFeedbackSession(randomUuid);"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.get(FeedbackSession.class, randomUuid), times(1));"},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" assertNull(sessionFetched);"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" public void testUpdateFeedbackSession_success() throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" doReturn(feedbackSession).when(feedbackSessionsDb).getFeedbackSession(any(UUID.class));"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" feedbackSessionsDb.updateFeedbackSession(feedbackSession);"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(feedbackSession), times(1));"},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" public void testUpdateFeedbackSession_sessionDoesNotExist_throwsEntityDoesNotExistException()"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" UUID uuid \u003d feedbackSession.getId();"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" doReturn(null).when(feedbackSessionsDb).getFeedbackSession(uuid);"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" () -\u003e feedbackSessionsDb.updateFeedbackSession(feedbackSession));"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(feedbackSession), never());"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":" public void testUpdateFeedbackSession_sessionInvalid_throwsInvalidParametersException()"},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" UUID uuid \u003d feedbackSession.getId();"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" feedbackSession.setName(\"\");"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" doReturn(feedbackSession).when(feedbackSessionsDb).getFeedbackSession(uuid);"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":" assertThrows(InvalidParametersException.class, () -\u003e feedbackSessionsDb.updateFeedbackSession(feedbackSession));"},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(feedbackSession), never());"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":" public void testDeleteFeedbackSession_success() throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":141,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":142,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":143,"author":{"gitId":"dishenggg"},"content":" feedbackSessionsDb.deleteFeedbackSession(feedbackSession);"},{"lineNumber":144,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":145,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.remove(feedbackSession), times(1));"},{"lineNumber":146,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":" public void testGetSoftDeletedFeedbackSession_isSoftDeleted_success() {"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":" String sessionName \u003d feedbackSession.getName();"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":" String courseId \u003d feedbackSession.getCourse().getId();"},{"lineNumber":153,"author":{"gitId":"dishenggg"},"content":" feedbackSession.setDeletedAt(TimeHelperExtension.getInstantDaysOffsetFromNow(2));"},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":" doReturn(feedbackSession).when(feedbackSessionsDb).getFeedbackSession(sessionName, courseId);"},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" FeedbackSession sessionFetched \u003d feedbackSessionsDb.getSoftDeletedFeedbackSession(sessionName, courseId);"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":158,"author":{"gitId":"dishenggg"},"content":" assertEquals(feedbackSession, sessionFetched);"},{"lineNumber":159,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":161,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":162,"author":{"gitId":"dishenggg"},"content":" public void testGetSoftDeletedFeedbackSession_notSoftDeleted_returnNull() {"},{"lineNumber":163,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":164,"author":{"gitId":"dishenggg"},"content":" String sessionName \u003d feedbackSession.getName();"},{"lineNumber":165,"author":{"gitId":"dishenggg"},"content":" String courseId \u003d feedbackSession.getCourse().getId();"},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":" doReturn(feedbackSession).when(feedbackSessionsDb).getFeedbackSession(sessionName, courseId);"},{"lineNumber":167,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":168,"author":{"gitId":"dishenggg"},"content":" FeedbackSession sessionFetched \u003d feedbackSessionsDb.getSoftDeletedFeedbackSession(sessionName, courseId);"},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" assertNull(sessionFetched);"},{"lineNumber":171,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":" public void testGetSoftDeletedFeedbackSession_sessionDoesNotExist_returnNull() {"},{"lineNumber":175,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":" String sessionName \u003d feedbackSession.getName();"},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":" String courseId \u003d feedbackSession.getCourse().getId();"},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":" doReturn(null).when(feedbackSessionsDb).getFeedbackSession(sessionName, courseId);"},{"lineNumber":179,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":180,"author":{"gitId":"dishenggg"},"content":" FeedbackSession sessionFetched \u003d feedbackSessionsDb.getSoftDeletedFeedbackSession(sessionName, courseId);"},{"lineNumber":181,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":182,"author":{"gitId":"dishenggg"},"content":" assertNull(sessionFetched);"},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":185,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":186,"author":{"gitId":"dishenggg"},"content":" public void testRestoreDeletedFeedbackSession_success() throws EntityDoesNotExistException {"},{"lineNumber":187,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":188,"author":{"gitId":"dishenggg"},"content":" String sessionName \u003d feedbackSession.getName();"},{"lineNumber":189,"author":{"gitId":"dishenggg"},"content":" String courseId \u003d feedbackSession.getCourse().getId();"},{"lineNumber":190,"author":{"gitId":"dishenggg"},"content":" feedbackSession.setDeletedAt(TimeHelperExtension.getInstantDaysOffsetFromNow(2));"},{"lineNumber":191,"author":{"gitId":"dishenggg"},"content":" doReturn(feedbackSession).when(feedbackSessionsDb).getFeedbackSession(sessionName, courseId);"},{"lineNumber":192,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":193,"author":{"gitId":"dishenggg"},"content":" feedbackSessionsDb.restoreDeletedFeedbackSession(sessionName, courseId);"},{"lineNumber":194,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":195,"author":{"gitId":"dishenggg"},"content":" assertNull(feedbackSession.getDeletedAt());"},{"lineNumber":196,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(feedbackSession), times(1));"},{"lineNumber":197,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":198,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":199,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":200,"author":{"gitId":"dishenggg"},"content":" public void testRestoreDeletedFeedbackSession_sessionDoesNotExist_throwsEntityDoesNotExistException()"},{"lineNumber":201,"author":{"gitId":"dishenggg"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":202,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":203,"author":{"gitId":"dishenggg"},"content":" String sessionName \u003d feedbackSession.getName();"},{"lineNumber":204,"author":{"gitId":"dishenggg"},"content":" String courseId \u003d feedbackSession.getCourse().getId();"},{"lineNumber":205,"author":{"gitId":"dishenggg"},"content":" doReturn(null).when(feedbackSessionsDb).getFeedbackSession(sessionName, courseId);"},{"lineNumber":206,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":207,"author":{"gitId":"dishenggg"},"content":" assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":208,"author":{"gitId":"dishenggg"},"content":" () -\u003e feedbackSessionsDb.restoreDeletedFeedbackSession(sessionName, courseId));"},{"lineNumber":209,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(feedbackSession), never());"},{"lineNumber":210,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":211,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":212,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":213,"author":{"gitId":"dishenggg"},"content":" public void testSoftDeleteFeedbackSession_success() throws EntityDoesNotExistException {"},{"lineNumber":214,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":215,"author":{"gitId":"dishenggg"},"content":" String sessionName \u003d feedbackSession.getName();"},{"lineNumber":216,"author":{"gitId":"dishenggg"},"content":" String courseId \u003d feedbackSession.getCourse().getId();"},{"lineNumber":217,"author":{"gitId":"dishenggg"},"content":" doReturn(feedbackSession).when(feedbackSessionsDb).getFeedbackSession(sessionName, courseId);"},{"lineNumber":218,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":219,"author":{"gitId":"dishenggg"},"content":" feedbackSessionsDb.softDeleteFeedbackSession(sessionName, courseId);"},{"lineNumber":220,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":221,"author":{"gitId":"dishenggg"},"content":" assertNotNull(feedbackSession.getDeletedAt());"},{"lineNumber":222,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(feedbackSession), times(1));"},{"lineNumber":223,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":224,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":225,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":226,"author":{"gitId":"dishenggg"},"content":" public void testSoftDeleteFeedbackSession_sessionDoesNotExist_throwsEntityDoesNotExistException()"},{"lineNumber":227,"author":{"gitId":"dishenggg"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":228,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":229,"author":{"gitId":"dishenggg"},"content":" String sessionName \u003d feedbackSession.getName();"},{"lineNumber":230,"author":{"gitId":"dishenggg"},"content":" String courseId \u003d feedbackSession.getCourse().getId();"},{"lineNumber":231,"author":{"gitId":"dishenggg"},"content":" doReturn(null).when(feedbackSessionsDb).getFeedbackSession(sessionName, courseId);"},{"lineNumber":232,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":233,"author":{"gitId":"dishenggg"},"content":" assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":234,"author":{"gitId":"dishenggg"},"content":" () -\u003e feedbackSessionsDb.restoreDeletedFeedbackSession(sessionName, courseId));"},{"lineNumber":235,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(feedbackSession), never());"},{"lineNumber":236,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":237,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":237}},{"path":"src/test/java/teammates/test/AbstractBackDoor.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.test;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.io.BufferedReader;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.io.IOException;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.io.InputStreamReader;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.net.URI;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.net.URISyntaxException;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.time.Duration;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import java.util.Collections;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"import org.apache.http.HttpEntity;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import org.apache.http.NameValuePair;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.CloseableHttpResponse;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpDelete;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpGet;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpPost;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpPut;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpRequestBase;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import org.apache.http.client.utils.URIBuilder;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import org.apache.http.entity.StringEntity;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import org.apache.http.impl.client.CloseableHttpClient;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import org.apache.http.impl.client.HttpClients;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import org.apache.http.message.BasicNameValuePair;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":"import com.google.gson.JsonObject;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import com.google.gson.JsonParser;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.DataBundle;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountAttributes;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountRequestAttributes;"},{"lineNumber":41,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":42,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.DeadlineExtensionAttributes;"},{"lineNumber":43,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseAttributes;"},{"lineNumber":45,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseCommentAttributes;"},{"lineNumber":46,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":47,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.NotificationAttributes;"},{"lineNumber":49,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":50,"author":{"gitId":"-"},"content":"import teammates.common.exception.HttpRequestFailedException;"},{"lineNumber":51,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":52,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":53,"author":{"gitId":"-"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":54,"author":{"gitId":"-"},"content":"import teammates.ui.output.AccountData;"},{"lineNumber":55,"author":{"gitId":"-"},"content":"import teammates.ui.output.AccountRequestData;"},{"lineNumber":56,"author":{"gitId":"-"},"content":"import teammates.ui.output.CourseData;"},{"lineNumber":57,"author":{"gitId":"-"},"content":"import teammates.ui.output.CoursesData;"},{"lineNumber":58,"author":{"gitId":"-"},"content":"import teammates.ui.output.DeadlineExtensionData;"},{"lineNumber":59,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackQuestionData;"},{"lineNumber":60,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackQuestionsData;"},{"lineNumber":61,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackResponseCommentData;"},{"lineNumber":62,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackResponseData;"},{"lineNumber":63,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackResponsesData;"},{"lineNumber":64,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionData;"},{"lineNumber":65,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionsData;"},{"lineNumber":66,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackVisibilityType;"},{"lineNumber":67,"author":{"gitId":"-"},"content":"import teammates.ui.output.InstructorData;"},{"lineNumber":68,"author":{"gitId":"-"},"content":"import teammates.ui.output.InstructorsData;"},{"lineNumber":69,"author":{"gitId":"-"},"content":"import teammates.ui.output.MessageOutput;"},{"lineNumber":70,"author":{"gitId":"-"},"content":"import teammates.ui.output.NotificationData;"},{"lineNumber":71,"author":{"gitId":"-"},"content":"import teammates.ui.output.NumberOfEntitiesToGiveFeedbackToSetting;"},{"lineNumber":72,"author":{"gitId":"-"},"content":"import teammates.ui.output.ResponseVisibleSetting;"},{"lineNumber":73,"author":{"gitId":"-"},"content":"import teammates.ui.output.SessionVisibleSetting;"},{"lineNumber":74,"author":{"gitId":"-"},"content":"import teammates.ui.output.StudentData;"},{"lineNumber":75,"author":{"gitId":"-"},"content":"import teammates.ui.request.Intent;"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":78,"author":{"gitId":"-"},"content":" * Used to create API calls to the back-end without going through the UI."},{"lineNumber":79,"author":{"gitId":"-"},"content":" */"},{"lineNumber":80,"author":{"gitId":"-"},"content":"public abstract class AbstractBackDoor {"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":83,"author":{"gitId":"-"},"content":" * Gets the URL of the back-end."},{"lineNumber":84,"author":{"gitId":"-"},"content":" */"},{"lineNumber":85,"author":{"gitId":"-"},"content":" protected abstract String getAppUrl();"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":88,"author":{"gitId":"-"},"content":" * Gets the backdoor key used to authenticate with the back-end."},{"lineNumber":89,"author":{"gitId":"-"},"content":" */"},{"lineNumber":90,"author":{"gitId":"-"},"content":" protected abstract String getBackdoorKey();"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":93,"author":{"gitId":"-"},"content":" * Gets the CSRF key used to authenticate with the back-end."},{"lineNumber":94,"author":{"gitId":"-"},"content":" */"},{"lineNumber":95,"author":{"gitId":"-"},"content":" protected abstract String getCsrfKey();"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":98,"author":{"gitId":"-"},"content":" * Executes GET request with the given {@code relativeUrl}."},{"lineNumber":99,"author":{"gitId":"-"},"content":" *"},{"lineNumber":100,"author":{"gitId":"-"},"content":" * @return The body content and status of the HTTP response"},{"lineNumber":101,"author":{"gitId":"-"},"content":" */"},{"lineNumber":102,"author":{"gitId":"-"},"content":" public ResponseBodyAndCode executeGetRequest(String relativeUrl, Map\u003cString, String\u003e params) {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" return executeRequest(HttpGet.METHOD_NAME, relativeUrl, params, null);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":107,"author":{"gitId":"-"},"content":" * Executes POST request with the given {@code relativeUrl}."},{"lineNumber":108,"author":{"gitId":"-"},"content":" *"},{"lineNumber":109,"author":{"gitId":"-"},"content":" * @return The body content and status of the HTTP response"},{"lineNumber":110,"author":{"gitId":"-"},"content":" */"},{"lineNumber":111,"author":{"gitId":"-"},"content":" public ResponseBodyAndCode executePostRequest(String relativeUrl, Map\u003cString, String\u003e params, String body) {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" return executeRequest(HttpPost.METHOD_NAME, relativeUrl, params, body);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" }"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":116,"author":{"gitId":"-"},"content":" * Executes PUT request with the given {@code relativeUrl}."},{"lineNumber":117,"author":{"gitId":"-"},"content":" *"},{"lineNumber":118,"author":{"gitId":"-"},"content":" * @return The body content and status of the HTTP response"},{"lineNumber":119,"author":{"gitId":"-"},"content":" */"},{"lineNumber":120,"author":{"gitId":"-"},"content":" public ResponseBodyAndCode executePutRequest(String relativeUrl, Map\u003cString, String\u003e params, String body) {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" return executeRequest(HttpPut.METHOD_NAME, relativeUrl, params, body);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" }"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":125,"author":{"gitId":"-"},"content":" * Executes DELETE request with the given {@code relativeUrl}."},{"lineNumber":126,"author":{"gitId":"-"},"content":" *"},{"lineNumber":127,"author":{"gitId":"-"},"content":" * @return The body content and status of the HTTP response"},{"lineNumber":128,"author":{"gitId":"-"},"content":" */"},{"lineNumber":129,"author":{"gitId":"-"},"content":" public ResponseBodyAndCode executeDeleteRequest(String relativeUrl, Map\u003cString, String\u003e params) {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" return executeRequest(HttpDelete.METHOD_NAME, relativeUrl, params, null);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" }"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":134,"author":{"gitId":"-"},"content":" * Executes HTTP request with the given {@code method} and {@code relativeUrl}."},{"lineNumber":135,"author":{"gitId":"-"},"content":" *"},{"lineNumber":136,"author":{"gitId":"-"},"content":" * @return The content of the HTTP response"},{"lineNumber":137,"author":{"gitId":"-"},"content":" */"},{"lineNumber":138,"author":{"gitId":"-"},"content":" private ResponseBodyAndCode executeRequest("},{"lineNumber":139,"author":{"gitId":"-"},"content":" String method, String relativeUrl, Map\u003cString, String\u003e params, String body) {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" String url \u003d getAppUrl() + relativeUrl;"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" HttpRequestBase request;"},{"lineNumber":143,"author":{"gitId":"-"},"content":" switch (method) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" case HttpGet.METHOD_NAME:"},{"lineNumber":145,"author":{"gitId":"-"},"content":" request \u003d createGetRequest(url, params);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":147,"author":{"gitId":"-"},"content":" case HttpPost.METHOD_NAME:"},{"lineNumber":148,"author":{"gitId":"-"},"content":" request \u003d createPostRequest(url, params, body);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":150,"author":{"gitId":"-"},"content":" case HttpPut.METHOD_NAME:"},{"lineNumber":151,"author":{"gitId":"-"},"content":" request \u003d createPutRequest(url, params, body);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":153,"author":{"gitId":"-"},"content":" case HttpDelete.METHOD_NAME:"},{"lineNumber":154,"author":{"gitId":"-"},"content":" request \u003d createDeleteRequest(url, params);"},{"lineNumber":155,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":156,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":157,"author":{"gitId":"-"},"content":" throw new RuntimeException(\"Unaccepted HTTP method: \" + method);"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" addAuthKeys(request);"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"-"},"content":" try (CloseableHttpClient httpClient \u003d HttpClients.createDefault();"},{"lineNumber":163,"author":{"gitId":"-"},"content":" CloseableHttpResponse response \u003d httpClient.execute(request)) {"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" String responseBody \u003d null;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" HttpEntity entity \u003d response.getEntity();"},{"lineNumber":167,"author":{"gitId":"-"},"content":" if (entity !\u003d null) {"},{"lineNumber":168,"author":{"gitId":"-"},"content":" try (BufferedReader br \u003d new BufferedReader("},{"lineNumber":169,"author":{"gitId":"-"},"content":" new InputStreamReader(entity.getContent(), Const.ENCODING))) {"},{"lineNumber":170,"author":{"gitId":"-"},"content":" responseBody \u003d br.lines().collect(Collectors.joining(System.lineSeparator()));"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":" }"},{"lineNumber":173,"author":{"gitId":"-"},"content":" return new ResponseBodyAndCode(responseBody, response.getStatusLine().getStatusCode());"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":178,"author":{"gitId":"-"},"content":" }"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":181,"author":{"gitId":"-"},"content":" * Executes GET request with the given {@code relativeUrl}."},{"lineNumber":182,"author":{"gitId":"-"},"content":" *"},{"lineNumber":183,"author":{"gitId":"-"},"content":" * @return The content of the HTTP response"},{"lineNumber":184,"author":{"gitId":"-"},"content":" */"},{"lineNumber":185,"author":{"gitId":"-"},"content":" private static HttpGet createGetRequest(String url, Map\u003cString, String\u003e params) {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" return new HttpGet(createBasicUri(url, params));"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":" private static HttpPost createPostRequest(String url, Map\u003cString, String\u003e params, String body) {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" HttpPost post \u003d new HttpPost(createBasicUri(url, params));"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"-"},"content":" if (body !\u003d null) {"},{"lineNumber":193,"author":{"gitId":"-"},"content":" StringEntity entity \u003d new StringEntity(body, Const.ENCODING);"},{"lineNumber":194,"author":{"gitId":"-"},"content":" post.setEntity(entity);"},{"lineNumber":195,"author":{"gitId":"-"},"content":" }"},{"lineNumber":196,"author":{"gitId":"-"},"content":""},{"lineNumber":197,"author":{"gitId":"-"},"content":" return post;"},{"lineNumber":198,"author":{"gitId":"-"},"content":" }"},{"lineNumber":199,"author":{"gitId":"-"},"content":""},{"lineNumber":200,"author":{"gitId":"-"},"content":" private static HttpPut createPutRequest(String url, Map\u003cString, String\u003e params, String body) {"},{"lineNumber":201,"author":{"gitId":"-"},"content":" HttpPut put \u003d new HttpPut(createBasicUri(url, params));"},{"lineNumber":202,"author":{"gitId":"-"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":" if (body !\u003d null) {"},{"lineNumber":204,"author":{"gitId":"-"},"content":" StringEntity entity \u003d new StringEntity(body, Const.ENCODING);"},{"lineNumber":205,"author":{"gitId":"-"},"content":" put.setEntity(entity);"},{"lineNumber":206,"author":{"gitId":"-"},"content":" }"},{"lineNumber":207,"author":{"gitId":"-"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" return put;"},{"lineNumber":209,"author":{"gitId":"-"},"content":" }"},{"lineNumber":210,"author":{"gitId":"-"},"content":""},{"lineNumber":211,"author":{"gitId":"-"},"content":" private static HttpDelete createDeleteRequest(String url, Map\u003cString, String\u003e params) {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" return new HttpDelete(createBasicUri(url, params));"},{"lineNumber":213,"author":{"gitId":"-"},"content":" }"},{"lineNumber":214,"author":{"gitId":"-"},"content":""},{"lineNumber":215,"author":{"gitId":"-"},"content":" private static URI createBasicUri(String url, Map\u003cString, String\u003e params) {"},{"lineNumber":216,"author":{"gitId":"-"},"content":" List\u003cNameValuePair\u003e postParameters \u003d new ArrayList\u003c\u003e();"},{"lineNumber":217,"author":{"gitId":"-"},"content":" if (params !\u003d null) {"},{"lineNumber":218,"author":{"gitId":"-"},"content":" params.forEach((key, value) -\u003e postParameters.add(new BasicNameValuePair(key, value)));"},{"lineNumber":219,"author":{"gitId":"-"},"content":" }"},{"lineNumber":220,"author":{"gitId":"-"},"content":""},{"lineNumber":221,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":222,"author":{"gitId":"-"},"content":" URIBuilder uriBuilder \u003d new URIBuilder(url);"},{"lineNumber":223,"author":{"gitId":"-"},"content":" uriBuilder.addParameters(postParameters);"},{"lineNumber":224,"author":{"gitId":"-"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":" return uriBuilder.build();"},{"lineNumber":226,"author":{"gitId":"-"},"content":" } catch (URISyntaxException e) {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":228,"author":{"gitId":"-"},"content":" }"},{"lineNumber":229,"author":{"gitId":"-"},"content":" }"},{"lineNumber":230,"author":{"gitId":"-"},"content":""},{"lineNumber":231,"author":{"gitId":"-"},"content":" private void addAuthKeys(HttpRequestBase request) {"},{"lineNumber":232,"author":{"gitId":"-"},"content":" request.addHeader(Const.HeaderNames.BACKDOOR_KEY, getBackdoorKey());"},{"lineNumber":233,"author":{"gitId":"-"},"content":" request.addHeader(Const.HeaderNames.CSRF_KEY, getCsrfKey());"},{"lineNumber":234,"author":{"gitId":"-"},"content":" }"},{"lineNumber":235,"author":{"gitId":"-"},"content":""},{"lineNumber":236,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":237,"author":{"gitId":"-"},"content":" * Removes and restores given data in the database. This method is to be called on test startup."},{"lineNumber":238,"author":{"gitId":"-"},"content":" *"},{"lineNumber":239,"author":{"gitId":"-"},"content":" * \u003cp\u003eNote: The data associated with the test accounts have to be \u003cstrong\u003emanually\u003c/strong\u003e removed by removing the data"},{"lineNumber":240,"author":{"gitId":"-"},"content":" * bundle when a test ends because the test accounts are shared across tests."},{"lineNumber":241,"author":{"gitId":"-"},"content":" *"},{"lineNumber":242,"author":{"gitId":"-"},"content":" * \u003cp\u003eTest data should never be cleared after test in order to prevent incurring additional database costs because the"},{"lineNumber":243,"author":{"gitId":"-"},"content":" * test\u0027s data may not be accessed in another test. Also although unlikely in normal conditions, when a test fail to"},{"lineNumber":244,"author":{"gitId":"-"},"content":" * remove data bundle on teardown, another test should have no reason to fail."},{"lineNumber":245,"author":{"gitId":"-"},"content":" *"},{"lineNumber":246,"author":{"gitId":"-"},"content":" * \u003cp\u003eAnother reason not to remove associated data after a test is that in case of test failures, it helps to have the"},{"lineNumber":247,"author":{"gitId":"-"},"content":" * associated data in the database to debug the failure."},{"lineNumber":248,"author":{"gitId":"-"},"content":" *"},{"lineNumber":249,"author":{"gitId":"-"},"content":" * \u003cp\u003eThis means that removing the data bundle on startup is not always sufficient because a test only knows how"},{"lineNumber":250,"author":{"gitId":"-"},"content":" * to remove its associated data."},{"lineNumber":251,"author":{"gitId":"-"},"content":" * This is why some tests would fail when they use the same account and use different data."},{"lineNumber":252,"author":{"gitId":"-"},"content":" * Extending this method to remove data outside its associated data would introduce"},{"lineNumber":253,"author":{"gitId":"-"},"content":" * unnecessary complications such as extra costs and knowing exactly how much data to remove. Removing too much data"},{"lineNumber":254,"author":{"gitId":"-"},"content":" * would not just incur higher database costs but we can make tests unexpectedly pass(fail) when the data is expected to"},{"lineNumber":255,"author":{"gitId":"-"},"content":" * be not present(present) in another test."},{"lineNumber":256,"author":{"gitId":"-"},"content":" *"},{"lineNumber":257,"author":{"gitId":"-"},"content":" * \u003cp\u003eTODO: Hence, we need to explicitly remove the data bundle in tests on teardown to avoid instability of tests."},{"lineNumber":258,"author":{"gitId":"-"},"content":" * However, removing the data bundle on teardown manually is not a perfect solution because two tests can concurrently"},{"lineNumber":259,"author":{"gitId":"-"},"content":" * access the same account and their data may get mixed up in the process. This is a major problem we need to address."},{"lineNumber":260,"author":{"gitId":"-"},"content":" */"},{"lineNumber":261,"author":{"gitId":"-"},"content":" public String removeAndRestoreDataBundle(DataBundle dataBundle) throws HttpRequestFailedException {"},{"lineNumber":262,"author":{"gitId":"-"},"content":" removeDataBundle(dataBundle);"},{"lineNumber":263,"author":{"gitId":"-"},"content":" ResponseBodyAndCode putRequestOutput \u003d"},{"lineNumber":264,"author":{"gitId":"-"},"content":" executePostRequest(Const.ResourceURIs.DATABUNDLE, null, JsonUtils.toJson(dataBundle));"},{"lineNumber":265,"author":{"gitId":"-"},"content":" if (putRequestOutput.responseCode !\u003d HttpStatus.SC_OK) {"},{"lineNumber":266,"author":{"gitId":"-"},"content":" throw new HttpRequestFailedException(\"Request failed: [\" + putRequestOutput.responseCode + \"] \""},{"lineNumber":267,"author":{"gitId":"-"},"content":" + putRequestOutput.responseBody);"},{"lineNumber":268,"author":{"gitId":"-"},"content":" }"},{"lineNumber":269,"author":{"gitId":"-"},"content":" return putRequestOutput.responseBody;"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":273,"author":{"gitId":"-"},"content":" * Removes and restores given data in the database. This method is to be called on test startup."},{"lineNumber":274,"author":{"gitId":"-"},"content":" */"},{"lineNumber":275,"author":{"gitId":"-"},"content":" public SqlDataBundle removeAndRestoreSqlDataBundle(SqlDataBundle dataBundle) throws HttpRequestFailedException {"},{"lineNumber":276,"author":{"gitId":"-"},"content":" removeSqlDataBundle(dataBundle);"},{"lineNumber":277,"author":{"gitId":"-"},"content":" ResponseBodyAndCode putRequestOutput \u003d"},{"lineNumber":278,"author":{"gitId":"-"},"content":" executePostRequest(Const.ResourceURIs.SQL_DATABUNDLE, null, JsonUtils.toJson(dataBundle));"},{"lineNumber":279,"author":{"gitId":"-"},"content":" if (putRequestOutput.responseCode !\u003d HttpStatus.SC_OK) {"},{"lineNumber":280,"author":{"gitId":"-"},"content":" throw new HttpRequestFailedException(\"Request failed: [\" + putRequestOutput.responseCode + \"] \""},{"lineNumber":281,"author":{"gitId":"-"},"content":" + putRequestOutput.responseBody);"},{"lineNumber":282,"author":{"gitId":"-"},"content":" }"},{"lineNumber":283,"author":{"gitId":"-"},"content":""},{"lineNumber":284,"author":{"gitId":"-"},"content":" JsonObject jsonObject \u003d JsonParser.parseString(putRequestOutput.responseBody).getAsJsonObject();"},{"lineNumber":285,"author":{"gitId":"-"},"content":" // data bundle is nested under message key"},{"lineNumber":286,"author":{"gitId":"-"},"content":" String message \u003d jsonObject.get(\"message\").getAsString();"},{"lineNumber":287,"author":{"gitId":"-"},"content":" return JsonUtils.fromJson(message, SqlDataBundle.class);"},{"lineNumber":288,"author":{"gitId":"-"},"content":" }"},{"lineNumber":289,"author":{"gitId":"-"},"content":""},{"lineNumber":290,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":291,"author":{"gitId":"-"},"content":" * Removes given data from the database."},{"lineNumber":292,"author":{"gitId":"-"},"content":" *"},{"lineNumber":293,"author":{"gitId":"-"},"content":" * \u003cp\u003eIf given entities have already been deleted, it fails silently."},{"lineNumber":294,"author":{"gitId":"-"},"content":" */"},{"lineNumber":295,"author":{"gitId":"-"},"content":" public void removeDataBundle(DataBundle dataBundle) {"},{"lineNumber":296,"author":{"gitId":"-"},"content":" executePutRequest(Const.ResourceURIs.DATABUNDLE, null, JsonUtils.toJson(dataBundle));"},{"lineNumber":297,"author":{"gitId":"-"},"content":" }"},{"lineNumber":298,"author":{"gitId":"-"},"content":""},{"lineNumber":299,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":300,"author":{"gitId":"-"},"content":" * Removes given data from the database."},{"lineNumber":301,"author":{"gitId":"-"},"content":" *"},{"lineNumber":302,"author":{"gitId":"-"},"content":" * \u003cp\u003eIf given entities have already been deleted, it fails silently."},{"lineNumber":303,"author":{"gitId":"-"},"content":" */"},{"lineNumber":304,"author":{"gitId":"-"},"content":" public void removeSqlDataBundle(SqlDataBundle dataBundle) {"},{"lineNumber":305,"author":{"gitId":"-"},"content":" executePutRequest(Const.ResourceURIs.SQL_DATABUNDLE, null, JsonUtils.toJson(dataBundle));"},{"lineNumber":306,"author":{"gitId":"-"},"content":" }"},{"lineNumber":307,"author":{"gitId":"-"},"content":""},{"lineNumber":308,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":309,"author":{"gitId":"-"},"content":" * Gets the cookie format for the given user ID."},{"lineNumber":310,"author":{"gitId":"-"},"content":" */"},{"lineNumber":311,"author":{"gitId":"-"},"content":" public String getUserCookie(String userId) {"},{"lineNumber":312,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":313,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.USER_ID, userId);"},{"lineNumber":314,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executePostRequest(Const.ResourceURIs.USER_COOKIE, params, null);"},{"lineNumber":315,"author":{"gitId":"-"},"content":""},{"lineNumber":316,"author":{"gitId":"-"},"content":" MessageOutput output \u003d JsonUtils.fromJson(response.responseBody, MessageOutput.class);"},{"lineNumber":317,"author":{"gitId":"-"},"content":" return output.getMessage();"},{"lineNumber":318,"author":{"gitId":"-"},"content":" }"},{"lineNumber":319,"author":{"gitId":"-"},"content":""},{"lineNumber":320,"author":{"gitId":"dishenggg"},"content":" // TODO: remove params after migration"},{"lineNumber":321,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":322,"author":{"gitId":"-"},"content":" * Puts searchable documents in data bundle into the database."},{"lineNumber":323,"author":{"gitId":"-"},"content":" */"},{"lineNumber":324,"author":{"gitId":"-"},"content":" public String putDocuments(DataBundle dataBundle) throws HttpRequestFailedException {"},{"lineNumber":325,"author":{"gitId":"dishenggg"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":326,"author":{"gitId":"dishenggg"},"content":" params.put(\"databundletype\", \"datastore\");"},{"lineNumber":327,"author":{"gitId":"-"},"content":" ResponseBodyAndCode putRequestOutput \u003d"},{"lineNumber":328,"author":{"gitId":"dishenggg"},"content":" executePutRequest(Const.ResourceURIs.DATABUNDLE_DOCUMENTS, params, JsonUtils.toJson(dataBundle));"},{"lineNumber":329,"author":{"gitId":"-"},"content":" if (putRequestOutput.responseCode !\u003d HttpStatus.SC_OK) {"},{"lineNumber":330,"author":{"gitId":"-"},"content":" throw new HttpRequestFailedException(\"Request failed: [\" + putRequestOutput.responseCode + \"] \""},{"lineNumber":331,"author":{"gitId":"-"},"content":" + putRequestOutput.responseBody);"},{"lineNumber":332,"author":{"gitId":"-"},"content":" }"},{"lineNumber":333,"author":{"gitId":"-"},"content":" return putRequestOutput.responseBody;"},{"lineNumber":334,"author":{"gitId":"-"},"content":" }"},{"lineNumber":335,"author":{"gitId":"-"},"content":""},{"lineNumber":336,"author":{"gitId":"dishenggg"},"content":" // TODO: remove method after migration"},{"lineNumber":337,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":338,"author":{"gitId":"dishenggg"},"content":" * Puts searchable documents in data bundle into the SQL database."},{"lineNumber":339,"author":{"gitId":"-"},"content":" */"},{"lineNumber":340,"author":{"gitId":"dishenggg"},"content":" public String putSqlDocuments(SqlDataBundle dataBundle) throws HttpRequestFailedException {"},{"lineNumber":341,"author":{"gitId":"dishenggg"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":342,"author":{"gitId":"dishenggg"},"content":" params.put(\"databundletype\", \"sql\");"},{"lineNumber":343,"author":{"gitId":"-"},"content":" ResponseBodyAndCode putRequestOutput \u003d"},{"lineNumber":344,"author":{"gitId":"dishenggg"},"content":" executePutRequest(Const.ResourceURIs.DATABUNDLE_DOCUMENTS, params, JsonUtils.toJson(dataBundle));"},{"lineNumber":345,"author":{"gitId":"-"},"content":" if (putRequestOutput.responseCode !\u003d HttpStatus.SC_OK) {"},{"lineNumber":346,"author":{"gitId":"-"},"content":" throw new HttpRequestFailedException(\"Request failed: [\" + putRequestOutput.responseCode + \"] \""},{"lineNumber":347,"author":{"gitId":"-"},"content":" + putRequestOutput.responseBody);"},{"lineNumber":348,"author":{"gitId":"-"},"content":" }"},{"lineNumber":349,"author":{"gitId":"-"},"content":" return putRequestOutput.responseBody;"},{"lineNumber":350,"author":{"gitId":"-"},"content":" }"},{"lineNumber":351,"author":{"gitId":"-"},"content":""},{"lineNumber":352,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":353,"author":{"gitId":"-"},"content":" * Gets account data from the database."},{"lineNumber":354,"author":{"gitId":"-"},"content":" */"},{"lineNumber":355,"author":{"gitId":"-"},"content":" public AccountData getAccountData(String googleId) {"},{"lineNumber":356,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":357,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.INSTRUCTOR_ID, googleId);"},{"lineNumber":358,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.ACCOUNT, params);"},{"lineNumber":359,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":360,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":361,"author":{"gitId":"-"},"content":" }"},{"lineNumber":362,"author":{"gitId":"-"},"content":""},{"lineNumber":363,"author":{"gitId":"-"},"content":" return JsonUtils.fromJson(response.responseBody, AccountData.class);"},{"lineNumber":364,"author":{"gitId":"-"},"content":" }"},{"lineNumber":365,"author":{"gitId":"-"},"content":""},{"lineNumber":366,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":367,"author":{"gitId":"-"},"content":" * Gets an account from the database."},{"lineNumber":368,"author":{"gitId":"-"},"content":" */"},{"lineNumber":369,"author":{"gitId":"-"},"content":" public AccountAttributes getAccount(String googleId) {"},{"lineNumber":370,"author":{"gitId":"-"},"content":" AccountData accountData \u003d getAccountData(googleId);"},{"lineNumber":371,"author":{"gitId":"-"},"content":" return AccountAttributes.builder(accountData.getGoogleId())"},{"lineNumber":372,"author":{"gitId":"-"},"content":" .withName(accountData.getName())"},{"lineNumber":373,"author":{"gitId":"-"},"content":" .withEmail(accountData.getEmail())"},{"lineNumber":374,"author":{"gitId":"-"},"content":" .withReadNotifications("},{"lineNumber":375,"author":{"gitId":"-"},"content":" accountData.getReadNotifications()"},{"lineNumber":376,"author":{"gitId":"-"},"content":" .entrySet()"},{"lineNumber":377,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":378,"author":{"gitId":"-"},"content":" .collect(Collectors.toMap("},{"lineNumber":379,"author":{"gitId":"-"},"content":" e -\u003e e.getKey(),"},{"lineNumber":380,"author":{"gitId":"-"},"content":" e -\u003e Instant.ofEpochMilli(e.getValue())"},{"lineNumber":381,"author":{"gitId":"-"},"content":" ))"},{"lineNumber":382,"author":{"gitId":"-"},"content":" )"},{"lineNumber":383,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":384,"author":{"gitId":"-"},"content":" }"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":387,"author":{"gitId":"-"},"content":" * Gets course data from the database."},{"lineNumber":388,"author":{"gitId":"-"},"content":" */"},{"lineNumber":389,"author":{"gitId":"-"},"content":" public CourseData getCourseData(String courseId) {"},{"lineNumber":390,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":391,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.COURSE_ID, courseId);"},{"lineNumber":392,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.COURSE, params);"},{"lineNumber":393,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":394,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":395,"author":{"gitId":"-"},"content":" }"},{"lineNumber":396,"author":{"gitId":"-"},"content":""},{"lineNumber":397,"author":{"gitId":"-"},"content":" return JsonUtils.fromJson(response.responseBody, CourseData.class);"},{"lineNumber":398,"author":{"gitId":"-"},"content":" }"},{"lineNumber":399,"author":{"gitId":"-"},"content":""},{"lineNumber":400,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":401,"author":{"gitId":"-"},"content":" * Gets a course from the database."},{"lineNumber":402,"author":{"gitId":"-"},"content":" */"},{"lineNumber":403,"author":{"gitId":"-"},"content":" public CourseAttributes getCourse(String courseId) {"},{"lineNumber":404,"author":{"gitId":"-"},"content":" CourseData courseData \u003d getCourseData(courseId);"},{"lineNumber":405,"author":{"gitId":"-"},"content":" if (courseData \u003d\u003d null) {"},{"lineNumber":406,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":407,"author":{"gitId":"-"},"content":" }"},{"lineNumber":408,"author":{"gitId":"-"},"content":" return CourseAttributes.builder(courseData.getCourseId())"},{"lineNumber":409,"author":{"gitId":"-"},"content":" .withName(courseData.getCourseName())"},{"lineNumber":410,"author":{"gitId":"-"},"content":" .withTimezone(courseData.getTimeZone())"},{"lineNumber":411,"author":{"gitId":"-"},"content":" .withInstitute(courseData.getInstitute())"},{"lineNumber":412,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":413,"author":{"gitId":"-"},"content":" }"},{"lineNumber":414,"author":{"gitId":"-"},"content":""},{"lineNumber":415,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":416,"author":{"gitId":"-"},"content":" * Gets archived course data from the database."},{"lineNumber":417,"author":{"gitId":"-"},"content":" */"},{"lineNumber":418,"author":{"gitId":"-"},"content":" public CourseData getArchivedCourseData(String instructorId, String courseId) {"},{"lineNumber":419,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":420,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.USER_ID, instructorId);"},{"lineNumber":421,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.COURSE_ID, courseId);"},{"lineNumber":422,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR);"},{"lineNumber":423,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.COURSE_STATUS, Const.CourseStatus.ARCHIVED);"},{"lineNumber":424,"author":{"gitId":"-"},"content":""},{"lineNumber":425,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.COURSES, params);"},{"lineNumber":426,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":428,"author":{"gitId":"-"},"content":" }"},{"lineNumber":429,"author":{"gitId":"-"},"content":""},{"lineNumber":430,"author":{"gitId":"-"},"content":" CoursesData coursesData \u003d JsonUtils.fromJson(response.responseBody, CoursesData.class);"},{"lineNumber":431,"author":{"gitId":"-"},"content":" CourseData courseData \u003d coursesData.getCourses()"},{"lineNumber":432,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":433,"author":{"gitId":"-"},"content":" .filter(cd -\u003e cd.getCourseId().equals(courseId))"},{"lineNumber":434,"author":{"gitId":"-"},"content":" .findFirst()"},{"lineNumber":435,"author":{"gitId":"-"},"content":" .orElse(null);"},{"lineNumber":436,"author":{"gitId":"-"},"content":""},{"lineNumber":437,"author":{"gitId":"-"},"content":" if (courseData \u003d\u003d null) {"},{"lineNumber":438,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":439,"author":{"gitId":"-"},"content":" }"},{"lineNumber":440,"author":{"gitId":"-"},"content":""},{"lineNumber":441,"author":{"gitId":"-"},"content":" return courseData;"},{"lineNumber":442,"author":{"gitId":"-"},"content":" }"},{"lineNumber":443,"author":{"gitId":"-"},"content":""},{"lineNumber":444,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":445,"author":{"gitId":"-"},"content":" * Gets a archived course from the database."},{"lineNumber":446,"author":{"gitId":"-"},"content":" */"},{"lineNumber":447,"author":{"gitId":"-"},"content":" public CourseAttributes getArchivedCourse(String instructorId, String courseId) {"},{"lineNumber":448,"author":{"gitId":"-"},"content":" CourseData courseData \u003d getArchivedCourseData(instructorId, courseId);"},{"lineNumber":449,"author":{"gitId":"-"},"content":" if (courseData \u003d\u003d null) {"},{"lineNumber":450,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":451,"author":{"gitId":"-"},"content":" }"},{"lineNumber":452,"author":{"gitId":"-"},"content":" return CourseAttributes.builder(courseData.getCourseId())"},{"lineNumber":453,"author":{"gitId":"-"},"content":" .withName(courseData.getCourseName())"},{"lineNumber":454,"author":{"gitId":"-"},"content":" .withTimezone(courseData.getTimeZone())"},{"lineNumber":455,"author":{"gitId":"-"},"content":" .withInstitute(courseData.getInstitute())"},{"lineNumber":456,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":457,"author":{"gitId":"-"},"content":" }"},{"lineNumber":458,"author":{"gitId":"-"},"content":""},{"lineNumber":459,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":460,"author":{"gitId":"-"},"content":" * Returns true if the course exists and is in recycle bin."},{"lineNumber":461,"author":{"gitId":"-"},"content":" */"},{"lineNumber":462,"author":{"gitId":"-"},"content":" public boolean isCourseInRecycleBin(String courseId) {"},{"lineNumber":463,"author":{"gitId":"-"},"content":" CourseData courseData \u003d getCourseData(courseId);"},{"lineNumber":464,"author":{"gitId":"-"},"content":" if (courseData \u003d\u003d null) {"},{"lineNumber":465,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":466,"author":{"gitId":"-"},"content":" }"},{"lineNumber":467,"author":{"gitId":"-"},"content":" return courseData.getDeletionTimestamp() !\u003d 0;"},{"lineNumber":468,"author":{"gitId":"-"},"content":" }"},{"lineNumber":469,"author":{"gitId":"-"},"content":""},{"lineNumber":470,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":471,"author":{"gitId":"-"},"content":" * Gets instructor data from the database."},{"lineNumber":472,"author":{"gitId":"-"},"content":" */"},{"lineNumber":473,"author":{"gitId":"-"},"content":" public InstructorData getInstructorData(String courseId, String email) {"},{"lineNumber":474,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":475,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.COURSE_ID, courseId);"},{"lineNumber":476,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.INTENT, Intent.FULL_DETAIL.toString());"},{"lineNumber":477,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.INSTRUCTORS, params);"},{"lineNumber":478,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":479,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":480,"author":{"gitId":"-"},"content":" }"},{"lineNumber":481,"author":{"gitId":"-"},"content":""},{"lineNumber":482,"author":{"gitId":"-"},"content":" InstructorsData instructorsData \u003d JsonUtils.fromJson(response.responseBody, InstructorsData.class);"},{"lineNumber":483,"author":{"gitId":"-"},"content":" InstructorData instructorData \u003d instructorsData.getInstructors()"},{"lineNumber":484,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":485,"author":{"gitId":"-"},"content":" .filter(instructor -\u003e instructor.getEmail().equals(email))"},{"lineNumber":486,"author":{"gitId":"-"},"content":" .findFirst()"},{"lineNumber":487,"author":{"gitId":"-"},"content":" .orElse(null);"},{"lineNumber":488,"author":{"gitId":"-"},"content":""},{"lineNumber":489,"author":{"gitId":"-"},"content":" if (instructorData \u003d\u003d null) {"},{"lineNumber":490,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":491,"author":{"gitId":"-"},"content":" }"},{"lineNumber":492,"author":{"gitId":"-"},"content":""},{"lineNumber":493,"author":{"gitId":"-"},"content":" return instructorData;"},{"lineNumber":494,"author":{"gitId":"-"},"content":" }"},{"lineNumber":495,"author":{"gitId":"-"},"content":""},{"lineNumber":496,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":497,"author":{"gitId":"-"},"content":" * Get instructor from database. Does not include certain fields like InstructorPrivileges."},{"lineNumber":498,"author":{"gitId":"-"},"content":" */"},{"lineNumber":499,"author":{"gitId":"-"},"content":" public InstructorAttributes getInstructor(String courseId, String instructorEmail) {"},{"lineNumber":500,"author":{"gitId":"-"},"content":" InstructorData instructorData \u003d getInstructorData(courseId, instructorEmail);"},{"lineNumber":501,"author":{"gitId":"-"},"content":" if (instructorData \u003d\u003d null) {"},{"lineNumber":502,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":503,"author":{"gitId":"-"},"content":" }"},{"lineNumber":504,"author":{"gitId":"-"},"content":" InstructorAttributes.Builder instructor \u003d InstructorAttributes.builder(instructorData.getCourseId(),"},{"lineNumber":505,"author":{"gitId":"-"},"content":" instructorData.getEmail());"},{"lineNumber":506,"author":{"gitId":"-"},"content":" if (instructorData.getGoogleId() !\u003d null) {"},{"lineNumber":507,"author":{"gitId":"-"},"content":" instructor.withGoogleId(instructorData.getGoogleId());"},{"lineNumber":508,"author":{"gitId":"-"},"content":" }"},{"lineNumber":509,"author":{"gitId":"-"},"content":" if (instructorData.getName() !\u003d null) {"},{"lineNumber":510,"author":{"gitId":"-"},"content":" instructor.withName(instructorData.getName());"},{"lineNumber":511,"author":{"gitId":"-"},"content":" }"},{"lineNumber":512,"author":{"gitId":"-"},"content":" if (instructorData.getRole() !\u003d null) {"},{"lineNumber":513,"author":{"gitId":"-"},"content":" instructor.withRole(instructorData.getRole().getRoleName());"},{"lineNumber":514,"author":{"gitId":"-"},"content":" }"},{"lineNumber":515,"author":{"gitId":"-"},"content":" if (instructorData.getIsDisplayedToStudents() !\u003d null) {"},{"lineNumber":516,"author":{"gitId":"-"},"content":" instructor.withIsDisplayedToStudents(instructorData.getIsDisplayedToStudents());"},{"lineNumber":517,"author":{"gitId":"-"},"content":" }"},{"lineNumber":518,"author":{"gitId":"-"},"content":" if (instructorData.getDisplayedToStudentsAs() !\u003d null) {"},{"lineNumber":519,"author":{"gitId":"-"},"content":" instructor.withDisplayedName(instructorData.getDisplayedToStudentsAs());"},{"lineNumber":520,"author":{"gitId":"-"},"content":" }"},{"lineNumber":521,"author":{"gitId":"-"},"content":" InstructorAttributes instructorAttributes \u003d instructor.build();"},{"lineNumber":522,"author":{"gitId":"-"},"content":" if (instructorData.getKey() !\u003d null) {"},{"lineNumber":523,"author":{"gitId":"-"},"content":" instructorAttributes.setKey(instructorData.getKey());"},{"lineNumber":524,"author":{"gitId":"-"},"content":" }"},{"lineNumber":525,"author":{"gitId":"-"},"content":" return instructorAttributes;"},{"lineNumber":526,"author":{"gitId":"-"},"content":" }"},{"lineNumber":527,"author":{"gitId":"-"},"content":""},{"lineNumber":528,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":529,"author":{"gitId":"-"},"content":" * Gets student data from the database."},{"lineNumber":530,"author":{"gitId":"-"},"content":" */"},{"lineNumber":531,"author":{"gitId":"-"},"content":" public StudentData getStudentData(String courseId, String studentEmail) {"},{"lineNumber":532,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":533,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.COURSE_ID, courseId);"},{"lineNumber":534,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.STUDENT_EMAIL, studentEmail);"},{"lineNumber":535,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.STUDENT, params);"},{"lineNumber":536,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":537,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":538,"author":{"gitId":"-"},"content":" }"},{"lineNumber":539,"author":{"gitId":"-"},"content":" return JsonUtils.fromJson(response.responseBody, StudentData.class);"},{"lineNumber":540,"author":{"gitId":"-"},"content":" }"},{"lineNumber":541,"author":{"gitId":"-"},"content":""},{"lineNumber":542,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":543,"author":{"gitId":"-"},"content":" * Get student from database."},{"lineNumber":544,"author":{"gitId":"-"},"content":" */"},{"lineNumber":545,"author":{"gitId":"-"},"content":" public StudentAttributes getStudent(String courseId, String studentEmail) {"},{"lineNumber":546,"author":{"gitId":"-"},"content":" StudentData studentData \u003d getStudentData(courseId, studentEmail);"},{"lineNumber":547,"author":{"gitId":"-"},"content":" if (studentData \u003d\u003d null) {"},{"lineNumber":548,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":549,"author":{"gitId":"-"},"content":" }"},{"lineNumber":550,"author":{"gitId":"-"},"content":" StudentAttributes.Builder builder \u003d StudentAttributes.builder(studentData.getCourseId(),"},{"lineNumber":551,"author":{"gitId":"-"},"content":" studentData.getEmail());"},{"lineNumber":552,"author":{"gitId":"-"},"content":" if (studentData.getGoogleId() !\u003d null) {"},{"lineNumber":553,"author":{"gitId":"-"},"content":" builder.withGoogleId(studentData.getGoogleId());"},{"lineNumber":554,"author":{"gitId":"-"},"content":" }"},{"lineNumber":555,"author":{"gitId":"-"},"content":" if (studentData.getName() !\u003d null) {"},{"lineNumber":556,"author":{"gitId":"-"},"content":" builder.withName(studentData.getName());"},{"lineNumber":557,"author":{"gitId":"-"},"content":" }"},{"lineNumber":558,"author":{"gitId":"-"},"content":" if (studentData.getSectionName() !\u003d null) {"},{"lineNumber":559,"author":{"gitId":"-"},"content":" builder.withSectionName(studentData.getSectionName());"},{"lineNumber":560,"author":{"gitId":"-"},"content":" }"},{"lineNumber":561,"author":{"gitId":"-"},"content":" if (studentData.getTeamName() !\u003d null) {"},{"lineNumber":562,"author":{"gitId":"-"},"content":" builder.withTeamName(studentData.getTeamName());"},{"lineNumber":563,"author":{"gitId":"-"},"content":" }"},{"lineNumber":564,"author":{"gitId":"-"},"content":" if (studentData.getComments() !\u003d null) {"},{"lineNumber":565,"author":{"gitId":"-"},"content":" builder.withComment(studentData.getComments());"},{"lineNumber":566,"author":{"gitId":"-"},"content":" }"},{"lineNumber":567,"author":{"gitId":"-"},"content":" StudentAttributes student \u003d builder.build();"},{"lineNumber":568,"author":{"gitId":"-"},"content":" if (studentData.getKey() !\u003d null) {"},{"lineNumber":569,"author":{"gitId":"-"},"content":" student.setKey(studentData.getKey());"},{"lineNumber":570,"author":{"gitId":"-"},"content":" }"},{"lineNumber":571,"author":{"gitId":"-"},"content":" return student;"},{"lineNumber":572,"author":{"gitId":"-"},"content":" }"},{"lineNumber":573,"author":{"gitId":"-"},"content":""},{"lineNumber":574,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":575,"author":{"gitId":"-"},"content":" * Get feedback session data from database."},{"lineNumber":576,"author":{"gitId":"-"},"content":" */"},{"lineNumber":577,"author":{"gitId":"-"},"content":" public FeedbackSessionData getFeedbackSessionData(String courseId, String feedbackSessionName) {"},{"lineNumber":578,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":579,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.COURSE_ID, courseId);"},{"lineNumber":580,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSessionName);"},{"lineNumber":581,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.INTENT, Intent.FULL_DETAIL.toString());"},{"lineNumber":582,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.SESSION, params);"},{"lineNumber":583,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":584,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":585,"author":{"gitId":"-"},"content":" }"},{"lineNumber":586,"author":{"gitId":"-"},"content":" return JsonUtils.fromJson(response.responseBody, FeedbackSessionData.class);"},{"lineNumber":587,"author":{"gitId":"-"},"content":" }"},{"lineNumber":588,"author":{"gitId":"-"},"content":""},{"lineNumber":589,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":590,"author":{"gitId":"-"},"content":" * Get feedback session from database."},{"lineNumber":591,"author":{"gitId":"-"},"content":" */"},{"lineNumber":592,"author":{"gitId":"-"},"content":" public FeedbackSessionAttributes getFeedbackSession(String courseId, String feedbackSessionName) {"},{"lineNumber":593,"author":{"gitId":"-"},"content":" FeedbackSessionData sessionData \u003d getFeedbackSessionData(courseId, feedbackSessionName);"},{"lineNumber":594,"author":{"gitId":"-"},"content":" if (sessionData \u003d\u003d null) {"},{"lineNumber":595,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":596,"author":{"gitId":"-"},"content":" }"},{"lineNumber":597,"author":{"gitId":"-"},"content":""},{"lineNumber":598,"author":{"gitId":"-"},"content":" Map\u003cString, Instant\u003e studentDeadlines \u003d"},{"lineNumber":599,"author":{"gitId":"-"},"content":" convertDeadlinesToInstant(sessionData.getStudentDeadlines(), sessionData.getTimeZone());"},{"lineNumber":600,"author":{"gitId":"-"},"content":" Map\u003cString, Instant\u003e instructorDeadlines \u003d"},{"lineNumber":601,"author":{"gitId":"-"},"content":" convertDeadlinesToInstant(sessionData.getInstructorDeadlines(), sessionData.getTimeZone());"},{"lineNumber":602,"author":{"gitId":"-"},"content":""},{"lineNumber":603,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes sessionAttributes \u003d FeedbackSessionAttributes"},{"lineNumber":604,"author":{"gitId":"-"},"content":" .builder(sessionData.getFeedbackSessionName(), sessionData.getCourseId())"},{"lineNumber":605,"author":{"gitId":"-"},"content":" .withInstructions(sessionData.getInstructions())"},{"lineNumber":606,"author":{"gitId":"-"},"content":" .withStartTime(Instant.ofEpochMilli(sessionData.getSubmissionStartTimestamp()))"},{"lineNumber":607,"author":{"gitId":"-"},"content":" .withEndTime(Instant.ofEpochMilli(sessionData.getSubmissionEndTimestamp()))"},{"lineNumber":608,"author":{"gitId":"-"},"content":" .withTimeZone(sessionData.getTimeZone())"},{"lineNumber":609,"author":{"gitId":"-"},"content":" .withGracePeriod(Duration.ofMinutes(sessionData.getGracePeriod()))"},{"lineNumber":610,"author":{"gitId":"-"},"content":" .withIsClosingEmailEnabled(sessionData.getIsClosingEmailEnabled())"},{"lineNumber":611,"author":{"gitId":"-"},"content":" .withIsPublishedEmailEnabled(sessionData.getIsPublishedEmailEnabled())"},{"lineNumber":612,"author":{"gitId":"-"},"content":" .withStudentDeadlines(studentDeadlines)"},{"lineNumber":613,"author":{"gitId":"-"},"content":" .withInstructorDeadlines(instructorDeadlines)"},{"lineNumber":614,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":615,"author":{"gitId":"-"},"content":""},{"lineNumber":616,"author":{"gitId":"-"},"content":" sessionAttributes.setCreatedTime(Instant.ofEpochMilli(sessionData.getCreatedAtTimestamp()));"},{"lineNumber":617,"author":{"gitId":"-"},"content":""},{"lineNumber":618,"author":{"gitId":"-"},"content":" if (sessionData.getSessionVisibleSetting().equals(SessionVisibleSetting.AT_OPEN)) {"},{"lineNumber":619,"author":{"gitId":"-"},"content":" sessionAttributes.setSessionVisibleFromTime(Const.TIME_REPRESENTS_FOLLOW_OPENING);"},{"lineNumber":620,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":621,"author":{"gitId":"-"},"content":" sessionAttributes.setSessionVisibleFromTime(Instant.ofEpochMilli("},{"lineNumber":622,"author":{"gitId":"-"},"content":" sessionData.getCustomSessionVisibleTimestamp()));"},{"lineNumber":623,"author":{"gitId":"-"},"content":" }"},{"lineNumber":624,"author":{"gitId":"-"},"content":""},{"lineNumber":625,"author":{"gitId":"-"},"content":" if (sessionData.getResponseVisibleSetting().equals(ResponseVisibleSetting.AT_VISIBLE)) {"},{"lineNumber":626,"author":{"gitId":"-"},"content":" sessionAttributes.setResultsVisibleFromTime(Const.TIME_REPRESENTS_FOLLOW_VISIBLE);"},{"lineNumber":627,"author":{"gitId":"-"},"content":" } else if (sessionData.getResponseVisibleSetting().equals(ResponseVisibleSetting.LATER)) {"},{"lineNumber":628,"author":{"gitId":"-"},"content":" sessionAttributes.setResultsVisibleFromTime(Const.TIME_REPRESENTS_LATER);"},{"lineNumber":629,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":630,"author":{"gitId":"-"},"content":" sessionAttributes.setResultsVisibleFromTime(Instant.ofEpochMilli("},{"lineNumber":631,"author":{"gitId":"-"},"content":" sessionData.getCustomResponseVisibleTimestamp()));"},{"lineNumber":632,"author":{"gitId":"-"},"content":" }"},{"lineNumber":633,"author":{"gitId":"-"},"content":""},{"lineNumber":634,"author":{"gitId":"-"},"content":" return sessionAttributes;"},{"lineNumber":635,"author":{"gitId":"-"},"content":" }"},{"lineNumber":636,"author":{"gitId":"-"},"content":""},{"lineNumber":637,"author":{"gitId":"-"},"content":" private Map\u003cString, Instant\u003e convertDeadlinesToInstant(Map\u003cString, Long\u003e deadlines, String timezone) {"},{"lineNumber":638,"author":{"gitId":"-"},"content":" return deadlines.entrySet()"},{"lineNumber":639,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":640,"author":{"gitId":"-"},"content":" .collect(Collectors.toMap(Map.Entry::getKey, entry -\u003e {"},{"lineNumber":641,"author":{"gitId":"-"},"content":" Instant deadline \u003d Instant.ofEpochMilli(entry.getValue());"},{"lineNumber":642,"author":{"gitId":"-"},"content":" return TimeHelper.getMidnightAdjustedInstantBasedOnZone(deadline, timezone, true);"},{"lineNumber":643,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":644,"author":{"gitId":"-"},"content":" }"},{"lineNumber":645,"author":{"gitId":"-"},"content":""},{"lineNumber":646,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":647,"author":{"gitId":"-"},"content":" * Get soft deleted feedback session from database."},{"lineNumber":648,"author":{"gitId":"-"},"content":" */"},{"lineNumber":649,"author":{"gitId":"-"},"content":" public FeedbackSessionData getSoftDeletedSessionData(String feedbackSessionName, String instructorId) {"},{"lineNumber":650,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":651,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR);"},{"lineNumber":652,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.IS_IN_RECYCLE_BIN, \"true\");"},{"lineNumber":653,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.USER_ID, instructorId);"},{"lineNumber":654,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.SESSIONS, params);"},{"lineNumber":655,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":656,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":657,"author":{"gitId":"-"},"content":" }"},{"lineNumber":658,"author":{"gitId":"-"},"content":""},{"lineNumber":659,"author":{"gitId":"-"},"content":" FeedbackSessionsData sessionsData \u003d JsonUtils.fromJson(response.responseBody, FeedbackSessionsData.class);"},{"lineNumber":660,"author":{"gitId":"-"},"content":" return sessionsData.getFeedbackSessions()"},{"lineNumber":661,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":662,"author":{"gitId":"-"},"content":" .filter(fs -\u003e fs.getFeedbackSessionName().equals(feedbackSessionName))"},{"lineNumber":663,"author":{"gitId":"-"},"content":" .findFirst()"},{"lineNumber":664,"author":{"gitId":"-"},"content":" .orElse(null);"},{"lineNumber":665,"author":{"gitId":"-"},"content":" }"},{"lineNumber":666,"author":{"gitId":"-"},"content":""},{"lineNumber":667,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":668,"author":{"gitId":"-"},"content":" * Get soft deleted feedback session from database."},{"lineNumber":669,"author":{"gitId":"-"},"content":" */"},{"lineNumber":670,"author":{"gitId":"-"},"content":" public FeedbackSessionAttributes getSoftDeletedSession(String feedbackSessionName, String instructorId) {"},{"lineNumber":671,"author":{"gitId":"-"},"content":" FeedbackSessionData feedbackSession \u003d getSoftDeletedSessionData(feedbackSessionName, instructorId);"},{"lineNumber":672,"author":{"gitId":"-"},"content":" if (feedbackSession \u003d\u003d null) {"},{"lineNumber":673,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":674,"author":{"gitId":"-"},"content":" }"},{"lineNumber":675,"author":{"gitId":"-"},"content":""},{"lineNumber":676,"author":{"gitId":"-"},"content":" return FeedbackSessionAttributes"},{"lineNumber":677,"author":{"gitId":"-"},"content":" .builder(feedbackSession.getCourseId(), feedbackSession.getFeedbackSessionName())"},{"lineNumber":678,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":679,"author":{"gitId":"-"},"content":" }"},{"lineNumber":680,"author":{"gitId":"-"},"content":""},{"lineNumber":681,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":682,"author":{"gitId":"-"},"content":" * Get feedback question data from database."},{"lineNumber":683,"author":{"gitId":"-"},"content":" */"},{"lineNumber":684,"author":{"gitId":"-"},"content":" public FeedbackQuestionData getFeedbackQuestionData(String courseId, String feedbackSessionName,"},{"lineNumber":685,"author":{"gitId":"-"},"content":" int qnNumber) {"},{"lineNumber":686,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":687,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.COURSE_ID, courseId);"},{"lineNumber":688,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSessionName);"},{"lineNumber":689,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.INTENT, Intent.FULL_DETAIL.toString());"},{"lineNumber":690,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.QUESTIONS, params);"},{"lineNumber":691,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":692,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":693,"author":{"gitId":"-"},"content":" }"},{"lineNumber":694,"author":{"gitId":"-"},"content":""},{"lineNumber":695,"author":{"gitId":"-"},"content":" FeedbackQuestionsData questionsData \u003d JsonUtils.fromJson(response.responseBody, FeedbackQuestionsData.class);"},{"lineNumber":696,"author":{"gitId":"-"},"content":" return questionsData.getQuestions()"},{"lineNumber":697,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":698,"author":{"gitId":"-"},"content":" .filter(fq -\u003e fq.getQuestionNumber() \u003d\u003d qnNumber)"},{"lineNumber":699,"author":{"gitId":"-"},"content":" .findFirst()"},{"lineNumber":700,"author":{"gitId":"-"},"content":" .orElse(null);"},{"lineNumber":701,"author":{"gitId":"-"},"content":" }"},{"lineNumber":702,"author":{"gitId":"-"},"content":""},{"lineNumber":703,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":704,"author":{"gitId":"-"},"content":" * Get feedback question from database."},{"lineNumber":705,"author":{"gitId":"-"},"content":" */"},{"lineNumber":706,"author":{"gitId":"-"},"content":" public FeedbackQuestionAttributes getFeedbackQuestion(String courseId, String feedbackSessionName,"},{"lineNumber":707,"author":{"gitId":"-"},"content":" int qnNumber) {"},{"lineNumber":708,"author":{"gitId":"-"},"content":" FeedbackQuestionData question \u003d getFeedbackQuestionData(courseId, feedbackSessionName, qnNumber);"},{"lineNumber":709,"author":{"gitId":"-"},"content":""},{"lineNumber":710,"author":{"gitId":"-"},"content":" if (question \u003d\u003d null) {"},{"lineNumber":711,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":712,"author":{"gitId":"-"},"content":" }"},{"lineNumber":713,"author":{"gitId":"-"},"content":""},{"lineNumber":714,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes questionAttr \u003d FeedbackQuestionAttributes.builder()"},{"lineNumber":715,"author":{"gitId":"-"},"content":" .withCourseId(courseId)"},{"lineNumber":716,"author":{"gitId":"-"},"content":" .withFeedbackSessionName(feedbackSessionName)"},{"lineNumber":717,"author":{"gitId":"-"},"content":" .withQuestionDetails(question.getQuestionDetails())"},{"lineNumber":718,"author":{"gitId":"-"},"content":" .withQuestionDescription(question.getQuestionDescription())"},{"lineNumber":719,"author":{"gitId":"-"},"content":" .withQuestionNumber(question.getQuestionNumber())"},{"lineNumber":720,"author":{"gitId":"-"},"content":" .withGiverType(question.getGiverType())"},{"lineNumber":721,"author":{"gitId":"-"},"content":" .withRecipientType(question.getRecipientType())"},{"lineNumber":722,"author":{"gitId":"-"},"content":" .withNumberOfEntitiesToGiveFeedbackTo(question.getNumberOfEntitiesToGiveFeedbackToSetting()"},{"lineNumber":723,"author":{"gitId":"-"},"content":" .equals(NumberOfEntitiesToGiveFeedbackToSetting.UNLIMITED)"},{"lineNumber":724,"author":{"gitId":"-"},"content":" ? Const.MAX_POSSIBLE_RECIPIENTS"},{"lineNumber":725,"author":{"gitId":"-"},"content":" : question.getCustomNumberOfEntitiesToGiveFeedbackTo())"},{"lineNumber":726,"author":{"gitId":"-"},"content":" .withShowResponsesTo(convertToFeedbackParticipantType(question.getShowResponsesTo()))"},{"lineNumber":727,"author":{"gitId":"-"},"content":" .withShowGiverNameTo(convertToFeedbackParticipantType(question.getShowGiverNameTo()))"},{"lineNumber":728,"author":{"gitId":"-"},"content":" .withShowRecipientNameTo(convertToFeedbackParticipantType(question.getShowRecipientNameTo()))"},{"lineNumber":729,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":730,"author":{"gitId":"-"},"content":" if (question.getFeedbackQuestionId() !\u003d null) {"},{"lineNumber":731,"author":{"gitId":"-"},"content":" questionAttr.setId(question.getFeedbackQuestionId());"},{"lineNumber":732,"author":{"gitId":"-"},"content":" }"},{"lineNumber":733,"author":{"gitId":"-"},"content":" return questionAttr;"},{"lineNumber":734,"author":{"gitId":"-"},"content":" }"},{"lineNumber":735,"author":{"gitId":"-"},"content":""},{"lineNumber":736,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":737,"author":{"gitId":"-"},"content":" * Converts List of FeedbackParticipantType to sorted List of FeedbackVisibilityType."},{"lineNumber":738,"author":{"gitId":"-"},"content":" */"},{"lineNumber":739,"author":{"gitId":"-"},"content":" private static List\u003cFeedbackParticipantType\u003e convertToFeedbackParticipantType("},{"lineNumber":740,"author":{"gitId":"-"},"content":" List\u003cFeedbackVisibilityType\u003e feedbackVisibilityTypeList) {"},{"lineNumber":741,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e feedbackParticipantTypeList \u003d feedbackVisibilityTypeList.stream()"},{"lineNumber":742,"author":{"gitId":"-"},"content":" .map(feedbackParticipantType -\u003e {"},{"lineNumber":743,"author":{"gitId":"-"},"content":" switch (feedbackParticipantType) {"},{"lineNumber":744,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":745,"author":{"gitId":"-"},"content":" return FeedbackParticipantType.STUDENTS;"},{"lineNumber":746,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":747,"author":{"gitId":"-"},"content":" return FeedbackParticipantType.INSTRUCTORS;"},{"lineNumber":748,"author":{"gitId":"-"},"content":" case RECIPIENT:"},{"lineNumber":749,"author":{"gitId":"-"},"content":" return FeedbackParticipantType.RECEIVER;"},{"lineNumber":750,"author":{"gitId":"-"},"content":" case GIVER_TEAM_MEMBERS:"},{"lineNumber":751,"author":{"gitId":"-"},"content":" return FeedbackParticipantType.OWN_TEAM_MEMBERS;"},{"lineNumber":752,"author":{"gitId":"-"},"content":" case RECIPIENT_TEAM_MEMBERS:"},{"lineNumber":753,"author":{"gitId":"-"},"content":" return FeedbackParticipantType.RECEIVER_TEAM_MEMBERS;"},{"lineNumber":754,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":755,"author":{"gitId":"-"},"content":" throw new RuntimeException(\"Unknown FeedbackVisibilityType \" + feedbackParticipantType);"},{"lineNumber":756,"author":{"gitId":"-"},"content":" }"},{"lineNumber":757,"author":{"gitId":"-"},"content":" }).collect(Collectors.toList());"},{"lineNumber":758,"author":{"gitId":"-"},"content":" Collections.sort(feedbackParticipantTypeList);"},{"lineNumber":759,"author":{"gitId":"-"},"content":" return feedbackParticipantTypeList;"},{"lineNumber":760,"author":{"gitId":"-"},"content":" }"},{"lineNumber":761,"author":{"gitId":"-"},"content":""},{"lineNumber":762,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":763,"author":{"gitId":"-"},"content":" * Get feedback response data from database."},{"lineNumber":764,"author":{"gitId":"-"},"content":" */"},{"lineNumber":765,"author":{"gitId":"-"},"content":" public FeedbackResponseData getFeedbackResponseData(String feedbackQuestionId, String giver,"},{"lineNumber":766,"author":{"gitId":"-"},"content":" String recipient) {"},{"lineNumber":767,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":768,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.FEEDBACK_QUESTION_ID, feedbackQuestionId);"},{"lineNumber":769,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.INTENT, Intent.STUDENT_SUBMISSION.toString());"},{"lineNumber":770,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON, giver);"},{"lineNumber":771,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.RESPONSES, params);"},{"lineNumber":772,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":773,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":774,"author":{"gitId":"-"},"content":" }"},{"lineNumber":775,"author":{"gitId":"-"},"content":""},{"lineNumber":776,"author":{"gitId":"-"},"content":" FeedbackResponsesData responsesData \u003d JsonUtils.fromJson(response.responseBody, FeedbackResponsesData.class);"},{"lineNumber":777,"author":{"gitId":"-"},"content":" return responsesData.getResponses()"},{"lineNumber":778,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":779,"author":{"gitId":"-"},"content":" .filter(r -\u003e r.getGiverIdentifier().equals(giver) \u0026\u0026 r.getRecipientIdentifier().equals(recipient))"},{"lineNumber":780,"author":{"gitId":"-"},"content":" .findFirst()"},{"lineNumber":781,"author":{"gitId":"-"},"content":" .orElse(null);"},{"lineNumber":782,"author":{"gitId":"-"},"content":" }"},{"lineNumber":783,"author":{"gitId":"-"},"content":""},{"lineNumber":784,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":785,"author":{"gitId":"-"},"content":" * Get feedback response from database."},{"lineNumber":786,"author":{"gitId":"-"},"content":" */"},{"lineNumber":787,"author":{"gitId":"-"},"content":" public FeedbackResponseAttributes getFeedbackResponse(String feedbackQuestionId, String giver,"},{"lineNumber":788,"author":{"gitId":"-"},"content":" String recipient) {"},{"lineNumber":789,"author":{"gitId":"-"},"content":" FeedbackResponseData fr \u003d getFeedbackResponseData(feedbackQuestionId, giver, recipient);"},{"lineNumber":790,"author":{"gitId":"-"},"content":""},{"lineNumber":791,"author":{"gitId":"-"},"content":" if (fr \u003d\u003d null) {"},{"lineNumber":792,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":793,"author":{"gitId":"-"},"content":" }"},{"lineNumber":794,"author":{"gitId":"-"},"content":""},{"lineNumber":795,"author":{"gitId":"-"},"content":" FeedbackResponseAttributes responseAttr \u003d FeedbackResponseAttributes"},{"lineNumber":796,"author":{"gitId":"-"},"content":" .builder(feedbackQuestionId, fr.getGiverIdentifier(), fr.getRecipientIdentifier())"},{"lineNumber":797,"author":{"gitId":"-"},"content":" .withResponseDetails(fr.getResponseDetails())"},{"lineNumber":798,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":799,"author":{"gitId":"-"},"content":" if (fr.getFeedbackResponseId() !\u003d null) {"},{"lineNumber":800,"author":{"gitId":"-"},"content":" responseAttr.setId(fr.getFeedbackResponseId());"},{"lineNumber":801,"author":{"gitId":"-"},"content":" }"},{"lineNumber":802,"author":{"gitId":"-"},"content":" return responseAttr;"},{"lineNumber":803,"author":{"gitId":"-"},"content":" }"},{"lineNumber":804,"author":{"gitId":"-"},"content":""},{"lineNumber":805,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":806,"author":{"gitId":"-"},"content":" * Get feedback response comment from database."},{"lineNumber":807,"author":{"gitId":"-"},"content":" */"},{"lineNumber":808,"author":{"gitId":"-"},"content":" public FeedbackResponseCommentAttributes getFeedbackResponseComment(String feedbackResponseId) {"},{"lineNumber":809,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":810,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.FEEDBACK_RESPONSE_ID, feedbackResponseId);"},{"lineNumber":811,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.INTENT, Intent.STUDENT_SUBMISSION.toString());"},{"lineNumber":812,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.RESPONSE_COMMENT, params);"},{"lineNumber":813,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":814,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":815,"author":{"gitId":"-"},"content":" }"},{"lineNumber":816,"author":{"gitId":"-"},"content":""},{"lineNumber":817,"author":{"gitId":"-"},"content":" FeedbackResponseCommentData frc \u003d JsonUtils.fromJson(response.responseBody, FeedbackResponseCommentData.class);"},{"lineNumber":818,"author":{"gitId":"-"},"content":""},{"lineNumber":819,"author":{"gitId":"-"},"content":" if (frc \u003d\u003d null) {"},{"lineNumber":820,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":821,"author":{"gitId":"-"},"content":" }"},{"lineNumber":822,"author":{"gitId":"-"},"content":""},{"lineNumber":823,"author":{"gitId":"-"},"content":" return FeedbackResponseCommentAttributes.builder()"},{"lineNumber":824,"author":{"gitId":"-"},"content":" .withCommentGiver(frc.getCommentGiver())"},{"lineNumber":825,"author":{"gitId":"-"},"content":" .withCommentText(frc.getCommentText())"},{"lineNumber":826,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":827,"author":{"gitId":"-"},"content":" }"},{"lineNumber":828,"author":{"gitId":"-"},"content":""},{"lineNumber":829,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":830,"author":{"gitId":"-"},"content":" * Deletes a course from the database."},{"lineNumber":831,"author":{"gitId":"-"},"content":" */"},{"lineNumber":832,"author":{"gitId":"-"},"content":" public void deleteCourse(String courseId) {"},{"lineNumber":833,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":834,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.COURSE_ID, courseId);"},{"lineNumber":835,"author":{"gitId":"-"},"content":" executeDeleteRequest(Const.ResourceURIs.COURSE, params);"},{"lineNumber":836,"author":{"gitId":"-"},"content":" }"},{"lineNumber":837,"author":{"gitId":"-"},"content":""},{"lineNumber":838,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":839,"author":{"gitId":"-"},"content":" * Gets an account request from the database."},{"lineNumber":840,"author":{"gitId":"-"},"content":" */"},{"lineNumber":841,"author":{"gitId":"-"},"content":" public AccountRequestAttributes getAccountRequest(UUID id) {"},{"lineNumber":842,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":843,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString());"},{"lineNumber":844,"author":{"gitId":"-"},"content":""},{"lineNumber":845,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.ACCOUNT_REQUEST, params);"},{"lineNumber":846,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":847,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":848,"author":{"gitId":"-"},"content":" }"},{"lineNumber":849,"author":{"gitId":"-"},"content":""},{"lineNumber":850,"author":{"gitId":"-"},"content":" AccountRequestData accountRequestData \u003d JsonUtils.fromJson(response.responseBody, AccountRequestData.class);"},{"lineNumber":851,"author":{"gitId":"-"},"content":""},{"lineNumber":852,"author":{"gitId":"-"},"content":" return AccountRequestAttributes"},{"lineNumber":853,"author":{"gitId":"-"},"content":" .builder(accountRequestData.getEmail(), accountRequestData.getInstitute(), accountRequestData.getName())"},{"lineNumber":854,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":855,"author":{"gitId":"-"},"content":" }"},{"lineNumber":856,"author":{"gitId":"-"},"content":""},{"lineNumber":857,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":858,"author":{"gitId":"-"},"content":" * Gets registration key of an account request from the database."},{"lineNumber":859,"author":{"gitId":"-"},"content":" */"},{"lineNumber":860,"author":{"gitId":"-"},"content":" public String getRegKeyForAccountRequest(UUID id) {"},{"lineNumber":861,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":862,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString());"},{"lineNumber":863,"author":{"gitId":"-"},"content":""},{"lineNumber":864,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.ACCOUNT_REQUEST, params);"},{"lineNumber":865,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":866,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":867,"author":{"gitId":"-"},"content":" }"},{"lineNumber":868,"author":{"gitId":"-"},"content":""},{"lineNumber":869,"author":{"gitId":"-"},"content":" return JsonUtils.fromJson(response.responseBody, AccountRequestData.class).getRegistrationKey();"},{"lineNumber":870,"author":{"gitId":"-"},"content":" }"},{"lineNumber":871,"author":{"gitId":"-"},"content":""},{"lineNumber":872,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":873,"author":{"gitId":"-"},"content":" * Deletes an account request from the database."},{"lineNumber":874,"author":{"gitId":"-"},"content":" */"},{"lineNumber":875,"author":{"gitId":"dishenggg"},"content":" public void deleteAccountRequest(UUID id) {"},{"lineNumber":876,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":877,"author":{"gitId":"dishenggg"},"content":" params.put(Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString());"},{"lineNumber":878,"author":{"gitId":"-"},"content":" executeDeleteRequest(Const.ResourceURIs.ACCOUNT_REQUEST, params);"},{"lineNumber":879,"author":{"gitId":"-"},"content":" }"},{"lineNumber":880,"author":{"gitId":"-"},"content":""},{"lineNumber":881,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":882,"author":{"gitId":"-"},"content":" * Gets notification data from the database."},{"lineNumber":883,"author":{"gitId":"-"},"content":" */"},{"lineNumber":884,"author":{"gitId":"-"},"content":" public NotificationData getNotificationData(String notificationId) {"},{"lineNumber":885,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":886,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.NOTIFICATION_ID, notificationId);"},{"lineNumber":887,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.NOTIFICATION, params);"},{"lineNumber":888,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":889,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":890,"author":{"gitId":"-"},"content":" }"},{"lineNumber":891,"author":{"gitId":"-"},"content":" return JsonUtils.fromJson(response.responseBody, NotificationData.class);"},{"lineNumber":892,"author":{"gitId":"-"},"content":" }"},{"lineNumber":893,"author":{"gitId":"-"},"content":""},{"lineNumber":894,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":895,"author":{"gitId":"-"},"content":" * Gets a notification from the database."},{"lineNumber":896,"author":{"gitId":"-"},"content":" */"},{"lineNumber":897,"author":{"gitId":"-"},"content":" public NotificationAttributes getNotification(String notificationId) {"},{"lineNumber":898,"author":{"gitId":"-"},"content":" NotificationData notificationData \u003d getNotificationData(notificationId);"},{"lineNumber":899,"author":{"gitId":"-"},"content":" if (notificationData \u003d\u003d null) {"},{"lineNumber":900,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":901,"author":{"gitId":"-"},"content":" }"},{"lineNumber":902,"author":{"gitId":"-"},"content":" NotificationAttributes notification \u003d NotificationAttributes.builder(notificationData.getNotificationId())"},{"lineNumber":903,"author":{"gitId":"-"},"content":" .withStartTime(Instant.ofEpochMilli(notificationData.getStartTimestamp()))"},{"lineNumber":904,"author":{"gitId":"-"},"content":" .withEndTime(Instant.ofEpochMilli(notificationData.getEndTimestamp()))"},{"lineNumber":905,"author":{"gitId":"-"},"content":" .withStyle(notificationData.getStyle())"},{"lineNumber":906,"author":{"gitId":"-"},"content":" .withTargetUser(notificationData.getTargetUser())"},{"lineNumber":907,"author":{"gitId":"-"},"content":" .withTitle(notificationData.getTitle())"},{"lineNumber":908,"author":{"gitId":"-"},"content":" .withMessage(notificationData.getMessage())"},{"lineNumber":909,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":910,"author":{"gitId":"-"},"content":" notification.setCreatedAt(Instant.ofEpochMilli(notificationData.getCreatedAt()));"},{"lineNumber":911,"author":{"gitId":"-"},"content":" return notification;"},{"lineNumber":912,"author":{"gitId":"-"},"content":" }"},{"lineNumber":913,"author":{"gitId":"-"},"content":""},{"lineNumber":914,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":915,"author":{"gitId":"-"},"content":" * Deletes a notification from the database."},{"lineNumber":916,"author":{"gitId":"-"},"content":" */"},{"lineNumber":917,"author":{"gitId":"-"},"content":" public void deleteNotification(String notificationId) {"},{"lineNumber":918,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":919,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.NOTIFICATION_ID, notificationId);"},{"lineNumber":920,"author":{"gitId":"-"},"content":" executeDeleteRequest(Const.ResourceURIs.NOTIFICATION, params);"},{"lineNumber":921,"author":{"gitId":"-"},"content":" }"},{"lineNumber":922,"author":{"gitId":"-"},"content":""},{"lineNumber":923,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":924,"author":{"gitId":"-"},"content":" * Deletes a notification from the database."},{"lineNumber":925,"author":{"gitId":"-"},"content":" */"},{"lineNumber":926,"author":{"gitId":"-"},"content":" public void deleteNotification(UUID notificationId) {"},{"lineNumber":927,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":928,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.NOTIFICATION_ID, notificationId.toString());"},{"lineNumber":929,"author":{"gitId":"-"},"content":" executeDeleteRequest(Const.ResourceURIs.NOTIFICATION, params);"},{"lineNumber":930,"author":{"gitId":"-"},"content":" }"},{"lineNumber":931,"author":{"gitId":"-"},"content":""},{"lineNumber":932,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":933,"author":{"gitId":"-"},"content":" * Gets a deadline extension from the database."},{"lineNumber":934,"author":{"gitId":"-"},"content":" */"},{"lineNumber":935,"author":{"gitId":"-"},"content":" public DeadlineExtensionAttributes getDeadlineExtension("},{"lineNumber":936,"author":{"gitId":"-"},"content":" String courseId, String feedbackSessionName, String userEmail, boolean isInstructor) {"},{"lineNumber":937,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":938,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.COURSE_ID, courseId);"},{"lineNumber":939,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSessionName);"},{"lineNumber":940,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.USER_EMAIL, userEmail);"},{"lineNumber":941,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.IS_INSTRUCTOR, Boolean.toString(isInstructor));"},{"lineNumber":942,"author":{"gitId":"-"},"content":""},{"lineNumber":943,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.DEADLINE_EXTENSION, params);"},{"lineNumber":944,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":945,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":946,"author":{"gitId":"-"},"content":" }"},{"lineNumber":947,"author":{"gitId":"-"},"content":""},{"lineNumber":948,"author":{"gitId":"-"},"content":" DeadlineExtensionData deadlineExtensionData \u003d JsonUtils.fromJson(response.responseBody, DeadlineExtensionData.class);"},{"lineNumber":949,"author":{"gitId":"-"},"content":""},{"lineNumber":950,"author":{"gitId":"-"},"content":" return DeadlineExtensionAttributes.builder("},{"lineNumber":951,"author":{"gitId":"-"},"content":" deadlineExtensionData.getCourseId(), deadlineExtensionData.getFeedbackSessionName(),"},{"lineNumber":952,"author":{"gitId":"-"},"content":" deadlineExtensionData.getUserEmail(), deadlineExtensionData.getIsInstructor())"},{"lineNumber":953,"author":{"gitId":"-"},"content":" .withEndTime(Instant.ofEpochMilli(deadlineExtensionData.getEndTime()))"},{"lineNumber":954,"author":{"gitId":"-"},"content":" .withSentClosingEmail(deadlineExtensionData.getSentClosingEmail())"},{"lineNumber":955,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":956,"author":{"gitId":"-"},"content":" }"},{"lineNumber":957,"author":{"gitId":"-"},"content":""},{"lineNumber":958,"author":{"gitId":"-"},"content":" private static final class ResponseBodyAndCode {"},{"lineNumber":959,"author":{"gitId":"-"},"content":""},{"lineNumber":960,"author":{"gitId":"-"},"content":" String responseBody;"},{"lineNumber":961,"author":{"gitId":"-"},"content":" int responseCode;"},{"lineNumber":962,"author":{"gitId":"-"},"content":""},{"lineNumber":963,"author":{"gitId":"-"},"content":" ResponseBodyAndCode(String responseBody, int responseCode) {"},{"lineNumber":964,"author":{"gitId":"-"},"content":" this.responseBody \u003d responseBody;"},{"lineNumber":965,"author":{"gitId":"-"},"content":" this.responseCode \u003d responseCode;"},{"lineNumber":966,"author":{"gitId":"-"},"content":" }"},{"lineNumber":967,"author":{"gitId":"-"},"content":""},{"lineNumber":968,"author":{"gitId":"-"},"content":" }"},{"lineNumber":969,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":13,"-":956}},{"path":"src/test/java/teammates/test/BaseTestCase.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.test;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.io.IOException;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.lang.reflect.Method;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.time.Duration;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.junit.jupiter.api.Assertions;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import org.junit.jupiter.api.function.Executable;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.DataBundle;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPermissionRole;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPrivileges;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationStyle;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationTargetUser;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.questions.FeedbackResponseDetails;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackTextQuestionDetails;"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.questions.FeedbackTextResponseDetails;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.TimeHelperExtension;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.DataBundleLogic;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":38,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":41,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":42,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":43,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":47,"author":{"gitId":"-"},"content":" * Base class for all test cases."},{"lineNumber":48,"author":{"gitId":"-"},"content":" */"},{"lineNumber":49,"author":{"gitId":"-"},"content":"@SuppressWarnings(\"PMD.TestClassWithoutTestCases\")"},{"lineNumber":50,"author":{"gitId":"-"},"content":"public class BaseTestCase {"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":53,"author":{"gitId":"-"},"content":" * Test Segment divider. Used to divide a test case into logical sections."},{"lineNumber":54,"author":{"gitId":"-"},"content":" * The weird name is for easy spotting."},{"lineNumber":55,"author":{"gitId":"-"},"content":" *"},{"lineNumber":56,"author":{"gitId":"-"},"content":" * @param description"},{"lineNumber":57,"author":{"gitId":"-"},"content":" * of the logical section. This will be printed."},{"lineNumber":58,"author":{"gitId":"-"},"content":" */"},{"lineNumber":59,"author":{"gitId":"-"},"content":" // CHECKSTYLE.OFF:AbbreviationAsWordInName|MethodName the weird name is for easy spotting."},{"lineNumber":60,"author":{"gitId":"-"},"content":" public static void ______TS(String description) {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" print(\" * \" + description);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" }"},{"lineNumber":63,"author":{"gitId":"-"},"content":" // CHECKSTYLE.ON:AbbreviationAsWordInName|MethodName"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" @BeforeClass"},{"lineNumber":66,"author":{"gitId":"-"},"content":" public void printTestClassHeader() {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" print(\"[\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\""},{"lineNumber":68,"author":{"gitId":"-"},"content":" + getClass().getCanonicalName()"},{"lineNumber":69,"author":{"gitId":"-"},"content":" + \"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d]\");"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":73,"author":{"gitId":"-"},"content":" public void printTestClassFooter() {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" print(getClass().getCanonicalName() + \" completed\");"},{"lineNumber":75,"author":{"gitId":"-"},"content":" }"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" protected static void print(String message) {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" System.out.println(message);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" }"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" protected String getTestDataFolder() {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" return TestProperties.TEST_DATA_FOLDER;"},{"lineNumber":83,"author":{"gitId":"-"},"content":" }"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":86,"author":{"gitId":"-"},"content":" * Creates a DataBundle as specified in typicalDataBundle.json."},{"lineNumber":87,"author":{"gitId":"-"},"content":" */"},{"lineNumber":88,"author":{"gitId":"-"},"content":" protected DataBundle getTypicalDataBundle() {"},{"lineNumber":89,"author":{"gitId":"-"},"content":" return loadDataBundle(\"/typicalDataBundle.json\");"},{"lineNumber":90,"author":{"gitId":"-"},"content":" }"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" protected DataBundle loadDataBundle(String jsonFileName) {"},{"lineNumber":93,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" String pathToJsonFile \u003d getTestDataFolder() + jsonFileName;"},{"lineNumber":95,"author":{"gitId":"-"},"content":" String jsonString \u003d FileHelper.readFile(pathToJsonFile);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" return JsonUtils.fromJson(jsonString, DataBundle.class);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" protected SqlDataBundle getTypicalSqlDataBundle() {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" return loadSqlDataBundle(\"/typicalDataBundle.json\");"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" protected SqlDataBundle loadSqlDataBundle(String jsonFileName) {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":108,"author":{"gitId":"-"},"content":" // TODO: rename to loadDataBundle after migration"},{"lineNumber":109,"author":{"gitId":"-"},"content":" String pathToJsonFile \u003d getTestDataFolder() + jsonFileName;"},{"lineNumber":110,"author":{"gitId":"-"},"content":" String jsonString \u003d FileHelper.readFile(pathToJsonFile);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" return DataBundleLogic.deserializeDataBundle(jsonString);"},{"lineNumber":112,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":" }"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":118,"author":{"gitId":"-"},"content":" * These getTypicalX functions are used to generate typical entities for tests."},{"lineNumber":119,"author":{"gitId":"-"},"content":" * The entity fields can be changed using setter methods if needed."},{"lineNumber":120,"author":{"gitId":"-"},"content":" * New entity generator functions for tests should be added here, and follow the"},{"lineNumber":121,"author":{"gitId":"-"},"content":" * same naming convention."},{"lineNumber":122,"author":{"gitId":"-"},"content":" *"},{"lineNumber":123,"author":{"gitId":"-"},"content":" * \u003cp\u003eExample usage:"},{"lineNumber":124,"author":{"gitId":"-"},"content":" * Account account \u003d getTypicalAccount();"},{"lineNumber":125,"author":{"gitId":"-"},"content":" * Student student \u003d getTypicalStudent();"},{"lineNumber":126,"author":{"gitId":"-"},"content":" * account.setEmail(\"newemail@teammates.com\");"},{"lineNumber":127,"author":{"gitId":"-"},"content":" * student.setName(\"New Student Name\");"},{"lineNumber":128,"author":{"gitId":"-"},"content":" */"},{"lineNumber":129,"author":{"gitId":"-"},"content":" protected Account getTypicalAccount() {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" return new Account(\"google-id\", \"name\", \"email@teammates.com\");"},{"lineNumber":131,"author":{"gitId":"-"},"content":" }"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" protected Notification getTypicalNotificationWithId() {"},{"lineNumber":134,"author":{"gitId":"-"},"content":" Notification notification \u003d new Notification(Instant.parse(\"2011-01-01T00:00:00Z\"),"},{"lineNumber":135,"author":{"gitId":"-"},"content":" Instant.parse(\"2099-01-01T00:00:00Z\"), NotificationStyle.DANGER, NotificationTargetUser.GENERAL,"},{"lineNumber":136,"author":{"gitId":"-"},"content":" \"A deprecation note\", \"\u003cp\u003eDeprecation happens in three minutes\u003c/p\u003e\");"},{"lineNumber":137,"author":{"gitId":"-"},"content":" notification.setId(UUID.randomUUID());"},{"lineNumber":138,"author":{"gitId":"-"},"content":" return notification;"},{"lineNumber":139,"author":{"gitId":"-"},"content":" }"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" protected Instructor getTypicalInstructor() {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":143,"author":{"gitId":"-"},"content":" InstructorPrivileges instructorPrivileges \u003d"},{"lineNumber":144,"author":{"gitId":"-"},"content":" new InstructorPrivileges(Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_COOWNER);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" InstructorPermissionRole role \u003d InstructorPermissionRole"},{"lineNumber":146,"author":{"gitId":"-"},"content":" .getEnum(Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_COOWNER);"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" return new Instructor(course, \"instructor-name\", \"valid@teammates.tmt\","},{"lineNumber":149,"author":{"gitId":"-"},"content":" false, Const.DEFAULT_DISPLAY_NAME_FOR_INSTRUCTOR, role, instructorPrivileges);"},{"lineNumber":150,"author":{"gitId":"-"},"content":" }"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" protected Course getTypicalCourse() {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" return new Course(\"course-id\", \"course-name\", Const.DEFAULT_TIME_ZONE, \"teammates\");"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" protected Student getTypicalStudent() {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":158,"author":{"gitId":"-"},"content":" return new Student(course, \"student-name\", \"validstudent@teammates.tmt\", \"comments\");"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" protected Section getTypicalSection() {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":163,"author":{"gitId":"-"},"content":" return new Section(course, \"test-section\");"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" protected Team getTypicalTeam() {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":168,"author":{"gitId":"-"},"content":" return new Team(section, \"test-team\");"},{"lineNumber":169,"author":{"gitId":"-"},"content":" }"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" protected FeedbackSession getTypicalFeedbackSessionForCourse(Course course) {"},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":" Instant startTime \u003d TimeHelperExtension.getInstantDaysOffsetFromNow(1);"},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":" Instant endTime \u003d TimeHelperExtension.getInstantDaysOffsetFromNow(7);"},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":" return new FeedbackSession(\"test-feedbacksession\","},{"lineNumber":175,"author":{"gitId":"dishenggg"},"content":" course,"},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":" \"test@teammates.tmt\","},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":" \"test-instructions\","},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":" startTime,"},{"lineNumber":179,"author":{"gitId":"dishenggg"},"content":" endTime,"},{"lineNumber":180,"author":{"gitId":"dishenggg"},"content":" startTime,"},{"lineNumber":181,"author":{"gitId":"dishenggg"},"content":" endTime,"},{"lineNumber":182,"author":{"gitId":"dishenggg"},"content":" Duration.ofMinutes(5),"},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":" false,"},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":" false,"},{"lineNumber":185,"author":{"gitId":"dishenggg"},"content":" false);"},{"lineNumber":186,"author":{"gitId":"-"},"content":" }"},{"lineNumber":187,"author":{"gitId":"-"},"content":""},{"lineNumber":188,"author":{"gitId":"-"},"content":" protected FeedbackQuestion getTypicalFeedbackQuestionForSession(FeedbackSession session) {"},{"lineNumber":189,"author":{"gitId":"-"},"content":" return FeedbackQuestion.makeQuestion(session, 1, \"test-description\","},{"lineNumber":190,"author":{"gitId":"-"},"content":" FeedbackParticipantType.SELF, FeedbackParticipantType.SELF, 1, new ArrayList\u003c\u003e(),"},{"lineNumber":191,"author":{"gitId":"-"},"content":" new ArrayList\u003c\u003e(), new ArrayList\u003c\u003e(),"},{"lineNumber":192,"author":{"gitId":"-"},"content":" new FeedbackTextQuestionDetails(\"test question text\"));"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"xenosf"},"content":" protected FeedbackResponse getTypicalFeedbackResponseForQuestion(FeedbackQuestion question) {"},{"lineNumber":196,"author":{"gitId":"xenosf"},"content":" return FeedbackResponse.makeResponse(question, \"test-giver\", getTypicalSection(), \"test-recipient\","},{"lineNumber":197,"author":{"gitId":"xenosf"},"content":" getTypicalSection(), getTypicalFeedbackResponseDetails());"},{"lineNumber":198,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":199,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":200,"author":{"gitId":"xenosf"},"content":" protected FeedbackResponseDetails getTypicalFeedbackResponseDetails() {"},{"lineNumber":201,"author":{"gitId":"xenosf"},"content":" return new FeedbackTextResponseDetails();"},{"lineNumber":202,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":203,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":204,"author":{"gitId":"mingyuanc"},"content":" protected FeedbackResponseComment getTypicalResponseComment(Long id) {"},{"lineNumber":205,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d new FeedbackResponseComment(null, \"\","},{"lineNumber":206,"author":{"gitId":"mingyuanc"},"content":" FeedbackParticipantType.STUDENTS, null, null, \"\","},{"lineNumber":207,"author":{"gitId":"mingyuanc"},"content":" false, false,"},{"lineNumber":208,"author":{"gitId":"mingyuanc"},"content":" null, null, null);"},{"lineNumber":209,"author":{"gitId":"mingyuanc"},"content":" comment.setId(id);"},{"lineNumber":210,"author":{"gitId":"mingyuanc"},"content":" return comment;"},{"lineNumber":211,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":212,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":213,"author":{"gitId":"xenosf"},"content":" protected AccountRequest getTypicalAccountRequest() {"},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" return new AccountRequest(\"valid@test.com\", \"Test Name\", \"TEAMMATES Test Institute 1, Test Country\","},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" AccountRequestStatus.PENDING, \"\");"},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":217,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":218,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":219,"author":{"gitId":"-"},"content":" * Populates the feedback question and response IDs within the data bundle."},{"lineNumber":220,"author":{"gitId":"-"},"content":" *"},{"lineNumber":221,"author":{"gitId":"-"},"content":" * \u003cp\u003eFor tests where simulated database is used, the backend will assign the question and response IDs"},{"lineNumber":222,"author":{"gitId":"-"},"content":" * when the entities are persisted into the database, and modify the relation IDs accordingly."},{"lineNumber":223,"author":{"gitId":"-"},"content":" * However, for tests that do not use simulated database (e.g. pure data structure tests),"},{"lineNumber":224,"author":{"gitId":"-"},"content":" * the assignment of IDs have to be simulated."},{"lineNumber":225,"author":{"gitId":"-"},"content":" */"},{"lineNumber":226,"author":{"gitId":"-"},"content":" protected void populateQuestionAndResponseIds(DataBundle dataBundle) {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" Map\u003cString, Map\u003cInteger, String\u003e\u003e sessionToQuestionNumberToId \u003d new HashMap\u003c\u003e();"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" dataBundle.feedbackQuestions.forEach((key, question) -\u003e {"},{"lineNumber":230,"author":{"gitId":"-"},"content":" // Assign the same ID as the key as a later function requires a match between the key and the question ID"},{"lineNumber":231,"author":{"gitId":"-"},"content":" question.setId(key);"},{"lineNumber":232,"author":{"gitId":"-"},"content":" Map\u003cInteger, String\u003e questionNumberToId \u003d sessionToQuestionNumberToId.computeIfAbsent("},{"lineNumber":233,"author":{"gitId":"-"},"content":" question.getCourseId() + \"%\" + question.getFeedbackSessionName(), k -\u003e new HashMap\u003c\u003e());"},{"lineNumber":234,"author":{"gitId":"-"},"content":" questionNumberToId.put(question.getQuestionNumber(), key);"},{"lineNumber":235,"author":{"gitId":"-"},"content":" });"},{"lineNumber":236,"author":{"gitId":"-"},"content":""},{"lineNumber":237,"author":{"gitId":"-"},"content":" dataBundle.feedbackResponses.forEach((key, response) -\u003e {"},{"lineNumber":238,"author":{"gitId":"-"},"content":" response.setId(key);"},{"lineNumber":239,"author":{"gitId":"-"},"content":" String feedbackQuestionId \u003d sessionToQuestionNumberToId"},{"lineNumber":240,"author":{"gitId":"-"},"content":" .get(response.getCourseId() + \"%\" + response.getFeedbackSessionName())"},{"lineNumber":241,"author":{"gitId":"-"},"content":" .get(Integer.valueOf(response.getFeedbackQuestionId()));"},{"lineNumber":242,"author":{"gitId":"-"},"content":" response.setFeedbackQuestionId(feedbackQuestionId);"},{"lineNumber":243,"author":{"gitId":"-"},"content":" });"},{"lineNumber":244,"author":{"gitId":"-"},"content":" }"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":247,"author":{"gitId":"-"},"content":" * Invokes the method named {@code methodName} as defined in the {@code definingClass}."},{"lineNumber":248,"author":{"gitId":"-"},"content":" * @param definingClass the class which defines the method"},{"lineNumber":249,"author":{"gitId":"-"},"content":" * @param parameterTypes the parameter types of the method,"},{"lineNumber":250,"author":{"gitId":"-"},"content":" * which must be passed in the same order defined in the method"},{"lineNumber":251,"author":{"gitId":"-"},"content":" * @param invokingObject the object which invokes the method, can be {@code null} if the method is static"},{"lineNumber":252,"author":{"gitId":"-"},"content":" * @param args the arguments to be passed to the method invocation"},{"lineNumber":253,"author":{"gitId":"-"},"content":" */"},{"lineNumber":254,"author":{"gitId":"-"},"content":" protected static Object invokeMethod(Class\u003c?\u003e definingClass, String methodName, Class\u003c?\u003e[] parameterTypes,"},{"lineNumber":255,"author":{"gitId":"-"},"content":" Object invokingObject, Object[] args)"},{"lineNumber":256,"author":{"gitId":"-"},"content":" throws ReflectiveOperationException {"},{"lineNumber":257,"author":{"gitId":"-"},"content":" Method method \u003d definingClass.getDeclaredMethod(methodName, parameterTypes);"},{"lineNumber":258,"author":{"gitId":"-"},"content":" method.setAccessible(true);"},{"lineNumber":259,"author":{"gitId":"-"},"content":" return method.invoke(invokingObject, args);"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":""},{"lineNumber":262,"author":{"gitId":"-"},"content":" protected static String getPopulatedErrorMessage(String messageTemplate, String userInput,"},{"lineNumber":263,"author":{"gitId":"-"},"content":" String fieldName, String errorReason)"},{"lineNumber":264,"author":{"gitId":"-"},"content":" throws ReflectiveOperationException {"},{"lineNumber":265,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(messageTemplate, userInput, fieldName, errorReason, 0);"},{"lineNumber":266,"author":{"gitId":"-"},"content":" }"},{"lineNumber":267,"author":{"gitId":"-"},"content":""},{"lineNumber":268,"author":{"gitId":"-"},"content":" protected static String getPopulatedErrorMessage(String messageTemplate, String userInput,"},{"lineNumber":269,"author":{"gitId":"-"},"content":" String fieldName, String errorReason, int maxLength)"},{"lineNumber":270,"author":{"gitId":"-"},"content":" throws ReflectiveOperationException {"},{"lineNumber":271,"author":{"gitId":"-"},"content":" return (String) invokeMethod(FieldValidator.class, \"getPopulatedErrorMessage\","},{"lineNumber":272,"author":{"gitId":"-"},"content":" new Class\u003c?\u003e[] { String.class, String.class, String.class, String.class, int.class },"},{"lineNumber":273,"author":{"gitId":"-"},"content":" null, new Object[] { messageTemplate, userInput, fieldName, errorReason, maxLength });"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" protected static String getPopulatedEmptyStringErrorMessage(String messageTemplate, String fieldName, int maxLength)"},{"lineNumber":277,"author":{"gitId":"-"},"content":" throws ReflectiveOperationException {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" return (String) invokeMethod(FieldValidator.class, \"getPopulatedEmptyStringErrorMessage\","},{"lineNumber":279,"author":{"gitId":"-"},"content":" new Class\u003c?\u003e[] { String.class, String.class, int.class },"},{"lineNumber":280,"author":{"gitId":"-"},"content":" null, new Object[] { messageTemplate, fieldName, maxLength });"},{"lineNumber":281,"author":{"gitId":"-"},"content":" }"},{"lineNumber":282,"author":{"gitId":"-"},"content":""},{"lineNumber":283,"author":{"gitId":"-"},"content":" /*"},{"lineNumber":284,"author":{"gitId":"-"},"content":" * Here are some of the most common assertion methods provided by JUnit."},{"lineNumber":285,"author":{"gitId":"-"},"content":" * They are copied here to prevent repetitive importing in test classes."},{"lineNumber":286,"author":{"gitId":"-"},"content":" */"},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":" protected static void assertTrue(boolean condition) {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" Assertions.assertTrue(condition);"},{"lineNumber":290,"author":{"gitId":"-"},"content":" }"},{"lineNumber":291,"author":{"gitId":"-"},"content":""},{"lineNumber":292,"author":{"gitId":"-"},"content":" protected static void assertTrue(String message, boolean condition) {"},{"lineNumber":293,"author":{"gitId":"-"},"content":" Assertions.assertTrue(condition, message);"},{"lineNumber":294,"author":{"gitId":"-"},"content":" }"},{"lineNumber":295,"author":{"gitId":"-"},"content":""},{"lineNumber":296,"author":{"gitId":"-"},"content":" protected static void assertFalse(boolean condition) {"},{"lineNumber":297,"author":{"gitId":"-"},"content":" Assertions.assertFalse(condition);"},{"lineNumber":298,"author":{"gitId":"-"},"content":" }"},{"lineNumber":299,"author":{"gitId":"-"},"content":""},{"lineNumber":300,"author":{"gitId":"-"},"content":" protected static void assertFalse(String message, boolean condition) {"},{"lineNumber":301,"author":{"gitId":"-"},"content":" Assertions.assertFalse(condition, message);"},{"lineNumber":302,"author":{"gitId":"-"},"content":" }"},{"lineNumber":303,"author":{"gitId":"-"},"content":""},{"lineNumber":304,"author":{"gitId":"-"},"content":" protected static void assertEquals(int expected, int actual) {"},{"lineNumber":305,"author":{"gitId":"-"},"content":" Assertions.assertEquals(expected, actual);"},{"lineNumber":306,"author":{"gitId":"-"},"content":" }"},{"lineNumber":307,"author":{"gitId":"-"},"content":""},{"lineNumber":308,"author":{"gitId":"-"},"content":" protected static void assertEquals(String message, int expected, int actual) {"},{"lineNumber":309,"author":{"gitId":"-"},"content":" Assertions.assertEquals(expected, actual, message);"},{"lineNumber":310,"author":{"gitId":"-"},"content":" }"},{"lineNumber":311,"author":{"gitId":"-"},"content":""},{"lineNumber":312,"author":{"gitId":"-"},"content":" protected static void assertEquals(long expected, long actual) {"},{"lineNumber":313,"author":{"gitId":"-"},"content":" Assertions.assertEquals(expected, actual);"},{"lineNumber":314,"author":{"gitId":"-"},"content":" }"},{"lineNumber":315,"author":{"gitId":"-"},"content":""},{"lineNumber":316,"author":{"gitId":"-"},"content":" protected static void assertEquals(double expected, double actual, double delta) {"},{"lineNumber":317,"author":{"gitId":"-"},"content":" Assertions.assertEquals(expected, actual, delta);"},{"lineNumber":318,"author":{"gitId":"-"},"content":" }"},{"lineNumber":319,"author":{"gitId":"-"},"content":""},{"lineNumber":320,"author":{"gitId":"-"},"content":" protected static void assertEquals(Object expected, Object actual) {"},{"lineNumber":321,"author":{"gitId":"-"},"content":" Assertions.assertEquals(expected, actual);"},{"lineNumber":322,"author":{"gitId":"-"},"content":" }"},{"lineNumber":323,"author":{"gitId":"-"},"content":""},{"lineNumber":324,"author":{"gitId":"-"},"content":" protected static void assertEquals(String message, Object expected, Object actual) {"},{"lineNumber":325,"author":{"gitId":"-"},"content":" Assertions.assertEquals(expected, actual, message);"},{"lineNumber":326,"author":{"gitId":"-"},"content":" }"},{"lineNumber":327,"author":{"gitId":"-"},"content":""},{"lineNumber":328,"author":{"gitId":"-"},"content":" protected static void assertArrayEquals(byte[] expected, byte[] actual) {"},{"lineNumber":329,"author":{"gitId":"-"},"content":" Assertions.assertArrayEquals(expected, actual);"},{"lineNumber":330,"author":{"gitId":"-"},"content":" }"},{"lineNumber":331,"author":{"gitId":"-"},"content":""},{"lineNumber":332,"author":{"gitId":"-"},"content":" protected static void assertNotEquals(Object first, Object second) {"},{"lineNumber":333,"author":{"gitId":"-"},"content":" Assertions.assertNotEquals(first, second);"},{"lineNumber":334,"author":{"gitId":"-"},"content":" }"},{"lineNumber":335,"author":{"gitId":"-"},"content":""},{"lineNumber":336,"author":{"gitId":"-"},"content":" protected static void assertSame(Object expected, Object actual) {"},{"lineNumber":337,"author":{"gitId":"-"},"content":" Assertions.assertSame(expected, actual);"},{"lineNumber":338,"author":{"gitId":"-"},"content":" }"},{"lineNumber":339,"author":{"gitId":"-"},"content":""},{"lineNumber":340,"author":{"gitId":"-"},"content":" protected static void assertNotSame(Object unexpected, Object actual) {"},{"lineNumber":341,"author":{"gitId":"-"},"content":" Assertions.assertNotSame(unexpected, actual);"},{"lineNumber":342,"author":{"gitId":"-"},"content":" }"},{"lineNumber":343,"author":{"gitId":"-"},"content":""},{"lineNumber":344,"author":{"gitId":"-"},"content":" protected static void assertNull(Object object) {"},{"lineNumber":345,"author":{"gitId":"-"},"content":" Assertions.assertNull(object);"},{"lineNumber":346,"author":{"gitId":"-"},"content":" }"},{"lineNumber":347,"author":{"gitId":"-"},"content":""},{"lineNumber":348,"author":{"gitId":"-"},"content":" protected static void assertNull(String message, Object object) {"},{"lineNumber":349,"author":{"gitId":"-"},"content":" Assertions.assertNull(object, message);"},{"lineNumber":350,"author":{"gitId":"-"},"content":" }"},{"lineNumber":351,"author":{"gitId":"-"},"content":""},{"lineNumber":352,"author":{"gitId":"-"},"content":" protected static void assertNotNull(Object object) {"},{"lineNumber":353,"author":{"gitId":"-"},"content":" Assertions.assertNotNull(object);"},{"lineNumber":354,"author":{"gitId":"-"},"content":" }"},{"lineNumber":355,"author":{"gitId":"-"},"content":""},{"lineNumber":356,"author":{"gitId":"-"},"content":" protected static void assertNotNull(String message, Object object) {"},{"lineNumber":357,"author":{"gitId":"-"},"content":" Assertions.assertNotNull(object, message);"},{"lineNumber":358,"author":{"gitId":"-"},"content":" }"},{"lineNumber":359,"author":{"gitId":"-"},"content":""},{"lineNumber":360,"author":{"gitId":"-"},"content":" protected static void fail(String message) {"},{"lineNumber":361,"author":{"gitId":"-"},"content":" Assertions.fail(message);"},{"lineNumber":362,"author":{"gitId":"-"},"content":" }"},{"lineNumber":363,"author":{"gitId":"-"},"content":""},{"lineNumber":364,"author":{"gitId":"-"},"content":" protected static \u003cT extends Throwable\u003e T assertThrows(Class\u003cT\u003e expectedType, Executable executable) {"},{"lineNumber":365,"author":{"gitId":"-"},"content":" return Assertions.assertThrows(expectedType, executable);"},{"lineNumber":366,"author":{"gitId":"-"},"content":" }"},{"lineNumber":367,"author":{"gitId":"-"},"content":""},{"lineNumber":368,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":19,"dishenggg":16,"mingyuanc":10,"-":323}},{"path":"src/test/java/teammates/test/BaseTestCaseWithDatabaseAccess.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.test;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.DataBundle;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountAttributes;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountRequestAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.DeadlineExtensionAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.EntityAttributes;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseAttributes;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseCommentAttributes;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.NotificationAttributes;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * Base class for all test cases which are allowed to access the database."},{"lineNumber":21,"author":{"gitId":"-"},"content":" */"},{"lineNumber":22,"author":{"gitId":"-"},"content":"public abstract class BaseTestCaseWithDatabaseAccess extends BaseTestCase {"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" private static final int VERIFICATION_RETRY_COUNT \u003d 5;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" private static final int VERIFICATION_RETRY_DELAY_IN_MS \u003d 1000;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" private static final int OPERATION_RETRY_COUNT \u003d 5;"},{"lineNumber":27,"author":{"gitId":"-"},"content":" private static final int OPERATION_RETRY_DELAY_IN_MS \u003d 1000;"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" protected void verifyPresentInDatabase(DataBundle data) {"},{"lineNumber":30,"author":{"gitId":"-"},"content":" data.accounts.values().forEach(this::verifyPresentInDatabase);"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" data.instructors.values().forEach(this::verifyPresentInDatabase);"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" data.courses.values().stream()"},{"lineNumber":35,"author":{"gitId":"-"},"content":" .filter(course -\u003e !course.isCourseDeleted())"},{"lineNumber":36,"author":{"gitId":"-"},"content":" .forEach(this::verifyPresentInDatabase);"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" data.students.values().forEach(this::verifyPresentInDatabase);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" protected void verifyPresentInDatabase(EntityAttributes\u003c?\u003e expected) {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" int retryLimit \u003d VERIFICATION_RETRY_COUNT;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" EntityAttributes\u003c?\u003e actual \u003d getEntity(expected);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" while (actual \u003d\u003d null \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":46,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(VERIFICATION_RETRY_DELAY_IN_MS);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" actual \u003d getEntity(expected);"},{"lineNumber":48,"author":{"gitId":"-"},"content":" }"},{"lineNumber":49,"author":{"gitId":"-"},"content":" verifyEquals(expected, actual);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" }"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" private EntityAttributes\u003c?\u003e getEntity(EntityAttributes\u003c?\u003e expected) {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" if (expected instanceof AccountAttributes) {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" return getAccount((AccountAttributes) expected);"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" } else if (expected instanceof CourseAttributes) {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" return getCourse((CourseAttributes) expected);"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackQuestionAttributes) {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" return getFeedbackQuestion((FeedbackQuestionAttributes) expected);"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackResponseCommentAttributes) {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" return getFeedbackResponseComment((FeedbackResponseCommentAttributes) expected);"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackResponseAttributes) {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" return getFeedbackResponse((FeedbackResponseAttributes) expected);"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackSessionAttributes) {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" return getFeedbackSession((FeedbackSessionAttributes) expected);"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" } else if (expected instanceof InstructorAttributes) {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" return getInstructor((InstructorAttributes) expected);"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" } else if (expected instanceof StudentAttributes) {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" return getStudent((StudentAttributes) expected);"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" } else if (expected instanceof AccountRequestAttributes) {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" return getAccountRequest((AccountRequestAttributes) expected);"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" } else if (expected instanceof DeadlineExtensionAttributes) {"},{"lineNumber":81,"author":{"gitId":"-"},"content":" return getDeadlineExtension((DeadlineExtensionAttributes) expected);"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" } else if (expected instanceof NotificationAttributes) {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" return getNotification((NotificationAttributes) expected);"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" throw new RuntimeException(\"Unknown entity type!\");"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":" }"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" protected void verifyAbsentInDatabase(EntityAttributes\u003c?\u003e entity) {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" int retryLimit \u003d VERIFICATION_RETRY_COUNT;"},{"lineNumber":93,"author":{"gitId":"-"},"content":" EntityAttributes\u003c?\u003e actual \u003d getEntity(entity);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" while (actual !\u003d null \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":96,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(VERIFICATION_RETRY_DELAY_IN_MS);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" actual \u003d getEntity(entity);"},{"lineNumber":98,"author":{"gitId":"-"},"content":" }"},{"lineNumber":99,"author":{"gitId":"-"},"content":" assertNull(actual);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" private void verifyEquals(EntityAttributes\u003c?\u003e expected, EntityAttributes\u003c?\u003e actual) {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" if (expected instanceof AccountAttributes) {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" AccountAttributes expectedAccount \u003d ((AccountAttributes) expected).getCopy();"},{"lineNumber":105,"author":{"gitId":"-"},"content":" AccountAttributes actualAccount \u003d (AccountAttributes) actual;"},{"lineNumber":106,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedAccount, actualAccount);"},{"lineNumber":107,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedAccount), JsonUtils.toJson(actualAccount));"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" } else if (expected instanceof CourseAttributes) {"},{"lineNumber":110,"author":{"gitId":"-"},"content":" CourseAttributes expectedCourse \u003d (CourseAttributes) expected;"},{"lineNumber":111,"author":{"gitId":"-"},"content":" CourseAttributes actualCourse \u003d (CourseAttributes) actual;"},{"lineNumber":112,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedCourse, actualCourse);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedCourse), JsonUtils.toJson(actualCourse));"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackQuestionAttributes) {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes expectedFq \u003d (FeedbackQuestionAttributes) expected;"},{"lineNumber":117,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes actualFq \u003d (FeedbackQuestionAttributes) actual;"},{"lineNumber":118,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedFq, actualFq);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedFq), JsonUtils.toJson(actualFq));"},{"lineNumber":120,"author":{"gitId":"-"},"content":""},{"lineNumber":121,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackResponseCommentAttributes) {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" FeedbackResponseCommentAttributes expectedFrc \u003d (FeedbackResponseCommentAttributes) expected;"},{"lineNumber":123,"author":{"gitId":"-"},"content":" FeedbackResponseCommentAttributes actualFrc \u003d (FeedbackResponseCommentAttributes) actual;"},{"lineNumber":124,"author":{"gitId":"-"},"content":" assertEquals(expectedFrc.getCourseId(), actualFrc.getCourseId());"},{"lineNumber":125,"author":{"gitId":"-"},"content":" assertEquals(expectedFrc.getCommentGiver(), actualFrc.getCommentGiver());"},{"lineNumber":126,"author":{"gitId":"-"},"content":" assertEquals(expectedFrc.getFeedbackSessionName(), actualFrc.getFeedbackSessionName());"},{"lineNumber":127,"author":{"gitId":"-"},"content":" assertEquals(expectedFrc.getCommentText(), actualFrc.getCommentText());"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackResponseAttributes) {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" FeedbackResponseAttributes expectedFr \u003d (FeedbackResponseAttributes) expected;"},{"lineNumber":131,"author":{"gitId":"-"},"content":" FeedbackResponseAttributes actualFr \u003d (FeedbackResponseAttributes) actual;"},{"lineNumber":132,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedFr, actualFr);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedFr), JsonUtils.toJson(actualFr));"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackSessionAttributes) {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes expectedFs \u003d ((FeedbackSessionAttributes) expected).getCopy();"},{"lineNumber":137,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes actualFs \u003d (FeedbackSessionAttributes) actual;"},{"lineNumber":138,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedFs, actualFs);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedFs), JsonUtils.toJson(actualFs));"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" } else if (expected instanceof InstructorAttributes) {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" InstructorAttributes expectedInstructor \u003d ((InstructorAttributes) expected).getCopy();"},{"lineNumber":143,"author":{"gitId":"-"},"content":" InstructorAttributes actualInstructor \u003d (InstructorAttributes) actual;"},{"lineNumber":144,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedInstructor, actualInstructor);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedInstructor), JsonUtils.toJson(actualInstructor));"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" } else if (expected instanceof StudentAttributes) {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" StudentAttributes expectedStudent \u003d ((StudentAttributes) expected).getCopy();"},{"lineNumber":149,"author":{"gitId":"-"},"content":" StudentAttributes actualStudent \u003d (StudentAttributes) actual;"},{"lineNumber":150,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedStudent, actualStudent);"},{"lineNumber":151,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedStudent), JsonUtils.toJson(actualStudent));"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":" } else if (expected instanceof AccountRequestAttributes) {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" AccountRequestAttributes expectedAccountRequest \u003d (AccountRequestAttributes) expected;"},{"lineNumber":155,"author":{"gitId":"-"},"content":" AccountRequestAttributes actualAccountRequest \u003d (AccountRequestAttributes) actual;"},{"lineNumber":156,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedAccountRequest), JsonUtils.toJson(actualAccountRequest));"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"-"},"content":" } else if (expected instanceof DeadlineExtensionAttributes) {"},{"lineNumber":159,"author":{"gitId":"-"},"content":" DeadlineExtensionAttributes expectedDeadlineExtension \u003d (DeadlineExtensionAttributes) expected;"},{"lineNumber":160,"author":{"gitId":"-"},"content":" DeadlineExtensionAttributes actualDeadlineExtension \u003d (DeadlineExtensionAttributes) actual;"},{"lineNumber":161,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedDeadlineExtension, actualDeadlineExtension);"},{"lineNumber":162,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedDeadlineExtension), JsonUtils.toJson(actualDeadlineExtension));"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" } else if (expected instanceof NotificationAttributes) {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" NotificationAttributes expectedNotification \u003d (NotificationAttributes) expected;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" NotificationAttributes actualNotification \u003d (NotificationAttributes) actual;"},{"lineNumber":167,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedNotification, actualNotification);"},{"lineNumber":168,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedNotification), JsonUtils.toJson(actualNotification));"},{"lineNumber":169,"author":{"gitId":"-"},"content":""},{"lineNumber":170,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":171,"author":{"gitId":"-"},"content":" throw new RuntimeException(\"Unknown entity type!\");"},{"lineNumber":172,"author":{"gitId":"-"},"content":" }"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" protected abstract AccountAttributes getAccount(AccountAttributes account);"},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(AccountAttributes expected, AccountAttributes actual) {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":179,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":180,"author":{"gitId":"-"},"content":" }"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(CourseAttributes expected, CourseAttributes actual) {"},{"lineNumber":183,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":184,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(FeedbackQuestionAttributes expected, FeedbackQuestionAttributes actual) {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" expected.setId(actual.getId());"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(FeedbackResponseAttributes expected, FeedbackResponseAttributes actual) {"},{"lineNumber":192,"author":{"gitId":"-"},"content":" expected.setId(actual.getId());"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(FeedbackSessionAttributes expected, FeedbackSessionAttributes actual) {"},{"lineNumber":196,"author":{"gitId":"-"},"content":" expected.setCreatedTime(actual.getCreatedTime());"},{"lineNumber":197,"author":{"gitId":"-"},"content":" // Not available in FeedbackSessionData and thus ignored"},{"lineNumber":198,"author":{"gitId":"-"},"content":" expected.setCreatorEmail(actual.getCreatorEmail());"},{"lineNumber":199,"author":{"gitId":"-"},"content":" }"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(InstructorAttributes expected, InstructorAttributes actual) {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" // pretend keys match because the key is generated only before storing into database"},{"lineNumber":203,"author":{"gitId":"-"},"content":" if (actual.getKey() !\u003d null) {"},{"lineNumber":204,"author":{"gitId":"-"},"content":" expected.setKey(actual.getKey());"},{"lineNumber":205,"author":{"gitId":"-"},"content":" }"},{"lineNumber":206,"author":{"gitId":"-"},"content":" }"},{"lineNumber":207,"author":{"gitId":"-"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(StudentAttributes expected, StudentAttributes actual) {"},{"lineNumber":209,"author":{"gitId":"-"},"content":" // For these fields, we consider null and \"\" equivalent."},{"lineNumber":210,"author":{"gitId":"-"},"content":" if (expected.getGoogleId() \u003d\u003d null \u0026\u0026 actual.getGoogleId().isEmpty()) {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" expected.setGoogleId(\"\");"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":" if (expected.getTeam() \u003d\u003d null \u0026\u0026 actual.getTeam().isEmpty()) {"},{"lineNumber":214,"author":{"gitId":"-"},"content":" expected.setTeam(\"\");"},{"lineNumber":215,"author":{"gitId":"-"},"content":" }"},{"lineNumber":216,"author":{"gitId":"-"},"content":" if (expected.getComments() \u003d\u003d null \u0026\u0026 actual.getComments().isEmpty()) {"},{"lineNumber":217,"author":{"gitId":"-"},"content":" expected.setComments(\"\");"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" // pretend keys match because the key is generated only before storing into database"},{"lineNumber":221,"author":{"gitId":"-"},"content":" if (actual.getKey() !\u003d null) {"},{"lineNumber":222,"author":{"gitId":"-"},"content":" expected.setKey(actual.getKey());"},{"lineNumber":223,"author":{"gitId":"-"},"content":" }"},{"lineNumber":224,"author":{"gitId":"-"},"content":" }"},{"lineNumber":225,"author":{"gitId":"-"},"content":""},{"lineNumber":226,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(DeadlineExtensionAttributes expected, DeadlineExtensionAttributes actual) {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":228,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":229,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":230,"author":{"gitId":"-"},"content":" }"},{"lineNumber":231,"author":{"gitId":"-"},"content":""},{"lineNumber":232,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(NotificationAttributes expected, NotificationAttributes actual) {"},{"lineNumber":233,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":234,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":235,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":236,"author":{"gitId":"-"},"content":" }"},{"lineNumber":237,"author":{"gitId":"-"},"content":""},{"lineNumber":238,"author":{"gitId":"-"},"content":" protected abstract CourseAttributes getCourse(CourseAttributes course);"},{"lineNumber":239,"author":{"gitId":"-"},"content":""},{"lineNumber":240,"author":{"gitId":"-"},"content":" protected abstract FeedbackQuestionAttributes getFeedbackQuestion(FeedbackQuestionAttributes fq);"},{"lineNumber":241,"author":{"gitId":"-"},"content":""},{"lineNumber":242,"author":{"gitId":"-"},"content":" protected abstract FeedbackResponseCommentAttributes getFeedbackResponseComment(FeedbackResponseCommentAttributes frc);"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" protected abstract FeedbackResponseAttributes getFeedbackResponse(FeedbackResponseAttributes fr);"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" protected abstract FeedbackSessionAttributes getFeedbackSession(FeedbackSessionAttributes fs);"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" protected abstract InstructorAttributes getInstructor(InstructorAttributes instructor);"},{"lineNumber":249,"author":{"gitId":"-"},"content":""},{"lineNumber":250,"author":{"gitId":"-"},"content":" protected abstract StudentAttributes getStudent(StudentAttributes student);"},{"lineNumber":251,"author":{"gitId":"-"},"content":""},{"lineNumber":252,"author":{"gitId":"-"},"content":" protected abstract AccountRequestAttributes getAccountRequest(AccountRequestAttributes accountRequest);"},{"lineNumber":253,"author":{"gitId":"-"},"content":""},{"lineNumber":254,"author":{"gitId":"-"},"content":" protected abstract DeadlineExtensionAttributes getDeadlineExtension(DeadlineExtensionAttributes accountRequest);"},{"lineNumber":255,"author":{"gitId":"-"},"content":""},{"lineNumber":256,"author":{"gitId":"-"},"content":" protected abstract NotificationAttributes getNotification(NotificationAttributes notification);"},{"lineNumber":257,"author":{"gitId":"-"},"content":""},{"lineNumber":258,"author":{"gitId":"-"},"content":" protected void removeAndRestoreDataBundle(DataBundle testData) {"},{"lineNumber":259,"author":{"gitId":"-"},"content":" int retryLimit \u003d OPERATION_RETRY_COUNT;"},{"lineNumber":260,"author":{"gitId":"-"},"content":" boolean isOperationSuccess \u003d doRemoveAndRestoreDataBundle(testData);"},{"lineNumber":261,"author":{"gitId":"-"},"content":" while (!isOperationSuccess \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":262,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":263,"author":{"gitId":"-"},"content":" print(\"Re-trying removeAndRestoreDataBundle\");"},{"lineNumber":264,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(OPERATION_RETRY_DELAY_IN_MS);"},{"lineNumber":265,"author":{"gitId":"-"},"content":" isOperationSuccess \u003d doRemoveAndRestoreDataBundle(testData);"},{"lineNumber":266,"author":{"gitId":"-"},"content":" }"},{"lineNumber":267,"author":{"gitId":"-"},"content":" assertTrue(isOperationSuccess);"},{"lineNumber":268,"author":{"gitId":"-"},"content":" }"},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":" protected abstract boolean doRemoveAndRestoreDataBundle(DataBundle testData);"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" protected SqlDataBundle removeAndRestoreSqlDataBundle(SqlDataBundle testData) {"},{"lineNumber":273,"author":{"gitId":"-"},"content":" int retryLimit \u003d OPERATION_RETRY_COUNT;"},{"lineNumber":274,"author":{"gitId":"-"},"content":" SqlDataBundle dataBundle \u003d doRemoveAndRestoreSqlDataBundle(testData);"},{"lineNumber":275,"author":{"gitId":"-"},"content":" while (dataBundle \u003d\u003d null \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":276,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":277,"author":{"gitId":"-"},"content":" print(\"Re-trying removeAndRestoreDataBundle\");"},{"lineNumber":278,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(OPERATION_RETRY_DELAY_IN_MS);"},{"lineNumber":279,"author":{"gitId":"-"},"content":" dataBundle \u003d doRemoveAndRestoreSqlDataBundle(testData);"},{"lineNumber":280,"author":{"gitId":"-"},"content":" }"},{"lineNumber":281,"author":{"gitId":"-"},"content":" assertNotNull(dataBundle);"},{"lineNumber":282,"author":{"gitId":"-"},"content":" return dataBundle;"},{"lineNumber":283,"author":{"gitId":"-"},"content":" }"},{"lineNumber":284,"author":{"gitId":"-"},"content":""},{"lineNumber":285,"author":{"gitId":"-"},"content":" protected abstract SqlDataBundle doRemoveAndRestoreSqlDataBundle(SqlDataBundle testData);"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"-"},"content":" protected void putDocuments(DataBundle testData) {"},{"lineNumber":288,"author":{"gitId":"-"},"content":" int retryLimit \u003d OPERATION_RETRY_COUNT;"},{"lineNumber":289,"author":{"gitId":"-"},"content":" boolean isOperationSuccess \u003d doPutDocuments(testData);"},{"lineNumber":290,"author":{"gitId":"-"},"content":" while (!isOperationSuccess \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":291,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":292,"author":{"gitId":"-"},"content":" print(\"Re-trying putDocuments\");"},{"lineNumber":293,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(OPERATION_RETRY_DELAY_IN_MS);"},{"lineNumber":294,"author":{"gitId":"-"},"content":" isOperationSuccess \u003d doPutDocuments(testData);"},{"lineNumber":295,"author":{"gitId":"-"},"content":" }"},{"lineNumber":296,"author":{"gitId":"-"},"content":" assertTrue(isOperationSuccess);"},{"lineNumber":297,"author":{"gitId":"-"},"content":" }"},{"lineNumber":298,"author":{"gitId":"-"},"content":""},{"lineNumber":299,"author":{"gitId":"-"},"content":" protected abstract boolean doPutDocuments(DataBundle testData);"},{"lineNumber":300,"author":{"gitId":"-"},"content":""},{"lineNumber":301,"author":{"gitId":"domoberzin"},"content":" protected void putSqlDocuments(SqlDataBundle testData) {"},{"lineNumber":302,"author":{"gitId":"domoberzin"},"content":" int retryLimit \u003d OPERATION_RETRY_COUNT;"},{"lineNumber":303,"author":{"gitId":"domoberzin"},"content":" boolean isOperationSuccess \u003d doPutDocumentsSql(testData);"},{"lineNumber":304,"author":{"gitId":"domoberzin"},"content":" while (!isOperationSuccess \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":305,"author":{"gitId":"domoberzin"},"content":" retryLimit--;"},{"lineNumber":306,"author":{"gitId":"domoberzin"},"content":" print(\"Re-trying putSqlDocuments\");"},{"lineNumber":307,"author":{"gitId":"domoberzin"},"content":" ThreadHelper.waitFor(OPERATION_RETRY_DELAY_IN_MS);"},{"lineNumber":308,"author":{"gitId":"domoberzin"},"content":" isOperationSuccess \u003d doPutDocumentsSql(testData);"},{"lineNumber":309,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":310,"author":{"gitId":"domoberzin"},"content":" assertTrue(isOperationSuccess);"},{"lineNumber":311,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":312,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":313,"author":{"gitId":"domoberzin"},"content":" protected abstract boolean doPutDocumentsSql(SqlDataBundle testData);"},{"lineNumber":314,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":13,"-":301}},{"path":"src/test/java/teammates/test/BaseTestCaseWithLocalDatabaseAccess.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.test;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import org.testcontainers.containers.PostgreSQLContainer;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterMethod;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterSuite;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeSuite;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import com.google.cloud.datastore.DatastoreOptions;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import com.google.cloud.datastore.testing.LocalDatastoreHelper;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import com.googlecode.objectify.ObjectifyFactory;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import com.googlecode.objectify.ObjectifyService;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import com.googlecode.objectify.util.Closeable;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.DataBundle;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountAttributes;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountRequestAttributes;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.DeadlineExtensionAttributes;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseAttributes;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseCommentAttributes;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.NotificationAttributes;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.logic.api.LogicExtension;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.logic.core.LogicStarter;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.sqllogic.api.Logic;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.storage.api.OfyHelper;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.storage.search.AccountRequestSearchManager;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.storage.search.InstructorSearchManager;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import teammates.storage.search.SearchManagerFactory;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"import teammates.storage.search.StudentSearchManager;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":43,"author":{"gitId":"-"},"content":" * Base class for all tests which require access to a locally run database."},{"lineNumber":44,"author":{"gitId":"-"},"content":" *"},{"lineNumber":45,"author":{"gitId":"-"},"content":" * \u003cp\u003eAs all tests are run against a single DB instance and we use shared test data for most tests,"},{"lineNumber":46,"author":{"gitId":"-"},"content":" * the tests need to be run in a single thread to prevent test data contamination across different tests."},{"lineNumber":47,"author":{"gitId":"-"},"content":" */"},{"lineNumber":48,"author":{"gitId":"-"},"content":"@Test(singleThreaded \u003d true)"},{"lineNumber":49,"author":{"gitId":"-"},"content":"public abstract class BaseTestCaseWithLocalDatabaseAccess extends BaseTestCaseWithDatabaseAccess {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" private static final PostgreSQLContainer\u003c?\u003e PGSQL \u003d new PostgreSQLContainer\u003c\u003e(\"postgres:15.1-alpine\");"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" private static final LocalDatastoreHelper LOCAL_DATASTORE_HELPER \u003d LocalDatastoreHelper.newBuilder()"},{"lineNumber":53,"author":{"gitId":"-"},"content":" .setConsistency(1.0)"},{"lineNumber":54,"author":{"gitId":"-"},"content":" .setPort(TestProperties.TEST_LOCALDATASTORE_PORT)"},{"lineNumber":55,"author":{"gitId":"-"},"content":" .setStoreOnDisk(false)"},{"lineNumber":56,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":57,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":58,"author":{"gitId":"-"},"content":" * sqlLogic for use in test cases."},{"lineNumber":59,"author":{"gitId":"-"},"content":" */"},{"lineNumber":60,"author":{"gitId":"-"},"content":" protected Logic sqlLogic;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" private final LogicExtension logic \u003d new LogicExtension();"},{"lineNumber":62,"author":{"gitId":"-"},"content":" private Closeable closeable;"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" @BeforeSuite"},{"lineNumber":65,"author":{"gitId":"-"},"content":" public void setupDbLayer() throws Exception {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" PGSQL.start();"},{"lineNumber":67,"author":{"gitId":"-"},"content":" HibernateUtil.buildSessionFactory(PGSQL.getJdbcUrl(), PGSQL.getUsername(), PGSQL.getPassword());"},{"lineNumber":68,"author":{"gitId":"-"},"content":" teammates.sqllogic.core.LogicStarter.initializeDependencies();"},{"lineNumber":69,"author":{"gitId":"-"},"content":" sqlLogic \u003d Logic.inst();"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" LOCAL_DATASTORE_HELPER.start();"},{"lineNumber":72,"author":{"gitId":"-"},"content":" DatastoreOptions options \u003d LOCAL_DATASTORE_HELPER.getOptions();"},{"lineNumber":73,"author":{"gitId":"-"},"content":" ObjectifyService.init(new ObjectifyFactory("},{"lineNumber":74,"author":{"gitId":"-"},"content":" options.getService()"},{"lineNumber":75,"author":{"gitId":"-"},"content":" ));"},{"lineNumber":76,"author":{"gitId":"-"},"content":" OfyHelper.registerEntityClasses();"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" SearchManagerFactory.registerAccountRequestSearchManager("},{"lineNumber":79,"author":{"gitId":"-"},"content":" new AccountRequestSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":80,"author":{"gitId":"-"},"content":" SearchManagerFactory.registerInstructorSearchManager("},{"lineNumber":81,"author":{"gitId":"-"},"content":" new InstructorSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":82,"author":{"gitId":"-"},"content":" SearchManagerFactory.registerStudentSearchManager("},{"lineNumber":83,"author":{"gitId":"-"},"content":" new StudentSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" teammates.storage.sqlsearch.SearchManagerFactory.registerAccountRequestSearchManager("},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":" new teammates.storage.sqlsearch.AccountRequestSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" teammates.storage.sqlsearch.SearchManagerFactory.registerInstructorSearchManager("},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" new teammates.storage.sqlsearch.InstructorSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" teammates.storage.sqlsearch.SearchManagerFactory.registerStudentSearchManager("},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" new teammates.storage.sqlsearch.StudentSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" LogicStarter.initializeDependencies();"},{"lineNumber":93,"author":{"gitId":"-"},"content":" }"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" @BeforeClass"},{"lineNumber":96,"author":{"gitId":"-"},"content":" public void setupObjectify() {"},{"lineNumber":97,"author":{"gitId":"-"},"content":" closeable \u003d ObjectifyService.begin();"},{"lineNumber":98,"author":{"gitId":"-"},"content":" }"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":101,"author":{"gitId":"-"},"content":" public void tearDownObjectify() {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" closeable.close();"},{"lineNumber":103,"author":{"gitId":"-"},"content":" }"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":106,"author":{"gitId":"-"},"content":" public void resetDbLayer() throws Exception {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" SearchManagerFactory.getAccountRequestSearchManager().resetCollections();"},{"lineNumber":108,"author":{"gitId":"-"},"content":" SearchManagerFactory.getInstructorSearchManager().resetCollections();"},{"lineNumber":109,"author":{"gitId":"-"},"content":" SearchManagerFactory.getStudentSearchManager().resetCollections();"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" LOCAL_DATASTORE_HELPER.reset();"},{"lineNumber":112,"author":{"gitId":"-"},"content":" }"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" @AfterSuite"},{"lineNumber":115,"author":{"gitId":"-"},"content":" public void tearDownLocalDatastoreHelper() throws Exception {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" PGSQL.close();"},{"lineNumber":117,"author":{"gitId":"-"},"content":" LOCAL_DATASTORE_HELPER.stop();"},{"lineNumber":118,"author":{"gitId":"-"},"content":" }"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":121,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":123,"author":{"gitId":"-"},"content":" }"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" @AfterMethod"},{"lineNumber":126,"author":{"gitId":"-"},"content":" protected void tearDown() {"},{"lineNumber":127,"author":{"gitId":"-"},"content":" HibernateUtil.rollbackTransaction();"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":131,"author":{"gitId":"-"},"content":" protected AccountAttributes getAccount(AccountAttributes account) {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" return logic.getAccount(account.getGoogleId());"},{"lineNumber":133,"author":{"gitId":"-"},"content":" }"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":136,"author":{"gitId":"-"},"content":" protected CourseAttributes getCourse(CourseAttributes course) {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" return logic.getCourse(course.getId());"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":141,"author":{"gitId":"-"},"content":" protected FeedbackQuestionAttributes getFeedbackQuestion(FeedbackQuestionAttributes fq) {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" return logic.getFeedbackQuestion(fq.getFeedbackSessionName(), fq.getCourseId(), fq.getQuestionNumber());"},{"lineNumber":143,"author":{"gitId":"-"},"content":" }"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":146,"author":{"gitId":"-"},"content":" protected FeedbackResponseCommentAttributes getFeedbackResponseComment(FeedbackResponseCommentAttributes frc) {"},{"lineNumber":147,"author":{"gitId":"-"},"content":" return logic.getFeedbackResponseComment(frc.getFeedbackResponseId(), frc.getCommentGiver(), frc.getCreatedAt());"},{"lineNumber":148,"author":{"gitId":"-"},"content":" }"},{"lineNumber":149,"author":{"gitId":"-"},"content":""},{"lineNumber":150,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":151,"author":{"gitId":"-"},"content":" protected FeedbackResponseAttributes getFeedbackResponse(FeedbackResponseAttributes fr) {"},{"lineNumber":152,"author":{"gitId":"-"},"content":" return logic.getFeedbackResponse(fr.getFeedbackQuestionId(), fr.getGiver(), fr.getRecipient());"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":156,"author":{"gitId":"-"},"content":" protected FeedbackSessionAttributes getFeedbackSession(FeedbackSessionAttributes fs) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" return logic.getFeedbackSession(fs.getFeedbackSessionName(), fs.getCourseId());"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":161,"author":{"gitId":"-"},"content":" protected InstructorAttributes getInstructor(InstructorAttributes instructor) {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" return instructor.getGoogleId() \u003d\u003d null"},{"lineNumber":163,"author":{"gitId":"-"},"content":" ? logic.getInstructorForEmail(instructor.getCourseId(), instructor.getEmail())"},{"lineNumber":164,"author":{"gitId":"-"},"content":" : logic.getInstructorForGoogleId(instructor.getCourseId(), instructor.getGoogleId());"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":168,"author":{"gitId":"-"},"content":" protected StudentAttributes getStudent(StudentAttributes student) {"},{"lineNumber":169,"author":{"gitId":"-"},"content":" return logic.getStudentForEmail(student.getCourse(), student.getEmail());"},{"lineNumber":170,"author":{"gitId":"-"},"content":" }"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":173,"author":{"gitId":"-"},"content":" protected AccountRequestAttributes getAccountRequest(AccountRequestAttributes accountRequest) {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" return logic.getAccountRequest(accountRequest.getEmail(), accountRequest.getInstitute());"},{"lineNumber":175,"author":{"gitId":"-"},"content":" }"},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":178,"author":{"gitId":"-"},"content":" protected DeadlineExtensionAttributes getDeadlineExtension(DeadlineExtensionAttributes deadlineExtension) {"},{"lineNumber":179,"author":{"gitId":"-"},"content":" return logic.getDeadlineExtension("},{"lineNumber":180,"author":{"gitId":"-"},"content":" deadlineExtension.getCourseId(), deadlineExtension.getFeedbackSessionName(),"},{"lineNumber":181,"author":{"gitId":"-"},"content":" deadlineExtension.getUserEmail(), deadlineExtension.getIsInstructor());"},{"lineNumber":182,"author":{"gitId":"-"},"content":" }"},{"lineNumber":183,"author":{"gitId":"-"},"content":""},{"lineNumber":184,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":185,"author":{"gitId":"-"},"content":" protected NotificationAttributes getNotification(NotificationAttributes notification) {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" return logic.getNotification(notification.getNotificationId());"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":" protected void removeAndRestoreTypicalDataBundle() {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" DataBundle dataBundle \u003d getTypicalDataBundle();"},{"lineNumber":191,"author":{"gitId":"-"},"content":" removeAndRestoreDataBundle(dataBundle);"},{"lineNumber":192,"author":{"gitId":"-"},"content":" }"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":195,"author":{"gitId":"-"},"content":" protected boolean doRemoveAndRestoreDataBundle(DataBundle dataBundle) {"},{"lineNumber":196,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" logic.removeDataBundle(dataBundle);"},{"lineNumber":198,"author":{"gitId":"-"},"content":" logic.persistDataBundle(dataBundle);"},{"lineNumber":199,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":200,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":201,"author":{"gitId":"-"},"content":" e.printStackTrace();"},{"lineNumber":202,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":203,"author":{"gitId":"-"},"content":" }"},{"lineNumber":204,"author":{"gitId":"-"},"content":" }"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":207,"author":{"gitId":"-"},"content":" protected SqlDataBundle doRemoveAndRestoreSqlDataBundle(SqlDataBundle dataBundle) {"},{"lineNumber":208,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":209,"author":{"gitId":"-"},"content":" sqlLogic.removeDataBundle(dataBundle);"},{"lineNumber":210,"author":{"gitId":"-"},"content":" return sqlLogic.persistDataBundle(dataBundle);"},{"lineNumber":211,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" e.printStackTrace();"},{"lineNumber":213,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":214,"author":{"gitId":"-"},"content":" }"},{"lineNumber":215,"author":{"gitId":"-"},"content":" }"},{"lineNumber":216,"author":{"gitId":"-"},"content":""},{"lineNumber":217,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":218,"author":{"gitId":"-"},"content":" protected boolean doPutDocuments(DataBundle dataBundle) {"},{"lineNumber":219,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" logic.putDocuments(dataBundle);"},{"lineNumber":221,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":222,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":223,"author":{"gitId":"-"},"content":" e.printStackTrace();"},{"lineNumber":224,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":225,"author":{"gitId":"-"},"content":" }"},{"lineNumber":226,"author":{"gitId":"-"},"content":" }"},{"lineNumber":227,"author":{"gitId":"-"},"content":""},{"lineNumber":228,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":229,"author":{"gitId":"domoberzin"},"content":" protected boolean doPutDocumentsSql(SqlDataBundle dataBundle) {"},{"lineNumber":230,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":231,"author":{"gitId":"domoberzin"},"content":" sqlLogic.putDocuments(dataBundle);"},{"lineNumber":232,"author":{"gitId":"domoberzin"},"content":" return true;"},{"lineNumber":233,"author":{"gitId":"domoberzin"},"content":" } catch (Exception e) {"},{"lineNumber":234,"author":{"gitId":"domoberzin"},"content":" e.printStackTrace();"},{"lineNumber":235,"author":{"gitId":"domoberzin"},"content":" return false;"},{"lineNumber":236,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":237,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":238,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":239,"author":{"gitId":"-"},"content":" protected Account getAccountFromDatabase(String googleId) {"},{"lineNumber":240,"author":{"gitId":"-"},"content":" return sqlLogic.getAccountForGoogleId(googleId);"},{"lineNumber":241,"author":{"gitId":"-"},"content":" }"},{"lineNumber":242,"author":{"gitId":"-"},"content":""},{"lineNumber":243,"author":{"gitId":"-"},"content":" protected void clearObjectifyCache() {"},{"lineNumber":244,"author":{"gitId":"-"},"content":" ObjectifyService.ofy().clear();"},{"lineNumber":245,"author":{"gitId":"-"},"content":" }"},{"lineNumber":246,"author":{"gitId":"-"},"content":""},{"lineNumber":247,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":18,"-":229}},{"path":"src/test/java/teammates/test/BaseTestCaseWithSqlDatabaseAccess.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.test;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionDetails;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackResponseDetails;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Const;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.BaseEntity;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.UsageStatistics;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.ui.output.AccountData;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.ui.output.ApiOutput;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.ui.output.CourseData;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.ui.output.DeadlineExtensionData;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackQuestionData;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackResponseCommentData;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackResponseData;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionData;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.ui.output.InstructorData;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.ui.output.NotificationData;"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.output.NumberOfEntitiesToGiveFeedbackToSetting;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.ui.output.StudentData;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.ui.output.UsageStatisticsData;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":34,"author":{"gitId":"-"},"content":" * Base class for all test cases which are allowed to access the database."},{"lineNumber":35,"author":{"gitId":"-"},"content":" */"},{"lineNumber":36,"author":{"gitId":"-"},"content":"public abstract class BaseTestCaseWithSqlDatabaseAccess extends BaseTestCase {"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" private static final int VERIFICATION_RETRY_COUNT \u003d 5;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" private static final int VERIFICATION_RETRY_DELAY_IN_MS \u003d 1000;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" private static final int OPERATION_RETRY_COUNT \u003d 5;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" private static final int OPERATION_RETRY_DELAY_IN_MS \u003d 1000;"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":44,"author":{"gitId":"-"},"content":" * Removes and restores the databundle, with retries."},{"lineNumber":45,"author":{"gitId":"-"},"content":" */"},{"lineNumber":46,"author":{"gitId":"-"},"content":" protected SqlDataBundle removeAndRestoreDataBundle(SqlDataBundle testData) {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" int retryLimit \u003d OPERATION_RETRY_COUNT;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" SqlDataBundle dataBundle \u003d doRemoveAndRestoreDataBundle(testData);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" while (dataBundle \u003d\u003d null \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" print(\"Re-trying removeAndRestoreDataBundle\");"},{"lineNumber":52,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(OPERATION_RETRY_DELAY_IN_MS);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" dataBundle \u003d doRemoveAndRestoreDataBundle(testData);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" }"},{"lineNumber":55,"author":{"gitId":"-"},"content":" assertNotNull(dataBundle);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" return dataBundle;"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" protected abstract SqlDataBundle doRemoveAndRestoreDataBundle(SqlDataBundle testData);"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":62,"author":{"gitId":"-"},"content":" * Verifies that two entities are equal."},{"lineNumber":63,"author":{"gitId":"-"},"content":" */"},{"lineNumber":64,"author":{"gitId":"-"},"content":" protected void verifyEquals(BaseEntity expected, ApiOutput actual) {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" if (expected instanceof FeedbackQuestion) {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" FeedbackQuestion expectedQuestion \u003d (FeedbackQuestion) expected;"},{"lineNumber":67,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails expectedQuestionDetails \u003d expectedQuestion.getQuestionDetailsCopy();"},{"lineNumber":68,"author":{"gitId":"-"},"content":" FeedbackQuestionData actualQuestion \u003d (FeedbackQuestionData) actual;"},{"lineNumber":69,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails actualQuestionDetails \u003d actualQuestion.getQuestionDetails();"},{"lineNumber":70,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestion.getQuestionNumber(), (Integer) actualQuestion.getQuestionNumber());"},{"lineNumber":71,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestion.getDescription(), actualQuestion.getQuestionDescription());"},{"lineNumber":72,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestion.getGiverType(), actualQuestion.getGiverType());"},{"lineNumber":73,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestion.getRecipientType(), actualQuestion.getRecipientType());"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" if (expectedQuestion.getNumOfEntitiesToGiveFeedbackTo() \u003d\u003d Const.MAX_POSSIBLE_RECIPIENTS) {"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" assertEquals(actualQuestion.getNumberOfEntitiesToGiveFeedbackToSetting(),"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" NumberOfEntitiesToGiveFeedbackToSetting.UNLIMITED);"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" assertNull(actualQuestion.getCustomNumberOfEntitiesToGiveFeedbackTo());"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" assertEquals(actualQuestion.getNumberOfEntitiesToGiveFeedbackToSetting(),"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" NumberOfEntitiesToGiveFeedbackToSetting.CUSTOM);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestion.getNumOfEntitiesToGiveFeedbackTo(),"},{"lineNumber":82,"author":{"gitId":"-"},"content":" actualQuestion.getCustomNumberOfEntitiesToGiveFeedbackTo());"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":84,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestionDetails.getJsonString(), actualQuestionDetails.getJsonString());"},{"lineNumber":85,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackResponse) {"},{"lineNumber":86,"author":{"gitId":"-"},"content":" FeedbackResponse expectedFeedbackResponse \u003d (FeedbackResponse) expected;"},{"lineNumber":87,"author":{"gitId":"-"},"content":" FeedbackResponseDetails expectedResponseDetails \u003d"},{"lineNumber":88,"author":{"gitId":"-"},"content":" expectedFeedbackResponse.getFeedbackResponseDetailsCopy();"},{"lineNumber":89,"author":{"gitId":"-"},"content":" FeedbackResponseData actualResponse \u003d (FeedbackResponseData) actual;"},{"lineNumber":90,"author":{"gitId":"-"},"content":" FeedbackResponseDetails actualResponseDetails \u003d actualResponse.getResponseDetails();"},{"lineNumber":91,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackResponse.getGiver(), actualResponse.getGiverIdentifier());"},{"lineNumber":92,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackResponse.getRecipient(), actualResponse.getRecipientIdentifier());"},{"lineNumber":93,"author":{"gitId":"-"},"content":" assertEquals(expectedResponseDetails.getAnswerString(),"},{"lineNumber":94,"author":{"gitId":"-"},"content":" actualResponse.getResponseDetails().getAnswerString());"},{"lineNumber":95,"author":{"gitId":"-"},"content":" assertEquals(expectedResponseDetails.getQuestionType(),"},{"lineNumber":96,"author":{"gitId":"-"},"content":" actualResponse.getResponseDetails().getQuestionType());"},{"lineNumber":97,"author":{"gitId":"-"},"content":" assertEquals(expectedResponseDetails.getJsonString(), actualResponseDetails.getJsonString());"},{"lineNumber":98,"author":{"gitId":"-"},"content":" } else if (expected instanceof Account) {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" Account expectedAccount \u003d (Account) expected;"},{"lineNumber":100,"author":{"gitId":"-"},"content":" AccountData actualAccount \u003d (AccountData) actual;"},{"lineNumber":101,"author":{"gitId":"-"},"content":" assertEquals(expectedAccount.getGoogleId(), actualAccount.getGoogleId());"},{"lineNumber":102,"author":{"gitId":"-"},"content":" assertEquals(expectedAccount.getName(), actualAccount.getName());"},{"lineNumber":103,"author":{"gitId":"-"},"content":" assertEquals(expectedAccount.getEmail(), actualAccount.getEmail());"},{"lineNumber":104,"author":{"gitId":"-"},"content":" } else if (expected instanceof Course) {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" Course expectedCourse \u003d (Course) expected;"},{"lineNumber":106,"author":{"gitId":"-"},"content":" CourseData actualCourse \u003d (CourseData) actual;"},{"lineNumber":107,"author":{"gitId":"-"},"content":" assertEquals(expectedCourse.getName(), actualCourse.getCourseName());"},{"lineNumber":108,"author":{"gitId":"-"},"content":" assertEquals(expectedCourse.getTimeZone(), actualCourse.getTimeZone());"},{"lineNumber":109,"author":{"gitId":"-"},"content":" assertEquals(expectedCourse.getInstitute(), actualCourse.getInstitute());"},{"lineNumber":110,"author":{"gitId":"-"},"content":" } else if (expected instanceof DeadlineExtension) {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" DeadlineExtension expectedDeadlineExtension \u003d (DeadlineExtension) expected;"},{"lineNumber":112,"author":{"gitId":"-"},"content":" DeadlineExtensionData actualDeadlineExtension \u003d (DeadlineExtensionData) actual;"},{"lineNumber":113,"author":{"gitId":"-"},"content":" assertEquals(expectedDeadlineExtension.getEndTime().toEpochMilli(), actualDeadlineExtension.getEndTime());"},{"lineNumber":114,"author":{"gitId":"-"},"content":" assertEquals(expectedDeadlineExtension.isClosingSoonEmailSent(),"},{"lineNumber":115,"author":{"gitId":"-"},"content":" actualDeadlineExtension.getSentClosingEmail());"},{"lineNumber":116,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackResponseComment) {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" FeedbackResponseComment expectedFeedbackResponseComment \u003d (FeedbackResponseComment) expected;"},{"lineNumber":118,"author":{"gitId":"-"},"content":" FeedbackResponseCommentData actualComment \u003d (FeedbackResponseCommentData) actual;"},{"lineNumber":119,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackResponseComment.getGiver(), actualComment.getCommentGiver());"},{"lineNumber":120,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackResponseComment.getCommentText(), actualComment.getCommentText());"},{"lineNumber":121,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackResponseComment.getIsVisibilityFollowingFeedbackQuestion(),"},{"lineNumber":122,"author":{"gitId":"-"},"content":" actualComment.isVisibilityFollowingFeedbackQuestion());"},{"lineNumber":123,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackResponseComment.getLastEditorEmail(), actualComment.getLastEditorEmail());"},{"lineNumber":124,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackSession) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" FeedbackSession expectedFeedbackSession \u003d (FeedbackSession) expected;"},{"lineNumber":126,"author":{"gitId":"-"},"content":" FeedbackSessionData actualFeedbackSession \u003d (FeedbackSessionData) actual;"},{"lineNumber":127,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackSession.getName(), actualFeedbackSession.getFeedbackSessionName());"},{"lineNumber":128,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackSession.getInstructions(), actualFeedbackSession.getInstructions());"},{"lineNumber":129,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackSession.getStartTime().toEpochMilli(),"},{"lineNumber":130,"author":{"gitId":"-"},"content":" actualFeedbackSession.getSubmissionStartTimestamp());"},{"lineNumber":131,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackSession.getEndTime().toEpochMilli(),"},{"lineNumber":132,"author":{"gitId":"-"},"content":" actualFeedbackSession.getSubmissionEndTimestamp());"},{"lineNumber":133,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackSession.getSessionVisibleFromTime().toEpochMilli(),"},{"lineNumber":134,"author":{"gitId":"-"},"content":" actualFeedbackSession.getSessionVisibleFromTimestamp().longValue());"},{"lineNumber":135,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackSession.getResultsVisibleFromTime().toEpochMilli(),"},{"lineNumber":136,"author":{"gitId":"-"},"content":" actualFeedbackSession.getResultVisibleFromTimestamp().longValue());"},{"lineNumber":137,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackSession.getGracePeriod().toMinutes(),"},{"lineNumber":138,"author":{"gitId":"-"},"content":" actualFeedbackSession.getGracePeriod().longValue());"},{"lineNumber":139,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackSession.isClosingEmailEnabled(),"},{"lineNumber":140,"author":{"gitId":"-"},"content":" actualFeedbackSession.getIsClosingEmailEnabled());"},{"lineNumber":141,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackSession.isPublishedEmailEnabled(),"},{"lineNumber":142,"author":{"gitId":"-"},"content":" actualFeedbackSession.getIsPublishedEmailEnabled());"},{"lineNumber":143,"author":{"gitId":"-"},"content":" } else if (expected instanceof Instructor) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" Instructor expectedInstructor \u003d (Instructor) expected;"},{"lineNumber":145,"author":{"gitId":"-"},"content":" InstructorData actualInstructor \u003d (InstructorData) actual;"},{"lineNumber":146,"author":{"gitId":"-"},"content":" assertEquals(expectedInstructor.getCourseId(), actualInstructor.getCourseId());"},{"lineNumber":147,"author":{"gitId":"-"},"content":" assertEquals(expectedInstructor.getName(), actualInstructor.getName());"},{"lineNumber":148,"author":{"gitId":"-"},"content":" assertEquals(expectedInstructor.getEmail(), actualInstructor.getEmail());"},{"lineNumber":149,"author":{"gitId":"-"},"content":" assertEquals(expectedInstructor.getRegKey(), actualInstructor.getKey());"},{"lineNumber":150,"author":{"gitId":"-"},"content":" assertEquals(expectedInstructor.isDisplayedToStudents(), actualInstructor.getIsDisplayedToStudents());"},{"lineNumber":151,"author":{"gitId":"-"},"content":" assertEquals(expectedInstructor.getDisplayName(), actualInstructor.getDisplayedToStudentsAs());"},{"lineNumber":152,"author":{"gitId":"-"},"content":" assertEquals(expectedInstructor.getRole(), actualInstructor.getRole());"},{"lineNumber":153,"author":{"gitId":"-"},"content":" } else if (expected instanceof Notification) {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" Notification expectedNotification \u003d (Notification) expected;"},{"lineNumber":155,"author":{"gitId":"-"},"content":" NotificationData actualNotification \u003d (NotificationData) actual;"},{"lineNumber":156,"author":{"gitId":"-"},"content":" assertEquals(expectedNotification.getStartTime().toEpochMilli(), actualNotification.getStartTimestamp());"},{"lineNumber":157,"author":{"gitId":"-"},"content":" assertEquals(expectedNotification.getEndTime().toEpochMilli(), actualNotification.getEndTimestamp());"},{"lineNumber":158,"author":{"gitId":"-"},"content":" assertEquals(expectedNotification.getStyle(), actualNotification.getStyle());"},{"lineNumber":159,"author":{"gitId":"-"},"content":" assertEquals(expectedNotification.getTargetUser(), actualNotification.getTargetUser());"},{"lineNumber":160,"author":{"gitId":"-"},"content":" assertEquals(expectedNotification.getTitle(), actualNotification.getTitle());"},{"lineNumber":161,"author":{"gitId":"-"},"content":" assertEquals(expectedNotification.getMessage(), actualNotification.getMessage());"},{"lineNumber":162,"author":{"gitId":"-"},"content":" assertEquals(expectedNotification.isShown(), actualNotification.isShown());"},{"lineNumber":163,"author":{"gitId":"-"},"content":" } else if (expected instanceof Student) {"},{"lineNumber":164,"author":{"gitId":"-"},"content":" Student expectedStudent \u003d (Student) expected;"},{"lineNumber":165,"author":{"gitId":"-"},"content":" StudentData actualStudent \u003d (StudentData) actual;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" assertEquals(expectedStudent.getCourseId(), actualStudent.getCourseId());"},{"lineNumber":167,"author":{"gitId":"-"},"content":" assertEquals(expectedStudent.getName(), actualStudent.getName());"},{"lineNumber":168,"author":{"gitId":"-"},"content":" assertEquals(expectedStudent.getEmail(), actualStudent.getEmail());"},{"lineNumber":169,"author":{"gitId":"-"},"content":" assertEquals(expectedStudent.getRegKey(), actualStudent.getKey());"},{"lineNumber":170,"author":{"gitId":"-"},"content":" assertEquals(expectedStudent.getComments(), actualStudent.getComments());"},{"lineNumber":171,"author":{"gitId":"-"},"content":" // TODO: A student might not have a team or section."},{"lineNumber":172,"author":{"gitId":"-"},"content":" // assertEquals(expectedStudent.getTeamName(), actualStudent.getTeamName());"},{"lineNumber":173,"author":{"gitId":"-"},"content":" // assertEquals(expectedStudent.getSectionName(), actualStudent.getSectionName());"},{"lineNumber":174,"author":{"gitId":"-"},"content":" } else if (expected instanceof UsageStatistics) {"},{"lineNumber":175,"author":{"gitId":"-"},"content":" UsageStatistics expectedUsageStatistics \u003d (UsageStatistics) expected;"},{"lineNumber":176,"author":{"gitId":"-"},"content":" UsageStatisticsData actualUsageStatistics \u003d (UsageStatisticsData) actual;"},{"lineNumber":177,"author":{"gitId":"-"},"content":" assertEquals(expectedUsageStatistics.getStartTime().toEpochMilli(), actualUsageStatistics.getStartTime());"},{"lineNumber":178,"author":{"gitId":"-"},"content":" assertEquals(expectedUsageStatistics.getTimePeriod(), actualUsageStatistics.getTimePeriod());"},{"lineNumber":179,"author":{"gitId":"-"},"content":" assertEquals(expectedUsageStatistics.getNumResponses(), actualUsageStatistics.getNumResponses());"},{"lineNumber":180,"author":{"gitId":"-"},"content":" assertEquals(expectedUsageStatistics.getNumCourses(), actualUsageStatistics.getNumCourses());"},{"lineNumber":181,"author":{"gitId":"-"},"content":" assertEquals(expectedUsageStatistics.getNumStudents(), actualUsageStatistics.getNumStudents());"},{"lineNumber":182,"author":{"gitId":"-"},"content":" assertEquals(expectedUsageStatistics.getNumInstructors(), actualUsageStatistics.getNumInstructors());"},{"lineNumber":183,"author":{"gitId":"-"},"content":" assertEquals(expectedUsageStatistics.getNumAccountRequests(),"},{"lineNumber":184,"author":{"gitId":"-"},"content":" actualUsageStatistics.getNumAccountRequests());"},{"lineNumber":185,"author":{"gitId":"-"},"content":" assertEquals(expectedUsageStatistics.getNumEmails(), actualUsageStatistics.getNumEmails());"},{"lineNumber":186,"author":{"gitId":"-"},"content":" assertEquals(expectedUsageStatistics.getNumSubmissions(), actualUsageStatistics.getNumSubmissions());"},{"lineNumber":187,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" fail(\"Unknown entity\");"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":" }"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":193,"author":{"gitId":"-"},"content":" * Verifies that the given entity is present in the database."},{"lineNumber":194,"author":{"gitId":"-"},"content":" */"},{"lineNumber":195,"author":{"gitId":"-"},"content":" protected void verifyPresentInDatabase(BaseEntity expected) {"},{"lineNumber":196,"author":{"gitId":"-"},"content":" int retryLimit \u003d VERIFICATION_RETRY_COUNT;"},{"lineNumber":197,"author":{"gitId":"-"},"content":" ApiOutput actual \u003d getEntity(expected);"},{"lineNumber":198,"author":{"gitId":"-"},"content":" while (actual \u003d\u003d null \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":199,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":200,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(VERIFICATION_RETRY_DELAY_IN_MS);"},{"lineNumber":201,"author":{"gitId":"-"},"content":" actual \u003d getEntity(expected);"},{"lineNumber":202,"author":{"gitId":"-"},"content":" }"},{"lineNumber":203,"author":{"gitId":"-"},"content":" verifyEquals(expected, actual);"},{"lineNumber":204,"author":{"gitId":"-"},"content":" }"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":207,"author":{"gitId":"-"},"content":" * Verifies that the given entity is absent in the database."},{"lineNumber":208,"author":{"gitId":"-"},"content":" */"},{"lineNumber":209,"author":{"gitId":"-"},"content":" protected void verifyAbsentInDatabase(BaseEntity expected) {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" int retryLimit \u003d VERIFICATION_RETRY_COUNT;"},{"lineNumber":211,"author":{"gitId":"-"},"content":" ApiOutput actual \u003d getEntity(expected);"},{"lineNumber":212,"author":{"gitId":"-"},"content":" while (actual !\u003d null \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":214,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(VERIFICATION_RETRY_DELAY_IN_MS);"},{"lineNumber":215,"author":{"gitId":"-"},"content":" actual \u003d getEntity(expected);"},{"lineNumber":216,"author":{"gitId":"-"},"content":" }"},{"lineNumber":217,"author":{"gitId":"-"},"content":" assertNull(actual);"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" private ApiOutput getEntity(BaseEntity entity) {"},{"lineNumber":221,"author":{"gitId":"-"},"content":" if (entity instanceof Student) {"},{"lineNumber":222,"author":{"gitId":"-"},"content":" return getStudent((Student) entity);"},{"lineNumber":223,"author":{"gitId":"-"},"content":" } else if (entity instanceof FeedbackQuestion) {"},{"lineNumber":224,"author":{"gitId":"-"},"content":" return getFeedbackQuestion((FeedbackQuestion) entity);"},{"lineNumber":225,"author":{"gitId":"-"},"content":" } else if (entity instanceof FeedbackSession) {"},{"lineNumber":226,"author":{"gitId":"-"},"content":" return getFeedbackSession((FeedbackSession) entity);"},{"lineNumber":227,"author":{"gitId":"-"},"content":" } else if (entity instanceof FeedbackResponse) {"},{"lineNumber":228,"author":{"gitId":"-"},"content":" return getFeedbackResponse((FeedbackResponse) entity);"},{"lineNumber":229,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":230,"author":{"gitId":"-"},"content":" throw new RuntimeException(\"Unknown entity type\");"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":" }"},{"lineNumber":233,"author":{"gitId":"-"},"content":""},{"lineNumber":234,"author":{"gitId":"-"},"content":" protected abstract FeedbackQuestionData getFeedbackQuestion(FeedbackQuestion fq);"},{"lineNumber":235,"author":{"gitId":"-"},"content":""},{"lineNumber":236,"author":{"gitId":"-"},"content":" protected abstract FeedbackSessionData getFeedbackSession(FeedbackSession fq);"},{"lineNumber":237,"author":{"gitId":"-"},"content":""},{"lineNumber":238,"author":{"gitId":"-"},"content":" protected abstract FeedbackResponseData getFeedbackResponse(FeedbackResponse fq);"},{"lineNumber":239,"author":{"gitId":"-"},"content":""},{"lineNumber":240,"author":{"gitId":"-"},"content":" protected abstract StudentData getStudent(Student student);"},{"lineNumber":241,"author":{"gitId":"-"},"content":""},{"lineNumber":242,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":10,"-":232}},{"path":"src/test/java/teammates/ui/request/AccountRequestRejectionRequestTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.ui.request;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import org.testng.annotations.Test;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":" * SUT: {@link AccountRequestRejectionRequest}."},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"public class AccountRequestRejectionRequestTest extends BaseTestCase {"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" private static final String TYPICAL_TITLE \u003d \"We are Unable to Create an Account for you\";"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" private static final String TYPICAL_BODY \u003d new StringBuilder()"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003eHi, Example\u003c/p\u003e\\n\")"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003eThanks for your interest in using TEAMMATES. \")"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" .append(\"We are unable to create a TEAMMATES instructor account for you.\u003c/p\u003e\\n\\n\")"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003e\\n\")"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":" .append(\" \u003cstrong\u003eReason:\u003c/strong\u003e The email address you provided \")"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":" .append(\"is not an \u0027official\u0027 email address provided by your institution.\u003cbr /\u003e\\n\")"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" .append(\" \u003cstrong\u003eRemedy:\u003c/strong\u003e \")"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" .append(\"Please re-submit an account request with your \u0027official\u0027 institution email address.\\n\")"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" .append(\"\u003c/p\u003e\\n\\n\")"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003eIf you need further clarification or would like to appeal this decision, \")"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" .append(\"please feel free to contact us at teammates@comp.nus.edu.sg.\u003c/p\u003e\\n\")"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003eRegards,\u003cbr /\u003eTEAMMATES Team.\u003c/p\u003e\\n\")"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" .toString();"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" public void testValidate_withNonNullBodyAndNonNullTitle_shouldPass() throws Exception {"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest request \u003d new AccountRequestRejectionRequest(TYPICAL_TITLE, TYPICAL_BODY);"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" request.validate();"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" public void testValidate_withNullBodyAndNullTitle_shouldPass() throws Exception {"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest request \u003d new AccountRequestRejectionRequest(null, null);"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" request.validate();"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" public void testValidate_withNonNullBodyAndNullTitle_shouldFail() {"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest request \u003d new AccountRequestRejectionRequest(null, TYPICAL_BODY);"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" assertThrows(InvalidHttpRequestBodyException.class, request::validate);"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" public void testValidate_withNullBodyAndNonNullTitle_shouldFail() {"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest request \u003d new AccountRequestRejectionRequest(TYPICAL_TITLE, null);"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" assertThrows(InvalidHttpRequestBodyException.class, request::validate);"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":51}},{"path":"src/test/java/teammates/ui/webapi/CreateFeedbackSessionLogActionTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.output.MessageOutput;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * SUT: {@link CreateFeedbackSessionLogAction}."},{"lineNumber":14,"author":{"gitId":"-"},"content":" */"},{"lineNumber":15,"author":{"gitId":"-"},"content":"public class CreateFeedbackSessionLogActionTest extends BaseActionTest\u003cCreateFeedbackSessionLogAction\u003e {"},{"lineNumber":16,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":17,"author":{"gitId":"-"},"content":" protected String getActionUri() {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" return Const.ResourceURIs.SESSION_LOGS;"},{"lineNumber":19,"author":{"gitId":"-"},"content":" }"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":22,"author":{"gitId":"-"},"content":" protected String getRequestMethod() {"},{"lineNumber":23,"author":{"gitId":"-"},"content":" return POST;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" }"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"-"},"content":" protected void testExecute() {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" CourseAttributes course1 \u003d typicalBundle.courses.get(\"typicalCourse1\");"},{"lineNumber":30,"author":{"gitId":"-"},"content":" String courseId1 \u003d course1.getId();"},{"lineNumber":31,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes fsa1 \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":32,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes fsa2 \u003d typicalBundle.feedbackSessions.get(\"session2InCourse1\");"},{"lineNumber":33,"author":{"gitId":"-"},"content":" StudentAttributes student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":34,"author":{"gitId":"-"},"content":" StudentAttributes student2 \u003d typicalBundle.students.get(\"student2InCourse1\");"},{"lineNumber":35,"author":{"gitId":"-"},"content":" StudentAttributes student3 \u003d typicalBundle.students.get(\"student1InCourse3\");"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: not enough parameters\");"},{"lineNumber":38,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure(Const.ParamsNames.COURSE_ID, courseId1);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure("},{"lineNumber":40,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":41,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fsa1.getFeedbackSessionName()"},{"lineNumber":42,"author":{"gitId":"-"},"content":" );"},{"lineNumber":43,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure("},{"lineNumber":44,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fsa1.getFeedbackSessionName(),"},{"lineNumber":45,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":46,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail()"},{"lineNumber":47,"author":{"gitId":"-"},"content":" );"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: invalid log type\");"},{"lineNumber":50,"author":{"gitId":"-"},"content":" String[] paramsInvalid \u003d {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fsa1.getFeedbackSessionName(),"},{"lineNumber":53,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, \"invalid log type\","},{"lineNumber":54,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":55,"author":{"gitId":"-"},"content":" };"},{"lineNumber":56,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure(paramsInvalid);"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" ______TS(\"Success case: typical access\");"},{"lineNumber":59,"author":{"gitId":"-"},"content":" String[] paramsSuccessfulAccess \u003d {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":61,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fsa1.getFeedbackSessionName(),"},{"lineNumber":62,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":63,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":64,"author":{"gitId":"-"},"content":" };"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" JsonResult response \u003d getJsonResult(getAction(paramsSuccessfulAccess));"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" MessageOutput output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" ______TS(\"Success case: typical submission\");"},{"lineNumber":70,"author":{"gitId":"-"},"content":" String[] paramsSuccessfulSubmission \u003d {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fsa2.getFeedbackSessionName(),"},{"lineNumber":73,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":74,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, student2.getEmail(),"},{"lineNumber":75,"author":{"gitId":"-"},"content":" };"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" response \u003d getJsonResult(getAction(paramsSuccessfulSubmission));"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" ______TS(\"Success case: should create even for invalid parameters\");"},{"lineNumber":81,"author":{"gitId":"-"},"content":" String[] paramsNonExistentFsName \u003d {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":83,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, \"non-existent-feedback-session-name\","},{"lineNumber":84,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":85,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":86,"author":{"gitId":"-"},"content":" };"},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" response \u003d getJsonResult(getAction(paramsNonExistentFsName));"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" String[] paramsNonExistentStudentEmail \u003d {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":93,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fsa1.getFeedbackSessionName(),"},{"lineNumber":94,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":95,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, \"non-existent-student@email.com\","},{"lineNumber":96,"author":{"gitId":"-"},"content":" };"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" response \u003d getJsonResult(getAction(paramsNonExistentStudentEmail));"},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" ______TS(\"Success case: should create even when student cannot access feedback session in course\");"},{"lineNumber":102,"author":{"gitId":"-"},"content":" String[] paramsWithoutAccess \u003d {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":104,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fsa1.getFeedbackSessionName(),"},{"lineNumber":105,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":106,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, student3.getEmail(),"},{"lineNumber":107,"author":{"gitId":"-"},"content":" };"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" response \u003d getJsonResult(getAction(paramsWithoutAccess));"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":" output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":114,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":115,"author":{"gitId":"-"},"content":" protected void testAccessControl() {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" verifyAnyUserCanAccess();"},{"lineNumber":117,"author":{"gitId":"-"},"content":" }"},{"lineNumber":118,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":16,"-":102}},{"path":"src/test/java/teammates/ui/webapi/GetActionClassesActionTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.Arrays;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Collections;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.ui.output.ActionClasses;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"-"},"content":" * SUT: {@link GetActionClassesAction}."},{"lineNumber":15,"author":{"gitId":"-"},"content":" */"},{"lineNumber":16,"author":{"gitId":"-"},"content":"public class GetActionClassesActionTest extends BaseActionTest\u003cGetActionClassesAction\u003e {"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":19,"author":{"gitId":"-"},"content":" protected String getActionUri() {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" return Const.ResourceURIs.ACTION_CLASS;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" }"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":24,"author":{"gitId":"-"},"content":" protected String getRequestMethod() {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" return GET;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" }"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":29,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":30,"author":{"gitId":"-"},"content":" protected void testExecute() {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" List\u003cClass\u003c? extends Action\u003e\u003e expectedActionClasses \u003d Arrays.asList("},{"lineNumber":32,"author":{"gitId":"-"},"content":" DeleteFeedbackResponseCommentAction.class,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" CreateFeedbackResponseCommentAction.class,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" GetFeedbackResponseCommentAction.class,"},{"lineNumber":35,"author":{"gitId":"-"},"content":" UpdateFeedbackResponseCommentAction.class,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" RestoreFeedbackSessionAction.class,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" BinFeedbackSessionAction.class,"},{"lineNumber":38,"author":{"gitId":"-"},"content":" GetCoursesAction.class,"},{"lineNumber":39,"author":{"gitId":"-"},"content":" GetRegkeyValidityAction.class,"},{"lineNumber":40,"author":{"gitId":"-"},"content":" PutDataBundleAction.class,"},{"lineNumber":41,"author":{"gitId":"-"},"content":" DeleteDataBundleAction.class,"},{"lineNumber":42,"author":{"gitId":"-"},"content":" CreateFeedbackSessionLogAction.class,"},{"lineNumber":43,"author":{"gitId":"-"},"content":" GetFeedbackSessionLogsAction.class,"},{"lineNumber":44,"author":{"gitId":"-"},"content":" GetInstructorPrivilegeAction.class,"},{"lineNumber":45,"author":{"gitId":"-"},"content":" UpdateInstructorPrivilegeAction.class,"},{"lineNumber":46,"author":{"gitId":"-"},"content":" GetFeedbackSessionsAction.class,"},{"lineNumber":47,"author":{"gitId":"-"},"content":" GenerateEmailAction.class,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" GetFeedbackQuestionsAction.class,"},{"lineNumber":49,"author":{"gitId":"-"},"content":" GetOngoingSessionsAction.class,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" AdminExceptionTestAction.class,"},{"lineNumber":51,"author":{"gitId":"-"},"content":" GetUserCookieAction.class,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" RemindFeedbackSessionResultAction.class,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" DeleteInstructorAction.class,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" CreateInstructorAction.class,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" GetInstructorAction.class,"},{"lineNumber":56,"author":{"gitId":"-"},"content":" UpdateInstructorAction.class,"},{"lineNumber":57,"author":{"gitId":"-"},"content":" ArchiveCourseAction.class,"},{"lineNumber":58,"author":{"gitId":"-"},"content":" InstructorCourseJoinEmailWorkerAction.class,"},{"lineNumber":59,"author":{"gitId":"-"},"content":" DeleteStudentAction.class,"},{"lineNumber":60,"author":{"gitId":"-"},"content":" GetStudentAction.class,"},{"lineNumber":61,"author":{"gitId":"-"},"content":" UpdateStudentAction.class,"},{"lineNumber":62,"author":{"gitId":"-"},"content":" SearchStudentsAction.class,"},{"lineNumber":63,"author":{"gitId":"-"},"content":" FeedbackSessionRemindEmailWorkerAction.class,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" DeleteFeedbackSessionAction.class,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" CreateFeedbackSessionAction.class,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" GetFeedbackSessionAction.class,"},{"lineNumber":67,"author":{"gitId":"-"},"content":" UpdateFeedbackSessionAction.class,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" FeedbackSessionClosingRemindersAction.class,"},{"lineNumber":69,"author":{"gitId":"-"},"content":" GetTimeZonesAction.class,"},{"lineNumber":70,"author":{"gitId":"-"},"content":" FeedbackSessionRemindParticularUsersEmailWorkerAction.class,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" GetFeedbackResponsesAction.class,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" SubmitFeedbackResponsesAction.class,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" FeedbackSessionPublishedEmailWorkerAction.class,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" FeedbackSessionClosedRemindersAction.class,"},{"lineNumber":75,"author":{"gitId":"-"},"content":" SendErrorReportAction.class,"},{"lineNumber":76,"author":{"gitId":"-"},"content":" GetActionClassesAction.class,"},{"lineNumber":77,"author":{"gitId":"-"},"content":" UnpublishFeedbackSessionAction.class,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" PublishFeedbackSessionAction.class,"},{"lineNumber":79,"author":{"gitId":"-"},"content":" GetSessionResultsAction.class,"},{"lineNumber":80,"author":{"gitId":"-"},"content":" GetHasResponsesAction.class,"},{"lineNumber":81,"author":{"gitId":"-"},"content":" DatastoreBackupAction.class,"},{"lineNumber":82,"author":{"gitId":"-"},"content":" RestoreCourseAction.class,"},{"lineNumber":83,"author":{"gitId":"-"},"content":" BinCourseAction.class,"},{"lineNumber":84,"author":{"gitId":"-"},"content":" DeleteAccountAction.class,"},{"lineNumber":85,"author":{"gitId":"-"},"content":" CreateAccountAction.class,"},{"lineNumber":86,"author":{"gitId":"-"},"content":" CreateAccountRequestAction.class,"},{"lineNumber":87,"author":{"gitId":"-"},"content":" GetAccountRequestAction.class,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" DeleteAccountRequestAction.class,"},{"lineNumber":89,"author":{"gitId":"-"},"content":" GetAccountRequestsAction.class,"},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" UpdateAccountRequestAction.class,"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":" RejectAccountRequestAction.class,"},{"lineNumber":92,"author":{"gitId":"-"},"content":" GetAccountAction.class,"},{"lineNumber":93,"author":{"gitId":"-"},"content":" GetAccountsAction.class,"},{"lineNumber":94,"author":{"gitId":"-"},"content":" FeedbackSessionPublishedRemindersAction.class,"},{"lineNumber":95,"author":{"gitId":"-"},"content":" QueryLogsAction.class,"},{"lineNumber":96,"author":{"gitId":"-"},"content":" SessionLinksRecoveryAction.class,"},{"lineNumber":97,"author":{"gitId":"-"},"content":" SendJoinReminderEmailAction.class,"},{"lineNumber":98,"author":{"gitId":"-"},"content":" RegenerateInstructorKeyAction.class,"},{"lineNumber":99,"author":{"gitId":"-"},"content":" RegenerateStudentKeyAction.class,"},{"lineNumber":100,"author":{"gitId":"-"},"content":" CompileLogsAction.class,"},{"lineNumber":101,"author":{"gitId":"-"},"content":" GetAuthInfoAction.class,"},{"lineNumber":102,"author":{"gitId":"-"},"content":" GetFeedbackSessionSubmittedGiverSetAction.class,"},{"lineNumber":103,"author":{"gitId":"-"},"content":" GetCourseJoinStatusAction.class,"},{"lineNumber":104,"author":{"gitId":"-"},"content":" JoinCourseAction.class,"},{"lineNumber":105,"author":{"gitId":"-"},"content":" GetSessionResponseStatsAction.class,"},{"lineNumber":106,"author":{"gitId":"-"},"content":" DeleteCourseAction.class,"},{"lineNumber":107,"author":{"gitId":"-"},"content":" CreateCourseAction.class,"},{"lineNumber":108,"author":{"gitId":"-"},"content":" GetCourseAction.class,"},{"lineNumber":109,"author":{"gitId":"-"},"content":" UpdateCourseAction.class,"},{"lineNumber":110,"author":{"gitId":"-"},"content":" GetFeedbackQuestionRecipientsAction.class,"},{"lineNumber":111,"author":{"gitId":"-"},"content":" RemindFeedbackSessionSubmissionAction.class,"},{"lineNumber":112,"author":{"gitId":"-"},"content":" FeedbackSessionUnpublishedEmailWorkerAction.class,"},{"lineNumber":113,"author":{"gitId":"-"},"content":" SendEmailWorkerAction.class,"},{"lineNumber":114,"author":{"gitId":"-"},"content":" GetInstructorsAction.class,"},{"lineNumber":115,"author":{"gitId":"-"},"content":" PutDataBundleDocumentsAction.class,"},{"lineNumber":116,"author":{"gitId":"-"},"content":" FeedbackSessionResendPublishedEmailWorkerAction.class,"},{"lineNumber":117,"author":{"gitId":"-"},"content":" StudentCourseJoinEmailWorkerAction.class,"},{"lineNumber":118,"author":{"gitId":"-"},"content":" SearchInstructorsAction.class,"},{"lineNumber":119,"author":{"gitId":"-"},"content":" GetCourseSectionNamesAction.class,"},{"lineNumber":120,"author":{"gitId":"-"},"content":" ResetAccountAction.class,"},{"lineNumber":121,"author":{"gitId":"-"},"content":" FeedbackSessionOpeningRemindersAction.class,"},{"lineNumber":122,"author":{"gitId":"-"},"content":" FeedbackSessionOpeningSoonRemindersAction.class,"},{"lineNumber":123,"author":{"gitId":"-"},"content":" DeleteStudentsAction.class,"},{"lineNumber":124,"author":{"gitId":"-"},"content":" GetStudentsAction.class,"},{"lineNumber":125,"author":{"gitId":"-"},"content":" EnrollStudentsAction.class,"},{"lineNumber":126,"author":{"gitId":"-"},"content":" DeleteFeedbackQuestionAction.class,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" CreateFeedbackQuestionAction.class,"},{"lineNumber":128,"author":{"gitId":"-"},"content":" UpdateFeedbackQuestionAction.class,"},{"lineNumber":129,"author":{"gitId":"-"},"content":" InstructorSearchIndexingWorkerAction.class,"},{"lineNumber":130,"author":{"gitId":"-"},"content":" StudentSearchIndexingWorkerAction.class,"},{"lineNumber":131,"author":{"gitId":"-"},"content":" AccountRequestSearchIndexingWorkerAction.class,"},{"lineNumber":132,"author":{"gitId":"-"},"content":" SearchAccountRequestsAction.class,"},{"lineNumber":133,"author":{"gitId":"-"},"content":" ResetAccountRequestAction.class,"},{"lineNumber":134,"author":{"gitId":"-"},"content":" CalculateUsageStatisticsAction.class,"},{"lineNumber":135,"author":{"gitId":"-"},"content":" GetUsageStatisticsAction.class,"},{"lineNumber":136,"author":{"gitId":"-"},"content":" GetNotificationAction.class,"},{"lineNumber":137,"author":{"gitId":"-"},"content":" CreateNotificationAction.class,"},{"lineNumber":138,"author":{"gitId":"-"},"content":" UpdateNotificationAction.class,"},{"lineNumber":139,"author":{"gitId":"-"},"content":" DeleteNotificationAction.class,"},{"lineNumber":140,"author":{"gitId":"-"},"content":" GetNotificationsAction.class,"},{"lineNumber":141,"author":{"gitId":"-"},"content":" MarkNotificationAsReadAction.class,"},{"lineNumber":142,"author":{"gitId":"-"},"content":" GetReadNotificationsAction.class,"},{"lineNumber":143,"author":{"gitId":"-"},"content":" GetDeadlineExtensionAction.class,"},{"lineNumber":144,"author":{"gitId":"-"},"content":" SendLoginEmailAction.class,"},{"lineNumber":145,"author":{"gitId":"-"},"content":" PutSqlDataBundleAction.class,"},{"lineNumber":146,"author":{"gitId":"dishenggg"},"content":" DeleteSqlDataBundleAction.class,"},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":" UpdateFeedbackSessionLogsAction.class"},{"lineNumber":148,"author":{"gitId":"-"},"content":" );"},{"lineNumber":149,"author":{"gitId":"-"},"content":" List\u003cString\u003e expectedActionClassesNames \u003d expectedActionClasses.stream()"},{"lineNumber":150,"author":{"gitId":"-"},"content":" .map(Class::getSimpleName)"},{"lineNumber":151,"author":{"gitId":"-"},"content":" .sorted()"},{"lineNumber":152,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"-"},"content":" GetActionClassesAction action \u003d getAction();"},{"lineNumber":155,"author":{"gitId":"-"},"content":" action.execute();"},{"lineNumber":156,"author":{"gitId":"-"},"content":" JsonResult result \u003d getJsonResult(action);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" ActionClasses data \u003d (ActionClasses) result.getOutput();"},{"lineNumber":158,"author":{"gitId":"-"},"content":" List\u003cString\u003e actualActionClasses \u003d data.getActionClasses();"},{"lineNumber":159,"author":{"gitId":"-"},"content":" Collections.sort(actualActionClasses);"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" assertEquals(expectedActionClassesNames, actualActionClasses);"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":165,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":166,"author":{"gitId":"-"},"content":" protected void testAccessControl() {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" verifyAccessibleForAdmin();"},{"lineNumber":168,"author":{"gitId":"-"},"content":" verifyAccessibleForMaintainers();"},{"lineNumber":169,"author":{"gitId":"-"},"content":" verifyInaccessibleForStudents();"},{"lineNumber":170,"author":{"gitId":"-"},"content":" verifyInaccessibleForInstructors();"},{"lineNumber":171,"author":{"gitId":"-"},"content":" verifyInaccessibleWithoutLogin();"},{"lineNumber":172,"author":{"gitId":"-"},"content":" verifyInaccessibleForUnregisteredUsers();"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":1,"xenosf":1,"dishenggg":2,"-":171}},{"path":"src/test/java/teammates/ui/webapi/GetFeedbackSessionLogsActionTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionLogData;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionLogEntryData;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionLogsData;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * SUT: {@link GetFeedbackSessionLogsAction}."},{"lineNumber":20,"author":{"gitId":"-"},"content":" */"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public class GetFeedbackSessionLogsActionTest extends BaseActionTest\u003cGetFeedbackSessionLogsAction\u003e {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":23,"author":{"gitId":"-"},"content":" protected String getActionUri() {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" return Const.ResourceURIs.SESSION_LOGS;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"-"},"content":" protected String getRequestMethod() {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" return GET;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":33,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":34,"author":{"gitId":"-"},"content":" protected void testExecute() {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" JsonResult actionOutput;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" CourseAttributes course \u003d typicalBundle.courses.get(\"typicalCourse1\");"},{"lineNumber":38,"author":{"gitId":"-"},"content":" String courseId \u003d course.getId();"},{"lineNumber":39,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes fsa1 \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":40,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes fsa2 \u003d typicalBundle.feedbackSessions.get(\"session2InCourse1\");"},{"lineNumber":41,"author":{"gitId":"-"},"content":" String fsa1Name \u003d fsa1.getFeedbackSessionName();"},{"lineNumber":42,"author":{"gitId":"-"},"content":" String fsa2Name \u003d fsa2.getFeedbackSessionName();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" StudentAttributes student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":44,"author":{"gitId":"-"},"content":" StudentAttributes student2 \u003d typicalBundle.students.get(\"student2InCourse1\");"},{"lineNumber":45,"author":{"gitId":"-"},"content":" String student1Email \u003d student1.getEmail();"},{"lineNumber":46,"author":{"gitId":"-"},"content":" String student2Email \u003d student2.getEmail();"},{"lineNumber":47,"author":{"gitId":"-"},"content":" long endTime \u003d Instant.now().toEpochMilli();"},{"lineNumber":48,"author":{"gitId":"-"},"content":" long startTime \u003d endTime - (Const.LOGS_RETENTION_PERIOD.toDays() - 1) * 24 * 60 * 60 * 1000;"},{"lineNumber":49,"author":{"gitId":"-"},"content":" long invalidStartTime \u003d endTime - (Const.LOGS_RETENTION_PERIOD.toDays() + 1) * 24 * 60 * 60 * 1000;"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(courseId, student1Email, fsa1Name,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime);"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(courseId, student1Email, fsa2Name,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime + 1000);"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(courseId, student1Email, fsa2Name,"},{"lineNumber":56,"author":{"gitId":"-"},"content":" FeedbackSessionLogType.SUBMISSION.getLabel(), startTime + 2000);"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(courseId, student2Email, fsa1Name,"},{"lineNumber":58,"author":{"gitId":"-"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime + 3000);"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(courseId, student2Email, fsa1Name,"},{"lineNumber":60,"author":{"gitId":"-"},"content":" FeedbackSessionLogType.SUBMISSION.getLabel(), startTime + 4000);"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: not enough parameters\");"},{"lineNumber":63,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure("},{"lineNumber":64,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId"},{"lineNumber":65,"author":{"gitId":"-"},"content":" );"},{"lineNumber":66,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure("},{"lineNumber":67,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime)"},{"lineNumber":69,"author":{"gitId":"-"},"content":" );"},{"lineNumber":70,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure("},{"lineNumber":71,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":72,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime)"},{"lineNumber":73,"author":{"gitId":"-"},"content":" );"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: invalid course id\");"},{"lineNumber":76,"author":{"gitId":"-"},"content":" String[] paramsInvalid1 \u003d {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, \"fake-course-id\","},{"lineNumber":78,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1Email,"},{"lineNumber":79,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":80,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":81,"author":{"gitId":"-"},"content":" };"},{"lineNumber":82,"author":{"gitId":"-"},"content":" verifyEntityNotFound(paramsInvalid1);"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: invalid student email\");"},{"lineNumber":85,"author":{"gitId":"-"},"content":" String[] paramsInvalid2 \u003d {"},{"lineNumber":86,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":87,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, \"fake-student-email@gmail.com\","},{"lineNumber":88,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":89,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":90,"author":{"gitId":"-"},"content":" };"},{"lineNumber":91,"author":{"gitId":"-"},"content":" verifyEntityNotFound(paramsInvalid2);"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: invalid start or end times\");"},{"lineNumber":94,"author":{"gitId":"-"},"content":" String[] paramsInvalid3 \u003d {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":96,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, \"abc\","},{"lineNumber":97,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":98,"author":{"gitId":"-"},"content":" };"},{"lineNumber":99,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure(paramsInvalid3);"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" String[] paramsInvalid4 \u003d {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":103,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":104,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, \" \","},{"lineNumber":105,"author":{"gitId":"-"},"content":" };"},{"lineNumber":106,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure(paramsInvalid4);"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: start time is before earliest search time\");"},{"lineNumber":109,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure("},{"lineNumber":110,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":111,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(invalidStartTime),"},{"lineNumber":112,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime)"},{"lineNumber":113,"author":{"gitId":"-"},"content":" );"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" ______TS(\"Success case: should group by feedback session\");"},{"lineNumber":116,"author":{"gitId":"-"},"content":" String[] paramsSuccessful1 \u003d {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":118,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":119,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":120,"author":{"gitId":"-"},"content":" };"},{"lineNumber":121,"author":{"gitId":"-"},"content":" actionOutput \u003d getJsonResult(getAction(paramsSuccessful1));"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" // The filtering by the logs processor cannot be tested directly, assume that it filters correctly"},{"lineNumber":124,"author":{"gitId":"-"},"content":" // Here, it simply returns all log entries"},{"lineNumber":125,"author":{"gitId":"-"},"content":" FeedbackSessionLogsData fslData \u003d (FeedbackSessionLogsData) actionOutput.getOutput();"},{"lineNumber":126,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogData\u003e fsLogs \u003d fslData.getFeedbackSessionLogs();"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" // Course has 6 feedback sessions, last 4 of which have no log entries"},{"lineNumber":129,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.size(), 6);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.get(2).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.get(3).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.get(4).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.get(5).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogEntryData\u003e fsLogEntries1 \u003d fsLogs.get(0).getFeedbackSessionLogEntries();"},{"lineNumber":136,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogEntryData\u003e fsLogEntries2 \u003d fsLogs.get(1).getFeedbackSessionLogEntries();"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.size(), 3);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(0).getStudentData().getEmail(), student1Email);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":141,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(1).getStudentData().getEmail(), student2Email);"},{"lineNumber":142,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(2).getStudentData().getEmail(), student2Email);"},{"lineNumber":144,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(2).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.size(), 2);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.get(0).getStudentData().getEmail(), student1Email);"},{"lineNumber":148,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.get(1).getStudentData().getEmail(), student1Email);"},{"lineNumber":150,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" ______TS(\"Success case: should accept optional email\");"},{"lineNumber":153,"author":{"gitId":"-"},"content":" String[] paramsSuccessful2 \u003d {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":155,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1Email,"},{"lineNumber":156,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":157,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":158,"author":{"gitId":"-"},"content":" };"},{"lineNumber":159,"author":{"gitId":"-"},"content":" getJsonResult(getAction(paramsSuccessful2));"},{"lineNumber":160,"author":{"gitId":"-"},"content":" // No need to check output again here, it will be exactly the same as the previous case"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"-"},"content":" // TODO: if we restrict the range from start to end time, it should be tested here as well"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":166,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":167,"author":{"gitId":"-"},"content":" protected void testAccessControl() {"},{"lineNumber":168,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d typicalBundle.instructors.get(\"instructor2OfCourse1\");"},{"lineNumber":169,"author":{"gitId":"-"},"content":" InstructorAttributes helper \u003d typicalBundle.instructors.get(\"helperOfCourse1\");"},{"lineNumber":170,"author":{"gitId":"-"},"content":" String courseId \u003d instructor.getCourseId();"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" ______TS(\"Only instructors of the same course can access\");"},{"lineNumber":173,"author":{"gitId":"-"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":175,"author":{"gitId":"-"},"content":" };"},{"lineNumber":176,"author":{"gitId":"-"},"content":" verifyOnlyInstructorsOfTheSameCourseCanAccess(submissionParams);"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" ______TS(\"Only instructors with modify student, session and instructor privilege can access\");"},{"lineNumber":179,"author":{"gitId":"-"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":181,"author":{"gitId":"-"},"content":" };"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":184,"author":{"gitId":"-"},"content":""},{"lineNumber":185,"author":{"gitId":"-"},"content":" loginAsInstructor(helper.getGoogleId());"},{"lineNumber":186,"author":{"gitId":"-"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":187,"author":{"gitId":"-"},"content":""},{"lineNumber":188,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":189,"author":{"gitId":"-"},"content":" verifyCanAccess(submissionParams);"},{"lineNumber":190,"author":{"gitId":"-"},"content":" }"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":5,"-":187}},{"path":"src/test/resources/emails/instructorNewAccountRequestAcknowledgementEmailWithComments.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"\u003cp\u003eHello, Darth Vader\u003c/p\u003e"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":" Thank you for submitting an account request. This is what you have submitted:"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"\u003cdiv\u003e"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":" \u003ctable style\u003d\"max-width:600px;border:1px solid black;\"\u003e"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" Full Name"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" Darth Vader"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" Country \u0026 Institute"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" Sith Order"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" Email Address"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" darth-vader@sith.org"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" Comments"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" I Am Your Father"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" \u003c/table\u003e"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":"\u003c/div\u003e"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" Your request will be reviewed within 24 hours. We will send another email once your request has been accepted."},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" If you have any additional queries, please feel free to contact us at ${support.email}."},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" Regards,\u003cbr\u003e"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" TEAMMATES Team."},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"}],"authorContributionMap":{"xenosf":65}},{"path":"src/test/resources/emails/instructorNewAccountRequestAcknowledgementEmailWithNoComments.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"\u003cp\u003eHello, Maul\u003c/p\u003e"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":" Thank you for submitting an account request. This is what you have submitted:"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"\u003cdiv\u003e"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":" \u003ctable style\u003d\"max-width:600px;border:1px solid black;\"\u003e"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" Full Name"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" Maul"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" Country \u0026 Institute"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" Sith Order"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" Email Address"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" maul@sith.org"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" Comments"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" "},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" \u003c/table\u003e"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":"\u003c/div\u003e"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" Your request will be reviewed within 24 hours. We will send another email once your request has been accepted."},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" If you have any additional queries, please feel free to contact us at ${support.email}."},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" Regards,\u003cbr\u003e"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" TEAMMATES Team."},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"}],"authorContributionMap":{"xenosf":65}},{"path":"src/web/app/components/account-requests-table/account-request-table-model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"import { AccountRequestStatus } from \u0027src/web/types/api-output\u0027;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":" * Model for the row entries in the account requests table."},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"export interface AccountRequestTableRowModel {"},{"lineNumber":7,"author":{"gitId":"-"},"content":" id: string;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" name: string;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":" email: string;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" instituteAndCountry: string;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":" createdAtText: string;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":" registeredAtText: string;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":" comments: string;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" registrationLink: string;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" showLinks: boolean;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":16,"-":1}},{"path":"src/web/app/components/account-requests-table/account-request-table.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"\u003cdiv class\u003d\"card bg-light top-padded\" *ngIf\u003d\"accountRequests.length\"\u003e"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"card-header bg-primary text-white\"\u003e"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":" \u003cdiv *ngIf\u003d\"searchString; else pendingRequests\"\u003e"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003eAccount Requests Found\u003c/strong\u003e"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":" \u003cng-template #pendingRequests\u003e"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003ePending Account Requests\u003c/strong\u003e"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" \u003c/ng-template\u003e"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":" \u003cdiv *ngIf\u003d\"searchString\" class\u003d\"card-header-btn-toolbar\"\u003e"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"show-account-request-links\" class\u003d\"btn btn-light btn-sm\" style\u003d\"margin-right: 10px;\" type\u003d\"button\" (click)\u003d\"showAllAccountRequestsLinks()\"\u003eExpand All\u003c/button\u003e"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"hide-account-request-links\" class\u003d\"btn btn-light btn-sm\" type\u003d\"button\" (click)\u003d\"hideAllAccountRequestsLinks()\"\u003eCollapse All\u003c/button\u003e"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"\u003cdiv class\u003d\"table-responsive\"\u003e"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" \u003ctable class\u003d\"table table-striped data-table\" id\u003d\"search-table-account-request\"\u003e"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" \u003cthead\u003e"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" \u003ctr\u003e"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" \u003cth\u003eName\u003c/th\u003e"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" \u003cth\u003eEmail\u003c/th\u003e"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" \u003cth\u003eStatus\u003c/th\u003e"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" \u003cth\u003eInstitute, Country\u003c/th\u003e"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" \u003cth\u003eCreated At\u003c/th\u003e"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" \u003cth *ngIf\u003d\"searchString\"\u003eRegistered At\u003c/th\u003e"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" \u003cth\u003eComments\u003c/th\u003e"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" \u003cth\u003eOptions\u003c/th\u003e"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" \u003c/tr\u003e"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" \u003c/thead\u003e"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" \u003ctbody\u003e"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" \u003cng-container *ngFor\u003d\"let accountRequest of accountRequests; let i \u003d index; trackBy: trackAccountRequest\"\u003e"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" \u003ctr\u003e"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" \u003ctd [innerHtml]\u003d\"accountRequest.name | highlighter:searchString:true\"\u003e"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" \u003cbr\u003e"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"col-sm-1\"\u003e"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" \u003cbutton *ngIf\u003d\"!accountRequest.showLinks\" class\u003d\"btn\" aria-label\u003d\"Expand\"\u003e"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" \u003ci class\u003d\"fas fa-chevron-circle-down\" style\u003d\"color: blue;\"\u003e\u003c/i\u003e"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" \u003c/button\u003e"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" \u003cbutton *ngIf\u003d\"accountRequest.showLinks\" class\u003d\"btn\" aria-label\u003d\"Collapse\"\u003e"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" \u003ci class\u003d\"fas fa-chevron-circle-up\" style\u003d\"color: blue;\"\u003e\u003c/i\u003e"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" \u003c/button\u003e"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" \u003c/td\u003e"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" \u003ctd [innerHtml]\u003d\"accountRequest.email | highlighter:searchString:true\"\u003e{{ accountRequest.email }}\u003c/td\u003e"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" \u003ctd [innerHtml]\u003d\"accountRequest.status | highlighter:searchString:true\"\u003e{{ accountRequest.status }}\u003c/td\u003e"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" \u003ctd [innerHtml]\u003d\"accountRequest.instituteAndCountry | highlighter:searchString:true\"\u003e{{ accountRequest.instituteAndCountry }}\u003c/td\u003e"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" \u003ctd id\u003d\"timestamp-box\"\u003e{{ accountRequest.createdAtText }}\u003c/td\u003e"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" \u003ctd *ngIf\u003d\"searchString\" id\u003d\"timestamp-box\"\u003e{{ accountRequest.registeredAtText || \u0027Not Registered Yet\u0027 }}\u003c/td\u003e"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" \u003ctd\u003e"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" \u003cdiv id\u003d\"comment-box\" [innerHtml]\u003d\"accountRequest.comments | highlighter:searchString:true\"\u003e"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" {{ accountRequest.comments }}"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" \u003c/td\u003e"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" \u003ctd class\u003d\"align-middle\"\u003e"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"d-flex flex-row align-items-center justify-content-center gap-2\"\u003e"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003e"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" \u003ca id\u003d\"edit-account-request-{{i}}\" href\u003d\"javascript:;\" (click)\u003d\"$event.stopPropagation(); editAccountRequest(accountRequest);\"\u003e"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" \u003ci class\u003d\"fa-solid fa-pen\"\u003e\u003c/i\u003e"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" \u003c/a\u003e"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"ngb-tooltip-class\" [ngbTooltip]\u003d\"accountRequest.registeredAtText \u0026\u0026 \u0027Account requests of registered instructors cannot be deleted\u0027\" placement\u003d\"top\"\u003e"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" \u003ca id\u003d\"delete-account-request-{{i}}\" href\u003d\"javascript:;\" (click)\u003d\"$event.stopPropagation(); deleteAccountRequest(accountRequest)\"\u003e"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" \u003ci class\u003d\"fa-solid fa-trash\"\u003e\u003c/i\u003e"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" \u003c/a\u003e"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003e"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" \u003ca id\u003d\"view-account-request-{{i}}\" href\u003d\"javascript:;\" (click)\u003d\"$event.stopPropagation(); viewAccountRequest(accountRequest)\"\u003e"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":" \u003ci class\u003d\"fa-solid fa-eye\"\u003e\u003c/i\u003e"},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" \u003c/a\u003e"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"approve-account-request-{{i}}\" class\u003d\"btn btn-success\" [disabled]\u003d\"!accountRequest.status || accountRequest.status \u003d\u003d\u003d \u0027APPROVED\u0027 || accountRequest.status \u003d\u003d\u003d \u0027REGISTERED\u0027\" (click)\u003d\"$event.stopPropagation(); approveAccountRequest(accountRequest)\"\u003eApprove\u003c/button\u003e"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" \u003cspan ngbDropdown container\u003d\"body\"\u003e"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"reject-account-request-{{i}}\" type\u003d\"button\" class\u003d\"btn btn-warning\" [disabled]\u003d\"!accountRequest.status || accountRequest.status \u003d\u003d\u003d \u0027REGISTERED\u0027 || accountRequest.status \u003d\u003d\u003d \u0027APPROVED\u0027 || accountRequest.status \u003d\u003d\u003d \u0027REJECTED\u0027\" ngbDropdownToggle\u003e Reject \u003c/button\u003e"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" \u003cdiv ngbDropdownMenu (click)\u003d\"$event.stopPropagation()\"\u003e"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"reject-request-{{i}}\" class\u003d\"btn btn-light btn-sm dropdown-item\" (click)\u003d\"$event.stopPropagation(); rejectAccountRequest(accountRequest)\"\u003e Reject \u003c/button\u003e"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"reject-request-with-reason-{{i}}\" class\u003d\"btn btn-light btn-sm dropdown-item\" (click)\u003d\"$event.stopPropagation(); rejectAccountRequestWithReason(accountRequest)\"\u003e Reject With Reason \u003c/button\u003e"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" \u003c/span\u003e"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" \u003cdiv *ngIf\u003d\"searchString\" class\u003d\"ngb-tooltip-class\" [ngbTooltip]\u003d\"accountRequest.registeredAtText \u0026\u0026 \u0027Account requests of registered instructors cannot be deleted\u0027\" placement\u003d\"top\"\u003e"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"reset-account-request-{{i}}\" class\u003d\"btn btn-primary\" [disabled]\u003d\"!accountRequest.registeredAtText\" (click)\u003d\"$event.stopPropagation(); resetAccountRequest(accountRequest);\"\u003eReset\u003c/button\u003e"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" \u003c/td\u003e"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" \u003c/tr\u003e"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" \u003ctr *ngIf\u003d\"accountRequest.showLinks \u0026\u0026 searchString\"\u003e"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" \u003ctd colspan\u003d\"100\"\u003e"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" \u003cul class\u003d\"list-group\" *ngIf\u003d\"accountRequest.showLinks\" @collapseAnim\u003e"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":" \u003cli class\u003d\"list-group-item list-group-item-info\"\u003e"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003eAccount Registration Link\u003c/strong\u003e"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" \u003cinput [value]\u003d\"accountRequest.registrationLink\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" \u003c/li\u003e"},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" \u003c/ul\u003e"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" \u003c/td\u003e"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" \u003c/tr\u003e"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":" \u003c/ng-container\u003e"},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":" \u003c/tbody\u003e"},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" \u003c/table\u003e"},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"}],"authorContributionMap":{"domoberzin":96}},{"path":"src/web/app/components/account-requests-table/account-request-table.component.scss","fileType":"scss","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"::ng-deep .highlighted-text {"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":" background-color: yellow;"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"}"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"/* stylelint-disable declaration-block-no-redundant-longhand-properties */"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":".table-responsive {"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":" overflow-y: visible;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" overflow-x: -moz-scrollbars-horizontal; "},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"}"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":".table-responsive \u003e table \u003e thead \u003e tr \u003e th {"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":" white-space: nowrap;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"}"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"/* stylelint-disable property-no-vendor-prefix */"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"::-webkit-scrollbar {"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" -webkit-appearance: none;"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" width: 1px;"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":"}"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":"::-webkit-scrollbar-thumb {"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" border-radius: 0;"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" background-color: rgb(0 0 0 / 50%);"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" box-shadow: 0 0 1px rgb(255 255 255 / 50%);"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":"}"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":"#search-table-account-request {"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" border-collapse: collapse;"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":"}"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":"#search-table-account-request th:last-child, "},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":"#search-table-account-request td:last-child {"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" min-width: 10vw;"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" position: sticky;"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" right: 0;"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" z-index: 1;"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" background-color: #F8F9FA;"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":"}"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":"#search-table-account-request th:last-child::after,"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":"#search-table-account-request td:last-child::after {"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" content: \"\";"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" position: absolute;"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" left: -1px;"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" top: 0;"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" bottom: 0;"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" width: 1px;"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" background: #c8c7c7;"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" z-index: 1;"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":"}"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":"#comment-box {"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" min-height: 5vh;"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" width: max(800px, 35vw);"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" max-width: max-content;"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" word-break: break-word;"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" word-wrap: break-all;"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":"}"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":".dropdown-item {"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" border: none;"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":65}},{"path":"src/web/app/components/account-requests-table/account-request-table.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"import { HttpClientTestingModule } from \u0027@angular/common/http/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":"import { ComponentFixture, TestBed, waitForAsync } from \u0027@angular/core/testing\u0027;"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import { BrowserAnimationsModule } from \u0027@angular/platform-browser/animations\u0027;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import { NgbModal } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import { of, throwError } from \u0027rxjs\u0027;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import { AccountRequestTableRowModel } from \u0027./account-request-table-model\u0027;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import { AccountRequestTableComponent } from \u0027./account-request-table.component\u0027;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import { AccountRequestTableModule } from \u0027./account-request-table.module\u0027;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import { EditRequestModalComponent } from \u0027./admin-edit-request-modal/admin-edit-request-modal.component\u0027;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import {"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" RejectWithReasonModalComponent,"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"} from \u0027./admin-reject-with-reason-modal/admin-reject-with-reason-modal.component\u0027;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import { AccountService } from \u0027../../../services/account.service\u0027;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import { SimpleModalService } from \u0027../../../services/simple-modal.service\u0027;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"import { StatusMessageService } from \u0027../../../services/status-message.service\u0027;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import { createBuilder } from \u0027../../../test-helpers/generic-builder\u0027;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"import { createMockNgbModalRef } from \u0027../../../test-helpers/mock-ngb-modal-ref\u0027;"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"import { AccountRequest, AccountRequestStatus } from \u0027../../../types/api-output\u0027;"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":"import { SimpleModalType } from \u0027../simple-modal/simple-modal-type\u0027;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":"describe(\u0027AccountRequestTableComponent\u0027, () \u003d\u003e {"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" let component: AccountRequestTableComponent;"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" let fixture: ComponentFixture\u003cAccountRequestTableComponent\u003e;"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" let accountService: AccountService;"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" let statusMessageService: StatusMessageService;"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" let simpleModalService: SimpleModalService;"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" let ngbModal: NgbModal;"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" const accountRequestDetailsBuilder \u003d createBuilder\u003cAccountRequestTableRowModel\u003e({"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" id: \u0027\u0027,"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" email: \u0027\u0027,"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" name: \u0027\u0027,"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" instituteAndCountry: \u0027\u0027,"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" registrationLink: \u0027\u0027,"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus.PENDING,"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" comments: \u0027\u0027,"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" registeredAtText: \u0027\u0027,"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" createdAtText: \u0027\u0027,"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" showLinks: false,"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" const DEFAULT_ACCOUNT_REQUEST \u003d accountRequestDetailsBuilder"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" .email(\u0027email\u0027)"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" .name(\u0027name\u0027)"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" .status(AccountRequestStatus.PENDING)"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" .instituteAndCountry(\u0027institute\u0027)"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" .createdAtText(\u0027Tue, 08 Feb 2022, 08:23 AM +00:00\u0027)"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" .comments(\u0027comment\u0027);"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" const resetModalContent \u003d `Are you sure you want to reset the account request for"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003ename\u003c/strong\u003e with email \u003cstrong\u003eemail\u003c/strong\u003e from"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003einstitute\u003c/strong\u003e?"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" An email with the account registration link will also be sent to the instructor.`;"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" const resetModalTitle \u003d \u0027Reset account request for \u003cstrong\u003ename\u003c/strong\u003e?\u0027;"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" const deleteModalContent \u003d `Are you sure you want to \u003cstrong\u003edelete\u003c/strong\u003e the account request for"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003ename\u003c/strong\u003e with email \u003cstrong\u003eemail\u003c/strong\u003e from"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003einstitute\u003c/strong\u003e?`;"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" const deleteModalTitle \u003d \u0027Delete account request for \u003cstrong\u003ename\u003c/strong\u003e?\u0027;"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" beforeEach(waitForAsync(() \u003d\u003e {"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" TestBed.configureTestingModule({"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" declarations: [AccountRequestTableComponent],"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" imports: ["},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" AccountRequestTableModule,"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" BrowserAnimationsModule,"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":" HttpClientTestingModule,"},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" ],"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":" providers: ["},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" AccountService, SimpleModalService,"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" ],"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" }).compileComponents();"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" }));"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" fixture \u003d TestBed.createComponent(AccountRequestTableComponent);"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" accountService \u003d TestBed.inject(AccountService);"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" statusMessageService \u003d TestBed.inject(StatusMessageService);"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" simpleModalService \u003d TestBed.inject(SimpleModalService);"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" ngbModal \u003d TestBed.inject(NgbModal);"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" expect(component).toBeTruthy();"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" it(\u0027should snap with an expanded account requests table\u0027, () \u003d\u003e {"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" const accountRequestResult: AccountRequestTableRowModel \u003d DEFAULT_ACCOUNT_REQUEST.build();"},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d ["},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" accountRequestResult,"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show account request links when expand all button clicked\u0027, () \u003d\u003e {"},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" const accountRequestResult: AccountRequestTableRowModel \u003d DEFAULT_ACCOUNT_REQUEST.build();"},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":" accountRequestResult.status \u003d AccountRequestStatus.APPROVED;"},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" accountRequestResult.registrationLink \u003d \u0027registrationLink\u0027;"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d ["},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":" accountRequestResult,"},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" component.searchString \u003d \u0027test\u0027;"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" const button: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#show-account-request-links\u0027);"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" button.click();"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" expect(component.accountRequests[0].showLinks).toEqual(true);"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" it(\u0027should display account requests with no reset or expand links button\u0027, () \u003d\u003e {"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" it(\u0027should display account requests with reset button and expandable links buttons\u0027,"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" () \u003d\u003e {"},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" const approvedAccountRequestResult: AccountRequestTableRowModel \u003d DEFAULT_ACCOUNT_REQUEST.build();"},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" approvedAccountRequestResult.status \u003d AccountRequestStatus.APPROVED;"},{"lineNumber":128,"author":{"gitId":"domoberzin"},"content":" approvedAccountRequestResult.registrationLink \u003d \u0027registrationLink\u0027;"},{"lineNumber":129,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":" const registeredAccountRequestResult: AccountRequestTableRowModel \u003d DEFAULT_ACCOUNT_REQUEST.build();"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult.status \u003d AccountRequestStatus.REGISTERED;"},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult.registrationLink \u003d \u0027registrationLink\u0027;"},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":" approvedAccountRequestResult,"},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult,"},{"lineNumber":137,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":140,"author":{"gitId":"domoberzin"},"content":" component.searchString \u003d \u0027test\u0027;"},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":145,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show success message when deleting account request is successful\u0027, () \u003d\u003e {"},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d ["},{"lineNumber":147,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":148,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":149,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":150,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":151,"author":{"gitId":"domoberzin"},"content":" const modalSpy \u003d jest.spyOn(simpleModalService, \u0027openConfirmationModal\u0027).mockImplementation(() \u003d\u003e {"},{"lineNumber":152,"author":{"gitId":"domoberzin"},"content":" return createMockNgbModalRef({});"},{"lineNumber":153,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":154,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":155,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027deleteAccountRequest\u0027).mockReturnValue(of({"},{"lineNumber":156,"author":{"gitId":"domoberzin"},"content":" message: \u0027Account request successfully deleted.\u0027,"},{"lineNumber":157,"author":{"gitId":"domoberzin"},"content":" }));"},{"lineNumber":158,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":159,"author":{"gitId":"domoberzin"},"content":" const spyStatusMessageService: any \u003d jest.spyOn(statusMessageService, \u0027showSuccessToast\u0027)"},{"lineNumber":160,"author":{"gitId":"domoberzin"},"content":" .mockImplementation((args: string) \u003d\u003e {"},{"lineNumber":161,"author":{"gitId":"domoberzin"},"content":" expect(args).toEqual(\u0027Account request successfully deleted.\u0027);"},{"lineNumber":162,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":163,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":164,"author":{"gitId":"domoberzin"},"content":" const deleteButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#delete-account-request-0\u0027);"},{"lineNumber":165,"author":{"gitId":"domoberzin"},"content":" deleteButton.click();"},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" expect(spyStatusMessageService).toHaveBeenCalled();"},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledWith(deleteModalTitle, SimpleModalType.DANGER, deleteModalContent);"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":171,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":172,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show error message when deleting account request is unsuccessful\u0027, () \u003d\u003e {"},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d ["},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" const modalSpy \u003d jest.spyOn(simpleModalService, \u0027openConfirmationModal\u0027).mockImplementation(() \u003d\u003e {"},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" return createMockNgbModalRef({});"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027deleteAccountRequest\u0027).mockReturnValue(throwError(() \u003d\u003e ({"},{"lineNumber":184,"author":{"gitId":"domoberzin"},"content":" error: {"},{"lineNumber":185,"author":{"gitId":"domoberzin"},"content":" message: \u0027This is the error message.\u0027,"},{"lineNumber":186,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":187,"author":{"gitId":"domoberzin"},"content":" })));"},{"lineNumber":188,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":189,"author":{"gitId":"domoberzin"},"content":" const spyStatusMessageService: any \u003d jest.spyOn(statusMessageService, \u0027showErrorToast\u0027)"},{"lineNumber":190,"author":{"gitId":"domoberzin"},"content":" .mockImplementation((args: string) \u003d\u003e {"},{"lineNumber":191,"author":{"gitId":"domoberzin"},"content":" expect(args).toEqual(\u0027This is the error message.\u0027);"},{"lineNumber":192,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" const deleteButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#delete-account-request-0\u0027);"},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" deleteButton.click();"},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":" expect(spyStatusMessageService).toHaveBeenCalled();"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledWith(deleteModalTitle, SimpleModalType.DANGER, deleteModalContent);"},{"lineNumber":200,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":201,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":202,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show success message when resetting account request is successful\u0027, () \u003d\u003e {"},{"lineNumber":203,"author":{"gitId":"domoberzin"},"content":" const registeredAccountRequestResult: AccountRequestTableRowModel \u003d DEFAULT_ACCOUNT_REQUEST.build();"},{"lineNumber":204,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult.status \u003d AccountRequestStatus.REGISTERED;"},{"lineNumber":205,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult.registrationLink \u003d \u0027registrationLink\u0027;"},{"lineNumber":206,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult.registeredAtText \u003d \u0027registeredTime\u0027;"},{"lineNumber":207,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d ["},{"lineNumber":208,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult,"},{"lineNumber":209,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":210,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":211,"author":{"gitId":"domoberzin"},"content":" component.searchString \u003d \u0027test\u0027;"},{"lineNumber":212,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":213,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":214,"author":{"gitId":"domoberzin"},"content":" const modalSpy \u003d jest.spyOn(simpleModalService, \u0027openConfirmationModal\u0027).mockImplementation(() \u003d\u003e {"},{"lineNumber":215,"author":{"gitId":"domoberzin"},"content":" return createMockNgbModalRef({});"},{"lineNumber":216,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":217,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":218,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027resetAccountRequest\u0027).mockReturnValue(of({"},{"lineNumber":219,"author":{"gitId":"domoberzin"},"content":" joinLink: \u0027joinlink\u0027,"},{"lineNumber":220,"author":{"gitId":"domoberzin"},"content":" }));"},{"lineNumber":221,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":222,"author":{"gitId":"domoberzin"},"content":" const spyStatusMessageService \u003d jest.spyOn(statusMessageService, \u0027showSuccessToast\u0027)"},{"lineNumber":223,"author":{"gitId":"domoberzin"},"content":" .mockImplementation((args: string) \u003d\u003e {"},{"lineNumber":224,"author":{"gitId":"domoberzin"},"content":" expect(args)"},{"lineNumber":225,"author":{"gitId":"domoberzin"},"content":" .toEqual(\u0027Reset successful. An email has been sent to email.\u0027);"},{"lineNumber":226,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":227,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":228,"author":{"gitId":"domoberzin"},"content":" const resetButton \u003d fixture.debugElement.nativeElement.querySelector(\u0027#reset-account-request-0\u0027);"},{"lineNumber":229,"author":{"gitId":"domoberzin"},"content":" resetButton.click();"},{"lineNumber":230,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":231,"author":{"gitId":"domoberzin"},"content":" expect(spyStatusMessageService).toHaveBeenCalled();"},{"lineNumber":232,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":233,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledWith(resetModalTitle, SimpleModalType.WARNING, resetModalContent);"},{"lineNumber":234,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":235,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":236,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show error message when resetting account request is unsuccessful\u0027, () \u003d\u003e {"},{"lineNumber":237,"author":{"gitId":"domoberzin"},"content":" const registeredAccountRequestResult: AccountRequestTableRowModel \u003d DEFAULT_ACCOUNT_REQUEST.build();"},{"lineNumber":238,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult.status \u003d AccountRequestStatus.REGISTERED;"},{"lineNumber":239,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult.registrationLink \u003d \u0027registrationLink\u0027;"},{"lineNumber":240,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult.registeredAtText \u003d \u0027registeredTime\u0027;"},{"lineNumber":241,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d ["},{"lineNumber":242,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult,"},{"lineNumber":243,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":244,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":245,"author":{"gitId":"domoberzin"},"content":" component.searchString \u003d \u0027test\u0027;"},{"lineNumber":246,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":247,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":248,"author":{"gitId":"domoberzin"},"content":" const modalSpy \u003d jest.spyOn(simpleModalService, \u0027openConfirmationModal\u0027).mockImplementation(() \u003d\u003e {"},{"lineNumber":249,"author":{"gitId":"domoberzin"},"content":" return createMockNgbModalRef({});"},{"lineNumber":250,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":251,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":252,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027resetAccountRequest\u0027).mockReturnValue(throwError(() \u003d\u003e ({"},{"lineNumber":253,"author":{"gitId":"domoberzin"},"content":" error: {"},{"lineNumber":254,"author":{"gitId":"domoberzin"},"content":" message: \u0027This is the error message.\u0027,"},{"lineNumber":255,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":256,"author":{"gitId":"domoberzin"},"content":" })));"},{"lineNumber":257,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":258,"author":{"gitId":"domoberzin"},"content":" const spyStatusMessageService \u003d jest.spyOn(statusMessageService, \u0027showErrorToast\u0027)"},{"lineNumber":259,"author":{"gitId":"domoberzin"},"content":" .mockImplementation((args: string) \u003d\u003e {"},{"lineNumber":260,"author":{"gitId":"domoberzin"},"content":" expect(args).toEqual(\u0027This is the error message.\u0027);"},{"lineNumber":261,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":262,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":263,"author":{"gitId":"domoberzin"},"content":" const resetButton \u003d fixture.debugElement.nativeElement.querySelector(\u0027#reset-account-request-0\u0027);"},{"lineNumber":264,"author":{"gitId":"domoberzin"},"content":" resetButton.click();"},{"lineNumber":265,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":266,"author":{"gitId":"domoberzin"},"content":" expect(spyStatusMessageService).toHaveBeenCalled();"},{"lineNumber":267,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":268,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledWith(resetModalTitle, SimpleModalType.WARNING, resetModalContent);"},{"lineNumber":269,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":270,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":271,"author":{"gitId":"domoberzin"},"content":" it(\u0027should display comment modal\u0027, () \u003d\u003e {"},{"lineNumber":272,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":273,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":274,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":275,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":276,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":277,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":278,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":279,"author":{"gitId":"domoberzin"},"content":" const modalSpy \u003d jest.spyOn(simpleModalService, \u0027openInformationModal\u0027)"},{"lineNumber":280,"author":{"gitId":"domoberzin"},"content":" .mockReturnValue(createMockNgbModalRef());"},{"lineNumber":281,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":282,"author":{"gitId":"domoberzin"},"content":" const viewCommentButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#view-account-request-0\u0027);"},{"lineNumber":283,"author":{"gitId":"domoberzin"},"content":" viewCommentButton.click();"},{"lineNumber":284,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":285,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledWith(\u0027Comments for \u003cstrong\u003ename\u003c/strong\u003e Request\u0027,"},{"lineNumber":286,"author":{"gitId":"domoberzin"},"content":" SimpleModalType.INFO, \u0027\u003cstrong\u003eComment:\u003c/strong\u003e comment\u0027);"},{"lineNumber":287,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":288,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":289,"author":{"gitId":"domoberzin"},"content":" it(\u0027should display edit modal when edit button is clicked\u0027, () \u003d\u003e {"},{"lineNumber":290,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":291,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":292,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":293,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":294,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":295,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":296,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":297,"author":{"gitId":"domoberzin"},"content":" const mockModalRef \u003d {"},{"lineNumber":298,"author":{"gitId":"domoberzin"},"content":" componentInstance: {},"},{"lineNumber":299,"author":{"gitId":"domoberzin"},"content":" result: Promise.resolve({}),"},{"lineNumber":300,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":301,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":302,"author":{"gitId":"domoberzin"},"content":" const modalSpy \u003d jest.spyOn(ngbModal, \u0027open\u0027).mockReturnValue(mockModalRef as any);"},{"lineNumber":303,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":304,"author":{"gitId":"domoberzin"},"content":" const editButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#edit-account-request-0\u0027);"},{"lineNumber":305,"author":{"gitId":"domoberzin"},"content":" editButton.click();"},{"lineNumber":306,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":307,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledWith(EditRequestModalComponent);"},{"lineNumber":308,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":309,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":310,"author":{"gitId":"domoberzin"},"content":" it(\u0027should display reject modal when reject button is clicked\u0027, () \u003d\u003e {"},{"lineNumber":311,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":312,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":313,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":314,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":315,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":316,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":317,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":318,"author":{"gitId":"domoberzin"},"content":" const modalSpy \u003d jest.spyOn(ngbModal, \u0027open\u0027).mockImplementation(() \u003d\u003e {"},{"lineNumber":319,"author":{"gitId":"domoberzin"},"content":" return createMockNgbModalRef({});"},{"lineNumber":320,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":321,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":322,"author":{"gitId":"domoberzin"},"content":" const rejectButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#reject-request-with-reason-0\u0027);"},{"lineNumber":323,"author":{"gitId":"domoberzin"},"content":" rejectButton.click();"},{"lineNumber":324,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":325,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":326,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledWith(RejectWithReasonModalComponent);"},{"lineNumber":327,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":328,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":329,"author":{"gitId":"domoberzin"},"content":" it(\u0027should display error message when rejection was unsuccessful\u0027, () \u003d\u003e {"},{"lineNumber":330,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":331,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":332,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":333,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":334,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":335,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":336,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":337,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027rejectAccountRequest\u0027).mockReturnValue(throwError(() \u003d\u003e ({"},{"lineNumber":338,"author":{"gitId":"domoberzin"},"content":" error: {"},{"lineNumber":339,"author":{"gitId":"domoberzin"},"content":" message: \u0027This is the error message.\u0027,"},{"lineNumber":340,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":341,"author":{"gitId":"domoberzin"},"content":" })));"},{"lineNumber":342,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":343,"author":{"gitId":"domoberzin"},"content":" const spyStatusMessageService \u003d jest.spyOn(statusMessageService, \u0027showErrorToast\u0027)"},{"lineNumber":344,"author":{"gitId":"domoberzin"},"content":" .mockImplementation((args: string) \u003d\u003e {"},{"lineNumber":345,"author":{"gitId":"domoberzin"},"content":" expect(args).toEqual(\u0027This is the error message.\u0027);"},{"lineNumber":346,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":347,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":348,"author":{"gitId":"domoberzin"},"content":" const rejectButton \u003d fixture.debugElement.nativeElement.querySelector(\u0027#reject-request-0\u0027);"},{"lineNumber":349,"author":{"gitId":"domoberzin"},"content":" rejectButton.click();"},{"lineNumber":350,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":351,"author":{"gitId":"domoberzin"},"content":" expect(spyStatusMessageService).toHaveBeenCalled();"},{"lineNumber":352,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":353,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":354,"author":{"gitId":"domoberzin"},"content":" it(\u0027should display error message when approval was unsuccessful\u0027, () \u003d\u003e {"},{"lineNumber":355,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":356,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":357,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":358,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":359,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":360,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":361,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":362,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027approveAccountRequest\u0027).mockReturnValue(throwError(() \u003d\u003e ({"},{"lineNumber":363,"author":{"gitId":"domoberzin"},"content":" error: {"},{"lineNumber":364,"author":{"gitId":"domoberzin"},"content":" message: \u0027This is the error message.\u0027,"},{"lineNumber":365,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":366,"author":{"gitId":"domoberzin"},"content":" })));"},{"lineNumber":367,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":368,"author":{"gitId":"domoberzin"},"content":" const spyStatusMessageService: any \u003d jest.spyOn(statusMessageService, \u0027showErrorToast\u0027)"},{"lineNumber":369,"author":{"gitId":"domoberzin"},"content":" .mockImplementation((args: string) \u003d\u003e {"},{"lineNumber":370,"author":{"gitId":"domoberzin"},"content":" expect(args).toEqual(\u0027This is the error message.\u0027);"},{"lineNumber":371,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":372,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":373,"author":{"gitId":"domoberzin"},"content":" const approveButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#approve-account-request-0\u0027);"},{"lineNumber":374,"author":{"gitId":"domoberzin"},"content":" approveButton.click();"},{"lineNumber":375,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":376,"author":{"gitId":"domoberzin"},"content":" expect(spyStatusMessageService).toHaveBeenCalled();"},{"lineNumber":377,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":378,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":379,"author":{"gitId":"domoberzin"},"content":" it(\u0027should display error message when edit was unsuccessful\u0027, () \u003d\u003e {"},{"lineNumber":380,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":381,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":382,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":383,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":384,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":385,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":386,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":387,"author":{"gitId":"domoberzin"},"content":" const mockModalRef \u003d {"},{"lineNumber":388,"author":{"gitId":"domoberzin"},"content":" componentInstance: {},"},{"lineNumber":389,"author":{"gitId":"domoberzin"},"content":" result: Promise.resolve({}),"},{"lineNumber":390,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":391,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":392,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(ngbModal, \u0027open\u0027).mockReturnValue(mockModalRef as any);"},{"lineNumber":393,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":394,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027editAccountRequest\u0027).mockReturnValue(throwError(() \u003d\u003e ({"},{"lineNumber":395,"author":{"gitId":"domoberzin"},"content":" error: {"},{"lineNumber":396,"author":{"gitId":"domoberzin"},"content":" message: \u0027This is the error message.\u0027,"},{"lineNumber":397,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":398,"author":{"gitId":"domoberzin"},"content":" })));"},{"lineNumber":399,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":400,"author":{"gitId":"domoberzin"},"content":" const spyStatusMessageService \u003d jest.spyOn(statusMessageService, \u0027showErrorToast\u0027)"},{"lineNumber":401,"author":{"gitId":"domoberzin"},"content":" .mockImplementation((args: string) \u003d\u003e {"},{"lineNumber":402,"author":{"gitId":"domoberzin"},"content":" expect(args).toEqual(\u0027This is the error message.\u0027);"},{"lineNumber":403,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":404,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":405,"author":{"gitId":"domoberzin"},"content":" const editButton \u003d fixture.debugElement.nativeElement.querySelector(\u0027#edit-account-request-0\u0027);"},{"lineNumber":406,"author":{"gitId":"domoberzin"},"content":" editButton.click();"},{"lineNumber":407,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":408,"author":{"gitId":"domoberzin"},"content":" expect(spyStatusMessageService).toHaveBeenCalled();"},{"lineNumber":409,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":410,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":411,"author":{"gitId":"domoberzin"},"content":" it(\u0027should update request when edit is succcessful\u0027, () \u003d\u003e {"},{"lineNumber":412,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":413,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":414,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":415,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":416,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":417,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":418,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":419,"author":{"gitId":"domoberzin"},"content":" const mockModalRef \u003d {"},{"lineNumber":420,"author":{"gitId":"domoberzin"},"content":" componentInstance: {},"},{"lineNumber":421,"author":{"gitId":"domoberzin"},"content":" result: Promise.resolve({}),"},{"lineNumber":422,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":423,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":424,"author":{"gitId":"domoberzin"},"content":" const modalSpy \u003d jest.spyOn(ngbModal, \u0027open\u0027).mockReturnValue(mockModalRef as any);"},{"lineNumber":425,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":426,"author":{"gitId":"domoberzin"},"content":" const editedAccountRequest : AccountRequest \u003d {"},{"lineNumber":427,"author":{"gitId":"domoberzin"},"content":" id: \u0027id\u0027,"},{"lineNumber":428,"author":{"gitId":"domoberzin"},"content":" comments: \u0027new comment\u0027,"},{"lineNumber":429,"author":{"gitId":"domoberzin"},"content":" email: \u0027new email\u0027,"},{"lineNumber":430,"author":{"gitId":"domoberzin"},"content":" institute: \u0027new institute\u0027,"},{"lineNumber":431,"author":{"gitId":"domoberzin"},"content":" registrationKey: \u0027registration key\u0027,"},{"lineNumber":432,"author":{"gitId":"domoberzin"},"content":" name: \u0027new name\u0027,"},{"lineNumber":433,"author":{"gitId":"domoberzin"},"content":" createdAt: 1,"},{"lineNumber":434,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus.PENDING,"},{"lineNumber":435,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":436,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":437,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027editAccountRequest\u0027).mockReturnValue(of(editedAccountRequest));"},{"lineNumber":438,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":439,"author":{"gitId":"domoberzin"},"content":" const editButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#edit-account-request-0\u0027);"},{"lineNumber":440,"author":{"gitId":"domoberzin"},"content":" editButton.click();"},{"lineNumber":441,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":442,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledWith(EditRequestModalComponent);"},{"lineNumber":443,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":444,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":445,"author":{"gitId":"domoberzin"},"content":" expect(component.accountRequests[0].comments).toEqual(\u0027new comment\u0027);"},{"lineNumber":446,"author":{"gitId":"domoberzin"},"content":" expect(component.accountRequests[0].email).toEqual(\u0027new email\u0027);"},{"lineNumber":447,"author":{"gitId":"domoberzin"},"content":" expect(component.accountRequests[0].instituteAndCountry).toEqual(\u0027new institute\u0027);"},{"lineNumber":448,"author":{"gitId":"domoberzin"},"content":" expect(component.accountRequests[0].name).toEqual(\u0027new name\u0027);"},{"lineNumber":449,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":450,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":451,"author":{"gitId":"domoberzin"},"content":" it(\u0027should update status when approval is succcessful\u0027, () \u003d\u003e {"},{"lineNumber":452,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":453,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":454,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":455,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":456,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":457,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":458,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":459,"author":{"gitId":"domoberzin"},"content":" const approvedRequest : AccountRequest \u003d {"},{"lineNumber":460,"author":{"gitId":"domoberzin"},"content":" id: component.accountRequests[0].id,"},{"lineNumber":461,"author":{"gitId":"domoberzin"},"content":" comments: component.accountRequests[0].comments,"},{"lineNumber":462,"author":{"gitId":"domoberzin"},"content":" email: component.accountRequests[0].email,"},{"lineNumber":463,"author":{"gitId":"domoberzin"},"content":" institute: component.accountRequests[0].instituteAndCountry,"},{"lineNumber":464,"author":{"gitId":"domoberzin"},"content":" registrationKey: \u0027registration key\u0027,"},{"lineNumber":465,"author":{"gitId":"domoberzin"},"content":" name: component.accountRequests[0].name,"},{"lineNumber":466,"author":{"gitId":"domoberzin"},"content":" createdAt: 1,"},{"lineNumber":467,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus.APPROVED,"},{"lineNumber":468,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":469,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":470,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027approveAccountRequest\u0027).mockReturnValue(of(approvedRequest));"},{"lineNumber":471,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":472,"author":{"gitId":"domoberzin"},"content":" const approveButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#approve-account-request-0\u0027);"},{"lineNumber":473,"author":{"gitId":"domoberzin"},"content":" approveButton.click();"},{"lineNumber":474,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":475,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":476,"author":{"gitId":"domoberzin"},"content":" expect(component.accountRequests[0].status).toEqual(AccountRequestStatus.APPROVED);"},{"lineNumber":477,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":478,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":479,"author":{"gitId":"domoberzin"},"content":" it(\u0027should update status when rejection is succcessful\u0027, () \u003d\u003e {"},{"lineNumber":480,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":481,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":482,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":483,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":484,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":485,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":486,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":487,"author":{"gitId":"domoberzin"},"content":" const rejectedRequest : AccountRequest \u003d {"},{"lineNumber":488,"author":{"gitId":"domoberzin"},"content":" id: component.accountRequests[0].id,"},{"lineNumber":489,"author":{"gitId":"domoberzin"},"content":" comments: component.accountRequests[0].comments,"},{"lineNumber":490,"author":{"gitId":"domoberzin"},"content":" email: component.accountRequests[0].email,"},{"lineNumber":491,"author":{"gitId":"domoberzin"},"content":" institute: component.accountRequests[0].instituteAndCountry,"},{"lineNumber":492,"author":{"gitId":"domoberzin"},"content":" registrationKey: \u0027registration key\u0027,"},{"lineNumber":493,"author":{"gitId":"domoberzin"},"content":" name: component.accountRequests[0].name,"},{"lineNumber":494,"author":{"gitId":"domoberzin"},"content":" createdAt: 1,"},{"lineNumber":495,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus.REJECTED,"},{"lineNumber":496,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":497,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":498,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027rejectAccountRequest\u0027).mockReturnValue(of(rejectedRequest));"},{"lineNumber":499,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":500,"author":{"gitId":"domoberzin"},"content":" const rejectButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#reject-request-0\u0027);"},{"lineNumber":501,"author":{"gitId":"domoberzin"},"content":" rejectButton.click();"},{"lineNumber":502,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":503,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":504,"author":{"gitId":"domoberzin"},"content":" expect(component.accountRequests[0].status).toEqual(AccountRequestStatus.REJECTED);"},{"lineNumber":505,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":506,"author":{"gitId":"domoberzin"},"content":"});"}],"authorContributionMap":{"domoberzin":506}},{"path":"src/web/app/components/account-requests-table/account-request-table.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"import { Component, Input } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":"import { NgbModalRef, NgbModal } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import { AccountRequestTableRowModel } from \u0027./account-request-table-model\u0027;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import { EditRequestModalComponentResult } from \u0027./admin-edit-request-modal/admin-edit-request-modal-model\u0027;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import { EditRequestModalComponent } from \u0027./admin-edit-request-modal/admin-edit-request-modal.component\u0027;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import {"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":" RejectWithReasonModalComponent,"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"} from \u0027./admin-reject-with-reason-modal/admin-reject-with-reason-modal.component\u0027;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import { AccountService } from \u0027../../../services/account.service\u0027;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import { SimpleModalService } from \u0027../../../services/simple-modal.service\u0027;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import { StatusMessageService } from \u0027../../../services/status-message.service\u0027;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import { AccountRequest, MessageOutput } from \u0027../../../types/api-output\u0027;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import { ErrorMessageOutput } from \u0027../../error-message-output\u0027;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import { SimpleModalType } from \u0027../simple-modal/simple-modal-type\u0027;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"import { collapseAnim } from \u0027../teammates-common/collapse-anim\u0027;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" * Account requests table component."},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":"@Component({"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" selector: \u0027tm-account-request-table\u0027,"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" templateUrl: \u0027./account-request-table.component.html\u0027,"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" styleUrls: [\u0027./account-request-table.component.scss\u0027],"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" animations: [collapseAnim],"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":"})"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":"export class AccountRequestTableComponent {"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" @Input()"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" accountRequests: AccountRequestTableRowModel[] \u003d [];"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" @Input()"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" searchString \u003d \u0027\u0027;"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" constructor("},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" private statusMessageService: StatusMessageService,"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" private simpleModalService: SimpleModalService,"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" private accountService: AccountService,"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" private ngbModal: NgbModal,"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" ) {}"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" * Shows all account requests\u0027 links in the page."},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" showAllAccountRequestsLinks(): void {"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" for (const accountRequest of this.accountRequests) {"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" accountRequest.showLinks \u003d true;"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" * Hides all account requests\u0027 links in the page."},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" hideAllAccountRequestsLinks(): void {"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" for (const accountRequest of this.accountRequests) {"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" accountRequest.showLinks \u003d false;"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" editAccountRequest(accountRequest: AccountRequestTableRowModel): void {"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" const modalRef: NgbModalRef \u003d this.ngbModal.open(EditRequestModalComponent);"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" modalRef.componentInstance.accountRequestName \u003d accountRequest.name;"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" modalRef.componentInstance.accountRequestEmail \u003d accountRequest.email;"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" modalRef.componentInstance.accountRequestInstitution \u003d accountRequest.instituteAndCountry;"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" modalRef.componentInstance.accountRequestComments \u003d accountRequest.comments;"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" modalRef.result.then((res: EditRequestModalComponentResult) \u003d\u003e {"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":" this.accountService.editAccountRequest("},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" accountRequest.id,"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" res.accountRequestName,"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" res.accountRequestEmail,"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" res.accountRequestInstitution,"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" accountRequest.status,"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" res.accountRequestComment)"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" .subscribe({"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" next: (resp: AccountRequest) \u003d\u003e {"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" accountRequest.comments \u003d resp.comments ?? \u0027\u0027;"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" accountRequest.name \u003d resp.name;"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" accountRequest.email \u003d resp.email;"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" accountRequest.instituteAndCountry \u003d resp.institute;"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showSuccessToast(\u0027Account request was successfully updated.\u0027);"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" approveAccountRequest(accountRequest: AccountRequestTableRowModel): void {"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" this.accountService.approveAccountRequest(accountRequest.id, accountRequest.name,"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" accountRequest.email, accountRequest.instituteAndCountry)"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":" .subscribe({"},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":" next: (resp : AccountRequest) \u003d\u003e {"},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" accountRequest.status \u003d resp.status;"},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showSuccessToast("},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":" `Account request was successfully approved. Email has been sent to ${accountRequest.email}.`,"},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":" );"},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" resetAccountRequest(accountRequest: AccountRequestTableRowModel): void {"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" const modalContent \u003d `Are you sure you want to reset the account request for"},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003e${accountRequest.name}\u003c/strong\u003e with email \u003cstrong\u003e${accountRequest.email}\u003c/strong\u003e from"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003e${accountRequest.instituteAndCountry}\u003c/strong\u003e?"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" An email with the account registration link will also be sent to the instructor.`;"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" const modalRef: NgbModalRef \u003d this.simpleModalService.openConfirmationModal("},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" `Reset account request for \u003cstrong\u003e${accountRequest.name}\u003c/strong\u003e?`, SimpleModalType.WARNING, modalContent);"},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" modalRef.result.then(() \u003d\u003e {"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" this.accountService.resetAccountRequest(accountRequest.id)"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" .subscribe({"},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":" next: () \u003d\u003e {"},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService"},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" .showSuccessToast(`Reset successful. An email has been sent to ${accountRequest.email}.`);"},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" accountRequest.registeredAtText \u003d \u0027\u0027;"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" }, () \u003d\u003e {});"},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":128,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":129,"author":{"gitId":"domoberzin"},"content":" deleteAccountRequest(accountRequest: AccountRequestTableRowModel): void {"},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":" const modalContent: string \u003d `Are you sure you want to \u003cstrong\u003edelete\u003c/strong\u003e the account request for"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003e${accountRequest.name}\u003c/strong\u003e with email \u003cstrong\u003e${accountRequest.email}\u003c/strong\u003e from"},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003e${accountRequest.instituteAndCountry}\u003c/strong\u003e?`;"},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" const modalRef: NgbModalRef \u003d this.simpleModalService.openConfirmationModal("},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" `Delete account request for \u003cstrong\u003e${accountRequest.name}\u003c/strong\u003e?`, SimpleModalType.DANGER, modalContent);"},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" modalRef.result.then(() \u003d\u003e {"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":" this.accountService.deleteAccountRequest(accountRequest.id)"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":" .subscribe({"},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":" next: (resp: MessageOutput) \u003d\u003e {"},{"lineNumber":140,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showSuccessToast(resp.message);"},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":" this.accountRequests \u003d this.accountRequests.filter((x: AccountRequestTableRowModel) \u003d\u003e x !\u003d\u003d accountRequest);"},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":145,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":147,"author":{"gitId":"domoberzin"},"content":" }, () \u003d\u003e {});"},{"lineNumber":148,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":149,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":150,"author":{"gitId":"domoberzin"},"content":" viewAccountRequest(accountRequest: AccountRequestTableRowModel): void {"},{"lineNumber":151,"author":{"gitId":"domoberzin"},"content":" const modalContent: string \u003d `\u003cstrong\u003eComment:\u003c/strong\u003e ${accountRequest.comments || \u0027No comments\u0027}`;"},{"lineNumber":152,"author":{"gitId":"domoberzin"},"content":" const modalRef: NgbModalRef \u003d this.simpleModalService.openInformationModal("},{"lineNumber":153,"author":{"gitId":"domoberzin"},"content":" `Comments for \u003cstrong\u003e${accountRequest.name}\u003c/strong\u003e Request`, SimpleModalType.INFO, modalContent);"},{"lineNumber":154,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":155,"author":{"gitId":"domoberzin"},"content":" modalRef.result.then(() \u003d\u003e {}, () \u003d\u003e {});"},{"lineNumber":156,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":157,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":158,"author":{"gitId":"domoberzin"},"content":" rejectAccountRequest(accountRequest: AccountRequestTableRowModel): void {"},{"lineNumber":159,"author":{"gitId":"domoberzin"},"content":" this.accountService.rejectAccountRequest(accountRequest.id)"},{"lineNumber":160,"author":{"gitId":"domoberzin"},"content":" .subscribe({"},{"lineNumber":161,"author":{"gitId":"domoberzin"},"content":" next: (resp : AccountRequest) \u003d\u003e {"},{"lineNumber":162,"author":{"gitId":"domoberzin"},"content":" accountRequest.status \u003d resp.status;"},{"lineNumber":163,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showSuccessToast(\u0027Account request was successfully rejected.\u0027);"},{"lineNumber":164,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":165,"author":{"gitId":"domoberzin"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":171,"author":{"gitId":"domoberzin"},"content":" rejectAccountRequestWithReason(accountRequest: AccountRequestTableRowModel): void {"},{"lineNumber":172,"author":{"gitId":"domoberzin"},"content":" const modalRef: NgbModalRef \u003d this.ngbModal.open(RejectWithReasonModalComponent);"},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":" modalRef.componentInstance.accountRequestName \u003d accountRequest.name;"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":" modalRef.componentInstance.accountRequestEmail \u003d accountRequest.email;"},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":" modalRef.result.then(() \u003d\u003e {"},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" this.accountService.rejectAccountRequest(accountRequest.id,"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":" modalRef.componentInstance.rejectionReasonTitle, modalRef.componentInstance.rejectionReasonBody)"},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" .subscribe({"},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" next: (resp: AccountRequest) \u003d\u003e {"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":" accountRequest.status \u003d resp.status;"},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showSuccessToast("},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":" `Account request was successfully rejected. Email has been sent to ${accountRequest.email}.`,"},{"lineNumber":184,"author":{"gitId":"domoberzin"},"content":" );"},{"lineNumber":185,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":186,"author":{"gitId":"domoberzin"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":187,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":188,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":189,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":190,"author":{"gitId":"domoberzin"},"content":" }, () \u003d\u003e {});"},{"lineNumber":191,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":192,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":" trackAccountRequest(accountRequest: AccountRequestTableRowModel): string {"},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" return accountRequest.id;"},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":194,"dishenggg":2}},{"path":"src/web/app/components/account-requests-table/account-request-table.module.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"import { CommonModule } from \u0027@angular/common\u0027;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":"import { NgModule } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import { FormsModule } from \u0027@angular/forms\u0027;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import { NgbTooltipModule, NgbDropdownModule } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import { AccountRequestTableComponent } from \u0027./account-request-table.component\u0027;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import { EditRequestModalComponent } from \u0027./admin-edit-request-modal/admin-edit-request-modal.component\u0027;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import {"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" RejectWithReasonModalComponent,"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"} from \u0027./admin-reject-with-reason-modal/admin-reject-with-reason-modal.component\u0027;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import { Pipes } from \u0027../../pipes/pipes.module\u0027;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import { RichTextEditorModule } from \u0027../rich-text-editor/rich-text-editor.module\u0027;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":" * Module for account requests table."},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"@NgModule({"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" declarations: ["},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" AccountRequestTableComponent,"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" EditRequestModalComponent,"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" RejectWithReasonModalComponent,"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" ],"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" exports: ["},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" AccountRequestTableComponent,"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" ],"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" imports: ["},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" CommonModule,"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" FormsModule,"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" NgbTooltipModule,"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" NgbDropdownModule,"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" Pipes,"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" RichTextEditorModule,"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" ],"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":"})"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":"export class AccountRequestTableModule { }"}],"authorContributionMap":{"domoberzin":34}},{"path":"src/web/app/components/account-requests-table/admin-edit-request-modal/admin-edit-request-modal-model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":" * Result of {@link EditRequestModalComponent}"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"export interface EditRequestModalComponentResult {"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":" accountRequestName: string;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":" accountRequestEmail: string;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":" accountRequestInstitution: string;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" accountRequestComment: string;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":9}},{"path":"src/web/app/components/account-requests-table/admin-edit-request-modal/admin-edit-request-modal.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"\u003cdiv class\u003d\"modal-header bg-primary\"\u003e"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":" \u003ch5 class\u003d\"modal-title text-white\"\u003e"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003eEdit Account Request for {{ accountRequestName }}\u003c/div\u003e"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":" \u003c/h5\u003e"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn-close\" (click)\u003d\"activeModal.dismiss()\"\u003e\u003c/button\u003e"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":" \u003cdiv id\u003d\"reject-account-request-modal\" class\u003d\"modal-body\"\u003e"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003e"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":" \u003clabel\u003e\u003cb\u003eName:\u003c/b\u003e\u003c/label\u003e"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" \u003cinput id\u003d\"request-name\" type\u003d\"text\" class\u003d\"form-control\" value\u003d\"{{ accountRequestName }}\" (input)\u003d\"accountRequestName \u003d $event.target.value\"\u003e"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003e"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":" \u003clabel\u003e\u003cb\u003eEmail:\u003c/b\u003e\u003c/label\u003e"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":" \u003cinput id\u003d\"request-email\" type\u003d\"text\" class\u003d\"form-control\" value\u003d\"{{ accountRequestEmail }}\" (input)\u003d\"accountRequestEmail \u003d $event.target.value\"\u003e"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003e"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" \u003clabel\u003e\u003cb\u003eInstitution, Country:\u003c/b\u003e\u003c/label\u003e"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" \u003cinput id\u003d\"request-institution\" type\u003d\"text\" class\u003d\"form-control\" value\u003d\"{{ accountRequestInstitution }}\" (input)\u003d\"accountRequestInstitution \u003d $event.target.value\"\u003e"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"row\"\u003e"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003e"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" \u003clabel\u003e\u003cb\u003eComments:\u003c/b\u003e\u003c/label\u003e"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"form-group\"\u003e"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" \u003ctextarea id\u003d\"request-comments\" class\u003d\"form-control\" rows\u003d\"5\" value\u003d\"{{ accountRequestComments }}\" (input)\u003d\"accountRequestComments \u003d $event.target.value\"\u003e\u003c/textarea\u003e"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"modal-footer\"\u003e"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn btn-light\" (click)\u003d\"activeModal.dismiss()\"\u003eCancel\u003c/button\u003e"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"btn-confirm-edit-request\" type\u003d\"button\" class\u003d\"btn btn-primary\" (click)\u003d\"edit()\"\u003e"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" Save"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" \u003c/button\u003e"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"}],"authorContributionMap":{"domoberzin":34}},{"path":"src/web/app/components/account-requests-table/admin-edit-request-modal/admin-edit-request-modal.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"import { HttpClientTestingModule } from \u0027@angular/common/http/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":"import { ComponentFixture, TestBed, waitForAsync } from \u0027@angular/core/testing\u0027;"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import { NgbActiveModal } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import { EditRequestModalComponent } from \u0027./admin-edit-request-modal.component\u0027;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"describe(\u0027RejectWithReasonModal\u0027, () \u003d\u003e {"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":" let fixture: ComponentFixture\u003cEditRequestModalComponent\u003e;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" let component: EditRequestModalComponent;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" beforeEach(waitForAsync(() \u003d\u003e {"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" TestBed.configureTestingModule({"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":" declarations: [],"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":" imports: ["},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":" HttpClientTestingModule,"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" ],"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" providers: [NgbActiveModal],"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" })"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" .compileComponents();"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" }));"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" fixture \u003d TestBed.createComponent(EditRequestModalComponent);"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" expect(component).toBeTruthy();"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show empty fields\u0027, () \u003d\u003e {"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show populated data\u0027, () \u003d\u003e {"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" component.accountRequestName \u003d \u0027John Doe\u0027;"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" component.accountRequestEmail \u003d \u0027johndoe@email.com\u0027;"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" component.accountRequestInstitution \u003d \u0027NUS\u0027;"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" component.accountRequestComments \u003d \u0027Comments\u0027;"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" it(\u0027should close modal with data\u0027, () \u003d\u003e {"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" const spyActiveModal \u003d jest.spyOn(component.activeModal, \u0027close\u0027);"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" component.accountRequestName \u003d \u0027John Doe\u0027;"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" component.accountRequestEmail \u003d \u0027johndoe@email.com\u0027;"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" component.accountRequestInstitution \u003d \u0027NUS\u0027;"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" component.accountRequestComments \u003d \u0027Comments\u0027;"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" component.edit();"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" expect(spyActiveModal).toHaveBeenCalled();"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" expect(spyActiveModal).toHaveBeenCalledWith({"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" accountRequestName: \u0027John Doe\u0027,"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" accountRequestEmail: \u0027johndoe@email.com\u0027,"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" accountRequestInstitution: \u0027NUS\u0027,"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" accountRequestComment: \u0027Comments\u0027,"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":"});"}],"authorContributionMap":{"domoberzin":60}},{"path":"src/web/app/components/account-requests-table/admin-edit-request-modal/admin-edit-request-modal.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"import { Component, Input } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":"import { NgbActiveModal } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import { EditRequestModalComponentResult } from \u0027./admin-edit-request-modal-model\u0027;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":" * Modal to select reject account requests with reason."},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"@Component({"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":" selector: \u0027tm-edit-request-modal\u0027,"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" templateUrl: \u0027./admin-edit-request-modal.component.html\u0027,"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" styleUrls: [\u0027./admin-edit-request-modal.component.scss\u0027],"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"})"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"export class EditRequestModalComponent {"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" @Input()"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" accountRequestName: string \u003d \u0027\u0027;"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" @Input()"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" accountRequestEmail: string \u003d \u0027\u0027;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" @Input()"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" accountRequestInstitution: string \u003d \u0027\u0027;"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" @Input()"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" accountRequestComments: string \u003d \u0027\u0027;"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" constructor(public activeModal: NgbActiveModal) {}"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" * Fires the edit event."},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" edit(): void {"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" const result: EditRequestModalComponentResult \u003d {"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" accountRequestName: this.accountRequestName,"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" accountRequestEmail: this.accountRequestEmail,"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" accountRequestInstitution: this.accountRequestInstitution,"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" accountRequestComment: this.accountRequestComments,"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" this.activeModal.close(result);"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":40}},{"path":"src/web/app/components/account-requests-table/admin-reject-with-reason-modal/admin-reject-with-reason-modal-model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"export interface RejectWithReasonModalComponentResult {"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":" rejectionReasonTitle: string;"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":" rejectionReasonBody: string;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":4}},{"path":"src/web/app/components/account-requests-table/admin-reject-with-reason-modal/admin-reject-with-reason-modal.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"\u003cdiv class\u003d\"modal-header bg-warning\"\u003e"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":" \u003ch5 class\u003d\"modal-title\"\u003e"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003eReject Account Request for {{ accountRequestName }} With Reason\u003c/div\u003e"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":" \u003c/h5\u003e"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn-close\" (click)\u003d\"activeModal.dismiss()\"\u003e\u003c/button\u003e"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"\u003c/div\u003e"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"\u003cdiv id\u003d\"reject-account-request-modal\" class\u003d\"modal-body\"\u003e"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"row\"\u003e"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003e"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" \u003clabel\u003e\u003cb\u003eRejection Message Title:\u003c/b\u003e\u003c/label\u003e"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"form-group\"\u003e"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":" \u003cinput id\u003d\"rejection-reason-title\" type\u003d\"text\" class\u003d\"form-control\" rows\u003d\"5\" value\u003d\"{{ rejectionReasonTitle }}\" (input)\u003d\"rejectionReasonTitle \u003d $event.target.value\"\u003e"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003e"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" \u003clabel\u003e\u003cb\u003eRejection Message Body:\u003c/b\u003e\u003c/label\u003e"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" \u003ctm-rich-text-editor id\u003d\"rejection-reason-body\" [richText]\u003d\"rejectionReasonBody\" (richTextChange)\u003d\"onRejectionReasonBodyChange($event)\"\u003e\u003c/tm-rich-text-editor\u003e"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":"\u003c/div\u003e"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":"\u003cdiv class\u003d\"modal-footer\"\u003e"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"btn-cancel-reject-request\" type\u003d\"button\" class\u003d\"btn btn-light\" (click)\u003d\"activeModal.dismiss()\"\u003eCancel\u003c/button\u003e"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"btn-confirm-reject-request\" type\u003d\"button\" class\u003d\"btn btn-warning\" (click)\u003d\"reject()\"\u003e"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" Reject"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" \u003c/button\u003e"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"domoberzin":26}},{"path":"src/web/app/components/account-requests-table/admin-reject-with-reason-modal/admin-reject-with-reason-modal.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"import { HttpClientTestingModule } from \u0027@angular/common/http/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":"import { ComponentFixture, TestBed, waitForAsync } from \u0027@angular/core/testing\u0027;"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import { By } from \u0027@angular/platform-browser\u0027;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import { NgbActiveModal } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import { RejectWithReasonModalComponent } from \u0027./admin-reject-with-reason-modal.component\u0027;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import { StatusMessageService } from \u0027../../../../services/status-message.service\u0027;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"describe(\u0027RejectWithReasonModal\u0027, () \u003d\u003e {"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":" let statusMessageService: StatusMessageService;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" let fixture: ComponentFixture\u003cRejectWithReasonModalComponent\u003e;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" let component: RejectWithReasonModalComponent;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":" beforeEach(waitForAsync(() \u003d\u003e {"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":" TestBed.configureTestingModule({"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" declarations: [],"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" imports: ["},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" HttpClientTestingModule,"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" ],"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" providers: [NgbActiveModal, StatusMessageService],"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" })"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" .compileComponents();"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" }));"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" fixture \u003d TestBed.createComponent(RejectWithReasonModalComponent);"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" statusMessageService \u003d TestBed.inject(StatusMessageService);"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" expect(component).toBeTruthy();"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show empty title and body\u0027, () \u003d\u003e {"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show error message when title is empty upon submitting\u0027, () \u003d\u003e {"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" component.rejectionReasonTitle \u003d \u0027\u0027;"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" const spyStatusMessageService \u003d jest.spyOn(statusMessageService, \u0027showErrorToast\u0027)"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" .mockImplementation((args: string) \u003d\u003e {"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" expect(args).toEqual(\u0027Please provide a title for the rejection email.\u0027);"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" const rejectButton: any \u003d fixture.debugElement.query(By.css(\u0027#btn-confirm-reject-request\u0027));"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" rejectButton.nativeElement.click();"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" expect(spyStatusMessageService).toHaveBeenCalled();"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show error message when body is empty upon submitting\u0027, () \u003d\u003e {"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" component.rejectionReasonBody \u003d \u0027\u0027;"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" const spyStatusMessageService \u003d jest.spyOn(statusMessageService, \u0027showErrorToast\u0027)"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" .mockImplementation((args: string) \u003d\u003e {"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" expect(args).toEqual(\u0027Please provide an email body for the rejection email.\u0027);"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" const rejectButton: any \u003d fixture.debugElement.query(By.css(\u0027#btn-confirm-reject-request\u0027));"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" rejectButton.nativeElement.click();"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" expect(spyStatusMessageService).toHaveBeenCalled();"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":" it(\u0027should close modal with data\u0027, () \u003d\u003e {"},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" const spyActiveModal \u003d jest.spyOn(component.activeModal, \u0027close\u0027);"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" component.rejectionReasonTitle \u003d \u0027Rejection Title\u0027;"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" component.rejectionReasonBody \u003d \u0027Rejection Body\u0027;"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" component.reject();"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" expect(spyActiveModal).toHaveBeenCalled();"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" expect(spyActiveModal).toHaveBeenCalledWith({"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" rejectionReasonTitle: \u0027Rejection Title\u0027,"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" rejectionReasonBody: \u0027Rejection Body\u0027,"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":"});"}],"authorContributionMap":{"domoberzin":80}},{"path":"src/web/app/components/account-requests-table/admin-reject-with-reason-modal/admin-reject-with-reason-modal.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"import { Component, Input, OnInit } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":"import { NgbActiveModal } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import { RejectWithReasonModalComponentResult } from \u0027./admin-reject-with-reason-modal-model\u0027;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import { environment } from \u0027../../../../environments/environment\u0027;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import { StatusMessageService } from \u0027../../../../services/status-message.service\u0027;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" * Modal to select reject account requests with reason."},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"@Component({"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" selector: \u0027tm-reject-with-reason-modal\u0027,"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":" templateUrl: \u0027./admin-reject-with-reason-modal.component.html\u0027,"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":" styleUrls: [\u0027./admin-reject-with-reason-modal.component.scss\u0027],"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"})"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"export class RejectWithReasonModalComponent implements OnInit {"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" @Input()"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" accountRequestName: string \u003d \u0027\u0027;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" @Input()"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" accountRequestEmail: string \u003d \u0027\u0027;"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" rejectionReasonBody: string \u003d \u0027\u003cp\u003eHi, {accountRequestName} \u003c/p\u003e\\n\\n\u0027"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" + \u0027\u003cp\u003eThanks for your interest in using TEAMMATES. \u0027"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" + \u0027We are unable to create a TEAMMATES instructor account for you.\u003c/p\u003e\u0027"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" + \u0027\u003cp\u003e\u003cstrong\u003eReason:\u003c/strong\u003e The email address you provided is not an \u0026#39;official\u0026#39; \u0027"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" + \u0027email address provided by your institution.\u003cbr /\u003e\u0027"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" + \u0027\u003cstrong\u003eRemedy:\u003c/strong\u003e Please re-submit an account request with your \u0026#39;official\u0026#39; \u0027"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" + \u0027institution email address.\u003c/p\u003e\\n\\n\u0027"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" + \u0027\u003cp\u003e\u003cstrong\u003eReason:\u003c/strong\u003e The email address you have provided seems like it belongs to a student \u0027"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" + \u0027(i.e., not a staff member) of your institution.\u003cbr /\u003e\u0027"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" + \u0027\u003cstrong\u003eRemedy:\u003c/strong\u003e If you are a student but you still need an instructor account, \u0027"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" + \u0027please send your justification to {supportEmail}\u003c/p\u003e\\n\\n\u0027"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" + \u0027\u003cp\u003e\u003cstrong\u003eReason:\u003c/strong\u003e You already have an account for this email address and this institution.\u003cbr /\u003e\u0027"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" + \u0027\u003cstrong\u003eRemedy:\u003c/strong\u003e You can login to TEAMMATES using your Google account {existingEmail} \u003c/p\u003e\\n\\n\u0027"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" + \u0027\u003cp\u003eIf you need further clarification or would like to appeal this decision, please \u0027"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" + \u0027feel free to contact us at {supportEmail}\u003c/p\u003e\u0027"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" + \u0027\u003cp\u003eRegards,\u003cbr /\u003eTEAMMATES Team.\u003c/p\u003e\u0027;"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" rejectionReasonTitle: string \u003d \u0027We are Unable to Create an Account for you\u0027;"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" constructor(public activeModal: NgbActiveModal, public statusMessageService: StatusMessageService) {}"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" ngOnInit(): void {"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" this.rejectionReasonBody \u003d this.rejectionReasonBody.replace(\u0027{accountRequestName}\u0027, this.accountRequestName);"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" this.rejectionReasonBody \u003d this.rejectionReasonBody.replace(\u0027{existingEmail}\u0027, this.accountRequestEmail);"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" this.rejectionReasonBody \u003d this.rejectionReasonBody.replaceAll(\u0027{supportEmail}\u0027, environment.supportEmail);"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" onRejectionReasonBodyChange(updatedText: string): void {"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" this.rejectionReasonBody \u003d updatedText;"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" * Fires the reject event."},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" reject(): void {"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" if (!this.rejectionReasonBody || this.rejectionReasonBody.length \u003d\u003d\u003d 0) {"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showErrorToast(\u0027Please provide an email body for the rejection email.\u0027);"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" return;"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" if (!this.rejectionReasonTitle || this.rejectionReasonTitle.length \u003d\u003d\u003d 0) {"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showErrorToast(\u0027Please provide a title for the rejection email.\u0027);"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":" return;"},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" const result: RejectWithReasonModalComponentResult \u003d {"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" rejectionReasonTitle: this.rejectionReasonTitle,"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" rejectionReasonBody: this.rejectionReasonBody,"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" this.activeModal.close(result);"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":76}},{"path":"src/web/app/components/comment-box/comment-row/comment-row.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003ctm-comment-edit-form *ngIf\u003d\"model.isEditing || mode \u003d\u003d\u003d CommentRowMode.ADD\""},{"lineNumber":2,"author":{"gitId":"-"},"content":" [mode]\u003d\"mode\""},{"lineNumber":3,"author":{"gitId":"-"},"content":" [model]\u003d\"model.commentEditFormModel\""},{"lineNumber":4,"author":{"gitId":"-"},"content":" (modelChange)\u003d\"triggerModelChange(\u0027commentEditFormModel\u0027, $event)\""},{"lineNumber":5,"author":{"gitId":"-"},"content":" [isVisibilityOptionEnabled]\u003d\"isVisibilityOptionEnabled\""},{"lineNumber":6,"author":{"gitId":"-"},"content":" [isDisabled]\u003d\"isDisabled\""},{"lineNumber":7,"author":{"gitId":"-"},"content":" [shouldHideSavingButton]\u003d\"shouldHideSavingButton\""},{"lineNumber":8,"author":{"gitId":"-"},"content":" [questionShowResponsesTo]\u003d\"questionShowResponsesTo\""},{"lineNumber":9,"author":{"gitId":"-"},"content":" [response]\u003d\"response\""},{"lineNumber":10,"author":{"gitId":"-"},"content":" [isFeedbackParticipantComment]\u003d\"isFeedbackParticipantComment\""},{"lineNumber":11,"author":{"gitId":"-"},"content":" [shouldHideClosingButton]\u003d\"shouldHideClosingButton\""},{"lineNumber":12,"author":{"gitId":"-"},"content":" (closeCommentBoxEvent)\u003d\"triggerCloseEditing()\""},{"lineNumber":13,"author":{"gitId":"-"},"content":" (saveCommentEvent)\u003d\"triggerSaveCommentEvent()\"\u003e\u003c/tm-comment-edit-form\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"card\" *ngIf\u003d\"!model.isEditing \u0026\u0026 mode \u003d\u003d\u003d CommentRowMode.EDIT \u0026\u0026 model.originalComment\"\u003e"},{"lineNumber":16,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row comment-row\"\u003e"},{"lineNumber":18,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":19,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"by-response-giver text-secondary\" *ngIf\u003d\"isFeedbackParticipantComment\"\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" Comment by response giver."},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":22,"author":{"gitId":"yuanxi1"},"content":" \u003cng-container class\u003d\"text-secondary\" *ngIf\u003d\"!isFeedbackParticipantComment\"\u003e"},{"lineNumber":23,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"comment-giver-name\"\u003e{{ model.commentGiverName ? model.commentGiverName : model.originalComment.commentGiver }} commented at \u003c/span\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"ngb-tooltip-class\" style\u003d\"margin-right: .25rem;\" [ngbTooltip]\u003d\"model.originalComment.createdAt | formatDateDetail: model.timezone!\"\u003e"},{"lineNumber":25,"author":{"gitId":"-"},"content":" {{ model.originalComment.createdAt | formatDateBrief: model.timezone! }}\u003c/span\u003e"},{"lineNumber":26,"author":{"gitId":"-"},"content":" \u003cng-container *ngIf\u003d\"model.originalComment.lastEditedAt \u0026\u0026 model.originalComment.lastEditedAt !\u003d\u003d model.originalComment.createdAt\"\u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-circle dot-xs align-middle\" style\u003d\"margin-right: .25rem;\"\u003e\u003c/i\u003e"},{"lineNumber":28,"author":{"gitId":"-"},"content":" \u003cspan id\u003d\"last-editor-name\" style\u003d\"margin-right: .25rem;\" class\u003d\"ngb-tooltip-class\""},{"lineNumber":29,"author":{"gitId":"-"},"content":" [ngbTooltip]\u003d\"model.originalComment.lastEditedAt | formatDateDetail: model.timezone!\"\u003eedited by {{ model.lastEditorName ? model.lastEditorName : model.originalComment.lastEditorEmail }}\u003c/span\u003e"},{"lineNumber":30,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":31,"author":{"gitId":"yuanxi1"},"content":" \u003c/ng-container\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fa fa-eye\" aria-hidden\u003d\"true\" ngbTooltip\u003d\"This response comment is visible to {{ visibilityStateMachine.getVisibilityTypesUnderVisibilityControl(CommentVisibilityControl.SHOW_COMMENT) | commentVisibilityTypesJointName }}\"\u003e\u003c/i\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"float-end\"\u003e"},{"lineNumber":36,"author":{"gitId":"-"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn-edit-comment btn btn-outline-primary btn-sm\" *ngIf\u003d\"!shouldHideEditButton\" ngbTooltip\u003d\u0027Edit this comment\u0027"},{"lineNumber":37,"author":{"gitId":"-"},"content":" (click)\u003d\"triggerModelChange(\u0027isEditing\u0027, true)\" [disabled]\u003d\"isDisabled\"\u003e\u003ci class\u003d\"fas fa-pencil-alt\"\u003e\u003c/i\u003e\u003c/button\u003e"},{"lineNumber":38,"author":{"gitId":"-"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn-delete-comment btn btn-outline-primary btn-sm btn-margin-left\" *ngIf\u003d\"!shouldHideDeleteButton\" ngbTooltip\u003d\u0027Delete this comment\u0027"},{"lineNumber":39,"author":{"gitId":"-"},"content":" (click)\u003d\"triggerDeleteCommentEvent()\" [disabled]\u003d\"isDisabled\"\u003e\u003ci class\u003d\"fas fa-trash\"\u003e\u003c/i\u003e\u003c/button\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"comment-text col-12\" [innerHTML]\u003d\"model.originalComment.commentText | safeHtml\"\u003e\u003c/div\u003e"},{"lineNumber":43,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":45,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"yuanxi1":2,"-":43}},{"path":"src/web/app/components/notification-banner/notification-banner.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"yuanxi1"},"content":"\u003cdiv id\u003d\"notification-banner\" class\u003d\"banner\" [ngClass]\u003d\"notifications[0].style | notificationStyleClass\" *ngIf\u003d\"isShown \u0026\u0026 notifications.length \u003e 0\" [attr.data-testid]\u003d\"notifications[0].notificationId\" @collapseAnim\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-close-notif\" type\u003d\"button\" class\u003d\"btn-close\" aria-label\u003d\"Close\" (click)\u003d\"closeNotification()\"\u003e\u003c/button\u003e"},{"lineNumber":3,"author":{"gitId":"-"},"content":" \u003ch5\u003e{{ notifications[0].title }}\u003c/h5\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"banner-text\" [innerHTML]\u003d\"notifications[0].message\"\u003e\u003c/div\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"d-flex flex-row-reverse mt-3 me-2\"\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-mark-as-read\" type\u003d\"button\" [ngClass]\u003d\"getButtonClass(notifications[0])\" (click)\u003d\"markNotificationAsRead(notifications[0])\"\u003e"},{"lineNumber":7,"author":{"gitId":"-"},"content":" Mark as Read"},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":9,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"yuanxi1":1,"-":9}},{"path":"src/web/app/components/session-edit-form/session-edit-form.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cdiv id\u003d\"session-edit-form\" class\u003d\"card card-plain\"\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"close-header\" *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.ADD\"\u003e"},{"lineNumber":3,"author":{"gitId":"-"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn-close\" aria-label\u003d\"Close\" (click)\u003d\"closeEditFormHandler()\"\u003e\u003c/button\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row\" *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.ADD\"\u003e"},{"lineNumber":7,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-lg-7\"\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row mb-2\"\u003e"},{"lineNumber":9,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 col-sm-3 session-heading-text\"\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003ch5\u003eCreate new\u003c/h5\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 col-sm-9 create-new-dropdown-div\"\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003cselect id\u003d\"session-type\" class\u003d\"form-control form-select\" [ngModel]\u003d\"model.templateSessionName\" (ngModelChange)\u003d\"triggerModelChange(\u0027templateSessionName\u0027, $event)\"\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":" \u003coption *ngFor\u003d\"let templateSession of templateSessions\" [ngValue]\u003d\"templateSession.name\"\u003e{{ templateSession.name }}\u003c/option\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":" \u003c/select\u003e"},{"lineNumber":16,"author":{"gitId":"-"},"content":" \u003ca type\u003d\"button\" class\u003d\"btn btn-link\" tmRouterLink\u003d\"/web/instructor/help\" [queryParams]\u003d\"{ questionId: \u0027sessions\u0027, section: \u0027sessions\u0027 }\" target\u003d\"_blank\" aria-label\u003d\"Help for feedback sessions\"\u003e\u003ci class\u003d\"fas fa-info-circle\"\u003e\u003c/i\u003e\u003c/a\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":18,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":19,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-lg-5\"\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row\"\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 col-sm-3 col-lg-1 session-heading-text\"\u003e"},{"lineNumber":23,"author":{"gitId":"-"},"content":" \u003ch5\u003eOr\u003c/h5\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 col-sm-9 col-lg-11 text-md-start\"\u003e"},{"lineNumber":26,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-copy-session\" type\u003d\"button\" class\u003d\"btn btn-info\" (click)\u003d\"copyOthersHandler()\"\u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003cspan\u003eCopy from previous feedback sessions\u003c/span\u003e"},{"lineNumber":28,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"padding-left-7px\"\u003e"},{"lineNumber":29,"author":{"gitId":"-"},"content":" \u003ctm-ajax-loading *ngIf\u003d\"isCopyOtherSessionLoading\"\u003e\u003c/tm-ajax-loading\u003e"},{"lineNumber":30,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":31,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":36,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row\" *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.EDIT\"\u003e"},{"lineNumber":37,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 text-center text-md-end session-form-buttons\"\u003e"},{"lineNumber":38,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-fs-edit\" type\u003d\"button\" class\u003d\"btn btn-primary\" (click)\u003d\"triggerModelChange(\u0027isEditable\u0027, true)\" *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.EDIT \u0026\u0026 !model.isEditable \u0026\u0026 !model.isSaving\"\u003e\u003ci class\u003d\"fas fa-pencil-alt\"\u003e\u003c/i\u003e Edit\u003c/button\u003e"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-fs-save\" type\u003d\"button\" class\u003d\"btn btn-primary\" (click)\u003d\"submitFormHandler()\" [disabled]\u003d\"model.isSaving\" *ngIf\u003d\"model.isEditable || model.isSaving\"\u003e\u003ctm-ajax-loading *ngIf\u003d\"model.isSaving\"\u003e\u003c/tm-ajax-loading\u003e \u003ci class\u003d\"fas fa-check\"\u003e\u003c/i\u003e Save\u003c/button\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn btn-primary\" ngbTooltip\u003d\"Discard changes to the feedback session\" (click)\u003d\"cancelHandler()\" *ngIf\u003d\"model.isEditable\" [disabled]\u003d\"model.isSaving\"\u003e\u003ci class\u003d\"fas fa-ban\"\u003e\u003c/i\u003e Cancel\u003c/button\u003e"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-fs-delete\" type\u003d\"button\" class\u003d\"btn btn-primary\" ngbTooltip\u003d\"Delete the feedback session\" (click)\u003d\"deleteHandler()\" [disabled]\u003d\"model.isSaving\"\u003e\u003ctm-ajax-loading *ngIf\u003d\"model.isDeleting\"\u003e\u003c/tm-ajax-loading\u003e\u003ci class\u003d\"fas fa-trash\"\u003e\u003c/i\u003e Delete\u003c/button\u003e"},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-fs-copy\" type\u003d\"button\" class\u003d\"btn btn-primary\" ngbTooltip\u003d\"Copy this feedback session to other courses\" (click)\u003d\"copyHandler()\" [disabled]\u003d\"model.isSaving\"\u003e\u003ctm-ajax-loading *ngIf\u003d\"model.isCopying\"\u003e\u003c/tm-ajax-loading\u003e\u003ci class\u003d\"far fa-copy\"\u003e\u003c/i\u003e Copy\u003c/button\u003e"},{"lineNumber":43,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card border-primary margin-top-20px\"\u003e"},{"lineNumber":47,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":48,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\"\u003e"},{"lineNumber":49,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2 text-md-end font-bold\" [ngClass]\u003d\"{\u0027col-form-label\u0027: formMode \u003d\u003d\u003d SessionEditFormMode.ADD}\"\u003e"},{"lineNumber":50,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"ngb-tooltip-class\" ngbTooltip\u003d\"Course for which the feedback session is for.\"\u003eCourse ID\u003c/span\u003e"},{"lineNumber":51,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":52,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-auto text-md-start\"\u003e"},{"lineNumber":53,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.ADD\"\u003e"},{"lineNumber":54,"author":{"gitId":"-"},"content":" \u003cselect id\u003d\"add-course-id\" class\u003d\"form-control form-select\" [ngClass]\u003d\"{\u0027is-invalid\u0027: courseCandidates.length \u003d\u003d\u003d 0}\" [ngModel]\u003d\"model.courseId\" (ngModelChange)\u003d\"courseIdChangeHandler($event)\" [disabled]\u003d\"courseCandidates.length \u003d\u003d\u003d 0\"\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":" \u003coption *ngFor\u003d\"let course of courseCandidates\" [ngValue]\u003d\"course.courseId\"\u003e{{ course.courseId }}\u003c/option\u003e"},{"lineNumber":56,"author":{"gitId":"-"},"content":" \u003c/select\u003e"},{"lineNumber":57,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"invalid-feedback\" *ngIf\u003d\"courseCandidates.length \u003d\u003d\u003d 0\"\u003e"},{"lineNumber":58,"author":{"gitId":"-"},"content":" There is no un-archived course."},{"lineNumber":59,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":60,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":61,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"edit-course-id\" *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.EDIT\"\u003e {{ model.courseId }} \u003c/div\u003e"},{"lineNumber":62,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":63,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":64,"author":{"gitId":"-"},"content":" \u003cbr/\u003e"},{"lineNumber":65,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\"\u003e"},{"lineNumber":66,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2 text-md-end font-bold\" [ngClass]\u003d\"{\u0027col-form-label\u0027: formMode \u003d\u003d\u003d SessionEditFormMode.ADD}\"\u003e"},{"lineNumber":67,"author":{"gitId":"-"},"content":" Time Zone"},{"lineNumber":68,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":69,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"time-zone\" class\u003d\"col-md-3 text-md-start\" [ngClass]\u003d\"{\u0027col-form-label\u0027: formMode \u003d\u003d\u003d SessionEditFormMode.ADD}\"\u003e"},{"lineNumber":70,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"ngb-tooltip-class\" ngbTooltip\u003d\"To change this, edit the course settings. TEAMMATES automatically adjusts to match the current time offset in your area, including clock changes due to daylight saving time.\"\u003e{{ model.timeZone }}\u003c/span\u003e"},{"lineNumber":71,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":72,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":73,"author":{"gitId":"-"},"content":" \u003cbr/\u003e"},{"lineNumber":74,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\"\u003e"},{"lineNumber":75,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2 text-md-end font-bold\"\u003e"},{"lineNumber":76,"author":{"gitId":"-"},"content":" Course Name"},{"lineNumber":77,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":78,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"course-name\" class\u003d\"col-md-10 text-md-start\"\u003e"},{"lineNumber":79,"author":{"gitId":"-"},"content":" {{ model.courseName }}"},{"lineNumber":80,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":81,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":82,"author":{"gitId":"-"},"content":" \u003cbr/\u003e"},{"lineNumber":83,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\"\u003e"},{"lineNumber":84,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2 text-md-end font-bold\"\u003e"},{"lineNumber":85,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.ADD\" class\u003d\"ngb-tooltip-class\" ngbTooltip\u003d\"Enter the name of the feedback session e.g. Feedback Session 1.\"\u003eSession Name*\u003c/span\u003e"},{"lineNumber":86,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"formMode !\u003d\u003d SessionEditFormMode.ADD\"\u003eSession Name\u003c/span\u003e"},{"lineNumber":87,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":88,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-10 text-md-start\"\u003e"},{"lineNumber":89,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.ADD\"\u003e"},{"lineNumber":90,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"add-session-name\" type\u003d\"text\" class\u003d\"form-control\" [ngModel]\u003d\"model.feedbackSessionName\" (ngModelChange)\u003d\"triggerModelChange(\u0027feedbackSessionName\u0027, $event)\" placeholder\u003d\"e.g. Feedback for Project Presentation 1\" maxlength\u003d\"64\" required #sessionName\u003d\"ngModel\" /\u003e"},{"lineNumber":91,"author":{"gitId":"-"},"content":" \u003cdiv [hidden]\u003d\"sessionName.valid || (sessionName.pristine \u0026\u0026 sessionName.untouched)\" class\u003d\"invalid-field\"\u003e"},{"lineNumber":92,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fa fa-exclamation-circle\" aria-hidden\u003d\"true\"\u003e\u003c/i\u003e"},{"lineNumber":93,"author":{"gitId":"-"},"content":" The field Session Name should not be empty."},{"lineNumber":94,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":95,"author":{"gitId":"-"},"content":" \u003cdiv\u003e"},{"lineNumber":96,"author":{"gitId":"-"},"content":" {{FEEDBACK_SESSION_NAME_MAX_LENGTH - model.feedbackSessionName.length}} characters left"},{"lineNumber":97,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":98,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":99,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"edit-session-name\" *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.EDIT\"\u003e {{ model.feedbackSessionName }} \u003c/div\u003e"},{"lineNumber":100,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":101,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":102,"author":{"gitId":"-"},"content":" \u003cbr/\u003e"},{"lineNumber":103,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\"\u003e"},{"lineNumber":104,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2 text-md-end font-bold\"\u003e"},{"lineNumber":105,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"ngb-tooltip-class\" ngbTooltip\u003d\"Will be displayed at the top of the page when users respond to the session.\"\u003eInstructions\u003c/span\u003e"},{"lineNumber":106,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":107,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-10 text-md-start\"\u003e"},{"lineNumber":108,"author":{"gitId":"-"},"content":" \u003ctm-rich-text-editor id\u003d\"instructions\" [richText]\u003d\"model.instructions\" (richTextChange)\u003d\"triggerModelChange(\u0027instructions\u0027, $event)\" [isDisabled]\u003d\"!model.isEditable\" [hasCharacterLimit]\u003d\"true\"\u003e\u003c/tm-rich-text-editor\u003e"},{"lineNumber":109,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":110,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":111,"author":{"gitId":"-"},"content":" \u003cbr/\u003e"},{"lineNumber":112,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\" *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.EDIT\"\u003e"},{"lineNumber":113,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2 text-md-end font-bold\"\u003e"},{"lineNumber":114,"author":{"gitId":"-"},"content":" Submission Status"},{"lineNumber":115,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":116,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"submission-status\" class\u003d\"col-md-4 text-md-start\"\u003e"},{"lineNumber":117,"author":{"gitId":"-"},"content":" {{ model.submissionStatus | submissionStatusName }}"},{"lineNumber":118,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":119,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2 text-md-end font-bold mt-3 mt-md-0\"\u003e"},{"lineNumber":120,"author":{"gitId":"-"},"content":" Published Status"},{"lineNumber":121,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":122,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"published-status\" class\u003d\"col-md-4 text-md-start\"\u003e"},{"lineNumber":123,"author":{"gitId":"-"},"content":" {{ model.publishStatus | publishStatusName }}"},{"lineNumber":124,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":125,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":126,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":127,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card border-primary margin-top-20px\"\u003e"},{"lineNumber":130,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":131,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\"\u003e"},{"lineNumber":132,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-4\"\u003e"},{"lineNumber":133,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 text-md-start\"\u003e"},{"lineNumber":134,"author":{"gitId":"-"},"content":" \u003cdiv\u003e"},{"lineNumber":135,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"ngb-tooltip-class label-control font-bold\" ngbTooltip\u003d\"Users can start submitting responses.\"\u003e"},{"lineNumber":136,"author":{"gitId":"-"},"content":" Submission opening time"},{"lineNumber":137,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":138,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":139,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":140,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center align-items-center\"\u003e"},{"lineNumber":141,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"submission-start-date\" class\u003d\"col-md-7 col-xs-center\"\u003e"},{"lineNumber":142,"author":{"gitId":"-"},"content":" \u003ctm-datepicker [isDisabled]\u003d\"!model.isEditable\" (dateChangeCallback)\u003d\"triggerSubmissionOpeningDateModelChange(\u0027submissionStartDate\u0027, $event)\""},{"lineNumber":143,"author":{"gitId":"-"},"content":" [minDate]\u003d\"minDateForSubmissionStart\" [maxDate]\u003d\"maxDateForSubmissionStart\""},{"lineNumber":144,"author":{"gitId":"-"},"content":" [date]\u003d\"model.submissionStartDate\"\u003e\u003c/tm-datepicker\u003e"},{"lineNumber":145,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":146,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-5\"\u003e"},{"lineNumber":147,"author":{"gitId":"-"},"content":" \u003ctm-timepicker id\u003d\"submission-start-time\" [isDisabled]\u003d\"!model.isEditable\" (timeChange)\u003d\"triggerModelChange(\u0027submissionStartTime\u0027, $event)\""},{"lineNumber":148,"author":{"gitId":"-"},"content":" [minDate]\u003d\"minDateForSubmissionStart\" [maxDate]\u003d\"maxDateForSubmissionStart\""},{"lineNumber":149,"author":{"gitId":"-"},"content":" [date]\u003d\"model.submissionStartDate\""},{"lineNumber":150,"author":{"gitId":"-"},"content":" [minTime]\u003d\"minTimeForSubmissionStart\" [maxTime]\u003d\"maxTimeForSubmissionStart\""},{"lineNumber":151,"author":{"gitId":"-"},"content":" [time]\u003d\"model.submissionStartTime\"\u003e\u003c/tm-timepicker\u003e"},{"lineNumber":152,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":153,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":154,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":155,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-4 border-left-gray\"\u003e"},{"lineNumber":156,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\"\u003e"},{"lineNumber":157,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 text-md-start ms-md-2\"\u003e"},{"lineNumber":158,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"ngb-tooltip-class label-control font-bold\" ngbTooltip\u003d\"No more submissions from users.\"\u003e"},{"lineNumber":159,"author":{"gitId":"-"},"content":" Submission closing time"},{"lineNumber":160,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":161,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":162,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":163,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row align-items-center\"\u003e"},{"lineNumber":164,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"submission-end-date\" class\u003d\"col-md-7 col-xs-center\"\u003e"},{"lineNumber":165,"author":{"gitId":"-"},"content":" \u003ctm-datepicker [isDisabled]\u003d\"!model.isEditable\" (dateChangeCallback)\u003d\"triggerModelChange(\u0027submissionEndDate\u0027, $event)\""},{"lineNumber":166,"author":{"gitId":"-"},"content":" [minDate]\u003d\"minDateForSubmissionEnd\" [maxDate]\u003d\"maxDateForSubmissionEnd\""},{"lineNumber":167,"author":{"gitId":"-"},"content":" [date]\u003d\"model.submissionEndDate\"\u003e\u003c/tm-datepicker\u003e"},{"lineNumber":168,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":169,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-5\"\u003e"},{"lineNumber":170,"author":{"gitId":"-"},"content":" \u003ctm-timepicker id\u003d\"submission-end-time\" [isDisabled]\u003d\"!model.isEditable\" (timeChange)\u003d\"triggerModelChange(\u0027submissionEndTime\u0027, $event)\""},{"lineNumber":171,"author":{"gitId":"-"},"content":" [minDate]\u003d\"minDateForSubmissionEnd\" [maxDate]\u003d\"maxDateForSubmissionEnd\""},{"lineNumber":172,"author":{"gitId":"-"},"content":" [date]\u003d\"model.submissionEndDate\""},{"lineNumber":173,"author":{"gitId":"-"},"content":" [minTime]\u003d\"minTimeForSubmissionEnd\" [maxTime]\u003d\"maxTimeForSubmissionEnd\""},{"lineNumber":174,"author":{"gitId":"-"},"content":" [time]\u003d\"model.submissionEndTime\"\u003e\u003c/tm-timepicker\u003e"},{"lineNumber":175,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":176,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":177,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":178,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-4 border-left-gray\"\u003e"},{"lineNumber":179,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\"\u003e"},{"lineNumber":180,"author":{"gitId":"nknguyenhc"},"content":" \u003cdiv class\u003d\"col-12 text-md-start ms-md-2\"\u003e"},{"lineNumber":181,"author":{"gitId":"nknguyenhc"},"content":" \u003clabel for\u003d\"grace-period\" class\u003d\"ngb-tooltip-class control-label font-bold\" ngbTooltip\u003d\"Amount of time the system will continue accepting submissions after the specified deadline.\"\u003e"},{"lineNumber":182,"author":{"gitId":"-"},"content":" Grace period"},{"lineNumber":183,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":184,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":185,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":186,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\"\u003e"},{"lineNumber":187,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":188,"author":{"gitId":"-"},"content":" \u003cselect id\u003d\"grace-period\" class\u003d\"form-control form-select\" [ngModel]\u003d\"model.gracePeriod\" (ngModelChange)\u003d\"triggerModelChange(\u0027gracePeriod\u0027, $event)\" [disabled]\u003d\"!model.isEditable\"\u003e"},{"lineNumber":189,"author":{"gitId":"-"},"content":" \u003coption *ngFor\u003d\"let graceMinute of [0, 5, 10, 15, 20, 25, 30]\" [ngValue]\u003d\"graceMinute\"\u003e{{ graceMinute + \u0027 min\u0027}}\u003c/option\u003e"},{"lineNumber":190,"author":{"gitId":"-"},"content":" \u003c/select\u003e"},{"lineNumber":191,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":192,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":193,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row\"\u003e"},{"lineNumber":194,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"ps-3 pt-2\""},{"lineNumber":195,"author":{"gitId":"-"},"content":" *ngIf\u003d\"formMode !\u003d\u003d SessionEditFormMode.ADD\""},{"lineNumber":196,"author":{"gitId":"-"},"content":" tmRouterLink\u003d\"/web/instructor/sessions/individual-extension\""},{"lineNumber":197,"author":{"gitId":"-"},"content":" [queryParams]\u003d\"{ courseid: model.courseId, fsname: model.feedbackSessionName, preselectnonsubmitters: false }\"\u003e"},{"lineNumber":198,"author":{"gitId":"-"},"content":" Individual Deadline Extensions"},{"lineNumber":199,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-edit\"\u003e\u003c/i\u003e"},{"lineNumber":200,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":201,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"ps-3 pt-2 disabled-link ngb-tooltip-class\""},{"lineNumber":202,"author":{"gitId":"-"},"content":" *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.ADD\""},{"lineNumber":203,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"You must save the new session before setting individual deadline extensions\"\u003e"},{"lineNumber":204,"author":{"gitId":"-"},"content":" Individual Deadline Extensions"},{"lineNumber":205,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-edit\"\u003e\u003c/i\u003e"},{"lineNumber":206,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":207,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":208,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":209,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":210,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":211,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":212,"author":{"gitId":"-"},"content":""},{"lineNumber":213,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"!model.hasVisibleSettingsPanelExpanded\" class\u003d\"margin-top-20px\"\u003e"},{"lineNumber":214,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"text-muted\"\u003eSession is visible at submission opening time, responses are only visible when you publish the results.\u003c/span\u003e"},{"lineNumber":215,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-change-visibility\" type\u003d\"button\" class\u003d\"btn btn-link\" (click)\u003d\"triggerModelChange(\u0027hasVisibleSettingsPanelExpanded\u0027, true)\" [disabled]\u003d\"!model.isEditable\"\u003e[Change]\u003c/button\u003e"},{"lineNumber":216,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":217,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card border-primary margin-top-20px\" *ngIf\u003d\"model.hasVisibleSettingsPanelExpanded\" @collapseAnim\u003e"},{"lineNumber":218,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":219,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row align-items-start\"\u003e"},{"lineNumber":220,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-6 text-center text-md-start\"\u003e"},{"lineNumber":221,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row ms-md-1\"\u003e"},{"lineNumber":222,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":223,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"ngb-tooltip-class label-control font-bold\" ngbTooltip\u003d\"Session can be visible before it is open for submissions so that users can preview the questions.\"\u003eMake session visible \u003c/label\u003e"},{"lineNumber":224,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":225,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":226,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row mt-md-2 ms-md-1\"\u003e"},{"lineNumber":227,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2 mt-md-1\"\u003e"},{"lineNumber":228,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"form-check\"\u003e"},{"lineNumber":229,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"form-check-label\"\u003e"},{"lineNumber":230,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"session-visibility-custom\" class\u003d\"form-check-input\" type\u003d\"radio\" name\u003d\"sessionVisibleRadio\" [value]\u003d\"SessionVisibleSetting.CUSTOM\" [ngModel]\u003d\"model.sessionVisibleSetting\" (ngModelChange)\u003d\"triggerModelChange(\u0027sessionVisibleSetting\u0027, $event)\" [disabled]\u003d\"!model.isEditable\"\u003e"},{"lineNumber":231,"author":{"gitId":"-"},"content":" At"},{"lineNumber":232,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":233,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":234,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":235,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"session-visibility-date\" class\u003d\"col-md-6\"\u003e"},{"lineNumber":236,"author":{"gitId":"-"},"content":" \u003ctm-datepicker [isDisabled]\u003d\"model.sessionVisibleSetting !\u003d\u003d SessionVisibleSetting.CUSTOM || !model.isEditable\""},{"lineNumber":237,"author":{"gitId":"-"},"content":" (dateChangeCallback)\u003d\"triggerModelChange(\u0027customSessionVisibleDate\u0027, $event)\""},{"lineNumber":238,"author":{"gitId":"-"},"content":" [minDate]\u003d\"minDateForSessionVisible\" [maxDate]\u003d\"maxDateForSessionVisible\""},{"lineNumber":239,"author":{"gitId":"-"},"content":" [date]\u003d\"model.customSessionVisibleDate\"\u003e\u003c/tm-datepicker\u003e"},{"lineNumber":240,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":241,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-4\"\u003e"},{"lineNumber":242,"author":{"gitId":"-"},"content":" \u003ctm-timepicker id\u003d\"session-visibility-time\" [isDisabled]\u003d\"model.sessionVisibleSetting !\u003d\u003d SessionVisibleSetting.CUSTOM || !model.isEditable\" (timeChange)\u003d\"triggerModelChange(\u0027customSessionVisibleTime\u0027, $event)\""},{"lineNumber":243,"author":{"gitId":"-"},"content":" [minDate]\u003d\"minDateForSessionVisible\" [maxDate]\u003d\"maxDateForSessionVisible\""},{"lineNumber":244,"author":{"gitId":"-"},"content":" [date]\u003d\"model.customSessionVisibleDate\""},{"lineNumber":245,"author":{"gitId":"-"},"content":" [minTime]\u003d\"minTimeForSessionVisible\" [maxTime]\u003d\"maxTimeForSessionVisible\""},{"lineNumber":246,"author":{"gitId":"-"},"content":" [time]\u003d\"model.customSessionVisibleTime\" \u003e\u003c/tm-timepicker\u003e"},{"lineNumber":247,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":248,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":249,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row mt-md-1 ms-md-3\"\u003e"},{"lineNumber":250,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 form-check\"\u003e"},{"lineNumber":251,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"form-check-label\"\u003e"},{"lineNumber":252,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"session-visibility-at-open\" class\u003d\"form-check-input\" type\u003d\"radio\" name\u003d\"sessionVisibleRadio\" [value]\u003d\"SessionVisibleSetting.AT_OPEN\" [ngModel]\u003d\"model.sessionVisibleSetting\" (ngModelChange)\u003d\"triggerModelChange(\u0027sessionVisibleSetting\u0027, $event)\" [disabled]\u003d\"!model.isEditable\"\u003e"},{"lineNumber":253,"author":{"gitId":"-"},"content":" Submission opening time"},{"lineNumber":254,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":255,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":256,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":257,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":258,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-6 sessionVisibleRadio border-left-gray text-center text-md-start\"\u003e"},{"lineNumber":259,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row ms-md-1\"\u003e"},{"lineNumber":260,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":261,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"ngb-tooltip-class label-control font-bold\" ngbTooltip\u003d\"Make responses for the feedback session visible to designated recipients.\"\u003eMake response visible \u003c/label\u003e"},{"lineNumber":262,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":263,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":264,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row mt-md-2 ms-md-1\"\u003e"},{"lineNumber":265,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2 mt-md-1\"\u003e"},{"lineNumber":266,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"form-check\"\u003e"},{"lineNumber":267,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"form-check-label\"\u003e"},{"lineNumber":268,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"response-visibility-custom\" class\u003d\"form-check-input\" type\u003d\"radio\" name\u003d\"responseVisibleRadio\" [value]\u003d\"ResponseVisibleSetting.CUSTOM\" [ngModel]\u003d\"model.responseVisibleSetting\" (ngModelChange)\u003d\"triggerModelChange(\u0027responseVisibleSetting\u0027, $event)\" [disabled]\u003d\"!model.isEditable\"/\u003e"},{"lineNumber":269,"author":{"gitId":"-"},"content":" At"},{"lineNumber":270,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":271,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":272,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":273,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"response-visibility-date\" class\u003d\"col-md-6\"\u003e"},{"lineNumber":274,"author":{"gitId":"-"},"content":" \u003ctm-datepicker [isDisabled]\u003d\"model.responseVisibleSetting !\u003d\u003d ResponseVisibleSetting.CUSTOM || !model.isEditable\""},{"lineNumber":275,"author":{"gitId":"-"},"content":" (dateChangeCallback)\u003d\"triggerModelChange(\u0027customResponseVisibleDate\u0027, $event)\""},{"lineNumber":276,"author":{"gitId":"-"},"content":" [minDate]\u003d\"minDateForResponseVisible\" [date]\u003d\"model.customResponseVisibleDate\"\u003e\u003c/tm-datepicker\u003e"},{"lineNumber":277,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":278,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-4\"\u003e"},{"lineNumber":279,"author":{"gitId":"-"},"content":" \u003ctm-timepicker id\u003d\"response-visibility-time\" [isDisabled]\u003d\"model.responseVisibleSetting !\u003d\u003d ResponseVisibleSetting.CUSTOM || !model.isEditable\" (timeChange)\u003d\"triggerModelChange(\u0027customResponseVisibleTime\u0027, $event)\""},{"lineNumber":280,"author":{"gitId":"-"},"content":" [minDate]\u003d\"minDateForResponseVisible\" [date]\u003d\"model.customResponseVisibleDate\""},{"lineNumber":281,"author":{"gitId":"-"},"content":" [minTime]\u003d\"minTimeForResponseVisible\" [time]\u003d\"model.customResponseVisibleTime\" \u003e\u003c/tm-timepicker\u003e"},{"lineNumber":282,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":283,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":284,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row mt-md-2 ms-md-1\"\u003e"},{"lineNumber":285,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":286,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"form-check\"\u003e"},{"lineNumber":287,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"ngb-tooltip-class form-check-label\" ngbTooltip\u003d\"Same time as when the session becomes visible to users.\"\u003e"},{"lineNumber":288,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"response-visibility-immediately\" class\u003d\"form-check-input\" type\u003d\"radio\" name\u003d\"responseVisibleRadio\" [value]\u003d\"ResponseVisibleSetting.AT_VISIBLE\" [ngModel]\u003d\"model.responseVisibleSetting\" (ngModelChange)\u003d\"triggerModelChange(\u0027responseVisibleSetting\u0027, $event)\" [disabled]\u003d\"!model.isEditable\"\u003e"},{"lineNumber":289,"author":{"gitId":"-"},"content":" Immediately"},{"lineNumber":290,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":291,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":292,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":293,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":294,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row mt-md-2 ms-md-1\"\u003e"},{"lineNumber":295,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":296,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"form-check\"\u003e"},{"lineNumber":297,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"ngb-tooltip-class form-check-label\" ngbTooltip\u003d\"Remember to manually publish the responses for this session later on.\"\u003e"},{"lineNumber":298,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"response-visibility-manually\" class\u003d\"form-check-input\" type\u003d\"radio\" name\u003d\"responseVisibleRadio\" [value]\u003d\"ResponseVisibleSetting.LATER\" [ngModel]\u003d\"model.responseVisibleSetting\" (ngModelChange)\u003d\"triggerModelChange(\u0027responseVisibleSetting\u0027, $event)\" [disabled]\u003d\"!model.isEditable\"\u003e"},{"lineNumber":299,"author":{"gitId":"-"},"content":" Not now (publish manually)"},{"lineNumber":300,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":301,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":302,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":303,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":304,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":305,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":306,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":307,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":308,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"!model.hasEmailSettingsPanelExpanded\"\u003e"},{"lineNumber":309,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"text-muted\"\u003eEmails are sent when session opens (within 15 minutes), 24 hrs before session closes and when results are published.\u003c/span\u003e"},{"lineNumber":310,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-change-email\" type\u003d\"button\" class\u003d\"btn btn-link\" (click)\u003d\"triggerModelChange(\u0027hasEmailSettingsPanelExpanded\u0027, true)\" [disabled]\u003d\"!model.isEditable\"\u003e[Change]\u003c/button\u003e"},{"lineNumber":311,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":312,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card border-primary margin-top-20px\" *ngIf\u003d\"model.hasEmailSettingsPanelExpanded\" @collapseAnim\u003e"},{"lineNumber":313,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":314,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 font-bold\"\u003e"},{"lineNumber":315,"author":{"gitId":"-"},"content":" Send emails for"},{"lineNumber":316,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":317,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row ms-md-1 mt-md-3\"\u003e"},{"lineNumber":318,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-4\"\u003e"},{"lineNumber":319,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"form-check form-check-inline\"\u003e"},{"lineNumber":320,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"ngb-tooltip-class form-check-label\" ngbTooltip\u003d\"Notify students when the session is open for submission.\"\u003e"},{"lineNumber":321,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"email-opening\" class\u003d\"form-check-input\" type\u003d\"checkbox\" checked disabled\u003eSession opening reminder"},{"lineNumber":322,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":323,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":324,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":325,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-4\"\u003e"},{"lineNumber":326,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"form-check form-check-inline\"\u003e"},{"lineNumber":327,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"ngb-tooltip-class form-check-label\" ngbTooltip\u003d\"Remind students to submit 24 hours before the end of the session.\"\u003e"},{"lineNumber":328,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"email-closing\" class\u003d\"form-check-input\" type\u003d\"checkbox\" [ngModel]\u003d\"model.isClosingEmailEnabled\" (ngModelChange)\u003d\"triggerModelChange(\u0027isClosingEmailEnabled\u0027, $event)\" [disabled]\u003d\"!model.isEditable\"\u003e Session closing reminder"},{"lineNumber":329,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":330,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":331,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":332,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-4\"\u003e"},{"lineNumber":333,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"form-check form-check-inline\"\u003e"},{"lineNumber":334,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"ngb-tooltip-class form-check-label\" ngbTooltip\u003d\"Notify students when the session results is published.\"\u003e"},{"lineNumber":335,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"email-published\" class\u003d\"form-check-input\" type\u003d\"checkbox\" [ngModel]\u003d\"model.isPublishedEmailEnabled\" (ngModelChange)\u003d\"triggerModelChange(\u0027isPublishedEmailEnabled\u0027, $event)\" [disabled]\u003d\"!model.isEditable\"\u003e Results published announcement"},{"lineNumber":336,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":337,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":338,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":339,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":340,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":341,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":342,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row margin-top-20px\"\u003e"},{"lineNumber":343,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 text-center\"\u003e"},{"lineNumber":344,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"loader\"\u003e\u003c/span\u003e"},{"lineNumber":345,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.ADD\"\u003e"},{"lineNumber":346,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-create-session\" type\u003d\"button\" class\u003d\"btn btn-primary\" [disabled]\u003d\"courseCandidates.length \u003d\u003d\u003d 0 || model.isSaving || !model.feedbackSessionName\" (click)\u003d\"submitFormHandler()\"\u003e"},{"lineNumber":347,"author":{"gitId":"-"},"content":" \u003ctm-ajax-loading *ngIf\u003d\"model.isSaving\"\u003e\u003c/tm-ajax-loading\u003eCreate Feedback Session"},{"lineNumber":348,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":349,"author":{"gitId":"-"},"content":" \u003cp class\u003d\"text-danger margin-top-20px\" *ngIf\u003d\"courseCandidates.length \u003d\u003d\u003d 0\"\u003e\u003cb\u003eYou need to have an active(unarchived) course to create a session!\u003c/b\u003e\u003c/p\u003e"},{"lineNumber":350,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":351,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.EDIT\"\u003e"},{"lineNumber":352,"author":{"gitId":"-"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn btn-success\" [disabled]\u003d\"model.isSaving || !model.isEditable\" *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.EDIT\" (click)\u003d\"submitFormHandler()\"\u003e"},{"lineNumber":353,"author":{"gitId":"-"},"content":" \u003ctm-ajax-loading *ngIf\u003d\"model.isSaving\"\u003e\u003c/tm-ajax-loading\u003eSave Changes"},{"lineNumber":354,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":355,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":356,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":357,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":358,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":359,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"nknguyenhc":2,"-":357}},{"path":"src/web/app/pages-admin/admin-home-page/admin-home-page.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"card bg-light top-padded\"\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":3,"author":{"gitId":"-"},"content":" \u003cdiv\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003cstrong\u003eAdding Multiple Instructors\u003c/strong\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":" \u003cp class\u003d\"text-muted\"\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-exclamation-circle\"\u003e\u003c/i\u003e Add Instructor Details in the format: Name | Email | Institution"},{"lineNumber":7,"author":{"gitId":"-"},"content":" \u003c/p\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003ctextarea class\u003d\"form-control\" id\u003d\"instructor-details-single-line\" [(ngModel)]\u003d\"instructorDetails\" aria-label\u003d\"Add multiple instructors\"\u003e\u003c/textarea\u003e"},{"lineNumber":9,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"top-padded\"\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003cbutton class\u003d\"btn btn-primary\" id\u003d\"add-instructor-single-line\" (click)\u003d\"validateAndAddInstructorDetails()\"\u003eAdd Instructors\u003c/button\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"card bg-light top-padded\"\u003e"},{"lineNumber":18,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":19,"author":{"gitId":"-"},"content":" \u003cdiv\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003cstrong\u003eAdding a Single Instructor\u003c/strong\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"top-padded\"\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":" \u003clabel for\u003d\"instructor-name\"\u003e"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u003cstrong\u003eName:\u003c/strong\u003e"},{"lineNumber":26,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003cinput class\u003d\"form-control\" type\u003d\"text\" id\u003d\"instructor-name\" [(ngModel)]\u003d\"instructorName\"\u003e"},{"lineNumber":28,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"top-padded\"\u003e"},{"lineNumber":31,"author":{"gitId":"-"},"content":" \u003clabel for\u003d\"instructor-email\"\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003cstrong\u003eEmail:\u003c/strong\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003cinput class\u003d\"form-control\" type\u003d\"text\" id\u003d\"instructor-email\" [(ngModel)]\u003d\"instructorEmail\"\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"top-padded\"\u003e"},{"lineNumber":38,"author":{"gitId":"-"},"content":" \u003clabel for\u003d\"instructor-institution\"\u003e"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003cstrong\u003eInstitution:\u003c/strong\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003cinput class\u003d\"form-control\" type\u003d\"text\" id\u003d\"instructor-institution\" [(ngModel)]\u003d\"instructorInstitution\"\u003e"},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"top-padded\"\u003e"},{"lineNumber":45,"author":{"gitId":"-"},"content":" \u003cbutton class\u003d\"btn btn-primary\" id\u003d\"add-instructor\" (click)\u003d\"validateAndAddInstructorDetail()\"\u003eAdd Instructor\u003c/button\u003e"},{"lineNumber":46,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":47,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":48,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"card bg-light top-padded\" *ngIf\u003d\"instructorsConsolidated.length\"\u003e"},{"lineNumber":51,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header bg-primary text-white\"\u003e"},{"lineNumber":52,"author":{"gitId":"-"},"content":" \u003cstrong\u003eResult\u003c/strong\u003e"},{"lineNumber":53,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":54,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"table-responsive\"\u003e"},{"lineNumber":56,"author":{"gitId":"-"},"content":" \u003ctable class\u003d\"table table-striped table-hover\"\u003e"},{"lineNumber":57,"author":{"gitId":"-"},"content":" \u003cthead\u003e"},{"lineNumber":58,"author":{"gitId":"-"},"content":" \u003ctr\u003e"},{"lineNumber":59,"author":{"gitId":"-"},"content":" \u003cth\u003eName\u003c/th\u003e"},{"lineNumber":60,"author":{"gitId":"-"},"content":" \u003cth\u003eEmail\u003c/th\u003e"},{"lineNumber":61,"author":{"gitId":"-"},"content":" \u003cth\u003eInstitution\u003c/th\u003e"},{"lineNumber":62,"author":{"gitId":"-"},"content":" \u003cth\u003eAction\u003c/th\u003e"},{"lineNumber":63,"author":{"gitId":"-"},"content":" \u003cth\u003eStatus\u003c/th\u003e"},{"lineNumber":64,"author":{"gitId":"-"},"content":" \u003cth\u003eMessage\u003c/th\u003e"},{"lineNumber":65,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":66,"author":{"gitId":"-"},"content":" \u003c/thead\u003e"},{"lineNumber":67,"author":{"gitId":"-"},"content":" \u003ctbody\u003e"},{"lineNumber":68,"author":{"gitId":"-"},"content":" \u003ctr tm-new-instructor-data-row"},{"lineNumber":69,"author":{"gitId":"-"},"content":" *ngFor\u003d\"let instructor of instructorsConsolidated; let i \u003d index\""},{"lineNumber":70,"author":{"gitId":"-"},"content":" [instructor]\u003d\"instructor\""},{"lineNumber":71,"author":{"gitId":"-"},"content":" [index]\u003d\"i\""},{"lineNumber":72,"author":{"gitId":"-"},"content":" [isAddDisabled]\u003d\"activeRequests \u003e 0\""},{"lineNumber":73,"author":{"gitId":"-"},"content":" (addInstructorEvent)\u003d\"addInstructor(i)\""},{"lineNumber":74,"author":{"gitId":"-"},"content":" (removeInstructorEvent)\u003d\"removeInstructor(i)\""},{"lineNumber":75,"author":{"gitId":"-"},"content":" (toggleEditModeEvent)\u003d\"setInstructorRowEditModeEnabled(i, $event)\""},{"lineNumber":76,"author":{"gitId":"-"},"content":" \u003e\u003c/tr\u003e"},{"lineNumber":77,"author":{"gitId":"-"},"content":" \u003c/tbody\u003e"},{"lineNumber":78,"author":{"gitId":"-"},"content":" \u003c/table\u003e"},{"lineNumber":79,"author":{"gitId":"-"},"content":" \u003cbutton class\u003d\"btn btn-primary top-padded\" (click)\u003d\"addAllInstructors()\" id\u003d\"add-all-instructors\" [disabled]\u003d\"activeRequests \u003e 0 || isAddingInstructors\"\u003e"},{"lineNumber":80,"author":{"gitId":"-"},"content":" \u003ctm-ajax-loading *ngIf\u003d\"isAddingInstructors\"\u003e\u003c/tm-ajax-loading\u003e"},{"lineNumber":81,"author":{"gitId":"-"},"content":" Add All Instructors"},{"lineNumber":82,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":83,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":84,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":85,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":"\u003ctm-account-request-table *ngIf\u003d\"accountReqs.length\" [accountRequests]\u003d\"accountReqs\" [searchString]\u003d\"\"\u003e\u003c/tm-account-request-table\u003e"}],"authorContributionMap":{"domoberzin":2,"-":85}},{"path":"src/web/app/pages-admin/admin-home-page/admin-home-page.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { HttpClientTestingModule } from \u0027@angular/common/http/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { ComponentFixture, TestBed, waitForAsync } from \u0027@angular/core/testing\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { FormsModule } from \u0027@angular/forms\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { RouterTestingModule } from \u0027@angular/router/testing\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { of, throwError } from \u0027rxjs\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { AdminHomePageComponent } from \u0027./admin-home-page.component\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { InstructorData } from \u0027./instructor-data\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { NewInstructorDataRowComponent } from \u0027./new-instructor-data-row/new-instructor-data-row.component\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { AccountService } from \u0027../../../services/account.service\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { LinkService } from \u0027../../../services/link.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { StatusMessageService } from \u0027../../../services/status-message.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { AccountRequestStatus } from \u0027../../../types/api-output\u0027;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import { AccountRequestTableModule } from \u0027../../components/account-requests-table/account-request-table.module\u0027;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import { AjaxLoadingModule } from \u0027../../components/ajax-loading/ajax-loading.module\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import { LoadingSpinnerModule } from \u0027../../components/loading-spinner/loading-spinner.module\u0027;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import { FormatDateDetailPipe } from \u0027../../components/teammates-common/format-date-detail.pipe\u0027;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"describe(\u0027AdminHomePageComponent\u0027, () \u003d\u003e {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" let component: AdminHomePageComponent;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" let fixture: ComponentFixture\u003cAdminHomePageComponent\u003e;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" let accountService: AccountService;"},{"lineNumber":22,"author":{"gitId":"-"},"content":" let linkService: LinkService;"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" beforeEach(waitForAsync(() \u003d\u003e {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" TestBed.configureTestingModule({"},{"lineNumber":26,"author":{"gitId":"-"},"content":" declarations: ["},{"lineNumber":27,"author":{"gitId":"-"},"content":" AdminHomePageComponent,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" NewInstructorDataRowComponent,"},{"lineNumber":29,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":30,"author":{"gitId":"-"},"content":" imports: ["},{"lineNumber":31,"author":{"gitId":"-"},"content":" FormsModule,"},{"lineNumber":32,"author":{"gitId":"-"},"content":" HttpClientTestingModule,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" LoadingSpinnerModule,"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" AccountRequestTableModule,"},{"lineNumber":35,"author":{"gitId":"-"},"content":" AjaxLoadingModule,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" RouterTestingModule,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":38,"author":{"gitId":"-"},"content":" providers: ["},{"lineNumber":39,"author":{"gitId":"-"},"content":" AccountService,"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" FormatDateDetailPipe,"},{"lineNumber":41,"author":{"gitId":"-"},"content":" StatusMessageService,"},{"lineNumber":42,"author":{"gitId":"-"},"content":" LinkService,"},{"lineNumber":43,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":44,"author":{"gitId":"-"},"content":" })"},{"lineNumber":45,"author":{"gitId":"-"},"content":" .compileComponents();"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" fixture \u003d TestBed.createComponent(AdminHomePageComponent);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" accountService \u003d TestBed.inject(AccountService);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" linkService \u003d TestBed.inject(LinkService);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":53,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":54,"author":{"gitId":"-"},"content":" });"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" expect(component).toBeTruthy();"},{"lineNumber":58,"author":{"gitId":"-"},"content":" });"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" it(\u0027should add one instructor to list if all fields are filled\u0027, () \u003d\u003e {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" component.instructorName \u003d \u0027Instructor Name\u0027;"},{"lineNumber":62,"author":{"gitId":"-"},"content":" component.instructorEmail \u003d \u0027instructor@example.com\u0027;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" component.instructorInstitution \u003d \u0027Instructor Institution\u0027;"},{"lineNumber":64,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" const button: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#add-instructor\u0027);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" button.click();"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" expect(component.instructorName).toEqual(\u0027\u0027);"},{"lineNumber":70,"author":{"gitId":"-"},"content":" expect(component.instructorEmail).toEqual(\u0027\u0027);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" expect(component.instructorInstitution).toEqual(\u0027\u0027);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated.length).toEqual(1);"},{"lineNumber":73,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[0]).toEqual({"},{"lineNumber":74,"author":{"gitId":"-"},"content":" email: \u0027instructor@example.com\u0027,"},{"lineNumber":75,"author":{"gitId":"-"},"content":" institution: \u0027Instructor Institution\u0027,"},{"lineNumber":76,"author":{"gitId":"-"},"content":" name: \u0027Instructor Name\u0027,"},{"lineNumber":77,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":79,"author":{"gitId":"-"},"content":" });"},{"lineNumber":80,"author":{"gitId":"-"},"content":" });"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" it(\u0027should not add one instructor to list if some fields are empty\u0027, () \u003d\u003e {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" component.instructorName \u003d \u0027Instructor Name\u0027;"},{"lineNumber":84,"author":{"gitId":"-"},"content":" component.instructorEmail \u003d \u0027\u0027;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" component.instructorInstitution \u003d \u0027Instructor Institution\u0027;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" const button: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#add-instructor\u0027);"},{"lineNumber":89,"author":{"gitId":"-"},"content":" button.click();"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" expect(component.instructorName).toEqual(\u0027Instructor Name\u0027);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" expect(component.instructorEmail).toEqual(\u0027\u0027);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" expect(component.instructorInstitution).toEqual(\u0027Instructor Institution\u0027);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated.length).toEqual(0);"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" component.instructorName \u003d \u0027\u0027;"},{"lineNumber":97,"author":{"gitId":"-"},"content":" component.instructorEmail \u003d \u0027instructor@example.com\u0027;"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" button.click();"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" expect(component.instructorName).toEqual(\u0027\u0027);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" expect(component.instructorEmail).toEqual(\u0027instructor@example.com\u0027);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" expect(component.instructorInstitution).toEqual(\u0027Instructor Institution\u0027);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated.length).toEqual(0);"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" component.instructorName \u003d \u0027Instructor Name\u0027;"},{"lineNumber":107,"author":{"gitId":"-"},"content":" component.instructorInstitution \u003d \u0027\u0027;"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" button.click();"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" expect(component.instructorName).toEqual(\u0027Instructor Name\u0027);"},{"lineNumber":112,"author":{"gitId":"-"},"content":" expect(component.instructorEmail).toEqual(\u0027instructor@example.com\u0027);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" expect(component.instructorInstitution).toEqual(\u0027\u0027);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated.length).toEqual(0);"},{"lineNumber":115,"author":{"gitId":"-"},"content":" });"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" it(\u0027should only add valid instructor details in the single line field\u0027, () \u003d\u003e {"},{"lineNumber":118,"author":{"gitId":"-"},"content":" component.instructorDetails \u003d ["},{"lineNumber":119,"author":{"gitId":"-"},"content":" \u0027Instructor A | instructora@example.com | Institution A\u0027,"},{"lineNumber":120,"author":{"gitId":"-"},"content":" \u0027Instructor B | instructorb@example.com\u0027,"},{"lineNumber":121,"author":{"gitId":"-"},"content":" \u0027Instructor C | | instructorc@example.com\u0027,"},{"lineNumber":122,"author":{"gitId":"-"},"content":" \u0027Instructor D | instructord@example.com | Institution D\u0027,"},{"lineNumber":123,"author":{"gitId":"-"},"content":" \u0027| instructore@example.com | Institution E\u0027,"},{"lineNumber":124,"author":{"gitId":"-"},"content":" ].join(\u0027\\n\u0027);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" const button: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#add-instructor-single-line\u0027);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" button.click();"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" expect(component.instructorDetails).toEqual(["},{"lineNumber":131,"author":{"gitId":"-"},"content":" \u0027Instructor B | instructorb@example.com\u0027,"},{"lineNumber":132,"author":{"gitId":"-"},"content":" \u0027Instructor C | | instructorc@example.com\u0027,"},{"lineNumber":133,"author":{"gitId":"-"},"content":" \u0027| instructore@example.com | Institution E\u0027,"},{"lineNumber":134,"author":{"gitId":"-"},"content":" ].join(\u0027\\r\\n\u0027));"},{"lineNumber":135,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated.length).toEqual(2);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[0]).toEqual({"},{"lineNumber":137,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":138,"author":{"gitId":"-"},"content":" institution: \u0027Institution A\u0027,"},{"lineNumber":139,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":140,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":141,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":142,"author":{"gitId":"-"},"content":" });"},{"lineNumber":143,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[1]).toEqual({"},{"lineNumber":144,"author":{"gitId":"-"},"content":" email: \u0027instructord@example.com\u0027,"},{"lineNumber":145,"author":{"gitId":"-"},"content":" institution: \u0027Institution D\u0027,"},{"lineNumber":146,"author":{"gitId":"-"},"content":" name: \u0027Instructor D\u0027,"},{"lineNumber":147,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":148,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":149,"author":{"gitId":"-"},"content":" });"},{"lineNumber":150,"author":{"gitId":"-"},"content":" });"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" it(\u0027should remove instructor out of queue if REMOVE is requested\u0027, () \u003d\u003e {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" const instructorData: InstructorData \u003d {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":155,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":156,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":157,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":158,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":159,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":160,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":161,"author":{"gitId":"-"},"content":" };"},{"lineNumber":162,"author":{"gitId":"-"},"content":" component.instructorsConsolidated \u003d [instructorData];"},{"lineNumber":163,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" const index: number \u003d 0;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" component.removeInstructor(index);"},{"lineNumber":167,"author":{"gitId":"-"},"content":""},{"lineNumber":168,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated.includes(instructorData)).toBeFalsy();"},{"lineNumber":169,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated.length).toEqual(0);"},{"lineNumber":170,"author":{"gitId":"-"},"content":" });"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" it(\u0027should add instructor and update field when successful\u0027, () \u003d\u003e {"},{"lineNumber":173,"author":{"gitId":"-"},"content":" component.instructorsConsolidated \u003d ["},{"lineNumber":174,"author":{"gitId":"-"},"content":" {"},{"lineNumber":175,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":176,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":177,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":178,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":179,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":180,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":181,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":182,"author":{"gitId":"-"},"content":" },"},{"lineNumber":183,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":184,"author":{"gitId":"-"},"content":" jest.spyOn(accountService, \u0027createAccountRequest\u0027).mockReturnValue(of({"},{"lineNumber":185,"author":{"gitId":"-"},"content":" id: \u0027some.person@example.com%NUS\u0027,"},{"lineNumber":186,"author":{"gitId":"-"},"content":" email: \u0027some.person@example.com\u0027,"},{"lineNumber":187,"author":{"gitId":"-"},"content":" name: \u0027Some Person\u0027,"},{"lineNumber":188,"author":{"gitId":"-"},"content":" institute: \u0027NUS\u0027,"},{"lineNumber":189,"author":{"gitId":"-"},"content":" status: AccountRequestStatus.APPROVED,"},{"lineNumber":190,"author":{"gitId":"-"},"content":" registrationKey: \u0027registrationKey\u0027,"},{"lineNumber":191,"author":{"gitId":"-"},"content":" createdAt: 528,"},{"lineNumber":192,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":193,"author":{"gitId":"-"},"content":" jest.spyOn(linkService, \u0027generateAccountRegistrationLink\u0027)"},{"lineNumber":194,"author":{"gitId":"-"},"content":" .mockReturnValue(\u0027http://localhost:4200/web/join?iscreatingaccount\u003dtrue\u0026key\u003dregistrationKey\u0027);"},{"lineNumber":195,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":196,"author":{"gitId":"-"},"content":""},{"lineNumber":197,"author":{"gitId":"-"},"content":" const index: number \u003d 0;"},{"lineNumber":198,"author":{"gitId":"-"},"content":" component.addInstructor(index);"},{"lineNumber":199,"author":{"gitId":"-"},"content":""},{"lineNumber":200,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[index].status).toEqual(\u0027SUCCESS\u0027);"},{"lineNumber":201,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[index].joinLink)"},{"lineNumber":202,"author":{"gitId":"-"},"content":" .toEqual(\u0027http://localhost:4200/web/join?iscreatingaccount\u003dtrue\u0026key\u003dregistrationKey\u0027);"},{"lineNumber":203,"author":{"gitId":"-"},"content":" expect(component.activeRequests).toEqual(0);"},{"lineNumber":204,"author":{"gitId":"-"},"content":" });"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" it(\u0027should not add instructor and update field during failure\u0027, () \u003d\u003e {"},{"lineNumber":207,"author":{"gitId":"-"},"content":" component.instructorsConsolidated \u003d ["},{"lineNumber":208,"author":{"gitId":"-"},"content":" {"},{"lineNumber":209,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":210,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":211,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":212,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":213,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":214,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":215,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":216,"author":{"gitId":"-"},"content":" },"},{"lineNumber":217,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":218,"author":{"gitId":"-"},"content":" jest.spyOn(accountService, \u0027createAccountRequest\u0027).mockReturnValue(throwError(() \u003d\u003e ({"},{"lineNumber":219,"author":{"gitId":"-"},"content":" error: {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" message: \u0027This is the error message\u0027,"},{"lineNumber":221,"author":{"gitId":"-"},"content":" },"},{"lineNumber":222,"author":{"gitId":"-"},"content":" })));"},{"lineNumber":223,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":224,"author":{"gitId":"-"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":" const index: number \u003d 0;"},{"lineNumber":226,"author":{"gitId":"-"},"content":" component.addInstructor(index);"},{"lineNumber":227,"author":{"gitId":"-"},"content":""},{"lineNumber":228,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[index].status).toEqual(\u0027FAIL\u0027);"},{"lineNumber":229,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[index].message).toEqual(\u0027This is the error message\u0027);"},{"lineNumber":230,"author":{"gitId":"-"},"content":" expect(component.activeRequests).toEqual(0);"},{"lineNumber":231,"author":{"gitId":"-"},"content":" });"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" it(\u0027should enter edit mode for only the specified instructor\u0027, () \u003d\u003e {"},{"lineNumber":234,"author":{"gitId":"-"},"content":" component.instructorsConsolidated \u003d ["},{"lineNumber":235,"author":{"gitId":"-"},"content":" {"},{"lineNumber":236,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":237,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":238,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":239,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":240,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":241,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":242,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":243,"author":{"gitId":"-"},"content":" },"},{"lineNumber":244,"author":{"gitId":"-"},"content":" {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" name: \u0027Instructor B\u0027,"},{"lineNumber":246,"author":{"gitId":"-"},"content":" email: \u0027instructorb@example.com\u0027,"},{"lineNumber":247,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution B\u0027,"},{"lineNumber":248,"author":{"gitId":"-"},"content":" status: \u0027SUCCESS\u0027,"},{"lineNumber":249,"author":{"gitId":"-"},"content":" statusCode: 200,"},{"lineNumber":250,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":251,"author":{"gitId":"-"},"content":" joinLink: \u0027http://localhost:4200/web/join\u0027,"},{"lineNumber":252,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":253,"author":{"gitId":"-"},"content":" },"},{"lineNumber":254,"author":{"gitId":"-"},"content":" {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" name: \u0027Instructor C\u0027,"},{"lineNumber":256,"author":{"gitId":"-"},"content":" email: \u0027instructorc@example.com\u0027,"},{"lineNumber":257,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution C\u0027,"},{"lineNumber":258,"author":{"gitId":"-"},"content":" status: \u0027FAIL\u0027,"},{"lineNumber":259,"author":{"gitId":"-"},"content":" statusCode: 400,"},{"lineNumber":260,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":261,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":262,"author":{"gitId":"-"},"content":" message: \u0027The instructor cannot be added for some reason\u0027,"},{"lineNumber":263,"author":{"gitId":"-"},"content":" },"},{"lineNumber":264,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":265,"author":{"gitId":"-"},"content":""},{"lineNumber":266,"author":{"gitId":"-"},"content":" const index: number \u003d 2;"},{"lineNumber":267,"author":{"gitId":"-"},"content":" component.setInstructorRowEditModeEnabled(index, true);"},{"lineNumber":268,"author":{"gitId":"-"},"content":""},{"lineNumber":269,"author":{"gitId":"-"},"content":" for (let i: number \u003d 0; i \u003c component.instructorsConsolidated.length; i +\u003d 1) {"},{"lineNumber":270,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[i].isCurrentlyBeingEdited).toEqual(i \u003d\u003d\u003d index);"},{"lineNumber":271,"author":{"gitId":"-"},"content":" }"},{"lineNumber":272,"author":{"gitId":"-"},"content":" });"},{"lineNumber":273,"author":{"gitId":"-"},"content":""},{"lineNumber":274,"author":{"gitId":"-"},"content":" it(\u0027should exit edit mode for only the specified instructor\u0027, () \u003d\u003e {"},{"lineNumber":275,"author":{"gitId":"-"},"content":" component.instructorsConsolidated \u003d ["},{"lineNumber":276,"author":{"gitId":"-"},"content":" {"},{"lineNumber":277,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":278,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":279,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":280,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":281,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":282,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":283,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":284,"author":{"gitId":"-"},"content":" },"},{"lineNumber":285,"author":{"gitId":"-"},"content":" {"},{"lineNumber":286,"author":{"gitId":"-"},"content":" name: \u0027Instructor B\u0027,"},{"lineNumber":287,"author":{"gitId":"-"},"content":" email: \u0027instructorb@example.com\u0027,"},{"lineNumber":288,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution B\u0027,"},{"lineNumber":289,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":290,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":291,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":292,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":293,"author":{"gitId":"-"},"content":" },"},{"lineNumber":294,"author":{"gitId":"-"},"content":" {"},{"lineNumber":295,"author":{"gitId":"-"},"content":" name: \u0027Instructor C\u0027,"},{"lineNumber":296,"author":{"gitId":"-"},"content":" email: \u0027instructorc@example.com\u0027,"},{"lineNumber":297,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution C\u0027,"},{"lineNumber":298,"author":{"gitId":"-"},"content":" status: \u0027FAIL\u0027,"},{"lineNumber":299,"author":{"gitId":"-"},"content":" statusCode: 400,"},{"lineNumber":300,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":301,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":302,"author":{"gitId":"-"},"content":" message: \u0027The instructor cannot be added for some reason\u0027,"},{"lineNumber":303,"author":{"gitId":"-"},"content":" },"},{"lineNumber":304,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":305,"author":{"gitId":"-"},"content":" for (let i: number \u003d 0; i \u003c component.instructorsConsolidated.length; i +\u003d 1) {"},{"lineNumber":306,"author":{"gitId":"-"},"content":" component.setInstructorRowEditModeEnabled(i, true);"},{"lineNumber":307,"author":{"gitId":"-"},"content":" }"},{"lineNumber":308,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":309,"author":{"gitId":"-"},"content":""},{"lineNumber":310,"author":{"gitId":"-"},"content":" const index: number \u003d 1;"},{"lineNumber":311,"author":{"gitId":"-"},"content":" component.setInstructorRowEditModeEnabled(index, false);"},{"lineNumber":312,"author":{"gitId":"-"},"content":""},{"lineNumber":313,"author":{"gitId":"-"},"content":" for (let i: number \u003d 0; i \u003c component.instructorsConsolidated.length; i +\u003d 1) {"},{"lineNumber":314,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[i].isCurrentlyBeingEdited).toEqual(i !\u003d\u003d index);"},{"lineNumber":315,"author":{"gitId":"-"},"content":" }"},{"lineNumber":316,"author":{"gitId":"-"},"content":" });"},{"lineNumber":317,"author":{"gitId":"-"},"content":""},{"lineNumber":318,"author":{"gitId":"-"},"content":" it(\u0027should add all instructors when prompted\u0027, () \u003d\u003e {"},{"lineNumber":319,"author":{"gitId":"-"},"content":" component.instructorsConsolidated \u003d ["},{"lineNumber":320,"author":{"gitId":"-"},"content":" {"},{"lineNumber":321,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":322,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":323,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":324,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":325,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":326,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":327,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":328,"author":{"gitId":"-"},"content":" },"},{"lineNumber":329,"author":{"gitId":"-"},"content":" {"},{"lineNumber":330,"author":{"gitId":"-"},"content":" name: \u0027Instructor B\u0027,"},{"lineNumber":331,"author":{"gitId":"-"},"content":" email: \u0027instructorb@example.com\u0027,"},{"lineNumber":332,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution B\u0027,"},{"lineNumber":333,"author":{"gitId":"-"},"content":" status: \u0027SUCCESS\u0027,"},{"lineNumber":334,"author":{"gitId":"-"},"content":" statusCode: 200,"},{"lineNumber":335,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":336,"author":{"gitId":"-"},"content":" joinLink: \u0027http://localhost:4200/web/join\u0027,"},{"lineNumber":337,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":338,"author":{"gitId":"-"},"content":" },"},{"lineNumber":339,"author":{"gitId":"-"},"content":" {"},{"lineNumber":340,"author":{"gitId":"-"},"content":" name: \u0027Instructor C\u0027,"},{"lineNumber":341,"author":{"gitId":"-"},"content":" email: \u0027instructorc@example.com\u0027,"},{"lineNumber":342,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution C\u0027,"},{"lineNumber":343,"author":{"gitId":"-"},"content":" status: \u0027FAIL\u0027,"},{"lineNumber":344,"author":{"gitId":"-"},"content":" statusCode: 400,"},{"lineNumber":345,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":346,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":347,"author":{"gitId":"-"},"content":" message: \u0027The instructor cannot be added for some reason\u0027,"},{"lineNumber":348,"author":{"gitId":"-"},"content":" },"},{"lineNumber":349,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":350,"author":{"gitId":"-"},"content":" // No need to spy here as this test only tests the number of active requests added"},{"lineNumber":351,"author":{"gitId":"-"},"content":" // Testing of adding individual instructors have been done before"},{"lineNumber":352,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":353,"author":{"gitId":"-"},"content":""},{"lineNumber":354,"author":{"gitId":"-"},"content":" const button: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#add-all-instructors\u0027);"},{"lineNumber":355,"author":{"gitId":"-"},"content":" button.click();"},{"lineNumber":356,"author":{"gitId":"-"},"content":""},{"lineNumber":357,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[0].status).toEqual(\u0027ADDING\u0027);"},{"lineNumber":358,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[1].status).toEqual(\u0027SUCCESS\u0027);"},{"lineNumber":359,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[2].status).toEqual(\u0027ADDING\u0027);"},{"lineNumber":360,"author":{"gitId":"-"},"content":" expect(component.activeRequests).toEqual(2);"},{"lineNumber":361,"author":{"gitId":"-"},"content":" });"},{"lineNumber":362,"author":{"gitId":"-"},"content":""},{"lineNumber":363,"author":{"gitId":"-"},"content":" it(\u0027should add only instructors that are not currently in edit mode when trying to add all\u0027, () \u003d\u003e {"},{"lineNumber":364,"author":{"gitId":"-"},"content":" component.instructorsConsolidated \u003d ["},{"lineNumber":365,"author":{"gitId":"-"},"content":" {"},{"lineNumber":366,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":367,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":368,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":369,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":370,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":371,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":372,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":373,"author":{"gitId":"-"},"content":" },"},{"lineNumber":374,"author":{"gitId":"-"},"content":" {"},{"lineNumber":375,"author":{"gitId":"-"},"content":" name: \u0027Instructor B\u0027,"},{"lineNumber":376,"author":{"gitId":"-"},"content":" email: \u0027instructorb@example.com\u0027,"},{"lineNumber":377,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution B\u0027,"},{"lineNumber":378,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":379,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: true,"},{"lineNumber":380,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":381,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":382,"author":{"gitId":"-"},"content":" },"},{"lineNumber":383,"author":{"gitId":"-"},"content":" {"},{"lineNumber":384,"author":{"gitId":"-"},"content":" name: \u0027Instructor C\u0027,"},{"lineNumber":385,"author":{"gitId":"-"},"content":" email: \u0027instructorc@example.com\u0027,"},{"lineNumber":386,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution C\u0027,"},{"lineNumber":387,"author":{"gitId":"-"},"content":" status: \u0027FAIL\u0027,"},{"lineNumber":388,"author":{"gitId":"-"},"content":" statusCode: 400,"},{"lineNumber":389,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":390,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":391,"author":{"gitId":"-"},"content":" message: \u0027The instructor cannot be added for some reason\u0027,"},{"lineNumber":392,"author":{"gitId":"-"},"content":" },"},{"lineNumber":393,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":394,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":395,"author":{"gitId":"-"},"content":""},{"lineNumber":396,"author":{"gitId":"-"},"content":" const addAllButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#add-all-instructors\u0027);"},{"lineNumber":397,"author":{"gitId":"-"},"content":" addAllButton.click();"},{"lineNumber":398,"author":{"gitId":"-"},"content":""},{"lineNumber":399,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[0].status).toEqual(\u0027ADDING\u0027);"},{"lineNumber":400,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[1].status).toEqual(\u0027PENDING\u0027);"},{"lineNumber":401,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[2].status).toEqual(\u0027ADDING\u0027);"},{"lineNumber":402,"author":{"gitId":"-"},"content":" expect(component.activeRequests).toEqual(2);"},{"lineNumber":403,"author":{"gitId":"-"},"content":" });"},{"lineNumber":404,"author":{"gitId":"-"},"content":""},{"lineNumber":405,"author":{"gitId":"-"},"content":" it(\u0027should snap with default view\u0027, () \u003d\u003e {"},{"lineNumber":406,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":407,"author":{"gitId":"-"},"content":" });"},{"lineNumber":408,"author":{"gitId":"-"},"content":""},{"lineNumber":409,"author":{"gitId":"-"},"content":" it(\u0027should snap with some instructors details\u0027, () \u003d\u003e {"},{"lineNumber":410,"author":{"gitId":"-"},"content":" component.instructorsConsolidated \u003d ["},{"lineNumber":411,"author":{"gitId":"-"},"content":" {"},{"lineNumber":412,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":413,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":414,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":415,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":416,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":417,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":418,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":419,"author":{"gitId":"-"},"content":" },"},{"lineNumber":420,"author":{"gitId":"-"},"content":" {"},{"lineNumber":421,"author":{"gitId":"-"},"content":" name: \u0027Instructor B\u0027,"},{"lineNumber":422,"author":{"gitId":"-"},"content":" email: \u0027instructorb@example.com\u0027,"},{"lineNumber":423,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution B\u0027,"},{"lineNumber":424,"author":{"gitId":"-"},"content":" status: \u0027SUCCESS\u0027,"},{"lineNumber":425,"author":{"gitId":"-"},"content":" statusCode: 200,"},{"lineNumber":426,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":427,"author":{"gitId":"-"},"content":" joinLink: \u0027http://localhost:4200/web/join\u0027,"},{"lineNumber":428,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":429,"author":{"gitId":"-"},"content":" },"},{"lineNumber":430,"author":{"gitId":"-"},"content":" {"},{"lineNumber":431,"author":{"gitId":"-"},"content":" name: \u0027Instructor C\u0027,"},{"lineNumber":432,"author":{"gitId":"-"},"content":" email: \u0027instructorc@example.com\u0027,"},{"lineNumber":433,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution C\u0027,"},{"lineNumber":434,"author":{"gitId":"-"},"content":" status: \u0027FAIL\u0027,"},{"lineNumber":435,"author":{"gitId":"-"},"content":" statusCode: 400,"},{"lineNumber":436,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":437,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":438,"author":{"gitId":"-"},"content":" message: \u0027The instructor cannot be added for some reason\u0027,"},{"lineNumber":439,"author":{"gitId":"-"},"content":" },"},{"lineNumber":440,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":441,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":442,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":443,"author":{"gitId":"-"},"content":" });"},{"lineNumber":444,"author":{"gitId":"-"},"content":""},{"lineNumber":445,"author":{"gitId":"-"},"content":" it(\u0027should snap with disabled adding instructor button if there are active requests\u0027, () \u003d\u003e {"},{"lineNumber":446,"author":{"gitId":"-"},"content":" component.instructorsConsolidated \u003d ["},{"lineNumber":447,"author":{"gitId":"-"},"content":" {"},{"lineNumber":448,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":449,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":450,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":451,"author":{"gitId":"-"},"content":" status: \u0027ADDING\u0027,"},{"lineNumber":452,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":453,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":454,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":455,"author":{"gitId":"-"},"content":" },"},{"lineNumber":456,"author":{"gitId":"-"},"content":" {"},{"lineNumber":457,"author":{"gitId":"-"},"content":" name: \u0027Instructor B\u0027,"},{"lineNumber":458,"author":{"gitId":"-"},"content":" email: \u0027instructorb@example.com\u0027,"},{"lineNumber":459,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution B\u0027,"},{"lineNumber":460,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":461,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":462,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":463,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":464,"author":{"gitId":"-"},"content":" },"},{"lineNumber":465,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":466,"author":{"gitId":"-"},"content":" component.activeRequests \u003d 1;"},{"lineNumber":467,"author":{"gitId":"-"},"content":" component.isAddingInstructors \u003d true;"},{"lineNumber":468,"author":{"gitId":"-"},"content":""},{"lineNumber":469,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":470,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":471,"author":{"gitId":"-"},"content":" });"},{"lineNumber":472,"author":{"gitId":"-"},"content":""},{"lineNumber":473,"author":{"gitId":"-"},"content":" it(\u0027should add multiple instructors split by tabs\u0027, () \u003d\u003e {"},{"lineNumber":474,"author":{"gitId":"-"},"content":" component.instructorDetails \u003d `Instructor A \\t instructora@example.com \\t Sample Institution A\\n"},{"lineNumber":475,"author":{"gitId":"-"},"content":" Instructor B \\t instructorb@example.com \\t Sample Institution B`;"},{"lineNumber":476,"author":{"gitId":"-"},"content":""},{"lineNumber":477,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":478,"author":{"gitId":"-"},"content":""},{"lineNumber":479,"author":{"gitId":"-"},"content":" const button: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#add-instructor-single-line\u0027);"},{"lineNumber":480,"author":{"gitId":"-"},"content":" button.click();"},{"lineNumber":481,"author":{"gitId":"-"},"content":""},{"lineNumber":482,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated.length).toEqual(2);"},{"lineNumber":483,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[0]).toEqual("},{"lineNumber":484,"author":{"gitId":"-"},"content":" {"},{"lineNumber":485,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":486,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":487,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":488,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":489,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":490,"author":{"gitId":"-"},"content":" },"},{"lineNumber":491,"author":{"gitId":"-"},"content":" );"},{"lineNumber":492,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[1]).toEqual("},{"lineNumber":493,"author":{"gitId":"-"},"content":" {"},{"lineNumber":494,"author":{"gitId":"-"},"content":" name: \u0027Instructor B\u0027,"},{"lineNumber":495,"author":{"gitId":"-"},"content":" email: \u0027instructorb@example.com\u0027,"},{"lineNumber":496,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution B\u0027,"},{"lineNumber":497,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":498,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":499,"author":{"gitId":"-"},"content":" },"},{"lineNumber":500,"author":{"gitId":"-"},"content":" );"},{"lineNumber":501,"author":{"gitId":"-"},"content":" });"},{"lineNumber":502,"author":{"gitId":"-"},"content":""},{"lineNumber":503,"author":{"gitId":"-"},"content":" it(\u0027should add multiple instructors split by vertical bars\u0027, () \u003d\u003e {"},{"lineNumber":504,"author":{"gitId":"-"},"content":" component.instructorDetails \u003d `Instructor A | instructora@example.com | Sample Institution A\\n"},{"lineNumber":505,"author":{"gitId":"-"},"content":" Instructor B | instructorb@example.com | Sample Institution B`;"},{"lineNumber":506,"author":{"gitId":"-"},"content":""},{"lineNumber":507,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":508,"author":{"gitId":"-"},"content":""},{"lineNumber":509,"author":{"gitId":"-"},"content":" const button: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#add-instructor-single-line\u0027);"},{"lineNumber":510,"author":{"gitId":"-"},"content":" button.click();"},{"lineNumber":511,"author":{"gitId":"-"},"content":""},{"lineNumber":512,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated.length).toEqual(2);"},{"lineNumber":513,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[0]).toEqual("},{"lineNumber":514,"author":{"gitId":"-"},"content":" {"},{"lineNumber":515,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":516,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":517,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":518,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":519,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":520,"author":{"gitId":"-"},"content":" },"},{"lineNumber":521,"author":{"gitId":"-"},"content":" );"},{"lineNumber":522,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[1]).toEqual("},{"lineNumber":523,"author":{"gitId":"-"},"content":" {"},{"lineNumber":524,"author":{"gitId":"-"},"content":" name: \u0027Instructor B\u0027,"},{"lineNumber":525,"author":{"gitId":"-"},"content":" email: \u0027instructorb@example.com\u0027,"},{"lineNumber":526,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution B\u0027,"},{"lineNumber":527,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":528,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":529,"author":{"gitId":"-"},"content":" },"},{"lineNumber":530,"author":{"gitId":"-"},"content":" );"},{"lineNumber":531,"author":{"gitId":"-"},"content":" });"},{"lineNumber":532,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"domoberzin":4,"-":528}},{"path":"src/web/app/pages-admin/admin-home-page/admin-home-page.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"import { Component, OnInit } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":"import { Observable, of } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import { finalize } from \u0027rxjs/operators\u0027;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import { InstructorData } from \u0027./instructor-data\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { AccountService } from \u0027../../../services/account.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { LinkService } from \u0027../../../services/link.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { StatusMessageService } from \u0027../../../services/status-message.service\u0027;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import { TimezoneService } from \u0027../../../services/timezone.service\u0027;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import { AccountRequest, AccountRequests } from \u0027../../../types/api-output\u0027;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import { AccountRequestTableRowModel } from \u0027../../components/account-requests-table/account-request-table-model\u0027;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import { FormatDateDetailPipe } from \u0027../../components/teammates-common/format-date-detail.pipe\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { ErrorMessageOutput } from \u0027../../error-message-output\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":15,"author":{"gitId":"-"},"content":" * Admin home page."},{"lineNumber":16,"author":{"gitId":"-"},"content":" */"},{"lineNumber":17,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":18,"author":{"gitId":"-"},"content":" selector: \u0027tm-admin-home-page\u0027,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" templateUrl: \u0027./admin-home-page.component.html\u0027,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./admin-home-page.component.scss\u0027],"},{"lineNumber":21,"author":{"gitId":"-"},"content":"})"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":"export class AdminHomePageComponent implements OnInit {"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" instructorDetails: string \u003d \u0027\u0027;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" instructorName: string \u003d \u0027\u0027;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" instructorEmail: string \u003d \u0027\u0027;"},{"lineNumber":27,"author":{"gitId":"-"},"content":" instructorInstitution: string \u003d \u0027\u0027;"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" instructorsConsolidated: InstructorData[] \u003d [];"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" accountReqs: AccountRequestTableRowModel[] \u003d [];"},{"lineNumber":31,"author":{"gitId":"-"},"content":" activeRequests: number \u003d 0;"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" currentPage: number \u003d 1;"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" pageSize: number \u003d 20;"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" items$: Observable\u003cany\u003e \u003d of([]);"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" isAddingInstructors: boolean \u003d false;"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" constructor("},{"lineNumber":39,"author":{"gitId":"-"},"content":" private accountService: AccountService,"},{"lineNumber":40,"author":{"gitId":"-"},"content":" private statusMessageService: StatusMessageService,"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" private timezoneService: TimezoneService,"},{"lineNumber":42,"author":{"gitId":"-"},"content":" private linkService: LinkService,"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" private formatDateDetailPipe: FormatDateDetailPipe,"},{"lineNumber":44,"author":{"gitId":"-"},"content":" ) {}"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" ngOnInit(): void {"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" this.fetchAccountRequests();"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":51,"author":{"gitId":"-"},"content":" * Validates and adds the instructor details filled with first form."},{"lineNumber":52,"author":{"gitId":"-"},"content":" */"},{"lineNumber":53,"author":{"gitId":"-"},"content":" validateAndAddInstructorDetails(): void {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" const invalidLines: string[] \u003d [];"},{"lineNumber":55,"author":{"gitId":"-"},"content":" for (const instructorDetail of this.instructorDetails.split(/\\r?\\n/)) {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" const instructorDetailSplit: string[] \u003d instructorDetail.split(/[|\\t]/).map((item: string) \u003d\u003e item.trim());"},{"lineNumber":57,"author":{"gitId":"-"},"content":" if (instructorDetailSplit.length \u003c 3) {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" // TODO handle error"},{"lineNumber":59,"author":{"gitId":"-"},"content":" invalidLines.push(instructorDetail);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":" if (!instructorDetailSplit[0] || !instructorDetailSplit[1] || !instructorDetailSplit[2]) {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" // TODO handle error"},{"lineNumber":64,"author":{"gitId":"-"},"content":" invalidLines.push(instructorDetail);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":" this.instructorsConsolidated.push({"},{"lineNumber":68,"author":{"gitId":"-"},"content":" name: instructorDetailSplit[0],"},{"lineNumber":69,"author":{"gitId":"-"},"content":" email: instructorDetailSplit[1],"},{"lineNumber":70,"author":{"gitId":"-"},"content":" institution: instructorDetailSplit[2],"},{"lineNumber":71,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" });"},{"lineNumber":74,"author":{"gitId":"-"},"content":" }"},{"lineNumber":75,"author":{"gitId":"-"},"content":" this.instructorDetails \u003d invalidLines.join(\u0027\\r\\n\u0027);"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":79,"author":{"gitId":"-"},"content":" * Validates and adds the instructor detail filled with second form."},{"lineNumber":80,"author":{"gitId":"-"},"content":" */"},{"lineNumber":81,"author":{"gitId":"-"},"content":" validateAndAddInstructorDetail(): void {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" if (!this.instructorName || !this.instructorEmail || !this.instructorInstitution) {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" // TODO handle error"},{"lineNumber":84,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" }"},{"lineNumber":86,"author":{"gitId":"-"},"content":" this.instructorsConsolidated.push({"},{"lineNumber":87,"author":{"gitId":"-"},"content":" name: this.instructorName,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" email: this.instructorEmail,"},{"lineNumber":89,"author":{"gitId":"-"},"content":" institution: this.instructorInstitution,"},{"lineNumber":90,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":91,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":92,"author":{"gitId":"-"},"content":" });"},{"lineNumber":93,"author":{"gitId":"-"},"content":" this.instructorName \u003d \u0027\u0027;"},{"lineNumber":94,"author":{"gitId":"-"},"content":" this.instructorEmail \u003d \u0027\u0027;"},{"lineNumber":95,"author":{"gitId":"-"},"content":" this.instructorInstitution \u003d \u0027\u0027;"},{"lineNumber":96,"author":{"gitId":"-"},"content":" }"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":99,"author":{"gitId":"-"},"content":" * Adds the instructor at the i-th index."},{"lineNumber":100,"author":{"gitId":"-"},"content":" */"},{"lineNumber":101,"author":{"gitId":"-"},"content":" addInstructor(i: number): void {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" const instructor: InstructorData \u003d this.instructorsConsolidated[i];"},{"lineNumber":103,"author":{"gitId":"-"},"content":" if (this.instructorsConsolidated[i].isCurrentlyBeingEdited"},{"lineNumber":104,"author":{"gitId":"-"},"content":" || (instructor.status !\u003d\u003d \u0027PENDING\u0027 \u0026\u0026 instructor.status !\u003d\u003d \u0027FAIL\u0027)) {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":106,"author":{"gitId":"-"},"content":" }"},{"lineNumber":107,"author":{"gitId":"-"},"content":" this.activeRequests +\u003d 1;"},{"lineNumber":108,"author":{"gitId":"-"},"content":" instructor.status \u003d \u0027ADDING\u0027;"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" this.isAddingInstructors \u003d true;"},{"lineNumber":111,"author":{"gitId":"-"},"content":" this.accountService.createAccountRequest({"},{"lineNumber":112,"author":{"gitId":"-"},"content":" instructorEmail: instructor.email,"},{"lineNumber":113,"author":{"gitId":"-"},"content":" instructorName: instructor.name,"},{"lineNumber":114,"author":{"gitId":"-"},"content":" instructorInstitution: instructor.institution,"},{"lineNumber":115,"author":{"gitId":"-"},"content":" })"},{"lineNumber":116,"author":{"gitId":"-"},"content":" .pipe(finalize(() \u003d\u003e {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" this.isAddingInstructors \u003d false;"},{"lineNumber":118,"author":{"gitId":"-"},"content":" }))"},{"lineNumber":119,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":120,"author":{"gitId":"-"},"content":" next: (resp: AccountRequest) \u003d\u003e {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" instructor.status \u003d \u0027SUCCESS\u0027;"},{"lineNumber":122,"author":{"gitId":"-"},"content":" instructor.statusCode \u003d 200;"},{"lineNumber":123,"author":{"gitId":"-"},"content":" instructor.joinLink \u003d this.linkService.generateAccountRegistrationLink(resp.registrationKey);"},{"lineNumber":124,"author":{"gitId":"-"},"content":" this.activeRequests -\u003d 1;"},{"lineNumber":125,"author":{"gitId":"-"},"content":" },"},{"lineNumber":126,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":127,"author":{"gitId":"-"},"content":" instructor.status \u003d \u0027FAIL\u0027;"},{"lineNumber":128,"author":{"gitId":"-"},"content":" instructor.statusCode \u003d resp.status;"},{"lineNumber":129,"author":{"gitId":"-"},"content":" instructor.message \u003d resp.error.message;"},{"lineNumber":130,"author":{"gitId":"-"},"content":" this.activeRequests -\u003d 1;"},{"lineNumber":131,"author":{"gitId":"-"},"content":" },"},{"lineNumber":132,"author":{"gitId":"-"},"content":" });"},{"lineNumber":133,"author":{"gitId":"-"},"content":" }"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":136,"author":{"gitId":"-"},"content":" * Removes the instructor at the i-th index."},{"lineNumber":137,"author":{"gitId":"-"},"content":" */"},{"lineNumber":138,"author":{"gitId":"-"},"content":" removeInstructor(i: number): void {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" this.instructorsConsolidated.splice(i, 1);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":143,"author":{"gitId":"-"},"content":" * Sets the i-th instructor data row\u0027s edit mode status."},{"lineNumber":144,"author":{"gitId":"-"},"content":" *"},{"lineNumber":145,"author":{"gitId":"-"},"content":" * @param i The index."},{"lineNumber":146,"author":{"gitId":"-"},"content":" * @param isEnabled Whether the edit mode status is enabled."},{"lineNumber":147,"author":{"gitId":"-"},"content":" */"},{"lineNumber":148,"author":{"gitId":"-"},"content":" setInstructorRowEditModeEnabled(i: number, isEnabled: boolean): void {"},{"lineNumber":149,"author":{"gitId":"-"},"content":" this.instructorsConsolidated[i].isCurrentlyBeingEdited \u003d isEnabled;"},{"lineNumber":150,"author":{"gitId":"-"},"content":" }"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":153,"author":{"gitId":"-"},"content":" * Adds all the pending and failed-to-add instructors."},{"lineNumber":154,"author":{"gitId":"-"},"content":" */"},{"lineNumber":155,"author":{"gitId":"-"},"content":" addAllInstructors(): void {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" for (let i: number \u003d 0; i \u003c this.instructorsConsolidated.length; i +\u003d 1) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" this.addInstructor(i);"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"domoberzin"},"content":" private formatAccountRequests(requests: AccountRequests): AccountRequestTableRowModel[] {"},{"lineNumber":162,"author":{"gitId":"domoberzin"},"content":" const timezone: string \u003d this.timezoneService.guessTimezone() || \u0027UTC\u0027;"},{"lineNumber":163,"author":{"gitId":"domoberzin"},"content":" return requests.accountRequests.map((request) \u003d\u003e {"},{"lineNumber":164,"author":{"gitId":"domoberzin"},"content":" return {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" id: request.id,"},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":" name: request.name,"},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" email: request.email,"},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":" status: request.status,"},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" instituteAndCountry: request.institute,"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" createdAtText: this.formatDateDetailPipe.transform(request.createdAt, timezone),"},{"lineNumber":171,"author":{"gitId":"domoberzin"},"content":" registeredAtText: request.registeredAt"},{"lineNumber":172,"author":{"gitId":"domoberzin"},"content":" ? this.formatDateDetailPipe.transform(request.registeredAt, timezone) : \u0027\u0027,"},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":" comments: request.comments || \u0027\u0027,"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":" registrationLink: \u0027\u0027,"},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" showLinks: false,"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" fetchAccountRequests(): void {"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":" this.accountService.getPendingAccountRequests().subscribe({"},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":" next: (resp: AccountRequests) \u003d\u003e {"},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":" this.accountReqs \u003d this.formatAccountRequests(resp);"},{"lineNumber":184,"author":{"gitId":"-"},"content":" },"},{"lineNumber":185,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":187,"author":{"gitId":"-"},"content":" },"},{"lineNumber":188,"author":{"gitId":"-"},"content":" });"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":35,"dishenggg":5,"-":150}},{"path":"src/web/app/pages-admin/admin-home-page/admin-home-page.module.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { CommonModule } from \u0027@angular/common\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { NgModule } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { FormsModule } from \u0027@angular/forms\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { RouterModule, Routes } from \u0027@angular/router\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { AdminHomePageComponent } from \u0027./admin-home-page.component\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { NewInstructorDataRowComponent } from \u0027./new-instructor-data-row/new-instructor-data-row.component\u0027;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import { AccountRequestTableModule } from \u0027../../components/account-requests-table/account-request-table.module\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { AjaxLoadingModule } from \u0027../../components/ajax-loading/ajax-loading.module\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { LoadingSpinnerModule } from \u0027../../components/loading-spinner/loading-spinner.module\u0027;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import { FormatDateDetailPipe } from \u0027../../components/teammates-common/format-date-detail.pipe\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"const routes: Routes \u003d ["},{"lineNumber":13,"author":{"gitId":"-"},"content":" {"},{"lineNumber":14,"author":{"gitId":"-"},"content":" path: \u0027\u0027,"},{"lineNumber":15,"author":{"gitId":"-"},"content":" component: AdminHomePageComponent,"},{"lineNumber":16,"author":{"gitId":"-"},"content":" },"},{"lineNumber":17,"author":{"gitId":"-"},"content":"];"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * Module for admin home page."},{"lineNumber":21,"author":{"gitId":"-"},"content":" */"},{"lineNumber":22,"author":{"gitId":"-"},"content":"@NgModule({"},{"lineNumber":23,"author":{"gitId":"-"},"content":" declarations: ["},{"lineNumber":24,"author":{"gitId":"-"},"content":" AdminHomePageComponent,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" NewInstructorDataRowComponent,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":27,"author":{"gitId":"-"},"content":" exports: ["},{"lineNumber":28,"author":{"gitId":"-"},"content":" AdminHomePageComponent,"},{"lineNumber":29,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":30,"author":{"gitId":"-"},"content":" imports: ["},{"lineNumber":31,"author":{"gitId":"-"},"content":" CommonModule,"},{"lineNumber":32,"author":{"gitId":"-"},"content":" FormsModule,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" RouterModule.forChild(routes),"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" AccountRequestTableModule,"},{"lineNumber":35,"author":{"gitId":"-"},"content":" AjaxLoadingModule,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" LoadingSpinnerModule,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" providers: ["},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" FormatDateDetailPipe,"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" ],"},{"lineNumber":41,"author":{"gitId":"-"},"content":"})"},{"lineNumber":42,"author":{"gitId":"-"},"content":"export class AdminHomePageModule { }"}],"authorContributionMap":{"domoberzin":6,"-":36}},{"path":"src/web/app/pages-admin/admin-search-page/admin-search-page.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"card bg-light top-padded\"\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":3,"author":{"gitId":"-"},"content":" \u003cp class\u003d\"text-muted\"\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" Tips: Surround key word to search a whole string or string contains punctuation like \"-\" \".\""},{"lineNumber":5,"author":{"gitId":"-"},"content":" \u003c/p\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"input-group\"\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"search-box\" type\u003d\"text\" class\u003d\"form-control\" aria-label\u003d\"Search\" [(ngModel)]\u003d\"searchQuery\""},{"lineNumber":9,"author":{"gitId":"-"},"content":" (keyup.enter)\u003d\"search()\" [maxlength]\u003d\"characterLimit\"\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"search-button\" class\u003d\"btn btn-primary input-group-text\" (click)\u003d\"search()\"\u003eSearch\u003c/button\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003cspan\u003e{{ characterLimit - searchQuery.length }} characters left\u003c/span\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"card bg-light top-padded\" *ngIf\u003d\"instructors.length\"\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header bg-info\"\u003e"},{"lineNumber":18,"author":{"gitId":"-"},"content":" \u003cstrong\u003eInstructors Found\u003c/strong\u003e"},{"lineNumber":19,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header-btn-toolbar\"\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"show-instructor-links\" class\u003d\"btn btn-light btn-sm\" style\u003d\"margin-right: 10px;\" type\u003d\"button\" (click)\u003d\"showAllInstructorsLinks()\"\u003eExpand All\u003c/button\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"hide-instructor-links\" class\u003d\"btn btn-light btn-sm\" type\u003d\"button\" (click)\u003d\"hideAllInstructorsLinks()\"\u003eCollapse All\u003c/button\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":23,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"table-responsive\"\u003e"},{"lineNumber":26,"author":{"gitId":"-"},"content":" \u003ctable id\u003d\"search-table-instructor\" class\u003d\"table table-striped data-table\"\u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003cthead\u003e"},{"lineNumber":28,"author":{"gitId":"-"},"content":" \u003ctr\u003e"},{"lineNumber":29,"author":{"gitId":"-"},"content":" \u003cth\u003eCourse\u003c/th\u003e"},{"lineNumber":30,"author":{"gitId":"-"},"content":" \u003cth\u003eName\u003c/th\u003e"},{"lineNumber":31,"author":{"gitId":"-"},"content":" \u003cth\u003eGoogle ID\u003c/th\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003cth\u003eInstitute\u003c/th\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003cth\u003eOptions\u003c/th\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":" \u003c/thead\u003e"},{"lineNumber":36,"author":{"gitId":"-"},"content":" \u003ctbody\u003e"},{"lineNumber":37,"author":{"gitId":"-"},"content":" \u003cng-container *ngFor\u003d\"let instructor of instructors; let i \u003d index\"\u003e"},{"lineNumber":38,"author":{"gitId":"-"},"content":" \u003ctr (click)\u003d\"instructor.showLinks \u003d !instructor.showLinks\"\u003e"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003ctd class\u003d\"text-break\"\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"ngb-tooltip-class\" [ngClass]\u003d\"{\u0027text-course-deleted\u0027: instructor.isCourseDeleted}\" [ngbTooltip]\u003d\"instructor.courseName\" [innerHtml]\u003d\"instructor.courseId | highlighter:searchString:true\"\u003e\u003c/span\u003e"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003ci *ngIf\u003d\"instructor.isCourseDeleted\" class\u003d\"fas fa-trash-alt text-course-deleted margin-left-5px bin-icon\" [ngbTooltip]\u003d\"\u0027This course is in the recycle bin.\u0027\"\u003e\u003c/i\u003e"},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u003cbr\u003e"},{"lineNumber":43,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-sm-1\"\u003e"},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u003cbutton *ngIf\u003d\"!instructor.showLinks\" class\u003d\"btn\" aria-label\u003d\"Expand\"\u003e"},{"lineNumber":45,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-chevron-circle-down\" style\u003d\"color: blue;\"\u003e\u003c/i\u003e"},{"lineNumber":46,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":47,"author":{"gitId":"-"},"content":" \u003cbutton *ngIf\u003d\"instructor.showLinks\" class\u003d\"btn\" aria-label\u003d\"Collapse\"\u003e"},{"lineNumber":48,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-chevron-circle-up\" style\u003d\"color: blue;\"\u003e\u003c/i\u003e"},{"lineNumber":49,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":50,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":51,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":52,"author":{"gitId":"-"},"content":" \u003ctd [innerHtml]\u003d\"instructor.name | highlighter:searchString:true\"\u003e\u003c/td\u003e"},{"lineNumber":53,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003ca href\u003d\"{{ instructor.homePageLink }}\" (click)\u003d\"$event.stopPropagation()\" target\u003d\"_blank\" rel\u003d\"noopener noreferrer\" [innerHtml]\u003d\"instructor.googleId | highlighter:searchString:true\"\u003e"},{"lineNumber":54,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":56,"author":{"gitId":"-"},"content":" \u003ctd [innerHtml]\u003d\"instructor.institute | highlighter:searchString:true\"\u003e\u003c/td\u003e"},{"lineNumber":57,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":58,"author":{"gitId":"-"},"content":" \u003ca href\u003d\"{{ instructor.manageAccountLink }}\" *ngIf\u003d\"instructor.manageAccountLink\""},{"lineNumber":59,"author":{"gitId":"-"},"content":" (click)\u003d\"$event.stopPropagation()\" target\u003d\"_blank\" rel\u003d\"noopener noreferrer\"\u003e"},{"lineNumber":60,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-info-circle\"\u003e\u003c/i\u003e Manage this account"},{"lineNumber":61,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":62,"author":{"gitId":"-"},"content":" \u003cbr\u003e"},{"lineNumber":63,"author":{"gitId":"-"},"content":" \u003ca id\u003d\"reset-instructor-id-{{i}}\" href\u003d\"javascript:;\" (click)\u003d\"resetInstructorGoogleId(instructor, $event)\" *ngIf\u003d\"instructor.googleId\"\u003e"},{"lineNumber":64,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sync\"\u003e\u003c/i\u003e Reset Google ID"},{"lineNumber":65,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":66,"author":{"gitId":"-"},"content":" \u003cbr\u003e"},{"lineNumber":67,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"regenerate-instructor-key-{{i}}\" class\u003d\"btn btn-danger\" (click)\u003d\"instructor.showLinks \u003d !instructor.showLinks; regenerateInstructorKey(instructor);\"\u003eRegenerate key\u003c/button\u003e"},{"lineNumber":68,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":69,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":70,"author":{"gitId":"-"},"content":" \u003ctr *ngIf\u003d\"instructor.showLinks\"\u003e"},{"lineNumber":71,"author":{"gitId":"-"},"content":" \u003ctd colspan\u003d\"5\"\u003e"},{"lineNumber":72,"author":{"gitId":"-"},"content":" \u003cul class\u003d\"list-group\"\u003e"},{"lineNumber":73,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-success has-success\"\u003e"},{"lineNumber":74,"author":{"gitId":"-"},"content":" \u003cstrong\u003eEmail\u003c/strong\u003e"},{"lineNumber":75,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"instructor.email\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":76,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":77,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-info\"\u003e"},{"lineNumber":78,"author":{"gitId":"-"},"content":" \u003cstrong\u003eCourse Join Link\u003c/strong\u003e"},{"lineNumber":79,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"instructor.courseJoinLink\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":80,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":81,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-light\" *ngFor\u003d\"let awaitingFs of instructor.awaitingSessions | keyvalue\"\u003e"},{"lineNumber":82,"author":{"gitId":"-"},"content":" \u003cstrong\u003e{{ awaitingFs.key + \u0027 \u0027 + awaitingFs.value.startTime + \u0027 - \u0027 + awaitingFs.value.endTime }}\u003c/strong\u003e"},{"lineNumber":83,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"awaitingFs.value.feedbackSessionUrl\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":84,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":85,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-warning\" *ngFor\u003d\"let openFs of instructor.openSessions | keyvalue\"\u003e"},{"lineNumber":86,"author":{"gitId":"-"},"content":" \u003cstrong\u003e{{ openFs.key + \u0027 \u0027 + openFs.value.startTime + \u0027 - \u0027 + openFs.value.endTime }}\u003c/strong\u003e"},{"lineNumber":87,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"openFs.value.feedbackSessionUrl\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":88,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":89,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-danger\" *ngFor\u003d\"let notOpenFs of instructor.notOpenSessions | keyvalue\"\u003e"},{"lineNumber":90,"author":{"gitId":"-"},"content":" \u003cstrong\u003e{{ notOpenFs.key + \u0027 \u0027 + notOpenFs.value.startTime + \u0027 - \u0027 + notOpenFs.value.endTime }}\u003c/strong\u003e"},{"lineNumber":91,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"notOpenFs.value.feedbackSessionUrl\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":92,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":93,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-success\" *ngFor\u003d\"let publishedFs of instructor.publishedSessions | keyvalue\"\u003e"},{"lineNumber":94,"author":{"gitId":"-"},"content":" \u003cstrong\u003e{{ publishedFs.key + \u0027 \u0027 + publishedFs.value.startTime + \u0027 - \u0027 + publishedFs.value.endTime }}\u003c/strong\u003e"},{"lineNumber":95,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"publishedFs.value.feedbackSessionUrl\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":96,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":97,"author":{"gitId":"-"},"content":" \u003c/ul\u003e"},{"lineNumber":98,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":99,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":100,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":101,"author":{"gitId":"-"},"content":" \u003c/tbody\u003e"},{"lineNumber":102,"author":{"gitId":"-"},"content":" \u003c/table\u003e"},{"lineNumber":103,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":104,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"card bg-light top-padded\" *ngIf\u003d\"students.length\"\u003e"},{"lineNumber":107,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header bg-primary text-white\"\u003e"},{"lineNumber":108,"author":{"gitId":"-"},"content":" \u003cstrong\u003eStudents Found\u003c/strong\u003e"},{"lineNumber":109,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header-btn-toolbar\"\u003e"},{"lineNumber":110,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"show-student-links\" class\u003d\"btn btn-light btn-sm\" style\u003d\"margin-right: 10px;\" type\u003d\"button\" (click)\u003d\"showAllStudentsLinks()\"\u003eExpand All\u003c/button\u003e"},{"lineNumber":111,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"hide-student-links\" class\u003d\"btn btn-light btn-sm\" type\u003d\"button\" (click)\u003d\"hideAllStudentsLinks()\"\u003eCollapse All\u003c/button\u003e"},{"lineNumber":112,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":113,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"table-responsive\"\u003e"},{"lineNumber":116,"author":{"gitId":"-"},"content":" \u003ctable class\u003d\"table table-striped data-table\" id\u003d\"search-table-student\"\u003e"},{"lineNumber":117,"author":{"gitId":"-"},"content":" \u003cthead\u003e"},{"lineNumber":118,"author":{"gitId":"-"},"content":" \u003ctr\u003e"},{"lineNumber":119,"author":{"gitId":"-"},"content":" \u003cth\u003eCourse [Section] (Team)\u003c/th\u003e"},{"lineNumber":120,"author":{"gitId":"-"},"content":" \u003cth\u003eName\u003c/th\u003e"},{"lineNumber":121,"author":{"gitId":"-"},"content":" \u003cth\u003eGoogle ID\u003c/th\u003e"},{"lineNumber":122,"author":{"gitId":"-"},"content":" \u003cth\u003eInstitute\u003c/th\u003e"},{"lineNumber":123,"author":{"gitId":"-"},"content":" \u003cth\u003eComments\u003c/th\u003e"},{"lineNumber":124,"author":{"gitId":"-"},"content":" \u003cth\u003eOptions\u003c/th\u003e"},{"lineNumber":125,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":126,"author":{"gitId":"-"},"content":" \u003c/thead\u003e"},{"lineNumber":127,"author":{"gitId":"-"},"content":" \u003ctbody\u003e"},{"lineNumber":128,"author":{"gitId":"-"},"content":" \u003cng-container *ngFor\u003d\"let student of students; let i \u003d index\"\u003e"},{"lineNumber":129,"author":{"gitId":"-"},"content":" \u003ctr (click)\u003d\"student.showLinks \u003d !student.showLinks\"\u003e"},{"lineNumber":130,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":131,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"text-break ngb-tooltip-class\" [ngClass]\u003d\"{\u0027text-course-deleted\u0027: student.isCourseDeleted}\" [ngbTooltip]\u003d\"student.courseName\""},{"lineNumber":132,"author":{"gitId":"-"},"content":" [innerHtml]\u003d\"student.courseId + \u0027 [\u0027 + student.section + \u0027] (\u0027 + student.team + \u0027)\u0027 | highlighter:searchString:true\"\u003e\u003c/span\u003e"},{"lineNumber":133,"author":{"gitId":"-"},"content":" \u003ci *ngIf\u003d\"student.isCourseDeleted\" class\u003d\"fas fa-trash-alt text-course-deleted margin-left-5px bin-icon\" [ngbTooltip]\u003d\"\u0027This course is in the recycle bin.\u0027\"\u003e\u003c/i\u003e"},{"lineNumber":134,"author":{"gitId":"-"},"content":" \u003cbr\u003e"},{"lineNumber":135,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-sm-1\"\u003e"},{"lineNumber":136,"author":{"gitId":"-"},"content":" \u003cbutton *ngIf\u003d\"!student.showLinks\" class\u003d\"btn\" aria-label\u003d\"Expand\"\u003e"},{"lineNumber":137,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-chevron-circle-down\" style\u003d\"color: blue;\"\u003e\u003c/i\u003e"},{"lineNumber":138,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":139,"author":{"gitId":"-"},"content":" \u003cbutton *ngIf\u003d\"student.showLinks\" class\u003d\"btn\" aria-label\u003d\"Collapse\"\u003e"},{"lineNumber":140,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-chevron-circle-up\" style\u003d\"color: blue;\"\u003e\u003c/i\u003e"},{"lineNumber":141,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":142,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":143,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":144,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003ca href\u003d\"{{ student.profilePageLink }}\""},{"lineNumber":145,"author":{"gitId":"-"},"content":" (click)\u003d\"$event.stopPropagation()\" target\u003d\"_blank\" rel\u003d\"noopener noreferrer\" [innerHtml]\u003d\"student.name | highlighter:searchString:true\"\u003e"},{"lineNumber":146,"author":{"gitId":"-"},"content":" \u003c/a\u003e\u003c/td\u003e"},{"lineNumber":147,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003ca href\u003d\"{{ student.homePageLink }}\" *ngIf\u003d\"student.googleId\""},{"lineNumber":148,"author":{"gitId":"-"},"content":" (click)\u003d\"$event.stopPropagation()\" target\u003d\"_blank\" rel\u003d\"noopener noreferrer\" [innerHtml]\u003d\"student.googleId | highlighter:searchString:true\"\u003e"},{"lineNumber":149,"author":{"gitId":"-"},"content":" \u003c/a\u003e\u003c/td\u003e"},{"lineNumber":150,"author":{"gitId":"-"},"content":" \u003ctd [innerHtml]\u003d\"student.institute | highlighter:searchString:true\"\u003e\u003c/td\u003e"},{"lineNumber":151,"author":{"gitId":"-"},"content":" \u003ctd [innerHtml]\u003d\"student.comments | highlighter:searchString:true\"\u003e\u003c/td\u003e"},{"lineNumber":152,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":153,"author":{"gitId":"-"},"content":" \u003ca href\u003d\"{{ student.manageAccountLink }}\" *ngIf\u003d\"student.googleId \u0026\u0026 student.manageAccountLink\""},{"lineNumber":154,"author":{"gitId":"-"},"content":" (click)\u003d\"$event.stopPropagation()\" target\u003d\"_blank\" rel\u003d\"noopener noreferrer\"\u003e"},{"lineNumber":155,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-info-circle\"\u003e\u003c/i\u003e Manage this account"},{"lineNumber":156,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":157,"author":{"gitId":"-"},"content":" \u003cbr\u003e"},{"lineNumber":158,"author":{"gitId":"-"},"content":" \u003ca id\u003d\"reset-student-id-{{i}}\" href\u003d\"javascript:;\" (click)\u003d\"resetStudentGoogleId(student, $event)\" *ngIf\u003d\"student.googleId\"\u003e"},{"lineNumber":159,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sync\"\u003e\u003c/i\u003e Reset Google ID"},{"lineNumber":160,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":161,"author":{"gitId":"-"},"content":" \u003cbr\u003e"},{"lineNumber":162,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"regenerate-student-key-{{i}}\" class\u003d\"btn btn-danger\" (click)\u003d\"student.showLinks \u003d !student.showLinks; regenerateStudentKey(student);\"\u003eRegenerate key\u003c/button\u003e"},{"lineNumber":163,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":164,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":165,"author":{"gitId":"-"},"content":" \u003ctr\u003e"},{"lineNumber":166,"author":{"gitId":"-"},"content":" \u003ctd colspan\u003d\"6\"\u003e"},{"lineNumber":167,"author":{"gitId":"-"},"content":" \u003cul class\u003d\"list-group\" *ngIf\u003d\"student.showLinks\" @collapseAnim\u003e"},{"lineNumber":168,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-success has-success\"\u003e"},{"lineNumber":169,"author":{"gitId":"-"},"content":" \u003cstrong\u003eEmail\u003c/strong\u003e"},{"lineNumber":170,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"student.email\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":171,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":172,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-info\"\u003e"},{"lineNumber":173,"author":{"gitId":"-"},"content":" \u003cstrong\u003eCourse Join Link\u003c/strong\u003e"},{"lineNumber":174,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"send-course-join-button\" type\u003d\"button\" class\u003d\"btn btn-primary margin-left-5px btn-sm\" (click)\u003d\"openCourseJoinEmail(student.courseId, student.email)\"\u003eSend mail\u003c/button\u003e"},{"lineNumber":175,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"student.courseJoinLink\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":176,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":177,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-light\" *ngFor\u003d\"let awaitingFs of student.awaitingSessions | keyvalue\"\u003e"},{"lineNumber":178,"author":{"gitId":"-"},"content":" \u003cstrong\u003e{{ awaitingFs.key + \u0027 \u0027 + awaitingFs.value.startTime + \u0027 - \u0027 + awaitingFs.value.endTime }}\u003c/strong\u003e"},{"lineNumber":179,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"send-awaiting-session-reminder-button\" type\u003d\"button\" class\u003d\"btn btn-primary margin-left-5px btn-sm\" (click)\u003d\"openFeedbackSessionReminderEmail(student.courseId, student.email, awaitingFs.key)\"\u003eSend mail\u003c/button\u003e"},{"lineNumber":180,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"awaitingFs.value.feedbackSessionUrl\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":181,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":182,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-warning\" *ngFor\u003d\"let openFs of student.openSessions | keyvalue\"\u003e"},{"lineNumber":183,"author":{"gitId":"-"},"content":" \u003cstrong\u003e{{ openFs.key + \u0027 \u0027 + openFs.value.startTime + \u0027 - \u0027 + openFs.value.endTime }}\u003c/strong\u003e"},{"lineNumber":184,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"send-open-session-reminder-button\" type\u003d\"button\" class\u003d\"btn btn-primary margin-left-5px btn-sm\" (click)\u003d\"openFeedbackSessionReminderEmail(student.courseId, student.email, openFs.key)\"\u003eSend mail\u003c/button\u003e"},{"lineNumber":185,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"openFs.value.feedbackSessionUrl\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":186,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":187,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-danger\" *ngFor\u003d\"let notOpenFs of student.notOpenSessions | keyvalue\"\u003e"},{"lineNumber":188,"author":{"gitId":"-"},"content":" \u003cstrong\u003e{{ notOpenFs.key + \u0027 \u0027 + notOpenFs.value.startTime + \u0027 - \u0027 + notOpenFs.value.endTime }}\u003c/strong\u003e"},{"lineNumber":189,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"send-not-open-session-reminder-button\" type\u003d\"button\" class\u003d\"btn btn-primary margin-left-5px btn-sm\" (click)\u003d\"openFeedbackSessionReminderEmail(student.courseId, student.email, notOpenFs.key)\"\u003eSend mail\u003c/button\u003e"},{"lineNumber":190,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"notOpenFs.value.feedbackSessionUrl\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":191,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":192,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-success\" *ngFor\u003d\"let publishedFs of student.publishedSessions | keyvalue\"\u003e"},{"lineNumber":193,"author":{"gitId":"-"},"content":" \u003cstrong\u003e{{ publishedFs.key + \u0027 \u0027 + publishedFs.value.startTime + \u0027 - \u0027 + publishedFs.value.endTime }}\u003c/strong\u003e"},{"lineNumber":194,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"send-published-session-reminder-button\" type\u003d\"button\" class\u003d\"btn btn-primary margin-left-5px btn-sm\" (click)\u003d\"openFeedbackSessionReminderEmail(student.courseId, student.email, publishedFs.key)\"\u003eSend mail\u003c/button\u003e"},{"lineNumber":195,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"publishedFs.value.feedbackSessionUrl\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":196,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":197,"author":{"gitId":"-"},"content":" \u003c/ul\u003e"},{"lineNumber":198,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":199,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":200,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":201,"author":{"gitId":"-"},"content":" \u003c/tbody\u003e"},{"lineNumber":202,"author":{"gitId":"-"},"content":" \u003c/table\u003e"},{"lineNumber":203,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":204,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"domoberzin"},"content":"\u003ctm-account-request-table *ngIf\u003d\"accountRequests.length\" [accountRequests]\u003d\"accountRequests\" [searchString]\u003d\"searchString\"\u003e\u003c/tm-account-request-table\u003e"}],"authorContributionMap":{"domoberzin":1,"-":205}},{"path":"src/web/app/pages-admin/admin-search-page/admin-search-page.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { NgbModalRef } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { finalize } from \u0027rxjs/operators\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { AccountService } from \u0027../../../services/account.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { EmailGenerationService } from \u0027../../../services/email-generation.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { InstructorService } from \u0027../../../services/instructor.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { LoadingBarService } from \u0027../../../services/loading-bar.service\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":9,"author":{"gitId":"-"},"content":" AccountRequestSearchResult,"},{"lineNumber":10,"author":{"gitId":"-"},"content":" AdminSearchResult,"},{"lineNumber":11,"author":{"gitId":"-"},"content":" FeedbackSessionsGroup,"},{"lineNumber":12,"author":{"gitId":"-"},"content":" InstructorAccountSearchResult,"},{"lineNumber":13,"author":{"gitId":"-"},"content":" SearchService,"},{"lineNumber":14,"author":{"gitId":"-"},"content":" StudentAccountSearchResult,"},{"lineNumber":15,"author":{"gitId":"-"},"content":"} from \u0027../../../services/search.service\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import { SimpleModalService } from \u0027../../../services/simple-modal.service\u0027;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import { StatusMessageService } from \u0027../../../services/status-message.service\u0027;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import { StudentService } from \u0027../../../services/student.service\u0027;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import { ApiConst } from \u0027../../../types/api-const\u0027;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":"import { Email, RegenerateKey } from \u0027../../../types/api-output\u0027;"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":"import {"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" AccountRequestTableRowModel,"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":"} from \u0027../../components/account-requests-table/account-request-table-model\u0027;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import { SimpleModalType } from \u0027../../components/simple-modal/simple-modal-type\u0027;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import { collapseAnim } from \u0027../../components/teammates-common/collapse-anim\u0027;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import { ErrorMessageOutput } from \u0027../../error-message-output\u0027;"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":29,"author":{"gitId":"-"},"content":" * Admin search page."},{"lineNumber":30,"author":{"gitId":"-"},"content":" */"},{"lineNumber":31,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":32,"author":{"gitId":"-"},"content":" selector: \u0027tm-admin-search-page\u0027,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" templateUrl: \u0027./admin-search-page.component.html\u0027,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./admin-search-page.component.scss\u0027],"},{"lineNumber":35,"author":{"gitId":"-"},"content":" animations: [collapseAnim],"},{"lineNumber":36,"author":{"gitId":"-"},"content":"})"},{"lineNumber":37,"author":{"gitId":"-"},"content":"export class AdminSearchPageComponent {"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" searchQuery: string \u003d \u0027\u0027;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" searchString: string \u003d \u0027\u0027;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" instructors: InstructorAccountSearchResult[] \u003d [];"},{"lineNumber":42,"author":{"gitId":"-"},"content":" students: StudentAccountSearchResult[] \u003d [];"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" accountRequests: AccountRequestTableRowModel[] \u003d [];"},{"lineNumber":44,"author":{"gitId":"-"},"content":" characterLimit \u003d 100;"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" constructor("},{"lineNumber":47,"author":{"gitId":"-"},"content":" private statusMessageService: StatusMessageService,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" private simpleModalService: SimpleModalService,"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private accountService: AccountService,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" private instructorService: InstructorService,"},{"lineNumber":51,"author":{"gitId":"-"},"content":" private studentService: StudentService,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" private searchService: SearchService,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" private emailGenerationService: EmailGenerationService,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" private loadingBarService: LoadingBarService,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" ) {}"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":58,"author":{"gitId":"-"},"content":" * Searches for students and instructors matching the search query."},{"lineNumber":59,"author":{"gitId":"-"},"content":" */"},{"lineNumber":60,"author":{"gitId":"-"},"content":" search(): void {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" this.loadingBarService.showLoadingBar();"},{"lineNumber":62,"author":{"gitId":"-"},"content":" this.searchService.searchAdmin("},{"lineNumber":63,"author":{"gitId":"-"},"content":" this.searchQuery,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" ).pipe(finalize(() \u003d\u003e {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" this.loadingBarService.hideLoadingBar();"},{"lineNumber":66,"author":{"gitId":"-"},"content":" })).subscribe({"},{"lineNumber":67,"author":{"gitId":"-"},"content":" next: (resp: AdminSearchResult) \u003d\u003e {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" const hasStudents: boolean \u003d !!(resp.students \u0026\u0026 resp.students.length);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" const hasInstructors: boolean \u003d !!(resp.instructors \u0026\u0026 resp.instructors.length);"},{"lineNumber":70,"author":{"gitId":"-"},"content":" const hasAccountRequests: boolean \u003d !!(resp.accountRequests \u0026\u0026 resp.accountRequests.length);"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" if (!hasStudents \u0026\u0026 !hasInstructors \u0026\u0026 !hasAccountRequests) {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" this.statusMessageService.showWarningToast(\u0027No results found.\u0027);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" this.instructors \u003d [];"},{"lineNumber":75,"author":{"gitId":"-"},"content":" this.students \u003d [];"},{"lineNumber":76,"author":{"gitId":"-"},"content":" this.accountRequests \u003d [];"},{"lineNumber":77,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" this.instructors \u003d resp.instructors;"},{"lineNumber":81,"author":{"gitId":"-"},"content":" this.students \u003d resp.students;"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" this.accountRequests \u003d this.formatAccountRequests(resp.accountRequests);"},{"lineNumber":83,"author":{"gitId":"-"},"content":" this.hideAllInstructorsLinks();"},{"lineNumber":84,"author":{"gitId":"-"},"content":" this.hideAllStudentsLinks();"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" // prompt user to use more specific terms if search results limit reached"},{"lineNumber":87,"author":{"gitId":"-"},"content":" const limit: number \u003d ApiConst.SEARCH_QUERY_SIZE_LIMIT;"},{"lineNumber":88,"author":{"gitId":"-"},"content":" const limitsReached: string[] \u003d [];"},{"lineNumber":89,"author":{"gitId":"-"},"content":" if (this.students.length \u003e\u003d limit) {"},{"lineNumber":90,"author":{"gitId":"-"},"content":" limitsReached.push(`${limit} student results`);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" }"},{"lineNumber":92,"author":{"gitId":"-"},"content":" if (this.instructors.length \u003e\u003d limit) {"},{"lineNumber":93,"author":{"gitId":"-"},"content":" limitsReached.push(`${limit} instructor results`);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" }"},{"lineNumber":95,"author":{"gitId":"-"},"content":" if (this.accountRequests.length \u003e\u003d limit) {"},{"lineNumber":96,"author":{"gitId":"-"},"content":" limitsReached.push(`${limit} account request results`);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" }"},{"lineNumber":98,"author":{"gitId":"-"},"content":" if (limitsReached.length) {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" this.statusMessageService.showWarningToast(`${limitsReached.join(\u0027 and \u0027)} have been shown on this page"},{"lineNumber":100,"author":{"gitId":"-"},"content":" but there may be more results not shown. Consider searching with more specific terms.`);"},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" this.searchString \u003d this.searchQuery;"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" },"},{"lineNumber":106,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" this.instructors \u003d [];"},{"lineNumber":108,"author":{"gitId":"-"},"content":" this.students \u003d [];"},{"lineNumber":109,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" },"},{"lineNumber":111,"author":{"gitId":"-"},"content":" });"},{"lineNumber":112,"author":{"gitId":"-"},"content":" }"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" private formatAccountRequests(accountRequests: AccountRequestSearchResult[]): AccountRequestTableRowModel[] {"},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" return accountRequests.map((accountRequest: AccountRequestSearchResult): AccountRequestTableRowModel \u003d\u003e {"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" return {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" id: accountRequest.id,"},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":" name: accountRequest.name,"},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" email: accountRequest.email,"},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" status: accountRequest.status,"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":" instituteAndCountry: accountRequest.institute,"},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" createdAtText: accountRequest.createdAtText,"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":" registeredAtText: accountRequest.registeredAtText || \u0027\u0027,"},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" comments: accountRequest.comments,"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" registrationLink: accountRequest.registrationLink,"},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" showLinks: accountRequest.showLinks,"},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":128,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":129,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":132,"author":{"gitId":"-"},"content":" * Shows all instructors\u0027 links in the page."},{"lineNumber":133,"author":{"gitId":"-"},"content":" */"},{"lineNumber":134,"author":{"gitId":"-"},"content":" showAllInstructorsLinks(): void {"},{"lineNumber":135,"author":{"gitId":"-"},"content":" for (const instructor of this.instructors) {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" instructor.showLinks \u003d true;"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":141,"author":{"gitId":"-"},"content":" * Hides all instructors\u0027 links in the page."},{"lineNumber":142,"author":{"gitId":"-"},"content":" */"},{"lineNumber":143,"author":{"gitId":"-"},"content":" hideAllInstructorsLinks(): void {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" for (const instructor of this.instructors) {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" instructor.showLinks \u003d false;"},{"lineNumber":146,"author":{"gitId":"-"},"content":" }"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":150,"author":{"gitId":"-"},"content":" * Shows all students\u0027 links in the page."},{"lineNumber":151,"author":{"gitId":"-"},"content":" */"},{"lineNumber":152,"author":{"gitId":"-"},"content":" showAllStudentsLinks(): void {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" for (const student of this.students) {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" student.showLinks \u003d true;"},{"lineNumber":155,"author":{"gitId":"-"},"content":" }"},{"lineNumber":156,"author":{"gitId":"-"},"content":" }"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":159,"author":{"gitId":"-"},"content":" * Hides all students\u0027 links in the page."},{"lineNumber":160,"author":{"gitId":"-"},"content":" */"},{"lineNumber":161,"author":{"gitId":"-"},"content":" hideAllStudentsLinks(): void {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" for (const student of this.students) {"},{"lineNumber":163,"author":{"gitId":"-"},"content":" student.showLinks \u003d false;"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":168,"author":{"gitId":"-"},"content":" * Resets the instructor\u0027s Google ID."},{"lineNumber":169,"author":{"gitId":"-"},"content":" */"},{"lineNumber":170,"author":{"gitId":"-"},"content":" resetInstructorGoogleId(instructor: InstructorAccountSearchResult, event: any): void {"},{"lineNumber":171,"author":{"gitId":"-"},"content":" if (event) {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" event.preventDefault();"},{"lineNumber":173,"author":{"gitId":"-"},"content":" event.stopPropagation();"},{"lineNumber":174,"author":{"gitId":"-"},"content":" }"},{"lineNumber":175,"author":{"gitId":"-"},"content":""},{"lineNumber":176,"author":{"gitId":"-"},"content":" const modalContent: string \u003d `Are you sure you want to reset the Google account ID currently associated for"},{"lineNumber":177,"author":{"gitId":"-"},"content":" \u003cstrong\u003e${instructor.name}\u003c/strong\u003e in the course \u003cstrong\u003e${instructor.courseId}\u003c/strong\u003e?"},{"lineNumber":178,"author":{"gitId":"-"},"content":" The user will need to re-associate their account with a new Google ID.`;"},{"lineNumber":179,"author":{"gitId":"-"},"content":" const modalRef: NgbModalRef \u003d this.simpleModalService.openConfirmationModal("},{"lineNumber":180,"author":{"gitId":"-"},"content":" `Reset \u003cstrong\u003e${instructor.name}\u003c/strong\u003e\u0027s Google ID?`, SimpleModalType.WARNING, modalContent);"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" modalRef.result.then(() \u003d\u003e {"},{"lineNumber":183,"author":{"gitId":"-"},"content":" this.accountService.resetInstructorAccount(instructor.courseId, instructor.email).subscribe({"},{"lineNumber":184,"author":{"gitId":"-"},"content":" next: () \u003d\u003e {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" this.search();"},{"lineNumber":186,"author":{"gitId":"-"},"content":" this.statusMessageService.showSuccessToast(\u0027The instructor\\\u0027s Google ID has been reset.\u0027);"},{"lineNumber":187,"author":{"gitId":"-"},"content":" },"},{"lineNumber":188,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":189,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":190,"author":{"gitId":"-"},"content":" },"},{"lineNumber":191,"author":{"gitId":"-"},"content":" });"},{"lineNumber":192,"author":{"gitId":"-"},"content":" }, () \u003d\u003e {});"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":196,"author":{"gitId":"-"},"content":" * Resets the student\u0027s Google ID."},{"lineNumber":197,"author":{"gitId":"-"},"content":" */"},{"lineNumber":198,"author":{"gitId":"-"},"content":" resetStudentGoogleId(student: StudentAccountSearchResult, event: any): void {"},{"lineNumber":199,"author":{"gitId":"-"},"content":" if (event) {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" event.preventDefault();"},{"lineNumber":201,"author":{"gitId":"-"},"content":" event.stopPropagation();"},{"lineNumber":202,"author":{"gitId":"-"},"content":" }"},{"lineNumber":203,"author":{"gitId":"-"},"content":" const modalContent: string \u003d `Are you sure you want to reset the Google account ID currently associated for"},{"lineNumber":204,"author":{"gitId":"-"},"content":" \u003cstrong\u003e${student.name}\u003c/strong\u003e in the course \u003cstrong\u003e${student.courseId}\u003c/strong\u003e?"},{"lineNumber":205,"author":{"gitId":"-"},"content":" The user will need to re-associate their account with a new Google ID.`;"},{"lineNumber":206,"author":{"gitId":"-"},"content":" const modalRef: NgbModalRef \u003d this.simpleModalService.openConfirmationModal("},{"lineNumber":207,"author":{"gitId":"-"},"content":" `Reset \u003cstrong\u003e${student.name}\u003c/strong\u003e\u0027s Google ID?`, SimpleModalType.WARNING, modalContent);"},{"lineNumber":208,"author":{"gitId":"-"},"content":""},{"lineNumber":209,"author":{"gitId":"-"},"content":" modalRef.result.then(() \u003d\u003e {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" this.accountService.resetStudentAccount(student.courseId, student.email).subscribe({"},{"lineNumber":211,"author":{"gitId":"-"},"content":" next: () \u003d\u003e {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" student.googleId \u003d \u0027\u0027;"},{"lineNumber":213,"author":{"gitId":"-"},"content":" this.statusMessageService.showSuccessToast(\u0027The student\\\u0027s Google ID has been reset.\u0027);"},{"lineNumber":214,"author":{"gitId":"-"},"content":" },"},{"lineNumber":215,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":216,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":217,"author":{"gitId":"-"},"content":" },"},{"lineNumber":218,"author":{"gitId":"-"},"content":" });"},{"lineNumber":219,"author":{"gitId":"-"},"content":" }, () \u003d\u003e {});"},{"lineNumber":220,"author":{"gitId":"-"},"content":" }"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":223,"author":{"gitId":"-"},"content":" * Regenerates the student\u0027s registration key."},{"lineNumber":224,"author":{"gitId":"-"},"content":" */"},{"lineNumber":225,"author":{"gitId":"-"},"content":" regenerateStudentKey(student: StudentAccountSearchResult): void {"},{"lineNumber":226,"author":{"gitId":"-"},"content":" const modalContent: string \u003d `Are you sure you want to regenerate the registration key for"},{"lineNumber":227,"author":{"gitId":"-"},"content":" \u003cstrong\u003e${student.name}\u003c/strong\u003e for the course \u003cstrong\u003e${student.courseId}\u003c/strong\u003e?"},{"lineNumber":228,"author":{"gitId":"-"},"content":" An email will be sent to the student with all the new course registration and feedback session links.`;"},{"lineNumber":229,"author":{"gitId":"-"},"content":" const modalRef: NgbModalRef \u003d this.simpleModalService.openConfirmationModal("},{"lineNumber":230,"author":{"gitId":"-"},"content":" `Regenerate \u003cstrong\u003e${student.name}\u003c/strong\u003e\u0027s course links?`, SimpleModalType.WARNING, modalContent);"},{"lineNumber":231,"author":{"gitId":"-"},"content":""},{"lineNumber":232,"author":{"gitId":"-"},"content":" modalRef.result.then(() \u003d\u003e {"},{"lineNumber":233,"author":{"gitId":"-"},"content":" this.studentService.regenerateStudentKey(student.courseId, student.email)"},{"lineNumber":234,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":235,"author":{"gitId":"-"},"content":" next: (resp: RegenerateKey) \u003d\u003e {"},{"lineNumber":236,"author":{"gitId":"-"},"content":" this.statusMessageService.showSuccessToast(resp.message);"},{"lineNumber":237,"author":{"gitId":"-"},"content":" this.updateDisplayedStudentCourseLinks(student, resp.newRegistrationKey);"},{"lineNumber":238,"author":{"gitId":"-"},"content":" },"},{"lineNumber":239,"author":{"gitId":"-"},"content":" error: (response: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":240,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(response.error.message);"},{"lineNumber":241,"author":{"gitId":"-"},"content":" },"},{"lineNumber":242,"author":{"gitId":"-"},"content":" });"},{"lineNumber":243,"author":{"gitId":"-"},"content":" }, () \u003d\u003e {});"},{"lineNumber":244,"author":{"gitId":"-"},"content":" }"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":247,"author":{"gitId":"-"},"content":" * Regenerates the instructor\u0027s registration key."},{"lineNumber":248,"author":{"gitId":"-"},"content":" */"},{"lineNumber":249,"author":{"gitId":"-"},"content":" regenerateInstructorKey(instructor: InstructorAccountSearchResult): void {"},{"lineNumber":250,"author":{"gitId":"-"},"content":" const modalContent: string \u003d `Are you sure you want to regenerate the registration key for"},{"lineNumber":251,"author":{"gitId":"-"},"content":" \u003cstrong\u003e${instructor.name}\u003c/strong\u003e for the course \u003cstrong\u003e${instructor.courseId}\u003c/strong\u003e?"},{"lineNumber":252,"author":{"gitId":"-"},"content":" An email will be sent to the instructor with all the new course registration and feedback session links.`;"},{"lineNumber":253,"author":{"gitId":"-"},"content":" const modalRef: NgbModalRef \u003d this.simpleModalService.openConfirmationModal("},{"lineNumber":254,"author":{"gitId":"-"},"content":" `Regenerate \u003cstrong\u003e${instructor.name}\u003c/strong\u003e\u0027s course links?`, SimpleModalType.WARNING, modalContent);"},{"lineNumber":255,"author":{"gitId":"-"},"content":""},{"lineNumber":256,"author":{"gitId":"-"},"content":" modalRef.result.then(() \u003d\u003e {"},{"lineNumber":257,"author":{"gitId":"-"},"content":" this.instructorService.regenerateInstructorKey(instructor.courseId, instructor.email)"},{"lineNumber":258,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":259,"author":{"gitId":"-"},"content":" next: (resp: RegenerateKey) \u003d\u003e {"},{"lineNumber":260,"author":{"gitId":"-"},"content":" this.statusMessageService.showSuccessToast(resp.message);"},{"lineNumber":261,"author":{"gitId":"-"},"content":" this.updateDisplayedInstructorCourseLinks(instructor, resp.newRegistrationKey);"},{"lineNumber":262,"author":{"gitId":"-"},"content":" },"},{"lineNumber":263,"author":{"gitId":"-"},"content":" error: (response: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(response.error.message);"},{"lineNumber":265,"author":{"gitId":"-"},"content":" },"},{"lineNumber":266,"author":{"gitId":"-"},"content":" });"},{"lineNumber":267,"author":{"gitId":"-"},"content":" }, () \u003d\u003e {});"},{"lineNumber":268,"author":{"gitId":"-"},"content":" }"},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":271,"author":{"gitId":"-"},"content":" * Updates the student\u0027s displayed course join and feedback session links with the value of the newKey."},{"lineNumber":272,"author":{"gitId":"-"},"content":" */"},{"lineNumber":273,"author":{"gitId":"-"},"content":" private updateDisplayedStudentCourseLinks(student: StudentAccountSearchResult, newKey: string): void {"},{"lineNumber":274,"author":{"gitId":"-"},"content":" const updateSessions \u003d (sessions: FeedbackSessionsGroup): void \u003d\u003e {"},{"lineNumber":275,"author":{"gitId":"-"},"content":" Object.keys(sessions).forEach((key: string): void \u003d\u003e {"},{"lineNumber":276,"author":{"gitId":"-"},"content":" sessions[key].feedbackSessionUrl \u003d this.getUpdatedUrl(sessions[key].feedbackSessionUrl, newKey);"},{"lineNumber":277,"author":{"gitId":"-"},"content":" });"},{"lineNumber":278,"author":{"gitId":"-"},"content":" };"},{"lineNumber":279,"author":{"gitId":"-"},"content":""},{"lineNumber":280,"author":{"gitId":"-"},"content":" student.courseJoinLink \u003d this.getUpdatedUrl(student.courseJoinLink, newKey);"},{"lineNumber":281,"author":{"gitId":"-"},"content":" updateSessions(student.awaitingSessions);"},{"lineNumber":282,"author":{"gitId":"-"},"content":" updateSessions(student.openSessions);"},{"lineNumber":283,"author":{"gitId":"-"},"content":" updateSessions(student.notOpenSessions);"},{"lineNumber":284,"author":{"gitId":"-"},"content":" updateSessions(student.publishedSessions);"},{"lineNumber":285,"author":{"gitId":"-"},"content":" }"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":288,"author":{"gitId":"-"},"content":" * Updates the instructor\u0027s displayed course join and feedback session links with the value of the newKey."},{"lineNumber":289,"author":{"gitId":"-"},"content":" */"},{"lineNumber":290,"author":{"gitId":"-"},"content":" private updateDisplayedInstructorCourseLinks(instructor: InstructorAccountSearchResult, newKey: string): void {"},{"lineNumber":291,"author":{"gitId":"-"},"content":" const updateSessions \u003d (sessions: FeedbackSessionsGroup): void \u003d\u003e {"},{"lineNumber":292,"author":{"gitId":"-"},"content":" Object.keys(sessions).forEach((key: string): void \u003d\u003e {"},{"lineNumber":293,"author":{"gitId":"-"},"content":" sessions[key].feedbackSessionUrl \u003d this.getUpdatedUrl(sessions[key].feedbackSessionUrl, newKey);"},{"lineNumber":294,"author":{"gitId":"-"},"content":" });"},{"lineNumber":295,"author":{"gitId":"-"},"content":" };"},{"lineNumber":296,"author":{"gitId":"-"},"content":""},{"lineNumber":297,"author":{"gitId":"-"},"content":" instructor.courseJoinLink \u003d this.getUpdatedUrl(instructor.courseJoinLink, newKey);"},{"lineNumber":298,"author":{"gitId":"-"},"content":" updateSessions(instructor.awaitingSessions);"},{"lineNumber":299,"author":{"gitId":"-"},"content":" updateSessions(instructor.openSessions);"},{"lineNumber":300,"author":{"gitId":"-"},"content":" updateSessions(instructor.notOpenSessions);"},{"lineNumber":301,"author":{"gitId":"-"},"content":" updateSessions(instructor.publishedSessions);"},{"lineNumber":302,"author":{"gitId":"-"},"content":" }"},{"lineNumber":303,"author":{"gitId":"-"},"content":""},{"lineNumber":304,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":305,"author":{"gitId":"-"},"content":" * Returns the URL after replacing the value of the `key` parameter with that of the new key."},{"lineNumber":306,"author":{"gitId":"-"},"content":" */"},{"lineNumber":307,"author":{"gitId":"-"},"content":" private getUpdatedUrl(link: string, newVal: string): string {"},{"lineNumber":308,"author":{"gitId":"-"},"content":" const param: string \u003d \u0027key\u0027;"},{"lineNumber":309,"author":{"gitId":"-"},"content":" const regex: RegExp \u003d new RegExp(`(${param}\u003d)[^\u0026]+`);"},{"lineNumber":310,"author":{"gitId":"-"},"content":""},{"lineNumber":311,"author":{"gitId":"-"},"content":" return link.replace(regex, `$1${newVal}`);"},{"lineNumber":312,"author":{"gitId":"-"},"content":" }"},{"lineNumber":313,"author":{"gitId":"-"},"content":""},{"lineNumber":314,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":315,"author":{"gitId":"-"},"content":" * Open up an email populated with content for course join invitation."},{"lineNumber":316,"author":{"gitId":"-"},"content":" */"},{"lineNumber":317,"author":{"gitId":"-"},"content":" openCourseJoinEmail(courseId: string, studentemail: string): void {"},{"lineNumber":318,"author":{"gitId":"-"},"content":" this.emailGenerationService.getCourseJoinEmail(courseId, studentemail)"},{"lineNumber":319,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":320,"author":{"gitId":"-"},"content":" next: (email: Email) \u003d\u003e {"},{"lineNumber":321,"author":{"gitId":"-"},"content":" window.location.href \u003d `mailto:${email.recipient}`"},{"lineNumber":322,"author":{"gitId":"-"},"content":" + `?Subject\u003d${email.subject}`"},{"lineNumber":323,"author":{"gitId":"-"},"content":" + `\u0026body\u003d${email.content}`;"},{"lineNumber":324,"author":{"gitId":"-"},"content":" },"},{"lineNumber":325,"author":{"gitId":"-"},"content":" error: (err: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":326,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(err.error.message);"},{"lineNumber":327,"author":{"gitId":"-"},"content":" },"},{"lineNumber":328,"author":{"gitId":"-"},"content":" });"},{"lineNumber":329,"author":{"gitId":"-"},"content":" }"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":332,"author":{"gitId":"-"},"content":" * Open up an email populated with content for feedback session reminder."},{"lineNumber":333,"author":{"gitId":"-"},"content":" */"},{"lineNumber":334,"author":{"gitId":"-"},"content":" openFeedbackSessionReminderEmail(courseId: string, studentemail: string, fsname: string): void {"},{"lineNumber":335,"author":{"gitId":"-"},"content":" this.emailGenerationService.getFeedbackSessionReminderEmail(courseId, studentemail, fsname)"},{"lineNumber":336,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":337,"author":{"gitId":"-"},"content":" next: (email: Email) \u003d\u003e {"},{"lineNumber":338,"author":{"gitId":"-"},"content":" window.location.href \u003d `mailto:${email.recipient}`"},{"lineNumber":339,"author":{"gitId":"-"},"content":" + `?Subject\u003d${email.subject}`"},{"lineNumber":340,"author":{"gitId":"-"},"content":" + `\u0026body\u003d${email.content}`;"},{"lineNumber":341,"author":{"gitId":"-"},"content":" },"},{"lineNumber":342,"author":{"gitId":"-"},"content":" error: (err: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":343,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(err.error.message);"},{"lineNumber":344,"author":{"gitId":"-"},"content":" },"},{"lineNumber":345,"author":{"gitId":"-"},"content":" });"},{"lineNumber":346,"author":{"gitId":"-"},"content":" }"},{"lineNumber":347,"author":{"gitId":"-"},"content":""},{"lineNumber":348,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":22,"-":326}},{"path":"src/web/app/pages-admin/admin-search-page/admin-search-page.module.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { CommonModule } from \u0027@angular/common\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { NgModule } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { FormsModule } from \u0027@angular/forms\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { RouterModule, Routes } from \u0027@angular/router\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { NgbTooltipModule } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { AdminSearchPageComponent } from \u0027./admin-search-page.component\u0027;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import {"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" AccountRequestTableModule,"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"} from \u0027../../components/account-requests-table/account-request-table.module\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { Pipes } from \u0027../../pipes/pipes.module\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"const routes: Routes \u003d ["},{"lineNumber":13,"author":{"gitId":"-"},"content":" {"},{"lineNumber":14,"author":{"gitId":"-"},"content":" path: \u0027\u0027,"},{"lineNumber":15,"author":{"gitId":"-"},"content":" component: AdminSearchPageComponent,"},{"lineNumber":16,"author":{"gitId":"-"},"content":" },"},{"lineNumber":17,"author":{"gitId":"-"},"content":"];"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * Module for admin search page."},{"lineNumber":21,"author":{"gitId":"-"},"content":" */"},{"lineNumber":22,"author":{"gitId":"-"},"content":"@NgModule({"},{"lineNumber":23,"author":{"gitId":"-"},"content":" declarations: ["},{"lineNumber":24,"author":{"gitId":"-"},"content":" AdminSearchPageComponent,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":26,"author":{"gitId":"-"},"content":" exports: ["},{"lineNumber":27,"author":{"gitId":"-"},"content":" AdminSearchPageComponent,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":29,"author":{"gitId":"-"},"content":" imports: ["},{"lineNumber":30,"author":{"gitId":"-"},"content":" CommonModule,"},{"lineNumber":31,"author":{"gitId":"-"},"content":" FormsModule,"},{"lineNumber":32,"author":{"gitId":"-"},"content":" NgbTooltipModule,"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" AccountRequestTableModule,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" RouterModule.forChild(routes),"},{"lineNumber":35,"author":{"gitId":"-"},"content":" Pipes,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":37,"author":{"gitId":"-"},"content":"})"},{"lineNumber":38,"author":{"gitId":"-"},"content":"export class AdminSearchPageModule { }"}],"authorContributionMap":{"domoberzin":4,"-":34}},{"path":"src/web/app/pages-instructor/instructor-courses-page/instructor-courses-page.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cdiv\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-add-course\" class\u003d\"btn btn-success\" (click)\u003d\"isAddNewCourseFormExpanded \u003d true\""},{"lineNumber":3,"author":{"gitId":"-"},"content":" [disabled]\u003d\"isAddNewCourseFormExpanded || isLoadingActiveCourses\"\u003e\u003ci class\u003d\"fas fa-plus\"\u003e\u003c/i\u003e Add New Course"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"\u003cdiv id\u003d\"add-course-section\" class\u003d\"course-section\" *ngIf\u003d\"isAddNewCourseFormExpanded \u0026\u0026 !isLoadingActiveCourses\" @collapseAnim\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003ctm-course-edit-form [formMode]\u003d\"CourseEditFormMode.ADD\" [(formModel)]\u003d\"courseFormModel\""},{"lineNumber":9,"author":{"gitId":"-"},"content":" [resetFormEvent]\u003d\"resetCourseForm\" (closeFormEvent)\u003d\"isAddNewCourseFormExpanded \u003d false\""},{"lineNumber":10,"author":{"gitId":"-"},"content":" (createNewCourseEvent)\u003d\"createNewCourse()\" (copyCourseEvent)\u003d\"createCopiedCourse($event)\"\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003c/tm-course-edit-form\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"\u003cdiv *ngIf\u003d\"isCopyingCourse\" class\u003d\"margin-top-30px\"\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":" \u003cp\u003eCopy Progress\u003c/p\u003e"},{"lineNumber":16,"author":{"gitId":"-"},"content":" \u003ctm-progress-bar\u003e\u003c/tm-progress-bar\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"\u003ctm-loading-retry [shouldShowRetry]\u003d\"hasLoadingFailed\" [message]\u003d\"\u0027Failed to load courses\u0027\""},{"lineNumber":20,"author":{"gitId":"-"},"content":" (retryEvent)\u003d\"loadInstructorCourses()\"\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"course-section\"\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u003ch2 class\u003d\"h3\"\u003eActive courses\u003c/h2\u003e"},{"lineNumber":23,"author":{"gitId":"-"},"content":" \u003cdiv *tmIsLoading\u003d\"isLoadingActiveCourses\"\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":" \u003cng-template #addCourseAlert\u003e"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"alert alert-warning margin-top-30px\" role\u003d\"alert\"\u003e"},{"lineNumber":26,"author":{"gitId":"-"},"content":" You do not seem to have any active courses. Use the button above to create a new course."},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":28,"author":{"gitId":"-"},"content":" \u003c/ng-template\u003e"},{"lineNumber":29,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"activeCourses.length; else addCourseAlert;\"\u003e"},{"lineNumber":30,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"table table-responsive\"\u003e"},{"lineNumber":31,"author":{"gitId":"-"},"content":" \u003ctable id\u003d\"active-courses-table\" class\u003d\"table table-striped table-bordered margin-0\"\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003cthead\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003ctr class\u003d\"bg-primary text-white\"\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003cth id\u003d\"sort-course-id\" class\u003d\"sortable-header\" (click)\u003d\"sortCoursesEvent(SortBy.COURSE_ID)\""},{"lineNumber":35,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortActive(SortBy.COURSE_ID)\"\u003e"},{"lineNumber":36,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":37,"author":{"gitId":"-"},"content":" Course ID"},{"lineNumber":38,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":41,"author":{"gitId":"-"},"content":" *ngIf\u003d\"activeTableSortBy \u003d\u003d\u003d SortBy.COURSE_ID \u0026\u0026 activeTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":43,"author":{"gitId":"-"},"content":" *ngIf\u003d\"activeTableSortBy \u003d\u003d\u003d SortBy.COURSE_ID \u0026\u0026 activeTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":45,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":46,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":47,"author":{"gitId":"-"},"content":" \u003cth id\u003d\"sort-course-name\" class\u003d\"sortable-header\" (click)\u003d\"sortCoursesEvent(SortBy.COURSE_NAME)\""},{"lineNumber":48,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortActive(SortBy.COURSE_NAME)\"\u003e"},{"lineNumber":49,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":50,"author":{"gitId":"-"},"content":" Course Name"},{"lineNumber":51,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":52,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":53,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":54,"author":{"gitId":"-"},"content":" *ngIf\u003d\"activeTableSortBy \u003d\u003d\u003d SortBy.COURSE_NAME \u0026\u0026 activeTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":56,"author":{"gitId":"-"},"content":" *ngIf\u003d\"activeTableSortBy \u003d\u003d\u003d SortBy.COURSE_NAME \u0026\u0026 activeTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":57,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":58,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":59,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":60,"author":{"gitId":"-"},"content":" \u003cth id\u003d\"sort-creation-date\" class\u003d\"sortable-header\""},{"lineNumber":61,"author":{"gitId":"-"},"content":" (click)\u003d\"sortCoursesEvent(SortBy.COURSE_CREATION_DATE)\""},{"lineNumber":62,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortActive(SortBy.COURSE_CREATION_DATE)\"\u003e"},{"lineNumber":63,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":64,"author":{"gitId":"-"},"content":" Creation Date"},{"lineNumber":65,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":66,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":67,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":68,"author":{"gitId":"-"},"content":" *ngIf\u003d\"activeTableSortBy \u003d\u003d\u003d SortBy.COURSE_CREATION_DATE \u0026\u0026 activeTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":69,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":70,"author":{"gitId":"-"},"content":" *ngIf\u003d\"activeTableSortBy \u003d\u003d\u003d SortBy.COURSE_CREATION_DATE \u0026\u0026 activeTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":71,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":72,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":73,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":74,"author":{"gitId":"-"},"content":" \u003cth\u003eSections\u003c/th\u003e"},{"lineNumber":75,"author":{"gitId":"-"},"content":" \u003cth\u003eTeams\u003c/th\u003e"},{"lineNumber":76,"author":{"gitId":"-"},"content":" \u003cth\u003eTotal Students\u003c/th\u003e"},{"lineNumber":77,"author":{"gitId":"-"},"content":" \u003cth\u003eTotal Unregistered\u003c/th\u003e"},{"lineNumber":78,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"text-center\"\u003eAction(s)\u003c/th\u003e"},{"lineNumber":79,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":80,"author":{"gitId":"-"},"content":" \u003c/thead\u003e"},{"lineNumber":81,"author":{"gitId":"-"},"content":" \u003ctbody\u003e"},{"lineNumber":82,"author":{"gitId":"-"},"content":" \u003cng-template #loadingSpinner\u003e"},{"lineNumber":83,"author":{"gitId":"-"},"content":" \u003ctm-ajax-loading [useBlueSpinner]\u003d\"true\"\u003e\u003c/tm-ajax-loading\u003e"},{"lineNumber":84,"author":{"gitId":"-"},"content":" \u003c/ng-template\u003e"},{"lineNumber":85,"author":{"gitId":"-"},"content":" \u003ctr *ngFor\u003d\"let course of activeCourses; let i \u003d index\"\u003e"},{"lineNumber":86,"author":{"gitId":"-"},"content":" \u003ctd id\u003d\"course-id-{{ i }}\" class\u003d\"text-break\"\u003e{{course.course.courseId}}\u003c/td\u003e"},{"lineNumber":87,"author":{"gitId":"-"},"content":" \u003ctd class\u003d\"text-break\"\u003e{{course.course.courseName}}\u003c/td\u003e"},{"lineNumber":88,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":89,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"ngb-tooltip-class\" container\u003d\"body\""},{"lineNumber":90,"author":{"gitId":"-"},"content":" [ngbTooltip]\u003d\"course.course.creationTimestamp | date:\u0027EEE, dd MMM yyyy, h:mma\u0027\"\u003e"},{"lineNumber":91,"author":{"gitId":"-"},"content":" {{course.course.creationTimestamp | date:\u0027d MMM yyyy\u0027}}"},{"lineNumber":92,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":93,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":94,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":95,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"!courseStats[course.course.courseId]\"\u003e"},{"lineNumber":96,"author":{"gitId":"-"},"content":" \u003cbutton *ngIf\u003d\"!course.isLoadingCourseStats; else loadingSpinner\""},{"lineNumber":97,"author":{"gitId":"-"},"content":" (click)\u003d\"getCourseStats(i)\" class\u003d\"link-button\" \u003e Show"},{"lineNumber":98,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":99,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":100,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"courseStats[course.course.courseId]\"\u003e"},{"lineNumber":101,"author":{"gitId":"-"},"content":" {{ courseStats[course.course.courseId][\u0027sections\u0027] }}"},{"lineNumber":102,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":103,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":104,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":105,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"!courseStats[course.course.courseId]\"\u003e"},{"lineNumber":106,"author":{"gitId":"-"},"content":" \u003cbutton *ngIf\u003d\"!course.isLoadingCourseStats; else loadingSpinner\" id\u003d\"show-statistics-{{ i }}\""},{"lineNumber":107,"author":{"gitId":"-"},"content":" (click)\u003d\"getCourseStats(i)\" class\u003d\"link-button\" \u003e Show"},{"lineNumber":108,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":109,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":110,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"courseStats[course.course.courseId]\"\u003e"},{"lineNumber":111,"author":{"gitId":"-"},"content":" {{ courseStats[course.course.courseId][\u0027teams\u0027] }}"},{"lineNumber":112,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":113,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":114,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":115,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"!courseStats[course.course.courseId]\"\u003e"},{"lineNumber":116,"author":{"gitId":"-"},"content":" \u003cbutton *ngIf\u003d\"!course.isLoadingCourseStats; else loadingSpinner\""},{"lineNumber":117,"author":{"gitId":"-"},"content":" (click)\u003d\"getCourseStats(i)\" class\u003d\"link-button\" \u003e Show"},{"lineNumber":118,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":119,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":120,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"courseStats[course.course.courseId]\"\u003e"},{"lineNumber":121,"author":{"gitId":"-"},"content":" {{ courseStats[course.course.courseId][\u0027students\u0027] }}"},{"lineNumber":122,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":123,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":124,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":125,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"!courseStats[course.course.courseId]\"\u003e"},{"lineNumber":126,"author":{"gitId":"-"},"content":" \u003cbutton *ngIf\u003d\"!course.isLoadingCourseStats; else loadingSpinner\""},{"lineNumber":127,"author":{"gitId":"-"},"content":" (click)\u003d\"getCourseStats(i)\" class\u003d\"link-button\" \u003e Show"},{"lineNumber":128,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":129,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":130,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"courseStats[course.course.courseId]\"\u003e"},{"lineNumber":131,"author":{"gitId":"-"},"content":" {{ courseStats[course.course.courseId][\u0027unregistered\u0027] }}"},{"lineNumber":132,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":133,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":134,"author":{"gitId":"-"},"content":" \u003ctd class\u003d\"text-center actions-cell\"\u003e"},{"lineNumber":135,"author":{"gitId":"-"},"content":" \u003ca id\u003d\"btn-enroll-{{ i }}\" class\u003d\"btn btn-light btn-sm custom-button-active\" *ngIf\u003d\"course.canModifyStudent\""},{"lineNumber":136,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Enroll student into the course\" tmRouterLink\u003d\"/web/instructor/courses/enroll\""},{"lineNumber":137,"author":{"gitId":"-"},"content":" [queryParams]\u003d\"{courseid: course.course.courseId}\"\u003e"},{"lineNumber":138,"author":{"gitId":"-"},"content":" Enroll"},{"lineNumber":139,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":140,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-enroll-disabled-{{ i }}\" class\u003d\"btn btn-light btn-sm disabled\""},{"lineNumber":141,"author":{"gitId":"-"},"content":" *ngIf\u003d\"!course.canModifyStudent\"\u003e"},{"lineNumber":142,"author":{"gitId":"-"},"content":" Enroll"},{"lineNumber":143,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":144,"author":{"gitId":"-"},"content":" \u003cdiv ngbDropdown class\u003d\"d-inline-block\"\u003e"},{"lineNumber":145,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-other-actions-{{ i }}\" class\u003d\"btn btn-light btn-sm custom-button-active\" ngbDropdownToggle\u003eOther"},{"lineNumber":146,"author":{"gitId":"-"},"content":" Actions\u003c/button\u003e"},{"lineNumber":147,"author":{"gitId":"-"},"content":" \u003cdiv ngbDropdownMenu\u003e"},{"lineNumber":148,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn btn-primary btn-sm dropdown-item clickable\""},{"lineNumber":149,"author":{"gitId":"-"},"content":" tmRouterLink\u003d\"/web/instructor/courses/details\" [queryParams]\u003d\"{courseid: course.course.courseId}\"\u003e"},{"lineNumber":150,"author":{"gitId":"-"},"content":" View"},{"lineNumber":151,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":152,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn btn-primary btn-sm dropdown-item clickable\""},{"lineNumber":153,"author":{"gitId":"-"},"content":" tmRouterLink\u003d\"/web/instructor/courses/edit\" [queryParams]\u003d\"{courseid: course.course.courseId}\"\u003e"},{"lineNumber":154,"author":{"gitId":"-"},"content":" Edit"},{"lineNumber":155,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":156,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-copy-{{ i }}\" class\u003d\"btn btn-primary btn-sm dropdown-item clickable\""},{"lineNumber":157,"author":{"gitId":"-"},"content":" *ngIf\u003d\"course.canModifyCourse\""},{"lineNumber":158,"author":{"gitId":"-"},"content":" (click)\u003d\"onCopy(course.course.courseId, course.course.courseName, course.course.timeZone)\""},{"lineNumber":159,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Copy the course and its corresponding sessions\" placement\u003d\"left\" container\u003d\"body\""},{"lineNumber":160,"author":{"gitId":"-"},"content":" [disabled]\u003d\"isCopyingCourse\"\u003e"},{"lineNumber":161,"author":{"gitId":"-"},"content":" Copy"},{"lineNumber":162,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":163,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-archive-{{ i }}\" class\u003d\"btn btn-primary btn-sm dropdown-item clickable\""},{"lineNumber":164,"author":{"gitId":"-"},"content":" (click)\u003d\"changeArchiveStatus(course.course.courseId, true)\""},{"lineNumber":165,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Archive the course so that it will not be shown in the home page any more (you can still access it from the \u0027Courses\u0027 tab)\""},{"lineNumber":166,"author":{"gitId":"-"},"content":" placement\u003d\"left\" container\u003d\"body\"\u003e"},{"lineNumber":167,"author":{"gitId":"-"},"content":" Archive"},{"lineNumber":168,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":" \u003ca class\u003d\"btn btn-primary btn-sm dropdown-item clickable\" *ngIf\u003d\"course.course.privileges?.canModifyInstructor \u0026\u0026 course.course.isMigrated\""},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" tmRouterLink\u003d\u0027/web/instructor/courses/student-activity-logs\u0027 [queryParams]\u003d\"{courseid: course.course.courseId}\"\u003e"},{"lineNumber":171,"author":{"gitId":"dishenggg"},"content":" View Logs"},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":" \u003c/a\u003e"},{"lineNumber":173,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-soft-delete-{{ i }}\" class\u003d\"btn btn-primary btn-sm dropdown-item clickable\""},{"lineNumber":174,"author":{"gitId":"-"},"content":" *ngIf\u003d\"course.canModifyCourse\" (click)\u003d\"onDelete(course.course.courseId)\""},{"lineNumber":175,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Delete the course and its corresponding students and sessions\" placement\u003d\"left\""},{"lineNumber":176,"author":{"gitId":"-"},"content":" container\u003d\"body\"\u003e"},{"lineNumber":177,"author":{"gitId":"-"},"content":" Delete"},{"lineNumber":178,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":179,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-soft-delete-disabled-{{ i }}\" class\u003d\"btn btn-primary btn-sm dropdown-item disabled\""},{"lineNumber":180,"author":{"gitId":"-"},"content":" *ngIf\u003d\"!course.canModifyCourse\"\u003e"},{"lineNumber":181,"author":{"gitId":"-"},"content":" Delete"},{"lineNumber":182,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":183,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":184,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":185,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":186,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":187,"author":{"gitId":"-"},"content":" \u003c/tbody\u003e"},{"lineNumber":188,"author":{"gitId":"-"},"content":" \u003ctr *ngIf\u003d\"!activeCourses.length\"\u003e"},{"lineNumber":189,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003c/td\u003e"},{"lineNumber":190,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003c/td\u003e"},{"lineNumber":191,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003c/td\u003e"},{"lineNumber":192,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003c/td\u003e"},{"lineNumber":193,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003c/td\u003e"},{"lineNumber":194,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003c/td\u003e"},{"lineNumber":195,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003c/td\u003e"},{"lineNumber":196,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003c/td\u003e"},{"lineNumber":197,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":198,"author":{"gitId":"-"},"content":" \u003c/table\u003e"},{"lineNumber":199,"author":{"gitId":"-"},"content":" \u003cp *ngIf\u003d\"!activeCourses.length\"\u003eNo records found.\u003c/p\u003e"},{"lineNumber":200,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":201,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":202,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":203,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":204,"author":{"gitId":"-"},"content":"\u003c/tm-loading-retry\u003e"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"course-section\"\u003e"},{"lineNumber":207,"author":{"gitId":"-"},"content":" \u003ch2 class\u003d\"h3 text-muted\"\u003e"},{"lineNumber":208,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa fa-file-archive\" aria-hidden\u003d\"true\"\u003e\u003c/span\u003e Archived courses"},{"lineNumber":209,"author":{"gitId":"-"},"content":" \u003c/h2\u003e"},{"lineNumber":210,"author":{"gitId":"-"},"content":" \u003cdiv *tmIsLoading\u003d\"isLoadingArchivedCourses\"\u003e"},{"lineNumber":211,"author":{"gitId":"-"},"content":" \u003cng-template #noArchiveAlert\u003e"},{"lineNumber":212,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"alert alert-warning margin-top-30px\" role\u003d\"alert\"\u003e"},{"lineNumber":213,"author":{"gitId":"-"},"content":" There are no courses archived currently."},{"lineNumber":214,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":215,"author":{"gitId":"-"},"content":" \u003c/ng-template\u003e"},{"lineNumber":216,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card top-padded\" *ngIf\u003d\"archivedCourses.length else noArchiveAlert\"\u003e"},{"lineNumber":217,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"archived-table-heading\" class\u003d\"card-header bg-info cursor-pointer\""},{"lineNumber":218,"author":{"gitId":"-"},"content":" (click)\u003d\"isArchivedCourseExpanded \u003d !isArchivedCourseExpanded\"\u003e"},{"lineNumber":219,"author":{"gitId":"-"},"content":" \u003cb\u003eArchive\u003c/b\u003e"},{"lineNumber":220,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header-btn-toolbar\"\u003e"},{"lineNumber":221,"author":{"gitId":"-"},"content":" \u003ctm-panel-chevron [isExpanded]\u003d\"isArchivedCourseExpanded\"\u003e\u003c/tm-panel-chevron\u003e"},{"lineNumber":222,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":223,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":224,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body archive-body table-responsive\" *ngIf\u003d\"isArchivedCourseExpanded\" @collapseAnim\u003e"},{"lineNumber":225,"author":{"gitId":"-"},"content":" \u003ctable id\u003d\"archived-courses-table\" class\u003d\"table table-striped table-bordered archive-table\"\u003e"},{"lineNumber":226,"author":{"gitId":"-"},"content":" \u003cthead\u003e"},{"lineNumber":227,"author":{"gitId":"-"},"content":" \u003ctr class\u003d\"background-color-medium-gray text-color-gray\"\u003e"},{"lineNumber":228,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"sortable-header\" (click)\u003d\"sortArchivedCoursesEvent(SortBy.COURSE_ID)\""},{"lineNumber":229,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortArchived(SortBy.COURSE_ID)\"\u003e"},{"lineNumber":230,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":231,"author":{"gitId":"-"},"content":" Course ID"},{"lineNumber":232,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":233,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":234,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":235,"author":{"gitId":"-"},"content":" *ngIf\u003d\"archivedTableSortBy \u003d\u003d\u003d SortBy.COURSE_ID \u0026\u0026 archivedTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":236,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":237,"author":{"gitId":"-"},"content":" *ngIf\u003d\"archivedTableSortBy \u003d\u003d\u003d SortBy.COURSE_ID \u0026\u0026 archivedTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":238,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":239,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":240,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":241,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"sortable-header\" (click)\u003d\"sortArchivedCoursesEvent(SortBy.COURSE_NAME)\""},{"lineNumber":242,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortArchived(SortBy.COURSE_NAME)\"\u003e"},{"lineNumber":243,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":244,"author":{"gitId":"-"},"content":" Course Name"},{"lineNumber":245,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":246,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":247,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":248,"author":{"gitId":"-"},"content":" *ngIf\u003d\"archivedTableSortBy \u003d\u003d\u003d SortBy.COURSE_NAME \u0026\u0026 archivedTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":249,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":250,"author":{"gitId":"-"},"content":" *ngIf\u003d\"archivedTableSortBy \u003d\u003d\u003d SortBy.COURSE_NAME \u0026\u0026 archivedTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":251,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":252,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":253,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":254,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"sortable-header\" (click)\u003d\"sortArchivedCoursesEvent(SortBy.COURSE_CREATION_DATE)\""},{"lineNumber":255,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortArchived(SortBy.COURSE_CREATION_DATE)\"\u003e"},{"lineNumber":256,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":257,"author":{"gitId":"-"},"content":" Creation Date"},{"lineNumber":258,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":259,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":260,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":261,"author":{"gitId":"-"},"content":" *ngIf\u003d\"archivedTableSortBy \u003d\u003d\u003d SortBy.COURSE_CREATION_DATE \u0026\u0026 archivedTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":262,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":263,"author":{"gitId":"-"},"content":" *ngIf\u003d\"archivedTableSortBy \u003d\u003d\u003d SortBy.COURSE_CREATION_DATE \u0026\u0026 archivedTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":264,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":265,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":266,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":267,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"text-center\"\u003eAction(s)\u003c/th\u003e"},{"lineNumber":268,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":269,"author":{"gitId":"-"},"content":" \u003c/thead\u003e"},{"lineNumber":270,"author":{"gitId":"-"},"content":" \u003ctbody\u003e"},{"lineNumber":271,"author":{"gitId":"-"},"content":" \u003ctr *ngFor\u003d\"let course of archivedCourses; let i \u003d index\"\u003e"},{"lineNumber":272,"author":{"gitId":"-"},"content":" \u003ctd id\u003d\"archived-course-id-{{ i }}\" class\u003d\"text-break\"\u003e{{course.course.courseId}}\u003c/td\u003e"},{"lineNumber":273,"author":{"gitId":"-"},"content":" \u003ctd class\u003d\"text-break\"\u003e{{course.course.courseName}}\u003c/td\u003e"},{"lineNumber":274,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":275,"author":{"gitId":"-"},"content":" \u003cspan container\u003d\"body\" class\u003d\"ngb-tooltip-class\""},{"lineNumber":276,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"{{course.course.creationTimestamp | date:\u0027EEE, dd MMM yyyy, h:mma\u0027}}\"\u003e{{course.course.creationTimestamp"},{"lineNumber":277,"author":{"gitId":"-"},"content":" | date:\u0027d MMM yyyy\u0027}}\u003c/span\u003e"},{"lineNumber":278,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":279,"author":{"gitId":"-"},"content":" \u003ctd class\u003d\"text-center actions-cell\"\u003e"},{"lineNumber":280,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-unarchive-{{ i }}\" class\u003d\"btn btn-light btn-sm custom-button-archived\""},{"lineNumber":281,"author":{"gitId":"-"},"content":" (click)\u003d\"changeArchiveStatus(course.course.courseId, false)\"\u003e"},{"lineNumber":282,"author":{"gitId":"-"},"content":" Unarchive"},{"lineNumber":283,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":284,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-soft-delete-archived-{{ i }}\" class\u003d\"btn btn-light btn-sm custom-button-archived\" *ngIf\u003d\"course.canModifyCourse\""},{"lineNumber":285,"author":{"gitId":"-"},"content":" (click)\u003d\"onDelete(course.course.courseId)\""},{"lineNumber":286,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Delete the course and its corresponding students and sessions\"\u003e"},{"lineNumber":287,"author":{"gitId":"-"},"content":" Delete"},{"lineNumber":288,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":289,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-soft-delete-archived-disabled-{{ i }}\" class\u003d\"btn btn-light btn-sm disabled\""},{"lineNumber":290,"author":{"gitId":"-"},"content":" *ngIf\u003d\"!course.canModifyCourse\"\u003e"},{"lineNumber":291,"author":{"gitId":"-"},"content":" Delete"},{"lineNumber":292,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":293,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":294,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":295,"author":{"gitId":"-"},"content":" \u003c/tbody\u003e"},{"lineNumber":296,"author":{"gitId":"-"},"content":" \u003c/table\u003e"},{"lineNumber":297,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":298,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":299,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":300,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":301,"author":{"gitId":"-"},"content":""},{"lineNumber":302,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"row course-section margin-top-30px\"\u003e"},{"lineNumber":303,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":304,"author":{"gitId":"-"},"content":" \u003ch2 class\u003d\"h3 text-muted\"\u003e"},{"lineNumber":305,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa fa-trash-alt\" aria-hidden\u003d\"true\"\u003e\u003c/span\u003e Deleted courses"},{"lineNumber":306,"author":{"gitId":"-"},"content":" \u003c/h2\u003e"},{"lineNumber":307,"author":{"gitId":"-"},"content":" \u003cdiv *tmIsLoading\u003d\"isLoadingSoftDeletedCourses\"\u003e"},{"lineNumber":308,"author":{"gitId":"-"},"content":" \u003cng-template #emptyBinAlert\u003e"},{"lineNumber":309,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"alert alert-warning margin-top-30px\" role\u003d\"alert\"\u003e"},{"lineNumber":310,"author":{"gitId":"-"},"content":" There are no courses in the bin."},{"lineNumber":311,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":312,"author":{"gitId":"-"},"content":" \u003c/ng-template\u003e"},{"lineNumber":313,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card bg-light top-padded\" *ngIf\u003d\"softDeletedCourses.length else emptyBinAlert\"\u003e"},{"lineNumber":314,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"deleted-table-heading\" class\u003d\"card-header bg-secondary text-white cursor-pointer\""},{"lineNumber":315,"author":{"gitId":"-"},"content":" (click)\u003d\"isRecycleBinExpanded \u003d !isRecycleBinExpanded\"\u003e"},{"lineNumber":316,"author":{"gitId":"-"},"content":" \u003cb\u003eRecycle Bin\u003c/b\u003e"},{"lineNumber":317,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header-btn-toolbar\"\u003e"},{"lineNumber":318,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-restore-all\" class\u003d\"btn btn-secondary btn-sm\" *ngIf\u003d\"canRestoreAll\""},{"lineNumber":319,"author":{"gitId":"-"},"content":" (click)\u003d\"$event.stopPropagation(); onRestoreAll()\""},{"lineNumber":320,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Restore all deleted courses and their corresponding students and sessions\"\u003e"},{"lineNumber":321,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-check\" aria-hidden\u003d\"true\"\u003e\u003c/i\u003e Restore All"},{"lineNumber":322,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":323,"author":{"gitId":"-"},"content":" \u003cbutton class\u003d\"btn btn-secondary btn-sm disabled\" *ngIf\u003d\"!canRestoreAll\"\u003e"},{"lineNumber":324,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-check\" aria-hidden\u003d\"true\"\u003e\u003c/i\u003e Restore All"},{"lineNumber":325,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":326,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-delete-all\" class\u003d\"btn btn-secondary btn-sm\" *ngIf\u003d\"canDeleteAll\""},{"lineNumber":327,"author":{"gitId":"-"},"content":" (click)\u003d\"$event.stopPropagation(); onDeleteAll()\""},{"lineNumber":328,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Permanently delete all courses and their corresponding students and sessions\"\u003e"},{"lineNumber":329,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-times\" aria-hidden\u003d\"true\"\u003e\u003c/i\u003e Delete All"},{"lineNumber":330,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":331,"author":{"gitId":"-"},"content":" \u003cbutton class\u003d\"btn btn-secondary btn-sm disabled\" *ngIf\u003d\"!canDeleteAll\"\u003e"},{"lineNumber":332,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-times\" aria-hidden\u003d\"true\"\u003e\u003c/i\u003e Delete All"},{"lineNumber":333,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":334,"author":{"gitId":"-"},"content":" \u003ctm-panel-chevron [isExpanded]\u003d\"isRecycleBinExpanded\"\u003e\u003c/tm-panel-chevron\u003e"},{"lineNumber":335,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":336,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":337,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body recycle-bin-body table-responsive\" *ngIf\u003d\"isRecycleBinExpanded\" @collapseAnim\u003e"},{"lineNumber":338,"author":{"gitId":"-"},"content":" \u003ctable id\u003d\"deleted-courses-table\""},{"lineNumber":339,"author":{"gitId":"-"},"content":" class\u003d\"table table-responsive-lg table-striped table-bordered recycle-bin-table\"\u003e"},{"lineNumber":340,"author":{"gitId":"-"},"content":" \u003cthead\u003e"},{"lineNumber":341,"author":{"gitId":"-"},"content":" \u003ctr class\u003d\"background-color-medium-gray text-color-gray\"\u003e"},{"lineNumber":342,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"sortable-header\" (click)\u003d\"sortDeletedCoursesEvent(SortBy.COURSE_ID)\""},{"lineNumber":343,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortDeleted(SortBy.COURSE_ID)\"\u003e"},{"lineNumber":344,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":345,"author":{"gitId":"-"},"content":" Course ID"},{"lineNumber":346,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":347,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":348,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":349,"author":{"gitId":"-"},"content":" *ngIf\u003d\"deletedTableSortBy \u003d\u003d\u003d SortBy.COURSE_ID \u0026\u0026 deletedTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":350,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":351,"author":{"gitId":"-"},"content":" *ngIf\u003d\"deletedTableSortBy \u003d\u003d\u003d SortBy.COURSE_ID \u0026\u0026 deletedTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":352,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":353,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":354,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":355,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"sortable-header\" (click)\u003d\"sortDeletedCoursesEvent(SortBy.COURSE_NAME)\""},{"lineNumber":356,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortDeleted(SortBy.COURSE_NAME)\"\u003e"},{"lineNumber":357,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":358,"author":{"gitId":"-"},"content":" Course Name"},{"lineNumber":359,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":360,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":361,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":362,"author":{"gitId":"-"},"content":" *ngIf\u003d\"deletedTableSortBy \u003d\u003d\u003d SortBy.COURSE_NAME \u0026\u0026 deletedTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":363,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":364,"author":{"gitId":"-"},"content":" *ngIf\u003d\"deletedTableSortBy \u003d\u003d\u003d SortBy.COURSE_NAME \u0026\u0026 deletedTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":365,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":366,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":367,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":368,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"sortable-header\" (click)\u003d\"sortDeletedCoursesEvent(SortBy.COURSE_CREATION_DATE)\""},{"lineNumber":369,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortDeleted(SortBy.COURSE_CREATION_DATE)\"\u003e"},{"lineNumber":370,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":371,"author":{"gitId":"-"},"content":" Creation Date"},{"lineNumber":372,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":373,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":374,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":375,"author":{"gitId":"-"},"content":" *ngIf\u003d\"deletedTableSortBy \u003d\u003d\u003d SortBy.COURSE_CREATION_DATE \u0026\u0026 deletedTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":376,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":377,"author":{"gitId":"-"},"content":" *ngIf\u003d\"deletedTableSortBy \u003d\u003d\u003d SortBy.COURSE_CREATION_DATE \u0026\u0026 deletedTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":378,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":379,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":380,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":381,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"sortable-header\" (click)\u003d\"sortDeletedCoursesEvent(SortBy.COURSE_DELETION_DATE)\""},{"lineNumber":382,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortDeleted(SortBy.COURSE_DELETION_DATE)\"\u003e"},{"lineNumber":383,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":384,"author":{"gitId":"-"},"content":" Deletion Date"},{"lineNumber":385,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":386,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":387,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":388,"author":{"gitId":"-"},"content":" *ngIf\u003d\"deletedTableSortBy \u003d\u003d\u003d SortBy.COURSE_DELETION_DATE \u0026\u0026 deletedTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":389,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":390,"author":{"gitId":"-"},"content":" *ngIf\u003d\"deletedTableSortBy \u003d\u003d\u003d SortBy.COURSE_DELETION_DATE \u0026\u0026 deletedTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":391,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":392,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":393,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":394,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"text-center\"\u003eAction(s)\u003c/th\u003e"},{"lineNumber":395,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":396,"author":{"gitId":"-"},"content":" \u003c/thead\u003e"},{"lineNumber":397,"author":{"gitId":"-"},"content":" \u003ctbody\u003e"},{"lineNumber":398,"author":{"gitId":"-"},"content":" \u003ctr *ngFor\u003d\"let course of softDeletedCourses; let i \u003d index\"\u003e"},{"lineNumber":399,"author":{"gitId":"-"},"content":" \u003ctd id\u003d\"deleted-course-id-{{ i }}\" class\u003d\"text-break\"\u003e{{course.course.courseId}}\u003c/td\u003e"},{"lineNumber":400,"author":{"gitId":"-"},"content":" \u003ctd class\u003d\"text-break\"\u003e{{course.course.courseName}}\u003c/td\u003e"},{"lineNumber":401,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":402,"author":{"gitId":"-"},"content":" \u003cspan container\u003d\"body\" class\u003d\"ngb-tooltip-class\""},{"lineNumber":403,"author":{"gitId":"-"},"content":" [ngbTooltip]\u003d\"course.course.creationTimestamp | date:\u0027EEE, dd MMM yyyy, h:mma\u0027\"\u003e"},{"lineNumber":404,"author":{"gitId":"-"},"content":" {{course.course.creationTimestamp | date:\u0027d MMM yyyy\u0027}}"},{"lineNumber":405,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":406,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":407,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":408,"author":{"gitId":"-"},"content":" \u003cspan container\u003d\"body\" class\u003d\"ngb-tooltip-class\""},{"lineNumber":409,"author":{"gitId":"-"},"content":" [ngbTooltip]\u003d\"course.course.deletionTimestamp | date:\u0027EEE, dd MMM yyyy, h:mma\u0027\"\u003e"},{"lineNumber":410,"author":{"gitId":"-"},"content":" {{course.course.deletionTimestamp | date:\u0027d MMM yyyy\u0027}}"},{"lineNumber":411,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":412,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":413,"author":{"gitId":"-"},"content":" \u003ctd class\u003d\"text-center actions-cell\"\u003e"},{"lineNumber":414,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-restore-{{ i }}\" class\u003d\"btn btn-light btn-sm\" *ngIf\u003d\"course.canModifyCourse\""},{"lineNumber":415,"author":{"gitId":"-"},"content":" (click)\u003d\"onRestore(course.course.courseId)\""},{"lineNumber":416,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Restore the deleted course and its corresponding students and sessions\"\u003e"},{"lineNumber":417,"author":{"gitId":"-"},"content":" Restore"},{"lineNumber":418,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":419,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-restore-disabled-{{ i }}\" class\u003d\"btn btn-light btn-sm disabled\""},{"lineNumber":420,"author":{"gitId":"-"},"content":" *ngIf\u003d\"!course.canModifyCourse\"\u003e"},{"lineNumber":421,"author":{"gitId":"-"},"content":" Restore"},{"lineNumber":422,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":423,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-delete-{{ i }}\" class\u003d\"btn btn-light btn-sm text-danger\" *ngIf\u003d\"course.canModifyCourse\""},{"lineNumber":424,"author":{"gitId":"-"},"content":" (click)\u003d\"onDeletePermanently(course.course.courseId)\""},{"lineNumber":425,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Permanently delete the course and its corresponding students and sessions\"\u003e"},{"lineNumber":426,"author":{"gitId":"-"},"content":" Delete Permanently"},{"lineNumber":427,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":428,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-delete-disabled-{{ i }}\" class\u003d\"btn btn-light btn-sm disabled text-danger\""},{"lineNumber":429,"author":{"gitId":"-"},"content":" *ngIf\u003d\"!course.canModifyCourse\"\u003e"},{"lineNumber":430,"author":{"gitId":"-"},"content":" Delete Permanently"},{"lineNumber":431,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":432,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":433,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":434,"author":{"gitId":"-"},"content":" \u003c/tbody\u003e"},{"lineNumber":435,"author":{"gitId":"-"},"content":" \u003c/table\u003e"},{"lineNumber":436,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":437,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":438,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":439,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":440,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":441,"author":{"gitId":"-"},"content":""},{"lineNumber":442,"author":{"gitId":"-"},"content":"\u003cng-template #modifiedTimestampsModal\u003e"},{"lineNumber":443,"author":{"gitId":"-"},"content":" \u003ctm-modified-timestamps-modal [modifiedSessions]\u003d\"this.modifiedSessions\"\u003e"},{"lineNumber":444,"author":{"gitId":"-"},"content":" \u003c/tm-modified-timestamps-modal\u003e"},{"lineNumber":445,"author":{"gitId":"-"},"content":"\u003c/ng-template\u003e"}],"authorContributionMap":{"dishenggg":4,"-":441}},{"path":"src/web/app/pages-instructor/instructor-home-page/instructor-home-page.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003ch1\u003eHome\u003c/h1\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"card bg-light\" style\u003d\"margin-bottom: 20px;\" *ngIf\u003d\"isNewUser\"\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":" New to TEAMMATES? You may wish to have a look at our \u003ca href\u003d\"/web/instructor/getting-started\" target\u003d\"_blank\""},{"lineNumber":6,"author":{"gitId":"-"},"content":" rel\u003d\"noopener noreferrer\"\u003eGetting Started Guide\u003c/a\u003e."},{"lineNumber":7,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"row mb-3\" *tmIsLoading\u003d\"!hasCoursesLoaded\"\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-4 mt-auto\"\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003ca tmRouterLink\u003d\"/web/instructor/courses\" class\u003d\"btn btn-success\" [queryParams]\u003d\"{isAddNewCourse: true}\"\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-plus\"\u003e\u003c/i\u003e Add New Course"},{"lineNumber":14,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":16,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-8\" *ngIf\u003d\"courseTabModels.length \u003e 0\"\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"float-end\"\u003e"},{"lineNumber":18,"author":{"gitId":"-"},"content":" \u003cstrong class\u003d\"d-inline\"\u003e Sort By: \u003c/strong\u003e"},{"lineNumber":19,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"btn-group\" data-toggle\u003d\"buttons\"\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"sort-course-id\" class\u003d\"btn btn-light\" [disabled]\u003d\"isSelectedForSorting(SortBy.COURSE_ID)\""},{"lineNumber":21,"author":{"gitId":"-"},"content":" (click)\u003d\"sortCoursesBy(SortBy.COURSE_ID)\"\u003eCourse ID\u003c/button\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"sort-course-name\" class\u003d\"btn btn-light\" [disabled]\u003d\"isSelectedForSorting(SortBy.COURSE_NAME)\""},{"lineNumber":23,"author":{"gitId":"-"},"content":" (click)\u003d\"sortCoursesBy(SortBy.COURSE_NAME)\"\u003eCourse Name\u003c/button\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"sort-course-date\" class\u003d\"btn btn-light\""},{"lineNumber":25,"author":{"gitId":"-"},"content":" [disabled]\u003d\"isSelectedForSorting(SortBy.COURSE_CREATION_DATE)\""},{"lineNumber":26,"author":{"gitId":"-"},"content":" (click)\u003d\"sortCoursesBy(SortBy.COURSE_CREATION_DATE)\"\u003eCreation Date\u003c/button\u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":28,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":29,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":30,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":"\u003cdiv *ngIf\u003d\"isCopyingCourse\" class\u003d\"mb-4\"\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003cp\u003eCopy Progress\u003c/p\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003ctm-progress-bar\u003e\u003c/tm-progress-bar\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":"\u003ctm-loading-retry [shouldShowRetry]\u003d\"hasCoursesLoadingFailed\" [message]\u003d\"\u0027Something went wrong\u0027\""},{"lineNumber":38,"author":{"gitId":"-"},"content":" (retryEvent)\u003d\"loadCourses()\"\u003e"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003cdiv *tmIsLoading\u003d\"!hasCoursesLoaded || isCopyLoading\"\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"courseTabModels.length \u003e 0\"\u003e"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"course-tab-{{ idx }}\" class\u003d\"card\" *ngFor\u003d\"let courseTabModel of courseTabModels; let idx \u003d index\"\u003e"},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header bg-primary text-white cursor-pointer\""},{"lineNumber":43,"author":{"gitId":"-"},"content":" (click)\u003d\"courseTabModel.isTabExpanded \u003d handleClick($event, courseTabModel); this.loadFeedbackSessions(idx);\"\u003e"},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u003cb class\u003d\"course-details text-break\"\u003e[{{ courseTabModel.course.courseId }}]: {{"},{"lineNumber":45,"author":{"gitId":"-"},"content":" courseTabModel.course.courseName }}\u003c/b\u003e"},{"lineNumber":46,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header-btn-toolbar flex-lg-shrink-0\" *ngIf\u003d\"courseTabModel.isAjaxSuccess\"\u003e"},{"lineNumber":47,"author":{"gitId":"-"},"content":" \u003cspan ngbDropdown container\u003d\"body\"\u003e"},{"lineNumber":48,"author":{"gitId":"-"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn btn-primary btn-sm\" ngbDropdownToggle\u003e Students \u003c/button\u003e"},{"lineNumber":49,"author":{"gitId":"-"},"content":" \u003cdiv ngbDropdownMenu (click)\u003d\"$event.stopPropagation()\"\u003e"},{"lineNumber":50,"author":{"gitId":"-"},"content":" \u003cng-container *ngIf\u003d\"courseTabModel.instructorPrivilege.canModifyStudent\"\u003e"},{"lineNumber":51,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn btn-light btn-sm dropdown-item\" tmRouterLink\u003d\"/web/instructor/courses/enroll\""},{"lineNumber":52,"author":{"gitId":"-"},"content":" [queryParams]\u003d\"{courseid: courseTabModel.course.courseId}\"\u003e Enroll"},{"lineNumber":53,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":54,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn btn-light btn-sm dropdown-item\" tmRouterLink\u003d\"/web/instructor/courses/details\""},{"lineNumber":56,"author":{"gitId":"-"},"content":" [queryParams]\u003d\"{courseid: courseTabModel.course.courseId}\"\u003e View / Edit"},{"lineNumber":57,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":58,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":59,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":60,"author":{"gitId":"-"},"content":" \u003cspan ngbDropdown container\u003d\"body\"\u003e"},{"lineNumber":61,"author":{"gitId":"-"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn btn-primary btn-sm\" ngbDropdownToggle\u003e Instructors \u003c/button\u003e"},{"lineNumber":62,"author":{"gitId":"-"},"content":" \u003cdiv ngbDropdownMenu (click)\u003d\"$event.stopPropagation()\"\u003e"},{"lineNumber":63,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn btn-light btn-sm dropdown-item\" tmRouterLink\u003d\"/web/instructor/courses/edit\""},{"lineNumber":64,"author":{"gitId":"-"},"content":" [queryParams]\u003d\"{courseid: courseTabModel.course.courseId}\"\u003e View / Edit"},{"lineNumber":65,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":66,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":67,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":68,"author":{"gitId":"-"},"content":" \u003cspan ngbDropdown container\u003d\"body\"\u003e"},{"lineNumber":69,"author":{"gitId":"-"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn btn-primary btn-sm\" ngbDropdownToggle\u003e Sessions \u003c/button\u003e"},{"lineNumber":70,"author":{"gitId":"-"},"content":" \u003cdiv ngbDropdownMenu (click)\u003d\"$event.stopPropagation()\"\u003e"},{"lineNumber":71,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn btn-light btn-sm dropdown-item\" tmRouterLink\u003d\"/web/instructor/sessions\""},{"lineNumber":72,"author":{"gitId":"-"},"content":" [queryParams]\u003d\"{courseid: courseTabModel.course.courseId}\"\u003e Add"},{"lineNumber":73,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":74,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":75,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":76,"author":{"gitId":"-"},"content":" \u003cspan ngbDropdown container\u003d\"body\"\u003e"},{"lineNumber":77,"author":{"gitId":"-"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn-course btn btn-primary btn-sm\" ngbDropdownToggle\u003e Course \u003c/button\u003e"},{"lineNumber":78,"author":{"gitId":"-"},"content":" \u003cdiv ngbDropdownMenu (click)\u003d\"$event.stopPropagation()\"\u003e"},{"lineNumber":79,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn-archive-course btn btn-light btn-sm dropdown-item\""},{"lineNumber":80,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Archive the course so that it will not be shown in the home page any more (you can still access it from the \u0027Courses\u0027 tab)\""},{"lineNumber":81,"author":{"gitId":"-"},"content":" (click)\u003d\"archiveCourse(courseTabModel.course.courseId)\""},{"lineNumber":82,"author":{"gitId":"-"},"content":" tmRouterLink\u003d\"./\"\u003e Archive"},{"lineNumber":83,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":84,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn btn-light btn-sm dropdown-item\" tmRouterLink\u003d\u0027/web/instructor/courses/edit\u0027"},{"lineNumber":85,"author":{"gitId":"-"},"content":" [queryParams]\u003d\"{courseid: courseTabModel.course.courseId}\"\u003e View / Edit"},{"lineNumber":86,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":87,"author":{"gitId":"-"},"content":" \u003cng-container *ngIf\u003d\"courseTabModel.instructorPrivilege.canModifyCourse\"\u003e"},{"lineNumber":88,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn-copy-course btn btn-light btn-sm dropdown-item\""},{"lineNumber":89,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Copy the course and its corresponding sessions\""},{"lineNumber":90,"author":{"gitId":"-"},"content":" (click)\u003d\"!isCopyingCourse \u0026\u0026 onCopy(courseTabModel.course.courseId, courseTabModel.course.courseName, courseTabModel.course.timeZone)\""},{"lineNumber":91,"author":{"gitId":"-"},"content":" tmRouterLink\u003d\"./\"\u003e Copy"},{"lineNumber":92,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":93,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" \u003cng-container *ngIf\u003d\"courseTabModel.instructorPrivilege.canModifyInstructor \u0026\u0026 courseTabModel.course.isMigrated\"\u003e"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" \u003ca class\u003d\"btn-course-logs btn btn-light btn-sm dropdown-item\" tmRouterLink\u003d\"/web/instructor/courses/student-activity-logs\""},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" [queryParams]\u003d\"{courseid: courseTabModel.course.courseId}\"\u003e View Logs"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" \u003c/a\u003e"},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" \u003c/ng-container\u003e"},{"lineNumber":99,"author":{"gitId":"-"},"content":" \u003cng-container *ngIf\u003d\"courseTabModel.instructorPrivilege.canModifyCourse\"\u003e"},{"lineNumber":100,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn-delete-course btn btn-light btn-sm dropdown-item\""},{"lineNumber":101,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Delete the course and its corresponding students and sessions\""},{"lineNumber":102,"author":{"gitId":"-"},"content":" (click)\u003d\"deleteCourse(courseTabModel.course.courseId)\""},{"lineNumber":103,"author":{"gitId":"-"},"content":" tmRouterLink\u003d\"./\"\u003e Delete"},{"lineNumber":104,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":105,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":106,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":107,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":108,"author":{"gitId":"-"},"content":" \u003ctm-panel-chevron [isExpanded]\u003d\"courseTabModel.isTabExpanded\"\u003e\u003c/tm-panel-chevron\u003e"},{"lineNumber":109,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":110,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":111,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body padding-0 table-responsive\" *ngIf\u003d\"courseTabModel.isTabExpanded\" @collapseAnim\u003e"},{"lineNumber":112,"author":{"gitId":"-"},"content":" \u003ctm-loading-retry [shouldShowRetry]\u003d\"courseTabModel.hasLoadingFailed\""},{"lineNumber":113,"author":{"gitId":"-"},"content":" [message]\u003d\"\u0027Error loading feedback sessions\u0027\" (retryEvent)\u003d\"loadFeedbackSessions(idx)\"\u003e"},{"lineNumber":114,"author":{"gitId":"-"},"content":" \u003ctm-sessions-table *tmIsLoading\u003d\"!courseTabModel.hasPopulated\""},{"lineNumber":115,"author":{"gitId":"-"},"content":" [sessionsTableRowModels]\u003d\"courseTabModel.sessionsTableRowModels\""},{"lineNumber":116,"author":{"gitId":"-"},"content":" id \u003d \"sessions-table-{{ idx }}\""},{"lineNumber":117,"author":{"gitId":"-"},"content":" [initialSortBy]\u003d\"initialSortBy\""},{"lineNumber":118,"author":{"gitId":"-"},"content":" [sortOrder]\u003d\"sortOrder\""},{"lineNumber":119,"author":{"gitId":"-"},"content":" [courseCandidates]\u003d\"courseCandidates\""},{"lineNumber":120,"author":{"gitId":"-"},"content":" [headerColorScheme]\u003d\"SortableTableHeaderColorScheme.WHITE\""},{"lineNumber":121,"author":{"gitId":"-"},"content":" [columnsToShow]\u003d\"["},{"lineNumber":122,"author":{"gitId":"-"},"content":" SessionsTableColumn.START_DATE,"},{"lineNumber":123,"author":{"gitId":"-"},"content":" SessionsTableColumn.END_DATE"},{"lineNumber":124,"author":{"gitId":"-"},"content":" ]\""},{"lineNumber":125,"author":{"gitId":"-"},"content":" [isSendReminderLoading]\u003d\"isSendReminderLoading\""},{"lineNumber":126,"author":{"gitId":"-"},"content":" (sortSessionsTableRowModelsEvent)\u003d\"sortSessionsTableRowModelsEvent(idx, $event)\""},{"lineNumber":127,"author":{"gitId":"-"},"content":" (loadResponseRateEvent)\u003d\"loadResponseRateEventHandler(idx, $event)\""},{"lineNumber":128,"author":{"gitId":"-"},"content":" (moveSessionToRecycleBinEvent)\u003d\"moveSessionToRecycleBinEventHandler(idx, $event)\""},{"lineNumber":129,"author":{"gitId":"-"},"content":" (copySessionEvent)\u003d\"copySessionEventHandler(idx, $event)\""},{"lineNumber":130,"author":{"gitId":"-"},"content":" (submitSessionAsInstructorEvent)\u003d\"submitSessionAsInstructorEventHandler(idx, $event)\""},{"lineNumber":131,"author":{"gitId":"-"},"content":" (publishSessionEvent)\u003d\"publishSessionEventHandler(idx, $event)\""},{"lineNumber":132,"author":{"gitId":"-"},"content":" (unpublishSessionEvent)\u003d\"unpublishSessionEventHandler(idx, $event)\""},{"lineNumber":133,"author":{"gitId":"-"},"content":" (downloadSessionResultsEvent)\u003d\"downloadSessionResultEventHandler(idx, $event)\""},{"lineNumber":134,"author":{"gitId":"-"},"content":" (resendResultsLinkToStudentsEvent)\u003d\"resendResultsLinkToRespondentsEventHandler(courseTabModel.sessionsTableRowModels[$event])\""},{"lineNumber":135,"author":{"gitId":"-"},"content":" (sendRemindersToAllNonSubmittersEvent)\u003d\"sendRemindersToRespondentsEventHandler(courseTabModel.sessionsTableRowModels[$event], true)\""},{"lineNumber":136,"author":{"gitId":"-"},"content":" (sendRemindersToSelectedNonSubmittersEvent)\u003d\"sendRemindersToRespondentsEventHandler(courseTabModel.sessionsTableRowModels[$event], false)\"\u003e\u003c/tm-sessions-table\u003e"},{"lineNumber":137,"author":{"gitId":"-"},"content":" \u003c/tm-loading-retry\u003e"},{"lineNumber":138,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":139,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":140,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":141,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":142,"author":{"gitId":"-"},"content":"\u003c/tm-loading-retry\u003e"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":"\u003cng-template #modifiedTimestampsModal\u003e"},{"lineNumber":145,"author":{"gitId":"-"},"content":" \u003ctm-modified-timestamps-modal [coursesOfModifiedSession]\u003d\"this.coursesOfModifiedSession\""},{"lineNumber":146,"author":{"gitId":"-"},"content":" [modifiedSessions]\u003d\"this.modifiedSession\"\u003e"},{"lineNumber":147,"author":{"gitId":"-"},"content":" \u003c/tm-modified-timestamps-modal\u003e"},{"lineNumber":148,"author":{"gitId":"-"},"content":"\u003c/ng-template\u003e"}],"authorContributionMap":{"dishenggg":5,"-":143}},{"path":"src/web/app/pages-instructor/instructor-student-activity-logs/instructor-student-activity-logs.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003ch1\u003eStudent Activity Logs For {{course.courseName}}\u003c/h1\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":"\u003cp\u003eThis page allows you to find when your students have accessed or submitted a particular feedback session or view a session results. Note that you can only view student logs if you have \u003cb\u003eowner or manager privileges\u003c/b\u003e for the course. The earliest date you can search for is \u003cb\u003e{{this.LOGS_RETENTION_PERIOD}} days\u003c/b\u003e before today.\u003c/p\u003e"},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"\u003cp\u003ePlease note that recent activity after \u003cb\u003e{{ this.lastUpdated }}\u003c/b\u003e may \u003cb\u003eNOT\u003c/b\u003e be shown as the information is updated in \u003cb\u003e{{ this.STUDENT_ACTIVITY_LOGS_UPDATE_INTERVAL }} minute\u003c/b\u003e intervals.\u003c/p\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":"\u003chr/\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"\u003cdiv *tmIsLoading\u003d\"isLoading\" class\u003d\"card bg-form no-border\"\u003e"},{"lineNumber":7,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row form-group\"\u003e"},{"lineNumber":9,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-4\"\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003clabel for\u003d\"activity-type-dropdown\" class\u003d\"fw-bold\"\u003eActivity Type\u003c/label\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":" \u003cselect id\u003d\"activity-type-dropdown\" class\u003d\"form-control form-select col-12\" [(ngModel)]\u003d\"formModel.logType\" (ngModelChange)\u003d\"triggerDefaultLogActivityTypeChange($event)\"\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":" \u003coption value\u003d\"\" disabled selected hidden\u003eSelect Activity Type\u003c/option\u003e"},{"lineNumber":16,"author":{"gitId":"-"},"content":" \u003coption *ngFor\u003d\"let logType of LOG_TYPES\" [value]\u003d\"logType.value\"\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":" {{logType.label}}"},{"lineNumber":18,"author":{"gitId":"-"},"content":" \u003c/option\u003e"},{"lineNumber":19,"author":{"gitId":"-"},"content":" \u003c/select\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-8\"\u003e"},{"lineNumber":23,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 mb-1\"\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"fw-bold\"\u003eSearch period from\u003c/label\u003e"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":26,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"input-group\"\u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"logs-from-datepicker\" class\u003d\"col-md-6 input-group\"\u003e"},{"lineNumber":28,"author":{"gitId":"-"},"content":" \u003cinput type\u003d\"text\" class\u003d\"form-control\" ngbDatepicker readonly [minDate]\u003d\"earliestSearchDate\""},{"lineNumber":29,"author":{"gitId":"-"},"content":" [maxDate]\u003d\"formModel.logsDateTo\" [(ngModel)]\u003d\"formModel.logsDateFrom\" #logsFromDp\u003d\"ngbDatepicker\""},{"lineNumber":30,"author":{"gitId":"-"},"content":" aria-label\u003d\"Date to search from\" /\u003e"},{"lineNumber":31,"author":{"gitId":"-"},"content":" \u003cbutton class\u003d\"btn btn-light\" aria-label\u003d\"Change date\" (click)\u003d\"logsFromDp.toggle()\" type\u003d\"button\"\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-calendar-alt\"\u003e\u003c/i\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-3\"\u003e"},{"lineNumber":36,"author":{"gitId":"-"},"content":" \u003ctm-timepicker id\u003d\"logs-from-timepicker\" [(time)]\u003d\"formModel.logsTimeFrom\"\u003e\u003c/tm-timepicker\u003e"},{"lineNumber":37,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":38,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row form-group\"\u003e"},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-4\"\u003e"},{"lineNumber":43,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u003clabel for\u003d\"student-name-dropdown\" class\u003d\"fw-bold\"\u003eStudent Name (Optional)\u003c/label\u003e"},{"lineNumber":45,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":46,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" \u003cselect id\u003d\"student-name-dropdown\" class\u003d\"form-control form-select col-12\" [(ngModel)]\u003d\"formModel.selectedStudent\"\u003e"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" \u003coption *ngFor\u003d\"let student of students\" [ngValue]\u003d\"{studentEmail: student.email || \u0027\u0027, studentId: student.studentId}\"\u003e"},{"lineNumber":49,"author":{"gitId":"-"},"content":" {{student.name}} {{student.email ? \u0027\u003c\u0027 + student.email + \u0027\u003e\u0027 : \u0027\u0027}}"},{"lineNumber":50,"author":{"gitId":"-"},"content":" \u003c/option\u003e"},{"lineNumber":51,"author":{"gitId":"-"},"content":" \u003c/select\u003e"},{"lineNumber":52,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":53,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":54,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-8\"\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 mb-1\"\u003e"},{"lineNumber":56,"author":{"gitId":"-"},"content":" \u003clabel for\u003d\"logs-to-datepicker\" class\u003d\"fw-bold\"\u003eSearch period until\u003c/label\u003e"},{"lineNumber":57,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":58,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"input-group\"\u003e"},{"lineNumber":59,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"logs-to-datepicker\" class\u003d\"col-md-6 input-group\"\u003e"},{"lineNumber":60,"author":{"gitId":"-"},"content":" \u003cinput type\u003d\"text\" class\u003d\"form-control\" ngbDatepicker readonly [minDate]\u003d\"formModel.logsDateFrom\""},{"lineNumber":61,"author":{"gitId":"-"},"content":" [maxDate]\u003d\"dateToday\" [(ngModel)]\u003d\"formModel.logsDateTo\" #logsToDp\u003d\"ngbDatepicker\""},{"lineNumber":62,"author":{"gitId":"-"},"content":" aria-label\u003d\"Date to search until\" /\u003e"},{"lineNumber":63,"author":{"gitId":"-"},"content":" \u003cbutton class\u003d\"btn btn-light\" aria-label\u003d\"Change date\" (click)\u003d\"logsToDp.toggle()\" type\u003d\"button\"\u003e"},{"lineNumber":64,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-calendar-alt\"\u003e\u003c/i\u003e"},{"lineNumber":65,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":66,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":67,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-3\"\u003e"},{"lineNumber":68,"author":{"gitId":"-"},"content":" \u003ctm-timepicker id\u003d\"logs-to-timepicker\" [(time)]\u003d\"formModel.logsTimeTo\" aria-label\u003d\"Search period until time\"\u003e\u003c/tm-timepicker\u003e"},{"lineNumber":69,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":70,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2\"\u003e"},{"lineNumber":71,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"search-button\" class\u003d\"float-end btn btn-primary\" (click)\u003d\"search()\" [disabled]\u003d\"course.courseId \u003d\u003d\u003d \u0027\u0027 || isSearching\"\u003eSearch\u003c/button\u003e"},{"lineNumber":72,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":73,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":74,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":75,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":76,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row form-group\"\u003e"},{"lineNumber":77,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-5\"\u003e"},{"lineNumber":78,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":79,"author":{"gitId":"-"},"content":" \u003clabel for\u003d\"session-dropdown\" class\u003d\"fw-bold\"\u003eFeedback Session Name (Optional)\u003c/label\u003e"},{"lineNumber":80,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":81,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" \u003cselect id\u003d\"session-dropdown\" class\u003d\"form-control form-select col-md-12\" [(ngModel)]\u003d\"formModel.selectedSession\"\u003e"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" \u003coption [ngValue]\u003d\"{feedbackSessionName: \u0027\u0027, sessionId: \u0027\u0027}\"\u003e\u003c/option\u003e"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" \u003coption *ngFor\u003d\"let session of feedbackSessions | keyvalue\" [ngValue]\u003d\"{feedbackSessionName: session.key, sessionId: session.value.sessionId}\"\u003e"},{"lineNumber":85,"author":{"gitId":"-"},"content":" {{session.key}}"},{"lineNumber":86,"author":{"gitId":"-"},"content":" \u003c/option\u003e"},{"lineNumber":87,"author":{"gitId":"-"},"content":" \u003c/select\u003e"},{"lineNumber":88,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":89,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":90,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row mt-md-1 ms-md-3\"\u003e"},{"lineNumber":91,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 form-check\" style\u003d\"margin-top: 30px;\"\u003e"},{"lineNumber":92,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"form-check-label\"\u003e"},{"lineNumber":93,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"show-actions\" class\u003d\"form-check-input\" type\u003d\"checkbox\" name\u003d\"showActions\" [checked]\u003d\"formModel.showActions\" (click)\u003d\"triggerModelChange(\u0027showActions\u0027, $event.target.checked)\"\u003e"},{"lineNumber":94,"author":{"gitId":"-"},"content":" Show actions"},{"lineNumber":95,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":96,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"form-check-label\" style\u003d\"margin-left: 40px;\"\u003e"},{"lineNumber":97,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"show-inactions\" class\u003d\"form-check-input\" type\u003d\"checkbox\" name\u003d\"showInactions\" [checked]\u003d\"formModel.showInactions\" (click)\u003d\"triggerModelChange(\u0027showInactions\u0027, $event.target.checked)\"\u003e"},{"lineNumber":98,"author":{"gitId":"-"},"content":" Show inactions"},{"lineNumber":99,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":100,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":101,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":102,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":103,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":104,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":105,"author":{"gitId":"-"},"content":"\u003cdiv id\u003d\"logs-output\"\u003e"},{"lineNumber":106,"author":{"gitId":"-"},"content":" \u003cdiv *tmIsLoading\u003d\"isSearching\"\u003e"},{"lineNumber":107,"author":{"gitId":"-"},"content":" \u003cdiv *ngFor\u003d\"let results of searchResults\"\u003e"},{"lineNumber":108,"author":{"gitId":"-"},"content":" \u003cdiv [ngClass]\u003d\"{ \u0027alert-success-border\u0027: results.logRowsData.length, \u0027alert-failure-border\u0027: !results.logRowsData.length }\" class\u003d\"card mb-3\"\u003e"},{"lineNumber":109,"author":{"gitId":"-"},"content":" \u003cdiv [ngClass]\u003d\"{ \u0027alert-success\u0027: results.logRowsData.length, \u0027alert-failure\u0027: !results.logRowsData.length}\" class\u003d\"card-header cursor-pointer text-break\" (click)\u003d\"results.isTabExpanded \u003d !results.isTabExpanded\"\u003e"},{"lineNumber":110,"author":{"gitId":"-"},"content":" {{results.feedbackSessionName}}"},{"lineNumber":111,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header-btn-toolbar\"\u003e"},{"lineNumber":112,"author":{"gitId":"-"},"content":" \u003ctm-panel-chevron [isExpanded]\u003d\"results.isTabExpanded\"\u003e\u003c/tm-panel-chevron\u003e"},{"lineNumber":113,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":114,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":115,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"results.isTabExpanded\"\u003e"},{"lineNumber":116,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"results.logRowsData[0]; else noActivityTemplate\" class\u003d\"card-body mb-4\"\u003e"},{"lineNumber":117,"author":{"gitId":"-"},"content":" \u003ctm-sortable-table [rows]\u003d\"results.logRowsData\" [columns]\u003d\"results.logColumnsData\" [initialSortBy]\u003d\"SortBy.GIVER_NAME\"\u003e\u003c/tm-sortable-table\u003e"},{"lineNumber":118,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":119,"author":{"gitId":"-"},"content":" \u003cng-template #noActivityTemplate\u003e"},{"lineNumber":120,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"no-activity-body\"\u003e"},{"lineNumber":121,"author":{"gitId":"-"},"content":" \u003ci\u003eNo activity for this feedback session in selected search period\u003c/i\u003e"},{"lineNumber":122,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":123,"author":{"gitId":"-"},"content":" \u003c/ng-template\u003e"},{"lineNumber":124,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":125,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":126,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":127,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":128,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"dishenggg":6,"-":122}},{"path":"src/web/app/pages-instructor/instructor-student-activity-logs/instructor-student-activity-logs.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { HttpClientTestingModule } from \u0027@angular/common/http/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { ComponentFixture, TestBed, waitForAsync } from \u0027@angular/core/testing\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { RouterTestingModule } from \u0027@angular/router/testing\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { of } from \u0027rxjs\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import SpyInstance \u003d jest.SpyInstance;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { InstructorStudentActivityLogsComponent } from \u0027./instructor-student-activity-logs.component\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { InstructorStudentActivityLogsModule } from \u0027./instructor-student-activity-logs.module\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { LogService } from \u0027../../../services/log.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { StudentService } from \u0027../../../services/student.service\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { TimezoneService } from \u0027../../../services/timezone.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":12,"author":{"gitId":"-"},"content":" Course,"},{"lineNumber":13,"author":{"gitId":"-"},"content":" FeedbackSession,"},{"lineNumber":14,"author":{"gitId":"-"},"content":" FeedbackSessionLog,"},{"lineNumber":15,"author":{"gitId":"-"},"content":" FeedbackSessionLogType,"},{"lineNumber":16,"author":{"gitId":"-"},"content":" FeedbackSessionPublishStatus,"},{"lineNumber":17,"author":{"gitId":"-"},"content":" FeedbackSessionSubmissionStatus,"},{"lineNumber":18,"author":{"gitId":"-"},"content":" ResponseVisibleSetting,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" SessionVisibleSetting,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" Student,"},{"lineNumber":21,"author":{"gitId":"-"},"content":"} from \u0027../../../types/api-output\u0027;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import { Milliseconds } from \u0027../../../types/datetime-const\u0027;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import { SortBy } from \u0027../../../types/sort-properties\u0027;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import { ColumnData } from \u0027../../components/sortable-table/sortable-table.component\u0027;"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":"describe(\u0027InstructorStudentActivityLogsComponent\u0027, () \u003d\u003e {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" let component: InstructorStudentActivityLogsComponent;"},{"lineNumber":28,"author":{"gitId":"-"},"content":" let fixture: ComponentFixture\u003cInstructorStudentActivityLogsComponent\u003e;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" let studentService: StudentService;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" let logService: LogService;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" let timezoneService: TimezoneService;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" const LOGS_DATE_TIME_FORMAT: string \u003d \u0027ddd, DD MMM YYYY hh:mm:ss A\u0027;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" const resultColumns: ColumnData[] \u003d ["},{"lineNumber":35,"author":{"gitId":"-"},"content":" { header: \u0027Status\u0027, sortBy: SortBy.RESULT_VIEW_STATUS },"},{"lineNumber":36,"author":{"gitId":"-"},"content":" { header: \u0027Name\u0027, sortBy: SortBy.GIVER_NAME },"},{"lineNumber":37,"author":{"gitId":"-"},"content":" { header: \u0027Email\u0027, sortBy: SortBy.RESPONDENT_EMAIL },"},{"lineNumber":38,"author":{"gitId":"-"},"content":" { header: \u0027Section\u0027, sortBy: SortBy.SECTION_NAME },"},{"lineNumber":39,"author":{"gitId":"-"},"content":" { header: \u0027Team\u0027, sortBy: SortBy.TEAM_NAME },"},{"lineNumber":40,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":41,"author":{"gitId":"-"},"content":" const testCourse1: Course \u003d {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" courseId: \u0027CS9999\u0027,"},{"lineNumber":43,"author":{"gitId":"-"},"content":" courseName: \u0027CS9999\u0027,"},{"lineNumber":44,"author":{"gitId":"-"},"content":" institute: \u0027Test Institute\u0027,"},{"lineNumber":45,"author":{"gitId":"-"},"content":" timeZone: \u0027Asia/Singapore\u0027,"},{"lineNumber":46,"author":{"gitId":"-"},"content":" creationTimestamp: 0,"},{"lineNumber":47,"author":{"gitId":"-"},"content":" deletionTimestamp: 0,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" privileges: {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" canModifyCourse: true,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" canModifySession: true,"},{"lineNumber":51,"author":{"gitId":"-"},"content":" canModifyStudent: true,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" canModifyInstructor: true,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" canViewStudentInSections: true,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" canModifySessionCommentsInSections: true,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" canViewSessionInSections: true,"},{"lineNumber":56,"author":{"gitId":"-"},"content":" canSubmitSessionInSections: true,"},{"lineNumber":57,"author":{"gitId":"-"},"content":" },"},{"lineNumber":58,"author":{"gitId":"-"},"content":" };"},{"lineNumber":59,"author":{"gitId":"-"},"content":" const emptyStudent: Student \u003d {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" courseId: \u0027\u0027, email: \u0027\u0027, name: \u0027\u0027, sectionName: \u0027\u0027, teamName: \u0027\u0027,"},{"lineNumber":61,"author":{"gitId":"-"},"content":" };"},{"lineNumber":62,"author":{"gitId":"-"},"content":" const testStudent: Student \u003d {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" email: \u0027doejohn@email.com\u0027,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" courseId: \u0027CS9999\u0027,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" name: \u0027Doe John\u0027,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" teamName: \u0027team 1\u0027,"},{"lineNumber":67,"author":{"gitId":"-"},"content":" sectionName: \u0027section 1\u0027,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" };"},{"lineNumber":69,"author":{"gitId":"-"},"content":" const testFeedbackSession: FeedbackSession \u003d {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" feedbackSessionName: \u0027Feedback Session 1\u0027,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" courseId: \u0027CS9999\u0027,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" timeZone: \u0027Asia/Singapore\u0027,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" instructions: \u0027\u0027,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" submissionStartTimestamp: 0,"},{"lineNumber":75,"author":{"gitId":"-"},"content":" submissionEndTimestamp: 1549095330000,"},{"lineNumber":76,"author":{"gitId":"-"},"content":" gracePeriod: 0,"},{"lineNumber":77,"author":{"gitId":"-"},"content":" sessionVisibleSetting: SessionVisibleSetting.AT_OPEN,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" responseVisibleSetting: ResponseVisibleSetting.AT_VISIBLE,"},{"lineNumber":79,"author":{"gitId":"-"},"content":" submissionStatus: FeedbackSessionSubmissionStatus.OPEN,"},{"lineNumber":80,"author":{"gitId":"-"},"content":" publishStatus: FeedbackSessionPublishStatus.PUBLISHED,"},{"lineNumber":81,"author":{"gitId":"-"},"content":" isClosingEmailEnabled: true,"},{"lineNumber":82,"author":{"gitId":"-"},"content":" isPublishedEmailEnabled: true,"},{"lineNumber":83,"author":{"gitId":"-"},"content":" createdAtTimestamp: 0,"},{"lineNumber":84,"author":{"gitId":"-"},"content":" studentDeadlines: {},"},{"lineNumber":85,"author":{"gitId":"-"},"content":" instructorDeadlines: {},"},{"lineNumber":86,"author":{"gitId":"-"},"content":" };"},{"lineNumber":87,"author":{"gitId":"-"},"content":" const testLogs1: FeedbackSessionLog \u003d {"},{"lineNumber":88,"author":{"gitId":"-"},"content":" feedbackSessionData: testFeedbackSession,"},{"lineNumber":89,"author":{"gitId":"-"},"content":" feedbackSessionLogEntries: ["},{"lineNumber":90,"author":{"gitId":"-"},"content":" {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" studentData: testStudent,"},{"lineNumber":92,"author":{"gitId":"-"},"content":" feedbackSessionLogType: FeedbackSessionLogType.SUBMISSION,"},{"lineNumber":93,"author":{"gitId":"-"},"content":" timestamp: 0,"},{"lineNumber":94,"author":{"gitId":"-"},"content":" },"},{"lineNumber":95,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":96,"author":{"gitId":"-"},"content":" };"},{"lineNumber":97,"author":{"gitId":"-"},"content":" const testLogs2: FeedbackSessionLog \u003d {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" feedbackSessionData: testFeedbackSession,"},{"lineNumber":99,"author":{"gitId":"-"},"content":" feedbackSessionLogEntries: ["},{"lineNumber":100,"author":{"gitId":"-"},"content":" {"},{"lineNumber":101,"author":{"gitId":"-"},"content":" studentData: testStudent,"},{"lineNumber":102,"author":{"gitId":"-"},"content":" feedbackSessionLogType: FeedbackSessionLogType.SUBMISSION,"},{"lineNumber":103,"author":{"gitId":"-"},"content":" timestamp: 0,"},{"lineNumber":104,"author":{"gitId":"-"},"content":" },"},{"lineNumber":105,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":106,"author":{"gitId":"-"},"content":" };"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" beforeEach(waitForAsync(() \u003d\u003e {"},{"lineNumber":109,"author":{"gitId":"-"},"content":" TestBed.configureTestingModule({"},{"lineNumber":110,"author":{"gitId":"-"},"content":" imports: ["},{"lineNumber":111,"author":{"gitId":"-"},"content":" InstructorStudentActivityLogsModule,"},{"lineNumber":112,"author":{"gitId":"-"},"content":" HttpClientTestingModule,"},{"lineNumber":113,"author":{"gitId":"-"},"content":" RouterTestingModule,"},{"lineNumber":114,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":115,"author":{"gitId":"-"},"content":" }).compileComponents();"},{"lineNumber":116,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":119,"author":{"gitId":"-"},"content":" fixture \u003d TestBed.createComponent(InstructorStudentActivityLogsComponent);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" studentService \u003d TestBed.inject(StudentService);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" logService \u003d TestBed.inject(LogService);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" timezoneService \u003d TestBed.inject(TimezoneService);"},{"lineNumber":123,"author":{"gitId":"-"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":124,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":125,"author":{"gitId":"-"},"content":" });"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":128,"author":{"gitId":"-"},"content":" expect(component).toBeTruthy();"},{"lineNumber":129,"author":{"gitId":"-"},"content":" });"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" it(\u0027should snap with default fields\u0027, () \u003d\u003e {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":133,"author":{"gitId":"-"},"content":" });"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" it(\u0027should snap when page is still loading\u0027, () \u003d\u003e {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" component.isLoading \u003d true;"},{"lineNumber":137,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":138,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":139,"author":{"gitId":"-"},"content":" });"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" it(\u0027should snap when searching for details in search form\u0027, () \u003d\u003e {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" component.course \u003d testCourse1;"},{"lineNumber":143,"author":{"gitId":"-"},"content":" component.formModel \u003d {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" logsDateFrom: { year: 1997, month: 9, day: 11 },"},{"lineNumber":145,"author":{"gitId":"-"},"content":" logsTimeFrom: { hour: 23, minute: 59 },"},{"lineNumber":146,"author":{"gitId":"-"},"content":" logsDateTo: { year: 1998, month: 9, day: 11 },"},{"lineNumber":147,"author":{"gitId":"-"},"content":" logsTimeTo: { hour: 15, minute: 0 },"},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":" selectedStudent: { studentEmail: \u0027doejohn@email.com\u0027, studentId: undefined },"},{"lineNumber":149,"author":{"gitId":"-"},"content":" logType: \u0027session access\u0027,"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":" selectedSession: { feedbackSessionName: undefined, sessionId: undefined },"},{"lineNumber":151,"author":{"gitId":"-"},"content":" showActions: false,"},{"lineNumber":152,"author":{"gitId":"-"},"content":" showInactions: false,"},{"lineNumber":153,"author":{"gitId":"-"},"content":" };"},{"lineNumber":154,"author":{"gitId":"-"},"content":" component.students \u003d [testStudent];"},{"lineNumber":155,"author":{"gitId":"-"},"content":" component.isLoading \u003d false;"},{"lineNumber":156,"author":{"gitId":"-"},"content":" component.isSearching \u003d true;"},{"lineNumber":157,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":160,"author":{"gitId":"-"},"content":" });"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"-"},"content":" it(\u0027should snap with results of a search\u0027, () \u003d\u003e {"},{"lineNumber":163,"author":{"gitId":"-"},"content":" component.searchResults \u003d ["},{"lineNumber":164,"author":{"gitId":"-"},"content":" {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" feedbackSessionName: \u0027Feedback session 1\u0027,"},{"lineNumber":166,"author":{"gitId":"-"},"content":" logColumnsData: resultColumns,"},{"lineNumber":167,"author":{"gitId":"-"},"content":" logRowsData: [["},{"lineNumber":168,"author":{"gitId":"-"},"content":" { value: \u002715 January 2021\u0027 },"},{"lineNumber":169,"author":{"gitId":"-"},"content":" { value: \u0027Doe John\u0027 },"},{"lineNumber":170,"author":{"gitId":"-"},"content":" { value: \u0027Viewed the submission page\u0027 },"},{"lineNumber":171,"author":{"gitId":"-"},"content":" { value: \u0027doejohn@email.com\u0027 },"},{"lineNumber":172,"author":{"gitId":"-"},"content":" { value: \u0027section 1\u0027 },"},{"lineNumber":173,"author":{"gitId":"-"},"content":" { value: \u0027team 1\u0027 },"},{"lineNumber":174,"author":{"gitId":"-"},"content":" ]],"},{"lineNumber":175,"author":{"gitId":"-"},"content":" isTabExpanded: true,"},{"lineNumber":176,"author":{"gitId":"-"},"content":" },"},{"lineNumber":177,"author":{"gitId":"-"},"content":" {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" feedbackSessionName: \u0027Feedback session 2\u0027,"},{"lineNumber":179,"author":{"gitId":"-"},"content":" logColumnsData: resultColumns,"},{"lineNumber":180,"author":{"gitId":"-"},"content":" logRowsData: [],"},{"lineNumber":181,"author":{"gitId":"-"},"content":" isTabExpanded: true,"},{"lineNumber":182,"author":{"gitId":"-"},"content":" },"},{"lineNumber":183,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":184,"author":{"gitId":"-"},"content":" component.isLoading \u003d false;"},{"lineNumber":185,"author":{"gitId":"-"},"content":" component.isSearching \u003d false;"},{"lineNumber":186,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":187,"author":{"gitId":"-"},"content":""},{"lineNumber":188,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":189,"author":{"gitId":"-"},"content":" });"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" it(\u0027should load all students of selected course has on select\u0027, () \u003d\u003e {"},{"lineNumber":192,"author":{"gitId":"-"},"content":" const studentSpy: SpyInstance \u003d jest.spyOn(studentService, \u0027getStudentsFromCourse\u0027)"},{"lineNumber":193,"author":{"gitId":"-"},"content":" .mockReturnValue(of({"},{"lineNumber":194,"author":{"gitId":"-"},"content":" students: ["},{"lineNumber":195,"author":{"gitId":"-"},"content":" testStudent,"},{"lineNumber":196,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" component.loadStudents(testCourse1.courseId);"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":" expect(component.students[0]).toEqual(emptyStudent);"},{"lineNumber":202,"author":{"gitId":"-"},"content":" expect(component.students[1]).toEqual(testStudent);"},{"lineNumber":203,"author":{"gitId":"-"},"content":" expect(studentSpy).toHaveBeenNthCalledWith(1, { courseId: testCourse1.courseId });"},{"lineNumber":204,"author":{"gitId":"-"},"content":" });"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" it(\u0027should load students from cache if present\u0027, () \u003d\u003e {"},{"lineNumber":207,"author":{"gitId":"-"},"content":" const studentSpy: SpyInstance \u003d jest.spyOn(studentService, \u0027getStudentsFromCourse\u0027)"},{"lineNumber":208,"author":{"gitId":"-"},"content":" .mockReturnValue(of({"},{"lineNumber":209,"author":{"gitId":"-"},"content":" students: ["},{"lineNumber":210,"author":{"gitId":"-"},"content":" testStudent,"},{"lineNumber":211,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" component.students \u003d [emptyStudent];"},{"lineNumber":215,"author":{"gitId":"-"},"content":" component.loadStudents(testCourse1.courseId);"},{"lineNumber":216,"author":{"gitId":"-"},"content":""},{"lineNumber":217,"author":{"gitId":"-"},"content":" expect(component.students.length).toEqual(1);"},{"lineNumber":218,"author":{"gitId":"-"},"content":" expect(component.students[0]).toEqual(emptyStudent);"},{"lineNumber":219,"author":{"gitId":"-"},"content":" expect(studentSpy).not.toHaveBeenCalled();"},{"lineNumber":220,"author":{"gitId":"-"},"content":" });"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"-"},"content":" it(\u0027should search for logs using feedback course timezone when search button is clicked\u0027, () \u003d\u003e {"},{"lineNumber":223,"author":{"gitId":"-"},"content":" const logSpy: SpyInstance \u003d jest.spyOn(logService, \u0027searchFeedbackSessionLog\u0027)"},{"lineNumber":224,"author":{"gitId":"-"},"content":" .mockReturnValue(of({ feedbackSessionLogs: [testLogs1, testLogs2] }));"},{"lineNumber":225,"author":{"gitId":"-"},"content":" const timeSpy: SpyInstance \u003d jest.spyOn(timezoneService, \u0027resolveLocalDateTime\u0027);"},{"lineNumber":226,"author":{"gitId":"-"},"content":" const tzOffset: number \u003d timezoneService.getTzOffsets()[testCourse1.timeZone];"},{"lineNumber":227,"author":{"gitId":"-"},"content":""},{"lineNumber":228,"author":{"gitId":"-"},"content":" component.isLoading \u003d false;"},{"lineNumber":229,"author":{"gitId":"-"},"content":" component.isSearching \u003d false;"},{"lineNumber":230,"author":{"gitId":"-"},"content":" component.formModel \u003d {"},{"lineNumber":231,"author":{"gitId":"-"},"content":" logsDateFrom: { year: 2020, month: 12, day: 30 },"},{"lineNumber":232,"author":{"gitId":"-"},"content":" logsTimeFrom: { hour: 23, minute: 59 },"},{"lineNumber":233,"author":{"gitId":"-"},"content":" logsDateTo: { year: 2020, month: 12, day: 31 },"},{"lineNumber":234,"author":{"gitId":"-"},"content":" logsTimeTo: { hour: 23, minute: 59 },"},{"lineNumber":235,"author":{"gitId":"dishenggg"},"content":" selectedStudent: { studentEmail: testStudent.email, studentId: \u0027\u0027 },"},{"lineNumber":236,"author":{"gitId":"-"},"content":" logType: \u0027submission\u0027,"},{"lineNumber":237,"author":{"gitId":"dishenggg"},"content":" selectedSession: { feedbackSessionName: \u0027\u0027, sessionId: \u0027\u0027 },"},{"lineNumber":238,"author":{"gitId":"-"},"content":" showActions: true,"},{"lineNumber":239,"author":{"gitId":"-"},"content":" showInactions: false,"},{"lineNumber":240,"author":{"gitId":"-"},"content":" };"},{"lineNumber":241,"author":{"gitId":"-"},"content":" component.course \u003d testCourse1;"},{"lineNumber":242,"author":{"gitId":"-"},"content":" component.students \u003d [testStudent];"},{"lineNumber":243,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":" fixture.debugElement.nativeElement.querySelector(\u0027#search-button\u0027).click();"},{"lineNumber":246,"author":{"gitId":"-"},"content":""},{"lineNumber":247,"author":{"gitId":"-"},"content":" expect(timeSpy).toHaveBeenCalledTimes(2);"},{"lineNumber":248,"author":{"gitId":"-"},"content":" expect(timeSpy).toHaveBeenCalledWith("},{"lineNumber":249,"author":{"gitId":"-"},"content":" component.formModel.logsDateFrom,"},{"lineNumber":250,"author":{"gitId":"-"},"content":" component.formModel.logsTimeFrom,"},{"lineNumber":251,"author":{"gitId":"-"},"content":" testCourse1.timeZone,"},{"lineNumber":252,"author":{"gitId":"-"},"content":" true,"},{"lineNumber":253,"author":{"gitId":"-"},"content":" );"},{"lineNumber":254,"author":{"gitId":"-"},"content":" expect(logSpy).toHaveBeenCalled();"},{"lineNumber":255,"author":{"gitId":"-"},"content":" expect(logSpy).toHaveBeenCalledWith({"},{"lineNumber":256,"author":{"gitId":"-"},"content":" courseId: testCourse1.courseId,"},{"lineNumber":257,"author":{"gitId":"-"},"content":" searchFrom: (new Date(\u00272020-12-31T00:00+00:00\u0027).getTime()"},{"lineNumber":258,"author":{"gitId":"-"},"content":" - tzOffset * Milliseconds.IN_ONE_MINUTE).toString(),"},{"lineNumber":259,"author":{"gitId":"-"},"content":" searchUntil: (new Date(\u00272021-01-01T00:00+00:00\u0027).getTime()"},{"lineNumber":260,"author":{"gitId":"-"},"content":" - tzOffset * Milliseconds.IN_ONE_MINUTE).toString(),"},{"lineNumber":261,"author":{"gitId":"-"},"content":" studentEmail: testStudent.email,"},{"lineNumber":262,"author":{"gitId":"-"},"content":" sessionName: \u0027\u0027,"},{"lineNumber":263,"author":{"gitId":"-"},"content":" logType: \u0027submission\u0027,"},{"lineNumber":264,"author":{"gitId":"dishenggg"},"content":" studentId: \u0027\u0027,"},{"lineNumber":265,"author":{"gitId":"dishenggg"},"content":" sessionId: \u0027\u0027,"},{"lineNumber":266,"author":{"gitId":"-"},"content":" });"},{"lineNumber":267,"author":{"gitId":"-"},"content":""},{"lineNumber":268,"author":{"gitId":"-"},"content":" expect(component.searchResults.length).toEqual(2);"},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":" const timestamp: string \u003d timezoneService.formatToString("},{"lineNumber":271,"author":{"gitId":"-"},"content":" 0, testFeedbackSession.timeZone, LOGS_DATE_TIME_FORMAT);"},{"lineNumber":272,"author":{"gitId":"-"},"content":""},{"lineNumber":273,"author":{"gitId":"-"},"content":" for (let i: number \u003d 0; i \u003c 2; i +\u003d 1) {"},{"lineNumber":274,"author":{"gitId":"-"},"content":" expect(component.searchResults[i].isTabExpanded).toBeTruthy();"},{"lineNumber":275,"author":{"gitId":"-"},"content":" expect(component.searchResults[i].logColumnsData).toEqual(resultColumns);"},{"lineNumber":276,"author":{"gitId":"-"},"content":" // Testing that the LogType is converted correctly."},{"lineNumber":277,"author":{"gitId":"-"},"content":" expect(component.searchResults[i].logRowsData[0][0].value).toEqual(`Submitted responses at ${timestamp}`);"},{"lineNumber":278,"author":{"gitId":"-"},"content":" }"},{"lineNumber":279,"author":{"gitId":"-"},"content":" });"},{"lineNumber":280,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"dishenggg":6,"-":274}},{"path":"src/web/app/pages-instructor/instructor-student-activity-logs/instructor-student-activity-logs.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component, OnInit } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { ActivatedRoute } from \u0027@angular/router\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { NgbDateParserFormatter } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { finalize } from \u0027rxjs/operators\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { CourseService } from \u0027../../../services/course.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { FeedbackSessionsService } from \u0027../../../services/feedback-sessions.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { LogService } from \u0027../../../services/log.service\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { StatusMessageService } from \u0027../../../services/status-message.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { StudentService } from \u0027../../../services/student.service\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { TimezoneService } from \u0027../../../services/timezone.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { ApiConst } from \u0027../../../types/api-const\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":13,"author":{"gitId":"-"},"content":" Course, FeedbackSession,"},{"lineNumber":14,"author":{"gitId":"-"},"content":" FeedbackSessionLog, FeedbackSessionLogEntry,"},{"lineNumber":15,"author":{"gitId":"-"},"content":" FeedbackSessionLogs, FeedbackSessions,"},{"lineNumber":16,"author":{"gitId":"-"},"content":" Student,"},{"lineNumber":17,"author":{"gitId":"-"},"content":"} from \u0027../../../types/api-output\u0027;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" getDefaultDateFormat,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" getDefaultTimeFormat,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" getLatestTimeFormat,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" DateFormat,"},{"lineNumber":23,"author":{"gitId":"-"},"content":" TimeFormat,"},{"lineNumber":24,"author":{"gitId":"-"},"content":" Milliseconds,"},{"lineNumber":25,"author":{"gitId":"-"},"content":"} from \u0027../../../types/datetime-const\u0027;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import { SortBy } from \u0027../../../types/sort-properties\u0027;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import { DatePickerFormatter } from \u0027../../components/datepicker/datepicker-formatter\u0027;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import { ColumnData, SortableTableCellData } from \u0027../../components/sortable-table/sortable-table.component\u0027;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import { ErrorMessageOutput } from \u0027../../error-message-output\u0027;"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":32,"author":{"gitId":"-"},"content":" * Model for searching of logs"},{"lineNumber":33,"author":{"gitId":"-"},"content":" */"},{"lineNumber":34,"author":{"gitId":"-"},"content":"interface SearchLogsFormModel {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" logsDateFrom: DateFormat;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" logsDateTo: DateFormat;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" logsTimeFrom: TimeFormat;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" logsTimeTo: TimeFormat;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" logType: string;"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" selectedSession: SelectedSession;"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" selectedStudent: SelectedStudent;"},{"lineNumber":42,"author":{"gitId":"-"},"content":" showActions: boolean;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" showInactions: boolean;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"}"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":"interface LogType {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" label: string;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" value: string;"},{"lineNumber":49,"author":{"gitId":"-"},"content":"}"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":"interface SelectedStudent {"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" studentEmail?: string;"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" studentId?: string;"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":"}"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":"interface SelectedSession {"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" feedbackSessionName?: string;"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" sessionId?: string;"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":"}"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":62,"author":{"gitId":"-"},"content":" * Model for displaying of feedback session logs"},{"lineNumber":63,"author":{"gitId":"-"},"content":" */"},{"lineNumber":64,"author":{"gitId":"-"},"content":"interface FeedbackSessionLogModel {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" feedbackSessionName: string;"},{"lineNumber":66,"author":{"gitId":"-"},"content":" logColumnsData: ColumnData[];"},{"lineNumber":67,"author":{"gitId":"-"},"content":" logRowsData: SortableTableCellData[][];"},{"lineNumber":68,"author":{"gitId":"-"},"content":" isTabExpanded: boolean;"},{"lineNumber":69,"author":{"gitId":"-"},"content":"}"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":72,"author":{"gitId":"-"},"content":" * Component for student activity and inactivity logs"},{"lineNumber":73,"author":{"gitId":"-"},"content":" */"},{"lineNumber":74,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":75,"author":{"gitId":"-"},"content":" selector: \u0027tm-instructor-student-activity-logs\u0027,"},{"lineNumber":76,"author":{"gitId":"-"},"content":" templateUrl: \u0027./instructor-student-activity-logs.component.html\u0027,"},{"lineNumber":77,"author":{"gitId":"-"},"content":" providers: [{ provide: NgbDateParserFormatter, useClass: DatePickerFormatter }],"},{"lineNumber":78,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./instructor-student-activity-logs.component.scss\u0027],"},{"lineNumber":79,"author":{"gitId":"-"},"content":"})"},{"lineNumber":80,"author":{"gitId":"-"},"content":"export class InstructorStudentActivityLogsComponent implements OnInit {"},{"lineNumber":81,"author":{"gitId":"-"},"content":" LOGS_DATE_TIME_FORMAT: string \u003d \u0027ddd, DD MMM YYYY hh:mm:ss A\u0027;"},{"lineNumber":82,"author":{"gitId":"-"},"content":" LOGS_RETENTION_PERIOD: number \u003d ApiConst.LOGS_RETENTION_PERIOD;"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" STUDENT_ACTIVITY_LOGS_UPDATE_INTERVAL: number \u003d ApiConst.STUDENT_ACTIVITY_LOGS_UPDATE_INTERVAL;"},{"lineNumber":84,"author":{"gitId":"-"},"content":" LOG_TYPES: LogType[] \u003d ["},{"lineNumber":85,"author":{"gitId":"-"},"content":" { label: \u0027session access\u0027, value: \u0027access\u0027 },"},{"lineNumber":86,"author":{"gitId":"-"},"content":" { label: \u0027session submission\u0027, value: \u0027submission\u0027 },"},{"lineNumber":87,"author":{"gitId":"-"},"content":" { label: \u0027session access and submission\u0027, value: \u0027access,submission\u0027 },"},{"lineNumber":88,"author":{"gitId":"-"},"content":" { label: \u0027view session results\u0027, value: \u0027view result\u0027 },"},{"lineNumber":89,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" // enum"},{"lineNumber":92,"author":{"gitId":"-"},"content":" SortBy: typeof SortBy \u003d SortBy;"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" formModel: SearchLogsFormModel \u003d {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" logsDateFrom: getDefaultDateFormat(),"},{"lineNumber":96,"author":{"gitId":"-"},"content":" logsTimeFrom: getDefaultTimeFormat(),"},{"lineNumber":97,"author":{"gitId":"-"},"content":" logsDateTo: getDefaultDateFormat(),"},{"lineNumber":98,"author":{"gitId":"-"},"content":" logsTimeTo: getDefaultTimeFormat(),"},{"lineNumber":99,"author":{"gitId":"-"},"content":" logType: \u0027\u0027,"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":" selectedStudent: { studentEmail: \u0027\u0027, studentId: \u0027\u0027 },"},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":" selectedSession: { feedbackSessionName: \u0027\u0027, sessionId: \u0027\u0027 },"},{"lineNumber":102,"author":{"gitId":"-"},"content":" showActions: false,"},{"lineNumber":103,"author":{"gitId":"-"},"content":" showInactions: false,"},{"lineNumber":104,"author":{"gitId":"-"},"content":" };"},{"lineNumber":105,"author":{"gitId":"-"},"content":" course: Course \u003d {"},{"lineNumber":106,"author":{"gitId":"-"},"content":" courseId: \u0027\u0027,"},{"lineNumber":107,"author":{"gitId":"-"},"content":" courseName: \u0027\u0027,"},{"lineNumber":108,"author":{"gitId":"-"},"content":" institute: \u0027\u0027,"},{"lineNumber":109,"author":{"gitId":"-"},"content":" timeZone: \u0027\u0027,"},{"lineNumber":110,"author":{"gitId":"-"},"content":" creationTimestamp: 0,"},{"lineNumber":111,"author":{"gitId":"-"},"content":" deletionTimestamp: 0,"},{"lineNumber":112,"author":{"gitId":"-"},"content":" };"},{"lineNumber":113,"author":{"gitId":"-"},"content":" dateToday: DateFormat \u003d getDefaultDateFormat();"},{"lineNumber":114,"author":{"gitId":"-"},"content":" earliestSearchDate: DateFormat \u003d getDefaultDateFormat();"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" studentLogsMap: Map\u003cstring, FeedbackSessionLogEntry[]\u003e \u003d new Map();"},{"lineNumber":116,"author":{"gitId":"-"},"content":" students: Student[] \u003d [];"},{"lineNumber":117,"author":{"gitId":"-"},"content":" feedbackSessions: Map\u003cstring, FeedbackSession\u003e \u003d new Map();"},{"lineNumber":118,"author":{"gitId":"-"},"content":" searchResults: FeedbackSessionLogModel[] \u003d [];"},{"lineNumber":119,"author":{"gitId":"-"},"content":" isLoading: boolean \u003d true;"},{"lineNumber":120,"author":{"gitId":"-"},"content":" isSearching: boolean \u003d false;"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" lastUpdated: string \u003d \u0027\u0027;"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" constructor(private route: ActivatedRoute,"},{"lineNumber":124,"author":{"gitId":"-"},"content":" private courseService: CourseService,"},{"lineNumber":125,"author":{"gitId":"-"},"content":" private feedbackSessionsService: FeedbackSessionsService,"},{"lineNumber":126,"author":{"gitId":"-"},"content":" private studentService: StudentService,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" private logsService: LogService,"},{"lineNumber":128,"author":{"gitId":"-"},"content":" private timezoneService: TimezoneService,"},{"lineNumber":129,"author":{"gitId":"-"},"content":" private statusMessageService: StatusMessageService) { }"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" ngOnInit(): void {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" this.route.queryParams.subscribe((queryParams: any) \u003d\u003e {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" const courseId \u003d queryParams.courseid;"},{"lineNumber":134,"author":{"gitId":"-"},"content":" this.loadControlPanel();"},{"lineNumber":135,"author":{"gitId":"-"},"content":" this.loadCourse(courseId);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" this.loadFeedbackSessions(courseId);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" this.loadStudents(courseId);"},{"lineNumber":138,"author":{"gitId":"-"},"content":" });"},{"lineNumber":139,"author":{"gitId":"-"},"content":" }"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":142,"author":{"gitId":"-"},"content":" * Loads the control panel based on the given course ID."},{"lineNumber":143,"author":{"gitId":"-"},"content":" */"},{"lineNumber":144,"author":{"gitId":"-"},"content":" loadControlPanel(): void {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" const today: Date \u003d new Date();"},{"lineNumber":146,"author":{"gitId":"-"},"content":" this.dateToday.year \u003d today.getFullYear();"},{"lineNumber":147,"author":{"gitId":"-"},"content":" this.dateToday.month \u003d today.getMonth() + 1;"},{"lineNumber":148,"author":{"gitId":"-"},"content":" this.dateToday.day \u003d today.getDate();"},{"lineNumber":149,"author":{"gitId":"-"},"content":""},{"lineNumber":150,"author":{"gitId":"-"},"content":" const earliestSearchDate: Date \u003d new Date(Date.now()"},{"lineNumber":151,"author":{"gitId":"-"},"content":" - this.LOGS_RETENTION_PERIOD * Milliseconds.IN_ONE_DAY);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" this.earliestSearchDate.year \u003d earliestSearchDate.getFullYear();"},{"lineNumber":153,"author":{"gitId":"-"},"content":" this.earliestSearchDate.month \u003d earliestSearchDate.getMonth() + 1;"},{"lineNumber":154,"author":{"gitId":"-"},"content":" this.earliestSearchDate.day \u003d earliestSearchDate.getDate();"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" const fromDate: Date \u003d new Date();"},{"lineNumber":157,"author":{"gitId":"-"},"content":" fromDate.setDate(today.getDate() - 1);"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" this.formModel.logsDateFrom \u003d {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" year: fromDate.getFullYear(),"},{"lineNumber":161,"author":{"gitId":"-"},"content":" month: fromDate.getMonth() + 1,"},{"lineNumber":162,"author":{"gitId":"-"},"content":" day: fromDate.getDate(),"},{"lineNumber":163,"author":{"gitId":"-"},"content":" };"},{"lineNumber":164,"author":{"gitId":"-"},"content":" this.formModel.logsDateTo \u003d { ...this.dateToday };"},{"lineNumber":165,"author":{"gitId":"-"},"content":" this.formModel.logsTimeFrom \u003d getLatestTimeFormat();"},{"lineNumber":166,"author":{"gitId":"-"},"content":" this.formModel.logsTimeTo \u003d getLatestTimeFormat();"},{"lineNumber":167,"author":{"gitId":"-"},"content":" }"},{"lineNumber":168,"author":{"gitId":"-"},"content":""},{"lineNumber":169,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":170,"author":{"gitId":"-"},"content":" * Search for logs of student activity"},{"lineNumber":171,"author":{"gitId":"-"},"content":" */"},{"lineNumber":172,"author":{"gitId":"-"},"content":" search(): void {"},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":" if (this.formModel.logType \u003d\u003d\u003d \u0027\u0027) {"},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":" this.statusMessageService.showErrorToast(\u0027Please select an activity type\u0027);"},{"lineNumber":175,"author":{"gitId":"dishenggg"},"content":" return;"},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":" this.studentLogsMap \u003d new Map();"},{"lineNumber":179,"author":{"gitId":"-"},"content":" this.searchResults \u003d [];"},{"lineNumber":180,"author":{"gitId":"-"},"content":" this.isSearching \u003d true;"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" const timeZone: string \u003d this.course.timeZone;"},{"lineNumber":183,"author":{"gitId":"-"},"content":" const searchFrom: number \u003d this.timezoneService.resolveLocalDateTime("},{"lineNumber":184,"author":{"gitId":"-"},"content":" this.formModel.logsDateFrom, this.formModel.logsTimeFrom, timeZone, true);"},{"lineNumber":185,"author":{"gitId":"-"},"content":" const searchUntil: number \u003d this.timezoneService.resolveLocalDateTime("},{"lineNumber":186,"author":{"gitId":"-"},"content":" this.formModel.logsDateTo, this.formModel.logsTimeTo, timeZone, true);"},{"lineNumber":187,"author":{"gitId":"-"},"content":""},{"lineNumber":188,"author":{"gitId":"-"},"content":" this.logsService.searchFeedbackSessionLog({"},{"lineNumber":189,"author":{"gitId":"-"},"content":" courseId: this.course.courseId,"},{"lineNumber":190,"author":{"gitId":"-"},"content":" searchFrom: searchFrom.toString(),"},{"lineNumber":191,"author":{"gitId":"-"},"content":" searchUntil: searchUntil.toString(),"},{"lineNumber":192,"author":{"gitId":"dishenggg"},"content":" studentEmail: this.formModel.selectedStudent.studentEmail,"},{"lineNumber":193,"author":{"gitId":"-"},"content":" logType: this.formModel.logType,"},{"lineNumber":194,"author":{"gitId":"dishenggg"},"content":" sessionName: this.formModel.selectedSession.feedbackSessionName,"},{"lineNumber":195,"author":{"gitId":"dishenggg"},"content":" studentId: this.formModel.selectedStudent.studentId,"},{"lineNumber":196,"author":{"gitId":"dishenggg"},"content":" sessionId: this.formModel.selectedSession.sessionId,"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }).pipe("},{"lineNumber":198,"author":{"gitId":"-"},"content":" finalize(() \u003d\u003e {"},{"lineNumber":199,"author":{"gitId":"-"},"content":" this.isSearching \u003d false;"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":201,"author":{"gitId":"-"},"content":" ).subscribe({"},{"lineNumber":202,"author":{"gitId":"-"},"content":" next: (logs: FeedbackSessionLogs) \u003d\u003e {"},{"lineNumber":203,"author":{"gitId":"dishenggg"},"content":" if (this.formModel.selectedSession.feedbackSessionName \u003d\u003d\u003d \u0027\u0027) {"},{"lineNumber":204,"author":{"gitId":"-"},"content":" logs.feedbackSessionLogs.forEach((log: FeedbackSessionLog) \u003d\u003e {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" log.feedbackSessionLogEntries.forEach((entry: FeedbackSessionLogEntry) \u003d\u003e {"},{"lineNumber":206,"author":{"gitId":"dishenggg"},"content":" const arr: FeedbackSessionLogEntry[] | undefined \u003d"},{"lineNumber":207,"author":{"gitId":"dishenggg"},"content":" this.studentLogsMap.get(this.getStudentKey(log, entry.studentData.email));"},{"lineNumber":208,"author":{"gitId":"dishenggg"},"content":" if (arr) {"},{"lineNumber":209,"author":{"gitId":"dishenggg"},"content":" arr.push(entry);"},{"lineNumber":210,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":211,"author":{"gitId":"dishenggg"},"content":" this.studentLogsMap.set(this.getStudentKey(log, entry.studentData.email), [entry]);"},{"lineNumber":212,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":" });"},{"lineNumber":214,"author":{"gitId":"-"},"content":" this.searchResults.push(this.toFeedbackSessionLogModel(log));"},{"lineNumber":215,"author":{"gitId":"-"},"content":" });"},{"lineNumber":216,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":217,"author":{"gitId":"-"},"content":" const targetFeedbackSessionLog \u003d logs.feedbackSessionLogs.find((log: FeedbackSessionLog) \u003d\u003e"},{"lineNumber":218,"author":{"gitId":"dishenggg"},"content":" log.feedbackSessionData.feedbackSessionName \u003d\u003d\u003d this.formModel.selectedSession.feedbackSessionName);"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" if (targetFeedbackSessionLog) {"},{"lineNumber":221,"author":{"gitId":"-"},"content":" targetFeedbackSessionLog.feedbackSessionLogEntries.forEach((entry: FeedbackSessionLogEntry) \u003d\u003e {"},{"lineNumber":222,"author":{"gitId":"dishenggg"},"content":" const arr: FeedbackSessionLogEntry[] | undefined \u003d"},{"lineNumber":223,"author":{"gitId":"dishenggg"},"content":" this.studentLogsMap.get(this.getStudentKey(targetFeedbackSessionLog, entry.studentData.email));"},{"lineNumber":224,"author":{"gitId":"dishenggg"},"content":" if (arr) {"},{"lineNumber":225,"author":{"gitId":"dishenggg"},"content":" arr.push(entry);"},{"lineNumber":226,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":227,"author":{"gitId":"dishenggg"},"content":" this.studentLogsMap.set("},{"lineNumber":228,"author":{"gitId":"dishenggg"},"content":" this.getStudentKey(targetFeedbackSessionLog, entry.studentData.email), [entry]);"},{"lineNumber":229,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":230,"author":{"gitId":"-"},"content":" });"},{"lineNumber":231,"author":{"gitId":"-"},"content":" this.searchResults.push(this.toFeedbackSessionLogModel(targetFeedbackSessionLog));"},{"lineNumber":232,"author":{"gitId":"-"},"content":" }"},{"lineNumber":233,"author":{"gitId":"-"},"content":" }"},{"lineNumber":234,"author":{"gitId":"-"},"content":" },"},{"lineNumber":235,"author":{"gitId":"-"},"content":" error: (e: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":236,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(e.error.message);"},{"lineNumber":237,"author":{"gitId":"-"},"content":" },"},{"lineNumber":238,"author":{"gitId":"-"},"content":" });"},{"lineNumber":239,"author":{"gitId":"-"},"content":" }"},{"lineNumber":240,"author":{"gitId":"-"},"content":""},{"lineNumber":241,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":242,"author":{"gitId":"-"},"content":" * Load the course based on the course id"},{"lineNumber":243,"author":{"gitId":"-"},"content":" */"},{"lineNumber":244,"author":{"gitId":"-"},"content":" private loadCourse(courseId: string): void {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" this.courseService"},{"lineNumber":246,"author":{"gitId":"-"},"content":" .getCourseAsInstructor(courseId)"},{"lineNumber":247,"author":{"gitId":"-"},"content":" .pipe(finalize(() \u003d\u003e {"},{"lineNumber":248,"author":{"gitId":"-"},"content":" this.isLoading \u003d false;"},{"lineNumber":249,"author":{"gitId":"-"},"content":" }))"},{"lineNumber":250,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":251,"author":{"gitId":"-"},"content":" next: (course: Course) \u003d\u003e {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" this.course \u003d course;"},{"lineNumber":253,"author":{"gitId":"dishenggg"},"content":" this.setLastUpdated();"},{"lineNumber":254,"author":{"gitId":"-"},"content":" },"},{"lineNumber":255,"author":{"gitId":"-"},"content":" error: (e: ErrorMessageOutput) \u003d\u003e this.statusMessageService.showErrorToast(e.error.message),"},{"lineNumber":256,"author":{"gitId":"-"},"content":" });"},{"lineNumber":257,"author":{"gitId":"-"},"content":" }"},{"lineNumber":258,"author":{"gitId":"-"},"content":""},{"lineNumber":259,"author":{"gitId":"-"},"content":" private loadFeedbackSessions(courseId: string): void {"},{"lineNumber":260,"author":{"gitId":"-"},"content":" this.feedbackSessionsService"},{"lineNumber":261,"author":{"gitId":"-"},"content":" .getFeedbackSessionsForInstructor(courseId)"},{"lineNumber":262,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":263,"author":{"gitId":"-"},"content":" next: (feedbackSessions: FeedbackSessions) \u003d\u003e {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" feedbackSessions.feedbackSessions.forEach((fs: FeedbackSession) \u003d\u003e {"},{"lineNumber":265,"author":{"gitId":"-"},"content":" this.feedbackSessions.set(fs.feedbackSessionName, fs);"},{"lineNumber":266,"author":{"gitId":"-"},"content":" });"},{"lineNumber":267,"author":{"gitId":"-"},"content":" },"},{"lineNumber":268,"author":{"gitId":"-"},"content":" error: (e: ErrorMessageOutput) \u003d\u003e this.statusMessageService.showErrorToast(e.error.message),"},{"lineNumber":269,"author":{"gitId":"-"},"content":" });"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":273,"author":{"gitId":"-"},"content":" * Load all students for the selected course"},{"lineNumber":274,"author":{"gitId":"-"},"content":" */"},{"lineNumber":275,"author":{"gitId":"-"},"content":" loadStudents(courseId: string): void {"},{"lineNumber":276,"author":{"gitId":"-"},"content":" if (this.students.length \u003d\u003d\u003d 0) {"},{"lineNumber":277,"author":{"gitId":"-"},"content":" this.isLoading \u003d true;"},{"lineNumber":278,"author":{"gitId":"-"},"content":" this.studentService.getStudentsFromCourse({ courseId })"},{"lineNumber":279,"author":{"gitId":"-"},"content":" .pipe(finalize(() \u003d\u003e { this.isLoading \u003d false; }))"},{"lineNumber":280,"author":{"gitId":"-"},"content":" .subscribe(({ students }: { students: Student[] }) \u003d\u003e {"},{"lineNumber":281,"author":{"gitId":"-"},"content":" const emptyStudent: Student \u003d {"},{"lineNumber":282,"author":{"gitId":"-"},"content":" courseId: \u0027\u0027, email: \u0027\u0027, name: \u0027\u0027, sectionName: \u0027\u0027, teamName: \u0027\u0027,"},{"lineNumber":283,"author":{"gitId":"-"},"content":" };"},{"lineNumber":284,"author":{"gitId":"-"},"content":" students.sort((a: Student, b: Student): number \u003d\u003e a.name.localeCompare(b.name));"},{"lineNumber":285,"author":{"gitId":"-"},"content":""},{"lineNumber":286,"author":{"gitId":"-"},"content":" // Student with no name is selectable to search for all students since the field is optional"},{"lineNumber":287,"author":{"gitId":"-"},"content":" this.students \u003d [emptyStudent, ...students];"},{"lineNumber":288,"author":{"gitId":"-"},"content":" });"},{"lineNumber":289,"author":{"gitId":"-"},"content":" }"},{"lineNumber":290,"author":{"gitId":"-"},"content":" }"},{"lineNumber":291,"author":{"gitId":"-"},"content":""},{"lineNumber":292,"author":{"gitId":"-"},"content":" private toFeedbackSessionLogModel(log: FeedbackSessionLog): FeedbackSessionLogModel {"},{"lineNumber":293,"author":{"gitId":"-"},"content":" const fsName \u003d log.feedbackSessionData.feedbackSessionName;"},{"lineNumber":294,"author":{"gitId":"-"},"content":""},{"lineNumber":295,"author":{"gitId":"-"},"content":" return {"},{"lineNumber":296,"author":{"gitId":"-"},"content":" feedbackSessionName: fsName,"},{"lineNumber":297,"author":{"gitId":"-"},"content":" logColumnsData: ["},{"lineNumber":298,"author":{"gitId":"-"},"content":" { header: \u0027Status\u0027, sortBy: SortBy.RESULT_VIEW_STATUS },"},{"lineNumber":299,"author":{"gitId":"-"},"content":" { header: \u0027Name\u0027, sortBy: SortBy.GIVER_NAME },"},{"lineNumber":300,"author":{"gitId":"-"},"content":" { header: \u0027Email\u0027, sortBy: SortBy.RESPONDENT_EMAIL },"},{"lineNumber":301,"author":{"gitId":"-"},"content":" { header: \u0027Section\u0027, sortBy: SortBy.SECTION_NAME },"},{"lineNumber":302,"author":{"gitId":"-"},"content":" { header: \u0027Team\u0027, sortBy: SortBy.TEAM_NAME },"},{"lineNumber":303,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":304,"author":{"gitId":"-"},"content":" logRowsData: this.students"},{"lineNumber":305,"author":{"gitId":"-"},"content":" .filter((student: Student) \u003d\u003e {"},{"lineNumber":306,"author":{"gitId":"-"},"content":" if (student.email \u003d\u003d\u003d \u0027\u0027) {"},{"lineNumber":307,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":308,"author":{"gitId":"-"},"content":" }"},{"lineNumber":309,"author":{"gitId":"-"},"content":""},{"lineNumber":310,"author":{"gitId":"dishenggg"},"content":" if ("},{"lineNumber":311,"author":{"gitId":"dishenggg"},"content":" this.formModel.selectedStudent.studentEmail !\u003d\u003d \u0027\u0027"},{"lineNumber":312,"author":{"gitId":"dishenggg"},"content":" \u0026\u0026 student.email !\u003d\u003d this.formModel.selectedStudent.studentEmail"},{"lineNumber":313,"author":{"gitId":"dishenggg"},"content":" ) {"},{"lineNumber":314,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":315,"author":{"gitId":"-"},"content":" }"},{"lineNumber":316,"author":{"gitId":"-"},"content":""},{"lineNumber":317,"author":{"gitId":"-"},"content":" if (this.formModel.showInactions \u0026\u0026 this.formModel.showActions) {"},{"lineNumber":318,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":319,"author":{"gitId":"-"},"content":" }"},{"lineNumber":320,"author":{"gitId":"-"},"content":""},{"lineNumber":321,"author":{"gitId":"-"},"content":" const studentKey \u003d this.getStudentKey(log, student.email);"},{"lineNumber":322,"author":{"gitId":"-"},"content":""},{"lineNumber":323,"author":{"gitId":"dishenggg"},"content":" if (this.studentLogsMap.has(studentKey)) {"},{"lineNumber":324,"author":{"gitId":"-"},"content":" if (this.formModel.showInactions) {"},{"lineNumber":325,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":326,"author":{"gitId":"-"},"content":" }"},{"lineNumber":327,"author":{"gitId":"-"},"content":" } else if (this.formModel.showActions) {"},{"lineNumber":328,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":329,"author":{"gitId":"-"},"content":" }"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":332,"author":{"gitId":"-"},"content":" })"},{"lineNumber":333,"author":{"gitId":"dishenggg"},"content":" .flatMap((student: Student) \u003d\u003e {"},{"lineNumber":334,"author":{"gitId":"-"},"content":" let status: string;"},{"lineNumber":335,"author":{"gitId":"-"},"content":" let dataStyle: string \u003d \u0027font-family:monospace; white-space:pre;\u0027;"},{"lineNumber":336,"author":{"gitId":"-"},"content":" const studentKey \u003d this.getStudentKey(log, student.email);"},{"lineNumber":337,"author":{"gitId":"-"},"content":""},{"lineNumber":338,"author":{"gitId":"dishenggg"},"content":" const entries: FeedbackSessionLogEntry[] | undefined \u003d this.studentLogsMap.get(studentKey);"},{"lineNumber":339,"author":{"gitId":"dishenggg"},"content":" const rows: any[] \u003d [];"},{"lineNumber":340,"author":{"gitId":"dishenggg"},"content":" if (entries) {"},{"lineNumber":341,"author":{"gitId":"dishenggg"},"content":" entries.forEach((entry: FeedbackSessionLogEntry) \u003d\u003e {"},{"lineNumber":342,"author":{"gitId":"-"},"content":" const timestamp: string \u003d this.timezoneService.formatToString("},{"lineNumber":343,"author":{"gitId":"-"},"content":" entry.timestamp, log.feedbackSessionData.timeZone, this.LOGS_DATE_TIME_FORMAT);"},{"lineNumber":344,"author":{"gitId":"dishenggg"},"content":" status \u003d `${this.logTypeToActivityDisplay(entry.feedbackSessionLogType)} at ${timestamp}`;"},{"lineNumber":345,"author":{"gitId":"dishenggg"},"content":" status \u003d status.charAt(0).toUpperCase() + status.slice(1);"},{"lineNumber":346,"author":{"gitId":"dishenggg"},"content":" rows.push([{"},{"lineNumber":347,"author":{"gitId":"dishenggg"},"content":" value: status,"},{"lineNumber":348,"author":{"gitId":"dishenggg"},"content":" style: dataStyle,"},{"lineNumber":349,"author":{"gitId":"dishenggg"},"content":" },"},{"lineNumber":350,"author":{"gitId":"dishenggg"},"content":" { value: student.name },"},{"lineNumber":351,"author":{"gitId":"dishenggg"},"content":" { value: student.email },"},{"lineNumber":352,"author":{"gitId":"dishenggg"},"content":" { value: student.sectionName },"},{"lineNumber":353,"author":{"gitId":"dishenggg"},"content":" { value: student.teamName }]);"},{"lineNumber":354,"author":{"gitId":"dishenggg"},"content":" });"},{"lineNumber":355,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":356,"author":{"gitId":"dishenggg"},"content":" status \u003d `Not ${this.logTypeToActivityDisplay(this.formModel.logType)} within the query range`;"},{"lineNumber":357,"author":{"gitId":"-"},"content":" dataStyle +\u003d \u0027color:red;\u0027;"},{"lineNumber":358,"author":{"gitId":"dishenggg"},"content":" rows.push(["},{"lineNumber":359,"author":{"gitId":"-"},"content":" {"},{"lineNumber":360,"author":{"gitId":"-"},"content":" value: status,"},{"lineNumber":361,"author":{"gitId":"-"},"content":" style: dataStyle,"},{"lineNumber":362,"author":{"gitId":"-"},"content":" },"},{"lineNumber":363,"author":{"gitId":"-"},"content":" { value: student.name },"},{"lineNumber":364,"author":{"gitId":"-"},"content":" { value: student.email },"},{"lineNumber":365,"author":{"gitId":"-"},"content":" { value: student.sectionName },"},{"lineNumber":366,"author":{"gitId":"-"},"content":" { value: student.teamName },"},{"lineNumber":367,"author":{"gitId":"dishenggg"},"content":" ]);"},{"lineNumber":368,"author":{"gitId":"-"},"content":" }"},{"lineNumber":369,"author":{"gitId":"dishenggg"},"content":" return rows;"},{"lineNumber":370,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":371,"author":{"gitId":"-"},"content":" isTabExpanded: (log.feedbackSessionLogEntries.length !\u003d\u003d 0 \u0026\u0026 this.formModel.showActions)"},{"lineNumber":372,"author":{"gitId":"-"},"content":" || (log.feedbackSessionLogEntries.length \u003d\u003d\u003d 0 \u0026\u0026 this.formModel.showInactions),"},{"lineNumber":373,"author":{"gitId":"-"},"content":" };"},{"lineNumber":374,"author":{"gitId":"-"},"content":" }"},{"lineNumber":375,"author":{"gitId":"-"},"content":""},{"lineNumber":376,"author":{"gitId":"-"},"content":" private logTypeToActivityDisplay(logType: string): string {"},{"lineNumber":377,"author":{"gitId":"-"},"content":" switch (logType.toUpperCase()) {"},{"lineNumber":378,"author":{"gitId":"-"},"content":" case \u0027ACCESS\u0027:"},{"lineNumber":379,"author":{"gitId":"dishenggg"},"content":" return \u0027viewed the submission page\u0027;"},{"lineNumber":380,"author":{"gitId":"-"},"content":" case \u0027SUBMISSION\u0027:"},{"lineNumber":381,"author":{"gitId":"dishenggg"},"content":" return \u0027submitted responses\u0027;"},{"lineNumber":382,"author":{"gitId":"dishenggg"},"content":" case \u0027VIEW_RESULT\u0027:"},{"lineNumber":383,"author":{"gitId":"-"},"content":" case \u0027VIEW RESULT\u0027:"},{"lineNumber":384,"author":{"gitId":"dishenggg"},"content":" return \u0027viewed the session results\u0027;"},{"lineNumber":385,"author":{"gitId":"-"},"content":" case \u0027ACCESS,SUBMISSION\u0027:"},{"lineNumber":386,"author":{"gitId":"dishenggg"},"content":" return \u0027viewed the submission page or submitted responses\u0027;"},{"lineNumber":387,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":388,"author":{"gitId":"dishenggg"},"content":" return \u0027unknown activity\u0027;"},{"lineNumber":389,"author":{"gitId":"-"},"content":" }"},{"lineNumber":390,"author":{"gitId":"-"},"content":" }"},{"lineNumber":391,"author":{"gitId":"-"},"content":""},{"lineNumber":392,"author":{"gitId":"-"},"content":" private getStudentKey(log: FeedbackSessionLog, studentEmail: string): string {"},{"lineNumber":393,"author":{"gitId":"-"},"content":" return `${log.feedbackSessionData.feedbackSessionName}-${studentEmail}`;"},{"lineNumber":394,"author":{"gitId":"-"},"content":" }"},{"lineNumber":395,"author":{"gitId":"-"},"content":""},{"lineNumber":396,"author":{"gitId":"-"},"content":" triggerDefaultLogActivityTypeChange(logType: string): void {"},{"lineNumber":397,"author":{"gitId":"-"},"content":" if (logType \u003d\u003d\u003d \u0027view result\u0027) {"},{"lineNumber":398,"author":{"gitId":"-"},"content":" this.formModel.showInactions \u003d true;"},{"lineNumber":399,"author":{"gitId":"-"},"content":" this.formModel.showActions \u003d false;"},{"lineNumber":400,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":401,"author":{"gitId":"-"},"content":" this.formModel.showInactions \u003d false;"},{"lineNumber":402,"author":{"gitId":"-"},"content":" this.formModel.showActions \u003d true;"},{"lineNumber":403,"author":{"gitId":"-"},"content":" }"},{"lineNumber":404,"author":{"gitId":"-"},"content":" }"},{"lineNumber":405,"author":{"gitId":"-"},"content":""},{"lineNumber":406,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":407,"author":{"gitId":"-"},"content":" * Triggers the change of the model for the form."},{"lineNumber":408,"author":{"gitId":"-"},"content":" */"},{"lineNumber":409,"author":{"gitId":"-"},"content":" triggerModelChange(field: string, data: any): void {"},{"lineNumber":410,"author":{"gitId":"-"},"content":" this.formModel \u003d {"},{"lineNumber":411,"author":{"gitId":"-"},"content":" ...this.formModel,"},{"lineNumber":412,"author":{"gitId":"-"},"content":" [field]: data,"},{"lineNumber":413,"author":{"gitId":"-"},"content":" };"},{"lineNumber":414,"author":{"gitId":"-"},"content":" }"},{"lineNumber":415,"author":{"gitId":"-"},"content":""},{"lineNumber":416,"author":{"gitId":"dishenggg"},"content":" private setLastUpdated(): void {"},{"lineNumber":417,"author":{"gitId":"dishenggg"},"content":" // 15 mins buffer to allow cron job to finish adding all logs to the database"},{"lineNumber":418,"author":{"gitId":"dishenggg"},"content":" const CRON_JOB_BUFFER \u003d 15;"},{"lineNumber":419,"author":{"gitId":"dishenggg"},"content":" const now: Date \u003d new Date();"},{"lineNumber":420,"author":{"gitId":"dishenggg"},"content":" const minsPastQuarter \u003d now.getMinutes() % 15;"},{"lineNumber":421,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":422,"author":{"gitId":"dishenggg"},"content":" const lastUpdated \u003d now.getTime() - ((CRON_JOB_BUFFER + minsPastQuarter) * Milliseconds.IN_ONE_MINUTE);"},{"lineNumber":423,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":424,"author":{"gitId":"dishenggg"},"content":" this.lastUpdated \u003d this.timezoneService.formatToString(lastUpdated, this.course.timeZone, \u0027DD MMM YYYY, hh:mm A\u0027);"},{"lineNumber":425,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":426,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":86,"-":340}},{"path":"src/web/app/pages-instructor/instructor-student-records-page/instructor-student-records-page.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003ch1 id\u003d\"records-header\"\u003e{{studentName}}\u0027s Records\u003csmall class\u003d\"text-muted text-break\"\u003e - {{courseId}}\u003c/small\u003e\u003c/h1\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":"\u003ch2\u003eRecords in feedback sessions\u003c/h2\u003e"},{"lineNumber":3,"author":{"gitId":"-"},"content":"\u003ctm-loading-retry [shouldShowRetry]\u003d\"hasStudentResultsLoadingFailed\" [message]\u003d\"\u0027Failed to load student results\u0027\" (retryEvent)\u003d\"loadStudentResults()\"\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003cdiv *tmIsLoading\u003d\"isStudentResultsLoading\"\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":" \u003cdiv *ngFor\u003d\"let session of sessionTabs\" class\u003d\"card card-default mb-4\"\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header cursor-pointer\" (click)\u003d\"session.isCollapsed \u003d !session.isCollapsed\"\u003e"},{"lineNumber":7,"author":{"gitId":"-"},"content":" \u003cstrong class\u003d\"text-break\"\u003eFeedback Session: {{ session.feedbackSession.feedbackSessionName }}\u003c/strong\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header-btn-toolbar\"\u003e"},{"lineNumber":9,"author":{"gitId":"Tim-Siu"},"content":" \u003ctm-panel-chevron [isExpanded]\u003d\"!session.isCollapsed\" chevronColor\u003d\"black\"\u003e\u003c/tm-panel-chevron\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\" *ngIf\u003d\"!session.isCollapsed\" @collapseAnim\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003ctm-grq-rgq-view-responses *ngIf\u003d\"session.responsesReceivedByStudent.length \u003e 0\""},{"lineNumber":14,"author":{"gitId":"-"},"content":" [session]\u003d\"session.feedbackSession\""},{"lineNumber":15,"author":{"gitId":"-"},"content":" [responses]\u003d\"session.responsesReceivedByStudent\" [groupByTeam]\u003d\"false\" [section]\u003d\"\" [sectionType]\u003d\"\""},{"lineNumber":16,"author":{"gitId":"-"},"content":" [isGrq]\u003d\"false\" [instructorCommentTableModel]\u003d\"instructorCommentTableModel\""},{"lineNumber":17,"author":{"gitId":"-"},"content":" (saveNewCommentEvent)\u003d\"saveNewComment($event, session.feedbackSession.timeZone)\""},{"lineNumber":18,"author":{"gitId":"-"},"content":" (deleteCommentEvent)\u003d\"deleteComment($event)\""},{"lineNumber":19,"author":{"gitId":"-"},"content":" (updateCommentEvent)\u003d\"updateComment($event, session.feedbackSession.timeZone)\""},{"lineNumber":20,"author":{"gitId":"-"},"content":" [isExpandAll]\u003d\"true\"\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003c/tm-grq-rgq-view-responses\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"session.responsesReceivedByStudent.length \u003d\u003d\u003d 0\" class\u003d\"mb-3\"\u003e"},{"lineNumber":23,"author":{"gitId":"-"},"content":" No feedback responses for {{studentName}} ({{studentTeam}}) found."},{"lineNumber":24,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u003ctm-grq-rgq-view-responses *ngIf\u003d\"session.responsesGivenByStudent.length \u003e 0\""},{"lineNumber":26,"author":{"gitId":"-"},"content":" [session]\u003d\"session.feedbackSession\""},{"lineNumber":27,"author":{"gitId":"-"},"content":" [responses]\u003d\"session.responsesGivenByStudent\" [groupByTeam]\u003d\"false\" [section]\u003d\"\" [sectionType]\u003d\"\""},{"lineNumber":28,"author":{"gitId":"-"},"content":" [isGrq]\u003d\"true\" [instructorCommentTableModel]\u003d\"instructorCommentTableModel\""},{"lineNumber":29,"author":{"gitId":"-"},"content":" (saveNewCommentEvent)\u003d\"saveNewComment($event, session.feedbackSession.timeZone)\""},{"lineNumber":30,"author":{"gitId":"-"},"content":" (deleteCommentEvent)\u003d\"deleteComment($event)\""},{"lineNumber":31,"author":{"gitId":"-"},"content":" (updateCommentEvent)\u003d\"updateComment($event, session.feedbackSession.timeZone)\""},{"lineNumber":32,"author":{"gitId":"-"},"content":" [isExpandAll]\u003d\"true\""},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003e\u003c/tm-grq-rgq-view-responses\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"session.responsesGivenByStudent.length \u003d\u003d\u003d 0\"\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":" No feedback responses from {{studentName}} ({{studentTeam}}) found."},{"lineNumber":36,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":37,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":38,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":"\u003c/tm-loading-retry\u003e"}],"authorContributionMap":{"-":39,"Tim-Siu":1}},{"path":"src/web/app/pages-session/session-result-page/session-result-page.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { HttpClientTestingModule } from \u0027@angular/common/http/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { ComponentFixture, TestBed, waitForAsync } from \u0027@angular/core/testing\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { ActivatedRoute } from \u0027@angular/router\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { RouterTestingModule } from \u0027@angular/router/testing\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { of, throwError } from \u0027rxjs\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import SpyInstance \u003d jest.SpyInstance;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { FeedbackQuestionModel, SessionResultPageComponent } from \u0027./session-result-page.component\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { environment } from \u0027../../../environments/environment\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { AuthService } from \u0027../../../services/auth.service\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { FeedbackQuestionsService } from \u0027../../../services/feedback-questions.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { FeedbackSessionsService } from \u0027../../../services/feedback-sessions.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { LogService } from \u0027../../../services/log.service\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { NavigationService } from \u0027../../../services/navigation.service\u0027;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import { StudentService } from \u0027../../../services/student.service\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":16,"author":{"gitId":"-"},"content":" AuthInfo,"},{"lineNumber":17,"author":{"gitId":"-"},"content":" FeedbackMcqQuestionDetails,"},{"lineNumber":18,"author":{"gitId":"-"},"content":" FeedbackParticipantType,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" FeedbackQuestion,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" FeedbackQuestions,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" FeedbackQuestionType,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" FeedbackSession,"},{"lineNumber":23,"author":{"gitId":"-"},"content":" FeedbackSessionPublishStatus,"},{"lineNumber":24,"author":{"gitId":"-"},"content":" FeedbackSessionSubmissionStatus,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" NumberOfEntitiesToGiveFeedbackToSetting,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" RegkeyValidity,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" ResponseVisibleSetting,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" SessionVisibleSetting,"},{"lineNumber":29,"author":{"gitId":"-"},"content":"} from \u0027../../../types/api-output\u0027;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import { Intent } from \u0027../../../types/api-request\u0027;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import { LoadingRetryModule } from \u0027../../components/loading-retry/loading-retry.module\u0027;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import { LoadingSpinnerModule } from \u0027../../components/loading-spinner/loading-spinner.module\u0027;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import { QuestionResponsePanelModule } from \u0027../../components/question-response-panel/question-response-panel.module\u0027;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import { SingleStatisticsModule } from \u0027../../components/question-responses/single-statistics/single-statistics.module\u0027;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" StudentViewResponsesModule,"},{"lineNumber":37,"author":{"gitId":"-"},"content":"} from \u0027../../components/question-responses/student-view-responses/student-view-responses.module\u0027;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import { QuestionTextWithInfoModule } from \u0027../../components/question-text-with-info/question-text-with-info.module\u0027;"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":"describe(\u0027SessionResultPageComponent\u0027, () \u003d\u003e {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" const testFeedbackSession: FeedbackSession \u003d {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" feedbackSessionName: \u0027First Session\u0027,"},{"lineNumber":43,"author":{"gitId":"-"},"content":" courseId: \u0027CS1231\u0027,"},{"lineNumber":44,"author":{"gitId":"-"},"content":" timeZone: \u0027Asia/Singapore\u0027,"},{"lineNumber":45,"author":{"gitId":"-"},"content":" instructions: \u0027\u0027,"},{"lineNumber":46,"author":{"gitId":"-"},"content":" submissionStartTimestamp: 0,"},{"lineNumber":47,"author":{"gitId":"-"},"content":" submissionEndTimestamp: 1549095330000,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" gracePeriod: 0,"},{"lineNumber":49,"author":{"gitId":"-"},"content":" sessionVisibleSetting: SessionVisibleSetting.AT_OPEN,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" responseVisibleSetting: ResponseVisibleSetting.AT_VISIBLE,"},{"lineNumber":51,"author":{"gitId":"-"},"content":" submissionStatus: FeedbackSessionSubmissionStatus.OPEN,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" publishStatus: FeedbackSessionPublishStatus.PUBLISHED,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" isClosingEmailEnabled: true,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" isPublishedEmailEnabled: true,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" createdAtTimestamp: 0,"},{"lineNumber":56,"author":{"gitId":"-"},"content":" studentDeadlines: {},"},{"lineNumber":57,"author":{"gitId":"-"},"content":" instructorDeadlines: {},"},{"lineNumber":58,"author":{"gitId":"-"},"content":" };"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" const testInfo: AuthInfo \u003d {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" masquerade: false,"},{"lineNumber":62,"author":{"gitId":"-"},"content":" user: {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" id: \u0027user-id\u0027,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" isAdmin: false,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" isInstructor: true,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" isStudent: false,"},{"lineNumber":67,"author":{"gitId":"-"},"content":" isMaintainer: false,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" },"},{"lineNumber":69,"author":{"gitId":"-"},"content":" };"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" const testFeedbackQuestion: FeedbackQuestion \u003d {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" feedbackQuestionId: \u0027feedbackQuestion1\u0027,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" questionNumber: 1,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" questionBrief: \u0027How well did team member perform?\u0027,"},{"lineNumber":75,"author":{"gitId":"-"},"content":" questionDescription: \u0027\u0027,"},{"lineNumber":76,"author":{"gitId":"-"},"content":" questionDetails: {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" hasAssignedWeights: false,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" mcqWeights: [],"},{"lineNumber":79,"author":{"gitId":"-"},"content":" mcqOtherWeight: 0,"},{"lineNumber":80,"author":{"gitId":"-"},"content":" mcqChoices: ["},{"lineNumber":81,"author":{"gitId":"-"},"content":" \u0027\u003cp\u003eGood\u003c/p\u003e\u0027,"},{"lineNumber":82,"author":{"gitId":"-"},"content":" \u0027\u003cp\u003eNormal\u003c/p\u003e\u0027,"},{"lineNumber":83,"author":{"gitId":"-"},"content":" \u0027\u003cp\u003eBad\u003c/p\u003e\u0027,"},{"lineNumber":84,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":85,"author":{"gitId":"-"},"content":" otherEnabled: false,"},{"lineNumber":86,"author":{"gitId":"-"},"content":" questionDropdownEnabled: false,"},{"lineNumber":87,"author":{"gitId":"-"},"content":" generateOptionsFor: \u0027NONE\u0027,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" questionType: FeedbackQuestionType.MCQ,"},{"lineNumber":89,"author":{"gitId":"-"},"content":" questionText: \u0027How well did team member perform?\u0027,"},{"lineNumber":90,"author":{"gitId":"-"},"content":" } as FeedbackMcqQuestionDetails,"},{"lineNumber":91,"author":{"gitId":"-"},"content":" questionType: FeedbackQuestionType.MCQ,"},{"lineNumber":92,"author":{"gitId":"-"},"content":" giverType: FeedbackParticipantType.STUDENTS,"},{"lineNumber":93,"author":{"gitId":"-"},"content":" recipientType: FeedbackParticipantType.OWN_TEAM_MEMBERS_INCLUDING_SELF,"},{"lineNumber":94,"author":{"gitId":"-"},"content":" numberOfEntitiesToGiveFeedbackToSetting: NumberOfEntitiesToGiveFeedbackToSetting.UNLIMITED,"},{"lineNumber":95,"author":{"gitId":"-"},"content":" showResponsesTo: [],"},{"lineNumber":96,"author":{"gitId":"-"},"content":" showGiverNameTo: [],"},{"lineNumber":97,"author":{"gitId":"-"},"content":" showRecipientNameTo: [],"},{"lineNumber":98,"author":{"gitId":"-"},"content":" customNumberOfEntitiesToGiveFeedbackTo: 0,"},{"lineNumber":99,"author":{"gitId":"-"},"content":" };"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" let component: SessionResultPageComponent;"},{"lineNumber":102,"author":{"gitId":"-"},"content":" let fixture: ComponentFixture\u003cSessionResultPageComponent\u003e;"},{"lineNumber":103,"author":{"gitId":"-"},"content":" let authService: AuthService;"},{"lineNumber":104,"author":{"gitId":"-"},"content":" let navService: NavigationService;"},{"lineNumber":105,"author":{"gitId":"-"},"content":" let studentService: StudentService;"},{"lineNumber":106,"author":{"gitId":"-"},"content":" let feedbackQuestionsService: FeedbackQuestionsService;"},{"lineNumber":107,"author":{"gitId":"-"},"content":" let feedbackSessionService: FeedbackSessionsService;"},{"lineNumber":108,"author":{"gitId":"-"},"content":" let logService: LogService;"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" const testQueryParams: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" courseid: \u0027CS3281\u0027,"},{"lineNumber":112,"author":{"gitId":"-"},"content":" fsname: \u0027Peer Feedback\u0027,"},{"lineNumber":113,"author":{"gitId":"-"},"content":" key: \u0027reg-key\u0027,"},{"lineNumber":114,"author":{"gitId":"-"},"content":" previewas: \u0027\u0027,"},{"lineNumber":115,"author":{"gitId":"-"},"content":" };"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" beforeEach(waitForAsync(() \u003d\u003e {"},{"lineNumber":118,"author":{"gitId":"-"},"content":" TestBed.configureTestingModule({"},{"lineNumber":119,"author":{"gitId":"-"},"content":" imports: ["},{"lineNumber":120,"author":{"gitId":"-"},"content":" HttpClientTestingModule,"},{"lineNumber":121,"author":{"gitId":"-"},"content":" RouterTestingModule,"},{"lineNumber":122,"author":{"gitId":"-"},"content":" StudentViewResponsesModule,"},{"lineNumber":123,"author":{"gitId":"-"},"content":" QuestionTextWithInfoModule,"},{"lineNumber":124,"author":{"gitId":"-"},"content":" QuestionResponsePanelModule,"},{"lineNumber":125,"author":{"gitId":"-"},"content":" SingleStatisticsModule,"},{"lineNumber":126,"author":{"gitId":"-"},"content":" LoadingSpinnerModule,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" LoadingRetryModule,"},{"lineNumber":128,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":129,"author":{"gitId":"-"},"content":" declarations: [SessionResultPageComponent],"},{"lineNumber":130,"author":{"gitId":"-"},"content":" providers: ["},{"lineNumber":131,"author":{"gitId":"-"},"content":" AuthService,"},{"lineNumber":132,"author":{"gitId":"-"},"content":" NavigationService,"},{"lineNumber":133,"author":{"gitId":"-"},"content":" StudentService,"},{"lineNumber":134,"author":{"gitId":"-"},"content":" FeedbackSessionsService,"},{"lineNumber":135,"author":{"gitId":"-"},"content":" LogService,"},{"lineNumber":136,"author":{"gitId":"-"},"content":" {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" provide: ActivatedRoute,"},{"lineNumber":138,"author":{"gitId":"-"},"content":" useValue: {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" queryParams: of(testQueryParams),"},{"lineNumber":140,"author":{"gitId":"-"},"content":" data: {"},{"lineNumber":141,"author":{"gitId":"-"},"content":" intent: Intent.STUDENT_RESULT,"},{"lineNumber":142,"author":{"gitId":"-"},"content":" pipe: () \u003d\u003e {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" return {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" subscribe: (fn: (value: any) \u003d\u003e void) \u003d\u003e fn(testQueryParams),"},{"lineNumber":145,"author":{"gitId":"-"},"content":" };"},{"lineNumber":146,"author":{"gitId":"-"},"content":" },"},{"lineNumber":147,"author":{"gitId":"-"},"content":" },"},{"lineNumber":148,"author":{"gitId":"-"},"content":" },"},{"lineNumber":149,"author":{"gitId":"-"},"content":" },"},{"lineNumber":150,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":151,"author":{"gitId":"-"},"content":" })"},{"lineNumber":152,"author":{"gitId":"-"},"content":" .compileComponents();"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" fixture \u003d TestBed.createComponent(SessionResultPageComponent);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" authService \u003d TestBed.inject(AuthService);"},{"lineNumber":158,"author":{"gitId":"-"},"content":" navService \u003d TestBed.inject(NavigationService);"},{"lineNumber":159,"author":{"gitId":"-"},"content":" studentService \u003d TestBed.inject(StudentService);"},{"lineNumber":160,"author":{"gitId":"-"},"content":" feedbackQuestionsService \u003d TestBed.inject(FeedbackQuestionsService);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" feedbackSessionService \u003d TestBed.inject(FeedbackSessionsService);"},{"lineNumber":162,"author":{"gitId":"-"},"content":" logService \u003d TestBed.inject(LogService);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":164,"author":{"gitId":"-"},"content":" // Set both loading flags to false initially for testing purposes only"},{"lineNumber":165,"author":{"gitId":"-"},"content":" component.isCourseLoading \u003d false;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" component.isFeedbackSessionDetailsLoading \u003d false;"},{"lineNumber":167,"author":{"gitId":"-"},"content":" component.isFeedbackSessionResultsLoading \u003d false;"},{"lineNumber":168,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":169,"author":{"gitId":"-"},"content":" });"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" expect(component).toBeTruthy();"},{"lineNumber":173,"author":{"gitId":"-"},"content":" });"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" it(\u0027should snap with default fields\u0027, () \u003d\u003e {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":177,"author":{"gitId":"-"},"content":" });"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" it(\u0027should snap with session details and results are loading\u0027, () \u003d\u003e {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" component.isCourseLoading \u003d true;"},{"lineNumber":181,"author":{"gitId":"-"},"content":" component.isFeedbackSessionDetailsLoading \u003d true;"},{"lineNumber":182,"author":{"gitId":"-"},"content":" component.isFeedbackSessionResultsLoading \u003d true;"},{"lineNumber":183,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":184,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":185,"author":{"gitId":"-"},"content":" });"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" it(\u0027should snap with session details loaded and results are loading\u0027, () \u003d\u003e {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" component.isCourseLoading \u003d false;"},{"lineNumber":189,"author":{"gitId":"-"},"content":" component.isFeedbackSessionDetailsLoading \u003d false;"},{"lineNumber":190,"author":{"gitId":"-"},"content":" component.isFeedbackSessionResultsLoading \u003d true;"},{"lineNumber":191,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":192,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":193,"author":{"gitId":"-"},"content":" });"},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"-"},"content":" it(\u0027should snap when session results failed to load\u0027, () \u003d\u003e {"},{"lineNumber":196,"author":{"gitId":"-"},"content":" component.isCourseLoading \u003d false;"},{"lineNumber":197,"author":{"gitId":"-"},"content":" component.isFeedbackSessionDetailsLoading \u003d false;"},{"lineNumber":198,"author":{"gitId":"-"},"content":" component.isFeedbackSessionResultsLoading \u003d false;"},{"lineNumber":199,"author":{"gitId":"-"},"content":" component.hasFeedbackSessionResultsLoadingFailed \u003d true;"},{"lineNumber":200,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":201,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":202,"author":{"gitId":"-"},"content":" });"},{"lineNumber":203,"author":{"gitId":"-"},"content":""},{"lineNumber":204,"author":{"gitId":"-"},"content":" it(\u0027should snap with user that is logged in and using session link\u0027, () \u003d\u003e {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" component.regKey \u003d \u0027session-link-key\u0027;"},{"lineNumber":206,"author":{"gitId":"-"},"content":" component.loggedInUser \u003d \u0027alice\u0027;"},{"lineNumber":207,"author":{"gitId":"-"},"content":" component.personName \u003d \u0027alice\u0027;"},{"lineNumber":208,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":209,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":210,"author":{"gitId":"-"},"content":" });"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" it(\u0027should snap with user that is not logged in and using session link\u0027, () \u003d\u003e {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" component.regKey \u003d \u0027session-link-key\u0027;"},{"lineNumber":214,"author":{"gitId":"-"},"content":" component.loggedInUser \u003d \u0027\u0027;"},{"lineNumber":215,"author":{"gitId":"-"},"content":" component.personName \u003d \u0027alice\u0027;"},{"lineNumber":216,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":217,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":218,"author":{"gitId":"-"},"content":" });"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" it(\u0027should snap with an open feedback session with no questions\u0027, () \u003d\u003e {"},{"lineNumber":221,"author":{"gitId":"-"},"content":" component.session \u003d {"},{"lineNumber":222,"author":{"gitId":"-"},"content":" courseId: \u0027CS3281\u0027,"},{"lineNumber":223,"author":{"gitId":"-"},"content":" timeZone: \u0027UTC\u0027,"},{"lineNumber":224,"author":{"gitId":"-"},"content":" feedbackSessionName: \u0027Peer Review 1\u0027,"},{"lineNumber":225,"author":{"gitId":"-"},"content":" instructions: \u0027\u0027,"},{"lineNumber":226,"author":{"gitId":"-"},"content":" submissionStartTimestamp: 1555232400,"},{"lineNumber":227,"author":{"gitId":"-"},"content":" submissionEndTimestamp: 1555233400,"},{"lineNumber":228,"author":{"gitId":"-"},"content":" gracePeriod: 0,"},{"lineNumber":229,"author":{"gitId":"-"},"content":" sessionVisibleSetting: SessionVisibleSetting.AT_OPEN,"},{"lineNumber":230,"author":{"gitId":"-"},"content":" responseVisibleSetting: ResponseVisibleSetting.AT_VISIBLE,"},{"lineNumber":231,"author":{"gitId":"-"},"content":" submissionStatus: FeedbackSessionSubmissionStatus.OPEN,"},{"lineNumber":232,"author":{"gitId":"-"},"content":" publishStatus: FeedbackSessionPublishStatus.NOT_PUBLISHED,"},{"lineNumber":233,"author":{"gitId":"-"},"content":" isClosingEmailEnabled: true,"},{"lineNumber":234,"author":{"gitId":"-"},"content":" isPublishedEmailEnabled: true,"},{"lineNumber":235,"author":{"gitId":"-"},"content":" createdAtTimestamp: 1555231400,"},{"lineNumber":236,"author":{"gitId":"-"},"content":" studentDeadlines: {},"},{"lineNumber":237,"author":{"gitId":"-"},"content":" instructorDeadlines: {},"},{"lineNumber":238,"author":{"gitId":"-"},"content":" };"},{"lineNumber":239,"author":{"gitId":"-"},"content":" component.questions \u003d [];"},{"lineNumber":240,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":241,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":242,"author":{"gitId":"-"},"content":" });"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" it(\u0027should snap when previewing results\u0027, () \u003d\u003e {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" component.intent \u003d Intent.STUDENT_RESULT;"},{"lineNumber":246,"author":{"gitId":"-"},"content":" component.regKey \u003d \u0027\u0027;"},{"lineNumber":247,"author":{"gitId":"-"},"content":" component.previewAsPerson \u003d \u0027alice2@tmt.tmt\u0027;"},{"lineNumber":248,"author":{"gitId":"-"},"content":" component.personName \u003d \u0027Alice2\u0027;"},{"lineNumber":249,"author":{"gitId":"-"},"content":" component.personEmail \u003d \u0027alice2@tmt.tmt\u0027;"},{"lineNumber":250,"author":{"gitId":"-"},"content":" component.session \u003d testFeedbackSession;"},{"lineNumber":251,"author":{"gitId":"-"},"content":" component.questions \u003d [];"},{"lineNumber":252,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":253,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":254,"author":{"gitId":"-"},"content":" });"},{"lineNumber":255,"author":{"gitId":"-"},"content":""},{"lineNumber":256,"author":{"gitId":"-"},"content":" it(\u0027should fetch auth info on init\u0027, () \u003d\u003e {"},{"lineNumber":257,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthUser\u0027).mockReturnValue(of(testInfo));"},{"lineNumber":258,"author":{"gitId":"-"},"content":""},{"lineNumber":259,"author":{"gitId":"-"},"content":" component.ngOnInit();"},{"lineNumber":260,"author":{"gitId":"-"},"content":""},{"lineNumber":261,"author":{"gitId":"-"},"content":" expect(component.courseId).toEqual(\u0027CS3281\u0027);"},{"lineNumber":262,"author":{"gitId":"-"},"content":" expect(component.feedbackSessionName).toEqual(\u0027Peer Feedback\u0027);"},{"lineNumber":263,"author":{"gitId":"-"},"content":" expect(component.regKey).toEqual(\u0027reg-key\u0027);"},{"lineNumber":264,"author":{"gitId":"-"},"content":" expect(component.loggedInUser).toEqual(\u0027user-id\u0027);"},{"lineNumber":265,"author":{"gitId":"-"},"content":" });"},{"lineNumber":266,"author":{"gitId":"-"},"content":""},{"lineNumber":267,"author":{"gitId":"-"},"content":" it(\u0027should verify allowed access and used reg key\u0027, () \u003d\u003e {"},{"lineNumber":268,"author":{"gitId":"-"},"content":" const testValidity: RegkeyValidity \u003d {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" isAllowedAccess: true,"},{"lineNumber":270,"author":{"gitId":"-"},"content":" isUsed: true,"},{"lineNumber":271,"author":{"gitId":"-"},"content":" isValid: false,"},{"lineNumber":272,"author":{"gitId":"-"},"content":" };"},{"lineNumber":273,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthUser\u0027).mockReturnValue(of(testInfo));"},{"lineNumber":274,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthRegkeyValidity\u0027).mockReturnValue(of(testValidity));"},{"lineNumber":275,"author":{"gitId":"-"},"content":" const navSpy: SpyInstance \u003d jest.spyOn(navService, \u0027navigateByURLWithParamEncoding\u0027).mockImplementation();"},{"lineNumber":276,"author":{"gitId":"-"},"content":""},{"lineNumber":277,"author":{"gitId":"-"},"content":" component.ngOnInit();"},{"lineNumber":278,"author":{"gitId":"-"},"content":""},{"lineNumber":279,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":280,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenLastCalledWith(\u0027/web/student/sessions/result\u0027,"},{"lineNumber":281,"author":{"gitId":"-"},"content":" { courseid: \u0027CS3281\u0027, fsname: \u0027Peer Feedback\u0027 });"},{"lineNumber":282,"author":{"gitId":"-"},"content":" });"},{"lineNumber":283,"author":{"gitId":"-"},"content":""},{"lineNumber":284,"author":{"gitId":"-"},"content":" it(\u0027should load info and create log for unused reg key that is allowed\u0027, () \u003d\u003e {"},{"lineNumber":285,"author":{"gitId":"-"},"content":" const testValidity: RegkeyValidity \u003d {"},{"lineNumber":286,"author":{"gitId":"-"},"content":" isAllowedAccess: true,"},{"lineNumber":287,"author":{"gitId":"-"},"content":" isUsed: false,"},{"lineNumber":288,"author":{"gitId":"-"},"content":" isValid: false,"},{"lineNumber":289,"author":{"gitId":"-"},"content":" };"},{"lineNumber":290,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthUser\u0027).mockReturnValue(of(testInfo));"},{"lineNumber":291,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthRegkeyValidity\u0027).mockReturnValue(of(testValidity));"},{"lineNumber":292,"author":{"gitId":"-"},"content":" jest.spyOn(studentService, \u0027getStudent\u0027).mockReturnValue(of({"},{"lineNumber":293,"author":{"gitId":"-"},"content":" name: \u0027student-name\u0027,"},{"lineNumber":294,"author":{"gitId":"dishenggg"},"content":" email: \u0027student@tmt.tmt\u0027,"},{"lineNumber":295,"author":{"gitId":"-"},"content":" courseId: \u0027\u0027,"},{"lineNumber":296,"author":{"gitId":"-"},"content":" sectionName: \u0027\u0027,"},{"lineNumber":297,"author":{"gitId":"-"},"content":" teamName: \u0027\u0027,"},{"lineNumber":298,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":299,"author":{"gitId":"-"},"content":" jest.spyOn(feedbackSessionService, \u0027getFeedbackSession\u0027).mockReturnValue(of(testFeedbackSession));"},{"lineNumber":300,"author":{"gitId":"-"},"content":" const logSpy: SpyInstance \u003d jest.spyOn(logService, \u0027createFeedbackSessionLog\u0027).mockReturnValue(of(\u0027log created\u0027));"},{"lineNumber":301,"author":{"gitId":"-"},"content":""},{"lineNumber":302,"author":{"gitId":"-"},"content":" component.ngOnInit();"},{"lineNumber":303,"author":{"gitId":"-"},"content":""},{"lineNumber":304,"author":{"gitId":"-"},"content":" expect(component.personName).toEqual(\u0027student-name\u0027);"},{"lineNumber":305,"author":{"gitId":"-"},"content":" expect(component.session.courseId).toEqual(\u0027CS1231\u0027);"},{"lineNumber":306,"author":{"gitId":"-"},"content":" expect(logSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":307,"author":{"gitId":"-"},"content":" });"},{"lineNumber":308,"author":{"gitId":"-"},"content":""},{"lineNumber":309,"author":{"gitId":"-"},"content":" it(\u0027should deny access for reg key not belonging to logged in user\u0027, () \u003d\u003e {"},{"lineNumber":310,"author":{"gitId":"-"},"content":" const testValidity: RegkeyValidity \u003d {"},{"lineNumber":311,"author":{"gitId":"-"},"content":" isAllowedAccess: false,"},{"lineNumber":312,"author":{"gitId":"-"},"content":" isUsed: false,"},{"lineNumber":313,"author":{"gitId":"-"},"content":" isValid: true,"},{"lineNumber":314,"author":{"gitId":"-"},"content":" };"},{"lineNumber":315,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthUser\u0027).mockReturnValue(of(testInfo));"},{"lineNumber":316,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthRegkeyValidity\u0027).mockReturnValue(of(testValidity));"},{"lineNumber":317,"author":{"gitId":"-"},"content":" const navSpy: SpyInstance \u003d jest.spyOn(navService, \u0027navigateWithErrorMessage\u0027).mockImplementation();"},{"lineNumber":318,"author":{"gitId":"-"},"content":""},{"lineNumber":319,"author":{"gitId":"-"},"content":" component.ngOnInit();"},{"lineNumber":320,"author":{"gitId":"-"},"content":""},{"lineNumber":321,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":322,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenLastCalledWith(\u0027/web/front\u0027,"},{"lineNumber":323,"author":{"gitId":"-"},"content":" `You are trying to access TEAMMATES using the Google account user-id, which"},{"lineNumber":324,"author":{"gitId":"-"},"content":" is not linked to this TEAMMATES account. If you used a different Google account to"},{"lineNumber":325,"author":{"gitId":"-"},"content":" join/access TEAMMATES before, please use that Google account to access TEAMMATES. If you"},{"lineNumber":326,"author":{"gitId":"-"},"content":" cannot remember which Google account you used before, please email us at"},{"lineNumber":327,"author":{"gitId":"-"},"content":" ${environment.supportEmail} for help.`);"},{"lineNumber":328,"author":{"gitId":"-"},"content":" });"},{"lineNumber":329,"author":{"gitId":"-"},"content":""},{"lineNumber":330,"author":{"gitId":"-"},"content":" it(\u0027should deny access for invalid reg key\u0027, () \u003d\u003e {"},{"lineNumber":331,"author":{"gitId":"-"},"content":" const testValidity: RegkeyValidity \u003d {"},{"lineNumber":332,"author":{"gitId":"-"},"content":" isAllowedAccess: false,"},{"lineNumber":333,"author":{"gitId":"-"},"content":" isUsed: false,"},{"lineNumber":334,"author":{"gitId":"-"},"content":" isValid: false,"},{"lineNumber":335,"author":{"gitId":"-"},"content":" };"},{"lineNumber":336,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthUser\u0027).mockReturnValue(of(testInfo));"},{"lineNumber":337,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthRegkeyValidity\u0027).mockReturnValue(of(testValidity));"},{"lineNumber":338,"author":{"gitId":"-"},"content":" const navSpy: SpyInstance \u003d jest.spyOn(navService, \u0027navigateWithErrorMessage\u0027).mockImplementation();"},{"lineNumber":339,"author":{"gitId":"-"},"content":""},{"lineNumber":340,"author":{"gitId":"-"},"content":" component.ngOnInit();"},{"lineNumber":341,"author":{"gitId":"-"},"content":""},{"lineNumber":342,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":343,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenLastCalledWith(\u0027/web/front\u0027,"},{"lineNumber":344,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":345,"author":{"gitId":"-"},"content":" });"},{"lineNumber":346,"author":{"gitId":"-"},"content":""},{"lineNumber":347,"author":{"gitId":"-"},"content":" it(\u0027should navigate away when error occurs\u0027, () \u003d\u003e {"},{"lineNumber":348,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthUser\u0027).mockReturnValue(throwError(() \u003d\u003e ({"},{"lineNumber":349,"author":{"gitId":"-"},"content":" error: { message: \u0027This is error\u0027 },"},{"lineNumber":350,"author":{"gitId":"-"},"content":" })));"},{"lineNumber":351,"author":{"gitId":"-"},"content":" const navSpy: SpyInstance \u003d jest.spyOn(navService, \u0027navigateWithErrorMessage\u0027).mockImplementation();"},{"lineNumber":352,"author":{"gitId":"-"},"content":""},{"lineNumber":353,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":354,"author":{"gitId":"-"},"content":" component.ngOnInit();"},{"lineNumber":355,"author":{"gitId":"-"},"content":""},{"lineNumber":356,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":357,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenLastCalledWith(\u0027/web/front\u0027,"},{"lineNumber":358,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":359,"author":{"gitId":"-"},"content":" });"},{"lineNumber":360,"author":{"gitId":"-"},"content":""},{"lineNumber":361,"author":{"gitId":"-"},"content":" it(\u0027should navigate to join course when user click on join course link\u0027, () \u003d\u003e {"},{"lineNumber":362,"author":{"gitId":"-"},"content":" component.regKey \u003d \u0027reg-key\u0027;"},{"lineNumber":363,"author":{"gitId":"-"},"content":" component.loggedInUser \u003d \u0027user\u0027;"},{"lineNumber":364,"author":{"gitId":"-"},"content":" const navSpy: SpyInstance \u003d jest.spyOn(navService, \u0027navigateByURL\u0027).mockImplementation();"},{"lineNumber":365,"author":{"gitId":"-"},"content":""},{"lineNumber":366,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":367,"author":{"gitId":"-"},"content":""},{"lineNumber":368,"author":{"gitId":"-"},"content":" const btn: any \u003d fixture.debugElement.nativeElement"},{"lineNumber":369,"author":{"gitId":"-"},"content":" .querySelector(\u0027#join-course-btn\u0027);"},{"lineNumber":370,"author":{"gitId":"-"},"content":" btn.click();"},{"lineNumber":371,"author":{"gitId":"-"},"content":""},{"lineNumber":372,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":373,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenLastCalledWith(\u0027/web/join\u0027, { entitytype: \u0027student\u0027, key: \u0027reg-key\u0027 });"},{"lineNumber":374,"author":{"gitId":"-"},"content":" });"},{"lineNumber":375,"author":{"gitId":"-"},"content":""},{"lineNumber":376,"author":{"gitId":"-"},"content":" it(\u0027should load feedback questions\u0027, () \u003d\u003e {"},{"lineNumber":377,"author":{"gitId":"-"},"content":" const testValidity: RegkeyValidity \u003d {"},{"lineNumber":378,"author":{"gitId":"-"},"content":" isAllowedAccess: true,"},{"lineNumber":379,"author":{"gitId":"-"},"content":" isUsed: false,"},{"lineNumber":380,"author":{"gitId":"-"},"content":" isValid: false,"},{"lineNumber":381,"author":{"gitId":"-"},"content":" };"},{"lineNumber":382,"author":{"gitId":"-"},"content":" const testFeedbackQuestions: FeedbackQuestions \u003d {"},{"lineNumber":383,"author":{"gitId":"-"},"content":" questions: [testFeedbackQuestion],"},{"lineNumber":384,"author":{"gitId":"-"},"content":" };"},{"lineNumber":385,"author":{"gitId":"-"},"content":" const testFeedbackQuestionModel: FeedbackQuestionModel \u003d {"},{"lineNumber":386,"author":{"gitId":"-"},"content":" feedbackQuestion: testFeedbackQuestion,"},{"lineNumber":387,"author":{"gitId":"-"},"content":" questionStatistics: \u0027\u0027,"},{"lineNumber":388,"author":{"gitId":"-"},"content":" allResponses: [],"},{"lineNumber":389,"author":{"gitId":"-"},"content":" responsesToSelf: [],"},{"lineNumber":390,"author":{"gitId":"-"},"content":" responsesFromSelf: [],"},{"lineNumber":391,"author":{"gitId":"-"},"content":" otherResponses: [],"},{"lineNumber":392,"author":{"gitId":"-"},"content":" isLoading: false,"},{"lineNumber":393,"author":{"gitId":"-"},"content":" isLoaded: false,"},{"lineNumber":394,"author":{"gitId":"-"},"content":" hasResponse: false,"},{"lineNumber":395,"author":{"gitId":"-"},"content":" hasResponseButNotVisibleForPreview: false,"},{"lineNumber":396,"author":{"gitId":"-"},"content":" hasCommentNotVisibleForPreview: false,"},{"lineNumber":397,"author":{"gitId":"-"},"content":" };"},{"lineNumber":398,"author":{"gitId":"-"},"content":""},{"lineNumber":399,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthUser\u0027).mockReturnValue(of(testInfo));"},{"lineNumber":400,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthRegkeyValidity\u0027).mockReturnValue(of(testValidity));"},{"lineNumber":401,"author":{"gitId":"-"},"content":" jest.spyOn(feedbackSessionService, \u0027getFeedbackSession\u0027).mockReturnValue(of(testFeedbackSession));"},{"lineNumber":402,"author":{"gitId":"-"},"content":" const getQuestionsSpy: SpyInstance \u003d jest.spyOn(feedbackQuestionsService, \u0027getFeedbackQuestions\u0027)"},{"lineNumber":403,"author":{"gitId":"-"},"content":" .mockReturnValue(of(testFeedbackQuestions));"},{"lineNumber":404,"author":{"gitId":"-"},"content":""},{"lineNumber":405,"author":{"gitId":"-"},"content":" component.ngOnInit();"},{"lineNumber":406,"author":{"gitId":"-"},"content":" expect(getQuestionsSpy).toHaveBeenLastCalledWith({"},{"lineNumber":407,"author":{"gitId":"-"},"content":" courseId: testQueryParams[\u0027courseid\u0027],"},{"lineNumber":408,"author":{"gitId":"-"},"content":" feedbackSessionName: testQueryParams[\u0027fsname\u0027],"},{"lineNumber":409,"author":{"gitId":"-"},"content":" intent: Intent.STUDENT_RESULT,"},{"lineNumber":410,"author":{"gitId":"-"},"content":" key: testQueryParams[\u0027key\u0027],"},{"lineNumber":411,"author":{"gitId":"-"},"content":" previewAs: testQueryParams[\u0027previewas\u0027],"},{"lineNumber":412,"author":{"gitId":"-"},"content":" });"},{"lineNumber":413,"author":{"gitId":"-"},"content":" expect(component.questions.length).toEqual(1);"},{"lineNumber":414,"author":{"gitId":"-"},"content":" expect(component.questions[0]).toEqual(testFeedbackQuestionModel);"},{"lineNumber":415,"author":{"gitId":"-"},"content":" });"},{"lineNumber":416,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"dishenggg":1,"-":415}},{"path":"src/web/app/pages-session/session-result-page/session-result-page.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component, OnInit } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { ActivatedRoute } from \u0027@angular/router\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { NgbModal, NgbModalRef } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { finalize, switchMap, tap } from \u0027rxjs/operators\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { environment } from \u0027../../../environments/environment\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { AuthService } from \u0027../../../services/auth.service\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { CourseService } from \u0027../../../services/course.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { FeedbackQuestionsService } from \u0027../../../services/feedback-questions.service\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { FeedbackSessionsService } from \u0027../../../services/feedback-sessions.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { InstructorService } from \u0027../../../services/instructor.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { LogService } from \u0027../../../services/log.service\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { NavigationService } from \u0027../../../services/navigation.service\u0027;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import { StatusMessageService } from \u0027../../../services/status-message.service\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import { StudentService } from \u0027../../../services/student.service\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import { TimezoneService } from \u0027../../../services/timezone.service\u0027;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" AuthInfo,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" Course,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" FeedbackQuestion,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" FeedbackQuestions,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" FeedbackSession, FeedbackSessionLogType,"},{"lineNumber":23,"author":{"gitId":"-"},"content":" FeedbackSessionPublishStatus, FeedbackSessionSubmissionStatus,"},{"lineNumber":24,"author":{"gitId":"-"},"content":" Instructor,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" RegkeyValidity,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" ResponseOutput,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" ResponseVisibleSetting,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" SessionVisibleSetting, Student,"},{"lineNumber":29,"author":{"gitId":"-"},"content":"} from \u0027../../../types/api-output\u0027;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import { FeedbackVisibilityType, Intent } from \u0027../../../types/api-request\u0027;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import { DEFAULT_NUMBER_OF_RETRY_ATTEMPTS } from \u0027../../../types/default-retry-attempts\u0027;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import { ErrorReportComponent } from \u0027../../components/error-report/error-report.component\u0027;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import { ErrorMessageOutput } from \u0027../../error-message-output\u0027;"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":"export interface FeedbackQuestionModel {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" feedbackQuestion: FeedbackQuestion;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" questionStatistics: string;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" allResponses: ResponseOutput[];"},{"lineNumber":39,"author":{"gitId":"-"},"content":" responsesToSelf: ResponseOutput[];"},{"lineNumber":40,"author":{"gitId":"-"},"content":" responsesFromSelf: ResponseOutput[];"},{"lineNumber":41,"author":{"gitId":"-"},"content":" otherResponses: ResponseOutput[][];"},{"lineNumber":42,"author":{"gitId":"-"},"content":" isLoading: boolean;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" isLoaded: boolean;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" hasResponse: boolean;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" errorMessage?: string;"},{"lineNumber":46,"author":{"gitId":"-"},"content":" hasResponseButNotVisibleForPreview: boolean;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" hasCommentNotVisibleForPreview: boolean;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"}"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":51,"author":{"gitId":"-"},"content":" * Feedback session result page."},{"lineNumber":52,"author":{"gitId":"-"},"content":" */"},{"lineNumber":53,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":54,"author":{"gitId":"-"},"content":" selector: \u0027tm-session-result-page\u0027,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" templateUrl: \u0027./session-result-page.component.html\u0027,"},{"lineNumber":56,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./session-result-page.component.scss\u0027],"},{"lineNumber":57,"author":{"gitId":"-"},"content":"})"},{"lineNumber":58,"author":{"gitId":"-"},"content":"export class SessionResultPageComponent implements OnInit {"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" // enum"},{"lineNumber":61,"author":{"gitId":"-"},"content":" Intent: typeof Intent \u003d Intent;"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" session: FeedbackSession \u003d {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" courseId: \u0027\u0027,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" timeZone: \u0027\u0027,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" feedbackSessionName: \u0027\u0027,"},{"lineNumber":67,"author":{"gitId":"-"},"content":" instructions: \u0027\u0027,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" submissionStartTimestamp: 0,"},{"lineNumber":69,"author":{"gitId":"-"},"content":" submissionEndTimestamp: 0,"},{"lineNumber":70,"author":{"gitId":"-"},"content":" gracePeriod: 0,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" sessionVisibleSetting: SessionVisibleSetting.AT_OPEN,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" responseVisibleSetting: ResponseVisibleSetting.AT_VISIBLE,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" submissionStatus: FeedbackSessionSubmissionStatus.OPEN,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" publishStatus: FeedbackSessionPublishStatus.NOT_PUBLISHED,"},{"lineNumber":75,"author":{"gitId":"-"},"content":" isClosingEmailEnabled: true,"},{"lineNumber":76,"author":{"gitId":"-"},"content":" isPublishedEmailEnabled: true,"},{"lineNumber":77,"author":{"gitId":"-"},"content":" createdAtTimestamp: 0,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" studentDeadlines: {},"},{"lineNumber":79,"author":{"gitId":"-"},"content":" instructorDeadlines: {},"},{"lineNumber":80,"author":{"gitId":"-"},"content":" };"},{"lineNumber":81,"author":{"gitId":"-"},"content":" questions: FeedbackQuestionModel[] \u003d [];"},{"lineNumber":82,"author":{"gitId":"-"},"content":" courseName: string \u003d \u0027\u0027;"},{"lineNumber":83,"author":{"gitId":"-"},"content":" courseInstitute: string \u003d \u0027\u0027;"},{"lineNumber":84,"author":{"gitId":"-"},"content":" formattedSessionOpeningTime: string \u003d \u0027\u0027;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" formattedSessionClosingTime: string \u003d \u0027\u0027;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" personName: string \u003d \u0027\u0027;"},{"lineNumber":87,"author":{"gitId":"-"},"content":" personEmail: string \u003d \u0027\u0027;"},{"lineNumber":88,"author":{"gitId":"-"},"content":" courseId: string \u003d \u0027\u0027;"},{"lineNumber":89,"author":{"gitId":"-"},"content":" feedbackSessionName: string \u003d \u0027\u0027;"},{"lineNumber":90,"author":{"gitId":"-"},"content":" entityType: string \u003d \u0027student\u0027;"},{"lineNumber":91,"author":{"gitId":"-"},"content":" regKey: string \u003d \u0027\u0027;"},{"lineNumber":92,"author":{"gitId":"-"},"content":" loggedInUser: string \u003d \u0027\u0027;"},{"lineNumber":93,"author":{"gitId":"-"},"content":" visibilityRecipient: FeedbackVisibilityType \u003d FeedbackVisibilityType.RECIPIENT;"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" intent: Intent \u003d Intent.STUDENT_RESULT;"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" previewAsPerson: string \u003d \u0027\u0027;"},{"lineNumber":98,"author":{"gitId":"-"},"content":" isPreviewHintExpanded: boolean \u003d false;"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" isCourseLoading: boolean \u003d true;"},{"lineNumber":101,"author":{"gitId":"-"},"content":" isFeedbackSessionDetailsLoading: boolean \u003d true;"},{"lineNumber":102,"author":{"gitId":"-"},"content":" isFeedbackSessionResultsLoading: boolean \u003d true;"},{"lineNumber":103,"author":{"gitId":"-"},"content":" hasFeedbackSessionResultsLoadingFailed: boolean \u003d false;"},{"lineNumber":104,"author":{"gitId":"-"},"content":" retryAttempts: number \u003d DEFAULT_NUMBER_OF_RETRY_ATTEMPTS;"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" feedbackSessionId: string | undefined \u003d \u0027\u0027;"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":" studentId: string | undefined \u003d \u0027\u0027;"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" private backendUrl: string \u003d environment.backendUrl;"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" constructor(private feedbackQuestionsService: FeedbackQuestionsService,"},{"lineNumber":112,"author":{"gitId":"-"},"content":" private feedbackSessionsService: FeedbackSessionsService,"},{"lineNumber":113,"author":{"gitId":"-"},"content":" private route: ActivatedRoute,"},{"lineNumber":114,"author":{"gitId":"-"},"content":" private timezoneService: TimezoneService,"},{"lineNumber":115,"author":{"gitId":"-"},"content":" private navigationService: NavigationService,"},{"lineNumber":116,"author":{"gitId":"-"},"content":" private authService: AuthService,"},{"lineNumber":117,"author":{"gitId":"-"},"content":" private studentService: StudentService,"},{"lineNumber":118,"author":{"gitId":"-"},"content":" private instructorService: InstructorService,"},{"lineNumber":119,"author":{"gitId":"-"},"content":" private courseService: CourseService,"},{"lineNumber":120,"author":{"gitId":"-"},"content":" private statusMessageService: StatusMessageService,"},{"lineNumber":121,"author":{"gitId":"-"},"content":" private logService: LogService,"},{"lineNumber":122,"author":{"gitId":"-"},"content":" private ngbModal: NgbModal) {"},{"lineNumber":123,"author":{"gitId":"-"},"content":" this.timezoneService.getTzVersion(); // import timezone service to load timezone data"},{"lineNumber":124,"author":{"gitId":"-"},"content":" }"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" ngOnInit(): void {"},{"lineNumber":127,"author":{"gitId":"-"},"content":" this.route.data.pipe("},{"lineNumber":128,"author":{"gitId":"-"},"content":" tap((data: any) \u003d\u003e {"},{"lineNumber":129,"author":{"gitId":"-"},"content":" this.intent \u003d data.intent;"},{"lineNumber":130,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":131,"author":{"gitId":"-"},"content":" switchMap(() \u003d\u003e this.route.queryParams),"},{"lineNumber":132,"author":{"gitId":"-"},"content":" ).subscribe((queryParams: any) \u003d\u003e {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" this.courseId \u003d queryParams.courseid;"},{"lineNumber":134,"author":{"gitId":"-"},"content":" this.feedbackSessionName \u003d queryParams.fsname;"},{"lineNumber":135,"author":{"gitId":"-"},"content":" this.regKey \u003d queryParams.key || \u0027\u0027;"},{"lineNumber":136,"author":{"gitId":"-"},"content":" this.previewAsPerson \u003d queryParams.previewas ? queryParams.previewas : \u0027\u0027;"},{"lineNumber":137,"author":{"gitId":"-"},"content":" if (queryParams.entitytype \u003d\u003d\u003d \u0027instructor\u0027) {"},{"lineNumber":138,"author":{"gitId":"-"},"content":" this.entityType \u003d \u0027instructor\u0027;"},{"lineNumber":139,"author":{"gitId":"-"},"content":" this.intent \u003d Intent.INSTRUCTOR_RESULT;"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" const nextUrl: string \u003d `${window.location.pathname}${window.location.search.replace(/\u0026/g, \u0027%26\u0027)}`;"},{"lineNumber":143,"author":{"gitId":"-"},"content":" this.authService.getAuthUser(undefined, nextUrl).subscribe({"},{"lineNumber":144,"author":{"gitId":"-"},"content":" next: (auth: AuthInfo) \u003d\u003e {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" const isPreview: boolean \u003d !!(auth.user \u0026\u0026 this.previewAsPerson);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" if (auth.user) {"},{"lineNumber":147,"author":{"gitId":"-"},"content":" this.loggedInUser \u003d auth.user.id;"},{"lineNumber":148,"author":{"gitId":"-"},"content":" }"},{"lineNumber":149,"author":{"gitId":"-"},"content":" // prevent having both key and previewas parameters in URL"},{"lineNumber":150,"author":{"gitId":"-"},"content":" if (this.regKey \u0026\u0026 isPreview) {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":152,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":153,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":" if (this.regKey) {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" this.authService.getAuthRegkeyValidity(this.regKey, this.intent).subscribe({"},{"lineNumber":157,"author":{"gitId":"-"},"content":" next: (resp: RegkeyValidity) \u003d\u003e {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" if (resp.isAllowedAccess) {"},{"lineNumber":159,"author":{"gitId":"-"},"content":" if (resp.isUsed) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" // The logged in user matches the registration key; redirect to the logged in URL"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"-"},"content":" this.navigationService.navigateByURLWithParamEncoding("},{"lineNumber":163,"author":{"gitId":"-"},"content":" `/web/${this.entityType}/sessions/result`,"},{"lineNumber":164,"author":{"gitId":"-"},"content":" { courseid: this.courseId, fsname: this.feedbackSessionName });"},{"lineNumber":165,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":166,"author":{"gitId":"-"},"content":" // Valid, unused registration key; load information based on the key"},{"lineNumber":167,"author":{"gitId":"-"},"content":" this.loadCourseInfo();"},{"lineNumber":168,"author":{"gitId":"-"},"content":" this.loadPersonName();"},{"lineNumber":169,"author":{"gitId":"-"},"content":" this.loadFeedbackSession();"},{"lineNumber":170,"author":{"gitId":"-"},"content":" }"},{"lineNumber":171,"author":{"gitId":"-"},"content":" } else if (resp.isValid) {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" // At this point, registration key must already be used, otherwise access would be granted"},{"lineNumber":173,"author":{"gitId":"-"},"content":" if (this.loggedInUser) {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" // Registration key belongs to another user who is not the logged in user"},{"lineNumber":175,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":176,"author":{"gitId":"-"},"content":" `You are trying to access TEAMMATES using the Google account ${this.loggedInUser}, which"},{"lineNumber":177,"author":{"gitId":"-"},"content":" is not linked to this TEAMMATES account. If you used a different Google account to"},{"lineNumber":178,"author":{"gitId":"-"},"content":" join/access TEAMMATES before, please use that Google account to access TEAMMATES. If you"},{"lineNumber":179,"author":{"gitId":"-"},"content":" cannot remember which Google account you used before, please email us at"},{"lineNumber":180,"author":{"gitId":"-"},"content":" ${environment.supportEmail} for help.`);"},{"lineNumber":181,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":182,"author":{"gitId":"-"},"content":" // There is no logged in user for a valid, used registration key, redirect to login page"},{"lineNumber":183,"author":{"gitId":"-"},"content":" // eslint-disable-next-line no-lonely-if"},{"lineNumber":184,"author":{"gitId":"-"},"content":" if (this.entityType \u003d\u003d\u003d \u0027student\u0027) {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" window.location.href \u003d `${this.backendUrl}${auth.studentLoginUrl}`;"},{"lineNumber":186,"author":{"gitId":"-"},"content":" } else if (this.entityType \u003d\u003d\u003d \u0027instructor\u0027) {"},{"lineNumber":187,"author":{"gitId":"-"},"content":" window.location.href \u003d `${this.backendUrl}${auth.instructorLoginUrl}`;"},{"lineNumber":188,"author":{"gitId":"-"},"content":" }"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" // The registration key is invalid"},{"lineNumber":192,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":193,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":194,"author":{"gitId":"-"},"content":" }"},{"lineNumber":195,"author":{"gitId":"-"},"content":" },"},{"lineNumber":196,"author":{"gitId":"-"},"content":" error: () \u003d\u003e {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":198,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":199,"author":{"gitId":"-"},"content":" },"},{"lineNumber":200,"author":{"gitId":"-"},"content":" });"},{"lineNumber":201,"author":{"gitId":"-"},"content":" } else if (this.loggedInUser) {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" // Load information based on logged in user"},{"lineNumber":203,"author":{"gitId":"-"},"content":" // This will also cover preview cases"},{"lineNumber":204,"author":{"gitId":"-"},"content":" this.loadCourseInfo();"},{"lineNumber":205,"author":{"gitId":"-"},"content":" this.loadPersonName();"},{"lineNumber":206,"author":{"gitId":"-"},"content":" this.loadFeedbackSession();"},{"lineNumber":207,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":208,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":209,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":210,"author":{"gitId":"-"},"content":" }"},{"lineNumber":211,"author":{"gitId":"-"},"content":" },"},{"lineNumber":212,"author":{"gitId":"-"},"content":" error: () \u003d\u003e {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":214,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":215,"author":{"gitId":"-"},"content":" },"},{"lineNumber":216,"author":{"gitId":"-"},"content":" });"},{"lineNumber":217,"author":{"gitId":"-"},"content":" });"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" private loadCourseInfo(): void {"},{"lineNumber":221,"author":{"gitId":"-"},"content":" this.isCourseLoading \u003d true;"},{"lineNumber":222,"author":{"gitId":"-"},"content":" let request: Observable\u003cCourse\u003e;"},{"lineNumber":223,"author":{"gitId":"-"},"content":" switch (this.intent) {"},{"lineNumber":224,"author":{"gitId":"-"},"content":" case Intent.STUDENT_RESULT:"},{"lineNumber":225,"author":{"gitId":"-"},"content":" if (this.previewAsPerson) {"},{"lineNumber":226,"author":{"gitId":"-"},"content":" request \u003d this.courseService.getCourseAsInstructor(this.courseId);"},{"lineNumber":227,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":228,"author":{"gitId":"-"},"content":" request \u003d this.courseService.getCourseAsStudent(this.courseId, this.regKey);"},{"lineNumber":229,"author":{"gitId":"-"},"content":" }"},{"lineNumber":230,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":231,"author":{"gitId":"-"},"content":" case Intent.INSTRUCTOR_RESULT:"},{"lineNumber":232,"author":{"gitId":"-"},"content":" request \u003d this.courseService.getCourseAsInstructor(this.courseId, this.regKey);"},{"lineNumber":233,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":234,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":235,"author":{"gitId":"-"},"content":" this.isCourseLoading \u003d false;"},{"lineNumber":236,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":237,"author":{"gitId":"-"},"content":" }"},{"lineNumber":238,"author":{"gitId":"-"},"content":" request.subscribe({"},{"lineNumber":239,"author":{"gitId":"-"},"content":" next: (resp: Course) \u003d\u003e {"},{"lineNumber":240,"author":{"gitId":"-"},"content":" this.courseName \u003d resp.courseName;"},{"lineNumber":241,"author":{"gitId":"-"},"content":" this.courseInstitute \u003d resp.institute;"},{"lineNumber":242,"author":{"gitId":"-"},"content":" this.isCourseLoading \u003d false;"},{"lineNumber":243,"author":{"gitId":"-"},"content":" },"},{"lineNumber":244,"author":{"gitId":"-"},"content":" error: () \u003d\u003e {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" this.isCourseLoading \u003d false;"},{"lineNumber":246,"author":{"gitId":"-"},"content":" },"},{"lineNumber":247,"author":{"gitId":"-"},"content":" });"},{"lineNumber":248,"author":{"gitId":"-"},"content":" }"},{"lineNumber":249,"author":{"gitId":"-"},"content":""},{"lineNumber":250,"author":{"gitId":"-"},"content":" private loadPersonName(): void {"},{"lineNumber":251,"author":{"gitId":"-"},"content":" switch (this.intent) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" case Intent.STUDENT_RESULT:"},{"lineNumber":253,"author":{"gitId":"-"},"content":" this.studentService.getStudent("},{"lineNumber":254,"author":{"gitId":"-"},"content":" this.courseId,"},{"lineNumber":255,"author":{"gitId":"-"},"content":" this.previewAsPerson,"},{"lineNumber":256,"author":{"gitId":"-"},"content":" this.regKey,"},{"lineNumber":257,"author":{"gitId":"-"},"content":" ).subscribe((student: Student) \u003d\u003e {"},{"lineNumber":258,"author":{"gitId":"dishenggg"},"content":" this.studentId \u003d student.studentId;"},{"lineNumber":259,"author":{"gitId":"-"},"content":" this.personName \u003d student.name;"},{"lineNumber":260,"author":{"gitId":"-"},"content":" this.personEmail \u003d student.email;"},{"lineNumber":261,"author":{"gitId":"dishenggg"},"content":" this.logStudentView();"},{"lineNumber":262,"author":{"gitId":"-"},"content":" });"},{"lineNumber":263,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":264,"author":{"gitId":"-"},"content":" case Intent.INSTRUCTOR_RESULT:"},{"lineNumber":265,"author":{"gitId":"-"},"content":" this.instructorService.getInstructor({"},{"lineNumber":266,"author":{"gitId":"-"},"content":" courseId: this.courseId,"},{"lineNumber":267,"author":{"gitId":"-"},"content":" feedbackSessionName: this.feedbackSessionName,"},{"lineNumber":268,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":269,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":270,"author":{"gitId":"-"},"content":" previewAs: this.previewAsPerson,"},{"lineNumber":271,"author":{"gitId":"-"},"content":" }).subscribe((instructor: Instructor) \u003d\u003e {"},{"lineNumber":272,"author":{"gitId":"-"},"content":" this.personName \u003d instructor.name;"},{"lineNumber":273,"author":{"gitId":"-"},"content":" this.personEmail \u003d instructor.email;"},{"lineNumber":274,"author":{"gitId":"-"},"content":" });"},{"lineNumber":275,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":276,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":277,"author":{"gitId":"-"},"content":" }"},{"lineNumber":278,"author":{"gitId":"-"},"content":" }"},{"lineNumber":279,"author":{"gitId":"-"},"content":""},{"lineNumber":280,"author":{"gitId":"-"},"content":" private loadFeedbackSession(): void {"},{"lineNumber":281,"author":{"gitId":"-"},"content":" this.isFeedbackSessionDetailsLoading \u003d true;"},{"lineNumber":282,"author":{"gitId":"-"},"content":" this.isFeedbackSessionResultsLoading \u003d true;"},{"lineNumber":283,"author":{"gitId":"-"},"content":" this.feedbackSessionsService.getFeedbackSession({"},{"lineNumber":284,"author":{"gitId":"-"},"content":" courseId: this.courseId,"},{"lineNumber":285,"author":{"gitId":"-"},"content":" feedbackSessionName: this.feedbackSessionName,"},{"lineNumber":286,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":287,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":288,"author":{"gitId":"-"},"content":" previewAs: this.previewAsPerson,"},{"lineNumber":289,"author":{"gitId":"-"},"content":" })"},{"lineNumber":290,"author":{"gitId":"dishenggg"},"content":" .pipe(finalize(() \u003d\u003e {"},{"lineNumber":291,"author":{"gitId":"dishenggg"},"content":" this.isFeedbackSessionDetailsLoading \u003d false;"},{"lineNumber":292,"author":{"gitId":"dishenggg"},"content":" }))"},{"lineNumber":293,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":294,"author":{"gitId":"-"},"content":" next: (feedbackSession: FeedbackSession) \u003d\u003e {"},{"lineNumber":295,"author":{"gitId":"-"},"content":" const TIME_FORMAT: string \u003d \u0027ddd, DD MMM, YYYY, hh:mm A zz\u0027;"},{"lineNumber":296,"author":{"gitId":"-"},"content":" this.session \u003d feedbackSession;"},{"lineNumber":297,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionId \u003d feedbackSession.feedbackSessionId;"},{"lineNumber":298,"author":{"gitId":"-"},"content":" this.formattedSessionOpeningTime \u003d this.timezoneService"},{"lineNumber":299,"author":{"gitId":"-"},"content":" .formatToString(this.session.submissionStartTimestamp, this.session.timeZone, TIME_FORMAT);"},{"lineNumber":300,"author":{"gitId":"-"},"content":" this.formattedSessionClosingTime \u003d this.timezoneService"},{"lineNumber":301,"author":{"gitId":"-"},"content":" .formatToString(this.session.submissionEndTimestamp, this.session.timeZone, TIME_FORMAT);"},{"lineNumber":302,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":303,"author":{"gitId":"dishenggg"},"content":" this.logStudentView();"},{"lineNumber":304,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":305,"author":{"gitId":"-"},"content":" this.feedbackQuestionsService.getFeedbackQuestions({"},{"lineNumber":306,"author":{"gitId":"-"},"content":" courseId: this.courseId,"},{"lineNumber":307,"author":{"gitId":"-"},"content":" feedbackSessionName: this.feedbackSessionName,"},{"lineNumber":308,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":309,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":310,"author":{"gitId":"-"},"content":" previewAs: this.previewAsPerson,"},{"lineNumber":311,"author":{"gitId":"-"},"content":" }).pipe(finalize(() \u003d\u003e {"},{"lineNumber":312,"author":{"gitId":"-"},"content":" this.isFeedbackSessionResultsLoading \u003d false;"},{"lineNumber":313,"author":{"gitId":"-"},"content":" }))"},{"lineNumber":314,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":315,"author":{"gitId":"-"},"content":" next: (feedbackQuestions: FeedbackQuestions) \u003d\u003e {"},{"lineNumber":316,"author":{"gitId":"-"},"content":" feedbackQuestions.questions.sort("},{"lineNumber":317,"author":{"gitId":"-"},"content":" (a: FeedbackQuestion, b: FeedbackQuestion) \u003d\u003e"},{"lineNumber":318,"author":{"gitId":"-"},"content":" a.questionNumber - b.questionNumber);"},{"lineNumber":319,"author":{"gitId":"-"},"content":" for (const question of feedbackQuestions.questions) {"},{"lineNumber":320,"author":{"gitId":"-"},"content":" this.questions.push({"},{"lineNumber":321,"author":{"gitId":"-"},"content":" feedbackQuestion: question,"},{"lineNumber":322,"author":{"gitId":"-"},"content":" questionStatistics: \u0027\u0027,"},{"lineNumber":323,"author":{"gitId":"-"},"content":" allResponses: [],"},{"lineNumber":324,"author":{"gitId":"-"},"content":" responsesToSelf: [],"},{"lineNumber":325,"author":{"gitId":"-"},"content":" responsesFromSelf: [],"},{"lineNumber":326,"author":{"gitId":"-"},"content":" otherResponses: [],"},{"lineNumber":327,"author":{"gitId":"-"},"content":" isLoading: false,"},{"lineNumber":328,"author":{"gitId":"-"},"content":" isLoaded: false,"},{"lineNumber":329,"author":{"gitId":"-"},"content":" hasResponse: false,"},{"lineNumber":330,"author":{"gitId":"-"},"content":" hasResponseButNotVisibleForPreview: false,"},{"lineNumber":331,"author":{"gitId":"-"},"content":" hasCommentNotVisibleForPreview: false,"},{"lineNumber":332,"author":{"gitId":"-"},"content":" });"},{"lineNumber":333,"author":{"gitId":"-"},"content":" }"},{"lineNumber":334,"author":{"gitId":"-"},"content":" },"},{"lineNumber":335,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":336,"author":{"gitId":"-"},"content":" this.handleError(resp);"},{"lineNumber":337,"author":{"gitId":"-"},"content":" },"},{"lineNumber":338,"author":{"gitId":"-"},"content":" });"},{"lineNumber":339,"author":{"gitId":"-"},"content":" },"},{"lineNumber":340,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":341,"author":{"gitId":"-"},"content":" this.isFeedbackSessionResultsLoading \u003d false;"},{"lineNumber":342,"author":{"gitId":"-"},"content":" this.handleError(resp);"},{"lineNumber":343,"author":{"gitId":"-"},"content":" },"},{"lineNumber":344,"author":{"gitId":"-"},"content":" });"},{"lineNumber":345,"author":{"gitId":"-"},"content":" }"},{"lineNumber":346,"author":{"gitId":"-"},"content":""},{"lineNumber":347,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":348,"author":{"gitId":"-"},"content":" * Redirects to join course link for unregistered student/instructor."},{"lineNumber":349,"author":{"gitId":"-"},"content":" */"},{"lineNumber":350,"author":{"gitId":"-"},"content":" joinCourseForUnregisteredEntity(): void {"},{"lineNumber":351,"author":{"gitId":"-"},"content":" this.navigationService.navigateByURL(\u0027/web/join\u0027, { entitytype: this.entityType, key: this.regKey });"},{"lineNumber":352,"author":{"gitId":"-"},"content":" }"},{"lineNumber":353,"author":{"gitId":"-"},"content":""},{"lineNumber":354,"author":{"gitId":"-"},"content":" navigateToSessionReportPage(): void {"},{"lineNumber":355,"author":{"gitId":"-"},"content":" this.navigationService.navigateByURL(\u0027/web/instructor/sessions/report\u0027,"},{"lineNumber":356,"author":{"gitId":"-"},"content":" { courseid: this.courseId, fsname: this.feedbackSessionName });"},{"lineNumber":357,"author":{"gitId":"-"},"content":" }"},{"lineNumber":358,"author":{"gitId":"-"},"content":""},{"lineNumber":359,"author":{"gitId":"-"},"content":" retryLoadingFeedbackSessionResults(): void {"},{"lineNumber":360,"author":{"gitId":"-"},"content":" this.hasFeedbackSessionResultsLoadingFailed \u003d false;"},{"lineNumber":361,"author":{"gitId":"-"},"content":" if (this.retryAttempts \u003e\u003d 0) {"},{"lineNumber":362,"author":{"gitId":"-"},"content":" this.retryAttempts -\u003d 1;"},{"lineNumber":363,"author":{"gitId":"-"},"content":" }"},{"lineNumber":364,"author":{"gitId":"-"},"content":" this.loadFeedbackSession();"},{"lineNumber":365,"author":{"gitId":"-"},"content":" }"},{"lineNumber":366,"author":{"gitId":"-"},"content":""},{"lineNumber":367,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":368,"author":{"gitId":"-"},"content":" * Handles error according to number of attempts at retry"},{"lineNumber":369,"author":{"gitId":"-"},"content":" */"},{"lineNumber":370,"author":{"gitId":"-"},"content":" handleError(resp: ErrorMessageOutput): void {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" this.hasFeedbackSessionResultsLoadingFailed \u003d true;"},{"lineNumber":372,"author":{"gitId":"-"},"content":" if (this.retryAttempts \u003c 0) {"},{"lineNumber":373,"author":{"gitId":"-"},"content":" const report: NgbModalRef \u003d this.ngbModal.open(ErrorReportComponent);"},{"lineNumber":374,"author":{"gitId":"-"},"content":" report.componentInstance.requestId \u003d resp.error.requestId;"},{"lineNumber":375,"author":{"gitId":"-"},"content":" report.componentInstance.errorMessage \u003d resp.error.message;"},{"lineNumber":376,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":377,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":378,"author":{"gitId":"-"},"content":" }"},{"lineNumber":379,"author":{"gitId":"-"},"content":" }"},{"lineNumber":380,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":381,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":382,"author":{"gitId":"dishenggg"},"content":" * Logs student activity after student/session details have been fetched."},{"lineNumber":383,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":384,"author":{"gitId":"dishenggg"},"content":" logStudentView(): void {"},{"lineNumber":385,"author":{"gitId":"dishenggg"},"content":" if (this.intent !\u003d\u003d Intent.STUDENT_RESULT) {"},{"lineNumber":386,"author":{"gitId":"dishenggg"},"content":" return;"},{"lineNumber":387,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":388,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":389,"author":{"gitId":"dishenggg"},"content":" // dummy vars to check that both student and session has been loaded"},{"lineNumber":390,"author":{"gitId":"dishenggg"},"content":" if (!this.personEmail || !this.session.courseId) {"},{"lineNumber":391,"author":{"gitId":"dishenggg"},"content":" return;"},{"lineNumber":392,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":393,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":394,"author":{"gitId":"dishenggg"},"content":" this.logService.createFeedbackSessionLog({"},{"lineNumber":395,"author":{"gitId":"dishenggg"},"content":" courseId: this.courseId,"},{"lineNumber":396,"author":{"gitId":"dishenggg"},"content":" feedbackSessionName: this.feedbackSessionName,"},{"lineNumber":397,"author":{"gitId":"dishenggg"},"content":" studentEmail: this.personEmail,"},{"lineNumber":398,"author":{"gitId":"dishenggg"},"content":" logType: FeedbackSessionLogType.VIEW_RESULT,"},{"lineNumber":399,"author":{"gitId":"dishenggg"},"content":" feedbackSessionId: this.feedbackSessionId,"},{"lineNumber":400,"author":{"gitId":"dishenggg"},"content":" studentId: this.studentId,"},{"lineNumber":401,"author":{"gitId":"dishenggg"},"content":" }).subscribe();"},{"lineNumber":402,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":403,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":35,"-":368}},{"path":"src/web/app/pages-session/session-submission-page/session-submission-page.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { DOCUMENT } from \u0027@angular/common\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { AfterViewInit, Component, Inject, OnInit } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { ActivatedRoute } from \u0027@angular/router\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { NgbModal, NgbModalRef } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { PageScrollService } from \u0027ngx-page-scroll-core\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { forkJoin, Observable, of } from \u0027rxjs\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { catchError, finalize, switchMap, tap } from \u0027rxjs/operators\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { SavingCompleteModalComponent } from \u0027./saving-complete-modal/saving-complete-modal.component\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { environment } from \u0027../../../environments/environment\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { AuthService } from \u0027../../../services/auth.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { CourseService } from \u0027../../../services/course.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { DeadlineExtensionHelper } from \u0027../../../services/deadline-extension-helper\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { FeedbackQuestionsService } from \u0027../../../services/feedback-questions.service\u0027;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import { FeedbackResponseCommentService } from \u0027../../../services/feedback-response-comment.service\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import { FeedbackResponsesResponse, FeedbackResponsesService } from \u0027../../../services/feedback-responses.service\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import { FeedbackSessionsService } from \u0027../../../services/feedback-sessions.service\u0027;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import { InstructorService } from \u0027../../../services/instructor.service\u0027;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import { LogService } from \u0027../../../services/log.service\u0027;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import { NavigationService } from \u0027../../../services/navigation.service\u0027;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import { SimpleModalService } from \u0027../../../services/simple-modal.service\u0027;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import { StatusMessageService } from \u0027../../../services/status-message.service\u0027;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import { StudentService } from \u0027../../../services/student.service\u0027;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import { TimezoneService } from \u0027../../../services/timezone.service\u0027;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" AuthInfo,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" Course,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" FeedbackParticipantType,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" FeedbackQuestion,"},{"lineNumber":29,"author":{"gitId":"-"},"content":" FeedbackQuestionRecipient,"},{"lineNumber":30,"author":{"gitId":"-"},"content":" FeedbackQuestionRecipients,"},{"lineNumber":31,"author":{"gitId":"-"},"content":" FeedbackQuestionType,"},{"lineNumber":32,"author":{"gitId":"-"},"content":" FeedbackResponse,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" FeedbackResponseComment,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" FeedbackResponses,"},{"lineNumber":35,"author":{"gitId":"-"},"content":" FeedbackSession,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" FeedbackSessionLogType,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" FeedbackSessionSubmissionStatus,"},{"lineNumber":38,"author":{"gitId":"-"},"content":" Instructor,"},{"lineNumber":39,"author":{"gitId":"-"},"content":" NumberOfEntitiesToGiveFeedbackToSetting,"},{"lineNumber":40,"author":{"gitId":"-"},"content":" RegkeyValidity,"},{"lineNumber":41,"author":{"gitId":"-"},"content":" Student,"},{"lineNumber":42,"author":{"gitId":"-"},"content":"} from \u0027../../../types/api-output\u0027;"},{"lineNumber":43,"author":{"gitId":"-"},"content":"import { FeedbackResponseRequest, Intent } from \u0027../../../types/api-request\u0027;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"import { Milliseconds } from \u0027../../../types/datetime-const\u0027;"},{"lineNumber":45,"author":{"gitId":"-"},"content":"import { DEFAULT_NUMBER_OF_RETRY_ATTEMPTS } from \u0027../../../types/default-retry-attempts\u0027;"},{"lineNumber":46,"author":{"gitId":"-"},"content":"import { CommentRowModel } from \u0027../../components/comment-box/comment-row/comment-row.component\u0027;"},{"lineNumber":47,"author":{"gitId":"-"},"content":"import { ErrorReportComponent } from \u0027../../components/error-report/error-report.component\u0027;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" FeedbackResponseRecipient,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" FeedbackResponseRecipientSubmissionFormModel,"},{"lineNumber":51,"author":{"gitId":"-"},"content":" QuestionSubmissionFormMode,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" QuestionSubmissionFormModel,"},{"lineNumber":53,"author":{"gitId":"-"},"content":"} from \u0027../../components/question-submission-form/question-submission-form-model\u0027;"},{"lineNumber":54,"author":{"gitId":"-"},"content":"import { SimpleModalType } from \u0027../../components/simple-modal/simple-modal-type\u0027;"},{"lineNumber":55,"author":{"gitId":"-"},"content":"import { ErrorMessageOutput } from \u0027../../error-message-output\u0027;"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":"interface FeedbackQuestionsResponse {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" questions: FeedbackQuestion[];"},{"lineNumber":59,"author":{"gitId":"-"},"content":"}"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":"// To export out"},{"lineNumber":62,"author":{"gitId":"-"},"content":"export enum SessionView {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" DEFAULT \u003d \u0027Question\u0027,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" GROUP_RECIPIENTS \u003d \u0027Recipient\u0027,"},{"lineNumber":65,"author":{"gitId":"-"},"content":"}"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":68,"author":{"gitId":"-"},"content":" * Feedback session submission page."},{"lineNumber":69,"author":{"gitId":"-"},"content":" */"},{"lineNumber":70,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":71,"author":{"gitId":"-"},"content":" selector: \u0027tm-session-submission-page\u0027,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" templateUrl: \u0027./session-submission-page.component.html\u0027,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./session-submission-page.component.scss\u0027],"},{"lineNumber":74,"author":{"gitId":"-"},"content":"})"},{"lineNumber":75,"author":{"gitId":"-"},"content":"export class SessionSubmissionPageComponent implements OnInit, AfterViewInit {"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" // enum"},{"lineNumber":78,"author":{"gitId":"-"},"content":" FeedbackSessionSubmissionStatus: typeof FeedbackSessionSubmissionStatus \u003d FeedbackSessionSubmissionStatus;"},{"lineNumber":79,"author":{"gitId":"-"},"content":" FeedbackQuestionType: typeof FeedbackQuestionType \u003d FeedbackQuestionType;"},{"lineNumber":80,"author":{"gitId":"-"},"content":" Intent: typeof Intent \u003d Intent;"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" courseId: string \u003d \u0027\u0027;"},{"lineNumber":83,"author":{"gitId":"-"},"content":" feedbackSessionName: string \u003d \u0027\u0027;"},{"lineNumber":84,"author":{"gitId":"-"},"content":" regKey: string \u003d \u0027\u0027;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" entityType: string \u003d \u0027student\u0027;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" loggedInUser: string \u003d \u0027\u0027;"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" moderatedPerson: string \u003d \u0027\u0027;"},{"lineNumber":89,"author":{"gitId":"-"},"content":" previewAsPerson: string \u003d \u0027\u0027;"},{"lineNumber":90,"author":{"gitId":"-"},"content":" // the name of the person involved"},{"lineNumber":91,"author":{"gitId":"-"},"content":" // (e.g. the student name for unregistered student, the name of instructor being moderated)"},{"lineNumber":92,"author":{"gitId":"-"},"content":" personName: string \u003d \u0027\u0027;"},{"lineNumber":93,"author":{"gitId":"-"},"content":" personEmail: string \u003d \u0027\u0027;"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" courseName: string \u003d \u0027\u0027;"},{"lineNumber":96,"author":{"gitId":"-"},"content":" courseInstitute: string \u003d \u0027\u0027;"},{"lineNumber":97,"author":{"gitId":"-"},"content":" formattedSessionOpeningTime: string \u003d \u0027\u0027;"},{"lineNumber":98,"author":{"gitId":"-"},"content":" formattedSessionClosingTime: string \u003d \u0027\u0027;"},{"lineNumber":99,"author":{"gitId":"-"},"content":" feedbackSessionInstructions: string \u003d \u0027\u0027;"},{"lineNumber":100,"author":{"gitId":"-"},"content":" feedbackSessionTimezone: string \u003d \u0027\u0027;"},{"lineNumber":101,"author":{"gitId":"-"},"content":" feedbackSessionSubmissionStatus: FeedbackSessionSubmissionStatus \u003d FeedbackSessionSubmissionStatus.OPEN;"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" intent: Intent \u003d Intent.STUDENT_SUBMISSION;"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" questionSubmissionForms: QuestionSubmissionFormModel[] \u003d [];"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" isSavingResponses: boolean \u003d false;"},{"lineNumber":108,"author":{"gitId":"-"},"content":" isSubmissionFormsDisabled: boolean \u003d false;"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" isModerationHintExpanded: boolean \u003d false;"},{"lineNumber":111,"author":{"gitId":"-"},"content":" moderatedQuestionId: string \u003d \u0027\u0027;"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" isCourseLoading: boolean \u003d true;"},{"lineNumber":114,"author":{"gitId":"-"},"content":" isFeedbackSessionLoading: boolean \u003d true;"},{"lineNumber":115,"author":{"gitId":"-"},"content":" isFeedbackSessionQuestionsLoading: boolean \u003d true;"},{"lineNumber":116,"author":{"gitId":"-"},"content":" hasFeedbackSessionQuestionsLoadingFailed: boolean \u003d false;"},{"lineNumber":117,"author":{"gitId":"-"},"content":" retryAttempts: number \u003d DEFAULT_NUMBER_OF_RETRY_ATTEMPTS;"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" isQuestionCountOne: boolean \u003d false;"},{"lineNumber":120,"author":{"gitId":"-"},"content":" isSubmitAllClicked: boolean \u003d false;"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" allSessionViews \u003d SessionView;"},{"lineNumber":123,"author":{"gitId":"-"},"content":" currentSelectedSessionView: SessionView \u003d SessionView.DEFAULT;"},{"lineNumber":124,"author":{"gitId":"-"},"content":" hasLoadedAllRecipients: boolean \u003d false;"},{"lineNumber":125,"author":{"gitId":"-"},"content":" // Records the recipient to groupable questions mapping used in grouping questions by recipients view"},{"lineNumber":126,"author":{"gitId":"-"},"content":" recipientQuestionMap: Map\u003cstring, Set\u003cnumber\u003e\u003e \u003d new Map\u003cstring, Set\u003cnumber\u003e\u003e();"},{"lineNumber":127,"author":{"gitId":"-"},"content":" ungroupableQuestions: Set\u003cnumber\u003e \u003d new Set();"},{"lineNumber":128,"author":{"gitId":"-"},"content":" ungroupableQuestionsSorted: number[] \u003d [];"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":" feedbackSessionId: string | undefined \u003d \u0027\u0027;"},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" studentId: string | undefined \u003d \u0027\u0027;"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" private backendUrl: string \u003d environment.backendUrl;"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" constructor(private route: ActivatedRoute,"},{"lineNumber":136,"author":{"gitId":"-"},"content":" private statusMessageService: StatusMessageService,"},{"lineNumber":137,"author":{"gitId":"-"},"content":" private timezoneService: TimezoneService,"},{"lineNumber":138,"author":{"gitId":"-"},"content":" private feedbackQuestionsService: FeedbackQuestionsService,"},{"lineNumber":139,"author":{"gitId":"-"},"content":" private feedbackResponsesService: FeedbackResponsesService,"},{"lineNumber":140,"author":{"gitId":"-"},"content":" private feedbackSessionsService: FeedbackSessionsService,"},{"lineNumber":141,"author":{"gitId":"-"},"content":" private studentService: StudentService,"},{"lineNumber":142,"author":{"gitId":"-"},"content":" private instructorService: InstructorService,"},{"lineNumber":143,"author":{"gitId":"-"},"content":" private courseService: CourseService,"},{"lineNumber":144,"author":{"gitId":"-"},"content":" private ngbModal: NgbModal,"},{"lineNumber":145,"author":{"gitId":"-"},"content":" private simpleModalService: SimpleModalService,"},{"lineNumber":146,"author":{"gitId":"-"},"content":" private pageScrollService: PageScrollService,"},{"lineNumber":147,"author":{"gitId":"-"},"content":" private authService: AuthService,"},{"lineNumber":148,"author":{"gitId":"-"},"content":" private navigationService: NavigationService,"},{"lineNumber":149,"author":{"gitId":"-"},"content":" private commentService: FeedbackResponseCommentService,"},{"lineNumber":150,"author":{"gitId":"-"},"content":" private logService: LogService,"},{"lineNumber":151,"author":{"gitId":"-"},"content":" @Inject(DOCUMENT) private document: any) {"},{"lineNumber":152,"author":{"gitId":"-"},"content":" this.timezoneService.getTzVersion(); // import timezone service to load timezone data"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" ngOnInit(): void {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" this.route.data.pipe("},{"lineNumber":157,"author":{"gitId":"-"},"content":" tap((data: any) \u003d\u003e {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" this.intent \u003d data.intent;"},{"lineNumber":159,"author":{"gitId":"-"},"content":" this.entityType \u003d data.intent \u003d\u003d\u003d Intent.INSTRUCTOR_SUBMISSION ? \u0027instructor\u0027 : this.entityType;"},{"lineNumber":160,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":161,"author":{"gitId":"-"},"content":" switchMap(() \u003d\u003e this.route.queryParams),"},{"lineNumber":162,"author":{"gitId":"-"},"content":" ).subscribe((queryParams: any) \u003d\u003e {"},{"lineNumber":163,"author":{"gitId":"-"},"content":" this.courseId \u003d queryParams.courseid;"},{"lineNumber":164,"author":{"gitId":"-"},"content":" this.feedbackSessionName \u003d queryParams.fsname;"},{"lineNumber":165,"author":{"gitId":"-"},"content":" this.regKey \u003d queryParams.key ? queryParams.key : \u0027\u0027;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" this.moderatedPerson \u003d queryParams.moderatedperson ? queryParams.moderatedperson : \u0027\u0027;"},{"lineNumber":167,"author":{"gitId":"-"},"content":" this.previewAsPerson \u003d queryParams.previewas ? queryParams.previewas : \u0027\u0027;"},{"lineNumber":168,"author":{"gitId":"-"},"content":" if (queryParams.entitytype \u003d\u003d\u003d \u0027instructor\u0027) {"},{"lineNumber":169,"author":{"gitId":"-"},"content":" this.entityType \u003d \u0027instructor\u0027;"},{"lineNumber":170,"author":{"gitId":"-"},"content":" this.intent \u003d Intent.INSTRUCTOR_SUBMISSION;"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":" this.moderatedQuestionId \u003d queryParams.moderatedquestionId ? queryParams.moderatedquestionId : \u0027\u0027;"},{"lineNumber":173,"author":{"gitId":"-"},"content":""},{"lineNumber":174,"author":{"gitId":"-"},"content":" if (this.previewAsPerson) {"},{"lineNumber":175,"author":{"gitId":"-"},"content":" // disable submission in the preview mode"},{"lineNumber":176,"author":{"gitId":"-"},"content":" this.isSubmissionFormsDisabled \u003d true;"},{"lineNumber":177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" const nextUrl: string \u003d `${window.location.pathname}${window.location.search.replace(/\u0026/g, \u0027%26\u0027)}`;"},{"lineNumber":180,"author":{"gitId":"-"},"content":" this.authService.getAuthUser(undefined, nextUrl).subscribe({"},{"lineNumber":181,"author":{"gitId":"-"},"content":" next: (auth: AuthInfo) \u003d\u003e {"},{"lineNumber":182,"author":{"gitId":"-"},"content":" const isPreviewOrModeration: boolean \u003d !!(auth.user \u0026\u0026 (this.moderatedPerson || this.previewAsPerson));"},{"lineNumber":183,"author":{"gitId":"-"},"content":" if (auth.user) {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" this.loggedInUser \u003d auth.user.id;"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":" if (this.regKey \u0026\u0026 !isPreviewOrModeration) {"},{"lineNumber":187,"author":{"gitId":"-"},"content":" this.authService.getAuthRegkeyValidity(this.regKey, this.intent).subscribe({"},{"lineNumber":188,"author":{"gitId":"-"},"content":" next: (resp: RegkeyValidity) \u003d\u003e {"},{"lineNumber":189,"author":{"gitId":"-"},"content":" if (resp.isAllowedAccess) {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" if (resp.isUsed) {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" // The logged in user matches the registration key; redirect to the logged in URL"},{"lineNumber":192,"author":{"gitId":"-"},"content":" this.navigationService.navigateByURLWithParamEncoding("},{"lineNumber":193,"author":{"gitId":"-"},"content":" `/web/${this.entityType}/sessions/submission`,"},{"lineNumber":194,"author":{"gitId":"-"},"content":" { courseid: this.courseId, fsname: this.feedbackSessionName });"},{"lineNumber":195,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":196,"author":{"gitId":"-"},"content":" // Valid, unused registration key; load information based on the key"},{"lineNumber":197,"author":{"gitId":"-"},"content":" this.loadCourseInfo();"},{"lineNumber":198,"author":{"gitId":"-"},"content":" this.loadPersonName();"},{"lineNumber":199,"author":{"gitId":"-"},"content":" this.loadFeedbackSession(false, auth);"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }"},{"lineNumber":201,"author":{"gitId":"-"},"content":" } else if (resp.isValid) {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" // At this point, registration key must already be used, otherwise access would be granted"},{"lineNumber":203,"author":{"gitId":"-"},"content":" if (this.loggedInUser) {"},{"lineNumber":204,"author":{"gitId":"-"},"content":" // Registration key belongs to another user who is not the logged in user"},{"lineNumber":205,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":206,"author":{"gitId":"-"},"content":" `You are trying to access TEAMMATES using the Google account ${this.loggedInUser}, which"},{"lineNumber":207,"author":{"gitId":"-"},"content":" is not linked to this TEAMMATES account. If you used a different Google account to"},{"lineNumber":208,"author":{"gitId":"-"},"content":" join/access TEAMMATES before, please use that Google account to access TEAMMATES. If you"},{"lineNumber":209,"author":{"gitId":"-"},"content":" cannot remember which Google account you used before, please email us at"},{"lineNumber":210,"author":{"gitId":"-"},"content":" ${environment.supportEmail} for help.`);"},{"lineNumber":211,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" this.loadFeedbackSession(true, auth);"},{"lineNumber":213,"author":{"gitId":"-"},"content":" }"},{"lineNumber":214,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" // The registration key is invalid"},{"lineNumber":216,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":217,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":" },"},{"lineNumber":220,"author":{"gitId":"-"},"content":" error: () \u003d\u003e {"},{"lineNumber":221,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":222,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":223,"author":{"gitId":"-"},"content":" },"},{"lineNumber":224,"author":{"gitId":"-"},"content":" });"},{"lineNumber":225,"author":{"gitId":"-"},"content":" } else if (this.loggedInUser) {"},{"lineNumber":226,"author":{"gitId":"-"},"content":" // Load information based on logged in user"},{"lineNumber":227,"author":{"gitId":"-"},"content":" // This will also cover moderation/preview cases"},{"lineNumber":228,"author":{"gitId":"-"},"content":" this.loadCourseInfo();"},{"lineNumber":229,"author":{"gitId":"-"},"content":" this.loadPersonName();"},{"lineNumber":230,"author":{"gitId":"-"},"content":" this.loadFeedbackSession(false, auth);"},{"lineNumber":231,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":232,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":233,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":234,"author":{"gitId":"-"},"content":" }"},{"lineNumber":235,"author":{"gitId":"-"},"content":" },"},{"lineNumber":236,"author":{"gitId":"-"},"content":" error: () \u003d\u003e {"},{"lineNumber":237,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":238,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":239,"author":{"gitId":"-"},"content":" },"},{"lineNumber":240,"author":{"gitId":"-"},"content":" });"},{"lineNumber":241,"author":{"gitId":"-"},"content":" });"},{"lineNumber":242,"author":{"gitId":"-"},"content":" }"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" // Solution for checking partial element visibility adapted from"},{"lineNumber":245,"author":{"gitId":"-"},"content":" // https://stackoverflow.com/questions/30943662/check-if-element-is-partially-in-viewport"},{"lineNumber":246,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":247,"author":{"gitId":"-"},"content":" * Checks if a given element is in view."},{"lineNumber":248,"author":{"gitId":"-"},"content":" *"},{"lineNumber":249,"author":{"gitId":"-"},"content":" * @param e element to perform check for"},{"lineNumber":250,"author":{"gitId":"-"},"content":" */"},{"lineNumber":251,"author":{"gitId":"-"},"content":" isInViewport(e: HTMLElement): boolean {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" const rect \u003d e.getBoundingClientRect();"},{"lineNumber":253,"author":{"gitId":"-"},"content":" const windowHeight: number \u003d (window.innerHeight || document.documentElement.clientHeight);"},{"lineNumber":254,"author":{"gitId":"-"},"content":""},{"lineNumber":255,"author":{"gitId":"-"},"content":" return !("},{"lineNumber":256,"author":{"gitId":"-"},"content":" Math.floor(100 - (((rect.top \u003e\u003d 0 ? 0 : rect.top) / +-rect.height) * 100)) \u003c 1"},{"lineNumber":257,"author":{"gitId":"-"},"content":" || Math.floor(100 - ((rect.bottom - windowHeight) / rect.height) * 100) \u003c 1"},{"lineNumber":258,"author":{"gitId":"-"},"content":" );"},{"lineNumber":259,"author":{"gitId":"-"},"content":" }"},{"lineNumber":260,"author":{"gitId":"-"},"content":""},{"lineNumber":261,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":262,"author":{"gitId":"-"},"content":" * Scrolls to the question based on its given question id."},{"lineNumber":263,"author":{"gitId":"-"},"content":" */"},{"lineNumber":264,"author":{"gitId":"-"},"content":" scrollToQuestion(): void {"},{"lineNumber":265,"author":{"gitId":"-"},"content":" const div: HTMLElement | null \u003d document.getElementById(this.moderatedQuestionId);"},{"lineNumber":266,"author":{"gitId":"-"},"content":""},{"lineNumber":267,"author":{"gitId":"-"},"content":" // continue scrolling as long as the element to scroll to is yet to be found or not in view"},{"lineNumber":268,"author":{"gitId":"-"},"content":" if (div \u003d\u003d null || !(this.isInViewport(div))) {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" setTimeout(() \u003d\u003e {"},{"lineNumber":270,"author":{"gitId":"-"},"content":" this.pageScrollService.scroll({"},{"lineNumber":271,"author":{"gitId":"-"},"content":" document: this.document,"},{"lineNumber":272,"author":{"gitId":"-"},"content":" scrollTarget: `#${this.moderatedQuestionId}`,"},{"lineNumber":273,"author":{"gitId":"-"},"content":" scrollOffset: 70,"},{"lineNumber":274,"author":{"gitId":"-"},"content":" });"},{"lineNumber":275,"author":{"gitId":"-"},"content":" this.scrollToQuestion();"},{"lineNumber":276,"author":{"gitId":"-"},"content":" }, 500);"},{"lineNumber":277,"author":{"gitId":"-"},"content":" }"},{"lineNumber":278,"author":{"gitId":"-"},"content":" }"},{"lineNumber":279,"author":{"gitId":"-"},"content":""},{"lineNumber":280,"author":{"gitId":"-"},"content":" ngAfterViewInit(): void {"},{"lineNumber":281,"author":{"gitId":"-"},"content":" if (!this.moderatedQuestionId) {"},{"lineNumber":282,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":283,"author":{"gitId":"-"},"content":" }"},{"lineNumber":284,"author":{"gitId":"-"},"content":" this.scrollToQuestion();"},{"lineNumber":285,"author":{"gitId":"-"},"content":" }"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"-"},"content":" private loadCourseInfo(): void {"},{"lineNumber":288,"author":{"gitId":"-"},"content":" this.isCourseLoading \u003d true;"},{"lineNumber":289,"author":{"gitId":"-"},"content":" let request: Observable\u003cCourse\u003e;"},{"lineNumber":290,"author":{"gitId":"-"},"content":" switch (this.intent) {"},{"lineNumber":291,"author":{"gitId":"-"},"content":" case Intent.STUDENT_SUBMISSION:"},{"lineNumber":292,"author":{"gitId":"-"},"content":" if (this.moderatedPerson || this.previewAsPerson) {"},{"lineNumber":293,"author":{"gitId":"-"},"content":" request \u003d this.courseService.getCourseAsInstructor(this.courseId);"},{"lineNumber":294,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":295,"author":{"gitId":"-"},"content":" request \u003d this.courseService.getCourseAsStudent(this.courseId, this.regKey);"},{"lineNumber":296,"author":{"gitId":"-"},"content":" }"},{"lineNumber":297,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":298,"author":{"gitId":"-"},"content":" case Intent.INSTRUCTOR_SUBMISSION:"},{"lineNumber":299,"author":{"gitId":"-"},"content":" request \u003d this.courseService.getCourseAsInstructor(this.courseId, this.regKey);"},{"lineNumber":300,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":301,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":302,"author":{"gitId":"-"},"content":" this.isCourseLoading \u003d false;"},{"lineNumber":303,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":304,"author":{"gitId":"-"},"content":" }"},{"lineNumber":305,"author":{"gitId":"-"},"content":" request.subscribe({"},{"lineNumber":306,"author":{"gitId":"-"},"content":" next: (resp: Course) \u003d\u003e {"},{"lineNumber":307,"author":{"gitId":"-"},"content":" this.courseName \u003d resp.courseName;"},{"lineNumber":308,"author":{"gitId":"-"},"content":" this.courseInstitute \u003d resp.institute;"},{"lineNumber":309,"author":{"gitId":"-"},"content":" this.isCourseLoading \u003d false;"},{"lineNumber":310,"author":{"gitId":"-"},"content":" },"},{"lineNumber":311,"author":{"gitId":"-"},"content":" error: () \u003d\u003e {"},{"lineNumber":312,"author":{"gitId":"-"},"content":" this.isCourseLoading \u003d false;"},{"lineNumber":313,"author":{"gitId":"-"},"content":" },"},{"lineNumber":314,"author":{"gitId":"-"},"content":" });"},{"lineNumber":315,"author":{"gitId":"-"},"content":" }"},{"lineNumber":316,"author":{"gitId":"-"},"content":""},{"lineNumber":317,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":318,"author":{"gitId":"-"},"content":" * Loads the name of the person involved in the submission."},{"lineNumber":319,"author":{"gitId":"-"},"content":" */"},{"lineNumber":320,"author":{"gitId":"-"},"content":" loadPersonName(): void {"},{"lineNumber":321,"author":{"gitId":"-"},"content":" switch (this.intent) {"},{"lineNumber":322,"author":{"gitId":"-"},"content":" case Intent.STUDENT_SUBMISSION:"},{"lineNumber":323,"author":{"gitId":"-"},"content":" this.studentService.getStudent("},{"lineNumber":324,"author":{"gitId":"-"},"content":" this.courseId,"},{"lineNumber":325,"author":{"gitId":"-"},"content":" this.moderatedPerson || this.previewAsPerson,"},{"lineNumber":326,"author":{"gitId":"-"},"content":" this.regKey,"},{"lineNumber":327,"author":{"gitId":"-"},"content":" ).subscribe((student: Student) \u003d\u003e {"},{"lineNumber":328,"author":{"gitId":"dishenggg"},"content":" this.studentId \u003d student.studentId;"},{"lineNumber":329,"author":{"gitId":"-"},"content":" this.personName \u003d student.name;"},{"lineNumber":330,"author":{"gitId":"-"},"content":" this.personEmail \u003d student.email;"},{"lineNumber":331,"author":{"gitId":"dishenggg"},"content":" this.logStudentAccess();"},{"lineNumber":332,"author":{"gitId":"-"},"content":" });"},{"lineNumber":333,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":334,"author":{"gitId":"-"},"content":" case Intent.INSTRUCTOR_SUBMISSION:"},{"lineNumber":335,"author":{"gitId":"-"},"content":" this.instructorService.getInstructor({"},{"lineNumber":336,"author":{"gitId":"-"},"content":" courseId: this.courseId,"},{"lineNumber":337,"author":{"gitId":"-"},"content":" feedbackSessionName: this.feedbackSessionName,"},{"lineNumber":338,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":339,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":340,"author":{"gitId":"-"},"content":" moderatedPerson: this.moderatedPerson,"},{"lineNumber":341,"author":{"gitId":"-"},"content":" previewAs: this.previewAsPerson,"},{"lineNumber":342,"author":{"gitId":"-"},"content":" }).subscribe((instructor: Instructor) \u003d\u003e {"},{"lineNumber":343,"author":{"gitId":"-"},"content":" this.personName \u003d instructor.name;"},{"lineNumber":344,"author":{"gitId":"-"},"content":" this.personEmail \u003d instructor.email;"},{"lineNumber":345,"author":{"gitId":"-"},"content":" });"},{"lineNumber":346,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":347,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":348,"author":{"gitId":"-"},"content":" }"},{"lineNumber":349,"author":{"gitId":"-"},"content":" }"},{"lineNumber":350,"author":{"gitId":"-"},"content":""},{"lineNumber":351,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":352,"author":{"gitId":"-"},"content":" * Redirects to join course link for unregistered student/instructor."},{"lineNumber":353,"author":{"gitId":"-"},"content":" */"},{"lineNumber":354,"author":{"gitId":"-"},"content":" joinCourseForUnregisteredEntity(): void {"},{"lineNumber":355,"author":{"gitId":"-"},"content":" this.navigationService.navigateByURL(\u0027/web/join\u0027, { entitytype: this.entityType, key: this.regKey });"},{"lineNumber":356,"author":{"gitId":"-"},"content":" }"},{"lineNumber":357,"author":{"gitId":"-"},"content":""},{"lineNumber":358,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":359,"author":{"gitId":"-"},"content":" * Loads the feedback session information."},{"lineNumber":360,"author":{"gitId":"-"},"content":" */"},{"lineNumber":361,"author":{"gitId":"-"},"content":" loadFeedbackSession(loginRequired: boolean, auth: AuthInfo): void {"},{"lineNumber":362,"author":{"gitId":"-"},"content":" this.isFeedbackSessionLoading \u003d true;"},{"lineNumber":363,"author":{"gitId":"-"},"content":" const TIME_FORMAT: string \u003d \u0027ddd, DD MMM, YYYY, hh:mm A zz\u0027;"},{"lineNumber":364,"author":{"gitId":"-"},"content":" this.feedbackSessionsService.getFeedbackSession({"},{"lineNumber":365,"author":{"gitId":"-"},"content":" courseId: this.courseId,"},{"lineNumber":366,"author":{"gitId":"-"},"content":" feedbackSessionName: this.feedbackSessionName,"},{"lineNumber":367,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":368,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":369,"author":{"gitId":"-"},"content":" moderatedPerson: this.moderatedPerson,"},{"lineNumber":370,"author":{"gitId":"-"},"content":" previewAs: this.previewAsPerson,"},{"lineNumber":371,"author":{"gitId":"-"},"content":" }).pipe(finalize(() \u003d\u003e {"},{"lineNumber":372,"author":{"gitId":"-"},"content":" this.isFeedbackSessionLoading \u003d false;"},{"lineNumber":373,"author":{"gitId":"-"},"content":" }))"},{"lineNumber":374,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":375,"author":{"gitId":"-"},"content":" next: (feedbackSession: FeedbackSession) \u003d\u003e {"},{"lineNumber":376,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionId \u003d feedbackSession.feedbackSessionId;"},{"lineNumber":377,"author":{"gitId":"-"},"content":" this.feedbackSessionInstructions \u003d feedbackSession.instructions;"},{"lineNumber":378,"author":{"gitId":"-"},"content":" this.formattedSessionOpeningTime \u003d this.timezoneService"},{"lineNumber":379,"author":{"gitId":"-"},"content":" .formatToString(feedbackSession.submissionStartTimestamp, feedbackSession.timeZone, TIME_FORMAT);"},{"lineNumber":380,"author":{"gitId":"-"},"content":""},{"lineNumber":381,"author":{"gitId":"-"},"content":" this.formattedSessionClosingTime \u003d this.getformattedSessionClosingTime(feedbackSession, TIME_FORMAT);"},{"lineNumber":382,"author":{"gitId":"-"},"content":""},{"lineNumber":383,"author":{"gitId":"-"},"content":" this.feedbackSessionSubmissionStatus \u003d feedbackSession.submissionStatus;"},{"lineNumber":384,"author":{"gitId":"-"},"content":" this.feedbackSessionTimezone \u003d feedbackSession.timeZone;"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"dishenggg"},"content":" this.logStudentAccess();"},{"lineNumber":387,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":388,"author":{"gitId":"-"},"content":" // don\u0027t show alert modal in moderation"},{"lineNumber":389,"author":{"gitId":"-"},"content":" if (!this.moderatedPerson) {"},{"lineNumber":390,"author":{"gitId":"-"},"content":" let modalContent: string;"},{"lineNumber":391,"author":{"gitId":"-"},"content":" switch (feedbackSession.submissionStatus) {"},{"lineNumber":392,"author":{"gitId":"-"},"content":" case FeedbackSessionSubmissionStatus.VISIBLE_NOT_OPEN:"},{"lineNumber":393,"author":{"gitId":"-"},"content":" this.isSubmissionFormsDisabled \u003d true;"},{"lineNumber":394,"author":{"gitId":"-"},"content":" modalContent \u003d `\u003cp\u003e\u003cstrong\u003eThe feedback session is currently not open for submissions.\u003c/strong\u003e\u003c/p\u003e"},{"lineNumber":395,"author":{"gitId":"-"},"content":" \u003cp\u003eYou can view the questions and any submitted responses"},{"lineNumber":396,"author":{"gitId":"-"},"content":" for this feedback session but cannot submit new responses.\u003c/p\u003e`;"},{"lineNumber":397,"author":{"gitId":"-"},"content":" this.simpleModalService.openInformationModal("},{"lineNumber":398,"author":{"gitId":"-"},"content":" \u0027Feedback Session Not Open\u0027, SimpleModalType.WARNING, modalContent);"},{"lineNumber":399,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":400,"author":{"gitId":"-"},"content":" case FeedbackSessionSubmissionStatus.OPEN:"},{"lineNumber":401,"author":{"gitId":"-"},"content":" if (this.isFeedbackEndingLessThanFifteenMinutes(feedbackSession)) {"},{"lineNumber":402,"author":{"gitId":"-"},"content":" modalContent \u003d \u0027Warning: you have less than 15 minutes before the submission deadline expires!\u0027;"},{"lineNumber":403,"author":{"gitId":"-"},"content":" this.simpleModalService.openInformationModal("},{"lineNumber":404,"author":{"gitId":"-"},"content":" \u0027Feedback Session Will Be Closing Soon!\u0027, SimpleModalType.WARNING, modalContent);"},{"lineNumber":405,"author":{"gitId":"-"},"content":" }"},{"lineNumber":406,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":407,"author":{"gitId":"-"},"content":" case FeedbackSessionSubmissionStatus.CLOSED:"},{"lineNumber":408,"author":{"gitId":"-"},"content":" this.isSubmissionFormsDisabled \u003d true;"},{"lineNumber":409,"author":{"gitId":"-"},"content":" modalContent \u003d `\u003cp\u003e\u003cstrong\u003eFeedback Session is Closed\u003c/strong\u003e\u003c/p\u003e"},{"lineNumber":410,"author":{"gitId":"-"},"content":" \u003cp\u003eYou can view the questions and any submitted responses"},{"lineNumber":411,"author":{"gitId":"-"},"content":" for this feedback session but cannot submit new responses.\u003c/p\u003e`;"},{"lineNumber":412,"author":{"gitId":"-"},"content":" this.simpleModalService.openInformationModal("},{"lineNumber":413,"author":{"gitId":"-"},"content":" \u0027Feedback Session Closed\u0027, SimpleModalType.WARNING, modalContent);"},{"lineNumber":414,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":415,"author":{"gitId":"-"},"content":" case FeedbackSessionSubmissionStatus.GRACE_PERIOD:"},{"lineNumber":416,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":417,"author":{"gitId":"-"},"content":" }"},{"lineNumber":418,"author":{"gitId":"-"},"content":" }"},{"lineNumber":419,"author":{"gitId":"-"},"content":""},{"lineNumber":420,"author":{"gitId":"-"},"content":" this.loadFeedbackQuestions();"},{"lineNumber":421,"author":{"gitId":"-"},"content":""},{"lineNumber":422,"author":{"gitId":"-"},"content":" // Display note on submission on mobile device"},{"lineNumber":423,"author":{"gitId":"-"},"content":" const mobileDeviceWidth: number \u003d 768;"},{"lineNumber":424,"author":{"gitId":"-"},"content":" if (this.feedbackSessionSubmissionStatus \u003d\u003d\u003d FeedbackSessionSubmissionStatus.OPEN"},{"lineNumber":425,"author":{"gitId":"-"},"content":" \u0026\u0026 window.innerWidth \u003c mobileDeviceWidth) {"},{"lineNumber":426,"author":{"gitId":"-"},"content":" const modalContent: string \u003d `Note that you can use the Submit button to save responses already entered,"},{"lineNumber":427,"author":{"gitId":"-"},"content":" and continue to answer remaining questions after that."},{"lineNumber":428,"author":{"gitId":"-"},"content":" You may also edit your submission any number of times before the closing time of this session.`;"},{"lineNumber":429,"author":{"gitId":"-"},"content":" this.simpleModalService.openInformationModal("},{"lineNumber":430,"author":{"gitId":"-"},"content":" \u0027Note On Submission\u0027, SimpleModalType.INFO, modalContent);"},{"lineNumber":431,"author":{"gitId":"-"},"content":" }"},{"lineNumber":432,"author":{"gitId":"-"},"content":" },"},{"lineNumber":433,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":434,"author":{"gitId":"-"},"content":" if (resp.status \u003d\u003d\u003d 404) {"},{"lineNumber":435,"author":{"gitId":"-"},"content":" const message \u003d \u0027The session does not exist \u0027"},{"lineNumber":436,"author":{"gitId":"-"},"content":" + \u0027(most likely deleted by an instructor after the submission link was sent).\u0027;"},{"lineNumber":437,"author":{"gitId":"-"},"content":" this.simpleModalService.openInformationModal(\u0027Feedback Session Does Not Exist!\u0027, SimpleModalType.DANGER,"},{"lineNumber":438,"author":{"gitId":"-"},"content":" message,"},{"lineNumber":439,"author":{"gitId":"-"},"content":" {"},{"lineNumber":440,"author":{"gitId":"-"},"content":" onClosed: () \u003d\u003e this.navigationService.navigateByURL("},{"lineNumber":441,"author":{"gitId":"-"},"content":" this.loggedInUser ? `/web/${this.entityType}/home` : \u0027/web/front/home\u0027),"},{"lineNumber":442,"author":{"gitId":"-"},"content":" },"},{"lineNumber":443,"author":{"gitId":"-"},"content":" { backdrop: \u0027static\u0027 });"},{"lineNumber":444,"author":{"gitId":"-"},"content":" } else if (resp.status \u003d\u003d\u003d 403) {"},{"lineNumber":445,"author":{"gitId":"-"},"content":" if (loginRequired \u0026\u0026 !auth.user) {"},{"lineNumber":446,"author":{"gitId":"-"},"content":" // There is no logged in user for a valid, used registration key, redirect to login page"},{"lineNumber":447,"author":{"gitId":"-"},"content":" if (this.entityType \u003d\u003d\u003d \u0027student\u0027) {"},{"lineNumber":448,"author":{"gitId":"-"},"content":" window.location.href \u003d `${this.backendUrl}${auth.studentLoginUrl}`;"},{"lineNumber":449,"author":{"gitId":"-"},"content":" } else if (this.entityType \u003d\u003d\u003d \u0027instructor\u0027) {"},{"lineNumber":450,"author":{"gitId":"-"},"content":" window.location.href \u003d `${this.backendUrl}${auth.instructorLoginUrl}`;"},{"lineNumber":451,"author":{"gitId":"-"},"content":" }"},{"lineNumber":452,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":453,"author":{"gitId":"-"},"content":" this.simpleModalService.openInformationModal(\u0027Not Authorised To Access!\u0027, SimpleModalType.DANGER,"},{"lineNumber":454,"author":{"gitId":"-"},"content":" resp.error.message,"},{"lineNumber":455,"author":{"gitId":"-"},"content":" {"},{"lineNumber":456,"author":{"gitId":"-"},"content":" onClosed: () \u003d\u003e this.navigationService.navigateByURL("},{"lineNumber":457,"author":{"gitId":"-"},"content":" this.loggedInUser ? `/web/${this.entityType}/home` : \u0027/web/front/home\u0027),"},{"lineNumber":458,"author":{"gitId":"-"},"content":" },"},{"lineNumber":459,"author":{"gitId":"-"},"content":" { backdrop: \u0027static\u0027 });"},{"lineNumber":460,"author":{"gitId":"-"},"content":" }"},{"lineNumber":461,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":462,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage("},{"lineNumber":463,"author":{"gitId":"-"},"content":" `/web/${this.entityType}/home`, resp.error.message);"},{"lineNumber":464,"author":{"gitId":"-"},"content":" }"},{"lineNumber":465,"author":{"gitId":"-"},"content":" },"},{"lineNumber":466,"author":{"gitId":"-"},"content":" });"},{"lineNumber":467,"author":{"gitId":"-"},"content":" }"},{"lineNumber":468,"author":{"gitId":"-"},"content":""},{"lineNumber":469,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":470,"author":{"gitId":"-"},"content":" * Loads feedback questions to submit."},{"lineNumber":471,"author":{"gitId":"-"},"content":" */"},{"lineNumber":472,"author":{"gitId":"-"},"content":" loadFeedbackQuestions(): void {"},{"lineNumber":473,"author":{"gitId":"-"},"content":" this.isFeedbackSessionQuestionsLoading \u003d true;"},{"lineNumber":474,"author":{"gitId":"-"},"content":" this.questionSubmissionForms \u003d [];"},{"lineNumber":475,"author":{"gitId":"-"},"content":" this.feedbackQuestionsService.getFeedbackQuestions({"},{"lineNumber":476,"author":{"gitId":"-"},"content":" courseId: this.courseId,"},{"lineNumber":477,"author":{"gitId":"-"},"content":" feedbackSessionName: this.feedbackSessionName,"},{"lineNumber":478,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":479,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":480,"author":{"gitId":"-"},"content":" moderatedPerson: this.moderatedPerson,"},{"lineNumber":481,"author":{"gitId":"-"},"content":" previewAs: this.previewAsPerson,"},{"lineNumber":482,"author":{"gitId":"-"},"content":" }).pipe(finalize(() \u003d\u003e {"},{"lineNumber":483,"author":{"gitId":"-"},"content":" this.isFeedbackSessionQuestionsLoading \u003d false;"},{"lineNumber":484,"author":{"gitId":"-"},"content":" }))"},{"lineNumber":485,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":486,"author":{"gitId":"-"},"content":" next: (response: FeedbackQuestionsResponse) \u003d\u003e {"},{"lineNumber":487,"author":{"gitId":"-"},"content":" response.questions.forEach((feedbackQuestion: FeedbackQuestion) \u003d\u003e {"},{"lineNumber":488,"author":{"gitId":"-"},"content":" const model: QuestionSubmissionFormModel \u003d {"},{"lineNumber":489,"author":{"gitId":"-"},"content":" isLoading: false,"},{"lineNumber":490,"author":{"gitId":"-"},"content":" isLoaded: false,"},{"lineNumber":491,"author":{"gitId":"-"},"content":" isTabExpanded: true,"},{"lineNumber":492,"author":{"gitId":"-"},"content":" feedbackQuestionId: feedbackQuestion.feedbackQuestionId,"},{"lineNumber":493,"author":{"gitId":"-"},"content":""},{"lineNumber":494,"author":{"gitId":"-"},"content":" questionNumber: feedbackQuestion.questionNumber,"},{"lineNumber":495,"author":{"gitId":"-"},"content":" questionBrief: feedbackQuestion.questionBrief,"},{"lineNumber":496,"author":{"gitId":"-"},"content":" questionDescription: feedbackQuestion.questionDescription,"},{"lineNumber":497,"author":{"gitId":"-"},"content":""},{"lineNumber":498,"author":{"gitId":"-"},"content":" giverType: feedbackQuestion.giverType,"},{"lineNumber":499,"author":{"gitId":"-"},"content":" recipientType: feedbackQuestion.recipientType,"},{"lineNumber":500,"author":{"gitId":"-"},"content":" recipientList: [],"},{"lineNumber":501,"author":{"gitId":"-"},"content":" recipientSubmissionForms: [],"},{"lineNumber":502,"author":{"gitId":"-"},"content":""},{"lineNumber":503,"author":{"gitId":"-"},"content":" questionType: feedbackQuestion.questionType,"},{"lineNumber":504,"author":{"gitId":"-"},"content":" questionDetails: feedbackQuestion.questionDetails,"},{"lineNumber":505,"author":{"gitId":"-"},"content":""},{"lineNumber":506,"author":{"gitId":"-"},"content":" numberOfEntitiesToGiveFeedbackToSetting: feedbackQuestion.numberOfEntitiesToGiveFeedbackToSetting,"},{"lineNumber":507,"author":{"gitId":"-"},"content":" customNumberOfEntitiesToGiveFeedbackTo: feedbackQuestion.customNumberOfEntitiesToGiveFeedbackTo"},{"lineNumber":508,"author":{"gitId":"-"},"content":" ? feedbackQuestion.customNumberOfEntitiesToGiveFeedbackTo : 0,"},{"lineNumber":509,"author":{"gitId":"-"},"content":""},{"lineNumber":510,"author":{"gitId":"-"},"content":" showGiverNameTo: feedbackQuestion.showGiverNameTo,"},{"lineNumber":511,"author":{"gitId":"-"},"content":" showRecipientNameTo: feedbackQuestion.showRecipientNameTo,"},{"lineNumber":512,"author":{"gitId":"-"},"content":" showResponsesTo: feedbackQuestion.showResponsesTo,"},{"lineNumber":513,"author":{"gitId":"-"},"content":""},{"lineNumber":514,"author":{"gitId":"-"},"content":" hasResponseChangedForRecipients: new Map\u003cstring, boolean\u003e(),"},{"lineNumber":515,"author":{"gitId":"-"},"content":" isTabExpandedForRecipients: new Map\u003cstring, boolean\u003e(),"},{"lineNumber":516,"author":{"gitId":"-"},"content":" };"},{"lineNumber":517,"author":{"gitId":"-"},"content":" this.questionSubmissionForms.push(model);"},{"lineNumber":518,"author":{"gitId":"-"},"content":" });"},{"lineNumber":519,"author":{"gitId":"-"},"content":""},{"lineNumber":520,"author":{"gitId":"-"},"content":" this.isQuestionCountOne \u003d this.questionSubmissionForms.length \u003d\u003d\u003d 1;"},{"lineNumber":521,"author":{"gitId":"-"},"content":" },"},{"lineNumber":522,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":523,"author":{"gitId":"-"},"content":" this.handleError(resp);"},{"lineNumber":524,"author":{"gitId":"-"},"content":" },"},{"lineNumber":525,"author":{"gitId":"-"},"content":" });"},{"lineNumber":526,"author":{"gitId":"-"},"content":" }"},{"lineNumber":527,"author":{"gitId":"-"},"content":""},{"lineNumber":528,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":529,"author":{"gitId":"-"},"content":" * Tracks the question submission form by feedback question id."},{"lineNumber":530,"author":{"gitId":"-"},"content":" *"},{"lineNumber":531,"author":{"gitId":"-"},"content":" * @see https://angular.io/api/common/NgForOf#properties"},{"lineNumber":532,"author":{"gitId":"-"},"content":" */"},{"lineNumber":533,"author":{"gitId":"-"},"content":" trackQuestionSubmissionFormByFn(_: any, item: QuestionSubmissionFormModel): any {"},{"lineNumber":534,"author":{"gitId":"-"},"content":" return item.feedbackQuestionId;"},{"lineNumber":535,"author":{"gitId":"-"},"content":" }"},{"lineNumber":536,"author":{"gitId":"-"},"content":""},{"lineNumber":537,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":538,"author":{"gitId":"-"},"content":" * Loads the feedback question recipients for the question."},{"lineNumber":539,"author":{"gitId":"-"},"content":" */"},{"lineNumber":540,"author":{"gitId":"-"},"content":" loadFeedbackQuestionRecipientsForQuestion(model: QuestionSubmissionFormModel): void {"},{"lineNumber":541,"author":{"gitId":"-"},"content":" this.feedbackQuestionsService.loadFeedbackQuestionRecipients({"},{"lineNumber":542,"author":{"gitId":"-"},"content":" questionId: model.feedbackQuestionId,"},{"lineNumber":543,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":544,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":545,"author":{"gitId":"-"},"content":" moderatedPerson: this.moderatedPerson,"},{"lineNumber":546,"author":{"gitId":"-"},"content":" previewAs: this.previewAsPerson,"},{"lineNumber":547,"author":{"gitId":"-"},"content":" }).subscribe({"},{"lineNumber":548,"author":{"gitId":"-"},"content":" next: (response: FeedbackQuestionRecipients) \u003d\u003e {"},{"lineNumber":549,"author":{"gitId":"-"},"content":" response.recipients.forEach((recipient: FeedbackQuestionRecipient) \u003d\u003e {"},{"lineNumber":550,"author":{"gitId":"-"},"content":" model.recipientList.push({"},{"lineNumber":551,"author":{"gitId":"-"},"content":" recipientIdentifier: recipient.identifier,"},{"lineNumber":552,"author":{"gitId":"-"},"content":" recipientName: recipient.name,"},{"lineNumber":553,"author":{"gitId":"-"},"content":" recipientSection: recipient.section,"},{"lineNumber":554,"author":{"gitId":"-"},"content":" recipientTeam: recipient.team,"},{"lineNumber":555,"author":{"gitId":"-"},"content":" });"},{"lineNumber":556,"author":{"gitId":"-"},"content":" });"},{"lineNumber":557,"author":{"gitId":"-"},"content":""},{"lineNumber":558,"author":{"gitId":"-"},"content":" if (!this.hasLoadedAllRecipients) {"},{"lineNumber":559,"author":{"gitId":"-"},"content":" // Keep track of the recipient to questions mapping and the ungroupable questions even before"},{"lineNumber":560,"author":{"gitId":"-"},"content":" // changing to grouping questions by recipients view"},{"lineNumber":561,"author":{"gitId":"-"},"content":" if (this.getQuestionSubmissionFormModeInDefaultView(model) \u003d\u003d\u003d QuestionSubmissionFormMode.FIXED_RECIPIENT"},{"lineNumber":562,"author":{"gitId":"-"},"content":" \u0026\u0026 model.questionType !\u003d\u003d FeedbackQuestionType.RANK_RECIPIENTS"},{"lineNumber":563,"author":{"gitId":"-"},"content":" \u0026\u0026 model.questionType !\u003d\u003d FeedbackQuestionType.CONSTSUM_RECIPIENTS"},{"lineNumber":564,"author":{"gitId":"-"},"content":" \u0026\u0026 model.questionType !\u003d\u003d FeedbackQuestionType.CONTRIB) {"},{"lineNumber":565,"author":{"gitId":"-"},"content":" model.recipientList.forEach((recipient: FeedbackResponseRecipient) \u003d\u003e {"},{"lineNumber":566,"author":{"gitId":"-"},"content":" this.addQuestionForRecipient(recipient.recipientIdentifier, model.questionNumber);"},{"lineNumber":567,"author":{"gitId":"-"},"content":" });"},{"lineNumber":568,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":569,"author":{"gitId":"-"},"content":" this.ungroupableQuestions.add(model.questionNumber);"},{"lineNumber":570,"author":{"gitId":"-"},"content":" }"},{"lineNumber":571,"author":{"gitId":"-"},"content":" }"},{"lineNumber":572,"author":{"gitId":"-"},"content":""},{"lineNumber":573,"author":{"gitId":"-"},"content":" if (this.previewAsPerson) {"},{"lineNumber":574,"author":{"gitId":"-"},"content":" // don\u0027t load responses in preview mode"},{"lineNumber":575,"author":{"gitId":"-"},"content":" // generate a list of empty response box"},{"lineNumber":576,"author":{"gitId":"-"},"content":" const formMode: QuestionSubmissionFormMode \u003d this.getQuestionSubmissionFormModeInDefaultView(model);"},{"lineNumber":577,"author":{"gitId":"-"},"content":" model.recipientList.forEach((recipient: FeedbackResponseRecipient) \u003d\u003e {"},{"lineNumber":578,"author":{"gitId":"-"},"content":" if (formMode \u003d\u003d\u003d QuestionSubmissionFormMode.FLEXIBLE_RECIPIENT"},{"lineNumber":579,"author":{"gitId":"-"},"content":" \u0026\u0026 model.recipientSubmissionForms.length \u003e\u003d model.customNumberOfEntitiesToGiveFeedbackTo) {"},{"lineNumber":580,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":581,"author":{"gitId":"-"},"content":" }"},{"lineNumber":582,"author":{"gitId":"-"},"content":""},{"lineNumber":583,"author":{"gitId":"-"},"content":" let recipientIdentifier: string \u003d \u0027\u0027;"},{"lineNumber":584,"author":{"gitId":"-"},"content":" if (formMode !\u003d\u003d QuestionSubmissionFormMode.FLEXIBLE_RECIPIENT) {"},{"lineNumber":585,"author":{"gitId":"-"},"content":" recipientIdentifier \u003d recipient.recipientIdentifier;"},{"lineNumber":586,"author":{"gitId":"-"},"content":" }"},{"lineNumber":587,"author":{"gitId":"-"},"content":""},{"lineNumber":588,"author":{"gitId":"-"},"content":" model.recipientSubmissionForms.push({"},{"lineNumber":589,"author":{"gitId":"-"},"content":" recipientIdentifier,"},{"lineNumber":590,"author":{"gitId":"-"},"content":" responseDetails: this.feedbackResponsesService.getDefaultFeedbackResponseDetails(model.questionType),"},{"lineNumber":591,"author":{"gitId":"-"},"content":" responseId: \u0027\u0027,"},{"lineNumber":592,"author":{"gitId":"-"},"content":" isValid: true,"},{"lineNumber":593,"author":{"gitId":"-"},"content":" });"},{"lineNumber":594,"author":{"gitId":"-"},"content":" });"},{"lineNumber":595,"author":{"gitId":"-"},"content":" model.isLoading \u003d false;"},{"lineNumber":596,"author":{"gitId":"-"},"content":" model.isLoaded \u003d true;"},{"lineNumber":597,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":598,"author":{"gitId":"-"},"content":" this.loadFeedbackResponses(model);"},{"lineNumber":599,"author":{"gitId":"-"},"content":" }"},{"lineNumber":600,"author":{"gitId":"-"},"content":" },"},{"lineNumber":601,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e this.statusMessageService.showErrorToast(resp.error.message),"},{"lineNumber":602,"author":{"gitId":"-"},"content":" });"},{"lineNumber":603,"author":{"gitId":"-"},"content":" }"},{"lineNumber":604,"author":{"gitId":"-"},"content":""},{"lineNumber":605,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":606,"author":{"gitId":"-"},"content":" * Gets the form mode of the question submission form."},{"lineNumber":607,"author":{"gitId":"-"},"content":" */"},{"lineNumber":608,"author":{"gitId":"-"},"content":" getQuestionSubmissionFormMode(model: QuestionSubmissionFormModel, recipientListLength: number):"},{"lineNumber":609,"author":{"gitId":"-"},"content":" QuestionSubmissionFormMode {"},{"lineNumber":610,"author":{"gitId":"-"},"content":" const isNumberOfEntitiesToGiveFeedbackToSettingLimited: boolean \u003d"},{"lineNumber":611,"author":{"gitId":"-"},"content":" (model.recipientType \u003d\u003d\u003d FeedbackParticipantType.STUDENTS"},{"lineNumber":612,"author":{"gitId":"-"},"content":" || model.recipientType \u003d\u003d\u003d FeedbackParticipantType.STUDENTS_EXCLUDING_SELF"},{"lineNumber":613,"author":{"gitId":"-"},"content":" || model.recipientType \u003d\u003d\u003d FeedbackParticipantType.STUDENTS_IN_SAME_SECTION"},{"lineNumber":614,"author":{"gitId":"-"},"content":" || model.recipientType \u003d\u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":615,"author":{"gitId":"-"},"content":" || model.recipientType \u003d\u003d\u003d FeedbackParticipantType.TEAMS_EXCLUDING_SELF"},{"lineNumber":616,"author":{"gitId":"-"},"content":" || model.recipientType \u003d\u003d\u003d FeedbackParticipantType.TEAMS_IN_SAME_SECTION"},{"lineNumber":617,"author":{"gitId":"-"},"content":" || model.recipientType \u003d\u003d\u003d FeedbackParticipantType.INSTRUCTORS)"},{"lineNumber":618,"author":{"gitId":"-"},"content":" \u0026\u0026 model.numberOfEntitiesToGiveFeedbackToSetting \u003d\u003d\u003d NumberOfEntitiesToGiveFeedbackToSetting.CUSTOM"},{"lineNumber":619,"author":{"gitId":"-"},"content":" \u0026\u0026 recipientListLength \u003e model.customNumberOfEntitiesToGiveFeedbackTo;"},{"lineNumber":620,"author":{"gitId":"-"},"content":""},{"lineNumber":621,"author":{"gitId":"-"},"content":" return isNumberOfEntitiesToGiveFeedbackToSettingLimited"},{"lineNumber":622,"author":{"gitId":"-"},"content":" ? QuestionSubmissionFormMode.FLEXIBLE_RECIPIENT : QuestionSubmissionFormMode.FIXED_RECIPIENT;"},{"lineNumber":623,"author":{"gitId":"-"},"content":" }"},{"lineNumber":624,"author":{"gitId":"-"},"content":""},{"lineNumber":625,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":626,"author":{"gitId":"-"},"content":" * Gets the form mode of the question submission form in {@code DEFAULT} view."},{"lineNumber":627,"author":{"gitId":"-"},"content":" */"},{"lineNumber":628,"author":{"gitId":"-"},"content":" getQuestionSubmissionFormModeInDefaultView(model: QuestionSubmissionFormModel): QuestionSubmissionFormMode {"},{"lineNumber":629,"author":{"gitId":"-"},"content":" return this.getQuestionSubmissionFormMode(model, model.recipientList.length);"},{"lineNumber":630,"author":{"gitId":"-"},"content":" }"},{"lineNumber":631,"author":{"gitId":"-"},"content":""},{"lineNumber":632,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":633,"author":{"gitId":"-"},"content":" * Loads the responses of the feedback question to {@recipientSubmissionForms} in the model."},{"lineNumber":634,"author":{"gitId":"-"},"content":" */"},{"lineNumber":635,"author":{"gitId":"-"},"content":" loadFeedbackResponses(model: QuestionSubmissionFormModel): void {"},{"lineNumber":636,"author":{"gitId":"-"},"content":" this.feedbackResponsesService.getFeedbackResponse({"},{"lineNumber":637,"author":{"gitId":"-"},"content":" questionId: model.feedbackQuestionId,"},{"lineNumber":638,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":639,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":640,"author":{"gitId":"-"},"content":" moderatedPerson: this.moderatedPerson,"},{"lineNumber":641,"author":{"gitId":"-"},"content":" }).pipe(finalize(() \u003d\u003e {"},{"lineNumber":642,"author":{"gitId":"-"},"content":" model.isLoading \u003d false;"},{"lineNumber":643,"author":{"gitId":"-"},"content":" model.isLoaded \u003d true;"},{"lineNumber":644,"author":{"gitId":"-"},"content":" }))"},{"lineNumber":645,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":646,"author":{"gitId":"-"},"content":" next: (existingResponses: FeedbackResponsesResponse) \u003d\u003e {"},{"lineNumber":647,"author":{"gitId":"-"},"content":" if (this.getQuestionSubmissionFormModeInDefaultView(model) \u003d\u003d\u003d QuestionSubmissionFormMode.FIXED_RECIPIENT) {"},{"lineNumber":648,"author":{"gitId":"-"},"content":" // need to generate a full list of submission forms"},{"lineNumber":649,"author":{"gitId":"-"},"content":" model.recipientList.forEach((recipient: FeedbackResponseRecipient) \u003d\u003e {"},{"lineNumber":650,"author":{"gitId":"-"},"content":" const matchedExistingResponse: FeedbackResponse | undefined \u003d"},{"lineNumber":651,"author":{"gitId":"-"},"content":" existingResponses.responses.find("},{"lineNumber":652,"author":{"gitId":"-"},"content":" (response: FeedbackResponse) \u003d\u003e response.recipientIdentifier \u003d\u003d\u003d recipient.recipientIdentifier);"},{"lineNumber":653,"author":{"gitId":"-"},"content":" const submissionForm: FeedbackResponseRecipientSubmissionFormModel \u003d {"},{"lineNumber":654,"author":{"gitId":"-"},"content":" recipientIdentifier: recipient.recipientIdentifier,"},{"lineNumber":655,"author":{"gitId":"-"},"content":" responseDetails: matchedExistingResponse"},{"lineNumber":656,"author":{"gitId":"-"},"content":" ? matchedExistingResponse.responseDetails"},{"lineNumber":657,"author":{"gitId":"-"},"content":" : this.feedbackResponsesService.getDefaultFeedbackResponseDetails(model.questionType),"},{"lineNumber":658,"author":{"gitId":"-"},"content":" responseId: matchedExistingResponse ? matchedExistingResponse.feedbackResponseId : \u0027\u0027,"},{"lineNumber":659,"author":{"gitId":"-"},"content":" isValid: true,"},{"lineNumber":660,"author":{"gitId":"-"},"content":" };"},{"lineNumber":661,"author":{"gitId":"-"},"content":" if (matchedExistingResponse \u0026\u0026 matchedExistingResponse.giverComment) {"},{"lineNumber":662,"author":{"gitId":"-"},"content":" submissionForm.commentByGiver \u003d this.getCommentModel("},{"lineNumber":663,"author":{"gitId":"-"},"content":" matchedExistingResponse.giverComment, recipient.recipientIdentifier);"},{"lineNumber":664,"author":{"gitId":"-"},"content":" }"},{"lineNumber":665,"author":{"gitId":"-"},"content":" model.recipientSubmissionForms.push(submissionForm);"},{"lineNumber":666,"author":{"gitId":"-"},"content":" });"},{"lineNumber":667,"author":{"gitId":"-"},"content":" }"},{"lineNumber":668,"author":{"gitId":"-"},"content":""},{"lineNumber":669,"author":{"gitId":"-"},"content":" if (this.getQuestionSubmissionFormModeInDefaultView(model)"},{"lineNumber":670,"author":{"gitId":"-"},"content":" \u003d\u003d\u003d QuestionSubmissionFormMode.FLEXIBLE_RECIPIENT) {"},{"lineNumber":671,"author":{"gitId":"-"},"content":" // need to generate limited number of submission forms"},{"lineNumber":672,"author":{"gitId":"-"},"content":" let numberOfRecipientSubmissionFormsNeeded: number \u003d"},{"lineNumber":673,"author":{"gitId":"-"},"content":" model.customNumberOfEntitiesToGiveFeedbackTo - existingResponses.responses.length;"},{"lineNumber":674,"author":{"gitId":"-"},"content":""},{"lineNumber":675,"author":{"gitId":"-"},"content":" existingResponses.responses.forEach((response: FeedbackResponse) \u003d\u003e {"},{"lineNumber":676,"author":{"gitId":"-"},"content":" const submissionForm: FeedbackResponseRecipientSubmissionFormModel \u003d {"},{"lineNumber":677,"author":{"gitId":"-"},"content":" recipientIdentifier: response.recipientIdentifier,"},{"lineNumber":678,"author":{"gitId":"-"},"content":" responseDetails: response.responseDetails,"},{"lineNumber":679,"author":{"gitId":"-"},"content":" responseId: response.feedbackResponseId,"},{"lineNumber":680,"author":{"gitId":"-"},"content":" isValid: true,"},{"lineNumber":681,"author":{"gitId":"-"},"content":" };"},{"lineNumber":682,"author":{"gitId":"-"},"content":" if (response.giverComment) {"},{"lineNumber":683,"author":{"gitId":"-"},"content":" submissionForm.commentByGiver \u003d this.getCommentModel("},{"lineNumber":684,"author":{"gitId":"-"},"content":" response.giverComment, response.recipientIdentifier);"},{"lineNumber":685,"author":{"gitId":"-"},"content":" }"},{"lineNumber":686,"author":{"gitId":"-"},"content":" model.recipientSubmissionForms.push(submissionForm);"},{"lineNumber":687,"author":{"gitId":"-"},"content":" });"},{"lineNumber":688,"author":{"gitId":"-"},"content":""},{"lineNumber":689,"author":{"gitId":"-"},"content":" // generate empty submission forms"},{"lineNumber":690,"author":{"gitId":"-"},"content":" while (numberOfRecipientSubmissionFormsNeeded \u003e 0) {"},{"lineNumber":691,"author":{"gitId":"-"},"content":" model.recipientSubmissionForms.push({"},{"lineNumber":692,"author":{"gitId":"-"},"content":" recipientIdentifier: \u0027\u0027,"},{"lineNumber":693,"author":{"gitId":"-"},"content":" responseDetails: this.feedbackResponsesService.getDefaultFeedbackResponseDetails(model.questionType),"},{"lineNumber":694,"author":{"gitId":"-"},"content":" responseId: \u0027\u0027,"},{"lineNumber":695,"author":{"gitId":"-"},"content":" isValid: true,"},{"lineNumber":696,"author":{"gitId":"-"},"content":" });"},{"lineNumber":697,"author":{"gitId":"-"},"content":" numberOfRecipientSubmissionFormsNeeded -\u003d 1;"},{"lineNumber":698,"author":{"gitId":"-"},"content":" }"},{"lineNumber":699,"author":{"gitId":"-"},"content":" }"},{"lineNumber":700,"author":{"gitId":"-"},"content":" },"},{"lineNumber":701,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e this.statusMessageService.showErrorToast(resp.error.message),"},{"lineNumber":702,"author":{"gitId":"-"},"content":" });"},{"lineNumber":703,"author":{"gitId":"-"},"content":" }"},{"lineNumber":704,"author":{"gitId":"-"},"content":""},{"lineNumber":705,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":706,"author":{"gitId":"-"},"content":" * Gets the comment model for a given comment."},{"lineNumber":707,"author":{"gitId":"-"},"content":" */"},{"lineNumber":708,"author":{"gitId":"-"},"content":" getCommentModel(comment: FeedbackResponseComment, recipientIdentifier: string): CommentRowModel {"},{"lineNumber":709,"author":{"gitId":"-"},"content":" return {"},{"lineNumber":710,"author":{"gitId":"-"},"content":" originalComment: comment,"},{"lineNumber":711,"author":{"gitId":"-"},"content":" originalRecipientIdentifier: recipientIdentifier,"},{"lineNumber":712,"author":{"gitId":"-"},"content":" commentEditFormModel: {"},{"lineNumber":713,"author":{"gitId":"-"},"content":" commentText: comment.commentText,"},{"lineNumber":714,"author":{"gitId":"-"},"content":" // the participant comment shall not use custom visibilities"},{"lineNumber":715,"author":{"gitId":"-"},"content":" isUsingCustomVisibilities: false,"},{"lineNumber":716,"author":{"gitId":"-"},"content":" showCommentTo: [],"},{"lineNumber":717,"author":{"gitId":"-"},"content":" showGiverNameTo: [],"},{"lineNumber":718,"author":{"gitId":"-"},"content":" },"},{"lineNumber":719,"author":{"gitId":"-"},"content":" timezone: this.feedbackSessionTimezone,"},{"lineNumber":720,"author":{"gitId":"-"},"content":" isEditing: false,"},{"lineNumber":721,"author":{"gitId":"-"},"content":" };"},{"lineNumber":722,"author":{"gitId":"-"},"content":" }"},{"lineNumber":723,"author":{"gitId":"-"},"content":""},{"lineNumber":724,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":725,"author":{"gitId":"-"},"content":" * Checks whether there is any submission forms in the current page."},{"lineNumber":726,"author":{"gitId":"-"},"content":" */"},{"lineNumber":727,"author":{"gitId":"-"},"content":" get questionsNeedingSubmission(): QuestionSubmissionFormModel[] {"},{"lineNumber":728,"author":{"gitId":"-"},"content":" return this.questionSubmissionForms"},{"lineNumber":729,"author":{"gitId":"-"},"content":" .filter((model: QuestionSubmissionFormModel) \u003d\u003e model.recipientSubmissionForms.length !\u003d\u003d 0);"},{"lineNumber":730,"author":{"gitId":"-"},"content":" }"},{"lineNumber":731,"author":{"gitId":"-"},"content":""},{"lineNumber":732,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":733,"author":{"gitId":"-"},"content":" * Saves the feedback responses for the specific questions."},{"lineNumber":734,"author":{"gitId":"-"},"content":" *"},{"lineNumber":735,"author":{"gitId":"-"},"content":" * \u003cp\u003eAll empty feedback response will be deleted; For non-empty responses, update/create them if necessary."},{"lineNumber":736,"author":{"gitId":"-"},"content":" *"},{"lineNumber":737,"author":{"gitId":"-"},"content":" * @param questionSubmissionForms An array of question submission forms to be saved"},{"lineNumber":738,"author":{"gitId":"-"},"content":" * @param isSubmitAll Is the \u0027Submit Responses for All Questions\u0027 button clicked when saving responses"},{"lineNumber":739,"author":{"gitId":"-"},"content":" * @param recipientId The recipient identifier of the selected recipient when saving responses for this recipient"},{"lineNumber":740,"author":{"gitId":"-"},"content":" * only. This parameter will be null when saving responses for all questions or saving responses for one question."},{"lineNumber":741,"author":{"gitId":"-"},"content":" */"},{"lineNumber":742,"author":{"gitId":"-"},"content":" saveFeedbackResponses(questionSubmissionForms: QuestionSubmissionFormModel[],"},{"lineNumber":743,"author":{"gitId":"-"},"content":" isSubmitAll: boolean, recipientId: string | null): void {"},{"lineNumber":744,"author":{"gitId":"-"},"content":" if (isSubmitAll) {"},{"lineNumber":745,"author":{"gitId":"-"},"content":" this.isSubmitAllClicked \u003d true;"},{"lineNumber":746,"author":{"gitId":"-"},"content":" }"},{"lineNumber":747,"author":{"gitId":"-"},"content":""},{"lineNumber":748,"author":{"gitId":"-"},"content":" const notYetAnsweredQuestions: Set\u003cnumber\u003e \u003d new Set();"},{"lineNumber":749,"author":{"gitId":"-"},"content":" const requestIds: Record\u003cstring, string\u003e \u003d {};"},{"lineNumber":750,"author":{"gitId":"-"},"content":" const answers: Record\u003cstring, FeedbackResponse[]\u003e \u003d {};"},{"lineNumber":751,"author":{"gitId":"-"},"content":" const failToSaveQuestions: Record\u003cnumber, string\u003e \u003d {}; // Map of question number to error message"},{"lineNumber":752,"author":{"gitId":"-"},"content":" const savingRequests: Observable\u003cany\u003e[] \u003d [];"},{"lineNumber":753,"author":{"gitId":"-"},"content":""},{"lineNumber":754,"author":{"gitId":"-"},"content":" this.logService.createFeedbackSessionLog({"},{"lineNumber":755,"author":{"gitId":"-"},"content":" courseId: this.courseId,"},{"lineNumber":756,"author":{"gitId":"-"},"content":" feedbackSessionName: this.feedbackSessionName,"},{"lineNumber":757,"author":{"gitId":"-"},"content":" studentEmail: this.personEmail,"},{"lineNumber":758,"author":{"gitId":"-"},"content":" logType: FeedbackSessionLogType.SUBMISSION,"},{"lineNumber":759,"author":{"gitId":"dishenggg"},"content":" feedbackSessionId: this.feedbackSessionId,"},{"lineNumber":760,"author":{"gitId":"dishenggg"},"content":" studentId: this.studentId,"},{"lineNumber":761,"author":{"gitId":"dishenggg"},"content":" }).subscribe();"},{"lineNumber":762,"author":{"gitId":"-"},"content":""},{"lineNumber":763,"author":{"gitId":"-"},"content":" questionSubmissionForms.forEach((questionSubmissionFormModel: QuestionSubmissionFormModel) \u003d\u003e {"},{"lineNumber":764,"author":{"gitId":"-"},"content":" let isQuestionFullyAnswered: boolean \u003d true;"},{"lineNumber":765,"author":{"gitId":"-"},"content":""},{"lineNumber":766,"author":{"gitId":"-"},"content":" const responses: FeedbackResponseRequest[] \u003d [];"},{"lineNumber":767,"author":{"gitId":"-"},"content":""},{"lineNumber":768,"author":{"gitId":"-"},"content":" questionSubmissionFormModel.recipientSubmissionForms"},{"lineNumber":769,"author":{"gitId":"-"},"content":" .forEach((recipientSubmissionFormModel: FeedbackResponseRecipientSubmissionFormModel) \u003d\u003e {"},{"lineNumber":770,"author":{"gitId":"-"},"content":" if (!recipientSubmissionFormModel.isValid) {"},{"lineNumber":771,"author":{"gitId":"-"},"content":" failToSaveQuestions[questionSubmissionFormModel.questionNumber] \u003d"},{"lineNumber":772,"author":{"gitId":"-"},"content":" \u0027Invalid responses provided. Please check question constraints.\u0027;"},{"lineNumber":773,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":774,"author":{"gitId":"-"},"content":" }"},{"lineNumber":775,"author":{"gitId":"-"},"content":" const isFeedbackResponseDetailsEmpty: boolean \u003d"},{"lineNumber":776,"author":{"gitId":"-"},"content":" this.feedbackResponsesService.isFeedbackResponseDetailsEmpty("},{"lineNumber":777,"author":{"gitId":"-"},"content":" questionSubmissionFormModel.questionType, recipientSubmissionFormModel.responseDetails);"},{"lineNumber":778,"author":{"gitId":"-"},"content":""},{"lineNumber":779,"author":{"gitId":"-"},"content":" if (!isFeedbackResponseDetailsEmpty) {"},{"lineNumber":780,"author":{"gitId":"-"},"content":" responses.push({"},{"lineNumber":781,"author":{"gitId":"-"},"content":" recipient: recipientSubmissionFormModel.recipientIdentifier,"},{"lineNumber":782,"author":{"gitId":"-"},"content":" responseDetails: recipientSubmissionFormModel.responseDetails,"},{"lineNumber":783,"author":{"gitId":"-"},"content":" });"},{"lineNumber":784,"author":{"gitId":"-"},"content":" }"},{"lineNumber":785,"author":{"gitId":"-"},"content":" });"},{"lineNumber":786,"author":{"gitId":"-"},"content":""},{"lineNumber":787,"author":{"gitId":"-"},"content":" isQuestionFullyAnswered \u003d responses.length \u003e 0;"},{"lineNumber":788,"author":{"gitId":"-"},"content":""},{"lineNumber":789,"author":{"gitId":"-"},"content":" if (!failToSaveQuestions[questionSubmissionFormModel.questionNumber]) {"},{"lineNumber":790,"author":{"gitId":"-"},"content":" savingRequests.push("},{"lineNumber":791,"author":{"gitId":"-"},"content":" this.feedbackResponsesService.submitFeedbackResponses(questionSubmissionFormModel.feedbackQuestionId, {"},{"lineNumber":792,"author":{"gitId":"-"},"content":" responses,"},{"lineNumber":793,"author":{"gitId":"-"},"content":" }, {"},{"lineNumber":794,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":795,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":796,"author":{"gitId":"-"},"content":" moderatedperson: this.moderatedPerson,"},{"lineNumber":797,"author":{"gitId":"-"},"content":" singlerecipientidforsubmission: recipientId?.toString() || \u0027\u0027,"},{"lineNumber":798,"author":{"gitId":"-"},"content":" }).pipe("},{"lineNumber":799,"author":{"gitId":"-"},"content":" tap((resp: FeedbackResponses) \u003d\u003e {"},{"lineNumber":800,"author":{"gitId":"-"},"content":" const responsesMap: Record\u003cstring, FeedbackResponse\u003e \u003d {};"},{"lineNumber":801,"author":{"gitId":"-"},"content":" resp.responses.forEach((response: FeedbackResponse) \u003d\u003e {"},{"lineNumber":802,"author":{"gitId":"-"},"content":" responsesMap[response.recipientIdentifier] \u003d response;"},{"lineNumber":803,"author":{"gitId":"-"},"content":" answers[questionSubmissionFormModel.feedbackQuestionId] \u003d"},{"lineNumber":804,"author":{"gitId":"-"},"content":" answers[questionSubmissionFormModel.feedbackQuestionId] || [];"},{"lineNumber":805,"author":{"gitId":"-"},"content":" answers[questionSubmissionFormModel.feedbackQuestionId].push(response);"},{"lineNumber":806,"author":{"gitId":"-"},"content":" });"},{"lineNumber":807,"author":{"gitId":"-"},"content":" requestIds[questionSubmissionFormModel.feedbackQuestionId] \u003d resp.requestId || \u0027\u0027;"},{"lineNumber":808,"author":{"gitId":"-"},"content":""},{"lineNumber":809,"author":{"gitId":"-"},"content":" questionSubmissionFormModel.recipientSubmissionForms"},{"lineNumber":810,"author":{"gitId":"-"},"content":" .forEach((recipientSubmissionFormModel: FeedbackResponseRecipientSubmissionFormModel) \u003d\u003e {"},{"lineNumber":811,"author":{"gitId":"-"},"content":" if (responsesMap[recipientSubmissionFormModel.recipientIdentifier]) {"},{"lineNumber":812,"author":{"gitId":"-"},"content":" const correspondingResp: FeedbackResponse \u003d"},{"lineNumber":813,"author":{"gitId":"-"},"content":" responsesMap[recipientSubmissionFormModel.recipientIdentifier];"},{"lineNumber":814,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.responseId \u003d correspondingResp.feedbackResponseId;"},{"lineNumber":815,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.responseDetails \u003d correspondingResp.responseDetails;"},{"lineNumber":816,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.recipientIdentifier \u003d correspondingResp.recipientIdentifier;"},{"lineNumber":817,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":818,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.responseId \u003d \u0027\u0027;"},{"lineNumber":819,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.commentByGiver \u003d undefined;"},{"lineNumber":820,"author":{"gitId":"-"},"content":" }"},{"lineNumber":821,"author":{"gitId":"-"},"content":" });"},{"lineNumber":822,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":823,"author":{"gitId":"-"},"content":" switchMap(() \u003d\u003e"},{"lineNumber":824,"author":{"gitId":"-"},"content":" forkJoin(questionSubmissionFormModel.recipientSubmissionForms"},{"lineNumber":825,"author":{"gitId":"-"},"content":" .map((recipientSubmissionFormModel: FeedbackResponseRecipientSubmissionFormModel) \u003d\u003e"},{"lineNumber":826,"author":{"gitId":"-"},"content":" this.createCommentRequest(recipientSubmissionFormModel))),"},{"lineNumber":827,"author":{"gitId":"-"},"content":" ),"},{"lineNumber":828,"author":{"gitId":"-"},"content":" catchError((error: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":829,"author":{"gitId":"-"},"content":" failToSaveQuestions[questionSubmissionFormModel.questionNumber] \u003d error.error.message;"},{"lineNumber":830,"author":{"gitId":"-"},"content":" return of(error);"},{"lineNumber":831,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":832,"author":{"gitId":"-"},"content":" ),"},{"lineNumber":833,"author":{"gitId":"-"},"content":" );"},{"lineNumber":834,"author":{"gitId":"-"},"content":" }"},{"lineNumber":835,"author":{"gitId":"-"},"content":""},{"lineNumber":836,"author":{"gitId":"-"},"content":" if (!isQuestionFullyAnswered) {"},{"lineNumber":837,"author":{"gitId":"-"},"content":" notYetAnsweredQuestions.add(questionSubmissionFormModel.questionNumber);"},{"lineNumber":838,"author":{"gitId":"-"},"content":" }"},{"lineNumber":839,"author":{"gitId":"-"},"content":" });"},{"lineNumber":840,"author":{"gitId":"-"},"content":""},{"lineNumber":841,"author":{"gitId":"-"},"content":" this.isSavingResponses \u003d true;"},{"lineNumber":842,"author":{"gitId":"-"},"content":" forkJoin(savingRequests).pipe("},{"lineNumber":843,"author":{"gitId":"-"},"content":" finalize(() \u003d\u003e {"},{"lineNumber":844,"author":{"gitId":"-"},"content":" this.isSavingResponses \u003d false;"},{"lineNumber":845,"author":{"gitId":"-"},"content":""},{"lineNumber":846,"author":{"gitId":"-"},"content":" const modalRef: NgbModalRef \u003d this.ngbModal.open(SavingCompleteModalComponent);"},{"lineNumber":847,"author":{"gitId":"-"},"content":" modalRef.componentInstance.requestIds \u003d requestIds;"},{"lineNumber":848,"author":{"gitId":"-"},"content":" modalRef.componentInstance.courseId \u003d this.courseId;"},{"lineNumber":849,"author":{"gitId":"-"},"content":" modalRef.componentInstance.feedbackSessionName \u003d this.feedbackSessionName;"},{"lineNumber":850,"author":{"gitId":"-"},"content":" modalRef.componentInstance.feedbackSessionTimezone \u003d this.feedbackSessionTimezone;"},{"lineNumber":851,"author":{"gitId":"-"},"content":" modalRef.componentInstance.personEmail \u003d this.personEmail;"},{"lineNumber":852,"author":{"gitId":"-"},"content":" modalRef.componentInstance.personName \u003d this.personName;"},{"lineNumber":853,"author":{"gitId":"-"},"content":" modalRef.componentInstance.questions \u003d questionSubmissionForms;"},{"lineNumber":854,"author":{"gitId":"-"},"content":" modalRef.componentInstance.answers \u003d answers;"},{"lineNumber":855,"author":{"gitId":"-"},"content":" modalRef.componentInstance.notYetAnsweredQuestions \u003d Array.from(notYetAnsweredQuestions.values());"},{"lineNumber":856,"author":{"gitId":"-"},"content":" modalRef.componentInstance.failToSaveQuestions \u003d failToSaveQuestions;"},{"lineNumber":857,"author":{"gitId":"-"},"content":""},{"lineNumber":858,"author":{"gitId":"-"},"content":" if (recipientId) {"},{"lineNumber":859,"author":{"gitId":"-"},"content":" this.questionSubmissionForms.forEach((model: QuestionSubmissionFormModel) \u003d\u003e {"},{"lineNumber":860,"author":{"gitId":"-"},"content":" if (this.recipientQuestionMap.get(recipientId)!.has(model.questionNumber)) {"},{"lineNumber":861,"author":{"gitId":"-"},"content":" model.hasResponseChangedForRecipients.set(recipientId, false);"},{"lineNumber":862,"author":{"gitId":"-"},"content":" }"},{"lineNumber":863,"author":{"gitId":"-"},"content":" });"},{"lineNumber":864,"author":{"gitId":"-"},"content":" }"},{"lineNumber":865,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":866,"author":{"gitId":"-"},"content":" ).subscribe();"},{"lineNumber":867,"author":{"gitId":"-"},"content":" }"},{"lineNumber":868,"author":{"gitId":"-"},"content":""},{"lineNumber":869,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":870,"author":{"gitId":"-"},"content":" * Creates comment request."},{"lineNumber":871,"author":{"gitId":"-"},"content":" */"},{"lineNumber":872,"author":{"gitId":"-"},"content":" createCommentRequest(recipientSubmissionFormModel: FeedbackResponseRecipientSubmissionFormModel): Observable\u003cany\u003e {"},{"lineNumber":873,"author":{"gitId":"-"},"content":" if (!recipientSubmissionFormModel.responseId) {"},{"lineNumber":874,"author":{"gitId":"-"},"content":" // responseId not set, cannot set comment"},{"lineNumber":875,"author":{"gitId":"-"},"content":" return of({});"},{"lineNumber":876,"author":{"gitId":"-"},"content":" }"},{"lineNumber":877,"author":{"gitId":"-"},"content":" if (!recipientSubmissionFormModel.commentByGiver) {"},{"lineNumber":878,"author":{"gitId":"-"},"content":" // comment not given, do nothing"},{"lineNumber":879,"author":{"gitId":"-"},"content":" return of({});"},{"lineNumber":880,"author":{"gitId":"-"},"content":" }"},{"lineNumber":881,"author":{"gitId":"-"},"content":""},{"lineNumber":882,"author":{"gitId":"-"},"content":" const isSameRecipient \u003d recipientSubmissionFormModel.recipientIdentifier"},{"lineNumber":883,"author":{"gitId":"-"},"content":" \u003d\u003d\u003d recipientSubmissionFormModel.commentByGiver.originalRecipientIdentifier;"},{"lineNumber":884,"author":{"gitId":"-"},"content":""},{"lineNumber":885,"author":{"gitId":"-"},"content":" if (!recipientSubmissionFormModel.commentByGiver.originalComment || !isSameRecipient) {"},{"lineNumber":886,"author":{"gitId":"-"},"content":" // comment is new or original comment deleted because recipient has changed"},{"lineNumber":887,"author":{"gitId":"-"},"content":""},{"lineNumber":888,"author":{"gitId":"-"},"content":" if (recipientSubmissionFormModel.commentByGiver.commentEditFormModel.commentText \u003d\u003d\u003d \u0027\u0027) {"},{"lineNumber":889,"author":{"gitId":"-"},"content":" // new comment is empty"},{"lineNumber":890,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.commentByGiver \u003d undefined;"},{"lineNumber":891,"author":{"gitId":"-"},"content":" return of({});"},{"lineNumber":892,"author":{"gitId":"-"},"content":" }"},{"lineNumber":893,"author":{"gitId":"-"},"content":""},{"lineNumber":894,"author":{"gitId":"-"},"content":" // create new comment"},{"lineNumber":895,"author":{"gitId":"-"},"content":" return this.commentService.createComment({"},{"lineNumber":896,"author":{"gitId":"-"},"content":" commentText: recipientSubmissionFormModel.commentByGiver.commentEditFormModel.commentText,"},{"lineNumber":897,"author":{"gitId":"-"},"content":" // we ignore the fields in comment edit model as participant comment"},{"lineNumber":898,"author":{"gitId":"-"},"content":" // will follow visibilities from question by design"},{"lineNumber":899,"author":{"gitId":"-"},"content":" showCommentTo: [],"},{"lineNumber":900,"author":{"gitId":"-"},"content":" showGiverNameTo: [],"},{"lineNumber":901,"author":{"gitId":"-"},"content":" }, recipientSubmissionFormModel.responseId, this.intent, {"},{"lineNumber":902,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":903,"author":{"gitId":"-"},"content":" moderatedperson: this.moderatedPerson,"},{"lineNumber":904,"author":{"gitId":"-"},"content":" }).pipe("},{"lineNumber":905,"author":{"gitId":"-"},"content":" tap((comment: FeedbackResponseComment) \u003d\u003e {"},{"lineNumber":906,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.commentByGiver \u003d this.getCommentModel("},{"lineNumber":907,"author":{"gitId":"-"},"content":" comment, recipientSubmissionFormModel.recipientIdentifier);"},{"lineNumber":908,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":909,"author":{"gitId":"-"},"content":" );"},{"lineNumber":910,"author":{"gitId":"-"},"content":" }"},{"lineNumber":911,"author":{"gitId":"-"},"content":""},{"lineNumber":912,"author":{"gitId":"-"},"content":" // existing comment"},{"lineNumber":913,"author":{"gitId":"-"},"content":""},{"lineNumber":914,"author":{"gitId":"-"},"content":" if (recipientSubmissionFormModel.commentByGiver.commentEditFormModel.commentText \u003d\u003d\u003d \u0027\u0027) {"},{"lineNumber":915,"author":{"gitId":"-"},"content":" // comment is empty, create delete request"},{"lineNumber":916,"author":{"gitId":"-"},"content":" return this.commentService.deleteComment("},{"lineNumber":917,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.commentByGiver.originalComment.feedbackResponseCommentId, this.intent, {"},{"lineNumber":918,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":919,"author":{"gitId":"-"},"content":" moderatedperson: this.moderatedPerson,"},{"lineNumber":920,"author":{"gitId":"-"},"content":" })"},{"lineNumber":921,"author":{"gitId":"-"},"content":" .pipe("},{"lineNumber":922,"author":{"gitId":"-"},"content":" tap(() \u003d\u003e {"},{"lineNumber":923,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.commentByGiver \u003d undefined;"},{"lineNumber":924,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":925,"author":{"gitId":"-"},"content":" }"},{"lineNumber":926,"author":{"gitId":"-"},"content":""},{"lineNumber":927,"author":{"gitId":"-"},"content":" // update comment"},{"lineNumber":928,"author":{"gitId":"-"},"content":" return this.commentService.updateComment({"},{"lineNumber":929,"author":{"gitId":"-"},"content":" commentText: recipientSubmissionFormModel.commentByGiver.commentEditFormModel.commentText,"},{"lineNumber":930,"author":{"gitId":"-"},"content":" // we ignore the fields in comment edit model as participant comment"},{"lineNumber":931,"author":{"gitId":"-"},"content":" // will follow visibilities from question by design"},{"lineNumber":932,"author":{"gitId":"-"},"content":" showCommentTo: [],"},{"lineNumber":933,"author":{"gitId":"-"},"content":" showGiverNameTo: [],"},{"lineNumber":934,"author":{"gitId":"-"},"content":" }, recipientSubmissionFormModel.commentByGiver.originalComment.feedbackResponseCommentId, this.intent, {"},{"lineNumber":935,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":936,"author":{"gitId":"-"},"content":" moderatedperson: this.moderatedPerson,"},{"lineNumber":937,"author":{"gitId":"-"},"content":" }).pipe("},{"lineNumber":938,"author":{"gitId":"-"},"content":" tap((comment: FeedbackResponseComment) \u003d\u003e {"},{"lineNumber":939,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.commentByGiver \u003d this.getCommentModel("},{"lineNumber":940,"author":{"gitId":"-"},"content":" comment, recipientSubmissionFormModel.recipientIdentifier);"},{"lineNumber":941,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":942,"author":{"gitId":"-"},"content":" );"},{"lineNumber":943,"author":{"gitId":"-"},"content":" }"},{"lineNumber":944,"author":{"gitId":"-"},"content":""},{"lineNumber":945,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":946,"author":{"gitId":"-"},"content":" * Deletes a comment by participants."},{"lineNumber":947,"author":{"gitId":"-"},"content":" */"},{"lineNumber":948,"author":{"gitId":"-"},"content":" deleteParticipantComment(questionIndex: number, responseIdx: number): void {"},{"lineNumber":949,"author":{"gitId":"-"},"content":" const recipientSubmissionFormModel: FeedbackResponseRecipientSubmissionFormModel \u003d"},{"lineNumber":950,"author":{"gitId":"-"},"content":" this.questionSubmissionForms[questionIndex].recipientSubmissionForms[responseIdx];"},{"lineNumber":951,"author":{"gitId":"-"},"content":""},{"lineNumber":952,"author":{"gitId":"-"},"content":" if (!recipientSubmissionFormModel.commentByGiver || !recipientSubmissionFormModel.commentByGiver.originalComment) {"},{"lineNumber":953,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":954,"author":{"gitId":"-"},"content":" }"},{"lineNumber":955,"author":{"gitId":"-"},"content":""},{"lineNumber":956,"author":{"gitId":"-"},"content":" this.commentService.deleteComment("},{"lineNumber":957,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.commentByGiver.originalComment.feedbackResponseCommentId, this.intent, {"},{"lineNumber":958,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":959,"author":{"gitId":"-"},"content":" moderatedperson: this.moderatedPerson,"},{"lineNumber":960,"author":{"gitId":"-"},"content":" })"},{"lineNumber":961,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":962,"author":{"gitId":"-"},"content":" next: () \u003d\u003e {"},{"lineNumber":963,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.commentByGiver \u003d undefined;"},{"lineNumber":964,"author":{"gitId":"-"},"content":" this.statusMessageService.showSuccessToast(\u0027Your comment has been deleted!\u0027);"},{"lineNumber":965,"author":{"gitId":"-"},"content":" },"},{"lineNumber":966,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":967,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":968,"author":{"gitId":"-"},"content":" },"},{"lineNumber":969,"author":{"gitId":"-"},"content":" });"},{"lineNumber":970,"author":{"gitId":"-"},"content":" }"},{"lineNumber":971,"author":{"gitId":"-"},"content":""},{"lineNumber":972,"author":{"gitId":"-"},"content":" retryLoadingFeedbackSessionQuestions(): void {"},{"lineNumber":973,"author":{"gitId":"-"},"content":" this.hasFeedbackSessionQuestionsLoadingFailed \u003d false;"},{"lineNumber":974,"author":{"gitId":"-"},"content":" if (this.retryAttempts \u003e\u003d 0) {"},{"lineNumber":975,"author":{"gitId":"-"},"content":" this.retryAttempts -\u003d 1;"},{"lineNumber":976,"author":{"gitId":"-"},"content":" }"},{"lineNumber":977,"author":{"gitId":"-"},"content":" this.loadFeedbackQuestions();"},{"lineNumber":978,"author":{"gitId":"-"},"content":" }"},{"lineNumber":979,"author":{"gitId":"-"},"content":""},{"lineNumber":980,"author":{"gitId":"-"},"content":" handleError(resp: ErrorMessageOutput): void {"},{"lineNumber":981,"author":{"gitId":"-"},"content":" this.hasFeedbackSessionQuestionsLoadingFailed \u003d true;"},{"lineNumber":982,"author":{"gitId":"-"},"content":" if (this.retryAttempts \u003c 0) {"},{"lineNumber":983,"author":{"gitId":"-"},"content":" const report: NgbModalRef \u003d this.ngbModal.open(ErrorReportComponent);"},{"lineNumber":984,"author":{"gitId":"-"},"content":" report.componentInstance.requestId \u003d resp.error.requestId;"},{"lineNumber":985,"author":{"gitId":"-"},"content":" report.componentInstance.errorMessage \u003d resp.error.message;"},{"lineNumber":986,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":987,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":988,"author":{"gitId":"-"},"content":" }"},{"lineNumber":989,"author":{"gitId":"-"},"content":" }"},{"lineNumber":990,"author":{"gitId":"-"},"content":""},{"lineNumber":991,"author":{"gitId":"-"},"content":" loadRecipientsAndResponses(event: any, questionSubmissionForm: QuestionSubmissionFormModel): void {"},{"lineNumber":992,"author":{"gitId":"-"},"content":" if (event \u0026\u0026 event.visible \u0026\u0026 !questionSubmissionForm.isLoaded \u0026\u0026 !questionSubmissionForm.isLoading) {"},{"lineNumber":993,"author":{"gitId":"-"},"content":" questionSubmissionForm.isLoading \u003d true;"},{"lineNumber":994,"author":{"gitId":"-"},"content":" this.loadFeedbackQuestionRecipientsForQuestion(questionSubmissionForm);"},{"lineNumber":995,"author":{"gitId":"-"},"content":" }"},{"lineNumber":996,"author":{"gitId":"-"},"content":" }"},{"lineNumber":997,"author":{"gitId":"-"},"content":""},{"lineNumber":998,"author":{"gitId":"-"},"content":" private getformattedSessionClosingTime(feedbackSession: FeedbackSession, TIME_FORMAT: string): string {"},{"lineNumber":999,"author":{"gitId":"-"},"content":" const userSessionEndingTime \u003d DeadlineExtensionHelper.getUserFeedbackSessionEndingTimestamp(feedbackSession);"},{"lineNumber":1000,"author":{"gitId":"-"},"content":" let formattedString \u003d this.timezoneService.formatToString("},{"lineNumber":1001,"author":{"gitId":"-"},"content":" userSessionEndingTime, feedbackSession.timeZone, TIME_FORMAT);"},{"lineNumber":1002,"author":{"gitId":"-"},"content":" if (DeadlineExtensionHelper.hasUserExtension(feedbackSession)) {"},{"lineNumber":1003,"author":{"gitId":"-"},"content":" formattedString +\u003d \u0027 (Extension given)\u0027;"},{"lineNumber":1004,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1005,"author":{"gitId":"-"},"content":" return formattedString;"},{"lineNumber":1006,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1007,"author":{"gitId":"-"},"content":""},{"lineNumber":1008,"author":{"gitId":"-"},"content":" private isFeedbackEndingLessThanFifteenMinutes(feedbackSession: FeedbackSession): boolean {"},{"lineNumber":1009,"author":{"gitId":"-"},"content":" const userSessionEndingTime \u003d DeadlineExtensionHelper.getOngoingUserFeedbackSessionEndingTimestamp(feedbackSession);"},{"lineNumber":1010,"author":{"gitId":"-"},"content":" return (userSessionEndingTime - Date.now()) \u003c Milliseconds.IN_FIFTEEN_MINUTES;"},{"lineNumber":1011,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1012,"author":{"gitId":"-"},"content":""},{"lineNumber":1013,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1014,"author":{"gitId":"-"},"content":" * Filter questions that we are submitting for intended recipient"},{"lineNumber":1015,"author":{"gitId":"-"},"content":" * when grouped session view is toggled and save the responses after."},{"lineNumber":1016,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1017,"author":{"gitId":"-"},"content":" saveResponsesForSelectedRecipientQuestions(recipientId: string,"},{"lineNumber":1018,"author":{"gitId":"-"},"content":" questionSubmissionForms: QuestionSubmissionFormModel[]): void {"},{"lineNumber":1019,"author":{"gitId":"-"},"content":" const questionsToRecipient: Set\u003cnumber\u003e | undefined \u003d this.recipientQuestionMap.get(recipientId);"},{"lineNumber":1020,"author":{"gitId":"-"},"content":" if (!questionsToRecipient) {"},{"lineNumber":1021,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(\u0027Failed to save response for this recipient. \u0027"},{"lineNumber":1022,"author":{"gitId":"-"},"content":" + \u0027Please switch back to \"Group by Question\" view to save responses.\u0027);"},{"lineNumber":1023,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1024,"author":{"gitId":"-"},"content":" const recipientQSForms \u003d questionSubmissionForms"},{"lineNumber":1025,"author":{"gitId":"-"},"content":" .filter((questionSubmissionFormModel: QuestionSubmissionFormModel) \u003d\u003e"},{"lineNumber":1026,"author":{"gitId":"-"},"content":" questionsToRecipient!.has(questionSubmissionFormModel.questionNumber));"},{"lineNumber":1027,"author":{"gitId":"-"},"content":""},{"lineNumber":1028,"author":{"gitId":"-"},"content":" this.saveFeedbackResponses(recipientQSForms, false, recipientId);"},{"lineNumber":1029,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1030,"author":{"gitId":"-"},"content":""},{"lineNumber":1031,"author":{"gitId":"-"},"content":" private addQuestionForRecipient(recipientId: string, questionId: any): void {"},{"lineNumber":1032,"author":{"gitId":"-"},"content":" if (this.recipientQuestionMap.has(recipientId)) {"},{"lineNumber":1033,"author":{"gitId":"-"},"content":" this.recipientQuestionMap.get(recipientId)!.add(questionId);"},{"lineNumber":1034,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1035,"author":{"gitId":"-"},"content":" const feedbackQuestionIds: Set\u003cany\u003e \u003d new Set\u003cany\u003e();"},{"lineNumber":1036,"author":{"gitId":"-"},"content":" feedbackQuestionIds.add(questionId);"},{"lineNumber":1037,"author":{"gitId":"-"},"content":" this.recipientQuestionMap.set(recipientId, feedbackQuestionIds);"},{"lineNumber":1038,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1039,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1040,"author":{"gitId":"-"},"content":""},{"lineNumber":1041,"author":{"gitId":"-"},"content":" toggleViewChange(selectedView: SessionView): void {"},{"lineNumber":1042,"author":{"gitId":"-"},"content":" if (selectedView \u003d\u003d\u003d this.currentSelectedSessionView) {"},{"lineNumber":1043,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":1044,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1045,"author":{"gitId":"-"},"content":""},{"lineNumber":1046,"author":{"gitId":"-"},"content":" if (selectedView \u003d\u003d\u003d SessionView.DEFAULT) {"},{"lineNumber":1047,"author":{"gitId":"-"},"content":" this.currentSelectedSessionView \u003d SessionView.DEFAULT;"},{"lineNumber":1048,"author":{"gitId":"-"},"content":" } else if (selectedView \u003d\u003d\u003d SessionView.GROUP_RECIPIENTS) {"},{"lineNumber":1049,"author":{"gitId":"-"},"content":" this.currentSelectedSessionView \u003d SessionView.GROUP_RECIPIENTS;"},{"lineNumber":1050,"author":{"gitId":"-"},"content":" this.groupQuestionsByRecipient();"},{"lineNumber":1051,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1052,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1053,"author":{"gitId":"-"},"content":""},{"lineNumber":1054,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1055,"author":{"gitId":"-"},"content":" * Group questions by recipients in {@code GROUP_RECIPIENTS} view."},{"lineNumber":1056,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1057,"author":{"gitId":"-"},"content":" groupQuestionsByRecipient(): void {"},{"lineNumber":1058,"author":{"gitId":"-"},"content":" if (this.hasLoadedAllRecipients) {"},{"lineNumber":1059,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":1060,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1061,"author":{"gitId":"-"},"content":" // We first need to load the recipient for all the questions. This is because questions with"},{"lineNumber":1062,"author":{"gitId":"-"},"content":" // FIXED_RECIPIENT question submission mode are ungroupable and to know whether the question"},{"lineNumber":1063,"author":{"gitId":"-"},"content":" // submission mode of a question, we need to load the recipient list first."},{"lineNumber":1064,"author":{"gitId":"-"},"content":" const recipientsObservables: Observable\u003cFeedbackQuestionRecipients\u003e[] \u003d [];"},{"lineNumber":1065,"author":{"gitId":"-"},"content":" const questionsToBeLoaded: QuestionSubmissionFormModel[] \u003d [];"},{"lineNumber":1066,"author":{"gitId":"-"},"content":""},{"lineNumber":1067,"author":{"gitId":"-"},"content":" this.questionSubmissionForms.forEach((model: QuestionSubmissionFormModel) \u003d\u003e {"},{"lineNumber":1068,"author":{"gitId":"-"},"content":" if (!model.isLoading \u0026\u0026 !model.isLoaded) {"},{"lineNumber":1069,"author":{"gitId":"-"},"content":" questionsToBeLoaded.push(model);"},{"lineNumber":1070,"author":{"gitId":"-"},"content":" recipientsObservables.push(this.feedbackQuestionsService.loadFeedbackQuestionRecipients({"},{"lineNumber":1071,"author":{"gitId":"-"},"content":" questionId: model.feedbackQuestionId,"},{"lineNumber":1072,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":1073,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":1074,"author":{"gitId":"-"},"content":" moderatedPerson: this.moderatedPerson,"},{"lineNumber":1075,"author":{"gitId":"-"},"content":" previewAs: this.previewAsPerson,"},{"lineNumber":1076,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":1077,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1078,"author":{"gitId":"-"},"content":" });"},{"lineNumber":1079,"author":{"gitId":"-"},"content":""},{"lineNumber":1080,"author":{"gitId":"-"},"content":" // Find the groupable and ungroupable questions and construct the recipient to question mapping."},{"lineNumber":1081,"author":{"gitId":"-"},"content":" forkJoin(recipientsObservables)"},{"lineNumber":1082,"author":{"gitId":"-"},"content":" .pipe(finalize(() \u003d\u003e {"},{"lineNumber":1083,"author":{"gitId":"-"},"content":" this.ungroupableQuestionsSorted \u003d Array.from(this.ungroupableQuestions).sort();"},{"lineNumber":1084,"author":{"gitId":"-"},"content":" this.hasLoadedAllRecipients \u003d true;"},{"lineNumber":1085,"author":{"gitId":"-"},"content":" }))"},{"lineNumber":1086,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":1087,"author":{"gitId":"-"},"content":" next: (feedbackQuestionRecipients: FeedbackQuestionRecipients[]) \u003d\u003e {"},{"lineNumber":1088,"author":{"gitId":"-"},"content":" for (let i \u003d 0; i \u003c feedbackQuestionRecipients.length; i +\u003d 1) {"},{"lineNumber":1089,"author":{"gitId":"-"},"content":" const question: QuestionSubmissionFormModel \u003d questionsToBeLoaded[i];"},{"lineNumber":1090,"author":{"gitId":"-"},"content":" // Only questions with question submission form mode being FIXED_RECIPIENT and with question type"},{"lineNumber":1091,"author":{"gitId":"-"},"content":" // not being CONSTSUM_RECIPIENTS, RANK_RECIPIENTS, and CONTRIB, are the groupable questions."},{"lineNumber":1092,"author":{"gitId":"-"},"content":" if (this.getQuestionSubmissionFormMode(question, feedbackQuestionRecipients[i].recipients.length)"},{"lineNumber":1093,"author":{"gitId":"-"},"content":" \u003d\u003d\u003d QuestionSubmissionFormMode.FIXED_RECIPIENT"},{"lineNumber":1094,"author":{"gitId":"-"},"content":" \u0026\u0026 question.questionType !\u003d\u003d FeedbackQuestionType.CONSTSUM_RECIPIENTS"},{"lineNumber":1095,"author":{"gitId":"-"},"content":" \u0026\u0026 question.questionType !\u003d\u003d FeedbackQuestionType.RANK_RECIPIENTS"},{"lineNumber":1096,"author":{"gitId":"-"},"content":" \u0026\u0026 question.questionType !\u003d\u003d FeedbackQuestionType.CONTRIB) {"},{"lineNumber":1097,"author":{"gitId":"-"},"content":""},{"lineNumber":1098,"author":{"gitId":"-"},"content":" for (let j \u003d 0; j \u003c feedbackQuestionRecipients[i].recipients.length; j +\u003d 1) {"},{"lineNumber":1099,"author":{"gitId":"-"},"content":" const recipient: FeedbackQuestionRecipient \u003d feedbackQuestionRecipients[i].recipients[j];"},{"lineNumber":1100,"author":{"gitId":"-"},"content":" this.addQuestionForRecipient(recipient.identifier, question.questionNumber);"},{"lineNumber":1101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1102,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1103,"author":{"gitId":"-"},"content":" this.ungroupableQuestions.add(question.questionNumber);"},{"lineNumber":1104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1105,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1106,"author":{"gitId":"-"},"content":" },"},{"lineNumber":1107,"author":{"gitId":"-"},"content":" error: () \u003d\u003e {"},{"lineNumber":1108,"author":{"gitId":"-"},"content":" this.statusMessageService.showWarningToast(\u0027Failed to build groupable questions\u0027);"},{"lineNumber":1109,"author":{"gitId":"-"},"content":" },"},{"lineNumber":1110,"author":{"gitId":"-"},"content":" },"},{"lineNumber":1111,"author":{"gitId":"-"},"content":" );"},{"lineNumber":1112,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1113,"author":{"gitId":"-"},"content":""},{"lineNumber":1114,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1115,"author":{"gitId":"-"},"content":" * Gets recipient name in {@code FIXED_RECIPIENT} mode and in {@code GROUP_RECIPIENTS} view."},{"lineNumber":1116,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1117,"author":{"gitId":"-"},"content":" getRecipientName(recipientIdentifier: string): string {"},{"lineNumber":1118,"author":{"gitId":"-"},"content":" const question: QuestionSubmissionFormModel | undefined \u003d"},{"lineNumber":1119,"author":{"gitId":"-"},"content":" this.questionSubmissionForms.find((model: QuestionSubmissionFormModel) \u003d\u003e"},{"lineNumber":1120,"author":{"gitId":"-"},"content":" model.questionNumber \u003d\u003d\u003d this.recipientQuestionMap.get(recipientIdentifier)!.values().next().value);"},{"lineNumber":1121,"author":{"gitId":"-"},"content":""},{"lineNumber":1122,"author":{"gitId":"-"},"content":" if (!question) {"},{"lineNumber":1123,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(\u0027Failed to build groupable questions\u0027);"},{"lineNumber":1124,"author":{"gitId":"-"},"content":" return \u0027Unknown\u0027;"},{"lineNumber":1125,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1126,"author":{"gitId":"-"},"content":""},{"lineNumber":1127,"author":{"gitId":"-"},"content":" const recipient: FeedbackResponseRecipient | undefined \u003d"},{"lineNumber":1128,"author":{"gitId":"-"},"content":" question!.recipientList.find("},{"lineNumber":1129,"author":{"gitId":"-"},"content":" (r: FeedbackResponseRecipient) \u003d\u003e r.recipientIdentifier \u003d\u003d\u003d recipientIdentifier);"},{"lineNumber":1130,"author":{"gitId":"-"},"content":""},{"lineNumber":1131,"author":{"gitId":"-"},"content":" return recipient ? recipient.recipientName : \u0027Unknown\u0027;"},{"lineNumber":1132,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1133,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":1134,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":1135,"author":{"gitId":"dishenggg"},"content":" * Logs student activity after student/session details have been fetched."},{"lineNumber":1136,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":1137,"author":{"gitId":"dishenggg"},"content":" logStudentAccess(): void {"},{"lineNumber":1138,"author":{"gitId":"dishenggg"},"content":" if (this.intent !\u003d\u003d Intent.STUDENT_SUBMISSION) {"},{"lineNumber":1139,"author":{"gitId":"dishenggg"},"content":" return;"},{"lineNumber":1140,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":1141,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":1142,"author":{"gitId":"dishenggg"},"content":" // dummy vars to check that both student and session has been loaded"},{"lineNumber":1143,"author":{"gitId":"dishenggg"},"content":" if (!this.personEmail || !this.feedbackSessionTimezone) {"},{"lineNumber":1144,"author":{"gitId":"dishenggg"},"content":" return;"},{"lineNumber":1145,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":1146,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":1147,"author":{"gitId":"dishenggg"},"content":" this.logService.createFeedbackSessionLog({"},{"lineNumber":1148,"author":{"gitId":"dishenggg"},"content":" courseId: this.courseId,"},{"lineNumber":1149,"author":{"gitId":"dishenggg"},"content":" feedbackSessionName: this.feedbackSessionName,"},{"lineNumber":1150,"author":{"gitId":"dishenggg"},"content":" studentEmail: this.personEmail,"},{"lineNumber":1151,"author":{"gitId":"dishenggg"},"content":" logType: FeedbackSessionLogType.ACCESS,"},{"lineNumber":1152,"author":{"gitId":"dishenggg"},"content":" feedbackSessionId: this.feedbackSessionId,"},{"lineNumber":1153,"author":{"gitId":"dishenggg"},"content":" studentId: this.studentId,"},{"lineNumber":1154,"author":{"gitId":"dishenggg"},"content":" }).subscribe();"},{"lineNumber":1155,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":1156,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":34,"-":1122}},{"path":"src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form-model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"export type InstructorRequestFormModel \u003d {"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":" name: string,"},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":" institution: string,"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":" country: string,"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":" email: string,"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":" comments: string,"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"};"}],"authorContributionMap":{"xenosf":7}},{"path":"src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"\u003cp aria-hidden\u003d\"true\"\u003e"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":" \u003c!-- aria-hidden as screen readers use inputs\u0027 required attribute instead (and cannot see the asterisks) --\u003e"},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":" Questions marked with an asterisk \u003cspan class\u003d\"red-font\"\u003e*\u003c/span\u003e are required."},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"\u003cform (ngSubmit)\u003d\"onSubmit()\" [formGroup]\u003d\"arf\"\u003e"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":" \u003cdiv class\u003d\"form-group {{checkIsFieldRequired(name) ? \u0027required\u0027 : \u0027\u0027}}\"\u003e"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":" \u003clabel for\u003d\"name\" id\u003d\"name-label\" class\u003d\"qn\"\u003e"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":" Full Name"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":" \u003c/label\u003e"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":" \u003cp class\u003d\"help-block\"\u003e"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":" This is the name that will be shown to your students. You may include salutation (Dr. Prof. etc.)"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" \u003c/p\u003e"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" \u003cinput class\u003d\"form-control {{getFieldValidationClasses(name)}}\" type\u003d\"text\" id\u003d\"name\" autocomplete\u003d\"name\""},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":" [formControl]\u003d\"name\" [required]\u003d\"checkIsFieldRequired(name)\" [attr.aria-invalid]\u003d\"name.invalid\"\u003e"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"name.errors?.[\u0027required\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"name-label\" tabindex\u003d\"0\" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" Please enter your name."},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"name.errors?.[\u0027maxlength\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"name-label\" tabindex\u003d\"0\" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":" Name must be shorter than {{STUDENT_NAME_MAX_LENGTH}} characters. (Current: {{name.value?.length}})"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"name.errors?.[\u0027pattern\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"name-label\" tabindex\u003d\"0\""},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" Name must start with an alphanumeric character (a-z, 0-9) and cannot contain any vertical bar (|) or percent sign (%)."},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" \u003cbr\u003e"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" \u003cdiv class\u003d\"form-group {{checkIsFieldRequired(institution) ? \u0027required\u0027 : \u0027\u0027}}\"\u003e"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" \u003clabel for\u003d\"institution\" id\u003d\"institution-label\" class\u003d\"qn\"\u003e"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" University/school/institution"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" \u003c/label\u003e"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" \u003cp class\u003d\"help-block\"\u003e"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" Please give full name of the university/institution."},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" \u003c/p\u003e"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" \u003cinput class\u003d\"form-control {{getFieldValidationClasses(institution)}}\" type\u003d\"text\" id\u003d\"institution\""},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" autocomplete\u003d\"organization\" [formControl]\u003d\"institution\" [required]\u003d\"checkIsFieldRequired(institution)\""},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" [attr.aria-invalid]\u003d\"institution.invalid\"\u003e"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"institution.errors?.[\u0027required\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"institution-label\" tabindex\u003d\"0\""},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" Please enter your institution name."},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"institution.errors?.[\u0027maxlength\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"institution-label\" tabindex\u003d\"0\""},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" Institution name must be shorter than {{INSTITUTION_NAME_MAX_LENGTH}} characters. (Current: {{institution.value?.length}})"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"institution.errors?.[\u0027pattern\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"institution-label\" tabindex\u003d\"0\""},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" Institution name must start with an alphanumeric character (a-z, 0-9) and cannot contain any vertical bar (|) or percent sign (%)."},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" \u003cbr\u003e"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" \u003cdiv class\u003d\"form-group {{checkIsFieldRequired(country) ? \u0027required\u0027 : \u0027\u0027}}\"\u003e"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" \u003clabel for\u003d\"country\" id\u003d\"country-label\" class\u003d\"qn\"\u003e"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" Country"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" \u003c/label\u003e"},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":" \u003cp class\u003d\"help-block\"\u003e"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" Which country is your university/institution based in?"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" \u003c/p\u003e"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" \u003cinput class\u003d\"form-control {{getFieldValidationClasses(country)}}\" type\u003d\"text\" id\u003d\"country\""},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" autocomplete\u003d\"country-name\" [formControl]\u003d\"country\" [required]\u003d\"checkIsFieldRequired(country)\""},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" [attr.aria-invalid]\u003d\"country.invalid\"\u003e"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"country.errors?.[\u0027required\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"country-label\" tabindex\u003d\"0\""},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" Please enter your institution\u0027s country."},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"country.errors?.[\u0027maxlength\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"country-label\" tabindex\u003d\"0\""},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":67,"author":{"gitId":"xenosf"},"content":" Country name must be shorter than {{COUNTRY_NAME_MAX_LENGTH}} characters. (Current: {{country.value?.length}})"},{"lineNumber":68,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"country.errors?.[\u0027pattern\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"country-label\" tabindex\u003d\"0\""},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" Country name must start with an alphanumeric character (a-z, 0-9) and cannot contain any vertical bar (|) or percent sign (%)."},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" \u003cbr\u003e"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" \u003cdiv class\u003d\"form-group {{checkIsFieldRequired(email) ? \u0027required\u0027 : \u0027\u0027}}\"\u003e"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" \u003clabel for\u003d\"email\" id\u003d\"email-label\" class\u003d\"qn\"\u003e"},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":" Official email address"},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" \u003c/label\u003e"},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":" \u003cp class\u003d\"help-block\"\u003e"},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" Please use the email address \u003cb\u003egiven to you by your school/university\u003c/b\u003e"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":" (not your personal Gmail/Hotmail address)."},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":" Note that this email address will be visible to the students you enroll in TEAMMATES."},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" \u003c/p\u003e"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":" \u003cinput class\u003d\"form-control {{getFieldValidationClasses(email)}}\" type\u003d\"email\" id\u003d\"email\" autocomplete\u003d\"email\""},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":" [formControl]\u003d\"email\" [required]\u003d\"checkIsFieldRequired(email)\" [attr.aria-invalid]\u003d\"email.invalid\"\u003e"},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"email.errors?.[\u0027required\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"email-label\" tabindex\u003d\"0\""},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" Please enter your email address."},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"email.errors?.[\u0027maxlength\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"email-label\" tabindex\u003d\"0\""},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":" Email address must be shorter than {{EMAIL_MAX_LENGTH}} characters. (Current: {{email.value?.length}})"},{"lineNumber":93,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":94,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"email.errors?.[\u0027pattern\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"email-label\" tabindex\u003d\"0\""},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":" Please enter a valid email address."},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" \u003cbr\u003e"},{"lineNumber":100,"author":{"gitId":"xenosf"},"content":" \u003cdiv class\u003d\"form-group {{checkIsFieldRequired(comments) ? \u0027required\u0027 : \u0027\u0027}}\"\u003e"},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":" \u003clabel for\u003d\"comments\" id\u003d\"comments-label\" class\u003d\"qn\"\u003e"},{"lineNumber":102,"author":{"gitId":"xenosf"},"content":" Any other comments/queries"},{"lineNumber":103,"author":{"gitId":"xenosf"},"content":" \u003c/label\u003e"},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" \u003ctextarea class\u003d\"form-control {{getFieldValidationClasses(comments)}}\" id\u003d\"comments\" [formControl]\u003d\"comments\""},{"lineNumber":105,"author":{"gitId":"xenosf"},"content":" [attr.aria-invalid]\u003d\"comments.invalid\"\u003e\u003c/textarea\u003e"},{"lineNumber":106,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":107,"author":{"gitId":"xenosf"},"content":" \u003cbr\u003e"},{"lineNumber":108,"author":{"gitId":"xenosf"},"content":" \u003cngb-alert type\u003d\"danger\" [dismissible]\u003d\"false\" *ngIf\u003d\"hasSubmitAttempt \u0026\u0026 arf.invalid\" class\u003d\"error-box\"\u003e"},{"lineNumber":109,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003eThere was a problem with your submission.\u003c/strong\u003e Please check and fix the errors above and submit again."},{"lineNumber":110,"author":{"gitId":"xenosf"},"content":" \u003c/ngb-alert\u003e"},{"lineNumber":111,"author":{"gitId":"xenosf"},"content":" \u003cngb-alert type\u003d\"danger\" [dismissible]\u003d\"false\" *ngIf\u003d\"serverErrorMessage\" class\u003d\"error-box\"\u003e"},{"lineNumber":112,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003eError submitting request:\u003c/strong\u003e {{serverErrorMessage}}"},{"lineNumber":113,"author":{"gitId":"xenosf"},"content":" \u003c/ngb-alert\u003e"},{"lineNumber":114,"author":{"gitId":"xenosf"},"content":" \u003cbutton type\u003d\"submit\" class\u003d\"btn btn-primary\" id\u003d\"submit-button\" [disabled]\u003d\"!canSubmit\"\u003e"},{"lineNumber":115,"author":{"gitId":"xenosf"},"content":" {{isLoading ? \"Submitting...\" : \"Submit\"}}"},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" \u003c/button\u003e"},{"lineNumber":117,"author":{"gitId":"xenosf"},"content":"\u003c/form\u003e"}],"authorContributionMap":{"xenosf":116,"dishenggg":1}},{"path":"src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.scss","fileType":"scss","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"label.qn {"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":" font-weight: bold;"},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":" font-size: 1rem;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":" margin-bottom: 0.3rem;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"}"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":".form-group {"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":" margin-bottom: 0.5rem;"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":"}"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":".form-group.required \u003e label::after {"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" content:\"*\";"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" color: red;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":"}"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":".help-block {"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" margin-bottom: 0.8rem;"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":"}"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":".red-font {"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" color: red;"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":"}"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":".error-box {"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" margin: 1rem 0;"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":26}},{"path":"src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"import { ComponentFixture, TestBed, waitForAsync } from \u0027@angular/core/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":"import { ReactiveFormsModule } from \u0027@angular/forms\u0027;"},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import { By } from \u0027@angular/platform-browser\u0027;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import { Observable, first } from \u0027rxjs\u0027;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import { InstructorRequestFormModel } from \u0027./instructor-request-form-model\u0027;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import { InstructorRequestFormComponent } from \u0027./instructor-request-form.component\u0027;"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import { AccountService } from \u0027../../../../services/account.service\u0027;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":"import { AccountCreateRequest } from \u0027../../../../types/api-request\u0027;"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"describe(\u0027InstructorRequestFormComponent\u0027, () \u003d\u003e {"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":" let component: InstructorRequestFormComponent;"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" let fixture: ComponentFixture\u003cInstructorRequestFormComponent\u003e;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" let accountService: AccountService;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":" const typicalModel: InstructorRequestFormModel \u003d {"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":" name: \u0027John Doe\u0027,"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" institution: \u0027Example Institution\u0027,"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" country: \u0027Example Country\u0027,"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":" email: \u0027jd@example.edu\u0027,"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":" comments: \u0027\u0027,"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" const typicalCreateRequest: AccountCreateRequest \u003d {"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" instructorEmail: typicalModel.email,"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" instructorName: typicalModel.name,"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" instructorInstitution: `${typicalModel.institution}, ${typicalModel.country}`,"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" const accountServiceStub: Partial\u003cAccountService\u003e \u003d {"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" createAccountRequest: () \u003d\u003e new Observable((subscriber) \u003d\u003e {"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" subscriber.next();"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" }),"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" * Fills in form fields with the given data."},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" * @param data Data to fill form with."},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" function fillFormWith(data: InstructorRequestFormModel): void {"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" component.name.setValue(data.name);"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" component.institution.setValue(data.institution);"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" component.country.setValue(data.country);"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" component.email.setValue(data.email);"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" component.comments.setValue(data.comments);"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" beforeEach(waitForAsync(() \u003d\u003e {"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" TestBed.configureTestingModule({"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" declarations: [InstructorRequestFormComponent],"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" imports: [ReactiveFormsModule],"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" providers: [{ provide: AccountService, useValue: accountServiceStub }],"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" })"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" .compileComponents();"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" }));"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" fixture \u003d TestBed.createComponent(InstructorRequestFormComponent);"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" accountService \u003d TestBed.inject(AccountService);"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" fixture.detectChanges();"},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" jest.clearAllMocks();"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" expect(component).toBeTruthy();"},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":67,"author":{"gitId":"xenosf"},"content":" it(\u0027should render correctly\u0027, () \u003d\u003e {"},{"lineNumber":68,"author":{"gitId":"xenosf"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" it(\u0027should run onSubmit() when submit button is clicked\u0027, () \u003d\u003e {"},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" jest.spyOn(component, \u0027onSubmit\u0027);"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" fillFormWith(typicalModel);"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" const submitButton \u003d fixture.debugElement.query(By.css(\u0027#submit-button\u0027));"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" submitButton.nativeElement.click();"},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" expect(component.onSubmit).toHaveBeenCalledTimes(1);"},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":" it(\u0027should emit requestSubmissionEvent with the correct data when form is submitted\u0027, () \u003d\u003e {"},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":" jest.spyOn(accountService, \u0027createAccountRequest\u0027).mockReturnValue("},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" new Observable((subscriber) \u003d\u003e { subscriber.next(); }));"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":" // Listen for emitted value"},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":" let actualModel: InstructorRequestFormModel | null \u003d null;"},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":" component.requestSubmissionEvent.pipe(first())"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" .subscribe((data: InstructorRequestFormModel) \u003d\u003e { actualModel \u003d data; });"},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" fillFormWith(typicalModel);"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":" component.onSubmit();"},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":93,"author":{"gitId":"xenosf"},"content":" expect(actualModel).toBeTruthy();"},{"lineNumber":94,"author":{"gitId":"xenosf"},"content":" expect(actualModel!.name).toBe(typicalModel.name);"},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":" expect(actualModel!.institution).toBe(typicalModel.institution);"},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":" expect(actualModel!.country).toBe(typicalModel.country);"},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" expect(actualModel!.email).toBe(typicalModel.email);"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" expect(actualModel!.comments).toBe(typicalModel.comments);"},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":100,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":" it(\u0027should send the correct request data when form is submitted\u0027, () \u003d\u003e {"},{"lineNumber":102,"author":{"gitId":"xenosf"},"content":" jest.spyOn(accountService, \u0027createAccountRequest\u0027).mockReturnValue("},{"lineNumber":103,"author":{"gitId":"xenosf"},"content":" new Observable((subscriber) \u003d\u003e { subscriber.next(); }));"},{"lineNumber":104,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":105,"author":{"gitId":"xenosf"},"content":" fillFormWith(typicalModel);"},{"lineNumber":106,"author":{"gitId":"xenosf"},"content":" component.onSubmit();"},{"lineNumber":107,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":108,"author":{"gitId":"xenosf"},"content":" expect(accountService.createAccountRequest).toHaveBeenCalledTimes(1);"},{"lineNumber":109,"author":{"gitId":"xenosf"},"content":" expect(accountService.createAccountRequest).toHaveBeenCalledWith(expect.objectContaining(typicalCreateRequest));"},{"lineNumber":110,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":111,"author":{"gitId":"xenosf"},"content":"});"}],"authorContributionMap":{"xenosf":111}},{"path":"src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"import { Component, EventEmitter, Output } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":"import { FormControl, FormGroup, Validators } from \u0027@angular/forms\u0027;"},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import { finalize } from \u0027rxjs\u0027;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import { InstructorRequestFormModel } from \u0027./instructor-request-form-model\u0027;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import { AccountService } from \u0027../../../../services/account.service\u0027;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import { AccountCreateRequest } from \u0027../../../../types/api-request\u0027;"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import { FormValidator } from \u0027../../../../types/form-validator\u0027;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":"import { ErrorMessageOutput } from \u0027../../../error-message-output\u0027;"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"@Component({"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":" selector: \u0027tm-instructor-request-form\u0027,"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" templateUrl: \u0027./instructor-request-form.component.html\u0027,"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" styleUrls: [\u0027./instructor-request-form.component.scss\u0027],"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":"})"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"export class InstructorRequestFormComponent {"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" constructor(private accountService: AccountService) {}"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":" // Create members to be accessed in template"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" readonly STUDENT_NAME_MAX_LENGTH \u003d FormValidator.STUDENT_NAME_MAX_LENGTH;"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" readonly INSTITUTION_NAME_MAX_LENGTH \u003d FormValidator.INSTITUTION_NAME_MAX_LENGTH;"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" readonly COUNTRY_NAME_MAX_LENGTH \u003d FormValidator.COUNTRY_NAME_MAX_LENGTH;"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" readonly EMAIL_MAX_LENGTH \u003d FormValidator.EMAIL_MAX_LENGTH;"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" arf \u003d new FormGroup({"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" name: new FormControl(\u0027\u0027, ["},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" Validators.required,"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" Validators.maxLength(FormValidator.STUDENT_NAME_MAX_LENGTH),"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" Validators.pattern(FormValidator.NAME_REGEX),"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" ]),"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" institution: new FormControl(\u0027\u0027, ["},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" Validators.required,"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" Validators.maxLength(FormValidator.INSTITUTION_NAME_MAX_LENGTH),"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" Validators.pattern(FormValidator.NAME_REGEX),"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" ]),"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" country: new FormControl(\u0027\u0027, ["},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" Validators.required,"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" Validators.maxLength(FormValidator.COUNTRY_NAME_MAX_LENGTH),"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" Validators.pattern(FormValidator.NAME_REGEX),"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" ]),"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" email: new FormControl(\u0027\u0027, ["},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" Validators.required,"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" Validators.pattern(FormValidator.EMAIL_REGEX),"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" Validators.maxLength(FormValidator.EMAIL_MAX_LENGTH),"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" ]),"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" comments: new FormControl(\u0027\u0027),"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" }, { updateOn: \u0027submit\u0027 });"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" // Create members for easier access of arf controls"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" name \u003d this.arf.controls.name;"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" institution \u003d this.arf.controls.institution;"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" country \u003d this.arf.controls.country;"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" email \u003d this.arf.controls.email;"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" comments \u003d this.arf.controls.comments;"},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" hasSubmitAttempt \u003d false;"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" isLoading \u003d false;"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" @Output() requestSubmissionEvent \u003d new EventEmitter\u003cInstructorRequestFormModel\u003e();"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" serverErrorMessage \u003d \u0027\u0027;"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" checkIsFieldRequired(field: FormControl): boolean {"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" return field.hasValidator(Validators.required);"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":" get canSubmit(): boolean {"},{"lineNumber":67,"author":{"gitId":"xenosf"},"content":" return !this.isLoading;"},{"lineNumber":68,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":" getFieldValidationClasses(field: FormControl): string {"},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" let str \u003d \u0027\u0027;"},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" if (this.hasSubmitAttempt) {"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":" if (field.invalid) {"},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" str \u003d \u0027is-invalid\u0027;"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" } else if (field.value !\u003d\u003d \u0027\u0027) {"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" str \u003d \u0027is-valid\u0027;"},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":" return str;"},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":" onSubmit(): void {"},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" this.hasSubmitAttempt \u003d true;"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":" this.isLoading \u003d true;"},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":" this.serverErrorMessage \u003d \u0027\u0027;"},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":" if (this.arf.invalid) {"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" this.isLoading \u003d false;"},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":" // Do not submit form"},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" return;"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":93,"author":{"gitId":"xenosf"},"content":" const name \u003d this.name.value!.trim();"},{"lineNumber":94,"author":{"gitId":"xenosf"},"content":" const email \u003d this.email.value!.trim();"},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":" const comments \u003d this.comments.value!.trim();"},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" // Combine country and institution"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" const country \u003d this.country.value!.trim();"},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" const institution \u003d this.institution.value!.trim();"},{"lineNumber":100,"author":{"gitId":"xenosf"},"content":" const combinedInstitution \u003d `${institution}, ${country}`;"},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":102,"author":{"gitId":"xenosf"},"content":" const requestData: AccountCreateRequest \u003d {"},{"lineNumber":103,"author":{"gitId":"xenosf"},"content":" instructorEmail: email,"},{"lineNumber":104,"author":{"gitId":"xenosf"},"content":" instructorName: name,"},{"lineNumber":105,"author":{"gitId":"xenosf"},"content":" instructorInstitution: combinedInstitution,"},{"lineNumber":106,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":107,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":108,"author":{"gitId":"xenosf"},"content":" if (comments) {"},{"lineNumber":109,"author":{"gitId":"xenosf"},"content":" requestData.instructorComments \u003d comments;"},{"lineNumber":110,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":111,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":112,"author":{"gitId":"xenosf"},"content":" this.accountService.createAccountRequest(requestData)"},{"lineNumber":113,"author":{"gitId":"xenosf"},"content":" .pipe(finalize(() \u003d\u003e { this.isLoading \u003d false; }))"},{"lineNumber":114,"author":{"gitId":"xenosf"},"content":" .subscribe({"},{"lineNumber":115,"author":{"gitId":"xenosf"},"content":" next: () \u003d\u003e {"},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" // Pass form input to parent to display confirmation"},{"lineNumber":117,"author":{"gitId":"xenosf"},"content":" this.requestSubmissionEvent.emit({"},{"lineNumber":118,"author":{"gitId":"xenosf"},"content":" name,"},{"lineNumber":119,"author":{"gitId":"xenosf"},"content":" institution,"},{"lineNumber":120,"author":{"gitId":"xenosf"},"content":" country,"},{"lineNumber":121,"author":{"gitId":"xenosf"},"content":" email,"},{"lineNumber":122,"author":{"gitId":"xenosf"},"content":" comments,"},{"lineNumber":123,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":124,"author":{"gitId":"xenosf"},"content":" },"},{"lineNumber":125,"author":{"gitId":"xenosf"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":126,"author":{"gitId":"xenosf"},"content":" this.serverErrorMessage \u003d resp.error.message;"},{"lineNumber":127,"author":{"gitId":"xenosf"},"content":" },"},{"lineNumber":128,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":129,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":130,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":130}},{"path":"src/web/app/pages-static/request-page/request-page.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003ch1 class\u003d\"color-orange\"\u003e"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":" Request for an Instructor Account"},{"lineNumber":3,"author":{"gitId":"-"},"content":"\u003c/h1\u003e"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"\u003cdiv class\u003d\"col-xs-12 col-md-10 col-lg-8 col-xl-7 col-xxl-6\"\u003e"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"!submittedFormData\"\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003cp\u003e"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":" Request for an instructor account using this form if you are an instructor and want to use TEAMMATES to manage peer evaluations and/or other feedback paths of your students."},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":" \u003c/p\u003e"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":" \u003chr\u003e"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"!isDeclarationDone\"\u003e"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":" \u003cp\u003e"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" Note: \u003cb\u003eStudents should not use this form to request for TEAMMATES accounts\u003c/b\u003e, as students do not need accounts to use TEAMMATES. Instead, TEAMMATES will email students (who have been added to TEAMMATES by a course instructor) an access link when there is a TEAMMATES session available for them to access."},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" \u003c/p\u003e"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":" \u003ca type\u003d\"button\" class\u003d\"btn btn-secondary\" tmRouterLink\u003d\"/web/front/home\"\u003eBack to home page\u003c/a\u003e"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":" \u003cbutton id\u003d\"btn-am-instructor\" type\u003d\"button\" class\u003d\"btn btn-primary ms-3\" (click)\u003d\"onDeclarationButtonClicked()\"\u003eI am an instructor\u003c/button\u003e"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"isDeclarationDone\"\u003e"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":" \u003ctm-instructor-request-form *ngIf\u003d\"!submittedFormData\" (requestSubmissionEvent)\u003d\"onRequestSubmitted($event)\"\u003e\u003c/tm-instructor-request-form\u003e"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" \u003chr\u003e"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"submittedFormData\"\u003e"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" \u003cp\u003e"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" Your request has been submitted successfully:"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" \u003c/p\u003e"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" \u003ctable class\u003d\"table table-bordered my-3\"\u003e"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" \u003ctbody\u003e"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" \u003cth scope\u003d\"row\" class\u003d\"col-3\"\u003eFull Name\u003c/th\u003e"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" \u003ctd\u003e{{submittedFormData.name}}\u003c/td\u003e"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" \u003cth scope\u003d\"row\"\u003eInstitution\u003c/th\u003e"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" \u003ctd\u003e{{submittedFormData.institution}}\u003c/td\u003e"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" \u003cth scope\u003d\"row\"\u003eCountry\u003c/th\u003e"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" \u003ctd\u003e{{submittedFormData.country}}\u003c/td\u003e"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" \u003cth scope\u003d\"row\"\u003eEmail\u003c/th\u003e"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" \u003ctd\u003e{{submittedFormData.email}}\u003c/td\u003e"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" \u003cth scope\u003d\"row\"\u003eComments\u003c/th\u003e"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" \u003ctd\u003e"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" {{submittedFormData.comments}}"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" \u003cspan class\u003d\"empty-field-placeholder\" *ngIf\u003d\"!submittedFormData.comments\"\u003e\u003c/span\u003e"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" \u003c/tbody\u003e"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" \u003c/table\u003e"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" \u003cp\u003e"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" We have sent an acknowledgement email to your email address \u003cb\u003e{{submittedFormData.email}}\u003c/b\u003e."},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":" Please check your email inbox or spam folder."},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" If you do not receive the acknowledgement email within 1 hour, please \u003ca tmRouterLink\u003d\"/web/front/contact\"\u003econtact\u003c/a\u003e us."},{"lineNumber":57,"author":{"gitId":"-"},"content":" \u003c/p\u003e"},{"lineNumber":58,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":59,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"xenosf":52,"dishenggg":1,"-":6}},{"path":"src/web/app/pages-static/request-page/request-page.component.scss","fileType":"scss","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":".empty-field-placeholder::after {"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":" content: \"(empty)\";"},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":" opacity: 0.5;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":" font-style: italic;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":5}},{"path":"src/web/app/pages-static/request-page/request-page.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { ComponentFixture, TestBed, waitForAsync } from \u0027@angular/core/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { RequestPageComponent } from \u0027./request-page.component\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":""},{"lineNumber":4,"author":{"gitId":"-"},"content":"describe(\u0027RequestPageComponent\u0027, () \u003d\u003e {"},{"lineNumber":5,"author":{"gitId":"-"},"content":" let component: RequestPageComponent;"},{"lineNumber":6,"author":{"gitId":"-"},"content":" let fixture: ComponentFixture\u003cRequestPageComponent\u003e;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":" beforeEach(waitForAsync(() \u003d\u003e {"},{"lineNumber":9,"author":{"gitId":"-"},"content":" TestBed.configureTestingModule({"},{"lineNumber":10,"author":{"gitId":"-"},"content":" declarations: [RequestPageComponent],"},{"lineNumber":11,"author":{"gitId":"-"},"content":" })"},{"lineNumber":12,"author":{"gitId":"-"},"content":" .compileComponents();"},{"lineNumber":13,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":16,"author":{"gitId":"-"},"content":" fixture \u003d TestBed.createComponent(RequestPageComponent);"},{"lineNumber":17,"author":{"gitId":"-"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":18,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":19,"author":{"gitId":"-"},"content":" });"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" expect(component).toBeTruthy();"},{"lineNumber":23,"author":{"gitId":"-"},"content":" });"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" it(\u0027should render correctly before instructor declaration is done\u0027, () \u003d\u003e {"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" component.isDeclarationDone \u003d false;"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" component.submittedFormData \u003d null;"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" fixture.detectChanges();"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" it(\u0027should render correctly after instructor declaration is done\u0027, () \u003d\u003e {"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" component.isDeclarationDone \u003d true;"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" component.submittedFormData \u003d null;"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" fixture.detectChanges();"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" it(\u0027should render correctly after form is submitted\u0027, () \u003d\u003e {"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" component.submittedFormData \u003d {"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" name: \u0027Jane Smith\u0027,"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" institution: \u0027University of Example\u0027,"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" country: \u0027Example Republic\u0027,"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" email: \u0027js@exampleu.edu\u0027,"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" comments: \u0027\u0027,"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" fixture.detectChanges();"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":50,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"xenosf":26,"-":24}},{"path":"src/web/app/pages-static/request-page/request-page.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { DomSanitizer, SafeResourceUrl } from \u0027@angular/platform-browser\u0027;"},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import { InstructorRequestFormModel } from \u0027./instructor-request-form/instructor-request-form-model\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { environment } from \u0027../../../environments/environment\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":7,"author":{"gitId":"-"},"content":" * Account request page."},{"lineNumber":8,"author":{"gitId":"-"},"content":" */"},{"lineNumber":9,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":10,"author":{"gitId":"-"},"content":" selector: \u0027tm-request-page\u0027,"},{"lineNumber":11,"author":{"gitId":"-"},"content":" templateUrl: \u0027./request-page.component.html\u0027,"},{"lineNumber":12,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./request-page.component.scss\u0027],"},{"lineNumber":13,"author":{"gitId":"-"},"content":"})"},{"lineNumber":14,"author":{"gitId":"-"},"content":"export class RequestPageComponent {"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":" accountRequestFormUrl: SafeResourceUrl | null;"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" isDeclarationDone: boolean \u003d false;"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":" submittedFormData: InstructorRequestFormModel | null \u003d null;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" constructor(private sanitizer: DomSanitizer) {"},{"lineNumber":21,"author":{"gitId":"-"},"content":" this.accountRequestFormUrl \u003d environment.accountRequestFormUrl"},{"lineNumber":22,"author":{"gitId":"-"},"content":" ? this.sanitizer.bypassSecurityTrustResourceUrl(environment.accountRequestFormUrl)"},{"lineNumber":23,"author":{"gitId":"-"},"content":" : null;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" }"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" onDeclarationButtonClicked(): void {"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" this.isDeclarationDone \u003d true;"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" onRequestSubmitted(data: InstructorRequestFormModel): void {"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" this.submittedFormData \u003d data;"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":33,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":10,"-":23}},{"path":"src/web/app/pages-static/request-page/request-page.module.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { CommonModule } from \u0027@angular/common\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { NgModule } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import { ReactiveFormsModule } from \u0027@angular/forms\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { RouterModule, Routes } from \u0027@angular/router\u0027;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import { NgbAlertModule } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import { InstructorRequestFormComponent } from \u0027./instructor-request-form/instructor-request-form.component\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { RequestPageComponent } from \u0027./request-page.component\u0027;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":"import { TeammatesRouterModule } from \u0027../../components/teammates-router/teammates-router.module\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"const routes: Routes \u003d ["},{"lineNumber":11,"author":{"gitId":"-"},"content":" {"},{"lineNumber":12,"author":{"gitId":"-"},"content":" path: \u0027\u0027,"},{"lineNumber":13,"author":{"gitId":"-"},"content":" component: RequestPageComponent,"},{"lineNumber":14,"author":{"gitId":"-"},"content":" },"},{"lineNumber":15,"author":{"gitId":"-"},"content":"];"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * Module for request page."},{"lineNumber":19,"author":{"gitId":"-"},"content":" */"},{"lineNumber":20,"author":{"gitId":"-"},"content":"@NgModule({"},{"lineNumber":21,"author":{"gitId":"-"},"content":" declarations: ["},{"lineNumber":22,"author":{"gitId":"-"},"content":" RequestPageComponent,"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" InstructorRequestFormComponent,"},{"lineNumber":24,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":25,"author":{"gitId":"-"},"content":" exports: ["},{"lineNumber":26,"author":{"gitId":"-"},"content":" RequestPageComponent,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":28,"author":{"gitId":"-"},"content":" imports: ["},{"lineNumber":29,"author":{"gitId":"-"},"content":" CommonModule,"},{"lineNumber":30,"author":{"gitId":"-"},"content":" RouterModule.forChild(routes),"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" TeammatesRouterModule,"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" ReactiveFormsModule,"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" NgbAlertModule,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":35,"author":{"gitId":"-"},"content":"})"},{"lineNumber":36,"author":{"gitId":"-"},"content":"export class RequestPageModule { }"}],"authorContributionMap":{"xenosf":8,"-":28}},{"path":"src/web/services/account.service.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { HttpClientTestingModule } from \u0027@angular/common/http/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { TestBed } from \u0027@angular/core/testing\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { AccountService } from \u0027./account.service\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { HttpRequestService } from \u0027./http-request.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import createSpyFromClass from \u0027../test-helpers/create-spy-from-class\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { ResourceEndpoints } from \u0027../types/api-const\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { AccountCreateRequest } from \u0027../types/api-request\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"describe(\u0027AccountService\u0027, () \u003d\u003e {"},{"lineNumber":10,"author":{"gitId":"-"},"content":" let spyHttpRequestService: any;"},{"lineNumber":11,"author":{"gitId":"-"},"content":" let service: AccountService;"},{"lineNumber":12,"author":{"gitId":"-"},"content":" const id: string \u003d \u0027TestID\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":15,"author":{"gitId":"-"},"content":" spyHttpRequestService \u003d createSpyFromClass(HttpRequestService);"},{"lineNumber":16,"author":{"gitId":"-"},"content":" TestBed.configureTestingModule({"},{"lineNumber":17,"author":{"gitId":"-"},"content":" imports: ["},{"lineNumber":18,"author":{"gitId":"-"},"content":" HttpClientTestingModule,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":20,"author":{"gitId":"-"},"content":" providers: ["},{"lineNumber":21,"author":{"gitId":"-"},"content":" { provide: HttpRequestService, useValue: spyHttpRequestService },"},{"lineNumber":22,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":23,"author":{"gitId":"-"},"content":" });"},{"lineNumber":24,"author":{"gitId":"-"},"content":" service \u003d TestBed.inject(AccountService);"},{"lineNumber":25,"author":{"gitId":"-"},"content":" });"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" it(\u0027should be created\u0027, () \u003d\u003e {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" expect(service).toBeTruthy();"},{"lineNumber":29,"author":{"gitId":"-"},"content":" });"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" it(\u0027should execute GET on account endpoint\u0027, () \u003d\u003e {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" service.getAccount(id);"},{"lineNumber":33,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" instructorid: id,"},{"lineNumber":35,"author":{"gitId":"-"},"content":" };"},{"lineNumber":36,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.get).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNT, paramMap);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" });"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" it(\u0027should execute GET on accounts endpoint\u0027, () \u003d\u003e {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" const email \u003d \u0027email@gmail.tmt\u0027;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" service.getAccounts(email);"},{"lineNumber":42,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" useremail: email,"},{"lineNumber":44,"author":{"gitId":"-"},"content":" };"},{"lineNumber":45,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.get).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNTS, paramMap);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" });"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" it(\u0027should execute POST on account endpoint with timezone string\u0027, () \u003d\u003e {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" const testKey: string \u003d \u0027testKey\u0027;"},{"lineNumber":50,"author":{"gitId":"-"},"content":" const testTimezone: string \u003d \u0027UTC\u0027;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" key: testKey,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" timezone: testTimezone,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" };"},{"lineNumber":55,"author":{"gitId":"-"},"content":" service.createAccount(testKey, testTimezone);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.post).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNT, paramMap);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" });"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" it(\u0027should execute POST on account endpoint with empty timezone string\u0027, () \u003d\u003e {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" const testKey: string \u003d \u0027testKey\u0027;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" key: testKey,"},{"lineNumber":63,"author":{"gitId":"-"},"content":" };"},{"lineNumber":64,"author":{"gitId":"-"},"content":" service.createAccount(testKey, \u0027\u0027);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.post).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNT, paramMap);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" });"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" it(\u0027should execute POST on account request endpoint\u0027, () \u003d\u003e {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" const testRequest: AccountCreateRequest \u003d {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" instructorEmail: \u0027testEmail\u0027,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" instructorInstitution: \u0027testInstitution\u0027,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" instructorName: \u0027testName\u0027,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" };"},{"lineNumber":74,"author":{"gitId":"-"},"content":" service.createAccountRequest(testRequest);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.post).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNT_REQUEST, {}, testRequest);"},{"lineNumber":76,"author":{"gitId":"-"},"content":" });"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" it(\u0027should execute DELETE on account endpoint\u0027, () \u003d\u003e {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" service.deleteAccount(id);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":81,"author":{"gitId":"-"},"content":" instructorid: id,"},{"lineNumber":82,"author":{"gitId":"-"},"content":" };"},{"lineNumber":83,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.delete).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNT, paramMap);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" });"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" it(\u0027should execute DELETE on account request endpoint\u0027, () \u003d\u003e {"},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" service.deleteAccountRequest(\u0027testId\u0027);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":" id: \u0027testId\u0027,"},{"lineNumber":90,"author":{"gitId":"-"},"content":" };"},{"lineNumber":91,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.delete).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNT_REQUEST, paramMap);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" });"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" it(\u0027should execute PUT on account request reset endpoint\u0027, () \u003d\u003e {"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" service.resetAccountRequest(\u0027testId\u0027);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" id: \u0027testId\u0027,"},{"lineNumber":98,"author":{"gitId":"-"},"content":" };"},{"lineNumber":99,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.put).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNT_REQUEST_RESET, paramMap);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" });"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" it(\u0027should execute PUT on account/reset endpoint for student\u0027, () \u003d\u003e {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" service.resetStudentAccount(id, \u0027testStudentEmail\u0027);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" courseid: id,"},{"lineNumber":106,"author":{"gitId":"-"},"content":" studentemail: \u0027testStudentEmail\u0027,"},{"lineNumber":107,"author":{"gitId":"-"},"content":" };"},{"lineNumber":108,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.put).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNT_RESET, paramMap);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" });"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" it(\u0027should execute PUT on account/reset endpoint for instructor\u0027, () \u003d\u003e {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" service.resetInstructorAccount(id, \u0027testInstructorEmail\u0027);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":114,"author":{"gitId":"-"},"content":" courseid: id,"},{"lineNumber":115,"author":{"gitId":"-"},"content":" instructoremail: \u0027testInstructorEmail\u0027,"},{"lineNumber":116,"author":{"gitId":"-"},"content":" };"},{"lineNumber":117,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.put).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNT_RESET, paramMap);"},{"lineNumber":118,"author":{"gitId":"-"},"content":" });"},{"lineNumber":119,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"dishenggg":4,"-":115}},{"path":"src/web/services/account.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { HttpRequestService } from \u0027./http-request.service\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { ResourceEndpoints } from \u0027../types/api-const\u0027;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import {"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":" Account,"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":" AccountRequest,"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" Accounts,"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":" AccountRequests,"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" JoinLink,"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" MessageOutput,"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":" AccountRequestStatus,"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"} from \u0027../types/api-output\u0027;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import {"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" AccountCreateRequest,"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" AccountRequestUpdateRequest,"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" AccountRequestRejectionRequest,"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"} from \u0027../types/api-request\u0027;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":21,"author":{"gitId":"-"},"content":" * Handles account related logic provision"},{"lineNumber":22,"author":{"gitId":"-"},"content":" */"},{"lineNumber":23,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":24,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027,"},{"lineNumber":25,"author":{"gitId":"-"},"content":"})"},{"lineNumber":26,"author":{"gitId":"-"},"content":"export class AccountService {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" constructor(private httpRequestService: HttpRequestService) {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" }"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":31,"author":{"gitId":"-"},"content":" * Creates an account by calling API."},{"lineNumber":32,"author":{"gitId":"-"},"content":" */"},{"lineNumber":33,"author":{"gitId":"-"},"content":" createAccount(key: string, timezone: string): Observable\u003cMessageOutput\u003e {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d { key };"},{"lineNumber":35,"author":{"gitId":"-"},"content":" if (timezone) {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" paramMap[\u0027timezone\u0027] \u003d timezone;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" }"},{"lineNumber":38,"author":{"gitId":"-"},"content":" return this.httpRequestService.post(ResourceEndpoints.ACCOUNT, paramMap);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":42,"author":{"gitId":"-"},"content":" * Creates an account request by calling API."},{"lineNumber":43,"author":{"gitId":"-"},"content":" */"},{"lineNumber":44,"author":{"gitId":"-"},"content":" createAccountRequest(request: AccountCreateRequest): Observable\u003cAccountRequest\u003e {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" return this.httpRequestService.post(ResourceEndpoints.ACCOUNT_REQUEST, {}, request);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":49,"author":{"gitId":"-"},"content":" * Deletes an account by calling API."},{"lineNumber":50,"author":{"gitId":"-"},"content":" */"},{"lineNumber":51,"author":{"gitId":"-"},"content":" deleteAccount(id: string): Observable\u003cMessageOutput\u003e {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" instructorid: id,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" };"},{"lineNumber":55,"author":{"gitId":"-"},"content":" return this.httpRequestService.delete(ResourceEndpoints.ACCOUNT, paramMap);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":59,"author":{"gitId":"-"},"content":" * Deletes an account request by calling API."},{"lineNumber":60,"author":{"gitId":"-"},"content":" */"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" deleteAccountRequest(id: string): Observable\u003cMessageOutput\u003e {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" id,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" };"},{"lineNumber":65,"author":{"gitId":"-"},"content":" return this.httpRequestService.delete(ResourceEndpoints.ACCOUNT_REQUEST, paramMap);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":69,"author":{"gitId":"-"},"content":" * Resets an account request by calling API."},{"lineNumber":70,"author":{"gitId":"-"},"content":" */"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" resetAccountRequest(id: string): Observable\u003cJoinLink\u003e {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" id,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" };"},{"lineNumber":75,"author":{"gitId":"-"},"content":" return this.httpRequestService.put(ResourceEndpoints.ACCOUNT_REQUEST_RESET, paramMap);"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":79,"author":{"gitId":"-"},"content":" * Resets a student account by calling API."},{"lineNumber":80,"author":{"gitId":"-"},"content":" */"},{"lineNumber":81,"author":{"gitId":"-"},"content":" resetStudentAccount(courseId: string, studentEmail: string): Observable\u003cMessageOutput\u003e {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" courseid: courseId,"},{"lineNumber":84,"author":{"gitId":"-"},"content":" studentemail: studentEmail,"},{"lineNumber":85,"author":{"gitId":"-"},"content":" };"},{"lineNumber":86,"author":{"gitId":"-"},"content":" return this.httpRequestService.put(ResourceEndpoints.ACCOUNT_RESET, paramMap);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" }"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":90,"author":{"gitId":"-"},"content":" * Resets an instructor account by calling API."},{"lineNumber":91,"author":{"gitId":"-"},"content":" */"},{"lineNumber":92,"author":{"gitId":"-"},"content":" resetInstructorAccount(courseId: string, instructorEmail: string): Observable\u003cMessageOutput\u003e {"},{"lineNumber":93,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" courseid: courseId,"},{"lineNumber":95,"author":{"gitId":"-"},"content":" instructoremail: instructorEmail,"},{"lineNumber":96,"author":{"gitId":"-"},"content":" };"},{"lineNumber":97,"author":{"gitId":"-"},"content":" return this.httpRequestService.put(ResourceEndpoints.ACCOUNT_RESET, paramMap);"},{"lineNumber":98,"author":{"gitId":"-"},"content":" }"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" * Approves account request by calling API"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":" approveAccountRequest(id: string, name: string, email: string, institute: string)"},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" : Observable\u003cAccountRequest\u003e {"},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" id,"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" const accountReqUpdateRequest : AccountRequestUpdateRequest \u003d {"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" name,"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" email,"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" institute,"},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus.APPROVED,"},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" return this.httpRequestService.put(ResourceEndpoints.ACCOUNT_REQUEST, paramMap, accountReqUpdateRequest);"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" * Edits an account request by calling API."},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":" editAccountRequest(id: string, name: string, email: string, institute: string,"},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus, comments: string)"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":" : Observable\u003cAccountRequest\u003e {"},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" id,"},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" const accountReqUpdateRequest : AccountRequestUpdateRequest \u003d {"},{"lineNumber":128,"author":{"gitId":"domoberzin"},"content":" name,"},{"lineNumber":129,"author":{"gitId":"domoberzin"},"content":" email,"},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":" institute,"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":" status,"},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":" comments,"},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":" return this.httpRequestService.put(ResourceEndpoints.ACCOUNT_REQUEST, paramMap, accountReqUpdateRequest);"},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":137,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":139,"author":{"gitId":"-"},"content":" * Gets an account by calling API."},{"lineNumber":140,"author":{"gitId":"-"},"content":" */"},{"lineNumber":141,"author":{"gitId":"-"},"content":" getAccount(googleId: string): Observable\u003cAccount\u003e {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" instructorid: googleId,"},{"lineNumber":144,"author":{"gitId":"-"},"content":" };"},{"lineNumber":145,"author":{"gitId":"-"},"content":" return this.httpRequestService.get(ResourceEndpoints.ACCOUNT, paramMap);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" }"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":149,"author":{"gitId":"-"},"content":" * Gets accounts by calling API."},{"lineNumber":150,"author":{"gitId":"-"},"content":" */"},{"lineNumber":151,"author":{"gitId":"-"},"content":" getAccounts(email: string): Observable\u003cAccounts\u003e {"},{"lineNumber":152,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" useremail: email,"},{"lineNumber":154,"author":{"gitId":"-"},"content":" };"},{"lineNumber":155,"author":{"gitId":"-"},"content":" return this.httpRequestService.get(ResourceEndpoints.ACCOUNTS, paramMap);"},{"lineNumber":156,"author":{"gitId":"-"},"content":" }"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":159,"author":{"gitId":"domoberzin"},"content":" * Gets account requests by calling API."},{"lineNumber":160,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":161,"author":{"gitId":"domoberzin"},"content":" getPendingAccountRequests(): Observable\u003cAccountRequests\u003e {"},{"lineNumber":162,"author":{"gitId":"domoberzin"},"content":" const paramMap \u003d {"},{"lineNumber":163,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus.PENDING,"},{"lineNumber":164,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":165,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":" return this.httpRequestService.get(ResourceEndpoints.ACCOUNT_REQUESTS, paramMap);"},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" * Rejects an account request by calling API."},{"lineNumber":171,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":172,"author":{"gitId":"domoberzin"},"content":" rejectAccountRequest(id: string, title?: string, body?: string): Observable\u003cAccountRequest\u003e {"},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":" let accountReqRejectRequest: AccountRequestRejectionRequest \u003d {};"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" if (title !\u003d\u003d undefined \u0026\u0026 body !\u003d\u003d undefined) {"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":" accountReqRejectRequest \u003d {"},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" reasonTitle: title,"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":" reasonBody: body,"},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":" id,"},{"lineNumber":184,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":185,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":186,"author":{"gitId":"domoberzin"},"content":" return this.httpRequestService.post(ResourceEndpoints.ACCOUNT_REQUEST_REJECT, paramMap, accountReqRejectRequest);"},{"lineNumber":187,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":188,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":83,"dishenggg":4,"-":102}},{"path":"src/web/services/log.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { HttpRequestService } from \u0027./http-request.service\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { ResourceEndpoints } from \u0027../types/api-const\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":6,"author":{"gitId":"-"},"content":" ActionClasses,"},{"lineNumber":7,"author":{"gitId":"-"},"content":" FeedbackSessionLogs,"},{"lineNumber":8,"author":{"gitId":"-"},"content":" FeedbackSessionLogType,"},{"lineNumber":9,"author":{"gitId":"-"},"content":" GeneralLogs,"},{"lineNumber":10,"author":{"gitId":"-"},"content":" QueryLogsParams,"},{"lineNumber":11,"author":{"gitId":"-"},"content":"} from \u0027../types/api-output\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"-"},"content":" * Handles logging related logic provision."},{"lineNumber":15,"author":{"gitId":"-"},"content":" */"},{"lineNumber":16,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":17,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027,"},{"lineNumber":18,"author":{"gitId":"-"},"content":"})"},{"lineNumber":19,"author":{"gitId":"-"},"content":"export class LogService {"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" constructor(private httpRequestService: HttpRequestService) { }"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * Creates a log for feedback session by calling API."},{"lineNumber":25,"author":{"gitId":"-"},"content":" */"},{"lineNumber":26,"author":{"gitId":"-"},"content":" createFeedbackSessionLog(queryParams: {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" courseId: string,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" feedbackSessionName: string,"},{"lineNumber":29,"author":{"gitId":"-"},"content":" studentEmail: string,"},{"lineNumber":30,"author":{"gitId":"-"},"content":" logType: FeedbackSessionLogType,"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" feedbackSessionId?: string,"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" studentId?: string,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }): Observable\u003cstring\u003e {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" courseid: queryParams.courseId,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" fsname: queryParams.feedbackSessionName,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" studentemail: queryParams.studentEmail,"},{"lineNumber":38,"author":{"gitId":"-"},"content":" fsltype: queryParams.logType.toString(),"},{"lineNumber":39,"author":{"gitId":"-"},"content":" };"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" if (queryParams.feedbackSessionId) {"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" paramMap[\u0027fsid\u0027] \u003d queryParams.feedbackSessionId;"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" if (queryParams.studentId) {"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" paramMap[\u0027studentid\u0027] \u003d queryParams.studentId;"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" return this.httpRequestService.post(ResourceEndpoints.SESSION_LOGS, paramMap);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" }"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":53,"author":{"gitId":"-"},"content":" * Searches for feedback session logs."},{"lineNumber":54,"author":{"gitId":"-"},"content":" */"},{"lineNumber":55,"author":{"gitId":"-"},"content":" searchFeedbackSessionLog(queryParams: {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" courseId: string,"},{"lineNumber":57,"author":{"gitId":"-"},"content":" searchFrom: string,"},{"lineNumber":58,"author":{"gitId":"-"},"content":" searchUntil: string,"},{"lineNumber":59,"author":{"gitId":"-"},"content":" studentEmail?: string,"},{"lineNumber":60,"author":{"gitId":"-"},"content":" sessionName?: string,"},{"lineNumber":61,"author":{"gitId":"-"},"content":" logType?: string,"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" studentId?: string,"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" sessionId?: string,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" }): Observable\u003cFeedbackSessionLogs\u003e {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" courseid: queryParams.courseId,"},{"lineNumber":67,"author":{"gitId":"-"},"content":" fslstarttime: queryParams.searchFrom,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" fslendtime: queryParams.searchUntil,"},{"lineNumber":69,"author":{"gitId":"-"},"content":" };"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" if (queryParams.studentEmail) {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" paramMap[\u0027studentemail\u0027] \u003d queryParams.studentEmail;"},{"lineNumber":73,"author":{"gitId":"-"},"content":" }"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" if (queryParams.sessionName) {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" paramMap[\u0027fsname\u0027] \u003d queryParams.sessionName;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" if (queryParams.logType) {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" paramMap[\u0027fsltype\u0027] \u003d queryParams.logType;"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" if (queryParams.studentId) {"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" paramMap[\u0027studentid\u0027] \u003d queryParams.studentId;"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" if (queryParams.sessionId) {"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" paramMap[\u0027fsid\u0027] \u003d queryParams.sessionId;"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" return this.httpRequestService.get(ResourceEndpoints.SESSION_LOGS, paramMap);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" searchLogs(queryParams: Partial\u003cQueryLogsParams\u003e): Observable\u003cGeneralLogs\u003e {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":96,"author":{"gitId":"-"},"content":" starttime: `${queryParams.startTime || -1}`,"},{"lineNumber":97,"author":{"gitId":"-"},"content":" endtime: `${queryParams.endTime || -1}`,"},{"lineNumber":98,"author":{"gitId":"-"},"content":" };"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" if (queryParams.order) {"},{"lineNumber":101,"author":{"gitId":"-"},"content":" paramMap[\u0027order\u0027] \u003d queryParams.order;"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" if (queryParams.severity) {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" paramMap[\u0027severity\u0027] \u003d queryParams.severity;"},{"lineNumber":106,"author":{"gitId":"-"},"content":" }"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" if (queryParams.minSeverity) {"},{"lineNumber":109,"author":{"gitId":"-"},"content":" paramMap[\u0027minseverity\u0027] \u003d queryParams.minSeverity;"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" if (queryParams.logEvent) {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" paramMap[\u0027logevent\u0027] \u003d queryParams.logEvent;"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" if (queryParams.actionClass) {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" paramMap[\u0027actionclass\u0027] \u003d queryParams.actionClass;"},{"lineNumber":118,"author":{"gitId":"-"},"content":" }"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" if (queryParams.traceId) {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" paramMap[\u0027traceid\u0027] \u003d queryParams.traceId;"},{"lineNumber":122,"author":{"gitId":"-"},"content":" }"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" if (queryParams.userInfoParams) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" if (queryParams.userInfoParams.googleId) {"},{"lineNumber":126,"author":{"gitId":"-"},"content":" paramMap[\u0027googleid\u0027] \u003d queryParams.userInfoParams.googleId;"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" if (queryParams.userInfoParams.regkey) {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" paramMap[\u0027key\u0027] \u003d queryParams.userInfoParams.regkey;"},{"lineNumber":131,"author":{"gitId":"-"},"content":" }"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" if (queryParams.userInfoParams.email) {"},{"lineNumber":134,"author":{"gitId":"-"},"content":" paramMap[\u0027email\u0027] \u003d queryParams.userInfoParams.email;"},{"lineNumber":135,"author":{"gitId":"-"},"content":" }"},{"lineNumber":136,"author":{"gitId":"-"},"content":" }"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" if (queryParams.sourceLocation) {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" if (queryParams.sourceLocation.file) {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" paramMap[\u0027sourcelocationfile\u0027] \u003d queryParams.sourceLocation.file;"},{"lineNumber":141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" if (queryParams.sourceLocation.function) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" paramMap[\u0027sourcelocationfunction\u0027] \u003d queryParams.sourceLocation.function;"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":" }"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" if (queryParams.exceptionClass) {"},{"lineNumber":149,"author":{"gitId":"-"},"content":" paramMap[\u0027exceptionclass\u0027] \u003d queryParams.exceptionClass;"},{"lineNumber":150,"author":{"gitId":"-"},"content":" }"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" if (queryParams.latency) {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" paramMap[\u0027latency\u0027] \u003d queryParams.latency;"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" if (queryParams.status) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" paramMap[\u0027status\u0027] \u003d queryParams.status;"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" if (queryParams.version) {"},{"lineNumber":161,"author":{"gitId":"-"},"content":" paramMap[\u0027version\u0027] \u003d queryParams.version;"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" if (queryParams.extraFilters) {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" paramMap[\u0027extrafilters\u0027] \u003d queryParams.extraFilters;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" }"},{"lineNumber":167,"author":{"gitId":"-"},"content":""},{"lineNumber":168,"author":{"gitId":"-"},"content":" return this.httpRequestService.get(ResourceEndpoints.LOGS, paramMap);"},{"lineNumber":169,"author":{"gitId":"-"},"content":" }"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" getActionClassList(): Observable\u003cActionClasses\u003e {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" return this.httpRequestService.get(ResourceEndpoints.ACTION_CLASS);"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":20,"-":154}},{"path":"src/web/services/search.service.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { HttpClientTestingModule } from \u0027@angular/common/http/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { TestBed } from \u0027@angular/core/testing\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { RouterTestingModule } from \u0027@angular/router/testing\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { HttpRequestService } from \u0027./http-request.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":6,"author":{"gitId":"-"},"content":" AccountRequestSearchResult,"},{"lineNumber":7,"author":{"gitId":"-"},"content":" InstructorAccountSearchResult,"},{"lineNumber":8,"author":{"gitId":"-"},"content":" SearchService,"},{"lineNumber":9,"author":{"gitId":"-"},"content":" StudentAccountSearchResult,"},{"lineNumber":10,"author":{"gitId":"-"},"content":"} from \u0027./search.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { TimezoneService } from \u0027./timezone.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import createSpyFromClass from \u0027../test-helpers/create-spy-from-class\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { ResourceEndpoints } from \u0027../types/api-const\u0027;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":15,"author":{"gitId":"-"},"content":" AccountRequest,"},{"lineNumber":16,"author":{"gitId":"-"},"content":" AccountRequestStatus,"},{"lineNumber":17,"author":{"gitId":"-"},"content":" Course,"},{"lineNumber":18,"author":{"gitId":"-"},"content":" FeedbackSession,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" FeedbackSessionPublishStatus,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" FeedbackSessionSubmissionStatus,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" Instructor,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" InstructorPermissionRole,"},{"lineNumber":23,"author":{"gitId":"-"},"content":" InstructorPrivilege,"},{"lineNumber":24,"author":{"gitId":"-"},"content":" JoinState,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" ResponseVisibleSetting,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" SessionVisibleSetting,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" Student,"},{"lineNumber":28,"author":{"gitId":"-"},"content":"} from \u0027../types/api-output\u0027;"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":"describe(\u0027SearchService\u0027, () \u003d\u003e {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" let spyHttpRequestService: any;"},{"lineNumber":32,"author":{"gitId":"-"},"content":" let service: SearchService;"},{"lineNumber":33,"author":{"gitId":"-"},"content":" let timezoneService: TimezoneService;"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" const mockStudent: Student \u003d {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" email: \u0027alice.b.tmms@gmail.tmt\u0027,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" courseId: \u0027dog.gma-demo\u0027,"},{"lineNumber":38,"author":{"gitId":"-"},"content":" name: \u0027Alice Betsy\u0027,"},{"lineNumber":39,"author":{"gitId":"-"},"content":" googleId: \u0027alice.b.tmms.sampleData\u0027,"},{"lineNumber":40,"author":{"gitId":"-"},"content":" comments: \"This student\u0027s name is Alice Betsy\","},{"lineNumber":41,"author":{"gitId":"-"},"content":" key: \u0027keyheehee\u0027,"},{"lineNumber":42,"author":{"gitId":"-"},"content":" institute: \u0027NUS\u0027,"},{"lineNumber":43,"author":{"gitId":"-"},"content":" joinState: JoinState.JOINED,"},{"lineNumber":44,"author":{"gitId":"-"},"content":" teamName: \u0027Team 1\u0027,"},{"lineNumber":45,"author":{"gitId":"-"},"content":" sectionName: \u0027Tutorial Group 1\u0027,"},{"lineNumber":46,"author":{"gitId":"-"},"content":" };"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" const mockInstructorA: Instructor \u003d {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" googleId: \u0027test@example.com\u0027,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" courseId: \u0027dog.gma-demo\u0027,"},{"lineNumber":51,"author":{"gitId":"-"},"content":" email: \u0027dog@gmail.com\u0027,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" isDisplayedToStudents: true,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" displayedToStudentsAs: \u0027Instructor\u0027,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" name: \u0027Hi\u0027,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" key: \u0027impicklerick\u0027,"},{"lineNumber":56,"author":{"gitId":"-"},"content":" role: InstructorPermissionRole.INSTRUCTOR_PERMISSION_ROLE_COOWNER,"},{"lineNumber":57,"author":{"gitId":"-"},"content":" joinState: JoinState.JOINED,"},{"lineNumber":58,"author":{"gitId":"-"},"content":" };"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" const mockInstructorB: Instructor \u003d {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" googleId: \u0027insB\u0027,"},{"lineNumber":62,"author":{"gitId":"-"},"content":" courseId: \u0027dog.gma-demo\u0027,"},{"lineNumber":63,"author":{"gitId":"-"},"content":" email: \u0027cat@gmail.com\u0027,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" isDisplayedToStudents: true,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" displayedToStudentsAs: \u0027Instructor\u0027,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" name: \u0027Cat\u0027,"},{"lineNumber":67,"author":{"gitId":"-"},"content":" key: \u0027qwertyuiop\u0027,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" role: InstructorPermissionRole.INSTRUCTOR_PERMISSION_ROLE_CUSTOM,"},{"lineNumber":69,"author":{"gitId":"-"},"content":" joinState: JoinState.JOINED,"},{"lineNumber":70,"author":{"gitId":"-"},"content":" };"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" const mockInstructorC: Instructor \u003d {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" googleId: \u0027insC\u0027,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" courseId: \u0027dog.gma-demo\u0027,"},{"lineNumber":75,"author":{"gitId":"-"},"content":" email: \u0027animal@gmail.com\u0027,"},{"lineNumber":76,"author":{"gitId":"-"},"content":" isDisplayedToStudents: true,"},{"lineNumber":77,"author":{"gitId":"-"},"content":" displayedToStudentsAs: \u0027Instructor\u0027,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" name: \u0027QWQ\u0027,"},{"lineNumber":79,"author":{"gitId":"-"},"content":" key: \u0027vjvkjsnffwicvvcsc\u0027,"},{"lineNumber":80,"author":{"gitId":"-"},"content":" role: InstructorPermissionRole.INSTRUCTOR_PERMISSION_ROLE_CUSTOM,"},{"lineNumber":81,"author":{"gitId":"-"},"content":" joinState: JoinState.JOINED,"},{"lineNumber":82,"author":{"gitId":"-"},"content":" };"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" const mockSessions: FeedbackSession[] \u003d ["},{"lineNumber":85,"author":{"gitId":"-"},"content":" {"},{"lineNumber":86,"author":{"gitId":"-"},"content":" courseId: \u0027dog.gma-demo\u0027,"},{"lineNumber":87,"author":{"gitId":"-"},"content":" timeZone: \u0027Asia/Singapore\u0027,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" feedbackSessionName: \u0027First team feedback session\u0027,"},{"lineNumber":89,"author":{"gitId":"-"},"content":" instructions: \u0027Please give your feedback based on the following questions.\u0027,"},{"lineNumber":90,"author":{"gitId":"-"},"content":" submissionStartTimestamp: 1333295940000,"},{"lineNumber":91,"author":{"gitId":"-"},"content":" submissionEndTimestamp: 1333382340000,"},{"lineNumber":92,"author":{"gitId":"-"},"content":" submissionStatus: FeedbackSessionSubmissionStatus.CLOSED,"},{"lineNumber":93,"author":{"gitId":"-"},"content":" publishStatus: FeedbackSessionPublishStatus.PUBLISHED,"},{"lineNumber":94,"author":{"gitId":"-"},"content":" createdAtTimestamp: 1333324740000,"},{"lineNumber":95,"author":{"gitId":"-"},"content":" gracePeriod: 1,"},{"lineNumber":96,"author":{"gitId":"-"},"content":" sessionVisibleSetting: SessionVisibleSetting.CUSTOM,"},{"lineNumber":97,"author":{"gitId":"-"},"content":" responseVisibleSetting: ResponseVisibleSetting.CUSTOM,"},{"lineNumber":98,"author":{"gitId":"-"},"content":" isClosingEmailEnabled: false,"},{"lineNumber":99,"author":{"gitId":"-"},"content":" isPublishedEmailEnabled: false,"},{"lineNumber":100,"author":{"gitId":"-"},"content":" studentDeadlines: {},"},{"lineNumber":101,"author":{"gitId":"-"},"content":" instructorDeadlines: {},"},{"lineNumber":102,"author":{"gitId":"-"},"content":" },"},{"lineNumber":103,"author":{"gitId":"-"},"content":" {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" courseId: \u0027dog.gma-demo\u0027,"},{"lineNumber":105,"author":{"gitId":"-"},"content":" timeZone: \u0027Asia/Singapore\u0027,"},{"lineNumber":106,"author":{"gitId":"-"},"content":" feedbackSessionName: \u0027Second team feedback session\u0027,"},{"lineNumber":107,"author":{"gitId":"-"},"content":" instructions: \u0027Please give your feedback based on the following questions.\u0027,"},{"lineNumber":108,"author":{"gitId":"-"},"content":" submissionStartTimestamp: 1333295940000,"},{"lineNumber":109,"author":{"gitId":"-"},"content":" submissionEndTimestamp: 2122300740000,"},{"lineNumber":110,"author":{"gitId":"-"},"content":" submissionStatus: FeedbackSessionSubmissionStatus.OPEN,"},{"lineNumber":111,"author":{"gitId":"-"},"content":" publishStatus: FeedbackSessionPublishStatus.NOT_PUBLISHED,"},{"lineNumber":112,"author":{"gitId":"-"},"content":" createdAtTimestamp: 1333324740000,"},{"lineNumber":113,"author":{"gitId":"-"},"content":" gracePeriod: 1,"},{"lineNumber":114,"author":{"gitId":"-"},"content":" sessionVisibleSetting: SessionVisibleSetting.CUSTOM,"},{"lineNumber":115,"author":{"gitId":"-"},"content":" responseVisibleSetting: ResponseVisibleSetting.CUSTOM,"},{"lineNumber":116,"author":{"gitId":"-"},"content":" isClosingEmailEnabled: false,"},{"lineNumber":117,"author":{"gitId":"-"},"content":" isPublishedEmailEnabled: false,"},{"lineNumber":118,"author":{"gitId":"-"},"content":" studentDeadlines: {},"},{"lineNumber":119,"author":{"gitId":"-"},"content":" instructorDeadlines: {},"},{"lineNumber":120,"author":{"gitId":"-"},"content":" },"},{"lineNumber":121,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" const mockPrivilegeA: InstructorPrivilege \u003d {"},{"lineNumber":124,"author":{"gitId":"-"},"content":" privileges: {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" courseLevel: {"},{"lineNumber":126,"author":{"gitId":"-"},"content":" canModifyCourse: true,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" canModifySession: true,"},{"lineNumber":128,"author":{"gitId":"-"},"content":" canModifyStudent: true,"},{"lineNumber":129,"author":{"gitId":"-"},"content":" canModifyInstructor: true,"},{"lineNumber":130,"author":{"gitId":"-"},"content":" canViewStudentInSections: true,"},{"lineNumber":131,"author":{"gitId":"-"},"content":" canModifySessionCommentsInSections: true,"},{"lineNumber":132,"author":{"gitId":"-"},"content":" canViewSessionInSections: true,"},{"lineNumber":133,"author":{"gitId":"-"},"content":" canSubmitSessionInSections: true,"},{"lineNumber":134,"author":{"gitId":"-"},"content":" },"},{"lineNumber":135,"author":{"gitId":"-"},"content":" sectionLevel: {},"},{"lineNumber":136,"author":{"gitId":"-"},"content":" sessionLevel: {},"},{"lineNumber":137,"author":{"gitId":"-"},"content":" },"},{"lineNumber":138,"author":{"gitId":"-"},"content":" requestId: \u0027checkyourprivilege\u0027,"},{"lineNumber":139,"author":{"gitId":"-"},"content":" };"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" const mockPrivilegeB: InstructorPrivilege \u003d {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" privileges: {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" courseLevel: {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" canModifyCourse: true,"},{"lineNumber":145,"author":{"gitId":"-"},"content":" canModifySession: true,"},{"lineNumber":146,"author":{"gitId":"-"},"content":" canModifyStudent: true,"},{"lineNumber":147,"author":{"gitId":"-"},"content":" canModifyInstructor: false,"},{"lineNumber":148,"author":{"gitId":"-"},"content":" canViewStudentInSections: true,"},{"lineNumber":149,"author":{"gitId":"-"},"content":" canModifySessionCommentsInSections: true,"},{"lineNumber":150,"author":{"gitId":"-"},"content":" canViewSessionInSections: true,"},{"lineNumber":151,"author":{"gitId":"-"},"content":" canSubmitSessionInSections: true,"},{"lineNumber":152,"author":{"gitId":"-"},"content":" },"},{"lineNumber":153,"author":{"gitId":"-"},"content":" sectionLevel: {},"},{"lineNumber":154,"author":{"gitId":"-"},"content":" sessionLevel: {},"},{"lineNumber":155,"author":{"gitId":"-"},"content":" },"},{"lineNumber":156,"author":{"gitId":"-"},"content":" requestId: \u0027123gyijuyol56w8refw123ce8f5\u0027,"},{"lineNumber":157,"author":{"gitId":"-"},"content":" };"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" const mockPrivilegeC: InstructorPrivilege \u003d {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" privileges: {"},{"lineNumber":161,"author":{"gitId":"-"},"content":" courseLevel: {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" canModifyCourse: false,"},{"lineNumber":163,"author":{"gitId":"-"},"content":" canModifySession: false,"},{"lineNumber":164,"author":{"gitId":"-"},"content":" canModifyStudent: false,"},{"lineNumber":165,"author":{"gitId":"-"},"content":" canModifyInstructor: true,"},{"lineNumber":166,"author":{"gitId":"-"},"content":" canViewStudentInSections: false,"},{"lineNumber":167,"author":{"gitId":"-"},"content":" canModifySessionCommentsInSections: false,"},{"lineNumber":168,"author":{"gitId":"-"},"content":" canViewSessionInSections: false,"},{"lineNumber":169,"author":{"gitId":"-"},"content":" canSubmitSessionInSections: false,"},{"lineNumber":170,"author":{"gitId":"-"},"content":" },"},{"lineNumber":171,"author":{"gitId":"-"},"content":" sectionLevel: {},"},{"lineNumber":172,"author":{"gitId":"-"},"content":" sessionLevel: {},"},{"lineNumber":173,"author":{"gitId":"-"},"content":" },"},{"lineNumber":174,"author":{"gitId":"-"},"content":" requestId: \u002798pa78342kjnk22s1213rsdff4\u0027,"},{"lineNumber":175,"author":{"gitId":"-"},"content":" };"},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":" const mockCourse: Course \u003d {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" courseId: \u0027dog.gma-demo\u0027,"},{"lineNumber":179,"author":{"gitId":"-"},"content":" courseName: \u0027Sample Course 101\u0027,"},{"lineNumber":180,"author":{"gitId":"-"},"content":" institute: \u0027Test Institute\u0027,"},{"lineNumber":181,"author":{"gitId":"-"},"content":" timeZone: \u0027UTC\u0027,"},{"lineNumber":182,"author":{"gitId":"-"},"content":" creationTimestamp: 1585487897502,"},{"lineNumber":183,"author":{"gitId":"-"},"content":" deletionTimestamp: 0,"},{"lineNumber":184,"author":{"gitId":"-"},"content":" requestId: \u00275e80aa3c00007918934385f5\u0027,"},{"lineNumber":185,"author":{"gitId":"-"},"content":" };"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" const mockAccountRequest: AccountRequest \u003d {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" id: \u0027132efa02-b208-4195-a262-a8eae25ceb95\u0027,"},{"lineNumber":189,"author":{"gitId":"-"},"content":" registrationKey: \u0027regkey\u0027,"},{"lineNumber":190,"author":{"gitId":"-"},"content":" createdAt: 1585487897502,"},{"lineNumber":191,"author":{"gitId":"-"},"content":" name: \u0027Test Instructor\u0027,"},{"lineNumber":192,"author":{"gitId":"-"},"content":" institute: \u0027Test Institute\u0027,"},{"lineNumber":193,"author":{"gitId":"-"},"content":" email: \u0027test@example.com\u0027,"},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" comments: \u0027This is a test account request\u0027,"},{"lineNumber":195,"author":{"gitId":"-"},"content":" status: AccountRequestStatus.APPROVED,"},{"lineNumber":196,"author":{"gitId":"-"},"content":" };"},{"lineNumber":197,"author":{"gitId":"-"},"content":""},{"lineNumber":198,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":199,"author":{"gitId":"-"},"content":" spyHttpRequestService \u003d createSpyFromClass(HttpRequestService);"},{"lineNumber":200,"author":{"gitId":"-"},"content":" TestBed.configureTestingModule({"},{"lineNumber":201,"author":{"gitId":"-"},"content":" imports: [HttpClientTestingModule, RouterTestingModule],"},{"lineNumber":202,"author":{"gitId":"-"},"content":" providers: ["},{"lineNumber":203,"author":{"gitId":"-"},"content":" { provide: HttpRequestService, useValue: spyHttpRequestService },"},{"lineNumber":204,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":205,"author":{"gitId":"-"},"content":" });"},{"lineNumber":206,"author":{"gitId":"-"},"content":" service \u003d TestBed.inject(SearchService);"},{"lineNumber":207,"author":{"gitId":"-"},"content":" timezoneService \u003d TestBed.inject(TimezoneService);"},{"lineNumber":208,"author":{"gitId":"-"},"content":" });"},{"lineNumber":209,"author":{"gitId":"-"},"content":""},{"lineNumber":210,"author":{"gitId":"-"},"content":" it(\u0027should be created\u0027, () \u003d\u003e {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" expect(service).toBeTruthy();"},{"lineNumber":212,"author":{"gitId":"-"},"content":" });"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" it(\u0027should execute GET when searching for students\u0027, () \u003d\u003e {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" service.searchStudents(\u0027Alice\u0027, \u0027instructor\u0027);"},{"lineNumber":216,"author":{"gitId":"-"},"content":" const paramMap: { [key: string]: string } \u003d {"},{"lineNumber":217,"author":{"gitId":"-"},"content":" searchkey: \u0027Alice\u0027,"},{"lineNumber":218,"author":{"gitId":"-"},"content":" entitytype: \u0027instructor\u0027,"},{"lineNumber":219,"author":{"gitId":"-"},"content":" };"},{"lineNumber":220,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.get).toHaveBeenCalledWith("},{"lineNumber":221,"author":{"gitId":"-"},"content":" ResourceEndpoints.SEARCH_STUDENTS,"},{"lineNumber":222,"author":{"gitId":"-"},"content":" paramMap,"},{"lineNumber":223,"author":{"gitId":"-"},"content":" );"},{"lineNumber":224,"author":{"gitId":"-"},"content":" });"},{"lineNumber":225,"author":{"gitId":"-"},"content":""},{"lineNumber":226,"author":{"gitId":"-"},"content":" it(\u0027should execute GET when searching for instructors\u0027, () \u003d\u003e {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" service.searchInstructors(\u0027YoyoImCoronavirus\u0027);"},{"lineNumber":228,"author":{"gitId":"-"},"content":" const paramMap: { [key: string]: string } \u003d {"},{"lineNumber":229,"author":{"gitId":"-"},"content":" searchkey: \u0027YoyoImCoronavirus\u0027,"},{"lineNumber":230,"author":{"gitId":"-"},"content":" };"},{"lineNumber":231,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.get).toHaveBeenCalledWith("},{"lineNumber":232,"author":{"gitId":"-"},"content":" ResourceEndpoints.SEARCH_INSTRUCTORS,"},{"lineNumber":233,"author":{"gitId":"-"},"content":" paramMap,"},{"lineNumber":234,"author":{"gitId":"-"},"content":" );"},{"lineNumber":235,"author":{"gitId":"-"},"content":" });"},{"lineNumber":236,"author":{"gitId":"-"},"content":""},{"lineNumber":237,"author":{"gitId":"-"},"content":" it(\u0027should execute GET when searching for account requests\u0027, () \u003d\u003e {"},{"lineNumber":238,"author":{"gitId":"-"},"content":" service.searchAccountRequests(\u0027Account Request\u0027);"},{"lineNumber":239,"author":{"gitId":"-"},"content":" const paramMap: { [key: string]: string } \u003d {"},{"lineNumber":240,"author":{"gitId":"-"},"content":" searchkey: \u0027Account Request\u0027,"},{"lineNumber":241,"author":{"gitId":"-"},"content":" };"},{"lineNumber":242,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.get).toHaveBeenCalledWith("},{"lineNumber":243,"author":{"gitId":"-"},"content":" ResourceEndpoints.SEARCH_ACCOUNT_REQUESTS,"},{"lineNumber":244,"author":{"gitId":"-"},"content":" paramMap,"},{"lineNumber":245,"author":{"gitId":"-"},"content":" );"},{"lineNumber":246,"author":{"gitId":"-"},"content":" });"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" it(\u0027should join students accurately when calling as admin\u0027, () \u003d\u003e {"},{"lineNumber":249,"author":{"gitId":"-"},"content":" const result: StudentAccountSearchResult \u003d service.joinAdminStudent("},{"lineNumber":250,"author":{"gitId":"-"},"content":" mockStudent,"},{"lineNumber":251,"author":{"gitId":"-"},"content":" { instructors: [mockInstructorA] },"},{"lineNumber":252,"author":{"gitId":"-"},"content":" mockCourse,"},{"lineNumber":253,"author":{"gitId":"-"},"content":" { feedbackSessions: mockSessions },"},{"lineNumber":254,"author":{"gitId":"-"},"content":" [mockPrivilegeA],"},{"lineNumber":255,"author":{"gitId":"-"},"content":" );"},{"lineNumber":256,"author":{"gitId":"-"},"content":" expect(result.comments).toBe(\"This student\u0027s name is Alice Betsy\");"},{"lineNumber":257,"author":{"gitId":"-"},"content":" expect(result.courseId).toBe(\u0027dog.gma-demo\u0027);"},{"lineNumber":258,"author":{"gitId":"-"},"content":" expect(result.courseJoinLink).toBe(`${window.location.origin}/web/join?key\u003dkeyheehee\u0026entitytype\u003dstudent`);"},{"lineNumber":259,"author":{"gitId":"-"},"content":" expect(result.courseName).toBe(\u0027Sample Course 101\u0027);"},{"lineNumber":260,"author":{"gitId":"-"},"content":" expect(result.email).toBe(\u0027alice.b.tmms@gmail.tmt\u0027);"},{"lineNumber":261,"author":{"gitId":"-"},"content":" expect(result.manageAccountLink).toBe(\u0027/web/admin/accounts?instructorid\u003dalice.b.tmms.sampleData\u0027);"},{"lineNumber":262,"author":{"gitId":"-"},"content":" });"},{"lineNumber":263,"author":{"gitId":"-"},"content":""},{"lineNumber":264,"author":{"gitId":"-"},"content":" it(\u0027should join students with correct profile page link when course has co-owner\u0027, () \u003d\u003e {"},{"lineNumber":265,"author":{"gitId":"-"},"content":" const result: StudentAccountSearchResult \u003d service.joinAdminStudent("},{"lineNumber":266,"author":{"gitId":"-"},"content":" mockStudent,"},{"lineNumber":267,"author":{"gitId":"-"},"content":" { instructors: [mockInstructorC, mockInstructorB, mockInstructorA] },"},{"lineNumber":268,"author":{"gitId":"-"},"content":" mockCourse,"},{"lineNumber":269,"author":{"gitId":"-"},"content":" { feedbackSessions: mockSessions },"},{"lineNumber":270,"author":{"gitId":"-"},"content":" [mockPrivilegeC, mockPrivilegeB, mockPrivilegeA],"},{"lineNumber":271,"author":{"gitId":"-"},"content":" );"},{"lineNumber":272,"author":{"gitId":"-"},"content":" expect(result.profilePageLink).toBe(\u0027/web/instructor/courses/student/details?\u0027"},{"lineNumber":273,"author":{"gitId":"-"},"content":" + \u0027courseid\u003ddog.gma-demo\u0026studentemail\u003dalice.b.tmms%40gmail.tmt\u0026user\u003dtest%40example.com\u0027);"},{"lineNumber":274,"author":{"gitId":"-"},"content":" });"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" it(\u0027should join students with correct profile page link when course has no co-owner\u0027, () \u003d\u003e {"},{"lineNumber":277,"author":{"gitId":"-"},"content":" const result: StudentAccountSearchResult \u003d service.joinAdminStudent("},{"lineNumber":278,"author":{"gitId":"-"},"content":" mockStudent,"},{"lineNumber":279,"author":{"gitId":"-"},"content":" { instructors: [mockInstructorB, mockInstructorC] },"},{"lineNumber":280,"author":{"gitId":"-"},"content":" mockCourse,"},{"lineNumber":281,"author":{"gitId":"-"},"content":" { feedbackSessions: mockSessions },"},{"lineNumber":282,"author":{"gitId":"-"},"content":" [mockPrivilegeB, mockPrivilegeC],"},{"lineNumber":283,"author":{"gitId":"-"},"content":" );"},{"lineNumber":284,"author":{"gitId":"-"},"content":" expect(result.profilePageLink).toBe(\u0027/web/instructor/courses/student/details?\u0027"},{"lineNumber":285,"author":{"gitId":"-"},"content":" + \u0027courseid\u003ddog.gma-demo\u0026studentemail\u003dalice.b.tmms%40gmail.tmt\u0026user\u003dinsC\u0027);"},{"lineNumber":286,"author":{"gitId":"-"},"content":" });"},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":" it(\u0027should join instructors accurately when calling as admin\u0027, () \u003d\u003e {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" const result: InstructorAccountSearchResult \u003d service"},{"lineNumber":290,"author":{"gitId":"-"},"content":" .joinAdminInstructor(mockInstructorA, mockCourse, { feedbackSessions: mockSessions });"},{"lineNumber":291,"author":{"gitId":"-"},"content":" expect(result.courseId).toBe(\u0027dog.gma-demo\u0027);"},{"lineNumber":292,"author":{"gitId":"-"},"content":" expect(result.courseJoinLink).toBe(`${window.location.origin}/web/join?key\u003dimpicklerick\u0026entitytype\u003dinstructor`);"},{"lineNumber":293,"author":{"gitId":"-"},"content":" expect(result.courseName).toBe(\u0027Sample Course 101\u0027);"},{"lineNumber":294,"author":{"gitId":"-"},"content":" expect(result.email).toBe(\u0027dog@gmail.com\u0027);"},{"lineNumber":295,"author":{"gitId":"-"},"content":" expect(result.manageAccountLink).toBe(\u0027/web/admin/accounts?instructorid\u003dtest%40example.com\u0027);"},{"lineNumber":296,"author":{"gitId":"-"},"content":" expect(result.homePageLink).toBe(\u0027/web/instructor/home?user\u003dtest%40example.com\u0027);"},{"lineNumber":297,"author":{"gitId":"-"},"content":" });"},{"lineNumber":298,"author":{"gitId":"-"},"content":""},{"lineNumber":299,"author":{"gitId":"-"},"content":" it(\u0027should join account requests accurately when timezone can be guessed and instructor is registered\u0027, () \u003d\u003e {"},{"lineNumber":300,"author":{"gitId":"-"},"content":" jest.spyOn(timezoneService, \u0027guessTimezone\u0027).mockReturnValue(\u0027Asia/Singapore\u0027);"},{"lineNumber":301,"author":{"gitId":"-"},"content":" const accountRequest: AccountRequest \u003d {"},{"lineNumber":302,"author":{"gitId":"-"},"content":" ...mockAccountRequest,"},{"lineNumber":303,"author":{"gitId":"-"},"content":" registeredAt: 1685487897502,"},{"lineNumber":304,"author":{"gitId":"-"},"content":" status: AccountRequestStatus.REGISTERED,"},{"lineNumber":305,"author":{"gitId":"-"},"content":" };"},{"lineNumber":306,"author":{"gitId":"-"},"content":" const result: AccountRequestSearchResult \u003d service.joinAdminAccountRequest(accountRequest);"},{"lineNumber":307,"author":{"gitId":"-"},"content":""},{"lineNumber":308,"author":{"gitId":"-"},"content":" expect(result.id).toBe(\u0027132efa02-b208-4195-a262-a8eae25ceb95\u0027);"},{"lineNumber":309,"author":{"gitId":"-"},"content":" expect(result.email).toBe(\u0027test@example.com\u0027);"},{"lineNumber":310,"author":{"gitId":"-"},"content":" expect(result.institute).toBe(\u0027Test Institute\u0027);"},{"lineNumber":311,"author":{"gitId":"-"},"content":" expect(result.name).toBe(\u0027Test Instructor\u0027);"},{"lineNumber":312,"author":{"gitId":"-"},"content":" expect(result.createdAtText).toBe(\u0027Sun, 29 Mar 2020, 09:18 PM +08:00\u0027);"},{"lineNumber":313,"author":{"gitId":"-"},"content":" expect(result.registeredAtText).toBe(\u0027Wed, 31 May 2023, 07:04 AM +08:00\u0027);"},{"lineNumber":314,"author":{"gitId":"-"},"content":" expect(result.registrationLink).toBe(`${window.location.origin}/web/join?iscreatingaccount\u003dtrue\u0026key\u003dregkey`);"},{"lineNumber":315,"author":{"gitId":"-"},"content":" });"},{"lineNumber":316,"author":{"gitId":"-"},"content":""},{"lineNumber":317,"author":{"gitId":"-"},"content":" it(\u0027should join account requests accurately when timezone cannot be guessed and instructor is not registered\u0027, () \u003d\u003e {"},{"lineNumber":318,"author":{"gitId":"-"},"content":" jest.spyOn(timezoneService, \u0027guessTimezone\u0027).mockReturnValue(\u0027\u0027);"},{"lineNumber":319,"author":{"gitId":"-"},"content":" const result: AccountRequestSearchResult \u003d service.joinAdminAccountRequest(mockAccountRequest);"},{"lineNumber":320,"author":{"gitId":"-"},"content":""},{"lineNumber":321,"author":{"gitId":"-"},"content":" expect(result.email).toBe(\u0027test@example.com\u0027);"},{"lineNumber":322,"author":{"gitId":"-"},"content":" expect(result.institute).toBe(\u0027Test Institute\u0027);"},{"lineNumber":323,"author":{"gitId":"-"},"content":" expect(result.name).toBe(\u0027Test Instructor\u0027);"},{"lineNumber":324,"author":{"gitId":"-"},"content":" expect(result.createdAtText).toBe(\u0027Sun, 29 Mar 2020, 01:18 PM +00:00\u0027);"},{"lineNumber":325,"author":{"gitId":"-"},"content":" expect(result.registeredAtText).toBe(null);"},{"lineNumber":326,"author":{"gitId":"-"},"content":" expect(result.registrationLink).toBe(`${window.location.origin}/web/join?iscreatingaccount\u003dtrue\u0026key\u003dregkey`);"},{"lineNumber":327,"author":{"gitId":"-"},"content":" });"},{"lineNumber":328,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"domoberzin":1,"-":327}},{"path":"src/web/services/search.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { forkJoin, Observable, of } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { map, mergeMap } from \u0027rxjs/operators\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { CourseService } from \u0027./course.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { FeedbackSessionsService } from \u0027./feedback-sessions.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { HttpRequestService } from \u0027./http-request.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { InstructorService } from \u0027./instructor.service\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { LinkService } from \u0027./link.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { TimezoneService } from \u0027./timezone.service\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { ResourceEndpoints } from \u0027../types/api-const\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":12,"author":{"gitId":"-"},"content":" AccountRequest,"},{"lineNumber":13,"author":{"gitId":"-"},"content":" AccountRequests,"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":" AccountRequestStatus,"},{"lineNumber":15,"author":{"gitId":"-"},"content":" Course, FeedbackSession,"},{"lineNumber":16,"author":{"gitId":"-"},"content":" FeedbackSessions,"},{"lineNumber":17,"author":{"gitId":"-"},"content":" Instructor,"},{"lineNumber":18,"author":{"gitId":"-"},"content":" InstructorPermissionRole,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" InstructorPrivilege,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" Instructors,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" Student,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" Students,"},{"lineNumber":23,"author":{"gitId":"-"},"content":"} from \u0027../types/api-output\u0027;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import { Intent } from \u0027../types/api-request\u0027;"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":27,"author":{"gitId":"-"},"content":" * Handles the logic for search."},{"lineNumber":28,"author":{"gitId":"-"},"content":" */"},{"lineNumber":29,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":30,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027,"},{"lineNumber":31,"author":{"gitId":"-"},"content":"})"},{"lineNumber":32,"author":{"gitId":"-"},"content":"export class SearchService {"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" constructor("},{"lineNumber":35,"author":{"gitId":"-"},"content":" private instructorService: InstructorService,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" private httpRequestService: HttpRequestService,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" private feedbackSessionService: FeedbackSessionsService,"},{"lineNumber":38,"author":{"gitId":"-"},"content":" private courseService: CourseService,"},{"lineNumber":39,"author":{"gitId":"-"},"content":" private linkService: LinkService,"},{"lineNumber":40,"author":{"gitId":"-"},"content":" private timezoneService: TimezoneService,"},{"lineNumber":41,"author":{"gitId":"-"},"content":" ) {}"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" searchInstructor(searchKey: string): Observable\u003cInstructorSearchResult\u003e {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return this.searchStudents(searchKey, \u0027instructor\u0027).pipe("},{"lineNumber":45,"author":{"gitId":"-"},"content":" map((studentsRes: Students) \u003d\u003e {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" return {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" students: studentsRes.students,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" comments: [],"},{"lineNumber":49,"author":{"gitId":"-"},"content":" };"},{"lineNumber":50,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":51,"author":{"gitId":"-"},"content":" );"},{"lineNumber":52,"author":{"gitId":"-"},"content":" }"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" searchAdmin(searchKey: string): Observable\u003cAdminSearchResult\u003e {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" return forkJoin(["},{"lineNumber":56,"author":{"gitId":"-"},"content":" this.searchStudents(searchKey, \u0027admin\u0027),"},{"lineNumber":57,"author":{"gitId":"-"},"content":" this.searchInstructors(searchKey),"},{"lineNumber":58,"author":{"gitId":"-"},"content":" this.searchAccountRequests(searchKey),"},{"lineNumber":59,"author":{"gitId":"-"},"content":" ]).pipe("},{"lineNumber":60,"author":{"gitId":"-"},"content":" map((value: [Students, Instructors, AccountRequests]): [Student[], Instructor[], AccountRequest[]] \u003d\u003e"},{"lineNumber":61,"author":{"gitId":"-"},"content":" [value[0].students, value[1].instructors, value[2].accountRequests],"},{"lineNumber":62,"author":{"gitId":"-"},"content":" ),"},{"lineNumber":63,"author":{"gitId":"-"},"content":" mergeMap((value: [Student[], Instructor[], AccountRequest[]]) \u003d\u003e {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" const [students, instructors, accountRequests]: [Student[], Instructor[], AccountRequest[]] \u003d value;"},{"lineNumber":65,"author":{"gitId":"-"},"content":" return forkJoin(["},{"lineNumber":66,"author":{"gitId":"-"},"content":" of(students),"},{"lineNumber":67,"author":{"gitId":"-"},"content":" of(instructors),"},{"lineNumber":68,"author":{"gitId":"-"},"content":" of(accountRequests),"},{"lineNumber":69,"author":{"gitId":"-"},"content":" this.getDistinctFields(students, instructors),"},{"lineNumber":70,"author":{"gitId":"-"},"content":" ]);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":72,"author":{"gitId":"-"},"content":" map((value: [Student[], Instructor[], AccountRequest[], DistinctFields]) \u003d\u003e {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" return {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" students: this.createStudentAccountSearchResults(value[0], ...value[3]),"},{"lineNumber":75,"author":{"gitId":"-"},"content":" instructors: this.createInstructorAccountSearchResults(value[1], value[3][1], value[3][2]),"},{"lineNumber":76,"author":{"gitId":"-"},"content":" accountRequests: this.createAccountRequestSearchResults(value[2]),"},{"lineNumber":77,"author":{"gitId":"-"},"content":" };"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":79,"author":{"gitId":"-"},"content":" );"},{"lineNumber":80,"author":{"gitId":"-"},"content":" }"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" searchStudents(searchKey: string, entityType: string): Observable\u003cStudents\u003e {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" const paramMap: { [key: string]: string } \u003d {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" searchkey: searchKey,"},{"lineNumber":85,"author":{"gitId":"-"},"content":" entitytype: entityType,"},{"lineNumber":86,"author":{"gitId":"-"},"content":" };"},{"lineNumber":87,"author":{"gitId":"-"},"content":" return this.httpRequestService.get(ResourceEndpoints.SEARCH_STUDENTS, paramMap);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" searchInstructors(searchKey: string): Observable\u003cInstructors\u003e {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" const paramMap: { [key: string]: string } \u003d {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" searchkey: searchKey,"},{"lineNumber":93,"author":{"gitId":"-"},"content":" };"},{"lineNumber":94,"author":{"gitId":"-"},"content":" return this.httpRequestService.get(ResourceEndpoints.SEARCH_INSTRUCTORS, paramMap);"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" searchAccountRequests(searchKey: string): Observable\u003cAccountRequests\u003e {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" const paramMap: { [key: string]: string } \u003d {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" searchkey: searchKey,"},{"lineNumber":100,"author":{"gitId":"-"},"content":" };"},{"lineNumber":101,"author":{"gitId":"-"},"content":" return this.httpRequestService.get(ResourceEndpoints.SEARCH_ACCOUNT_REQUESTS, paramMap);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" createStudentAccountSearchResults("},{"lineNumber":105,"author":{"gitId":"-"},"content":" students: Student[],"},{"lineNumber":106,"author":{"gitId":"-"},"content":" distinctInstructorsMap: DistinctInstructorsMap,"},{"lineNumber":107,"author":{"gitId":"-"},"content":" distinctCoursesMap: DistinctCoursesMap,"},{"lineNumber":108,"author":{"gitId":"-"},"content":" distinctFeedbackSessionsMap: DistinctFeedbackSessionsMap,"},{"lineNumber":109,"author":{"gitId":"-"},"content":" distinctInstructorPrivilegesMap: DistinctInstructorPrivilegesMap,"},{"lineNumber":110,"author":{"gitId":"-"},"content":" ): StudentAccountSearchResult[] {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" return students.map((student: Student) \u003d\u003e {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" const { courseId }: Student \u003d student;"},{"lineNumber":113,"author":{"gitId":"-"},"content":" return this.joinAdminStudent("},{"lineNumber":114,"author":{"gitId":"-"},"content":" student,"},{"lineNumber":115,"author":{"gitId":"-"},"content":" distinctInstructorsMap[courseId],"},{"lineNumber":116,"author":{"gitId":"-"},"content":" distinctCoursesMap[courseId],"},{"lineNumber":117,"author":{"gitId":"-"},"content":" distinctFeedbackSessionsMap[courseId],"},{"lineNumber":118,"author":{"gitId":"-"},"content":" distinctInstructorPrivilegesMap[courseId],"},{"lineNumber":119,"author":{"gitId":"-"},"content":" );"},{"lineNumber":120,"author":{"gitId":"-"},"content":" });"},{"lineNumber":121,"author":{"gitId":"-"},"content":" }"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" joinAdminStudent("},{"lineNumber":124,"author":{"gitId":"-"},"content":" student: Student,"},{"lineNumber":125,"author":{"gitId":"-"},"content":" instructors: Instructors,"},{"lineNumber":126,"author":{"gitId":"-"},"content":" course: Course,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" feedbackSessions: FeedbackSessions,"},{"lineNumber":128,"author":{"gitId":"-"},"content":" instructorPrivileges: InstructorPrivilege[],"},{"lineNumber":129,"author":{"gitId":"-"},"content":" ): StudentAccountSearchResult {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" let studentResult: StudentAccountSearchResult \u003d {"},{"lineNumber":131,"author":{"gitId":"-"},"content":" email: \u0027\u0027,"},{"lineNumber":132,"author":{"gitId":"-"},"content":" name: \u0027\u0027,"},{"lineNumber":133,"author":{"gitId":"-"},"content":" comments: \u0027\u0027,"},{"lineNumber":134,"author":{"gitId":"-"},"content":" team: \u0027\u0027,"},{"lineNumber":135,"author":{"gitId":"-"},"content":" section: \u0027\u0027,"},{"lineNumber":136,"author":{"gitId":"-"},"content":" awaitingSessions: {},"},{"lineNumber":137,"author":{"gitId":"-"},"content":" openSessions: {},"},{"lineNumber":138,"author":{"gitId":"-"},"content":" notOpenSessions: {},"},{"lineNumber":139,"author":{"gitId":"-"},"content":" publishedSessions: {},"},{"lineNumber":140,"author":{"gitId":"-"},"content":" courseId: \u0027\u0027,"},{"lineNumber":141,"author":{"gitId":"-"},"content":" courseName: \u0027\u0027,"},{"lineNumber":142,"author":{"gitId":"-"},"content":" isCourseDeleted: false,"},{"lineNumber":143,"author":{"gitId":"-"},"content":" institute: \u0027\u0027,"},{"lineNumber":144,"author":{"gitId":"-"},"content":" manageAccountLink: \u0027\u0027,"},{"lineNumber":145,"author":{"gitId":"-"},"content":" homePageLink: \u0027\u0027,"},{"lineNumber":146,"author":{"gitId":"-"},"content":" profilePageLink: \u0027\u0027,"},{"lineNumber":147,"author":{"gitId":"-"},"content":" courseJoinLink: \u0027\u0027,"},{"lineNumber":148,"author":{"gitId":"-"},"content":" googleId: \u0027\u0027,"},{"lineNumber":149,"author":{"gitId":"-"},"content":" showLinks: false,"},{"lineNumber":150,"author":{"gitId":"-"},"content":" };"},{"lineNumber":151,"author":{"gitId":"-"},"content":" const {"},{"lineNumber":152,"author":{"gitId":"-"},"content":" email,"},{"lineNumber":153,"author":{"gitId":"-"},"content":" name,"},{"lineNumber":154,"author":{"gitId":"-"},"content":" comments \u003d \u0027\u0027,"},{"lineNumber":155,"author":{"gitId":"-"},"content":" teamName: team,"},{"lineNumber":156,"author":{"gitId":"-"},"content":" sectionName: section,"},{"lineNumber":157,"author":{"gitId":"-"},"content":" googleId \u003d \u0027\u0027,"},{"lineNumber":158,"author":{"gitId":"-"},"content":" institute \u003d \u0027\u0027,"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }: Student \u003d student;"},{"lineNumber":160,"author":{"gitId":"-"},"content":" studentResult \u003d { ...studentResult, email, name, comments, team, section, googleId, institute };"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"-"},"content":" const { courseId, courseName, deletionTimestamp }: Course \u003d course;"},{"lineNumber":163,"author":{"gitId":"-"},"content":" studentResult \u003d { ...studentResult, courseId, courseName, isCourseDeleted: Boolean(deletionTimestamp) };"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" let masqueradeGoogleId: string \u003d \u0027\u0027;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" for (const instructor of instructors.instructors) {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" if (instructor.googleId"},{"lineNumber":168,"author":{"gitId":"-"},"content":" \u0026\u0026 instructor.role \u003d\u003d\u003d InstructorPermissionRole.INSTRUCTOR_PERMISSION_ROLE_COOWNER) {"},{"lineNumber":169,"author":{"gitId":"-"},"content":" masqueradeGoogleId \u003d instructor.googleId;"},{"lineNumber":170,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":" }"},{"lineNumber":173,"author":{"gitId":"-"},"content":" // no instructor with co-owner privileges"},{"lineNumber":174,"author":{"gitId":"-"},"content":" // there is usually at least one instructor with \"modify instructor\" permission"},{"lineNumber":175,"author":{"gitId":"-"},"content":" if (masqueradeGoogleId \u003d\u003d\u003d \u0027\u0027) {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" for (const instructor of instructors.instructors) {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" const instructorPrivilege: InstructorPrivilege | undefined \u003d instructorPrivileges.shift();"},{"lineNumber":178,"author":{"gitId":"-"},"content":" if (instructor.googleId"},{"lineNumber":179,"author":{"gitId":"-"},"content":" \u0026\u0026 (instructorPrivilege \u0026\u0026 instructorPrivilege.privileges.courseLevel.canModifyInstructor)) {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" masqueradeGoogleId \u003d instructor.googleId;"},{"lineNumber":181,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":182,"author":{"gitId":"-"},"content":" }"},{"lineNumber":183,"author":{"gitId":"-"},"content":" }"},{"lineNumber":184,"author":{"gitId":"-"},"content":" }"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" // Generate feedback session urls"},{"lineNumber":187,"author":{"gitId":"-"},"content":" const { awaitingSessions, openSessions, notOpenSessions, publishedSessions }: StudentFeedbackSessions \u003d"},{"lineNumber":188,"author":{"gitId":"-"},"content":" this.classifyFeedbackSessions(feedbackSessions, student, false);"},{"lineNumber":189,"author":{"gitId":"-"},"content":" studentResult \u003d { ...studentResult, awaitingSessions, openSessions, notOpenSessions, publishedSessions };"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" // Generate links for students"},{"lineNumber":192,"author":{"gitId":"-"},"content":" studentResult.courseJoinLink \u003d this.linkService.generateCourseJoinLink(student, \u0027student\u0027);"},{"lineNumber":193,"author":{"gitId":"-"},"content":" studentResult.homePageLink \u003d this.linkService"},{"lineNumber":194,"author":{"gitId":"-"},"content":" .generateHomePageLink(googleId, this.linkService.STUDENT_HOME_PAGE);"},{"lineNumber":195,"author":{"gitId":"-"},"content":" studentResult.profilePageLink \u003d this.linkService.generateProfilePageLink(student, masqueradeGoogleId);"},{"lineNumber":196,"author":{"gitId":"-"},"content":" studentResult.manageAccountLink \u003d this.linkService"},{"lineNumber":197,"author":{"gitId":"-"},"content":" .generateManageAccountLink(googleId, this.linkService.ADMIN_ACCOUNTS_PAGE);"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" return studentResult;"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }"},{"lineNumber":201,"author":{"gitId":"-"},"content":""},{"lineNumber":202,"author":{"gitId":"-"},"content":" createInstructorAccountSearchResults("},{"lineNumber":203,"author":{"gitId":"-"},"content":" instructors: Instructor[],"},{"lineNumber":204,"author":{"gitId":"-"},"content":" distinctCoursesMap: DistinctCoursesMap,"},{"lineNumber":205,"author":{"gitId":"-"},"content":" distinctFeedbackSessionsMap: DistinctFeedbackSessionsMap,"},{"lineNumber":206,"author":{"gitId":"-"},"content":" ): InstructorAccountSearchResult[] {"},{"lineNumber":207,"author":{"gitId":"-"},"content":" return instructors.map((instructor: Instructor) \u003d\u003e"},{"lineNumber":208,"author":{"gitId":"-"},"content":" this.joinAdminInstructor(instructor, distinctCoursesMap[instructor.courseId],"},{"lineNumber":209,"author":{"gitId":"-"},"content":" distinctFeedbackSessionsMap[instructor.courseId]));"},{"lineNumber":210,"author":{"gitId":"-"},"content":" }"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" joinAdminInstructor("},{"lineNumber":213,"author":{"gitId":"-"},"content":" instructor: Instructor,"},{"lineNumber":214,"author":{"gitId":"-"},"content":" course: Course,"},{"lineNumber":215,"author":{"gitId":"-"},"content":" feedbackSessions: FeedbackSessions,"},{"lineNumber":216,"author":{"gitId":"-"},"content":" ): InstructorAccountSearchResult {"},{"lineNumber":217,"author":{"gitId":"-"},"content":" let instructorResult: InstructorAccountSearchResult \u003d {"},{"lineNumber":218,"author":{"gitId":"-"},"content":" email: \u0027\u0027,"},{"lineNumber":219,"author":{"gitId":"-"},"content":" name: \u0027\u0027,"},{"lineNumber":220,"author":{"gitId":"-"},"content":" courseId: \u0027\u0027,"},{"lineNumber":221,"author":{"gitId":"-"},"content":" courseName: \u0027\u0027,"},{"lineNumber":222,"author":{"gitId":"-"},"content":" isCourseDeleted: false,"},{"lineNumber":223,"author":{"gitId":"-"},"content":" institute: \u0027\u0027,"},{"lineNumber":224,"author":{"gitId":"-"},"content":" manageAccountLink: \u0027\u0027,"},{"lineNumber":225,"author":{"gitId":"-"},"content":" homePageLink: \u0027\u0027,"},{"lineNumber":226,"author":{"gitId":"-"},"content":" courseJoinLink: \u0027\u0027,"},{"lineNumber":227,"author":{"gitId":"-"},"content":" googleId: \u0027\u0027,"},{"lineNumber":228,"author":{"gitId":"-"},"content":" showLinks: false,"},{"lineNumber":229,"author":{"gitId":"-"},"content":" awaitingSessions: {},"},{"lineNumber":230,"author":{"gitId":"-"},"content":" openSessions: {},"},{"lineNumber":231,"author":{"gitId":"-"},"content":" notOpenSessions: {},"},{"lineNumber":232,"author":{"gitId":"-"},"content":" publishedSessions: {},"},{"lineNumber":233,"author":{"gitId":"-"},"content":" };"},{"lineNumber":234,"author":{"gitId":"-"},"content":" const { email, name, googleId \u003d \u0027\u0027, institute \u003d \u0027\u0027 }: Instructor \u003d instructor;"},{"lineNumber":235,"author":{"gitId":"-"},"content":" instructorResult \u003d { ...instructorResult, email, name, googleId, institute };"},{"lineNumber":236,"author":{"gitId":"-"},"content":""},{"lineNumber":237,"author":{"gitId":"-"},"content":" const { courseId, courseName, deletionTimestamp }: Course \u003d course;"},{"lineNumber":238,"author":{"gitId":"-"},"content":" instructorResult \u003d { ...instructorResult, courseId, courseName, isCourseDeleted: Boolean(deletionTimestamp) };"},{"lineNumber":239,"author":{"gitId":"-"},"content":""},{"lineNumber":240,"author":{"gitId":"-"},"content":" // Generate feedback session urls"},{"lineNumber":241,"author":{"gitId":"-"},"content":" const { awaitingSessions, openSessions, notOpenSessions, publishedSessions }: StudentFeedbackSessions \u003d"},{"lineNumber":242,"author":{"gitId":"-"},"content":" this.classifyFeedbackSessions(feedbackSessions, instructor, true);"},{"lineNumber":243,"author":{"gitId":"-"},"content":" instructorResult \u003d { ...instructorResult, awaitingSessions, openSessions, notOpenSessions, publishedSessions };"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":" // Generate links for instructors"},{"lineNumber":246,"author":{"gitId":"-"},"content":" instructorResult.courseJoinLink \u003d this.linkService.generateCourseJoinLink(instructor, \u0027instructor\u0027);"},{"lineNumber":247,"author":{"gitId":"-"},"content":" instructorResult.homePageLink \u003d this.linkService"},{"lineNumber":248,"author":{"gitId":"-"},"content":" .generateHomePageLink(googleId, this.linkService.INSTRUCTOR_HOME_PAGE);"},{"lineNumber":249,"author":{"gitId":"-"},"content":" instructorResult.manageAccountLink \u003d this.linkService"},{"lineNumber":250,"author":{"gitId":"-"},"content":" .generateManageAccountLink(googleId, this.linkService.ADMIN_ACCOUNTS_PAGE);"},{"lineNumber":251,"author":{"gitId":"-"},"content":""},{"lineNumber":252,"author":{"gitId":"-"},"content":" return instructorResult;"},{"lineNumber":253,"author":{"gitId":"-"},"content":" }"},{"lineNumber":254,"author":{"gitId":"-"},"content":""},{"lineNumber":255,"author":{"gitId":"-"},"content":" classifyFeedbackSessions(feedbackSessions: FeedbackSessions, entity: Student | Instructor, isInstructor: boolean):"},{"lineNumber":256,"author":{"gitId":"-"},"content":" StudentFeedbackSessions {"},{"lineNumber":257,"author":{"gitId":"-"},"content":" const feedbackSessionLinks: StudentFeedbackSessions \u003d {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" awaitingSessions: {},"},{"lineNumber":259,"author":{"gitId":"-"},"content":" openSessions: {},"},{"lineNumber":260,"author":{"gitId":"-"},"content":" notOpenSessions: {},"},{"lineNumber":261,"author":{"gitId":"-"},"content":" publishedSessions: {},"},{"lineNumber":262,"author":{"gitId":"-"},"content":" };"},{"lineNumber":263,"author":{"gitId":"-"},"content":" for (const feedbackSession of feedbackSessions.feedbackSessions) {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" if (this.feedbackSessionService.isFeedbackSessionOpen(feedbackSession)) {"},{"lineNumber":265,"author":{"gitId":"-"},"content":" feedbackSessionLinks.openSessions[feedbackSession.feedbackSessionName] \u003d {"},{"lineNumber":266,"author":{"gitId":"-"},"content":" ...this.formatProperties(feedbackSession),"},{"lineNumber":267,"author":{"gitId":"-"},"content":" feedbackSessionUrl: this.linkService.generateSubmitUrl("},{"lineNumber":268,"author":{"gitId":"-"},"content":" entity, feedbackSession.feedbackSessionName, isInstructor),"},{"lineNumber":269,"author":{"gitId":"-"},"content":" };"},{"lineNumber":270,"author":{"gitId":"-"},"content":" } else if (this.feedbackSessionService.isFeedbackSessionAwaiting(feedbackSession)) {"},{"lineNumber":271,"author":{"gitId":"-"},"content":" feedbackSessionLinks.awaitingSessions[feedbackSession.feedbackSessionName] \u003d {"},{"lineNumber":272,"author":{"gitId":"-"},"content":" ...this.formatProperties(feedbackSession),"},{"lineNumber":273,"author":{"gitId":"-"},"content":" feedbackSessionUrl: this.linkService.generateSubmitUrl("},{"lineNumber":274,"author":{"gitId":"-"},"content":" entity, feedbackSession.feedbackSessionName, isInstructor),"},{"lineNumber":275,"author":{"gitId":"-"},"content":" };"},{"lineNumber":276,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":277,"author":{"gitId":"-"},"content":" feedbackSessionLinks.notOpenSessions[feedbackSession.feedbackSessionName] \u003d {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" ...this.formatProperties(feedbackSession),"},{"lineNumber":279,"author":{"gitId":"-"},"content":" feedbackSessionUrl: this.linkService.generateSubmitUrl("},{"lineNumber":280,"author":{"gitId":"-"},"content":" entity, feedbackSession.feedbackSessionName, isInstructor),"},{"lineNumber":281,"author":{"gitId":"-"},"content":" };"},{"lineNumber":282,"author":{"gitId":"-"},"content":" }"},{"lineNumber":283,"author":{"gitId":"-"},"content":""},{"lineNumber":284,"author":{"gitId":"-"},"content":" if (this.feedbackSessionService.isFeedbackSessionPublished(feedbackSession)) {"},{"lineNumber":285,"author":{"gitId":"-"},"content":" feedbackSessionLinks.publishedSessions[feedbackSession.feedbackSessionName] \u003d {"},{"lineNumber":286,"author":{"gitId":"-"},"content":" ...this.formatProperties(feedbackSession),"},{"lineNumber":287,"author":{"gitId":"-"},"content":" feedbackSessionUrl: this.linkService.generateResultUrl("},{"lineNumber":288,"author":{"gitId":"-"},"content":" entity, feedbackSession.feedbackSessionName, isInstructor),"},{"lineNumber":289,"author":{"gitId":"-"},"content":" };"},{"lineNumber":290,"author":{"gitId":"-"},"content":" }"},{"lineNumber":291,"author":{"gitId":"-"},"content":" }"},{"lineNumber":292,"author":{"gitId":"-"},"content":" return feedbackSessionLinks;"},{"lineNumber":293,"author":{"gitId":"-"},"content":" }"},{"lineNumber":294,"author":{"gitId":"-"},"content":""},{"lineNumber":295,"author":{"gitId":"-"},"content":" createAccountRequestSearchResults("},{"lineNumber":296,"author":{"gitId":"-"},"content":" accountRequests: AccountRequest[],"},{"lineNumber":297,"author":{"gitId":"-"},"content":" ): AccountRequestSearchResult[] {"},{"lineNumber":298,"author":{"gitId":"-"},"content":" return accountRequests.map((accountRequest: AccountRequest) \u003d\u003e this.joinAdminAccountRequest(accountRequest));"},{"lineNumber":299,"author":{"gitId":"-"},"content":" }"},{"lineNumber":300,"author":{"gitId":"-"},"content":""},{"lineNumber":301,"author":{"gitId":"-"},"content":" joinAdminAccountRequest(accountRequest: AccountRequest): AccountRequestSearchResult {"},{"lineNumber":302,"author":{"gitId":"-"},"content":" let accountRequestResult: AccountRequestSearchResult \u003d {"},{"lineNumber":303,"author":{"gitId":"-"},"content":" id: \u0027\u0027,"},{"lineNumber":304,"author":{"gitId":"-"},"content":" name: \u0027\u0027,"},{"lineNumber":305,"author":{"gitId":"-"},"content":" email: \u0027\u0027,"},{"lineNumber":306,"author":{"gitId":"-"},"content":" institute: \u0027\u0027,"},{"lineNumber":307,"author":{"gitId":"-"},"content":" createdAtText: \u0027\u0027,"},{"lineNumber":308,"author":{"gitId":"-"},"content":" registeredAtText: \u0027\u0027,"},{"lineNumber":309,"author":{"gitId":"-"},"content":" registrationLink: \u0027\u0027,"},{"lineNumber":310,"author":{"gitId":"-"},"content":" showLinks: false,"},{"lineNumber":311,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus.PENDING,"},{"lineNumber":312,"author":{"gitId":"domoberzin"},"content":" comments: \u0027\u0027,"},{"lineNumber":313,"author":{"gitId":"-"},"content":" };"},{"lineNumber":314,"author":{"gitId":"-"},"content":""},{"lineNumber":315,"author":{"gitId":"domoberzin"},"content":" const {"},{"lineNumber":316,"author":{"gitId":"-"},"content":" id, registrationKey, createdAt, registeredAt,"},{"lineNumber":317,"author":{"gitId":"domoberzin"},"content":" name, institute, email, status, comments,"},{"lineNumber":318,"author":{"gitId":"domoberzin"},"content":" }: AccountRequest \u003d accountRequest;"},{"lineNumber":319,"author":{"gitId":"-"},"content":""},{"lineNumber":320,"author":{"gitId":"-"},"content":" const timezone: string \u003d this.timezoneService.guessTimezone() || \u0027UTC\u0027;"},{"lineNumber":321,"author":{"gitId":"-"},"content":" accountRequestResult.createdAtText \u003d this.formatTimestampAsString(createdAt, timezone);"},{"lineNumber":322,"author":{"gitId":"-"},"content":" accountRequestResult.registeredAtText \u003d registeredAt ? this.formatTimestampAsString(registeredAt, timezone) : null;"},{"lineNumber":323,"author":{"gitId":"domoberzin"},"content":" accountRequestResult.comments \u003d comments || \u0027\u0027;"},{"lineNumber":324,"author":{"gitId":"-"},"content":""},{"lineNumber":325,"author":{"gitId":"-"},"content":" const registrationLink: string \u003d this.linkService.generateAccountRegistrationLink(registrationKey);"},{"lineNumber":326,"author":{"gitId":"-"},"content":" accountRequestResult \u003d { ...accountRequestResult, id, name, email, institute, registrationLink, status };"},{"lineNumber":327,"author":{"gitId":"-"},"content":""},{"lineNumber":328,"author":{"gitId":"-"},"content":" return accountRequestResult;"},{"lineNumber":329,"author":{"gitId":"-"},"content":" }"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" private getDistinctFields(students: Student[], instructors: Instructor[]): Observable\u003cDistinctFields\u003e {"},{"lineNumber":332,"author":{"gitId":"-"},"content":" const distinctCourseIds: string[] \u003d Array.from(new Set(["},{"lineNumber":333,"author":{"gitId":"-"},"content":" ...students.map((student: Student) \u003d\u003e student.courseId),"},{"lineNumber":334,"author":{"gitId":"-"},"content":" ...instructors.map((instructor: Instructor) \u003d\u003e instructor.courseId),"},{"lineNumber":335,"author":{"gitId":"-"},"content":" ]));"},{"lineNumber":336,"author":{"gitId":"-"},"content":" if (distinctCourseIds.length \u003d\u003d\u003d 0) {"},{"lineNumber":337,"author":{"gitId":"-"},"content":" return forkJoin([of({}), of({}), of({}), of({})]);"},{"lineNumber":338,"author":{"gitId":"-"},"content":" }"},{"lineNumber":339,"author":{"gitId":"-"},"content":" return forkJoin(["},{"lineNumber":340,"author":{"gitId":"-"},"content":" this.getDistinctInstructors(distinctCourseIds),"},{"lineNumber":341,"author":{"gitId":"-"},"content":" this.getDistinctCourses(distinctCourseIds),"},{"lineNumber":342,"author":{"gitId":"-"},"content":" this.getDistinctFeedbackSessions(distinctCourseIds),"},{"lineNumber":343,"author":{"gitId":"-"},"content":" ]).pipe("},{"lineNumber":344,"author":{"gitId":"-"},"content":" mergeMap((value: ["},{"lineNumber":345,"author":{"gitId":"-"},"content":" DistinctInstructorsMap,"},{"lineNumber":346,"author":{"gitId":"-"},"content":" DistinctCoursesMap,"},{"lineNumber":347,"author":{"gitId":"-"},"content":" DistinctFeedbackSessionsMap],"},{"lineNumber":348,"author":{"gitId":"-"},"content":" ) \u003d\u003e {"},{"lineNumber":349,"author":{"gitId":"-"},"content":" return forkJoin(["},{"lineNumber":350,"author":{"gitId":"-"},"content":" of(value[0]),"},{"lineNumber":351,"author":{"gitId":"-"},"content":" of(value[1]),"},{"lineNumber":352,"author":{"gitId":"-"},"content":" of(value[2]),"},{"lineNumber":353,"author":{"gitId":"-"},"content":" this.getDistinctInstructorPrivileges(value[0]),"},{"lineNumber":354,"author":{"gitId":"-"},"content":" ]);"},{"lineNumber":355,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":356,"author":{"gitId":"-"},"content":" );"},{"lineNumber":357,"author":{"gitId":"-"},"content":" }"},{"lineNumber":358,"author":{"gitId":"-"},"content":""},{"lineNumber":359,"author":{"gitId":"-"},"content":" private getDistinctInstructors(distinctCourseIds: string[]): Observable\u003cDistinctInstructorsMap\u003e {"},{"lineNumber":360,"author":{"gitId":"-"},"content":" return forkJoin("},{"lineNumber":361,"author":{"gitId":"-"},"content":" distinctCourseIds.map((courseId: string) \u003d\u003e"},{"lineNumber":362,"author":{"gitId":"-"},"content":" this.instructorService.loadInstructors({ courseId, intent: Intent.FULL_DETAIL })),"},{"lineNumber":363,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":364,"author":{"gitId":"-"},"content":" map((instructorsArray: Instructors[]) \u003d\u003e {"},{"lineNumber":365,"author":{"gitId":"-"},"content":" const distinctInstructorsMap: DistinctInstructorsMap \u003d {};"},{"lineNumber":366,"author":{"gitId":"-"},"content":" instructorsArray.forEach((instructors: Instructors, index: number) \u003d\u003e {"},{"lineNumber":367,"author":{"gitId":"-"},"content":" distinctInstructorsMap[distinctCourseIds[index]] \u003d instructors;"},{"lineNumber":368,"author":{"gitId":"-"},"content":" });"},{"lineNumber":369,"author":{"gitId":"-"},"content":" return distinctInstructorsMap;"},{"lineNumber":370,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":371,"author":{"gitId":"-"},"content":" );"},{"lineNumber":372,"author":{"gitId":"-"},"content":" }"},{"lineNumber":373,"author":{"gitId":"-"},"content":""},{"lineNumber":374,"author":{"gitId":"-"},"content":" private getDistinctInstructorPrivileges("},{"lineNumber":375,"author":{"gitId":"-"},"content":" distinctInstructorsMap: DistinctInstructorsMap,"},{"lineNumber":376,"author":{"gitId":"-"},"content":" ): Observable\u003cDistinctInstructorPrivilegesMap\u003e {"},{"lineNumber":377,"author":{"gitId":"-"},"content":" const distinctCourseIds: string[] \u003d Object.keys(distinctInstructorsMap);"},{"lineNumber":378,"author":{"gitId":"-"},"content":" const instructorsArray: Instructors[] \u003d Object.values(distinctInstructorsMap);"},{"lineNumber":379,"author":{"gitId":"-"},"content":" return forkJoin(["},{"lineNumber":380,"author":{"gitId":"-"},"content":" of(distinctCourseIds),"},{"lineNumber":381,"author":{"gitId":"-"},"content":" forkJoin(instructorsArray.map((instructors: Instructors) \u003d\u003e {"},{"lineNumber":382,"author":{"gitId":"-"},"content":" return forkJoin("},{"lineNumber":383,"author":{"gitId":"-"},"content":" instructors.instructors.map("},{"lineNumber":384,"author":{"gitId":"-"},"content":" (instructor: Instructor) \u003d\u003e this.instructorService.loadInstructorPrivilege("},{"lineNumber":385,"author":{"gitId":"-"},"content":" {"},{"lineNumber":386,"author":{"gitId":"-"},"content":" courseId: instructor.courseId,"},{"lineNumber":387,"author":{"gitId":"-"},"content":" instructorEmail: instructor.email,"},{"lineNumber":388,"author":{"gitId":"-"},"content":" },"},{"lineNumber":389,"author":{"gitId":"-"},"content":" ),"},{"lineNumber":390,"author":{"gitId":"-"},"content":" ),"},{"lineNumber":391,"author":{"gitId":"-"},"content":" );"},{"lineNumber":392,"author":{"gitId":"-"},"content":" })),"},{"lineNumber":393,"author":{"gitId":"-"},"content":" ]).pipe("},{"lineNumber":394,"author":{"gitId":"-"},"content":" map("},{"lineNumber":395,"author":{"gitId":"-"},"content":" (value: [string[], InstructorPrivilege[][]]) \u003d\u003e {"},{"lineNumber":396,"author":{"gitId":"-"},"content":" const distinctInstructorPrivilegesMap: DistinctInstructorPrivilegesMap \u003d {};"},{"lineNumber":397,"author":{"gitId":"-"},"content":" value[1].forEach((instructorPrivilegesArray: InstructorPrivilege[], index: number) \u003d\u003e {"},{"lineNumber":398,"author":{"gitId":"-"},"content":" distinctInstructorPrivilegesMap[value[0][index]] \u003d instructorPrivilegesArray;"},{"lineNumber":399,"author":{"gitId":"-"},"content":" });"},{"lineNumber":400,"author":{"gitId":"-"},"content":" return distinctInstructorPrivilegesMap;"},{"lineNumber":401,"author":{"gitId":"-"},"content":" },"},{"lineNumber":402,"author":{"gitId":"-"},"content":" ),"},{"lineNumber":403,"author":{"gitId":"-"},"content":" );"},{"lineNumber":404,"author":{"gitId":"-"},"content":" }"},{"lineNumber":405,"author":{"gitId":"-"},"content":""},{"lineNumber":406,"author":{"gitId":"-"},"content":" private getDistinctCourses(distinctCourseIds: string[]): Observable\u003cDistinctCoursesMap\u003e {"},{"lineNumber":407,"author":{"gitId":"-"},"content":" return forkJoin("},{"lineNumber":408,"author":{"gitId":"-"},"content":" distinctCourseIds.map((id: string) \u003d\u003e this.courseService.getCourseAsInstructor(id)),"},{"lineNumber":409,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":410,"author":{"gitId":"-"},"content":" map((courses: Course[]) \u003d\u003e {"},{"lineNumber":411,"author":{"gitId":"-"},"content":" const distinctCoursesMap: DistinctCoursesMap \u003d {};"},{"lineNumber":412,"author":{"gitId":"-"},"content":" courses.forEach((course: Course, index: number) \u003d\u003e {"},{"lineNumber":413,"author":{"gitId":"-"},"content":" distinctCoursesMap[distinctCourseIds[index]] \u003d course;"},{"lineNumber":414,"author":{"gitId":"-"},"content":" });"},{"lineNumber":415,"author":{"gitId":"-"},"content":" return distinctCoursesMap;"},{"lineNumber":416,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":417,"author":{"gitId":"-"},"content":" );"},{"lineNumber":418,"author":{"gitId":"-"},"content":" }"},{"lineNumber":419,"author":{"gitId":"-"},"content":""},{"lineNumber":420,"author":{"gitId":"-"},"content":" private getDistinctFeedbackSessions(distinctCourseIds: string[]): Observable\u003cDistinctFeedbackSessionsMap\u003e {"},{"lineNumber":421,"author":{"gitId":"-"},"content":" return forkJoin("},{"lineNumber":422,"author":{"gitId":"-"},"content":" distinctCourseIds.map((id: string) \u003d\u003e"},{"lineNumber":423,"author":{"gitId":"-"},"content":" this.feedbackSessionService.getFeedbackSessionsForStudent(\u0027admin\u0027, id)),"},{"lineNumber":424,"author":{"gitId":"-"},"content":" )"},{"lineNumber":425,"author":{"gitId":"-"},"content":" .pipe("},{"lineNumber":426,"author":{"gitId":"-"},"content":" map((feedbackSessionsArray: FeedbackSessions[]) \u003d\u003e {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" const distinctFeedbackSessionsMap: DistinctFeedbackSessionsMap \u003d {};"},{"lineNumber":428,"author":{"gitId":"-"},"content":" feedbackSessionsArray.forEach("},{"lineNumber":429,"author":{"gitId":"-"},"content":" (feedbackSessions: FeedbackSessions, index: number) \u003d\u003e {"},{"lineNumber":430,"author":{"gitId":"-"},"content":" distinctFeedbackSessionsMap[distinctCourseIds[index]] \u003d feedbackSessions;"},{"lineNumber":431,"author":{"gitId":"-"},"content":" },"},{"lineNumber":432,"author":{"gitId":"-"},"content":" );"},{"lineNumber":433,"author":{"gitId":"-"},"content":" return distinctFeedbackSessionsMap;"},{"lineNumber":434,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":435,"author":{"gitId":"-"},"content":" );"},{"lineNumber":436,"author":{"gitId":"-"},"content":" }"},{"lineNumber":437,"author":{"gitId":"-"},"content":""},{"lineNumber":438,"author":{"gitId":"-"},"content":" private formatProperties(feedbackSession: FeedbackSession): { startTime: string, endTime: string } {"},{"lineNumber":439,"author":{"gitId":"-"},"content":" const startTime: string \u003d"},{"lineNumber":440,"author":{"gitId":"-"},"content":" this.formatTimestampAsString(feedbackSession.submissionStartTimestamp, feedbackSession.timeZone);"},{"lineNumber":441,"author":{"gitId":"-"},"content":" const endTime: string \u003d"},{"lineNumber":442,"author":{"gitId":"-"},"content":" this.formatTimestampAsString(feedbackSession.submissionEndTimestamp, feedbackSession.timeZone);"},{"lineNumber":443,"author":{"gitId":"-"},"content":""},{"lineNumber":444,"author":{"gitId":"-"},"content":" return { startTime, endTime };"},{"lineNumber":445,"author":{"gitId":"-"},"content":" }"},{"lineNumber":446,"author":{"gitId":"-"},"content":""},{"lineNumber":447,"author":{"gitId":"-"},"content":" private formatTimestampAsString(timestamp: number, timezone: string): string {"},{"lineNumber":448,"author":{"gitId":"-"},"content":" const dateFormatWithZoneInfo: string \u003d \u0027ddd, DD MMM YYYY, hh:mm A Z\u0027;"},{"lineNumber":449,"author":{"gitId":"-"},"content":""},{"lineNumber":450,"author":{"gitId":"-"},"content":" return this.timezoneService"},{"lineNumber":451,"author":{"gitId":"-"},"content":" .formatToString(timestamp, timezone, dateFormatWithZoneInfo);"},{"lineNumber":452,"author":{"gitId":"-"},"content":" }"},{"lineNumber":453,"author":{"gitId":"-"},"content":"}"},{"lineNumber":454,"author":{"gitId":"-"},"content":""},{"lineNumber":455,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":456,"author":{"gitId":"-"},"content":" * The typings for the response object returned by the instructor search service."},{"lineNumber":457,"author":{"gitId":"-"},"content":" */"},{"lineNumber":458,"author":{"gitId":"-"},"content":"export interface InstructorSearchResult {"},{"lineNumber":459,"author":{"gitId":"-"},"content":" students: Student[];"},{"lineNumber":460,"author":{"gitId":"-"},"content":"}"},{"lineNumber":461,"author":{"gitId":"-"},"content":""},{"lineNumber":462,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":463,"author":{"gitId":"-"},"content":" * The typings for the response object returned by admin search service."},{"lineNumber":464,"author":{"gitId":"-"},"content":" */"},{"lineNumber":465,"author":{"gitId":"-"},"content":"export interface AdminSearchResult {"},{"lineNumber":466,"author":{"gitId":"-"},"content":" students: StudentAccountSearchResult[];"},{"lineNumber":467,"author":{"gitId":"-"},"content":" instructors: InstructorAccountSearchResult[];"},{"lineNumber":468,"author":{"gitId":"-"},"content":" accountRequests: AccountRequestSearchResult[];"},{"lineNumber":469,"author":{"gitId":"-"},"content":"}"},{"lineNumber":470,"author":{"gitId":"-"},"content":""},{"lineNumber":471,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":472,"author":{"gitId":"-"},"content":" * Search results for account requests from the admin endpoint."},{"lineNumber":473,"author":{"gitId":"-"},"content":" */"},{"lineNumber":474,"author":{"gitId":"-"},"content":"export interface AccountRequestSearchResult {"},{"lineNumber":475,"author":{"gitId":"-"},"content":" id: string;"},{"lineNumber":476,"author":{"gitId":"-"},"content":" name: string;"},{"lineNumber":477,"author":{"gitId":"-"},"content":" email: string;"},{"lineNumber":478,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus;"},{"lineNumber":479,"author":{"gitId":"-"},"content":" institute: string;"},{"lineNumber":480,"author":{"gitId":"-"},"content":" createdAtText: string;"},{"lineNumber":481,"author":{"gitId":"-"},"content":" registeredAtText: string | null;"},{"lineNumber":482,"author":{"gitId":"-"},"content":" registrationLink: string;"},{"lineNumber":483,"author":{"gitId":"-"},"content":" showLinks: boolean;"},{"lineNumber":484,"author":{"gitId":"domoberzin"},"content":" comments: string;"},{"lineNumber":485,"author":{"gitId":"-"},"content":"}"},{"lineNumber":486,"author":{"gitId":"-"},"content":""},{"lineNumber":487,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":488,"author":{"gitId":"-"},"content":" * Search results for instructors for the admin endpoint"},{"lineNumber":489,"author":{"gitId":"-"},"content":" */"},{"lineNumber":490,"author":{"gitId":"-"},"content":"export interface InstructorAccountSearchResult {"},{"lineNumber":491,"author":{"gitId":"-"},"content":" name: string;"},{"lineNumber":492,"author":{"gitId":"-"},"content":" email: string;"},{"lineNumber":493,"author":{"gitId":"-"},"content":" googleId: string;"},{"lineNumber":494,"author":{"gitId":"-"},"content":" courseId: string;"},{"lineNumber":495,"author":{"gitId":"-"},"content":" courseName: string;"},{"lineNumber":496,"author":{"gitId":"-"},"content":" isCourseDeleted: boolean;"},{"lineNumber":497,"author":{"gitId":"-"},"content":" institute: string;"},{"lineNumber":498,"author":{"gitId":"-"},"content":" courseJoinLink: string;"},{"lineNumber":499,"author":{"gitId":"-"},"content":" homePageLink: string;"},{"lineNumber":500,"author":{"gitId":"-"},"content":" manageAccountLink: string;"},{"lineNumber":501,"author":{"gitId":"-"},"content":" showLinks: boolean;"},{"lineNumber":502,"author":{"gitId":"-"},"content":" awaitingSessions: FeedbackSessionsGroup;"},{"lineNumber":503,"author":{"gitId":"-"},"content":" openSessions: FeedbackSessionsGroup;"},{"lineNumber":504,"author":{"gitId":"-"},"content":" notOpenSessions: FeedbackSessionsGroup;"},{"lineNumber":505,"author":{"gitId":"-"},"content":" publishedSessions: FeedbackSessionsGroup;"},{"lineNumber":506,"author":{"gitId":"-"},"content":"}"},{"lineNumber":507,"author":{"gitId":"-"},"content":""},{"lineNumber":508,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":509,"author":{"gitId":"-"},"content":" * Search results for students from the Admin endpoint."},{"lineNumber":510,"author":{"gitId":"-"},"content":" */"},{"lineNumber":511,"author":{"gitId":"-"},"content":"export interface StudentAccountSearchResult extends InstructorAccountSearchResult {"},{"lineNumber":512,"author":{"gitId":"-"},"content":" section: string;"},{"lineNumber":513,"author":{"gitId":"-"},"content":" team: string;"},{"lineNumber":514,"author":{"gitId":"-"},"content":" comments: string;"},{"lineNumber":515,"author":{"gitId":"-"},"content":" profilePageLink: string;"},{"lineNumber":516,"author":{"gitId":"-"},"content":"}"},{"lineNumber":517,"author":{"gitId":"-"},"content":""},{"lineNumber":518,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":519,"author":{"gitId":"-"},"content":" * Feedback session information for search result."},{"lineNumber":520,"author":{"gitId":"-"},"content":" */"},{"lineNumber":521,"author":{"gitId":"-"},"content":"export interface FeedbackSessionsGroup {"},{"lineNumber":522,"author":{"gitId":"-"},"content":" [name: string]: {"},{"lineNumber":523,"author":{"gitId":"-"},"content":" startTime: string,"},{"lineNumber":524,"author":{"gitId":"-"},"content":" endTime: string,"},{"lineNumber":525,"author":{"gitId":"-"},"content":" feedbackSessionUrl: string,"},{"lineNumber":526,"author":{"gitId":"-"},"content":" };"},{"lineNumber":527,"author":{"gitId":"-"},"content":"}"},{"lineNumber":528,"author":{"gitId":"-"},"content":""},{"lineNumber":529,"author":{"gitId":"-"},"content":"interface StudentFeedbackSessions {"},{"lineNumber":530,"author":{"gitId":"-"},"content":" awaitingSessions: FeedbackSessionsGroup;"},{"lineNumber":531,"author":{"gitId":"-"},"content":" openSessions: FeedbackSessionsGroup;"},{"lineNumber":532,"author":{"gitId":"-"},"content":" notOpenSessions: FeedbackSessionsGroup;"},{"lineNumber":533,"author":{"gitId":"-"},"content":" publishedSessions: FeedbackSessionsGroup;"},{"lineNumber":534,"author":{"gitId":"-"},"content":"}"},{"lineNumber":535,"author":{"gitId":"-"},"content":""},{"lineNumber":536,"author":{"gitId":"-"},"content":"interface DistinctInstructorsMap {"},{"lineNumber":537,"author":{"gitId":"-"},"content":" [courseId: string]: Instructors;"},{"lineNumber":538,"author":{"gitId":"-"},"content":"}"},{"lineNumber":539,"author":{"gitId":"-"},"content":""},{"lineNumber":540,"author":{"gitId":"-"},"content":"interface DistinctFeedbackSessionsMap {"},{"lineNumber":541,"author":{"gitId":"-"},"content":" [courseId: string]: FeedbackSessions;"},{"lineNumber":542,"author":{"gitId":"-"},"content":"}"},{"lineNumber":543,"author":{"gitId":"-"},"content":""},{"lineNumber":544,"author":{"gitId":"-"},"content":"interface DistinctCoursesMap {"},{"lineNumber":545,"author":{"gitId":"-"},"content":" [courseId: string]: Course;"},{"lineNumber":546,"author":{"gitId":"-"},"content":"}"},{"lineNumber":547,"author":{"gitId":"-"},"content":""},{"lineNumber":548,"author":{"gitId":"-"},"content":"interface DistinctInstructorPrivilegesMap {"},{"lineNumber":549,"author":{"gitId":"-"},"content":" [courseId: string]: InstructorPrivilege[];"},{"lineNumber":550,"author":{"gitId":"-"},"content":"}"},{"lineNumber":551,"author":{"gitId":"-"},"content":""},{"lineNumber":552,"author":{"gitId":"-"},"content":"type DistinctFields \u003d ["},{"lineNumber":553,"author":{"gitId":"-"},"content":" DistinctInstructorsMap,"},{"lineNumber":554,"author":{"gitId":"-"},"content":" DistinctCoursesMap,"},{"lineNumber":555,"author":{"gitId":"-"},"content":" DistinctFeedbackSessionsMap,"},{"lineNumber":556,"author":{"gitId":"-"},"content":" DistinctInstructorPrivilegesMap,"},{"lineNumber":557,"author":{"gitId":"-"},"content":"];"}],"authorContributionMap":{"domoberzin":9,"-":548}},{"path":"src/web/types/const.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"import { ApiConst, ApiStringConst } from \u0027./api-const\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { FeedbackQuestionType } from \u0027./api-output\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":4,"author":{"gitId":"-"},"content":" DEFAULT_INSTRUCTOR_PRIVILEGE,"},{"lineNumber":5,"author":{"gitId":"-"},"content":" DEFAULT_PRIVILEGE_COOWNER,"},{"lineNumber":6,"author":{"gitId":"-"},"content":" DEFAULT_PRIVILEGE_MANAGER,"},{"lineNumber":7,"author":{"gitId":"-"},"content":" DEFAULT_PRIVILEGE_OBSERVER,"},{"lineNumber":8,"author":{"gitId":"-"},"content":" DEFAULT_PRIVILEGE_TUTOR,"},{"lineNumber":9,"author":{"gitId":"-"},"content":"} from \u0027./default-instructor-privilege\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":11,"author":{"gitId":"-"},"content":" DEFAULT_CONSTSUM_OPTIONS_QUESTION_DETAILS,"},{"lineNumber":12,"author":{"gitId":"-"},"content":" DEFAULT_CONSTSUM_RECIPIENTS_QUESTION_DETAILS,"},{"lineNumber":13,"author":{"gitId":"-"},"content":" DEFAULT_CONSTSUM_RESPONSE_DETAILS,"},{"lineNumber":14,"author":{"gitId":"-"},"content":" DEFAULT_CONTRIBUTION_QUESTION_DETAILS,"},{"lineNumber":15,"author":{"gitId":"-"},"content":" DEFAULT_CONTRIBUTION_RESPONSE_DETAILS,"},{"lineNumber":16,"author":{"gitId":"-"},"content":" DEFAULT_MCQ_QUESTION_DETAILS,"},{"lineNumber":17,"author":{"gitId":"-"},"content":" DEFAULT_MCQ_RESPONSE_DETAILS,"},{"lineNumber":18,"author":{"gitId":"-"},"content":" DEFAULT_MSQ_QUESTION_DETAILS,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" DEFAULT_MSQ_RESPONSE_DETAILS,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" DEFAULT_NUMSCALE_QUESTION_DETAILS,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" DEFAULT_NUMSCALE_RESPONSE_DETAILS,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" DEFAULT_RANK_OPTIONS_QUESTION_DETAILS,"},{"lineNumber":23,"author":{"gitId":"-"},"content":" DEFAULT_RANK_OPTIONS_RESPONSE_DETAILS,"},{"lineNumber":24,"author":{"gitId":"-"},"content":" DEFAULT_RANK_RECIPIENTS_QUESTION_DETAILS,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" DEFAULT_RANK_RECIPIENTS_RESPONSE_DETAILS,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" DEFAULT_RUBRIC_QUESTION_DETAILS,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" DEFAULT_RUBRIC_RESPONSE_DETAILS,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" DEFAULT_TEXT_QUESTION_DETAILS,"},{"lineNumber":29,"author":{"gitId":"-"},"content":" DEFAULT_TEXT_RESPONSE_DETAILS,"},{"lineNumber":30,"author":{"gitId":"-"},"content":"} from \u0027./default-question-structs\u0027;"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":"describe(\u0027Constants\u0027, () \u003d\u003e {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" // Here we test that the constants are positive numbers"},{"lineNumber":34,"author":{"gitId":"-"},"content":" // The exact values are implementation details that do not matter"},{"lineNumber":35,"author":{"gitId":"-"},"content":" it(\u0027should generate length limits correctly\u0027, () \u003d\u003e {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.COURSE_ID_MAX_LENGTH).toEqual(\u0027number\u0027);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" expect(ApiConst.COURSE_ID_MAX_LENGTH).toBeGreaterThan(0);"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.COURSE_NAME_MAX_LENGTH).toEqual(\u0027number\u0027);"},{"lineNumber":40,"author":{"gitId":"-"},"content":" expect(ApiConst.COURSE_NAME_MAX_LENGTH).toBeGreaterThan(0);"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.STUDENT_NAME_MAX_LENGTH).toEqual(\u0027number\u0027);"},{"lineNumber":43,"author":{"gitId":"-"},"content":" expect(ApiConst.STUDENT_NAME_MAX_LENGTH).toBeGreaterThan(0);"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.SECTION_NAME_MAX_LENGTH).toEqual(\u0027number\u0027);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" expect(ApiConst.SECTION_NAME_MAX_LENGTH).toBeGreaterThan(0);"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.TEAM_NAME_MAX_LENGTH).toEqual(\u0027number\u0027);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" expect(ApiConst.TEAM_NAME_MAX_LENGTH).toBeGreaterThan(0);"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.EMAIL_MAX_LENGTH).toEqual(\u0027number\u0027);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" expect(ApiConst.EMAIL_MAX_LENGTH).toBeGreaterThan(0);"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.FEEDBACK_SESSION_NAME_MAX_LENGTH).toEqual(\u0027number\u0027);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" expect(ApiConst.FEEDBACK_SESSION_NAME_MAX_LENGTH).toBeGreaterThan(0);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" });"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" // Here we test that the constants are numbers"},{"lineNumber":59,"author":{"gitId":"-"},"content":" // The exact values are implementation details that do not matter"},{"lineNumber":60,"author":{"gitId":"-"},"content":" it(\u0027should generate numerical constants correctly\u0027, () \u003d\u003e {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.CONTRIBUTION_POINT_NOT_SUBMITTED).toEqual(\u0027number\u0027);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.CONTRIBUTION_POINT_NOT_INITIALIZED).toEqual(\u0027number\u0027);"},{"lineNumber":63,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.CONTRIBUTION_POINT_NOT_SURE).toEqual(\u0027number\u0027);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.CONTRIBUTION_POINT_EQUAL_SHARE).toEqual(\u0027number\u0027);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.NUMERICAL_SCALE_ANSWER_NOT_SUBMITTED).toEqual(\u0027number\u0027);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.RANK_OPTIONS_ANSWER_NOT_SUBMITTED).toEqual(\u0027number\u0027);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.RANK_RECIPIENTS_ANSWER_NOT_SUBMITTED).toEqual(\u0027number\u0027);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.NO_VALUE).toEqual(\u0027number\u0027);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" });"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" // Here we test that the constants are strings"},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" it(\u0027should generate string constants correctly\u0027, () \u003d\u003e {"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":" expect(typeof ApiStringConst.EMAIL_REGEX).toEqual(\u0027string\u0027);"},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" expect(() \u003d\u003e new RegExp(ApiStringConst.EMAIL_REGEX)).not.toThrow();"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" // Here we test that:"},{"lineNumber":78,"author":{"gitId":"-"},"content":" // 1. The string is parseable to JSON"},{"lineNumber":79,"author":{"gitId":"-"},"content":" // 2. The question type is correct"},{"lineNumber":80,"author":{"gitId":"-"},"content":" // 3. There is questionText field"},{"lineNumber":81,"author":{"gitId":"-"},"content":" // They are sufficient to ascertain that the correct structure is generated"},{"lineNumber":82,"author":{"gitId":"-"},"content":" it(\u0027should generate question details correctly\u0027, () \u003d\u003e {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONSTSUM_OPTIONS_QUESTION_DETAILS().questionType).toEqual(FeedbackQuestionType.CONSTSUM_OPTIONS);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONSTSUM_OPTIONS_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONSTSUM_RECIPIENTS_QUESTION_DETAILS().questionType)"},{"lineNumber":87,"author":{"gitId":"-"},"content":" .toEqual(FeedbackQuestionType.CONSTSUM_RECIPIENTS);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONSTSUM_RECIPIENTS_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONTRIBUTION_QUESTION_DETAILS().questionType).toEqual(FeedbackQuestionType.CONTRIB);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONTRIBUTION_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" expect(DEFAULT_MCQ_QUESTION_DETAILS().questionType).toEqual(FeedbackQuestionType.MCQ);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" expect(DEFAULT_MCQ_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" expect(DEFAULT_MSQ_QUESTION_DETAILS().questionType).toEqual(FeedbackQuestionType.MSQ);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" expect(DEFAULT_MSQ_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" expect(DEFAULT_NUMSCALE_QUESTION_DETAILS().questionType).toEqual(FeedbackQuestionType.NUMSCALE);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" expect(DEFAULT_NUMSCALE_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" expect(DEFAULT_RANK_OPTIONS_QUESTION_DETAILS().questionType).toEqual(FeedbackQuestionType.RANK_OPTIONS);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" expect(DEFAULT_RANK_OPTIONS_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" expect(DEFAULT_RANK_RECIPIENTS_QUESTION_DETAILS().questionType).toEqual(FeedbackQuestionType.RANK_RECIPIENTS);"},{"lineNumber":106,"author":{"gitId":"-"},"content":" expect(DEFAULT_RANK_RECIPIENTS_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" expect(DEFAULT_RUBRIC_QUESTION_DETAILS().questionType).toEqual(FeedbackQuestionType.RUBRIC);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" expect(DEFAULT_RUBRIC_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" expect(DEFAULT_TEXT_QUESTION_DETAILS().questionType).toEqual(FeedbackQuestionType.TEXT);"},{"lineNumber":112,"author":{"gitId":"-"},"content":" expect(DEFAULT_TEXT_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" });"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" // Here we test that:"},{"lineNumber":116,"author":{"gitId":"-"},"content":" // 1. The string is parseable to JSON"},{"lineNumber":117,"author":{"gitId":"-"},"content":" // 2. The question type is correct"},{"lineNumber":118,"author":{"gitId":"-"},"content":" // 3. There is either answer or answers field (depending on question type)"},{"lineNumber":119,"author":{"gitId":"-"},"content":" // They are sufficient to ascertain that the correct structure is generated"},{"lineNumber":120,"author":{"gitId":"-"},"content":" it(\u0027should generate response details correctly\u0027, () \u003d\u003e {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONSTSUM_RESPONSE_DETAILS().questionType).toEqual(FeedbackQuestionType.CONSTSUM);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONSTSUM_RESPONSE_DETAILS().answers).toBeTruthy();"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONTRIBUTION_RESPONSE_DETAILS().questionType).toEqual(FeedbackQuestionType.CONTRIB);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONTRIBUTION_RESPONSE_DETAILS().answer).toBeTruthy();"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" expect(DEFAULT_MCQ_RESPONSE_DETAILS().questionType).toEqual(FeedbackQuestionType.MCQ);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" expect(DEFAULT_MCQ_RESPONSE_DETAILS().answer).toEqual(\u0027\u0027);"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" expect(DEFAULT_MSQ_RESPONSE_DETAILS().questionType).toEqual(FeedbackQuestionType.MSQ);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" expect(DEFAULT_MSQ_RESPONSE_DETAILS().answers).toBeTruthy();"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" expect(DEFAULT_NUMSCALE_RESPONSE_DETAILS().questionType).toEqual(FeedbackQuestionType.NUMSCALE);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" expect(DEFAULT_NUMSCALE_RESPONSE_DETAILS().answer).toBeTruthy();"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" expect(DEFAULT_RANK_OPTIONS_RESPONSE_DETAILS().questionType).toEqual(FeedbackQuestionType.RANK_OPTIONS);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" expect(DEFAULT_RANK_OPTIONS_RESPONSE_DETAILS().answers).toBeTruthy();"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" expect(DEFAULT_RANK_RECIPIENTS_RESPONSE_DETAILS().questionType).toEqual(FeedbackQuestionType.RANK_RECIPIENTS);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" expect(DEFAULT_RANK_RECIPIENTS_RESPONSE_DETAILS().answer).toBeTruthy();"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" expect(DEFAULT_RUBRIC_RESPONSE_DETAILS().questionType).toEqual(FeedbackQuestionType.RUBRIC);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" expect(DEFAULT_RUBRIC_RESPONSE_DETAILS().answer).toBeTruthy();"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" expect(DEFAULT_TEXT_RESPONSE_DETAILS().questionType).toEqual(FeedbackQuestionType.TEXT);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" expect(DEFAULT_TEXT_RESPONSE_DETAILS().answer).toEqual(\u0027\u0027);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" });"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" // Here we just test that the string is parseable to JSON and one representative privilege is correct"},{"lineNumber":150,"author":{"gitId":"-"},"content":" it(\u0027should generate instructor privileges correctly\u0027, () \u003d\u003e {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" expect(DEFAULT_INSTRUCTOR_PRIVILEGE()).toBeTruthy();"},{"lineNumber":152,"author":{"gitId":"-"},"content":" expect(DEFAULT_INSTRUCTOR_PRIVILEGE().canModifyCourse).toBeFalsy();"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"-"},"content":" expect(DEFAULT_PRIVILEGE_COOWNER()).toBeTruthy();"},{"lineNumber":155,"author":{"gitId":"-"},"content":" expect(DEFAULT_PRIVILEGE_COOWNER().canModifyCourse).toBeTruthy();"},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"-"},"content":" expect(DEFAULT_PRIVILEGE_MANAGER()).toBeTruthy();"},{"lineNumber":158,"author":{"gitId":"-"},"content":" expect(DEFAULT_PRIVILEGE_MANAGER().canModifyStudent).toBeTruthy();"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" expect(DEFAULT_PRIVILEGE_OBSERVER()).toBeTruthy();"},{"lineNumber":161,"author":{"gitId":"-"},"content":" expect(DEFAULT_PRIVILEGE_OBSERVER().canViewStudentInSections).toBeTruthy();"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" expect(DEFAULT_PRIVILEGE_TUTOR()).toBeTruthy();"},{"lineNumber":164,"author":{"gitId":"-"},"content":" expect(DEFAULT_PRIVILEGE_TUTOR().canSubmitSessionInSections).toBeTruthy();"},{"lineNumber":165,"author":{"gitId":"-"},"content":" });"},{"lineNumber":166,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"xenosf":7,"-":159}},{"path":"src/web/types/form-validator.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"import { ApiConst, ApiStringConst } from \u0027./api-const\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":4,"author":{"gitId":"-"},"content":" * Represents the root FormValidator object of all form fields."},{"lineNumber":5,"author":{"gitId":"-"},"content":" */"},{"lineNumber":6,"author":{"gitId":"-"},"content":"export enum FormValidator {"},{"lineNumber":7,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":8,"author":{"gitId":"-"},"content":" * Max length for the \u0027Course ID\u0027 field."},{"lineNumber":9,"author":{"gitId":"-"},"content":" */"},{"lineNumber":10,"author":{"gitId":"-"},"content":" COURSE_ID_MAX_LENGTH \u003d ApiConst.COURSE_ID_MAX_LENGTH,"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * Max length for the \u0027Course Name\u0027 field."},{"lineNumber":14,"author":{"gitId":"-"},"content":" */"},{"lineNumber":15,"author":{"gitId":"-"},"content":" COURSE_NAME_MAX_LENGTH \u003d ApiConst.COURSE_NAME_MAX_LENGTH,"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * Max length for the \u0027Student Name` field."},{"lineNumber":19,"author":{"gitId":"-"},"content":" */"},{"lineNumber":20,"author":{"gitId":"-"},"content":" STUDENT_NAME_MAX_LENGTH \u003d ApiConst.STUDENT_NAME_MAX_LENGTH,"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":23,"author":{"gitId":"-"},"content":" * Max length for the \u0027Section Name` field."},{"lineNumber":24,"author":{"gitId":"-"},"content":" */"},{"lineNumber":25,"author":{"gitId":"-"},"content":" SECTION_NAME_MAX_LENGTH \u003d ApiConst.SECTION_NAME_MAX_LENGTH,"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":28,"author":{"gitId":"-"},"content":" * Max length for the \u0027Team Name` field."},{"lineNumber":29,"author":{"gitId":"-"},"content":" */"},{"lineNumber":30,"author":{"gitId":"-"},"content":" TEAM_NAME_MAX_LENGTH \u003d ApiConst.TEAM_NAME_MAX_LENGTH,"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":33,"author":{"gitId":"-"},"content":" * Max length for the \u0027E-mail Address` field."},{"lineNumber":34,"author":{"gitId":"-"},"content":" */"},{"lineNumber":35,"author":{"gitId":"-"},"content":" EMAIL_MAX_LENGTH \u003d ApiConst.EMAIL_MAX_LENGTH,"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" * Regex used to verify emails in the back-end."},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" EMAIL_REGEX \u003d ApiStringConst.EMAIL_REGEX,"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" * Regex used to verify names."},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" * Based on back-end\u0027s `FieldValidator.REGEX_NAME`."},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" * The back-end regex is not converted to use here as the pattern syntax is not accepted in JS."},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" NAME_REGEX \u003d \u0027^[a-zA-Z0-9][^|%]*$\u0027,"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" * Regex used to verify country names."},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" * Based on back-end\u0027s `FieldValidator.REGEX_NAME`, but without needing to start with alphanumeric"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" * as the country is added to the end of the combined institute string."},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" COUNTRY_REGEX \u003d \u0027^[^|%]*$\u0027,"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" * Max length for institution name in account request. (to be combined with country)"},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" INSTITUTION_NAME_MAX_LENGTH \u003d 86,"},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" * Max length for country in account request. (to be combined with institution name)"},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":" COUNTRY_NAME_MAX_LENGTH \u003d 40,"},{"lineNumber":67,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":32,"-":35}}] +[{"path":"docs/_markbind/layouts/default.md","fileType":"md","lines":[{"lineNumber":1,"author":{"gitId":"jingting1412"},"content":"{% include \"_markbind/layouts/header.md\" %}"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"\u003cdiv id\u003d\"flex-body\"\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003cnav id\u003d\"site-nav\" class\u003d\"fixed-header-padding\"\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"nav-component slim-scroll\"\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003csite-nav\u003e"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"* About TEAMMATES :expanded:"},{"lineNumber":9,"author":{"gitId":"-"},"content":" * [Introduction]({{ baseUrl }}/index.html)"},{"lineNumber":10,"author":{"gitId":"-"},"content":" * [Overview]({{ baseUrl }}/overview.html)"},{"lineNumber":11,"author":{"gitId":"-"},"content":"* Getting Started :expanded:"},{"lineNumber":12,"author":{"gitId":"-"},"content":" * [Setting Up]({{ baseUrl }}/setting-up.html)"},{"lineNumber":13,"author":{"gitId":"-"},"content":"* [Contributing]({{ baseUrl }}/contributing-doc.html)"},{"lineNumber":14,"author":{"gitId":"-"},"content":"* Workflow :expanded:"},{"lineNumber":15,"author":{"gitId":"-"},"content":" * [Issues]({{ baseUrl }}/issues.html)"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * [Process]({{ baseUrl }}/process.html)"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * [Development]({{ baseUrl }}/development.html)"},{"lineNumber":18,"author":{"gitId":"-"},"content":"* [Design]({{ baseUrl }}/design.html)"},{"lineNumber":19,"author":{"gitId":"-"},"content":"* Best Practices :expanded:"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * [Coding]({{ baseUrl }}/best-practices/coding.html)"},{"lineNumber":21,"author":{"gitId":"-"},"content":" * [Testing]({{ baseUrl }}/best-practices/testing.html)"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * [Data Migration]({{ baseUrl }}/best-practices/data-migration.html)"},{"lineNumber":23,"author":{"gitId":"-"},"content":" * [UI Design]({{ baseUrl }}/best-practices/ui-design.html)"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * [Accessibility]({{ baseUrl }}/best-practices/accessibility.html)"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * [Mobile-Friendliness]({{ baseUrl }}/best-practices/mobile-friendliness.html)"},{"lineNumber":26,"author":{"gitId":"-"},"content":"* How-to :expanded:"},{"lineNumber":27,"author":{"gitId":"-"},"content":" * [Captcha]({{ baseUrl }}/captcha.html)"},{"lineNumber":28,"author":{"gitId":"-"},"content":" * [Documentation]({{ baseUrl }}/documentation.html)"},{"lineNumber":29,"author":{"gitId":"-"},"content":" * [Emails]({{ baseUrl }}/emails.html)"},{"lineNumber":30,"author":{"gitId":"-"},"content":" * [Unit Testing]({{ baseUrl }}/unit-testing.html)"},{"lineNumber":31,"author":{"gitId":"-"},"content":" * [End-to-End Testing]({{ baseUrl }}/e2e-testing.html)"},{"lineNumber":32,"author":{"gitId":"-"},"content":" * [Performance Testing]({{ baseUrl }}/performance-testing.html)"},{"lineNumber":33,"author":{"gitId":"-"},"content":" * [Accessibility Testing]({{ baseUrl }}/axe-testing.html)"},{"lineNumber":34,"author":{"gitId":"-"},"content":" * [Search]({{ baseUrl }}/search.html)"},{"lineNumber":35,"author":{"gitId":"-"},"content":" * [Snapshot Testing]({{ baseUrl }}/snapshot-testing.html)"},{"lineNumber":36,"author":{"gitId":"-"},"content":" * [Static Analysis]({{ baseUrl }}/static-analysis.html)"},{"lineNumber":37,"author":{"gitId":"-"},"content":"* [Troubleshooting Guide]({{ baseUrl }}/troubleshooting-guide.html)"},{"lineNumber":38,"author":{"gitId":"-"},"content":"* [Glossary]({{ baseUrl }}/glossary.html)"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003c/site-nav\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003c/nav\u003e"},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"content-wrapper\" class\u003d\"fixed-header-padding\"\u003e"},{"lineNumber":43,"author":{"gitId":"jingting1412"},"content":" \u003cbreadcrumb/\u003e"},{"lineNumber":44,"author":{"gitId":"-"},"content":" {{ content }}"},{"lineNumber":45,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":46,"author":{"gitId":"-"},"content":" \u003cnav id\u003d\"page-nav\" class\u003d\"fixed-header-padding\"\u003e"},{"lineNumber":47,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"nav-component slim-scroll\"\u003e"},{"lineNumber":48,"author":{"gitId":"-"},"content":" \u003cpage-nav /\u003e"},{"lineNumber":49,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":50,"author":{"gitId":"-"},"content":" \u003c/nav\u003e"},{"lineNumber":51,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"jingting1412"},"content":"{% include \"_markbind/layouts/footer.md\" %}"}],"authorContributionMap":{"jingting1412":3,"-":50}},{"path":"docs/_markbind/layouts/footer.md","fileType":"md","lines":[{"lineNumber":1,"author":{"gitId":"jingting1412"},"content":"\u003cfooter\u003e"},{"lineNumber":2,"author":{"gitId":"jingting1412"},"content":"\u003c!-- Support MarkBind by including a link to us on your landing page! --\u003e"},{"lineNumber":3,"author":{"gitId":"jingting1412"},"content":"\u003cdiv class\u003d\"text-center\"\u003e"},{"lineNumber":4,"author":{"gitId":"jingting1412"},"content":" \u003csmall\u003e[Generated by {{MarkBind}} on {{timestamp}}]\u003c/small\u003e"},{"lineNumber":5,"author":{"gitId":"jingting1412"},"content":"\u003c/div\u003e"},{"lineNumber":6,"author":{"gitId":"jingting1412"},"content":"\u003c/footer\u003e"}],"authorContributionMap":{"jingting1412":6}},{"path":"docs/_markbind/layouts/header.md","fileType":"md","lines":[{"lineNumber":1,"author":{"gitId":"jingting1412"},"content":"\u003chead-bottom\u003e"},{"lineNumber":2,"author":{"gitId":"jingting1412"},"content":" \u003clink rel\u003d\"stylesheet\" href\u003d\"{{ baseUrl }}/stylesheets/main.css\"\u003e"},{"lineNumber":3,"author":{"gitId":"jingting1412"},"content":"\u003c/head-bottom\u003e"},{"lineNumber":4,"author":{"gitId":"jingting1412"},"content":""},{"lineNumber":5,"author":{"gitId":"jingting1412"},"content":"\u003cheader sticky\u003e"},{"lineNumber":6,"author":{"gitId":"jingting1412"},"content":" \u003cnavbar type\u003d\"inverse\"\u003e"},{"lineNumber":7,"author":{"gitId":"jingting1412"},"content":" \u003ca slot\u003d\"brand\" href\u003d\"{{ baseUrl }}/index.html\" title\u003d\"Home\" class\u003d\"navbar-brand\"\u003e"},{"lineNumber":8,"author":{"gitId":"jingting1412"},"content":" \u003cpic src\u003d\"{{ baseUrl }}/images/teammateslogo.png\" width\u003d\"150\" alt\u003d\"Logo\" caption\u003d\"\"/\u003e"},{"lineNumber":9,"author":{"gitId":"jingting1412"},"content":" \u003cspan style\u003d\"font-style:italic;font-size:small\"\u003e[dev docs]\u003c/span\u003e"},{"lineNumber":10,"author":{"gitId":"jingting1412"},"content":" \u003c/a\u003e"},{"lineNumber":11,"author":{"gitId":"jingting1412"},"content":" \u003cli\u003e\u003ca href\u003d\"{{ baseUrl }}/index.html\" class\u003d\"nav-link\"\u003eHome\u003c/a\u003e\u003c/li\u003e"},{"lineNumber":12,"author":{"gitId":"jingting1412"},"content":" \u003cli\u003e\u003ca href\u003d\"{{ baseUrl }}/contributing-doc.html\" class\u003d\"nav-link\"\u003eContributing\u003c/a\u003e\u003c/li\u003e"},{"lineNumber":13,"author":{"gitId":"jingting1412"},"content":" \u003cli\u003e\u003ca href\u003d\"https://teammatesv4.appspot.com/\" target\u003d\"_blank\" class\u003d\"nav-link\"\u003eProduct Website \u003cmd\u003e:glyphicon-share-alt:\u003c/md\u003e\u003c/a\u003e\u003c/li\u003e"},{"lineNumber":14,"author":{"gitId":"jingting1412"},"content":" \u003cli\u003e\u003ca href\u003d\"https://github.com/TEAMMATES/teammates\" target\u003d\"_blank\" class\u003d\"nav-link\"\u003e\u003cmd\u003e:fab-github:\u003c/md\u003e\u003c/a\u003e\u003c/li\u003e"},{"lineNumber":15,"author":{"gitId":"jingting1412"},"content":" \u003cli slot\u003d\"right\"\u003e"},{"lineNumber":16,"author":{"gitId":"jingting1412"},"content":" \u003cform class\u003d\"navbar-form\"\u003e"},{"lineNumber":17,"author":{"gitId":"jingting1412"},"content":" \u003csearchbar :data\u003d\"searchData\" placeholder\u003d\"Search\" :on-hit\u003d\"searchCallback\" menu-align-right\u003e\u003c/searchbar\u003e"},{"lineNumber":18,"author":{"gitId":"jingting1412"},"content":" \u003c/form\u003e"},{"lineNumber":19,"author":{"gitId":"jingting1412"},"content":" \u003c/li\u003e"},{"lineNumber":20,"author":{"gitId":"jingting1412"},"content":" \u003c/navbar\u003e"},{"lineNumber":21,"author":{"gitId":"jingting1412"},"content":"\u003c/header\u003e"}],"authorContributionMap":{"jingting1412":21}},{"path":"docs/design.md","fileType":"md","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cfrontmatter\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" title: \"Design\""},{"lineNumber":3,"author":{"gitId":"-"},"content":"\u003c/frontmatter\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"# Design"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"## Architecture"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/highlevelArchitecture.puml\"/\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"TEAMMATES is a Web application that runs on Google App Engine (GAE). Given above is an overview of the main components."},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"- **UI (Browser)**: The UI seen by users consists of Web pages containing HTML, CSS (for styling) and JavaScript (for client-side interactions such as sorting, input validation, etc.). This UI is a single HTML page generated by Angular framework. The initial page request is sent to the server over HTTP, and requests for data are sent asynchronously with AJAX."},{"lineNumber":14,"author":{"gitId":"-"},"content":"- **UI (Server)**: The entry point for the application back end logic is designed as a REST-ful controller."},{"lineNumber":15,"author":{"gitId":"-"},"content":"- **Logic**: The main logic of the application is in POJOs (Plain Old Java Objects)."},{"lineNumber":16,"author":{"gitId":"-"},"content":"- **Storage**: The storage layer of the application uses the persistence framework provided by **Google Cloud Datastore**, a NoSQL database."},{"lineNumber":17,"author":{"gitId":"-"},"content":"- **Test Driver**: TEAMMATES makes heavy use of automated regression testing. Test data is transmitted using JSON format."},{"lineNumber":18,"author":{"gitId":"-"},"content":" - `TestNG` is used for Java testing (all levels) and `Jest` for JavaScript unit-testing."},{"lineNumber":19,"author":{"gitId":"-"},"content":"- **E2E**: The E2E (end-to-end) component is used to interact with the application as a whole with Web browsers. Its primary function is for E2E tests."},{"lineNumber":20,"author":{"gitId":"-"},"content":" - `Selenium (Java)` is used to automate E2E testing with actual Web browsers."},{"lineNumber":21,"author":{"gitId":"-"},"content":"- **Client**: The Client component can connect to the back end directly without using a Web browser. It is used for administrative purposes, e.g. migrating data to a new schema."},{"lineNumber":22,"author":{"gitId":"-"},"content":"- **Common**: The Common component contains utility code (data transfer objects, helper classes, etc.) used across the application."},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":"The diagram below shows how the code in each component is organized into packages and the dependencies between them."},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/packageDiagram.puml\"/\u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":"Notes:"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":"- `[logic] - [ui::website] - [ui::webapi]` represent an application of `Model-View-Controller` pattern."},{"lineNumber":31,"author":{"gitId":"-"},"content":" - `ui::website` is not a real package; it is a conceptual package representing the front-end of the application."},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":"## UI Component"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":"The diagram below shows the object structure of the UI component."},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/UiComponent.puml\"/\u003e"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":"Notes:"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":"- `ui::website` is not a Java package. It is written in Angular framework and consists of HTML, SCSS, and TypeScript files. The framework will build those files into HTML, CSS and JavaScript files ready to be used by standard Web browsers."},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":"The UI component is the first stop for 99% of all requests that are received by the application."},{"lineNumber":44,"author":{"gitId":"-"},"content":"Such a request will go through the following steps:"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":"1. Request received by the GAE server."},{"lineNumber":47,"author":{"gitId":"-"},"content":"1. Custom filters are applied according to the order specified in `web.xml`, e.g. `OriginCheckFilter`."},{"lineNumber":48,"author":{"gitId":"-"},"content":"1. Request forwarded to a `*Servlet` object as specified in `web.xml` for further processing, depending on the type of request."},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":"There are two general types of requests: user-invoked requests and automated (GAE server-invoked) requests, which are processed differently."},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":"### User-invoked requests"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":"User-invoked requests are all requests made by the users of the application, typically from the Web browser (i.e. by navigating to a particular URL of the application)."},{"lineNumber":55,"author":{"gitId":"-"},"content":"The request will be processed as follows:"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/UiWorkflow.puml\"/\u003e"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":"The initial request for the web page will be processed as follows:"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":"1. Request forwarded to `WebPageServlet`."},{"lineNumber":62,"author":{"gitId":"-"},"content":"1. `WebPageServlet` returns the built single web page (`index.html`)."},{"lineNumber":63,"author":{"gitId":"-"},"content":"1. The browser will render the page and execute the page scripts, most of the time requiring AJAX requests to the server."},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":"Subsequent AJAX requests sent to the server will be processed as follows:"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":"1. Request forwarded to the `WebApiServlet`."},{"lineNumber":68,"author":{"gitId":"-"},"content":"1. `WebApiServlet` uses the `ActionFactory` to generate the matching `Action` object, e.g. `GetFeedbackSessionsAction`."},{"lineNumber":69,"author":{"gitId":"-"},"content":"1. `WebApiServlet` executes the action."},{"lineNumber":70,"author":{"gitId":"-"},"content":" 1. The `Action` object checks the access rights of the user. If the action is allowed, it will be performed, interacting with the `Logic` component as necessary."},{"lineNumber":71,"author":{"gitId":"-"},"content":" 1. The `Action` packages and processes the result into an `ActionResult` object. The most common format is `JsonResult` (requests for obtaining data or processing existing data) and other formats can be defined as necessary."},{"lineNumber":72,"author":{"gitId":"-"},"content":"1. `WebApiServlet` sends the result back to the browser which will then process it on the front-end."},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":"Requests for static asset files (e.g. CSS, JS files, images) are served directly without going through `web.xml` configuration at all."},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":"The Web API is protected by two layers of access control check:"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":"- Origin check: This mitigates [CSRF attack](https://owasp.org/www-community/attacks/csrf)."},{"lineNumber":79,"author":{"gitId":"-"},"content":"- Authentication and authorization check: This checks if the logged in user (or lack thereof) has sufficient privileges to trigger the API\u0027s actions."},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":"Special keys (`csrf key` and `backdoor key`) can be used to bypass each of the checks, typically for testing purpose. Those keys are strings known only to the person who deployed the application (typically, the administrator)."},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":"### Automated requests"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":"Automated requests are all requests sent automatically by the GAE server during specific periods of time."},{"lineNumber":86,"author":{"gitId":"-"},"content":"This type of request will be processed as follows:"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":"1. The source of the request will be checked for administrator privilege. If this privilege is absent (e.g. non-administrator users trying to invoke the automated actions), the request will be dropped and a `403 Forbidden` status will be returned."},{"lineNumber":89,"author":{"gitId":"-"},"content":" - Requests generated by the GAE server are equipped with this privilege."},{"lineNumber":90,"author":{"gitId":"-"},"content":" - Administrators can manually invoke these requests; this is particularly useful in testing the actions associated with those requests."},{"lineNumber":91,"author":{"gitId":"-"},"content":"1. Request forwarded to the `WebApiServlet` and subsequent actions are the same as user-invoked AJAX requests."},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":"GAE server sends such automated requests through two different configurations:"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":"- Cron jobs: These are jobs that are automatically scheduled for a specified period of time, e.g. scheduling feedback session opening reminders. It is configured in `cron.yaml`."},{"lineNumber":96,"author":{"gitId":"-"},"content":"- Task queue workers: These are hybrids of user-invoked and GAE-invoked in that they are queued by users (i.e. users request for the tasks to be added to queue), but executed by GAE (i.e. GAE determines when and which tasks in the queue are executed at any point of time). This is typically used for tasks that may take a long time to finish and might be blocking user\u0027s interaction. It is configured in `queue.yaml` as well as the `TaskQueue` nested class of the [Const](https://github.com/TEAMMATES/teammates/blob/master/src/main/java/teammates/common/util/Const.java) class."},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":"### Template Method pattern"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":"- Since the high-level workflow of processing a request is same for any request (differing by the two request types only), we use the [Template Method pattern](http://en.wikipedia.org/wiki/Template_method_pattern) to abstract the process flow into the `Action` classes."},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":"### Policies"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":"On designing API endpoints (for AJAX requests):"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":"- Design endpoints for resources. For example, `FeedbackSession` is a resource. The corresponding endpoint is `/session`. We use `GET`, `POST`, `PUT`, `DELETE` HTTP methods to get, create, update and delete the resource respectively."},{"lineNumber":107,"author":{"gitId":"-"},"content":"- Prefer multiple REST calls over single RPC (Remote Procedure Call) calls."},{"lineNumber":108,"author":{"gitId":"-"},"content":" - Reason 1: REST paradigm promotes reuse of many business logic and is not dependent of the structure of the requesting web page (or any other type of requesting agent)."},{"lineNumber":109,"author":{"gitId":"-"},"content":" - Reason 2: Multiple REST calls can be parallelized which will improve performance."},{"lineNumber":110,"author":{"gitId":"-"},"content":"- Separate access control logic and execution logic completely."},{"lineNumber":111,"author":{"gitId":"-"},"content":" - In the case that an endpoint serves multiple purposes, we use `Intent` to distinguish the intent for the request. For example, instructors can access `/session` with intent `INSTRUCTOR_SUBMISSION` or `FULL_DETAIL`. Some `Intent` will naturally require stricter access rights."},{"lineNumber":112,"author":{"gitId":"-"},"content":"- Prefer HTTP request body over URL parameters (key-value) to contain data for `POST` and `PUT` requests."},{"lineNumber":113,"author":{"gitId":"-"},"content":" - Reason 1: The URL parameters are used to identify a specific resource for an endpoint, not what should be done to them."},{"lineNumber":114,"author":{"gitId":"-"},"content":" - Reason 2: Request body is not limited to key-value format which allows proper design and validation."},{"lineNumber":115,"author":{"gitId":"-"},"content":" - Data Transfer Objects (DTOs) which represent different API requests and responses are defined in `request` and `output` package respectively."},{"lineNumber":116,"author":{"gitId":"-"},"content":"- Preprocess data sent/received by the server to hide complexities. For example, timestamp is passed as UNIX epoch milliseconds in the output while it is represented as `Instant` in the back-end."},{"lineNumber":117,"author":{"gitId":"-"},"content":" - Some constructors in the `output` package contain logic to hide \"hacks\" in the backend."},{"lineNumber":118,"author":{"gitId":"-"},"content":" - Some getters/setters in the `request` package contain logic to cater the conventions in the backend."},{"lineNumber":119,"author":{"gitId":"-"},"content":" - Some fields are required be hidden in the API response, mostly for data privacy purposes. Whenever required, there should be methods in the request output objects catered for this."},{"lineNumber":120,"author":{"gitId":"-"},"content":"- API endpoints should not be concerned with how data is presented."},{"lineNumber":121,"author":{"gitId":"-"},"content":" - Case study 1: some endpoint will pass timezone information via two information: timezone ID and UNIX epoch milliseconds. It is up to the front-end on how to make use of those two pieces of information."},{"lineNumber":122,"author":{"gitId":"-"},"content":" - Case study 2: CSV file for session result or student list is just a different way of presenting the same information in the web page. Due to this, when downloading CSV, the web page will request the same information as that used when displaying in web page and do the necessary conversion to CSV."},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":"On data exchange between front-end and back-end:"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":"- Back-end is the single source of truth for all data format and the code used by front-end is generated from this."},{"lineNumber":127,"author":{"gitId":"-"},"content":" - Some important constants (including API endpoints information) are synced to `api-const.ts`."},{"lineNumber":128,"author":{"gitId":"-"},"content":" - The schemas of the DTOs defined in `output` and `request` packages are synced to `api-output.ts` and `api-request.ts` in the frontend."},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":"On handling exceptions:"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":"- The UI component is responsible for catching all exceptions and transforming them to properly formed, user-friendly output format. It includes the status message shown to user as well as the HTTP status code."},{"lineNumber":133,"author":{"gitId":"-"},"content":" - As a consequence, the UI component cannot throw any exception, because there is no layer which will catch those exceptions if it does."},{"lineNumber":134,"author":{"gitId":"-"},"content":"- In order to streamline the process, custom runtime exception classes which correspond to different HTTP status codes are used. For example, there is `EntityNotFoundException` which corresponds to HTTP 404, `UnauthorizedAccessException` which corresponds to HTTP 403, etc."},{"lineNumber":135,"author":{"gitId":"-"},"content":" - It is highly preferred to throw these custom exceptions instead of setting the HTTP status manually in the action class, as the API layer has been configured to automatically log the exception and assign the correct status code to the HTTP response."},{"lineNumber":136,"author":{"gitId":"-"},"content":"- All `4XX` responses must be accompanied with logging at `warning` level or above. `5XX` responses must be accompanied with `severe` level logging."},{"lineNumber":137,"author":{"gitId":"-"},"content":" - `502` (Bad Gateway) responses may skip the `severe` level logging if the upstream components (where the error happened) already did the `severe` level logging."},{"lineNumber":138,"author":{"gitId":"-"},"content":"- We use the HTTP status codes as close to their standard definition in [RFC7231](https://tools.ietf.org/html/rfc7231) as possible."},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":"## Logic Component"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":"The `Logic` component handles the business logic of TEAMMATES. In particular, it is responsible for:"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":"- Managing relationships between entities, e.g. cascade logic for create/update/delete."},{"lineNumber":145,"author":{"gitId":"-"},"content":"- Managing transactions, e.g. ensuring atomicity of a transaction."},{"lineNumber":146,"author":{"gitId":"-"},"content":"- Sanitizing input values received from the UI component."},{"lineNumber":147,"author":{"gitId":"-"},"content":"- Connecting to GCP or third-party services, e.g. for adding tasks to the task queue and for sending emails with third-party providers."},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/LogicComponent.puml\"/\u003e"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":"Package overview:"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":"- **`logic.api`**: Provides the API of the component to be accessed by the UI."},{"lineNumber":154,"author":{"gitId":"-"},"content":"- **`logic.core`**: Contains the core logic of the system."},{"lineNumber":155,"author":{"gitId":"-"},"content":"- **`logic.external`**: Holds the logic of external services such as task queue service."},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"-"},"content":"### Logic API"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":"Represented by these classes:"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":"- `Logic`: A [Facade class](http://en.wikipedia.org/wiki/Facade_pattern) which connects to the several `*Logic` classes to handle the logic related to various types of data and to access data from the `Storage` component."},{"lineNumber":162,"author":{"gitId":"-"},"content":"- `UserProvision`: Retrieves user information (based on request cookies)."},{"lineNumber":163,"author":{"gitId":"-"},"content":"- `EmailGenerator`: Generates emails to be sent."},{"lineNumber":164,"author":{"gitId":"-"},"content":"- `EmailSender`: Sends email with the provider chosen based on the build configuration."},{"lineNumber":165,"author":{"gitId":"-"},"content":"- `TaskQueuer`: Adds tasks to the task queue, i.e. to be executed at a later time."},{"lineNumber":166,"author":{"gitId":"-"},"content":"- `LogsProcessor`: For more advanced usage of logging that cannot be captured by the standard logger class."},{"lineNumber":167,"author":{"gitId":"-"},"content":"- `RecaptchaVerifier`: For verification of the reCAPTCHA token."},{"lineNumber":168,"author":{"gitId":"-"},"content":""},{"lineNumber":169,"author":{"gitId":"-"},"content":"Many classes in this layer make use of proxy pattern, i.e. they only connect to production services such as Google Cloud Tasks in the staging/production server."},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":"### Policies"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":"Access control:"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":"+ Although this component provides methods that are relevant to access control (e.g. providing user information), the access control check itself does not happen in this component. The UI is expected to check access control (using `GateKeeper` class) before calling a method in the logic component."},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":"API for creating entities:"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":"+ Null parameters: Causes an assertion failure."},{"lineNumber":180,"author":{"gitId":"-"},"content":"+ Invalid parameters: Throws `InvalidParametersException`."},{"lineNumber":181,"author":{"gitId":"-"},"content":"+ Entity already exists: Throws `EntityAlreadyExistsException` (escalated from Storage level)."},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":"API for retrieving entities:"},{"lineNumber":184,"author":{"gitId":"-"},"content":""},{"lineNumber":185,"author":{"gitId":"-"},"content":"+ Attempting to retrieve objects using `null` parameters: Causes an assertion failure."},{"lineNumber":186,"author":{"gitId":"-"},"content":"+ Entity not found:"},{"lineNumber":187,"author":{"gitId":"-"},"content":" - Returns `null` if the target entity not found. This way, read operations can be used easily for checking the existence of an entity."},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":"API for updating entities:"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":"+ Update is done using `*UpdateOptions` inside every `*Attributes`. The `UpdateOptions` will specify what is used to identify the entity to update and what will be updated."},{"lineNumber":192,"author":{"gitId":"-"},"content":"+ Entity not found: Throws `EntityDoesNotExistException`."},{"lineNumber":193,"author":{"gitId":"-"},"content":"+ Invalid parameters: Throws `InvalidParametersException`."},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"-"},"content":"API for deleting entities:"},{"lineNumber":196,"author":{"gitId":"-"},"content":""},{"lineNumber":197,"author":{"gitId":"-"},"content":"+ FailDeleteSilentlyPolicy: In general, delete operation do not throw exceptions if the target entity does not exist. This is because if it does not exist, it is as good as deleted."},{"lineNumber":198,"author":{"gitId":"-"},"content":"+ Cascade policy: When a parent entity is deleted, entities that have referential integrity with the deleted entity should also be deleted."},{"lineNumber":199,"author":{"gitId":"-"},"content":" Refer to the API for the cascade logic."},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":"## Storage Component"},{"lineNumber":202,"author":{"gitId":"-"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":"The `Storage` component performs CRUD (Create, Read, Update, Delete) operations on data entities individually."},{"lineNumber":204,"author":{"gitId":"-"},"content":"It contains minimal logic beyond what is directly relevant to CRUD operations."},{"lineNumber":205,"author":{"gitId":"-"},"content":"In particular, it is reponsible for:"},{"lineNumber":206,"author":{"gitId":"-"},"content":""},{"lineNumber":207,"author":{"gitId":"-"},"content":"- Validating data inside entities before creating/updating them, to ensure they are in a valid state."},{"lineNumber":208,"author":{"gitId":"-"},"content":"- Hiding the complexities of the database from the `Logic` component."},{"lineNumber":209,"author":{"gitId":"-"},"content":"- Hiding the persistable objects: Classes in the `storage::entity` package are not visible outside this component to hide information specific to data persistence."},{"lineNumber":210,"author":{"gitId":"-"},"content":" - Instead, a corresponding non-persistent [data transfer object](http://en.wikipedia.org/wiki/Data_transfer_object) named `*Attributes` (e.g., `CourseAttributes` is the data transfer object for `Course` entities) object is returned. These datatransfer classes are in `common::datatransfer` package, to be explained later."},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":"The `Storage` component does not perform any cascade delete/create operations. Cascade logic is handled by the `Logic` component."},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/StorageComponent.puml\"/\u003e"},{"lineNumber":215,"author":{"gitId":"-"},"content":""},{"lineNumber":216,"author":{"gitId":"-"},"content":"Package overview:"},{"lineNumber":217,"author":{"gitId":"-"},"content":""},{"lineNumber":218,"author":{"gitId":"-"},"content":"+ **`storage.api`**: Provides the API of the component to be accessed by the logic component."},{"lineNumber":219,"author":{"gitId":"-"},"content":"+ **`storage.entity`**: Classes that represent persistable entities."},{"lineNumber":220,"author":{"gitId":"-"},"content":"+ **`storage.search`**: Classes for dealing with searching and indexing."},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/StorageClassDiagram.puml\"/\u003e"},{"lineNumber":223,"author":{"gitId":"-"},"content":""},{"lineNumber":224,"author":{"gitId":"-"},"content":"Note that the navigability of the association links between entity objects appear to be in the reverse direction of what we see in a normal OOP design."},{"lineNumber":225,"author":{"gitId":"-"},"content":"This is because we want to keep the data schema flexible so that new entity types can be added later with minimal modifications to existing elements."},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"-"},"content":"### Storage API"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":"Represented by the `*Db` classes. These classes act as the bridge to the database."},{"lineNumber":230,"author":{"gitId":"-"},"content":""},{"lineNumber":231,"author":{"gitId":"-"},"content":"### Policies"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":"Add and Delete operations try to wait until data is persisted in the database before returning. This is not enough to compensate for eventual consistency involving multiple servers in the Google Cloud Datastore environment. However, it is expected to avoid test failures caused by eventual consistency in dev server and reduce such problems in the live server."},{"lineNumber":234,"author":{"gitId":"-"},"content":"Note: \u0027Eventual consistency\u0027 here means it takes some time for a database operation to propagate across all replicas of the Google Cloud Datastore. As a result, the data may be in an inconsistent states for short periods of time although things should become consistent \u0027eventually\u0027. For example, an object we deleted may appear to still exist for a short while."},{"lineNumber":235,"author":{"gitId":"-"},"content":""},{"lineNumber":236,"author":{"gitId":"-"},"content":"Implementation of Transaction Control has been minimized due to limitations of Google Cloud Datastore environment and the nature of our data schema."},{"lineNumber":237,"author":{"gitId":"-"},"content":""},{"lineNumber":238,"author":{"gitId":"-"},"content":"API for creating:"},{"lineNumber":239,"author":{"gitId":"-"},"content":""},{"lineNumber":240,"author":{"gitId":"-"},"content":"+ Attempt to create an entity that already exists: Throws `EntityAlreadyExistsException`."},{"lineNumber":241,"author":{"gitId":"-"},"content":"+ Attempt to create an entity with invalid data: Throws `InvalidParametersException`."},{"lineNumber":242,"author":{"gitId":"-"},"content":""},{"lineNumber":243,"author":{"gitId":"-"},"content":"API for retrieving:"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":"+ Attempt to retrieve an entity that does not exist: Returns `null`."},{"lineNumber":246,"author":{"gitId":"-"},"content":""},{"lineNumber":247,"author":{"gitId":"-"},"content":"API for updating:"},{"lineNumber":248,"author":{"gitId":"-"},"content":""},{"lineNumber":249,"author":{"gitId":"-"},"content":"+ Attempt to update an entity that does not exist: Throws `EntityDoesNotExistException`."},{"lineNumber":250,"author":{"gitId":"-"},"content":"+ Attempt to update an entity with invalid data: Throws `InvalidParametersException`."},{"lineNumber":251,"author":{"gitId":"-"},"content":""},{"lineNumber":252,"author":{"gitId":"-"},"content":"API for deleting:"},{"lineNumber":253,"author":{"gitId":"-"},"content":""},{"lineNumber":254,"author":{"gitId":"-"},"content":"+ Attempt to delete an entity that does not exist: Fails silently."},{"lineNumber":255,"author":{"gitId":"-"},"content":""},{"lineNumber":256,"author":{"gitId":"-"},"content":"## Common Component"},{"lineNumber":257,"author":{"gitId":"-"},"content":""},{"lineNumber":258,"author":{"gitId":"-"},"content":"The Common component contains common utilities used across TEAMMATES."},{"lineNumber":259,"author":{"gitId":"-"},"content":""},{"lineNumber":260,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/CommonComponent.puml\"/\u003e"},{"lineNumber":261,"author":{"gitId":"-"},"content":""},{"lineNumber":262,"author":{"gitId":"-"},"content":"Package overview:"},{"lineNumber":263,"author":{"gitId":"-"},"content":""},{"lineNumber":264,"author":{"gitId":"-"},"content":"- **`common.util`**: Contains utility classes."},{"lineNumber":265,"author":{"gitId":"-"},"content":"- **`common.exceptions`**: Contains custom exceptions."},{"lineNumber":266,"author":{"gitId":"-"},"content":"- **`common.datatransfer`**: Contains data transfer objects."},{"lineNumber":267,"author":{"gitId":"-"},"content":""},{"lineNumber":268,"author":{"gitId":"-"},"content":"`common.datatransfer` package contains lightweight \"data transfer object\" classes for transferring data among components. They can be combined in various ways to transfer structured data between components. Given below are three examples."},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/DataTransferClasses.puml\"/\u003e"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":"1. `Test Driver` can use the `DataBundle` in this manner to send an arbitrary number of objects to be persisted in the database."},{"lineNumber":273,"author":{"gitId":"-"},"content":"1. This structure can be used to transfer search results of a student or instructor or response comments."},{"lineNumber":274,"author":{"gitId":"-"},"content":"1. This structure can be used to send results of a feedback session (e.g., when showing a feedback session report to an instructor)."},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":"Some of these classes are methodless (and thus more of a data structure rather than a class); these classes use public variables for data for easy access."},{"lineNumber":277,"author":{"gitId":"-"},"content":""},{"lineNumber":278,"author":{"gitId":"-"},"content":"## Test Driver Component"},{"lineNumber":279,"author":{"gitId":"-"},"content":""},{"lineNumber":280,"author":{"gitId":"-"},"content":"This component automates the testing of TEAMMATES."},{"lineNumber":281,"author":{"gitId":"-"},"content":""},{"lineNumber":282,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/TestDriverComponent.puml\"/\u003e"},{"lineNumber":283,"author":{"gitId":"-"},"content":""},{"lineNumber":284,"author":{"gitId":"-"},"content":"The test driver component\u0027s package structure follows the corresponding production package structure\u0027s exactly,"},{"lineNumber":285,"author":{"gitId":"-"},"content":"e.g. `teammates.logic.core.*` will contain the test cases for the production code inside `teammates.logic.core` package."},{"lineNumber":286,"author":{"gitId":"-"},"content":"In the same spirit, for the front end, each `*.component.ts` will have the corresponding `*.component.spec.ts` in the same folder (similarly for `*.service.ts`, `*.pipe.ts`, etc.)."},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":"The test driver component introduces the following additional packages:"},{"lineNumber":289,"author":{"gitId":"-"},"content":""},{"lineNumber":290,"author":{"gitId":"-"},"content":"- **`architecture`**: Contains test cases used by one of the lint tools to check for architectural integrity."},{"lineNumber":291,"author":{"gitId":"-"},"content":"- **`test`**: Contains infrastructure and helpers needed for running the tests. Also contains the test cases for the said infrastructure/helpers."},{"lineNumber":292,"author":{"gitId":"-"},"content":""},{"lineNumber":293,"author":{"gitId":"-"},"content":"Notes:"},{"lineNumber":294,"author":{"gitId":"-"},"content":""},{"lineNumber":295,"author":{"gitId":"-"},"content":"- Component tests: Some of these are pure unit tests (i.e. testing one component in isolation) while others are integration tests that test units as well as integration of units with each other."},{"lineNumber":296,"author":{"gitId":"-"},"content":"- Front-end files (particularly TypeScript) are tested separately with `Jest`. The test cases are found in `*.spec.ts` files."},{"lineNumber":297,"author":{"gitId":"-"},"content":""},{"lineNumber":298,"author":{"gitId":"-"},"content":"This is how TEAMMATES testing maps to standard types of testing."},{"lineNumber":299,"author":{"gitId":"-"},"content":""},{"lineNumber":300,"author":{"gitId":"-"},"content":"```"},{"lineNumber":301,"author":{"gitId":"-"},"content":"Normal"},{"lineNumber":302,"author":{"gitId":"-"},"content":"|-----acceptance tests-----|-------------------system tests-------------------|-----integration tests-----|-----unit tests-----|"},{"lineNumber":303,"author":{"gitId":"-"},"content":"|--------manual testing--------|------automated E2E tests------|-------------------automated component tests-------------------|"},{"lineNumber":304,"author":{"gitId":"-"},"content":"TEAMMATES"},{"lineNumber":305,"author":{"gitId":"-"},"content":"```"},{"lineNumber":306,"author":{"gitId":"-"},"content":""},{"lineNumber":307,"author":{"gitId":"-"},"content":"## E2E Component"},{"lineNumber":308,"author":{"gitId":"-"},"content":""},{"lineNumber":309,"author":{"gitId":"-"},"content":"The E2E component has no knowledge of the internal workings of the application and can only interact either with Web browser (as a whole application) or REST API calls (for the back-end logic). Its primary function is for E2E tests."},{"lineNumber":310,"author":{"gitId":"-"},"content":""},{"lineNumber":311,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/E2EComponent.puml\"/\u003e"},{"lineNumber":312,"author":{"gitId":"-"},"content":""},{"lineNumber":313,"author":{"gitId":"-"},"content":"Package overview:"},{"lineNumber":314,"author":{"gitId":"-"},"content":""},{"lineNumber":315,"author":{"gitId":"-"},"content":"- **`e2e.util`**: Contains helpers needed for running E2E tests. Also contains the test cases for the said infrastructure/helpers."},{"lineNumber":316,"author":{"gitId":"-"},"content":"- **`e2e.pageobjects`**: Contains abstractions of the pages as they appear on a Browser (i.e. SUTs)."},{"lineNumber":317,"author":{"gitId":"-"},"content":"- **`e2e.cases`**: Contains system test cases for testing the application as a whole."},{"lineNumber":318,"author":{"gitId":"-"},"content":""},{"lineNumber":319,"author":{"gitId":"-"},"content":"## Client Component"},{"lineNumber":320,"author":{"gitId":"-"},"content":""},{"lineNumber":321,"author":{"gitId":"-"},"content":"The Client component contains scripts that can connect directly to the application back-end for administrative purposes, such as migrating data to a new schema and calculating statistics."},{"lineNumber":322,"author":{"gitId":"-"},"content":""},{"lineNumber":323,"author":{"gitId":"jingting1412"},"content":"\u003cpuml src\u003d\"diagrams/ClientComponent.puml\"/\u003e"},{"lineNumber":324,"author":{"gitId":"-"},"content":""},{"lineNumber":325,"author":{"gitId":"-"},"content":"Package overview:"},{"lineNumber":326,"author":{"gitId":"-"},"content":""},{"lineNumber":327,"author":{"gitId":"-"},"content":"- **`client.util`**: Contains helpers needed for client scripts."},{"lineNumber":328,"author":{"gitId":"-"},"content":"- **`client.connector`**: Classes needed to connect to the back end directly."},{"lineNumber":329,"author":{"gitId":"-"},"content":"- **`client.scripts`**: Scripts that deal with the back end data for administrative purposes."}],"authorContributionMap":{"jingting1412":12,"-":317}},{"path":"src/client/java/teammates/client/scripts/sql/IndexCourseFields.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"marquestye"},"content":"package teammates.client.scripts.sql;"},{"lineNumber":2,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":3,"author":{"gitId":"marquestye"},"content":"import com.googlecode.objectify.cmd.Query;"},{"lineNumber":4,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":5,"author":{"gitId":"marquestye"},"content":"import teammates.client.scripts.DataMigrationEntitiesBaseScript;"},{"lineNumber":6,"author":{"gitId":"marquestye"},"content":"import teammates.storage.entity.Course;"},{"lineNumber":7,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":8,"author":{"gitId":"marquestye"},"content":"/**"},{"lineNumber":9,"author":{"gitId":"marquestye"},"content":" * Index the newly-indexable fields of courses."},{"lineNumber":10,"author":{"gitId":"marquestye"},"content":" */"},{"lineNumber":11,"author":{"gitId":"marquestye"},"content":"public class IndexCourseFields extends DataMigrationEntitiesBaseScript\u003cCourse\u003e {"},{"lineNumber":12,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":13,"author":{"gitId":"marquestye"},"content":" public static void main(String[] args) {"},{"lineNumber":14,"author":{"gitId":"marquestye"},"content":" new IndexCourseFields().doOperationRemotely();"},{"lineNumber":15,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":16,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":17,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":18,"author":{"gitId":"marquestye"},"content":" protected Query\u003cCourse\u003e getFilterQuery() {"},{"lineNumber":19,"author":{"gitId":"marquestye"},"content":" return ofy().load().type(Course.class);"},{"lineNumber":20,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":21,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":22,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":23,"author":{"gitId":"marquestye"},"content":" protected boolean isPreview() {"},{"lineNumber":24,"author":{"gitId":"marquestye"},"content":" return true;"},{"lineNumber":25,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":26,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":27,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"marquestye"},"content":" protected boolean isMigrationNeeded(Course course) {"},{"lineNumber":29,"author":{"gitId":"marquestye"},"content":" return true;"},{"lineNumber":30,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":31,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":32,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":33,"author":{"gitId":"marquestye"},"content":" protected void migrateEntity(Course course) {"},{"lineNumber":34,"author":{"gitId":"marquestye"},"content":" // Save without any update; this will build the previously non-existing indexes"},{"lineNumber":35,"author":{"gitId":"marquestye"},"content":" saveEntityDeferred(course);"},{"lineNumber":36,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":37,"author":{"gitId":"marquestye"},"content":"}"}],"authorContributionMap":{"marquestye":37}},{"path":"src/e2e/java/teammates/e2e/cases/AdminNotificationsPageE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.LocalDate;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.time.LocalDateTime;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.ZoneId;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import java.util.UUID;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationStyle;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationTargetUser;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.AdminNotificationsPage;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.output.NotificationData;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * SUT: {@link Const.WebPageURIs#ADMIN_NOTIFICATIONS_PAGE}."},{"lineNumber":21,"author":{"gitId":"-"},"content":" */"},{"lineNumber":22,"author":{"gitId":"-"},"content":"public class AdminNotificationsPageE2ETest extends BaseE2ETestCase {"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" private Notification[] notifications \u003d new Notification[2];"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":26,"author":{"gitId":"-"},"content":" protected void prepareTestData() {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" testData \u003d loadDataBundle(\"/AdminNotificationsPageE2ETest.json\");"},{"lineNumber":28,"author":{"gitId":"-"},"content":" removeAndRestoreDataBundle(testData);"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" sqlTestData \u003d removeAndRestoreSqlDataBundle("},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" loadSqlDataBundle(\"/AdminNotificationsPageE2ETest_SqlEntities.json\"));"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" notifications[0] \u003d sqlTestData.notifications.get(\"notification1\");"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" notifications[1] \u003d sqlTestData.notifications.get(\"notification2\");"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":36,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":37,"author":{"gitId":"-"},"content":" public void testAll() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" ______TS(\"verify loaded data\");"},{"lineNumber":40,"author":{"gitId":"-"},"content":" AppUrl url \u003d createFrontendUrl(Const.WebPageURIs.ADMIN_NOTIFICATIONS_PAGE);"},{"lineNumber":41,"author":{"gitId":"-"},"content":" AdminNotificationsPage notificationsPage \u003d loginAdminToPage(url, AdminNotificationsPage.class);"},{"lineNumber":42,"author":{"gitId":"-"},"content":" // Only validates that the notifications are present in the notifications table instead of checking every row"},{"lineNumber":43,"author":{"gitId":"-"},"content":" // This is because the page will display all notifications in the database, which is not predictable"},{"lineNumber":44,"author":{"gitId":"-"},"content":" notificationsPage.verifyNotificationsTableRow(notifications[0]);"},{"lineNumber":45,"author":{"gitId":"-"},"content":" notificationsPage.verifyNotificationsTableRow(notifications[1]);"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" NotificationData notif \u003d BACKDOOR.getNotificationData(notifications[0].getId().toString());"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" assertEquals(notif.getNotificationId(), notifications[0].getId().toString());"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" assertEquals(notif.getMessage(), notifications[0].getMessage());"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" assertEquals(notif.getTitle(), notifications[0].getTitle());"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" notif \u003d BACKDOOR.getNotificationData(notifications[1].getId().toString());"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" assertEquals(notif.getNotificationId(), notifications[1].getId().toString());"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" assertEquals(notif.getMessage(), notifications[1].getMessage());"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" assertEquals(notif.getTitle(), notifications[1].getTitle());"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" ______TS(\"add new notification\");"},{"lineNumber":56,"author":{"gitId":"-"},"content":" int currentYear \u003d LocalDate.now().getYear();"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" Notification newNotification \u003d new Notification("},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" LocalDateTime.of(currentYear + 5, 2, 2, 12, 0).atZone(ZoneId.of(\"UTC\")).toInstant(),"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" LocalDateTime.of(currentYear + 5, 2, 3, 12, 0).atZone(ZoneId.of(\"UTC\")).toInstant(),"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" NotificationStyle.INFO,"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" NotificationTargetUser.STUDENT,"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" \"New E2E test notification 1\","},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" \"\u003cp\u003eNew E2E test notification message\u003c/p\u003e\""},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" );"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" notificationsPage.addNotification(newNotification);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" notificationsPage.verifyStatusMessage(\"Notification created successfully.\");"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" // Replace placeholder ID with actual ID of created notification"},{"lineNumber":70,"author":{"gitId":"-"},"content":" notificationsPage.sortNotificationsTableByDescendingCreateTime();"},{"lineNumber":71,"author":{"gitId":"-"},"content":" String newestNotificationId \u003d notificationsPage.getFirstRowNotificationId();"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" newNotification.setId(UUID.fromString(newestNotificationId));"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" // Checks that notification is in the database first"},{"lineNumber":75,"author":{"gitId":"-"},"content":" // so that newNotification is updated with the created time before checking table row"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" notif \u003d BACKDOOR.getNotificationData(newestNotificationId);"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" assertEquals(notif.getNotificationId(), newestNotificationId);"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" assertEquals(notif.getMessage(), newNotification.getMessage());"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" assertEquals(notif.getTitle(), newNotification.getTitle());"},{"lineNumber":80,"author":{"gitId":"-"},"content":" notificationsPage.verifyNotificationsTableRow(newNotification);"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" ______TS(\"edit notification\");"},{"lineNumber":83,"author":{"gitId":"-"},"content":" newNotification.setStartTime(LocalDateTime.of(currentYear + 7, 2, 2, 12, 0).atZone(ZoneId.of(\"UTC\")).toInstant());"},{"lineNumber":84,"author":{"gitId":"-"},"content":" newNotification.setEndTime(LocalDateTime.of(currentYear + 7, 2, 3, 12, 0).atZone(ZoneId.of(\"UTC\")).toInstant());"},{"lineNumber":85,"author":{"gitId":"-"},"content":" newNotification.setStyle(NotificationStyle.DANGER);"},{"lineNumber":86,"author":{"gitId":"-"},"content":" newNotification.setTargetUser(NotificationTargetUser.INSTRUCTOR);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" newNotification.setTitle(\"Edited E2E test notification 1\");"},{"lineNumber":88,"author":{"gitId":"-"},"content":" newNotification.setMessage(\"\u003cp\u003eEdited E2E test notification message\u003c/p\u003e\");"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" notificationsPage.editNotification(newNotification);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" notificationsPage.verifyStatusMessage(\"Notification updated successfully.\");"},{"lineNumber":92,"author":{"gitId":"-"},"content":" notificationsPage.verifyNotificationsTableRow(newNotification);"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" // verify that notification is present in database by reloading"},{"lineNumber":95,"author":{"gitId":"-"},"content":" notificationsPage.reloadPage();"},{"lineNumber":96,"author":{"gitId":"-"},"content":" notificationsPage.verifyNotificationsTableRow(newNotification);"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" ______TS(\"delete notification\");"},{"lineNumber":99,"author":{"gitId":"-"},"content":" notificationsPage.deleteNotification(newNotification);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" notificationsPage.verifyStatusMessage(\"Notification has been deleted.\");"},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" notif \u003d BACKDOOR.getNotificationData(newestNotificationId);"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" assertNull(notif);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" }"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":106,"author":{"gitId":"-"},"content":" public void classTeardown() {"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" for (Notification notification : sqlTestData.notifications.values()) {"},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" BACKDOOR.deleteNotification(notification.getId().toString());"},{"lineNumber":109,"author":{"gitId":"-"},"content":" }"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":33,"-":79}},{"path":"src/e2e/java/teammates/e2e/cases/AdminSearchPageE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.AdminSearchPage;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.e2e.util.TestProperties;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * SUT: {@link Const.WebPageURIs#ADMIN_SEARCH_PAGE}."},{"lineNumber":20,"author":{"gitId":"-"},"content":" */"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public class AdminSearchPageE2ETest extends BaseE2ETestCase {"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":24,"author":{"gitId":"-"},"content":" protected void prepareTestData() {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":27,"author":{"gitId":"-"},"content":" }"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" testData \u003d loadDataBundle(\"/AdminSearchPageE2ETest.json\");"},{"lineNumber":30,"author":{"gitId":"-"},"content":" removeAndRestoreDataBundle(testData);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" putDocuments(testData);"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" sqlTestData \u003d loadSqlDataBundle(\"/AdminSearchPageE2ETest_SqlEntities.json\");"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" removeAndRestoreSqlDataBundle(sqlTestData);"},{"lineNumber":34,"author":{"gitId":"-"},"content":" putSqlDocuments(sqlTestData);"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":38,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":39,"author":{"gitId":"-"},"content":" public void testAll() {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":42,"author":{"gitId":"-"},"content":" }"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" AppUrl url \u003d createFrontendUrl(Const.WebPageURIs.ADMIN_SEARCH_PAGE);"},{"lineNumber":45,"author":{"gitId":"-"},"content":" AdminSearchPage searchPage \u003d loginAdminToPage(url, AdminSearchPage.class);"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" CourseAttributes course \u003d testData.courses.get(\"typicalCourse1\");"},{"lineNumber":48,"author":{"gitId":"-"},"content":" StudentAttributes student \u003d testData.students.get(\"student1InCourse1\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d testData.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d sqlTestData.accountRequests.get(\"instructor1OfCourse1\");"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Search student email\");"},{"lineNumber":53,"author":{"gitId":"-"},"content":" String searchContent \u003d student.getEmail();"},{"lineNumber":54,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":56,"author":{"gitId":"-"},"content":" String studentDetails \u003d getExpectedStudentDetails(student);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" String studentManageAccountLink \u003d getExpectedStudentManageAccountLink(student);"},{"lineNumber":58,"author":{"gitId":"-"},"content":" String studentHomePageLink \u003d getExpectedStudentHomePageLink(student);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" int numExpandedRows \u003d getExpectedNumExpandedRows(student);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" searchPage.verifyStudentRowContent(student, course, studentDetails, studentManageAccountLink,"},{"lineNumber":61,"author":{"gitId":"-"},"content":" studentHomePageLink);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" searchPage.verifyStudentExpandedLinks(student, numExpandedRows);"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Reset student google id\");"},{"lineNumber":65,"author":{"gitId":"-"},"content":" searchPage.resetStudentGoogleId(student);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" student.setGoogleId(null);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" studentManageAccountLink \u003d getExpectedStudentManageAccountLink(student);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" studentHomePageLink \u003d getExpectedStudentHomePageLink(student);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" searchPage.verifyStudentRowContent(student, course, studentDetails, studentManageAccountLink,"},{"lineNumber":70,"author":{"gitId":"-"},"content":" studentHomePageLink);"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Regenerate registration key for a course student\");"},{"lineNumber":73,"author":{"gitId":"-"},"content":" searchPage.clickExpandStudentLinks();"},{"lineNumber":74,"author":{"gitId":"-"},"content":" String originalJoinLink \u003d searchPage.getStudentJoinLink(student);"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" searchPage.regenerateStudentKey(student);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" searchPage.verifyRegenerateStudentKey(student, originalJoinLink);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" searchPage.waitForPageToLoad();"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Search for instructor email\");"},{"lineNumber":81,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":82,"author":{"gitId":"-"},"content":" searchContent \u003d instructor.getEmail();"},{"lineNumber":83,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":85,"author":{"gitId":"-"},"content":" String instructorManageAccountLink \u003d getExpectedInstructorManageAccountLink(instructor);"},{"lineNumber":86,"author":{"gitId":"-"},"content":" String instructorHomePageLink \u003d getExpectedInstructorHomePageLink(instructor);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" searchPage.verifyInstructorRowContent(instructor, course, instructorManageAccountLink,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" instructorHomePageLink);"},{"lineNumber":89,"author":{"gitId":"-"},"content":" searchPage.verifyInstructorExpandedLinks(instructor);"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Reset instructor google id\");"},{"lineNumber":92,"author":{"gitId":"-"},"content":" searchPage.resetInstructorGoogleId(instructor);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" instructor.setGoogleId(null);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" instructorManageAccountLink \u003d getExpectedInstructorManageAccountLink(instructor);"},{"lineNumber":95,"author":{"gitId":"-"},"content":" instructorHomePageLink \u003d getExpectedInstructorHomePageLink(instructor);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" searchPage.verifyInstructorRowContent(instructor, course, instructorManageAccountLink,"},{"lineNumber":97,"author":{"gitId":"-"},"content":" instructorHomePageLink);"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Regenerate registration key for an instructor\");"},{"lineNumber":100,"author":{"gitId":"-"},"content":" searchPage.clickExpandInstructorLinks();"},{"lineNumber":101,"author":{"gitId":"-"},"content":" originalJoinLink \u003d searchPage.getInstructorJoinLink(instructor);"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" searchPage.regenerateInstructorKey(instructor);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" searchPage.verifyRegenerateInstructorKey(instructor, originalJoinLink);"},{"lineNumber":105,"author":{"gitId":"-"},"content":" searchPage.waitForPageToLoad();"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Search for account request by email\");"},{"lineNumber":108,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":109,"author":{"gitId":"-"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":110,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":112,"author":{"gitId":"-"},"content":" searchPage.verifyAccountRequestRowContent(accountRequest);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" searchPage.verifyAccountRequestExpandedLinks(accountRequest);"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Search common search key\");"},{"lineNumber":116,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":117,"author":{"gitId":"-"},"content":" searchContent \u003d \"Course1\";"},{"lineNumber":118,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":120,"author":{"gitId":"-"},"content":" searchPage.verifyStudentRowContent(student, course, studentDetails, studentManageAccountLink,"},{"lineNumber":121,"author":{"gitId":"-"},"content":" studentHomePageLink);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" searchPage.verifyInstructorRowContent(instructor, course, instructorManageAccountLink,"},{"lineNumber":123,"author":{"gitId":"-"},"content":" instructorHomePageLink);"},{"lineNumber":124,"author":{"gitId":"-"},"content":" searchPage.verifyAccountRequestRowContent(accountRequest);"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Expand and collapse links\");"},{"lineNumber":127,"author":{"gitId":"-"},"content":" searchPage.verifyLinkExpansionButtons(student, instructor, accountRequest);"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Reset account request successful\");"},{"lineNumber":130,"author":{"gitId":"-"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":131,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":132,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":134,"author":{"gitId":"-"},"content":" searchPage.clickResetAccountRequestButton(accountRequest);"},{"lineNumber":135,"author":{"gitId":"-"},"content":" assertNull(BACKDOOR.getAccountRequest(accountRequest.getId()).getRegisteredAt());"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Delete account request successful\");"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d sqlTestData.accountRequests.get(\"unregisteredInstructor1\");"},{"lineNumber":139,"author":{"gitId":"-"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":140,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":141,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":142,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":143,"author":{"gitId":"-"},"content":" searchPage.clickDeleteAccountRequestButton(accountRequest);"},{"lineNumber":144,"author":{"gitId":"-"},"content":" assertNull(BACKDOOR.getAccountRequest(accountRequest.getId()));"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" private String getExpectedStudentDetails(StudentAttributes student) {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" return String.format(\"%s [%s] (%s)\", student.getCourse(),"},{"lineNumber":149,"author":{"gitId":"-"},"content":" student.getSection() \u003d\u003d null ? Const.DEFAULT_SECTION : student.getSection(), student.getTeam());"},{"lineNumber":150,"author":{"gitId":"-"},"content":" }"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" private String getExpectedStudentHomePageLink(StudentAttributes student) {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" return student.isRegistered() ? createFrontendUrl(Const.WebPageURIs.STUDENT_HOME_PAGE)"},{"lineNumber":154,"author":{"gitId":"-"},"content":" .withUserId(student.getGoogleId())"},{"lineNumber":155,"author":{"gitId":"-"},"content":" .toAbsoluteString()"},{"lineNumber":156,"author":{"gitId":"-"},"content":" : \"\";"},{"lineNumber":157,"author":{"gitId":"-"},"content":" }"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" private String getExpectedStudentManageAccountLink(StudentAttributes student) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" return student.isRegistered() ? createFrontendUrl(Const.WebPageURIs.ADMIN_ACCOUNTS_PAGE)"},{"lineNumber":161,"author":{"gitId":"-"},"content":" .withParam(Const.ParamsNames.INSTRUCTOR_ID, student.getGoogleId())"},{"lineNumber":162,"author":{"gitId":"-"},"content":" .toAbsoluteString()"},{"lineNumber":163,"author":{"gitId":"-"},"content":" : \"\";"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" private int getExpectedNumExpandedRows(StudentAttributes student) {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" int expectedNumExpandedRows \u003d 2;"},{"lineNumber":168,"author":{"gitId":"-"},"content":" for (FeedbackSessionAttributes sessions : testData.feedbackSessions.values()) {"},{"lineNumber":169,"author":{"gitId":"-"},"content":" if (sessions.getCourseId().equals(student.getCourse())) {"},{"lineNumber":170,"author":{"gitId":"-"},"content":" expectedNumExpandedRows +\u003d 1;"},{"lineNumber":171,"author":{"gitId":"-"},"content":" if (sessions.getResultsVisibleFromTime().isBefore(Instant.now())) {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" expectedNumExpandedRows +\u003d 1;"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":" }"},{"lineNumber":175,"author":{"gitId":"-"},"content":" }"},{"lineNumber":176,"author":{"gitId":"-"},"content":" return expectedNumExpandedRows;"},{"lineNumber":177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" private String getExpectedInstructorHomePageLink(InstructorAttributes instructor) {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" String googleId \u003d instructor.isRegistered() ? instructor.getGoogleId() : \"\";"},{"lineNumber":181,"author":{"gitId":"-"},"content":" return createFrontendUrl(Const.WebPageURIs.INSTRUCTOR_HOME_PAGE)"},{"lineNumber":182,"author":{"gitId":"-"},"content":" .withUserId(googleId)"},{"lineNumber":183,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":184,"author":{"gitId":"-"},"content":" }"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" private String getExpectedInstructorManageAccountLink(InstructorAttributes instructor) {"},{"lineNumber":187,"author":{"gitId":"-"},"content":" String googleId \u003d instructor.isRegistered() ? instructor.getGoogleId() : \"\";"},{"lineNumber":188,"author":{"gitId":"-"},"content":" return createFrontendUrl(Const.WebPageURIs.ADMIN_ACCOUNTS_PAGE)"},{"lineNumber":189,"author":{"gitId":"-"},"content":" .withParam(Const.ParamsNames.INSTRUCTOR_ID, googleId)"},{"lineNumber":190,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":191,"author":{"gitId":"-"},"content":" }"},{"lineNumber":192,"author":{"gitId":"-"},"content":""},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":" @AfterClass"},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" public void classTeardown() {"},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" for (AccountRequest request : sqlTestData.accountRequests.values()) {"},{"lineNumber":196,"author":{"gitId":"dishenggg"},"content":" BACKDOOR.deleteAccountRequest(request.getId());"},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":200,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":12,"dishenggg":1,"-":187}},{"path":"src/e2e/java/teammates/e2e/cases/BaseE2ETestCase.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.io.IOException;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.nio.file.Files;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.nio.file.Paths;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.ITestContext;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.DataBundle;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountAttributes;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountRequestAttributes;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.DeadlineExtensionAttributes;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseAttributes;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseCommentAttributes;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.NotificationAttributes;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.exception.HttpRequestFailedException;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.AppPage;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.Browser;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.DevServerLoginPage;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.HomePage;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.e2e.util.BackDoor;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.e2e.util.EmailAccount;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.e2e.util.TestProperties;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCaseWithDatabaseAccess;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.test.FileHelper;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import teammates.test.ThreadHelper;"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":41,"author":{"gitId":"-"},"content":" * Base class for all browser tests."},{"lineNumber":42,"author":{"gitId":"-"},"content":" *"},{"lineNumber":43,"author":{"gitId":"-"},"content":" * \u003cp\u003eThis type of test has no knowledge of the workings of the application,"},{"lineNumber":44,"author":{"gitId":"-"},"content":" * and can only communicate via the UI or via {@link BackDoor} to obtain/transmit data."},{"lineNumber":45,"author":{"gitId":"-"},"content":" */"},{"lineNumber":46,"author":{"gitId":"-"},"content":"public abstract class BaseE2ETestCase extends BaseTestCaseWithDatabaseAccess {"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":49,"author":{"gitId":"-"},"content":" * Backdoor used to call APIs."},{"lineNumber":50,"author":{"gitId":"-"},"content":" */"},{"lineNumber":51,"author":{"gitId":"-"},"content":" protected static final BackDoor BACKDOOR \u003d BackDoor.getInstance();"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":54,"author":{"gitId":"-"},"content":" * Data to be used in the test."},{"lineNumber":55,"author":{"gitId":"-"},"content":" */"},{"lineNumber":56,"author":{"gitId":"-"},"content":" protected DataBundle testData;"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":59,"author":{"gitId":"-"},"content":" * Sql Data to be used in the test."},{"lineNumber":60,"author":{"gitId":"-"},"content":" */"},{"lineNumber":61,"author":{"gitId":"-"},"content":" protected SqlDataBundle sqlTestData;"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" private Browser browser;"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" @BeforeClass"},{"lineNumber":66,"author":{"gitId":"-"},"content":" public void baseClassSetup() {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" prepareTestData();"},{"lineNumber":68,"author":{"gitId":"-"},"content":" prepareBrowser();"},{"lineNumber":69,"author":{"gitId":"-"},"content":" }"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":72,"author":{"gitId":"-"},"content":" * Prepares the browser used for the current test."},{"lineNumber":73,"author":{"gitId":"-"},"content":" */"},{"lineNumber":74,"author":{"gitId":"-"},"content":" protected void prepareBrowser() {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" browser \u003d new Browser();"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":79,"author":{"gitId":"-"},"content":" * Prepares the test data used for the current test."},{"lineNumber":80,"author":{"gitId":"-"},"content":" */"},{"lineNumber":81,"author":{"gitId":"-"},"content":" protected abstract void prepareTestData();"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":84,"author":{"gitId":"-"},"content":" * Contains all the tests for the page."},{"lineNumber":85,"author":{"gitId":"-"},"content":" *"},{"lineNumber":86,"author":{"gitId":"-"},"content":" * \u003cp\u003eThis approach is chosen so that setup and teardown are only needed once per test page,"},{"lineNumber":87,"author":{"gitId":"-"},"content":" * thereby saving time. While it necessitates failed tests to be restarted from the beginning,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" * test failures are rare and thus not causing significant overhead."},{"lineNumber":89,"author":{"gitId":"-"},"content":" */"},{"lineNumber":90,"author":{"gitId":"-"},"content":" protected abstract void testAll();"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":93,"author":{"gitId":"-"},"content":" protected String getTestDataFolder() {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" return TestProperties.TEST_DATA_FOLDER;"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":98,"author":{"gitId":"-"},"content":" public void baseClassTearDown(ITestContext context) {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" if (browser \u003d\u003d null) {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":" boolean isSuccess \u003d context.getFailedTests().getAllMethods()"},{"lineNumber":103,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":104,"author":{"gitId":"-"},"content":" .noneMatch(method -\u003e method.getConstructorOrMethod().getMethod().getDeclaringClass() \u003d\u003d this.getClass());"},{"lineNumber":105,"author":{"gitId":"-"},"content":" if (isSuccess || TestProperties.CLOSE_BROWSER_ON_FAILURE) {"},{"lineNumber":106,"author":{"gitId":"-"},"content":" browser.close();"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":111,"author":{"gitId":"-"},"content":" * Creates an {@link AppUrl} for the supplied {@code relativeUrl} parameter."},{"lineNumber":112,"author":{"gitId":"-"},"content":" * The base URL will be the value of test.app.frontend.url in test.properties."},{"lineNumber":113,"author":{"gitId":"-"},"content":" * {@code relativeUrl} must start with a \"/\"."},{"lineNumber":114,"author":{"gitId":"-"},"content":" */"},{"lineNumber":115,"author":{"gitId":"-"},"content":" protected static AppUrl createFrontendUrl(String relativeUrl) {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" return new AppUrl(TestProperties.TEAMMATES_FRONTEND_URL + relativeUrl);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" }"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":120,"author":{"gitId":"-"},"content":" * Creates an {@link AppUrl} for the supplied {@code relativeUrl} parameter."},{"lineNumber":121,"author":{"gitId":"-"},"content":" * The base URL will be the value of test.app.backend.url in test.properties."},{"lineNumber":122,"author":{"gitId":"-"},"content":" * {@code relativeUrl} must start with a \"/\"."},{"lineNumber":123,"author":{"gitId":"-"},"content":" */"},{"lineNumber":124,"author":{"gitId":"-"},"content":" protected static AppUrl createBackendUrl(String relativeUrl) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" return new AppUrl(TestProperties.TEAMMATES_BACKEND_URL + relativeUrl);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" }"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":129,"author":{"gitId":"-"},"content":" * Logs in to a page using the given credentials."},{"lineNumber":130,"author":{"gitId":"-"},"content":" */"},{"lineNumber":131,"author":{"gitId":"-"},"content":" protected \u003cT extends AppPage\u003e T loginToPage(AppUrl url, Class\u003cT\u003e typeOfPage, String userId) {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" // When not using dev server, Google blocks log in by automation."},{"lineNumber":133,"author":{"gitId":"-"},"content":" // To work around that, we inject the user cookie directly into the browser session."},{"lineNumber":134,"author":{"gitId":"-"},"content":" if (!TestProperties.isDevServer()) {"},{"lineNumber":135,"author":{"gitId":"-"},"content":" // In order for the cookie injection to work, we need to be in the domain."},{"lineNumber":136,"author":{"gitId":"-"},"content":" // Use the home page to minimize the page load time."},{"lineNumber":137,"author":{"gitId":"-"},"content":" browser.goToUrl(TestProperties.TEAMMATES_FRONTEND_URL);"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" String cookieValue \u003d BACKDOOR.getUserCookie(userId);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" browser.addCookie(Const.SecurityConfig.AUTH_COOKIE_NAME, cookieValue, true, true);"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" return getNewPageInstance(url, typeOfPage);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" }"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" // This will be redirected to the dev server login page."},{"lineNumber":146,"author":{"gitId":"-"},"content":" browser.goToUrl(url.toAbsoluteString());"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" DevServerLoginPage loginPage \u003d AppPage.getNewPageInstance(browser, DevServerLoginPage.class);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" loginPage.loginAsUser(userId);"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" return getNewPageInstance(url, typeOfPage);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" }"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":155,"author":{"gitId":"-"},"content":" * Logs in to a page using admin credentials."},{"lineNumber":156,"author":{"gitId":"-"},"content":" */"},{"lineNumber":157,"author":{"gitId":"-"},"content":" protected \u003cT extends AppPage\u003e T loginAdminToPage(AppUrl url, Class\u003cT\u003e typeOfPage) {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" return loginToPage(url, typeOfPage, TestProperties.TEST_ADMIN);"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":162,"author":{"gitId":"-"},"content":" * Equivalent to clicking the \u0027logout\u0027 link in the top menu of the page."},{"lineNumber":163,"author":{"gitId":"-"},"content":" */"},{"lineNumber":164,"author":{"gitId":"-"},"content":" protected void logout() {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" AppUrl url \u003d createBackendUrl(Const.WebPageURIs.LOGOUT);"},{"lineNumber":166,"author":{"gitId":"-"},"content":" if (!TestProperties.TEAMMATES_FRONTEND_URL.equals(TestProperties.TEAMMATES_BACKEND_URL)) {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" url \u003d url.withParam(\"frontendUrl\", TestProperties.TEAMMATES_FRONTEND_URL);"},{"lineNumber":168,"author":{"gitId":"-"},"content":" }"},{"lineNumber":169,"author":{"gitId":"-"},"content":""},{"lineNumber":170,"author":{"gitId":"-"},"content":" browser.goToUrl(url.toAbsoluteString());"},{"lineNumber":171,"author":{"gitId":"-"},"content":" AppPage.getNewPageInstance(browser, HomePage.class).waitForPageToLoad();"},{"lineNumber":172,"author":{"gitId":"-"},"content":" }"},{"lineNumber":173,"author":{"gitId":"-"},"content":""},{"lineNumber":174,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":175,"author":{"gitId":"-"},"content":" * Deletes file with fileName from the downloads folder."},{"lineNumber":176,"author":{"gitId":"-"},"content":" */"},{"lineNumber":177,"author":{"gitId":"-"},"content":" protected void deleteDownloadsFile(String fileName) {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" String filePath \u003d TestProperties.TEST_DOWNLOADS_FOLDER + fileName;"},{"lineNumber":179,"author":{"gitId":"-"},"content":" FileHelper.deleteFile(filePath);"},{"lineNumber":180,"author":{"gitId":"-"},"content":" }"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":183,"author":{"gitId":"-"},"content":" * Verifies downloaded file has correct fileName and contains expected content."},{"lineNumber":184,"author":{"gitId":"-"},"content":" */"},{"lineNumber":185,"author":{"gitId":"-"},"content":" protected void verifyDownloadedFile(String expectedFileName, List\u003cString\u003e expectedContent) {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" String filePath \u003d TestProperties.TEST_DOWNLOADS_FOLDER + expectedFileName;"},{"lineNumber":187,"author":{"gitId":"-"},"content":" int retryLimit \u003d TestProperties.TEST_TIMEOUT;"},{"lineNumber":188,"author":{"gitId":"-"},"content":" boolean actual \u003d Files.exists(Paths.get(filePath));"},{"lineNumber":189,"author":{"gitId":"-"},"content":" while (!actual \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":191,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(1000);"},{"lineNumber":192,"author":{"gitId":"-"},"content":" actual \u003d Files.exists(Paths.get(filePath));"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":" assertTrue(actual);"},{"lineNumber":195,"author":{"gitId":"-"},"content":""},{"lineNumber":196,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" String actualContent \u003d FileHelper.readFile(filePath);"},{"lineNumber":198,"author":{"gitId":"-"},"content":" for (String content : expectedContent) {"},{"lineNumber":199,"author":{"gitId":"-"},"content":" assertTrue(actualContent.contains(content));"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }"},{"lineNumber":201,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":203,"author":{"gitId":"-"},"content":" }"},{"lineNumber":204,"author":{"gitId":"-"},"content":" }"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":207,"author":{"gitId":"-"},"content":" * Visits the URL and gets the page object representation of the visited web page in the browser."},{"lineNumber":208,"author":{"gitId":"-"},"content":" */"},{"lineNumber":209,"author":{"gitId":"-"},"content":" protected \u003cT extends AppPage\u003e T getNewPageInstance(AppUrl url, Class\u003cT\u003e typeOfPage) {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" browser.goToUrl(url.toAbsoluteString());"},{"lineNumber":211,"author":{"gitId":"-"},"content":" return AppPage.getNewPageInstance(browser, typeOfPage);"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":215,"author":{"gitId":"-"},"content":" * Verifies that email with subject is found in inbox."},{"lineNumber":216,"author":{"gitId":"-"},"content":" * Email used must be an authentic gmail account."},{"lineNumber":217,"author":{"gitId":"-"},"content":" */"},{"lineNumber":218,"author":{"gitId":"-"},"content":" protected void verifyEmailSent(String email, String subject) {"},{"lineNumber":219,"author":{"gitId":"-"},"content":" if (TestProperties.isDevServer() || !TestProperties.INCLUDE_EMAIL_VERIFICATION) {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":221,"author":{"gitId":"-"},"content":" }"},{"lineNumber":222,"author":{"gitId":"-"},"content":" if (!TestProperties.TEST_EMAIL.equals(email)) {"},{"lineNumber":223,"author":{"gitId":"-"},"content":" fail(\"Email verification is allowed only on preset test email.\");"},{"lineNumber":224,"author":{"gitId":"-"},"content":" }"},{"lineNumber":225,"author":{"gitId":"-"},"content":" EmailAccount emailAccount \u003d new EmailAccount(email);"},{"lineNumber":226,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" emailAccount.getUserAuthenticated();"},{"lineNumber":228,"author":{"gitId":"-"},"content":" int retryLimit \u003d 5;"},{"lineNumber":229,"author":{"gitId":"-"},"content":" boolean actual \u003d emailAccount.isRecentEmailWithSubjectPresent(subject, TestProperties.TEST_SENDER_EMAIL);"},{"lineNumber":230,"author":{"gitId":"-"},"content":" while (!actual \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":231,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":232,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(1000);"},{"lineNumber":233,"author":{"gitId":"-"},"content":" actual \u003d emailAccount.isRecentEmailWithSubjectPresent(subject, TestProperties.TEST_SENDER_EMAIL);"},{"lineNumber":234,"author":{"gitId":"-"},"content":" }"},{"lineNumber":235,"author":{"gitId":"-"},"content":" assertTrue(actual);"},{"lineNumber":236,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":237,"author":{"gitId":"-"},"content":" fail(\"Failed to verify email sent:\" + e);"},{"lineNumber":238,"author":{"gitId":"-"},"content":" }"},{"lineNumber":239,"author":{"gitId":"-"},"content":" }"},{"lineNumber":240,"author":{"gitId":"-"},"content":""},{"lineNumber":241,"author":{"gitId":"-"},"content":" AccountAttributes getAccount(String googleId) {"},{"lineNumber":242,"author":{"gitId":"-"},"content":" return BACKDOOR.getAccount(googleId);"},{"lineNumber":243,"author":{"gitId":"-"},"content":" }"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":246,"author":{"gitId":"-"},"content":" protected AccountAttributes getAccount(AccountAttributes account) {"},{"lineNumber":247,"author":{"gitId":"-"},"content":" return getAccount(account.getGoogleId());"},{"lineNumber":248,"author":{"gitId":"-"},"content":" }"},{"lineNumber":249,"author":{"gitId":"-"},"content":""},{"lineNumber":250,"author":{"gitId":"-"},"content":" CourseAttributes getCourse(String courseId) {"},{"lineNumber":251,"author":{"gitId":"-"},"content":" return BACKDOOR.getCourse(courseId);"},{"lineNumber":252,"author":{"gitId":"-"},"content":" }"},{"lineNumber":253,"author":{"gitId":"-"},"content":""},{"lineNumber":254,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":255,"author":{"gitId":"-"},"content":" protected CourseAttributes getCourse(CourseAttributes course) {"},{"lineNumber":256,"author":{"gitId":"-"},"content":" return getCourse(course.getId());"},{"lineNumber":257,"author":{"gitId":"-"},"content":" }"},{"lineNumber":258,"author":{"gitId":"-"},"content":""},{"lineNumber":259,"author":{"gitId":"-"},"content":" CourseAttributes getArchivedCourse(String instructorId, String courseId) {"},{"lineNumber":260,"author":{"gitId":"-"},"content":" return BACKDOOR.getArchivedCourse(instructorId, courseId);"},{"lineNumber":261,"author":{"gitId":"-"},"content":" }"},{"lineNumber":262,"author":{"gitId":"-"},"content":""},{"lineNumber":263,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes getFeedbackQuestion(String courseId, String feedbackSessionName, int qnNumber) {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" return BACKDOOR.getFeedbackQuestion(courseId, feedbackSessionName, qnNumber);"},{"lineNumber":265,"author":{"gitId":"-"},"content":" }"},{"lineNumber":266,"author":{"gitId":"-"},"content":""},{"lineNumber":267,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":268,"author":{"gitId":"-"},"content":" protected FeedbackQuestionAttributes getFeedbackQuestion(FeedbackQuestionAttributes fq) {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" return getFeedbackQuestion(fq.getCourseId(), fq.getFeedbackSessionName(), fq.getQuestionNumber());"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" FeedbackResponseCommentAttributes getFeedbackResponseComment(String feedbackResponseId) {"},{"lineNumber":273,"author":{"gitId":"-"},"content":" return BACKDOOR.getFeedbackResponseComment(feedbackResponseId);"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":277,"author":{"gitId":"-"},"content":" protected FeedbackResponseCommentAttributes getFeedbackResponseComment(FeedbackResponseCommentAttributes frc) {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" return getFeedbackResponseComment(frc.getFeedbackResponseId());"},{"lineNumber":279,"author":{"gitId":"-"},"content":" }"},{"lineNumber":280,"author":{"gitId":"-"},"content":""},{"lineNumber":281,"author":{"gitId":"-"},"content":" FeedbackResponseAttributes getFeedbackResponse(String feedbackQuestionId, String giver, String recipient) {"},{"lineNumber":282,"author":{"gitId":"-"},"content":" return BACKDOOR.getFeedbackResponse(feedbackQuestionId, giver, recipient);"},{"lineNumber":283,"author":{"gitId":"-"},"content":" }"},{"lineNumber":284,"author":{"gitId":"-"},"content":""},{"lineNumber":285,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":286,"author":{"gitId":"-"},"content":" protected FeedbackResponseAttributes getFeedbackResponse(FeedbackResponseAttributes fr) {"},{"lineNumber":287,"author":{"gitId":"-"},"content":" return getFeedbackResponse(fr.getFeedbackQuestionId(), fr.getGiver(), fr.getRecipient());"},{"lineNumber":288,"author":{"gitId":"-"},"content":" }"},{"lineNumber":289,"author":{"gitId":"-"},"content":""},{"lineNumber":290,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes getFeedbackSession(String courseId, String feedbackSessionName) {"},{"lineNumber":291,"author":{"gitId":"-"},"content":" return BACKDOOR.getFeedbackSession(courseId, feedbackSessionName);"},{"lineNumber":292,"author":{"gitId":"-"},"content":" }"},{"lineNumber":293,"author":{"gitId":"-"},"content":""},{"lineNumber":294,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":295,"author":{"gitId":"-"},"content":" protected FeedbackSessionAttributes getFeedbackSession(FeedbackSessionAttributes fs) {"},{"lineNumber":296,"author":{"gitId":"-"},"content":" return getFeedbackSession(fs.getCourseId(), fs.getFeedbackSessionName());"},{"lineNumber":297,"author":{"gitId":"-"},"content":" }"},{"lineNumber":298,"author":{"gitId":"-"},"content":""},{"lineNumber":299,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes getSoftDeletedSession(String feedbackSessionName, String instructorId) {"},{"lineNumber":300,"author":{"gitId":"-"},"content":" return BACKDOOR.getSoftDeletedSession(feedbackSessionName, instructorId);"},{"lineNumber":301,"author":{"gitId":"-"},"content":" }"},{"lineNumber":302,"author":{"gitId":"-"},"content":""},{"lineNumber":303,"author":{"gitId":"-"},"content":" InstructorAttributes getInstructor(String courseId, String instructorEmail) {"},{"lineNumber":304,"author":{"gitId":"-"},"content":" return BACKDOOR.getInstructor(courseId, instructorEmail);"},{"lineNumber":305,"author":{"gitId":"-"},"content":" }"},{"lineNumber":306,"author":{"gitId":"-"},"content":""},{"lineNumber":307,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":308,"author":{"gitId":"-"},"content":" protected InstructorAttributes getInstructor(InstructorAttributes instructor) {"},{"lineNumber":309,"author":{"gitId":"-"},"content":" return getInstructor(instructor.getCourseId(), instructor.getEmail());"},{"lineNumber":310,"author":{"gitId":"-"},"content":" }"},{"lineNumber":311,"author":{"gitId":"-"},"content":""},{"lineNumber":312,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":313,"author":{"gitId":"-"},"content":" * Gets registration key for a given instructor."},{"lineNumber":314,"author":{"gitId":"-"},"content":" */"},{"lineNumber":315,"author":{"gitId":"-"},"content":" protected String getKeyForInstructor(String courseId, String instructorEmail) {"},{"lineNumber":316,"author":{"gitId":"-"},"content":" return getInstructor(courseId, instructorEmail).getKey();"},{"lineNumber":317,"author":{"gitId":"-"},"content":" }"},{"lineNumber":318,"author":{"gitId":"-"},"content":""},{"lineNumber":319,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":320,"author":{"gitId":"-"},"content":" protected StudentAttributes getStudent(StudentAttributes student) {"},{"lineNumber":321,"author":{"gitId":"-"},"content":" return BACKDOOR.getStudent(student.getCourse(), student.getEmail());"},{"lineNumber":322,"author":{"gitId":"-"},"content":" }"},{"lineNumber":323,"author":{"gitId":"-"},"content":""},{"lineNumber":324,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":325,"author":{"gitId":"-"},"content":" * Gets registration key for a given student."},{"lineNumber":326,"author":{"gitId":"-"},"content":" */"},{"lineNumber":327,"author":{"gitId":"-"},"content":" protected String getKeyForStudent(StudentAttributes student) {"},{"lineNumber":328,"author":{"gitId":"-"},"content":" return getStudent(student).getKey();"},{"lineNumber":329,"author":{"gitId":"-"},"content":" }"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":332,"author":{"gitId":"-"},"content":" protected AccountRequestAttributes getAccountRequest(AccountRequestAttributes accountRequest) {"},{"lineNumber":333,"author":{"gitId":"-"},"content":" return BACKDOOR.getAccountRequest(UUID.fromString(accountRequest.getId()));"},{"lineNumber":334,"author":{"gitId":"-"},"content":" }"},{"lineNumber":335,"author":{"gitId":"-"},"content":""},{"lineNumber":336,"author":{"gitId":"-"},"content":" NotificationAttributes getNotification(String notificationId) {"},{"lineNumber":337,"author":{"gitId":"-"},"content":" return BACKDOOR.getNotification(notificationId);"},{"lineNumber":338,"author":{"gitId":"-"},"content":" }"},{"lineNumber":339,"author":{"gitId":"-"},"content":""},{"lineNumber":340,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":341,"author":{"gitId":"-"},"content":" protected NotificationAttributes getNotification(NotificationAttributes notification) {"},{"lineNumber":342,"author":{"gitId":"-"},"content":" return getNotification(notification.getNotificationId());"},{"lineNumber":343,"author":{"gitId":"-"},"content":" }"},{"lineNumber":344,"author":{"gitId":"-"},"content":""},{"lineNumber":345,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":346,"author":{"gitId":"-"},"content":" protected DeadlineExtensionAttributes getDeadlineExtension(DeadlineExtensionAttributes deadlineExtension) {"},{"lineNumber":347,"author":{"gitId":"-"},"content":" return BACKDOOR.getDeadlineExtension("},{"lineNumber":348,"author":{"gitId":"-"},"content":" deadlineExtension.getCourseId(), deadlineExtension.getFeedbackSessionName(),"},{"lineNumber":349,"author":{"gitId":"-"},"content":" deadlineExtension.getUserEmail(), deadlineExtension.getIsInstructor());"},{"lineNumber":350,"author":{"gitId":"-"},"content":" }"},{"lineNumber":351,"author":{"gitId":"-"},"content":""},{"lineNumber":352,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":353,"author":{"gitId":"-"},"content":" protected boolean doRemoveAndRestoreDataBundle(DataBundle testData) {"},{"lineNumber":354,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":355,"author":{"gitId":"-"},"content":" BACKDOOR.removeAndRestoreDataBundle(testData);"},{"lineNumber":356,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":357,"author":{"gitId":"-"},"content":" } catch (HttpRequestFailedException e) {"},{"lineNumber":358,"author":{"gitId":"-"},"content":" e.printStackTrace();"},{"lineNumber":359,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":360,"author":{"gitId":"-"},"content":" }"},{"lineNumber":361,"author":{"gitId":"-"},"content":" }"},{"lineNumber":362,"author":{"gitId":"-"},"content":""},{"lineNumber":363,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":364,"author":{"gitId":"-"},"content":" protected SqlDataBundle doRemoveAndRestoreSqlDataBundle(SqlDataBundle testData) {"},{"lineNumber":365,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":366,"author":{"gitId":"-"},"content":" return BACKDOOR.removeAndRestoreSqlDataBundle(testData);"},{"lineNumber":367,"author":{"gitId":"-"},"content":" } catch (HttpRequestFailedException e) {"},{"lineNumber":368,"author":{"gitId":"-"},"content":" e.printStackTrace();"},{"lineNumber":369,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":370,"author":{"gitId":"-"},"content":" }"},{"lineNumber":371,"author":{"gitId":"-"},"content":" }"},{"lineNumber":372,"author":{"gitId":"-"},"content":""},{"lineNumber":373,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":374,"author":{"gitId":"-"},"content":" protected boolean doPutDocuments(DataBundle testData) {"},{"lineNumber":375,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":376,"author":{"gitId":"-"},"content":" BACKDOOR.putDocuments(testData);"},{"lineNumber":377,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":378,"author":{"gitId":"-"},"content":" } catch (HttpRequestFailedException e) {"},{"lineNumber":379,"author":{"gitId":"-"},"content":" e.printStackTrace();"},{"lineNumber":380,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":381,"author":{"gitId":"-"},"content":" }"},{"lineNumber":382,"author":{"gitId":"-"},"content":" }"},{"lineNumber":383,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":384,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":385,"author":{"gitId":"domoberzin"},"content":" protected boolean doPutDocumentsSql(SqlDataBundle testData) {"},{"lineNumber":386,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":387,"author":{"gitId":"domoberzin"},"content":" BACKDOOR.putSqlDocuments(testData);"},{"lineNumber":388,"author":{"gitId":"domoberzin"},"content":" return true;"},{"lineNumber":389,"author":{"gitId":"domoberzin"},"content":" } catch (HttpRequestFailedException e) {"},{"lineNumber":390,"author":{"gitId":"domoberzin"},"content":" e.printStackTrace();"},{"lineNumber":391,"author":{"gitId":"domoberzin"},"content":" return false;"},{"lineNumber":392,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":393,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":394,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":11,"-":383}},{"path":"src/e2e/java/teammates/e2e/cases/InstructorNotificationsPageE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.Set;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.stream.Collectors;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.stream.Stream;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.NotificationAttributes;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.InstructorNotificationsPage;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.output.AccountData;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * SUT: {@link Const.WebPageURIs#INSTRUCTOR_NOTIFICATIONS_PAGE}."},{"lineNumber":20,"author":{"gitId":"-"},"content":" */"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public class InstructorNotificationsPageE2ETest extends BaseE2ETestCase {"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":24,"author":{"gitId":"-"},"content":" protected void prepareTestData() {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" testData \u003d loadDataBundle(\"/InstructorNotificationsPageE2ETest.json\");"},{"lineNumber":26,"author":{"gitId":"-"},"content":" removeAndRestoreDataBundle(testData);"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" sqlTestData \u003d removeAndRestoreSqlDataBundle("},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" loadSqlDataBundle(\"/InstructorNotificationsPageE2ETest_SqlEntities.json\"));"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":32,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":33,"author":{"gitId":"-"},"content":" public void testAll() {"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" Account account \u003d sqlTestData.accounts.get(\"INotifs.instr\");"},{"lineNumber":35,"author":{"gitId":"-"},"content":" AppUrl notificationsPageUrl \u003d createFrontendUrl(Const.WebPageURIs.INSTRUCTOR_NOTIFICATIONS_PAGE);"},{"lineNumber":36,"author":{"gitId":"-"},"content":" InstructorNotificationsPage notificationsPage \u003d loginToPage(notificationsPageUrl, InstructorNotificationsPage.class,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" account.getGoogleId());"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" ______TS(\"verify that only active notifications with correct target user are shown\");"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" Notification[] notShownNotifications \u003d {"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" sqlTestData.notifications.get(\"notification2\"),"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" sqlTestData.notifications.get(\"expiredNotification1\"),"},{"lineNumber":43,"author":{"gitId":"-"},"content":" };"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" Notification[] shownNotifications \u003d {"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" sqlTestData.notifications.get(\"notification1\"),"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" sqlTestData.notifications.get(\"notification3\"),"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" sqlTestData.notifications.get(\"notification4\"),"},{"lineNumber":48,"author":{"gitId":"-"},"content":" };"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" Notification[] readNotifications \u003d {"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" sqlTestData.notifications.get(\"notification4\"),"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" Set\u003cString\u003e readNotificationsIds \u003d Stream.of(readNotifications)"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" .map(readNotification -\u003e readNotification.getId().toString())"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" .collect(Collectors.toSet());"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" notificationsPage.verifyNotShownNotifications(notShownNotifications);"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" notificationsPage.verifyShownNotifications(shownNotifications, readNotificationsIds);"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" ______TS(\"mark notification as read\");"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" Notification notificationToMarkAsRead \u003d sqlTestData.notifications.get(\"notification3\");"},{"lineNumber":63,"author":{"gitId":"-"},"content":" notificationsPage.markNotificationAsRead(notificationToMarkAsRead);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" notificationsPage.verifyStatusMessage(\"Notification marked as read.\");"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" // Verify that account\u0027s readNotifications attribute is updated"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" AccountData accountFromDb \u003d BACKDOOR.getAccountData(account.getGoogleId());"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" assertTrue(accountFromDb.getReadNotifications().containsKey(notificationToMarkAsRead.getId().toString()));"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" ______TS(\"notification banner is not visible\");"},{"lineNumber":71,"author":{"gitId":"-"},"content":" assertFalse(notificationsPage.isBannerVisible());"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public void classTeardown() {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" for (NotificationAttributes notification : testData.notifications.values()) {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" BACKDOOR.deleteNotification(notification.getNotificationId());"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }"},{"lineNumber":79,"author":{"gitId":"-"},"content":" }"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":28,"-":53}},{"path":"src/e2e/java/teammates/e2e/cases/InstructorSearchPageE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.InstructorCourseStudentDetailsEditPage;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.InstructorCourseStudentDetailsViewPage;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.InstructorSearchPage;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.InstructorStudentRecordsPage;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.e2e.util.TestProperties;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * SUT: {@link Const.WebPageURIs#INSTRUCTOR_SEARCH_PAGE}."},{"lineNumber":20,"author":{"gitId":"-"},"content":" */"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public class InstructorSearchPageE2ETest extends BaseE2ETestCase {"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":24,"author":{"gitId":"-"},"content":" protected void prepareTestData() {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":27,"author":{"gitId":"-"},"content":" }"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" sqlTestData \u003d removeAndRestoreSqlDataBundle("},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" loadSqlDataBundle(\"/InstructorSearchPageE2ETest_SqlEntities.json\"));"},{"lineNumber":30,"author":{"gitId":"-"},"content":" testData \u003d loadDataBundle(\"/InstructorSearchPageE2ETest.json\");"},{"lineNumber":31,"author":{"gitId":"-"},"content":" removeAndRestoreDataBundle(testData);"},{"lineNumber":32,"author":{"gitId":"-"},"content":" putDocuments(testData);"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":36,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":37,"author":{"gitId":"-"},"content":" public void testAll() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" String instructorId \u003d sqlTestData.accounts.get(\"instructor1OfCourse1\").getGoogleId();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" AppUrl searchPageUrl \u003d createFrontendUrl(Const.WebPageURIs.INSTRUCTOR_SEARCH_PAGE);"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" InstructorSearchPage searchPage \u003d loginToPage(searchPageUrl, InstructorSearchPage.class, instructorId);"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" ______TS(\"cannot click search button if no search term is entered\");"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" searchPage.search(\"\");"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" ______TS(\"search with no result\");"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" searchPage.search(\"thiswillnothitanything\");"},{"lineNumber":54,"author":{"gitId":"-"},"content":" searchPage.verifyStatusMessage(\"No results found.\");"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" ______TS(\"search for students\");"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" searchPage.search(\"student2\");"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" CourseAttributes course1 \u003d testData.courses.get(\"typicalCourse1\");"},{"lineNumber":61,"author":{"gitId":"-"},"content":" CourseAttributes course2 \u003d testData.courses.get(\"typicalCourse2\");"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" StudentAttributes[] studentsInCourse1 \u003d {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" testData.students.get(\"student2.2InCourse1\"),"},{"lineNumber":65,"author":{"gitId":"-"},"content":" testData.students.get(\"student2InCourse1\"),"},{"lineNumber":66,"author":{"gitId":"-"},"content":" };"},{"lineNumber":67,"author":{"gitId":"-"},"content":" StudentAttributes[] studentsInCourse2 \u003d {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" testData.students.get(\"student2.2InCourse2\"),"},{"lineNumber":69,"author":{"gitId":"-"},"content":" testData.students.get(\"student2InCourse2\"),"},{"lineNumber":70,"author":{"gitId":"-"},"content":" };"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" Map\u003cString, StudentAttributes[]\u003e courseIdToStudents \u003d new HashMap\u003c\u003e();"},{"lineNumber":73,"author":{"gitId":"-"},"content":" courseIdToStudents.put(course1.getId(), studentsInCourse1);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" courseIdToStudents.put(course2.getId(), studentsInCourse2);"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" Map\u003cString, CourseAttributes\u003e courseIdToCourse \u003d new HashMap\u003c\u003e();"},{"lineNumber":77,"author":{"gitId":"-"},"content":" courseIdToCourse.put(course1.getId(), course1);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" courseIdToCourse.put(course2.getId(), course2);"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" searchPage.verifyStudentDetails(courseIdToCourse, courseIdToStudents);"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" ______TS(\"link: view student details page\");"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" StudentAttributes studentToView \u003d testData.students.get(\"student2.2InCourse1\");"},{"lineNumber":85,"author":{"gitId":"-"},"content":" String studentEmail \u003d studentToView.getEmail();"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" InstructorCourseStudentDetailsViewPage studentDetailsViewPage \u003d"},{"lineNumber":88,"author":{"gitId":"-"},"content":" searchPage.clickViewStudent(course1, studentEmail);"},{"lineNumber":89,"author":{"gitId":"-"},"content":" studentDetailsViewPage.verifyIsCorrectPage(course1.getId(), studentEmail);"},{"lineNumber":90,"author":{"gitId":"-"},"content":" studentDetailsViewPage.closeCurrentWindowAndSwitchToParentWindow();"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" ______TS(\"link: edit student details page\");"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" InstructorCourseStudentDetailsEditPage studentDetailsEditPage \u003d"},{"lineNumber":95,"author":{"gitId":"-"},"content":" searchPage.clickEditStudent(course1, studentEmail);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" studentDetailsEditPage.verifyIsCorrectPage(course1.getId(), studentEmail);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" studentDetailsEditPage.closeCurrentWindowAndSwitchToParentWindow();"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" ______TS(\"link: view all records page\");"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" InstructorStudentRecordsPage studentRecordsPage \u003d"},{"lineNumber":102,"author":{"gitId":"-"},"content":" searchPage.clickViewAllRecords(course1, studentEmail);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" studentRecordsPage.verifyIsCorrectPage(course1.getId(), studentToView.getName());"},{"lineNumber":104,"author":{"gitId":"-"},"content":" studentRecordsPage.closeCurrentWindowAndSwitchToParentWindow();"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" ______TS(\"action: delete student\");"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" StudentAttributes studentToDelete \u003d testData.students.get(\"student2InCourse2\");"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" searchPage.deleteStudent(course2, studentToDelete.getEmail());"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" StudentAttributes[] studentsAfterDelete \u003d {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" testData.students.get(\"student2.2InCourse2\"),"},{"lineNumber":114,"author":{"gitId":"-"},"content":" };"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" searchPage.verifyStudentDetails(course2, studentsAfterDelete);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" verifyAbsentInDatabase(studentToDelete);"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" }"},{"lineNumber":120,"author":{"gitId":"-"},"content":""},{"lineNumber":121,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":3,"-":118}},{"path":"src/e2e/java/teammates/e2e/cases/NotificationBannerE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.NotificationAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.StudentHomePage;"},{"lineNumber":10,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":11,"author":{"gitId":"yuanxi1"},"content":"import teammates.ui.output.AccountData;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"-"},"content":" * SUT: The reusable notification banner, which can be displayed across many pages."},{"lineNumber":15,"author":{"gitId":"-"},"content":" * {@link Const.WebPageURIs#STUDENT_HOME_PAGE} is used to test the behaviour of the banner in this case,"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * {@link Const.WebPageURIs#STUDENT_NOTIFICATIONS_PAGE}"},{"lineNumber":17,"author":{"gitId":"-"},"content":" */"},{"lineNumber":18,"author":{"gitId":"-"},"content":"public class NotificationBannerE2ETest extends BaseE2ETestCase {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":20,"author":{"gitId":"-"},"content":" protected void prepareTestData() {"},{"lineNumber":21,"author":{"gitId":"-"},"content":" testData \u003d loadDataBundle(\"/NotificationBannerE2ETest.json\");"},{"lineNumber":22,"author":{"gitId":"-"},"content":" removeAndRestoreDataBundle(testData);"},{"lineNumber":23,"author":{"gitId":"yuanxi1"},"content":" sqlTestData \u003d removeAndRestoreSqlDataBundle("},{"lineNumber":24,"author":{"gitId":"yuanxi1"},"content":" loadSqlDataBundle(\"/NotificationBannerE2ETest_SqlEntities.json\"));"},{"lineNumber":25,"author":{"gitId":"-"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":28,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":29,"author":{"gitId":"-"},"content":" protected void testAll() {"},{"lineNumber":30,"author":{"gitId":"yuanxi1"},"content":" Account account \u003d sqlTestData.accounts.get(\"NotifBanner.student\");"},{"lineNumber":31,"author":{"gitId":"-"},"content":" AppUrl studentHomePageUrl \u003d createFrontendUrl(Const.WebPageURIs.STUDENT_HOME_PAGE);"},{"lineNumber":32,"author":{"gitId":"-"},"content":" StudentHomePage studentHomePage \u003d loginToPage(studentHomePageUrl, StudentHomePage.class,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" account.getGoogleId());"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" ______TS(\"verify active notification with correct information is shown\");"},{"lineNumber":36,"author":{"gitId":"-"},"content":" assertTrue(studentHomePage.isBannerVisible());"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" ______TS(\"close notification\");"},{"lineNumber":39,"author":{"gitId":"-"},"content":" // After user closes a notification banner, it should not appear till user refreshes page"},{"lineNumber":40,"author":{"gitId":"-"},"content":" studentHomePage.clickCloseNotificationBannerButton();"},{"lineNumber":41,"author":{"gitId":"-"},"content":" assertFalse(studentHomePage.isBannerVisible());"},{"lineNumber":42,"author":{"gitId":"-"},"content":" studentHomePage.reloadPage();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" assertTrue(studentHomePage.isBannerVisible());"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" ______TS(\"mark notification as read\");"},{"lineNumber":46,"author":{"gitId":"-"},"content":" studentHomePage.reloadPage();"},{"lineNumber":47,"author":{"gitId":"-"},"content":" assertTrue(studentHomePage.isBannerVisible());"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"yuanxi1"},"content":" String notificationId \u003d studentHomePage.getNotificationId();"},{"lineNumber":50,"author":{"gitId":"-"},"content":" studentHomePage.clickMarkAsReadButton();"},{"lineNumber":51,"author":{"gitId":"yuanxi1"},"content":" AccountData accountFromDb \u003d BACKDOOR.getAccountData(account.getGoogleId());"},{"lineNumber":52,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" studentHomePage.verifyStatusMessage(\"Notification marked as read.\");"},{"lineNumber":54,"author":{"gitId":"-"},"content":" assertFalse(studentHomePage.isBannerVisible());"},{"lineNumber":55,"author":{"gitId":"yuanxi1"},"content":" assertTrue(accountFromDb.getReadNotifications().containsKey(notificationId));"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":60,"author":{"gitId":"-"},"content":" public void classTeardown() {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" for (NotificationAttributes notification : testData.notifications.values()) {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" BACKDOOR.deleteNotification(notification.getNotificationId());"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"-"},"content":" }"},{"lineNumber":65,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"yuanxi1":9,"-":56}},{"path":"src/e2e/java/teammates/e2e/cases/axe/AdminSearchPageAxeTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases.axe;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import com.deque.html.axecore.results.Results;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.AdminSearchPage;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.e2e.util.TestProperties;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * SUT: {@link Const.WebPageURIs#ADMIN_SEARCH_PAGE}."},{"lineNumber":14,"author":{"gitId":"-"},"content":" */"},{"lineNumber":15,"author":{"gitId":"-"},"content":"public class AdminSearchPageAxeTest extends BaseAxeTestCase {"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":18,"author":{"gitId":"-"},"content":" protected void prepareTestData() {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" }"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" testData \u003d loadDataBundle(\"/AdminSearchPageE2ETest.json\");"},{"lineNumber":24,"author":{"gitId":"-"},"content":" removeAndRestoreDataBundle(testData);"},{"lineNumber":25,"author":{"gitId":"-"},"content":" putDocuments(testData);"},{"lineNumber":26,"author":{"gitId":"-"},"content":" sqlTestData \u003d loadSqlDataBundle(\"/AdminSearchPageE2ETest_SqlEntities.json\");"},{"lineNumber":27,"author":{"gitId":"-"},"content":" removeAndRestoreSqlDataBundle(sqlTestData);"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" putSqlDocuments(sqlTestData);"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":32,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":33,"author":{"gitId":"-"},"content":" public void testAll() {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" }"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" AppUrl url \u003d createFrontendUrl(Const.WebPageURIs.ADMIN_SEARCH_PAGE);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" AdminSearchPage searchPage \u003d loginAdminToPage(url, AdminSearchPage.class);"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(testData.students.get(\"student1InCourse1\").getEmail());"},{"lineNumber":42,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" Results results \u003d getAxeBuilder().analyze(searchPage.getBrowser().getDriver());"},{"lineNumber":45,"author":{"gitId":"-"},"content":" assertTrue(formatViolations(results), results.violationFree());"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":1,"-":47}},{"path":"src/e2e/java/teammates/e2e/cases/axe/InstructorSearchPageAxeTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases.axe;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import com.deque.html.axecore.results.Results;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.InstructorSearchPage;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.e2e.util.TestProperties;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * SUT: {@link Const.WebPageURIs#INSTRUCTOR_SEARCH_PAGE}."},{"lineNumber":14,"author":{"gitId":"-"},"content":" */"},{"lineNumber":15,"author":{"gitId":"-"},"content":"public class InstructorSearchPageAxeTest extends BaseAxeTestCase {"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":18,"author":{"gitId":"-"},"content":" protected void prepareTestData() {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" }"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" sqlTestData \u003d loadSqlDataBundle(\"/InstructorSearchPageE2ETest_SqlEntities.json\");"},{"lineNumber":24,"author":{"gitId":"-"},"content":" testData \u003d loadDataBundle(\"/InstructorSearchPageE2ETest.json\");"},{"lineNumber":25,"author":{"gitId":"-"},"content":" removeAndRestoreDataBundle(testData);"},{"lineNumber":26,"author":{"gitId":"-"},"content":" putDocuments(testData);"},{"lineNumber":27,"author":{"gitId":"-"},"content":" }"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":30,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":31,"author":{"gitId":"-"},"content":" public void testAll() {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" AppUrl searchPageUrl \u003d createFrontendUrl(Const.WebPageURIs.INSTRUCTOR_SEARCH_PAGE);"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" InstructorSearchPage searchPage \u003d loginToPage(searchPageUrl, InstructorSearchPage.class,"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" sqlTestData.accounts.get(\"instructor1OfCourse1\").getGoogleId());"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" searchPage.search(\"student2\");"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" Results results \u003d getAxeBuilder().analyze(searchPage.getBrowser().getDriver());"},{"lineNumber":44,"author":{"gitId":"-"},"content":" assertTrue(formatViolations(results), results.violationFree());"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":2,"-":45}},{"path":"src/e2e/java/teammates/e2e/cases/sql/AdminHomePageE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.e2e.cases.sql;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.Test;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.Const;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import teammates.e2e.pageobjects.AdminHomePage;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" * SUT: {@link Const.WebPageURIs#ADMIN_HOME_PAGE}."},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"public class AdminHomePageE2ETest extends BaseE2ETestCase {"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" protected void prepareTestData() {"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" // not needed"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" public void testAll() {"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" AppUrl url \u003d createFrontendUrl(Const.WebPageURIs.ADMIN_HOME_PAGE);"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" AdminHomePage homePage \u003d loginAdminToPage(url, AdminHomePage.class);"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Test adding instructors with both valid and invalid details\");"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" String name \u003d \"AHPUiT Instrúctör WithPlusInEmail\";"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" String email \u003d \"AHPUiT+++_.instr1!@gmail.tmt\";"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" String institute \u003d \"TEAMMATES Test Institute 1\";"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" homePage.queueInstructorForAdding(name, email, institute);"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" String singleLineDetails \u003d \"Instructor With Invalid Email | invalidemail | TEAMMATES Test Institute 1\";"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" homePage.queueInstructorForAdding(singleLineDetails);"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" homePage.addAllInstructors();"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" String successMessage \u003d homePage.getMessageForInstructor(0);"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" assertTrue(successMessage.contains("},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" \"Instructor \\\"AHPUiT Instrúctör WithPlusInEmail\\\" has been successfully created\"));"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" String failureMessage \u003d homePage.getMessageForInstructor(1);"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" assertTrue(failureMessage.contains("},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" \"\\\"invalidemail\\\" is not acceptable to TEAMMATES as a/an email because it is not in the correct format.\"));"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" homePage.reloadPage();"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Verify that newly added instructor appears in account request table\");"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" homePage.verifyInstructorInAccountRequestTable(name, email, institute);"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":55}},{"path":"src/e2e/java/teammates/e2e/cases/sql/AdminSearchPageE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases.sql;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.StringHelperExtension;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.AdminSearchPage;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.e2e.util.TestProperties;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * SUT: {@link Const.WebPageURIs#ADMIN_SEARCH_PAGE}."},{"lineNumber":23,"author":{"gitId":"-"},"content":" */"},{"lineNumber":24,"author":{"gitId":"-"},"content":"public class AdminSearchPageE2ETest extends BaseE2ETestCase {"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":27,"author":{"gitId":"-"},"content":" protected void prepareTestData() {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":" testData \u003d removeAndRestoreDataBundle(loadSqlDataBundle(\"/AdminSearchPageE2ESqlTest.json\"));"},{"lineNumber":32,"author":{"gitId":"-"},"content":" putDocuments(testData);"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":36,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":37,"author":{"gitId":"-"},"content":" public void testAll() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" if (!TestProperties.INCLUDE_SEARCH_TESTS) {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" AppUrl url \u003d createFrontendUrl(Const.WebPageURIs.ADMIN_SEARCH_PAGE);"},{"lineNumber":43,"author":{"gitId":"-"},"content":" AdminSearchPage searchPage \u003d loginAdminToPage(url, AdminSearchPage.class);"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" Course course \u003d testData.courses.get(\"typicalCourse1\");"},{"lineNumber":46,"author":{"gitId":"-"},"content":" Student student \u003d testData.students.get(\"student1InCourse1\");"},{"lineNumber":47,"author":{"gitId":"-"},"content":" Instructor instructor \u003d testData.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":48,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d testData.accountRequests.get(\"instructor1OfCourse1\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Search student email\");"},{"lineNumber":51,"author":{"gitId":"-"},"content":" String searchContent \u003d student.getEmail();"},{"lineNumber":52,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":54,"author":{"gitId":"-"},"content":" String studentDetails \u003d getExpectedStudentDetails(student);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" String studentManageAccountLink \u003d getExpectedStudentManageAccountLink(student);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" String studentHomePageLink \u003d getExpectedStudentHomePageLink(student);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" int numExpandedRows \u003d getExpectedNumExpandedRows(student);"},{"lineNumber":58,"author":{"gitId":"-"},"content":" searchPage.verifyStudentRowContent(student, course, studentDetails, studentManageAccountLink,"},{"lineNumber":59,"author":{"gitId":"-"},"content":" studentHomePageLink);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" searchPage.verifyStudentExpandedLinks(student, numExpandedRows);"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Reset student google id\");"},{"lineNumber":63,"author":{"gitId":"-"},"content":" searchPage.resetStudentGoogleId(student);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" student.setGoogleId(null);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" searchPage.verifyStudentRowContentAfterReset(student, course);"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Regenerate registration key for a course student\");"},{"lineNumber":68,"author":{"gitId":"-"},"content":" searchPage.clickExpandStudentLinks();"},{"lineNumber":69,"author":{"gitId":"-"},"content":" String originalJoinLink \u003d searchPage.getStudentJoinLink(student);"},{"lineNumber":70,"author":{"gitId":"-"},"content":" searchPage.regenerateStudentKey(student);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" searchPage.verifyRegenerateStudentKey(student, originalJoinLink);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" searchPage.waitForPageToLoad();"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Search for instructor email\");"},{"lineNumber":75,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":76,"author":{"gitId":"-"},"content":" searchContent \u003d instructor.getEmail();"},{"lineNumber":77,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":79,"author":{"gitId":"-"},"content":" String instructorManageAccountLink \u003d getExpectedInstructorManageAccountLink(instructor);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" String instructorHomePageLink \u003d getExpectedInstructorHomePageLink(instructor);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" searchPage.verifyInstructorRowContent(instructor, course, instructorManageAccountLink,"},{"lineNumber":82,"author":{"gitId":"-"},"content":" instructorHomePageLink);"},{"lineNumber":83,"author":{"gitId":"-"},"content":" searchPage.verifyInstructorExpandedLinks(instructor);"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Reset instructor google id\");"},{"lineNumber":86,"author":{"gitId":"-"},"content":" searchPage.resetInstructorGoogleId(instructor);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" searchPage.verifyInstructorRowContentAfterReset(instructor, course);"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Regenerate registration key for an instructor\");"},{"lineNumber":90,"author":{"gitId":"-"},"content":" searchPage.clickExpandInstructorLinks();"},{"lineNumber":91,"author":{"gitId":"-"},"content":" originalJoinLink \u003d searchPage.getInstructorJoinLink(instructor);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" searchPage.regenerateInstructorKey(instructor);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" searchPage.verifyRegenerateInstructorKey(instructor, originalJoinLink);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" searchPage.waitForPageToLoad();"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Search for account request by email\");"},{"lineNumber":97,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":98,"author":{"gitId":"-"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":99,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":101,"author":{"gitId":"-"},"content":" searchPage.verifyAccountRequestRowContent(accountRequest);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" searchPage.verifyAccountRequestExpandedLinks(accountRequest);"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Search common search key\");"},{"lineNumber":105,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":106,"author":{"gitId":"-"},"content":" searchContent \u003d \"Course1\";"},{"lineNumber":107,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":109,"author":{"gitId":"-"},"content":" searchPage.verifyStudentRowContentAfterReset(student, course);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" searchPage.verifyInstructorRowContentAfterReset(instructor, course);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" searchPage.verifyAccountRequestRowContent(accountRequest);"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Expand and collapse links\");"},{"lineNumber":114,"author":{"gitId":"-"},"content":" searchPage.verifyLinkExpansionButtons(student, instructor, accountRequest);"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Reset account request successful\");"},{"lineNumber":117,"author":{"gitId":"-"},"content":" searchContent \u003d \"ASearch.instructor1@gmail.tmt\";"},{"lineNumber":118,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":119,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":121,"author":{"gitId":"-"},"content":" searchPage.clickResetAccountRequestButton(accountRequest);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" assertNull(BACKDOOR.getAccountRequest(accountRequest.getId()).getRegisteredAt());"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" ______TS(\"Typical case: Delete account request successful\");"},{"lineNumber":125,"author":{"gitId":"-"},"content":" accountRequest \u003d testData.accountRequests.get(\"unregisteredInstructor1\");"},{"lineNumber":126,"author":{"gitId":"-"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":127,"author":{"gitId":"-"},"content":" searchPage.clearSearchBox();"},{"lineNumber":128,"author":{"gitId":"-"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":129,"author":{"gitId":"-"},"content":" searchPage.clickSearchButton();"},{"lineNumber":130,"author":{"gitId":"-"},"content":" searchPage.clickDeleteAccountRequestButton(accountRequest);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" assertNull(BACKDOOR.getAccountRequest(accountRequest.getId()));"},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Typical case: Edit account request successful\");"},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d testData.accountRequests.get(\"unregisteredInstructor2\");"},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" searchPage.clearSearchBox();"},{"lineNumber":137,"author":{"gitId":"domoberzin"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSearchButton();"},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":" searchPage.clickEditAccountRequestButton(accountRequest);"},{"lineNumber":140,"author":{"gitId":"domoberzin"},"content":" searchPage.fillInEditModalFields(\"Different name\", accountRequest.getEmail(),"},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":" accountRequest.getInstitute(), \"New comment\");"},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSaveEditAccountRequestButton();"},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":" accountRequest.setName(\"Different name\");"},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":" accountRequest.setComments(\"New comment\");"},{"lineNumber":145,"author":{"gitId":"domoberzin"},"content":" searchPage.verifyAccountRequestRowContent(accountRequest);"},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":147,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Typical case: View comment of account request\");"},{"lineNumber":148,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d testData.accountRequests.get(\"unregisteredInstructor2\");"},{"lineNumber":149,"author":{"gitId":"domoberzin"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":150,"author":{"gitId":"domoberzin"},"content":" searchPage.clearSearchBox();"},{"lineNumber":151,"author":{"gitId":"domoberzin"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":152,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSearchButton();"},{"lineNumber":153,"author":{"gitId":"domoberzin"},"content":" searchPage.clickViewAccountRequestAndVerifyCommentsButton(accountRequest, \"New comment\");"},{"lineNumber":154,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":155,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Edit account request with invalid details\");"},{"lineNumber":156,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d testData.accountRequests.get(\"unregisteredInstructor2\");"},{"lineNumber":157,"author":{"gitId":"domoberzin"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":158,"author":{"gitId":"domoberzin"},"content":" searchPage.clearSearchBox();"},{"lineNumber":159,"author":{"gitId":"domoberzin"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":160,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSearchButton();"},{"lineNumber":161,"author":{"gitId":"domoberzin"},"content":" searchPage.clickEditAccountRequestButton(accountRequest);"},{"lineNumber":162,"author":{"gitId":"domoberzin"},"content":" searchPage.fillInEditModalFields(accountRequest.getName(), \"invalid\","},{"lineNumber":163,"author":{"gitId":"domoberzin"},"content":" accountRequest.getInstitute(), \"New comment\");"},{"lineNumber":164,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSaveEditAccountRequestButton();"},{"lineNumber":165,"author":{"gitId":"domoberzin"},"content":" String formattedErrorMessage \u003d String.format(\"\\\"%s\\\" is not acceptable to TEAMMATES as a/an %s because it %s. \""},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":" + \"An email address contains some text followed by one \u0027@\u0027 sign followed by some more text, \""},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" + \"and should end with a top level domain address like .com. It cannot be longer than %d characters, \""},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":" + \"cannot be empty and cannot contain spaces.\","},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" \"invalid\", FieldValidator.EMAIL_FIELD_NAME, FieldValidator.REASON_INCORRECT_FORMAT,"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" FieldValidator.EMAIL_MAX_LENGTH);"},{"lineNumber":171,"author":{"gitId":"domoberzin"},"content":" searchPage.verifyStatusMessage(formattedErrorMessage);"},{"lineNumber":172,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":" String name \u003d StringHelperExtension.generateStringOfLength(FieldValidator.PERSON_NAME_MAX_LENGTH + 1);"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" searchPage.clickEditAccountRequestButton(accountRequest);"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":" searchPage.fillInEditModalFields(name, accountRequest.getEmail(), accountRequest.getInstitute(), \"New comment\");"},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSaveEditAccountRequestButton();"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":" formattedErrorMessage \u003d String.format(\"\\\"%s\\\" is not acceptable to TEAMMATES as a/an %s because it %s. \""},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" + \"The value of a/an %s should be no longer than %d characters. It should not be empty.\","},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" name, FieldValidator.PERSON_NAME_FIELD_NAME, FieldValidator.REASON_TOO_LONG,"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":" FieldValidator.PERSON_NAME_FIELD_NAME, FieldValidator.PERSON_NAME_MAX_LENGTH);"},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":" searchPage.verifyStatusMessage(formattedErrorMessage);"},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":184,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Typical case: Approve account request successful\");"},{"lineNumber":185,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d testData.accountRequests.get(\"unregisteredInstructor2\");"},{"lineNumber":186,"author":{"gitId":"domoberzin"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":187,"author":{"gitId":"domoberzin"},"content":" searchPage.clearSearchBox();"},{"lineNumber":188,"author":{"gitId":"domoberzin"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":189,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSearchButton();"},{"lineNumber":190,"author":{"gitId":"domoberzin"},"content":" searchPage.clickApproveAccountRequestButton(accountRequest);"},{"lineNumber":191,"author":{"gitId":"domoberzin"},"content":" accountRequest.setStatus(AccountRequestStatus.APPROVED);"},{"lineNumber":192,"author":{"gitId":"domoberzin"},"content":" searchPage.verifyAccountRequestRowContent(accountRequest);"},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Typical case: Reject account request successfully\");"},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d testData.accountRequests.get(\"unregisteredInstructor3\");"},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":" searchPage.clearSearchBox();"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSearchButton();"},{"lineNumber":200,"author":{"gitId":"domoberzin"},"content":" searchPage.clickRejectAccountRequestButton(accountRequest);"},{"lineNumber":201,"author":{"gitId":"domoberzin"},"content":" accountRequest.setStatus(AccountRequestStatus.REJECTED);"},{"lineNumber":202,"author":{"gitId":"domoberzin"},"content":" searchPage.verifyAccountRequestRowContent(accountRequest);"},{"lineNumber":203,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":204,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Reject account request with empty body\");"},{"lineNumber":205,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d testData.accountRequests.get(\"unregisteredInstructor5\");"},{"lineNumber":206,"author":{"gitId":"domoberzin"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":207,"author":{"gitId":"domoberzin"},"content":" searchPage.clearSearchBox();"},{"lineNumber":208,"author":{"gitId":"domoberzin"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":209,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSearchButton();"},{"lineNumber":210,"author":{"gitId":"domoberzin"},"content":" searchPage.clickRejectAccountRequestWithReasonButton(accountRequest);"},{"lineNumber":211,"author":{"gitId":"domoberzin"},"content":" searchPage.fillInRejectionModalBody(\"\");"},{"lineNumber":212,"author":{"gitId":"domoberzin"},"content":" searchPage.clickConfirmRejectAccountRequest();"},{"lineNumber":213,"author":{"gitId":"domoberzin"},"content":" searchPage.verifyStatusMessage(\"Please provide an email body for the rejection email.\");"},{"lineNumber":214,"author":{"gitId":"domoberzin"},"content":" searchPage.closeRejectionModal();"},{"lineNumber":215,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":216,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Typical case: Reject account request with reason successfully\");"},{"lineNumber":217,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d testData.accountRequests.get(\"unregisteredInstructor4\");"},{"lineNumber":218,"author":{"gitId":"domoberzin"},"content":" searchContent \u003d accountRequest.getEmail();"},{"lineNumber":219,"author":{"gitId":"domoberzin"},"content":" searchPage.clearSearchBox();"},{"lineNumber":220,"author":{"gitId":"domoberzin"},"content":" searchPage.inputSearchContent(searchContent);"},{"lineNumber":221,"author":{"gitId":"domoberzin"},"content":" searchPage.clickSearchButton();"},{"lineNumber":222,"author":{"gitId":"domoberzin"},"content":" searchPage.clickRejectAccountRequestWithReasonButton(accountRequest);"},{"lineNumber":223,"author":{"gitId":"domoberzin"},"content":" accountRequest.setStatus(AccountRequestStatus.REJECTED);"},{"lineNumber":224,"author":{"gitId":"domoberzin"},"content":" searchPage.verifyAccountRequestRowContent(accountRequest);"},{"lineNumber":225,"author":{"gitId":"-"},"content":" }"},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"-"},"content":" private String getExpectedStudentDetails(Student student) {"},{"lineNumber":228,"author":{"gitId":"-"},"content":" return String.format(\"%s [%s] (%s)\", student.getCourse().getId(),"},{"lineNumber":229,"author":{"gitId":"-"},"content":" student.getSection() \u003d\u003d null"},{"lineNumber":230,"author":{"gitId":"-"},"content":" ? Const.DEFAULT_SECTION"},{"lineNumber":231,"author":{"gitId":"-"},"content":" : student.getSection().getName(),"},{"lineNumber":232,"author":{"gitId":"-"},"content":" student.getTeam().getName());"},{"lineNumber":233,"author":{"gitId":"-"},"content":" }"},{"lineNumber":234,"author":{"gitId":"-"},"content":""},{"lineNumber":235,"author":{"gitId":"-"},"content":" private String getExpectedStudentHomePageLink(Student student) {"},{"lineNumber":236,"author":{"gitId":"-"},"content":" return student.isRegistered() ? createFrontendUrl(Const.WebPageURIs.STUDENT_HOME_PAGE)"},{"lineNumber":237,"author":{"gitId":"-"},"content":" .withUserId(student.getGoogleId())"},{"lineNumber":238,"author":{"gitId":"-"},"content":" .toAbsoluteString()"},{"lineNumber":239,"author":{"gitId":"-"},"content":" : \"\";"},{"lineNumber":240,"author":{"gitId":"-"},"content":" }"},{"lineNumber":241,"author":{"gitId":"-"},"content":""},{"lineNumber":242,"author":{"gitId":"-"},"content":" private String getExpectedStudentManageAccountLink(Student student) {"},{"lineNumber":243,"author":{"gitId":"-"},"content":" return student.isRegistered() ? createFrontendUrl(Const.WebPageURIs.ADMIN_ACCOUNTS_PAGE)"},{"lineNumber":244,"author":{"gitId":"-"},"content":" .withParam(Const.ParamsNames.INSTRUCTOR_ID, student.getGoogleId())"},{"lineNumber":245,"author":{"gitId":"-"},"content":" .toAbsoluteString()"},{"lineNumber":246,"author":{"gitId":"-"},"content":" : \"\";"},{"lineNumber":247,"author":{"gitId":"-"},"content":" }"},{"lineNumber":248,"author":{"gitId":"-"},"content":""},{"lineNumber":249,"author":{"gitId":"-"},"content":" private int getExpectedNumExpandedRows(Student student) {"},{"lineNumber":250,"author":{"gitId":"-"},"content":" int expectedNumExpandedRows \u003d 2;"},{"lineNumber":251,"author":{"gitId":"-"},"content":" for (FeedbackSession sessions : testData.feedbackSessions.values()) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" if (sessions.getCourse().equals(student.getCourse())) {"},{"lineNumber":253,"author":{"gitId":"-"},"content":" expectedNumExpandedRows +\u003d 1;"},{"lineNumber":254,"author":{"gitId":"-"},"content":" if (sessions.getResultsVisibleFromTime().isBefore(Instant.now())) {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" expectedNumExpandedRows +\u003d 1;"},{"lineNumber":256,"author":{"gitId":"-"},"content":" }"},{"lineNumber":257,"author":{"gitId":"-"},"content":" }"},{"lineNumber":258,"author":{"gitId":"-"},"content":" }"},{"lineNumber":259,"author":{"gitId":"-"},"content":" return expectedNumExpandedRows;"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":""},{"lineNumber":262,"author":{"gitId":"-"},"content":" private String getExpectedInstructorHomePageLink(Instructor instructor) {"},{"lineNumber":263,"author":{"gitId":"-"},"content":" String googleId \u003d instructor.isRegistered() ? instructor.getGoogleId() : \"\";"},{"lineNumber":264,"author":{"gitId":"-"},"content":" return createFrontendUrl(Const.WebPageURIs.INSTRUCTOR_HOME_PAGE)"},{"lineNumber":265,"author":{"gitId":"-"},"content":" .withUserId(googleId)"},{"lineNumber":266,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":267,"author":{"gitId":"-"},"content":" }"},{"lineNumber":268,"author":{"gitId":"-"},"content":""},{"lineNumber":269,"author":{"gitId":"-"},"content":" private String getExpectedInstructorManageAccountLink(Instructor instructor) {"},{"lineNumber":270,"author":{"gitId":"-"},"content":" String googleId \u003d instructor.isRegistered() ? instructor.getGoogleId() : \"\";"},{"lineNumber":271,"author":{"gitId":"-"},"content":" return createFrontendUrl(Const.WebPageURIs.ADMIN_ACCOUNTS_PAGE)"},{"lineNumber":272,"author":{"gitId":"-"},"content":" .withParam(Const.ParamsNames.INSTRUCTOR_ID, googleId)"},{"lineNumber":273,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":277,"author":{"gitId":"-"},"content":" public void classTeardown() {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" for (AccountRequest request : testData.accountRequests.values()) {"},{"lineNumber":279,"author":{"gitId":"-"},"content":" BACKDOOR.deleteAccountRequest(request.getId());"},{"lineNumber":280,"author":{"gitId":"-"},"content":" }"},{"lineNumber":281,"author":{"gitId":"-"},"content":" }"},{"lineNumber":282,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":96,"-":186}},{"path":"src/e2e/java/teammates/e2e/cases/sql/BaseE2ETestCase.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.cases.sql;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.io.IOException;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.nio.file.Files;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.nio.file.Paths;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.ITestContext;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.exception.HttpRequestFailedException;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.AppPage;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.Browser;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.DevServerLoginPage;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.e2e.pageobjects.HomePage;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.e2e.util.BackDoor;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.e2e.util.EmailAccount;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.e2e.util.TestProperties;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.test.FileHelper;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.test.ThreadHelper;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackQuestionData;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackResponseData;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionData;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionPublishStatus;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.ui.output.StudentData;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":37,"author":{"gitId":"-"},"content":" * Base class for all browser tests."},{"lineNumber":38,"author":{"gitId":"-"},"content":" *"},{"lineNumber":39,"author":{"gitId":"-"},"content":" * \u003cp\u003eThis type of test has no knowledge of the workings of the application,"},{"lineNumber":40,"author":{"gitId":"-"},"content":" * and can only communicate via the UI or via {@link BackDoor} to obtain/transmit data."},{"lineNumber":41,"author":{"gitId":"-"},"content":" */"},{"lineNumber":42,"author":{"gitId":"-"},"content":"public abstract class BaseE2ETestCase extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":45,"author":{"gitId":"-"},"content":" * Backdoor used to call APIs."},{"lineNumber":46,"author":{"gitId":"-"},"content":" */"},{"lineNumber":47,"author":{"gitId":"-"},"content":" protected static final BackDoor BACKDOOR \u003d BackDoor.getInstance();"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":50,"author":{"gitId":"-"},"content":" * DataBundle used in tests."},{"lineNumber":51,"author":{"gitId":"-"},"content":" */"},{"lineNumber":52,"author":{"gitId":"-"},"content":" protected SqlDataBundle testData;"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" private Browser browser;"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" @BeforeClass"},{"lineNumber":57,"author":{"gitId":"-"},"content":" public void baseClassSetup() {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" prepareTestData();"},{"lineNumber":59,"author":{"gitId":"-"},"content":" prepareBrowser();"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":63,"author":{"gitId":"-"},"content":" * Prepares the browser used for the current test."},{"lineNumber":64,"author":{"gitId":"-"},"content":" */"},{"lineNumber":65,"author":{"gitId":"-"},"content":" protected void prepareBrowser() {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" browser \u003d new Browser();"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":70,"author":{"gitId":"-"},"content":" * Prepares the test data used for the current test."},{"lineNumber":71,"author":{"gitId":"-"},"content":" */"},{"lineNumber":72,"author":{"gitId":"-"},"content":" protected abstract void prepareTestData();"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":75,"author":{"gitId":"-"},"content":" * Contains all the tests for the page."},{"lineNumber":76,"author":{"gitId":"-"},"content":" *"},{"lineNumber":77,"author":{"gitId":"-"},"content":" * \u003cp\u003eThis approach is chosen so that setup and teardown are only needed once per test page,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" * thereby saving time. While it necessitates failed tests to be restarted from the beginning,"},{"lineNumber":79,"author":{"gitId":"-"},"content":" * test failures are rare and thus not causing significant overhead."},{"lineNumber":80,"author":{"gitId":"-"},"content":" */"},{"lineNumber":81,"author":{"gitId":"-"},"content":" protected abstract void testAll();"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":84,"author":{"gitId":"-"},"content":" protected String getTestDataFolder() {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" return TestProperties.TEST_DATA_FOLDER;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" }"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":89,"author":{"gitId":"-"},"content":" public void baseClassTearDown(ITestContext context) {"},{"lineNumber":90,"author":{"gitId":"-"},"content":" if (browser \u003d\u003d null) {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":" boolean isSuccess \u003d context.getFailedTests().getAllMethods()"},{"lineNumber":94,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":95,"author":{"gitId":"-"},"content":" .noneMatch(method -\u003e method.getConstructorOrMethod().getMethod().getDeclaringClass() \u003d\u003d this.getClass());"},{"lineNumber":96,"author":{"gitId":"-"},"content":" if (isSuccess || TestProperties.CLOSE_BROWSER_ON_FAILURE) {"},{"lineNumber":97,"author":{"gitId":"-"},"content":" browser.close();"},{"lineNumber":98,"author":{"gitId":"-"},"content":" }"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":102,"author":{"gitId":"-"},"content":" * Creates an {@link AppUrl} for the supplied {@code relativeUrl} parameter."},{"lineNumber":103,"author":{"gitId":"-"},"content":" * The base URL will be the value of test.app.frontend.url in test.properties."},{"lineNumber":104,"author":{"gitId":"-"},"content":" * {@code relativeUrl} must start with a \"/\"."},{"lineNumber":105,"author":{"gitId":"-"},"content":" */"},{"lineNumber":106,"author":{"gitId":"-"},"content":" protected static AppUrl createFrontendUrl(String relativeUrl) {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" return new AppUrl(TestProperties.TEAMMATES_FRONTEND_URL + relativeUrl);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":111,"author":{"gitId":"-"},"content":" * Creates an {@link AppUrl} for the supplied {@code relativeUrl} parameter."},{"lineNumber":112,"author":{"gitId":"-"},"content":" * The base URL will be the value of test.app.backend.url in test.properties."},{"lineNumber":113,"author":{"gitId":"-"},"content":" * {@code relativeUrl} must start with a \"/\"."},{"lineNumber":114,"author":{"gitId":"-"},"content":" */"},{"lineNumber":115,"author":{"gitId":"-"},"content":" protected static AppUrl createBackendUrl(String relativeUrl) {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" return new AppUrl(TestProperties.TEAMMATES_BACKEND_URL + relativeUrl);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" }"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":120,"author":{"gitId":"-"},"content":" * Logs in to a page using the given credentials."},{"lineNumber":121,"author":{"gitId":"-"},"content":" */"},{"lineNumber":122,"author":{"gitId":"-"},"content":" protected \u003cT extends AppPage\u003e T loginToPage(AppUrl url, Class\u003cT\u003e typeOfPage, String userId) {"},{"lineNumber":123,"author":{"gitId":"-"},"content":" // When not using dev server, Google blocks log in by automation."},{"lineNumber":124,"author":{"gitId":"-"},"content":" // To work around that, we inject the user cookie directly into the browser session."},{"lineNumber":125,"author":{"gitId":"-"},"content":" if (!TestProperties.isDevServer()) {"},{"lineNumber":126,"author":{"gitId":"-"},"content":" // In order for the cookie injection to work, we need to be in the domain."},{"lineNumber":127,"author":{"gitId":"-"},"content":" // Use the home page to minimize the page load time."},{"lineNumber":128,"author":{"gitId":"-"},"content":" browser.goToUrl(TestProperties.TEAMMATES_FRONTEND_URL);"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" String cookieValue \u003d BACKDOOR.getUserCookie(userId);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" browser.addCookie(Const.SecurityConfig.AUTH_COOKIE_NAME, cookieValue, true, true);"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" return getNewPageInstance(url, typeOfPage);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" }"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" // This will be redirected to the dev server login page."},{"lineNumber":137,"author":{"gitId":"-"},"content":" browser.goToUrl(url.toAbsoluteString());"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" DevServerLoginPage loginPage \u003d AppPage.getNewPageInstance(browser, DevServerLoginPage.class);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" loginPage.loginAsUser(userId);"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" return getNewPageInstance(url, typeOfPage);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" }"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":146,"author":{"gitId":"-"},"content":" * Logs in to a page using admin credentials."},{"lineNumber":147,"author":{"gitId":"-"},"content":" */"},{"lineNumber":148,"author":{"gitId":"-"},"content":" protected \u003cT extends AppPage\u003e T loginAdminToPage(AppUrl url, Class\u003cT\u003e typeOfPage) {"},{"lineNumber":149,"author":{"gitId":"-"},"content":" return loginToPage(url, typeOfPage, TestProperties.TEST_ADMIN);"},{"lineNumber":150,"author":{"gitId":"-"},"content":" }"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":153,"author":{"gitId":"-"},"content":" * Equivalent to clicking the \u0027logout\u0027 link in the top menu of the page."},{"lineNumber":154,"author":{"gitId":"-"},"content":" */"},{"lineNumber":155,"author":{"gitId":"-"},"content":" protected void logout() {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" AppUrl url \u003d createBackendUrl(Const.WebPageURIs.LOGOUT);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" if (!TestProperties.TEAMMATES_FRONTEND_URL.equals(TestProperties.TEAMMATES_BACKEND_URL)) {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" url \u003d url.withParam(\"frontendUrl\", TestProperties.TEAMMATES_FRONTEND_URL);"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" browser.goToUrl(url.toAbsoluteString());"},{"lineNumber":162,"author":{"gitId":"-"},"content":" AppPage.getNewPageInstance(browser, HomePage.class).waitForPageToLoad();"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":166,"author":{"gitId":"-"},"content":" * Deletes file with fileName from the downloads folder."},{"lineNumber":167,"author":{"gitId":"-"},"content":" */"},{"lineNumber":168,"author":{"gitId":"-"},"content":" protected void deleteDownloadsFile(String fileName) {"},{"lineNumber":169,"author":{"gitId":"-"},"content":" String filePath \u003d TestProperties.TEST_DOWNLOADS_FOLDER + fileName;"},{"lineNumber":170,"author":{"gitId":"-"},"content":" FileHelper.deleteFile(filePath);"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":174,"author":{"gitId":"-"},"content":" * Verifies downloaded file has correct fileName and contains expected content."},{"lineNumber":175,"author":{"gitId":"-"},"content":" */"},{"lineNumber":176,"author":{"gitId":"-"},"content":" protected void verifyDownloadedFile(String expectedFileName, List\u003cString\u003e expectedContent) {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" String filePath \u003d TestProperties.TEST_DOWNLOADS_FOLDER + expectedFileName;"},{"lineNumber":178,"author":{"gitId":"-"},"content":" int retryLimit \u003d TestProperties.TEST_TIMEOUT;"},{"lineNumber":179,"author":{"gitId":"-"},"content":" boolean actual \u003d Files.exists(Paths.get(filePath));"},{"lineNumber":180,"author":{"gitId":"-"},"content":" while (!actual \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":181,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":182,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(1000);"},{"lineNumber":183,"author":{"gitId":"-"},"content":" actual \u003d Files.exists(Paths.get(filePath));"},{"lineNumber":184,"author":{"gitId":"-"},"content":" }"},{"lineNumber":185,"author":{"gitId":"-"},"content":" assertTrue(actual);"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" String actualContent \u003d FileHelper.readFile(filePath);"},{"lineNumber":189,"author":{"gitId":"-"},"content":" for (String content : expectedContent) {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" assertTrue(actualContent.contains(content));"},{"lineNumber":191,"author":{"gitId":"-"},"content":" }"},{"lineNumber":192,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":193,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":194,"author":{"gitId":"-"},"content":" }"},{"lineNumber":195,"author":{"gitId":"-"},"content":" }"},{"lineNumber":196,"author":{"gitId":"-"},"content":""},{"lineNumber":197,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":198,"author":{"gitId":"-"},"content":" * Visits the URL and gets the page object representation of the visited web page in the browser."},{"lineNumber":199,"author":{"gitId":"-"},"content":" */"},{"lineNumber":200,"author":{"gitId":"-"},"content":" protected \u003cT extends AppPage\u003e T getNewPageInstance(AppUrl url, Class\u003cT\u003e typeOfPage) {"},{"lineNumber":201,"author":{"gitId":"-"},"content":" browser.goToUrl(url.toAbsoluteString());"},{"lineNumber":202,"author":{"gitId":"-"},"content":" return AppPage.getNewPageInstance(browser, typeOfPage);"},{"lineNumber":203,"author":{"gitId":"-"},"content":" }"},{"lineNumber":204,"author":{"gitId":"-"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":206,"author":{"gitId":"-"},"content":" * Verifies that email with subject is found in inbox."},{"lineNumber":207,"author":{"gitId":"-"},"content":" * Email used must be an authentic gmail account."},{"lineNumber":208,"author":{"gitId":"-"},"content":" */"},{"lineNumber":209,"author":{"gitId":"-"},"content":" protected void verifyEmailSent(String email, String subject) {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" if (TestProperties.isDevServer() || !TestProperties.INCLUDE_EMAIL_VERIFICATION) {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":" if (!TestProperties.TEST_EMAIL.equals(email)) {"},{"lineNumber":214,"author":{"gitId":"-"},"content":" fail(\"Email verification is allowed only on preset test email.\");"},{"lineNumber":215,"author":{"gitId":"-"},"content":" }"},{"lineNumber":216,"author":{"gitId":"-"},"content":" EmailAccount emailAccount \u003d new EmailAccount(email);"},{"lineNumber":217,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":218,"author":{"gitId":"-"},"content":" emailAccount.getUserAuthenticated();"},{"lineNumber":219,"author":{"gitId":"-"},"content":" int retryLimit \u003d 5;"},{"lineNumber":220,"author":{"gitId":"-"},"content":" boolean actual \u003d emailAccount.isRecentEmailWithSubjectPresent(subject, TestProperties.TEST_SENDER_EMAIL);"},{"lineNumber":221,"author":{"gitId":"-"},"content":" while (!actual \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":222,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":223,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(1000);"},{"lineNumber":224,"author":{"gitId":"-"},"content":" actual \u003d emailAccount.isRecentEmailWithSubjectPresent(subject, TestProperties.TEST_SENDER_EMAIL);"},{"lineNumber":225,"author":{"gitId":"-"},"content":" }"},{"lineNumber":226,"author":{"gitId":"-"},"content":" assertTrue(actual);"},{"lineNumber":227,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":228,"author":{"gitId":"-"},"content":" fail(\"Failed to verify email sent:\" + e);"},{"lineNumber":229,"author":{"gitId":"-"},"content":" }"},{"lineNumber":230,"author":{"gitId":"-"},"content":" }"},{"lineNumber":231,"author":{"gitId":"-"},"content":""},{"lineNumber":232,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":233,"author":{"gitId":"-"},"content":" * Removes and restores the databundle using BACKDOOR."},{"lineNumber":234,"author":{"gitId":"-"},"content":" */"},{"lineNumber":235,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":236,"author":{"gitId":"-"},"content":" protected SqlDataBundle doRemoveAndRestoreDataBundle(SqlDataBundle testData) {"},{"lineNumber":237,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":238,"author":{"gitId":"-"},"content":" return BACKDOOR.removeAndRestoreSqlDataBundle(testData);"},{"lineNumber":239,"author":{"gitId":"-"},"content":" } catch (HttpRequestFailedException e) {"},{"lineNumber":240,"author":{"gitId":"-"},"content":" e.printStackTrace();"},{"lineNumber":241,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":242,"author":{"gitId":"-"},"content":" }"},{"lineNumber":243,"author":{"gitId":"-"},"content":" }"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":" FeedbackQuestionData getFeedbackQuestion(String courseId, String feedbackSessionName, int qnNumber) {"},{"lineNumber":246,"author":{"gitId":"-"},"content":" return BACKDOOR.getFeedbackQuestionData(courseId, feedbackSessionName, qnNumber);"},{"lineNumber":247,"author":{"gitId":"-"},"content":" }"},{"lineNumber":248,"author":{"gitId":"-"},"content":""},{"lineNumber":249,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":250,"author":{"gitId":"-"},"content":" protected FeedbackQuestionData getFeedbackQuestion(FeedbackQuestion fq) {"},{"lineNumber":251,"author":{"gitId":"-"},"content":" return getFeedbackQuestion(fq.getCourseId(), fq.getFeedbackSession().getName(), fq.getQuestionNumber());"},{"lineNumber":252,"author":{"gitId":"-"},"content":" }"},{"lineNumber":253,"author":{"gitId":"-"},"content":""},{"lineNumber":254,"author":{"gitId":"-"},"content":" FeedbackResponseData getFeedbackResponse(String questionId, String giver, String recipient) {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" return BACKDOOR.getFeedbackResponseData(questionId, giver, recipient);"},{"lineNumber":256,"author":{"gitId":"-"},"content":" }"},{"lineNumber":257,"author":{"gitId":"-"},"content":""},{"lineNumber":258,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":259,"author":{"gitId":"-"},"content":" protected FeedbackResponseData getFeedbackResponse(FeedbackResponse fr) {"},{"lineNumber":260,"author":{"gitId":"-"},"content":" return getFeedbackResponse(fr.getFeedbackQuestion().getId().toString(), fr.getGiver(), fr.getRecipient());"},{"lineNumber":261,"author":{"gitId":"-"},"content":" }"},{"lineNumber":262,"author":{"gitId":"-"},"content":""},{"lineNumber":263,"author":{"gitId":"-"},"content":" StudentData getStudent(String courseId, String studentEmailAddress) {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" return BACKDOOR.getStudentData(courseId, studentEmailAddress);"},{"lineNumber":265,"author":{"gitId":"-"},"content":" }"},{"lineNumber":266,"author":{"gitId":"-"},"content":""},{"lineNumber":267,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":268,"author":{"gitId":"-"},"content":" protected StudentData getStudent(Student student) {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" return getStudent(student.getCourseId(), student.getEmail());"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" FeedbackSessionData getFeedbackSession(String courseId, String feedbackSessionName) {"},{"lineNumber":273,"author":{"gitId":"-"},"content":" return BACKDOOR.getFeedbackSessionData(courseId, feedbackSessionName);"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":277,"author":{"gitId":"-"},"content":" protected FeedbackSessionData getFeedbackSession(FeedbackSession feedbackSession) {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" return getFeedbackSession(feedbackSession.getCourse().getId(), feedbackSession.getName());"},{"lineNumber":279,"author":{"gitId":"-"},"content":" }"},{"lineNumber":280,"author":{"gitId":"-"},"content":""},{"lineNumber":281,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":282,"author":{"gitId":"-"},"content":" * Checks if the feedback session is published."},{"lineNumber":283,"author":{"gitId":"-"},"content":" */"},{"lineNumber":284,"author":{"gitId":"-"},"content":" protected boolean isFeedbackSessionPublished(FeedbackSessionPublishStatus status) {"},{"lineNumber":285,"author":{"gitId":"-"},"content":" return status \u003d\u003d FeedbackSessionPublishStatus.PUBLISHED;"},{"lineNumber":286,"author":{"gitId":"-"},"content":" }"},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":" FeedbackSessionData getSoftDeletedSession(String feedbackSessionName, String instructorId) {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" return BACKDOOR.getSoftDeletedSessionData(feedbackSessionName, instructorId);"},{"lineNumber":290,"author":{"gitId":"-"},"content":" }"},{"lineNumber":291,"author":{"gitId":"-"},"content":""},{"lineNumber":292,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":293,"author":{"gitId":"domoberzin"},"content":" * Puts the documents in the database using BACKDOOR."},{"lineNumber":294,"author":{"gitId":"domoberzin"},"content":" * @param dataBundle the data to be put in the database"},{"lineNumber":295,"author":{"gitId":"domoberzin"},"content":" * @return the result of the operation"},{"lineNumber":296,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":297,"author":{"gitId":"domoberzin"},"content":" protected String putDocuments(SqlDataBundle dataBundle) {"},{"lineNumber":298,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":299,"author":{"gitId":"domoberzin"},"content":" return BACKDOOR.putSqlDocuments(dataBundle);"},{"lineNumber":300,"author":{"gitId":"domoberzin"},"content":" } catch (HttpRequestFailedException e) {"},{"lineNumber":301,"author":{"gitId":"domoberzin"},"content":" e.printStackTrace();"},{"lineNumber":302,"author":{"gitId":"domoberzin"},"content":" return null;"},{"lineNumber":303,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":304,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":305,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":14,"-":291}},{"path":"src/e2e/java/teammates/e2e/cases/sql/FeedbackMcqQuestionE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.e2e.cases.sql;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.stream.Collectors;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.questions.FeedbackMcqQuestionDetails;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.questions.FeedbackMcqResponseDetails;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import teammates.e2e.pageobjects.FeedbackSubmitPage;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.e2e.pageobjects.InstructorFeedbackEditPage;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link Const.WebPageURIs#INSTRUCTOR_SESSION_EDIT_PAGE},"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" * {@link Const.WebPageURIs#SESSION_SUBMISSION_PAGE}"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":" * specifically for MCQ questions."},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":"public class FeedbackMcqQuestionE2ETest extends BaseFeedbackQuestionE2ETest {"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":" protected void prepareTestData() {"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":" testData \u003d removeAndRestoreDataBundle(loadSqlDataBundle(\"/FeedbackMcqQuestionE2ESqlTest.json\"));"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" instructor \u003d testData.instructors.get(\"instructor\");"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" course \u003d testData.courses.get(\"course\");"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" feedbackSession \u003d testData.feedbackSessions.get(\"openSession\");"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" student \u003d testData.students.get(\"alice.tmms@FMcqQn.CS2104\");"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" public void testAll() {"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" testEditPage();"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" logout();"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" testSubmitPage();"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" protected void testEditPage() {"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" InstructorFeedbackEditPage feedbackEditPage \u003d loginToFeedbackEditPage();"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" ______TS(\"verify loaded question\");"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion loadedQuestion \u003d testData.feedbackQuestions.get(\"qn1ForFirstSession\");"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" FeedbackMcqQuestionDetails questionDetails \u003d (FeedbackMcqQuestionDetails) loadedQuestion"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" .getQuestionDetailsCopy();"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.verifyMcqQuestionDetails(1, questionDetails);"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" ______TS(\"add new question\");"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" // add new question exactly like loaded question"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" loadedQuestion.setQuestionNumber(2);"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.addMcqQuestion(loadedQuestion);"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.verifyMcqQuestionDetails(2, questionDetails);"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" verifyPresentInDatabase(loadedQuestion);"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" ______TS(\"copy question\");"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion copiedQuestion \u003d testData.feedbackQuestions.get(\"qn1ForSecondSession\");"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" questionDetails \u003d (FeedbackMcqQuestionDetails) copiedQuestion.getQuestionDetailsCopy();"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.copyQuestion(copiedQuestion.getCourseId(),"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" copiedQuestion.getQuestionDetailsCopy().getQuestionText());"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" copiedQuestion.setFeedbackSession(feedbackSession);"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" copiedQuestion.setQuestionNumber(3);"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.verifyMcqQuestionDetails(3, questionDetails);"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" verifyPresentInDatabase(copiedQuestion);"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" ______TS(\"edit question\");"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" questionDetails \u003d (FeedbackMcqQuestionDetails) loadedQuestion.getQuestionDetailsCopy();"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" questionDetails.setHasAssignedWeights(false);"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" questionDetails.setMcqWeights(new ArrayList\u003c\u003e());"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" questionDetails.setOtherEnabled(false);"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" questionDetails.setQuestionDropdownEnabled(false);"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" questionDetails.setMcqOtherWeight(0);"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" List\u003cString\u003e choices \u003d questionDetails.getMcqChoices();"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" choices.add(\"Edited choice\");"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" questionDetails.setMcqChoices(choices);"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" loadedQuestion \u003d testData.feedbackQuestions.get(\"qn1ForFirstSession\").makeDeepCopy(feedbackSession);"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":" loadedQuestion.setQuestionDetails(questionDetails);"},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.editMcqQuestion(2, questionDetails);"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.waitForPageToLoad();"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.verifyMcqQuestionDetails(2, questionDetails);"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":" verifyPresentInDatabase(loadedQuestion);"},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" protected void testSubmitPage() {"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":" FeedbackSubmitPage feedbackSubmitPage \u003d loginToFeedbackSubmitPage();"},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":" ______TS(\"verify loaded question\");"},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion question \u003d testData.feedbackQuestions.get(\"qn1ForFirstSession\");"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" feedbackSubmitPage.verifyMcqQuestion(1, \"\","},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" (FeedbackMcqQuestionDetails) question.getQuestionDetailsCopy());"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" ______TS(\"verify question with generated options\");"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" feedbackSubmitPage.verifyGeneratedMcqQuestion(3, \"\", getGeneratedStudentOptions());"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":" ______TS(\"submit response\");"},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" FeedbackResponse response \u003d getResponse(question, false, \"UI\");"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":" feedbackSubmitPage.fillMcqResponse(1, \"\", response);"},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" feedbackSubmitPage.clickSubmitQuestionButton(1);"},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" // verifyPresentInDatabase(response);"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" // ______TS(\"check previous response\");"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage \u003d getFeedbackSubmitPage();"},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage.verifyMcqResponse(1, \"\", response);"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":" // ______TS(\"edit response\");"},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" // response \u003d getResponse(questionId, true, \"This is the edited response.\");"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage.fillMcqResponse(1, \"\", response);"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage.clickSubmitQuestionButton(1);"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage \u003d getFeedbackSubmitPage();"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage.verifyMcqResponse(1, \"\", response);"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" // verifyPresentInDatabase(response);"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" private List\u003cString\u003e getGeneratedStudentOptions() {"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" return testData.students.values().stream()"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" .filter(s -\u003e s.getCourse().equals(student.getCourse()))"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" .map(s -\u003e s.getName() + \" (\" + s.getTeam().getName() + \")\")"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" .collect(Collectors.toList());"},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":" private FeedbackResponse getResponse(FeedbackQuestion feedbackQuestion, boolean isOther, String answer) {"},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":" FeedbackMcqResponseDetails details \u003d new FeedbackMcqResponseDetails();"},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" if (isOther) {"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" details.setOther(true);"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" details.setOtherFieldContent(answer);"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":" details.setAnswer(answer);"},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":" return FeedbackResponse.makeResponse(feedbackQuestion, student.getEmail(), null, instructor.getEmail(), null,"},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":" details);"},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":140}},{"path":"src/e2e/java/teammates/e2e/cases/sql/FeedbackMsqQuestionE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.e2e.cases.sql;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.Arrays;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import java.util.stream.Collectors;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.questions.FeedbackMsqQuestionDetails;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.questions.FeedbackMsqResponseDetails;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Const;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.e2e.pageobjects.FeedbackSubmitPage;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.e2e.pageobjects.InstructorFeedbackEditPage;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link Const.WebPageURIs#INSTRUCTOR_SESSION_EDIT_PAGE},"},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":" * {@link Const.WebPageURIs#SESSION_SUBMISSION_PAGE}"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" * specifically for msq questions."},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":"public class FeedbackMsqQuestionE2ETest extends BaseFeedbackQuestionE2ETest {"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" protected void prepareTestData() {"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" testData \u003d removeAndRestoreDataBundle(loadSqlDataBundle(\"/FeedbackMsqQuestionE2ESqlTest.json\"));"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" instructor \u003d testData.instructors.get(\"instructor\");"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" course \u003d testData.courses.get(\"course\");"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" feedbackSession \u003d testData.feedbackSessions.get(\"openSession\");"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" student \u003d testData.students.get(\"alice.tmms@FMsqQn.CS2104\");"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" public void testAll() {"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" testEditPage();"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" logout();"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" testSubmitPage();"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" protected void testEditPage() {"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" InstructorFeedbackEditPage feedbackEditPage \u003d loginToFeedbackEditPage();"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" ______TS(\"verify loaded question\");"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion loadedQuestion \u003d testData.feedbackQuestions.get(\"qn1ForFirstSession\")"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" .makeDeepCopy(feedbackSession);"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" FeedbackMsqQuestionDetails questionDetails \u003d (FeedbackMsqQuestionDetails) loadedQuestion"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" .getQuestionDetailsCopy();"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.verifyMsqQuestionDetails(1, questionDetails);"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" ______TS(\"add new question\");"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" // add new question exactly like loaded question"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" loadedQuestion.setQuestionNumber(2);"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.addMsqQuestion(loadedQuestion);"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.verifyMsqQuestionDetails(2, questionDetails);"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" verifyPresentInDatabase(loadedQuestion);"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" ______TS(\"copy question\");"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion copiedQuestion \u003d testData.feedbackQuestions.get(\"qn1ForSecondSession\");"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" questionDetails \u003d (FeedbackMsqQuestionDetails) copiedQuestion.getQuestionDetailsCopy();"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.copyQuestion(copiedQuestion.getCourseId(),"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" copiedQuestion.getQuestionDetailsCopy().getQuestionText());"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" copiedQuestion.setFeedbackSession(feedbackSession);"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" copiedQuestion.setQuestionNumber(3);"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.verifyMsqQuestionDetails(3, questionDetails);"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" verifyPresentInDatabase(copiedQuestion);"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" ______TS(\"edit question\");"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" questionDetails \u003d (FeedbackMsqQuestionDetails) loadedQuestion.getQuestionDetailsCopy();"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" questionDetails.setHasAssignedWeights(false);"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" questionDetails.setMsqWeights(new ArrayList\u003c\u003e());"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" questionDetails.setOtherEnabled(false);"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" questionDetails.setMsqOtherWeight(0);"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" questionDetails.setMaxSelectableChoices(Const.POINTS_NO_VALUE);"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" List\u003cString\u003e choices \u003d questionDetails.getMsqChoices();"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":" choices.add(\"Edited choice\");"},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" questionDetails.setMsqChoices(choices);"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" loadedQuestion.setQuestionDetails(questionDetails);"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.editMsqQuestion(2, questionDetails);"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.waitForPageToLoad();"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" feedbackEditPage.verifyMsqQuestionDetails(2, questionDetails);"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" verifyPresentInDatabase(loadedQuestion);"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" protected void testSubmitPage() {"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":" FeedbackSubmitPage feedbackSubmitPage \u003d loginToFeedbackSubmitPage();"},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" ______TS(\"verify loaded question\");"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion question \u003d testData.feedbackQuestions.get(\"qn1ForFirstSession\");"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" Student receiver \u003d testData.students.get(\"benny.tmms@FMsqQn.CS2104\");"},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" feedbackSubmitPage.verifyMsqQuestion(1, receiver.getName(),"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" (FeedbackMsqQuestionDetails) question.getQuestionDetailsCopy());"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":" ______TS(\"verify loaded question with generated options\");"},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion generatedQn \u003d testData.feedbackQuestions.get(\"qn1ForSecondSession\");"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":" feedbackSubmitPage.verifyGeneratedMsqQuestion(3, \"\","},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" (FeedbackMsqQuestionDetails) generatedQn.getQuestionDetailsCopy(), getGeneratedTeams());"},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" ______TS(\"submit response\");"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":" List\u003cString\u003e answers \u003d Arrays.asList(\"Leadership\", \"This is the other response.\");"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" FeedbackResponse response \u003d getResponse(question, receiver, answers.get(answers.size() - 1), answers);"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":" feedbackSubmitPage.fillMsqResponse(1, receiver.getName(), response);"},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" feedbackSubmitPage.clickSubmitQuestionButton(1);"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":" // TODO: uncomment when SubmitFeedbackResponse is working"},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" // verifyPresentInDatabase(response);"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" // ______TS(\"check previous response\");"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage \u003d getFeedbackSubmitPage();"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage.verifyMsqResponse(1, receiver.getName(), response);"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" // ______TS(\"edit response\");"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" // answers \u003d Arrays.asList(\"\");"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" // response \u003d getResponse(question, receiver, \"\", answers);"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage.fillMsqResponse(1, receiver.getName(), response);"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage.clickSubmitQuestionButton(1);"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage \u003d getFeedbackSubmitPage();"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" // feedbackSubmitPage.verifyMsqResponse(1, receiver.getName(), response);"},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" // verifyPresentInDatabase(response);"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":" private List\u003cString\u003e getGeneratedTeams() {"},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" return testData.students.values().stream()"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" .filter(s -\u003e s.getCourse().equals(student.getCourse()))"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" .map(s -\u003e s.getTeam().getName())"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":" .distinct()"},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":" .collect(Collectors.toList());"},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":" private FeedbackResponse getResponse(FeedbackQuestion feedbackQuestion, Student receiver, String other,"},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" List\u003cString\u003e answers) {"},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":" FeedbackMsqResponseDetails details \u003d new FeedbackMsqResponseDetails();"},{"lineNumber":141,"author":{"gitId":"dishenggg"},"content":" if (!other.isEmpty()) {"},{"lineNumber":142,"author":{"gitId":"dishenggg"},"content":" details.setOther(true);"},{"lineNumber":143,"author":{"gitId":"dishenggg"},"content":" details.setOtherFieldContent(other);"},{"lineNumber":144,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":145,"author":{"gitId":"dishenggg"},"content":" details.setAnswers(answers);"},{"lineNumber":146,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":" return FeedbackResponse.makeResponse(feedbackQuestion, student.getEmail(), student.getSection(),"},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":" receiver.getEmail(), receiver.getSection(), details);"},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":150}},{"path":"src/e2e/java/teammates/e2e/cases/sql/FeedbackNumScaleQuestionE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"marquestye"},"content":"package teammates.e2e.cases.sql;"},{"lineNumber":2,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":3,"author":{"gitId":"marquestye"},"content":"import org.testng.annotations.Test;"},{"lineNumber":4,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":5,"author":{"gitId":"marquestye"},"content":"import teammates.common.datatransfer.questions.FeedbackNumericalScaleQuestionDetails;"},{"lineNumber":6,"author":{"gitId":"marquestye"},"content":"import teammates.common.datatransfer.questions.FeedbackNumericalScaleResponseDetails;"},{"lineNumber":7,"author":{"gitId":"marquestye"},"content":"import teammates.e2e.pageobjects.FeedbackSubmitPage;"},{"lineNumber":8,"author":{"gitId":"marquestye"},"content":"import teammates.e2e.pageobjects.InstructorFeedbackEditPage;"},{"lineNumber":9,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":10,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":11,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":12,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":13,"author":{"gitId":"marquestye"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"marquestye"},"content":" * SUT: {@link Const.WebPageURIs#INSTRUCTOR_SESSION_EDIT_PAGE}, {@link Const.WebPageURIs#SESSION_SUBMISSION_PAGE}"},{"lineNumber":15,"author":{"gitId":"marquestye"},"content":" * specifically for NumScale questions."},{"lineNumber":16,"author":{"gitId":"marquestye"},"content":" */"},{"lineNumber":17,"author":{"gitId":"marquestye"},"content":"public class FeedbackNumScaleQuestionE2ETest extends BaseFeedbackQuestionE2ETest {"},{"lineNumber":18,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":19,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":20,"author":{"gitId":"marquestye"},"content":" protected void prepareTestData() {"},{"lineNumber":21,"author":{"gitId":"marquestye"},"content":" testData \u003d removeAndRestoreDataBundle(loadSqlDataBundle(\"/FeedbackNumScaleQuestionE2ESqlTest.json\"));"},{"lineNumber":22,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":23,"author":{"gitId":"marquestye"},"content":" instructor \u003d testData.instructors.get(\"instructor\");"},{"lineNumber":24,"author":{"gitId":"marquestye"},"content":" course \u003d testData.courses.get(\"course\");"},{"lineNumber":25,"author":{"gitId":"marquestye"},"content":" feedbackSession \u003d testData.feedbackSessions.get(\"openSession\");"},{"lineNumber":26,"author":{"gitId":"marquestye"},"content":" student \u003d testData.students.get(\"alice.tmms@FNumScaleQn.CS2104\");"},{"lineNumber":27,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":28,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":29,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":30,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":31,"author":{"gitId":"marquestye"},"content":" public void testAll() {"},{"lineNumber":32,"author":{"gitId":"marquestye"},"content":" testEditPage();"},{"lineNumber":33,"author":{"gitId":"marquestye"},"content":" logout();"},{"lineNumber":34,"author":{"gitId":"marquestye"},"content":" testSubmitPage();"},{"lineNumber":35,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":36,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":37,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"marquestye"},"content":" protected void testEditPage() {"},{"lineNumber":39,"author":{"gitId":"marquestye"},"content":" InstructorFeedbackEditPage feedbackEditPage \u003d loginToFeedbackEditPage();"},{"lineNumber":40,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":41,"author":{"gitId":"marquestye"},"content":" ______TS(\"verify loaded question\");"},{"lineNumber":42,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion loadedQuestion \u003d testData.feedbackQuestions.get(\"qn1ForFirstSession\");"},{"lineNumber":43,"author":{"gitId":"marquestye"},"content":" FeedbackNumericalScaleQuestionDetails questionDetails \u003d"},{"lineNumber":44,"author":{"gitId":"marquestye"},"content":" (FeedbackNumericalScaleQuestionDetails) loadedQuestion.getQuestionDetailsCopy();"},{"lineNumber":45,"author":{"gitId":"marquestye"},"content":" feedbackEditPage.verifyNumScaleQuestionDetails(1, questionDetails);"},{"lineNumber":46,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":47,"author":{"gitId":"marquestye"},"content":" ______TS(\"add new question\");"},{"lineNumber":48,"author":{"gitId":"marquestye"},"content":" // add new question exactly like loaded question"},{"lineNumber":49,"author":{"gitId":"marquestye"},"content":" loadedQuestion.setQuestionNumber(2);"},{"lineNumber":50,"author":{"gitId":"marquestye"},"content":" feedbackEditPage.addNumScaleQuestion(loadedQuestion);"},{"lineNumber":51,"author":{"gitId":"marquestye"},"content":" feedbackEditPage.waitUntilAnimationFinish();"},{"lineNumber":52,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":53,"author":{"gitId":"marquestye"},"content":" feedbackEditPage.verifyNumScaleQuestionDetails(2, questionDetails);"},{"lineNumber":54,"author":{"gitId":"marquestye"},"content":" verifyPresentInDatabase(loadedQuestion);"},{"lineNumber":55,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":56,"author":{"gitId":"marquestye"},"content":" ______TS(\"copy question\");"},{"lineNumber":57,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion copiedQuestion \u003d testData.feedbackQuestions.get(\"qn1ForSecondSession\");"},{"lineNumber":58,"author":{"gitId":"marquestye"},"content":" questionDetails \u003d (FeedbackNumericalScaleQuestionDetails) copiedQuestion.getQuestionDetailsCopy();"},{"lineNumber":59,"author":{"gitId":"marquestye"},"content":" feedbackEditPage.copyQuestion(copiedQuestion.getCourseId(),"},{"lineNumber":60,"author":{"gitId":"marquestye"},"content":" copiedQuestion.getQuestionDetailsCopy().getQuestionText());"},{"lineNumber":61,"author":{"gitId":"marquestye"},"content":" copiedQuestion.setQuestionNumber(3);"},{"lineNumber":62,"author":{"gitId":"marquestye"},"content":" copiedQuestion.setFeedbackSession(feedbackSession);"},{"lineNumber":63,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":64,"author":{"gitId":"marquestye"},"content":" feedbackEditPage.verifyNumScaleQuestionDetails(3, questionDetails);"},{"lineNumber":65,"author":{"gitId":"marquestye"},"content":" verifyPresentInDatabase(copiedQuestion);"},{"lineNumber":66,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":67,"author":{"gitId":"marquestye"},"content":" ______TS(\"edit question\");"},{"lineNumber":68,"author":{"gitId":"marquestye"},"content":" questionDetails \u003d (FeedbackNumericalScaleQuestionDetails) loadedQuestion.getQuestionDetailsCopy();"},{"lineNumber":69,"author":{"gitId":"marquestye"},"content":" FeedbackNumericalScaleQuestionDetails newQuestionDetails \u003d"},{"lineNumber":70,"author":{"gitId":"marquestye"},"content":" (FeedbackNumericalScaleQuestionDetails) questionDetails.getDeepCopy();"},{"lineNumber":71,"author":{"gitId":"marquestye"},"content":" newQuestionDetails.setMinScale(0);"},{"lineNumber":72,"author":{"gitId":"marquestye"},"content":" newQuestionDetails.setStep(1);"},{"lineNumber":73,"author":{"gitId":"marquestye"},"content":" newQuestionDetails.setMaxScale(100);"},{"lineNumber":74,"author":{"gitId":"marquestye"},"content":" loadedQuestion.setQuestionDetails(newQuestionDetails);"},{"lineNumber":75,"author":{"gitId":"marquestye"},"content":" feedbackEditPage.editNumScaleQuestion(2, newQuestionDetails);"},{"lineNumber":76,"author":{"gitId":"marquestye"},"content":" feedbackEditPage.waitForPageToLoad();"},{"lineNumber":77,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":78,"author":{"gitId":"marquestye"},"content":" feedbackEditPage.verifyNumScaleQuestionDetails(2, newQuestionDetails);"},{"lineNumber":79,"author":{"gitId":"marquestye"},"content":" verifyPresentInDatabase(loadedQuestion);"},{"lineNumber":80,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":81,"author":{"gitId":"marquestye"},"content":" // reset question details to original"},{"lineNumber":82,"author":{"gitId":"marquestye"},"content":" loadedQuestion.setQuestionDetails(questionDetails);"},{"lineNumber":83,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":84,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":85,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":86,"author":{"gitId":"marquestye"},"content":" protected void testSubmitPage() {"},{"lineNumber":87,"author":{"gitId":"marquestye"},"content":" FeedbackSubmitPage feedbackSubmitPage \u003d loginToFeedbackSubmitPage();"},{"lineNumber":88,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":89,"author":{"gitId":"marquestye"},"content":" ______TS(\"verify loaded question\");"},{"lineNumber":90,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion question \u003d testData.feedbackQuestions.get(\"qn1ForFirstSession\");"},{"lineNumber":91,"author":{"gitId":"marquestye"},"content":" Student receiver \u003d testData.students.get(\"benny.tmms@FNumScaleQn.CS2104\");"},{"lineNumber":92,"author":{"gitId":"marquestye"},"content":" feedbackSubmitPage.verifyNumScaleQuestion(1, receiver.getTeamName(),"},{"lineNumber":93,"author":{"gitId":"marquestye"},"content":" (FeedbackNumericalScaleQuestionDetails) question.getQuestionDetailsCopy());"},{"lineNumber":94,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":95,"author":{"gitId":"marquestye"},"content":" ______TS(\"submit response\");"},{"lineNumber":96,"author":{"gitId":"marquestye"},"content":" FeedbackResponse response \u003d getResponse(question, receiver, 5.4);"},{"lineNumber":97,"author":{"gitId":"marquestye"},"content":" feedbackSubmitPage.fillNumScaleResponse(1, receiver.getTeamName(), response);"},{"lineNumber":98,"author":{"gitId":"marquestye"},"content":" feedbackSubmitPage.clickSubmitQuestionButton(1);"},{"lineNumber":99,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":100,"author":{"gitId":"marquestye"},"content":" // TODO: uncomment when SubmitFeedbackResponse is working"},{"lineNumber":101,"author":{"gitId":"marquestye"},"content":" // verifyPresentInDatabase(response);"},{"lineNumber":102,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":103,"author":{"gitId":"marquestye"},"content":" // ______TS(\"check previous response\");"},{"lineNumber":104,"author":{"gitId":"marquestye"},"content":" // feedbackSubmitPage \u003d getFeedbackSubmitPage();"},{"lineNumber":105,"author":{"gitId":"marquestye"},"content":" // feedbackSubmitPage.verifyNumScaleResponse(1, receiver.getTeamName(), response);"},{"lineNumber":106,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":107,"author":{"gitId":"marquestye"},"content":" // ______TS(\"edit response\");"},{"lineNumber":108,"author":{"gitId":"marquestye"},"content":" // response \u003d getResponse(question, receiver, 10.0);"},{"lineNumber":109,"author":{"gitId":"marquestye"},"content":" // feedbackSubmitPage.fillNumScaleResponse(1, receiver.getTeamName(), response);"},{"lineNumber":110,"author":{"gitId":"marquestye"},"content":" // feedbackSubmitPage.clickSubmitQuestionButton(1);"},{"lineNumber":111,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":112,"author":{"gitId":"marquestye"},"content":" // feedbackSubmitPage \u003d getFeedbackSubmitPage();"},{"lineNumber":113,"author":{"gitId":"marquestye"},"content":" // feedbackSubmitPage.verifyNumScaleResponse(1, receiver.getTeamName(), response);"},{"lineNumber":114,"author":{"gitId":"marquestye"},"content":" // verifyPresentInDatabase(response);"},{"lineNumber":115,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":116,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":117,"author":{"gitId":"marquestye"},"content":" private FeedbackResponse getResponse(FeedbackQuestion feedbackQuestion, Student receiver, Double answer) {"},{"lineNumber":118,"author":{"gitId":"marquestye"},"content":" FeedbackNumericalScaleResponseDetails details \u003d new FeedbackNumericalScaleResponseDetails();"},{"lineNumber":119,"author":{"gitId":"marquestye"},"content":" details.setAnswer(answer);"},{"lineNumber":120,"author":{"gitId":"marquestye"},"content":" return FeedbackResponse.makeResponse("},{"lineNumber":121,"author":{"gitId":"marquestye"},"content":" feedbackQuestion, student.getEmail(), null, receiver.getTeamName(), null, details);"},{"lineNumber":122,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":123,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":124,"author":{"gitId":"marquestye"},"content":"}"}],"authorContributionMap":{"marquestye":124}},{"path":"src/e2e/java/teammates/e2e/cases/sql/FeedbackRankOptionQuestionE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"mingyuanc"},"content":"package teammates.e2e.cases.sql;"},{"lineNumber":2,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":3,"author":{"gitId":"mingyuanc"},"content":"import java.util.Arrays;"},{"lineNumber":4,"author":{"gitId":"mingyuanc"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":6,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":8,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.datatransfer.questions.FeedbackRankOptionsQuestionDetails;"},{"lineNumber":9,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.datatransfer.questions.FeedbackRankOptionsResponseDetails;"},{"lineNumber":10,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.datatransfer.questions.FeedbackRankQuestionDetails;"},{"lineNumber":11,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"mingyuanc"},"content":"import teammates.e2e.pageobjects.FeedbackSubmitPage;"},{"lineNumber":13,"author":{"gitId":"mingyuanc"},"content":"import teammates.e2e.pageobjects.InstructorFeedbackEditPage;"},{"lineNumber":14,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":15,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":16,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":17,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":18,"author":{"gitId":"mingyuanc"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"mingyuanc"},"content":" * SUT: {@link Const.WebPageURIs#INSTRUCTOR_SESSION_EDIT_PAGE},"},{"lineNumber":20,"author":{"gitId":"mingyuanc"},"content":" * {@link Const.WebPageURIs#SESSION_SUBMISSION_PAGE}"},{"lineNumber":21,"author":{"gitId":"mingyuanc"},"content":" * specifically for RankOption questions."},{"lineNumber":22,"author":{"gitId":"mingyuanc"},"content":" */"},{"lineNumber":23,"author":{"gitId":"mingyuanc"},"content":"public class FeedbackRankOptionQuestionE2ETest extends BaseFeedbackQuestionE2ETest {"},{"lineNumber":24,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":25,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":26,"author":{"gitId":"mingyuanc"},"content":" protected void prepareTestData() {"},{"lineNumber":27,"author":{"gitId":"mingyuanc"},"content":" testData \u003d removeAndRestoreDataBundle(loadSqlDataBundle(\"/FeedbackRankOptionQuestionE2ESqlTest.json\"));"},{"lineNumber":28,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":29,"author":{"gitId":"mingyuanc"},"content":" instructor \u003d testData.instructors.get(\"instructor\");"},{"lineNumber":30,"author":{"gitId":"mingyuanc"},"content":" course \u003d testData.courses.get(\"course\");"},{"lineNumber":31,"author":{"gitId":"mingyuanc"},"content":" feedbackSession \u003d testData.feedbackSessions.get(\"openSession\");"},{"lineNumber":32,"author":{"gitId":"mingyuanc"},"content":" student \u003d testData.students.get(\"alice.tmms@FRankOptQn.CS2104\");"},{"lineNumber":33,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":34,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":35,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":36,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":37,"author":{"gitId":"mingyuanc"},"content":" public void testAll() {"},{"lineNumber":38,"author":{"gitId":"mingyuanc"},"content":" testEditPage();"},{"lineNumber":39,"author":{"gitId":"mingyuanc"},"content":" logout();"},{"lineNumber":40,"author":{"gitId":"mingyuanc"},"content":" testSubmitPage();"},{"lineNumber":41,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":42,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":43,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":44,"author":{"gitId":"mingyuanc"},"content":" protected void testEditPage() {"},{"lineNumber":45,"author":{"gitId":"mingyuanc"},"content":" InstructorFeedbackEditPage feedbackEditPage \u003d loginToFeedbackEditPage();"},{"lineNumber":46,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":47,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"verify loaded question\");"},{"lineNumber":48,"author":{"gitId":"mingyuanc"},"content":" FeedbackQuestion loadedQuestion \u003d testData.feedbackQuestions.get(\"qn1ForFirstSession\")"},{"lineNumber":49,"author":{"gitId":"mingyuanc"},"content":" .makeDeepCopy(feedbackSession);"},{"lineNumber":50,"author":{"gitId":"mingyuanc"},"content":" FeedbackRankOptionsQuestionDetails questionDetails \u003d (FeedbackRankOptionsQuestionDetails) loadedQuestion"},{"lineNumber":51,"author":{"gitId":"mingyuanc"},"content":" .getQuestionDetailsCopy();"},{"lineNumber":52,"author":{"gitId":"mingyuanc"},"content":" feedbackEditPage.verifyRankQuestionDetails(1, questionDetails);"},{"lineNumber":53,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":54,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"add new question\");"},{"lineNumber":55,"author":{"gitId":"mingyuanc"},"content":" // add new question exactly like loaded question"},{"lineNumber":56,"author":{"gitId":"mingyuanc"},"content":" loadedQuestion.setQuestionNumber(2);"},{"lineNumber":57,"author":{"gitId":"mingyuanc"},"content":" feedbackEditPage.addRankOptionsQuestion(loadedQuestion);"},{"lineNumber":58,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":59,"author":{"gitId":"mingyuanc"},"content":" feedbackEditPage.verifyRankQuestionDetails(2, questionDetails);"},{"lineNumber":60,"author":{"gitId":"mingyuanc"},"content":" verifyPresentInDatabase(loadedQuestion);"},{"lineNumber":61,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":62,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"copy question\");"},{"lineNumber":63,"author":{"gitId":"mingyuanc"},"content":" FeedbackQuestion copiedQuestion \u003d testData.feedbackQuestions.get(\"qn1ForSecondSession\");"},{"lineNumber":64,"author":{"gitId":"mingyuanc"},"content":" questionDetails \u003d (FeedbackRankOptionsQuestionDetails) copiedQuestion.getQuestionDetailsCopy();"},{"lineNumber":65,"author":{"gitId":"mingyuanc"},"content":" feedbackEditPage.copyQuestion(copiedQuestion.getCourseId(),"},{"lineNumber":66,"author":{"gitId":"mingyuanc"},"content":" copiedQuestion.getQuestionDetailsCopy().getQuestionText());"},{"lineNumber":67,"author":{"gitId":"mingyuanc"},"content":" copiedQuestion.setFeedbackSession(feedbackSession);"},{"lineNumber":68,"author":{"gitId":"mingyuanc"},"content":" copiedQuestion.setQuestionNumber(3);"},{"lineNumber":69,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":70,"author":{"gitId":"mingyuanc"},"content":" feedbackEditPage.verifyRankQuestionDetails(3, questionDetails);"},{"lineNumber":71,"author":{"gitId":"mingyuanc"},"content":" verifyPresentInDatabase(copiedQuestion);"},{"lineNumber":72,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":73,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"edit question\");"},{"lineNumber":74,"author":{"gitId":"mingyuanc"},"content":" questionDetails \u003d (FeedbackRankOptionsQuestionDetails) loadedQuestion.getQuestionDetailsCopy();"},{"lineNumber":75,"author":{"gitId":"mingyuanc"},"content":" List\u003cString\u003e options \u003d questionDetails.getOptions();"},{"lineNumber":76,"author":{"gitId":"mingyuanc"},"content":" options.remove(0);"},{"lineNumber":77,"author":{"gitId":"mingyuanc"},"content":" options.set(1, \"Edited option.\");"},{"lineNumber":78,"author":{"gitId":"mingyuanc"},"content":" questionDetails.setOptions(options);"},{"lineNumber":79,"author":{"gitId":"mingyuanc"},"content":" questionDetails.setAreDuplicatesAllowed(true);"},{"lineNumber":80,"author":{"gitId":"mingyuanc"},"content":" questionDetails.setMaxOptionsToBeRanked(Const.POINTS_NO_VALUE);"},{"lineNumber":81,"author":{"gitId":"mingyuanc"},"content":" questionDetails.setMinOptionsToBeRanked(1);"},{"lineNumber":82,"author":{"gitId":"mingyuanc"},"content":" loadedQuestion.setQuestionDetails(questionDetails);"},{"lineNumber":83,"author":{"gitId":"mingyuanc"},"content":" feedbackEditPage.editRankQuestion(2, questionDetails);"},{"lineNumber":84,"author":{"gitId":"mingyuanc"},"content":" feedbackEditPage.waitForPageToLoad();"},{"lineNumber":85,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":86,"author":{"gitId":"mingyuanc"},"content":" feedbackEditPage.verifyRankQuestionDetails(2, questionDetails);"},{"lineNumber":87,"author":{"gitId":"mingyuanc"},"content":" verifyPresentInDatabase(loadedQuestion);"},{"lineNumber":88,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":89,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":90,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":91,"author":{"gitId":"mingyuanc"},"content":" protected void testSubmitPage() {"},{"lineNumber":92,"author":{"gitId":"mingyuanc"},"content":" FeedbackSubmitPage feedbackSubmitPage \u003d loginToFeedbackSubmitPage();"},{"lineNumber":93,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":94,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"verify loaded question\");"},{"lineNumber":95,"author":{"gitId":"mingyuanc"},"content":" FeedbackQuestion question \u003d testData.feedbackQuestions.get(\"qn1ForFirstSession\");"},{"lineNumber":96,"author":{"gitId":"mingyuanc"},"content":" Student receiver \u003d testData.students.get(\"benny.tmms@FRankOptQn.CS2104\");"},{"lineNumber":97,"author":{"gitId":"mingyuanc"},"content":" feedbackSubmitPage.verifyRankQuestion(1, receiver.getName(),"},{"lineNumber":98,"author":{"gitId":"mingyuanc"},"content":" (FeedbackRankQuestionDetails) question.getQuestionDetailsCopy());"},{"lineNumber":99,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":100,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"submit response\");"},{"lineNumber":101,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponse response \u003d getResponse(question, receiver, Arrays.asList(2, 1, 3,"},{"lineNumber":102,"author":{"gitId":"mingyuanc"},"content":" Const.POINTS_NOT_SUBMITTED));"},{"lineNumber":103,"author":{"gitId":"mingyuanc"},"content":" feedbackSubmitPage.fillRankOptionResponse(1, receiver.getName(), response);"},{"lineNumber":104,"author":{"gitId":"mingyuanc"},"content":" feedbackSubmitPage.clickSubmitQuestionButton(1);"},{"lineNumber":105,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":106,"author":{"gitId":"mingyuanc"},"content":" // verifyPresentInDatabase(response);"},{"lineNumber":107,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":108,"author":{"gitId":"mingyuanc"},"content":" // ______TS(\"check previous response\");"},{"lineNumber":109,"author":{"gitId":"mingyuanc"},"content":" // feedbackSubmitPage \u003d getFeedbackSubmitPage();"},{"lineNumber":110,"author":{"gitId":"mingyuanc"},"content":" // feedbackSubmitPage.verifyRankOptionResponse(1, receiver.getName(), response);"},{"lineNumber":111,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":112,"author":{"gitId":"mingyuanc"},"content":" // ______TS(\"edit response\");"},{"lineNumber":113,"author":{"gitId":"mingyuanc"},"content":" // response \u003d getResponse(questionId, receiver,"},{"lineNumber":114,"author":{"gitId":"mingyuanc"},"content":" // Arrays.asList(Const.POINTS_NOT_SUBMITTED, 1, 3, 2));"},{"lineNumber":115,"author":{"gitId":"mingyuanc"},"content":" // feedbackSubmitPage.fillRankOptionResponse(1, receiver.getName(), response);"},{"lineNumber":116,"author":{"gitId":"mingyuanc"},"content":" // feedbackSubmitPage.clickSubmitQuestionButton(1);"},{"lineNumber":117,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":118,"author":{"gitId":"mingyuanc"},"content":" // feedbackSubmitPage \u003d getFeedbackSubmitPage();"},{"lineNumber":119,"author":{"gitId":"mingyuanc"},"content":" // feedbackSubmitPage.verifyRankOptionResponse(1, receiver.getName(), response);"},{"lineNumber":120,"author":{"gitId":"mingyuanc"},"content":" // verifyPresentInDatabase(response);"},{"lineNumber":121,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":122,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":123,"author":{"gitId":"mingyuanc"},"content":" private FeedbackResponse getResponse(FeedbackQuestion question, Student receiver, List\u003cInteger\u003e answers) {"},{"lineNumber":124,"author":{"gitId":"mingyuanc"},"content":" FeedbackRankOptionsResponseDetails details \u003d new FeedbackRankOptionsResponseDetails();"},{"lineNumber":125,"author":{"gitId":"mingyuanc"},"content":" details.setAnswers(answers);"},{"lineNumber":126,"author":{"gitId":"mingyuanc"},"content":" return FeedbackResponse.makeResponse(question, student.getEmail(), null, receiver.getEmail(), null, details);"},{"lineNumber":127,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":128,"author":{"gitId":"mingyuanc"},"content":"}"}],"authorContributionMap":{"mingyuanc":128}},{"path":"src/e2e/java/teammates/e2e/cases/sql/InstructorNotificationsPageE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"yuanxi1"},"content":"package teammates.e2e.cases.sql;"},{"lineNumber":2,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":3,"author":{"gitId":"yuanxi1"},"content":"import java.util.Set;"},{"lineNumber":4,"author":{"gitId":"yuanxi1"},"content":"import java.util.stream.Collectors;"},{"lineNumber":5,"author":{"gitId":"yuanxi1"},"content":"import java.util.stream.Stream;"},{"lineNumber":6,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":7,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":8,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.Test;"},{"lineNumber":9,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":10,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":11,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"yuanxi1"},"content":"import teammates.e2e.pageobjects.InstructorNotificationsPage;"},{"lineNumber":13,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":14,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":15,"author":{"gitId":"yuanxi1"},"content":"import teammates.ui.output.AccountData;"},{"lineNumber":16,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":17,"author":{"gitId":"yuanxi1"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"yuanxi1"},"content":" * SUT: {@link Const.WebPageURIs#INSTRUCTOR_NOTIFICATIONS_PAGE}."},{"lineNumber":19,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":20,"author":{"gitId":"yuanxi1"},"content":"public class InstructorNotificationsPageE2ETest extends BaseE2ETestCase {"},{"lineNumber":21,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":22,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":23,"author":{"gitId":"yuanxi1"},"content":" protected void prepareTestData() {"},{"lineNumber":24,"author":{"gitId":"yuanxi1"},"content":" testData \u003d loadSqlDataBundle(\"/InstructorNotificationsPageE2ESqlTest.json\");"},{"lineNumber":25,"author":{"gitId":"yuanxi1"},"content":" removeAndRestoreDataBundle(testData);"},{"lineNumber":26,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":27,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":28,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":29,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":30,"author":{"gitId":"yuanxi1"},"content":" protected void testAll() {"},{"lineNumber":31,"author":{"gitId":"yuanxi1"},"content":" Account account \u003d testData.accounts.get(\"INotifs.instr\");"},{"lineNumber":32,"author":{"gitId":"yuanxi1"},"content":" AppUrl notificationsPageUrl \u003d createFrontendUrl(Const.WebPageURIs.INSTRUCTOR_NOTIFICATIONS_PAGE);"},{"lineNumber":33,"author":{"gitId":"yuanxi1"},"content":" InstructorNotificationsPage notificationsPage \u003d loginToPage(notificationsPageUrl, InstructorNotificationsPage.class,"},{"lineNumber":34,"author":{"gitId":"yuanxi1"},"content":" account.getGoogleId());"},{"lineNumber":35,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":36,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"verify that only active notifications with correct target user are shown\");"},{"lineNumber":37,"author":{"gitId":"yuanxi1"},"content":" Notification[] notShownNotifications \u003d {"},{"lineNumber":38,"author":{"gitId":"yuanxi1"},"content":" testData.notifications.get(\"notification2\"),"},{"lineNumber":39,"author":{"gitId":"yuanxi1"},"content":" testData.notifications.get(\"expiredNotification1\"),"},{"lineNumber":40,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":41,"author":{"gitId":"yuanxi1"},"content":" Notification[] shownNotifications \u003d {"},{"lineNumber":42,"author":{"gitId":"yuanxi1"},"content":" testData.notifications.get(\"notification1\"),"},{"lineNumber":43,"author":{"gitId":"yuanxi1"},"content":" testData.notifications.get(\"notification3\"),"},{"lineNumber":44,"author":{"gitId":"yuanxi1"},"content":" testData.notifications.get(\"notification4\"),"},{"lineNumber":45,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":46,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":47,"author":{"gitId":"yuanxi1"},"content":" Notification[] readNotifications \u003d {"},{"lineNumber":48,"author":{"gitId":"yuanxi1"},"content":" testData.notifications.get(\"notification4\"),"},{"lineNumber":49,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":50,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":51,"author":{"gitId":"yuanxi1"},"content":" Set\u003cString\u003e readNotificationsIds \u003d Stream.of(readNotifications)"},{"lineNumber":52,"author":{"gitId":"yuanxi1"},"content":" .map(readNotification -\u003e readNotification.getId().toString())"},{"lineNumber":53,"author":{"gitId":"yuanxi1"},"content":" .collect(Collectors.toSet());"},{"lineNumber":54,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":55,"author":{"gitId":"yuanxi1"},"content":" notificationsPage.verifyNotShownNotifications(notShownNotifications);"},{"lineNumber":56,"author":{"gitId":"yuanxi1"},"content":" notificationsPage.verifyShownNotifications(shownNotifications, readNotificationsIds);"},{"lineNumber":57,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":58,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"mark notification as read\");"},{"lineNumber":59,"author":{"gitId":"yuanxi1"},"content":" Notification notificationToMarkAsRead \u003d testData.notifications.get(\"notification3\");"},{"lineNumber":60,"author":{"gitId":"yuanxi1"},"content":" notificationsPage.markNotificationAsRead(notificationToMarkAsRead);"},{"lineNumber":61,"author":{"gitId":"yuanxi1"},"content":" notificationsPage.verifyStatusMessage(\"Notification marked as read.\");"},{"lineNumber":62,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":63,"author":{"gitId":"yuanxi1"},"content":" // Verify that account\u0027s readNotifications attribute is updated"},{"lineNumber":64,"author":{"gitId":"yuanxi1"},"content":" AccountData accountFromDb \u003d BACKDOOR.getAccountData(account.getGoogleId());"},{"lineNumber":65,"author":{"gitId":"yuanxi1"},"content":" assertTrue(accountFromDb.getReadNotifications().containsKey(notificationToMarkAsRead.getId().toString()));"},{"lineNumber":66,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":67,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"notification banner is not visible\");"},{"lineNumber":68,"author":{"gitId":"yuanxi1"},"content":" assertFalse(notificationsPage.isBannerVisible());"},{"lineNumber":69,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":70,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":71,"author":{"gitId":"yuanxi1"},"content":" @AfterClass"},{"lineNumber":72,"author":{"gitId":"yuanxi1"},"content":" public void classTeardown() {"},{"lineNumber":73,"author":{"gitId":"yuanxi1"},"content":" for (Notification notification : testData.notifications.values()) {"},{"lineNumber":74,"author":{"gitId":"yuanxi1"},"content":" BACKDOOR.deleteNotification(notification.getId());"},{"lineNumber":75,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":76,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":77,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":78,"author":{"gitId":"yuanxi1"},"content":"}"}],"authorContributionMap":{"yuanxi1":78}},{"path":"src/e2e/java/teammates/e2e/cases/sql/RequestPageE2ETest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.e2e.cases.sql;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.AppUrl;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Const;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.EmailType;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import teammates.e2e.pageobjects.RequestPage;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import teammates.e2e.util.TestProperties;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link Const.WebPageURIs#ACCOUNT_REQUEST_PAGE}."},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"public class RequestPageE2ETest extends BaseE2ETestCase {"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":" protected void prepareTestData() {"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" // No test data needed"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" protected void testAll() {"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":" String name \u003d \"arf-test-name\";"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":" String institution \u003d \"arf-test-institution\";"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" String country \u003d \"arf-test-country\";"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" String email \u003d TestProperties.TEST_EMAIL;"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" String comments \u003d \"arf-test-comments\";"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" AppUrl url \u003d createFrontendUrl(Const.WebPageURIs.ACCOUNT_REQUEST_PAGE);"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" RequestPage requestPage \u003d getNewPageInstance(url, RequestPage.class);"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" ______TS(\"verify submission with comments\");"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" requestPage.clickAmInstructorButton();"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" requestPage.fillForm(name, institution, country, email, comments);"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" requestPage.clickSubmitFormButton();"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" requestPage.verifySubmittedInfo(name, institution, country, email, comments);"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" String expectedEmailSubject \u003d EmailType.NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT.toString();"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" verifyEmailSent(email, expectedEmailSubject);"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" ______TS(\"verify submission without comments\");"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" requestPage \u003d getNewPageInstance(url, RequestPage.class);"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" requestPage.clickAmInstructorButton();"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" requestPage.fillForm(name, institution, country, email, \"\");"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" requestPage.clickSubmitFormButton();"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" requestPage.verifySubmittedInfo(name, institution, country, email, \"\");"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" expectedEmailSubject \u003d EmailType.NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT.toString();"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" verifyEmailSent(email, expectedEmailSubject);"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":52}},{"path":"src/e2e/java/teammates/e2e/pageobjects/AdminHomePage.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.pageobjects;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import static org.junit.Assert.assertNotNull;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.openqa.selenium.By;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.openqa.selenium.WebElement;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.openqa.selenium.support.FindBy;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.test.ThreadHelper;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"-"},"content":" * Represents the admin home page of the website."},{"lineNumber":15,"author":{"gitId":"-"},"content":" */"},{"lineNumber":16,"author":{"gitId":"-"},"content":"public class AdminHomePage extends AppPage {"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" private static final int ACCOUNT_REQUEST_COL_NAME \u003d 1;"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" private static final int ACCOUNT_REQUEST_COL_EMAIL \u003d 2;"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" private static final int ACCOUNT_REQUEST_COL_INSTITUTE \u003d 4;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"instructor-details-single-line\")"},{"lineNumber":22,"author":{"gitId":"-"},"content":" private WebElement detailsSingleLineTextBox;"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" @FindBy (id \u003d \"instructor-name\")"},{"lineNumber":25,"author":{"gitId":"-"},"content":" private WebElement nameTextBox;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @FindBy (id \u003d \"instructor-email\")"},{"lineNumber":28,"author":{"gitId":"-"},"content":" private WebElement emailTextBox;"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" @FindBy (id \u003d \"instructor-institution\")"},{"lineNumber":31,"author":{"gitId":"-"},"content":" private WebElement institutionTextBox;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" @FindBy (id \u003d \"add-instructor\")"},{"lineNumber":34,"author":{"gitId":"-"},"content":" private WebElement submitButton;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" @FindBy (id \u003d \"add-instructor-single-line\")"},{"lineNumber":37,"author":{"gitId":"-"},"content":" private WebElement submitButtonDetailsSingleLineForm;"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" @FindBy (id \u003d \"add-all-instructors\")"},{"lineNumber":40,"author":{"gitId":"-"},"content":" private WebElement addAllInstructorsButton;"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" public AdminHomePage(Browser browser) {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" super(browser);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" }"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":47,"author":{"gitId":"-"},"content":" protected boolean containsExpectedPageContents() {"},{"lineNumber":48,"author":{"gitId":"-"},"content":" return getPageSource().contains(\"Add New Instructor\u003c/h1\u003e\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" public void queueInstructorForAdding(String name, String email, String institute) {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" if (name !\u003d null) {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" fillTextBox(nameTextBox, name);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" }"},{"lineNumber":55,"author":{"gitId":"-"},"content":" if (email !\u003d null) {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" fillTextBox(emailTextBox, email);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":" if (institute !\u003d null) {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" fillTextBox(institutionTextBox, institute);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" click(submitButton);"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" public void queueInstructorForAdding(String instructorDetails) {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" if (instructorDetails !\u003d null) {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" fillTextBox(detailsSingleLineTextBox, instructorDetails);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" }"},{"lineNumber":69,"author":{"gitId":"-"},"content":" click(submitButtonDetailsSingleLineForm);"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" public void addAllInstructors() {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" click(addAllInstructorsButton);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" waitForElementToBeClickable(addAllInstructorsButton);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" }"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" public String getMessageForInstructor(int i) {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" By by \u003d By.id(\"message-instructor-\" + i);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" waitForElementVisibility(by);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" WebElement element \u003d browser.driver.findElement(by);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" if (element \u003d\u003d null) {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":83,"author":{"gitId":"-"},"content":" }"},{"lineNumber":84,"author":{"gitId":"-"},"content":" return element.getText();"},{"lineNumber":85,"author":{"gitId":"-"},"content":" }"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" public void clickMoreInfoButtonForRegisteredInstructor(int i) {"},{"lineNumber":88,"author":{"gitId":"-"},"content":" By by \u003d By.id(\"instructor-\" + i + \"-registered-info-button\");"},{"lineNumber":89,"author":{"gitId":"-"},"content":" waitForElementVisibility(by);"},{"lineNumber":90,"author":{"gitId":"-"},"content":" WebElement element \u003d browser.driver.findElement(by);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" click(element);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" waitForElementVisibility(By.id(\"reset-account-request-link\"));"},{"lineNumber":93,"author":{"gitId":"-"},"content":" }"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" public void clickResetAccountRequestLink() {"},{"lineNumber":96,"author":{"gitId":"-"},"content":" By by \u003d By.id(\"reset-account-request-link\");"},{"lineNumber":97,"author":{"gitId":"-"},"content":" WebElement element \u003d browser.driver.findElement(by);"},{"lineNumber":98,"author":{"gitId":"-"},"content":" click(element);"},{"lineNumber":99,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(1000); // Modals are stacked, wait briefly to ensure confirmation modal is shown"},{"lineNumber":100,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e okButtons \u003d browser.driver.findElements(By.className(\"modal-btn-ok\"));"},{"lineNumber":101,"author":{"gitId":"-"},"content":" clickDismissModalButtonAndWaitForModalHidden(okButtons.get(1)); // Second modal is confirmation modal"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" public String removeSpanFromText(String text) {"},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" return text.replace(\"\u003cspan class\u003d\\\"highlighted-text\\\"\u003e\", \"\").replace(\"\u003c/span\u003e\", \"\");"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" public WebElement getAccountRequestRow(String name, String email, String institute) {"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" List\u003cWebElement\u003e rows \u003d browser.driver.findElements(By.cssSelector(\"tm-account-request-table tbody tr\"));"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" for (WebElement row : rows) {"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" List\u003cWebElement\u003e columns \u003d row.findElements(By.tagName(\"td\"));"},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" if (removeSpanFromText(columns.get(ACCOUNT_REQUEST_COL_NAME - 1)"},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" .getAttribute(\"innerHTML\")).contains(name)"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" \u0026\u0026 removeSpanFromText(columns.get(ACCOUNT_REQUEST_COL_EMAIL - 1)"},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" .getAttribute(\"innerHTML\")).contains(email)"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" \u0026\u0026 removeSpanFromText(columns.get(ACCOUNT_REQUEST_COL_INSTITUTE - 1)"},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":" .getAttribute(\"innerHTML\")).contains(institute)) {"},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":" return row;"},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":" return null;"},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" public void verifyInstructorInAccountRequestTable(String name, String email, String institute) {"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" WebElement row \u003d getAccountRequestRow(name, email, institute);"},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" assertNotNull(row);"},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":30,"-":98}},{"path":"src/e2e/java/teammates/e2e/pageobjects/AdminNotificationsPage.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.pageobjects;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.time.ZoneId;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.ZonedDateTime;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.openqa.selenium.By;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.openqa.selenium.WebElement;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.openqa.selenium.support.FindBy;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationStyle;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationTargetUser;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * Page Object Model for the admin notifications page."},{"lineNumber":18,"author":{"gitId":"-"},"content":" */"},{"lineNumber":19,"author":{"gitId":"-"},"content":"public class AdminNotificationsPage extends AppPage {"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-add-notification\")"},{"lineNumber":22,"author":{"gitId":"-"},"content":" private WebElement addNotificationButton;"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-create-notification\")"},{"lineNumber":25,"author":{"gitId":"-"},"content":" private WebElement createNotificationButton;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-edit-notification\")"},{"lineNumber":28,"author":{"gitId":"-"},"content":" private WebElement editNotificationButton;"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notifications-timezone\")"},{"lineNumber":31,"author":{"gitId":"-"},"content":" private WebElement notificationsTimezone;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notification-target-user\")"},{"lineNumber":34,"author":{"gitId":"-"},"content":" private WebElement notificationTargetUserDropdown;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notification-style\")"},{"lineNumber":37,"author":{"gitId":"-"},"content":" private WebElement notificationStyleDropdown;"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notification-title\")"},{"lineNumber":40,"author":{"gitId":"-"},"content":" private WebElement notificationTitleTextBox;"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notification-message\")"},{"lineNumber":43,"author":{"gitId":"-"},"content":" private WebElement notificationMessageEditor;"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notification-start-date\")"},{"lineNumber":46,"author":{"gitId":"-"},"content":" private WebElement startDateBox;"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notification-start-time\")"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private WebElement startTimeDropdown;"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notification-end-date\")"},{"lineNumber":52,"author":{"gitId":"-"},"content":" private WebElement endDateBox;"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notification-end-time\")"},{"lineNumber":55,"author":{"gitId":"-"},"content":" private WebElement endTimeDropdown;"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"notifications-table\")"},{"lineNumber":58,"author":{"gitId":"-"},"content":" private WebElement notificationsTable;"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" public AdminNotificationsPage(Browser browser) {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" super(browser);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" }"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":65,"author":{"gitId":"-"},"content":" protected boolean containsExpectedPageContents() {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" return getPageSource().contains(\"Notifications\");"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" public void verifyNotificationsTableRow(Notification notification) {"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" WebElement notificationRow \u003d notificationsTable.findElement(By.id(notification.getId().toString()));"},{"lineNumber":71,"author":{"gitId":"-"},"content":" verifyTableRowValues(notificationRow, getNotificationTableDisplayDetails(notification));"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" public void addNotification(Notification notification) {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" clickAddNotificationButton();"},{"lineNumber":76,"author":{"gitId":"-"},"content":" waitForElementPresence(By.id(\"btn-create-notification\"));"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" fillNotificationForm(notification);"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" clickCreateNotificationButton();"},{"lineNumber":81,"author":{"gitId":"-"},"content":" waitForPageToLoad(true);"},{"lineNumber":82,"author":{"gitId":"-"},"content":" }"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" public void editNotification(Notification notification) {"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" WebElement notificationRow \u003d notificationsTable.findElement(By.id(notification.getId().toString()));"},{"lineNumber":86,"author":{"gitId":"-"},"content":" WebElement editButton \u003d notificationRow.findElement(By.className(\"btn-light\"));"},{"lineNumber":87,"author":{"gitId":"-"},"content":" editButton.click();"},{"lineNumber":88,"author":{"gitId":"-"},"content":" waitForElementPresence(By.id(\"btn-edit-notification\"));"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" fillNotificationForm(notification);"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" clickEditNotificationButton();"},{"lineNumber":93,"author":{"gitId":"-"},"content":" waitForPageToLoad(true);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" }"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" public void deleteNotification(Notification notification) {"},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":" WebElement notificationRow \u003d notificationsTable.findElement(By.id(notification.getId().toString()));"},{"lineNumber":98,"author":{"gitId":"-"},"content":" WebElement deleteButton \u003d notificationRow.findElement(By.className(\"btn-danger\"));"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" deleteButton.click();"},{"lineNumber":101,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":102,"author":{"gitId":"-"},"content":" waitForPageToLoad(true);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" }"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" public void fillNotificationForm(Notification notification) {"},{"lineNumber":106,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(notificationTargetUserDropdown, getTargetUserText(notification.getTargetUser()));"},{"lineNumber":107,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(notificationStyleDropdown, getNotificationStyle(notification.getStyle()));"},{"lineNumber":108,"author":{"gitId":"-"},"content":" fillTextBox(notificationTitleTextBox, notification.getTitle());"},{"lineNumber":109,"author":{"gitId":"-"},"content":" setMessage(notification.getMessage());"},{"lineNumber":110,"author":{"gitId":"-"},"content":" setNotificationStartDateTime(notification.getStartTime());"},{"lineNumber":111,"author":{"gitId":"-"},"content":" setNotificationEndDateTime(notification.getEndTime());"},{"lineNumber":112,"author":{"gitId":"-"},"content":" }"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" public String getFirstRowNotificationId() {"},{"lineNumber":115,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e notificationRows \u003d"},{"lineNumber":116,"author":{"gitId":"-"},"content":" notificationsTable.findElement(By.tagName(\"tbody\")).findElements(By.tagName(\"tr\"));"},{"lineNumber":117,"author":{"gitId":"-"},"content":" return notificationRows.get(0).getAttribute(\"id\");"},{"lineNumber":118,"author":{"gitId":"-"},"content":" }"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" public void sortNotificationsTableByDescendingCreateTime() {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" WebElement creationTimeHeader \u003d notificationsTable.findElements(By.tagName(\"th\")).get(5);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" if (creationTimeHeader.findElements(By.className(\"fa-sort-down\")).isEmpty()) {"},{"lineNumber":123,"author":{"gitId":"-"},"content":" click(creationTimeHeader);"},{"lineNumber":124,"author":{"gitId":"-"},"content":" }"},{"lineNumber":125,"author":{"gitId":"-"},"content":" }"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" private void clickAddNotificationButton() {"},{"lineNumber":128,"author":{"gitId":"-"},"content":" click(addNotificationButton);"},{"lineNumber":129,"author":{"gitId":"-"},"content":" }"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" private void clickCreateNotificationButton() {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" click(createNotificationButton);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" }"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" private void clickEditNotificationButton() {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" click(editNotificationButton);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" private void setMessage(String message) {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" writeToRichTextEditor(notificationMessageEditor, message);"},{"lineNumber":141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" private void setNotificationStartDateTime(Instant startInstant) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" setDateTime(startDateBox, startTimeDropdown, startInstant);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" private void setNotificationEndDateTime(Instant endInstant) {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" setDateTime(endDateBox, endTimeDropdown, endInstant);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" }"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" private void setDateTime(WebElement dateBox, WebElement timeBox, Instant startInstant) {"},{"lineNumber":152,"author":{"gitId":"-"},"content":" fillDatePicker(dateBox, startInstant, getTimezone());"},{"lineNumber":153,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(timeBox.findElement(By.tagName(\"select\")), getInputTimeString(startInstant));"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"domoberzin"},"content":" private String[] getNotificationTableDisplayDetails(Notification notification) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" return new String[] {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" notification.getTitle(),"},{"lineNumber":159,"author":{"gitId":"-"},"content":" getTableDisplayDateString(notification.getStartTime()),"},{"lineNumber":160,"author":{"gitId":"-"},"content":" getTableDisplayDateString(notification.getEndTime()),"},{"lineNumber":161,"author":{"gitId":"-"},"content":" notification.getTargetUser().toString(),"},{"lineNumber":162,"author":{"gitId":"-"},"content":" getNotificationStyle(notification.getStyle()),"},{"lineNumber":163,"author":{"gitId":"-"},"content":" };"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" private String getTimezone() {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" return notificationsTimezone.getText().replace(\"All dates are displayed in \", \"\").replace(\" time.\", \"\");"},{"lineNumber":168,"author":{"gitId":"-"},"content":" }"},{"lineNumber":169,"author":{"gitId":"-"},"content":""},{"lineNumber":170,"author":{"gitId":"-"},"content":" private String getInputTimeString(Instant instant) {"},{"lineNumber":171,"author":{"gitId":"-"},"content":" String timezone \u003d getTimezone();"},{"lineNumber":172,"author":{"gitId":"-"},"content":" ZonedDateTime dateTime \u003d instant.atZone(ZoneId.of(timezone));"},{"lineNumber":173,"author":{"gitId":"-"},"content":" if (dateTime.getHour() \u003d\u003d 0 \u0026\u0026 dateTime.getMinute() \u003d\u003d 0) {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" return \"23:59H\";"},{"lineNumber":175,"author":{"gitId":"-"},"content":" }"},{"lineNumber":176,"author":{"gitId":"-"},"content":" return getDisplayedDateTime(instant, timezone, \"HH:00\") + \"H\";"},{"lineNumber":177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" private String getTableDisplayDateString(Instant date) {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" return getDisplayedDateTime(date, getTimezone(), \"d MMM h:mm a\");"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" private String getTargetUserText(NotificationTargetUser userType) {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" switch (userType) {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" case STUDENT:"},{"lineNumber":186,"author":{"gitId":"-"},"content":" return \"Students\";"},{"lineNumber":187,"author":{"gitId":"-"},"content":" case INSTRUCTOR:"},{"lineNumber":188,"author":{"gitId":"-"},"content":" return \"Instructors\";"},{"lineNumber":189,"author":{"gitId":"-"},"content":" case GENERAL:"},{"lineNumber":190,"author":{"gitId":"-"},"content":" return \"General (for both students and instructors)\";"},{"lineNumber":191,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":192,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":" }"},{"lineNumber":195,"author":{"gitId":"-"},"content":""},{"lineNumber":196,"author":{"gitId":"-"},"content":" private String getNotificationStyle(NotificationStyle style) {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" switch (style) {"},{"lineNumber":198,"author":{"gitId":"-"},"content":" case PRIMARY:"},{"lineNumber":199,"author":{"gitId":"-"},"content":" return \"Primary (blue)\";"},{"lineNumber":200,"author":{"gitId":"-"},"content":" case SECONDARY:"},{"lineNumber":201,"author":{"gitId":"-"},"content":" return \"Secondary (grey)\";"},{"lineNumber":202,"author":{"gitId":"-"},"content":" case SUCCESS:"},{"lineNumber":203,"author":{"gitId":"-"},"content":" return \"Success (green)\";"},{"lineNumber":204,"author":{"gitId":"-"},"content":" case DANGER:"},{"lineNumber":205,"author":{"gitId":"-"},"content":" return \"Danger (red)\";"},{"lineNumber":206,"author":{"gitId":"-"},"content":" case WARNING:"},{"lineNumber":207,"author":{"gitId":"-"},"content":" return \"Warning (yellow)\";"},{"lineNumber":208,"author":{"gitId":"-"},"content":" case INFO:"},{"lineNumber":209,"author":{"gitId":"-"},"content":" return \"Info (cyan)\";"},{"lineNumber":210,"author":{"gitId":"-"},"content":" case LIGHT:"},{"lineNumber":211,"author":{"gitId":"-"},"content":" return \"Light\";"},{"lineNumber":212,"author":{"gitId":"-"},"content":" case DARK:"},{"lineNumber":213,"author":{"gitId":"-"},"content":" return \"Dark\";"},{"lineNumber":214,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":215,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":216,"author":{"gitId":"-"},"content":" }"},{"lineNumber":217,"author":{"gitId":"-"},"content":" }"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":10,"-":209}},{"path":"src/e2e/java/teammates/e2e/pageobjects/AdminSearchPage.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.pageobjects;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertEquals;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertFalse;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertNotEquals;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.openqa.selenium.By;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.openqa.selenium.NoSuchElementException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import org.openqa.selenium.WebElement;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.openqa.selenium.support.FindBy;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountRequestAttributes;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.util.StringHelper;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"-"},"content":" * Represents the admin home page of the website."},{"lineNumber":27,"author":{"gitId":"-"},"content":" */"},{"lineNumber":28,"author":{"gitId":"-"},"content":"public class AdminSearchPage extends AppPage {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" private static final int STUDENT_COL_DETAILS \u003d 1;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" private static final int STUDENT_COL_NAME \u003d 2;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" private static final int STUDENT_COL_GOOGLE_ID \u003d 3;"},{"lineNumber":32,"author":{"gitId":"-"},"content":" private static final int STUDENT_COL_INSTITUTE \u003d 4;"},{"lineNumber":33,"author":{"gitId":"-"},"content":" private static final int STUDENT_COL_COMMENTS \u003d 5;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" private static final int STUDENT_COL_OPTIONS \u003d 6;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" private static final int INSTRUCTOR_COL_COURSE_ID \u003d 1;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" private static final int INSTRUCTOR_COL_NAME \u003d 2;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" private static final int INSTRUCTOR_COL_GOOGLE_ID \u003d 3;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" private static final int INSTRUCTOR_COL_INSTITUTE \u003d 4;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" private static final int INSTRUCTOR_COL_OPTIONS \u003d 5;"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" private static final int ACCOUNT_REQUEST_COL_NAME \u003d 1;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" private static final int ACCOUNT_REQUEST_COL_EMAIL \u003d 2;"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" private static final int ACCOUNT_REQUEST_COL_INSTITUTE \u003d 4;"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" private static final int ACCOUNT_REQUEST_COL_CREATED_AT \u003d 5;"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" private static final int ACCOUNT_REQUEST_COL_REGISTERED_AT \u003d 6;"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" private static final String EXPANDED_ROWS_HEADER_EMAIL \u003d \"Email\";"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private static final String EXPANDED_ROWS_HEADER_COURSE_JOIN_LINK \u003d \"Course Join Link\";"},{"lineNumber":50,"author":{"gitId":"-"},"content":" private static final String EXPANDED_ROWS_HEADER_ACCOUNT_REGISTRATION_LINK \u003d \"Account Registration Link\";"},{"lineNumber":51,"author":{"gitId":"-"},"content":" private static final String LINK_TEXT_RESET_GOOGLE_ID \u003d \"Reset Google ID\";"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"search-box\")"},{"lineNumber":54,"author":{"gitId":"-"},"content":" private WebElement inputBox;"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"search-button\")"},{"lineNumber":57,"author":{"gitId":"-"},"content":" private WebElement searchButton;"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"show-student-links\")"},{"lineNumber":60,"author":{"gitId":"-"},"content":" private WebElement expandStudentLinksButton;"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"show-instructor-links\")"},{"lineNumber":63,"author":{"gitId":"-"},"content":" private WebElement expandInstructorLinksButton;"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"show-account-request-links\")"},{"lineNumber":66,"author":{"gitId":"-"},"content":" private WebElement expandAccountRequestLinksButton;"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"hide-student-links\")"},{"lineNumber":69,"author":{"gitId":"-"},"content":" private WebElement collapseStudentLinksButton;"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"hide-instructor-links\")"},{"lineNumber":72,"author":{"gitId":"-"},"content":" private WebElement collapseInstructorLinksButton;"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"hide-account-request-links\")"},{"lineNumber":75,"author":{"gitId":"-"},"content":" private WebElement collapseAccountRequestLinksButton;"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" public AdminSearchPage(Browser browser) {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" super(browser);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" }"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":82,"author":{"gitId":"-"},"content":" protected boolean containsExpectedPageContents() {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" return getPageSource().contains(\"Admin Search\u003c/h1\u003e\");"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" public void inputSearchContent(String content) {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" inputBox.sendKeys(content);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" public void clearSearchBox() {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" inputBox.clear();"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" public void clickSearchButton() {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" click(searchButton);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":97,"author":{"gitId":"-"},"content":" }"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" public void regenerateStudentKey(Student student) {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":101,"author":{"gitId":"-"},"content":" studentRow.findElement(By.xpath(\"//button[text()\u003d\u0027Regenerate key\u0027]\")).click();"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":104,"author":{"gitId":"-"},"content":" waitForPageToLoad(true);"},{"lineNumber":105,"author":{"gitId":"-"},"content":" }"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" public void regenerateStudentKey(StudentAttributes student) {"},{"lineNumber":108,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" studentRow.findElement(By.xpath(\"//button[text()\u003d\u0027Regenerate key\u0027]\")).click();"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":112,"author":{"gitId":"-"},"content":" waitForPageToLoad(true);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" }"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" public void verifyRegenerateStudentKey(Student student, String originalJoinLink) {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" verifyStatusMessage(\"Student\u0027s key for this course has been successfully regenerated,\""},{"lineNumber":117,"author":{"gitId":"-"},"content":" + \" and the email has been sent.\");"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" String regeneratedJoinLink \u003d getStudentJoinLink(student);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" assertNotEquals(regeneratedJoinLink, originalJoinLink);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" }"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" public void verifyRegenerateStudentKey(StudentAttributes student, String originalJoinLink) {"},{"lineNumber":124,"author":{"gitId":"-"},"content":" verifyStatusMessage(\"Student\u0027s key for this course has been successfully regenerated,\""},{"lineNumber":125,"author":{"gitId":"-"},"content":" + \" and the email has been sent.\");"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" String regeneratedJoinLink \u003d getStudentJoinLink(student);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" assertNotEquals(regeneratedJoinLink, originalJoinLink);"},{"lineNumber":129,"author":{"gitId":"-"},"content":" }"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" public void regenerateInstructorKey(Instructor instructor) {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" instructorRow.findElement(By.xpath(\"//button[text()\u003d\u0027Regenerate key\u0027]\")).click();"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":136,"author":{"gitId":"-"},"content":" waitForPageToLoad(true);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" public void regenerateInstructorKey(InstructorAttributes instructor) {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":141,"author":{"gitId":"-"},"content":" instructorRow.findElement(By.xpath(\"//button[text()\u003d\u0027Regenerate key\u0027]\")).click();"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":144,"author":{"gitId":"-"},"content":" waitForPageToLoad(true);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" public void clickExpandStudentLinks() {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" click(expandStudentLinksButton);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":150,"author":{"gitId":"-"},"content":" }"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" public void clickExpandInstructorLinks() {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" click(expandInstructorLinksButton);"},{"lineNumber":154,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":155,"author":{"gitId":"-"},"content":" }"},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"-"},"content":" public void clickExpandAccountRequestLinks() {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" click(expandAccountRequestLinksButton);"},{"lineNumber":159,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":160,"author":{"gitId":"-"},"content":" }"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"-"},"content":" public void clickCollapseStudentLinks() {"},{"lineNumber":163,"author":{"gitId":"-"},"content":" click(collapseStudentLinksButton);"},{"lineNumber":164,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" public void clickCollapseInstructorLinks() {"},{"lineNumber":168,"author":{"gitId":"-"},"content":" click(collapseInstructorLinksButton);"},{"lineNumber":169,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":170,"author":{"gitId":"-"},"content":" }"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" public void clickCollapseAccountRequestLinks() {"},{"lineNumber":173,"author":{"gitId":"-"},"content":" click(collapseAccountRequestLinksButton);"},{"lineNumber":174,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":175,"author":{"gitId":"-"},"content":" }"},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":" public String removeSpanFromText(String text) {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" return text.replace(\"\u003cspan class\u003d\\\"highlighted-text\\\"\u003e\", \"\").replace(\"\u003c/span\u003e\", \"\");"},{"lineNumber":179,"author":{"gitId":"-"},"content":" }"},{"lineNumber":180,"author":{"gitId":"-"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":" public WebElement getStudentRow(Student student) {"},{"lineNumber":182,"author":{"gitId":"-"},"content":" String details \u003d String.format(\"%s [%s] (%s)\", student.getCourse().getId(),"},{"lineNumber":183,"author":{"gitId":"-"},"content":" student.getSection() \u003d\u003d null"},{"lineNumber":184,"author":{"gitId":"-"},"content":" ? Const.DEFAULT_SECTION"},{"lineNumber":185,"author":{"gitId":"-"},"content":" : student.getSection().getName(), student.getTeam().getName());"},{"lineNumber":186,"author":{"gitId":"-"},"content":" WebElement table \u003d browser.driver.findElement(By.id(\"search-table-student\"));"},{"lineNumber":187,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d table.findElements(By.tagName(\"tr\"));"},{"lineNumber":188,"author":{"gitId":"-"},"content":" for (WebElement row : rows) {"},{"lineNumber":189,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e columns \u003d row.findElements(By.tagName(\"td\"));"},{"lineNumber":190,"author":{"gitId":"-"},"content":" if (!columns.isEmpty() \u0026\u0026 removeSpanFromText(columns.get(STUDENT_COL_DETAILS - 1)"},{"lineNumber":191,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(details)"},{"lineNumber":192,"author":{"gitId":"-"},"content":" \u0026\u0026 removeSpanFromText(columns.get(STUDENT_COL_NAME - 1)"},{"lineNumber":193,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(student.getName())) {"},{"lineNumber":194,"author":{"gitId":"-"},"content":" return row;"},{"lineNumber":195,"author":{"gitId":"-"},"content":" }"},{"lineNumber":196,"author":{"gitId":"-"},"content":" }"},{"lineNumber":197,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":198,"author":{"gitId":"-"},"content":" }"},{"lineNumber":199,"author":{"gitId":"-"},"content":""},{"lineNumber":200,"author":{"gitId":"-"},"content":" public WebElement getStudentRow(StudentAttributes student) {"},{"lineNumber":201,"author":{"gitId":"-"},"content":" String details \u003d String.format(\"%s [%s] (%s)\", student.getCourse(),"},{"lineNumber":202,"author":{"gitId":"-"},"content":" student.getSection() \u003d\u003d null ? Const.DEFAULT_SECTION : student.getSection(), student.getTeam());"},{"lineNumber":203,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d browser.driver.findElements(By.cssSelector(\"#search-table-student tbody tr\"));"},{"lineNumber":204,"author":{"gitId":"-"},"content":" for (WebElement row : rows) {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e columns \u003d row.findElements(By.tagName(\"td\"));"},{"lineNumber":206,"author":{"gitId":"-"},"content":" if (removeSpanFromText(columns.get(STUDENT_COL_DETAILS - 1)"},{"lineNumber":207,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(details)"},{"lineNumber":208,"author":{"gitId":"-"},"content":" \u0026\u0026 removeSpanFromText(columns.get(STUDENT_COL_NAME - 1)"},{"lineNumber":209,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(student.getName())) {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" return row;"},{"lineNumber":211,"author":{"gitId":"-"},"content":" }"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":214,"author":{"gitId":"-"},"content":" }"},{"lineNumber":215,"author":{"gitId":"-"},"content":""},{"lineNumber":216,"author":{"gitId":"-"},"content":" public String getStudentDetails(WebElement studentRow) {"},{"lineNumber":217,"author":{"gitId":"-"},"content":" return getColumnText(studentRow, STUDENT_COL_DETAILS);"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" public String getStudentName(WebElement studentRow) {"},{"lineNumber":221,"author":{"gitId":"-"},"content":" return getColumnText(studentRow, STUDENT_COL_NAME);"},{"lineNumber":222,"author":{"gitId":"-"},"content":" }"},{"lineNumber":223,"author":{"gitId":"-"},"content":""},{"lineNumber":224,"author":{"gitId":"-"},"content":" public String getStudentGoogleId(WebElement studentRow) {"},{"lineNumber":225,"author":{"gitId":"-"},"content":" return getColumnText(studentRow, STUDENT_COL_GOOGLE_ID);"},{"lineNumber":226,"author":{"gitId":"-"},"content":" }"},{"lineNumber":227,"author":{"gitId":"-"},"content":""},{"lineNumber":228,"author":{"gitId":"-"},"content":" public String getStudentHomeLink(WebElement studentRow) {"},{"lineNumber":229,"author":{"gitId":"-"},"content":" return getColumnLink(studentRow, STUDENT_COL_GOOGLE_ID);"},{"lineNumber":230,"author":{"gitId":"-"},"content":" }"},{"lineNumber":231,"author":{"gitId":"-"},"content":""},{"lineNumber":232,"author":{"gitId":"-"},"content":" public String getStudentInstitute(WebElement studentRow) {"},{"lineNumber":233,"author":{"gitId":"-"},"content":" return getColumnText(studentRow, STUDENT_COL_INSTITUTE);"},{"lineNumber":234,"author":{"gitId":"-"},"content":" }"},{"lineNumber":235,"author":{"gitId":"-"},"content":""},{"lineNumber":236,"author":{"gitId":"-"},"content":" public String getStudentComments(WebElement studentRow) {"},{"lineNumber":237,"author":{"gitId":"-"},"content":" return getColumnText(studentRow, STUDENT_COL_COMMENTS);"},{"lineNumber":238,"author":{"gitId":"-"},"content":" }"},{"lineNumber":239,"author":{"gitId":"-"},"content":""},{"lineNumber":240,"author":{"gitId":"-"},"content":" public String getStudentManageAccountLink(WebElement studentRow) {"},{"lineNumber":241,"author":{"gitId":"-"},"content":" return getColumnLink(studentRow, STUDENT_COL_OPTIONS);"},{"lineNumber":242,"author":{"gitId":"-"},"content":" }"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" public String getStudentEmail(WebElement studentRow) {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" return getExpandedRowInputValue(studentRow, EXPANDED_ROWS_HEADER_EMAIL);"},{"lineNumber":246,"author":{"gitId":"-"},"content":" }"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" public String getStudentJoinLink(WebElement studentRow) {"},{"lineNumber":249,"author":{"gitId":"-"},"content":" return getExpandedRowInputValue(studentRow, EXPANDED_ROWS_HEADER_COURSE_JOIN_LINK);"},{"lineNumber":250,"author":{"gitId":"-"},"content":" }"},{"lineNumber":251,"author":{"gitId":"-"},"content":""},{"lineNumber":252,"author":{"gitId":"-"},"content":" public String getStudentJoinLink(Student student) {"},{"lineNumber":253,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":254,"author":{"gitId":"-"},"content":" return getStudentJoinLink(studentRow);"},{"lineNumber":255,"author":{"gitId":"-"},"content":" }"},{"lineNumber":256,"author":{"gitId":"-"},"content":""},{"lineNumber":257,"author":{"gitId":"-"},"content":" public String getStudentJoinLink(StudentAttributes student) {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":259,"author":{"gitId":"-"},"content":" return getStudentJoinLink(studentRow);"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":""},{"lineNumber":262,"author":{"gitId":"-"},"content":" public void resetStudentGoogleId(Student student) {"},{"lineNumber":263,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":264,"author":{"gitId":"-"},"content":" WebElement link \u003d studentRow.findElement(By.linkText(LINK_TEXT_RESET_GOOGLE_ID));"},{"lineNumber":265,"author":{"gitId":"-"},"content":" link.click();"},{"lineNumber":266,"author":{"gitId":"-"},"content":""},{"lineNumber":267,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":268,"author":{"gitId":"-"},"content":" waitForElementStaleness(link);"},{"lineNumber":269,"author":{"gitId":"-"},"content":" }"},{"lineNumber":270,"author":{"gitId":"-"},"content":""},{"lineNumber":271,"author":{"gitId":"-"},"content":" public void resetStudentGoogleId(StudentAttributes student) {"},{"lineNumber":272,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":273,"author":{"gitId":"-"},"content":" WebElement link \u003d studentRow.findElement(By.linkText(LINK_TEXT_RESET_GOOGLE_ID));"},{"lineNumber":274,"author":{"gitId":"-"},"content":" link.click();"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":277,"author":{"gitId":"-"},"content":" waitForElementStaleness(link);"},{"lineNumber":278,"author":{"gitId":"-"},"content":" }"},{"lineNumber":279,"author":{"gitId":"-"},"content":""},{"lineNumber":280,"author":{"gitId":"-"},"content":" public WebElement getInstructorRow(Instructor instructor) {"},{"lineNumber":281,"author":{"gitId":"-"},"content":" WebElement table \u003d browser.driver.findElement(By.id(\"search-table-instructor\"));"},{"lineNumber":282,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d table.findElements(By.tagName(\"tr\"));"},{"lineNumber":283,"author":{"gitId":"-"},"content":" for (WebElement row : rows) {"},{"lineNumber":284,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e columns \u003d row.findElements(By.tagName(\"td\"));"},{"lineNumber":285,"author":{"gitId":"-"},"content":" if (columns.size() \u003e\u003d 3 \u0026\u0026 (removeSpanFromText(columns.get(2)"},{"lineNumber":286,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(instructor.getGoogleId())"},{"lineNumber":287,"author":{"gitId":"-"},"content":" || removeSpanFromText(columns.get(1)"},{"lineNumber":288,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(instructor.getName()))) {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" return row;"},{"lineNumber":290,"author":{"gitId":"-"},"content":" }"},{"lineNumber":291,"author":{"gitId":"-"},"content":" }"},{"lineNumber":292,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":293,"author":{"gitId":"-"},"content":" }"},{"lineNumber":294,"author":{"gitId":"-"},"content":""},{"lineNumber":295,"author":{"gitId":"-"},"content":" public WebElement getInstructorRow(InstructorAttributes instructor) {"},{"lineNumber":296,"author":{"gitId":"-"},"content":" String courseId \u003d instructor.getCourseId();"},{"lineNumber":297,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d browser.driver.findElements(By.cssSelector(\"#search-table-instructor tbody tr\"));"},{"lineNumber":298,"author":{"gitId":"-"},"content":" for (WebElement row : rows) {"},{"lineNumber":299,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e columns \u003d row.findElements(By.tagName(\"td\"));"},{"lineNumber":300,"author":{"gitId":"-"},"content":" if (removeSpanFromText(columns.get(INSTRUCTOR_COL_COURSE_ID - 1)"},{"lineNumber":301,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(courseId)"},{"lineNumber":302,"author":{"gitId":"-"},"content":" \u0026\u0026 removeSpanFromText(columns.get(INSTRUCTOR_COL_NAME - 1)"},{"lineNumber":303,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(instructor.getName())) {"},{"lineNumber":304,"author":{"gitId":"-"},"content":" return row;"},{"lineNumber":305,"author":{"gitId":"-"},"content":" }"},{"lineNumber":306,"author":{"gitId":"-"},"content":" }"},{"lineNumber":307,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":308,"author":{"gitId":"-"},"content":" }"},{"lineNumber":309,"author":{"gitId":"-"},"content":""},{"lineNumber":310,"author":{"gitId":"-"},"content":" public String getInstructorCourseId(WebElement instructorRow) {"},{"lineNumber":311,"author":{"gitId":"-"},"content":" return getColumnText(instructorRow, INSTRUCTOR_COL_COURSE_ID);"},{"lineNumber":312,"author":{"gitId":"-"},"content":" }"},{"lineNumber":313,"author":{"gitId":"-"},"content":""},{"lineNumber":314,"author":{"gitId":"-"},"content":" public String getInstructorName(WebElement instructorRow) {"},{"lineNumber":315,"author":{"gitId":"-"},"content":" return getColumnText(instructorRow, INSTRUCTOR_COL_NAME);"},{"lineNumber":316,"author":{"gitId":"-"},"content":" }"},{"lineNumber":317,"author":{"gitId":"-"},"content":""},{"lineNumber":318,"author":{"gitId":"-"},"content":" public String getInstructorGoogleId(WebElement instructorRow) {"},{"lineNumber":319,"author":{"gitId":"-"},"content":" return getColumnText(instructorRow, INSTRUCTOR_COL_GOOGLE_ID);"},{"lineNumber":320,"author":{"gitId":"-"},"content":" }"},{"lineNumber":321,"author":{"gitId":"-"},"content":""},{"lineNumber":322,"author":{"gitId":"-"},"content":" public String getInstructorHomePageLink(WebElement instructorRow) {"},{"lineNumber":323,"author":{"gitId":"-"},"content":" return getColumnLink(instructorRow, INSTRUCTOR_COL_GOOGLE_ID);"},{"lineNumber":324,"author":{"gitId":"-"},"content":" }"},{"lineNumber":325,"author":{"gitId":"-"},"content":""},{"lineNumber":326,"author":{"gitId":"-"},"content":" public String getInstructorInstitute(WebElement instructorRow) {"},{"lineNumber":327,"author":{"gitId":"-"},"content":" return getColumnText(instructorRow, INSTRUCTOR_COL_INSTITUTE);"},{"lineNumber":328,"author":{"gitId":"-"},"content":" }"},{"lineNumber":329,"author":{"gitId":"-"},"content":""},{"lineNumber":330,"author":{"gitId":"-"},"content":" public String getInstructorManageAccountLink(WebElement instructorRow) {"},{"lineNumber":331,"author":{"gitId":"-"},"content":" return getColumnLink(instructorRow, INSTRUCTOR_COL_OPTIONS);"},{"lineNumber":332,"author":{"gitId":"-"},"content":" }"},{"lineNumber":333,"author":{"gitId":"-"},"content":""},{"lineNumber":334,"author":{"gitId":"-"},"content":" public String getInstructorEmail(WebElement instructorRow) {"},{"lineNumber":335,"author":{"gitId":"-"},"content":" return getExpandedRowInputValue(instructorRow, EXPANDED_ROWS_HEADER_EMAIL);"},{"lineNumber":336,"author":{"gitId":"-"},"content":" }"},{"lineNumber":337,"author":{"gitId":"-"},"content":""},{"lineNumber":338,"author":{"gitId":"-"},"content":" public String getInstructorJoinLink(WebElement instructorRow) {"},{"lineNumber":339,"author":{"gitId":"-"},"content":" return getExpandedRowInputValue(instructorRow, EXPANDED_ROWS_HEADER_COURSE_JOIN_LINK);"},{"lineNumber":340,"author":{"gitId":"-"},"content":" }"},{"lineNumber":341,"author":{"gitId":"-"},"content":""},{"lineNumber":342,"author":{"gitId":"-"},"content":" public String getInstructorJoinLink(Instructor instructor) {"},{"lineNumber":343,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":344,"author":{"gitId":"-"},"content":" return getInstructorJoinLink(instructorRow);"},{"lineNumber":345,"author":{"gitId":"-"},"content":" }"},{"lineNumber":346,"author":{"gitId":"-"},"content":""},{"lineNumber":347,"author":{"gitId":"-"},"content":" public String getInstructorJoinLink(InstructorAttributes instructor) {"},{"lineNumber":348,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":349,"author":{"gitId":"-"},"content":" return getInstructorJoinLink(instructorRow);"},{"lineNumber":350,"author":{"gitId":"-"},"content":" }"},{"lineNumber":351,"author":{"gitId":"-"},"content":""},{"lineNumber":352,"author":{"gitId":"-"},"content":" public void resetInstructorGoogleId(Instructor instructor) {"},{"lineNumber":353,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":354,"author":{"gitId":"-"},"content":" WebElement link \u003d instructorRow.findElement(By.linkText(LINK_TEXT_RESET_GOOGLE_ID));"},{"lineNumber":355,"author":{"gitId":"-"},"content":" link.click();"},{"lineNumber":356,"author":{"gitId":"-"},"content":""},{"lineNumber":357,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":358,"author":{"gitId":"-"},"content":" waitForElementStaleness(link);"},{"lineNumber":359,"author":{"gitId":"-"},"content":" }"},{"lineNumber":360,"author":{"gitId":"-"},"content":""},{"lineNumber":361,"author":{"gitId":"-"},"content":" public void resetInstructorGoogleId(InstructorAttributes instructor) {"},{"lineNumber":362,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":363,"author":{"gitId":"-"},"content":" WebElement link \u003d instructorRow.findElement(By.linkText(LINK_TEXT_RESET_GOOGLE_ID));"},{"lineNumber":364,"author":{"gitId":"-"},"content":" link.click();"},{"lineNumber":365,"author":{"gitId":"-"},"content":""},{"lineNumber":366,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":367,"author":{"gitId":"-"},"content":" waitForElementStaleness(link);"},{"lineNumber":368,"author":{"gitId":"-"},"content":" }"},{"lineNumber":369,"author":{"gitId":"-"},"content":""},{"lineNumber":370,"author":{"gitId":"-"},"content":" public WebElement getAccountRequestRow(AccountRequestAttributes accountRequest) {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" String email \u003d accountRequest.getEmail();"},{"lineNumber":372,"author":{"gitId":"-"},"content":" String institute \u003d accountRequest.getInstitute();"},{"lineNumber":373,"author":{"gitId":"domoberzin"},"content":" List\u003cWebElement\u003e rows \u003d browser.driver.findElements(By.cssSelector(\"tm-account-request-table tbody tr\"));"},{"lineNumber":374,"author":{"gitId":"-"},"content":" for (WebElement row : rows) {"},{"lineNumber":375,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e columns \u003d row.findElements(By.tagName(\"td\"));"},{"lineNumber":376,"author":{"gitId":"-"},"content":" if (removeSpanFromText(columns.get(ACCOUNT_REQUEST_COL_EMAIL - 1)"},{"lineNumber":377,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(email)"},{"lineNumber":378,"author":{"gitId":"-"},"content":" \u0026\u0026 removeSpanFromText(columns.get(ACCOUNT_REQUEST_COL_INSTITUTE - 1)"},{"lineNumber":379,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(institute)) {"},{"lineNumber":380,"author":{"gitId":"-"},"content":" return row;"},{"lineNumber":381,"author":{"gitId":"-"},"content":" }"},{"lineNumber":382,"author":{"gitId":"-"},"content":" }"},{"lineNumber":383,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":384,"author":{"gitId":"-"},"content":" }"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"domoberzin"},"content":" public WebElement getAccountRequestRow(AccountRequest accountRequest) {"},{"lineNumber":387,"author":{"gitId":"domoberzin"},"content":" String email \u003d accountRequest.getEmail();"},{"lineNumber":388,"author":{"gitId":"domoberzin"},"content":" String institute \u003d accountRequest.getInstitute();"},{"lineNumber":389,"author":{"gitId":"domoberzin"},"content":" List\u003cWebElement\u003e rows \u003d browser.driver.findElements(By.cssSelector(\"tm-account-request-table tbody tr\"));"},{"lineNumber":390,"author":{"gitId":"-"},"content":" for (WebElement row : rows) {"},{"lineNumber":391,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e columns \u003d row.findElements(By.tagName(\"td\"));"},{"lineNumber":392,"author":{"gitId":"-"},"content":" if (removeSpanFromText(columns.get(ACCOUNT_REQUEST_COL_EMAIL - 1)"},{"lineNumber":393,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(email)"},{"lineNumber":394,"author":{"gitId":"-"},"content":" \u0026\u0026 removeSpanFromText(columns.get(ACCOUNT_REQUEST_COL_INSTITUTE - 1)"},{"lineNumber":395,"author":{"gitId":"-"},"content":" .getAttribute(\"innerHTML\")).contains(institute)) {"},{"lineNumber":396,"author":{"gitId":"-"},"content":" return row;"},{"lineNumber":397,"author":{"gitId":"-"},"content":" }"},{"lineNumber":398,"author":{"gitId":"-"},"content":" }"},{"lineNumber":399,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":400,"author":{"gitId":"-"},"content":" }"},{"lineNumber":401,"author":{"gitId":"-"},"content":""},{"lineNumber":402,"author":{"gitId":"-"},"content":" public String getAccountRequestName(WebElement accountRequestRow) {"},{"lineNumber":403,"author":{"gitId":"-"},"content":" return getColumnText(accountRequestRow, ACCOUNT_REQUEST_COL_NAME);"},{"lineNumber":404,"author":{"gitId":"-"},"content":" }"},{"lineNumber":405,"author":{"gitId":"-"},"content":""},{"lineNumber":406,"author":{"gitId":"-"},"content":" public String getAccountRequestEmail(WebElement accountRequestRow) {"},{"lineNumber":407,"author":{"gitId":"-"},"content":" return getColumnText(accountRequestRow, ACCOUNT_REQUEST_COL_EMAIL);"},{"lineNumber":408,"author":{"gitId":"-"},"content":" }"},{"lineNumber":409,"author":{"gitId":"-"},"content":""},{"lineNumber":410,"author":{"gitId":"-"},"content":" public String getAccountRequestInstitute(WebElement accountRequestRow) {"},{"lineNumber":411,"author":{"gitId":"-"},"content":" return getColumnText(accountRequestRow, ACCOUNT_REQUEST_COL_INSTITUTE);"},{"lineNumber":412,"author":{"gitId":"-"},"content":" }"},{"lineNumber":413,"author":{"gitId":"-"},"content":""},{"lineNumber":414,"author":{"gitId":"-"},"content":" public String getAccountRequestCreatedAt(WebElement accountRequestRow) {"},{"lineNumber":415,"author":{"gitId":"-"},"content":" return getColumnText(accountRequestRow, ACCOUNT_REQUEST_COL_CREATED_AT);"},{"lineNumber":416,"author":{"gitId":"-"},"content":" }"},{"lineNumber":417,"author":{"gitId":"-"},"content":""},{"lineNumber":418,"author":{"gitId":"-"},"content":" public String getAccountRequestRegisteredAt(WebElement accountRequestRow) {"},{"lineNumber":419,"author":{"gitId":"-"},"content":" return getColumnText(accountRequestRow, ACCOUNT_REQUEST_COL_REGISTERED_AT);"},{"lineNumber":420,"author":{"gitId":"-"},"content":" }"},{"lineNumber":421,"author":{"gitId":"-"},"content":""},{"lineNumber":422,"author":{"gitId":"-"},"content":" public String getAccountRequestRegistrationLink(WebElement accountRequestRow) {"},{"lineNumber":423,"author":{"gitId":"-"},"content":" return getExpandedRowInputValue(accountRequestRow, EXPANDED_ROWS_HEADER_ACCOUNT_REGISTRATION_LINK);"},{"lineNumber":424,"author":{"gitId":"-"},"content":" }"},{"lineNumber":425,"author":{"gitId":"-"},"content":""},{"lineNumber":426,"author":{"gitId":"-"},"content":" public void clickDeleteAccountRequestButton(AccountRequestAttributes accountRequest) {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":428,"author":{"gitId":"-"},"content":" WebElement deleteButton \u003d accountRequestRow.findElement(By.cssSelector(\"[id^\u003d\u0027delete-account-request-\u0027]\"));"},{"lineNumber":429,"author":{"gitId":"-"},"content":" deleteButton.click();"},{"lineNumber":430,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":431,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":432,"author":{"gitId":"-"},"content":" }"},{"lineNumber":433,"author":{"gitId":"-"},"content":""},{"lineNumber":434,"author":{"gitId":"domoberzin"},"content":" public void clickDeleteAccountRequestButton(AccountRequest accountRequest) {"},{"lineNumber":435,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":436,"author":{"gitId":"domoberzin"},"content":" WebElement deleteButton \u003d accountRequestRow.findElement(By.cssSelector(\"[id^\u003d\u0027delete-account-request-\u0027]\"));"},{"lineNumber":437,"author":{"gitId":"domoberzin"},"content":" deleteButton.click();"},{"lineNumber":438,"author":{"gitId":"domoberzin"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":439,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":440,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":441,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":442,"author":{"gitId":"domoberzin"},"content":" public void clickApproveAccountRequestButton(AccountRequest accountRequest) {"},{"lineNumber":443,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":444,"author":{"gitId":"domoberzin"},"content":" waitForElementPresence(By.cssSelector(\"[id^\u003d\u0027approve-account-request-\u0027]\"));"},{"lineNumber":445,"author":{"gitId":"domoberzin"},"content":" WebElement approveButton \u003d accountRequestRow.findElement(By.cssSelector(\"[id^\u003d\u0027approve-account-request-\u0027]\"));"},{"lineNumber":446,"author":{"gitId":"domoberzin"},"content":" waitForElementToBeClickable(approveButton);"},{"lineNumber":447,"author":{"gitId":"domoberzin"},"content":" approveButton.click();"},{"lineNumber":448,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":449,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":450,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":451,"author":{"gitId":"domoberzin"},"content":" public void clickRejectAccountRequestButton(AccountRequest accountRequest) {"},{"lineNumber":452,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":453,"author":{"gitId":"domoberzin"},"content":" WebElement rejectButton \u003d accountRequestRow.findElement(By.cssSelector(\"[id^\u003d\u0027reject-account-request-\u0027]\"));"},{"lineNumber":454,"author":{"gitId":"domoberzin"},"content":" rejectButton.click();"},{"lineNumber":455,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":456,"author":{"gitId":"domoberzin"},"content":" WebElement rejectWithoutReasonButton \u003d browser.driver.findElement(By.cssSelector(\"[id^\u003d\u0027reject-request-\u0027]\"));"},{"lineNumber":457,"author":{"gitId":"domoberzin"},"content":" rejectWithoutReasonButton.click();"},{"lineNumber":458,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":459,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":460,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":461,"author":{"gitId":"domoberzin"},"content":" public void clickRejectAccountRequestWithReasonButton(AccountRequest accountRequest) {"},{"lineNumber":462,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":463,"author":{"gitId":"domoberzin"},"content":" WebElement rejectButton \u003d accountRequestRow.findElement(By.cssSelector(\"[id^\u003d\u0027reject-account-request-\u0027]\"));"},{"lineNumber":464,"author":{"gitId":"domoberzin"},"content":" rejectButton.click();"},{"lineNumber":465,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":466,"author":{"gitId":"domoberzin"},"content":" WebElement rejectWithReasonButton \u003d browser.driver.findElement(By.cssSelector(\"[id^\u003d\u0027reject-request-with-reason\u0027]\"));"},{"lineNumber":467,"author":{"gitId":"domoberzin"},"content":" waitForElementToBeClickable(rejectWithReasonButton);"},{"lineNumber":468,"author":{"gitId":"domoberzin"},"content":" rejectWithReasonButton.click();"},{"lineNumber":469,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":470,"author":{"gitId":"domoberzin"},"content":" waitForElementPresence(By.cssSelector(\"tm-reject-with-reason-modal\"));"},{"lineNumber":471,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":472,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":473,"author":{"gitId":"domoberzin"},"content":" public void fillInRejectionModalTitle(String title) {"},{"lineNumber":474,"author":{"gitId":"domoberzin"},"content":" WebElement rejectionModal \u003d browser.driver.findElement(By.cssSelector(\"tm-reject-with-reason-modal\"));"},{"lineNumber":475,"author":{"gitId":"domoberzin"},"content":" WebElement titleInput \u003d rejectionModal.findElement(By.cssSelector(\"[id^\u003d\u0027rejection-reason-title\u0027]\"));"},{"lineNumber":476,"author":{"gitId":"domoberzin"},"content":" titleInput.clear();"},{"lineNumber":477,"author":{"gitId":"domoberzin"},"content":" titleInput.sendKeys(title);"},{"lineNumber":478,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":479,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":480,"author":{"gitId":"domoberzin"},"content":" public void fillInRejectionModalBody(String body) {"},{"lineNumber":481,"author":{"gitId":"domoberzin"},"content":" WebElement rejectionModal \u003d browser.driver.findElement(By.cssSelector(\"tm-reject-with-reason-modal\"));"},{"lineNumber":482,"author":{"gitId":"domoberzin"},"content":" WebElement bodyInput \u003d rejectionModal.findElement(By.cssSelector(\"tm-rich-text-editor\"));"},{"lineNumber":483,"author":{"gitId":"domoberzin"},"content":" clearRichTextEditor(bodyInput);"},{"lineNumber":484,"author":{"gitId":"domoberzin"},"content":" writeToRichTextEditor(bodyInput, body);"},{"lineNumber":485,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":486,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":487,"author":{"gitId":"domoberzin"},"content":" public void clickConfirmRejectAccountRequest() {"},{"lineNumber":488,"author":{"gitId":"domoberzin"},"content":" WebElement rejectionModal \u003d browser.driver.findElement(By.cssSelector(\"tm-reject-with-reason-modal\"));"},{"lineNumber":489,"author":{"gitId":"domoberzin"},"content":" WebElement clickReject \u003d rejectionModal.findElement(By.cssSelector(\"[id^\u003d\u0027btn-confirm-reject-request\u0027]\"));"},{"lineNumber":490,"author":{"gitId":"domoberzin"},"content":" clickReject.click();"},{"lineNumber":491,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":492,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":493,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":494,"author":{"gitId":"domoberzin"},"content":" public void closeRejectionModal() {"},{"lineNumber":495,"author":{"gitId":"domoberzin"},"content":" WebElement rejectionModal \u003d browser.driver.findElement(By.cssSelector(\"tm-reject-with-reason-modal\"));"},{"lineNumber":496,"author":{"gitId":"domoberzin"},"content":" WebElement clickCancel \u003d rejectionModal.findElement(By.cssSelector(\"[id^\u003d\u0027btn-cancel-reject-request\u0027]\"));"},{"lineNumber":497,"author":{"gitId":"domoberzin"},"content":" clickCancel.click();"},{"lineNumber":498,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":499,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":500,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":501,"author":{"gitId":"domoberzin"},"content":" public void clickEditAccountRequestButton(AccountRequest accountRequest) {"},{"lineNumber":502,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":503,"author":{"gitId":"domoberzin"},"content":" WebElement editButton \u003d accountRequestRow.findElement(By.cssSelector(\"[id^\u003d\u0027edit-account-request-\u0027]\"));"},{"lineNumber":504,"author":{"gitId":"domoberzin"},"content":" editButton.click();"},{"lineNumber":505,"author":{"gitId":"domoberzin"},"content":" waitForElementPresence(By.cssSelector(\"tm-edit-request-modal\"));"},{"lineNumber":506,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":507,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":508,"author":{"gitId":"domoberzin"},"content":" public void fillInEditModalFields(String name, String email, String institute, String comments) {"},{"lineNumber":509,"author":{"gitId":"domoberzin"},"content":" waitForElementPresence(By.cssSelector(\"tm-edit-request-modal\"));"},{"lineNumber":510,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":511,"author":{"gitId":"domoberzin"},"content":" WebElement editModal \u003d browser.driver.findElement(By.cssSelector(\"tm-edit-request-modal\"));"},{"lineNumber":512,"author":{"gitId":"domoberzin"},"content":" WebElement nameInput \u003d editModal.findElement(By.cssSelector(\"[id^\u003d\u0027request-name\u0027]\"));"},{"lineNumber":513,"author":{"gitId":"domoberzin"},"content":" nameInput.clear();"},{"lineNumber":514,"author":{"gitId":"domoberzin"},"content":" nameInput.sendKeys(name);"},{"lineNumber":515,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":516,"author":{"gitId":"domoberzin"},"content":" WebElement emailInput \u003d editModal.findElement(By.cssSelector(\"[id^\u003d\u0027request-email\u0027]\"));"},{"lineNumber":517,"author":{"gitId":"domoberzin"},"content":" emailInput.clear();"},{"lineNumber":518,"author":{"gitId":"domoberzin"},"content":" emailInput.sendKeys(email);"},{"lineNumber":519,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":520,"author":{"gitId":"domoberzin"},"content":" WebElement instituteInput \u003d editModal.findElement(By.cssSelector(\"[id^\u003d\u0027request-institution\u0027]\"));"},{"lineNumber":521,"author":{"gitId":"domoberzin"},"content":" instituteInput.clear();"},{"lineNumber":522,"author":{"gitId":"domoberzin"},"content":" instituteInput.sendKeys(institute);"},{"lineNumber":523,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":524,"author":{"gitId":"domoberzin"},"content":" WebElement commentsInput \u003d editModal.findElement(By.cssSelector(\"[id^\u003d\u0027request-comments\u0027]\"));"},{"lineNumber":525,"author":{"gitId":"domoberzin"},"content":" commentsInput.clear();"},{"lineNumber":526,"author":{"gitId":"domoberzin"},"content":" commentsInput.sendKeys(comments);"},{"lineNumber":527,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":528,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":529,"author":{"gitId":"domoberzin"},"content":" public void clickSaveEditAccountRequestButton() {"},{"lineNumber":530,"author":{"gitId":"domoberzin"},"content":" WebElement editModal \u003d browser.driver.findElement(By.cssSelector(\"tm-edit-request-modal\"));"},{"lineNumber":531,"author":{"gitId":"domoberzin"},"content":" WebElement saveButton \u003d editModal.findElement(By.cssSelector(\"[id^\u003d\u0027btn-confirm-edit-request\u0027]\"));"},{"lineNumber":532,"author":{"gitId":"domoberzin"},"content":" saveButton.click();"},{"lineNumber":533,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":534,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":535,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":536,"author":{"gitId":"domoberzin"},"content":" public void clickViewAccountRequestAndVerifyCommentsButton(AccountRequest accountRequest, String comments) {"},{"lineNumber":537,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":538,"author":{"gitId":"domoberzin"},"content":" WebElement viewCommentsButton \u003d accountRequestRow.findElement(By.cssSelector(\"[id^\u003d\u0027view-account-request-\u0027]\"));"},{"lineNumber":539,"author":{"gitId":"domoberzin"},"content":" viewCommentsButton.click();"},{"lineNumber":540,"author":{"gitId":"domoberzin"},"content":" waitForElementVisibility(By.className(\"modal-btn-ok\"));"},{"lineNumber":541,"author":{"gitId":"domoberzin"},"content":" WebElement modal \u003d browser.driver.findElement(By.className(\"modal-body\"));"},{"lineNumber":542,"author":{"gitId":"domoberzin"},"content":" String actualComments \u003d modal.findElement(By.tagName(\"div\")).getText();"},{"lineNumber":543,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"Comment: \" + comments, actualComments);"},{"lineNumber":544,"author":{"gitId":"domoberzin"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":545,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":546,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":547,"author":{"gitId":"-"},"content":" public void clickResetAccountRequestButton(AccountRequestAttributes accountRequest) {"},{"lineNumber":548,"author":{"gitId":"-"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":549,"author":{"gitId":"-"},"content":" WebElement deleteButton \u003d accountRequestRow.findElement(By.cssSelector(\"[id^\u003d\u0027reset-account-request-\u0027]\"));"},{"lineNumber":550,"author":{"gitId":"-"},"content":" deleteButton.click();"},{"lineNumber":551,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":552,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":553,"author":{"gitId":"-"},"content":" }"},{"lineNumber":554,"author":{"gitId":"-"},"content":""},{"lineNumber":555,"author":{"gitId":"domoberzin"},"content":" public void clickResetAccountRequestButton(AccountRequest accountRequest) {"},{"lineNumber":556,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":557,"author":{"gitId":"domoberzin"},"content":" WebElement deleteButton \u003d accountRequestRow.findElement(By.cssSelector(\"[id^\u003d\u0027reset-account-request-\u0027]\"));"},{"lineNumber":558,"author":{"gitId":"domoberzin"},"content":" deleteButton.click();"},{"lineNumber":559,"author":{"gitId":"domoberzin"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":560,"author":{"gitId":"domoberzin"},"content":" waitForPageToLoad();"},{"lineNumber":561,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":562,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":563,"author":{"gitId":"-"},"content":" public int getNumExpandedRows(WebElement row) {"},{"lineNumber":564,"author":{"gitId":"-"},"content":" String xpath \u003d \"following-sibling::tr[1]/td/ul/li\";"},{"lineNumber":565,"author":{"gitId":"-"},"content":" return row.findElements(By.xpath(xpath)).size();"},{"lineNumber":566,"author":{"gitId":"-"},"content":" }"},{"lineNumber":567,"author":{"gitId":"-"},"content":""},{"lineNumber":568,"author":{"gitId":"-"},"content":" private String getColumnText(WebElement row, int columnNum) {"},{"lineNumber":569,"author":{"gitId":"-"},"content":" String xpath \u003d String.format(\"td[%d]\", columnNum);"},{"lineNumber":570,"author":{"gitId":"-"},"content":" return row.findElement(By.xpath(xpath)).getText();"},{"lineNumber":571,"author":{"gitId":"-"},"content":" }"},{"lineNumber":572,"author":{"gitId":"-"},"content":""},{"lineNumber":573,"author":{"gitId":"-"},"content":" private String getColumnLink(WebElement row, int columnNum) {"},{"lineNumber":574,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":575,"author":{"gitId":"-"},"content":" String xpath \u003d String.format(\"td[%d]/a\", columnNum);"},{"lineNumber":576,"author":{"gitId":"-"},"content":" return row.findElement(By.xpath(xpath)).getAttribute(\"href\");"},{"lineNumber":577,"author":{"gitId":"-"},"content":" } catch (NoSuchElementException e) {"},{"lineNumber":578,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":579,"author":{"gitId":"-"},"content":" }"},{"lineNumber":580,"author":{"gitId":"-"},"content":" }"},{"lineNumber":581,"author":{"gitId":"-"},"content":""},{"lineNumber":582,"author":{"gitId":"-"},"content":" private String getExpandedRowInputValue(WebElement row, String rowHeader) {"},{"lineNumber":583,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":584,"author":{"gitId":"-"},"content":" String xpath \u003d String.format(\"following-sibling::tr[1]/td/ul/li[contains(., \u0027%s\u0027)]/input\", rowHeader);"},{"lineNumber":585,"author":{"gitId":"-"},"content":" return row.findElement(By.xpath(xpath)).getAttribute(\"value\");"},{"lineNumber":586,"author":{"gitId":"-"},"content":" } catch (NoSuchElementException e) {"},{"lineNumber":587,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":588,"author":{"gitId":"-"},"content":" }"},{"lineNumber":589,"author":{"gitId":"-"},"content":" }"},{"lineNumber":590,"author":{"gitId":"-"},"content":""},{"lineNumber":591,"author":{"gitId":"-"},"content":" public void verifyStudentRowContent(Student student, Course course,"},{"lineNumber":592,"author":{"gitId":"-"},"content":" String expectedDetails, String expectedManageAccountLink,"},{"lineNumber":593,"author":{"gitId":"-"},"content":" String expectedHomePageLink) {"},{"lineNumber":594,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":595,"author":{"gitId":"-"},"content":" String actualDetails \u003d getStudentDetails(studentRow);"},{"lineNumber":596,"author":{"gitId":"-"},"content":" String actualName \u003d getStudentName(studentRow);"},{"lineNumber":597,"author":{"gitId":"-"},"content":" String actualGoogleId \u003d getStudentGoogleId(studentRow);"},{"lineNumber":598,"author":{"gitId":"-"},"content":" String actualHomepageLink \u003d getStudentHomeLink(studentRow);"},{"lineNumber":599,"author":{"gitId":"-"},"content":" String actualInstitute \u003d getStudentInstitute(studentRow);"},{"lineNumber":600,"author":{"gitId":"-"},"content":" String actualComment \u003d getStudentComments(studentRow);"},{"lineNumber":601,"author":{"gitId":"-"},"content":" String actualManageAccountLink \u003d getStudentManageAccountLink(studentRow);"},{"lineNumber":602,"author":{"gitId":"-"},"content":""},{"lineNumber":603,"author":{"gitId":"-"},"content":" String expectedName \u003d student.getName();"},{"lineNumber":604,"author":{"gitId":"-"},"content":" String expectedGoogleId \u003d StringHelper.convertToEmptyStringIfNull(student.getGoogleId());"},{"lineNumber":605,"author":{"gitId":"-"},"content":" String expectedInstitute \u003d StringHelper.convertToEmptyStringIfNull(course.getInstitute());"},{"lineNumber":606,"author":{"gitId":"-"},"content":" String expectedComment \u003d StringHelper.convertToEmptyStringIfNull(student.getComments());"},{"lineNumber":607,"author":{"gitId":"-"},"content":""},{"lineNumber":608,"author":{"gitId":"-"},"content":" assertEquals(expectedDetails, actualDetails);"},{"lineNumber":609,"author":{"gitId":"-"},"content":" assertEquals(expectedName, actualName);"},{"lineNumber":610,"author":{"gitId":"-"},"content":" assertEquals(expectedGoogleId, actualGoogleId);"},{"lineNumber":611,"author":{"gitId":"-"},"content":" assertEquals(expectedInstitute, actualInstitute);"},{"lineNumber":612,"author":{"gitId":"-"},"content":" assertEquals(expectedComment, actualComment);"},{"lineNumber":613,"author":{"gitId":"-"},"content":" assertEquals(expectedManageAccountLink, actualManageAccountLink);"},{"lineNumber":614,"author":{"gitId":"-"},"content":" assertEquals(expectedHomePageLink, actualHomepageLink);"},{"lineNumber":615,"author":{"gitId":"-"},"content":" }"},{"lineNumber":616,"author":{"gitId":"-"},"content":""},{"lineNumber":617,"author":{"gitId":"-"},"content":" public void verifyStudentRowContent(StudentAttributes student, CourseAttributes course,"},{"lineNumber":618,"author":{"gitId":"-"},"content":" String expectedDetails, String expectedManageAccountLink,"},{"lineNumber":619,"author":{"gitId":"-"},"content":" String expectedHomePageLink) {"},{"lineNumber":620,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":621,"author":{"gitId":"-"},"content":" String actualDetails \u003d getStudentDetails(studentRow);"},{"lineNumber":622,"author":{"gitId":"-"},"content":" String actualName \u003d getStudentName(studentRow);"},{"lineNumber":623,"author":{"gitId":"-"},"content":" String actualGoogleId \u003d getStudentGoogleId(studentRow);"},{"lineNumber":624,"author":{"gitId":"-"},"content":" String actualHomepageLink \u003d getStudentHomeLink(studentRow);"},{"lineNumber":625,"author":{"gitId":"-"},"content":" String actualInstitute \u003d getStudentInstitute(studentRow);"},{"lineNumber":626,"author":{"gitId":"-"},"content":" String actualComment \u003d getStudentComments(studentRow);"},{"lineNumber":627,"author":{"gitId":"-"},"content":" String actualManageAccountLink \u003d getStudentManageAccountLink(studentRow);"},{"lineNumber":628,"author":{"gitId":"-"},"content":""},{"lineNumber":629,"author":{"gitId":"-"},"content":" String expectedName \u003d student.getName();"},{"lineNumber":630,"author":{"gitId":"-"},"content":" String expectedGoogleId \u003d StringHelper.convertToEmptyStringIfNull(student.getGoogleId());"},{"lineNumber":631,"author":{"gitId":"-"},"content":" String expectedInstitute \u003d StringHelper.convertToEmptyStringIfNull(course.getInstitute());"},{"lineNumber":632,"author":{"gitId":"-"},"content":" String expectedComment \u003d StringHelper.convertToEmptyStringIfNull(student.getComments());"},{"lineNumber":633,"author":{"gitId":"-"},"content":""},{"lineNumber":634,"author":{"gitId":"-"},"content":" assertEquals(expectedDetails, actualDetails);"},{"lineNumber":635,"author":{"gitId":"-"},"content":" assertEquals(expectedName, actualName);"},{"lineNumber":636,"author":{"gitId":"-"},"content":" assertEquals(expectedGoogleId, actualGoogleId);"},{"lineNumber":637,"author":{"gitId":"-"},"content":" assertEquals(expectedInstitute, actualInstitute);"},{"lineNumber":638,"author":{"gitId":"-"},"content":" assertEquals(expectedComment, actualComment);"},{"lineNumber":639,"author":{"gitId":"-"},"content":" assertEquals(expectedManageAccountLink, actualManageAccountLink);"},{"lineNumber":640,"author":{"gitId":"-"},"content":" assertEquals(expectedHomePageLink, actualHomepageLink);"},{"lineNumber":641,"author":{"gitId":"-"},"content":" }"},{"lineNumber":642,"author":{"gitId":"-"},"content":""},{"lineNumber":643,"author":{"gitId":"-"},"content":" public void verifyStudentRowContentAfterReset(Student student, Course course) {"},{"lineNumber":644,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":645,"author":{"gitId":"-"},"content":" String actualName \u003d getStudentName(studentRow);"},{"lineNumber":646,"author":{"gitId":"-"},"content":" String actualInstitute \u003d getStudentInstitute(studentRow);"},{"lineNumber":647,"author":{"gitId":"-"},"content":" String actualComment \u003d getStudentComments(studentRow);"},{"lineNumber":648,"author":{"gitId":"-"},"content":""},{"lineNumber":649,"author":{"gitId":"-"},"content":" String expectedName \u003d student.getName();"},{"lineNumber":650,"author":{"gitId":"-"},"content":" String expectedInstitute \u003d StringHelper.convertToEmptyStringIfNull(course.getInstitute());"},{"lineNumber":651,"author":{"gitId":"-"},"content":" String expectedComment \u003d StringHelper.convertToEmptyStringIfNull(student.getComments());"},{"lineNumber":652,"author":{"gitId":"-"},"content":""},{"lineNumber":653,"author":{"gitId":"-"},"content":" assertEquals(expectedName, actualName);"},{"lineNumber":654,"author":{"gitId":"-"},"content":" assertEquals(expectedInstitute, actualInstitute);"},{"lineNumber":655,"author":{"gitId":"-"},"content":" assertEquals(expectedComment, actualComment);"},{"lineNumber":656,"author":{"gitId":"-"},"content":" }"},{"lineNumber":657,"author":{"gitId":"-"},"content":""},{"lineNumber":658,"author":{"gitId":"-"},"content":" public void verifyStudentExpandedLinks(Student student, int expectedNumExpandedRows) {"},{"lineNumber":659,"author":{"gitId":"-"},"content":" clickExpandStudentLinks();"},{"lineNumber":660,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":661,"author":{"gitId":"-"},"content":" String actualEmail \u003d getStudentEmail(studentRow);"},{"lineNumber":662,"author":{"gitId":"-"},"content":" String actualJoinLink \u003d getStudentJoinLink(studentRow);"},{"lineNumber":663,"author":{"gitId":"-"},"content":" int actualNumExpandedRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":664,"author":{"gitId":"-"},"content":""},{"lineNumber":665,"author":{"gitId":"-"},"content":" String expectedEmail \u003d student.getEmail();"},{"lineNumber":666,"author":{"gitId":"-"},"content":""},{"lineNumber":667,"author":{"gitId":"-"},"content":" assertEquals(expectedEmail, actualEmail);"},{"lineNumber":668,"author":{"gitId":"-"},"content":" assertNotEquals(\"\", actualJoinLink);"},{"lineNumber":669,"author":{"gitId":"-"},"content":" assertEquals(expectedNumExpandedRows, actualNumExpandedRows);"},{"lineNumber":670,"author":{"gitId":"-"},"content":" }"},{"lineNumber":671,"author":{"gitId":"-"},"content":""},{"lineNumber":672,"author":{"gitId":"-"},"content":" public void verifyStudentExpandedLinks(StudentAttributes student, int expectedNumExpandedRows) {"},{"lineNumber":673,"author":{"gitId":"-"},"content":" clickExpandStudentLinks();"},{"lineNumber":674,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":675,"author":{"gitId":"-"},"content":" String actualEmail \u003d getStudentEmail(studentRow);"},{"lineNumber":676,"author":{"gitId":"-"},"content":" String actualJoinLink \u003d getStudentJoinLink(studentRow);"},{"lineNumber":677,"author":{"gitId":"-"},"content":" int actualNumExpandedRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":678,"author":{"gitId":"-"},"content":""},{"lineNumber":679,"author":{"gitId":"-"},"content":" String expectedEmail \u003d student.getEmail();"},{"lineNumber":680,"author":{"gitId":"-"},"content":""},{"lineNumber":681,"author":{"gitId":"-"},"content":" assertEquals(expectedEmail, actualEmail);"},{"lineNumber":682,"author":{"gitId":"-"},"content":" assertNotEquals(\"\", actualJoinLink);"},{"lineNumber":683,"author":{"gitId":"-"},"content":" assertEquals(expectedNumExpandedRows, actualNumExpandedRows);"},{"lineNumber":684,"author":{"gitId":"-"},"content":" }"},{"lineNumber":685,"author":{"gitId":"-"},"content":""},{"lineNumber":686,"author":{"gitId":"-"},"content":" public void verifyInstructorRowContent(Instructor instructor, Course course,"},{"lineNumber":687,"author":{"gitId":"-"},"content":" String expectedManageAccountLink, String expectedHomePageLink) {"},{"lineNumber":688,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":689,"author":{"gitId":"-"},"content":" String actualCourseId \u003d getInstructorCourseId(instructorRow);"},{"lineNumber":690,"author":{"gitId":"-"},"content":" String actualName \u003d getInstructorName(instructorRow);"},{"lineNumber":691,"author":{"gitId":"-"},"content":" String actualGoogleId \u003d getInstructorGoogleId(instructorRow);"},{"lineNumber":692,"author":{"gitId":"-"},"content":" String actualHomePageLink \u003d getInstructorHomePageLink(instructorRow);"},{"lineNumber":693,"author":{"gitId":"-"},"content":" String actualInstitute \u003d getInstructorInstitute(instructorRow);"},{"lineNumber":694,"author":{"gitId":"-"},"content":" String actualManageAccountLink \u003d getInstructorManageAccountLink(instructorRow);"},{"lineNumber":695,"author":{"gitId":"-"},"content":""},{"lineNumber":696,"author":{"gitId":"-"},"content":" String expectedCourseId \u003d instructor.getCourseId();"},{"lineNumber":697,"author":{"gitId":"-"},"content":" String expectedName \u003d instructor.getName();"},{"lineNumber":698,"author":{"gitId":"-"},"content":" String expectedGoogleId \u003d StringHelper.convertToEmptyStringIfNull(instructor.getGoogleId());"},{"lineNumber":699,"author":{"gitId":"-"},"content":" String expectedInstitute \u003d StringHelper.convertToEmptyStringIfNull(course.getInstitute());"},{"lineNumber":700,"author":{"gitId":"-"},"content":""},{"lineNumber":701,"author":{"gitId":"-"},"content":" assertEquals(expectedCourseId, actualCourseId);"},{"lineNumber":702,"author":{"gitId":"-"},"content":" assertEquals(expectedName, actualName);"},{"lineNumber":703,"author":{"gitId":"-"},"content":" assertEquals(expectedGoogleId, actualGoogleId);"},{"lineNumber":704,"author":{"gitId":"-"},"content":" assertEquals(expectedHomePageLink, actualHomePageLink);"},{"lineNumber":705,"author":{"gitId":"-"},"content":" assertEquals(expectedInstitute, actualInstitute);"},{"lineNumber":706,"author":{"gitId":"-"},"content":" assertEquals(expectedManageAccountLink, actualManageAccountLink);"},{"lineNumber":707,"author":{"gitId":"-"},"content":" }"},{"lineNumber":708,"author":{"gitId":"-"},"content":""},{"lineNumber":709,"author":{"gitId":"-"},"content":" public void verifyInstructorRowContent(InstructorAttributes instructor, CourseAttributes course,"},{"lineNumber":710,"author":{"gitId":"-"},"content":" String expectedManageAccountLink, String expectedHomePageLink) {"},{"lineNumber":711,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":712,"author":{"gitId":"-"},"content":" String actualCourseId \u003d getInstructorCourseId(instructorRow);"},{"lineNumber":713,"author":{"gitId":"-"},"content":" String actualName \u003d getInstructorName(instructorRow);"},{"lineNumber":714,"author":{"gitId":"-"},"content":" String actualGoogleId \u003d getInstructorGoogleId(instructorRow);"},{"lineNumber":715,"author":{"gitId":"-"},"content":" String actualHomePageLink \u003d getInstructorHomePageLink(instructorRow);"},{"lineNumber":716,"author":{"gitId":"-"},"content":" String actualInstitute \u003d getInstructorInstitute(instructorRow);"},{"lineNumber":717,"author":{"gitId":"-"},"content":" String actualManageAccountLink \u003d getInstructorManageAccountLink(instructorRow);"},{"lineNumber":718,"author":{"gitId":"-"},"content":""},{"lineNumber":719,"author":{"gitId":"-"},"content":" String expectedCourseId \u003d instructor.getCourseId();"},{"lineNumber":720,"author":{"gitId":"-"},"content":" String expectedName \u003d instructor.getName();"},{"lineNumber":721,"author":{"gitId":"-"},"content":" String expectedGoogleId \u003d StringHelper.convertToEmptyStringIfNull(instructor.getGoogleId());"},{"lineNumber":722,"author":{"gitId":"-"},"content":" String expectedInstitute \u003d StringHelper.convertToEmptyStringIfNull(course.getInstitute());"},{"lineNumber":723,"author":{"gitId":"-"},"content":""},{"lineNumber":724,"author":{"gitId":"-"},"content":" assertEquals(expectedCourseId, actualCourseId);"},{"lineNumber":725,"author":{"gitId":"-"},"content":" assertEquals(expectedName, actualName);"},{"lineNumber":726,"author":{"gitId":"-"},"content":" assertEquals(expectedGoogleId, actualGoogleId);"},{"lineNumber":727,"author":{"gitId":"-"},"content":" assertEquals(expectedHomePageLink, actualHomePageLink);"},{"lineNumber":728,"author":{"gitId":"-"},"content":" assertEquals(expectedInstitute, actualInstitute);"},{"lineNumber":729,"author":{"gitId":"-"},"content":" assertEquals(expectedManageAccountLink, actualManageAccountLink);"},{"lineNumber":730,"author":{"gitId":"-"},"content":" }"},{"lineNumber":731,"author":{"gitId":"-"},"content":""},{"lineNumber":732,"author":{"gitId":"-"},"content":" public void verifyInstructorRowContentAfterReset(Instructor instructor, Course course) {"},{"lineNumber":733,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":734,"author":{"gitId":"-"},"content":" String actualCourseId \u003d getInstructorCourseId(instructorRow);"},{"lineNumber":735,"author":{"gitId":"-"},"content":" String actualName \u003d getInstructorName(instructorRow);"},{"lineNumber":736,"author":{"gitId":"-"},"content":" String actualInstitute \u003d getInstructorInstitute(instructorRow);"},{"lineNumber":737,"author":{"gitId":"-"},"content":""},{"lineNumber":738,"author":{"gitId":"-"},"content":" String expectedCourseId \u003d instructor.getCourseId();"},{"lineNumber":739,"author":{"gitId":"-"},"content":" String expectedName \u003d instructor.getName();"},{"lineNumber":740,"author":{"gitId":"-"},"content":" String expectedInstitute \u003d StringHelper.convertToEmptyStringIfNull(course.getInstitute());"},{"lineNumber":741,"author":{"gitId":"-"},"content":""},{"lineNumber":742,"author":{"gitId":"-"},"content":" assertEquals(expectedCourseId, actualCourseId);"},{"lineNumber":743,"author":{"gitId":"-"},"content":" assertEquals(expectedName, actualName);"},{"lineNumber":744,"author":{"gitId":"-"},"content":" assertEquals(expectedInstitute, actualInstitute);"},{"lineNumber":745,"author":{"gitId":"-"},"content":" }"},{"lineNumber":746,"author":{"gitId":"-"},"content":""},{"lineNumber":747,"author":{"gitId":"-"},"content":" public void verifyInstructorExpandedLinks(Instructor instructor) {"},{"lineNumber":748,"author":{"gitId":"-"},"content":" clickExpandInstructorLinks();"},{"lineNumber":749,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":750,"author":{"gitId":"-"},"content":" String actualEmail \u003d getInstructorEmail(instructorRow);"},{"lineNumber":751,"author":{"gitId":"-"},"content":" String actualJoinLink \u003d getInstructorJoinLink(instructorRow);"},{"lineNumber":752,"author":{"gitId":"-"},"content":""},{"lineNumber":753,"author":{"gitId":"-"},"content":" String expectedEmail \u003d instructor.getEmail();"},{"lineNumber":754,"author":{"gitId":"-"},"content":""},{"lineNumber":755,"author":{"gitId":"-"},"content":" assertEquals(expectedEmail, actualEmail);"},{"lineNumber":756,"author":{"gitId":"-"},"content":" assertNotEquals(\"\", actualJoinLink);"},{"lineNumber":757,"author":{"gitId":"-"},"content":" }"},{"lineNumber":758,"author":{"gitId":"-"},"content":""},{"lineNumber":759,"author":{"gitId":"-"},"content":" public void verifyInstructorExpandedLinks(InstructorAttributes instructor) {"},{"lineNumber":760,"author":{"gitId":"-"},"content":" clickExpandInstructorLinks();"},{"lineNumber":761,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":762,"author":{"gitId":"-"},"content":" String actualEmail \u003d getInstructorEmail(instructorRow);"},{"lineNumber":763,"author":{"gitId":"-"},"content":" String actualJoinLink \u003d getInstructorJoinLink(instructorRow);"},{"lineNumber":764,"author":{"gitId":"-"},"content":""},{"lineNumber":765,"author":{"gitId":"-"},"content":" String expectedEmail \u003d instructor.getEmail();"},{"lineNumber":766,"author":{"gitId":"-"},"content":""},{"lineNumber":767,"author":{"gitId":"-"},"content":" assertEquals(expectedEmail, actualEmail);"},{"lineNumber":768,"author":{"gitId":"-"},"content":" assertNotEquals(\"\", actualJoinLink);"},{"lineNumber":769,"author":{"gitId":"-"},"content":" }"},{"lineNumber":770,"author":{"gitId":"-"},"content":""},{"lineNumber":771,"author":{"gitId":"-"},"content":" public void verifyAccountRequestRowContent(AccountRequestAttributes accountRequest) {"},{"lineNumber":772,"author":{"gitId":"-"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":773,"author":{"gitId":"-"},"content":" String actualName \u003d getAccountRequestName(accountRequestRow);"},{"lineNumber":774,"author":{"gitId":"-"},"content":" String actualEmail \u003d getAccountRequestEmail(accountRequestRow);"},{"lineNumber":775,"author":{"gitId":"-"},"content":" String actualInstitute \u003d getAccountRequestInstitute(accountRequestRow);"},{"lineNumber":776,"author":{"gitId":"-"},"content":" String actualCreatedAt \u003d getAccountRequestCreatedAt(accountRequestRow);"},{"lineNumber":777,"author":{"gitId":"-"},"content":" String actualRegisteredAt \u003d getAccountRequestRegisteredAt(accountRequestRow);"},{"lineNumber":778,"author":{"gitId":"-"},"content":""},{"lineNumber":779,"author":{"gitId":"-"},"content":" assertEquals(accountRequest.getName(), actualName);"},{"lineNumber":780,"author":{"gitId":"-"},"content":" assertEquals(accountRequest.getEmail(), actualEmail);"},{"lineNumber":781,"author":{"gitId":"-"},"content":" assertEquals(accountRequest.getInstitute(), actualInstitute);"},{"lineNumber":782,"author":{"gitId":"-"},"content":" assertFalse(actualCreatedAt.isBlank());"},{"lineNumber":783,"author":{"gitId":"-"},"content":" if (accountRequest.getRegisteredAt() \u003d\u003d null) {"},{"lineNumber":784,"author":{"gitId":"-"},"content":" assertEquals(\"Not Registered Yet\", actualRegisteredAt);"},{"lineNumber":785,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":786,"author":{"gitId":"-"},"content":" assertFalse(actualRegisteredAt.isBlank());"},{"lineNumber":787,"author":{"gitId":"-"},"content":" }"},{"lineNumber":788,"author":{"gitId":"-"},"content":" }"},{"lineNumber":789,"author":{"gitId":"-"},"content":""},{"lineNumber":790,"author":{"gitId":"domoberzin"},"content":" public void verifyAccountRequestRowContent(AccountRequest accountRequest) {"},{"lineNumber":791,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":792,"author":{"gitId":"domoberzin"},"content":" String actualName \u003d getAccountRequestName(accountRequestRow);"},{"lineNumber":793,"author":{"gitId":"domoberzin"},"content":" String actualEmail \u003d getAccountRequestEmail(accountRequestRow);"},{"lineNumber":794,"author":{"gitId":"domoberzin"},"content":" String actualInstitute \u003d getAccountRequestInstitute(accountRequestRow);"},{"lineNumber":795,"author":{"gitId":"domoberzin"},"content":" String actualCreatedAt \u003d getAccountRequestCreatedAt(accountRequestRow);"},{"lineNumber":796,"author":{"gitId":"domoberzin"},"content":" String actualRegisteredAt \u003d getAccountRequestRegisteredAt(accountRequestRow);"},{"lineNumber":797,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":798,"author":{"gitId":"domoberzin"},"content":" assertEquals(accountRequest.getName(), actualName);"},{"lineNumber":799,"author":{"gitId":"domoberzin"},"content":" assertEquals(accountRequest.getEmail(), actualEmail);"},{"lineNumber":800,"author":{"gitId":"domoberzin"},"content":" assertEquals(accountRequest.getInstitute(), actualInstitute);"},{"lineNumber":801,"author":{"gitId":"domoberzin"},"content":" assertFalse(actualCreatedAt.isBlank());"},{"lineNumber":802,"author":{"gitId":"domoberzin"},"content":" if (accountRequest.getRegisteredAt() \u003d\u003d null) {"},{"lineNumber":803,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"Not Registered Yet\", actualRegisteredAt);"},{"lineNumber":804,"author":{"gitId":"domoberzin"},"content":" } else {"},{"lineNumber":805,"author":{"gitId":"domoberzin"},"content":" assertFalse(actualRegisteredAt.isBlank());"},{"lineNumber":806,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":807,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":808,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":809,"author":{"gitId":"-"},"content":" public void verifyAccountRequestExpandedLinks(AccountRequestAttributes accountRequest) {"},{"lineNumber":810,"author":{"gitId":"-"},"content":" clickExpandAccountRequestLinks();"},{"lineNumber":811,"author":{"gitId":"-"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":812,"author":{"gitId":"-"},"content":" String actualRegistrationLink \u003d getAccountRequestRegistrationLink(accountRequestRow);"},{"lineNumber":813,"author":{"gitId":"-"},"content":""},{"lineNumber":814,"author":{"gitId":"-"},"content":" assertFalse(actualRegistrationLink.isBlank());"},{"lineNumber":815,"author":{"gitId":"-"},"content":" }"},{"lineNumber":816,"author":{"gitId":"-"},"content":""},{"lineNumber":817,"author":{"gitId":"domoberzin"},"content":" public void verifyAccountRequestExpandedLinks(AccountRequest accountRequest) {"},{"lineNumber":818,"author":{"gitId":"domoberzin"},"content":" clickExpandAccountRequestLinks();"},{"lineNumber":819,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":820,"author":{"gitId":"domoberzin"},"content":" String actualRegistrationLink \u003d getAccountRequestRegistrationLink(accountRequestRow);"},{"lineNumber":821,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":822,"author":{"gitId":"domoberzin"},"content":" assertFalse(actualRegistrationLink.isBlank());"},{"lineNumber":823,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":824,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":825,"author":{"gitId":"-"},"content":" public void verifyLinkExpansionButtons(Student student,"},{"lineNumber":826,"author":{"gitId":"-"},"content":" Instructor instructor, AccountRequest accountRequest) {"},{"lineNumber":827,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":828,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":829,"author":{"gitId":"-"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":830,"author":{"gitId":"-"},"content":""},{"lineNumber":831,"author":{"gitId":"-"},"content":" clickExpandStudentLinks();"},{"lineNumber":832,"author":{"gitId":"-"},"content":" clickExpandInstructorLinks();"},{"lineNumber":833,"author":{"gitId":"-"},"content":" clickExpandAccountRequestLinks();"},{"lineNumber":834,"author":{"gitId":"-"},"content":" int numExpandedStudentRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":835,"author":{"gitId":"-"},"content":" int numExpandedInstructorRows \u003d getNumExpandedRows(instructorRow);"},{"lineNumber":836,"author":{"gitId":"-"},"content":" int numExpandedAccountRequestRows \u003d getNumExpandedRows(accountRequestRow);"},{"lineNumber":837,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedStudentRows, 0);"},{"lineNumber":838,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedInstructorRows, 0);"},{"lineNumber":839,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedAccountRequestRows, 0);"},{"lineNumber":840,"author":{"gitId":"-"},"content":""},{"lineNumber":841,"author":{"gitId":"-"},"content":" clickCollapseInstructorLinks();"},{"lineNumber":842,"author":{"gitId":"-"},"content":" numExpandedStudentRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":843,"author":{"gitId":"-"},"content":" numExpandedInstructorRows \u003d getNumExpandedRows(instructorRow);"},{"lineNumber":844,"author":{"gitId":"-"},"content":" numExpandedAccountRequestRows \u003d getNumExpandedRows(accountRequestRow);"},{"lineNumber":845,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedStudentRows, 0);"},{"lineNumber":846,"author":{"gitId":"-"},"content":" assertEquals(numExpandedInstructorRows, 0);"},{"lineNumber":847,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedAccountRequestRows, 0);"},{"lineNumber":848,"author":{"gitId":"-"},"content":""},{"lineNumber":849,"author":{"gitId":"-"},"content":" clickExpandInstructorLinks();"},{"lineNumber":850,"author":{"gitId":"-"},"content":" clickCollapseStudentLinks();"},{"lineNumber":851,"author":{"gitId":"-"},"content":" clickCollapseAccountRequestLinks();"},{"lineNumber":852,"author":{"gitId":"-"},"content":" waitUntilAnimationFinish();"},{"lineNumber":853,"author":{"gitId":"-"},"content":""},{"lineNumber":854,"author":{"gitId":"-"},"content":" numExpandedStudentRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":855,"author":{"gitId":"-"},"content":" numExpandedInstructorRows \u003d getNumExpandedRows(instructorRow);"},{"lineNumber":856,"author":{"gitId":"-"},"content":" numExpandedAccountRequestRows \u003d getNumExpandedRows(accountRequestRow);"},{"lineNumber":857,"author":{"gitId":"-"},"content":" assertEquals(numExpandedStudentRows, 0);"},{"lineNumber":858,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedInstructorRows, 0);"},{"lineNumber":859,"author":{"gitId":"-"},"content":" assertEquals(numExpandedAccountRequestRows, 0);"},{"lineNumber":860,"author":{"gitId":"-"},"content":" }"},{"lineNumber":861,"author":{"gitId":"-"},"content":""},{"lineNumber":862,"author":{"gitId":"-"},"content":" public void verifyLinkExpansionButtons(StudentAttributes student,"},{"lineNumber":863,"author":{"gitId":"-"},"content":" InstructorAttributes instructor, AccountRequestAttributes accountRequest) {"},{"lineNumber":864,"author":{"gitId":"-"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":865,"author":{"gitId":"-"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":866,"author":{"gitId":"-"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":867,"author":{"gitId":"-"},"content":""},{"lineNumber":868,"author":{"gitId":"-"},"content":" clickExpandStudentLinks();"},{"lineNumber":869,"author":{"gitId":"-"},"content":" clickExpandInstructorLinks();"},{"lineNumber":870,"author":{"gitId":"-"},"content":" clickExpandAccountRequestLinks();"},{"lineNumber":871,"author":{"gitId":"-"},"content":" int numExpandedStudentRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":872,"author":{"gitId":"-"},"content":" int numExpandedInstructorRows \u003d getNumExpandedRows(instructorRow);"},{"lineNumber":873,"author":{"gitId":"-"},"content":" int numExpandedAccountRequestRows \u003d getNumExpandedRows(accountRequestRow);"},{"lineNumber":874,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedStudentRows, 0);"},{"lineNumber":875,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedInstructorRows, 0);"},{"lineNumber":876,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedAccountRequestRows, 0);"},{"lineNumber":877,"author":{"gitId":"-"},"content":""},{"lineNumber":878,"author":{"gitId":"-"},"content":" clickCollapseInstructorLinks();"},{"lineNumber":879,"author":{"gitId":"-"},"content":" numExpandedStudentRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":880,"author":{"gitId":"-"},"content":" numExpandedInstructorRows \u003d getNumExpandedRows(instructorRow);"},{"lineNumber":881,"author":{"gitId":"-"},"content":" numExpandedAccountRequestRows \u003d getNumExpandedRows(accountRequestRow);"},{"lineNumber":882,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedStudentRows, 0);"},{"lineNumber":883,"author":{"gitId":"-"},"content":" assertEquals(numExpandedInstructorRows, 0);"},{"lineNumber":884,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedAccountRequestRows, 0);"},{"lineNumber":885,"author":{"gitId":"-"},"content":""},{"lineNumber":886,"author":{"gitId":"-"},"content":" clickExpandInstructorLinks();"},{"lineNumber":887,"author":{"gitId":"-"},"content":" clickCollapseStudentLinks();"},{"lineNumber":888,"author":{"gitId":"-"},"content":" clickCollapseAccountRequestLinks();"},{"lineNumber":889,"author":{"gitId":"-"},"content":" waitUntilAnimationFinish();"},{"lineNumber":890,"author":{"gitId":"-"},"content":""},{"lineNumber":891,"author":{"gitId":"-"},"content":" numExpandedStudentRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":892,"author":{"gitId":"-"},"content":" numExpandedInstructorRows \u003d getNumExpandedRows(instructorRow);"},{"lineNumber":893,"author":{"gitId":"-"},"content":" numExpandedAccountRequestRows \u003d getNumExpandedRows(accountRequestRow);"},{"lineNumber":894,"author":{"gitId":"-"},"content":" assertEquals(numExpandedStudentRows, 0);"},{"lineNumber":895,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedInstructorRows, 0);"},{"lineNumber":896,"author":{"gitId":"-"},"content":" assertEquals(numExpandedAccountRequestRows, 0);"},{"lineNumber":897,"author":{"gitId":"-"},"content":" }"},{"lineNumber":898,"author":{"gitId":"-"},"content":""},{"lineNumber":899,"author":{"gitId":"domoberzin"},"content":" public void verifyLinkExpansionButtons(StudentAttributes student,"},{"lineNumber":900,"author":{"gitId":"domoberzin"},"content":" InstructorAttributes instructor, AccountRequest accountRequest) {"},{"lineNumber":901,"author":{"gitId":"domoberzin"},"content":" WebElement studentRow \u003d getStudentRow(student);"},{"lineNumber":902,"author":{"gitId":"domoberzin"},"content":" WebElement instructorRow \u003d getInstructorRow(instructor);"},{"lineNumber":903,"author":{"gitId":"domoberzin"},"content":" WebElement accountRequestRow \u003d getAccountRequestRow(accountRequest);"},{"lineNumber":904,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":905,"author":{"gitId":"domoberzin"},"content":" clickExpandStudentLinks();"},{"lineNumber":906,"author":{"gitId":"domoberzin"},"content":" clickExpandInstructorLinks();"},{"lineNumber":907,"author":{"gitId":"domoberzin"},"content":" clickExpandAccountRequestLinks();"},{"lineNumber":908,"author":{"gitId":"domoberzin"},"content":" int numExpandedStudentRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":909,"author":{"gitId":"domoberzin"},"content":" int numExpandedInstructorRows \u003d getNumExpandedRows(instructorRow);"},{"lineNumber":910,"author":{"gitId":"-"},"content":" int numExpandedAccountRequestRows \u003d getNumExpandedRows(accountRequestRow);"},{"lineNumber":911,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedStudentRows, 0);"},{"lineNumber":912,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedInstructorRows, 0);"},{"lineNumber":913,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedAccountRequestRows, 0);"},{"lineNumber":914,"author":{"gitId":"-"},"content":""},{"lineNumber":915,"author":{"gitId":"-"},"content":" clickCollapseInstructorLinks();"},{"lineNumber":916,"author":{"gitId":"-"},"content":" numExpandedStudentRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":917,"author":{"gitId":"-"},"content":" numExpandedInstructorRows \u003d getNumExpandedRows(instructorRow);"},{"lineNumber":918,"author":{"gitId":"-"},"content":" numExpandedAccountRequestRows \u003d getNumExpandedRows(accountRequestRow);"},{"lineNumber":919,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedStudentRows, 0);"},{"lineNumber":920,"author":{"gitId":"-"},"content":" assertEquals(numExpandedInstructorRows, 0);"},{"lineNumber":921,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedAccountRequestRows, 0);"},{"lineNumber":922,"author":{"gitId":"-"},"content":""},{"lineNumber":923,"author":{"gitId":"-"},"content":" clickExpandInstructorLinks();"},{"lineNumber":924,"author":{"gitId":"-"},"content":" clickCollapseStudentLinks();"},{"lineNumber":925,"author":{"gitId":"-"},"content":" clickCollapseAccountRequestLinks();"},{"lineNumber":926,"author":{"gitId":"-"},"content":" waitUntilAnimationFinish();"},{"lineNumber":927,"author":{"gitId":"-"},"content":""},{"lineNumber":928,"author":{"gitId":"-"},"content":" numExpandedStudentRows \u003d getNumExpandedRows(studentRow);"},{"lineNumber":929,"author":{"gitId":"-"},"content":" numExpandedInstructorRows \u003d getNumExpandedRows(instructorRow);"},{"lineNumber":930,"author":{"gitId":"-"},"content":" numExpandedAccountRequestRows \u003d getNumExpandedRows(accountRequestRow);"},{"lineNumber":931,"author":{"gitId":"-"},"content":" assertEquals(numExpandedStudentRows, 0);"},{"lineNumber":932,"author":{"gitId":"-"},"content":" assertNotEquals(numExpandedInstructorRows, 0);"},{"lineNumber":933,"author":{"gitId":"-"},"content":" assertEquals(numExpandedAccountRequestRows, 0);"},{"lineNumber":934,"author":{"gitId":"-"},"content":" }"},{"lineNumber":935,"author":{"gitId":"-"},"content":""},{"lineNumber":936,"author":{"gitId":"-"},"content":" public void verifyRegenerateInstructorKey(Instructor instructor, String originalJoinLink) {"},{"lineNumber":937,"author":{"gitId":"-"},"content":" verifyStatusMessage(\"Instructor\u0027s key for this course has been successfully regenerated,\""},{"lineNumber":938,"author":{"gitId":"-"},"content":" + \" and the email has been sent.\");"},{"lineNumber":939,"author":{"gitId":"-"},"content":""},{"lineNumber":940,"author":{"gitId":"-"},"content":" String regeneratedJoinLink \u003d getInstructorJoinLink(instructor);"},{"lineNumber":941,"author":{"gitId":"-"},"content":" assertNotEquals(regeneratedJoinLink, originalJoinLink);"},{"lineNumber":942,"author":{"gitId":"-"},"content":" }"},{"lineNumber":943,"author":{"gitId":"-"},"content":""},{"lineNumber":944,"author":{"gitId":"-"},"content":" public void verifyRegenerateInstructorKey(InstructorAttributes instructor, String originalJoinLink) {"},{"lineNumber":945,"author":{"gitId":"-"},"content":" verifyStatusMessage(\"Instructor\u0027s key for this course has been successfully regenerated,\""},{"lineNumber":946,"author":{"gitId":"-"},"content":" + \" and the email has been sent.\");"},{"lineNumber":947,"author":{"gitId":"-"},"content":""},{"lineNumber":948,"author":{"gitId":"-"},"content":" String regeneratedJoinLink \u003d getInstructorJoinLink(instructor);"},{"lineNumber":949,"author":{"gitId":"-"},"content":" assertNotEquals(regeneratedJoinLink, originalJoinLink);"},{"lineNumber":950,"author":{"gitId":"-"},"content":" }"},{"lineNumber":951,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":168,"-":783}},{"path":"src/e2e/java/teammates/e2e/pageobjects/AppPage.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.pageobjects;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static com.google.common.base.Preconditions.checkNotNull;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertEquals;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertNotEquals;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertNotNull;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertTrue;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.io.File;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.io.IOException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import java.lang.reflect.Constructor;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import java.lang.reflect.InvocationTargetException;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import java.time.Duration;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import java.time.ZoneId;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import java.time.ZonedDateTime;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import java.time.format.DateTimeFormatter;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":19,"author":{"gitId":"yuanxi1"},"content":"import java.util.Locale;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":"import org.openqa.selenium.By;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import org.openqa.selenium.InvalidElementStateException;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import org.openqa.selenium.JavascriptExecutor;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import org.openqa.selenium.Keys;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import org.openqa.selenium.NoSuchElementException;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import org.openqa.selenium.WebDriverException;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import org.openqa.selenium.WebElement;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import org.openqa.selenium.remote.RemoteWebElement;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import org.openqa.selenium.remote.UselessFileDetector;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import org.openqa.selenium.support.PageFactory;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import org.openqa.selenium.support.ui.ExpectedCondition;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import org.openqa.selenium.support.ui.ExpectedConditions;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import org.openqa.selenium.support.ui.Select;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import org.openqa.selenium.support.ui.WebDriverWait;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.NotificationAttributes;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"import teammates.e2e.util.MaximumRetriesExceededException;"},{"lineNumber":41,"author":{"gitId":"-"},"content":"import teammates.e2e.util.RetryManager;"},{"lineNumber":42,"author":{"gitId":"-"},"content":"import teammates.e2e.util.Retryable;"},{"lineNumber":43,"author":{"gitId":"-"},"content":"import teammates.e2e.util.TestProperties;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"import teammates.test.FileHelper;"},{"lineNumber":45,"author":{"gitId":"-"},"content":"import teammates.test.ThreadHelper;"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":48,"author":{"gitId":"-"},"content":" * An abstract class that represents a browser-loaded page of the app and"},{"lineNumber":49,"author":{"gitId":"-"},"content":" * provides ways to interact with it. Also contains methods to validate some"},{"lineNumber":50,"author":{"gitId":"-"},"content":" * aspects of the page, e.g. HTML page source."},{"lineNumber":51,"author":{"gitId":"-"},"content":" *"},{"lineNumber":52,"author":{"gitId":"-"},"content":" * \u003cp\u003eNote: We are using the Page Object pattern here."},{"lineNumber":53,"author":{"gitId":"-"},"content":" *"},{"lineNumber":54,"author":{"gitId":"-"},"content":" * @see \u003ca href\u003d\"https://martinfowler.com/bliki/PageObject.html\"\u003ehttps://martinfowler.com/bliki/PageObject.html\u003c/a\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":" */"},{"lineNumber":56,"author":{"gitId":"-"},"content":"public abstract class AppPage {"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" private static final String CLEAR_ELEMENT_SCRIPT;"},{"lineNumber":59,"author":{"gitId":"-"},"content":" private static final String SCROLL_ELEMENT_TO_CENTER_AND_CLICK_SCRIPT;"},{"lineNumber":60,"author":{"gitId":"-"},"content":" private static final String READ_TINYMCE_CONTENT_SCRIPT;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" private static final String WRITE_TO_TINYMCE_SCRIPT;"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" static {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" CLEAR_ELEMENT_SCRIPT \u003d FileHelper.readFile(\"src/e2e/resources/scripts/clearElementWithoutEvents.js\");"},{"lineNumber":66,"author":{"gitId":"-"},"content":" SCROLL_ELEMENT_TO_CENTER_AND_CLICK_SCRIPT \u003d FileHelper"},{"lineNumber":67,"author":{"gitId":"-"},"content":" .readFile(\"src/e2e/resources/scripts/scrollElementToCenterAndClick.js\");"},{"lineNumber":68,"author":{"gitId":"-"},"content":" READ_TINYMCE_CONTENT_SCRIPT \u003d FileHelper.readFile(\"src/e2e/resources/scripts/readTinyMCEContent.js\");"},{"lineNumber":69,"author":{"gitId":"-"},"content":" WRITE_TO_TINYMCE_SCRIPT \u003d FileHelper.readFile(\"src/e2e/resources/scripts/writeToTinyMCE.js\");"},{"lineNumber":70,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":" }"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" /** Browser instance the page is loaded into. */"},{"lineNumber":76,"author":{"gitId":"-"},"content":" protected Browser browser;"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" /** Use for retrying due to transient UI issues. */"},{"lineNumber":79,"author":{"gitId":"-"},"content":" protected RetryManager uiRetryManager \u003d new RetryManager((TestProperties.TEST_TIMEOUT + 1) / 2);"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":82,"author":{"gitId":"-"},"content":" * Used by subclasses to create a {@code AppPage} object to wrap around the"},{"lineNumber":83,"author":{"gitId":"-"},"content":" * given {@code browser} object. Fails if the page content does not match"},{"lineNumber":84,"author":{"gitId":"-"},"content":" * the page type, as defined by the sub-class."},{"lineNumber":85,"author":{"gitId":"-"},"content":" */"},{"lineNumber":86,"author":{"gitId":"-"},"content":" public AppPage(Browser browser) {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" this.browser \u003d browser;"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" boolean isCorrectPageType;"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" isCorrectPageType \u003d containsExpectedPageContents();"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" if (isCorrectPageType) {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":96,"author":{"gitId":"-"},"content":" }"},{"lineNumber":97,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" // ignore and try again"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" // To minimize test failures due to eventual consistency, we try to"},{"lineNumber":102,"author":{"gitId":"-"},"content":" // reload the page and compare once more."},{"lineNumber":103,"author":{"gitId":"-"},"content":" System.out.println(\"#### Incorrect page type: going to try reloading the page.\");"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(2000);"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" reloadPage();"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" isCorrectPageType \u003d containsExpectedPageContents();"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" if (isCorrectPageType) {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":113,"author":{"gitId":"-"},"content":" }"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" System.out.println(\"######### Not in the correct page! ##########\");"},{"lineNumber":116,"author":{"gitId":"-"},"content":" throw new IllegalStateException(\"Not in the correct page!\");"},{"lineNumber":117,"author":{"gitId":"-"},"content":" }"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" public Browser getBrowser() {"},{"lineNumber":120,"author":{"gitId":"-"},"content":" return browser;"},{"lineNumber":121,"author":{"gitId":"-"},"content":" }"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":124,"author":{"gitId":"-"},"content":" * Gets a new page object representation of the currently open web page in the browser."},{"lineNumber":125,"author":{"gitId":"-"},"content":" *"},{"lineNumber":126,"author":{"gitId":"-"},"content":" * \u003cp\u003eFails if the new page content does not match content expected in a page of"},{"lineNumber":127,"author":{"gitId":"-"},"content":" * the type indicated by the parameter {@code typeOfPage}."},{"lineNumber":128,"author":{"gitId":"-"},"content":" */"},{"lineNumber":129,"author":{"gitId":"-"},"content":" public static \u003cT extends AppPage\u003e T getNewPageInstance(Browser currentBrowser, Class\u003cT\u003e typeOfPage) {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" waitUntilAnimationFinish(currentBrowser);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" Constructor\u003cT\u003e constructor \u003d typeOfPage.getConstructor(Browser.class);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" T page \u003d constructor.newInstance(currentBrowser);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" PageFactory.initElements(currentBrowser.driver, page);"},{"lineNumber":135,"author":{"gitId":"-"},"content":" page.waitForPageToLoad();"},{"lineNumber":136,"author":{"gitId":"-"},"content":" return page;"},{"lineNumber":137,"author":{"gitId":"-"},"content":" } catch (InvocationTargetException e) {"},{"lineNumber":138,"author":{"gitId":"-"},"content":" if (e.getCause() instanceof IllegalStateException) {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" throw (IllegalStateException) e.getCause();"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":142,"author":{"gitId":"-"},"content":" } catch (NoSuchMethodException | IllegalAccessException | InstantiationException e) {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":144,"author":{"gitId":"-"},"content":" }"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":148,"author":{"gitId":"-"},"content":" * Fails if the new page content does not match content expected in a page of"},{"lineNumber":149,"author":{"gitId":"-"},"content":" * the type indicated by the parameter {@code newPageType}."},{"lineNumber":150,"author":{"gitId":"-"},"content":" */"},{"lineNumber":151,"author":{"gitId":"-"},"content":" public \u003cT extends AppPage\u003e T changePageType(Class\u003cT\u003e newPageType) {"},{"lineNumber":152,"author":{"gitId":"-"},"content":" return getNewPageInstance(browser, newPageType);"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" public \u003cE\u003e E waitFor(ExpectedCondition\u003cE\u003e expectedCondition) {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" WebDriverWait wait \u003d new WebDriverWait(browser.driver, Duration.ofSeconds(TestProperties.TEST_TIMEOUT));"},{"lineNumber":157,"author":{"gitId":"-"},"content":" return wait.until(expectedCondition);"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":161,"author":{"gitId":"-"},"content":" * Waits until the page is fully loaded."},{"lineNumber":162,"author":{"gitId":"-"},"content":" */"},{"lineNumber":163,"author":{"gitId":"-"},"content":" public void waitForPageToLoad() {"},{"lineNumber":164,"author":{"gitId":"-"},"content":" waitForPageToLoad(false);"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":168,"author":{"gitId":"-"},"content":" * Waits until the page is fully loaded."},{"lineNumber":169,"author":{"gitId":"-"},"content":" *"},{"lineNumber":170,"author":{"gitId":"-"},"content":" * @param excludeToast Set this to true if toast message\u0027s disappearance should not be counted"},{"lineNumber":171,"author":{"gitId":"-"},"content":" * as criteria for page load\u0027s completion."},{"lineNumber":172,"author":{"gitId":"-"},"content":" */"},{"lineNumber":173,"author":{"gitId":"-"},"content":" public void waitForPageToLoad(boolean excludeToast) {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" browser.waitForPageLoad(excludeToast);"},{"lineNumber":175,"author":{"gitId":"-"},"content":" }"},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":" public void waitForElementVisibility(WebElement element) {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" waitFor(ExpectedConditions.visibilityOf(element));"},{"lineNumber":179,"author":{"gitId":"-"},"content":" }"},{"lineNumber":180,"author":{"gitId":"-"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":" public void waitForElementVisibility(By by) {"},{"lineNumber":182,"author":{"gitId":"-"},"content":" waitFor(ExpectedConditions.visibilityOfElementLocated(by));"},{"lineNumber":183,"author":{"gitId":"-"},"content":" }"},{"lineNumber":184,"author":{"gitId":"-"},"content":""},{"lineNumber":185,"author":{"gitId":"-"},"content":" public void waitForElementToBeClickable(WebElement element) {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" waitFor(ExpectedConditions.elementToBeClickable(element));"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":" public static void waitUntilAnimationFinish(Browser browser) {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" WebDriverWait wait \u003d new WebDriverWait(browser.driver, Duration.ofSeconds(TestProperties.TEST_TIMEOUT));"},{"lineNumber":191,"author":{"gitId":"-"},"content":" wait.until(ExpectedConditions.invisibilityOfElementLocated(By.className(\"ng-animating\")));"},{"lineNumber":192,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(1000);"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"-"},"content":" public void waitUntilAnimationFinish() {"},{"lineNumber":196,"author":{"gitId":"-"},"content":" waitUntilAnimationFinish(browser);"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":200,"author":{"gitId":"-"},"content":" * Waits until an element is no longer attached to the DOM or the timeout expires."},{"lineNumber":201,"author":{"gitId":"-"},"content":" * @param element the WebElement that expires after {@link TestProperties#TEST_TIMEOUT}"},{"lineNumber":202,"author":{"gitId":"-"},"content":" * @see org.openqa.selenium.support.ui.FluentWait#until(java.util.function.Function)"},{"lineNumber":203,"author":{"gitId":"-"},"content":" */"},{"lineNumber":204,"author":{"gitId":"-"},"content":" public void waitForElementStaleness(WebElement element) {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" waitFor(ExpectedConditions.stalenessOf(element));"},{"lineNumber":206,"author":{"gitId":"-"},"content":" }"},{"lineNumber":207,"author":{"gitId":"-"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" public void verifyUnclickable(WebElement element) {"},{"lineNumber":209,"author":{"gitId":"-"},"content":" if (\"a\".equals(element.getTagName())) {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" assertTrue(element.getAttribute(\"class\").contains(\"disabled\"));"},{"lineNumber":211,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" assertNotNull(element.getAttribute(\"disabled\"));"},{"lineNumber":213,"author":{"gitId":"-"},"content":" }"},{"lineNumber":214,"author":{"gitId":"-"},"content":" }"},{"lineNumber":215,"author":{"gitId":"-"},"content":""},{"lineNumber":216,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":217,"author":{"gitId":"-"},"content":" * Waits for a confirmation modal to appear and click the confirm button."},{"lineNumber":218,"author":{"gitId":"-"},"content":" */"},{"lineNumber":219,"author":{"gitId":"-"},"content":" public void waitForConfirmationModalAndClickOk() {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" waitForModalShown();"},{"lineNumber":221,"author":{"gitId":"-"},"content":" waitForElementVisibility(By.className(\"modal-btn-ok\"));"},{"lineNumber":222,"author":{"gitId":"-"},"content":" WebElement okayButton \u003d browser.driver.findElement(By.className(\"modal-btn-ok\"));"},{"lineNumber":223,"author":{"gitId":"-"},"content":" waitForElementToBeClickable(okayButton);"},{"lineNumber":224,"author":{"gitId":"-"},"content":" clickDismissModalButtonAndWaitForModalHidden(okayButton);"},{"lineNumber":225,"author":{"gitId":"-"},"content":" }"},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"-"},"content":" private void waitForModalShown() {"},{"lineNumber":228,"author":{"gitId":"-"},"content":" // Possible exploration: Change to listening to modal shown event as"},{"lineNumber":229,"author":{"gitId":"-"},"content":" // this is based on the implementation detail assumption that once modal-backdrop is added the modal is shown"},{"lineNumber":230,"author":{"gitId":"-"},"content":" waitForElementVisibility(By.className(\"modal-backdrop\"));"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" void waitForModalHidden(WebElement modalBackdrop) {"},{"lineNumber":234,"author":{"gitId":"-"},"content":" // Possible exploration: Change to listening to modal hidden event as"},{"lineNumber":235,"author":{"gitId":"-"},"content":" // this is based on the implementation detail assumption that once modal-backdrop is removed the modal is hidden"},{"lineNumber":236,"author":{"gitId":"-"},"content":" waitForElementStaleness(modalBackdrop);"},{"lineNumber":237,"author":{"gitId":"-"},"content":" }"},{"lineNumber":238,"author":{"gitId":"-"},"content":""},{"lineNumber":239,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":240,"author":{"gitId":"-"},"content":" * Waits for the element to appear in the page, up to the timeout specified."},{"lineNumber":241,"author":{"gitId":"-"},"content":" */"},{"lineNumber":242,"author":{"gitId":"-"},"content":" public WebElement waitForElementPresence(By by) {"},{"lineNumber":243,"author":{"gitId":"-"},"content":" return waitFor(ExpectedConditions.presenceOfElementLocated(by));"},{"lineNumber":244,"author":{"gitId":"-"},"content":" }"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" public void reloadPage() {"},{"lineNumber":247,"author":{"gitId":"-"},"content":" browser.goToUrl(browser.driver.getCurrentUrl());"},{"lineNumber":248,"author":{"gitId":"-"},"content":" waitForPageToLoad();"},{"lineNumber":249,"author":{"gitId":"-"},"content":" }"},{"lineNumber":250,"author":{"gitId":"-"},"content":""},{"lineNumber":251,"author":{"gitId":"-"},"content":" protected Object executeScript(String script, Object... args) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" JavascriptExecutor javascriptExecutor \u003d (JavascriptExecutor) browser.driver;"},{"lineNumber":253,"author":{"gitId":"-"},"content":" return javascriptExecutor.executeScript(script, args);"},{"lineNumber":254,"author":{"gitId":"-"},"content":" }"},{"lineNumber":255,"author":{"gitId":"-"},"content":""},{"lineNumber":256,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":257,"author":{"gitId":"-"},"content":" * Returns the HTML source of the currently loaded page."},{"lineNumber":258,"author":{"gitId":"-"},"content":" */"},{"lineNumber":259,"author":{"gitId":"-"},"content":" public String getPageSource() {"},{"lineNumber":260,"author":{"gitId":"-"},"content":" return browser.driver.getPageSource();"},{"lineNumber":261,"author":{"gitId":"-"},"content":" }"},{"lineNumber":262,"author":{"gitId":"-"},"content":""},{"lineNumber":263,"author":{"gitId":"-"},"content":" public String getTitle() {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" return browser.driver.getTitle();"},{"lineNumber":265,"author":{"gitId":"-"},"content":" }"},{"lineNumber":266,"author":{"gitId":"-"},"content":""},{"lineNumber":267,"author":{"gitId":"-"},"content":" public String getPageTitle() {"},{"lineNumber":268,"author":{"gitId":"-"},"content":" return waitForElementPresence(By.tagName(\"h1\")).getText();"},{"lineNumber":269,"author":{"gitId":"-"},"content":" }"},{"lineNumber":270,"author":{"gitId":"-"},"content":""},{"lineNumber":271,"author":{"gitId":"-"},"content":" public void click(By by) {"},{"lineNumber":272,"author":{"gitId":"-"},"content":" WebElement element \u003d browser.driver.findElement(by);"},{"lineNumber":273,"author":{"gitId":"-"},"content":" click(element);"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" protected void click(WebElement element) {"},{"lineNumber":277,"author":{"gitId":"-"},"content":" executeScript(\"arguments[0].click();\", element);"},{"lineNumber":278,"author":{"gitId":"-"},"content":" }"},{"lineNumber":279,"author":{"gitId":"-"},"content":""},{"lineNumber":280,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":281,"author":{"gitId":"-"},"content":" * Simulates the clearing and sending of keys to an element."},{"lineNumber":282,"author":{"gitId":"-"},"content":" *"},{"lineNumber":283,"author":{"gitId":"-"},"content":" * \u003cp\u003e\u003cb\u003eNote:\u003c/b\u003e This method is not the same as using {@link WebElement#clear} followed by {@link WebElement#sendKeys}."},{"lineNumber":284,"author":{"gitId":"-"},"content":" * It avoids double firing of the {@code change} event which may occur when {@link WebElement#clear} is followed by"},{"lineNumber":285,"author":{"gitId":"-"},"content":" * {@link WebElement#sendKeys}."},{"lineNumber":286,"author":{"gitId":"-"},"content":" *"},{"lineNumber":287,"author":{"gitId":"-"},"content":" * @see AppPage#clearWithoutEvents(WebElement)"},{"lineNumber":288,"author":{"gitId":"-"},"content":" */"},{"lineNumber":289,"author":{"gitId":"-"},"content":" private void clearAndSendKeys(WebElement element, CharSequence... keysToSend) {"},{"lineNumber":290,"author":{"gitId":"-"},"content":" Map\u003cString, Object\u003e result \u003d clearWithoutEvents(element);"},{"lineNumber":291,"author":{"gitId":"-"},"content":" @SuppressWarnings(\"unchecked\")"},{"lineNumber":292,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e errors \u003d (Map\u003cString, String\u003e) result.get(\"errors\");"},{"lineNumber":293,"author":{"gitId":"-"},"content":" if (errors !\u003d null) {"},{"lineNumber":294,"author":{"gitId":"-"},"content":" throw new InvalidElementStateException(errors.get(\"detail\"));"},{"lineNumber":295,"author":{"gitId":"-"},"content":" }"},{"lineNumber":296,"author":{"gitId":"-"},"content":""},{"lineNumber":297,"author":{"gitId":"-"},"content":" element.sendKeys(keysToSend);"},{"lineNumber":298,"author":{"gitId":"-"},"content":" }"},{"lineNumber":299,"author":{"gitId":"-"},"content":""},{"lineNumber":300,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":301,"author":{"gitId":"-"},"content":" * Clears any kind of editable element, but without firing the {@code change} event (unlike {@link WebElement#clear()})."},{"lineNumber":302,"author":{"gitId":"-"},"content":" * Avoid using this method if {@link WebElement#clear()} meets the requirements as this method depends on implementation"},{"lineNumber":303,"author":{"gitId":"-"},"content":" * details."},{"lineNumber":304,"author":{"gitId":"-"},"content":" */"},{"lineNumber":305,"author":{"gitId":"-"},"content":" private Map\u003cString, Object\u003e clearWithoutEvents(WebElement element) {"},{"lineNumber":306,"author":{"gitId":"-"},"content":" // This method is a close mirror of HtmlUnitWebElement#clear(), except that events are not handled. Note that"},{"lineNumber":307,"author":{"gitId":"-"},"content":" // HtmlUnitWebElement is mirrored as opposed to RemoteWebElement (which is used with actual browsers) for convenience"},{"lineNumber":308,"author":{"gitId":"-"},"content":" // and the implementation can differ."},{"lineNumber":309,"author":{"gitId":"-"},"content":" checkNotNull(element);"},{"lineNumber":310,"author":{"gitId":"-"},"content":""},{"lineNumber":311,"author":{"gitId":"-"},"content":" // Adapted from ExpectedConditions#stalenessOf which forces a staleness check. This allows a meaningful"},{"lineNumber":312,"author":{"gitId":"-"},"content":" // StaleElementReferenceException to be thrown rather than just getting a boolean from ExpectedConditions."},{"lineNumber":313,"author":{"gitId":"-"},"content":" element.isEnabled();"},{"lineNumber":314,"author":{"gitId":"-"},"content":""},{"lineNumber":315,"author":{"gitId":"-"},"content":" // Fail safe in case the implementation of staleness checks is changed"},{"lineNumber":316,"author":{"gitId":"-"},"content":" if (isExpectedCondition(ExpectedConditions.stalenessOf(element))) {"},{"lineNumber":317,"author":{"gitId":"-"},"content":" throw new AssertionError("},{"lineNumber":318,"author":{"gitId":"-"},"content":" \"Element is stale but should have been caught earlier by element.isEnabled().\");"},{"lineNumber":319,"author":{"gitId":"-"},"content":" }"},{"lineNumber":320,"author":{"gitId":"-"},"content":""},{"lineNumber":321,"author":{"gitId":"-"},"content":" @SuppressWarnings(\"unchecked\")"},{"lineNumber":322,"author":{"gitId":"-"},"content":" Map\u003cString, Object\u003e result \u003d (Map\u003cString, Object\u003e) executeScript(CLEAR_ELEMENT_SCRIPT, element);"},{"lineNumber":323,"author":{"gitId":"-"},"content":" return result;"},{"lineNumber":324,"author":{"gitId":"-"},"content":" }"},{"lineNumber":325,"author":{"gitId":"-"},"content":""},{"lineNumber":326,"author":{"gitId":"-"},"content":" protected void fillTextBox(WebElement textBoxElement, String value) {"},{"lineNumber":327,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":328,"author":{"gitId":"-"},"content":" scrollElementToCenterAndClick(textBoxElement);"},{"lineNumber":329,"author":{"gitId":"-"},"content":" } catch (WebDriverException e) {"},{"lineNumber":330,"author":{"gitId":"-"},"content":" // It is important that a text box element is clickable before we fill it but due to legacy reasons we continue"},{"lineNumber":331,"author":{"gitId":"-"},"content":" // attempting to fill the text box element even if it\u0027s not clickable (which may lead to an unexpected failure"},{"lineNumber":332,"author":{"gitId":"-"},"content":" // later on)"},{"lineNumber":333,"author":{"gitId":"-"},"content":" System.out.println(\"Unexpectedly not able to click on the text box element because of: \");"},{"lineNumber":334,"author":{"gitId":"-"},"content":" System.out.println(e);"},{"lineNumber":335,"author":{"gitId":"-"},"content":" }"},{"lineNumber":336,"author":{"gitId":"-"},"content":""},{"lineNumber":337,"author":{"gitId":"-"},"content":" // If the intended value is empty `clear` works well enough for us"},{"lineNumber":338,"author":{"gitId":"-"},"content":" if (value.isEmpty()) {"},{"lineNumber":339,"author":{"gitId":"-"},"content":" textBoxElement.clear();"},{"lineNumber":340,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":341,"author":{"gitId":"-"},"content":" }"},{"lineNumber":342,"author":{"gitId":"-"},"content":""},{"lineNumber":343,"author":{"gitId":"-"},"content":" // Otherwise we need to do special handling of entering input because `clear` and `sendKeys` work differently."},{"lineNumber":344,"author":{"gitId":"-"},"content":" // See documentation for `clearAndSendKeys` for more details."},{"lineNumber":345,"author":{"gitId":"-"},"content":" clearAndSendKeys(textBoxElement, value);"},{"lineNumber":346,"author":{"gitId":"-"},"content":""},{"lineNumber":347,"author":{"gitId":"-"},"content":" textBoxElement.sendKeys(Keys.TAB); // blur the element to receive events"},{"lineNumber":348,"author":{"gitId":"-"},"content":" }"},{"lineNumber":349,"author":{"gitId":"-"},"content":""},{"lineNumber":350,"author":{"gitId":"-"},"content":" protected void fillDatePicker(WebElement dateBox, Instant startInstant, String timeZone) {"},{"lineNumber":351,"author":{"gitId":"-"},"content":" WebElement buttonToOpenPicker \u003d dateBox.findElement(By.tagName(\"button\"));"},{"lineNumber":352,"author":{"gitId":"-"},"content":" click(buttonToOpenPicker);"},{"lineNumber":353,"author":{"gitId":"-"},"content":""},{"lineNumber":354,"author":{"gitId":"-"},"content":" WebElement datePicker \u003d dateBox.findElement(By.tagName(\"ngb-datepicker\"));"},{"lineNumber":355,"author":{"gitId":"-"},"content":" WebElement monthAndYearPicker \u003d datePicker.findElement(By.tagName(\"ngb-datepicker-navigation-select\"));"},{"lineNumber":356,"author":{"gitId":"-"},"content":" WebElement monthPicker \u003d monthAndYearPicker.findElement(By.cssSelector(\"[title\u003d\u0027Select month\u0027]\"));"},{"lineNumber":357,"author":{"gitId":"-"},"content":" WebElement yearPicker \u003d monthAndYearPicker.findElement(By.cssSelector(\"[title\u003d\u0027Select year\u0027]\"));"},{"lineNumber":358,"author":{"gitId":"-"},"content":" WebElement dayPicker \u003d datePicker.findElement(By.cssSelector(\"ngb-datepicker-month\"));"},{"lineNumber":359,"author":{"gitId":"-"},"content":""},{"lineNumber":360,"author":{"gitId":"-"},"content":" String year \u003d getYearString(startInstant, timeZone);"},{"lineNumber":361,"author":{"gitId":"-"},"content":" String month \u003d getMonthString(startInstant, timeZone);"},{"lineNumber":362,"author":{"gitId":"-"},"content":" String date \u003d getFullDateString(startInstant, timeZone);"},{"lineNumber":363,"author":{"gitId":"-"},"content":""},{"lineNumber":364,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(yearPicker, year);"},{"lineNumber":365,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(monthPicker, month);"},{"lineNumber":366,"author":{"gitId":"-"},"content":" click(dayPicker.findElement(By.cssSelector(String.format(\"[aria-label\u003d\u0027%s\u0027]\", date))));"},{"lineNumber":367,"author":{"gitId":"-"},"content":" }"},{"lineNumber":368,"author":{"gitId":"-"},"content":""},{"lineNumber":369,"author":{"gitId":"-"},"content":" protected void fillFileBox(RemoteWebElement fileBoxElement, String fileName) {"},{"lineNumber":370,"author":{"gitId":"-"},"content":" if (fileName.isEmpty()) {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" fileBoxElement.clear();"},{"lineNumber":372,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":373,"author":{"gitId":"-"},"content":" fileBoxElement.setFileDetector(new UselessFileDetector());"},{"lineNumber":374,"author":{"gitId":"-"},"content":" String filePath \u003d new File(fileName).getAbsolutePath();"},{"lineNumber":375,"author":{"gitId":"-"},"content":" fileBoxElement.sendKeys(filePath);"},{"lineNumber":376,"author":{"gitId":"-"},"content":" }"},{"lineNumber":377,"author":{"gitId":"-"},"content":" }"},{"lineNumber":378,"author":{"gitId":"-"},"content":""},{"lineNumber":379,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":380,"author":{"gitId":"-"},"content":" * Get rich text from editor."},{"lineNumber":381,"author":{"gitId":"-"},"content":" */"},{"lineNumber":382,"author":{"gitId":"-"},"content":" protected String getEditorRichText(WebElement editor) {"},{"lineNumber":383,"author":{"gitId":"-"},"content":" waitForElementPresence(By.tagName(\"iframe\"));"},{"lineNumber":384,"author":{"gitId":"-"},"content":" String id \u003d editor.findElement(By.tagName(\"textarea\")).getAttribute(\"id\");"},{"lineNumber":385,"author":{"gitId":"-"},"content":" return (String) ((JavascriptExecutor) browser.driver)"},{"lineNumber":386,"author":{"gitId":"-"},"content":" .executeAsyncScript(READ_TINYMCE_CONTENT_SCRIPT, id);"},{"lineNumber":387,"author":{"gitId":"-"},"content":" }"},{"lineNumber":388,"author":{"gitId":"-"},"content":""},{"lineNumber":389,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":390,"author":{"gitId":"-"},"content":" * Write rich text to editor."},{"lineNumber":391,"author":{"gitId":"-"},"content":" */"},{"lineNumber":392,"author":{"gitId":"-"},"content":" protected void writeToRichTextEditor(WebElement editor, String text) {"},{"lineNumber":393,"author":{"gitId":"-"},"content":" waitForElementPresence(By.tagName(\"iframe\"));"},{"lineNumber":394,"author":{"gitId":"-"},"content":" String id \u003d editor.findElement(By.tagName(\"textarea\")).getAttribute(\"id\");"},{"lineNumber":395,"author":{"gitId":"-"},"content":" ((JavascriptExecutor) browser.driver).executeAsyncScript(WRITE_TO_TINYMCE_SCRIPT, id, text);"},{"lineNumber":396,"author":{"gitId":"-"},"content":" }"},{"lineNumber":397,"author":{"gitId":"-"},"content":""},{"lineNumber":398,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":399,"author":{"gitId":"domoberzin"},"content":" * Clear existing text in the editor."},{"lineNumber":400,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":401,"author":{"gitId":"domoberzin"},"content":" protected void clearRichTextEditor(WebElement editor) {"},{"lineNumber":402,"author":{"gitId":"domoberzin"},"content":" writeToRichTextEditor(editor, \"\");"},{"lineNumber":403,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":404,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":405,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":406,"author":{"gitId":"-"},"content":" * Select the option, if it is not already selected."},{"lineNumber":407,"author":{"gitId":"-"},"content":" * No action taken if it is already selected."},{"lineNumber":408,"author":{"gitId":"-"},"content":" */"},{"lineNumber":409,"author":{"gitId":"-"},"content":" protected void markOptionAsSelected(WebElement option) {"},{"lineNumber":410,"author":{"gitId":"-"},"content":" waitForElementVisibility(option);"},{"lineNumber":411,"author":{"gitId":"-"},"content":" if (!option.isSelected()) {"},{"lineNumber":412,"author":{"gitId":"-"},"content":" click(option);"},{"lineNumber":413,"author":{"gitId":"-"},"content":" }"},{"lineNumber":414,"author":{"gitId":"-"},"content":" }"},{"lineNumber":415,"author":{"gitId":"-"},"content":""},{"lineNumber":416,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":417,"author":{"gitId":"-"},"content":" * Unselect the option, if it is not already unselected."},{"lineNumber":418,"author":{"gitId":"-"},"content":" * No action taken if it is already unselected\u0027."},{"lineNumber":419,"author":{"gitId":"-"},"content":" */"},{"lineNumber":420,"author":{"gitId":"-"},"content":" protected void markOptionAsUnselected(WebElement option) {"},{"lineNumber":421,"author":{"gitId":"-"},"content":" waitForElementVisibility(option);"},{"lineNumber":422,"author":{"gitId":"-"},"content":" if (option.isSelected()) {"},{"lineNumber":423,"author":{"gitId":"-"},"content":" click(option);"},{"lineNumber":424,"author":{"gitId":"-"},"content":" }"},{"lineNumber":425,"author":{"gitId":"-"},"content":" }"},{"lineNumber":426,"author":{"gitId":"-"},"content":""},{"lineNumber":427,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":428,"author":{"gitId":"-"},"content":" * Returns the text of the option selected in the dropdown."},{"lineNumber":429,"author":{"gitId":"-"},"content":" */"},{"lineNumber":430,"author":{"gitId":"-"},"content":" protected String getSelectedDropdownOptionText(WebElement dropdown) {"},{"lineNumber":431,"author":{"gitId":"-"},"content":" Select select \u003d new Select(dropdown);"},{"lineNumber":432,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":433,"author":{"gitId":"-"},"content":" uiRetryManager.runUntilNoRecognizedException(new Retryable(\"Wait for dropdown text to load\") {"},{"lineNumber":434,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":435,"author":{"gitId":"-"},"content":" public void run() {"},{"lineNumber":436,"author":{"gitId":"-"},"content":" String txt \u003d select.getFirstSelectedOption().getText();"},{"lineNumber":437,"author":{"gitId":"-"},"content":" assertNotEquals(\"\", txt);"},{"lineNumber":438,"author":{"gitId":"-"},"content":" }"},{"lineNumber":439,"author":{"gitId":"-"},"content":" }, WebDriverException.class, AssertionError.class);"},{"lineNumber":440,"author":{"gitId":"-"},"content":" return select.getFirstSelectedOption().getText();"},{"lineNumber":441,"author":{"gitId":"-"},"content":" } catch (MaximumRetriesExceededException e) {"},{"lineNumber":442,"author":{"gitId":"-"},"content":" return select.getFirstSelectedOption().getText();"},{"lineNumber":443,"author":{"gitId":"-"},"content":" }"},{"lineNumber":444,"author":{"gitId":"-"},"content":" }"},{"lineNumber":445,"author":{"gitId":"-"},"content":""},{"lineNumber":446,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":447,"author":{"gitId":"-"},"content":" * Selects option in dropdown based on visible text."},{"lineNumber":448,"author":{"gitId":"-"},"content":" */"},{"lineNumber":449,"author":{"gitId":"-"},"content":" protected void selectDropdownOptionByText(WebElement dropdown, String text) {"},{"lineNumber":450,"author":{"gitId":"-"},"content":" scrollElementToCenter(dropdown);"},{"lineNumber":451,"author":{"gitId":"-"},"content":" Select select \u003d new Select(dropdown);"},{"lineNumber":452,"author":{"gitId":"-"},"content":" select.selectByVisibleText(text);"},{"lineNumber":453,"author":{"gitId":"-"},"content":" }"},{"lineNumber":454,"author":{"gitId":"-"},"content":""},{"lineNumber":455,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":456,"author":{"gitId":"-"},"content":" * Selects option in dropdown based on value."},{"lineNumber":457,"author":{"gitId":"-"},"content":" */"},{"lineNumber":458,"author":{"gitId":"-"},"content":" protected void selectDropdownOptionByValue(WebElement dropdown, String value) {"},{"lineNumber":459,"author":{"gitId":"-"},"content":" scrollElementToCenter(dropdown);"},{"lineNumber":460,"author":{"gitId":"-"},"content":" Select select \u003d new Select(dropdown);"},{"lineNumber":461,"author":{"gitId":"-"},"content":" select.selectByValue(value);"},{"lineNumber":462,"author":{"gitId":"-"},"content":" }"},{"lineNumber":463,"author":{"gitId":"-"},"content":""},{"lineNumber":464,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":465,"author":{"gitId":"-"},"content":" * Asserts that all values in the body of the given table are equal to the expectedTableBodyValues."},{"lineNumber":466,"author":{"gitId":"-"},"content":" */"},{"lineNumber":467,"author":{"gitId":"-"},"content":" protected void verifyTableBodyValues(WebElement table, String[][] expectedTableBodyValues) {"},{"lineNumber":468,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d table.findElement(By.tagName(\"tbody\")).findElements(By.tagName(\"tr\"));"},{"lineNumber":469,"author":{"gitId":"-"},"content":" assertTrue(expectedTableBodyValues.length \u003c\u003d rows.size());"},{"lineNumber":470,"author":{"gitId":"-"},"content":" for (int rowIndex \u003d 0; rowIndex \u003c expectedTableBodyValues.length; rowIndex++) {"},{"lineNumber":471,"author":{"gitId":"-"},"content":" verifyTableRowValues(rows.get(rowIndex), expectedTableBodyValues[rowIndex]);"},{"lineNumber":472,"author":{"gitId":"-"},"content":" }"},{"lineNumber":473,"author":{"gitId":"-"},"content":" }"},{"lineNumber":474,"author":{"gitId":"-"},"content":""},{"lineNumber":475,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":476,"author":{"gitId":"-"},"content":" * Asserts that all values in the row header of the given table are equal to the expectedRowHeaderValues."},{"lineNumber":477,"author":{"gitId":"-"},"content":" */"},{"lineNumber":478,"author":{"gitId":"-"},"content":" protected void verifyTableRowHeaderValues(WebElement table, String[][] expectedTableRowHeaderValues) {"},{"lineNumber":479,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d table.findElement(By.tagName(\"thead\")).findElements(By.tagName(\"tr\"));"},{"lineNumber":480,"author":{"gitId":"-"},"content":" assertTrue(expectedTableRowHeaderValues.length \u003c\u003d rows.size());"},{"lineNumber":481,"author":{"gitId":"-"},"content":" for (int rowIndex \u003d 0; rowIndex \u003c expectedTableRowHeaderValues.length; rowIndex++) {"},{"lineNumber":482,"author":{"gitId":"-"},"content":" verifyTableHeaderValues(rows.get(rowIndex), expectedTableRowHeaderValues[rowIndex]);"},{"lineNumber":483,"author":{"gitId":"-"},"content":" }"},{"lineNumber":484,"author":{"gitId":"-"},"content":" }"},{"lineNumber":485,"author":{"gitId":"-"},"content":""},{"lineNumber":486,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":487,"author":{"gitId":"-"},"content":" * Asserts that all values in the column header of the given table are equal to the expectedTablColumnHeaderValues."},{"lineNumber":488,"author":{"gitId":"-"},"content":" */"},{"lineNumber":489,"author":{"gitId":"-"},"content":" protected void verifyTableColumnHeaderValues(WebElement table, String[][] expectedTablColumnHeaderValues) {"},{"lineNumber":490,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d table.findElement(By.tagName(\"tbody\")).findElements(By.tagName(\"tr\"));"},{"lineNumber":491,"author":{"gitId":"-"},"content":" assertTrue(expectedTablColumnHeaderValues.length \u003c\u003d rows.size());"},{"lineNumber":492,"author":{"gitId":"-"},"content":" for (int rowIndex \u003d 0; rowIndex \u003c expectedTablColumnHeaderValues.length; rowIndex++) {"},{"lineNumber":493,"author":{"gitId":"-"},"content":" verifyTableHeaderValues(rows.get(rowIndex), expectedTablColumnHeaderValues[rowIndex]);"},{"lineNumber":494,"author":{"gitId":"-"},"content":" }"},{"lineNumber":495,"author":{"gitId":"-"},"content":" }"},{"lineNumber":496,"author":{"gitId":"-"},"content":""},{"lineNumber":497,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":498,"author":{"gitId":"-"},"content":" * Asserts that all data values in the given table row are equal to the expectedRowValues."},{"lineNumber":499,"author":{"gitId":"-"},"content":" */"},{"lineNumber":500,"author":{"gitId":"-"},"content":" protected void verifyTableRowValues(WebElement row, String[] expectedRowValues) {"},{"lineNumber":501,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e cells \u003d row.findElements(By.tagName(\"td\"));"},{"lineNumber":502,"author":{"gitId":"-"},"content":" assertTrue(expectedRowValues.length \u003c\u003d cells.size());"},{"lineNumber":503,"author":{"gitId":"-"},"content":" for (int cellIndex \u003d 0; cellIndex \u003c expectedRowValues.length; cellIndex++) {"},{"lineNumber":504,"author":{"gitId":"-"},"content":" assertEquals(expectedRowValues[cellIndex], cells.get(cellIndex).getText());"},{"lineNumber":505,"author":{"gitId":"-"},"content":" }"},{"lineNumber":506,"author":{"gitId":"-"},"content":" }"},{"lineNumber":507,"author":{"gitId":"-"},"content":""},{"lineNumber":508,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":509,"author":{"gitId":"-"},"content":" * Asserts that all header values in the given table row are equal to the expectedRowHeaderValues."},{"lineNumber":510,"author":{"gitId":"-"},"content":" */"},{"lineNumber":511,"author":{"gitId":"-"},"content":" protected void verifyTableHeaderValues(WebElement row, String[] expectedRowHeaderValues) {"},{"lineNumber":512,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e cells \u003d row.findElements(By.tagName(\"th\"));"},{"lineNumber":513,"author":{"gitId":"-"},"content":" assertTrue(expectedRowHeaderValues.length \u003c\u003d cells.size());"},{"lineNumber":514,"author":{"gitId":"-"},"content":" for (int cellIndex \u003d 0; cellIndex \u003c expectedRowHeaderValues.length; cellIndex++) {"},{"lineNumber":515,"author":{"gitId":"-"},"content":" assertEquals(expectedRowHeaderValues[cellIndex], cells.get(cellIndex).getText());"},{"lineNumber":516,"author":{"gitId":"-"},"content":" }"},{"lineNumber":517,"author":{"gitId":"-"},"content":" }"},{"lineNumber":518,"author":{"gitId":"-"},"content":""},{"lineNumber":519,"author":{"gitId":"-"},"content":" public void verifyBannerContent(NotificationAttributes expected) {"},{"lineNumber":520,"author":{"gitId":"-"},"content":" WebElement banner \u003d browser.driver.findElement(By.className(\"banner\"));"},{"lineNumber":521,"author":{"gitId":"-"},"content":" String title \u003d banner.findElement(By.tagName(\"h5\")).getText();"},{"lineNumber":522,"author":{"gitId":"-"},"content":" String message \u003d banner.findElement(By.className(\"banner-text\")).getAttribute(\"innerHTML\");"},{"lineNumber":523,"author":{"gitId":"-"},"content":" assertEquals(expected.getTitle(), title);"},{"lineNumber":524,"author":{"gitId":"-"},"content":" assertEquals(expected.getMessage(), message);"},{"lineNumber":525,"author":{"gitId":"-"},"content":" }"},{"lineNumber":526,"author":{"gitId":"-"},"content":""},{"lineNumber":527,"author":{"gitId":"-"},"content":" public boolean isBannerVisible() {"},{"lineNumber":528,"author":{"gitId":"-"},"content":" return isElementVisible(By.className(\"banner\"));"},{"lineNumber":529,"author":{"gitId":"-"},"content":" }"},{"lineNumber":530,"author":{"gitId":"-"},"content":""},{"lineNumber":531,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":532,"author":{"gitId":"-"},"content":" * Clicks the element and clicks \u0027Yes\u0027 in the follow up dialog box."},{"lineNumber":533,"author":{"gitId":"-"},"content":" * Fails if there is no dialog box."},{"lineNumber":534,"author":{"gitId":"-"},"content":" * @return the resulting page."},{"lineNumber":535,"author":{"gitId":"-"},"content":" */"},{"lineNumber":536,"author":{"gitId":"-"},"content":" public AppPage clickAndConfirm(WebElement elementToClick) {"},{"lineNumber":537,"author":{"gitId":"-"},"content":" click(elementToClick);"},{"lineNumber":538,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":539,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":540,"author":{"gitId":"-"},"content":" }"},{"lineNumber":541,"author":{"gitId":"-"},"content":""},{"lineNumber":542,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":543,"author":{"gitId":"-"},"content":" * Returns True if the page contains some basic elements expected in a page of the"},{"lineNumber":544,"author":{"gitId":"-"},"content":" * specific type. e.g., the top heading."},{"lineNumber":545,"author":{"gitId":"-"},"content":" */"},{"lineNumber":546,"author":{"gitId":"-"},"content":" protected abstract boolean containsExpectedPageContents();"},{"lineNumber":547,"author":{"gitId":"-"},"content":""},{"lineNumber":548,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":549,"author":{"gitId":"-"},"content":" * Returns True if there is a corresponding element for the given locator."},{"lineNumber":550,"author":{"gitId":"-"},"content":" */"},{"lineNumber":551,"author":{"gitId":"-"},"content":" public boolean isElementPresent(By by) {"},{"lineNumber":552,"author":{"gitId":"-"},"content":" return !browser.driver.findElements(by).isEmpty();"},{"lineNumber":553,"author":{"gitId":"-"},"content":" }"},{"lineNumber":554,"author":{"gitId":"-"},"content":""},{"lineNumber":555,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":556,"author":{"gitId":"-"},"content":" * Returns True if there is a corresponding element for the given id or name."},{"lineNumber":557,"author":{"gitId":"-"},"content":" */"},{"lineNumber":558,"author":{"gitId":"-"},"content":" public boolean isElementPresent(String elementId) {"},{"lineNumber":559,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":560,"author":{"gitId":"-"},"content":" browser.driver.findElement(By.id(elementId));"},{"lineNumber":561,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":562,"author":{"gitId":"-"},"content":" } catch (NoSuchElementException e) {"},{"lineNumber":563,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":564,"author":{"gitId":"-"},"content":" }"},{"lineNumber":565,"author":{"gitId":"-"},"content":" }"},{"lineNumber":566,"author":{"gitId":"-"},"content":""},{"lineNumber":567,"author":{"gitId":"-"},"content":" public boolean isElementVisible(By by) {"},{"lineNumber":568,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":569,"author":{"gitId":"-"},"content":" return browser.driver.findElement(by).isDisplayed();"},{"lineNumber":570,"author":{"gitId":"-"},"content":" } catch (NoSuchElementException e) {"},{"lineNumber":571,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":572,"author":{"gitId":"-"},"content":" }"},{"lineNumber":573,"author":{"gitId":"-"},"content":" }"},{"lineNumber":574,"author":{"gitId":"-"},"content":""},{"lineNumber":575,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":576,"author":{"gitId":"-"},"content":" * Returns true if the expected condition is evaluated to true immediately."},{"lineNumber":577,"author":{"gitId":"-"},"content":" * @see ExpectedConditions"},{"lineNumber":578,"author":{"gitId":"-"},"content":" */"},{"lineNumber":579,"author":{"gitId":"-"},"content":" private boolean isExpectedCondition(ExpectedCondition\u003c?\u003e expectedCondition) {"},{"lineNumber":580,"author":{"gitId":"-"},"content":" Object value \u003d expectedCondition.apply(browser.driver);"},{"lineNumber":581,"author":{"gitId":"-"},"content":" if (value \u003d\u003d null) {"},{"lineNumber":582,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":583,"author":{"gitId":"-"},"content":" }"},{"lineNumber":584,"author":{"gitId":"-"},"content":""},{"lineNumber":585,"author":{"gitId":"-"},"content":" if (value.getClass() \u003d\u003d Boolean.class) {"},{"lineNumber":586,"author":{"gitId":"-"},"content":" return (boolean) value;"},{"lineNumber":587,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":588,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":589,"author":{"gitId":"-"},"content":" }"},{"lineNumber":590,"author":{"gitId":"-"},"content":" }"},{"lineNumber":591,"author":{"gitId":"-"},"content":""},{"lineNumber":592,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":593,"author":{"gitId":"-"},"content":" * Clicks a button (can be inside or outside the modal) that dismisses the modal and waits for the modal to be hidden."},{"lineNumber":594,"author":{"gitId":"-"},"content":" * The caller must ensure the button is in the modal or a timeout will occur while waiting for the modal to be hidden."},{"lineNumber":595,"author":{"gitId":"-"},"content":" * @param dismissModalButton a button that dismisses the modal"},{"lineNumber":596,"author":{"gitId":"-"},"content":" */"},{"lineNumber":597,"author":{"gitId":"-"},"content":" public void clickDismissModalButtonAndWaitForModalHidden(WebElement dismissModalButton) {"},{"lineNumber":598,"author":{"gitId":"-"},"content":" // Note: Should first check if the button can actually dismiss the modal otherwise the state will be consistent."},{"lineNumber":599,"author":{"gitId":"-"},"content":" // However, it is too difficult to check."},{"lineNumber":600,"author":{"gitId":"-"},"content":""},{"lineNumber":601,"author":{"gitId":"-"},"content":" WebElement modalBackdrop \u003d browser.driver.findElement(By.className(\"modal-backdrop\"));"},{"lineNumber":602,"author":{"gitId":"-"},"content":""},{"lineNumber":603,"author":{"gitId":"-"},"content":" click(dismissModalButton);"},{"lineNumber":604,"author":{"gitId":"-"},"content":" waitForModalHidden(modalBackdrop);"},{"lineNumber":605,"author":{"gitId":"-"},"content":" }"},{"lineNumber":606,"author":{"gitId":"-"},"content":""},{"lineNumber":607,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":608,"author":{"gitId":"-"},"content":" * Scrolls element to center and clicks on it."},{"lineNumber":609,"author":{"gitId":"-"},"content":" *"},{"lineNumber":610,"author":{"gitId":"-"},"content":" * \u003cp\u003eAs compared to {@link org.openqa.selenium.interactions.Actions#moveToElement(WebElement)}, this method is"},{"lineNumber":611,"author":{"gitId":"-"},"content":" * more reliable as the element will not get blocked by elements such as the header."},{"lineNumber":612,"author":{"gitId":"-"},"content":" *"},{"lineNumber":613,"author":{"gitId":"-"},"content":" * \u003cp\u003eFurthermore, {@link org.openqa.selenium.interactions.Actions#moveToElement(WebElement)} is currently not"},{"lineNumber":614,"author":{"gitId":"-"},"content":" * working in Geckodriver."},{"lineNumber":615,"author":{"gitId":"-"},"content":" *"},{"lineNumber":616,"author":{"gitId":"-"},"content":" * \u003cp\u003e\u003cb\u003eNote:\u003c/b\u003e A \"scroll into view\" Actions primitive is in progress and may allow scrolling element to center."},{"lineNumber":617,"author":{"gitId":"-"},"content":" * Tracking issue:"},{"lineNumber":618,"author":{"gitId":"-"},"content":" * \u003ca href\u003d\"https://github.com/w3c/webdriver/issues/1005\"\u003eMissing \"scroll into view\" Actions primitive\u003c/a\u003e."},{"lineNumber":619,"author":{"gitId":"-"},"content":" *"},{"lineNumber":620,"author":{"gitId":"-"},"content":" * \u003cp\u003eAlso note that there are some other caveats, for example"},{"lineNumber":621,"author":{"gitId":"-"},"content":" * {@code new Actions(browser.driver).moveToElement(...).click(...).perform()} does not behave consistently across"},{"lineNumber":622,"author":{"gitId":"-"},"content":" * browsers."},{"lineNumber":623,"author":{"gitId":"-"},"content":" * \u003cul\u003e"},{"lineNumber":624,"author":{"gitId":"-"},"content":" * \u003cli\u003eIn FirefoxDriver, the element is scrolled to and then a click is attempted on the element."},{"lineNumber":625,"author":{"gitId":"-"},"content":" * \u003cli\u003eIn ChromeDriver, the mouse is scrolled to the element and then a click is attempted on the mouse coordinate,"},{"lineNumber":626,"author":{"gitId":"-"},"content":" * which means another element can actually be clicked (such as the header or a blocking pop-up)."},{"lineNumber":627,"author":{"gitId":"-"},"content":" * \u003c/ul\u003e"},{"lineNumber":628,"author":{"gitId":"-"},"content":" *"},{"lineNumber":629,"author":{"gitId":"-"},"content":" * \u003cp\u003eChromeDriver also automatically scrolls to an element when clicking an element if it is not in the viewport."},{"lineNumber":630,"author":{"gitId":"-"},"content":" */"},{"lineNumber":631,"author":{"gitId":"-"},"content":" void scrollElementToCenterAndClick(WebElement element) {"},{"lineNumber":632,"author":{"gitId":"-"},"content":" // TODO: migrate to `scrollIntoView` when Geckodriver is adopted"},{"lineNumber":633,"author":{"gitId":"-"},"content":" scrollElementToCenter(element);"},{"lineNumber":634,"author":{"gitId":"-"},"content":" element.click();"},{"lineNumber":635,"author":{"gitId":"-"},"content":" }"},{"lineNumber":636,"author":{"gitId":"-"},"content":""},{"lineNumber":637,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":638,"author":{"gitId":"-"},"content":" * Scrolls element to center."},{"lineNumber":639,"author":{"gitId":"-"},"content":" */"},{"lineNumber":640,"author":{"gitId":"-"},"content":" void scrollElementToCenter(WebElement element) {"},{"lineNumber":641,"author":{"gitId":"-"},"content":" executeScript(SCROLL_ELEMENT_TO_CENTER_AND_CLICK_SCRIPT, element);"},{"lineNumber":642,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(1000);"},{"lineNumber":643,"author":{"gitId":"-"},"content":" }"},{"lineNumber":644,"author":{"gitId":"-"},"content":""},{"lineNumber":645,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":646,"author":{"gitId":"-"},"content":" * Asserts message in toast is equal to the expected message."},{"lineNumber":647,"author":{"gitId":"-"},"content":" */"},{"lineNumber":648,"author":{"gitId":"-"},"content":" public void verifyStatusMessage(String expectedMessage) {"},{"lineNumber":649,"author":{"gitId":"-"},"content":" verifyStatusMessageWithLinks(expectedMessage, new String[] {});"},{"lineNumber":650,"author":{"gitId":"-"},"content":" closeToast();"},{"lineNumber":651,"author":{"gitId":"-"},"content":" }"},{"lineNumber":652,"author":{"gitId":"-"},"content":""},{"lineNumber":653,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":654,"author":{"gitId":"-"},"content":" * Asserts message in toast is equal to the expected message and contains the expected links."},{"lineNumber":655,"author":{"gitId":"-"},"content":" */"},{"lineNumber":656,"author":{"gitId":"-"},"content":" public void verifyStatusMessageWithLinks(String expectedMessage, String[] expectedLinks) {"},{"lineNumber":657,"author":{"gitId":"-"},"content":" WebElement[] statusMessage \u003d new WebElement[1];"},{"lineNumber":658,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":659,"author":{"gitId":"-"},"content":" uiRetryManager.runUntilNoRecognizedException(new Retryable(\"Verify status to user\") {"},{"lineNumber":660,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":661,"author":{"gitId":"-"},"content":" public void run() {"},{"lineNumber":662,"author":{"gitId":"-"},"content":" statusMessage[0] \u003d waitForElementPresence(By.className(\"toast-body\"));"},{"lineNumber":663,"author":{"gitId":"-"},"content":" assertEquals(expectedMessage, statusMessage[0].getText());"},{"lineNumber":664,"author":{"gitId":"-"},"content":" }"},{"lineNumber":665,"author":{"gitId":"-"},"content":" }, WebDriverException.class, AssertionError.class);"},{"lineNumber":666,"author":{"gitId":"-"},"content":" } catch (MaximumRetriesExceededException e) {"},{"lineNumber":667,"author":{"gitId":"-"},"content":" statusMessage[0] \u003d waitForElementPresence(By.className(\"toast-body\"));"},{"lineNumber":668,"author":{"gitId":"-"},"content":" assertEquals(expectedMessage, statusMessage[0].getText());"},{"lineNumber":669,"author":{"gitId":"-"},"content":" } finally {"},{"lineNumber":670,"author":{"gitId":"-"},"content":" if (expectedLinks.length \u003e 0) {"},{"lineNumber":671,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e actualLinks \u003d statusMessage[0].findElements(By.tagName(\"a\"));"},{"lineNumber":672,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c expectedLinks.length; i++) {"},{"lineNumber":673,"author":{"gitId":"-"},"content":" assertTrue(actualLinks.get(i).getAttribute(\"href\").contains(expectedLinks[i]));"},{"lineNumber":674,"author":{"gitId":"-"},"content":" }"},{"lineNumber":675,"author":{"gitId":"-"},"content":" }"},{"lineNumber":676,"author":{"gitId":"-"},"content":" }"},{"lineNumber":677,"author":{"gitId":"-"},"content":" }"},{"lineNumber":678,"author":{"gitId":"-"},"content":""},{"lineNumber":679,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":680,"author":{"gitId":"-"},"content":" * Closes toast message."},{"lineNumber":681,"author":{"gitId":"-"},"content":" */"},{"lineNumber":682,"author":{"gitId":"-"},"content":" public void closeToast() {"},{"lineNumber":683,"author":{"gitId":"-"},"content":" WebElement toastCloseButton \u003d waitForElementPresence(By.className(\"btn-close\"));"},{"lineNumber":684,"author":{"gitId":"-"},"content":" click(toastCloseButton);"},{"lineNumber":685,"author":{"gitId":"-"},"content":" }"},{"lineNumber":686,"author":{"gitId":"-"},"content":""},{"lineNumber":687,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":688,"author":{"gitId":"-"},"content":" * Switches to the new browser window just opened."},{"lineNumber":689,"author":{"gitId":"-"},"content":" */"},{"lineNumber":690,"author":{"gitId":"-"},"content":" protected void switchToNewWindow() {"},{"lineNumber":691,"author":{"gitId":"-"},"content":" browser.switchToNewWindow();"},{"lineNumber":692,"author":{"gitId":"-"},"content":" }"},{"lineNumber":693,"author":{"gitId":"-"},"content":""},{"lineNumber":694,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":695,"author":{"gitId":"-"},"content":" * Closes current window and switches back to parent window."},{"lineNumber":696,"author":{"gitId":"-"},"content":" */"},{"lineNumber":697,"author":{"gitId":"-"},"content":" public void closeCurrentWindowAndSwitchToParentWindow() {"},{"lineNumber":698,"author":{"gitId":"-"},"content":" browser.closeCurrentWindowAndSwitchToParentWindow();"},{"lineNumber":699,"author":{"gitId":"-"},"content":" }"},{"lineNumber":700,"author":{"gitId":"-"},"content":""},{"lineNumber":701,"author":{"gitId":"-"},"content":" String getDisplayGiverName(FeedbackParticipantType type) {"},{"lineNumber":702,"author":{"gitId":"-"},"content":" switch (type) {"},{"lineNumber":703,"author":{"gitId":"-"},"content":" case SELF:"},{"lineNumber":704,"author":{"gitId":"-"},"content":" return \"Feedback session creator (i.e., me)\";"},{"lineNumber":705,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":706,"author":{"gitId":"-"},"content":" return \"Students in this course\";"},{"lineNumber":707,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":708,"author":{"gitId":"-"},"content":" return \"Instructors in this course\";"},{"lineNumber":709,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":710,"author":{"gitId":"-"},"content":" return \"Teams in this course\";"},{"lineNumber":711,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":712,"author":{"gitId":"-"},"content":" throw new IllegalArgumentException(\"Unknown FeedbackParticipantType: \" + type);"},{"lineNumber":713,"author":{"gitId":"-"},"content":" }"},{"lineNumber":714,"author":{"gitId":"-"},"content":" }"},{"lineNumber":715,"author":{"gitId":"-"},"content":""},{"lineNumber":716,"author":{"gitId":"-"},"content":" String getDisplayRecipientName(FeedbackParticipantType type) {"},{"lineNumber":717,"author":{"gitId":"-"},"content":" switch (type) {"},{"lineNumber":718,"author":{"gitId":"-"},"content":" case SELF:"},{"lineNumber":719,"author":{"gitId":"-"},"content":" return \"Giver (Self feedback)\";"},{"lineNumber":720,"author":{"gitId":"-"},"content":" case STUDENTS_IN_SAME_SECTION:"},{"lineNumber":721,"author":{"gitId":"-"},"content":" return \"Other students in the same section\";"},{"lineNumber":722,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":723,"author":{"gitId":"-"},"content":" return \"Students in the course\";"},{"lineNumber":724,"author":{"gitId":"-"},"content":" case STUDENTS_EXCLUDING_SELF:"},{"lineNumber":725,"author":{"gitId":"-"},"content":" return \"Other students in the course\";"},{"lineNumber":726,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":727,"author":{"gitId":"-"},"content":" return \"Instructors in the course\";"},{"lineNumber":728,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":729,"author":{"gitId":"-"},"content":" return \"Other teams in the same section\";"},{"lineNumber":730,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":731,"author":{"gitId":"-"},"content":" return \"Teams in the course\";"},{"lineNumber":732,"author":{"gitId":"-"},"content":" case TEAMS_EXCLUDING_SELF:"},{"lineNumber":733,"author":{"gitId":"-"},"content":" return \"Other teams in the course\";"},{"lineNumber":734,"author":{"gitId":"-"},"content":" case OWN_TEAM:"},{"lineNumber":735,"author":{"gitId":"-"},"content":" return \"Giver\u0027s team\";"},{"lineNumber":736,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":737,"author":{"gitId":"-"},"content":" return \"Giver\u0027s team members\";"},{"lineNumber":738,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS_INCLUDING_SELF:"},{"lineNumber":739,"author":{"gitId":"-"},"content":" return \"Giver\u0027s team members and Giver\";"},{"lineNumber":740,"author":{"gitId":"-"},"content":" case NONE:"},{"lineNumber":741,"author":{"gitId":"-"},"content":" return \"Nobody specific (For general class feedback)\";"},{"lineNumber":742,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":743,"author":{"gitId":"-"},"content":" throw new IllegalArgumentException(\"Unknown FeedbackParticipantType: \" + type);"},{"lineNumber":744,"author":{"gitId":"-"},"content":" }"},{"lineNumber":745,"author":{"gitId":"-"},"content":" }"},{"lineNumber":746,"author":{"gitId":"-"},"content":""},{"lineNumber":747,"author":{"gitId":"-"},"content":" String getDisplayedDateTime(Instant instant, String timeZone, String pattern) {"},{"lineNumber":748,"author":{"gitId":"-"},"content":" ZonedDateTime zonedDateTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone(instant, timeZone, false)"},{"lineNumber":749,"author":{"gitId":"-"},"content":" .atZone(ZoneId.of(timeZone));"},{"lineNumber":750,"author":{"gitId":"yuanxi1"},"content":" return DateTimeFormatter.ofPattern(pattern, Locale.ENGLISH).format(zonedDateTime);"},{"lineNumber":751,"author":{"gitId":"-"},"content":" }"},{"lineNumber":752,"author":{"gitId":"-"},"content":""},{"lineNumber":753,"author":{"gitId":"-"},"content":" private String getFullDateString(Instant instant, String timeZone) {"},{"lineNumber":754,"author":{"gitId":"-"},"content":" return getDisplayedDateTime(instant, timeZone, \"EEEE, MMMM d, yyyy\");"},{"lineNumber":755,"author":{"gitId":"-"},"content":" }"},{"lineNumber":756,"author":{"gitId":"-"},"content":""},{"lineNumber":757,"author":{"gitId":"-"},"content":" private String getYearString(Instant instant, String timeZone) {"},{"lineNumber":758,"author":{"gitId":"-"},"content":" return getDisplayedDateTime(instant, timeZone, \"yyyy\");"},{"lineNumber":759,"author":{"gitId":"-"},"content":" }"},{"lineNumber":760,"author":{"gitId":"-"},"content":""},{"lineNumber":761,"author":{"gitId":"-"},"content":" private String getMonthString(Instant instant, String timeZone) {"},{"lineNumber":762,"author":{"gitId":"-"},"content":" return getDisplayedDateTime(instant, timeZone, \"MMM\");"},{"lineNumber":763,"author":{"gitId":"-"},"content":" }"},{"lineNumber":764,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":7,"yuanxi1":2,"-":755}},{"path":"src/e2e/java/teammates/e2e/pageobjects/FeedbackSubmitPage.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.pageobjects;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertEquals;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertFalse;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertTrue;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.fail;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.Collections;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.openqa.selenium.By;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import org.openqa.selenium.NoSuchElementException;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import org.openqa.selenium.WebElement;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseAttributes;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackConstantSumQuestionDetails;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackConstantSumResponseDetails;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackContributionQuestionDetails;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackContributionResponseDetails;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackMcqQuestionDetails;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackMcqResponseDetails;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackMsqQuestionDetails;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackMsqResponseDetails;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackNumericalScaleQuestionDetails;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackNumericalScaleResponseDetails;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRankOptionsQuestionDetails;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRankOptionsResponseDetails;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRankQuestionDetails;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRankRecipientsResponseDetails;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRubricQuestionDetails;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRubricResponseDetails;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackTextQuestionDetails;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackTextResponseDetails;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":43,"author":{"gitId":"-"},"content":" * Represents the feedback submission page of the website."},{"lineNumber":44,"author":{"gitId":"-"},"content":" */"},{"lineNumber":45,"author":{"gitId":"-"},"content":"public class FeedbackSubmitPage extends AppPage {"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" public FeedbackSubmitPage(Browser browser) {"},{"lineNumber":48,"author":{"gitId":"-"},"content":" super(browser);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":52,"author":{"gitId":"-"},"content":" protected boolean containsExpectedPageContents() {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" if (isElementPresent(By.className(\"modal-content\"))) {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":" return getPageTitle().contains(\"Submit Feedback\");"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" public void verifyFeedbackSessionDetails(FeedbackSessionAttributes feedbackSession, CourseAttributes course) {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" assertEquals(getCourseId(), feedbackSession.getCourseId());"},{"lineNumber":61,"author":{"gitId":"-"},"content":" assertEquals(getCourseName(), course.getName());"},{"lineNumber":62,"author":{"gitId":"-"},"content":" assertEquals(getCourseInstitute(), course.getInstitute());"},{"lineNumber":63,"author":{"gitId":"-"},"content":" assertEquals(getFeedbackSessionName(), feedbackSession.getFeedbackSessionName());"},{"lineNumber":64,"author":{"gitId":"-"},"content":" assertDateEquals(getOpeningTime(), feedbackSession.getStartTime(), feedbackSession.getTimeZone());"},{"lineNumber":65,"author":{"gitId":"-"},"content":" assertDateEquals(getClosingTime(), feedbackSession.getEndTime(), feedbackSession.getTimeZone());"},{"lineNumber":66,"author":{"gitId":"-"},"content":" assertEquals(getInstructions(), feedbackSession.getInstructions());"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" public void verifyNumQuestions(int expected) {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" assertEquals(browser.driver.findElements(By.cssSelector(\"[id^\u003d\u0027question-submission-form-qn-\u0027]\")).size(), expected);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" public void verifyQuestionDetails(int qnNumber, FeedbackQuestionAttributes questionAttributes) {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" assertEquals(getQuestionBrief(qnNumber), questionAttributes.getQuestionDetailsCopy().getQuestionText());"},{"lineNumber":75,"author":{"gitId":"-"},"content":" verifyVisibilityList(qnNumber, questionAttributes);"},{"lineNumber":76,"author":{"gitId":"-"},"content":" if (questionAttributes.getQuestionDescription() !\u003d null) {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" assertEquals(getQuestionDescription(qnNumber), questionAttributes.getQuestionDescription());"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }"},{"lineNumber":79,"author":{"gitId":"-"},"content":" }"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" public void verifyLimitedRecipients(int qnNumber, int numRecipients, List\u003cString\u003e recipientNames) {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e recipientDropdowns \u003d getQuestionForm(qnNumber)"},{"lineNumber":83,"author":{"gitId":"-"},"content":" .findElements(By.cssSelector(\"[id^\u003d\u0027recipient-dropdown-qn-\u0027]\"));"},{"lineNumber":84,"author":{"gitId":"-"},"content":" assertEquals(numRecipients, recipientDropdowns.size());"},{"lineNumber":85,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e recipients \u003d recipientDropdowns.get(0).findElements(By.tagName(\"option\"));"},{"lineNumber":86,"author":{"gitId":"-"},"content":" assertEquals(recipientNames.size(), recipients.size() - 1);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" Collections.sort(recipientNames);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c recipientNames.size(); i++) {"},{"lineNumber":89,"author":{"gitId":"-"},"content":" assertEquals(recipientNames.get(i), recipients.get(i + 1).getText());"},{"lineNumber":90,"author":{"gitId":"-"},"content":" }"},{"lineNumber":91,"author":{"gitId":"-"},"content":" }"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" public void verifyRecipients(int qnNumber, List\u003cString\u003e recipientNames, String role) {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(qnNumber);"},{"lineNumber":95,"author":{"gitId":"-"},"content":" Collections.sort(recipientNames);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c recipientNames.size(); i++) {"},{"lineNumber":97,"author":{"gitId":"-"},"content":" assertEquals(recipientNames.get(i) + \" (\" + role + \")\","},{"lineNumber":98,"author":{"gitId":"-"},"content":" questionForm.findElement(By.id(\"recipient-name-qn-\" + qnNumber + \"-idx-\" + i)).getText());"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" public void verifyWarningMessageForPartialResponse(int[] unansweredQuestions) {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" click(getSubmitAllQuestionsButton());"},{"lineNumber":104,"author":{"gitId":"-"},"content":" StringBuilder expectedSb \u003d new StringBuilder();"},{"lineNumber":105,"author":{"gitId":"-"},"content":" for (int unansweredQuestion : unansweredQuestions) {"},{"lineNumber":106,"author":{"gitId":"-"},"content":" expectedSb.append(unansweredQuestion).append(\", \");"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":" String expectedString \u003d expectedSb.toString().substring(0, expectedSb.length() - 2) + \".\";"},{"lineNumber":109,"author":{"gitId":"-"},"content":" String warningString \u003d waitForElementPresence(By.id(\"not-answered-questions\")).getText();"},{"lineNumber":110,"author":{"gitId":"-"},"content":" assertEquals(warningString.split(\": \")[1], expectedString);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" waitForConfirmationModalAndClickOk();"},{"lineNumber":112,"author":{"gitId":"-"},"content":" }"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" public void verifyCannotSubmit() {"},{"lineNumber":115,"author":{"gitId":"-"},"content":" WebElement submitButton \u003d waitForElementPresence(By.cssSelector(\"[id^\u003d\u0027btn-submit-qn-\u0027]\"));"},{"lineNumber":116,"author":{"gitId":"-"},"content":" if (submitButton !\u003d null) {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" assertFalse(submitButton.isEnabled());"},{"lineNumber":118,"author":{"gitId":"-"},"content":" }"},{"lineNumber":119,"author":{"gitId":"-"},"content":" }"},{"lineNumber":120,"author":{"gitId":"-"},"content":""},{"lineNumber":121,"author":{"gitId":"-"},"content":" public void addComment(int qnNumber, String recipient, String newComment) {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" WebElement commentSection \u003d getCommentSection(qnNumber, recipient);"},{"lineNumber":123,"author":{"gitId":"-"},"content":" click(commentSection.findElement(By.className(\"btn-add-comment\")));"},{"lineNumber":124,"author":{"gitId":"-"},"content":" writeToCommentEditor(commentSection, newComment);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" }"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" public void editComment(int qnNumber, String recipient, String editedComment) {"},{"lineNumber":128,"author":{"gitId":"-"},"content":" WebElement commentSection \u003d getCommentSection(qnNumber, recipient);"},{"lineNumber":129,"author":{"gitId":"-"},"content":" click(commentSection.findElement(By.className(\"btn-edit-comment\")));"},{"lineNumber":130,"author":{"gitId":"-"},"content":" writeToCommentEditor(commentSection, editedComment);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" }"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" public void deleteComment(int qnNumber, String recipient) {"},{"lineNumber":134,"author":{"gitId":"-"},"content":" clickAndConfirm(getCommentSection(qnNumber, recipient).findElement(By.className(\"btn-delete-comment\")));"},{"lineNumber":135,"author":{"gitId":"-"},"content":" }"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" public void verifyComment(int qnNumber, String recipient, String expectedComment) {"},{"lineNumber":138,"author":{"gitId":"-"},"content":" WebElement commentSection \u003d getCommentSection(qnNumber, recipient);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" String actualComment \u003d commentSection.findElement(By.className(\"comment-text\")).getAttribute(\"innerHTML\");"},{"lineNumber":140,"author":{"gitId":"-"},"content":" assertEquals(expectedComment, actualComment);"},{"lineNumber":141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" public void verifyNoCommentPresent(int qnNumber, String recipient) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" int numComments \u003d getCommentSection(qnNumber, recipient).findElements(By.className(\"comment-text\")).size();"},{"lineNumber":145,"author":{"gitId":"-"},"content":" assertEquals(numComments, 0);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" }"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" public void verifyTextQuestion(int qnNumber, FeedbackTextQuestionDetails questionDetails) {"},{"lineNumber":149,"author":{"gitId":"-"},"content":" String recommendedLengthText \u003d getQuestionForm(qnNumber).findElement(By.id(\"recommended-length\")).getText();"},{"lineNumber":150,"author":{"gitId":"-"},"content":" assertEquals(recommendedLengthText, \"Recommended length for the answer: \""},{"lineNumber":151,"author":{"gitId":"-"},"content":" + questionDetails.getRecommendedLength() + \" words\");"},{"lineNumber":152,"author":{"gitId":"-"},"content":" }"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"-"},"content":" public void fillTextResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":155,"author":{"gitId":"-"},"content":" FeedbackTextResponseDetails responseDetails \u003d (FeedbackTextResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":156,"author":{"gitId":"-"},"content":" writeToRichTextEditor(getTextResponseEditor(qnNumber, recipient), responseDetails.getAnswer());"},{"lineNumber":157,"author":{"gitId":"-"},"content":" }"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" public void fillTextResponse(int qnNumber, String recipient, FeedbackResponse response) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" FeedbackTextResponseDetails responseDetails \u003d"},{"lineNumber":161,"author":{"gitId":"-"},"content":" (FeedbackTextResponseDetails) response.getFeedbackResponseDetailsCopy();"},{"lineNumber":162,"author":{"gitId":"-"},"content":" writeToRichTextEditor(getTextResponseEditor(qnNumber, recipient), responseDetails.getAnswer());"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" public void verifyTextResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":166,"author":{"gitId":"-"},"content":" FeedbackTextResponseDetails responseDetails \u003d (FeedbackTextResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":167,"author":{"gitId":"-"},"content":" int responseLength \u003d responseDetails.getAnswer().split(\" \").length;"},{"lineNumber":168,"author":{"gitId":"-"},"content":" assertEquals(getEditorRichText(getTextResponseEditor(qnNumber, recipient)), responseDetails.getAnswer());"},{"lineNumber":169,"author":{"gitId":"-"},"content":" assertEquals(getResponseLengthText(qnNumber, recipient), \"Response length: \" + responseLength"},{"lineNumber":170,"author":{"gitId":"-"},"content":" + \" words\");"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" public void verifyTextResponse(int qnNumber, String recipient, FeedbackResponse response) {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" FeedbackTextResponseDetails responseDetails \u003d"},{"lineNumber":175,"author":{"gitId":"-"},"content":" (FeedbackTextResponseDetails) response.getFeedbackResponseDetailsCopy();"},{"lineNumber":176,"author":{"gitId":"-"},"content":" int responseLength \u003d responseDetails.getAnswer().split(\" \").length;"},{"lineNumber":177,"author":{"gitId":"-"},"content":" assertEquals(getEditorRichText(getTextResponseEditor(qnNumber, recipient)), responseDetails.getAnswer());"},{"lineNumber":178,"author":{"gitId":"-"},"content":" assertEquals(getResponseLengthText(qnNumber, recipient), \"Response length: \" + responseLength"},{"lineNumber":179,"author":{"gitId":"-"},"content":" + \" words\");"},{"lineNumber":180,"author":{"gitId":"-"},"content":" }"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" public void verifyMcqQuestion(int qnNumber, String recipient, FeedbackMcqQuestionDetails questionDetails) {"},{"lineNumber":183,"author":{"gitId":"-"},"content":" List\u003cString\u003e mcqChoices \u003d questionDetails.getMcqChoices();"},{"lineNumber":184,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMcqOptions(qnNumber, recipient);"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c mcqChoices.size(); i++) {"},{"lineNumber":187,"author":{"gitId":"-"},"content":" assertEquals(mcqChoices.get(i), optionTexts.get(i).getText());"},{"lineNumber":188,"author":{"gitId":"-"},"content":" }"},{"lineNumber":189,"author":{"gitId":"-"},"content":""},{"lineNumber":190,"author":{"gitId":"-"},"content":" if (questionDetails.isOtherEnabled()) {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" assertEquals(\"Other\", getMcqSection(qnNumber, recipient).findElement(By.id(\"other-option\")).getText());"},{"lineNumber":192,"author":{"gitId":"-"},"content":" }"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"-"},"content":" public void verifyGeneratedMcqQuestion(int qnNumber, String recipient, List\u003cString\u003e options) {"},{"lineNumber":196,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMcqOptions(qnNumber, recipient);"},{"lineNumber":197,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c options.size(); i++) {"},{"lineNumber":198,"author":{"gitId":"-"},"content":" assertEquals(options.get(i), optionTexts.get(i).getText());"},{"lineNumber":199,"author":{"gitId":"-"},"content":" }"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }"},{"lineNumber":201,"author":{"gitId":"-"},"content":""},{"lineNumber":202,"author":{"gitId":"-"},"content":" public void fillMcqResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":203,"author":{"gitId":"-"},"content":" FeedbackMcqResponseDetails responseDetails \u003d (FeedbackMcqResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":204,"author":{"gitId":"-"},"content":" if (responseDetails.isOther()) {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" markOptionAsSelected(getMcqOtherOptionRadioBtn(qnNumber, recipient));"},{"lineNumber":206,"author":{"gitId":"-"},"content":" fillTextBox(getMcqOtherOptionTextbox(qnNumber, recipient), responseDetails.getOtherFieldContent());"},{"lineNumber":207,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":208,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMcqOptions(qnNumber, recipient);"},{"lineNumber":209,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c optionTexts.size(); i++) {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" if (optionTexts.get(i).getText().equals(responseDetails.getAnswer())) {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" markOptionAsSelected(getMcqRadioBtns(qnNumber, recipient).get(i));"},{"lineNumber":212,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":213,"author":{"gitId":"-"},"content":" }"},{"lineNumber":214,"author":{"gitId":"-"},"content":" }"},{"lineNumber":215,"author":{"gitId":"-"},"content":" }"},{"lineNumber":216,"author":{"gitId":"-"},"content":" }"},{"lineNumber":217,"author":{"gitId":"-"},"content":""},{"lineNumber":218,"author":{"gitId":"dishenggg"},"content":" public void fillMcqResponse(int qnNumber, String recipient, FeedbackResponse response) {"},{"lineNumber":219,"author":{"gitId":"dishenggg"},"content":" FeedbackMcqResponseDetails responseDetails \u003d (FeedbackMcqResponseDetails) response.getFeedbackResponseDetailsCopy();"},{"lineNumber":220,"author":{"gitId":"dishenggg"},"content":" if (responseDetails.isOther()) {"},{"lineNumber":221,"author":{"gitId":"dishenggg"},"content":" markOptionAsSelected(getMcqOtherOptionRadioBtn(qnNumber, recipient));"},{"lineNumber":222,"author":{"gitId":"dishenggg"},"content":" fillTextBox(getMcqOtherOptionTextbox(qnNumber, recipient), responseDetails.getOtherFieldContent());"},{"lineNumber":223,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":224,"author":{"gitId":"dishenggg"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMcqOptions(qnNumber, recipient);"},{"lineNumber":225,"author":{"gitId":"dishenggg"},"content":" for (int i \u003d 0; i \u003c optionTexts.size(); i++) {"},{"lineNumber":226,"author":{"gitId":"dishenggg"},"content":" if (optionTexts.get(i).getText().equals(responseDetails.getAnswer())) {"},{"lineNumber":227,"author":{"gitId":"dishenggg"},"content":" markOptionAsSelected(getMcqRadioBtns(qnNumber, recipient).get(i));"},{"lineNumber":228,"author":{"gitId":"dishenggg"},"content":" break;"},{"lineNumber":229,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":230,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":231,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":232,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":233,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":234,"author":{"gitId":"-"},"content":" public void verifyMcqResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":235,"author":{"gitId":"-"},"content":" FeedbackMcqResponseDetails responseDetails \u003d (FeedbackMcqResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":236,"author":{"gitId":"-"},"content":" if (responseDetails.isOther()) {"},{"lineNumber":237,"author":{"gitId":"-"},"content":" assertTrue(getMcqOtherOptionRadioBtn(qnNumber, recipient).isSelected());"},{"lineNumber":238,"author":{"gitId":"-"},"content":" assertEquals(getMcqOtherOptionTextbox(qnNumber, recipient).getAttribute(\"value\"),"},{"lineNumber":239,"author":{"gitId":"-"},"content":" responseDetails.getOtherFieldContent());"},{"lineNumber":240,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":241,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMcqOptions(qnNumber, recipient);"},{"lineNumber":242,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e radioBtns \u003d getMcqRadioBtns(qnNumber, recipient);"},{"lineNumber":243,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c optionTexts.size(); i++) {"},{"lineNumber":244,"author":{"gitId":"-"},"content":" if (optionTexts.get(i).getText().equals(responseDetails.getAnswer())) {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" assertTrue(radioBtns.get(i).isSelected());"},{"lineNumber":246,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":247,"author":{"gitId":"-"},"content":" }"},{"lineNumber":248,"author":{"gitId":"-"},"content":" assertFalse(radioBtns.get(i).isSelected());"},{"lineNumber":249,"author":{"gitId":"-"},"content":" }"},{"lineNumber":250,"author":{"gitId":"-"},"content":" }"},{"lineNumber":251,"author":{"gitId":"-"},"content":" }"},{"lineNumber":252,"author":{"gitId":"-"},"content":""},{"lineNumber":253,"author":{"gitId":"-"},"content":" public void verifyMsqQuestion(int qnNumber, String recipient, FeedbackMsqQuestionDetails questionDetails) {"},{"lineNumber":254,"author":{"gitId":"-"},"content":" List\u003cString\u003e msqChoices \u003d questionDetails.getMsqChoices();"},{"lineNumber":255,"author":{"gitId":"-"},"content":" if (questionDetails.isOtherEnabled()) {"},{"lineNumber":256,"author":{"gitId":"-"},"content":" msqChoices.add(\"Other\");"},{"lineNumber":257,"author":{"gitId":"-"},"content":" }"},{"lineNumber":258,"author":{"gitId":"-"},"content":" if (questionDetails.getMinSelectableChoices() \u003d\u003d Const.POINTS_NO_VALUE) {"},{"lineNumber":259,"author":{"gitId":"-"},"content":" msqChoices.add(\"None of the above\");"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMsqOptions(qnNumber, recipient);"},{"lineNumber":262,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c msqChoices.size(); i++) {"},{"lineNumber":263,"author":{"gitId":"-"},"content":" assertEquals(msqChoices.get(i), optionTexts.get(i).getText());"},{"lineNumber":264,"author":{"gitId":"-"},"content":" }"},{"lineNumber":265,"author":{"gitId":"-"},"content":" verifyMsqSelectableOptionsMessage(qnNumber, questionDetails);"},{"lineNumber":266,"author":{"gitId":"-"},"content":" }"},{"lineNumber":267,"author":{"gitId":"-"},"content":""},{"lineNumber":268,"author":{"gitId":"-"},"content":" private void verifyMsqSelectableOptionsMessage(int qnNumber, FeedbackMsqQuestionDetails questionDetails) {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" if (questionDetails.getMinSelectableChoices() !\u003d Const.POINTS_NO_VALUE) {"},{"lineNumber":270,"author":{"gitId":"-"},"content":" assertEquals(getQuestionForm(qnNumber).findElement(By.id(\"min-options-message\")).getText(),"},{"lineNumber":271,"author":{"gitId":"-"},"content":" \"Choose at least \" + questionDetails.getMinSelectableChoices() + \" options.\");"},{"lineNumber":272,"author":{"gitId":"-"},"content":" }"},{"lineNumber":273,"author":{"gitId":"-"},"content":" if (questionDetails.getMaxSelectableChoices() !\u003d Const.POINTS_NO_VALUE) {"},{"lineNumber":274,"author":{"gitId":"-"},"content":" assertEquals(getQuestionForm(qnNumber).findElement(By.id(\"max-options-message\")).getText(),"},{"lineNumber":275,"author":{"gitId":"-"},"content":" \"Choose no more than \" + questionDetails.getMaxSelectableChoices() + \" options.\");"},{"lineNumber":276,"author":{"gitId":"-"},"content":" }"},{"lineNumber":277,"author":{"gitId":"-"},"content":" }"},{"lineNumber":278,"author":{"gitId":"-"},"content":""},{"lineNumber":279,"author":{"gitId":"-"},"content":" public void verifyGeneratedMsqQuestion(int qnNumber, String recipient, FeedbackMsqQuestionDetails questionDetails,"},{"lineNumber":280,"author":{"gitId":"-"},"content":" List\u003cString\u003e options) {"},{"lineNumber":281,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMsqOptions(qnNumber, recipient);"},{"lineNumber":282,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c options.size(); i++) {"},{"lineNumber":283,"author":{"gitId":"-"},"content":" assertEquals(options.get(i), optionTexts.get(i).getText());"},{"lineNumber":284,"author":{"gitId":"-"},"content":" }"},{"lineNumber":285,"author":{"gitId":"-"},"content":" verifyMsqSelectableOptionsMessage(qnNumber, questionDetails);"},{"lineNumber":286,"author":{"gitId":"-"},"content":" }"},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":" public void fillMsqResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" FeedbackMsqResponseDetails responseDetails \u003d (FeedbackMsqResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":290,"author":{"gitId":"-"},"content":" List\u003cString\u003e answers \u003d responseDetails.getAnswers();"},{"lineNumber":291,"author":{"gitId":"-"},"content":" if (answers.get(0).isEmpty()) {"},{"lineNumber":292,"author":{"gitId":"-"},"content":" answers.add(\"None of the above\");"},{"lineNumber":293,"author":{"gitId":"-"},"content":" }"},{"lineNumber":294,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMsqOptions(qnNumber, recipient);"},{"lineNumber":295,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e checkboxes \u003d getMsqCheckboxes(qnNumber, recipient);"},{"lineNumber":296,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c optionTexts.size(); i++) {"},{"lineNumber":297,"author":{"gitId":"-"},"content":" if (answers.contains(optionTexts.get(i).getText())) {"},{"lineNumber":298,"author":{"gitId":"-"},"content":" markOptionAsSelected(checkboxes.get(i));"},{"lineNumber":299,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":300,"author":{"gitId":"-"},"content":" markOptionAsUnselected(checkboxes.get(i));"},{"lineNumber":301,"author":{"gitId":"-"},"content":" }"},{"lineNumber":302,"author":{"gitId":"-"},"content":" }"},{"lineNumber":303,"author":{"gitId":"-"},"content":" if (responseDetails.isOther()) {"},{"lineNumber":304,"author":{"gitId":"-"},"content":" markOptionAsSelected(getMsqOtherOptionCheckbox(qnNumber, recipient));"},{"lineNumber":305,"author":{"gitId":"-"},"content":" fillTextBox(getMsqOtherOptionTextbox(qnNumber, recipient), responseDetails.getOtherFieldContent());"},{"lineNumber":306,"author":{"gitId":"-"},"content":" }"},{"lineNumber":307,"author":{"gitId":"-"},"content":" }"},{"lineNumber":308,"author":{"gitId":"-"},"content":""},{"lineNumber":309,"author":{"gitId":"dishenggg"},"content":" public void fillMsqResponse(int qnNumber, String recipient, FeedbackResponse response) {"},{"lineNumber":310,"author":{"gitId":"dishenggg"},"content":" FeedbackMsqResponseDetails responseDetails \u003d (FeedbackMsqResponseDetails) response.getFeedbackResponseDetailsCopy();"},{"lineNumber":311,"author":{"gitId":"dishenggg"},"content":" List\u003cString\u003e answers \u003d responseDetails.getAnswers();"},{"lineNumber":312,"author":{"gitId":"dishenggg"},"content":" if (answers.get(0).isEmpty()) {"},{"lineNumber":313,"author":{"gitId":"dishenggg"},"content":" answers.add(\"None of the above\");"},{"lineNumber":314,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":315,"author":{"gitId":"dishenggg"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMsqOptions(qnNumber, recipient);"},{"lineNumber":316,"author":{"gitId":"dishenggg"},"content":" List\u003cWebElement\u003e checkboxes \u003d getMsqCheckboxes(qnNumber, recipient);"},{"lineNumber":317,"author":{"gitId":"dishenggg"},"content":" for (int i \u003d 0; i \u003c optionTexts.size(); i++) {"},{"lineNumber":318,"author":{"gitId":"dishenggg"},"content":" if (answers.contains(optionTexts.get(i).getText())) {"},{"lineNumber":319,"author":{"gitId":"dishenggg"},"content":" markOptionAsSelected(checkboxes.get(i));"},{"lineNumber":320,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":321,"author":{"gitId":"dishenggg"},"content":" markOptionAsUnselected(checkboxes.get(i));"},{"lineNumber":322,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":323,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":324,"author":{"gitId":"dishenggg"},"content":" if (responseDetails.isOther()) {"},{"lineNumber":325,"author":{"gitId":"dishenggg"},"content":" markOptionAsSelected(getMsqOtherOptionCheckbox(qnNumber, recipient));"},{"lineNumber":326,"author":{"gitId":"dishenggg"},"content":" fillTextBox(getMsqOtherOptionTextbox(qnNumber, recipient), responseDetails.getOtherFieldContent());"},{"lineNumber":327,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":328,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":329,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":330,"author":{"gitId":"-"},"content":" public void verifyMsqResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":331,"author":{"gitId":"-"},"content":" FeedbackMsqResponseDetails responseDetails \u003d (FeedbackMsqResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":332,"author":{"gitId":"-"},"content":" List\u003cString\u003e answers \u003d responseDetails.getAnswers();"},{"lineNumber":333,"author":{"gitId":"-"},"content":" if (answers.get(0).isEmpty()) {"},{"lineNumber":334,"author":{"gitId":"-"},"content":" answers.add(\"None of the above\");"},{"lineNumber":335,"author":{"gitId":"-"},"content":" }"},{"lineNumber":336,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMsqOptions(qnNumber, recipient);"},{"lineNumber":337,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e checkboxes \u003d getMsqCheckboxes(qnNumber, recipient);"},{"lineNumber":338,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c optionTexts.size(); i++) {"},{"lineNumber":339,"author":{"gitId":"-"},"content":" if (answers.contains(optionTexts.get(i).getText())) {"},{"lineNumber":340,"author":{"gitId":"-"},"content":" assertTrue(checkboxes.get(i).isSelected());"},{"lineNumber":341,"author":{"gitId":"-"},"content":" } else if (\"Other\".equals(optionTexts.get(i).getText())) {"},{"lineNumber":342,"author":{"gitId":"-"},"content":" assertEquals(checkboxes.get(i).isSelected(), responseDetails.isOther());"},{"lineNumber":343,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":344,"author":{"gitId":"-"},"content":" assertFalse(checkboxes.get(i).isSelected());"},{"lineNumber":345,"author":{"gitId":"-"},"content":" }"},{"lineNumber":346,"author":{"gitId":"-"},"content":" }"},{"lineNumber":347,"author":{"gitId":"-"},"content":" if (responseDetails.isOther()) {"},{"lineNumber":348,"author":{"gitId":"-"},"content":" assertEquals(getMsqOtherOptionTextbox(qnNumber, recipient).getAttribute(\"value\"),"},{"lineNumber":349,"author":{"gitId":"-"},"content":" responseDetails.getOtherFieldContent());"},{"lineNumber":350,"author":{"gitId":"-"},"content":" }"},{"lineNumber":351,"author":{"gitId":"-"},"content":" }"},{"lineNumber":352,"author":{"gitId":"-"},"content":""},{"lineNumber":353,"author":{"gitId":"dishenggg"},"content":" public void verifyMsqResponse(int qnNumber, String recipient, FeedbackResponse response) {"},{"lineNumber":354,"author":{"gitId":"dishenggg"},"content":" FeedbackMsqResponseDetails responseDetails \u003d (FeedbackMsqResponseDetails) response.getFeedbackResponseDetailsCopy();"},{"lineNumber":355,"author":{"gitId":"dishenggg"},"content":" List\u003cString\u003e answers \u003d responseDetails.getAnswers();"},{"lineNumber":356,"author":{"gitId":"dishenggg"},"content":" if (answers.get(0).isEmpty()) {"},{"lineNumber":357,"author":{"gitId":"dishenggg"},"content":" answers.add(\"None of the above\");"},{"lineNumber":358,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":359,"author":{"gitId":"dishenggg"},"content":" List\u003cWebElement\u003e optionTexts \u003d getMsqOptions(qnNumber, recipient);"},{"lineNumber":360,"author":{"gitId":"dishenggg"},"content":" List\u003cWebElement\u003e checkboxes \u003d getMsqCheckboxes(qnNumber, recipient);"},{"lineNumber":361,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c optionTexts.size(); i++) {"},{"lineNumber":362,"author":{"gitId":"-"},"content":" if (answers.contains(optionTexts.get(i).getText())) {"},{"lineNumber":363,"author":{"gitId":"-"},"content":" assertTrue(checkboxes.get(i).isSelected());"},{"lineNumber":364,"author":{"gitId":"-"},"content":" } else if (\"Other\".equals(optionTexts.get(i).getText())) {"},{"lineNumber":365,"author":{"gitId":"-"},"content":" assertEquals(checkboxes.get(i).isSelected(), responseDetails.isOther());"},{"lineNumber":366,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":367,"author":{"gitId":"-"},"content":" assertFalse(checkboxes.get(i).isSelected());"},{"lineNumber":368,"author":{"gitId":"-"},"content":" }"},{"lineNumber":369,"author":{"gitId":"-"},"content":" }"},{"lineNumber":370,"author":{"gitId":"-"},"content":" if (responseDetails.isOther()) {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" assertEquals(getMsqOtherOptionTextbox(qnNumber, recipient).getAttribute(\"value\"),"},{"lineNumber":372,"author":{"gitId":"-"},"content":" responseDetails.getOtherFieldContent());"},{"lineNumber":373,"author":{"gitId":"-"},"content":" }"},{"lineNumber":374,"author":{"gitId":"-"},"content":" }"},{"lineNumber":375,"author":{"gitId":"-"},"content":""},{"lineNumber":376,"author":{"gitId":"-"},"content":" public void verifyNumScaleQuestion(int qnNumber, String recipient,"},{"lineNumber":377,"author":{"gitId":"-"},"content":" FeedbackNumericalScaleQuestionDetails questionDetails) {"},{"lineNumber":378,"author":{"gitId":"-"},"content":" double step \u003d questionDetails.getStep();"},{"lineNumber":379,"author":{"gitId":"-"},"content":" double twoSteps \u003d 2 * step;"},{"lineNumber":380,"author":{"gitId":"-"},"content":" double min \u003d questionDetails.getMinScale();"},{"lineNumber":381,"author":{"gitId":"-"},"content":" double max \u003d questionDetails.getMaxScale();"},{"lineNumber":382,"author":{"gitId":"-"},"content":" String possibleValues \u003d String.format(\"Possible values: [%s, %s, %s, ..., %s, %s, %s]\","},{"lineNumber":383,"author":{"gitId":"-"},"content":" getDoubleString(min), getDoubleString(min + step), getDoubleString(min + twoSteps),"},{"lineNumber":384,"author":{"gitId":"-"},"content":" getDoubleString(max - twoSteps), getDoubleString(max - step), getDoubleString(max));"},{"lineNumber":385,"author":{"gitId":"-"},"content":" String actualValues \u003d getNumScaleSection(qnNumber, recipient).findElement(By.id(\"possible-values\")).getText();"},{"lineNumber":386,"author":{"gitId":"-"},"content":" assertEquals(actualValues, possibleValues);"},{"lineNumber":387,"author":{"gitId":"-"},"content":" }"},{"lineNumber":388,"author":{"gitId":"-"},"content":""},{"lineNumber":389,"author":{"gitId":"-"},"content":" public void fillNumScaleResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":390,"author":{"gitId":"-"},"content":" FeedbackNumericalScaleResponseDetails responseDetails \u003d"},{"lineNumber":391,"author":{"gitId":"-"},"content":" (FeedbackNumericalScaleResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":392,"author":{"gitId":"-"},"content":" fillTextBox(getNumScaleInput(qnNumber, recipient), Double.toString(responseDetails.getAnswer()));"},{"lineNumber":393,"author":{"gitId":"-"},"content":" }"},{"lineNumber":394,"author":{"gitId":"-"},"content":""},{"lineNumber":395,"author":{"gitId":"marquestye"},"content":" public void fillNumScaleResponse(int qnNumber, String recipient, FeedbackResponse response) {"},{"lineNumber":396,"author":{"gitId":"marquestye"},"content":" FeedbackNumericalScaleResponseDetails responseDetails \u003d"},{"lineNumber":397,"author":{"gitId":"marquestye"},"content":" (FeedbackNumericalScaleResponseDetails) response.getFeedbackResponseDetailsCopy();"},{"lineNumber":398,"author":{"gitId":"marquestye"},"content":" fillTextBox(getNumScaleInput(qnNumber, recipient), Double.toString(responseDetails.getAnswer()));"},{"lineNumber":399,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":400,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":401,"author":{"gitId":"-"},"content":" public void verifyNumScaleResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":402,"author":{"gitId":"-"},"content":" FeedbackNumericalScaleResponseDetails responseDetails \u003d"},{"lineNumber":403,"author":{"gitId":"-"},"content":" (FeedbackNumericalScaleResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":404,"author":{"gitId":"-"},"content":" assertEquals(getNumScaleInput(qnNumber, recipient).getAttribute(\"value\"),"},{"lineNumber":405,"author":{"gitId":"-"},"content":" getDoubleString(responseDetails.getAnswer()));"},{"lineNumber":406,"author":{"gitId":"-"},"content":" }"},{"lineNumber":407,"author":{"gitId":"-"},"content":""},{"lineNumber":408,"author":{"gitId":"marquestye"},"content":" public void verifyNumScaleResponse(int qnNumber, String recipient, FeedbackResponse response) {"},{"lineNumber":409,"author":{"gitId":"marquestye"},"content":" FeedbackNumericalScaleResponseDetails responseDetails \u003d"},{"lineNumber":410,"author":{"gitId":"marquestye"},"content":" (FeedbackNumericalScaleResponseDetails) response.getFeedbackResponseDetailsCopy();"},{"lineNumber":411,"author":{"gitId":"marquestye"},"content":" assertEquals(getNumScaleInput(qnNumber, recipient).getAttribute(\"value\"),"},{"lineNumber":412,"author":{"gitId":"marquestye"},"content":" getDoubleString(responseDetails.getAnswer()));"},{"lineNumber":413,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":414,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":415,"author":{"gitId":"-"},"content":" public void verifyConstSumQuestion(int qnNumber, String recipient,"},{"lineNumber":416,"author":{"gitId":"-"},"content":" FeedbackConstantSumQuestionDetails questionDetails) {"},{"lineNumber":417,"author":{"gitId":"-"},"content":" if (!questionDetails.isDistributeToRecipients()) {"},{"lineNumber":418,"author":{"gitId":"-"},"content":" List\u003cString\u003e constSumOptions \u003d questionDetails.getConstSumOptions();"},{"lineNumber":419,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getConstSumOptions(qnNumber, recipient);"},{"lineNumber":420,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c constSumOptions.size(); i++) {"},{"lineNumber":421,"author":{"gitId":"-"},"content":" assertEquals(constSumOptions.get(i), optionTexts.get(i).getText());"},{"lineNumber":422,"author":{"gitId":"-"},"content":" }"},{"lineNumber":423,"author":{"gitId":"-"},"content":" }"},{"lineNumber":424,"author":{"gitId":"-"},"content":""},{"lineNumber":425,"author":{"gitId":"-"},"content":" int totalPoints \u003d questionDetails.getPoints();"},{"lineNumber":426,"author":{"gitId":"-"},"content":" if (questionDetails.isPointsPerOption()) {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" totalPoints *\u003d questionDetails.getNumOfConstSumOptions();"},{"lineNumber":428,"author":{"gitId":"-"},"content":" }"},{"lineNumber":429,"author":{"gitId":"-"},"content":" assertEquals(getQuestionForm(qnNumber).findElement(By.id(\"total-points-message\")).getText(),"},{"lineNumber":430,"author":{"gitId":"-"},"content":" \"Total points distributed should add up to \" + totalPoints + \".\");"},{"lineNumber":431,"author":{"gitId":"-"},"content":""},{"lineNumber":432,"author":{"gitId":"-"},"content":" if (questionDetails.isForceUnevenDistribution()) {"},{"lineNumber":433,"author":{"gitId":"-"},"content":" String entityType \u003d questionDetails.isDistributeToRecipients() ? \"recipient\" : \"option\";"},{"lineNumber":434,"author":{"gitId":"-"},"content":" if (\"All options\".equals(questionDetails.getDistributePointsFor())) {"},{"lineNumber":435,"author":{"gitId":"-"},"content":" assertEquals(getQuestionForm(qnNumber).findElement(By.id(\"all-uneven-message\")).getText(),"},{"lineNumber":436,"author":{"gitId":"-"},"content":" \"Every \" + entityType + \" should be allocated different number of points.\");"},{"lineNumber":437,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":438,"author":{"gitId":"-"},"content":" assertEquals(getQuestionForm(qnNumber).findElement(By.id(\"one-uneven-message\")).getText(),"},{"lineNumber":439,"author":{"gitId":"-"},"content":" \"At least one \" + entityType + \" should be allocated different number of points.\");"},{"lineNumber":440,"author":{"gitId":"-"},"content":" }"},{"lineNumber":441,"author":{"gitId":"-"},"content":" }"},{"lineNumber":442,"author":{"gitId":"-"},"content":" }"},{"lineNumber":443,"author":{"gitId":"-"},"content":""},{"lineNumber":444,"author":{"gitId":"-"},"content":" public void fillConstSumOptionResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":445,"author":{"gitId":"-"},"content":" FeedbackConstantSumResponseDetails responseDetails \u003d"},{"lineNumber":446,"author":{"gitId":"-"},"content":" (FeedbackConstantSumResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":447,"author":{"gitId":"-"},"content":" List\u003cInteger\u003e answers \u003d responseDetails.getAnswers();"},{"lineNumber":448,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e constSumInputs \u003d getConstSumInputs(qnNumber, recipient);"},{"lineNumber":449,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c answers.size(); i++) {"},{"lineNumber":450,"author":{"gitId":"-"},"content":" fillTextBox(constSumInputs.get(i), Integer.toString(answers.get(i)));"},{"lineNumber":451,"author":{"gitId":"-"},"content":" }"},{"lineNumber":452,"author":{"gitId":"-"},"content":" }"},{"lineNumber":453,"author":{"gitId":"-"},"content":""},{"lineNumber":454,"author":{"gitId":"-"},"content":" public void verifyConstSumOptionResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":455,"author":{"gitId":"-"},"content":" FeedbackConstantSumResponseDetails responseDetails \u003d"},{"lineNumber":456,"author":{"gitId":"-"},"content":" (FeedbackConstantSumResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":457,"author":{"gitId":"-"},"content":" List\u003cInteger\u003e answers \u003d responseDetails.getAnswers();"},{"lineNumber":458,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e constSumInputs \u003d getConstSumInputs(qnNumber, recipient);"},{"lineNumber":459,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c answers.size(); i++) {"},{"lineNumber":460,"author":{"gitId":"-"},"content":" assertEquals(constSumInputs.get(i).getAttribute(\"value\"), Integer.toString(answers.get(i)));"},{"lineNumber":461,"author":{"gitId":"-"},"content":" }"},{"lineNumber":462,"author":{"gitId":"-"},"content":" }"},{"lineNumber":463,"author":{"gitId":"-"},"content":""},{"lineNumber":464,"author":{"gitId":"-"},"content":" public void fillConstSumRecipientResponse(int qnNumber, List\u003cFeedbackResponseAttributes\u003e responses) {"},{"lineNumber":465,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e recipientInputs \u003d getConstSumRecipientInputs(qnNumber);"},{"lineNumber":466,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c responses.size(); i++) {"},{"lineNumber":467,"author":{"gitId":"-"},"content":" FeedbackConstantSumResponseDetails response \u003d"},{"lineNumber":468,"author":{"gitId":"-"},"content":" (FeedbackConstantSumResponseDetails) responses.get(i).getResponseDetailsCopy();"},{"lineNumber":469,"author":{"gitId":"-"},"content":" fillTextBox(recipientInputs.get(i), Integer.toString(response.getAnswers().get(0)));"},{"lineNumber":470,"author":{"gitId":"-"},"content":" }"},{"lineNumber":471,"author":{"gitId":"-"},"content":" }"},{"lineNumber":472,"author":{"gitId":"-"},"content":""},{"lineNumber":473,"author":{"gitId":"-"},"content":" public void verifyConstSumRecipientResponse(int qnNumber, List\u003cFeedbackResponseAttributes\u003e responses) {"},{"lineNumber":474,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e recipientInputs \u003d getConstSumRecipientInputs(qnNumber);"},{"lineNumber":475,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c responses.size(); i++) {"},{"lineNumber":476,"author":{"gitId":"-"},"content":" FeedbackConstantSumResponseDetails response \u003d"},{"lineNumber":477,"author":{"gitId":"-"},"content":" (FeedbackConstantSumResponseDetails) responses.get(i).getResponseDetailsCopy();"},{"lineNumber":478,"author":{"gitId":"-"},"content":" assertEquals(recipientInputs.get(i).getAttribute(\"value\"),"},{"lineNumber":479,"author":{"gitId":"-"},"content":" Integer.toString(response.getAnswers().get(0)));"},{"lineNumber":480,"author":{"gitId":"-"},"content":" }"},{"lineNumber":481,"author":{"gitId":"-"},"content":" }"},{"lineNumber":482,"author":{"gitId":"-"},"content":""},{"lineNumber":483,"author":{"gitId":"-"},"content":" public void verifyContributionQuestion(int qnNumber, FeedbackContributionQuestionDetails questionDetails) {"},{"lineNumber":484,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":485,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(getContributionDropdowns(qnNumber).get(0), \"Not Sure\");"},{"lineNumber":486,"author":{"gitId":"-"},"content":" assertTrue(questionDetails.isNotSureAllowed());"},{"lineNumber":487,"author":{"gitId":"-"},"content":" assertFalse(questionDetails.isZeroSum());"},{"lineNumber":488,"author":{"gitId":"-"},"content":" } catch (NoSuchElementException e) {"},{"lineNumber":489,"author":{"gitId":"-"},"content":" assertFalse(questionDetails.isNotSureAllowed());"},{"lineNumber":490,"author":{"gitId":"-"},"content":" }"},{"lineNumber":491,"author":{"gitId":"-"},"content":" }"},{"lineNumber":492,"author":{"gitId":"-"},"content":""},{"lineNumber":493,"author":{"gitId":"-"},"content":" public void fillContributionResponse(int qnNumber, List\u003cFeedbackResponseAttributes\u003e responses) {"},{"lineNumber":494,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e dropdowns \u003d getContributionDropdowns(qnNumber);"},{"lineNumber":495,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c responses.size(); i++) {"},{"lineNumber":496,"author":{"gitId":"-"},"content":" FeedbackContributionResponseDetails response \u003d"},{"lineNumber":497,"author":{"gitId":"-"},"content":" (FeedbackContributionResponseDetails) responses.get(i).getResponseDetailsCopy();"},{"lineNumber":498,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(dropdowns.get(i), getContributionString(response.getAnswer()));"},{"lineNumber":499,"author":{"gitId":"-"},"content":" }"},{"lineNumber":500,"author":{"gitId":"-"},"content":" }"},{"lineNumber":501,"author":{"gitId":"-"},"content":""},{"lineNumber":502,"author":{"gitId":"-"},"content":" public void verifyContributionResponse(int qnNumber, List\u003cFeedbackResponseAttributes\u003e responses) {"},{"lineNumber":503,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e dropdowns \u003d getContributionDropdowns(qnNumber);"},{"lineNumber":504,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c responses.size(); i++) {"},{"lineNumber":505,"author":{"gitId":"-"},"content":" FeedbackContributionResponseDetails response \u003d"},{"lineNumber":506,"author":{"gitId":"-"},"content":" (FeedbackContributionResponseDetails) responses.get(i).getResponseDetailsCopy();"},{"lineNumber":507,"author":{"gitId":"-"},"content":" assertEquals(getSelectedDropdownOptionText(dropdowns.get(i)), getContributionString(response.getAnswer()));"},{"lineNumber":508,"author":{"gitId":"-"},"content":" }"},{"lineNumber":509,"author":{"gitId":"-"},"content":" }"},{"lineNumber":510,"author":{"gitId":"-"},"content":""},{"lineNumber":511,"author":{"gitId":"-"},"content":" public void verifyRubricQuestion(int qnNumber, String recipient, FeedbackRubricQuestionDetails questionDetails) {"},{"lineNumber":512,"author":{"gitId":"-"},"content":" List\u003cString\u003e choices \u003d questionDetails.getRubricChoices();"},{"lineNumber":513,"author":{"gitId":"-"},"content":" List\u003cString\u003e subQuestions \u003d questionDetails.getRubricSubQuestions();"},{"lineNumber":514,"author":{"gitId":"-"},"content":" List\u003cList\u003cString\u003e\u003e descriptions \u003d questionDetails.getRubricDescriptions();"},{"lineNumber":515,"author":{"gitId":"-"},"content":""},{"lineNumber":516,"author":{"gitId":"-"},"content":" String[][] expectedTableData \u003d new String[subQuestions.size()][choices.size()];"},{"lineNumber":517,"author":{"gitId":"-"},"content":" String[][] expectedTableRowHeader \u003d new String[1][choices.size()];"},{"lineNumber":518,"author":{"gitId":"-"},"content":" String[][] expectedTableColumnHeader \u003d new String[subQuestions.size()][1];"},{"lineNumber":519,"author":{"gitId":"-"},"content":""},{"lineNumber":520,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c choices.size(); i++) {"},{"lineNumber":521,"author":{"gitId":"-"},"content":" expectedTableRowHeader[0][i] \u003d choices.get(i);"},{"lineNumber":522,"author":{"gitId":"-"},"content":" }"},{"lineNumber":523,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c subQuestions.size(); i++) {"},{"lineNumber":524,"author":{"gitId":"-"},"content":" expectedTableColumnHeader[i][0] \u003d subQuestions.get(i);"},{"lineNumber":525,"author":{"gitId":"-"},"content":" }"},{"lineNumber":526,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c descriptions.size(); i++) {"},{"lineNumber":527,"author":{"gitId":"-"},"content":" List\u003cString\u003e description \u003d descriptions.get(i);"},{"lineNumber":528,"author":{"gitId":"-"},"content":" for (int j \u003d 0; j \u003c description.size(); j++) {"},{"lineNumber":529,"author":{"gitId":"-"},"content":" expectedTableData[i][j] \u003d description.get(j);"},{"lineNumber":530,"author":{"gitId":"-"},"content":" }"},{"lineNumber":531,"author":{"gitId":"-"},"content":" }"},{"lineNumber":532,"author":{"gitId":"-"},"content":" WebElement rubricTable \u003d getRubricTable(qnNumber, recipient);"},{"lineNumber":533,"author":{"gitId":"-"},"content":" verifyTableBodyValues(rubricTable, expectedTableData);"},{"lineNumber":534,"author":{"gitId":"-"},"content":" verifyTableRowHeaderValues(rubricTable, expectedTableRowHeader);"},{"lineNumber":535,"author":{"gitId":"-"},"content":" verifyTableColumnHeaderValues(rubricTable, expectedTableColumnHeader);"},{"lineNumber":536,"author":{"gitId":"-"},"content":" }"},{"lineNumber":537,"author":{"gitId":"-"},"content":""},{"lineNumber":538,"author":{"gitId":"-"},"content":" public void fillRubricResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":539,"author":{"gitId":"-"},"content":" FeedbackRubricResponseDetails responseDetails \u003d"},{"lineNumber":540,"author":{"gitId":"-"},"content":" (FeedbackRubricResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":541,"author":{"gitId":"-"},"content":" List\u003cInteger\u003e answers \u003d responseDetails.getAnswer();"},{"lineNumber":542,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c answers.size(); i++) {"},{"lineNumber":543,"author":{"gitId":"-"},"content":" click(getRubricInputs(qnNumber, recipient, i + 2).get(answers.get(i)));"},{"lineNumber":544,"author":{"gitId":"-"},"content":" }"},{"lineNumber":545,"author":{"gitId":"-"},"content":" }"},{"lineNumber":546,"author":{"gitId":"-"},"content":""},{"lineNumber":547,"author":{"gitId":"-"},"content":" public void verifyRubricResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":548,"author":{"gitId":"-"},"content":" FeedbackRubricResponseDetails responseDetails \u003d"},{"lineNumber":549,"author":{"gitId":"-"},"content":" (FeedbackRubricResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":550,"author":{"gitId":"-"},"content":" List\u003cInteger\u003e answers \u003d responseDetails.getAnswer();"},{"lineNumber":551,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c answers.size(); i++) {"},{"lineNumber":552,"author":{"gitId":"-"},"content":" assertTrue(getRubricInputs(qnNumber, recipient, i + 2).get(answers.get(i)).isSelected());"},{"lineNumber":553,"author":{"gitId":"-"},"content":" }"},{"lineNumber":554,"author":{"gitId":"-"},"content":" }"},{"lineNumber":555,"author":{"gitId":"-"},"content":""},{"lineNumber":556,"author":{"gitId":"-"},"content":" public void verifyRankQuestion(int qnNumber, String recipient, FeedbackRankQuestionDetails questionDetails) {"},{"lineNumber":557,"author":{"gitId":"-"},"content":" if (questionDetails.getMaxOptionsToBeRanked() !\u003d Const.POINTS_NO_VALUE) {"},{"lineNumber":558,"author":{"gitId":"-"},"content":" assertEquals(getQuestionForm(qnNumber).findElement(By.id(\"max-options-message\")).getText(),"},{"lineNumber":559,"author":{"gitId":"-"},"content":" \"Rank no more than \" + questionDetails.getMaxOptionsToBeRanked() + \" options.\");"},{"lineNumber":560,"author":{"gitId":"-"},"content":" }"},{"lineNumber":561,"author":{"gitId":"-"},"content":" if (questionDetails.getMinOptionsToBeRanked() !\u003d Const.POINTS_NO_VALUE) {"},{"lineNumber":562,"author":{"gitId":"-"},"content":" assertEquals(getQuestionForm(qnNumber).findElement(By.id(\"min-options-message\")).getText(),"},{"lineNumber":563,"author":{"gitId":"-"},"content":" \"Rank at least \" + questionDetails.getMinOptionsToBeRanked() + \" options.\");"},{"lineNumber":564,"author":{"gitId":"-"},"content":" }"},{"lineNumber":565,"author":{"gitId":"-"},"content":" if (questionDetails instanceof FeedbackRankOptionsQuestionDetails) {"},{"lineNumber":566,"author":{"gitId":"-"},"content":" FeedbackRankOptionsQuestionDetails optionDetails \u003d (FeedbackRankOptionsQuestionDetails) questionDetails;"},{"lineNumber":567,"author":{"gitId":"-"},"content":" List\u003cString\u003e options \u003d optionDetails.getOptions();"},{"lineNumber":568,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e optionTexts \u003d getRankOptions(qnNumber, recipient);"},{"lineNumber":569,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c options.size(); i++) {"},{"lineNumber":570,"author":{"gitId":"-"},"content":" assertEquals(options.get(i), optionTexts.get(i).getText());"},{"lineNumber":571,"author":{"gitId":"-"},"content":" }"},{"lineNumber":572,"author":{"gitId":"-"},"content":" }"},{"lineNumber":573,"author":{"gitId":"-"},"content":" }"},{"lineNumber":574,"author":{"gitId":"-"},"content":""},{"lineNumber":575,"author":{"gitId":"-"},"content":" public void fillRankOptionResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":576,"author":{"gitId":"-"},"content":" FeedbackRankOptionsResponseDetails responseDetails \u003d"},{"lineNumber":577,"author":{"gitId":"-"},"content":" (FeedbackRankOptionsResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":578,"author":{"gitId":"-"},"content":" List\u003cInteger\u003e answers \u003d responseDetails.getAnswers();"},{"lineNumber":579,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c answers.size(); i++) {"},{"lineNumber":580,"author":{"gitId":"-"},"content":" if (answers.get(i) \u003d\u003d Const.POINTS_NOT_SUBMITTED) {"},{"lineNumber":581,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(getRankOptionsDropdowns(qnNumber, recipient).get(i), \"\");"},{"lineNumber":582,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":583,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(getRankOptionsDropdowns(qnNumber, recipient).get(i),"},{"lineNumber":584,"author":{"gitId":"-"},"content":" Integer.toString(answers.get(i)));"},{"lineNumber":585,"author":{"gitId":"-"},"content":" }"},{"lineNumber":586,"author":{"gitId":"-"},"content":" }"},{"lineNumber":587,"author":{"gitId":"-"},"content":" }"},{"lineNumber":588,"author":{"gitId":"-"},"content":""},{"lineNumber":589,"author":{"gitId":"mingyuanc"},"content":" public void fillRankOptionResponse(int qnNumber, String recipient, FeedbackResponse response) {"},{"lineNumber":590,"author":{"gitId":"mingyuanc"},"content":" FeedbackRankOptionsResponseDetails responseDetails \u003d"},{"lineNumber":591,"author":{"gitId":"mingyuanc"},"content":" (FeedbackRankOptionsResponseDetails) response.getFeedbackResponseDetailsCopy();"},{"lineNumber":592,"author":{"gitId":"mingyuanc"},"content":" List\u003cInteger\u003e answers \u003d responseDetails.getAnswers();"},{"lineNumber":593,"author":{"gitId":"mingyuanc"},"content":" for (int i \u003d 0; i \u003c answers.size(); i++) {"},{"lineNumber":594,"author":{"gitId":"mingyuanc"},"content":" if (answers.get(i) \u003d\u003d Const.POINTS_NOT_SUBMITTED) {"},{"lineNumber":595,"author":{"gitId":"mingyuanc"},"content":" selectDropdownOptionByText(getRankOptionsDropdowns(qnNumber, recipient).get(i), \"\");"},{"lineNumber":596,"author":{"gitId":"mingyuanc"},"content":" } else {"},{"lineNumber":597,"author":{"gitId":"mingyuanc"},"content":" selectDropdownOptionByText(getRankOptionsDropdowns(qnNumber, recipient).get(i),"},{"lineNumber":598,"author":{"gitId":"mingyuanc"},"content":" Integer.toString(answers.get(i)));"},{"lineNumber":599,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":600,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":601,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":602,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":603,"author":{"gitId":"-"},"content":" public void verifyRankOptionResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {"},{"lineNumber":604,"author":{"gitId":"-"},"content":" FeedbackRankOptionsResponseDetails responseDetails \u003d"},{"lineNumber":605,"author":{"gitId":"-"},"content":" (FeedbackRankOptionsResponseDetails) response.getResponseDetailsCopy();"},{"lineNumber":606,"author":{"gitId":"-"},"content":" List\u003cInteger\u003e answers \u003d responseDetails.getAnswers();"},{"lineNumber":607,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c answers.size(); i++) {"},{"lineNumber":608,"author":{"gitId":"-"},"content":" if (answers.get(i) \u003d\u003d Const.POINTS_NOT_SUBMITTED) {"},{"lineNumber":609,"author":{"gitId":"-"},"content":" assertEquals(getSelectedDropdownOptionText(getRankOptionsDropdowns(qnNumber, recipient).get(i)),"},{"lineNumber":610,"author":{"gitId":"-"},"content":" \"\");"},{"lineNumber":611,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":612,"author":{"gitId":"-"},"content":" assertEquals(getSelectedDropdownOptionText(getRankOptionsDropdowns(qnNumber, recipient).get(i)),"},{"lineNumber":613,"author":{"gitId":"-"},"content":" Integer.toString(answers.get(i)));"},{"lineNumber":614,"author":{"gitId":"-"},"content":" }"},{"lineNumber":615,"author":{"gitId":"-"},"content":" }"},{"lineNumber":616,"author":{"gitId":"-"},"content":" }"},{"lineNumber":617,"author":{"gitId":"-"},"content":""},{"lineNumber":618,"author":{"gitId":"-"},"content":" public void fillRankRecipientResponse(int qnNumber, List\u003cFeedbackResponseAttributes\u003e responses) {"},{"lineNumber":619,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e recipientDropdowns \u003d getRankRecipientDropdowns(qnNumber);"},{"lineNumber":620,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c responses.size(); i++) {"},{"lineNumber":621,"author":{"gitId":"-"},"content":" FeedbackRankRecipientsResponseDetails response \u003d"},{"lineNumber":622,"author":{"gitId":"-"},"content":" (FeedbackRankRecipientsResponseDetails) responses.get(i).getResponseDetailsCopy();"},{"lineNumber":623,"author":{"gitId":"-"},"content":" if (response.getAnswer() \u003d\u003d Const.POINTS_NOT_SUBMITTED) {"},{"lineNumber":624,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(recipientDropdowns.get(i), \"\");"},{"lineNumber":625,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":626,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(recipientDropdowns.get(i), Integer.toString(response.getAnswer()));"},{"lineNumber":627,"author":{"gitId":"-"},"content":" }"},{"lineNumber":628,"author":{"gitId":"-"},"content":" }"},{"lineNumber":629,"author":{"gitId":"-"},"content":" }"},{"lineNumber":630,"author":{"gitId":"-"},"content":""},{"lineNumber":631,"author":{"gitId":"-"},"content":" public void verifyRankRecipientResponse(int qnNumber, List\u003cFeedbackResponseAttributes\u003e responses) {"},{"lineNumber":632,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e recipientDropdowns \u003d getRankRecipientDropdowns(qnNumber);"},{"lineNumber":633,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c responses.size(); i++) {"},{"lineNumber":634,"author":{"gitId":"-"},"content":" FeedbackRankRecipientsResponseDetails response \u003d"},{"lineNumber":635,"author":{"gitId":"-"},"content":" (FeedbackRankRecipientsResponseDetails) responses.get(i).getResponseDetailsCopy();"},{"lineNumber":636,"author":{"gitId":"-"},"content":" if (response.getAnswer() \u003d\u003d Const.POINTS_NOT_SUBMITTED) {"},{"lineNumber":637,"author":{"gitId":"-"},"content":" assertEquals(getSelectedDropdownOptionText(recipientDropdowns.get(i)), \"\");"},{"lineNumber":638,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":639,"author":{"gitId":"-"},"content":" assertEquals(getSelectedDropdownOptionText(recipientDropdowns.get(i)),"},{"lineNumber":640,"author":{"gitId":"-"},"content":" Integer.toString(response.getAnswer()));"},{"lineNumber":641,"author":{"gitId":"-"},"content":" }"},{"lineNumber":642,"author":{"gitId":"-"},"content":" }"},{"lineNumber":643,"author":{"gitId":"-"},"content":" }"},{"lineNumber":644,"author":{"gitId":"-"},"content":""},{"lineNumber":645,"author":{"gitId":"-"},"content":" private String getCourseId() {"},{"lineNumber":646,"author":{"gitId":"-"},"content":" return browser.driver.findElement(By.id(\"course-id\")).getText();"},{"lineNumber":647,"author":{"gitId":"-"},"content":" }"},{"lineNumber":648,"author":{"gitId":"-"},"content":""},{"lineNumber":649,"author":{"gitId":"-"},"content":" private String getCourseName() {"},{"lineNumber":650,"author":{"gitId":"-"},"content":" return browser.driver.findElement(By.id(\"course-name\")).getText();"},{"lineNumber":651,"author":{"gitId":"-"},"content":" }"},{"lineNumber":652,"author":{"gitId":"-"},"content":""},{"lineNumber":653,"author":{"gitId":"-"},"content":" private String getCourseInstitute() {"},{"lineNumber":654,"author":{"gitId":"-"},"content":" return browser.driver.findElement(By.id(\"course-institute\")).getText();"},{"lineNumber":655,"author":{"gitId":"-"},"content":" }"},{"lineNumber":656,"author":{"gitId":"-"},"content":""},{"lineNumber":657,"author":{"gitId":"-"},"content":" private String getFeedbackSessionName() {"},{"lineNumber":658,"author":{"gitId":"-"},"content":" return browser.driver.findElement(By.id(\"fs-name\")).getText();"},{"lineNumber":659,"author":{"gitId":"-"},"content":" }"},{"lineNumber":660,"author":{"gitId":"-"},"content":""},{"lineNumber":661,"author":{"gitId":"-"},"content":" private String getOpeningTime() {"},{"lineNumber":662,"author":{"gitId":"-"},"content":" return browser.driver.findElement(By.id(\"opening-time\")).getText();"},{"lineNumber":663,"author":{"gitId":"-"},"content":" }"},{"lineNumber":664,"author":{"gitId":"-"},"content":""},{"lineNumber":665,"author":{"gitId":"-"},"content":" private String getClosingTime() {"},{"lineNumber":666,"author":{"gitId":"-"},"content":" return browser.driver.findElement(By.id(\"closing-time\")).getText();"},{"lineNumber":667,"author":{"gitId":"-"},"content":" }"},{"lineNumber":668,"author":{"gitId":"-"},"content":""},{"lineNumber":669,"author":{"gitId":"-"},"content":" private String getInstructions() {"},{"lineNumber":670,"author":{"gitId":"-"},"content":" return browser.driver.findElement(By.id(\"instructions\")).getAttribute(\"innerHTML\");"},{"lineNumber":671,"author":{"gitId":"-"},"content":" }"},{"lineNumber":672,"author":{"gitId":"-"},"content":""},{"lineNumber":673,"author":{"gitId":"-"},"content":" private void assertDateEquals(String actual, Instant instant, String timeZone) {"},{"lineNumber":674,"author":{"gitId":"-"},"content":" String dateStrWithAbbr \u003d getDateStringWithAbbr(instant, timeZone);"},{"lineNumber":675,"author":{"gitId":"-"},"content":" String dateStrWithOffset \u003d getDateStringWithOffset(instant, timeZone);"},{"lineNumber":676,"author":{"gitId":"-"},"content":""},{"lineNumber":677,"author":{"gitId":"-"},"content":" boolean isExpected \u003d actual.equals(dateStrWithAbbr) || actual.equals(dateStrWithOffset);"},{"lineNumber":678,"author":{"gitId":"-"},"content":" assertTrue(isExpected);"},{"lineNumber":679,"author":{"gitId":"-"},"content":" }"},{"lineNumber":680,"author":{"gitId":"-"},"content":""},{"lineNumber":681,"author":{"gitId":"-"},"content":" private String getDateStringWithAbbr(Instant instant, String timeZone) {"},{"lineNumber":682,"author":{"gitId":"-"},"content":" return getDisplayedDateTime(instant, timeZone, \"EE, dd MMM, yyyy, hh:mm a z\");"},{"lineNumber":683,"author":{"gitId":"-"},"content":" }"},{"lineNumber":684,"author":{"gitId":"-"},"content":""},{"lineNumber":685,"author":{"gitId":"-"},"content":" private String getDateStringWithOffset(Instant instant, String timeZone) {"},{"lineNumber":686,"author":{"gitId":"-"},"content":" return getDisplayedDateTime(instant, timeZone, \"EE, dd MMM, yyyy, hh:mm a X\");"},{"lineNumber":687,"author":{"gitId":"-"},"content":" }"},{"lineNumber":688,"author":{"gitId":"-"},"content":""},{"lineNumber":689,"author":{"gitId":"-"},"content":" private WebElement getQuestionForm(int qnNumber) {"},{"lineNumber":690,"author":{"gitId":"-"},"content":" By questionFormId \u003d By.id(\"question-submission-form-qn-\" + qnNumber);"},{"lineNumber":691,"author":{"gitId":"-"},"content":" waitForElementPresence(questionFormId);"},{"lineNumber":692,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d browser.driver.findElement(questionFormId);"},{"lineNumber":693,"author":{"gitId":"-"},"content":" // Scroll to the question to ensure that the details are fully loaded"},{"lineNumber":694,"author":{"gitId":"-"},"content":" scrollElementToCenter(questionForm);"},{"lineNumber":695,"author":{"gitId":"-"},"content":" waitUntilAnimationFinish();"},{"lineNumber":696,"author":{"gitId":"-"},"content":" return questionForm;"},{"lineNumber":697,"author":{"gitId":"-"},"content":" }"},{"lineNumber":698,"author":{"gitId":"-"},"content":""},{"lineNumber":699,"author":{"gitId":"-"},"content":" private String getQuestionBrief(int qnNumber) {"},{"lineNumber":700,"author":{"gitId":"-"},"content":" String questionDetails \u003d getQuestionForm(qnNumber).findElement(By.className(\"question-details\")).getText();"},{"lineNumber":701,"author":{"gitId":"-"},"content":" return questionDetails.split(\": \")[1];"},{"lineNumber":702,"author":{"gitId":"-"},"content":" }"},{"lineNumber":703,"author":{"gitId":"-"},"content":""},{"lineNumber":704,"author":{"gitId":"-"},"content":" private void verifyVisibilityList(int qnNumber, FeedbackQuestionAttributes questionAttributes) {"},{"lineNumber":705,"author":{"gitId":"-"},"content":" if (questionAttributes.getShowResponsesTo().isEmpty()) {"},{"lineNumber":706,"author":{"gitId":"-"},"content":" verifyVisibilityStringPresent(qnNumber, \"No-one can see your responses\");"},{"lineNumber":707,"author":{"gitId":"-"},"content":" }"},{"lineNumber":708,"author":{"gitId":"-"},"content":" if (questionAttributes.getRecipientType().equals(FeedbackParticipantType.SELF)) {"},{"lineNumber":709,"author":{"gitId":"-"},"content":" verifyVisibilityStringPresent(qnNumber, \"You can see your own feedback in the results page later on.\");"},{"lineNumber":710,"author":{"gitId":"-"},"content":" }"},{"lineNumber":711,"author":{"gitId":"-"},"content":" for (FeedbackParticipantType viewerType : questionAttributes.getShowResponsesTo()) {"},{"lineNumber":712,"author":{"gitId":"-"},"content":" verifyVisibilityStringPresent(qnNumber, getVisibilityString(questionAttributes, viewerType));"},{"lineNumber":713,"author":{"gitId":"-"},"content":" }"},{"lineNumber":714,"author":{"gitId":"-"},"content":" }"},{"lineNumber":715,"author":{"gitId":"-"},"content":""},{"lineNumber":716,"author":{"gitId":"-"},"content":" private void verifyVisibilityStringPresent(int qnNumber, String expectedString) {"},{"lineNumber":717,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e visibilityStrings \u003d getQuestionForm(qnNumber).findElement(By.className(\"visibility-list\"))"},{"lineNumber":718,"author":{"gitId":"-"},"content":" .findElements(By.tagName(\"li\"));"},{"lineNumber":719,"author":{"gitId":"-"},"content":" for (WebElement visibilityString : visibilityStrings) {"},{"lineNumber":720,"author":{"gitId":"-"},"content":" if (visibilityString.getText().equals(expectedString)) {"},{"lineNumber":721,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":722,"author":{"gitId":"-"},"content":" }"},{"lineNumber":723,"author":{"gitId":"-"},"content":" }"},{"lineNumber":724,"author":{"gitId":"-"},"content":" fail(\"Expected visibility string not found: \" + qnNumber + \": \" + expectedString);"},{"lineNumber":725,"author":{"gitId":"-"},"content":" }"},{"lineNumber":726,"author":{"gitId":"-"},"content":""},{"lineNumber":727,"author":{"gitId":"-"},"content":" private String getVisibilityString(FeedbackQuestionAttributes questionAttributes,"},{"lineNumber":728,"author":{"gitId":"-"},"content":" FeedbackParticipantType viewerType) {"},{"lineNumber":729,"author":{"gitId":"-"},"content":" if (!questionAttributes.getShowResponsesTo().contains(viewerType)) {"},{"lineNumber":730,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":731,"author":{"gitId":"-"},"content":" }"},{"lineNumber":732,"author":{"gitId":"-"},"content":""},{"lineNumber":733,"author":{"gitId":"-"},"content":" StringBuilder message \u003d new StringBuilder(getViewerString(viewerType, questionAttributes.getRecipientType()));"},{"lineNumber":734,"author":{"gitId":"-"},"content":" message.append(\" can see your response\");"},{"lineNumber":735,"author":{"gitId":"-"},"content":" if (questionAttributes.getShowRecipientNameTo().contains(viewerType)) {"},{"lineNumber":736,"author":{"gitId":"-"},"content":" message.append(\", the name of the recipient\");"},{"lineNumber":737,"author":{"gitId":"-"},"content":" if (questionAttributes.getShowGiverNameTo().contains(viewerType)) {"},{"lineNumber":738,"author":{"gitId":"-"},"content":" message.append(\", and your name\");"},{"lineNumber":739,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":740,"author":{"gitId":"-"},"content":" message.append(\", but not your name\");"},{"lineNumber":741,"author":{"gitId":"-"},"content":" }"},{"lineNumber":742,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":743,"author":{"gitId":"-"},"content":" if (questionAttributes.getShowGiverNameTo().contains(viewerType)) {"},{"lineNumber":744,"author":{"gitId":"-"},"content":" message.append(\", and your name, but not the name of the recipient\");"},{"lineNumber":745,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":746,"author":{"gitId":"-"},"content":" message.append(\", but not the name of the recipient, or your name\");"},{"lineNumber":747,"author":{"gitId":"-"},"content":" }"},{"lineNumber":748,"author":{"gitId":"-"},"content":" }"},{"lineNumber":749,"author":{"gitId":"-"},"content":" return message.toString();"},{"lineNumber":750,"author":{"gitId":"-"},"content":" }"},{"lineNumber":751,"author":{"gitId":"-"},"content":""},{"lineNumber":752,"author":{"gitId":"-"},"content":" private String getViewerString(FeedbackParticipantType viewerType, FeedbackParticipantType recipientType) {"},{"lineNumber":753,"author":{"gitId":"-"},"content":" switch (viewerType) {"},{"lineNumber":754,"author":{"gitId":"-"},"content":" case RECEIVER:"},{"lineNumber":755,"author":{"gitId":"-"},"content":" return \"The receiving \" + getRecipientString(recipientType);"},{"lineNumber":756,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":757,"author":{"gitId":"-"},"content":" return \"Your team members\";"},{"lineNumber":758,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":759,"author":{"gitId":"-"},"content":" return \"Other students in the course\";"},{"lineNumber":760,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":761,"author":{"gitId":"-"},"content":" return \"Instructors in this course\";"},{"lineNumber":762,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":763,"author":{"gitId":"-"},"content":" throw new RuntimeException(\"Unknown viewer type\");"},{"lineNumber":764,"author":{"gitId":"-"},"content":" }"},{"lineNumber":765,"author":{"gitId":"-"},"content":" }"},{"lineNumber":766,"author":{"gitId":"-"},"content":""},{"lineNumber":767,"author":{"gitId":"-"},"content":" private String getRecipientString(FeedbackParticipantType recipientType) {"},{"lineNumber":768,"author":{"gitId":"-"},"content":" switch (recipientType) {"},{"lineNumber":769,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":770,"author":{"gitId":"-"},"content":" case TEAMS_EXCLUDING_SELF:"},{"lineNumber":771,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":772,"author":{"gitId":"-"},"content":" return \"teams\";"},{"lineNumber":773,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":774,"author":{"gitId":"-"},"content":" return \"student\";"},{"lineNumber":775,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":776,"author":{"gitId":"-"},"content":" case STUDENTS_EXCLUDING_SELF:"},{"lineNumber":777,"author":{"gitId":"-"},"content":" case STUDENTS_IN_SAME_SECTION:"},{"lineNumber":778,"author":{"gitId":"-"},"content":" return \"students\";"},{"lineNumber":779,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":780,"author":{"gitId":"-"},"content":" return \"instructors\";"},{"lineNumber":781,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":782,"author":{"gitId":"-"},"content":" throw new RuntimeException(\"Unknown recipientType\");"},{"lineNumber":783,"author":{"gitId":"-"},"content":" }"},{"lineNumber":784,"author":{"gitId":"-"},"content":" }"},{"lineNumber":785,"author":{"gitId":"-"},"content":""},{"lineNumber":786,"author":{"gitId":"-"},"content":" public void clickSubmitQuestionButton(int qnNumber) {"},{"lineNumber":787,"author":{"gitId":"-"},"content":" WebElement submitQnButton \u003d waitForElementPresence(By.id(\"btn-submit-qn-\" + qnNumber));"},{"lineNumber":788,"author":{"gitId":"-"},"content":" clickAndConfirm(submitQnButton);"},{"lineNumber":789,"author":{"gitId":"-"},"content":" }"},{"lineNumber":790,"author":{"gitId":"-"},"content":""},{"lineNumber":791,"author":{"gitId":"-"},"content":" public void clickSubmitAllQuestionsButton() {"},{"lineNumber":792,"author":{"gitId":"-"},"content":" clickAndConfirm(getSubmitAllQuestionsButton());"},{"lineNumber":793,"author":{"gitId":"-"},"content":" }"},{"lineNumber":794,"author":{"gitId":"-"},"content":""},{"lineNumber":795,"author":{"gitId":"-"},"content":" private WebElement getSubmitAllQuestionsButton() {"},{"lineNumber":796,"author":{"gitId":"-"},"content":" return waitForElementPresence(By.id(\"btn-submit\"));"},{"lineNumber":797,"author":{"gitId":"-"},"content":" }"},{"lineNumber":798,"author":{"gitId":"-"},"content":""},{"lineNumber":799,"author":{"gitId":"-"},"content":" private String getQuestionDescription(int qnNumber) {"},{"lineNumber":800,"author":{"gitId":"-"},"content":" return getQuestionForm(qnNumber).findElement(By.className(\"question-description\")).getAttribute(\"innerHTML\");"},{"lineNumber":801,"author":{"gitId":"-"},"content":" }"},{"lineNumber":802,"author":{"gitId":"-"},"content":""},{"lineNumber":803,"author":{"gitId":"-"},"content":" private WebElement getCommentSection(int qnNumber, String recipient) {"},{"lineNumber":804,"author":{"gitId":"-"},"content":" int recipientIndex \u003d getRecipientIndex(qnNumber, recipient);"},{"lineNumber":805,"author":{"gitId":"-"},"content":" return getQuestionForm(qnNumber).findElement(By.id(\"comment-section-qn-\" + qnNumber + \"-idx-\" + recipientIndex));"},{"lineNumber":806,"author":{"gitId":"-"},"content":" }"},{"lineNumber":807,"author":{"gitId":"-"},"content":""},{"lineNumber":808,"author":{"gitId":"-"},"content":" private void writeToCommentEditor(WebElement commentSection, String comment) {"},{"lineNumber":809,"author":{"gitId":"-"},"content":" scrollElementToCenter(commentSection);"},{"lineNumber":810,"author":{"gitId":"-"},"content":" waitForElementPresence(By.tagName(\"editor\"));"},{"lineNumber":811,"author":{"gitId":"-"},"content":" writeToRichTextEditor(commentSection.findElement(By.tagName(\"editor\")), comment);"},{"lineNumber":812,"author":{"gitId":"-"},"content":" }"},{"lineNumber":813,"author":{"gitId":"-"},"content":""},{"lineNumber":814,"author":{"gitId":"-"},"content":" private int getRecipientIndex(int qnNumber, String recipient) {"},{"lineNumber":815,"author":{"gitId":"-"},"content":" // For questions with recipient none or self."},{"lineNumber":816,"author":{"gitId":"-"},"content":" if (recipient.isEmpty()) {"},{"lineNumber":817,"author":{"gitId":"-"},"content":" return 0;"},{"lineNumber":818,"author":{"gitId":"-"},"content":" }"},{"lineNumber":819,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(qnNumber);"},{"lineNumber":820,"author":{"gitId":"-"},"content":" // For questions with flexible recipient."},{"lineNumber":821,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":822,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e recipientDropdowns \u003d"},{"lineNumber":823,"author":{"gitId":"-"},"content":" questionForm.findElements(By.cssSelector(\"[id^\u003d\u0027recipient-dropdown-qn-\u0027]\"));"},{"lineNumber":824,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c recipientDropdowns.size(); i++) {"},{"lineNumber":825,"author":{"gitId":"-"},"content":" String dropdownText \u003d getSelectedDropdownOptionText(recipientDropdowns.get(i));"},{"lineNumber":826,"author":{"gitId":"-"},"content":" if (dropdownText.isEmpty()) {"},{"lineNumber":827,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(recipientDropdowns.get(i), recipient);"},{"lineNumber":828,"author":{"gitId":"-"},"content":" return i;"},{"lineNumber":829,"author":{"gitId":"-"},"content":" } else if (dropdownText.equals(recipient)) {"},{"lineNumber":830,"author":{"gitId":"-"},"content":" return i;"},{"lineNumber":831,"author":{"gitId":"-"},"content":" }"},{"lineNumber":832,"author":{"gitId":"-"},"content":" }"},{"lineNumber":833,"author":{"gitId":"-"},"content":" } catch (NoSuchElementException e) {"},{"lineNumber":834,"author":{"gitId":"-"},"content":" // continue"},{"lineNumber":835,"author":{"gitId":"-"},"content":" }"},{"lineNumber":836,"author":{"gitId":"-"},"content":" int limit \u003d 20; // we are not likely to set test data exceeding this number"},{"lineNumber":837,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c limit; i++) {"},{"lineNumber":838,"author":{"gitId":"-"},"content":" if (questionForm.findElement(By.id(\"recipient-name-qn-\" + qnNumber + \"-idx-\" + i))"},{"lineNumber":839,"author":{"gitId":"-"},"content":" .getText().contains(recipient)) {"},{"lineNumber":840,"author":{"gitId":"-"},"content":" return i;"},{"lineNumber":841,"author":{"gitId":"-"},"content":" }"},{"lineNumber":842,"author":{"gitId":"-"},"content":" }"},{"lineNumber":843,"author":{"gitId":"-"},"content":" return -1;"},{"lineNumber":844,"author":{"gitId":"-"},"content":" }"},{"lineNumber":845,"author":{"gitId":"-"},"content":""},{"lineNumber":846,"author":{"gitId":"-"},"content":" private WebElement getTextResponseEditor(int qnNumber, String recipient) {"},{"lineNumber":847,"author":{"gitId":"-"},"content":" int recipientIndex \u003d getRecipientIndex(qnNumber, recipient);"},{"lineNumber":848,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(qnNumber);"},{"lineNumber":849,"author":{"gitId":"-"},"content":" WebElement editor \u003d questionForm.findElements(By.tagName(\"tm-rich-text-editor\")).get(recipientIndex);"},{"lineNumber":850,"author":{"gitId":"-"},"content":" scrollElementToCenter(editor);"},{"lineNumber":851,"author":{"gitId":"-"},"content":" return editor;"},{"lineNumber":852,"author":{"gitId":"-"},"content":" }"},{"lineNumber":853,"author":{"gitId":"-"},"content":""},{"lineNumber":854,"author":{"gitId":"-"},"content":" private String getResponseLengthText(int qnNumber, String recipient) {"},{"lineNumber":855,"author":{"gitId":"-"},"content":" int recipientIndex \u003d getRecipientIndex(qnNumber, recipient);"},{"lineNumber":856,"author":{"gitId":"-"},"content":" return getQuestionForm(qnNumber).findElements(By.id(\"response-length\")).get(recipientIndex).getText();"},{"lineNumber":857,"author":{"gitId":"-"},"content":" }"},{"lineNumber":858,"author":{"gitId":"-"},"content":""},{"lineNumber":859,"author":{"gitId":"-"},"content":" private String getDoubleString(Double value) {"},{"lineNumber":860,"author":{"gitId":"-"},"content":" return value % 1 \u003d\u003d 0 ? Integer.toString(value.intValue()) : Double.toString(value);"},{"lineNumber":861,"author":{"gitId":"-"},"content":" }"},{"lineNumber":862,"author":{"gitId":"-"},"content":""},{"lineNumber":863,"author":{"gitId":"-"},"content":" private WebElement getMcqSection(int qnNumber, String recipient) {"},{"lineNumber":864,"author":{"gitId":"-"},"content":" int recipientIndex \u003d getRecipientIndex(qnNumber, recipient);"},{"lineNumber":865,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(qnNumber);"},{"lineNumber":866,"author":{"gitId":"-"},"content":" return questionForm.findElements(By.tagName(\"tm-mcq-question-edit-answer-form\")).get(recipientIndex);"},{"lineNumber":867,"author":{"gitId":"-"},"content":" }"},{"lineNumber":868,"author":{"gitId":"-"},"content":""},{"lineNumber":869,"author":{"gitId":"-"},"content":" private WebElement getMcqOtherOptionRadioBtn(int qnNumber, String recipient) {"},{"lineNumber":870,"author":{"gitId":"-"},"content":" WebElement mcqSection \u003d getMcqSection(qnNumber, recipient);"},{"lineNumber":871,"author":{"gitId":"-"},"content":" return mcqSection.findElement(By.cssSelector(\"#other-option input[type\u003dradio]\"));"},{"lineNumber":872,"author":{"gitId":"-"},"content":" }"},{"lineNumber":873,"author":{"gitId":"-"},"content":""},{"lineNumber":874,"author":{"gitId":"-"},"content":" private WebElement getMcqOtherOptionTextbox(int qnNumber, String recipient) {"},{"lineNumber":875,"author":{"gitId":"-"},"content":" WebElement mcqSection \u003d getMcqSection(qnNumber, recipient);"},{"lineNumber":876,"author":{"gitId":"-"},"content":" return mcqSection.findElement(By.cssSelector(\"#other-option input[type\u003dtext]\"));"},{"lineNumber":877,"author":{"gitId":"-"},"content":" }"},{"lineNumber":878,"author":{"gitId":"-"},"content":""},{"lineNumber":879,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getMcqOptions(int qnNumber, String recipient) {"},{"lineNumber":880,"author":{"gitId":"-"},"content":" WebElement mcqSection \u003d getMcqSection(qnNumber, recipient);"},{"lineNumber":881,"author":{"gitId":"-"},"content":" return mcqSection.findElements(By.className(\"option-text\"));"},{"lineNumber":882,"author":{"gitId":"-"},"content":" }"},{"lineNumber":883,"author":{"gitId":"-"},"content":""},{"lineNumber":884,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getMcqRadioBtns(int qnNumber, String recipient) {"},{"lineNumber":885,"author":{"gitId":"-"},"content":" WebElement mcqSection \u003d getMcqSection(qnNumber, recipient);"},{"lineNumber":886,"author":{"gitId":"-"},"content":" return mcqSection.findElements(By.cssSelector(\"input[type\u003dradio]\"));"},{"lineNumber":887,"author":{"gitId":"-"},"content":" }"},{"lineNumber":888,"author":{"gitId":"-"},"content":""},{"lineNumber":889,"author":{"gitId":"-"},"content":" private WebElement getMsqSection(int qnNumber, String recipient) {"},{"lineNumber":890,"author":{"gitId":"-"},"content":" int recipientIndex \u003d getRecipientIndex(qnNumber, recipient);"},{"lineNumber":891,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(qnNumber);"},{"lineNumber":892,"author":{"gitId":"-"},"content":" return questionForm.findElements(By.tagName(\"tm-msq-question-edit-answer-form\")).get(recipientIndex);"},{"lineNumber":893,"author":{"gitId":"-"},"content":" }"},{"lineNumber":894,"author":{"gitId":"-"},"content":""},{"lineNumber":895,"author":{"gitId":"-"},"content":" private WebElement getMsqOtherOptionCheckbox(int qnNumber, String recipient) {"},{"lineNumber":896,"author":{"gitId":"-"},"content":" WebElement msqSection \u003d getMsqSection(qnNumber, recipient);"},{"lineNumber":897,"author":{"gitId":"-"},"content":" return msqSection.findElement(By.cssSelector(\"#other-option input[type\u003dcheckbox]\"));"},{"lineNumber":898,"author":{"gitId":"-"},"content":" }"},{"lineNumber":899,"author":{"gitId":"-"},"content":""},{"lineNumber":900,"author":{"gitId":"-"},"content":" private WebElement getMsqOtherOptionTextbox(int qnNumber, String recipient) {"},{"lineNumber":901,"author":{"gitId":"-"},"content":" WebElement msqSection \u003d getMsqSection(qnNumber, recipient);"},{"lineNumber":902,"author":{"gitId":"-"},"content":" return msqSection.findElement(By.cssSelector(\"#other-option input[type\u003dtext]\"));"},{"lineNumber":903,"author":{"gitId":"-"},"content":" }"},{"lineNumber":904,"author":{"gitId":"-"},"content":""},{"lineNumber":905,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getMsqOptions(int qnNumber, String recipient) {"},{"lineNumber":906,"author":{"gitId":"-"},"content":" WebElement msqSection \u003d getMsqSection(qnNumber, recipient);"},{"lineNumber":907,"author":{"gitId":"-"},"content":" return msqSection.findElements(By.tagName(\"strong\"));"},{"lineNumber":908,"author":{"gitId":"-"},"content":" }"},{"lineNumber":909,"author":{"gitId":"-"},"content":""},{"lineNumber":910,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getMsqCheckboxes(int qnNumber, String recipient) {"},{"lineNumber":911,"author":{"gitId":"-"},"content":" WebElement msqSection \u003d getMsqSection(qnNumber, recipient);"},{"lineNumber":912,"author":{"gitId":"-"},"content":" return msqSection.findElements(By.cssSelector(\"input[type\u003dcheckbox]\"));"},{"lineNumber":913,"author":{"gitId":"-"},"content":" }"},{"lineNumber":914,"author":{"gitId":"-"},"content":""},{"lineNumber":915,"author":{"gitId":"-"},"content":" private WebElement getNumScaleSection(int qnNumber, String recipient) {"},{"lineNumber":916,"author":{"gitId":"-"},"content":" int recipientIndex \u003d getRecipientIndex(qnNumber, recipient);"},{"lineNumber":917,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(qnNumber);"},{"lineNumber":918,"author":{"gitId":"-"},"content":" return questionForm.findElements(By.tagName(\"tm-num-scale-question-edit-answer-form\")).get(recipientIndex);"},{"lineNumber":919,"author":{"gitId":"-"},"content":" }"},{"lineNumber":920,"author":{"gitId":"-"},"content":""},{"lineNumber":921,"author":{"gitId":"-"},"content":" private WebElement getNumScaleInput(int qnNumber, String recipient) {"},{"lineNumber":922,"author":{"gitId":"-"},"content":" WebElement numScaleSection \u003d getNumScaleSection(qnNumber, recipient);"},{"lineNumber":923,"author":{"gitId":"-"},"content":" return numScaleSection.findElement(By.tagName(\"input\"));"},{"lineNumber":924,"author":{"gitId":"-"},"content":" }"},{"lineNumber":925,"author":{"gitId":"-"},"content":""},{"lineNumber":926,"author":{"gitId":"-"},"content":" private WebElement getConstSumOptionsSection(int qnNumber, String recipient) {"},{"lineNumber":927,"author":{"gitId":"-"},"content":" int recipientIndex \u003d getRecipientIndex(qnNumber, recipient);"},{"lineNumber":928,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(qnNumber);"},{"lineNumber":929,"author":{"gitId":"-"},"content":" return questionForm.findElements(By.tagName(\"tm-constsum-options-question-edit-answer-form\")).get(recipientIndex);"},{"lineNumber":930,"author":{"gitId":"-"},"content":" }"},{"lineNumber":931,"author":{"gitId":"-"},"content":""},{"lineNumber":932,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getConstSumOptions(int qnNumber, String recipient) {"},{"lineNumber":933,"author":{"gitId":"-"},"content":" WebElement constSumOptionSection \u003d getConstSumOptionsSection(qnNumber, recipient);"},{"lineNumber":934,"author":{"gitId":"-"},"content":" return constSumOptionSection.findElements(By.tagName(\"strong\"));"},{"lineNumber":935,"author":{"gitId":"-"},"content":" }"},{"lineNumber":936,"author":{"gitId":"-"},"content":""},{"lineNumber":937,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getConstSumInputs(int qnNumber, String recipient) {"},{"lineNumber":938,"author":{"gitId":"-"},"content":" WebElement constSumOptionSection \u003d getConstSumOptionsSection(qnNumber, recipient);"},{"lineNumber":939,"author":{"gitId":"-"},"content":" return constSumOptionSection.findElements(By.cssSelector(\"input[type\u003dnumber]\"));"},{"lineNumber":940,"author":{"gitId":"-"},"content":" }"},{"lineNumber":941,"author":{"gitId":"-"},"content":""},{"lineNumber":942,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getConstSumRecipientInputs(int qnNumber) {"},{"lineNumber":943,"author":{"gitId":"-"},"content":" return getQuestionForm(qnNumber).findElements(By.cssSelector(\"input[type\u003dnumber]\"));"},{"lineNumber":944,"author":{"gitId":"-"},"content":" }"},{"lineNumber":945,"author":{"gitId":"-"},"content":""},{"lineNumber":946,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getContributionDropdowns(int questionNum) {"},{"lineNumber":947,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElements(By.tagName(\"select\"));"},{"lineNumber":948,"author":{"gitId":"-"},"content":" }"},{"lineNumber":949,"author":{"gitId":"-"},"content":""},{"lineNumber":950,"author":{"gitId":"-"},"content":" private String getContributionString(int answer) {"},{"lineNumber":951,"author":{"gitId":"-"},"content":" if (answer \u003d\u003d Const.POINTS_NOT_SURE) {"},{"lineNumber":952,"author":{"gitId":"-"},"content":" return \"Not Sure\";"},{"lineNumber":953,"author":{"gitId":"-"},"content":" } else if (answer \u003d\u003d Const.POINTS_EQUAL_SHARE) {"},{"lineNumber":954,"author":{"gitId":"-"},"content":" return \"Equal share\";"},{"lineNumber":955,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":956,"author":{"gitId":"-"},"content":" return \"Equal share\" + (answer \u003e 100 ? \" + \" : \" - \") + Math.abs(answer - 100) + \"%\";"},{"lineNumber":957,"author":{"gitId":"-"},"content":" }"},{"lineNumber":958,"author":{"gitId":"-"},"content":" }"},{"lineNumber":959,"author":{"gitId":"-"},"content":""},{"lineNumber":960,"author":{"gitId":"-"},"content":" private WebElement getRubricSection(int qnNumber, String recipient) {"},{"lineNumber":961,"author":{"gitId":"-"},"content":" int recipientIndex \u003d getRecipientIndex(qnNumber, recipient);"},{"lineNumber":962,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(qnNumber);"},{"lineNumber":963,"author":{"gitId":"-"},"content":" return questionForm.findElements(By.tagName(\"tm-rubric-question-edit-answer-form\")).get(recipientIndex);"},{"lineNumber":964,"author":{"gitId":"-"},"content":" }"},{"lineNumber":965,"author":{"gitId":"-"},"content":""},{"lineNumber":966,"author":{"gitId":"-"},"content":" private WebElement getRubricTable(int qnNumber, String recipient) {"},{"lineNumber":967,"author":{"gitId":"-"},"content":" return getRubricSection(qnNumber, recipient).findElement(By.tagName(\"table\"));"},{"lineNumber":968,"author":{"gitId":"-"},"content":" }"},{"lineNumber":969,"author":{"gitId":"-"},"content":""},{"lineNumber":970,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getRubricInputs(int qnNumber, String recipient, int rowNumber) {"},{"lineNumber":971,"author":{"gitId":"-"},"content":" WebElement rubricRow \u003d getRubricSection(qnNumber, recipient).findElements(By.tagName(\"tr\")).get(rowNumber - 1);"},{"lineNumber":972,"author":{"gitId":"-"},"content":" return rubricRow.findElements(By.tagName(\"input\"));"},{"lineNumber":973,"author":{"gitId":"-"},"content":" }"},{"lineNumber":974,"author":{"gitId":"-"},"content":""},{"lineNumber":975,"author":{"gitId":"-"},"content":" private WebElement getRankOptionsSection(int qnNumber, String recipient) {"},{"lineNumber":976,"author":{"gitId":"-"},"content":" int recipientIndex \u003d getRecipientIndex(qnNumber, recipient);"},{"lineNumber":977,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(qnNumber);"},{"lineNumber":978,"author":{"gitId":"-"},"content":" return questionForm.findElements(By.tagName(\"tm-rank-options-question-edit-answer-form\")).get(recipientIndex);"},{"lineNumber":979,"author":{"gitId":"-"},"content":" }"},{"lineNumber":980,"author":{"gitId":"-"},"content":""},{"lineNumber":981,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getRankOptions(int questionNum, String recipient) {"},{"lineNumber":982,"author":{"gitId":"-"},"content":" WebElement rankSection \u003d getRankOptionsSection(questionNum, recipient);"},{"lineNumber":983,"author":{"gitId":"-"},"content":" return rankSection.findElements(By.tagName(\"strong\"));"},{"lineNumber":984,"author":{"gitId":"-"},"content":" }"},{"lineNumber":985,"author":{"gitId":"-"},"content":""},{"lineNumber":986,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getRankOptionsDropdowns(int questionNum, String recipient) {"},{"lineNumber":987,"author":{"gitId":"-"},"content":" WebElement rankSection \u003d getRankOptionsSection(questionNum, recipient);"},{"lineNumber":988,"author":{"gitId":"-"},"content":" return rankSection.findElements(By.tagName(\"select\"));"},{"lineNumber":989,"author":{"gitId":"-"},"content":" }"},{"lineNumber":990,"author":{"gitId":"-"},"content":""},{"lineNumber":991,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getRankRecipientDropdowns(int questionNum) {"},{"lineNumber":992,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElements(By.tagName(\"select\"));"},{"lineNumber":993,"author":{"gitId":"-"},"content":" }"},{"lineNumber":994,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":13,"dishenggg":45,"mingyuanc":14,"-":922}},{"path":"src/e2e/java/teammates/e2e/pageobjects/InstructorFeedbackEditPage.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.pageobjects;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertEquals;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertFalse;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertTrue;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.time.ZoneId;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.time.ZonedDateTime;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import java.util.Arrays;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import org.openqa.selenium.By;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import org.openqa.selenium.Keys;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import org.openqa.selenium.WebElement;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import org.openqa.selenium.support.FindBy;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackConstantSumQuestionDetails;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackContributionQuestionDetails;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackMcqQuestionDetails;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackMsqQuestionDetails;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackNumericalScaleQuestionDetails;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionType;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRankOptionsQuestionDetails;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRankQuestionDetails;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRubricQuestionDetails;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackTextQuestionDetails;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.test.ThreadHelper;"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":40,"author":{"gitId":"-"},"content":" * Represents the instructor feedback edit page of the website."},{"lineNumber":41,"author":{"gitId":"-"},"content":" */"},{"lineNumber":42,"author":{"gitId":"-"},"content":"public class InstructorFeedbackEditPage extends AppPage {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" private static final String CUSTOM_FEEDBACK_PATH_OPTION \u003d \"Custom feedback path\";"},{"lineNumber":44,"author":{"gitId":"-"},"content":" private static final String FEEDBACK_PATH_SEPARATOR \u003d \" will give feedback on \";"},{"lineNumber":45,"author":{"gitId":"-"},"content":" private static final String CUSTOM_VISIBILITY_OPTION \u003d \"Custom visibility options\";"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-fs-edit\")"},{"lineNumber":48,"author":{"gitId":"-"},"content":" private WebElement fsEditButton;"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-fs-save\")"},{"lineNumber":51,"author":{"gitId":"-"},"content":" private WebElement fsSaveButton;"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-fs-copy\")"},{"lineNumber":54,"author":{"gitId":"-"},"content":" private WebElement fsCopyButton;"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"edit-course-id\")"},{"lineNumber":57,"author":{"gitId":"-"},"content":" private WebElement courseIdTextBox;"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"time-zone\")"},{"lineNumber":60,"author":{"gitId":"-"},"content":" private WebElement timezoneDropDown;"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"course-name\")"},{"lineNumber":63,"author":{"gitId":"-"},"content":" private WebElement courseNameTextBox;"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"edit-session-name\")"},{"lineNumber":66,"author":{"gitId":"-"},"content":" private WebElement sessionNameTextBox;"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"instructions\")"},{"lineNumber":69,"author":{"gitId":"-"},"content":" private WebElement instructionsEditor;"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"submission-start-date\")"},{"lineNumber":72,"author":{"gitId":"-"},"content":" private WebElement startDateBox;"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"submission-start-time\")"},{"lineNumber":75,"author":{"gitId":"-"},"content":" private WebElement startTimeDropdown;"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"submission-end-date\")"},{"lineNumber":78,"author":{"gitId":"-"},"content":" private WebElement endDateBox;"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"submission-end-time\")"},{"lineNumber":81,"author":{"gitId":"-"},"content":" private WebElement endTimeDropdown;"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"grace-period\")"},{"lineNumber":84,"author":{"gitId":"-"},"content":" private WebElement gracePeriodDropdown;"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"submission-status\")"},{"lineNumber":87,"author":{"gitId":"-"},"content":" private WebElement submissionStatusTextBox;"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"published-status\")"},{"lineNumber":90,"author":{"gitId":"-"},"content":" private WebElement publishStatusTextBox;"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-change-visibility\")"},{"lineNumber":93,"author":{"gitId":"-"},"content":" private WebElement changeVisibilityButton;"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"session-visibility-custom\")"},{"lineNumber":96,"author":{"gitId":"-"},"content":" private WebElement customSessionVisibleTimeButton;"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"session-visibility-date\")"},{"lineNumber":99,"author":{"gitId":"-"},"content":" private WebElement sessionVisibilityDateBox;"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"session-visibility-time\")"},{"lineNumber":102,"author":{"gitId":"-"},"content":" private WebElement sessionVisibilityTimeDropdown;"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"session-visibility-at-open\")"},{"lineNumber":105,"author":{"gitId":"-"},"content":" private WebElement openSessionVisibleTimeButton;"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"response-visibility-custom\")"},{"lineNumber":108,"author":{"gitId":"-"},"content":" private WebElement customResponseVisibleTimeButton;"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"response-visibility-date\")"},{"lineNumber":111,"author":{"gitId":"-"},"content":" private WebElement responseVisibilityDateBox;"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"response-visibility-time\")"},{"lineNumber":114,"author":{"gitId":"-"},"content":" private WebElement responseVisibilityTimeDropdown;"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"response-visibility-immediately\")"},{"lineNumber":117,"author":{"gitId":"-"},"content":" private WebElement immediateResponseVisibleTimeButton;"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"response-visibility-manually\")"},{"lineNumber":120,"author":{"gitId":"-"},"content":" private WebElement manualResponseVisibleTimeButton;"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-change-email\")"},{"lineNumber":123,"author":{"gitId":"-"},"content":" private WebElement changeEmailButton;"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"email-opening\")"},{"lineNumber":126,"author":{"gitId":"-"},"content":" private WebElement openingSessionEmailCheckbox;"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"email-closing\")"},{"lineNumber":129,"author":{"gitId":"-"},"content":" private WebElement closingSessionEmailCheckbox;"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"email-published\")"},{"lineNumber":132,"author":{"gitId":"-"},"content":" private WebElement publishedSessionEmailCheckbox;"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-new-question\")"},{"lineNumber":135,"author":{"gitId":"-"},"content":" private WebElement addNewQuestionButton;"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-copy-question\")"},{"lineNumber":138,"author":{"gitId":"-"},"content":" private WebElement copyQuestionButton;"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"preview-student\")"},{"lineNumber":141,"author":{"gitId":"-"},"content":" private WebElement previewAsStudentDropdown;"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-preview-student\")"},{"lineNumber":144,"author":{"gitId":"-"},"content":" private WebElement previewAsStudentButton;"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"preview-instructor\")"},{"lineNumber":147,"author":{"gitId":"-"},"content":" private WebElement previewAsInstructorDropdown;"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" @FindBy(id \u003d \"btn-preview-instructor\")"},{"lineNumber":150,"author":{"gitId":"-"},"content":" private WebElement previewAsInstructorButton;"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" public InstructorFeedbackEditPage(Browser browser) {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" super(browser);"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":157,"author":{"gitId":"-"},"content":" protected boolean containsExpectedPageContents() {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" return getPageTitle().contains(\"Edit Feedback Session\");"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" public void verifySessionDetails(CourseAttributes course, FeedbackSessionAttributes feedbackSession) {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" waitForElementPresence(By.id(\"instructions\"));"},{"lineNumber":163,"author":{"gitId":"-"},"content":" assertEquals(getCourseId(), course.getId());"},{"lineNumber":164,"author":{"gitId":"-"},"content":" assertEquals(getCourseName(), course.getName());"},{"lineNumber":165,"author":{"gitId":"-"},"content":" assertEquals(getTimeZone(), feedbackSession.getTimeZone());"},{"lineNumber":166,"author":{"gitId":"-"},"content":" assertEquals(getFeedbackSessionName(), feedbackSession.getFeedbackSessionName());"},{"lineNumber":167,"author":{"gitId":"-"},"content":" assertEquals(getInstructions(), feedbackSession.getInstructions());"},{"lineNumber":168,"author":{"gitId":"-"},"content":" assertEquals(getStartDate(), getDateString(feedbackSession.getStartTime(), feedbackSession.getTimeZone()));"},{"lineNumber":169,"author":{"gitId":"-"},"content":" assertEquals(getStartTime(), getTimeString(feedbackSession.getStartTime(), feedbackSession.getTimeZone()));"},{"lineNumber":170,"author":{"gitId":"-"},"content":" assertEquals(getEndDate(), getDateString(feedbackSession.getEndTime(), feedbackSession.getTimeZone()));"},{"lineNumber":171,"author":{"gitId":"-"},"content":" assertEquals(getEndTime(), getTimeString(feedbackSession.getEndTime(), feedbackSession.getTimeZone()));"},{"lineNumber":172,"author":{"gitId":"-"},"content":" assertEquals(getGracePeriod(), feedbackSession.getGracePeriodMinutes() + \" min\");"},{"lineNumber":173,"author":{"gitId":"-"},"content":" verifySubmissionStatus(feedbackSession);"},{"lineNumber":174,"author":{"gitId":"-"},"content":" verifyPublishedStatus(feedbackSession);"},{"lineNumber":175,"author":{"gitId":"-"},"content":" verifyVisibilitySettings(feedbackSession);"},{"lineNumber":176,"author":{"gitId":"-"},"content":" verifyEmailSettings(feedbackSession);"},{"lineNumber":177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" private void verifySubmissionStatus(FeedbackSessionAttributes feedbackSession) {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" String submissionStatus \u003d getSubmissionStatus();"},{"lineNumber":181,"author":{"gitId":"-"},"content":" if (feedbackSession.isClosed()) {"},{"lineNumber":182,"author":{"gitId":"-"},"content":" assertEquals(submissionStatus, \"Closed\");"},{"lineNumber":183,"author":{"gitId":"-"},"content":" } else if (feedbackSession.isVisible() \u0026\u0026 (feedbackSession.isOpened() || feedbackSession.isInGracePeriod())) {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" assertEquals(submissionStatus, \"Open\");"},{"lineNumber":185,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" assertEquals(submissionStatus, \"Awaiting\");"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":" }"},{"lineNumber":189,"author":{"gitId":"-"},"content":""},{"lineNumber":190,"author":{"gitId":"-"},"content":" private void verifyPublishedStatus(FeedbackSessionAttributes feedbackSession) {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" String publishedStatus \u003d getPublishedStatus();"},{"lineNumber":192,"author":{"gitId":"-"},"content":" if (feedbackSession.isPublished()) {"},{"lineNumber":193,"author":{"gitId":"-"},"content":" assertEquals(publishedStatus, \"Published\");"},{"lineNumber":194,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":195,"author":{"gitId":"-"},"content":" assertEquals(publishedStatus, \"Not Published\");"},{"lineNumber":196,"author":{"gitId":"-"},"content":" }"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" private void verifyVisibilitySettings(FeedbackSessionAttributes feedbackSession) {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" Instant sessionVisibleTime \u003d feedbackSession.getSessionVisibleFromTime();"},{"lineNumber":201,"author":{"gitId":"-"},"content":" Instant responseVisibleTime \u003d feedbackSession.getResultsVisibleFromTime();"},{"lineNumber":202,"author":{"gitId":"-"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":" // Default settings, assert setting section not expanded"},{"lineNumber":204,"author":{"gitId":"-"},"content":" if (sessionVisibleTime.equals(Const.TIME_REPRESENTS_FOLLOW_OPENING)"},{"lineNumber":205,"author":{"gitId":"-"},"content":" \u0026\u0026 responseVisibleTime.equals(Const.TIME_REPRESENTS_LATER)) {"},{"lineNumber":206,"author":{"gitId":"-"},"content":" assertTrue(isElementPresent(\"btn-change-visibility\"));"},{"lineNumber":207,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":208,"author":{"gitId":"-"},"content":" }"},{"lineNumber":209,"author":{"gitId":"-"},"content":" verifySessionVisibilitySettings(sessionVisibleTime, feedbackSession);"},{"lineNumber":210,"author":{"gitId":"-"},"content":" verifyResponseVisibilitySettings(responseVisibleTime, feedbackSession);"},{"lineNumber":211,"author":{"gitId":"-"},"content":" }"},{"lineNumber":212,"author":{"gitId":"-"},"content":""},{"lineNumber":213,"author":{"gitId":"-"},"content":" private void verifySessionVisibilitySettings(Instant sessionVisibleTime,"},{"lineNumber":214,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes feedbackSession) {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" if (sessionVisibleTime.equals(Const.TIME_REPRESENTS_FOLLOW_OPENING)) {"},{"lineNumber":216,"author":{"gitId":"-"},"content":" assertTrue(openSessionVisibleTimeButton.isSelected());"},{"lineNumber":217,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":218,"author":{"gitId":"-"},"content":" assertTrue(customSessionVisibleTimeButton.isSelected());"},{"lineNumber":219,"author":{"gitId":"-"},"content":" assertEquals(getSessionVisibilityDate(), getDateString(feedbackSession.getSessionVisibleFromTime(),"},{"lineNumber":220,"author":{"gitId":"-"},"content":" feedbackSession.getTimeZone()));"},{"lineNumber":221,"author":{"gitId":"-"},"content":" assertEquals(getSessionVisibilityTime(), getTimeString(feedbackSession.getSessionVisibleFromTime(),"},{"lineNumber":222,"author":{"gitId":"-"},"content":" feedbackSession.getTimeZone()));"},{"lineNumber":223,"author":{"gitId":"-"},"content":" }"},{"lineNumber":224,"author":{"gitId":"-"},"content":" }"},{"lineNumber":225,"author":{"gitId":"-"},"content":""},{"lineNumber":226,"author":{"gitId":"-"},"content":" private void verifyResponseVisibilitySettings(Instant responseVisibleTime,"},{"lineNumber":227,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes feedbackSession) {"},{"lineNumber":228,"author":{"gitId":"-"},"content":" if (responseVisibleTime.equals(Const.TIME_REPRESENTS_FOLLOW_VISIBLE)) {"},{"lineNumber":229,"author":{"gitId":"-"},"content":" assertTrue(immediateResponseVisibleTimeButton.isSelected());"},{"lineNumber":230,"author":{"gitId":"-"},"content":" } else if (responseVisibleTime.equals(Const.TIME_REPRESENTS_LATER)) {"},{"lineNumber":231,"author":{"gitId":"-"},"content":" assertTrue(manualResponseVisibleTimeButton.isSelected());"},{"lineNumber":232,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":233,"author":{"gitId":"-"},"content":" assertTrue(customSessionVisibleTimeButton.isSelected());"},{"lineNumber":234,"author":{"gitId":"-"},"content":" assertEquals(getResponseVisibilityDate(), getDateString(feedbackSession.getResultsVisibleFromTime(),"},{"lineNumber":235,"author":{"gitId":"-"},"content":" feedbackSession.getTimeZone()));"},{"lineNumber":236,"author":{"gitId":"-"},"content":" assertEquals(getResponseVisibilityTime(), getTimeString(feedbackSession.getResultsVisibleFromTime(),"},{"lineNumber":237,"author":{"gitId":"-"},"content":" feedbackSession.getTimeZone()));"},{"lineNumber":238,"author":{"gitId":"-"},"content":" }"},{"lineNumber":239,"author":{"gitId":"-"},"content":" }"},{"lineNumber":240,"author":{"gitId":"-"},"content":""},{"lineNumber":241,"author":{"gitId":"-"},"content":" private void verifyEmailSettings(FeedbackSessionAttributes feedbackSession) {"},{"lineNumber":242,"author":{"gitId":"-"},"content":" boolean isOpeningEmailEnabled \u003d feedbackSession.isOpeningEmailEnabled();"},{"lineNumber":243,"author":{"gitId":"-"},"content":" boolean isClosingEmailEnabled \u003d feedbackSession.isClosingEmailEnabled();"},{"lineNumber":244,"author":{"gitId":"-"},"content":" boolean isPublishedEmailEnabled \u003d feedbackSession.isPublishedEmailEnabled();"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" // Default settings, assert setting section not expanded"},{"lineNumber":247,"author":{"gitId":"-"},"content":" if (isOpeningEmailEnabled \u0026\u0026 isClosingEmailEnabled \u0026\u0026 isPublishedEmailEnabled) {"},{"lineNumber":248,"author":{"gitId":"-"},"content":" assertTrue(isElementPresent(\"btn-change-email\"));"},{"lineNumber":249,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":250,"author":{"gitId":"-"},"content":" }"},{"lineNumber":251,"author":{"gitId":"-"},"content":" if (isOpeningEmailEnabled) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" assertTrue(openingSessionEmailCheckbox.isSelected());"},{"lineNumber":253,"author":{"gitId":"-"},"content":" }"},{"lineNumber":254,"author":{"gitId":"-"},"content":" if (isClosingEmailEnabled) {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" assertTrue(closingSessionEmailCheckbox.isSelected());"},{"lineNumber":256,"author":{"gitId":"-"},"content":" }"},{"lineNumber":257,"author":{"gitId":"-"},"content":" if (isPublishedEmailEnabled) {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" assertTrue(publishedSessionEmailCheckbox.isSelected());"},{"lineNumber":259,"author":{"gitId":"-"},"content":" }"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":""},{"lineNumber":262,"author":{"gitId":"-"},"content":" public void editSessionDetails(FeedbackSessionAttributes newFeedbackSessionDetails) {"},{"lineNumber":263,"author":{"gitId":"-"},"content":" click(fsEditButton);"},{"lineNumber":264,"author":{"gitId":"-"},"content":" setInstructions(newFeedbackSessionDetails.getInstructions());"},{"lineNumber":265,"author":{"gitId":"-"},"content":" setSessionStartDateTime(newFeedbackSessionDetails.getStartTime(), newFeedbackSessionDetails.getTimeZone());"},{"lineNumber":266,"author":{"gitId":"-"},"content":" setSessionEndDateTime(newFeedbackSessionDetails.getEndTime(), newFeedbackSessionDetails.getTimeZone());"},{"lineNumber":267,"author":{"gitId":"-"},"content":" selectGracePeriod(newFeedbackSessionDetails.getGracePeriodMinutes());"},{"lineNumber":268,"author":{"gitId":"-"},"content":" setVisibilitySettings(newFeedbackSessionDetails);"},{"lineNumber":269,"author":{"gitId":"-"},"content":" setEmailSettings(newFeedbackSessionDetails);"},{"lineNumber":270,"author":{"gitId":"-"},"content":" click(fsSaveButton);"},{"lineNumber":271,"author":{"gitId":"-"},"content":" }"},{"lineNumber":272,"author":{"gitId":"-"},"content":""},{"lineNumber":273,"author":{"gitId":"-"},"content":" public void copySessionToOtherCourse(CourseAttributes otherCourse, String sessionName) {"},{"lineNumber":274,"author":{"gitId":"-"},"content":" click(fsCopyButton);"},{"lineNumber":275,"author":{"gitId":"-"},"content":" WebElement copyFsModal \u003d waitForElementPresence(By.id(\"copy-course-modal\"));"},{"lineNumber":276,"author":{"gitId":"-"},"content":""},{"lineNumber":277,"author":{"gitId":"-"},"content":" fillTextBox(copyFsModal.findElement(By.id(\"copy-session-name\")), sessionName);"},{"lineNumber":278,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e options \u003d copyFsModal.findElements(By.className(\"form-check\"));"},{"lineNumber":279,"author":{"gitId":"-"},"content":" for (WebElement option : options) {"},{"lineNumber":280,"author":{"gitId":"-"},"content":" String courseId \u003d option.findElement(By.cssSelector(\"label span\")).getText();"},{"lineNumber":281,"author":{"gitId":"-"},"content":" if (courseId.equals(otherCourse.getId())) {"},{"lineNumber":282,"author":{"gitId":"-"},"content":" click(option.findElement(By.tagName(\"input\")));"},{"lineNumber":283,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":284,"author":{"gitId":"-"},"content":" }"},{"lineNumber":285,"author":{"gitId":"-"},"content":" }"},{"lineNumber":286,"author":{"gitId":"-"},"content":" click(browser.driver.findElement(By.id(\"btn-confirm-copy-course\")));"},{"lineNumber":287,"author":{"gitId":"-"},"content":" }"},{"lineNumber":288,"author":{"gitId":"-"},"content":""},{"lineNumber":289,"author":{"gitId":"-"},"content":" public void deleteSession() {"},{"lineNumber":290,"author":{"gitId":"-"},"content":" clickAndConfirm(waitForElementPresence(By.id(\"btn-fs-delete\")));"},{"lineNumber":291,"author":{"gitId":"-"},"content":" }"},{"lineNumber":292,"author":{"gitId":"-"},"content":""},{"lineNumber":293,"author":{"gitId":"-"},"content":" public FeedbackSubmitPage previewAsStudent(StudentAttributes student) {"},{"lineNumber":294,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(previewAsStudentDropdown, String.format(\"[%s] %s\", student.getTeam(), student.getName()));"},{"lineNumber":295,"author":{"gitId":"-"},"content":" click(previewAsStudentButton);"},{"lineNumber":296,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(2000);"},{"lineNumber":297,"author":{"gitId":"-"},"content":" switchToNewWindow();"},{"lineNumber":298,"author":{"gitId":"-"},"content":" return changePageType(FeedbackSubmitPage.class);"},{"lineNumber":299,"author":{"gitId":"-"},"content":" }"},{"lineNumber":300,"author":{"gitId":"-"},"content":""},{"lineNumber":301,"author":{"gitId":"-"},"content":" public FeedbackSubmitPage previewAsInstructor(InstructorAttributes instructor) {"},{"lineNumber":302,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(previewAsInstructorDropdown, instructor.getName());"},{"lineNumber":303,"author":{"gitId":"-"},"content":" click(previewAsInstructorButton);"},{"lineNumber":304,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(2000);"},{"lineNumber":305,"author":{"gitId":"-"},"content":" switchToNewWindow();"},{"lineNumber":306,"author":{"gitId":"-"},"content":" return changePageType(FeedbackSubmitPage.class);"},{"lineNumber":307,"author":{"gitId":"-"},"content":" }"},{"lineNumber":308,"author":{"gitId":"-"},"content":""},{"lineNumber":309,"author":{"gitId":"-"},"content":" public void verifyNumQuestions(int expected) {"},{"lineNumber":310,"author":{"gitId":"-"},"content":" assertEquals(getNumQuestions(), expected);"},{"lineNumber":311,"author":{"gitId":"-"},"content":" }"},{"lineNumber":312,"author":{"gitId":"-"},"content":""},{"lineNumber":313,"author":{"gitId":"-"},"content":" public void verifyQuestionDetails(int questionNum, FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":314,"author":{"gitId":"-"},"content":" scrollElementToCenter(getQuestionForm(questionNum));"},{"lineNumber":315,"author":{"gitId":"-"},"content":" assertEquals(feedbackQuestion.getQuestionType(), getQuestionType(questionNum));"},{"lineNumber":316,"author":{"gitId":"-"},"content":" assertEquals(feedbackQuestion.getQuestionNumber(), getQuestionNumber(questionNum));"},{"lineNumber":317,"author":{"gitId":"-"},"content":" assertEquals(feedbackQuestion.getQuestionDetailsCopy().getQuestionText(), getQuestionBrief(questionNum));"},{"lineNumber":318,"author":{"gitId":"-"},"content":" assertEquals(getQuestionDescription(questionNum), feedbackQuestion.getQuestionDescription());"},{"lineNumber":319,"author":{"gitId":"-"},"content":" verifyFeedbackPathSettings(questionNum, feedbackQuestion);"},{"lineNumber":320,"author":{"gitId":"-"},"content":" verifyQuestionVisibilitySettings(questionNum, feedbackQuestion);"},{"lineNumber":321,"author":{"gitId":"-"},"content":" }"},{"lineNumber":322,"author":{"gitId":"-"},"content":""},{"lineNumber":323,"author":{"gitId":"-"},"content":" private void verifyFeedbackPathSettings(int questionNum, FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":324,"author":{"gitId":"-"},"content":" assertEquals(getDisplayGiverName(feedbackQuestion.getGiverType()), getFeedbackGiver(questionNum));"},{"lineNumber":325,"author":{"gitId":"-"},"content":" String feedbackReceiver \u003d getFeedbackReceiver(questionNum);"},{"lineNumber":326,"author":{"gitId":"-"},"content":" assertEquals(getDisplayRecipientName(feedbackQuestion.getRecipientType()), feedbackReceiver);"},{"lineNumber":327,"author":{"gitId":"-"},"content":""},{"lineNumber":328,"author":{"gitId":"-"},"content":" if (feedbackReceiver.equals(getDisplayRecipientName(FeedbackParticipantType.INSTRUCTORS))"},{"lineNumber":329,"author":{"gitId":"-"},"content":" || feedbackReceiver.equals(getDisplayRecipientName(FeedbackParticipantType.STUDENTS_EXCLUDING_SELF))"},{"lineNumber":330,"author":{"gitId":"-"},"content":" || feedbackReceiver.equals(getDisplayRecipientName(FeedbackParticipantType.TEAMS_EXCLUDING_SELF))) {"},{"lineNumber":331,"author":{"gitId":"-"},"content":" verifyNumberOfEntitiesToGiveFeedbackTo(questionNum, feedbackQuestion.getNumberOfEntitiesToGiveFeedbackTo());"},{"lineNumber":332,"author":{"gitId":"-"},"content":" }"},{"lineNumber":333,"author":{"gitId":"-"},"content":" }"},{"lineNumber":334,"author":{"gitId":"-"},"content":""},{"lineNumber":335,"author":{"gitId":"-"},"content":" private void verifyNumberOfEntitiesToGiveFeedbackTo(int questionNum, int numberOfEntitiesToGiveFeedbackTo) {"},{"lineNumber":336,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(questionNum);"},{"lineNumber":337,"author":{"gitId":"-"},"content":" WebElement feedbackPathPanel \u003d questionForm.findElement(By.tagName(\"tm-feedback-path-panel\"));"},{"lineNumber":338,"author":{"gitId":"-"},"content":" if (numberOfEntitiesToGiveFeedbackTo \u003d\u003d Const.MAX_POSSIBLE_RECIPIENTS) {"},{"lineNumber":339,"author":{"gitId":"-"},"content":" assertTrue(feedbackPathPanel.findElement(By.id(\"unlimited-recipients\")).isSelected());"},{"lineNumber":340,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":341,"author":{"gitId":"-"},"content":" assertTrue(feedbackPathPanel.findElement(By.id(\"custom-recipients\")).isSelected());"},{"lineNumber":342,"author":{"gitId":"-"},"content":" assertEquals(feedbackPathPanel.findElement(By.id(\"custom-recipients-number\")).getAttribute(\"value\"),"},{"lineNumber":343,"author":{"gitId":"-"},"content":" Integer.toString(numberOfEntitiesToGiveFeedbackTo));"},{"lineNumber":344,"author":{"gitId":"-"},"content":" }"},{"lineNumber":345,"author":{"gitId":"-"},"content":" }"},{"lineNumber":346,"author":{"gitId":"-"},"content":""},{"lineNumber":347,"author":{"gitId":"-"},"content":" private void verifyQuestionVisibilitySettings(int questionNum, FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":348,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(questionNum);"},{"lineNumber":349,"author":{"gitId":"-"},"content":" WebElement visibilityPanel \u003d questionForm.findElement(By.tagName(\"tm-visibility-panel\"));"},{"lineNumber":350,"author":{"gitId":"-"},"content":" String visibility \u003d visibilityPanel.findElement(By.cssSelector(\"#btn-question-visibility span\")).getText();"},{"lineNumber":351,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showResponsesTo \u003d feedbackQuestion.getShowResponsesTo();"},{"lineNumber":352,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showGiverNameTo \u003d feedbackQuestion.getShowGiverNameTo();"},{"lineNumber":353,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showRecipientNameTo \u003d feedbackQuestion.getShowRecipientNameTo();"},{"lineNumber":354,"author":{"gitId":"-"},"content":""},{"lineNumber":355,"author":{"gitId":"-"},"content":" switch (visibility) {"},{"lineNumber":356,"author":{"gitId":"-"},"content":" case \"Shown anonymously to recipient and giver\u0027s team members, visible to instructors\":"},{"lineNumber":357,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":358,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":359,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.OWN_TEAM_MEMBERS));"},{"lineNumber":360,"author":{"gitId":"-"},"content":" assertEquals(showResponsesTo.size(), 3);"},{"lineNumber":361,"author":{"gitId":"-"},"content":""},{"lineNumber":362,"author":{"gitId":"-"},"content":" assertTrue(showGiverNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":363,"author":{"gitId":"-"},"content":" assertEquals(showGiverNameTo.size(), 1);"},{"lineNumber":364,"author":{"gitId":"-"},"content":""},{"lineNumber":365,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":366,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":367,"author":{"gitId":"-"},"content":" assertEquals(showRecipientNameTo.size(), 2);"},{"lineNumber":368,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":369,"author":{"gitId":"-"},"content":""},{"lineNumber":370,"author":{"gitId":"-"},"content":" case \"Visible to instructors only\":"},{"lineNumber":371,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":372,"author":{"gitId":"-"},"content":" assertEquals(showResponsesTo.size(), 1);"},{"lineNumber":373,"author":{"gitId":"-"},"content":""},{"lineNumber":374,"author":{"gitId":"-"},"content":" assertTrue(showGiverNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":375,"author":{"gitId":"-"},"content":" assertEquals(showGiverNameTo.size(), 1);"},{"lineNumber":376,"author":{"gitId":"-"},"content":""},{"lineNumber":377,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":378,"author":{"gitId":"-"},"content":" assertEquals(showRecipientNameTo.size(), 1);"},{"lineNumber":379,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":380,"author":{"gitId":"-"},"content":""},{"lineNumber":381,"author":{"gitId":"-"},"content":" case \"Shown anonymously to recipient and instructors\":"},{"lineNumber":382,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":383,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":384,"author":{"gitId":"-"},"content":" assertEquals(showResponsesTo.size(), 2);"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"-"},"content":" assertEquals(showGiverNameTo.size(), 0);"},{"lineNumber":387,"author":{"gitId":"-"},"content":""},{"lineNumber":388,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":389,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":390,"author":{"gitId":"-"},"content":" assertEquals(showRecipientNameTo.size(), 2);"},{"lineNumber":391,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":392,"author":{"gitId":"-"},"content":""},{"lineNumber":393,"author":{"gitId":"-"},"content":" case \"Shown anonymously to recipient, visible to instructors\":"},{"lineNumber":394,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":395,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":396,"author":{"gitId":"-"},"content":" assertEquals(showResponsesTo.size(), 2);"},{"lineNumber":397,"author":{"gitId":"-"},"content":""},{"lineNumber":398,"author":{"gitId":"-"},"content":" assertTrue(showGiverNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":399,"author":{"gitId":"-"},"content":" assertEquals(showGiverNameTo.size(), 1);"},{"lineNumber":400,"author":{"gitId":"-"},"content":""},{"lineNumber":401,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":402,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":403,"author":{"gitId":"-"},"content":" assertEquals(showRecipientNameTo.size(), 2);"},{"lineNumber":404,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":405,"author":{"gitId":"-"},"content":""},{"lineNumber":406,"author":{"gitId":"-"},"content":" case \"Shown anonymously to recipient and giver/recipient\u0027s team members, visible to instructors\":"},{"lineNumber":407,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":408,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":409,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.OWN_TEAM_MEMBERS));"},{"lineNumber":410,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.RECEIVER_TEAM_MEMBERS));"},{"lineNumber":411,"author":{"gitId":"-"},"content":" assertEquals(showResponsesTo.size(), 4);"},{"lineNumber":412,"author":{"gitId":"-"},"content":""},{"lineNumber":413,"author":{"gitId":"-"},"content":" assertTrue(showGiverNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":414,"author":{"gitId":"-"},"content":" assertEquals(showGiverNameTo.size(), 1);"},{"lineNumber":415,"author":{"gitId":"-"},"content":""},{"lineNumber":416,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":417,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":418,"author":{"gitId":"-"},"content":" assertEquals(showRecipientNameTo.size(), 2);"},{"lineNumber":419,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":420,"author":{"gitId":"-"},"content":""},{"lineNumber":421,"author":{"gitId":"-"},"content":" case \"Visible to recipient and instructors\":"},{"lineNumber":422,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":423,"author":{"gitId":"-"},"content":" assertTrue(showResponsesTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":424,"author":{"gitId":"-"},"content":" assertEquals(showResponsesTo.size(), 2);"},{"lineNumber":425,"author":{"gitId":"-"},"content":""},{"lineNumber":426,"author":{"gitId":"-"},"content":" assertTrue(showGiverNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":427,"author":{"gitId":"-"},"content":" assertTrue(showGiverNameTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":428,"author":{"gitId":"-"},"content":" assertEquals(showGiverNameTo.size(), 2);"},{"lineNumber":429,"author":{"gitId":"-"},"content":""},{"lineNumber":430,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":431,"author":{"gitId":"-"},"content":" assertTrue(showRecipientNameTo.contains(FeedbackParticipantType.RECEIVER));"},{"lineNumber":432,"author":{"gitId":"-"},"content":" assertEquals(showRecipientNameTo.size(), 2);"},{"lineNumber":433,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":434,"author":{"gitId":"-"},"content":""},{"lineNumber":435,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":436,"author":{"gitId":"-"},"content":" verifyCustomQuestionVisibility(questionNum, feedbackQuestion);"},{"lineNumber":437,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":438,"author":{"gitId":"-"},"content":" }"},{"lineNumber":439,"author":{"gitId":"-"},"content":" }"},{"lineNumber":440,"author":{"gitId":"-"},"content":""},{"lineNumber":441,"author":{"gitId":"-"},"content":" private void verifyCustomQuestionVisibility(int questionNum, FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":442,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(questionNum);"},{"lineNumber":443,"author":{"gitId":"-"},"content":" WebElement visibilityPanel \u003d questionForm.findElement(By.tagName(\"tm-visibility-panel\"));"},{"lineNumber":444,"author":{"gitId":"-"},"content":" String visibility \u003d visibilityPanel.findElement(By.cssSelector(\"#btn-question-visibility span\")).getText();"},{"lineNumber":445,"author":{"gitId":"-"},"content":" assertEquals(visibility, CUSTOM_VISIBILITY_OPTION);"},{"lineNumber":446,"author":{"gitId":"-"},"content":""},{"lineNumber":447,"author":{"gitId":"-"},"content":" FeedbackParticipantType giver \u003d feedbackQuestion.getGiverType();"},{"lineNumber":448,"author":{"gitId":"-"},"content":" FeedbackParticipantType receiver \u003d feedbackQuestion.getRecipientType();"},{"lineNumber":449,"author":{"gitId":"-"},"content":" WebElement customVisibilityTable \u003d visibilityPanel.findElement(By.id(\"custom-visibility-table\"));"},{"lineNumber":450,"author":{"gitId":"-"},"content":" assertVisibilityBoxesSelected(customVisibilityTable, giver, receiver, feedbackQuestion.getShowResponsesTo(), 1);"},{"lineNumber":451,"author":{"gitId":"-"},"content":" assertVisibilityBoxesSelected(customVisibilityTable, giver, receiver, feedbackQuestion.getShowGiverNameTo(), 2);"},{"lineNumber":452,"author":{"gitId":"-"},"content":" assertVisibilityBoxesSelected(customVisibilityTable, giver, receiver, feedbackQuestion.getShowRecipientNameTo(), 3);"},{"lineNumber":453,"author":{"gitId":"-"},"content":" }"},{"lineNumber":454,"author":{"gitId":"-"},"content":""},{"lineNumber":455,"author":{"gitId":"-"},"content":" private void assertVisibilityBoxesSelected(WebElement table, FeedbackParticipantType giver,"},{"lineNumber":456,"author":{"gitId":"-"},"content":" FeedbackParticipantType receiver, List\u003cFeedbackParticipantType\u003e participants,"},{"lineNumber":457,"author":{"gitId":"-"},"content":" int colNum) {"},{"lineNumber":458,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e possibleTypes \u003d new ArrayList\u003c\u003e(Arrays.asList(FeedbackParticipantType.RECEIVER,"},{"lineNumber":459,"author":{"gitId":"-"},"content":" FeedbackParticipantType.OWN_TEAM_MEMBERS, FeedbackParticipantType.RECEIVER_TEAM_MEMBERS,"},{"lineNumber":460,"author":{"gitId":"-"},"content":" FeedbackParticipantType.STUDENTS, FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":461,"author":{"gitId":"-"},"content":" if (!giver.equals(FeedbackParticipantType.STUDENTS)) {"},{"lineNumber":462,"author":{"gitId":"-"},"content":" possibleTypes.remove(FeedbackParticipantType.OWN_TEAM_MEMBERS);"},{"lineNumber":463,"author":{"gitId":"-"},"content":" }"},{"lineNumber":464,"author":{"gitId":"-"},"content":" if (!receiver.equals(FeedbackParticipantType.STUDENTS)) {"},{"lineNumber":465,"author":{"gitId":"-"},"content":" possibleTypes.remove(FeedbackParticipantType.RECEIVER_TEAM_MEMBERS);"},{"lineNumber":466,"author":{"gitId":"-"},"content":" }"},{"lineNumber":467,"author":{"gitId":"-"},"content":" if (receiver.equals(FeedbackParticipantType.NONE)"},{"lineNumber":468,"author":{"gitId":"-"},"content":" || receiver.equals(FeedbackParticipantType.SELF)"},{"lineNumber":469,"author":{"gitId":"-"},"content":" || receiver.equals(FeedbackParticipantType.OWN_TEAM)) {"},{"lineNumber":470,"author":{"gitId":"-"},"content":" possibleTypes.remove(FeedbackParticipantType.RECEIVER);"},{"lineNumber":471,"author":{"gitId":"-"},"content":" possibleTypes.remove(FeedbackParticipantType.RECEIVER_TEAM_MEMBERS);"},{"lineNumber":472,"author":{"gitId":"-"},"content":" }"},{"lineNumber":473,"author":{"gitId":"-"},"content":""},{"lineNumber":474,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d table.findElements(By.tagName(\"tr\"));"},{"lineNumber":475,"author":{"gitId":"-"},"content":" int index \u003d colNum - 1;"},{"lineNumber":476,"author":{"gitId":"-"},"content":" for (FeedbackParticipantType participant : participants) {"},{"lineNumber":477,"author":{"gitId":"-"},"content":" assertTrue(rows.get(possibleTypes.indexOf(participant)).findElements(By.tagName(\"input\")).get(index)"},{"lineNumber":478,"author":{"gitId":"-"},"content":" .isSelected());"},{"lineNumber":479,"author":{"gitId":"-"},"content":" }"},{"lineNumber":480,"author":{"gitId":"-"},"content":" }"},{"lineNumber":481,"author":{"gitId":"-"},"content":""},{"lineNumber":482,"author":{"gitId":"-"},"content":" public void addTemplateQuestion(int optionNum) {"},{"lineNumber":483,"author":{"gitId":"-"},"content":" addNewQuestion(1);"},{"lineNumber":484,"author":{"gitId":"-"},"content":" WebElement templateQuestionModal \u003d waitForElementPresence(By.id(\"template-question-modal\"));"},{"lineNumber":485,"author":{"gitId":"-"},"content":""},{"lineNumber":486,"author":{"gitId":"-"},"content":" click(templateQuestionModal.findElements(By.tagName(\"input\")).get(optionNum - 1));"},{"lineNumber":487,"author":{"gitId":"-"},"content":" clickAndWaitForNewQuestion(browser.driver.findElement(By.id(\"btn-confirm-template\")));"},{"lineNumber":488,"author":{"gitId":"-"},"content":" }"},{"lineNumber":489,"author":{"gitId":"-"},"content":""},{"lineNumber":490,"author":{"gitId":"-"},"content":" public void copyQuestion(String courseId, String questionText) {"},{"lineNumber":491,"author":{"gitId":"-"},"content":" click(copyQuestionButton);"},{"lineNumber":492,"author":{"gitId":"-"},"content":" WebElement copyQuestionModal \u003d waitForElementPresence(By.id(\"copy-question-modal\"));"},{"lineNumber":493,"author":{"gitId":"-"},"content":""},{"lineNumber":494,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e cards \u003d copyQuestionModal.findElements(By.className(\"card\"));"},{"lineNumber":495,"author":{"gitId":"-"},"content":" for (WebElement card : cards) {"},{"lineNumber":496,"author":{"gitId":"-"},"content":" WebElement cardHeader \u003d card.findElement(By.className(\"card-header\"));"},{"lineNumber":497,"author":{"gitId":"-"},"content":" if (cardHeader.getText().startsWith(\"[\" + courseId + \"]\")) {"},{"lineNumber":498,"author":{"gitId":"-"},"content":" click(cardHeader);"},{"lineNumber":499,"author":{"gitId":"-"},"content":" WebElement cardBody \u003d waitForElementPresence(By.className(\"card-body\"));"},{"lineNumber":500,"author":{"gitId":"-"},"content":" // Reload questions"},{"lineNumber":501,"author":{"gitId":"-"},"content":" WebElement reloadBtn \u003d cardBody.findElement(By.tagName(\"button\"));"},{"lineNumber":502,"author":{"gitId":"-"},"content":" click(reloadBtn);"},{"lineNumber":503,"author":{"gitId":"-"},"content":" WebElement table \u003d waitForElementPresence(By.id(\"copy-question-table\"));"},{"lineNumber":504,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d table.findElements(By.cssSelector(\"tbody tr\"));"},{"lineNumber":505,"author":{"gitId":"-"},"content":" for (WebElement row : rows) {"},{"lineNumber":506,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e cells \u003d row.findElements(By.tagName(\"td\"));"},{"lineNumber":507,"author":{"gitId":"-"},"content":" if (cells.get(2).getText().equals(questionText)) {"},{"lineNumber":508,"author":{"gitId":"-"},"content":" markOptionAsSelected(cells.get(0).findElement(By.tagName(\"input\")));"},{"lineNumber":509,"author":{"gitId":"-"},"content":" }"},{"lineNumber":510,"author":{"gitId":"-"},"content":" }"},{"lineNumber":511,"author":{"gitId":"-"},"content":" }"},{"lineNumber":512,"author":{"gitId":"-"},"content":" }"},{"lineNumber":513,"author":{"gitId":"-"},"content":" clickAndWaitForNewQuestion(browser.driver.findElement(By.id(\"btn-confirm-copy-question\")));"},{"lineNumber":514,"author":{"gitId":"-"},"content":" }"},{"lineNumber":515,"author":{"gitId":"-"},"content":""},{"lineNumber":516,"author":{"gitId":"-"},"content":" public void editQuestionNumber(int questionNum, int newQuestionNumber) {"},{"lineNumber":517,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":518,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(getQuestionForm(questionNum).findElement(By.id(\"question-number-dropdown\")),"},{"lineNumber":519,"author":{"gitId":"-"},"content":" Integer.toString(newQuestionNumber));"},{"lineNumber":520,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":521,"author":{"gitId":"-"},"content":" }"},{"lineNumber":522,"author":{"gitId":"-"},"content":""},{"lineNumber":523,"author":{"gitId":"-"},"content":" public void editQuestionDetails(int questionNum, FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":524,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":525,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":526,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":527,"author":{"gitId":"-"},"content":" }"},{"lineNumber":528,"author":{"gitId":"-"},"content":""},{"lineNumber":529,"author":{"gitId":"-"},"content":" private void inputQuestionDetails(int questionNum, FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":530,"author":{"gitId":"-"},"content":" setQuestionBrief(questionNum, feedbackQuestion.getQuestionDetailsCopy().getQuestionText());"},{"lineNumber":531,"author":{"gitId":"-"},"content":" setQuestionDescription(questionNum, feedbackQuestion.getQuestionDescription());"},{"lineNumber":532,"author":{"gitId":"-"},"content":" FeedbackQuestionType questionType \u003d feedbackQuestion.getQuestionType();"},{"lineNumber":533,"author":{"gitId":"-"},"content":" if (!questionType.equals(FeedbackQuestionType.CONTRIB)) {"},{"lineNumber":534,"author":{"gitId":"-"},"content":" setFeedbackPath(questionNum, feedbackQuestion);"},{"lineNumber":535,"author":{"gitId":"-"},"content":" setQuestionVisibility(questionNum, feedbackQuestion);"},{"lineNumber":536,"author":{"gitId":"-"},"content":" }"},{"lineNumber":537,"author":{"gitId":"-"},"content":" }"},{"lineNumber":538,"author":{"gitId":"-"},"content":""},{"lineNumber":539,"author":{"gitId":"-"},"content":" private void inputQuestionDetails(int questionNum, FeedbackQuestion feedbackQuestion) {"},{"lineNumber":540,"author":{"gitId":"-"},"content":" setQuestionBrief(questionNum, feedbackQuestion.getQuestionDetailsCopy().getQuestionText());"},{"lineNumber":541,"author":{"gitId":"-"},"content":" setQuestionDescription(questionNum, feedbackQuestion.getDescription());"},{"lineNumber":542,"author":{"gitId":"-"},"content":" FeedbackQuestionType questionType \u003d feedbackQuestion.getQuestionDetailsCopy().getQuestionType();"},{"lineNumber":543,"author":{"gitId":"-"},"content":" if (!questionType.equals(FeedbackQuestionType.CONTRIB)) {"},{"lineNumber":544,"author":{"gitId":"-"},"content":" setFeedbackPath(questionNum, feedbackQuestion);"},{"lineNumber":545,"author":{"gitId":"-"},"content":" setQuestionVisibility(questionNum, feedbackQuestion);"},{"lineNumber":546,"author":{"gitId":"-"},"content":" }"},{"lineNumber":547,"author":{"gitId":"-"},"content":" }"},{"lineNumber":548,"author":{"gitId":"-"},"content":""},{"lineNumber":549,"author":{"gitId":"-"},"content":" public void duplicateQuestion(int questionNum) {"},{"lineNumber":550,"author":{"gitId":"-"},"content":" clickAndWaitForNewQuestion(getQuestionForm(questionNum).findElement(By.id(\"btn-duplicate-question\")));"},{"lineNumber":551,"author":{"gitId":"-"},"content":" }"},{"lineNumber":552,"author":{"gitId":"-"},"content":""},{"lineNumber":553,"author":{"gitId":"-"},"content":" public void deleteQuestion(int questionNum) {"},{"lineNumber":554,"author":{"gitId":"-"},"content":" clickAndConfirm(getQuestionForm(questionNum).findElement(By.id(\"btn-delete-question\")));"},{"lineNumber":555,"author":{"gitId":"-"},"content":" }"},{"lineNumber":556,"author":{"gitId":"-"},"content":""},{"lineNumber":557,"author":{"gitId":"-"},"content":" public void verifyTextQuestionDetails(int questionNum, FeedbackTextQuestionDetails questionDetails) {"},{"lineNumber":558,"author":{"gitId":"-"},"content":" String recommendLength \u003d getRecommendedTextLengthField(questionNum).getAttribute(\"value\");"},{"lineNumber":559,"author":{"gitId":"-"},"content":" assertEquals(recommendLength, questionDetails.getRecommendedLength().toString());"},{"lineNumber":560,"author":{"gitId":"-"},"content":" }"},{"lineNumber":561,"author":{"gitId":"-"},"content":""},{"lineNumber":562,"author":{"gitId":"-"},"content":" public void addTextQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":563,"author":{"gitId":"-"},"content":" addNewQuestion(2);"},{"lineNumber":564,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":565,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":566,"author":{"gitId":"-"},"content":" FeedbackTextQuestionDetails questionDetails \u003d"},{"lineNumber":567,"author":{"gitId":"-"},"content":" (FeedbackTextQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":568,"author":{"gitId":"-"},"content":" fillTextBox(getRecommendedTextLengthField(questionNum), questionDetails.getRecommendedLength().toString());"},{"lineNumber":569,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":570,"author":{"gitId":"-"},"content":" }"},{"lineNumber":571,"author":{"gitId":"-"},"content":""},{"lineNumber":572,"author":{"gitId":"-"},"content":" public void addTextQuestion(FeedbackQuestion feedbackQuestion) {"},{"lineNumber":573,"author":{"gitId":"-"},"content":" addNewQuestion(2);"},{"lineNumber":574,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":575,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":576,"author":{"gitId":"-"},"content":" FeedbackTextQuestionDetails questionDetails \u003d"},{"lineNumber":577,"author":{"gitId":"-"},"content":" (FeedbackTextQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":578,"author":{"gitId":"-"},"content":" fillTextBox(getRecommendedTextLengthField(questionNum), questionDetails.getRecommendedLength().toString());"},{"lineNumber":579,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":580,"author":{"gitId":"-"},"content":" }"},{"lineNumber":581,"author":{"gitId":"-"},"content":""},{"lineNumber":582,"author":{"gitId":"-"},"content":" public void editTextQuestion(int questionNum, FeedbackTextQuestionDetails textQuestionDetails) {"},{"lineNumber":583,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":584,"author":{"gitId":"-"},"content":" WebElement recommendedTextLengthField \u003d getRecommendedTextLengthField(questionNum);"},{"lineNumber":585,"author":{"gitId":"-"},"content":" waitForElementToBeClickable(recommendedTextLengthField);"},{"lineNumber":586,"author":{"gitId":"-"},"content":" fillTextBox(recommendedTextLengthField, textQuestionDetails.getRecommendedLength().toString());"},{"lineNumber":587,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":588,"author":{"gitId":"-"},"content":" }"},{"lineNumber":589,"author":{"gitId":"-"},"content":""},{"lineNumber":590,"author":{"gitId":"-"},"content":" public void verifyMcqQuestionDetails(int questionNum, FeedbackMcqQuestionDetails questionDetails) {"},{"lineNumber":591,"author":{"gitId":"-"},"content":" if (verifyGeneratedOptions(questionNum, questionDetails.getGenerateOptionsFor())) {"},{"lineNumber":592,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":593,"author":{"gitId":"-"},"content":" }"},{"lineNumber":594,"author":{"gitId":"-"},"content":" verifyOptions(questionNum, questionDetails.getMcqChoices());"},{"lineNumber":595,"author":{"gitId":"-"},"content":" verifyOptionWeights(questionNum, questionDetails.isHasAssignedWeights(), questionDetails.getMcqWeights());"},{"lineNumber":596,"author":{"gitId":"-"},"content":" verifyOtherOption(questionNum, questionDetails.isOtherEnabled(), questionDetails.getMcqOtherWeight());"},{"lineNumber":597,"author":{"gitId":"-"},"content":" }"},{"lineNumber":598,"author":{"gitId":"-"},"content":""},{"lineNumber":599,"author":{"gitId":"-"},"content":" public void addMcqQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":600,"author":{"gitId":"-"},"content":" addNewQuestion(3);"},{"lineNumber":601,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":602,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":603,"author":{"gitId":"-"},"content":" FeedbackMcqQuestionDetails questionDetails \u003d (FeedbackMcqQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":604,"author":{"gitId":"-"},"content":" inputMcqDetails(questionNum, questionDetails);"},{"lineNumber":605,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":606,"author":{"gitId":"-"},"content":" }"},{"lineNumber":607,"author":{"gitId":"-"},"content":""},{"lineNumber":608,"author":{"gitId":"dishenggg"},"content":" public void addMcqQuestion(FeedbackQuestion feedbackQuestion) {"},{"lineNumber":609,"author":{"gitId":"dishenggg"},"content":" addNewQuestion(3);"},{"lineNumber":610,"author":{"gitId":"dishenggg"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":611,"author":{"gitId":"dishenggg"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":612,"author":{"gitId":"-"},"content":" FeedbackMcqQuestionDetails questionDetails \u003d (FeedbackMcqQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":613,"author":{"gitId":"-"},"content":" inputMcqDetails(questionNum, questionDetails);"},{"lineNumber":614,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":615,"author":{"gitId":"-"},"content":" }"},{"lineNumber":616,"author":{"gitId":"-"},"content":""},{"lineNumber":617,"author":{"gitId":"-"},"content":" public void editMcqQuestion(int questionNum, FeedbackMcqQuestionDetails questionDetails) {"},{"lineNumber":618,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":619,"author":{"gitId":"-"},"content":" inputMcqDetails(questionNum, questionDetails);"},{"lineNumber":620,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":621,"author":{"gitId":"-"},"content":" }"},{"lineNumber":622,"author":{"gitId":"-"},"content":""},{"lineNumber":623,"author":{"gitId":"-"},"content":" public void verifyMsqQuestionDetails(int questionNum, FeedbackMsqQuestionDetails questionDetails) {"},{"lineNumber":624,"author":{"gitId":"-"},"content":" verifyMaxOptions(questionNum, questionDetails.getMaxSelectableChoices());"},{"lineNumber":625,"author":{"gitId":"-"},"content":" verifyMinOptions(questionNum, questionDetails.getMinSelectableChoices());"},{"lineNumber":626,"author":{"gitId":"-"},"content":" if (verifyGeneratedOptions(questionNum, questionDetails.getGenerateOptionsFor())) {"},{"lineNumber":627,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":628,"author":{"gitId":"-"},"content":" }"},{"lineNumber":629,"author":{"gitId":"-"},"content":" verifyOptions(questionNum, questionDetails.getMsqChoices());"},{"lineNumber":630,"author":{"gitId":"-"},"content":" verifyOptionWeights(questionNum, questionDetails.isHasAssignedWeights(), questionDetails.getMsqWeights());"},{"lineNumber":631,"author":{"gitId":"-"},"content":" verifyOtherOption(questionNum, questionDetails.isOtherEnabled(), questionDetails.getMsqOtherWeight());"},{"lineNumber":632,"author":{"gitId":"-"},"content":" }"},{"lineNumber":633,"author":{"gitId":"-"},"content":""},{"lineNumber":634,"author":{"gitId":"-"},"content":" public void addMsqQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":635,"author":{"gitId":"-"},"content":" addNewQuestion(4);"},{"lineNumber":636,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":637,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":638,"author":{"gitId":"-"},"content":" FeedbackMsqQuestionDetails questionDetails \u003d (FeedbackMsqQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":639,"author":{"gitId":"-"},"content":" inputMsqDetails(questionNum, questionDetails);"},{"lineNumber":640,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":641,"author":{"gitId":"-"},"content":" }"},{"lineNumber":642,"author":{"gitId":"-"},"content":""},{"lineNumber":643,"author":{"gitId":"dishenggg"},"content":" public void addMsqQuestion(FeedbackQuestion feedbackQuestion) {"},{"lineNumber":644,"author":{"gitId":"dishenggg"},"content":" addNewQuestion(4);"},{"lineNumber":645,"author":{"gitId":"dishenggg"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":646,"author":{"gitId":"dishenggg"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":647,"author":{"gitId":"dishenggg"},"content":" FeedbackMsqQuestionDetails questionDetails \u003d (FeedbackMsqQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":648,"author":{"gitId":"dishenggg"},"content":" inputMsqDetails(questionNum, questionDetails);"},{"lineNumber":649,"author":{"gitId":"dishenggg"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":650,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":651,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":652,"author":{"gitId":"-"},"content":" public void editMsqQuestion(int questionNum, FeedbackMsqQuestionDetails msqQuestionDetails) {"},{"lineNumber":653,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":654,"author":{"gitId":"-"},"content":" inputMsqDetails(questionNum, msqQuestionDetails);"},{"lineNumber":655,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":656,"author":{"gitId":"-"},"content":" }"},{"lineNumber":657,"author":{"gitId":"-"},"content":""},{"lineNumber":658,"author":{"gitId":"-"},"content":" public void verifyNumScaleQuestionDetails(int questionNum, FeedbackNumericalScaleQuestionDetails questionDetails) {"},{"lineNumber":659,"author":{"gitId":"-"},"content":" assertEquals(getMinNumscaleInput(questionNum).getAttribute(\"value\"),"},{"lineNumber":660,"author":{"gitId":"-"},"content":" Integer.toString(questionDetails.getMinScale()));"},{"lineNumber":661,"author":{"gitId":"-"},"content":" assertEquals(getNumScaleIncrementInput(questionNum).getAttribute(\"value\"),"},{"lineNumber":662,"author":{"gitId":"-"},"content":" getDoubleString(questionDetails.getStep()));"},{"lineNumber":663,"author":{"gitId":"-"},"content":" assertEquals(getMaxNumscaleInput(questionNum).getAttribute(\"value\"),"},{"lineNumber":664,"author":{"gitId":"-"},"content":" Integer.toString(questionDetails.getMaxScale()));"},{"lineNumber":665,"author":{"gitId":"-"},"content":" }"},{"lineNumber":666,"author":{"gitId":"-"},"content":""},{"lineNumber":667,"author":{"gitId":"-"},"content":" public void addNumScaleQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":668,"author":{"gitId":"-"},"content":" addNewQuestion(5);"},{"lineNumber":669,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":670,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":671,"author":{"gitId":"-"},"content":" FeedbackNumericalScaleQuestionDetails questionDetails \u003d"},{"lineNumber":672,"author":{"gitId":"-"},"content":" (FeedbackNumericalScaleQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":673,"author":{"gitId":"-"},"content":" inputNumScaleDetails(questionNum, questionDetails);"},{"lineNumber":674,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":675,"author":{"gitId":"-"},"content":" }"},{"lineNumber":676,"author":{"gitId":"-"},"content":""},{"lineNumber":677,"author":{"gitId":"marquestye"},"content":" public void addNumScaleQuestion(FeedbackQuestion feedbackQuestion) {"},{"lineNumber":678,"author":{"gitId":"marquestye"},"content":" addNewQuestion(5);"},{"lineNumber":679,"author":{"gitId":"marquestye"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":680,"author":{"gitId":"marquestye"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":681,"author":{"gitId":"marquestye"},"content":" FeedbackNumericalScaleQuestionDetails questionDetails \u003d"},{"lineNumber":682,"author":{"gitId":"-"},"content":" (FeedbackNumericalScaleQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":683,"author":{"gitId":"-"},"content":" inputNumScaleDetails(questionNum, questionDetails);"},{"lineNumber":684,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":685,"author":{"gitId":"-"},"content":" }"},{"lineNumber":686,"author":{"gitId":"-"},"content":""},{"lineNumber":687,"author":{"gitId":"-"},"content":" public void editNumScaleQuestion(int questionNum, FeedbackNumericalScaleQuestionDetails questionDetails) {"},{"lineNumber":688,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":689,"author":{"gitId":"-"},"content":" inputNumScaleDetails(questionNum, questionDetails);"},{"lineNumber":690,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":691,"author":{"gitId":"-"},"content":" }"},{"lineNumber":692,"author":{"gitId":"-"},"content":""},{"lineNumber":693,"author":{"gitId":"-"},"content":" public void verifyConstSumQuestionDetails(int questionNum, FeedbackConstantSumQuestionDetails questionDetails) {"},{"lineNumber":694,"author":{"gitId":"-"},"content":" if (!questionDetails.isDistributeToRecipients()) {"},{"lineNumber":695,"author":{"gitId":"-"},"content":" verifyOptions(questionNum, questionDetails.getConstSumOptions());"},{"lineNumber":696,"author":{"gitId":"-"},"content":" }"},{"lineNumber":697,"author":{"gitId":"-"},"content":""},{"lineNumber":698,"author":{"gitId":"-"},"content":" if (questionDetails.isPointsPerOption()) {"},{"lineNumber":699,"author":{"gitId":"-"},"content":" assertTrue(getConstSumPerOptionPointsRadioBtn(questionNum).isSelected());"},{"lineNumber":700,"author":{"gitId":"-"},"content":" assertEquals(getConstSumPerOptionPointsInput(questionNum).getAttribute(\"value\"),"},{"lineNumber":701,"author":{"gitId":"-"},"content":" Integer.toString(questionDetails.getPoints()));"},{"lineNumber":702,"author":{"gitId":"-"},"content":" assertFalse(getConstSumTotalPointsRadioBtn(questionNum).isSelected());"},{"lineNumber":703,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":704,"author":{"gitId":"-"},"content":" assertTrue(getConstSumTotalPointsRadioBtn(questionNum).isSelected());"},{"lineNumber":705,"author":{"gitId":"-"},"content":" assertEquals(getConstSumTotalPointsInput(questionNum).getAttribute(\"value\"),"},{"lineNumber":706,"author":{"gitId":"-"},"content":" Integer.toString(questionDetails.getPoints()));"},{"lineNumber":707,"author":{"gitId":"-"},"content":" assertFalse(getConstSumPerOptionPointsRadioBtn(questionNum).isSelected());"},{"lineNumber":708,"author":{"gitId":"-"},"content":" }"},{"lineNumber":709,"author":{"gitId":"-"},"content":""},{"lineNumber":710,"author":{"gitId":"-"},"content":" if (questionDetails.isForceUnevenDistribution()) {"},{"lineNumber":711,"author":{"gitId":"-"},"content":" String distributeFor \u003d questionDetails.getDistributePointsFor();"},{"lineNumber":712,"author":{"gitId":"-"},"content":" assertTrue(getConstSumUnevenDistributionCheckbox(questionNum).isSelected());"},{"lineNumber":713,"author":{"gitId":"-"},"content":" assertEquals(getSelectedDropdownOptionText(getConstSumUnevenDistributionDropdown(questionNum)).trim(),"},{"lineNumber":714,"author":{"gitId":"-"},"content":" \"All options\".equals(distributeFor) ? \"Every option\" : distributeFor);"},{"lineNumber":715,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":716,"author":{"gitId":"-"},"content":" assertFalse(getConstSumUnevenDistributionCheckbox(questionNum).isSelected());"},{"lineNumber":717,"author":{"gitId":"-"},"content":" }"},{"lineNumber":718,"author":{"gitId":"-"},"content":" }"},{"lineNumber":719,"author":{"gitId":"-"},"content":""},{"lineNumber":720,"author":{"gitId":"-"},"content":" public void addConstSumOptionQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":721,"author":{"gitId":"-"},"content":" addNewQuestion(6);"},{"lineNumber":722,"author":{"gitId":"-"},"content":" addConstSumQuestion(feedbackQuestion);"},{"lineNumber":723,"author":{"gitId":"-"},"content":" }"},{"lineNumber":724,"author":{"gitId":"-"},"content":""},{"lineNumber":725,"author":{"gitId":"-"},"content":" public void addConstSumRecipientQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":726,"author":{"gitId":"-"},"content":" addNewQuestion(7);"},{"lineNumber":727,"author":{"gitId":"-"},"content":" addConstSumQuestion(feedbackQuestion);"},{"lineNumber":728,"author":{"gitId":"-"},"content":" }"},{"lineNumber":729,"author":{"gitId":"-"},"content":""},{"lineNumber":730,"author":{"gitId":"-"},"content":" public void addConstSumQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":731,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":732,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":733,"author":{"gitId":"-"},"content":" FeedbackConstantSumQuestionDetails questionDetails \u003d"},{"lineNumber":734,"author":{"gitId":"-"},"content":" (FeedbackConstantSumQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":735,"author":{"gitId":"-"},"content":" inputConstSumDetails(questionNum, questionDetails);"},{"lineNumber":736,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":737,"author":{"gitId":"-"},"content":" }"},{"lineNumber":738,"author":{"gitId":"-"},"content":""},{"lineNumber":739,"author":{"gitId":"-"},"content":" public void editConstSumQuestion(int questionNum, FeedbackConstantSumQuestionDetails csQuestionDetails) {"},{"lineNumber":740,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":741,"author":{"gitId":"-"},"content":" inputConstSumDetails(questionNum, csQuestionDetails);"},{"lineNumber":742,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":743,"author":{"gitId":"-"},"content":" }"},{"lineNumber":744,"author":{"gitId":"-"},"content":""},{"lineNumber":745,"author":{"gitId":"-"},"content":" public void verifyContributionQuestionDetails(int questionNum, FeedbackContributionQuestionDetails questionDetails) {"},{"lineNumber":746,"author":{"gitId":"-"},"content":" assertEquals(questionDetails.isZeroSum(), getZeroSumCheckbox(questionNum).isSelected());"},{"lineNumber":747,"author":{"gitId":"-"},"content":" assertEquals(questionDetails.isNotSureAllowed(), getAllowNotSureContributionCheckbox(questionNum).isSelected());"},{"lineNumber":748,"author":{"gitId":"-"},"content":" if (questionDetails.isZeroSum()) {"},{"lineNumber":749,"author":{"gitId":"-"},"content":" assertFalse(questionDetails.isNotSureAllowed());"},{"lineNumber":750,"author":{"gitId":"-"},"content":" }"},{"lineNumber":751,"author":{"gitId":"-"},"content":" }"},{"lineNumber":752,"author":{"gitId":"-"},"content":""},{"lineNumber":753,"author":{"gitId":"-"},"content":" public void addContributionQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":754,"author":{"gitId":"-"},"content":" addNewQuestion(8);"},{"lineNumber":755,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":756,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":757,"author":{"gitId":"-"},"content":" FeedbackContributionQuestionDetails questionDetails \u003d"},{"lineNumber":758,"author":{"gitId":"-"},"content":" (FeedbackContributionQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":759,"author":{"gitId":"-"},"content":" inputContributionDetails(questionNum, questionDetails);"},{"lineNumber":760,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":761,"author":{"gitId":"-"},"content":" }"},{"lineNumber":762,"author":{"gitId":"-"},"content":""},{"lineNumber":763,"author":{"gitId":"-"},"content":" public void editContributionQuestion(int questionNum, FeedbackContributionQuestionDetails questionDetails) {"},{"lineNumber":764,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":765,"author":{"gitId":"-"},"content":" inputContributionDetails(questionNum, questionDetails);"},{"lineNumber":766,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":767,"author":{"gitId":"-"},"content":" }"},{"lineNumber":768,"author":{"gitId":"-"},"content":""},{"lineNumber":769,"author":{"gitId":"-"},"content":" public void verifyRubricQuestionDetails(int questionNum, FeedbackRubricQuestionDetails questionDetails) {"},{"lineNumber":770,"author":{"gitId":"-"},"content":" int numChoices \u003d questionDetails.getNumOfRubricChoices();"},{"lineNumber":771,"author":{"gitId":"-"},"content":" List\u003cString\u003e choices \u003d questionDetails.getRubricChoices();"},{"lineNumber":772,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c numChoices; i++) {"},{"lineNumber":773,"author":{"gitId":"-"},"content":" assertEquals(choices.get(i), getRubricChoiceInputs(questionNum).get(i).getAttribute(\"value\"));"},{"lineNumber":774,"author":{"gitId":"-"},"content":" }"},{"lineNumber":775,"author":{"gitId":"-"},"content":""},{"lineNumber":776,"author":{"gitId":"-"},"content":" int numSubQn \u003d questionDetails.getNumOfRubricSubQuestions();"},{"lineNumber":777,"author":{"gitId":"-"},"content":" List\u003cString\u003e subQuestions \u003d questionDetails.getRubricSubQuestions();"},{"lineNumber":778,"author":{"gitId":"-"},"content":" List\u003cList\u003cString\u003e\u003e descriptions \u003d questionDetails.getRubricDescriptions();"},{"lineNumber":779,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c numSubQn; i++) {"},{"lineNumber":780,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e textAreas \u003d getRubricTextareas(questionNum, i + 2);"},{"lineNumber":781,"author":{"gitId":"-"},"content":" assertEquals(subQuestions.get(i), textAreas.get(0).getAttribute(\"value\"));"},{"lineNumber":782,"author":{"gitId":"-"},"content":" for (int j \u003d 0; j \u003c numChoices; j++) {"},{"lineNumber":783,"author":{"gitId":"-"},"content":" assertEquals(descriptions.get(i).get(j), textAreas.get(j + 1).getAttribute(\"value\"));"},{"lineNumber":784,"author":{"gitId":"-"},"content":" }"},{"lineNumber":785,"author":{"gitId":"-"},"content":" }"},{"lineNumber":786,"author":{"gitId":"-"},"content":""},{"lineNumber":787,"author":{"gitId":"-"},"content":" if (questionDetails.isHasAssignedWeights()) {"},{"lineNumber":788,"author":{"gitId":"-"},"content":" assertTrue(getWeightCheckbox(questionNum).isSelected());"},{"lineNumber":789,"author":{"gitId":"-"},"content":" List\u003cList\u003cDouble\u003e\u003e weights \u003d questionDetails.getRubricWeights();"},{"lineNumber":790,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c numSubQn; i++) {"},{"lineNumber":791,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rubricWeights \u003d getRubricWeights(questionNum, i + 2);"},{"lineNumber":792,"author":{"gitId":"-"},"content":" for (int j \u003d 0; j \u003c numChoices; j++) {"},{"lineNumber":793,"author":{"gitId":"-"},"content":" assertEquals(getDoubleString(weights.get(i).get(j)),"},{"lineNumber":794,"author":{"gitId":"-"},"content":" rubricWeights.get(j).getAttribute(\"value\"));"},{"lineNumber":795,"author":{"gitId":"-"},"content":" }"},{"lineNumber":796,"author":{"gitId":"-"},"content":" }"},{"lineNumber":797,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":798,"author":{"gitId":"-"},"content":" assertFalse(getWeightCheckbox(questionNum).isSelected());"},{"lineNumber":799,"author":{"gitId":"-"},"content":" }"},{"lineNumber":800,"author":{"gitId":"-"},"content":" }"},{"lineNumber":801,"author":{"gitId":"-"},"content":""},{"lineNumber":802,"author":{"gitId":"-"},"content":" public void addRubricQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":803,"author":{"gitId":"-"},"content":" addNewQuestion(9);"},{"lineNumber":804,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":805,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":806,"author":{"gitId":"-"},"content":" FeedbackRubricQuestionDetails questionDetails \u003d"},{"lineNumber":807,"author":{"gitId":"-"},"content":" (FeedbackRubricQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":808,"author":{"gitId":"-"},"content":" inputRubricDetails(questionNum, questionDetails);"},{"lineNumber":809,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":810,"author":{"gitId":"-"},"content":" }"},{"lineNumber":811,"author":{"gitId":"-"},"content":""},{"lineNumber":812,"author":{"gitId":"-"},"content":" public void editRubricQuestion(int questionNum, FeedbackRubricQuestionDetails questionDetails) {"},{"lineNumber":813,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":814,"author":{"gitId":"-"},"content":" inputRubricDetails(questionNum, questionDetails);"},{"lineNumber":815,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":816,"author":{"gitId":"-"},"content":" }"},{"lineNumber":817,"author":{"gitId":"-"},"content":""},{"lineNumber":818,"author":{"gitId":"-"},"content":" public void verifyRankQuestionDetails(int questionNum, FeedbackRankQuestionDetails questionDetails) {"},{"lineNumber":819,"author":{"gitId":"-"},"content":" if (questionDetails instanceof FeedbackRankOptionsQuestionDetails) {"},{"lineNumber":820,"author":{"gitId":"-"},"content":" FeedbackRankOptionsQuestionDetails optionDetails \u003d (FeedbackRankOptionsQuestionDetails) questionDetails;"},{"lineNumber":821,"author":{"gitId":"-"},"content":" verifyOptions(questionNum, optionDetails.getOptions());"},{"lineNumber":822,"author":{"gitId":"-"},"content":" }"},{"lineNumber":823,"author":{"gitId":"-"},"content":" assertEquals(getAllowDuplicateRankCheckbox(questionNum).isSelected(), questionDetails.isAreDuplicatesAllowed());"},{"lineNumber":824,"author":{"gitId":"-"},"content":" verifyMaxOptions(questionNum, questionDetails.getMaxOptionsToBeRanked());"},{"lineNumber":825,"author":{"gitId":"-"},"content":" verifyMinOptions(questionNum, questionDetails.getMinOptionsToBeRanked());"},{"lineNumber":826,"author":{"gitId":"-"},"content":" }"},{"lineNumber":827,"author":{"gitId":"-"},"content":""},{"lineNumber":828,"author":{"gitId":"-"},"content":" public void addRankOptionsQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":829,"author":{"gitId":"-"},"content":" addNewQuestion(10);"},{"lineNumber":830,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":831,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":832,"author":{"gitId":"-"},"content":" FeedbackRankOptionsQuestionDetails questionDetails \u003d"},{"lineNumber":833,"author":{"gitId":"-"},"content":" (FeedbackRankOptionsQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":834,"author":{"gitId":"-"},"content":" inputRankDetails(questionNum, questionDetails);"},{"lineNumber":835,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":836,"author":{"gitId":"-"},"content":" }"},{"lineNumber":837,"author":{"gitId":"-"},"content":""},{"lineNumber":838,"author":{"gitId":"mingyuanc"},"content":" public void addRankOptionsQuestion(FeedbackQuestion feedbackQuestion) {"},{"lineNumber":839,"author":{"gitId":"mingyuanc"},"content":" addNewQuestion(10);"},{"lineNumber":840,"author":{"gitId":"mingyuanc"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":841,"author":{"gitId":"mingyuanc"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":842,"author":{"gitId":"mingyuanc"},"content":" FeedbackRankOptionsQuestionDetails questionDetails \u003d"},{"lineNumber":843,"author":{"gitId":"-"},"content":" (FeedbackRankOptionsQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":844,"author":{"gitId":"-"},"content":" inputRankDetails(questionNum, questionDetails);"},{"lineNumber":845,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":846,"author":{"gitId":"-"},"content":" }"},{"lineNumber":847,"author":{"gitId":"-"},"content":""},{"lineNumber":848,"author":{"gitId":"-"},"content":" public void addRankRecipientsQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":849,"author":{"gitId":"-"},"content":" addNewQuestion(11);"},{"lineNumber":850,"author":{"gitId":"-"},"content":" int questionNum \u003d getNumQuestions();"},{"lineNumber":851,"author":{"gitId":"-"},"content":" inputQuestionDetails(questionNum, feedbackQuestion);"},{"lineNumber":852,"author":{"gitId":"-"},"content":" FeedbackRankQuestionDetails questionDetails \u003d"},{"lineNumber":853,"author":{"gitId":"-"},"content":" (FeedbackRankQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":854,"author":{"gitId":"-"},"content":" inputRankDetails(questionNum, questionDetails);"},{"lineNumber":855,"author":{"gitId":"-"},"content":" clickSaveNewQuestionButton();"},{"lineNumber":856,"author":{"gitId":"-"},"content":" }"},{"lineNumber":857,"author":{"gitId":"-"},"content":""},{"lineNumber":858,"author":{"gitId":"-"},"content":" public void editRankQuestion(int questionNum, FeedbackRankQuestionDetails questionDetails) {"},{"lineNumber":859,"author":{"gitId":"-"},"content":" clickEditQuestionButton(questionNum);"},{"lineNumber":860,"author":{"gitId":"-"},"content":" inputRankDetails(questionNum, questionDetails);"},{"lineNumber":861,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":862,"author":{"gitId":"-"},"content":" }"},{"lineNumber":863,"author":{"gitId":"-"},"content":""},{"lineNumber":864,"author":{"gitId":"-"},"content":" private String getCourseId() {"},{"lineNumber":865,"author":{"gitId":"-"},"content":" return courseIdTextBox.getText();"},{"lineNumber":866,"author":{"gitId":"-"},"content":" }"},{"lineNumber":867,"author":{"gitId":"-"},"content":""},{"lineNumber":868,"author":{"gitId":"-"},"content":" private String getCourseName() {"},{"lineNumber":869,"author":{"gitId":"-"},"content":" return courseNameTextBox.getText();"},{"lineNumber":870,"author":{"gitId":"-"},"content":" }"},{"lineNumber":871,"author":{"gitId":"-"},"content":""},{"lineNumber":872,"author":{"gitId":"-"},"content":" private String getTimeZone() {"},{"lineNumber":873,"author":{"gitId":"-"},"content":" return timezoneDropDown.getText();"},{"lineNumber":874,"author":{"gitId":"-"},"content":" }"},{"lineNumber":875,"author":{"gitId":"-"},"content":""},{"lineNumber":876,"author":{"gitId":"-"},"content":" private String getFeedbackSessionName() {"},{"lineNumber":877,"author":{"gitId":"-"},"content":" return sessionNameTextBox.getText();"},{"lineNumber":878,"author":{"gitId":"-"},"content":" }"},{"lineNumber":879,"author":{"gitId":"-"},"content":""},{"lineNumber":880,"author":{"gitId":"-"},"content":" private String getInstructions() {"},{"lineNumber":881,"author":{"gitId":"-"},"content":" return getEditorRichText(instructionsEditor.findElement(By.tagName(\"editor\")));"},{"lineNumber":882,"author":{"gitId":"-"},"content":" }"},{"lineNumber":883,"author":{"gitId":"-"},"content":""},{"lineNumber":884,"author":{"gitId":"-"},"content":" private String getStartDate() {"},{"lineNumber":885,"author":{"gitId":"-"},"content":" return startDateBox.findElement(By.tagName(\"input\")).getAttribute(\"value\");"},{"lineNumber":886,"author":{"gitId":"-"},"content":" }"},{"lineNumber":887,"author":{"gitId":"-"},"content":""},{"lineNumber":888,"author":{"gitId":"-"},"content":" private String getStartTime() {"},{"lineNumber":889,"author":{"gitId":"-"},"content":" return getSelectedDropdownOptionText(startTimeDropdown.findElement(By.tagName(\"select\")));"},{"lineNumber":890,"author":{"gitId":"-"},"content":" }"},{"lineNumber":891,"author":{"gitId":"-"},"content":""},{"lineNumber":892,"author":{"gitId":"-"},"content":" private String getEndDate() {"},{"lineNumber":893,"author":{"gitId":"-"},"content":" return endDateBox.findElement(By.tagName(\"input\")).getAttribute(\"value\");"},{"lineNumber":894,"author":{"gitId":"-"},"content":" }"},{"lineNumber":895,"author":{"gitId":"-"},"content":""},{"lineNumber":896,"author":{"gitId":"-"},"content":" private String getEndTime() {"},{"lineNumber":897,"author":{"gitId":"-"},"content":" return getSelectedDropdownOptionText(endTimeDropdown.findElement(By.tagName(\"select\")));"},{"lineNumber":898,"author":{"gitId":"-"},"content":" }"},{"lineNumber":899,"author":{"gitId":"-"},"content":""},{"lineNumber":900,"author":{"gitId":"-"},"content":" private String getSessionVisibilityDate() {"},{"lineNumber":901,"author":{"gitId":"-"},"content":" return sessionVisibilityDateBox.findElement(By.tagName(\"input\")).getAttribute(\"value\");"},{"lineNumber":902,"author":{"gitId":"-"},"content":" }"},{"lineNumber":903,"author":{"gitId":"-"},"content":""},{"lineNumber":904,"author":{"gitId":"-"},"content":" private String getSessionVisibilityTime() {"},{"lineNumber":905,"author":{"gitId":"-"},"content":" return getSelectedDropdownOptionText(sessionVisibilityTimeDropdown.findElement(By.tagName(\"select\")));"},{"lineNumber":906,"author":{"gitId":"-"},"content":" }"},{"lineNumber":907,"author":{"gitId":"-"},"content":""},{"lineNumber":908,"author":{"gitId":"-"},"content":" private String getResponseVisibilityDate() {"},{"lineNumber":909,"author":{"gitId":"-"},"content":" return responseVisibilityDateBox.findElement(By.tagName(\"input\"))"},{"lineNumber":910,"author":{"gitId":"-"},"content":" .getAttribute(\"value\");"},{"lineNumber":911,"author":{"gitId":"-"},"content":" }"},{"lineNumber":912,"author":{"gitId":"-"},"content":""},{"lineNumber":913,"author":{"gitId":"-"},"content":" private String getResponseVisibilityTime() {"},{"lineNumber":914,"author":{"gitId":"-"},"content":" return getSelectedDropdownOptionText(responseVisibilityTimeDropdown.findElement(By.tagName(\"select\")));"},{"lineNumber":915,"author":{"gitId":"-"},"content":" }"},{"lineNumber":916,"author":{"gitId":"-"},"content":""},{"lineNumber":917,"author":{"gitId":"-"},"content":" private String getGracePeriod() {"},{"lineNumber":918,"author":{"gitId":"-"},"content":" return getSelectedDropdownOptionText(gracePeriodDropdown);"},{"lineNumber":919,"author":{"gitId":"-"},"content":" }"},{"lineNumber":920,"author":{"gitId":"-"},"content":""},{"lineNumber":921,"author":{"gitId":"-"},"content":" private String getSubmissionStatus() {"},{"lineNumber":922,"author":{"gitId":"-"},"content":" return submissionStatusTextBox.getText();"},{"lineNumber":923,"author":{"gitId":"-"},"content":" }"},{"lineNumber":924,"author":{"gitId":"-"},"content":""},{"lineNumber":925,"author":{"gitId":"-"},"content":" private String getPublishedStatus() {"},{"lineNumber":926,"author":{"gitId":"-"},"content":" return publishStatusTextBox.getText();"},{"lineNumber":927,"author":{"gitId":"-"},"content":" }"},{"lineNumber":928,"author":{"gitId":"-"},"content":""},{"lineNumber":929,"author":{"gitId":"-"},"content":" private String getDateString(Instant instant, String timeZone) {"},{"lineNumber":930,"author":{"gitId":"-"},"content":" return getDisplayedDateTime(instant, timeZone, \"EE, dd MMM, yyyy\");"},{"lineNumber":931,"author":{"gitId":"-"},"content":" }"},{"lineNumber":932,"author":{"gitId":"-"},"content":""},{"lineNumber":933,"author":{"gitId":"-"},"content":" private String getTimeString(Instant instant, String timeZone) {"},{"lineNumber":934,"author":{"gitId":"-"},"content":" ZonedDateTime dateTime \u003d instant.atZone(ZoneId.of(timeZone));"},{"lineNumber":935,"author":{"gitId":"-"},"content":" if (dateTime.getHour() \u003d\u003d 0 \u0026\u0026 dateTime.getMinute() \u003d\u003d 0) {"},{"lineNumber":936,"author":{"gitId":"-"},"content":" return \"23:59H\";"},{"lineNumber":937,"author":{"gitId":"-"},"content":" }"},{"lineNumber":938,"author":{"gitId":"-"},"content":" return getDisplayedDateTime(instant, timeZone, \"HH:00\") + \"H\";"},{"lineNumber":939,"author":{"gitId":"-"},"content":" }"},{"lineNumber":940,"author":{"gitId":"-"},"content":""},{"lineNumber":941,"author":{"gitId":"-"},"content":" private void setInstructions(String newInstructions) {"},{"lineNumber":942,"author":{"gitId":"-"},"content":" writeToRichTextEditor(instructionsEditor.findElement(By.tagName(\"editor\")), newInstructions);"},{"lineNumber":943,"author":{"gitId":"-"},"content":" }"},{"lineNumber":944,"author":{"gitId":"-"},"content":""},{"lineNumber":945,"author":{"gitId":"-"},"content":" private void setSessionStartDateTime(Instant startInstant, String timeZone) {"},{"lineNumber":946,"author":{"gitId":"-"},"content":" setDateTime(startDateBox, startTimeDropdown, startInstant, timeZone);"},{"lineNumber":947,"author":{"gitId":"-"},"content":" }"},{"lineNumber":948,"author":{"gitId":"-"},"content":""},{"lineNumber":949,"author":{"gitId":"-"},"content":" private void setSessionEndDateTime(Instant endInstant, String timeZone) {"},{"lineNumber":950,"author":{"gitId":"-"},"content":" setDateTime(endDateBox, endTimeDropdown, endInstant, timeZone);"},{"lineNumber":951,"author":{"gitId":"-"},"content":" }"},{"lineNumber":952,"author":{"gitId":"-"},"content":""},{"lineNumber":953,"author":{"gitId":"-"},"content":" private void setVisibilityDateTime(Instant startInstant, String timeZone) {"},{"lineNumber":954,"author":{"gitId":"-"},"content":" setDateTime(sessionVisibilityDateBox, sessionVisibilityTimeDropdown, startInstant, timeZone);"},{"lineNumber":955,"author":{"gitId":"-"},"content":" }"},{"lineNumber":956,"author":{"gitId":"-"},"content":""},{"lineNumber":957,"author":{"gitId":"-"},"content":" private void setResponseDateTime(Instant endInstant, String timeZone) {"},{"lineNumber":958,"author":{"gitId":"-"},"content":" setDateTime(responseVisibilityDateBox, responseVisibilityTimeDropdown, endInstant, timeZone);"},{"lineNumber":959,"author":{"gitId":"-"},"content":" }"},{"lineNumber":960,"author":{"gitId":"-"},"content":""},{"lineNumber":961,"author":{"gitId":"-"},"content":" private void setDateTime(WebElement dateBox, WebElement timeBox, Instant startInstant, String timeZone) {"},{"lineNumber":962,"author":{"gitId":"-"},"content":" fillDatePicker(dateBox, startInstant, timeZone);"},{"lineNumber":963,"author":{"gitId":"-"},"content":""},{"lineNumber":964,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(timeBox.findElement(By.tagName(\"select\")), getTimeString(startInstant, timeZone));"},{"lineNumber":965,"author":{"gitId":"-"},"content":" }"},{"lineNumber":966,"author":{"gitId":"-"},"content":""},{"lineNumber":967,"author":{"gitId":"-"},"content":" private void selectGracePeriod(long gracePeriodMinutes) {"},{"lineNumber":968,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(gracePeriodDropdown, gracePeriodMinutes + \" min\");"},{"lineNumber":969,"author":{"gitId":"-"},"content":" }"},{"lineNumber":970,"author":{"gitId":"-"},"content":""},{"lineNumber":971,"author":{"gitId":"-"},"content":" private void setVisibilitySettings(FeedbackSessionAttributes newFeedbackSession) {"},{"lineNumber":972,"author":{"gitId":"-"},"content":" showVisibilitySettings();"},{"lineNumber":973,"author":{"gitId":"-"},"content":""},{"lineNumber":974,"author":{"gitId":"-"},"content":" setSessionVisibilitySettings(newFeedbackSession);"},{"lineNumber":975,"author":{"gitId":"-"},"content":" setResponseVisibilitySettings(newFeedbackSession);"},{"lineNumber":976,"author":{"gitId":"-"},"content":" }"},{"lineNumber":977,"author":{"gitId":"-"},"content":""},{"lineNumber":978,"author":{"gitId":"-"},"content":" private void setSessionVisibilitySettings(FeedbackSessionAttributes newFeedbackSession) {"},{"lineNumber":979,"author":{"gitId":"-"},"content":" Instant sessionDateTime \u003d newFeedbackSession.getSessionVisibleFromTime();"},{"lineNumber":980,"author":{"gitId":"-"},"content":" if (sessionDateTime.equals(Const.TIME_REPRESENTS_FOLLOW_OPENING)) {"},{"lineNumber":981,"author":{"gitId":"-"},"content":" click(openSessionVisibleTimeButton);"},{"lineNumber":982,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":983,"author":{"gitId":"-"},"content":" click(customSessionVisibleTimeButton);"},{"lineNumber":984,"author":{"gitId":"-"},"content":" setVisibilityDateTime(sessionDateTime, newFeedbackSession.getTimeZone());"},{"lineNumber":985,"author":{"gitId":"-"},"content":" }"},{"lineNumber":986,"author":{"gitId":"-"},"content":" }"},{"lineNumber":987,"author":{"gitId":"-"},"content":""},{"lineNumber":988,"author":{"gitId":"-"},"content":" private void setResponseVisibilitySettings(FeedbackSessionAttributes newFeedbackSession) {"},{"lineNumber":989,"author":{"gitId":"-"},"content":" Instant responseDateTime \u003d newFeedbackSession.getResultsVisibleFromTime();"},{"lineNumber":990,"author":{"gitId":"-"},"content":" if (responseDateTime.equals(Const.TIME_REPRESENTS_FOLLOW_VISIBLE)) {"},{"lineNumber":991,"author":{"gitId":"-"},"content":" click(immediateResponseVisibleTimeButton);"},{"lineNumber":992,"author":{"gitId":"-"},"content":" } else if (responseDateTime.equals(Const.TIME_REPRESENTS_LATER)) {"},{"lineNumber":993,"author":{"gitId":"-"},"content":" click(manualResponseVisibleTimeButton);"},{"lineNumber":994,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":995,"author":{"gitId":"-"},"content":" click(customResponseVisibleTimeButton);"},{"lineNumber":996,"author":{"gitId":"-"},"content":" setResponseDateTime(responseDateTime, newFeedbackSession.getTimeZone());"},{"lineNumber":997,"author":{"gitId":"-"},"content":" }"},{"lineNumber":998,"author":{"gitId":"-"},"content":" }"},{"lineNumber":999,"author":{"gitId":"-"},"content":""},{"lineNumber":1000,"author":{"gitId":"-"},"content":" private void setEmailSettings(FeedbackSessionAttributes newFeedbackSessionDetails) {"},{"lineNumber":1001,"author":{"gitId":"-"},"content":" showEmailSettings();"},{"lineNumber":1002,"author":{"gitId":"-"},"content":" if (newFeedbackSessionDetails.isOpeningEmailEnabled() !\u003d openingSessionEmailCheckbox.isSelected()) {"},{"lineNumber":1003,"author":{"gitId":"-"},"content":" click(openingSessionEmailCheckbox);"},{"lineNumber":1004,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1005,"author":{"gitId":"-"},"content":" if (newFeedbackSessionDetails.isClosingEmailEnabled() !\u003d closingSessionEmailCheckbox.isSelected()) {"},{"lineNumber":1006,"author":{"gitId":"-"},"content":" click(closingSessionEmailCheckbox);"},{"lineNumber":1007,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1008,"author":{"gitId":"-"},"content":" if (newFeedbackSessionDetails.isPublishedEmailEnabled() !\u003d publishedSessionEmailCheckbox.isSelected()) {"},{"lineNumber":1009,"author":{"gitId":"-"},"content":" click(publishedSessionEmailCheckbox);"},{"lineNumber":1010,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1011,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1012,"author":{"gitId":"-"},"content":""},{"lineNumber":1013,"author":{"gitId":"-"},"content":" private void showVisibilitySettings() {"},{"lineNumber":1014,"author":{"gitId":"-"},"content":" if (isElementPresent(By.id(\"btn-change-visibility\"))) {"},{"lineNumber":1015,"author":{"gitId":"-"},"content":" click(changeVisibilityButton);"},{"lineNumber":1016,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1017,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1018,"author":{"gitId":"-"},"content":""},{"lineNumber":1019,"author":{"gitId":"-"},"content":" private void showEmailSettings() {"},{"lineNumber":1020,"author":{"gitId":"-"},"content":" if (isElementPresent(By.id(\"btn-change-email\"))) {"},{"lineNumber":1021,"author":{"gitId":"-"},"content":" click(changeEmailButton);"},{"lineNumber":1022,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1023,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1024,"author":{"gitId":"-"},"content":""},{"lineNumber":1025,"author":{"gitId":"-"},"content":" private int getNumQuestions() {"},{"lineNumber":1026,"author":{"gitId":"-"},"content":" return browser.driver.findElements(By.tagName(\"tm-question-edit-form\")).size();"},{"lineNumber":1027,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1028,"author":{"gitId":"-"},"content":""},{"lineNumber":1029,"author":{"gitId":"-"},"content":" private WebElement getQuestionForm(int questionNum) {"},{"lineNumber":1030,"author":{"gitId":"-"},"content":" return browser.driver.findElements(By.tagName(\"tm-question-edit-form\")).get(questionNum - 1);"},{"lineNumber":1031,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1032,"author":{"gitId":"-"},"content":""},{"lineNumber":1033,"author":{"gitId":"-"},"content":" private FeedbackQuestionType getQuestionType(int questionNum) {"},{"lineNumber":1034,"author":{"gitId":"-"},"content":" String questionType \u003d getQuestionForm(questionNum).findElement(By.id(\"question-type\")).getText().trim();"},{"lineNumber":1035,"author":{"gitId":"-"},"content":""},{"lineNumber":1036,"author":{"gitId":"-"},"content":" switch (questionType) {"},{"lineNumber":1037,"author":{"gitId":"-"},"content":" case \"Essay question\":"},{"lineNumber":1038,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.TEXT;"},{"lineNumber":1039,"author":{"gitId":"-"},"content":" case \"Multiple-Choice (single answer) question\":"},{"lineNumber":1040,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.MCQ;"},{"lineNumber":1041,"author":{"gitId":"-"},"content":" case \"Multiple-choice (multiple answers) question\":"},{"lineNumber":1042,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.MSQ;"},{"lineNumber":1043,"author":{"gitId":"-"},"content":" case \"Numerical Scale Question\":"},{"lineNumber":1044,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.NUMSCALE;"},{"lineNumber":1045,"author":{"gitId":"-"},"content":" case \"Distribute points (among options) question\":"},{"lineNumber":1046,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.CONSTSUM_OPTIONS;"},{"lineNumber":1047,"author":{"gitId":"-"},"content":" case \"Distribute points (among recipients) question\":"},{"lineNumber":1048,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.CONSTSUM_RECIPIENTS;"},{"lineNumber":1049,"author":{"gitId":"-"},"content":" case \"Team contribution question\":"},{"lineNumber":1050,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.CONTRIB;"},{"lineNumber":1051,"author":{"gitId":"-"},"content":" case \"Rubric question\":"},{"lineNumber":1052,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.RUBRIC;"},{"lineNumber":1053,"author":{"gitId":"-"},"content":" case \"Rank (options) question\":"},{"lineNumber":1054,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.RANK_OPTIONS;"},{"lineNumber":1055,"author":{"gitId":"-"},"content":" case \"Rank (recipients) question\":"},{"lineNumber":1056,"author":{"gitId":"-"},"content":" return FeedbackQuestionType.RANK_RECIPIENTS;"},{"lineNumber":1057,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":1058,"author":{"gitId":"-"},"content":" throw new IllegalArgumentException(\"Unknown FeedbackQuestionType\");"},{"lineNumber":1059,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1060,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1061,"author":{"gitId":"-"},"content":""},{"lineNumber":1062,"author":{"gitId":"-"},"content":" private int getQuestionNumber(int questionNum) {"},{"lineNumber":1063,"author":{"gitId":"-"},"content":" return Integer.parseInt(getQuestionForm(questionNum).findElement(By.id(\"question-number\")).getText());"},{"lineNumber":1064,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1065,"author":{"gitId":"-"},"content":""},{"lineNumber":1066,"author":{"gitId":"-"},"content":" private String getQuestionBrief(int questionNum) {"},{"lineNumber":1067,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"question-brief\")).getAttribute(\"value\");"},{"lineNumber":1068,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1069,"author":{"gitId":"-"},"content":""},{"lineNumber":1070,"author":{"gitId":"-"},"content":" private String getQuestionDescription(int questionNum) {"},{"lineNumber":1071,"author":{"gitId":"-"},"content":" WebElement editor \u003d waitForElementPresence(By.cssSelector(\"#question-form-\" + questionNum + \" editor\"));"},{"lineNumber":1072,"author":{"gitId":"-"},"content":" return getEditorRichText(editor);"},{"lineNumber":1073,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1074,"author":{"gitId":"-"},"content":""},{"lineNumber":1075,"author":{"gitId":"-"},"content":" private String getFeedbackGiver(int questionNum) {"},{"lineNumber":1076,"author":{"gitId":"-"},"content":" String feedbackPath \u003d getFeedbackPath(questionNum);"},{"lineNumber":1077,"author":{"gitId":"-"},"content":" if (CUSTOM_FEEDBACK_PATH_OPTION.equals(feedbackPath)) {"},{"lineNumber":1078,"author":{"gitId":"-"},"content":" return getSelectedDropdownOptionText(getQuestionForm(questionNum)"},{"lineNumber":1079,"author":{"gitId":"-"},"content":" .findElement(By.tagName(\"tm-feedback-path-panel\"))"},{"lineNumber":1080,"author":{"gitId":"-"},"content":" .findElement(By.id(\"giver-type\")));"},{"lineNumber":1081,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1082,"author":{"gitId":"-"},"content":" return feedbackPath.split(FEEDBACK_PATH_SEPARATOR)[0];"},{"lineNumber":1083,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1084,"author":{"gitId":"-"},"content":""},{"lineNumber":1085,"author":{"gitId":"-"},"content":" private String getFeedbackReceiver(int questionNum) {"},{"lineNumber":1086,"author":{"gitId":"-"},"content":" String feedbackPath \u003d getFeedbackPath(questionNum);"},{"lineNumber":1087,"author":{"gitId":"-"},"content":" if (CUSTOM_FEEDBACK_PATH_OPTION.equals(feedbackPath)) {"},{"lineNumber":1088,"author":{"gitId":"-"},"content":" return getSelectedDropdownOptionText(getQuestionForm(questionNum)"},{"lineNumber":1089,"author":{"gitId":"-"},"content":" .findElement(By.tagName(\"tm-feedback-path-panel\"))"},{"lineNumber":1090,"author":{"gitId":"-"},"content":" .findElement(By.id(\"receiver-type\")));"},{"lineNumber":1091,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1092,"author":{"gitId":"-"},"content":" return feedbackPath.split(FEEDBACK_PATH_SEPARATOR)[1];"},{"lineNumber":1093,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1094,"author":{"gitId":"-"},"content":""},{"lineNumber":1095,"author":{"gitId":"-"},"content":" private String getFeedbackPath(int questionNum) {"},{"lineNumber":1096,"author":{"gitId":"-"},"content":" WebElement feedbackPathPanel \u003d getQuestionForm(questionNum).findElement(By.tagName(\"tm-feedback-path-panel\"));"},{"lineNumber":1097,"author":{"gitId":"-"},"content":" return feedbackPathPanel.findElement(By.cssSelector(\"#btn-feedback-path span\")).getText();"},{"lineNumber":1098,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1099,"author":{"gitId":"-"},"content":""},{"lineNumber":1100,"author":{"gitId":"-"},"content":" private void setQuestionBrief(int questionNum, String newBrief) {"},{"lineNumber":1101,"author":{"gitId":"-"},"content":" fillTextBox(getQuestionForm(questionNum).findElement(By.id(\"question-brief\")), newBrief);"},{"lineNumber":1102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1103,"author":{"gitId":"-"},"content":""},{"lineNumber":1104,"author":{"gitId":"-"},"content":" private void setQuestionDescription(int questionNum, String newDescription) {"},{"lineNumber":1105,"author":{"gitId":"-"},"content":" WebElement editor \u003d waitForElementPresence(By.cssSelector(\"#question-form-\" + questionNum + \" editor\"));"},{"lineNumber":1106,"author":{"gitId":"-"},"content":" writeToRichTextEditor(editor, newDescription);"},{"lineNumber":1107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1108,"author":{"gitId":"-"},"content":""},{"lineNumber":1109,"author":{"gitId":"-"},"content":" private void setFeedbackPath(int questionNum, FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":1110,"author":{"gitId":"-"},"content":" FeedbackParticipantType newGiver \u003d feedbackQuestion.getGiverType();"},{"lineNumber":1111,"author":{"gitId":"-"},"content":" FeedbackParticipantType newRecipient \u003d feedbackQuestion.getRecipientType();"},{"lineNumber":1112,"author":{"gitId":"-"},"content":" String feedbackPath \u003d getFeedbackPath(questionNum);"},{"lineNumber":1113,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(questionNum).findElement(By.tagName(\"tm-feedback-path-panel\"));"},{"lineNumber":1114,"author":{"gitId":"-"},"content":" if (!CUSTOM_FEEDBACK_PATH_OPTION.equals(feedbackPath)) {"},{"lineNumber":1115,"author":{"gitId":"-"},"content":" selectFeedbackPathDropdownOption(questionNum, CUSTOM_FEEDBACK_PATH_OPTION + \"...\");"},{"lineNumber":1116,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1117,"author":{"gitId":"-"},"content":" // Set to type STUDENT first to adjust NumberOfEntitiesToGiveFeedbackTo"},{"lineNumber":1118,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(questionForm.findElement(By.id(\"giver-type\")),"},{"lineNumber":1119,"author":{"gitId":"-"},"content":" getDisplayGiverName(FeedbackParticipantType.STUDENTS));"},{"lineNumber":1120,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(questionForm.findElement(By.id(\"receiver-type\")),"},{"lineNumber":1121,"author":{"gitId":"-"},"content":" getDisplayRecipientName(FeedbackParticipantType.STUDENTS_EXCLUDING_SELF));"},{"lineNumber":1122,"author":{"gitId":"-"},"content":" if (feedbackQuestion.getNumberOfEntitiesToGiveFeedbackTo() \u003d\u003d Const.MAX_POSSIBLE_RECIPIENTS) {"},{"lineNumber":1123,"author":{"gitId":"-"},"content":" click(questionForm.findElement(By.id(\"unlimited-recipients\")));"},{"lineNumber":1124,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1125,"author":{"gitId":"-"},"content":" click(questionForm.findElement(By.id(\"custom-recipients\")));"},{"lineNumber":1126,"author":{"gitId":"-"},"content":" fillTextBox(questionForm.findElement(By.id(\"custom-recipients-number\")),"},{"lineNumber":1127,"author":{"gitId":"-"},"content":" Integer.toString(feedbackQuestion.getNumberOfEntitiesToGiveFeedbackTo()));"},{"lineNumber":1128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1129,"author":{"gitId":"-"},"content":""},{"lineNumber":1130,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(questionForm.findElement(By.id(\"giver-type\")), getDisplayGiverName(newGiver));"},{"lineNumber":1131,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(questionForm.findElement(By.id(\"receiver-type\")),"},{"lineNumber":1132,"author":{"gitId":"-"},"content":" getDisplayRecipientName(newRecipient));"},{"lineNumber":1133,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1134,"author":{"gitId":"-"},"content":""},{"lineNumber":1135,"author":{"gitId":"-"},"content":" private void setFeedbackPath(int questionNum, FeedbackQuestion feedbackQuestion) {"},{"lineNumber":1136,"author":{"gitId":"-"},"content":" FeedbackParticipantType newGiver \u003d feedbackQuestion.getGiverType();"},{"lineNumber":1137,"author":{"gitId":"-"},"content":" FeedbackParticipantType newRecipient \u003d feedbackQuestion.getRecipientType();"},{"lineNumber":1138,"author":{"gitId":"-"},"content":" String feedbackPath \u003d getFeedbackPath(questionNum);"},{"lineNumber":1139,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(questionNum).findElement(By.tagName(\"tm-feedback-path-panel\"));"},{"lineNumber":1140,"author":{"gitId":"-"},"content":" if (!CUSTOM_FEEDBACK_PATH_OPTION.equals(feedbackPath)) {"},{"lineNumber":1141,"author":{"gitId":"-"},"content":" selectFeedbackPathDropdownOption(questionNum, CUSTOM_FEEDBACK_PATH_OPTION + \"...\");"},{"lineNumber":1142,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1143,"author":{"gitId":"-"},"content":" // Set to type STUDENT first to adjust NumberOfEntitiesToGiveFeedbackTo"},{"lineNumber":1144,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(questionForm.findElement(By.id(\"giver-type\")),"},{"lineNumber":1145,"author":{"gitId":"-"},"content":" getDisplayGiverName(FeedbackParticipantType.STUDENTS));"},{"lineNumber":1146,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(questionForm.findElement(By.id(\"receiver-type\")),"},{"lineNumber":1147,"author":{"gitId":"-"},"content":" getDisplayRecipientName(FeedbackParticipantType.STUDENTS_EXCLUDING_SELF));"},{"lineNumber":1148,"author":{"gitId":"-"},"content":" if (feedbackQuestion.getNumOfEntitiesToGiveFeedbackTo() \u003d\u003d Const.MAX_POSSIBLE_RECIPIENTS) {"},{"lineNumber":1149,"author":{"gitId":"-"},"content":" click(questionForm.findElement(By.id(\"unlimited-recipients\")));"},{"lineNumber":1150,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1151,"author":{"gitId":"-"},"content":" click(questionForm.findElement(By.id(\"custom-recipients\")));"},{"lineNumber":1152,"author":{"gitId":"-"},"content":" fillTextBox(questionForm.findElement(By.id(\"custom-recipients-number\")),"},{"lineNumber":1153,"author":{"gitId":"-"},"content":" Integer.toString(feedbackQuestion.getNumOfEntitiesToGiveFeedbackTo()));"},{"lineNumber":1154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1155,"author":{"gitId":"-"},"content":""},{"lineNumber":1156,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(questionForm.findElement(By.id(\"giver-type\")), getDisplayGiverName(newGiver));"},{"lineNumber":1157,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(questionForm.findElement(By.id(\"receiver-type\")),"},{"lineNumber":1158,"author":{"gitId":"-"},"content":" getDisplayRecipientName(newRecipient));"},{"lineNumber":1159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1160,"author":{"gitId":"-"},"content":""},{"lineNumber":1161,"author":{"gitId":"-"},"content":" private void selectFeedbackPathDropdownOption(int questionNum, String text) {"},{"lineNumber":1162,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(questionNum);"},{"lineNumber":1163,"author":{"gitId":"-"},"content":" WebElement feedbackPathPanel \u003d questionForm.findElement(By.tagName(\"tm-feedback-path-panel\"));"},{"lineNumber":1164,"author":{"gitId":"-"},"content":" click(feedbackPathPanel.findElement(By.id(\"btn-feedback-path\")));"},{"lineNumber":1165,"author":{"gitId":"-"},"content":" WebElement dropdown \u003d feedbackPathPanel.findElement(By.id(\"feedback-path-dropdown\"));"},{"lineNumber":1166,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e options \u003d dropdown.findElements(By.className(\"dropdown-button\"));"},{"lineNumber":1167,"author":{"gitId":"-"},"content":" for (WebElement option : options) {"},{"lineNumber":1168,"author":{"gitId":"-"},"content":" if (option.getText().equals(text)) {"},{"lineNumber":1169,"author":{"gitId":"-"},"content":" click(option);"},{"lineNumber":1170,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":1171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1172,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1174,"author":{"gitId":"-"},"content":""},{"lineNumber":1175,"author":{"gitId":"-"},"content":" private void clickEditQuestionButton(int questionNum) {"},{"lineNumber":1176,"author":{"gitId":"-"},"content":" click(getQuestionForm(questionNum).findElement(By.id(\"btn-edit-question\")));"},{"lineNumber":1177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1178,"author":{"gitId":"-"},"content":""},{"lineNumber":1179,"author":{"gitId":"-"},"content":" private void clickSaveQuestionButton(int questionNum) {"},{"lineNumber":1180,"author":{"gitId":"-"},"content":" WebElement saveButton \u003d getQuestionForm(questionNum).findElement(By.id(\"btn-save-question\"));"},{"lineNumber":1181,"author":{"gitId":"-"},"content":" click(saveButton);"},{"lineNumber":1182,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(1000);"},{"lineNumber":1183,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1184,"author":{"gitId":"-"},"content":""},{"lineNumber":1185,"author":{"gitId":"-"},"content":" private void setQuestionVisibility(int questionNum, FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":1186,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(questionNum);"},{"lineNumber":1187,"author":{"gitId":"-"},"content":" WebElement visibilityPanel \u003d questionForm.findElement(By.tagName(\"tm-visibility-panel\"));"},{"lineNumber":1188,"author":{"gitId":"-"},"content":" String visibility \u003d visibilityPanel.findElement(By.cssSelector(\"#btn-question-visibility span\")).getText();"},{"lineNumber":1189,"author":{"gitId":"-"},"content":" if (!CUSTOM_VISIBILITY_OPTION.equals(visibility)) {"},{"lineNumber":1190,"author":{"gitId":"-"},"content":" selectVisibilityDropdownOption(questionNum, CUSTOM_VISIBILITY_OPTION + \"...\");"},{"lineNumber":1191,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1192,"author":{"gitId":"-"},"content":""},{"lineNumber":1193,"author":{"gitId":"-"},"content":" FeedbackParticipantType giver \u003d feedbackQuestion.getGiverType();"},{"lineNumber":1194,"author":{"gitId":"-"},"content":" FeedbackParticipantType receiver \u003d feedbackQuestion.getRecipientType();"},{"lineNumber":1195,"author":{"gitId":"-"},"content":" WebElement customVisibilityTable \u003d visibilityPanel.findElement(By.id(\"custom-visibility-table\"));"},{"lineNumber":1196,"author":{"gitId":"-"},"content":" selectVisibilityBoxes(customVisibilityTable, giver, receiver, feedbackQuestion.getShowResponsesTo(), 1);"},{"lineNumber":1197,"author":{"gitId":"-"},"content":" selectVisibilityBoxes(customVisibilityTable, giver, receiver, feedbackQuestion.getShowGiverNameTo(), 2);"},{"lineNumber":1198,"author":{"gitId":"-"},"content":" selectVisibilityBoxes(customVisibilityTable, giver, receiver, feedbackQuestion.getShowRecipientNameTo(), 3);"},{"lineNumber":1199,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1200,"author":{"gitId":"-"},"content":""},{"lineNumber":1201,"author":{"gitId":"-"},"content":" private void setQuestionVisibility(int questionNum, FeedbackQuestion feedbackQuestion) {"},{"lineNumber":1202,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(questionNum);"},{"lineNumber":1203,"author":{"gitId":"-"},"content":" WebElement visibilityPanel \u003d questionForm.findElement(By.tagName(\"tm-visibility-panel\"));"},{"lineNumber":1204,"author":{"gitId":"-"},"content":" String visibility \u003d visibilityPanel.findElement(By.cssSelector(\"#btn-question-visibility span\")).getText();"},{"lineNumber":1205,"author":{"gitId":"-"},"content":" if (!CUSTOM_VISIBILITY_OPTION.equals(visibility)) {"},{"lineNumber":1206,"author":{"gitId":"-"},"content":" selectVisibilityDropdownOption(questionNum, CUSTOM_VISIBILITY_OPTION + \"...\");"},{"lineNumber":1207,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1208,"author":{"gitId":"-"},"content":""},{"lineNumber":1209,"author":{"gitId":"-"},"content":" FeedbackParticipantType giver \u003d feedbackQuestion.getGiverType();"},{"lineNumber":1210,"author":{"gitId":"-"},"content":" FeedbackParticipantType receiver \u003d feedbackQuestion.getRecipientType();"},{"lineNumber":1211,"author":{"gitId":"-"},"content":" WebElement customVisibilityTable \u003d visibilityPanel.findElement(By.id(\"custom-visibility-table\"));"},{"lineNumber":1212,"author":{"gitId":"-"},"content":" selectVisibilityBoxes(customVisibilityTable, giver, receiver, feedbackQuestion.getShowResponsesTo(), 1);"},{"lineNumber":1213,"author":{"gitId":"-"},"content":" selectVisibilityBoxes(customVisibilityTable, giver, receiver, feedbackQuestion.getShowGiverNameTo(), 2);"},{"lineNumber":1214,"author":{"gitId":"-"},"content":" selectVisibilityBoxes(customVisibilityTable, giver, receiver, feedbackQuestion.getShowRecipientNameTo(), 3);"},{"lineNumber":1215,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1216,"author":{"gitId":"-"},"content":""},{"lineNumber":1217,"author":{"gitId":"-"},"content":" private void selectVisibilityBoxes(WebElement table, FeedbackParticipantType giver,"},{"lineNumber":1218,"author":{"gitId":"-"},"content":" FeedbackParticipantType receiver, List\u003cFeedbackParticipantType\u003e participants,"},{"lineNumber":1219,"author":{"gitId":"-"},"content":" int colNum) {"},{"lineNumber":1220,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e possibleTypes \u003d new ArrayList\u003c\u003e(Arrays.asList(FeedbackParticipantType.RECEIVER,"},{"lineNumber":1221,"author":{"gitId":"-"},"content":" FeedbackParticipantType.OWN_TEAM_MEMBERS, FeedbackParticipantType.RECEIVER_TEAM_MEMBERS,"},{"lineNumber":1222,"author":{"gitId":"-"},"content":" FeedbackParticipantType.STUDENTS, FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":1223,"author":{"gitId":"-"},"content":" if (!giver.equals(FeedbackParticipantType.STUDENTS)) {"},{"lineNumber":1224,"author":{"gitId":"-"},"content":" possibleTypes.remove(FeedbackParticipantType.OWN_TEAM_MEMBERS);"},{"lineNumber":1225,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1226,"author":{"gitId":"-"},"content":" if (!receiver.equals(FeedbackParticipantType.STUDENTS_EXCLUDING_SELF)) {"},{"lineNumber":1227,"author":{"gitId":"-"},"content":" possibleTypes.remove(FeedbackParticipantType.RECEIVER_TEAM_MEMBERS);"},{"lineNumber":1228,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1229,"author":{"gitId":"-"},"content":" if (receiver.equals(FeedbackParticipantType.NONE)"},{"lineNumber":1230,"author":{"gitId":"-"},"content":" || receiver.equals(FeedbackParticipantType.SELF)"},{"lineNumber":1231,"author":{"gitId":"-"},"content":" || receiver.equals(FeedbackParticipantType.OWN_TEAM)) {"},{"lineNumber":1232,"author":{"gitId":"-"},"content":" possibleTypes.remove(FeedbackParticipantType.RECEIVER);"},{"lineNumber":1233,"author":{"gitId":"-"},"content":" possibleTypes.remove(FeedbackParticipantType.RECEIVER_TEAM_MEMBERS);"},{"lineNumber":1234,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1235,"author":{"gitId":"-"},"content":""},{"lineNumber":1236,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e rows \u003d table.findElements(By.tagName(\"tr\"));"},{"lineNumber":1237,"author":{"gitId":"-"},"content":" int index \u003d colNum - 1;"},{"lineNumber":1238,"author":{"gitId":"-"},"content":" for (FeedbackParticipantType participant : participants) {"},{"lineNumber":1239,"author":{"gitId":"-"},"content":" markOptionAsSelected(rows.get(possibleTypes.indexOf(participant)).findElements(By.tagName(\"input\")).get(index));"},{"lineNumber":1240,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1241,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1242,"author":{"gitId":"-"},"content":""},{"lineNumber":1243,"author":{"gitId":"-"},"content":" private void selectVisibilityDropdownOption(int questionNum, String text) {"},{"lineNumber":1244,"author":{"gitId":"-"},"content":" WebElement questionForm \u003d getQuestionForm(questionNum);"},{"lineNumber":1245,"author":{"gitId":"-"},"content":" WebElement visibilityPanel \u003d questionForm.findElement(By.tagName(\"tm-visibility-panel\"));"},{"lineNumber":1246,"author":{"gitId":"-"},"content":" click(visibilityPanel.findElement(By.id(\"btn-question-visibility\")));"},{"lineNumber":1247,"author":{"gitId":"-"},"content":" WebElement dropdown \u003d visibilityPanel.findElement(By.id(\"question-visibility-dropdown\"));"},{"lineNumber":1248,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e options \u003d dropdown.findElements(By.className(\"dropdown-button\"));"},{"lineNumber":1249,"author":{"gitId":"-"},"content":" for (WebElement option : options) {"},{"lineNumber":1250,"author":{"gitId":"-"},"content":" if (option.getText().equals(text)) {"},{"lineNumber":1251,"author":{"gitId":"-"},"content":" click(option);"},{"lineNumber":1252,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":1253,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1254,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1255,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1256,"author":{"gitId":"-"},"content":""},{"lineNumber":1257,"author":{"gitId":"-"},"content":" private void clickAndWaitForNewQuestion(WebElement button) {"},{"lineNumber":1258,"author":{"gitId":"-"},"content":" int newQuestionNum \u003d getNumQuestions() + 1;"},{"lineNumber":1259,"author":{"gitId":"-"},"content":" click(button);"},{"lineNumber":1260,"author":{"gitId":"-"},"content":" waitForElementPresence(By.id(\"question-form-\" + newQuestionNum));"},{"lineNumber":1261,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1262,"author":{"gitId":"-"},"content":""},{"lineNumber":1263,"author":{"gitId":"-"},"content":" private void addNewQuestion(int optionNumber) {"},{"lineNumber":1264,"author":{"gitId":"-"},"content":" click(addNewQuestionButton);"},{"lineNumber":1265,"author":{"gitId":"-"},"content":" WebElement newQuestionDropdown \u003d waitForElementPresence(By.id(\"new-question-dropdown\"));"},{"lineNumber":1266,"author":{"gitId":"-"},"content":" WebElement optionButton \u003d newQuestionDropdown.findElements(By.tagName(\"button\")).get(optionNumber - 1);"},{"lineNumber":1267,"author":{"gitId":"-"},"content":" if (optionNumber \u003d\u003d 1) {"},{"lineNumber":1268,"author":{"gitId":"-"},"content":" click(optionButton);"},{"lineNumber":1269,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1270,"author":{"gitId":"-"},"content":" clickAndWaitForNewQuestion(optionButton);"},{"lineNumber":1271,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1272,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1273,"author":{"gitId":"-"},"content":""},{"lineNumber":1274,"author":{"gitId":"-"},"content":" private void clickSaveNewQuestionButton() {"},{"lineNumber":1275,"author":{"gitId":"-"},"content":" WebElement saveButton \u003d browser.driver.findElement(By.id(\"btn-save-new\"));"},{"lineNumber":1276,"author":{"gitId":"-"},"content":" click(saveButton);"},{"lineNumber":1277,"author":{"gitId":"-"},"content":" waitForElementStaleness(saveButton);"},{"lineNumber":1278,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1279,"author":{"gitId":"-"},"content":""},{"lineNumber":1280,"author":{"gitId":"-"},"content":" private WebElement getRecommendedTextLengthField(int questionNum) {"},{"lineNumber":1281,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum)"},{"lineNumber":1282,"author":{"gitId":"-"},"content":" .findElement(By.tagName(\"tm-text-question-edit-details-form\"))"},{"lineNumber":1283,"author":{"gitId":"-"},"content":" .findElement(By.id(\"recommended-length\"));"},{"lineNumber":1284,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1285,"author":{"gitId":"-"},"content":""},{"lineNumber":1286,"author":{"gitId":"-"},"content":" private WebElement getGenerateOptionsCheckbox(int questionNum) {"},{"lineNumber":1287,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"generate-checkbox\"));"},{"lineNumber":1288,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1289,"author":{"gitId":"-"},"content":""},{"lineNumber":1290,"author":{"gitId":"-"},"content":" private WebElement getGenerateOptionsDropdown(int questionNum) {"},{"lineNumber":1291,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"generate-dropdown\"));"},{"lineNumber":1292,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1293,"author":{"gitId":"-"},"content":""},{"lineNumber":1294,"author":{"gitId":"-"},"content":" private WebElement getWeightCheckbox(int questionNum) {"},{"lineNumber":1295,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"weights-checkbox\"));"},{"lineNumber":1296,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1297,"author":{"gitId":"-"},"content":""},{"lineNumber":1298,"author":{"gitId":"-"},"content":" private WebElement getOtherOptionCheckbox(int questionNum) {"},{"lineNumber":1299,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"other-checkbox\"));"},{"lineNumber":1300,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1301,"author":{"gitId":"-"},"content":""},{"lineNumber":1302,"author":{"gitId":"-"},"content":" private WebElement getQuestionDropdownCheckbox(int questionNum) {"},{"lineNumber":1303,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"make-question-dropdown\"));"},{"lineNumber":1304,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1305,"author":{"gitId":"-"},"content":""},{"lineNumber":1306,"author":{"gitId":"-"},"content":" private String getGeneratedOptionString(FeedbackParticipantType type) {"},{"lineNumber":1307,"author":{"gitId":"-"},"content":" switch (type) {"},{"lineNumber":1308,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":1309,"author":{"gitId":"-"},"content":" case STUDENTS_IN_SAME_SECTION:"},{"lineNumber":1310,"author":{"gitId":"-"},"content":" return \"students\";"},{"lineNumber":1311,"author":{"gitId":"-"},"content":" case STUDENTS_EXCLUDING_SELF:"},{"lineNumber":1312,"author":{"gitId":"-"},"content":" return \"students (excluding self)\";"},{"lineNumber":1313,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":1314,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":1315,"author":{"gitId":"-"},"content":" return \"teams\";"},{"lineNumber":1316,"author":{"gitId":"-"},"content":" case TEAMS_EXCLUDING_SELF:"},{"lineNumber":1317,"author":{"gitId":"-"},"content":" return \"teams (excluding own team)\";"},{"lineNumber":1318,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":1319,"author":{"gitId":"-"},"content":" return \"instructors\";"},{"lineNumber":1320,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":1321,"author":{"gitId":"-"},"content":" return \"unknown\";"},{"lineNumber":1322,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1323,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1324,"author":{"gitId":"-"},"content":""},{"lineNumber":1325,"author":{"gitId":"-"},"content":" private String getDoubleString(Double value) {"},{"lineNumber":1326,"author":{"gitId":"-"},"content":" return value % 1 \u003d\u003d 0 ? Integer.toString(value.intValue()) : Double.toString(value);"},{"lineNumber":1327,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1328,"author":{"gitId":"-"},"content":""},{"lineNumber":1329,"author":{"gitId":"-"},"content":" private WebElement getOptionsSection(int questionNum) {"},{"lineNumber":1330,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"options-section\"));"},{"lineNumber":1331,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1332,"author":{"gitId":"-"},"content":""},{"lineNumber":1333,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getOptionInputs(int questionNum) {"},{"lineNumber":1334,"author":{"gitId":"-"},"content":" WebElement optionsSection \u003d getOptionsSection(questionNum);"},{"lineNumber":1335,"author":{"gitId":"-"},"content":" return optionsSection.findElements(By.cssSelector(\"input[type\u003d\u0027text\u0027]\"));"},{"lineNumber":1336,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1337,"author":{"gitId":"-"},"content":""},{"lineNumber":1338,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getOptionWeightInputs(int questionNum) {"},{"lineNumber":1339,"author":{"gitId":"-"},"content":" WebElement optionsSection \u003d getOptionsSection(questionNum);"},{"lineNumber":1340,"author":{"gitId":"-"},"content":" return optionsSection.findElements(By.cssSelector(\"tm-weight-field input\"));"},{"lineNumber":1341,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1342,"author":{"gitId":"-"},"content":""},{"lineNumber":1343,"author":{"gitId":"-"},"content":" private WebElement getOtherWeightInput(int questionNum) {"},{"lineNumber":1344,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"other-weight\"));"},{"lineNumber":1345,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1346,"author":{"gitId":"-"},"content":""},{"lineNumber":1347,"author":{"gitId":"-"},"content":" private boolean verifyGeneratedOptions(int questionNum, FeedbackParticipantType participantType) {"},{"lineNumber":1348,"author":{"gitId":"-"},"content":" if (!participantType.equals(FeedbackParticipantType.NONE)) {"},{"lineNumber":1349,"author":{"gitId":"-"},"content":" assertTrue(getGenerateOptionsCheckbox(questionNum).isSelected());"},{"lineNumber":1350,"author":{"gitId":"-"},"content":" assertEquals(getSelectedDropdownOptionText(getGenerateOptionsDropdown(questionNum)),"},{"lineNumber":1351,"author":{"gitId":"-"},"content":" getGeneratedOptionString(participantType));"},{"lineNumber":1352,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":1353,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1354,"author":{"gitId":"-"},"content":" assertFalse(getGenerateOptionsCheckbox(questionNum).isSelected());"},{"lineNumber":1355,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":1356,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1357,"author":{"gitId":"-"},"content":""},{"lineNumber":1358,"author":{"gitId":"-"},"content":" private void verifyOptions(int questionNum, List\u003cString\u003e options) {"},{"lineNumber":1359,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e inputs \u003d getOptionInputs(questionNum);"},{"lineNumber":1360,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c options.size(); i++) {"},{"lineNumber":1361,"author":{"gitId":"-"},"content":" assertEquals(options.get(i), inputs.get(i).getAttribute(\"value\"));"},{"lineNumber":1362,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1363,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1364,"author":{"gitId":"-"},"content":""},{"lineNumber":1365,"author":{"gitId":"-"},"content":" private void verifyOptionWeights(int questionNum, boolean hasWeights, List\u003cDouble\u003e weights) {"},{"lineNumber":1366,"author":{"gitId":"-"},"content":" if (hasWeights) {"},{"lineNumber":1367,"author":{"gitId":"-"},"content":" assertTrue(getWeightCheckbox(questionNum).isSelected());"},{"lineNumber":1368,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e weightInputs \u003d getOptionWeightInputs(questionNum);"},{"lineNumber":1369,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c weights.size(); i++) {"},{"lineNumber":1370,"author":{"gitId":"-"},"content":" assertEquals(getDoubleString(weights.get(i)), weightInputs.get(i).getAttribute(\"value\"));"},{"lineNumber":1371,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1372,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1373,"author":{"gitId":"-"},"content":" assertFalse(getWeightCheckbox(questionNum).isSelected());"},{"lineNumber":1374,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1375,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1376,"author":{"gitId":"-"},"content":""},{"lineNumber":1377,"author":{"gitId":"-"},"content":" private void verifyOtherOption(int questionNum, boolean hasOther, Double weight) {"},{"lineNumber":1378,"author":{"gitId":"-"},"content":" if (hasOther) {"},{"lineNumber":1379,"author":{"gitId":"-"},"content":" assertTrue(getOtherOptionCheckbox(questionNum).isSelected());"},{"lineNumber":1380,"author":{"gitId":"-"},"content":" if (weight \u003e 0) {"},{"lineNumber":1381,"author":{"gitId":"-"},"content":" String otherWeight \u003d getOtherWeightInput(questionNum).getAttribute(\"value\");"},{"lineNumber":1382,"author":{"gitId":"-"},"content":" assertEquals(getDoubleString(weight), otherWeight);"},{"lineNumber":1383,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1384,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1385,"author":{"gitId":"-"},"content":" assertFalse(getOtherOptionCheckbox(questionNum).isSelected());"},{"lineNumber":1386,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1387,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1388,"author":{"gitId":"-"},"content":""},{"lineNumber":1389,"author":{"gitId":"-"},"content":" private void inputMcqDetails(int questionNum, FeedbackMcqQuestionDetails questionDetails) {"},{"lineNumber":1390,"author":{"gitId":"-"},"content":" if (inputGenerateOptions(questionNum, questionDetails.getGenerateOptionsFor())) {"},{"lineNumber":1391,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":1392,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1393,"author":{"gitId":"-"},"content":""},{"lineNumber":1394,"author":{"gitId":"-"},"content":" inputOptions(questionNum, questionDetails.getMcqChoices());"},{"lineNumber":1395,"author":{"gitId":"-"},"content":" inputOptionWeights(questionNum, questionDetails.isHasAssignedWeights(), questionDetails.getMcqWeights());"},{"lineNumber":1396,"author":{"gitId":"-"},"content":" inputOtherChoice(questionNum, questionDetails.isOtherEnabled(), questionDetails.getMcqOtherWeight());"},{"lineNumber":1397,"author":{"gitId":"-"},"content":" inputDropdownEnabledChoice(questionNum, questionDetails.isQuestionDropdownEnabled());"},{"lineNumber":1398,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1399,"author":{"gitId":"-"},"content":""},{"lineNumber":1400,"author":{"gitId":"-"},"content":" private boolean inputGenerateOptions(int questionNum, FeedbackParticipantType participantType) {"},{"lineNumber":1401,"author":{"gitId":"-"},"content":" if (!participantType.equals(FeedbackParticipantType.NONE)) {"},{"lineNumber":1402,"author":{"gitId":"-"},"content":" markOptionAsSelected(getGenerateOptionsCheckbox(questionNum));"},{"lineNumber":1403,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(getGenerateOptionsDropdown(questionNum),"},{"lineNumber":1404,"author":{"gitId":"-"},"content":" getGeneratedOptionString(participantType));"},{"lineNumber":1405,"author":{"gitId":"-"},"content":" clickSaveQuestionButton(questionNum);"},{"lineNumber":1406,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":1407,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1408,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getGenerateOptionsCheckbox(questionNum));"},{"lineNumber":1409,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":1410,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1411,"author":{"gitId":"-"},"content":""},{"lineNumber":1412,"author":{"gitId":"-"},"content":" private void inputOptions(int questionNum, List\u003cString\u003e options) {"},{"lineNumber":1413,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e inputs \u003d getOptionInputs(questionNum);"},{"lineNumber":1414,"author":{"gitId":"-"},"content":" int numInputsNeeded \u003d options.size() - inputs.size();"},{"lineNumber":1415,"author":{"gitId":"-"},"content":" if (numInputsNeeded \u003e 0) {"},{"lineNumber":1416,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c numInputsNeeded; i++) {"},{"lineNumber":1417,"author":{"gitId":"-"},"content":" click(getQuestionForm(questionNum).findElement(By.id(\"btn-add-option\")));"},{"lineNumber":1418,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1419,"author":{"gitId":"-"},"content":" inputs \u003d getOptionInputs(questionNum);"},{"lineNumber":1420,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1421,"author":{"gitId":"-"},"content":" if (numInputsNeeded \u003c 0) {"},{"lineNumber":1422,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c -numInputsNeeded; i++) {"},{"lineNumber":1423,"author":{"gitId":"-"},"content":" click(getOptionsSection(questionNum).findElement(By.tagName(\"button\")));"},{"lineNumber":1424,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1425,"author":{"gitId":"-"},"content":" inputs \u003d getOptionInputs(questionNum);"},{"lineNumber":1426,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1427,"author":{"gitId":"-"},"content":""},{"lineNumber":1428,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c options.size(); i++) {"},{"lineNumber":1429,"author":{"gitId":"-"},"content":" fillTextBox(inputs.get(i), options.get(i));"},{"lineNumber":1430,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1431,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1432,"author":{"gitId":"-"},"content":""},{"lineNumber":1433,"author":{"gitId":"-"},"content":" private void inputOptionWeights(int questionNum, boolean hasWeights, List\u003cDouble\u003e weights) {"},{"lineNumber":1434,"author":{"gitId":"-"},"content":" if (hasWeights) {"},{"lineNumber":1435,"author":{"gitId":"-"},"content":" markOptionAsSelected(getWeightCheckbox(questionNum));"},{"lineNumber":1436,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e weightInputs \u003d getOptionWeightInputs(questionNum);"},{"lineNumber":1437,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c weights.size(); i++) {"},{"lineNumber":1438,"author":{"gitId":"-"},"content":" fillTextBox(weightInputs.get(i), getDoubleString(weights.get(i)));"},{"lineNumber":1439,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1440,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1441,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getWeightCheckbox(questionNum));"},{"lineNumber":1442,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1443,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1444,"author":{"gitId":"-"},"content":""},{"lineNumber":1445,"author":{"gitId":"-"},"content":" private void inputOtherChoice(int questionNum, boolean hasOther, Double otherWeight) {"},{"lineNumber":1446,"author":{"gitId":"-"},"content":" if (hasOther) {"},{"lineNumber":1447,"author":{"gitId":"-"},"content":" markOptionAsSelected(getOtherOptionCheckbox(questionNum));"},{"lineNumber":1448,"author":{"gitId":"-"},"content":" if (otherWeight \u003e 0) {"},{"lineNumber":1449,"author":{"gitId":"-"},"content":" fillTextBox(getOtherWeightInput(questionNum), getDoubleString(otherWeight));"},{"lineNumber":1450,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1451,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1452,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getOtherOptionCheckbox(questionNum));"},{"lineNumber":1453,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1454,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1455,"author":{"gitId":"-"},"content":""},{"lineNumber":1456,"author":{"gitId":"-"},"content":" private void inputDropdownEnabledChoice(int questionNum, boolean hasOther) {"},{"lineNumber":1457,"author":{"gitId":"-"},"content":" if (hasOther) {"},{"lineNumber":1458,"author":{"gitId":"-"},"content":" markOptionAsSelected(getQuestionDropdownCheckbox(questionNum));"},{"lineNumber":1459,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1460,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getQuestionDropdownCheckbox(questionNum));"},{"lineNumber":1461,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1462,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1463,"author":{"gitId":"-"},"content":""},{"lineNumber":1464,"author":{"gitId":"-"},"content":" private WebElement getMaxOptionsCheckbox(int questionNum) {"},{"lineNumber":1465,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"max-options-checkbox\"));"},{"lineNumber":1466,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1467,"author":{"gitId":"-"},"content":""},{"lineNumber":1468,"author":{"gitId":"-"},"content":" private WebElement getMaxOptionsInput(int questionNum) {"},{"lineNumber":1469,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"max-options\"));"},{"lineNumber":1470,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1471,"author":{"gitId":"-"},"content":""},{"lineNumber":1472,"author":{"gitId":"-"},"content":" private WebElement getMinOptionsCheckbox(int questionNum) {"},{"lineNumber":1473,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"min-options-checkbox\"));"},{"lineNumber":1474,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1475,"author":{"gitId":"-"},"content":""},{"lineNumber":1476,"author":{"gitId":"-"},"content":" private WebElement getMinOptionsInput(int questionNum) {"},{"lineNumber":1477,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"min-options\"));"},{"lineNumber":1478,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1479,"author":{"gitId":"-"},"content":""},{"lineNumber":1480,"author":{"gitId":"-"},"content":" private void verifyMaxOptions(int questionNum, int maxOptions) {"},{"lineNumber":1481,"author":{"gitId":"-"},"content":" if (maxOptions \u003d\u003d Const.POINTS_NO_VALUE) {"},{"lineNumber":1482,"author":{"gitId":"-"},"content":" assertFalse(getMaxOptionsCheckbox(questionNum).isSelected());"},{"lineNumber":1483,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1484,"author":{"gitId":"-"},"content":" assertTrue(getMaxOptionsCheckbox(questionNum).isSelected());"},{"lineNumber":1485,"author":{"gitId":"-"},"content":" assertEquals(getMaxOptionsInput(questionNum).getAttribute(\"value\"),"},{"lineNumber":1486,"author":{"gitId":"-"},"content":" Integer.toString(maxOptions));"},{"lineNumber":1487,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1488,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1489,"author":{"gitId":"-"},"content":""},{"lineNumber":1490,"author":{"gitId":"-"},"content":" private void verifyMinOptions(int questionNum, int minOptions) {"},{"lineNumber":1491,"author":{"gitId":"-"},"content":" if (minOptions \u003d\u003d Const.POINTS_NO_VALUE) {"},{"lineNumber":1492,"author":{"gitId":"-"},"content":" assertFalse(getMinOptionsCheckbox(questionNum).isSelected());"},{"lineNumber":1493,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1494,"author":{"gitId":"-"},"content":" assertTrue(getMinOptionsCheckbox(questionNum).isSelected());"},{"lineNumber":1495,"author":{"gitId":"-"},"content":" assertEquals(getMinOptionsInput(questionNum).getAttribute(\"value\"),"},{"lineNumber":1496,"author":{"gitId":"-"},"content":" Integer.toString(minOptions));"},{"lineNumber":1497,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1498,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1499,"author":{"gitId":"-"},"content":""},{"lineNumber":1500,"author":{"gitId":"-"},"content":" private void inputMsqDetails(int questionNum, FeedbackMsqQuestionDetails questionDetails) {"},{"lineNumber":1501,"author":{"gitId":"-"},"content":" if (inputGenerateOptions(questionNum, questionDetails.getGenerateOptionsFor())) {"},{"lineNumber":1502,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":1503,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1504,"author":{"gitId":"-"},"content":""},{"lineNumber":1505,"author":{"gitId":"-"},"content":" inputOptions(questionNum, questionDetails.getMsqChoices());"},{"lineNumber":1506,"author":{"gitId":"-"},"content":" inputOptionWeights(questionNum, questionDetails.isHasAssignedWeights(), questionDetails.getMsqWeights());"},{"lineNumber":1507,"author":{"gitId":"-"},"content":" inputOtherChoice(questionNum, questionDetails.isOtherEnabled(), questionDetails.getMsqOtherWeight());"},{"lineNumber":1508,"author":{"gitId":"-"},"content":" inputMaxOptions(questionNum, questionDetails.getMaxSelectableChoices());"},{"lineNumber":1509,"author":{"gitId":"-"},"content":" inputMinOptions(questionNum, questionDetails.getMinSelectableChoices());"},{"lineNumber":1510,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1511,"author":{"gitId":"-"},"content":""},{"lineNumber":1512,"author":{"gitId":"-"},"content":" private void inputMaxOptions(int questionNum, int maxOptions) {"},{"lineNumber":1513,"author":{"gitId":"-"},"content":" if (maxOptions \u003d\u003d Const.POINTS_NO_VALUE) {"},{"lineNumber":1514,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getMaxOptionsCheckbox(questionNum));"},{"lineNumber":1515,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1516,"author":{"gitId":"-"},"content":" markOptionAsSelected(getMaxOptionsCheckbox(questionNum));"},{"lineNumber":1517,"author":{"gitId":"-"},"content":" fillTextBox(getMaxOptionsInput(questionNum), Integer.toString(maxOptions));"},{"lineNumber":1518,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1519,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1520,"author":{"gitId":"-"},"content":""},{"lineNumber":1521,"author":{"gitId":"-"},"content":" private void inputMinOptions(int questionNum, int minOptions) {"},{"lineNumber":1522,"author":{"gitId":"-"},"content":" if (minOptions \u003d\u003d Const.POINTS_NO_VALUE) {"},{"lineNumber":1523,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getMinOptionsCheckbox(questionNum));"},{"lineNumber":1524,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1525,"author":{"gitId":"-"},"content":" markOptionAsSelected(getMinOptionsCheckbox(questionNum));"},{"lineNumber":1526,"author":{"gitId":"-"},"content":" fillTextBox(getMinOptionsInput(questionNum), Integer.toString(minOptions));"},{"lineNumber":1527,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1528,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1529,"author":{"gitId":"-"},"content":""},{"lineNumber":1530,"author":{"gitId":"-"},"content":" private WebElement getMinNumscaleInput(int questionNum) {"},{"lineNumber":1531,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"min-value\"));"},{"lineNumber":1532,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1533,"author":{"gitId":"-"},"content":""},{"lineNumber":1534,"author":{"gitId":"-"},"content":" private WebElement getMaxNumscaleInput(int questionNum) {"},{"lineNumber":1535,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"max-value\"));"},{"lineNumber":1536,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1537,"author":{"gitId":"-"},"content":""},{"lineNumber":1538,"author":{"gitId":"-"},"content":" private WebElement getNumScaleIncrementInput(int questionNum) {"},{"lineNumber":1539,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"increment-value\"));"},{"lineNumber":1540,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1541,"author":{"gitId":"-"},"content":""},{"lineNumber":1542,"author":{"gitId":"-"},"content":" private void inputNumScaleDetails(int questionNum, FeedbackNumericalScaleQuestionDetails questionDetails) {"},{"lineNumber":1543,"author":{"gitId":"-"},"content":" inputNumScaleValue(getMinNumscaleInput(questionNum), Integer.toString(questionDetails.getMinScale()));"},{"lineNumber":1544,"author":{"gitId":"-"},"content":" inputNumScaleValue(getNumScaleIncrementInput(questionNum), getDoubleString(questionDetails.getStep()));"},{"lineNumber":1545,"author":{"gitId":"-"},"content":" inputNumScaleValue(getMaxNumscaleInput(questionNum), Integer.toString(questionDetails.getMaxScale()));"},{"lineNumber":1546,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1547,"author":{"gitId":"-"},"content":""},{"lineNumber":1548,"author":{"gitId":"-"},"content":" private void inputNumScaleValue(WebElement input, String value) {"},{"lineNumber":1549,"author":{"gitId":"-"},"content":" input.clear();"},{"lineNumber":1550,"author":{"gitId":"-"},"content":" input.sendKeys(value);"},{"lineNumber":1551,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1552,"author":{"gitId":"-"},"content":""},{"lineNumber":1553,"author":{"gitId":"-"},"content":" private WebElement getConstSumTotalPointsRadioBtn(int questionNum) {"},{"lineNumber":1554,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"total-points-radio\"));"},{"lineNumber":1555,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1556,"author":{"gitId":"-"},"content":""},{"lineNumber":1557,"author":{"gitId":"-"},"content":" private WebElement getConstSumTotalPointsInput(int questionNum) {"},{"lineNumber":1558,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"total-points\"));"},{"lineNumber":1559,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1560,"author":{"gitId":"-"},"content":""},{"lineNumber":1561,"author":{"gitId":"-"},"content":" private WebElement getConstSumPerOptionPointsRadioBtn(int questionNum) {"},{"lineNumber":1562,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"per-option-points-radio\"));"},{"lineNumber":1563,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1564,"author":{"gitId":"-"},"content":""},{"lineNumber":1565,"author":{"gitId":"-"},"content":" private WebElement getConstSumPerOptionPointsInput(int questionNum) {"},{"lineNumber":1566,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"per-option-points\"));"},{"lineNumber":1567,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1568,"author":{"gitId":"-"},"content":""},{"lineNumber":1569,"author":{"gitId":"-"},"content":" private WebElement getConstSumUnevenDistributionCheckbox(int questionNum) {"},{"lineNumber":1570,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"uneven-distribution-checkbox\"));"},{"lineNumber":1571,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1572,"author":{"gitId":"-"},"content":""},{"lineNumber":1573,"author":{"gitId":"-"},"content":" private WebElement getConstSumUnevenDistributionDropdown(int questionNum) {"},{"lineNumber":1574,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"uneven-distribution-dropdown\"));"},{"lineNumber":1575,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1576,"author":{"gitId":"-"},"content":""},{"lineNumber":1577,"author":{"gitId":"-"},"content":" private void inputConstSumDetails(int questionNum, FeedbackConstantSumQuestionDetails questionDetails) {"},{"lineNumber":1578,"author":{"gitId":"-"},"content":" if (!questionDetails.isDistributeToRecipients()) {"},{"lineNumber":1579,"author":{"gitId":"-"},"content":" inputOptions(questionNum, questionDetails.getConstSumOptions());"},{"lineNumber":1580,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1581,"author":{"gitId":"-"},"content":" if (questionDetails.isPointsPerOption()) {"},{"lineNumber":1582,"author":{"gitId":"-"},"content":" click(getConstSumPerOptionPointsRadioBtn(questionNum));"},{"lineNumber":1583,"author":{"gitId":"-"},"content":" fillTextBox(getConstSumPerOptionPointsInput(questionNum), Integer.toString(questionDetails.getPoints()));"},{"lineNumber":1584,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1585,"author":{"gitId":"-"},"content":" click(getConstSumTotalPointsRadioBtn(questionNum));"},{"lineNumber":1586,"author":{"gitId":"-"},"content":" fillTextBox(getConstSumTotalPointsInput(questionNum), Integer.toString(questionDetails.getPoints()));"},{"lineNumber":1587,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1588,"author":{"gitId":"-"},"content":" String distributeFor \u003d questionDetails.getDistributePointsFor();"},{"lineNumber":1589,"author":{"gitId":"-"},"content":" if (questionDetails.isForceUnevenDistribution()) {"},{"lineNumber":1590,"author":{"gitId":"-"},"content":" markOptionAsSelected(getConstSumUnevenDistributionCheckbox(questionNum));"},{"lineNumber":1591,"author":{"gitId":"-"},"content":" selectDropdownOptionByText(getConstSumUnevenDistributionDropdown(questionNum),"},{"lineNumber":1592,"author":{"gitId":"-"},"content":" \"All options\".equals(distributeFor) ? \"Every option\" : distributeFor);"},{"lineNumber":1593,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1594,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getConstSumUnevenDistributionCheckbox(questionNum));"},{"lineNumber":1595,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1596,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1597,"author":{"gitId":"-"},"content":""},{"lineNumber":1598,"author":{"gitId":"-"},"content":" private WebElement getZeroSumCheckbox(int questionNum) {"},{"lineNumber":1599,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"zero-sum-checkbox\"));"},{"lineNumber":1600,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1601,"author":{"gitId":"-"},"content":""},{"lineNumber":1602,"author":{"gitId":"-"},"content":" private WebElement getAllowNotSureContributionCheckbox(int questionNum) {"},{"lineNumber":1603,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"not-sure-checkbox\"));"},{"lineNumber":1604,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1605,"author":{"gitId":"-"},"content":""},{"lineNumber":1606,"author":{"gitId":"-"},"content":" private void inputContributionDetails(int questionNum, FeedbackContributionQuestionDetails questionDetails) {"},{"lineNumber":1607,"author":{"gitId":"-"},"content":" if (questionDetails.isZeroSum()) {"},{"lineNumber":1608,"author":{"gitId":"-"},"content":" markOptionAsSelected(getZeroSumCheckbox(questionNum));"},{"lineNumber":1609,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1610,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getZeroSumCheckbox(questionNum));"},{"lineNumber":1611,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1612,"author":{"gitId":"-"},"content":" if (questionDetails.isNotSureAllowed()) {"},{"lineNumber":1613,"author":{"gitId":"-"},"content":" markOptionAsSelected(getAllowNotSureContributionCheckbox(questionNum));"},{"lineNumber":1614,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1615,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getAllowNotSureContributionCheckbox(questionNum));"},{"lineNumber":1616,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1617,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1618,"author":{"gitId":"-"},"content":""},{"lineNumber":1619,"author":{"gitId":"-"},"content":" private WebElement getRubricRow(int questionNum, int rowNumber) {"},{"lineNumber":1620,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElements(By.cssSelector(\"tm-rubric-question-edit-details-form tr\"))"},{"lineNumber":1621,"author":{"gitId":"-"},"content":" .get(rowNumber - 1);"},{"lineNumber":1622,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1623,"author":{"gitId":"-"},"content":""},{"lineNumber":1624,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getRubricChoiceInputs(int questionNum) {"},{"lineNumber":1625,"author":{"gitId":"-"},"content":" return getRubricRow(questionNum, 1).findElements(By.tagName(\"input\"));"},{"lineNumber":1626,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1627,"author":{"gitId":"-"},"content":""},{"lineNumber":1628,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getRubricTextareas(int questionNum, int rowNum) {"},{"lineNumber":1629,"author":{"gitId":"-"},"content":" return getRubricRow(questionNum, rowNum).findElements(By.tagName(\"textarea\"));"},{"lineNumber":1630,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1631,"author":{"gitId":"-"},"content":""},{"lineNumber":1632,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getRubricWeights(int questionNum, int rowNum) {"},{"lineNumber":1633,"author":{"gitId":"-"},"content":" return getRubricRow(questionNum, rowNum).findElements(By.tagName(\"input\"));"},{"lineNumber":1634,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1635,"author":{"gitId":"-"},"content":""},{"lineNumber":1636,"author":{"gitId":"-"},"content":" private WebElement getRubricDeleteSubQnBtn(int questionNum, int rowNum) {"},{"lineNumber":1637,"author":{"gitId":"-"},"content":" return getRubricRow(questionNum, rowNum).findElement(By.id(\"btn-delete-subquestion\"));"},{"lineNumber":1638,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1639,"author":{"gitId":"-"},"content":""},{"lineNumber":1640,"author":{"gitId":"-"},"content":" private WebElement getRubricDeleteChoiceBtn(int questionNum, int colNum) {"},{"lineNumber":1641,"author":{"gitId":"-"},"content":" return getRubricRow(questionNum, getNumRubricRows(questionNum)).findElements(By.id(\"btn-delete-choice\")).get(colNum);"},{"lineNumber":1642,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1643,"author":{"gitId":"-"},"content":""},{"lineNumber":1644,"author":{"gitId":"-"},"content":" private int getNumRubricRows(int questionNum) {"},{"lineNumber":1645,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElements(By.cssSelector(\"#rubric-table tr\")).size();"},{"lineNumber":1646,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1647,"author":{"gitId":"-"},"content":""},{"lineNumber":1648,"author":{"gitId":"-"},"content":" private int getNumRubricCols(int questionNum) {"},{"lineNumber":1649,"author":{"gitId":"-"},"content":" WebElement row \u003d getRubricRow(questionNum, 1);"},{"lineNumber":1650,"author":{"gitId":"-"},"content":" return row.findElements(By.tagName(\"td\")).size() + row.findElements(By.tagName(\"th\")).size();"},{"lineNumber":1651,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1652,"author":{"gitId":"-"},"content":""},{"lineNumber":1653,"author":{"gitId":"-"},"content":" private void inputRubricDetails(int questionNum, FeedbackRubricQuestionDetails questionDetails) {"},{"lineNumber":1654,"author":{"gitId":"-"},"content":" int numSubQn \u003d questionDetails.getNumOfRubricSubQuestions();"},{"lineNumber":1655,"author":{"gitId":"-"},"content":" int numChoices \u003d questionDetails.getNumOfRubricChoices();"},{"lineNumber":1656,"author":{"gitId":"-"},"content":" adjustNumRubricFields(questionNum, numSubQn, numChoices);"},{"lineNumber":1657,"author":{"gitId":"-"},"content":""},{"lineNumber":1658,"author":{"gitId":"-"},"content":" List\u003cString\u003e choices \u003d questionDetails.getRubricChoices();"},{"lineNumber":1659,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c numChoices; i++) {"},{"lineNumber":1660,"author":{"gitId":"-"},"content":" fillTextBox(getRubricChoiceInputs(questionNum).get(i), choices.get(i));"},{"lineNumber":1661,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1662,"author":{"gitId":"-"},"content":""},{"lineNumber":1663,"author":{"gitId":"-"},"content":" List\u003cString\u003e subQuestions \u003d questionDetails.getRubricSubQuestions();"},{"lineNumber":1664,"author":{"gitId":"-"},"content":" List\u003cList\u003cString\u003e\u003e descriptions \u003d questionDetails.getRubricDescriptions();"},{"lineNumber":1665,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c numSubQn; i++) {"},{"lineNumber":1666,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e textAreas \u003d getRubricTextareas(questionNum, i + 2);"},{"lineNumber":1667,"author":{"gitId":"-"},"content":" fillTextBox(textAreas.get(0), subQuestions.get(i));"},{"lineNumber":1668,"author":{"gitId":"-"},"content":" for (int j \u003d 0; j \u003c numChoices; j++) {"},{"lineNumber":1669,"author":{"gitId":"-"},"content":" fillTextBox(textAreas.get(j + 1), descriptions.get(i).get(j));"},{"lineNumber":1670,"author":{"gitId":"-"},"content":" if (descriptions.get(i).get(j).isEmpty()) {"},{"lineNumber":1671,"author":{"gitId":"-"},"content":" // using clear does not send the required event"},{"lineNumber":1672,"author":{"gitId":"-"},"content":" // as a workaround, after clearing without event, enter a random character and delete it"},{"lineNumber":1673,"author":{"gitId":"-"},"content":" textAreas.get(j + 1).sendKeys(\"a\");"},{"lineNumber":1674,"author":{"gitId":"-"},"content":" textAreas.get(j + 1).sendKeys(Keys.BACK_SPACE);"},{"lineNumber":1675,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1676,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1677,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1678,"author":{"gitId":"-"},"content":""},{"lineNumber":1679,"author":{"gitId":"-"},"content":" if (questionDetails.isHasAssignedWeights()) {"},{"lineNumber":1680,"author":{"gitId":"-"},"content":" markOptionAsSelected(getWeightCheckbox(questionNum));"},{"lineNumber":1681,"author":{"gitId":"-"},"content":" List\u003cList\u003cDouble\u003e\u003e weights \u003d questionDetails.getRubricWeights();"},{"lineNumber":1682,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c numSubQn; i++) {"},{"lineNumber":1683,"author":{"gitId":"-"},"content":" for (int j \u003d 0; j \u003c numChoices; j++) {"},{"lineNumber":1684,"author":{"gitId":"-"},"content":" fillTextBox(getRubricWeights(questionNum, i + 2).get(j), getDoubleString(weights.get(i).get(j)));"},{"lineNumber":1685,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1686,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1687,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1688,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getWeightCheckbox(questionNum));"},{"lineNumber":1689,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1690,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1691,"author":{"gitId":"-"},"content":""},{"lineNumber":1692,"author":{"gitId":"-"},"content":" private void adjustNumRubricFields(int questionNum, int numSubQn, int numChoices) {"},{"lineNumber":1693,"author":{"gitId":"-"},"content":" int numSubQnsNeeded \u003d numSubQn - (getNumRubricRows(questionNum) - 2);"},{"lineNumber":1694,"author":{"gitId":"-"},"content":" int numChoicesNeeded \u003d numChoices - (getNumRubricCols(questionNum) - 1);"},{"lineNumber":1695,"author":{"gitId":"-"},"content":" if (numSubQnsNeeded \u003e 0) {"},{"lineNumber":1696,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c numSubQnsNeeded; i++) {"},{"lineNumber":1697,"author":{"gitId":"-"},"content":" click(getQuestionForm(questionNum).findElement(By.id(\"btn-add-row\")));"},{"lineNumber":1698,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1699,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1700,"author":{"gitId":"-"},"content":" if (numChoicesNeeded \u003e 0) {"},{"lineNumber":1701,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c numChoicesNeeded; i++) {"},{"lineNumber":1702,"author":{"gitId":"-"},"content":" click(getQuestionForm(questionNum).findElement(By.id(\"btn-add-col\")));"},{"lineNumber":1703,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1704,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1705,"author":{"gitId":"-"},"content":" if (numSubQnsNeeded \u003c 0) {"},{"lineNumber":1706,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c -numSubQnsNeeded; i++) {"},{"lineNumber":1707,"author":{"gitId":"-"},"content":" click(getRubricDeleteSubQnBtn(questionNum, 2));"},{"lineNumber":1708,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1709,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1710,"author":{"gitId":"-"},"content":" if (numChoicesNeeded \u003c 0) {"},{"lineNumber":1711,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c -numChoicesNeeded; i++) {"},{"lineNumber":1712,"author":{"gitId":"-"},"content":" clickAndConfirm(getRubricDeleteChoiceBtn(questionNum, 2));"},{"lineNumber":1713,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1714,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1715,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1716,"author":{"gitId":"-"},"content":""},{"lineNumber":1717,"author":{"gitId":"-"},"content":" private WebElement getAllowDuplicateRankCheckbox(int questionNum) {"},{"lineNumber":1718,"author":{"gitId":"-"},"content":" return getQuestionForm(questionNum).findElement(By.id(\"duplicate-rank-checkbox\"));"},{"lineNumber":1719,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1720,"author":{"gitId":"-"},"content":""},{"lineNumber":1721,"author":{"gitId":"-"},"content":" private void inputRankDetails(int questionNum, FeedbackRankQuestionDetails questionDetails) {"},{"lineNumber":1722,"author":{"gitId":"-"},"content":" if (questionDetails instanceof FeedbackRankOptionsQuestionDetails) {"},{"lineNumber":1723,"author":{"gitId":"-"},"content":" FeedbackRankOptionsQuestionDetails optionDetails \u003d (FeedbackRankOptionsQuestionDetails) questionDetails;"},{"lineNumber":1724,"author":{"gitId":"-"},"content":" inputOptions(questionNum, optionDetails.getOptions());"},{"lineNumber":1725,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1726,"author":{"gitId":"-"},"content":" if (questionDetails.isAreDuplicatesAllowed()) {"},{"lineNumber":1727,"author":{"gitId":"-"},"content":" markOptionAsSelected(getAllowDuplicateRankCheckbox(questionNum));"},{"lineNumber":1728,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1729,"author":{"gitId":"-"},"content":" markOptionAsUnselected(getAllowDuplicateRankCheckbox(questionNum));"},{"lineNumber":1730,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1731,"author":{"gitId":"-"},"content":" inputMaxOptions(questionNum, questionDetails.getMaxOptionsToBeRanked());"},{"lineNumber":1732,"author":{"gitId":"-"},"content":" inputMinOptions(questionNum, questionDetails.getMinOptionsToBeRanked());"},{"lineNumber":1733,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1734,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":5,"dishenggg":13,"mingyuanc":5,"-":1711}},{"path":"src/e2e/java/teammates/e2e/pageobjects/RequestPage.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.e2e.pageobjects;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import org.openqa.selenium.By;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import org.openqa.selenium.WebElement;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import org.openqa.selenium.support.FindBy;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":" * Page Object Model for account request form page."},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"public class RequestPage extends AppPage {"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":" @FindBy(id \u003d \"btn-am-instructor\")"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":" private WebElement amInstructorButton;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":" @FindBy(id \u003d \"name\")"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":" private WebElement nameBox;"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" @FindBy(id \u003d \"institution\")"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":" private WebElement institutionBox;"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":" @FindBy(id \u003d \"country\")"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" private WebElement countryBox;"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":" @FindBy(id \u003d \"email\")"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":" private WebElement emailBox;"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" @FindBy(id \u003d \"comments\")"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" private WebElement commentsBox;"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" @FindBy(id \u003d \"submit-button\")"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" private WebElement submitButton;"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" public RequestPage(Browser browser) {"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" super(browser);"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" protected boolean containsExpectedPageContents() {"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" return getPageTitle().contains(\"Request for an Instructor Account\");"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" public void clickAmInstructorButton() {"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" click(amInstructorButton);"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" waitForPageToLoad();"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" public void fillForm(String name, String institution, String country, String email, String comments) {"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" fillTextBox(nameBox, name);"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" fillTextBox(institutionBox, institution);"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" fillTextBox(countryBox, country);"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" fillTextBox(emailBox, email);"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" fillTextBox(commentsBox, comments);"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" public void clickSubmitFormButton() {"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" click(submitButton);"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" waitForPageToLoad();"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" public void verifySubmittedInfo(String name, String institution, String country, String email, String comments) {"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" WebElement table \u003d browser.driver.findElement(By.className(\"table\"));"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" String[][] expected \u003d {"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" { name },"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" { institution },"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" { country },"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" { email },"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" { comments },"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" verifyTableBodyValues(table, expected);"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":71}},{"path":"src/e2e/java/teammates/e2e/pageobjects/StudentHomePage.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.e2e.pageobjects;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static org.junit.jupiter.api.Assertions.assertTrue;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.openqa.selenium.By;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.openqa.selenium.WebElement;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * Page Object Model for student home page."},{"lineNumber":12,"author":{"gitId":"-"},"content":" */"},{"lineNumber":13,"author":{"gitId":"-"},"content":"public class StudentHomePage extends AppPage {"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":" public StudentHomePage(Browser browser) {"},{"lineNumber":16,"author":{"gitId":"-"},"content":" super(browser);"},{"lineNumber":17,"author":{"gitId":"-"},"content":" }"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":20,"author":{"gitId":"-"},"content":" protected boolean containsExpectedPageContents() {"},{"lineNumber":21,"author":{"gitId":"-"},"content":" return \"Student Home\".equals(getPageTitle());"},{"lineNumber":22,"author":{"gitId":"-"},"content":" }"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" private List\u003cWebElement\u003e getStudentHomeCoursePanels() {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" return browser.driver.findElements(By.cssSelector(\"div.card.bg-light\"));"},{"lineNumber":26,"author":{"gitId":"-"},"content":" }"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" public int getStudentHomeCoursePanelIndex(String courseName) {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" List\u003cWebElement\u003e coursePanels \u003d getStudentHomeCoursePanels();"},{"lineNumber":30,"author":{"gitId":"-"},"content":" int coursePanelIndex \u003d -1;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c coursePanels.size(); i++) {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" if (coursePanels.get(i).getText().contains(courseName)) {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" coursePanelIndex \u003d i;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":" assertTrue(coursePanelIndex \u003e\u003d 0);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" return coursePanelIndex;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" }"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" public void verifyVisibleFeedbackSessionToStudents(String feedbackSessionName, int index) {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" assertTrue(getStudentHomeCoursePanels().get(index)"},{"lineNumber":42,"author":{"gitId":"-"},"content":" .findElement(By.cssSelector(\"div.table-responsive table.table tbody\")).getText()"},{"lineNumber":43,"author":{"gitId":"-"},"content":" .contains(feedbackSessionName));"},{"lineNumber":44,"author":{"gitId":"-"},"content":" }"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" public void clickCloseNotificationBannerButton() {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" WebElement closeNotifButton \u003d browser.driver.findElement(By.id(\"btn-close-notif\"));"},{"lineNumber":48,"author":{"gitId":"-"},"content":" waitForElementToBeClickable(closeNotifButton);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" click(closeNotifButton);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" waitUntilAnimationFinish();"},{"lineNumber":51,"author":{"gitId":"-"},"content":" }"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" public void clickMarkAsReadButton() {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" WebElement markNotifAsReadButton \u003d browser.driver.findElement(By.id(\"btn-mark-as-read\"));"},{"lineNumber":55,"author":{"gitId":"-"},"content":" waitForElementToBeClickable(markNotifAsReadButton);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" click(markNotifAsReadButton);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" waitUntilAnimationFinish();"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"yuanxi1"},"content":" public String getNotificationId() {"},{"lineNumber":61,"author":{"gitId":"yuanxi1"},"content":" WebElement notificationBanner \u003d browser.driver.findElement(By.id(\"notification-banner\"));"},{"lineNumber":62,"author":{"gitId":"yuanxi1"},"content":" return notificationBanner.getAttribute(\"data-testid\");"},{"lineNumber":63,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":64,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"yuanxi1":5,"-":60}},{"path":"src/it/java/teammates/it/sqllogic/core/AccountRequestsLogicIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.AccountRequestsLogic;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.AccountRequestsDb;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * SUT: {@link AccountRequestsLogic}."},{"lineNumber":19,"author":{"gitId":"-"},"content":" */"},{"lineNumber":20,"author":{"gitId":"-"},"content":"public class AccountRequestsLogicIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" private AccountRequestsLogic accountRequestsLogic \u003d AccountRequestsLogic.inst();"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":25,"author":{"gitId":"-"},"content":" public void testGetAccountRequest_nonExistentAccountRequest_returnsNull() {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" UUID id \u003d UUID.randomUUID();"},{"lineNumber":27,"author":{"gitId":"-"},"content":" AccountRequest actualAccountRequest \u003d accountRequestsLogic.getAccountRequest(id);"},{"lineNumber":28,"author":{"gitId":"-"},"content":" assertNull(actualAccountRequest);"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":32,"author":{"gitId":"-"},"content":" public void testGetAccountRequest_existingAccountRequest_getsSuccessfully() throws InvalidParametersException {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" AccountRequest expectedAccountRequest \u003d"},{"lineNumber":34,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":35,"author":{"gitId":"-"},"content":" UUID id \u003d expectedAccountRequest.getId();"},{"lineNumber":36,"author":{"gitId":"-"},"content":" accountRequestsLogic.createAccountRequest(expectedAccountRequest);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" AccountRequest actualAccountRequest \u003d accountRequestsLogic.getAccountRequest(id);"},{"lineNumber":38,"author":{"gitId":"-"},"content":" assertEquals(expectedAccountRequest, actualAccountRequest);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":42,"author":{"gitId":"-"},"content":" public void testResetAccountRequest()"},{"lineNumber":43,"author":{"gitId":"-"},"content":" throws EntityAlreadyExistsException, InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" ______TS(\"success: create account request and update registeredAt field\");"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" String name \u003d \"name lee\";"},{"lineNumber":48,"author":{"gitId":"-"},"content":" String email \u003d \"email@gmail.com\";"},{"lineNumber":49,"author":{"gitId":"-"},"content":" String institute \u003d \"institute\";"},{"lineNumber":50,"author":{"gitId":"-"},"content":" AccountRequestStatus status \u003d AccountRequestStatus.PENDING;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" String comments \u003d \"comments\";"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" AccountRequest toReset \u003d accountRequestsLogic.createAccountRequest(name, email, institute, status, comments);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" AccountRequestsDb accountRequestsDb \u003d AccountRequestsDb.inst();"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" toReset.setRegisteredAt(Instant.now());"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" UUID id \u003d toReset.getId();"},{"lineNumber":58,"author":{"gitId":"-"},"content":" toReset \u003d accountRequestsDb.getAccountRequest(id);"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" assertNotNull(toReset);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" assertNotNull(toReset.getRegisteredAt());"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" ______TS(\"success: reset account request that already exists\");"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" AccountRequest resetted \u003d accountRequestsLogic.resetAccountRequest(id);"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" assertNull(resetted.getRegisteredAt());"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" ______TS(\"success: test delete account request\");"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" accountRequestsLogic.deleteAccountRequest(toReset.getId());"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" assertNull(accountRequestsLogic.getAccountRequest(toReset.getId()));"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" ______TS(\"failure: reset account request that does not exist\");"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" () -\u003e accountRequestsLogic.resetAccountRequest(id));"},{"lineNumber":79,"author":{"gitId":"-"},"content":" }"},{"lineNumber":80,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":5,"-":75}},{"path":"src/it/java/teammates/it/sqllogic/core/AccountsLogicIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":8,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationStyle;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationTargetUser;"},{"lineNumber":13,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":17,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":18,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":19,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.StringHelper;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.AccountsLogic;"},{"lineNumber":22,"author":{"gitId":"yuanxi1"},"content":"import teammates.sqllogic.core.CoursesLogic;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.NotificationsLogic;"},{"lineNumber":24,"author":{"gitId":"yuanxi1"},"content":"import teammates.sqllogic.core.UsersLogic;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.AccountsDb;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":27,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":28,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.ReadNotification;"},{"lineNumber":31,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":32,"author":{"gitId":"yuanxi1"},"content":"import teammates.test.AssertHelper;"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":35,"author":{"gitId":"-"},"content":" * SUT: {@link AccountsLogic}."},{"lineNumber":36,"author":{"gitId":"-"},"content":" */"},{"lineNumber":37,"author":{"gitId":"-"},"content":"public class AccountsLogicIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" private AccountsLogic accountsLogic \u003d AccountsLogic.inst();"},{"lineNumber":40,"author":{"gitId":"-"},"content":" private NotificationsLogic notificationsLogic \u003d NotificationsLogic.inst();"},{"lineNumber":41,"author":{"gitId":"yuanxi1"},"content":" private UsersLogic usersLogic \u003d UsersLogic.inst();"},{"lineNumber":42,"author":{"gitId":"yuanxi1"},"content":" private CoursesLogic coursesLogic \u003d CoursesLogic.inst();"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" private AccountsDb accountsDb \u003d AccountsDb.inst();"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"yuanxi1"},"content":" private SqlDataBundle typicalDataBundle;"},{"lineNumber":47,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":48,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":49,"author":{"gitId":"yuanxi1"},"content":" @BeforeClass"},{"lineNumber":50,"author":{"gitId":"yuanxi1"},"content":" public void setupClass() {"},{"lineNumber":51,"author":{"gitId":"yuanxi1"},"content":" super.setupClass();"},{"lineNumber":52,"author":{"gitId":"yuanxi1"},"content":" typicalDataBundle \u003d getTypicalSqlDataBundle();"},{"lineNumber":53,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":54,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":55,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":56,"author":{"gitId":"yuanxi1"},"content":" @BeforeMethod"},{"lineNumber":57,"author":{"gitId":"yuanxi1"},"content":" protected void setUp() throws Exception {"},{"lineNumber":58,"author":{"gitId":"yuanxi1"},"content":" super.setUp();"},{"lineNumber":59,"author":{"gitId":"yuanxi1"},"content":" persistDataBundle(typicalDataBundle);"},{"lineNumber":60,"author":{"gitId":"yuanxi1"},"content":" HibernateUtil.flushSession();"},{"lineNumber":61,"author":{"gitId":"yuanxi1"},"content":" HibernateUtil.clearSession();"},{"lineNumber":62,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":63,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":65,"author":{"gitId":"-"},"content":" public void testUpdateReadNotifications()"},{"lineNumber":66,"author":{"gitId":"-"},"content":" throws EntityAlreadyExistsException, InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" ______TS(\"success: mark notification as read\");"},{"lineNumber":68,"author":{"gitId":"-"},"content":" Account account \u003d new Account(\"google-id\", \"name\", \"email@teammates.com\");"},{"lineNumber":69,"author":{"gitId":"-"},"content":" Notification notification \u003d new Notification(Instant.parse(\"2011-01-01T00:00:00Z\"),"},{"lineNumber":70,"author":{"gitId":"-"},"content":" Instant.parse(\"2099-01-01T00:00:00Z\"), NotificationStyle.DANGER, NotificationTargetUser.GENERAL,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" \"A deprecation note\", \"\u003cp\u003eDeprecation happens in three minutes\u003c/p\u003e\");"},{"lineNumber":72,"author":{"gitId":"-"},"content":" accountsDb.createAccount(account);"},{"lineNumber":73,"author":{"gitId":"-"},"content":" notificationsLogic.createNotification(notification);"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":76,"author":{"gitId":"-"},"content":" UUID notificationId \u003d notification.getId();"},{"lineNumber":77,"author":{"gitId":"-"},"content":" accountsLogic.updateReadNotifications(googleId, notificationId, notification.getEndTime());"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" Account actualAccount \u003d accountsDb.getAccountByGoogleId(googleId);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" List\u003cReadNotification\u003e accountReadNotifications \u003d actualAccount.getReadNotifications();"},{"lineNumber":81,"author":{"gitId":"-"},"content":" assertEquals(1, accountReadNotifications.size());"},{"lineNumber":82,"author":{"gitId":"-"},"content":" assertSame(actualAccount, accountReadNotifications.get(0).getAccount());"},{"lineNumber":83,"author":{"gitId":"-"},"content":" assertSame(notification, accountReadNotifications.get(0).getNotification());"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":86,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":87,"author":{"gitId":"yuanxi1"},"content":" public void testJoinCourseForStudent()"},{"lineNumber":88,"author":{"gitId":"yuanxi1"},"content":" throws EntityAlreadyExistsException, InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":89,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":90,"author":{"gitId":"yuanxi1"},"content":" Student student2YetToJoinCourse \u003d typicalDataBundle.students.get(\"student2YetToJoinCourse4\");"},{"lineNumber":91,"author":{"gitId":"yuanxi1"},"content":" Student student3YetToJoinCourse \u003d typicalDataBundle.students.get(\"student3YetToJoinCourse4\");"},{"lineNumber":92,"author":{"gitId":"yuanxi1"},"content":" Student studentInCourse \u003d typicalDataBundle.students.get(\"student1InCourse1\");"},{"lineNumber":93,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":94,"author":{"gitId":"yuanxi1"},"content":" String loggedInGoogleId \u003d \"AccLogicT.student.id\";"},{"lineNumber":95,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":96,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: wrong key\");"},{"lineNumber":97,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":98,"author":{"gitId":"yuanxi1"},"content":" String wrongKey \u003d StringHelper.encrypt(\"wrongkey\");"},{"lineNumber":99,"author":{"gitId":"yuanxi1"},"content":" EntityDoesNotExistException ednee \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":100,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForStudent(wrongKey, loggedInGoogleId));"},{"lineNumber":101,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"No student with given registration key: \" + wrongKey, ednee.getMessage());"},{"lineNumber":102,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":103,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: invalid parameters\");"},{"lineNumber":104,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":105,"author":{"gitId":"yuanxi1"},"content":" InvalidParametersException ipe \u003d assertThrows(InvalidParametersException.class,"},{"lineNumber":106,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForStudent(student2YetToJoinCourse.getRegKey(), \"wrong student\"));"},{"lineNumber":107,"author":{"gitId":"yuanxi1"},"content":" AssertHelper.assertContains(FieldValidator.REASON_INCORRECT_FORMAT, ipe.getMessage());"},{"lineNumber":108,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":109,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: googleID belongs to an existing student in the course\");"},{"lineNumber":110,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":111,"author":{"gitId":"yuanxi1"},"content":" EntityAlreadyExistsException eaee \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":112,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForStudent(student2YetToJoinCourse.getRegKey(),"},{"lineNumber":113,"author":{"gitId":"yuanxi1"},"content":" studentInCourse.getGoogleId()));"},{"lineNumber":114,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"Student has already joined course\", eaee.getMessage());"},{"lineNumber":115,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":116,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: with encryption and new account to be created\");"},{"lineNumber":117,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":118,"author":{"gitId":"yuanxi1"},"content":" accountsLogic.joinCourseForStudent(student2YetToJoinCourse.getRegKey(), loggedInGoogleId);"},{"lineNumber":119,"author":{"gitId":"yuanxi1"},"content":" Account accountCreated \u003d accountsLogic.getAccountForGoogleId(loggedInGoogleId);"},{"lineNumber":120,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":121,"author":{"gitId":"yuanxi1"},"content":" assertEquals(loggedInGoogleId, usersLogic.getStudentForEmail("},{"lineNumber":122,"author":{"gitId":"yuanxi1"},"content":" student2YetToJoinCourse.getCourseId(), student2YetToJoinCourse.getEmail()).getGoogleId());"},{"lineNumber":123,"author":{"gitId":"yuanxi1"},"content":" assertNotNull(accountCreated);"},{"lineNumber":124,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":125,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: student joined but account already exists\");"},{"lineNumber":126,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":127,"author":{"gitId":"yuanxi1"},"content":" String existingAccountId \u003d \"existingAccountId\";"},{"lineNumber":128,"author":{"gitId":"yuanxi1"},"content":" Account existingAccount \u003d new Account(existingAccountId, \"accountName\", student3YetToJoinCourse.getEmail());"},{"lineNumber":129,"author":{"gitId":"yuanxi1"},"content":" accountsDb.createAccount(existingAccount);"},{"lineNumber":130,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":131,"author":{"gitId":"yuanxi1"},"content":" accountsLogic.joinCourseForStudent(student3YetToJoinCourse.getRegKey(), existingAccountId);"},{"lineNumber":132,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":133,"author":{"gitId":"yuanxi1"},"content":" assertEquals(existingAccountId, usersLogic.getStudentForEmail("},{"lineNumber":134,"author":{"gitId":"yuanxi1"},"content":" student3YetToJoinCourse.getCourseId(), student3YetToJoinCourse.getEmail()).getGoogleId());"},{"lineNumber":135,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":136,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: already joined\");"},{"lineNumber":137,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":138,"author":{"gitId":"yuanxi1"},"content":" eaee \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":139,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForStudent(student2YetToJoinCourse.getRegKey(), loggedInGoogleId));"},{"lineNumber":140,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"Student has already joined course\", eaee.getMessage());"},{"lineNumber":141,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":142,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: course is deleted\");"},{"lineNumber":143,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":144,"author":{"gitId":"yuanxi1"},"content":" Course originalCourse \u003d usersLogic.getStudentForEmail("},{"lineNumber":145,"author":{"gitId":"yuanxi1"},"content":" student2YetToJoinCourse.getCourseId(), student2YetToJoinCourse.getEmail()).getCourse();"},{"lineNumber":146,"author":{"gitId":"yuanxi1"},"content":" coursesLogic.moveCourseToRecycleBin(originalCourse.getId());"},{"lineNumber":147,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":148,"author":{"gitId":"yuanxi1"},"content":" ednee \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":149,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForStudent(student2YetToJoinCourse.getRegKey(),"},{"lineNumber":150,"author":{"gitId":"yuanxi1"},"content":" loggedInGoogleId));"},{"lineNumber":151,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"The course you are trying to join has been deleted by an instructor\", ednee.getMessage());"},{"lineNumber":152,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":153,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":154,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":155,"author":{"gitId":"yuanxi1"},"content":" public void testJoinCourseForInstructor() throws Exception {"},{"lineNumber":156,"author":{"gitId":"yuanxi1"},"content":" String instructorIdAlreadyJoinedCourse \u003d \"instructor1\";"},{"lineNumber":157,"author":{"gitId":"yuanxi1"},"content":" Instructor instructor2YetToJoinCourse \u003d typicalDataBundle.instructors.get(\"instructor2YetToJoinCourse4\");"},{"lineNumber":158,"author":{"gitId":"yuanxi1"},"content":" Instructor instructor3YetToJoinCourse \u003d typicalDataBundle.instructors.get(\"instructor3YetToJoinCourse4\");"},{"lineNumber":159,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":160,"author":{"gitId":"yuanxi1"},"content":" String loggedInGoogleId \u003d \"AccLogicT.instr.id\";"},{"lineNumber":161,"author":{"gitId":"yuanxi1"},"content":" String[] key \u003d new String[] {"},{"lineNumber":162,"author":{"gitId":"yuanxi1"},"content":" getRegKeyForInstructor(instructor2YetToJoinCourse.getCourseId(), instructor2YetToJoinCourse.getEmail()),"},{"lineNumber":163,"author":{"gitId":"yuanxi1"},"content":" getRegKeyForInstructor(instructor2YetToJoinCourse.getCourseId(), instructor3YetToJoinCourse.getEmail()),"},{"lineNumber":164,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":165,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":166,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: googleID belongs to an existing instructor in the course\");"},{"lineNumber":167,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":168,"author":{"gitId":"yuanxi1"},"content":" EntityAlreadyExistsException eaee \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":169,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForInstructor("},{"lineNumber":170,"author":{"gitId":"yuanxi1"},"content":" key[0], instructorIdAlreadyJoinedCourse));"},{"lineNumber":171,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"Instructor has already joined course\", eaee.getMessage());"},{"lineNumber":172,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":173,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: instructor joined and new account be created\");"},{"lineNumber":174,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":175,"author":{"gitId":"yuanxi1"},"content":" accountsLogic.joinCourseForInstructor(key[0], loggedInGoogleId);"},{"lineNumber":176,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":177,"author":{"gitId":"yuanxi1"},"content":" Instructor joinedInstructor \u003d usersLogic.getInstructorForEmail("},{"lineNumber":178,"author":{"gitId":"yuanxi1"},"content":" instructor2YetToJoinCourse.getCourseId(), instructor2YetToJoinCourse.getEmail());"},{"lineNumber":179,"author":{"gitId":"yuanxi1"},"content":" assertEquals(loggedInGoogleId, joinedInstructor.getGoogleId());"},{"lineNumber":180,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":181,"author":{"gitId":"yuanxi1"},"content":" Account accountCreated \u003d accountsLogic.getAccountForGoogleId(loggedInGoogleId);"},{"lineNumber":182,"author":{"gitId":"yuanxi1"},"content":" assertNotNull(accountCreated);"},{"lineNumber":183,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":184,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: instructor joined but account already exists\");"},{"lineNumber":185,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":186,"author":{"gitId":"yuanxi1"},"content":" String existingAccountId \u003d \"existingAccountId\";"},{"lineNumber":187,"author":{"gitId":"yuanxi1"},"content":" Account existingAccount \u003d new Account(existingAccountId, \"accountName\", instructor3YetToJoinCourse.getEmail());"},{"lineNumber":188,"author":{"gitId":"yuanxi1"},"content":" accountsDb.createAccount(existingAccount);"},{"lineNumber":189,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":190,"author":{"gitId":"yuanxi1"},"content":" accountsLogic.joinCourseForInstructor(key[1], existingAccount.getGoogleId());"},{"lineNumber":191,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":192,"author":{"gitId":"yuanxi1"},"content":" joinedInstructor \u003d usersLogic.getInstructorForEmail("},{"lineNumber":193,"author":{"gitId":"yuanxi1"},"content":" instructor3YetToJoinCourse.getCourseId(), existingAccount.getEmail());"},{"lineNumber":194,"author":{"gitId":"yuanxi1"},"content":" assertEquals(existingAccountId, joinedInstructor.getGoogleId());"},{"lineNumber":195,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":196,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: instructor already joined\");"},{"lineNumber":197,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":198,"author":{"gitId":"yuanxi1"},"content":" eaee \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":199,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForInstructor(key[0], loggedInGoogleId));"},{"lineNumber":200,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"Instructor has already joined course\", eaee.getMessage());"},{"lineNumber":201,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":202,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: key belongs to a different user\");"},{"lineNumber":203,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":204,"author":{"gitId":"yuanxi1"},"content":" eaee \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":205,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForInstructor(key[0], \"otherUserId\"));"},{"lineNumber":206,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"Instructor has already joined course\", eaee.getMessage());"},{"lineNumber":207,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":208,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: invalid key\");"},{"lineNumber":209,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":210,"author":{"gitId":"yuanxi1"},"content":" String invalidKey \u003d StringHelper.encrypt(\"invalidKey\");"},{"lineNumber":211,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":212,"author":{"gitId":"yuanxi1"},"content":" EntityDoesNotExistException ednee \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":213,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForInstructor(invalidKey, loggedInGoogleId));"},{"lineNumber":214,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"No instructor with given registration key: \" + invalidKey,"},{"lineNumber":215,"author":{"gitId":"yuanxi1"},"content":" ednee.getMessage());"},{"lineNumber":216,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":217,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: course deleted\");"},{"lineNumber":218,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":219,"author":{"gitId":"yuanxi1"},"content":" Course originalCourse \u003d usersLogic.getInstructorForEmail("},{"lineNumber":220,"author":{"gitId":"yuanxi1"},"content":" instructor2YetToJoinCourse.getCourseId(), instructor2YetToJoinCourse.getEmail()).getCourse();"},{"lineNumber":221,"author":{"gitId":"yuanxi1"},"content":" coursesLogic.moveCourseToRecycleBin(originalCourse.getId());"},{"lineNumber":222,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":223,"author":{"gitId":"yuanxi1"},"content":" ednee \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":224,"author":{"gitId":"yuanxi1"},"content":" () -\u003e accountsLogic.joinCourseForInstructor(instructor2YetToJoinCourse.getRegKey(),"},{"lineNumber":225,"author":{"gitId":"yuanxi1"},"content":" instructor2YetToJoinCourse.getGoogleId()));"},{"lineNumber":226,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"The course you are trying to join has been deleted by an instructor\", ednee.getMessage());"},{"lineNumber":227,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":228,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":229,"author":{"gitId":"yuanxi1"},"content":" private String getRegKeyForInstructor(String courseId, String email) {"},{"lineNumber":230,"author":{"gitId":"yuanxi1"},"content":" return usersLogic.getInstructorForEmail(courseId, email).getRegKey();"},{"lineNumber":231,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"yuanxi1":179,"-":53}},{"path":"src/it/java/teammates/it/sqllogic/core/FeedbackQuestionsLogicIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionDetails;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionType;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackTextQuestionDetails;"},{"lineNumber":16,"author":{"gitId":"marquestye"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.FeedbackQuestionsLogic;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackVisibilityType;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.ui.output.NumberOfEntitiesToGiveFeedbackToSetting;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.ui.request.FeedbackQuestionUpdateRequest;"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":29,"author":{"gitId":"-"},"content":" * SUT: {@link FeedbackQuestionsLogic}."},{"lineNumber":30,"author":{"gitId":"-"},"content":" */"},{"lineNumber":31,"author":{"gitId":"-"},"content":"public class FeedbackQuestionsLogicIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private FeedbackQuestionsLogic fqLogic \u003d FeedbackQuestionsLogic.inst();"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" private SqlDataBundle typicalDataBundle;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"-"},"content":" @BeforeClass"},{"lineNumber":39,"author":{"gitId":"-"},"content":" public void setupClass() {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" super.setupClass();"},{"lineNumber":41,"author":{"gitId":"-"},"content":" typicalDataBundle \u003d getTypicalSqlDataBundle();"},{"lineNumber":42,"author":{"gitId":"-"},"content":" }"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":45,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":46,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":48,"author":{"gitId":"-"},"content":" persistDataBundle(typicalDataBundle);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":50,"author":{"gitId":"-"},"content":" }"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":53,"author":{"gitId":"marquestye"},"content":" public void testCreateFeedbackQuestion() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d typicalDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":55,"author":{"gitId":"-"},"content":" FeedbackTextQuestionDetails newQuestionDetails \u003d new FeedbackTextQuestionDetails(\"New question text.\");"},{"lineNumber":56,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showTos \u003d new ArrayList\u003c\u003e();"},{"lineNumber":57,"author":{"gitId":"-"},"content":" showTos.add(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":58,"author":{"gitId":"-"},"content":" FeedbackQuestion newQuestion \u003d FeedbackQuestion.makeQuestion(fs, 6, \"This is a new text question\","},{"lineNumber":59,"author":{"gitId":"-"},"content":" FeedbackParticipantType.STUDENTS, FeedbackParticipantType.OWN_TEAM_MEMBERS, -100,"},{"lineNumber":60,"author":{"gitId":"-"},"content":" showTos, showTos, showTos, newQuestionDetails);"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" newQuestion \u003d fqLogic.createFeedbackQuestion(newQuestion);"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" FeedbackQuestion actualQuestion \u003d fqLogic.getFeedbackQuestion(newQuestion.getId());"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" verifyEquals(newQuestion, actualQuestion);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":70,"author":{"gitId":"-"},"content":" public void testGetFeedbackQuestionsForSession() {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d typicalDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":72,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d typicalDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":73,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d typicalDataBundle.feedbackQuestions.get(\"qn2InSession1InCourse1\");"},{"lineNumber":74,"author":{"gitId":"-"},"content":" FeedbackQuestion fq3 \u003d typicalDataBundle.feedbackQuestions.get(\"qn3InSession1InCourse1\");"},{"lineNumber":75,"author":{"gitId":"-"},"content":" FeedbackQuestion fq4 \u003d typicalDataBundle.feedbackQuestions.get(\"qn4InSession1InCourse1\");"},{"lineNumber":76,"author":{"gitId":"-"},"content":" FeedbackQuestion fq5 \u003d typicalDataBundle.feedbackQuestions.get(\"qn5InSession1InCourse1\");"},{"lineNumber":77,"author":{"gitId":"-"},"content":" FeedbackQuestion fq6 \u003d typicalDataBundle.feedbackQuestions.get(\"qn6InSession1InCourse1NoResponses\");"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e expectedQuestions \u003d List.of(fq1, fq2, fq3, fq4, fq5, fq6);"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e actualQuestions \u003d fqLogic.getFeedbackQuestionsForSession(fs);"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestions.size(), actualQuestions.size());"},{"lineNumber":84,"author":{"gitId":"-"},"content":" assertTrue(expectedQuestions.containsAll(actualQuestions));"},{"lineNumber":85,"author":{"gitId":"-"},"content":" }"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":88,"author":{"gitId":"-"},"content":" public void testUpdateFeedbackQuestionCascade() throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":89,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d typicalDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":90,"author":{"gitId":"-"},"content":" fq1.setDescription(\"New question description\");"},{"lineNumber":91,"author":{"gitId":"-"},"content":" FeedbackQuestionUpdateRequest updateRequest \u003d generateFeedbackQuestionUpdateRequest("},{"lineNumber":92,"author":{"gitId":"-"},"content":" fq1.getQuestionNumber(),"},{"lineNumber":93,"author":{"gitId":"-"},"content":" fq1.getDescription(),"},{"lineNumber":94,"author":{"gitId":"-"},"content":" fq1.getQuestionDetailsCopy(),"},{"lineNumber":95,"author":{"gitId":"-"},"content":" fq1.getQuestionDetailsCopy().getQuestionType(),"},{"lineNumber":96,"author":{"gitId":"-"},"content":" fq1.getGiverType(),"},{"lineNumber":97,"author":{"gitId":"-"},"content":" fq1.getRecipientType(),"},{"lineNumber":98,"author":{"gitId":"-"},"content":" fq1.getNumOfEntitiesToGiveFeedbackTo(),"},{"lineNumber":99,"author":{"gitId":"-"},"content":" fq1.getShowResponsesTo(),"},{"lineNumber":100,"author":{"gitId":"-"},"content":" fq1.getShowGiverNameTo(),"},{"lineNumber":101,"author":{"gitId":"-"},"content":" fq1.getShowRecipientNameTo()"},{"lineNumber":102,"author":{"gitId":"-"},"content":" );"},{"lineNumber":103,"author":{"gitId":"-"},"content":" updateRequest.setNumberOfEntitiesToGiveFeedbackToSetting(NumberOfEntitiesToGiveFeedbackToSetting.CUSTOM);"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" fqLogic.updateFeedbackQuestionCascade(fq1.getId(), updateRequest);"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" FeedbackQuestion actualFeedbackQuestion \u003d fqLogic.getFeedbackQuestion(fq1.getId());"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" verifyEquals(fq1, actualFeedbackQuestion);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" private FeedbackQuestionUpdateRequest generateFeedbackQuestionUpdateRequest("},{"lineNumber":113,"author":{"gitId":"-"},"content":" int questionNumber,"},{"lineNumber":114,"author":{"gitId":"-"},"content":" String questionDescription,"},{"lineNumber":115,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails questionDetails,"},{"lineNumber":116,"author":{"gitId":"-"},"content":" FeedbackQuestionType questionType,"},{"lineNumber":117,"author":{"gitId":"-"},"content":" FeedbackParticipantType giverType,"},{"lineNumber":118,"author":{"gitId":"-"},"content":" FeedbackParticipantType recipientType,"},{"lineNumber":119,"author":{"gitId":"-"},"content":" Integer customNumberOfEntitiesToGiveFeedbackTo,"},{"lineNumber":120,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showResponsesTo,"},{"lineNumber":121,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showGiverNameTo,"},{"lineNumber":122,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showRecipientNameTo"},{"lineNumber":123,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":124,"author":{"gitId":"-"},"content":" FeedbackQuestionUpdateRequest updateRequest \u003d new FeedbackQuestionUpdateRequest();"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" updateRequest.setQuestionNumber(questionNumber);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" updateRequest.setQuestionDescription(questionDescription);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" updateRequest.setQuestionDetails(questionDetails);"},{"lineNumber":129,"author":{"gitId":"-"},"content":" updateRequest.setQuestionType(questionType);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" updateRequest.setGiverType(giverType);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" updateRequest.setRecipientType(recipientType);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" updateRequest.setCustomNumberOfEntitiesToGiveFeedbackTo(customNumberOfEntitiesToGiveFeedbackTo);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" updateRequest.setShowResponsesTo(convertToFeedbackVisibilityType(showResponsesTo));"},{"lineNumber":134,"author":{"gitId":"-"},"content":" updateRequest.setShowGiverNameTo(convertToFeedbackVisibilityType(showGiverNameTo));"},{"lineNumber":135,"author":{"gitId":"-"},"content":" updateRequest.setShowRecipientNameTo(convertToFeedbackVisibilityType(showRecipientNameTo));"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" return updateRequest;"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" private List\u003cFeedbackVisibilityType\u003e convertToFeedbackVisibilityType("},{"lineNumber":141,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e feedbackParticipantTypes) {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" return feedbackParticipantTypes.stream().map(feedbackParticipantType -\u003e {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" switch (feedbackParticipantType) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":145,"author":{"gitId":"-"},"content":" return FeedbackVisibilityType.STUDENTS;"},{"lineNumber":146,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":147,"author":{"gitId":"-"},"content":" return FeedbackVisibilityType.INSTRUCTORS;"},{"lineNumber":148,"author":{"gitId":"-"},"content":" case RECEIVER:"},{"lineNumber":149,"author":{"gitId":"-"},"content":" return FeedbackVisibilityType.RECIPIENT;"},{"lineNumber":150,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":151,"author":{"gitId":"-"},"content":" return FeedbackVisibilityType.GIVER_TEAM_MEMBERS;"},{"lineNumber":152,"author":{"gitId":"-"},"content":" case RECEIVER_TEAM_MEMBERS:"},{"lineNumber":153,"author":{"gitId":"-"},"content":" return FeedbackVisibilityType.RECIPIENT_TEAM_MEMBERS;"},{"lineNumber":154,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":155,"author":{"gitId":"-"},"content":" assert false : \"Unknown feedbackParticipantType\" + feedbackParticipantType;"},{"lineNumber":156,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":157,"author":{"gitId":"-"},"content":" }"},{"lineNumber":158,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }).collect(Collectors.toList());"},{"lineNumber":160,"author":{"gitId":"-"},"content":" }"},{"lineNumber":161,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":2,"-":159}},{"path":"src/it/java/teammates/it/sqllogic/core/FeedbackSessionLogsLogicIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.it.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import teammates.sqllogic.core.FeedbackSessionLogsLogic;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link FeedbackSessionLogsLogic}."},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":"public class FeedbackSessionLogsLogicIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" private FeedbackSessionLogsLogic fslLogic \u003d FeedbackSessionLogsLogic.inst();"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" private SqlDataBundle typicalDataBundle;"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" @BeforeClass"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" public void setupClass() {"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" super.setupClass();"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" typicalDataBundle \u003d getTypicalSqlDataBundle();"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" @BeforeMethod"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" protected void setUp() throws Exception {"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" super.setUp();"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" persistDataBundle(typicalDataBundle);"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" HibernateUtil.flushSession();"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" HibernateUtil.clearSession();"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" public void test_createFeedbackSessionLog_success() {"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" Course course \u003d typicalDataBundle.courses.get(\"course1\");"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" FeedbackSession fs \u003d typicalDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" Student student \u003d typicalDataBundle.students.get(\"student1InCourse1\");"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" Instant timestamp \u003d Instant.now();"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog newLog1 \u003d new FeedbackSessionLog(student, fs, FeedbackSessionLogType.ACCESS, timestamp);"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog newLog2 \u003d new FeedbackSessionLog(student, fs, FeedbackSessionLogType.SUBMISSION, timestamp);"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog newLog3 \u003d new FeedbackSessionLog(student, fs, FeedbackSessionLogType.VIEW_RESULT, timestamp);"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e expected \u003d List.of(newLog1, newLog2, newLog3);"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" fslLogic.createFeedbackSessionLogs(expected);"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e actual \u003d fslLogic.getOrderedFeedbackSessionLogs(course.getId(), student.getId(),"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" fs.getId(), timestamp, timestamp.plusSeconds(1));"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" assertEquals(expected, actual);"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" public void test_getOrderedFeedbackSessionLogs_success() {"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" Instant startTime \u003d Instant.parse(\"2012-01-01T12:00:00Z\");"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" Instant endTime \u003d Instant.parse(\"2012-01-01T23:59:59Z\");"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" Course course \u003d typicalDataBundle.courses.get(\"course1\");"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" Student student1 \u003d typicalDataBundle.students.get(\"student1InCourse1\");"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" FeedbackSession fs1 \u003d typicalDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student1Session1Log1 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student1Session1Log1\");"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student1Session2Log1 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student1Session2Log1\");"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student1Session2Log2 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student1Session2Log2\");"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student2Session1Log1 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student2Session1Log1\");"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student2Session1Log2 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student2Session1Log2\");"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Return logs belonging to a course in time range\");"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e expectedLogs \u003d List.of("},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":" student1Session1Log1,"},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" student1Session2Log1,"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" student1Session2Log2,"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" student2Session1Log1,"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" student2Session1Log2);"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e actualLogs \u003d fslLogic.getOrderedFeedbackSessionLogs(course.getId(), null, null,"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" startTime, endTime);"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Return logs belonging to a student in a course in time range\");"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":" expectedLogs \u003d List.of("},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" student1Session1Log1,"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" student1Session2Log1,"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" student1Session2Log2);"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" actualLogs \u003d fslLogic.getOrderedFeedbackSessionLogs(course.getId(), student1.getId(), null, startTime,"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" endTime);"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Return logs belonging to a feedback session in time range\");"},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" expectedLogs \u003d List.of("},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":" student1Session1Log1,"},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" student2Session1Log1,"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":" student2Session1Log2);"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":" actualLogs \u003d fslLogic.getOrderedFeedbackSessionLogs(course.getId(), null, fs1.getId(), startTime, endTime);"},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Return logs belonging to a student in a feedback session in time range\");"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":" expectedLogs \u003d List.of(student1Session1Log1);"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" actualLogs \u003d fslLogic.getOrderedFeedbackSessionLogs(course.getId(), student1.getId(), fs1.getId(),"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" startTime,"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" endTime);"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" ______TS(\"No logs in time range, return empty list\");"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" expectedLogs \u003d new ArrayList\u003c\u003e();"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" actualLogs \u003d fslLogic.getOrderedFeedbackSessionLogs(course.getId(), null, null, endTime.plusSeconds(3600),"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" endTime.plusSeconds(7200));"},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":131}},{"path":"src/it/java/teammates/it/storage/sqlapi/AccountRequestsDbIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.AccountRequestsDb;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * SUT: {@link AccountRequestsDb}."},{"lineNumber":17,"author":{"gitId":"-"},"content":" */"},{"lineNumber":18,"author":{"gitId":"-"},"content":"public class AccountRequestsDbIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" private final AccountRequestsDb accountRequestDb \u003d AccountRequestsDb.inst();"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":23,"author":{"gitId":"-"},"content":" public void testCreateReadDeleteAccountRequest() throws Exception {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" ______TS(\"Create account request, does not exists, succeeds\");"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":27,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":28,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" ______TS(\"Read account request using the given ID\");"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" AccountRequest actualAccReqEmalAndInstitute \u003d accountRequestDb.getAccountRequest(accountRequest.getId());"},{"lineNumber":33,"author":{"gitId":"-"},"content":" verifyEquals(accountRequest, actualAccReqEmalAndInstitute);"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" ______TS(\"Read account request using the given registration key\");"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" AccountRequest actualAccReqRegistrationKey \u003d"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" accountRequestDb.getAccountRequestByRegistrationKey(accountRequest.getRegistrationKey());"},{"lineNumber":39,"author":{"gitId":"-"},"content":" verifyEquals(accountRequest, actualAccReqRegistrationKey);"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" ______TS(\"Read account request using the given start and end timing\");"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" List\u003cAccountRequest\u003e actualAccReqCreatedAt \u003d"},{"lineNumber":44,"author":{"gitId":"-"},"content":" accountRequestDb.getAccountRequests(accountRequest.getCreatedAt(), accountRequest.getCreatedAt());"},{"lineNumber":45,"author":{"gitId":"-"},"content":" assertEquals(1, actualAccReqCreatedAt.size());"},{"lineNumber":46,"author":{"gitId":"-"},"content":" verifyEquals(accountRequest, actualAccReqCreatedAt.get(0));"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" ______TS(\"Read account request not found using the outside start and end timing\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" List\u003cAccountRequest\u003e actualAccReqCreatedAtOutside \u003d"},{"lineNumber":51,"author":{"gitId":"-"},"content":" accountRequestDb.getAccountRequests("},{"lineNumber":52,"author":{"gitId":"-"},"content":" accountRequest.getCreatedAt().minusMillis(3000),"},{"lineNumber":53,"author":{"gitId":"-"},"content":" accountRequest.getCreatedAt().minusMillis(2000));"},{"lineNumber":54,"author":{"gitId":"-"},"content":" assertEquals(0, actualAccReqCreatedAtOutside.size());"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" ______TS(\"Create account request, same email address and institute already exist, creates successfully\");"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" AccountRequest identicalAccountRequest \u003d"},{"lineNumber":59,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":60,"author":{"gitId":"-"},"content":" assertNotSame(accountRequest, identicalAccountRequest);"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(identicalAccountRequest);"},{"lineNumber":63,"author":{"gitId":"-"},"content":" AccountRequest actualIdenticalAccountRequest \u003d"},{"lineNumber":64,"author":{"gitId":"-"},"content":" accountRequestDb.getAccountRequestByRegistrationKey(identicalAccountRequest.getRegistrationKey());"},{"lineNumber":65,"author":{"gitId":"-"},"content":" verifyEquals(identicalAccountRequest, actualIdenticalAccountRequest);"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" ______TS(\"Delete account request that was created\");"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" accountRequestDb.deleteAccountRequest(accountRequest);"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" AccountRequest actualAccountRequest \u003d"},{"lineNumber":72,"author":{"gitId":"-"},"content":" accountRequestDb.getAccountRequestByRegistrationKey(accountRequest.getRegistrationKey());"},{"lineNumber":73,"author":{"gitId":"-"},"content":" assertNull(actualAccountRequest);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" }"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":77,"author":{"gitId":"-"},"content":" public void testGetAccountRequest_nonExistentAccountRequest_returnsNull() {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" UUID id \u003d UUID.randomUUID();"},{"lineNumber":79,"author":{"gitId":"-"},"content":" AccountRequest actualAccountRequest \u003d accountRequestDb.getAccountRequest(id);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" assertNull(actualAccountRequest);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":84,"author":{"gitId":"-"},"content":" public void testGetAccountRequest_existingAccountRequest_getsSuccessfully() throws InvalidParametersException {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" AccountRequest expectedAccountRequest \u003d"},{"lineNumber":86,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":87,"author":{"gitId":"-"},"content":" UUID id \u003d expectedAccountRequest.getId();"},{"lineNumber":88,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(expectedAccountRequest);"},{"lineNumber":89,"author":{"gitId":"-"},"content":" AccountRequest actualAccountRequest \u003d accountRequestDb.getAccountRequest(id);"},{"lineNumber":90,"author":{"gitId":"-"},"content":" assertEquals(expectedAccountRequest, actualAccountRequest);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" }"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":94,"author":{"gitId":"-"},"content":" public void testUpdateAccountRequest() throws Exception {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" ______TS(\"Update account request, does not exists, exception thrown\");"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":98,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":101,"author":{"gitId":"-"},"content":" () -\u003e accountRequestDb.updateAccountRequest(accountRequest));"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" ______TS(\"Update account request, already exists, update successful\");"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":106,"author":{"gitId":"-"},"content":" accountRequest.setName(\"new account request name\");"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" accountRequestDb.updateAccountRequest(accountRequest);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" AccountRequest actual \u003d accountRequestDb.getAccountRequest(accountRequest.getId());"},{"lineNumber":110,"author":{"gitId":"-"},"content":" verifyEquals(accountRequest, actual);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":114,"author":{"gitId":"-"},"content":" public void testSqlInjectionInCreateAccountRequestEmailField() throws Exception {"},{"lineNumber":115,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in email field\");"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" // Attempt to use SQL commands in email field"},{"lineNumber":118,"author":{"gitId":"-"},"content":" String email \u003d \"email\u0027/**/OR/**/1\u003d1/**/@gmail.com\";"},{"lineNumber":119,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":120,"author":{"gitId":"-"},"content":" new AccountRequest(email, \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" // The system should treat the input as a plain text string"},{"lineNumber":123,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":124,"author":{"gitId":"-"},"content":" AccountRequest actual \u003d accountRequestDb.getAccountRequest(accountRequest.getId());"},{"lineNumber":125,"author":{"gitId":"-"},"content":" assertEquals(email, actual.getEmail());"},{"lineNumber":126,"author":{"gitId":"-"},"content":" }"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":129,"author":{"gitId":"-"},"content":" public void testSqlInjectionInCreateAccountRequestNameField() throws Exception {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in name field\");"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":" // Attempt to use SQL commands in name field"},{"lineNumber":133,"author":{"gitId":"-"},"content":" String name \u003d \"name\u0027; SELECT * FROM account_requests; --\";"},{"lineNumber":134,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":135,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", name, \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" // The system should treat the input as a plain text string"},{"lineNumber":138,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" AccountRequest actual \u003d accountRequestDb.getAccountRequest(accountRequest.getId());"},{"lineNumber":140,"author":{"gitId":"-"},"content":" assertEquals(name, actual.getName());"},{"lineNumber":141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":144,"author":{"gitId":"-"},"content":" public void testSqlInjectionInCreateAccountRequestInstituteField() throws Exception {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in institute field\");"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" // Attempt to use SQL commands in institute field"},{"lineNumber":148,"author":{"gitId":"-"},"content":" String institute \u003d \"institute\u0027; DROP TABLE account_requests; --\";"},{"lineNumber":149,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":150,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", institute, AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" // The system should treat the input as a plain text string"},{"lineNumber":153,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":154,"author":{"gitId":"-"},"content":" AccountRequest actual \u003d accountRequestDb.getAccountRequest(accountRequest.getId());"},{"lineNumber":155,"author":{"gitId":"-"},"content":" assertEquals(institute, actual.getInstitute());"},{"lineNumber":156,"author":{"gitId":"-"},"content":" }"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":159,"author":{"gitId":"xenosf"},"content":" public void testSqlInjectionInCreateAccountRequestCommentsField() throws Exception {"},{"lineNumber":160,"author":{"gitId":"xenosf"},"content":" ______TS(\"SQL Injection test in comments field\");"},{"lineNumber":161,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":162,"author":{"gitId":"xenosf"},"content":" // Attempt to use SQL commands in comments field"},{"lineNumber":163,"author":{"gitId":"xenosf"},"content":" String comments \u003d \"comment\u0027; DROP TABLE account_requests; --\";"},{"lineNumber":164,"author":{"gitId":"xenosf"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":165,"author":{"gitId":"xenosf"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, comments);"},{"lineNumber":166,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":167,"author":{"gitId":"xenosf"},"content":" // The system should treat the input as a plain text string"},{"lineNumber":168,"author":{"gitId":"xenosf"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":169,"author":{"gitId":"xenosf"},"content":" AccountRequest actual \u003d accountRequestDb.getAccountRequest(accountRequest.getId());"},{"lineNumber":170,"author":{"gitId":"xenosf"},"content":" assertEquals(comments, actual.getComments());"},{"lineNumber":171,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":172,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":174,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetAccountRequestByRegistrationKey() throws Exception {"},{"lineNumber":175,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in getAccountRequestByRegistrationKey\");"},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":178,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":179,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":180,"author":{"gitId":"-"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":" String regKeyInjection \u003d \"regKey\u0027; DROP TABLE account_requests; --\";"},{"lineNumber":182,"author":{"gitId":"-"},"content":" AccountRequest actualInjection \u003d accountRequestDb.getAccountRequestByRegistrationKey(regKeyInjection);"},{"lineNumber":183,"author":{"gitId":"-"},"content":" assertNull(actualInjection);"},{"lineNumber":184,"author":{"gitId":"-"},"content":""},{"lineNumber":185,"author":{"gitId":"-"},"content":" AccountRequest actual \u003d accountRequestDb.getAccountRequestByRegistrationKey(accountRequest.getRegistrationKey());"},{"lineNumber":186,"author":{"gitId":"-"},"content":" assertEquals(accountRequest, actual);"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":190,"author":{"gitId":"xenosf"},"content":" public void testSqlInjectionInGetApprovedAccountRequestsForEmail() throws Exception {"},{"lineNumber":191,"author":{"gitId":"xenosf"},"content":" ______TS(\"SQL Injection test in getApprovedAccountRequestsForEmail\");"},{"lineNumber":192,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":193,"author":{"gitId":"xenosf"},"content":" String email \u003d \"test@gmail.com\";"},{"lineNumber":194,"author":{"gitId":"xenosf"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":195,"author":{"gitId":"xenosf"},"content":" new AccountRequest(email, \"name\", \"institute\", AccountRequestStatus.APPROVED, \"comments\");"},{"lineNumber":196,"author":{"gitId":"xenosf"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":197,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":198,"author":{"gitId":"xenosf"},"content":" // Attempt to use SQL commands in email field"},{"lineNumber":199,"author":{"gitId":"xenosf"},"content":" String emailInjection \u003d \"email\u0027/**/OR/**/1\u003d1/**/@gmail.com\";"},{"lineNumber":200,"author":{"gitId":"xenosf"},"content":" List\u003cAccountRequest\u003e actualInjection \u003d accountRequestDb.getApprovedAccountRequestsForEmail(emailInjection);"},{"lineNumber":201,"author":{"gitId":"xenosf"},"content":" // The system should treat the input as a plain text string"},{"lineNumber":202,"author":{"gitId":"xenosf"},"content":" assertEquals(0, actualInjection.size());"},{"lineNumber":203,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":204,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":206,"author":{"gitId":"-"},"content":" public void testSqlInjectionInUpdateAccountRequest() throws Exception {"},{"lineNumber":207,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in updateAccountRequest\");"},{"lineNumber":208,"author":{"gitId":"-"},"content":""},{"lineNumber":209,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":210,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":211,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":212,"author":{"gitId":"-"},"content":""},{"lineNumber":213,"author":{"gitId":"-"},"content":" String nameInjection \u003d \"newName\u0027; DROP TABLE account_requests; --\";"},{"lineNumber":214,"author":{"gitId":"-"},"content":" accountRequest.setName(nameInjection);"},{"lineNumber":215,"author":{"gitId":"-"},"content":" accountRequestDb.updateAccountRequest(accountRequest);"},{"lineNumber":216,"author":{"gitId":"-"},"content":""},{"lineNumber":217,"author":{"gitId":"-"},"content":" AccountRequest actual \u003d accountRequestDb.getAccountRequest(accountRequest.getId());"},{"lineNumber":218,"author":{"gitId":"-"},"content":" assertEquals(accountRequest, actual);"},{"lineNumber":219,"author":{"gitId":"-"},"content":" }"},{"lineNumber":220,"author":{"gitId":"-"},"content":""},{"lineNumber":221,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":222,"author":{"gitId":"-"},"content":" public void testSqlInjectionInDeleteAccountRequest() throws Exception {"},{"lineNumber":223,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in deleteAccountRequest\");"},{"lineNumber":224,"author":{"gitId":"-"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":226,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":227,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" String emailInjection \u003d \"email\u0027/**/OR/**/1\u003d1/**/@gmail.com\";"},{"lineNumber":230,"author":{"gitId":"-"},"content":" String nameInjection \u003d \"name\u0027; DROP TABLE account_requests; --\";"},{"lineNumber":231,"author":{"gitId":"-"},"content":" String instituteInjection \u003d \"institute\u0027; DROP TABLE account_requests; --\";"},{"lineNumber":232,"author":{"gitId":"-"},"content":" AccountRequest accountRequestInjection \u003d new AccountRequest(emailInjection, nameInjection, instituteInjection,"},{"lineNumber":233,"author":{"gitId":"-"},"content":" AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":234,"author":{"gitId":"-"},"content":" accountRequestDb.deleteAccountRequest(accountRequestInjection);"},{"lineNumber":235,"author":{"gitId":"-"},"content":""},{"lineNumber":236,"author":{"gitId":"-"},"content":" AccountRequest actual \u003d accountRequestDb.getAccountRequest(accountRequest.getId());"},{"lineNumber":237,"author":{"gitId":"-"},"content":" assertEquals(accountRequest, actual);"},{"lineNumber":238,"author":{"gitId":"-"},"content":" }"},{"lineNumber":239,"author":{"gitId":"-"},"content":""},{"lineNumber":240,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":241,"author":{"gitId":"-"},"content":" public void testSqlInjectionSearchAccountRequestsInWholeSystem() throws Exception {"},{"lineNumber":242,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in searchAccountRequestsInWholeSystem\");"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d"},{"lineNumber":245,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":246,"author":{"gitId":"-"},"content":" accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" String searchInjection \u003d \"institute\u0027; DROP TABLE account_requests; --\";"},{"lineNumber":249,"author":{"gitId":"-"},"content":" List\u003cAccountRequest\u003e actualInjection \u003d accountRequestDb.searchAccountRequestsInWholeSystem(searchInjection);"},{"lineNumber":250,"author":{"gitId":"-"},"content":" assertEquals(0, actualInjection.size());"},{"lineNumber":251,"author":{"gitId":"-"},"content":""},{"lineNumber":252,"author":{"gitId":"-"},"content":" AccountRequest actual \u003d accountRequestDb.getAccountRequest(accountRequest.getId());"},{"lineNumber":253,"author":{"gitId":"-"},"content":" assertEquals(accountRequest, actual);"},{"lineNumber":254,"author":{"gitId":"-"},"content":" }"},{"lineNumber":255,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":31,"dishenggg":1,"-":223}},{"path":"src/it/java/teammates/it/storage/sqlapi/CoursesDbIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.CoursesDb;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * SUT: {@link CoursesDb}."},{"lineNumber":19,"author":{"gitId":"-"},"content":" */"},{"lineNumber":20,"author":{"gitId":"-"},"content":"public class CoursesDbIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" private final CoursesDb coursesDb \u003d CoursesDb.inst();"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" public void testGetCourse() throws Exception {"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: get course that does not exist\");"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" Course actual \u003d coursesDb.getCourse(\"non-existent-course-id\");"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" assertNull(actual);"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null assertion exception thrown\");"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.getCourse(null));"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: get course that already exists\");"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" Course expected \u003d getTypicalCourse();"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" coursesDb.createCourse(expected);"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" actual \u003d coursesDb.getCourse(expected.getId());"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" verifyEquals(expected, actual);"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":42,"author":{"gitId":"-"},"content":" public void testCreateCourse() throws Exception {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" ______TS(\"success: create course that does not exist\");"},{"lineNumber":44,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":45,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" Course actualCourse \u003d coursesDb.getCourse(\"course-id\");"},{"lineNumber":47,"author":{"gitId":"-"},"content":" verifyEquals(course, actualCourse);"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null course assertion exception thrown\");"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.createCourse(null));"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: invalid course details\");"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" Course invalidCourse \u003d new Course(\"course-id\", \"!@#!@#\", \"Asia/Singapore\", \"institute\");"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" assertThrows(InvalidParametersException.class, () -\u003e coursesDb.createCourse(invalidCourse));"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" ______TS(\"failure: create course that already exist, execption thrown\");"},{"lineNumber":57,"author":{"gitId":"-"},"content":" Course identicalCourse \u003d getTypicalCourse();"},{"lineNumber":58,"author":{"gitId":"-"},"content":" assertNotSame(course, identicalCourse);"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" assertThrows(EntityAlreadyExistsException.class, () -\u003e coursesDb.createCourse(identicalCourse));"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":64,"author":{"gitId":"-"},"content":" public void testUpdateCourse() throws Exception {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" ______TS(\"failure: update course that does not exist, exception thrown\");"},{"lineNumber":66,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":67,"author":{"gitId":"-"},"content":" assertThrows(EntityDoesNotExistException.class, () -\u003e coursesDb.updateCourse(course));"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null course assertion exception thrown\");"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.updateCourse(null));"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: update course that already exists\");"},{"lineNumber":73,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" course.setName(\"new course name\");"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" coursesDb.updateCourse(course);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" Course actual \u003d coursesDb.getCourse(\"course-id\");"},{"lineNumber":78,"author":{"gitId":"-"},"content":" verifyEquals(course, actual);"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" ______TS(\"success: update detached course that already exists\");"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" // same id, different name"},{"lineNumber":83,"author":{"gitId":"-"},"content":" Course detachedCourse \u003d getTypicalCourse();"},{"lineNumber":84,"author":{"gitId":"-"},"content":" detachedCourse.setName(\"different-name\");"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" coursesDb.updateCourse(detachedCourse);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" verifyEquals(course, detachedCourse);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" public void testDeleteCourse() throws Exception {"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: delete course that already exists\");"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":" coursesDb.createCourse(course);"},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" coursesDb.deleteCourse(course);"},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":" Course actualCourse \u003d coursesDb.getCourse(course.getId());"},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":" assertNull(actualCourse);"},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" public void testCreateSection() throws Exception {"},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" coursesDb.createCourse(course);"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: create section that does not exist\");"},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" coursesDb.createSection(section);"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" Section actualSection \u003d coursesDb.getSectionByName(course.getId(), section.getName());"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" verifyEquals(section, actualSection);"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null section assertion exception thrown\");"},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.createSection(null));"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: invalid section details\");"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" Section invalidSection \u003d new Section(course, null);"},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":" assertThrows(InvalidParametersException.class, () -\u003e coursesDb.createSection(invalidSection));"},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: create section that already exist, execption thrown\");"},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" assertThrows(EntityAlreadyExistsException.class, () -\u003e coursesDb.createSection(section));"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" public void testGetSectionByName() throws Exception {"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" coursesDb.createCourse(course);"},{"lineNumber":128,"author":{"gitId":"domoberzin"},"content":" coursesDb.createSection(section);"},{"lineNumber":129,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null courseId assertion exception thrown\");"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.getSectionByName(null, section.getName()));"},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null sectionName assertion exception thrown\");"},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.getSectionByName(course.getId(), null));"},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: get section that already exists\");"},{"lineNumber":137,"author":{"gitId":"domoberzin"},"content":" Section actualSection \u003d coursesDb.getSectionByName(course.getId(), section.getName());"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":" verifyEquals(section, actualSection);"},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":140,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: get section that does not exist\");"},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":" Section nonExistentSection \u003d coursesDb.getSectionByName(course.getId(), \"non-existent-section-name\");"},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":" assertNull(nonExistentSection);"},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":146,"author":{"gitId":"-"},"content":" public void testGetSectionByCourseIdAndTeam() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":147,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":148,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, \"section-name\");"},{"lineNumber":149,"author":{"gitId":"-"},"content":" course.addSection(section);"},{"lineNumber":150,"author":{"gitId":"-"},"content":" Team team \u003d new Team(section, \"team-name\");"},{"lineNumber":151,"author":{"gitId":"-"},"content":" section.addTeam(team);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null courseId assertion exception thrown\");"},{"lineNumber":155,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.getSectionByCourseIdAndTeam(null, team.getName()));"},{"lineNumber":156,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":157,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null teamName assertion exception thrown\");"},{"lineNumber":158,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.getSectionByCourseIdAndTeam(course.getId(), null));"},{"lineNumber":159,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":161,"author":{"gitId":"-"},"content":" Section actualSection \u003d coursesDb.getSectionByCourseIdAndTeam(course.getId(), team.getName());"},{"lineNumber":162,"author":{"gitId":"-"},"content":" verifyEquals(section, actualSection);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":166,"author":{"gitId":"-"},"content":" public void testGetTeamsForSection() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":168,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, \"section-name\");"},{"lineNumber":169,"author":{"gitId":"-"},"content":" course.addSection(section);"},{"lineNumber":170,"author":{"gitId":"-"},"content":" Team team1 \u003d new Team(section, \"team-name1\");"},{"lineNumber":171,"author":{"gitId":"-"},"content":" section.addTeam(team1);"},{"lineNumber":172,"author":{"gitId":"-"},"content":" Team team2 \u003d new Team(section, \"team-name2\");"},{"lineNumber":173,"author":{"gitId":"-"},"content":" section.addTeam(team2);"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" List\u003cTeam\u003e expectedTeams \u003d List.of(team1, team2);"},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null section assertion exception thrown\");"},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.getTeamsForSection(null));"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":183,"author":{"gitId":"-"},"content":" List\u003cTeam\u003e actualTeams \u003d coursesDb.getTeamsForSection(section);"},{"lineNumber":184,"author":{"gitId":"-"},"content":" assertEquals(expectedTeams.size(), actualTeams.size());"},{"lineNumber":185,"author":{"gitId":"-"},"content":" assertTrue(expectedTeams.containsAll(actualTeams));"},{"lineNumber":186,"author":{"gitId":"-"},"content":" }"},{"lineNumber":187,"author":{"gitId":"-"},"content":""},{"lineNumber":188,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":189,"author":{"gitId":"domoberzin"},"content":" public void testDeleteSectionsByCourseId() throws Exception {"},{"lineNumber":190,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":191,"author":{"gitId":"domoberzin"},"content":" coursesDb.createCourse(course);"},{"lineNumber":192,"author":{"gitId":"domoberzin"},"content":" List\u003cSection\u003e expectedSections \u003d new ArrayList\u003c\u003e();"},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":" for (int i \u003d 0; i \u003c 5; i++) {"},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" Section newSection \u003d new Section(course, \"section-name\" + i);"},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" expectedSections.add(newSection);"},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":" course.addSection(newSection);"},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":" assertNotNull(coursesDb.getSectionByName(course.getId(), newSection.getName()));"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":200,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: delete sections by course id\");"},{"lineNumber":201,"author":{"gitId":"domoberzin"},"content":" coursesDb.deleteSectionsByCourseId(course.getId());"},{"lineNumber":202,"author":{"gitId":"domoberzin"},"content":" for (Section section : expectedSections) {"},{"lineNumber":203,"author":{"gitId":"domoberzin"},"content":" Section actualSection \u003d coursesDb.getSectionByName(course.getId(), section.getName());"},{"lineNumber":204,"author":{"gitId":"domoberzin"},"content":" assertNull(actualSection);"},{"lineNumber":205,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":206,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":207,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":209,"author":{"gitId":"-"},"content":" public void testGetTeamsForCourse() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" Section section1 \u003d new Section(course, \"section-name1\");"},{"lineNumber":213,"author":{"gitId":"-"},"content":" course.addSection(section1);"},{"lineNumber":214,"author":{"gitId":"-"},"content":" Team team1 \u003d new Team(section1, \"team-name1\");"},{"lineNumber":215,"author":{"gitId":"-"},"content":" section1.addTeam(team1);"},{"lineNumber":216,"author":{"gitId":"-"},"content":" Team team2 \u003d new Team(section1, \"team-name2\");"},{"lineNumber":217,"author":{"gitId":"-"},"content":" section1.addTeam(team2);"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":" Section section2 \u003d new Section(course, \"section-name2\");"},{"lineNumber":220,"author":{"gitId":"-"},"content":" course.addSection(section2);"},{"lineNumber":221,"author":{"gitId":"-"},"content":" Team team3 \u003d new Team(section2, \"team-name3\");"},{"lineNumber":222,"author":{"gitId":"-"},"content":" section2.addTeam(team3);"},{"lineNumber":223,"author":{"gitId":"-"},"content":" Team team4 \u003d new Team(section2, \"team-name4\");"},{"lineNumber":224,"author":{"gitId":"-"},"content":" section2.addTeam(team4);"},{"lineNumber":225,"author":{"gitId":"-"},"content":""},{"lineNumber":226,"author":{"gitId":"-"},"content":" List\u003cTeam\u003e expectedTeams \u003d List.of(team1, team2, team3, team4);"},{"lineNumber":227,"author":{"gitId":"-"},"content":""},{"lineNumber":228,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":229,"author":{"gitId":"-"},"content":""},{"lineNumber":230,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null courseId assertion exception thrown\");"},{"lineNumber":231,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.getTeamsForCourse(null));"},{"lineNumber":232,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":234,"author":{"gitId":"-"},"content":" List\u003cTeam\u003e actualTeams \u003d coursesDb.getTeamsForCourse(course.getId());"},{"lineNumber":235,"author":{"gitId":"-"},"content":" assertEquals(expectedTeams.size(), actualTeams.size());"},{"lineNumber":236,"author":{"gitId":"-"},"content":" assertTrue(expectedTeams.containsAll(actualTeams));"},{"lineNumber":237,"author":{"gitId":"-"},"content":" }"},{"lineNumber":238,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":239,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":240,"author":{"gitId":"domoberzin"},"content":" public void testCreateTeam() throws Exception {"},{"lineNumber":241,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":242,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":243,"author":{"gitId":"domoberzin"},"content":" Team team \u003d new Team(section, \"team-name1\");"},{"lineNumber":244,"author":{"gitId":"domoberzin"},"content":" coursesDb.createCourse(course);"},{"lineNumber":245,"author":{"gitId":"domoberzin"},"content":" coursesDb.createSection(section);"},{"lineNumber":246,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":247,"author":{"gitId":"domoberzin"},"content":" assertNotNull(coursesDb.getSectionByName(course.getId(), section.getName()));"},{"lineNumber":248,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":249,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null team assertion exception thrown\");"},{"lineNumber":250,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.createTeam(null));"},{"lineNumber":251,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":252,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: create team that does not exist\");"},{"lineNumber":253,"author":{"gitId":"domoberzin"},"content":" coursesDb.createTeam(team);"},{"lineNumber":254,"author":{"gitId":"domoberzin"},"content":" Team actualTeam \u003d coursesDb.getTeamByName(section.getId(), team.getName());"},{"lineNumber":255,"author":{"gitId":"domoberzin"},"content":" verifyEquals(team, actualTeam);"},{"lineNumber":256,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":257,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: invalid team details\");"},{"lineNumber":258,"author":{"gitId":"domoberzin"},"content":" Team invalidTeam \u003d new Team(section, null);"},{"lineNumber":259,"author":{"gitId":"domoberzin"},"content":" assertThrows(InvalidParametersException.class, () -\u003e coursesDb.createTeam(invalidTeam));"},{"lineNumber":260,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":261,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: create team that already exist, execption thrown\");"},{"lineNumber":262,"author":{"gitId":"domoberzin"},"content":" assertThrows(EntityAlreadyExistsException.class, () -\u003e coursesDb.createTeam(team));"},{"lineNumber":263,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":264,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":265,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":266,"author":{"gitId":"domoberzin"},"content":" public void testGetTeamByName() throws Exception {"},{"lineNumber":267,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":268,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":269,"author":{"gitId":"domoberzin"},"content":" Team team \u003d new Team(section, \"team-name1\");"},{"lineNumber":270,"author":{"gitId":"domoberzin"},"content":" coursesDb.createCourse(course);"},{"lineNumber":271,"author":{"gitId":"domoberzin"},"content":" coursesDb.createSection(section);"},{"lineNumber":272,"author":{"gitId":"domoberzin"},"content":" coursesDb.createTeam(team);"},{"lineNumber":273,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":274,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: get team that already exists\");"},{"lineNumber":275,"author":{"gitId":"domoberzin"},"content":" Team actualTeam \u003d coursesDb.getTeamByName(section.getId(), team.getName());"},{"lineNumber":276,"author":{"gitId":"domoberzin"},"content":" verifyEquals(team, actualTeam);"},{"lineNumber":277,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":278,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null sectionId assertion exception thrown\");"},{"lineNumber":279,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.getTeamByName(null, team.getName()));"},{"lineNumber":280,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":281,"author":{"gitId":"domoberzin"},"content":" ______TS(\"failure: null teamName assertion exception thrown\");"},{"lineNumber":282,"author":{"gitId":"domoberzin"},"content":" assertThrows(AssertionError.class, () -\u003e coursesDb.getTeamByName(section.getId(), null));"},{"lineNumber":283,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":284,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: null return\");"},{"lineNumber":285,"author":{"gitId":"domoberzin"},"content":" Team nonExistentTeam \u003d coursesDb.getTeamByName(section.getId(), \"non-existent-team-name\");"},{"lineNumber":286,"author":{"gitId":"domoberzin"},"content":" assertNull(nonExistentTeam);"},{"lineNumber":287,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":288,"author":{"gitId":"-"},"content":""},{"lineNumber":289,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":290,"author":{"gitId":"-"},"content":" public void testSqlInjectionInCreateCourse() throws Exception {"},{"lineNumber":291,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in createCourse\");"},{"lineNumber":292,"author":{"gitId":"-"},"content":""},{"lineNumber":293,"author":{"gitId":"-"},"content":" // Attempt to use SQL commands in name field"},{"lineNumber":294,"author":{"gitId":"-"},"content":" String courseName \u003d \"test\u0027; DROP TABLE courses; --\";"},{"lineNumber":295,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", courseName, \"UTC\", \"teammates\");"},{"lineNumber":296,"author":{"gitId":"-"},"content":""},{"lineNumber":297,"author":{"gitId":"-"},"content":" // The system should treat the input as a plain text string"},{"lineNumber":298,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":299,"author":{"gitId":"-"},"content":" Course actual \u003d coursesDb.getCourse(\"course-id\");"},{"lineNumber":300,"author":{"gitId":"-"},"content":" assertEquals(courseName, actual.getName());"},{"lineNumber":301,"author":{"gitId":"-"},"content":" }"},{"lineNumber":302,"author":{"gitId":"-"},"content":""},{"lineNumber":303,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":304,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetCourse() throws Exception {"},{"lineNumber":305,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in getCourse\");"},{"lineNumber":306,"author":{"gitId":"-"},"content":""},{"lineNumber":307,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"course-name\", \"UTC\", \"teammates\");"},{"lineNumber":308,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":309,"author":{"gitId":"-"},"content":""},{"lineNumber":310,"author":{"gitId":"-"},"content":" // Attempt to use SQL commands in courseId field"},{"lineNumber":311,"author":{"gitId":"-"},"content":" String courseId \u003d \"test\u0027 OR 1 \u003d 1; --\";"},{"lineNumber":312,"author":{"gitId":"-"},"content":" Course actual \u003d coursesDb.getCourse(courseId);"},{"lineNumber":313,"author":{"gitId":"-"},"content":" assertEquals(null, actual);"},{"lineNumber":314,"author":{"gitId":"-"},"content":" }"},{"lineNumber":315,"author":{"gitId":"-"},"content":""},{"lineNumber":316,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":317,"author":{"gitId":"-"},"content":" public void testSqlInjectionInUpdateCourse() throws Exception {"},{"lineNumber":318,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in updateCourse\");"},{"lineNumber":319,"author":{"gitId":"-"},"content":""},{"lineNumber":320,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"name\", \"UTC\", \"institute\");"},{"lineNumber":321,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":322,"author":{"gitId":"-"},"content":""},{"lineNumber":323,"author":{"gitId":"-"},"content":" // The system should treat the input as a plain text string"},{"lineNumber":324,"author":{"gitId":"-"},"content":" String newName \u003d \"newName\u0027; DROP TABLE courses; --\";"},{"lineNumber":325,"author":{"gitId":"-"},"content":" course.setName(newName);"},{"lineNumber":326,"author":{"gitId":"-"},"content":" coursesDb.updateCourse(course);"},{"lineNumber":327,"author":{"gitId":"-"},"content":" Course actual \u003d coursesDb.getCourse(\"course-id\");"},{"lineNumber":328,"author":{"gitId":"-"},"content":" assertEquals(newName, actual.getName());"},{"lineNumber":329,"author":{"gitId":"-"},"content":" }"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":332,"author":{"gitId":"-"},"content":" public void testSqlInjectionInDeleteCourse() throws Exception {"},{"lineNumber":333,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in deleteCourse\");"},{"lineNumber":334,"author":{"gitId":"-"},"content":""},{"lineNumber":335,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"name\", \"UTC\", \"institute\");"},{"lineNumber":336,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":337,"author":{"gitId":"-"},"content":""},{"lineNumber":338,"author":{"gitId":"-"},"content":" String name \u003d \"newName\u0027; DELETE FROM courses; --\";"},{"lineNumber":339,"author":{"gitId":"-"},"content":" Course injectionCourse \u003d new Course(\"course-id-injection\", name, \"UTC\", \"institute\");"},{"lineNumber":340,"author":{"gitId":"-"},"content":" coursesDb.createCourse(injectionCourse);"},{"lineNumber":341,"author":{"gitId":"-"},"content":""},{"lineNumber":342,"author":{"gitId":"-"},"content":" coursesDb.deleteCourse(injectionCourse);"},{"lineNumber":343,"author":{"gitId":"-"},"content":" Course actualInjectionCourse \u003d coursesDb.getCourse(\"course-id-injection\");"},{"lineNumber":344,"author":{"gitId":"-"},"content":""},{"lineNumber":345,"author":{"gitId":"-"},"content":" // The course should be deleted"},{"lineNumber":346,"author":{"gitId":"-"},"content":" assertEquals(null, actualInjectionCourse);"},{"lineNumber":347,"author":{"gitId":"-"},"content":""},{"lineNumber":348,"author":{"gitId":"-"},"content":" // All other courses should not be deleted"},{"lineNumber":349,"author":{"gitId":"-"},"content":" Course actualCourse \u003d coursesDb.getCourse(\"course-id\");"},{"lineNumber":350,"author":{"gitId":"-"},"content":" assertEquals(course, actualCourse);"},{"lineNumber":351,"author":{"gitId":"-"},"content":" }"},{"lineNumber":352,"author":{"gitId":"-"},"content":""},{"lineNumber":353,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":354,"author":{"gitId":"-"},"content":" public void testSqlInjectionInCreateSection() throws Exception {"},{"lineNumber":355,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in createSection\");"},{"lineNumber":356,"author":{"gitId":"-"},"content":""},{"lineNumber":357,"author":{"gitId":"-"},"content":" // Attempt to use SQL commands in sectionName fields"},{"lineNumber":358,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"name\", \"UTC\", \"institute\");"},{"lineNumber":359,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":360,"author":{"gitId":"-"},"content":" String sectionName \u003d \"section\u0027; DROP TABLE courses; --\";"},{"lineNumber":361,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, sectionName);"},{"lineNumber":362,"author":{"gitId":"-"},"content":""},{"lineNumber":363,"author":{"gitId":"-"},"content":" // The system should treat the input as a plain text string"},{"lineNumber":364,"author":{"gitId":"-"},"content":" coursesDb.createSection(section);"},{"lineNumber":365,"author":{"gitId":"-"},"content":""},{"lineNumber":366,"author":{"gitId":"-"},"content":" // Check that we are still able to get courses"},{"lineNumber":367,"author":{"gitId":"-"},"content":" Course actualCourse \u003d coursesDb.getCourse(\"course-id\");"},{"lineNumber":368,"author":{"gitId":"-"},"content":" assertEquals(course, actualCourse);"},{"lineNumber":369,"author":{"gitId":"-"},"content":" }"},{"lineNumber":370,"author":{"gitId":"-"},"content":""},{"lineNumber":371,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":372,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetSectionByName() throws Exception {"},{"lineNumber":373,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in getSectionByName\");"},{"lineNumber":374,"author":{"gitId":"-"},"content":""},{"lineNumber":375,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"course-name\", \"UTC\", \"institute\");"},{"lineNumber":376,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":377,"author":{"gitId":"-"},"content":" String sectionName \u003d \"section-name\";"},{"lineNumber":378,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, sectionName);"},{"lineNumber":379,"author":{"gitId":"-"},"content":""},{"lineNumber":380,"author":{"gitId":"-"},"content":" coursesDb.createSection(section);"},{"lineNumber":381,"author":{"gitId":"-"},"content":" Section actual \u003d coursesDb.getSectionByName(\"course-id\", \"section-name\u0027; DROP TABLE courses; --\");"},{"lineNumber":382,"author":{"gitId":"-"},"content":" assertEquals(null, actual);"},{"lineNumber":383,"author":{"gitId":"-"},"content":" Section actualSection \u003d coursesDb.getSectionByName(\"course-id\", sectionName);"},{"lineNumber":384,"author":{"gitId":"-"},"content":" assertEquals(sectionName, actualSection.getName());"},{"lineNumber":385,"author":{"gitId":"-"},"content":" }"},{"lineNumber":386,"author":{"gitId":"-"},"content":""},{"lineNumber":387,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":388,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetSectionByCourseIdAndTeam() throws Exception {"},{"lineNumber":389,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in getSectionByCourseIdAndTeam\");"},{"lineNumber":390,"author":{"gitId":"-"},"content":""},{"lineNumber":391,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"course-name\", \"UTC\", \"institute\");"},{"lineNumber":392,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, \"section-name\");"},{"lineNumber":393,"author":{"gitId":"-"},"content":" course.addSection(section);"},{"lineNumber":394,"author":{"gitId":"-"},"content":" Team team \u003d new Team(section, \"team-name\");"},{"lineNumber":395,"author":{"gitId":"-"},"content":" section.addTeam(team);"},{"lineNumber":396,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":397,"author":{"gitId":"-"},"content":""},{"lineNumber":398,"author":{"gitId":"-"},"content":" // The system should treat the input as a plain text string"},{"lineNumber":399,"author":{"gitId":"-"},"content":" String teamNameInjection \u003d \"team-name\u0027; DROP TABLE courses; --\";"},{"lineNumber":400,"author":{"gitId":"-"},"content":" Section actual \u003d coursesDb.getSectionByCourseIdAndTeam(\"course-id\", teamNameInjection);"},{"lineNumber":401,"author":{"gitId":"-"},"content":" assertEquals(null, actual);"},{"lineNumber":402,"author":{"gitId":"-"},"content":" Section actualSection \u003d coursesDb.getSectionByCourseIdAndTeam(\"course-id\", \"team-name\");"},{"lineNumber":403,"author":{"gitId":"-"},"content":" assertEquals(\"team-name\", actualSection.getTeams().get(0).getName());"},{"lineNumber":404,"author":{"gitId":"-"},"content":" }"},{"lineNumber":405,"author":{"gitId":"-"},"content":""},{"lineNumber":406,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":407,"author":{"gitId":"-"},"content":" public void testSqlInjectionInDeleteSectionsByCourseId() throws Exception {"},{"lineNumber":408,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in deleteSectionsByCourseId\");"},{"lineNumber":409,"author":{"gitId":"-"},"content":""},{"lineNumber":410,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"name\", \"UTC\", \"institute\");"},{"lineNumber":411,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, \"section-name\");"},{"lineNumber":412,"author":{"gitId":"-"},"content":" course.addSection(section);"},{"lineNumber":413,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":414,"author":{"gitId":"-"},"content":""},{"lineNumber":415,"author":{"gitId":"-"},"content":" String courseId \u003d \"course-id\u0027; DELETE FROM courses; --\";"},{"lineNumber":416,"author":{"gitId":"-"},"content":" coursesDb.deleteSectionsByCourseId(courseId);"},{"lineNumber":417,"author":{"gitId":"-"},"content":""},{"lineNumber":418,"author":{"gitId":"-"},"content":" // The sections should not be deleted"},{"lineNumber":419,"author":{"gitId":"-"},"content":" Section actualSection \u003d coursesDb.getSectionByName(\"course-id\", \"section-name\");"},{"lineNumber":420,"author":{"gitId":"-"},"content":" assertEquals(section, actualSection);"},{"lineNumber":421,"author":{"gitId":"-"},"content":" }"},{"lineNumber":422,"author":{"gitId":"-"},"content":""},{"lineNumber":423,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":424,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetTeamsForSection() throws Exception {"},{"lineNumber":425,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in getTeamsForSection\");"},{"lineNumber":426,"author":{"gitId":"-"},"content":""},{"lineNumber":427,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"course-name\", \"UTC\", \"institute\");"},{"lineNumber":428,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, \"section-name\");"},{"lineNumber":429,"author":{"gitId":"-"},"content":" course.addSection(section);"},{"lineNumber":430,"author":{"gitId":"-"},"content":" Team team \u003d new Team(section, \"team-name\");"},{"lineNumber":431,"author":{"gitId":"-"},"content":" section.addTeam(team);"},{"lineNumber":432,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":433,"author":{"gitId":"-"},"content":""},{"lineNumber":434,"author":{"gitId":"-"},"content":" String sectionName \u003d \"section-name\u0027 OR 1 \u003d 1; --\";"},{"lineNumber":435,"author":{"gitId":"-"},"content":" Section sectionInjection \u003d new Section(course, sectionName);"},{"lineNumber":436,"author":{"gitId":"-"},"content":" List\u003cTeam\u003e actual \u003d coursesDb.getTeamsForSection(sectionInjection);"},{"lineNumber":437,"author":{"gitId":"-"},"content":" assertEquals(0, actual.size());"},{"lineNumber":438,"author":{"gitId":"-"},"content":" }"},{"lineNumber":439,"author":{"gitId":"-"},"content":""},{"lineNumber":440,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":441,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetTeamsForCourse() throws Exception {"},{"lineNumber":442,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in getTeamsForCourse\");"},{"lineNumber":443,"author":{"gitId":"-"},"content":""},{"lineNumber":444,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"course-name\", \"UTC\", \"institute\");"},{"lineNumber":445,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, \"section-name\");"},{"lineNumber":446,"author":{"gitId":"-"},"content":" course.addSection(section);"},{"lineNumber":447,"author":{"gitId":"-"},"content":" Team team \u003d new Team(section, \"team-name\");"},{"lineNumber":448,"author":{"gitId":"-"},"content":" section.addTeam(team);"},{"lineNumber":449,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":450,"author":{"gitId":"-"},"content":""},{"lineNumber":451,"author":{"gitId":"-"},"content":" String courseId \u003d \"course-id\u0027 OR 1 \u003d 1; --\";"},{"lineNumber":452,"author":{"gitId":"-"},"content":" List\u003cTeam\u003e actual \u003d coursesDb.getTeamsForCourse(courseId);"},{"lineNumber":453,"author":{"gitId":"-"},"content":" assertEquals(0, actual.size());"},{"lineNumber":454,"author":{"gitId":"-"},"content":" }"},{"lineNumber":455,"author":{"gitId":"-"},"content":""},{"lineNumber":456,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":457,"author":{"gitId":"-"},"content":" public void testSqlInjectionInCreateTeam() throws Exception {"},{"lineNumber":458,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in createTeam\");"},{"lineNumber":459,"author":{"gitId":"-"},"content":""},{"lineNumber":460,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"course-name\", \"UTC\", \"institute\");"},{"lineNumber":461,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, \"section-name\");"},{"lineNumber":462,"author":{"gitId":"-"},"content":" course.addSection(section);"},{"lineNumber":463,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":464,"author":{"gitId":"-"},"content":""},{"lineNumber":465,"author":{"gitId":"-"},"content":" String teamName \u003d \"team\u0027; DROP TABLE courses; --\";"},{"lineNumber":466,"author":{"gitId":"-"},"content":" Team team \u003d new Team(section, teamName);"},{"lineNumber":467,"author":{"gitId":"-"},"content":" coursesDb.createTeam(team);"},{"lineNumber":468,"author":{"gitId":"-"},"content":""},{"lineNumber":469,"author":{"gitId":"-"},"content":" List\u003cTeam\u003e actual \u003d coursesDb.getTeamsForSection(section);"},{"lineNumber":470,"author":{"gitId":"-"},"content":" assertEquals(1, actual.size());"},{"lineNumber":471,"author":{"gitId":"-"},"content":" assertEquals(teamName, actual.get(0).getName());"},{"lineNumber":472,"author":{"gitId":"-"},"content":" }"},{"lineNumber":473,"author":{"gitId":"-"},"content":""},{"lineNumber":474,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":475,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetTeamByName() throws Exception {"},{"lineNumber":476,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in getTeamByName\");"},{"lineNumber":477,"author":{"gitId":"-"},"content":""},{"lineNumber":478,"author":{"gitId":"-"},"content":" Course course \u003d new Course(\"course-id\", \"course-name\", \"UTC\", \"institute\");"},{"lineNumber":479,"author":{"gitId":"-"},"content":" Section section \u003d new Section(course, \"section-name\");"},{"lineNumber":480,"author":{"gitId":"-"},"content":" course.addSection(section);"},{"lineNumber":481,"author":{"gitId":"-"},"content":" Team team \u003d new Team(section, \"team-name\");"},{"lineNumber":482,"author":{"gitId":"-"},"content":" section.addTeam(team);"},{"lineNumber":483,"author":{"gitId":"-"},"content":" coursesDb.createCourse(course);"},{"lineNumber":484,"author":{"gitId":"-"},"content":""},{"lineNumber":485,"author":{"gitId":"-"},"content":" String teamName \u003d \"team-name\u0027; DROP TABLE courses; --\";"},{"lineNumber":486,"author":{"gitId":"-"},"content":" Team actual \u003d coursesDb.getTeamByName(section.getId(), teamName);"},{"lineNumber":487,"author":{"gitId":"-"},"content":" assertEquals(null, actual);"},{"lineNumber":488,"author":{"gitId":"-"},"content":" Team actualTeam \u003d coursesDb.getTeamByName(section.getId(), \"team-name\");"},{"lineNumber":489,"author":{"gitId":"-"},"content":" assertEquals(team, actualTeam);"},{"lineNumber":490,"author":{"gitId":"-"},"content":" }"},{"lineNumber":491,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":165,"-":326}},{"path":"src/it/java/teammates/it/storage/sqlapi/FeedbackQuestionsDbIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackQuestionsDb;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * SUT: {@link FeedbackQuestionsDb}."},{"lineNumber":23,"author":{"gitId":"-"},"content":" */"},{"lineNumber":24,"author":{"gitId":"-"},"content":"public class FeedbackQuestionsDbIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" private final FeedbackQuestionsDb fqDb \u003d FeedbackQuestionsDb.inst();"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" private SqlDataBundle typicalDataBundle;"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":31,"author":{"gitId":"-"},"content":" @BeforeClass"},{"lineNumber":32,"author":{"gitId":"-"},"content":" public void setupClass() {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" super.setupClass();"},{"lineNumber":34,"author":{"gitId":"-"},"content":" typicalDataBundle \u003d getTypicalSqlDataBundle();"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":39,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":41,"author":{"gitId":"-"},"content":" persistDataBundle(typicalDataBundle);"},{"lineNumber":42,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" }"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" public void testGetFeedbackQuestion() {"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion expectedFq \u003d typicalDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion actualFq \u003d fqDb.getFeedbackQuestion(expectedFq.getId());"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedFq, actualFq);"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" ______TS(\"failure: does not exist, returns null\");"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" actualFq \u003d fqDb.getFeedbackQuestion(UUID.randomUUID());"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" assertNull(actualFq);"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" ______TS(\"failure: null parameter, assertion error\");"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" assertThrows(AssertionError.class, () -\u003e fqDb.getFeedbackQuestion(null));"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" public void testCreateFeedbackQuestion() throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion expectedFq \u003d getTypicalFeedbackQuestionForSession("},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" getTypicalFeedbackSessionForCourse(getTypicalCourse()));"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" fqDb.createFeedbackQuestion(expectedFq);"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" verifyPresentInDatabase(expectedFq);"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" ______TS(\"failure: duplicate question, throws error\");"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" assertThrows(EntityAlreadyExistsException.class, () -\u003e fqDb.createFeedbackQuestion(expectedFq));"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" ______TS(\"failure: invalid question, throws error\");"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion invalidFq \u003d getTypicalFeedbackQuestionForSession("},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" getTypicalFeedbackSessionForCourse(getTypicalCourse()));"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" invalidFq.setGiverType(FeedbackParticipantType.RECEIVER);"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" assertThrows(InvalidParametersException.class, () -\u003e fqDb.createFeedbackQuestion(invalidFq));"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" assertNull(fqDb.getFeedbackQuestion(invalidFq.getId()));"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" ______TS(\"failure: null parameter, assertion error\");"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" assertThrows(AssertionError.class, () -\u003e fqDb.createFeedbackQuestion(null));"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":87,"author":{"gitId":"-"},"content":" public void testGetFeedbackQuestionsForSession() {"},{"lineNumber":88,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":89,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d typicalDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":90,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d typicalDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":91,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d typicalDataBundle.feedbackQuestions.get(\"qn2InSession1InCourse1\");"},{"lineNumber":92,"author":{"gitId":"-"},"content":" FeedbackQuestion fq3 \u003d typicalDataBundle.feedbackQuestions.get(\"qn3InSession1InCourse1\");"},{"lineNumber":93,"author":{"gitId":"-"},"content":" FeedbackQuestion fq4 \u003d typicalDataBundle.feedbackQuestions.get(\"qn4InSession1InCourse1\");"},{"lineNumber":94,"author":{"gitId":"-"},"content":" FeedbackQuestion fq5 \u003d typicalDataBundle.feedbackQuestions.get(\"qn5InSession1InCourse1\");"},{"lineNumber":95,"author":{"gitId":"-"},"content":" FeedbackQuestion fq6 \u003d typicalDataBundle.feedbackQuestions.get(\"qn6InSession1InCourse1NoResponses\");"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e expectedQuestions \u003d List.of(fq1, fq2, fq3, fq4, fq5, fq6);"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e actualQuestions \u003d fqDb.getFeedbackQuestionsForSession(fs.getId());"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestions.size(), actualQuestions.size());"},{"lineNumber":102,"author":{"gitId":"-"},"content":" assertTrue(expectedQuestions.containsAll(actualQuestions));"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" ______TS(\"failure: session does not exist, returns no questions\");"},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":" actualQuestions \u003d fqDb.getFeedbackQuestionsForSession(UUID.randomUUID());"},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" assertEquals(0, actualQuestions.size());"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":110,"author":{"gitId":"-"},"content":" public void testGetFeedbackQuestionsForGiverType() {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":112,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d typicalDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":113,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d typicalDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":114,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d typicalDataBundle.feedbackQuestions.get(\"qn2InSession1InCourse1\");"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e expectedQuestions \u003d List.of(fq1, fq2);"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e actualQuestions \u003d fqDb.getFeedbackQuestionsForGiverType(fs, FeedbackParticipantType.STUDENTS);"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestions.size(), actualQuestions.size());"},{"lineNumber":121,"author":{"gitId":"-"},"content":" assertTrue(expectedQuestions.containsAll(actualQuestions));"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" ______TS(\"failure: session does not exist, returns no questions\");"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" fs \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" actualQuestions \u003d fqDb.getFeedbackQuestionsForGiverType(fs, FeedbackParticipantType.STUDENTS);"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" assertEquals(0, actualQuestions.size());"},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":" public void testDeleteFeedbackQuestion() {"},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" FeedbackQuestion fq \u003d typicalDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" verifyPresentInDatabase(fq);"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":" fqDb.deleteFeedbackQuestion(fq.getId());"},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" assertNull(fqDb.getFeedbackQuestion(fq.getId()));"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":" ______TS(\"failure: null parameter, assertion error\");"},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" assertThrows(AssertionError.class, () -\u003e fqDb.deleteFeedbackQuestion(null));"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":143,"author":{"gitId":"-"},"content":" public void testHasFeedbackQuestionsForGiverType() {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":145,"author":{"gitId":"-"},"content":" Course course \u003d typicalDataBundle.courses.get(\"course1\");"},{"lineNumber":146,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d typicalDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" boolean actual \u003d fqDb.hasFeedbackQuestionsForGiverType("},{"lineNumber":149,"author":{"gitId":"-"},"content":" fs.getName(), course.getId(), FeedbackParticipantType.STUDENTS);"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" assertTrue(actual);"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":153,"author":{"gitId":"dishenggg"},"content":" ______TS(\"failure: session/course does not exist, returns false\");"},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":" actual \u003d fqDb.hasFeedbackQuestionsForGiverType(\"session-name\", \"course-id\", FeedbackParticipantType.STUDENTS);"},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":" assertFalse(actual);"},{"lineNumber":156,"author":{"gitId":"-"},"content":" }"},{"lineNumber":157,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":70,"-":87}},{"path":"src/it/java/teammates/it/storage/sqlapi/FeedbackResponseCommentsDbIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import java.util.HashSet;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import java.util.UUID;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackResponseCommentsDb;"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":27,"author":{"gitId":"-"},"content":" * SUT: {@link FeedbackResponseCommentsDb}."},{"lineNumber":28,"author":{"gitId":"-"},"content":" */"},{"lineNumber":29,"author":{"gitId":"-"},"content":"public class FeedbackResponseCommentsDbIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" private final FeedbackResponseCommentsDb frcDb \u003d FeedbackResponseCommentsDb.inst();"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" private SqlDataBundle testDataBundle;"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":36,"author":{"gitId":"-"},"content":" @BeforeClass"},{"lineNumber":37,"author":{"gitId":"-"},"content":" public void setupClass() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" super.setupClass();"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" testDataBundle \u003d loadSqlDataBundle(\"/FeedbackResponsesITBundle.json\");"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":43,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":44,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" persistDataBundle(testDataBundle);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" HibernateUtil.clearSession();"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":52,"author":{"gitId":"-"},"content":" public void testGetFeedbackResponseCommentForResponseFromParticipant() {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" FeedbackResponse fr \u003d testDataBundle.feedbackResponses.get(\"response1ForQ1\");"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" FeedbackResponseComment expectedComment \u003d testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ1\");"},{"lineNumber":57,"author":{"gitId":"-"},"content":" FeedbackResponseComment actualComment \u003d frcDb.getFeedbackResponseCommentForResponseFromParticipant(fr.getId());"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" assertEquals(expectedComment, actualComment);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" private FeedbackResponseComment prepareSqlInjectionTest() {"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" FeedbackResponseComment frc \u003d testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ1\");"},{"lineNumber":64,"author":{"gitId":"-"},"content":" assertNotNull(frcDb.getFeedbackResponseComment(frc.getId()));"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" return frc;"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" private void checkSqlInjectionFailed(FeedbackResponseComment frc) {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" assertNotNull(frcDb.getFeedbackResponseComment(frc.getId()));"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":74,"author":{"gitId":"-"},"content":" public void testSqlInjectionInUpdateGiverEmailOfFeedbackResponseComments() {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" FeedbackResponseComment frc \u003d prepareSqlInjectionTest();"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" String sqli \u003d \"\u0027; DELETE FROM feedback_response_comments;--\";"},{"lineNumber":78,"author":{"gitId":"-"},"content":" frcDb.updateGiverEmailOfFeedbackResponseComments(sqli, \"\", \"\");"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" checkSqlInjectionFailed(frc);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":84,"author":{"gitId":"-"},"content":" public void testSqlInjectionInUpdateLastEditorEmailOfFeedbackResponseComments() {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" FeedbackResponseComment frc \u003d prepareSqlInjectionTest();"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" String sqli \u003d \"\u0027; DELETE FROM feedback_response_comments;--\";"},{"lineNumber":88,"author":{"gitId":"-"},"content":" frcDb.updateLastEditorEmailOfFeedbackResponseComments(sqli, \"\", \"\");"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" checkSqlInjectionFailed(frc);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" }"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":94,"author":{"gitId":"-"},"content":" public void testSqlInjectionInCreateFeedbackResponseComment() throws Exception {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" FeedbackResponseComment frc \u003d prepareSqlInjectionTest();"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" FeedbackResponse fr \u003d testDataBundle.feedbackResponses.get(\"response1ForQ1\");"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" Section s \u003d testDataBundle.sections.get(\"section2InCourse1\");"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" String sqli \u003d \"\u0027\u0027);/**/DELETE/**/FROM/**/feedback_response_comments;--@gmail.com\";"},{"lineNumber":101,"author":{"gitId":"-"},"content":" FeedbackResponseComment newFrc \u003d new FeedbackResponseComment("},{"lineNumber":102,"author":{"gitId":"-"},"content":" fr, \"\", FeedbackParticipantType.INSTRUCTORS, s, s, \"\","},{"lineNumber":103,"author":{"gitId":"-"},"content":" false, false,"},{"lineNumber":104,"author":{"gitId":"-"},"content":" new ArrayList\u003c\u003e(), new ArrayList\u003c\u003e(), sqli);"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" frcDb.createFeedbackResponseComment(newFrc);"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" checkSqlInjectionFailed(frc);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" }"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":112,"author":{"gitId":"-"},"content":" public void testSqlInjectionInUpdateFeedbackResponseComment() throws Exception {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" FeedbackResponseComment frc \u003d prepareSqlInjectionTest();"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" String sqli \u003d \"\u0027\u0027);/**/DELETE/**/FROM/**/feedback_response_comments;--@gmail.com\";"},{"lineNumber":116,"author":{"gitId":"-"},"content":" frc.setLastEditorEmail(sqli);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" frcDb.updateFeedbackResponseComment(frc);"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" checkSqlInjectionFailed(frc);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" }"},{"lineNumber":121,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":122,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":123,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponseCommentsForSession_matchFound_success() {"},{"lineNumber":124,"author":{"gitId":"xenosf"},"content":" Course course \u003d testDataBundle.courses.get(\"course1\");"},{"lineNumber":125,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":126,"author":{"gitId":"xenosf"},"content":" ______TS(\"Session with comments\");"},{"lineNumber":127,"author":{"gitId":"xenosf"},"content":" FeedbackSession sessionWithComments \u003d testDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":128,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e expected \u003d List.of("},{"lineNumber":129,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ1\"),"},{"lineNumber":130,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment2ToResponse1ForQ1\"),"},{"lineNumber":131,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment2ToResponse2ForQ1\"),"},{"lineNumber":132,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ2s\"),"},{"lineNumber":133,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ3\"),"},{"lineNumber":134,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse4ForQ1\")"},{"lineNumber":135,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":136,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e results \u003d frcDb.getFeedbackResponseCommentsForSession("},{"lineNumber":137,"author":{"gitId":"xenosf"},"content":" course.getId(), sessionWithComments.getName());"},{"lineNumber":138,"author":{"gitId":"xenosf"},"content":" assertListCommentsEqual(expected, results);"},{"lineNumber":139,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":140,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":141,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":142,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponseCommentsForSession_matchNotFound_shouldReturnEmptyList() {"},{"lineNumber":143,"author":{"gitId":"xenosf"},"content":" Course course \u003d testDataBundle.courses.get(\"course1\");"},{"lineNumber":144,"author":{"gitId":"xenosf"},"content":" FeedbackSession session \u003d testDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":145,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":146,"author":{"gitId":"xenosf"},"content":" ______TS(\"Course not found\");"},{"lineNumber":147,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e results \u003d frcDb.getFeedbackResponseCommentsForSession(\"not_exist\", session.getName());"},{"lineNumber":148,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":149,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":150,"author":{"gitId":"xenosf"},"content":" ______TS(\"Session not found\");"},{"lineNumber":151,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForSession(course.getId(), \"Nonexistent session\");"},{"lineNumber":152,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":153,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":154,"author":{"gitId":"xenosf"},"content":" ______TS(\"Session without comments\");"},{"lineNumber":155,"author":{"gitId":"xenosf"},"content":" FeedbackSession sessionWithoutComments \u003d testDataBundle.feedbackSessions.get(\"ongoingSession1InCourse1\");"},{"lineNumber":156,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForSession(course.getId(), sessionWithoutComments.getName());"},{"lineNumber":157,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":158,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":159,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":160,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":161,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponseCommentsForQuestion_matchFound_success() {"},{"lineNumber":162,"author":{"gitId":"xenosf"},"content":" ______TS(\"Question with comments\");"},{"lineNumber":163,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion questionWithComments \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":164,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e expectedComments \u003d List.of("},{"lineNumber":165,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ1\"),"},{"lineNumber":166,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment2ToResponse1ForQ1\"),"},{"lineNumber":167,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment2ToResponse2ForQ1\"),"},{"lineNumber":168,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse4ForQ1\")"},{"lineNumber":169,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":170,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e results \u003d frcDb.getFeedbackResponseCommentsForQuestion(questionWithComments.getId());"},{"lineNumber":171,"author":{"gitId":"xenosf"},"content":" assertListCommentsEqual(expectedComments, results);"},{"lineNumber":172,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":173,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":174,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":175,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponseCommentsForQuestion_matchNotFound_shouldReturnEmptyList() {"},{"lineNumber":176,"author":{"gitId":"xenosf"},"content":" ______TS(\"Question not found\");"},{"lineNumber":177,"author":{"gitId":"xenosf"},"content":" UUID nonexistentQuestionId \u003d UUID.fromString(\"11110000-0000-0000-0000-000000000000\");"},{"lineNumber":178,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e results \u003d frcDb.getFeedbackResponseCommentsForQuestion(nonexistentQuestionId);"},{"lineNumber":179,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":180,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":181,"author":{"gitId":"xenosf"},"content":" ______TS(\"Question without comments\");"},{"lineNumber":182,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion questionWithoutComments \u003d testDataBundle.feedbackQuestions.get(\"qn5InSession1InCourse1\");"},{"lineNumber":183,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForQuestion(questionWithoutComments.getId());"},{"lineNumber":184,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":185,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":186,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":187,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":188,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponseCommentsForSessionInSection_matchFound_success()"},{"lineNumber":189,"author":{"gitId":"xenosf"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":190,"author":{"gitId":"xenosf"},"content":" Section section1 \u003d testDataBundle.sections.get(\"section1InCourse1\");"},{"lineNumber":191,"author":{"gitId":"xenosf"},"content":" Section section2 \u003d testDataBundle.sections.get(\"section2InCourse1\");"},{"lineNumber":192,"author":{"gitId":"xenosf"},"content":" Course course \u003d testDataBundle.courses.get(\"course1\");"},{"lineNumber":193,"author":{"gitId":"xenosf"},"content":" FeedbackSession session1 \u003d testDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":194,"author":{"gitId":"xenosf"},"content":" FeedbackSession session2 \u003d testDataBundle.feedbackSessions.get(\"session2InTypicalCourse\");"},{"lineNumber":195,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":196,"author":{"gitId":"xenosf"},"content":" ______TS(\"Section 1 Session 2 match\");"},{"lineNumber":197,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e expected \u003d List.of("},{"lineNumber":198,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ1InSession2\")"},{"lineNumber":199,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":200,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e results \u003d frcDb.getFeedbackResponseCommentsForSessionInSection("},{"lineNumber":201,"author":{"gitId":"xenosf"},"content":" course.getId(), session2.getName(), section1.getName());"},{"lineNumber":202,"author":{"gitId":"xenosf"},"content":" assertListCommentsEqual(expected, results);"},{"lineNumber":203,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":204,"author":{"gitId":"xenosf"},"content":" ______TS(\"Section 2 Session 1 match\");"},{"lineNumber":205,"author":{"gitId":"xenosf"},"content":" expected \u003d List.of("},{"lineNumber":206,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse4ForQ1\")"},{"lineNumber":207,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":208,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForSessionInSection("},{"lineNumber":209,"author":{"gitId":"xenosf"},"content":" course.getId(), session1.getName(), section2.getName());"},{"lineNumber":210,"author":{"gitId":"xenosf"},"content":" assertListCommentsEqual(expected, results);"},{"lineNumber":211,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":212,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":213,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponseCommentsForSessionInSection_matchNotFound_shouldReturnEmptyList() {"},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" Course course \u003d testDataBundle.courses.get(\"course1\");"},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" FeedbackSession session1 \u003d testDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":217,"author":{"gitId":"xenosf"},"content":" FeedbackSession session2 \u003d testDataBundle.feedbackSessions.get(\"session2InTypicalCourse\");"},{"lineNumber":218,"author":{"gitId":"xenosf"},"content":" Section section1 \u003d testDataBundle.sections.get(\"section1InCourse1\");"},{"lineNumber":219,"author":{"gitId":"xenosf"},"content":" Section section2 \u003d testDataBundle.sections.get(\"section2InCourse1\");"},{"lineNumber":220,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":221,"author":{"gitId":"xenosf"},"content":" ______TS(\"Course not found\");"},{"lineNumber":222,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e results \u003d frcDb.getFeedbackResponseCommentsForSessionInSection("},{"lineNumber":223,"author":{"gitId":"xenosf"},"content":" \"not_exist\", session1.getName(), section1.getName());"},{"lineNumber":224,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":225,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":226,"author":{"gitId":"xenosf"},"content":" ______TS(\"Session not found\");"},{"lineNumber":227,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForSessionInSection("},{"lineNumber":228,"author":{"gitId":"xenosf"},"content":" course.getId(), \"Nonexistent session\", section1.getName());"},{"lineNumber":229,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":230,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":231,"author":{"gitId":"xenosf"},"content":" ______TS(\"Section not found\");"},{"lineNumber":232,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForSessionInSection("},{"lineNumber":233,"author":{"gitId":"xenosf"},"content":" course.getId(), session1.getName(), \"Nonexistent section\");"},{"lineNumber":234,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":235,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":236,"author":{"gitId":"xenosf"},"content":" ______TS(\"No matching comments exist\");"},{"lineNumber":237,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForSessionInSection("},{"lineNumber":238,"author":{"gitId":"xenosf"},"content":" course.getId(), session2.getName(), section2.getName());"},{"lineNumber":239,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":240,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":241,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":242,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":243,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponseCommentsForQuestionInSection_matchFound_success() {"},{"lineNumber":244,"author":{"gitId":"xenosf"},"content":" Section section1 \u003d testDataBundle.sections.get(\"section1InCourse1\");"},{"lineNumber":245,"author":{"gitId":"xenosf"},"content":" Section section2 \u003d testDataBundle.sections.get(\"section2InCourse1\");"},{"lineNumber":246,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question1 \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":247,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question2 \u003d testDataBundle.feedbackQuestions.get(\"qn2InSession1InCourse1\");"},{"lineNumber":248,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":249,"author":{"gitId":"xenosf"},"content":" ______TS(\"Section 1 Question 1 match\");"},{"lineNumber":250,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e expected \u003d List.of("},{"lineNumber":251,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ1\"),"},{"lineNumber":252,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment2ToResponse1ForQ1\"),"},{"lineNumber":253,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment2ToResponse2ForQ1\"),"},{"lineNumber":254,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse4ForQ1\")"},{"lineNumber":255,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":256,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e results \u003d frcDb.getFeedbackResponseCommentsForQuestionInSection("},{"lineNumber":257,"author":{"gitId":"xenosf"},"content":" question1.getId(), section1.getName());"},{"lineNumber":258,"author":{"gitId":"xenosf"},"content":" assertListCommentsEqual(expected, results);"},{"lineNumber":259,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":260,"author":{"gitId":"xenosf"},"content":" ______TS(\"Section 2 Question 1 match\");"},{"lineNumber":261,"author":{"gitId":"xenosf"},"content":" expected \u003d List.of("},{"lineNumber":262,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse4ForQ1\")"},{"lineNumber":263,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":264,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForQuestionInSection("},{"lineNumber":265,"author":{"gitId":"xenosf"},"content":" question1.getId(), section2.getName());"},{"lineNumber":266,"author":{"gitId":"xenosf"},"content":" assertListCommentsEqual(expected, results);"},{"lineNumber":267,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":268,"author":{"gitId":"xenosf"},"content":" ______TS(\"Section 1 Question 2 match\");"},{"lineNumber":269,"author":{"gitId":"xenosf"},"content":" expected \u003d List.of("},{"lineNumber":270,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ2s\")"},{"lineNumber":271,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":272,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForQuestionInSection("},{"lineNumber":273,"author":{"gitId":"xenosf"},"content":" question2.getId(), section1.getName());"},{"lineNumber":274,"author":{"gitId":"xenosf"},"content":" assertListCommentsEqual(expected, results);"},{"lineNumber":275,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":276,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":277,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":278,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponseCommentsForQuestionInSection_matchNotFound_shouldReturnEmptyList() {"},{"lineNumber":279,"author":{"gitId":"xenosf"},"content":" Section section \u003d testDataBundle.sections.get(\"section1InCourse1\");"},{"lineNumber":280,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question1 \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":281,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question2 \u003d testDataBundle.feedbackQuestions.get(\"qn4InSession1InCourse1\");"},{"lineNumber":282,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":283,"author":{"gitId":"xenosf"},"content":" ______TS(\"Question not found\");"},{"lineNumber":284,"author":{"gitId":"xenosf"},"content":" UUID nonexistentQuestionId \u003d UUID.fromString(\"11110000-0000-0000-0000-000000000000\");"},{"lineNumber":285,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e results \u003d frcDb.getFeedbackResponseCommentsForQuestionInSection("},{"lineNumber":286,"author":{"gitId":"xenosf"},"content":" nonexistentQuestionId, section.getName());"},{"lineNumber":287,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":288,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":289,"author":{"gitId":"xenosf"},"content":" ______TS(\"Section not found\");"},{"lineNumber":290,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForQuestionInSection(question1.getId(), \"Nonexistent section\");"},{"lineNumber":291,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":292,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":293,"author":{"gitId":"xenosf"},"content":" ______TS(\"No matching comments exist\");"},{"lineNumber":294,"author":{"gitId":"xenosf"},"content":" results \u003d frcDb.getFeedbackResponseCommentsForQuestionInSection(question2.getId(), section.getName());"},{"lineNumber":295,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":296,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":297,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":298,"author":{"gitId":"xenosf"},"content":" private void assertListCommentsEqual(List\u003cFeedbackResponseComment\u003e expected, List\u003cFeedbackResponseComment\u003e actual) {"},{"lineNumber":299,"author":{"gitId":"xenosf"},"content":" assertTrue("},{"lineNumber":300,"author":{"gitId":"xenosf"},"content":" String.format(\"List contents are not equal.%nExpected: %s,%nActual: %s\","},{"lineNumber":301,"author":{"gitId":"xenosf"},"content":" expected.toString(), actual.toString()),"},{"lineNumber":302,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(expected).equals(new HashSet\u003c\u003e(actual)));"},{"lineNumber":303,"author":{"gitId":"xenosf"},"content":" assertEquals(\"List size not equal.\", expected.size(), actual.size());"},{"lineNumber":304,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":305,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":306,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":202,"-":104}},{"path":"src/it/java/teammates/it/storage/sqlapi/FeedbackResponsesDbIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import java.util.HashSet;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import java.util.UUID;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.FeedbackResultFetchType;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackResponseDetails;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackTextResponseDetails;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackResponseCommentsDb;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackResponsesDb;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackTextResponse;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":28,"author":{"gitId":"-"},"content":" * SUT: {@link FeedbackResponsesDb}."},{"lineNumber":29,"author":{"gitId":"-"},"content":" */"},{"lineNumber":30,"author":{"gitId":"-"},"content":"public class FeedbackResponsesDbIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" private final FeedbackResponsesDb frDb \u003d FeedbackResponsesDb.inst();"},{"lineNumber":33,"author":{"gitId":"-"},"content":" private final FeedbackResponseCommentsDb frcDb \u003d FeedbackResponseCommentsDb.inst();"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" private SqlDataBundle testDataBundle;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"-"},"content":" @BeforeClass"},{"lineNumber":39,"author":{"gitId":"-"},"content":" public void setupClass() {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" super.setupClass();"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" testDataBundle \u003d loadSqlDataBundle(\"/FeedbackResponsesITBundle.json\");"},{"lineNumber":42,"author":{"gitId":"-"},"content":" }"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":45,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":46,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" persistDataBundle(testDataBundle);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":50,"author":{"gitId":"-"},"content":" HibernateUtil.clearSession();"},{"lineNumber":51,"author":{"gitId":"-"},"content":" }"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":54,"author":{"gitId":"-"},"content":" public void testGetFeedbackResponsesFromGiverForQuestion() {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion fq \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e expectedQuestions \u003d List.of("},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response1ForQ1\"),"},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response3ForQ1\")"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponse\u003e actualQuestions \u003d"},{"lineNumber":64,"author":{"gitId":"-"},"content":" frDb.getFeedbackResponsesFromGiverForQuestion(fq.getId(), \"student1@teammates.tmt\");"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestions.size(), actualQuestions.size());"},{"lineNumber":67,"author":{"gitId":"-"},"content":" assertTrue(expectedQuestions.containsAll(actualQuestions));"},{"lineNumber":68,"author":{"gitId":"-"},"content":" }"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":71,"author":{"gitId":"-"},"content":" public void testDeleteFeedbackResponsesForQuestionCascade() {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion fq \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" FeedbackResponse fr1 \u003d testDataBundle.feedbackResponses.get(\"response1ForQ1\");"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" FeedbackResponse fr2 \u003d testDataBundle.feedbackResponses.get(\"response2ForQ1\");"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" FeedbackResponseComment frc1 \u003d testDataBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ1\");"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" frDb.deleteFeedbackResponsesForQuestionCascade(fq.getId());"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" assertNull(frDb.getFeedbackResponse(fr1.getId()));"},{"lineNumber":81,"author":{"gitId":"-"},"content":" assertNull(frDb.getFeedbackResponse(fr2.getId()));"},{"lineNumber":82,"author":{"gitId":"-"},"content":" assertNull(frcDb.getFeedbackResponseComment(frc1.getId()));"},{"lineNumber":83,"author":{"gitId":"-"},"content":" }"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":86,"author":{"gitId":"-"},"content":" public void testDeleteFeedback() {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" FeedbackResponse fr1 \u003d testDataBundle.feedbackResponses.get(\"response1ForQ1\");"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" frDb.deleteFeedbackResponse(fr1);"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" assertNull(frDb.getFeedbackResponse(fr1.getId()));"},{"lineNumber":93,"author":{"gitId":"-"},"content":" }"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":96,"author":{"gitId":"-"},"content":" public void testHasResponsesFromGiverInSession() {"},{"lineNumber":97,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" Course course \u003d testDataBundle.courses.get(\"course1\");"},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" FeedbackSession fs \u003d testDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" boolean actualHasReponses1 \u003d"},{"lineNumber":102,"author":{"gitId":"-"},"content":" frDb.hasResponsesFromGiverInSession(\"student1@teammates.tmt\", fs.getName(), course.getId());"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" assertTrue(actualHasReponses1);"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" ______TS(\"student with no responses\");"},{"lineNumber":107,"author":{"gitId":"-"},"content":" boolean actualHasReponses2 \u003d"},{"lineNumber":108,"author":{"gitId":"-"},"content":" frDb.hasResponsesFromGiverInSession(\"studentnorespones@teammates.tmt\", fs.getName(), course.getId());"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" assertFalse(actualHasReponses2);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":114,"author":{"gitId":"-"},"content":" public void testAreThereResponsesForQuestion() {"},{"lineNumber":115,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion fq1 \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" boolean actualResponse1 \u003d"},{"lineNumber":119,"author":{"gitId":"-"},"content":" frDb.areThereResponsesForQuestion(fq1.getId());"},{"lineNumber":120,"author":{"gitId":"-"},"content":""},{"lineNumber":121,"author":{"gitId":"-"},"content":" assertTrue(actualResponse1);"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" ______TS(\"feedback question with no responses\");"},{"lineNumber":124,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion fq2 \u003d testDataBundle.feedbackQuestions.get(\"qn6InSession1InCourse1NoResponses\");"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" boolean actualResponse2 \u003d"},{"lineNumber":127,"author":{"gitId":"-"},"content":" frDb.areThereResponsesForQuestion(fq2.getId());"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" assertFalse(actualResponse2);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" }"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":133,"author":{"gitId":"-"},"content":" public void testHasResponsesForCourse() {"},{"lineNumber":134,"author":{"gitId":"-"},"content":" ______TS(\"success: typical case\");"},{"lineNumber":135,"author":{"gitId":"xenosf"},"content":" Course course \u003d testDataBundle.courses.get(\"course1\");"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" boolean actual \u003d"},{"lineNumber":138,"author":{"gitId":"-"},"content":" frDb.hasResponsesForCourse(course.getId());"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" assertTrue(actual);"},{"lineNumber":141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" private FeedbackResponse prepareSqlInjectionTest() {"},{"lineNumber":144,"author":{"gitId":"xenosf"},"content":" FeedbackResponse fr \u003d testDataBundle.feedbackResponses.get(\"response1ForQ1\");"},{"lineNumber":145,"author":{"gitId":"-"},"content":" assertNotNull(frDb.getFeedbackResponse(fr.getId()));"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" return fr;"},{"lineNumber":148,"author":{"gitId":"-"},"content":" }"},{"lineNumber":149,"author":{"gitId":"-"},"content":""},{"lineNumber":150,"author":{"gitId":"-"},"content":" private void checkSqliFailed(FeedbackResponse fr) {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" // If SQLi is successful, feedback responses would have been deleted from db."},{"lineNumber":152,"author":{"gitId":"-"},"content":" // So get will return null."},{"lineNumber":153,"author":{"gitId":"-"},"content":" assertNotNull(frDb.getFeedbackResponse(fr.getId()));"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":157,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetFeedbackResponsesFromGiverForCourse() {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" FeedbackResponse fr \u003d prepareSqlInjectionTest();"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in GetFeedbackResponsesFromGiverForCourse, courseId param\");"},{"lineNumber":161,"author":{"gitId":"-"},"content":" String courseId \u003d \"\u0027; DELETE FROM feedback_responses;--\";"},{"lineNumber":162,"author":{"gitId":"-"},"content":" frDb.getFeedbackResponsesFromGiverForCourse(courseId, \"\");"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" checkSqliFailed(fr);"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":168,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetFeedbackResponsesForRecipientForCourse() {"},{"lineNumber":169,"author":{"gitId":"-"},"content":" FeedbackResponse fr \u003d prepareSqlInjectionTest();"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in GetFeedbackResponsesForRecipientForCourse, courseId param\");"},{"lineNumber":172,"author":{"gitId":"-"},"content":" String courseId \u003d \"\u0027; DELETE FROM feedback_responses;--\";"},{"lineNumber":173,"author":{"gitId":"-"},"content":" frDb.getFeedbackResponsesForRecipientForCourse(courseId, \"\");"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" checkSqliFailed(fr);"},{"lineNumber":176,"author":{"gitId":"-"},"content":" }"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":179,"author":{"gitId":"-"},"content":" public void testSqlInjectionInGetFeedbackResponsesFromGiverForQuestion() {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" FeedbackResponse fr \u003d prepareSqlInjectionTest();"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in GetFeedbackResponsesFromGiverForQuestion, giverEmail param\");"},{"lineNumber":183,"author":{"gitId":"-"},"content":" String giverEmail \u003d \"\u0027;/**/DELETE/**/FROM/**/feedback_responses;--@gmail.com\";"},{"lineNumber":184,"author":{"gitId":"-"},"content":" frDb.getFeedbackResponsesFromGiverForQuestion(fr.getId(), giverEmail);"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" checkSqliFailed(fr);"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":190,"author":{"gitId":"-"},"content":" public void testSqlInjectionInHasResponsesFromGiverInSession() {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" FeedbackResponse fr \u003d prepareSqlInjectionTest();"},{"lineNumber":192,"author":{"gitId":"-"},"content":""},{"lineNumber":193,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in HasResponsesFromGiverInSession, giver param\");"},{"lineNumber":194,"author":{"gitId":"-"},"content":" String giver \u003d \"\u0027; DELETE FROM feedback_responses;--\";"},{"lineNumber":195,"author":{"gitId":"-"},"content":" frDb.hasResponsesFromGiverInSession(giver, \"\", \"\");"},{"lineNumber":196,"author":{"gitId":"-"},"content":""},{"lineNumber":197,"author":{"gitId":"-"},"content":" checkSqliFailed(fr);"},{"lineNumber":198,"author":{"gitId":"-"},"content":" }"},{"lineNumber":199,"author":{"gitId":"-"},"content":""},{"lineNumber":200,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":201,"author":{"gitId":"-"},"content":" public void testSqlInjectionInHasResponsesForCourse() {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" FeedbackResponse fr \u003d prepareSqlInjectionTest();"},{"lineNumber":203,"author":{"gitId":"-"},"content":""},{"lineNumber":204,"author":{"gitId":"-"},"content":" ______TS(\"SQL Injection test in HasResponsesForCourse, courseId param\");"},{"lineNumber":205,"author":{"gitId":"-"},"content":" String courseId \u003d \"\u0027; DELETE FROM feedback_responses;--\";"},{"lineNumber":206,"author":{"gitId":"-"},"content":" frDb.hasResponsesForCourse(courseId);"},{"lineNumber":207,"author":{"gitId":"-"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" checkSqliFailed(fr);"},{"lineNumber":209,"author":{"gitId":"-"},"content":" }"},{"lineNumber":210,"author":{"gitId":"-"},"content":""},{"lineNumber":211,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":212,"author":{"gitId":"-"},"content":" public void testSqlInjectionInCreateFeedbackResponse() throws Exception {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" FeedbackResponse fr \u003d prepareSqlInjectionTest();"},{"lineNumber":214,"author":{"gitId":"-"},"content":""},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion fq \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" Section s \u003d testDataBundle.sections.get(\"section1InCourse1\");"},{"lineNumber":217,"author":{"gitId":"-"},"content":" String dummyUuid \u003d \"00000000-0000-4000-8000-000000000001\";"},{"lineNumber":218,"author":{"gitId":"-"},"content":" FeedbackResponseDetails frd \u003d new FeedbackTextResponseDetails();"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" String sqli \u003d \"\u0027, \" + dummyUuid + \", \" + dummyUuid + \"); DELETE FROM feedback_responses;--\";"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"-"},"content":" FeedbackResponse newFr \u003d new FeedbackTextResponse(fq, \"\", s, sqli, s, frd);"},{"lineNumber":223,"author":{"gitId":"-"},"content":" frDb.createFeedbackResponse(newFr);"},{"lineNumber":224,"author":{"gitId":"-"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":" checkSqliFailed(fr);"},{"lineNumber":226,"author":{"gitId":"-"},"content":" }"},{"lineNumber":227,"author":{"gitId":"-"},"content":""},{"lineNumber":228,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":229,"author":{"gitId":"-"},"content":" public void testSqlInjectionInCpdateFeedbackResponse() throws Exception {"},{"lineNumber":230,"author":{"gitId":"-"},"content":" FeedbackResponse fr \u003d prepareSqlInjectionTest();"},{"lineNumber":231,"author":{"gitId":"-"},"content":""},{"lineNumber":232,"author":{"gitId":"-"},"content":" String sqli \u003d \"\u0027\u0027); DELETE FROM feedback_response_comments;--\";"},{"lineNumber":233,"author":{"gitId":"-"},"content":" fr.setGiver(sqli);"},{"lineNumber":234,"author":{"gitId":"-"},"content":" frDb.updateFeedbackResponse(fr);"},{"lineNumber":235,"author":{"gitId":"-"},"content":""},{"lineNumber":236,"author":{"gitId":"-"},"content":" checkSqliFailed(fr);"},{"lineNumber":237,"author":{"gitId":"-"},"content":" }"},{"lineNumber":238,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":239,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":240,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponsesForRecipientForQuestion_matchNotFound_shouldReturnEmptyList() {"},{"lineNumber":241,"author":{"gitId":"xenosf"},"content":" ______TS(\"Question not found\");"},{"lineNumber":242,"author":{"gitId":"xenosf"},"content":" String recipient \u003d \"student1@teammates.tmt\";"},{"lineNumber":243,"author":{"gitId":"xenosf"},"content":" UUID nonexistentQuestionId \u003d UUID.fromString(\"11110000-0000-0000-0000-000000000000\");"},{"lineNumber":244,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e results \u003d frDb.getFeedbackResponsesForRecipientForQuestion(nonexistentQuestionId, recipient);"},{"lineNumber":245,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":246,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":247,"author":{"gitId":"xenosf"},"content":" ______TS(\"No matching responses exist\");"},{"lineNumber":248,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion questionWithNoResponses \u003d testDataBundle.feedbackQuestions.get(\"qn4InSession1InCourse1\");"},{"lineNumber":249,"author":{"gitId":"xenosf"},"content":" results \u003d frDb.getFeedbackResponsesForRecipientForQuestion(questionWithNoResponses.getId(), recipient);"},{"lineNumber":250,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":251,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":252,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":253,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":254,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":255,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponsesForRecipientForQuestion_matchFound_success() {"},{"lineNumber":256,"author":{"gitId":"xenosf"},"content":" ______TS(\"Matching responses exist\");"},{"lineNumber":257,"author":{"gitId":"xenosf"},"content":" String recipient \u003d \"student2@teammates.tmt\";"},{"lineNumber":258,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":259,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e expected \u003d List.of("},{"lineNumber":260,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response2ForQ1\")"},{"lineNumber":261,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":262,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e actual \u003d frDb.getFeedbackResponsesForRecipientForQuestion(question.getId(), recipient);"},{"lineNumber":263,"author":{"gitId":"xenosf"},"content":" assertListResponsesEqual(expected, actual);"},{"lineNumber":264,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":265,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":266,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":267,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":268,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponsesForSessionInSection_matchNotFound_shouldReturnEmptyList() {"},{"lineNumber":269,"author":{"gitId":"xenosf"},"content":" String section3 \u003d testDataBundle.sections.get(\"section3InCourse1\").getName();"},{"lineNumber":270,"author":{"gitId":"xenosf"},"content":" FeedbackSession session \u003d testDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":271,"author":{"gitId":"xenosf"},"content":" String courseId \u003d session.getCourse().getId();"},{"lineNumber":272,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":273,"author":{"gitId":"xenosf"},"content":" ______TS(\"No matching responses exist for giver section\");"},{"lineNumber":274,"author":{"gitId":"xenosf"},"content":" FeedbackResultFetchType fetchType \u003d FeedbackResultFetchType.GIVER;"},{"lineNumber":275,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e results \u003d frDb.getFeedbackResponsesForSessionInSection("},{"lineNumber":276,"author":{"gitId":"xenosf"},"content":" session, courseId, section3, fetchType);"},{"lineNumber":277,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":278,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":279,"author":{"gitId":"xenosf"},"content":" ______TS(\"No matching responses exist for recipient section\");"},{"lineNumber":280,"author":{"gitId":"xenosf"},"content":" fetchType \u003d FeedbackResultFetchType.RECEIVER;"},{"lineNumber":281,"author":{"gitId":"xenosf"},"content":" results \u003d frDb.getFeedbackResponsesForSessionInSection(session, courseId, section3, fetchType);"},{"lineNumber":282,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":283,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":284,"author":{"gitId":"xenosf"},"content":" ______TS(\"No matching responses exist for both giver and recipient section\");"},{"lineNumber":285,"author":{"gitId":"xenosf"},"content":" fetchType \u003d FeedbackResultFetchType.BOTH;"},{"lineNumber":286,"author":{"gitId":"xenosf"},"content":" results \u003d frDb.getFeedbackResponsesForSessionInSection(session, courseId, section3, fetchType);"},{"lineNumber":287,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":288,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":289,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":290,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":291,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponsesForSessionInSection_matchFound_success() {"},{"lineNumber":292,"author":{"gitId":"xenosf"},"content":" Course course \u003d testDataBundle.courses.get(\"course1\");"},{"lineNumber":293,"author":{"gitId":"xenosf"},"content":" FeedbackSession session1 \u003d testDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":294,"author":{"gitId":"xenosf"},"content":" Section section1 \u003d testDataBundle.sections.get(\"section1InCourse1\");"},{"lineNumber":295,"author":{"gitId":"xenosf"},"content":" Section section2 \u003d testDataBundle.sections.get(\"section2InCourse1\");"},{"lineNumber":296,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":297,"author":{"gitId":"xenosf"},"content":" ______TS(\"Match giver section 1 in session 1\");"},{"lineNumber":298,"author":{"gitId":"xenosf"},"content":" FeedbackResultFetchType fetchType \u003d FeedbackResultFetchType.GIVER;"},{"lineNumber":299,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e expected \u003d List.of("},{"lineNumber":300,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response1ForQ1\"),"},{"lineNumber":301,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response2ForQ1\"),"},{"lineNumber":302,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response1ForQ2\"),"},{"lineNumber":303,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response2ForQ2\"),"},{"lineNumber":304,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response1ForQ3\"),"},{"lineNumber":305,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response3ForQ1\"),"},{"lineNumber":306,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response3ForQ2\")"},{"lineNumber":307,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":308,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e actual \u003d frDb.getFeedbackResponsesForSessionInSection("},{"lineNumber":309,"author":{"gitId":"xenosf"},"content":" session1, course.getId(), section1.getName(), fetchType);"},{"lineNumber":310,"author":{"gitId":"xenosf"},"content":" assertListResponsesEqual(expected, actual);"},{"lineNumber":311,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":312,"author":{"gitId":"xenosf"},"content":" ______TS(\"Match recipient section 2 in session 1\");"},{"lineNumber":313,"author":{"gitId":"xenosf"},"content":" fetchType \u003d FeedbackResultFetchType.RECEIVER;"},{"lineNumber":314,"author":{"gitId":"xenosf"},"content":" expected \u003d List.of("},{"lineNumber":315,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response3ForQ1\"),"},{"lineNumber":316,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response3ForQ2\"),"},{"lineNumber":317,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response4ForQ1\")"},{"lineNumber":318,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":319,"author":{"gitId":"xenosf"},"content":" actual \u003d frDb.getFeedbackResponsesForSessionInSection(session1, course.getId(),"},{"lineNumber":320,"author":{"gitId":"xenosf"},"content":" section2.getName(), fetchType);"},{"lineNumber":321,"author":{"gitId":"xenosf"},"content":" assertListResponsesEqual(expected, actual);"},{"lineNumber":322,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":323,"author":{"gitId":"xenosf"},"content":" ______TS(\"Match both giver and recipient section 2 in session 1\");"},{"lineNumber":324,"author":{"gitId":"xenosf"},"content":" fetchType \u003d FeedbackResultFetchType.BOTH;"},{"lineNumber":325,"author":{"gitId":"xenosf"},"content":" expected \u003d List.of("},{"lineNumber":326,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response4ForQ1\")"},{"lineNumber":327,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":328,"author":{"gitId":"xenosf"},"content":" actual \u003d frDb.getFeedbackResponsesForSessionInSection(session1, course.getId(),"},{"lineNumber":329,"author":{"gitId":"xenosf"},"content":" section2.getName(), fetchType);"},{"lineNumber":330,"author":{"gitId":"xenosf"},"content":" assertListResponsesEqual(expected, actual);"},{"lineNumber":331,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":332,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":333,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":334,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponsesForQuestionInSection_matchNotFound_shouldReturnEmptyList() {"},{"lineNumber":335,"author":{"gitId":"xenosf"},"content":" String section1 \u003d testDataBundle.sections.get(\"section1InCourse1\").getName();"},{"lineNumber":336,"author":{"gitId":"xenosf"},"content":" String section3 \u003d testDataBundle.sections.get(\"section3InCourse1\").getName();"},{"lineNumber":337,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":338,"author":{"gitId":"xenosf"},"content":" ______TS(\"Question not found\");"},{"lineNumber":339,"author":{"gitId":"xenosf"},"content":" UUID nonexistentQuestionId \u003d UUID.fromString(\"11110000-0000-0000-0000-000000000000\");"},{"lineNumber":340,"author":{"gitId":"xenosf"},"content":" FeedbackResultFetchType fetchType \u003d FeedbackResultFetchType.BOTH;"},{"lineNumber":341,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e results \u003d frDb.getFeedbackResponsesForQuestionInSection(nonexistentQuestionId,"},{"lineNumber":342,"author":{"gitId":"xenosf"},"content":" section1, fetchType);"},{"lineNumber":343,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":344,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":345,"author":{"gitId":"xenosf"},"content":" ______TS(\"No matching responses exist for giver section\");"},{"lineNumber":346,"author":{"gitId":"xenosf"},"content":" UUID questionId \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\").getId();"},{"lineNumber":347,"author":{"gitId":"xenosf"},"content":" fetchType \u003d FeedbackResultFetchType.GIVER;"},{"lineNumber":348,"author":{"gitId":"xenosf"},"content":" results \u003d frDb.getFeedbackResponsesForQuestionInSection(questionId, section3, fetchType);"},{"lineNumber":349,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":350,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":351,"author":{"gitId":"xenosf"},"content":" ______TS(\"No matching responses exist for recipient section\");"},{"lineNumber":352,"author":{"gitId":"xenosf"},"content":" fetchType \u003d FeedbackResultFetchType.RECEIVER;"},{"lineNumber":353,"author":{"gitId":"xenosf"},"content":" results \u003d frDb.getFeedbackResponsesForQuestionInSection(questionId, section3, fetchType);"},{"lineNumber":354,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":355,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":356,"author":{"gitId":"xenosf"},"content":" ______TS(\"No matching responses exist for both giver and recipient section\");"},{"lineNumber":357,"author":{"gitId":"xenosf"},"content":" fetchType \u003d FeedbackResultFetchType.BOTH;"},{"lineNumber":358,"author":{"gitId":"xenosf"},"content":" results \u003d frDb.getFeedbackResponsesForQuestionInSection(questionId, section3, fetchType);"},{"lineNumber":359,"author":{"gitId":"xenosf"},"content":" assertEquals(0, results.size());"},{"lineNumber":360,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":361,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":362,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":363,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponsesForQuestionInSection_matchFound_success() {"},{"lineNumber":364,"author":{"gitId":"xenosf"},"content":" Section section1 \u003d testDataBundle.sections.get(\"section1InCourse1\");"},{"lineNumber":365,"author":{"gitId":"xenosf"},"content":" Section section2 \u003d testDataBundle.sections.get(\"section2InCourse1\");"},{"lineNumber":366,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question1 \u003d testDataBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":367,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":368,"author":{"gitId":"xenosf"},"content":" ______TS(\"Match giver section 1 for Q1\");"},{"lineNumber":369,"author":{"gitId":"xenosf"},"content":" FeedbackResultFetchType fetchType \u003d FeedbackResultFetchType.GIVER;"},{"lineNumber":370,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e expected \u003d List.of("},{"lineNumber":371,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response1ForQ1\"),"},{"lineNumber":372,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response2ForQ1\"),"},{"lineNumber":373,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response3ForQ1\")"},{"lineNumber":374,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":375,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e actual \u003d frDb.getFeedbackResponsesForQuestionInSection(question1.getId(),"},{"lineNumber":376,"author":{"gitId":"xenosf"},"content":" section1.getName(), fetchType);"},{"lineNumber":377,"author":{"gitId":"xenosf"},"content":" assertListResponsesEqual(expected, actual);"},{"lineNumber":378,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":379,"author":{"gitId":"xenosf"},"content":" ______TS(\"Match recipient section 2 for Q1\");"},{"lineNumber":380,"author":{"gitId":"xenosf"},"content":" fetchType \u003d FeedbackResultFetchType.RECEIVER;"},{"lineNumber":381,"author":{"gitId":"xenosf"},"content":" expected \u003d List.of("},{"lineNumber":382,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response3ForQ1\"),"},{"lineNumber":383,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response4ForQ1\")"},{"lineNumber":384,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":385,"author":{"gitId":"xenosf"},"content":" actual \u003d frDb.getFeedbackResponsesForQuestionInSection(question1.getId(), section2.getName(), fetchType);"},{"lineNumber":386,"author":{"gitId":"xenosf"},"content":" assertListResponsesEqual(expected, actual);"},{"lineNumber":387,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":388,"author":{"gitId":"xenosf"},"content":" ______TS(\"Match both giver and recipient section 2 for Q1\");"},{"lineNumber":389,"author":{"gitId":"xenosf"},"content":" fetchType \u003d FeedbackResultFetchType.BOTH;"},{"lineNumber":390,"author":{"gitId":"xenosf"},"content":" expected \u003d List.of("},{"lineNumber":391,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response4ForQ1\")"},{"lineNumber":392,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":393,"author":{"gitId":"xenosf"},"content":" actual \u003d frDb.getFeedbackResponsesForQuestionInSection(question1.getId(), section2.getName(), fetchType);"},{"lineNumber":394,"author":{"gitId":"xenosf"},"content":" assertListResponsesEqual(expected, actual);"},{"lineNumber":395,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":396,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":397,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":398,"author":{"gitId":"xenosf"},"content":" public void testGetFeedbackResponsesForSession() {"},{"lineNumber":399,"author":{"gitId":"xenosf"},"content":" ______TS(\"Session has responses\");"},{"lineNumber":400,"author":{"gitId":"xenosf"},"content":" FeedbackSession sessionWithResponses \u003d testDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":401,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e expected \u003d List.of("},{"lineNumber":402,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response1ForQ1\"),"},{"lineNumber":403,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response2ForQ1\"),"},{"lineNumber":404,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response1ForQ2\"),"},{"lineNumber":405,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response2ForQ2\"),"},{"lineNumber":406,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response1ForQ3\"),"},{"lineNumber":407,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response3ForQ1\"),"},{"lineNumber":408,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response3ForQ2\"),"},{"lineNumber":409,"author":{"gitId":"xenosf"},"content":" testDataBundle.feedbackResponses.get(\"response4ForQ1\")"},{"lineNumber":410,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":411,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e actual \u003d frDb.getFeedbackResponsesForSession(sessionWithResponses,"},{"lineNumber":412,"author":{"gitId":"xenosf"},"content":" sessionWithResponses.getCourse().getId());"},{"lineNumber":413,"author":{"gitId":"xenosf"},"content":" assertListResponsesEqual(expected, actual);"},{"lineNumber":414,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":415,"author":{"gitId":"xenosf"},"content":" ______TS(\"Session has no responses\");"},{"lineNumber":416,"author":{"gitId":"xenosf"},"content":" FeedbackSession sessionWithoutResponses \u003d testDataBundle.feedbackSessions.get("},{"lineNumber":417,"author":{"gitId":"xenosf"},"content":" \"unpublishedSession1InTypicalCourse\");"},{"lineNumber":418,"author":{"gitId":"xenosf"},"content":" actual \u003d frDb.getFeedbackResponsesForSession(sessionWithoutResponses, sessionWithResponses.getCourse().getId());"},{"lineNumber":419,"author":{"gitId":"xenosf"},"content":" assertEquals(0, actual.size());"},{"lineNumber":420,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":421,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":422,"author":{"gitId":"xenosf"},"content":" private void assertListResponsesEqual(List\u003cFeedbackResponse\u003e expected, List\u003cFeedbackResponse\u003e actual) {"},{"lineNumber":423,"author":{"gitId":"xenosf"},"content":" assertEquals(\"List size not equal.\", expected.size(), actual.size());"},{"lineNumber":424,"author":{"gitId":"xenosf"},"content":" assertTrue("},{"lineNumber":425,"author":{"gitId":"xenosf"},"content":" String.format(\"List contents are not equal.%nExpected: %s,%nActual: %s\","},{"lineNumber":426,"author":{"gitId":"xenosf"},"content":" expected.toString(), actual.toString()),"},{"lineNumber":427,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(expected).equals(new HashSet\u003c\u003e(actual)));"},{"lineNumber":428,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":429,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":215,"-":214}},{"path":"src/it/java/teammates/it/storage/sqlapi/FeedbackSessionLogsDbIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.it.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlapi.FeedbackSessionLogsDb;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link FeedbackSessionLogsDb}."},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":"public class FeedbackSessionLogsDbIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" private final FeedbackSessionLogsDb fslDb \u003d FeedbackSessionLogsDb.inst();"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" private SqlDataBundle typicalDataBundle;"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" @BeforeClass"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" public void setupClass() {"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" super.setupClass();"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" typicalDataBundle \u003d getTypicalSqlDataBundle();"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" @BeforeMethod"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" protected void setUp() throws Exception {"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" super.setUp();"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" persistDataBundle(typicalDataBundle);"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" HibernateUtil.flushSession();"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" public void test_createFeedbackSessionLog_success() {"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" Course course \u003d typicalDataBundle.courses.get(\"course1\");"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d typicalDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" Student student \u003d typicalDataBundle.students.get(\"student1InCourse1\");"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" Instant logTimestamp \u003d Instant.parse(\"2011-01-01T00:00:00Z\");"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog expected \u003d new FeedbackSessionLog(student, feedbackSession, FeedbackSessionLogType.ACCESS,"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" logTimestamp);"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" fslDb.createFeedbackSessionLog(expected);"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e actualLogs \u003d fslDb.getOrderedFeedbackSessionLogs(course.getId(), student.getId(),"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" feedbackSession.getId(), logTimestamp, logTimestamp.plusSeconds(1));"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" assertEquals(actualLogs.size(), 1);"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" assertEquals(expected, actualLogs.get(0));"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" public void test_getOrderedFeedbackSessionLogs_success() {"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" Instant startTime \u003d Instant.parse(\"2012-01-01T12:00:00Z\");"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" Instant endTime \u003d Instant.parse(\"2012-01-01T23:59:59Z\");"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" Course course \u003d typicalDataBundle.courses.get(\"course1\");"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" Student student1 \u003d typicalDataBundle.students.get(\"student1InCourse1\");"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" FeedbackSession fs1 \u003d typicalDataBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student1Session1Log1 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student1Session1Log1\");"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student1Session2Log1 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student1Session2Log1\");"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student1Session2Log2 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student1Session2Log2\");"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student2Session1Log1 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student2Session1Log1\");"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student2Session1Log2 \u003d typicalDataBundle.feedbackSessionLogs.get(\"student2Session1Log2\");"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Return logs belonging to a course in time range\");"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e expectedLogs \u003d List.of("},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" student1Session1Log1,"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":" student1Session2Log1,"},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" student1Session2Log2,"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" student2Session1Log1,"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" student2Session1Log2"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" );"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e actualLogs \u003d fslDb.getOrderedFeedbackSessionLogs(course.getId(), null, null,"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" startTime, endTime);"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Return logs belonging to a student in time range\");"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":" expectedLogs \u003d List.of("},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" student1Session1Log1,"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" student1Session2Log1,"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" student1Session2Log2);"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" actualLogs \u003d fslDb.getOrderedFeedbackSessionLogs(course.getId(), student1.getId(), null, startTime, endTime);"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Return logs belonging to a feedback session in time range\");"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":" expectedLogs \u003d List.of("},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" student1Session1Log1,"},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":" student2Session1Log1,"},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" student2Session1Log2);"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" actualLogs \u003d fslDb.getOrderedFeedbackSessionLogs(course.getId(), null, fs1.getId(), startTime, endTime);"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Return logs belonging to a student in a feedback session in time range\");"},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" expectedLogs \u003d List.of(student1Session1Log1);"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" actualLogs \u003d fslDb.getOrderedFeedbackSessionLogs(course.getId(), student1.getId(), fs1.getId(), startTime,"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" endTime);"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" ______TS(\"No logs in time range, return empty list\");"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" expectedLogs \u003d new ArrayList\u003c\u003e();"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" actualLogs \u003d fslDb.getOrderedFeedbackSessionLogs(course.getId(), null, null, endTime.plusSeconds(3600),"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" endTime.plusSeconds(7200));"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedLogs, actualLogs);"},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":128}},{"path":"src/it/java/teammates/it/storage/sqlsearch/AccountRequestSearchIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.it.storage.sqlsearch;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.Arrays;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.Test;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlapi.AccountRequestsDb;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"import teammates.test.AssertHelper;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import teammates.test.TestProperties;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" * SUT: {@link AccountRequestsDb},"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" * {@link teammates.storage.search.AccountRequestSearchDocument}."},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":"public class AccountRequestSearchIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" private final SqlDataBundle typicalBundle \u003d getTypicalSqlDataBundle();"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" private final AccountRequestsDb accountRequestsDb \u003d AccountRequestsDb.inst();"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" @BeforeMethod"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" protected void setUp() throws Exception {"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" super.setUp();"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" putDocuments(typicalBundle);"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.flushSession();"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" public void allTests() throws Exception {"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" return;"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins1General \u003d typicalBundle.accountRequests.get(\"instructor1\");"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins2General \u003d typicalBundle.accountRequests.get(\"instructor2\");"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins1InCourse1 \u003d typicalBundle.accountRequests.get(\"instructor1OfCourse1\");"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins2InCourse1 \u003d typicalBundle.accountRequests.get(\"instructor2OfCourse1\");"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins1InCourse2 \u003d typicalBundle.accountRequests.get(\"instructor1OfCourse2\");"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins2InCourse2 \u003d typicalBundle.accountRequests.get(\"instructor2OfCourse2\");"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins1InCourse3 \u003d typicalBundle.accountRequests.get(\"instructor1OfCourse3\");"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins2InCourse3 \u003d typicalBundle.accountRequests.get(\"instructor2OfCourse3\");"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" AccountRequest insInUnregCourse \u003d typicalBundle.accountRequests.get(\"instructor3\");"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" AccountRequest unregisteredInstructor1 \u003d"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" typicalBundle.accountRequests.get(\"unregisteredInstructor1\");"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" AccountRequest unregisteredInstructor2 \u003d"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" typicalBundle.accountRequests.get(\"unregisteredInstructor2\");"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; query string does not match anyone\");"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" List\u003cAccountRequest\u003e results \u003d"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" accountRequestsDb.searchAccountRequestsInWholeSystem(\"non-existent\");"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results);"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; empty query string does not match anyone\");"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\");"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results);"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; query string matches some account requests\");"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"Instructor 1\\\"\");"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, ins1InCourse1, ins1InCourse2, ins1InCourse3, unregisteredInstructor1, ins1General);"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; query string should be case-insensitive\");"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"InStRuCtOr 2\\\"\");"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, ins2InCourse1, ins2InCourse2, ins2InCourse3, unregisteredInstructor2, ins2General);"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; account requests should be searchable by their name\");"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"Instructor 3 of CourseNoRegister\\\"\");"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, insInUnregCourse);"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; account requests should be searchable by their email\");"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"instr2@course2.tmt\");"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, ins2InCourse2);"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; account requests should be searchable by their institute\");"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"TEAMMATES Test Institute 2\\\"\");"},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, unregisteredInstructor2);"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" ______TS(\"success: search for account requests; account requests should be searchable by their comments\");"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"Comments for account request from instructor2\");"},{"lineNumber":95,"author":{"gitId":"-"},"content":" verifySearchResults(results, ins2General);"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" ______TS(\"success: search for account requests; account requests should be searchable by their status\");"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"registered\");"},{"lineNumber":100,"author":{"gitId":"-"},"content":" verifySearchResults(results, ins2General);"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; unregistered account requests should be searchable\");"},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"unregisteredinstructor1@gmail.tmt\\\"\");"},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, unregisteredInstructor1);"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; deleted account requests no longer searchable\");"},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" accountRequestsDb.deleteAccountRequest(ins1InCourse1);"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"instructor 1\\\"\");"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, ins1InCourse2, ins1InCourse3, unregisteredInstructor1, ins1General);"},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; account requests created without searchability unsearchable\");"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" accountRequestsDb.createAccountRequest(ins1InCourse1);"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"instructor 1\\\"\");"},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, ins1InCourse2, ins1InCourse3, unregisteredInstructor1, ins1General);"},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" ______TS(\"success: search for account requests; deleting account request without deleting document:\""},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" + \"document deleted during search, account request unsearchable\");"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" accountRequestsDb.deleteAccountRequest(ins2InCourse1);"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"instructor 2\\\"\");"},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, ins2InCourse2, ins2InCourse3, unregisteredInstructor2, ins2General);"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":128,"author":{"gitId":"domoberzin"},"content":" public void testSearchAccountRequest_deleteAfterSearch_shouldNotBeSearchable() throws Exception {"},{"lineNumber":129,"author":{"gitId":"domoberzin"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":" return;"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins1InCourse2 \u003d typicalBundle.accountRequests.get(\"instructor1OfCourse2\");"},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" AccountRequest ins2InCourse2 \u003d typicalBundle.accountRequests.get(\"instructor2OfCourse2\");"},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" // there is search result before deletion"},{"lineNumber":137,"author":{"gitId":"domoberzin"},"content":" List\u003cAccountRequest\u003e results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"of Course 2\\\"\");"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, ins1InCourse2, ins2InCourse2);"},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":140,"author":{"gitId":"domoberzin"},"content":" // delete an account request"},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":" accountRequestsDb.deleteAccountRequest(ins1InCourse2);"},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":" // the search result will change"},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"of Course 2\\\"\");"},{"lineNumber":145,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, ins2InCourse2);"},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":147,"author":{"gitId":"domoberzin"},"content":" // delete all account requests"},{"lineNumber":148,"author":{"gitId":"domoberzin"},"content":" accountRequestsDb.deleteAccountRequest(ins2InCourse2);"},{"lineNumber":149,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":150,"author":{"gitId":"domoberzin"},"content":" // there should be no search result"},{"lineNumber":151,"author":{"gitId":"domoberzin"},"content":" results \u003d accountRequestsDb.searchAccountRequestsInWholeSystem(\"\\\"of Course 2\\\"\");"},{"lineNumber":152,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results);"},{"lineNumber":153,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":154,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":155,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":156,"author":{"gitId":"domoberzin"},"content":" public void testSearchAccountRequest_noSearchService_shouldThrowException() {"},{"lineNumber":157,"author":{"gitId":"domoberzin"},"content":" if (TestProperties.isSearchServiceActive()) {"},{"lineNumber":158,"author":{"gitId":"domoberzin"},"content":" return;"},{"lineNumber":159,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":160,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":161,"author":{"gitId":"domoberzin"},"content":" assertThrows(SearchServiceException.class,"},{"lineNumber":162,"author":{"gitId":"domoberzin"},"content":" () -\u003e accountRequestsDb.searchAccountRequestsInWholeSystem(\"anything\"));"},{"lineNumber":163,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":164,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":165,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":" * Verifies that search results match with expected output."},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":" * @param actual the results from the search query."},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" * @param expected the expected results for the search query."},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":171,"author":{"gitId":"domoberzin"},"content":" private static void verifySearchResults(List\u003cAccountRequest\u003e actual,"},{"lineNumber":172,"author":{"gitId":"domoberzin"},"content":" AccountRequest... expected) {"},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":" assertEquals(expected.length, actual.size());"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":" AssertHelper.assertSameContentIgnoreOrder(Arrays.asList(expected), actual);"},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":167,"-":10}},{"path":"src/it/java/teammates/it/storage/sqlsearch/InstructorSearchIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.storage.sqlsearch;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.Arrays;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.UsersDb;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.test.AssertHelper;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.test.TestProperties;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * SUT: {@link UsersDb},"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * {@link teammates.storage.sqlsearch.InstructorSearchDocument}."},{"lineNumber":21,"author":{"gitId":"-"},"content":" */"},{"lineNumber":22,"author":{"gitId":"-"},"content":"public class InstructorSearchIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" private final SqlDataBundle typicalBundle \u003d getTypicalSqlDataBundle();"},{"lineNumber":25,"author":{"gitId":"-"},"content":" private final UsersDb usersDb \u003d UsersDb.inst();"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":29,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":30,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":31,"author":{"gitId":"-"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":32,"author":{"gitId":"-"},"content":" putDocuments(typicalBundle);"},{"lineNumber":33,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":37,"author":{"gitId":"-"},"content":" public void allTests() throws Exception {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" Instructor ins1InCourse1 \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":43,"author":{"gitId":"-"},"content":" Instructor ins2InCourse1 \u003d typicalBundle.instructors.get(\"instructor2OfCourse1\");"},{"lineNumber":44,"author":{"gitId":"yuanxi1"},"content":" Instructor ins1InCourse4 \u003d typicalBundle.instructors.get(\"instructor1OfCourse4\");"},{"lineNumber":45,"author":{"gitId":"yuanxi1"},"content":" Instructor ins2InCourse4 \u003d typicalBundle.instructors.get(\"instructor2YetToJoinCourse4\");"},{"lineNumber":46,"author":{"gitId":"yuanxi1"},"content":" Instructor ins3InCourse4 \u003d typicalBundle.instructors.get(\"instructor3YetToJoinCourse4\");"},{"lineNumber":47,"author":{"gitId":"-"},"content":" Instructor insInArchivedCourse \u003d typicalBundle.instructors.get(\"instructorOfArchivedCourse\");"},{"lineNumber":48,"author":{"gitId":"-"},"content":" Instructor insInUnregCourse \u003d typicalBundle.instructors.get(\"instructorOfUnregisteredCourse\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":" Instructor insUniqueDisplayName \u003d typicalBundle.instructors.get(\"instructorOfCourse2WithUniqueDisplayName\");"},{"lineNumber":50,"author":{"gitId":"-"},"content":" Instructor ins1InCourse3 \u003d typicalBundle.instructors.get(\"instructor1OfCourse3\");"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" Instructor unregisteredInsInCourse1 \u003d typicalBundle.instructors.get(\"unregisteredInstructorOfCourse1\");"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; query string does not match anyone\");"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e results \u003d usersDb.searchInstructorsInWholeSystem(\"non-existent\");"},{"lineNumber":56,"author":{"gitId":"-"},"content":" verifySearchResults(results);"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; empty query string does not match anyone\");"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\");"},{"lineNumber":61,"author":{"gitId":"-"},"content":" verifySearchResults(results);"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; query string matches some instructors\");"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"Instructor of\\\"\");"},{"lineNumber":66,"author":{"gitId":"-"},"content":" verifySearchResults(results, insInArchivedCourse, insInUnregCourse, insUniqueDisplayName);"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; query string should be case-insensitive\");"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"InStRuCtOr 2\\\"\");"},{"lineNumber":71,"author":{"gitId":"yuanxi1"},"content":" verifySearchResults(results, ins2InCourse1, ins2InCourse4);"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; instructors in archived courses should be included\");"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"Instructor Of Archived Course\\\"\");"},{"lineNumber":76,"author":{"gitId":"-"},"content":" verifySearchResults(results, insInArchivedCourse);"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" ______TS("},{"lineNumber":79,"author":{"gitId":"-"},"content":" \"success: search for instructors in whole system; instructors in unregistered course should be included\");"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"Instructor Of Unregistered Course\\\"\");"},{"lineNumber":82,"author":{"gitId":"-"},"content":" verifySearchResults(results, insInUnregCourse);"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; instructors should be searchable by course id\");"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"course-1\\\"\");"},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" verifySearchResults(results, ins1InCourse1, ins2InCourse1, unregisteredInsInCourse1);"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; instructors should be searchable by course name\");"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"Typical Course 1\\\"\");"},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" verifySearchResults(results, ins1InCourse1, ins2InCourse1, unregisteredInsInCourse1);"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; instructors should be searchable by their name\");"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"Instructor Of Unregistered Course\\\"\");"},{"lineNumber":97,"author":{"gitId":"-"},"content":" verifySearchResults(results, insInUnregCourse);"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; instructors should be searchable by their email\");"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"instr2@teammates.tmt\");"},{"lineNumber":102,"author":{"gitId":"yuanxi1"},"content":" verifySearchResults(results, ins2InCourse1, ins2InCourse4);"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; instructors should be searchable by their role\");"},{"lineNumber":105,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"Co-owner\\\"\");"},{"lineNumber":106,"author":{"gitId":"-"},"content":" verifySearchResults(results, ins1InCourse1, insInArchivedCourse,"},{"lineNumber":107,"author":{"gitId":"yuanxi1"},"content":" insInUnregCourse, insUniqueDisplayName, ins1InCourse3,"},{"lineNumber":108,"author":{"gitId":"yuanxi1"},"content":" ins1InCourse4, ins2InCourse4, ins3InCourse4);"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; instructors should be searchable by displayed name\");"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" String displayName \u003d insUniqueDisplayName.getDisplayName();"},{"lineNumber":113,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(displayName);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" verifySearchResults(results, insUniqueDisplayName);"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; deleted instructors no longer searchable\");"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" usersDb.deleteUser(insUniqueDisplayName);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"Instructor of\\\"\");"},{"lineNumber":120,"author":{"gitId":"-"},"content":" verifySearchResults(results, insInArchivedCourse, insInUnregCourse);"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" // This method used to use usersDb.putEntity, not sure if the .createInstructor method has the same functionality"},{"lineNumber":123,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; instructors created without searchability unsearchable\");"},{"lineNumber":124,"author":{"gitId":"-"},"content":" usersDb.createInstructor(insUniqueDisplayName);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"Instructor of\\\"\");"},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" verifySearchResults(results, insInArchivedCourse, insInUnregCourse, insUniqueDisplayName);"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" ______TS(\"success: search for instructors in whole system; deleting instructor without deleting document:\""},{"lineNumber":129,"author":{"gitId":"-"},"content":" + \"document deleted during search, instructor unsearchable\");"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" usersDb.deleteUser(ins1InCourse3);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"Instructor 1\\\"\");"},{"lineNumber":133,"author":{"gitId":"yuanxi1"},"content":" verifySearchResults(results, ins1InCourse1, ins1InCourse4);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" }"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":137,"author":{"gitId":"-"},"content":" public void testSearchInstructor_deleteAfterSearch_shouldNotBeSearchable() throws Exception {"},{"lineNumber":138,"author":{"gitId":"-"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" Instructor ins1InCourse1 \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":143,"author":{"gitId":"-"},"content":" Instructor ins2InCourse1 \u003d typicalBundle.instructors.get(\"instructor2OfCourse1\");"},{"lineNumber":144,"author":{"gitId":"dishenggg"},"content":" Instructor unregisteredInsInCourse1 \u003d typicalBundle.instructors.get(\"unregisteredInstructorOfCourse1\");"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"course-1\\\"\");"},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":" verifySearchResults(results, ins1InCourse1, ins2InCourse1, unregisteredInsInCourse1);"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" usersDb.deleteUser(ins1InCourse1);"},{"lineNumber":150,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"course-1\\\"\");"},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":" verifySearchResults(results, ins2InCourse1, unregisteredInsInCourse1);"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":" // This used to test .deleteInstructors, but we don\u0027t seem to have a similar method to delete all users in course"},{"lineNumber":154,"author":{"gitId":"-"},"content":" usersDb.deleteUser(ins2InCourse1);"},{"lineNumber":155,"author":{"gitId":"-"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"course-1\\\"\");"},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" verifySearchResults(results, unregisteredInsInCourse1);"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":158,"author":{"gitId":"dishenggg"},"content":" usersDb.deleteUser(unregisteredInsInCourse1);"},{"lineNumber":159,"author":{"gitId":"dishenggg"},"content":" results \u003d usersDb.searchInstructorsInWholeSystem(\"\\\"course-1\\\"\");"},{"lineNumber":160,"author":{"gitId":"-"},"content":" verifySearchResults(results);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":164,"author":{"gitId":"-"},"content":" public void testSearchInstructor_noSearchService_shouldThrowException() {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" if (TestProperties.isSearchServiceActive()) {"},{"lineNumber":166,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":167,"author":{"gitId":"-"},"content":" }"},{"lineNumber":168,"author":{"gitId":"-"},"content":""},{"lineNumber":169,"author":{"gitId":"-"},"content":" assertThrows(SearchServiceException.class,"},{"lineNumber":170,"author":{"gitId":"-"},"content":" () -\u003e usersDb.searchInstructorsInWholeSystem(\"anything\"));"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":174,"author":{"gitId":"-"},"content":" * Verifies that search results match with expected output."},{"lineNumber":175,"author":{"gitId":"-"},"content":" *"},{"lineNumber":176,"author":{"gitId":"-"},"content":" * @param actual the results from the search query."},{"lineNumber":177,"author":{"gitId":"-"},"content":" * @param expected the expected results for the search query."},{"lineNumber":178,"author":{"gitId":"-"},"content":" */"},{"lineNumber":179,"author":{"gitId":"-"},"content":" private static void verifySearchResults(List\u003cInstructor\u003e actual,"},{"lineNumber":180,"author":{"gitId":"-"},"content":" Instructor... expected) {"},{"lineNumber":181,"author":{"gitId":"-"},"content":" assertEquals(expected.length, actual.size());"},{"lineNumber":182,"author":{"gitId":"-"},"content":" AssertHelper.assertSameContentIgnoreOrder(Arrays.asList(expected), actual);"},{"lineNumber":183,"author":{"gitId":"-"},"content":" }"},{"lineNumber":184,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":1,"yuanxi1":8,"dishenggg":10,"-":165}},{"path":"src/it/java/teammates/it/storage/sqlsearch/StudentSearchIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"yuanxi1"},"content":"package teammates.it.storage.sqlsearch;"},{"lineNumber":2,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":3,"author":{"gitId":"yuanxi1"},"content":"import java.util.Arrays;"},{"lineNumber":4,"author":{"gitId":"yuanxi1"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":6,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":7,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.Test;"},{"lineNumber":8,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":9,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":10,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":11,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":12,"author":{"gitId":"yuanxi1"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":13,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlapi.UsersDb;"},{"lineNumber":14,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":15,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":16,"author":{"gitId":"yuanxi1"},"content":"import teammates.test.AssertHelper;"},{"lineNumber":17,"author":{"gitId":"yuanxi1"},"content":"import teammates.test.TestProperties;"},{"lineNumber":18,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":19,"author":{"gitId":"yuanxi1"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"yuanxi1"},"content":" * SUT: {@link UsersDb},"},{"lineNumber":21,"author":{"gitId":"yuanxi1"},"content":" * {@link teammates.storage.sqlsearch.InstructorSearchDocument}."},{"lineNumber":22,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":23,"author":{"gitId":"yuanxi1"},"content":"public class StudentSearchIT extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":24,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":25,"author":{"gitId":"yuanxi1"},"content":" private final SqlDataBundle typicalBundle \u003d getTypicalSqlDataBundle();"},{"lineNumber":26,"author":{"gitId":"yuanxi1"},"content":" private final UsersDb usersDb \u003d UsersDb.inst();"},{"lineNumber":27,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":28,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":29,"author":{"gitId":"yuanxi1"},"content":" @BeforeMethod"},{"lineNumber":30,"author":{"gitId":"yuanxi1"},"content":" protected void setUp() throws Exception {"},{"lineNumber":31,"author":{"gitId":"yuanxi1"},"content":" super.setUp();"},{"lineNumber":32,"author":{"gitId":"yuanxi1"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":33,"author":{"gitId":"yuanxi1"},"content":" putDocuments(typicalBundle);"},{"lineNumber":34,"author":{"gitId":"yuanxi1"},"content":" HibernateUtil.flushSession();"},{"lineNumber":35,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":36,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":37,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":38,"author":{"gitId":"yuanxi1"},"content":" public void allTests() throws Exception {"},{"lineNumber":39,"author":{"gitId":"yuanxi1"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":40,"author":{"gitId":"yuanxi1"},"content":" return;"},{"lineNumber":41,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":42,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":43,"author":{"gitId":"yuanxi1"},"content":" Student stu1InCourse1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":44,"author":{"gitId":"yuanxi1"},"content":" Student stu2InCourse1 \u003d typicalBundle.students.get(\"student2InCourse1\");"},{"lineNumber":45,"author":{"gitId":"yuanxi1"},"content":" Student stu3InCourse1 \u003d typicalBundle.students.get(\"student3InCourse1\");"},{"lineNumber":46,"author":{"gitId":"marquestye"},"content":" Student stu4InCourse1 \u003d typicalBundle.students.get(\"student4InCourse1\");"},{"lineNumber":47,"author":{"gitId":"yuanxi1"},"content":" Student stu1InCourse2 \u003d typicalBundle.students.get(\"student1InCourse2\");"},{"lineNumber":48,"author":{"gitId":"yuanxi1"},"content":" Student unregisteredStuInCourse1 \u003d typicalBundle.students.get(\"unregisteredStudentInCourse1\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":" Student stu1InCourse3 \u003d typicalBundle.students.get(\"student1InCourse3\");"},{"lineNumber":50,"author":{"gitId":"yuanxi1"},"content":" Student stu1InCourse4 \u003d typicalBundle.students.get(\"student1InCourse4\");"},{"lineNumber":51,"author":{"gitId":"yuanxi1"},"content":" Student stuOfArchivedCourse \u003d typicalBundle.students.get(\"studentOfArchivedCourse\");"},{"lineNumber":52,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":53,"author":{"gitId":"yuanxi1"},"content":" Instructor ins1InCourse1 \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":54,"author":{"gitId":"yuanxi1"},"content":" Instructor ins1InCourse4 \u003d typicalBundle.instructors.get(\"instructor1OfCourse4\");"},{"lineNumber":55,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":56,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; query string does not match anyone\");"},{"lineNumber":57,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":58,"author":{"gitId":"yuanxi1"},"content":" List\u003cStudent\u003e results \u003d usersDb.searchStudentsInWholeSystem(\"non-existent\");"},{"lineNumber":59,"author":{"gitId":"yuanxi1"},"content":" verifySearchResults(results);"},{"lineNumber":60,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":61,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; empty query string does not match anyone\");"},{"lineNumber":62,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":63,"author":{"gitId":"yuanxi1"},"content":" results \u003d usersDb.searchStudentsInWholeSystem(\"\");"},{"lineNumber":64,"author":{"gitId":"yuanxi1"},"content":" verifySearchResults(results);"},{"lineNumber":65,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":66,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; query string matches some students\");"},{"lineNumber":67,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":68,"author":{"gitId":"yuanxi1"},"content":" results \u003d usersDb.searchStudentsInWholeSystem(\"\\\"student1\\\"\");"},{"lineNumber":69,"author":{"gitId":"-"},"content":" verifySearchResults(results, stu1InCourse1, stu1InCourse2, stu1InCourse3, stu1InCourse4);"},{"lineNumber":70,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":71,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; query string should be case-insensitive\");"},{"lineNumber":72,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":73,"author":{"gitId":"yuanxi1"},"content":" results \u003d usersDb.searchStudentsInWholeSystem(\"\\\"sTuDeNt1\\\"\");"},{"lineNumber":74,"author":{"gitId":"-"},"content":" verifySearchResults(results, stu1InCourse1, stu1InCourse2, stu1InCourse3, stu1InCourse4);"},{"lineNumber":75,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":76,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; students in archived courses should be included\");"},{"lineNumber":77,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":78,"author":{"gitId":"yuanxi1"},"content":" results \u003d usersDb.searchStudentsInWholeSystem(\"\\\"Student In Archived Course\\\"\");"},{"lineNumber":79,"author":{"gitId":"yuanxi1"},"content":" verifySearchResults(results, stuOfArchivedCourse);"},{"lineNumber":80,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":81,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; students should be searchable by course id\");"},{"lineNumber":82,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":83,"author":{"gitId":"yuanxi1"},"content":" results \u003d usersDb.searchStudentsInWholeSystem(\"\\\"course-1\\\"\");"},{"lineNumber":84,"author":{"gitId":"marquestye"},"content":" verifySearchResults(results, stu1InCourse1, stu2InCourse1, stu3InCourse1, stu4InCourse1, unregisteredStuInCourse1);"},{"lineNumber":85,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":86,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; students should be searchable by course name\");"},{"lineNumber":87,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":88,"author":{"gitId":"yuanxi1"},"content":" results \u003d usersDb.searchStudentsInWholeSystem(\"\\\"Typical Course 1\\\"\");"},{"lineNumber":89,"author":{"gitId":"marquestye"},"content":" verifySearchResults(results, stu1InCourse1, stu2InCourse1, stu3InCourse1, stu4InCourse1, unregisteredStuInCourse1);"},{"lineNumber":90,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":91,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; students should be searchable by their name\");"},{"lineNumber":92,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":93,"author":{"gitId":"yuanxi1"},"content":" results \u003d usersDb.searchStudentsInWholeSystem(\"\\\"student3 In Course1\\\"\");"},{"lineNumber":94,"author":{"gitId":"yuanxi1"},"content":" verifySearchResults(results, stu3InCourse1);"},{"lineNumber":95,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":96,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; students should be searchable by their email\");"},{"lineNumber":97,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":98,"author":{"gitId":"yuanxi1"},"content":" results \u003d usersDb.searchStudentsInWholeSystem(\"student1@teammates.tmt\");"},{"lineNumber":99,"author":{"gitId":"-"},"content":" verifySearchResults(results, stu1InCourse1, stu1InCourse2, stu1InCourse3, stu1InCourse4);"},{"lineNumber":100,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":101,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students; query string matches some students; results restricted \""},{"lineNumber":102,"author":{"gitId":"yuanxi1"},"content":" + \"based on instructor\u0027s privilege\");"},{"lineNumber":103,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":104,"author":{"gitId":"yuanxi1"},"content":" List\u003cInstructor\u003e ins1OfCourse1 \u003d Arrays.asList("},{"lineNumber":105,"author":{"gitId":"yuanxi1"},"content":" new Instructor[] { ins1InCourse1 });"},{"lineNumber":106,"author":{"gitId":"yuanxi1"},"content":" List\u003cInstructor\u003e ins1OfCourse4 \u003d Arrays.asList("},{"lineNumber":107,"author":{"gitId":"yuanxi1"},"content":" new Instructor[] { ins1InCourse4 });"},{"lineNumber":108,"author":{"gitId":"yuanxi1"},"content":" List\u003cStudent\u003e studentList \u003d usersDb.searchStudents(\"student1\", ins1OfCourse1);"},{"lineNumber":109,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":110,"author":{"gitId":"yuanxi1"},"content":" verifySearchResults(studentList, stu1InCourse1);"},{"lineNumber":111,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":112,"author":{"gitId":"yuanxi1"},"content":" studentList \u003d usersDb.searchStudents(\"student1\", ins1OfCourse4);"},{"lineNumber":113,"author":{"gitId":"yuanxi1"},"content":" verifySearchResults(studentList, stu1InCourse4);"},{"lineNumber":114,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":115,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: search for students in whole system; deleted students no longer searchable\");"},{"lineNumber":116,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":117,"author":{"gitId":"yuanxi1"},"content":" usersDb.deleteUser(stu1InCourse1);"},{"lineNumber":118,"author":{"gitId":"yuanxi1"},"content":" results \u003d usersDb.searchStudentsInWholeSystem(\"\\\"student1\\\"\");"},{"lineNumber":119,"author":{"gitId":"-"},"content":" verifySearchResults(results, stu1InCourse2, stu1InCourse3, stu1InCourse4);"},{"lineNumber":120,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":121,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":122,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":123,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":124,"author":{"gitId":"yuanxi1"},"content":" public void testSearchStudent_deleteAfterSearch_shouldNotBeSearchable() throws Exception {"},{"lineNumber":125,"author":{"gitId":"yuanxi1"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":126,"author":{"gitId":"yuanxi1"},"content":" return;"},{"lineNumber":127,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":128,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":129,"author":{"gitId":"yuanxi1"},"content":" Student stu1InCourse1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":130,"author":{"gitId":"yuanxi1"},"content":" Student stu1InCourse2 \u003d typicalBundle.students.get(\"student1InCourse2\");"},{"lineNumber":131,"author":{"gitId":"-"},"content":" Student stu1InCourse3 \u003d typicalBundle.students.get(\"student1InCourse3\");"},{"lineNumber":132,"author":{"gitId":"yuanxi1"},"content":" Student stu1InCourse4 \u003d typicalBundle.students.get(\"student1InCourse4\");"},{"lineNumber":133,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":134,"author":{"gitId":"yuanxi1"},"content":" List\u003cStudent\u003e studentList \u003d usersDb.searchStudentsInWholeSystem(\"student1\");"},{"lineNumber":135,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":136,"author":{"gitId":"yuanxi1"},"content":" // there is search result before deletion"},{"lineNumber":137,"author":{"gitId":"-"},"content":" verifySearchResults(studentList, stu1InCourse1, stu1InCourse2, stu1InCourse3, stu1InCourse4);"},{"lineNumber":138,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":139,"author":{"gitId":"yuanxi1"},"content":" // delete a student"},{"lineNumber":140,"author":{"gitId":"yuanxi1"},"content":" usersDb.deleteUser(stu1InCourse1);"},{"lineNumber":141,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":142,"author":{"gitId":"yuanxi1"},"content":" // the search result will change"},{"lineNumber":143,"author":{"gitId":"yuanxi1"},"content":" studentList \u003d usersDb.searchStudentsInWholeSystem(\"student1\");"},{"lineNumber":144,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" verifySearchResults(studentList, stu1InCourse2, stu1InCourse3, stu1InCourse4);"},{"lineNumber":146,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":147,"author":{"gitId":"yuanxi1"},"content":" // delete all students in course 2"},{"lineNumber":148,"author":{"gitId":"yuanxi1"},"content":" usersDb.deleteUser(stu1InCourse2);"},{"lineNumber":149,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":150,"author":{"gitId":"yuanxi1"},"content":" // the search result will change"},{"lineNumber":151,"author":{"gitId":"yuanxi1"},"content":" studentList \u003d usersDb.searchStudentsInWholeSystem(\"student1\");"},{"lineNumber":152,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":" verifySearchResults(studentList, stu1InCourse3, stu1InCourse4);"},{"lineNumber":154,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":155,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":156,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":157,"author":{"gitId":"yuanxi1"},"content":" public void testSearchStudent_noSearchService_shouldThrowException() {"},{"lineNumber":158,"author":{"gitId":"yuanxi1"},"content":" if (TestProperties.isSearchServiceActive()) {"},{"lineNumber":159,"author":{"gitId":"yuanxi1"},"content":" return;"},{"lineNumber":160,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":161,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":162,"author":{"gitId":"yuanxi1"},"content":" assertThrows(SearchServiceException.class,"},{"lineNumber":163,"author":{"gitId":"yuanxi1"},"content":" () -\u003e usersDb.searchStudentsInWholeSystem(\"anything\"));"},{"lineNumber":164,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":165,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":166,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":167,"author":{"gitId":"yuanxi1"},"content":" * Verifies that search results match with expected output."},{"lineNumber":168,"author":{"gitId":"yuanxi1"},"content":" *"},{"lineNumber":169,"author":{"gitId":"yuanxi1"},"content":" * @param actual the results from the search query."},{"lineNumber":170,"author":{"gitId":"yuanxi1"},"content":" * @param expected the expected results for the search query."},{"lineNumber":171,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":172,"author":{"gitId":"yuanxi1"},"content":" private static void verifySearchResults(List\u003cStudent\u003e actual,"},{"lineNumber":173,"author":{"gitId":"yuanxi1"},"content":" Student... expected) {"},{"lineNumber":174,"author":{"gitId":"yuanxi1"},"content":" assertEquals(expected.length, actual.size());"},{"lineNumber":175,"author":{"gitId":"yuanxi1"},"content":" AssertHelper.assertSameContentIgnoreOrder(Arrays.asList(expected), actual);"},{"lineNumber":176,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":177,"author":{"gitId":"yuanxi1"},"content":"}"}],"authorContributionMap":{"yuanxi1":165,"marquestye":3,"-":9}},{"path":"src/it/java/teammates/it/test/BaseTestCaseWithSqlDatabaseAccess.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.test;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.testcontainers.containers.PostgreSQLContainer;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterMethod;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterSuite;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeSuite;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import com.google.cloud.datastore.DatastoreOptions;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import com.google.cloud.datastore.testing.LocalDatastoreHelper;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import com.googlecode.objectify.ObjectifyFactory;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import com.googlecode.objectify.ObjectifyService;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import com.googlecode.objectify.util.Closeable;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.sqllogic.api.Logic;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.LogicStarter;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.api.OfyHelper;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.BaseEntity;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":41,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.ReadNotification;"},{"lineNumber":42,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":43,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":45,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.UsageStatistics;"},{"lineNumber":46,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.AccountRequestSearchManager;"},{"lineNumber":47,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.InstructorSearchManager;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.SearchManagerFactory;"},{"lineNumber":49,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.StudentSearchManager;"},{"lineNumber":50,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":53,"author":{"gitId":"-"},"content":" * Base test case for tests that access the database."},{"lineNumber":54,"author":{"gitId":"-"},"content":" */"},{"lineNumber":55,"author":{"gitId":"-"},"content":"@Test(singleThreaded \u003d true)"},{"lineNumber":56,"author":{"gitId":"-"},"content":"public class BaseTestCaseWithSqlDatabaseAccess extends BaseTestCase {"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" private static final PostgreSQLContainer\u003c?\u003e PGSQL \u003d new PostgreSQLContainer\u003c\u003e(\"postgres:15.1-alpine\");"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" private static final LocalDatastoreHelper LOCAL_DATASTORE_HELPER \u003d LocalDatastoreHelper.newBuilder()"},{"lineNumber":61,"author":{"gitId":"-"},"content":" .setConsistency(1.0)"},{"lineNumber":62,"author":{"gitId":"-"},"content":" .setPort(TestProperties.TEST_LOCALDATASTORE_PORT)"},{"lineNumber":63,"author":{"gitId":"-"},"content":" .setStoreOnDisk(false)"},{"lineNumber":64,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" private final Logic logic \u003d Logic.inst();"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" private Closeable closeable;"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" @BeforeSuite"},{"lineNumber":71,"author":{"gitId":"-"},"content":" protected static void setUpSuite() throws Exception {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" PGSQL.start();"},{"lineNumber":73,"author":{"gitId":"-"},"content":" // Temporarily disable migration utility"},{"lineNumber":74,"author":{"gitId":"-"},"content":" // DbMigrationUtil.resetDb(PGSQL.getJdbcUrl(), PGSQL.getUsername(),"},{"lineNumber":75,"author":{"gitId":"-"},"content":" // PGSQL.getPassword());"},{"lineNumber":76,"author":{"gitId":"-"},"content":" HibernateUtil.buildSessionFactory(PGSQL.getJdbcUrl(), PGSQL.getUsername(), PGSQL.getPassword());"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" LogicStarter.initializeDependencies();"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" SearchManagerFactory.registerAccountRequestSearchManager("},{"lineNumber":81,"author":{"gitId":"-"},"content":" new AccountRequestSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":82,"author":{"gitId":"-"},"content":" SearchManagerFactory.registerInstructorSearchManager("},{"lineNumber":83,"author":{"gitId":"-"},"content":" new InstructorSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":84,"author":{"gitId":"-"},"content":" SearchManagerFactory.registerStudentSearchManager("},{"lineNumber":85,"author":{"gitId":"-"},"content":" new StudentSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" // TODO: remove after migration, needed for dual db support"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" teammates.storage.search.SearchManagerFactory.registerAccountRequestSearchManager("},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" new teammates.storage.search.AccountRequestSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" teammates.storage.search.SearchManagerFactory.registerInstructorSearchManager("},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" new teammates.storage.search.InstructorSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":" teammates.storage.search.SearchManagerFactory.registerStudentSearchManager("},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":" new teammates.storage.search.StudentSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" teammates.logic.core.LogicStarter.initializeDependencies();"},{"lineNumber":97,"author":{"gitId":"-"},"content":" LOCAL_DATASTORE_HELPER.start();"},{"lineNumber":98,"author":{"gitId":"-"},"content":" DatastoreOptions options \u003d LOCAL_DATASTORE_HELPER.getOptions();"},{"lineNumber":99,"author":{"gitId":"-"},"content":" ObjectifyService.init(new ObjectifyFactory("},{"lineNumber":100,"author":{"gitId":"-"},"content":" options.getService()));"},{"lineNumber":101,"author":{"gitId":"-"},"content":" OfyHelper.registerEntityClasses();"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" }"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" @BeforeClass"},{"lineNumber":106,"author":{"gitId":"-"},"content":" public void setupClass() {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" closeable \u003d ObjectifyService.begin();"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":111,"author":{"gitId":"-"},"content":" public void tearDownClass() {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" closeable.close();"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" SearchManagerFactory.getAccountRequestSearchManager().resetCollections();"},{"lineNumber":115,"author":{"gitId":"-"},"content":" SearchManagerFactory.getInstructorSearchManager().resetCollections();"},{"lineNumber":116,"author":{"gitId":"-"},"content":" SearchManagerFactory.getStudentSearchManager().resetCollections();"},{"lineNumber":117,"author":{"gitId":"-"},"content":" }"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" @AfterSuite"},{"lineNumber":120,"author":{"gitId":"-"},"content":" protected static void tearDownSuite() throws Exception {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" PGSQL.close();"},{"lineNumber":122,"author":{"gitId":"-"},"content":" LOCAL_DATASTORE_HELPER.stop();"},{"lineNumber":123,"author":{"gitId":"-"},"content":" }"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":126,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":127,"author":{"gitId":"-"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" @AfterMethod"},{"lineNumber":131,"author":{"gitId":"-"},"content":" protected void tearDown() {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" HibernateUtil.rollbackTransaction();"},{"lineNumber":133,"author":{"gitId":"-"},"content":" }"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":136,"author":{"gitId":"-"},"content":" protected String getTestDataFolder() {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" return TestProperties.TEST_DATA_FOLDER;"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":141,"author":{"gitId":"-"},"content":" * Persist data bundle into the db."},{"lineNumber":142,"author":{"gitId":"-"},"content":" */"},{"lineNumber":143,"author":{"gitId":"-"},"content":" protected void persistDataBundle(SqlDataBundle dataBundle)"},{"lineNumber":144,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException, EntityDoesNotExistException {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" logic.persistDataBundle(dataBundle);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" }"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":149,"author":{"gitId":"-"},"content":" * Puts searchable documents from the data bundle to the solr database."},{"lineNumber":150,"author":{"gitId":"-"},"content":" */"},{"lineNumber":151,"author":{"gitId":"-"},"content":" protected void putDocuments(SqlDataBundle dataBundle) throws SearchServiceException {"},{"lineNumber":152,"author":{"gitId":"-"},"content":" logic.putDocuments(dataBundle);"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":156,"author":{"gitId":"-"},"content":" * Verifies that two entities are equal."},{"lineNumber":157,"author":{"gitId":"-"},"content":" */"},{"lineNumber":158,"author":{"gitId":"-"},"content":" protected void verifyEquals(BaseEntity expected, BaseEntity actual) {"},{"lineNumber":159,"author":{"gitId":"-"},"content":" if (expected instanceof Course) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" Course expectedCourse \u003d (Course) expected;"},{"lineNumber":161,"author":{"gitId":"-"},"content":" Course actualCourse \u003d (Course) actual;"},{"lineNumber":162,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedCourse, actualCourse);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedCourse), JsonUtils.toJson(actualCourse));"},{"lineNumber":164,"author":{"gitId":"-"},"content":" } else if (expected instanceof DeadlineExtension) {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" DeadlineExtension expectedDeadlineExtension \u003d (DeadlineExtension) expected;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" DeadlineExtension actualDeadlineExtension \u003d (DeadlineExtension) actual;"},{"lineNumber":167,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedDeadlineExtension, actualDeadlineExtension);"},{"lineNumber":168,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedDeadlineExtension), JsonUtils.toJson(actualDeadlineExtension));"},{"lineNumber":169,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackSession) {"},{"lineNumber":170,"author":{"gitId":"-"},"content":" FeedbackSession expectedSession \u003d (FeedbackSession) expected;"},{"lineNumber":171,"author":{"gitId":"-"},"content":" FeedbackSession actualSession \u003d (FeedbackSession) actual;"},{"lineNumber":172,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedSession, actualSession);"},{"lineNumber":173,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedSession), JsonUtils.toJson(actualSession));"},{"lineNumber":174,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackQuestion) {"},{"lineNumber":175,"author":{"gitId":"-"},"content":" FeedbackQuestion expectedQuestion \u003d (FeedbackQuestion) expected;"},{"lineNumber":176,"author":{"gitId":"-"},"content":" FeedbackQuestion actualQuestion \u003d (FeedbackQuestion) actual;"},{"lineNumber":177,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedQuestion, actualQuestion);"},{"lineNumber":178,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedQuestion), JsonUtils.toJson(actualQuestion));"},{"lineNumber":179,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackResponse) {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" FeedbackResponse expectedResponse \u003d (FeedbackResponse) expected;"},{"lineNumber":181,"author":{"gitId":"-"},"content":" FeedbackResponse actualResponse \u003d (FeedbackResponse) actual;"},{"lineNumber":182,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedResponse, actualResponse);"},{"lineNumber":183,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedResponse), JsonUtils.toJson(actualResponse));"},{"lineNumber":184,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackResponseComment) {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" FeedbackResponseComment expectedComment \u003d (FeedbackResponseComment) expected;"},{"lineNumber":186,"author":{"gitId":"-"},"content":" FeedbackResponseComment actualComment \u003d (FeedbackResponseComment) actual;"},{"lineNumber":187,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedComment, actualComment);"},{"lineNumber":188,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedComment), JsonUtils.toJson(actualComment));"},{"lineNumber":189,"author":{"gitId":"-"},"content":" } else if (expected instanceof Notification) {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" Notification expectedNotification \u003d (Notification) expected;"},{"lineNumber":191,"author":{"gitId":"-"},"content":" Notification actualNotification \u003d (Notification) actual;"},{"lineNumber":192,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedNotification, actualNotification);"},{"lineNumber":193,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedNotification), JsonUtils.toJson(actualNotification));"},{"lineNumber":194,"author":{"gitId":"-"},"content":" } else if (expected instanceof Account) {"},{"lineNumber":195,"author":{"gitId":"-"},"content":" Account expectedAccount \u003d (Account) expected;"},{"lineNumber":196,"author":{"gitId":"-"},"content":" Account actualAccount \u003d (Account) actual;"},{"lineNumber":197,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedAccount, actualAccount);"},{"lineNumber":198,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedAccount), JsonUtils.toJson(actualAccount));"},{"lineNumber":199,"author":{"gitId":"-"},"content":" } else if (expected instanceof AccountRequest) {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" AccountRequest expectedAccountRequest \u003d (AccountRequest) expected;"},{"lineNumber":201,"author":{"gitId":"-"},"content":" AccountRequest actualAccountRequest \u003d (AccountRequest) actual;"},{"lineNumber":202,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedAccountRequest, actualAccountRequest);"},{"lineNumber":203,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedAccountRequest), JsonUtils.toJson(actualAccountRequest));"},{"lineNumber":204,"author":{"gitId":"-"},"content":" } else if (expected instanceof UsageStatistics) {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" UsageStatistics expectedUsageStatistics \u003d (UsageStatistics) expected;"},{"lineNumber":206,"author":{"gitId":"-"},"content":" UsageStatistics actualUsageStatistics \u003d (UsageStatistics) actual;"},{"lineNumber":207,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedUsageStatistics, actualUsageStatistics);"},{"lineNumber":208,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedUsageStatistics), JsonUtils.toJson(actualUsageStatistics));"},{"lineNumber":209,"author":{"gitId":"-"},"content":" } else if (expected instanceof Instructor) {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" Instructor expectedInstructor \u003d (Instructor) expected;"},{"lineNumber":211,"author":{"gitId":"-"},"content":" Instructor actualInstructor \u003d (Instructor) actual;"},{"lineNumber":212,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedInstructor, actualInstructor);"},{"lineNumber":213,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedInstructor), JsonUtils.toJson(actualInstructor));"},{"lineNumber":214,"author":{"gitId":"-"},"content":" } else if (expected instanceof Student) {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" Student expectedStudent \u003d (Student) expected;"},{"lineNumber":216,"author":{"gitId":"-"},"content":" Student actualStudent \u003d (Student) actual;"},{"lineNumber":217,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedStudent, actualStudent);"},{"lineNumber":218,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedStudent), JsonUtils.toJson(actualStudent));"},{"lineNumber":219,"author":{"gitId":"-"},"content":" } else if (expected instanceof Section) {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" Section expectedSection \u003d (Section) expected;"},{"lineNumber":221,"author":{"gitId":"-"},"content":" Section actualSection \u003d (Section) actual;"},{"lineNumber":222,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedSection, actualSection);"},{"lineNumber":223,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedSection), JsonUtils.toJson(actualSection));"},{"lineNumber":224,"author":{"gitId":"-"},"content":" } else if (expected instanceof Team) {"},{"lineNumber":225,"author":{"gitId":"-"},"content":" Team expectedTeam \u003d (Team) expected;"},{"lineNumber":226,"author":{"gitId":"-"},"content":" Team actualTeam \u003d (Team) actual;"},{"lineNumber":227,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedTeam, actualTeam);"},{"lineNumber":228,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedTeam), JsonUtils.toJson(actualTeam));"},{"lineNumber":229,"author":{"gitId":"-"},"content":" } else if (expected instanceof ReadNotification) {"},{"lineNumber":230,"author":{"gitId":"-"},"content":" ReadNotification expectedReadNotification \u003d (ReadNotification) expected;"},{"lineNumber":231,"author":{"gitId":"-"},"content":" ReadNotification actualReadNotification \u003d (ReadNotification) actual;"},{"lineNumber":232,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedReadNotification, actualReadNotification);"},{"lineNumber":233,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":234,"author":{"gitId":"-"},"content":" fail(\"Unknown entity\");"},{"lineNumber":235,"author":{"gitId":"-"},"content":" }"},{"lineNumber":236,"author":{"gitId":"-"},"content":" }"},{"lineNumber":237,"author":{"gitId":"-"},"content":""},{"lineNumber":238,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":239,"author":{"gitId":"-"},"content":" * Verifies that the given entity is present in the database."},{"lineNumber":240,"author":{"gitId":"-"},"content":" */"},{"lineNumber":241,"author":{"gitId":"-"},"content":" protected void verifyPresentInDatabase(BaseEntity expected) {"},{"lineNumber":242,"author":{"gitId":"-"},"content":" assertNotNull(expected);"},{"lineNumber":243,"author":{"gitId":"-"},"content":" BaseEntity actual \u003d getEntity(expected);"},{"lineNumber":244,"author":{"gitId":"-"},"content":" verifyEquals(expected, actual);"},{"lineNumber":245,"author":{"gitId":"-"},"content":" }"},{"lineNumber":246,"author":{"gitId":"-"},"content":""},{"lineNumber":247,"author":{"gitId":"-"},"content":" private BaseEntity getEntity(BaseEntity entity) {"},{"lineNumber":248,"author":{"gitId":"-"},"content":" if (entity instanceof Course) {"},{"lineNumber":249,"author":{"gitId":"-"},"content":" return logic.getCourse(((Course) entity).getId());"},{"lineNumber":250,"author":{"gitId":"-"},"content":" } else if (entity instanceof FeedbackSession) {"},{"lineNumber":251,"author":{"gitId":"-"},"content":" return logic.getFeedbackSession(((FeedbackSession) entity).getId());"},{"lineNumber":252,"author":{"gitId":"dishenggg"},"content":" } else if (entity instanceof FeedbackQuestion) {"},{"lineNumber":253,"author":{"gitId":"dishenggg"},"content":" return logic.getFeedbackQuestion(((FeedbackQuestion) entity).getId());"},{"lineNumber":254,"author":{"gitId":"-"},"content":" } else if (entity instanceof Account) {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" return logic.getAccount(((Account) entity).getId());"},{"lineNumber":256,"author":{"gitId":"-"},"content":" } else if (entity instanceof Notification) {"},{"lineNumber":257,"author":{"gitId":"-"},"content":" return logic.getNotification(((Notification) entity).getId());"},{"lineNumber":258,"author":{"gitId":"-"},"content":" } else if (entity instanceof AccountRequest) {"},{"lineNumber":259,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d (AccountRequest) entity;"},{"lineNumber":260,"author":{"gitId":"-"},"content":" return logic.getAccountRequest(accountRequest.getId());"},{"lineNumber":261,"author":{"gitId":"yuanxi1"},"content":" } else if (entity instanceof Instructor) {"},{"lineNumber":262,"author":{"gitId":"yuanxi1"},"content":" return logic.getInstructor(((Instructor) entity).getId());"},{"lineNumber":263,"author":{"gitId":"yuanxi1"},"content":" } else if (entity instanceof Student) {"},{"lineNumber":264,"author":{"gitId":"yuanxi1"},"content":" return logic.getStudent(((Student) entity).getId());"},{"lineNumber":265,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":266,"author":{"gitId":"-"},"content":" throw new RuntimeException(\"Unknown entity type\");"},{"lineNumber":267,"author":{"gitId":"-"},"content":" }"},{"lineNumber":268,"author":{"gitId":"-"},"content":" }"},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(Course expected, Course actual) {"},{"lineNumber":271,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":272,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":273,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(DeadlineExtension expected, DeadlineExtension actual) {"},{"lineNumber":277,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":278,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":279,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":280,"author":{"gitId":"-"},"content":" }"},{"lineNumber":281,"author":{"gitId":"-"},"content":""},{"lineNumber":282,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(FeedbackSession expected, FeedbackSession actual) {"},{"lineNumber":283,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":284,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":285,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":286,"author":{"gitId":"-"},"content":" }"},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(FeedbackQuestion expected, FeedbackQuestion actual) {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":290,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":291,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":292,"author":{"gitId":"-"},"content":" }"},{"lineNumber":293,"author":{"gitId":"-"},"content":""},{"lineNumber":294,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(FeedbackResponse expected, FeedbackResponse actual) {"},{"lineNumber":295,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":296,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":297,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":298,"author":{"gitId":"-"},"content":" }"},{"lineNumber":299,"author":{"gitId":"-"},"content":""},{"lineNumber":300,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(FeedbackResponseComment expected, FeedbackResponseComment actual) {"},{"lineNumber":301,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":302,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":303,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":304,"author":{"gitId":"-"},"content":" }"},{"lineNumber":305,"author":{"gitId":"-"},"content":""},{"lineNumber":306,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(Notification expected, Notification actual) {"},{"lineNumber":307,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":308,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":309,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":310,"author":{"gitId":"-"},"content":" }"},{"lineNumber":311,"author":{"gitId":"-"},"content":""},{"lineNumber":312,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(Account expected, Account actual) {"},{"lineNumber":313,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":314,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":315,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":316,"author":{"gitId":"-"},"content":" }"},{"lineNumber":317,"author":{"gitId":"-"},"content":""},{"lineNumber":318,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(AccountRequest expected, AccountRequest actual) {"},{"lineNumber":319,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":320,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":321,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":322,"author":{"gitId":"-"},"content":" }"},{"lineNumber":323,"author":{"gitId":"-"},"content":""},{"lineNumber":324,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(UsageStatistics expected, UsageStatistics actual) {"},{"lineNumber":325,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":326,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":327,"author":{"gitId":"-"},"content":" }"},{"lineNumber":328,"author":{"gitId":"-"},"content":""},{"lineNumber":329,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(Instructor expected, Instructor actual) {"},{"lineNumber":330,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":331,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":332,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":333,"author":{"gitId":"-"},"content":" }"},{"lineNumber":334,"author":{"gitId":"-"},"content":""},{"lineNumber":335,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(Student expected, Student actual) {"},{"lineNumber":336,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":337,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":338,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":339,"author":{"gitId":"-"},"content":" }"},{"lineNumber":340,"author":{"gitId":"-"},"content":""},{"lineNumber":341,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(Section expected, Section actual) {"},{"lineNumber":342,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":343,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":344,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":345,"author":{"gitId":"-"},"content":" }"},{"lineNumber":346,"author":{"gitId":"-"},"content":""},{"lineNumber":347,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(Team expected, Team actual) {"},{"lineNumber":348,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":349,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":350,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":351,"author":{"gitId":"-"},"content":" }"},{"lineNumber":352,"author":{"gitId":"-"},"content":""},{"lineNumber":353,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(ReadNotification expected, ReadNotification actual) {"},{"lineNumber":354,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":355,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":356,"author":{"gitId":"-"},"content":" }"},{"lineNumber":357,"author":{"gitId":"-"},"content":""},{"lineNumber":358,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":359,"author":{"gitId":"-"},"content":" * Generates a UUID that is different from the given {@code uuid}."},{"lineNumber":360,"author":{"gitId":"-"},"content":" */"},{"lineNumber":361,"author":{"gitId":"-"},"content":" protected UUID generateDifferentUuid(UUID uuid) {"},{"lineNumber":362,"author":{"gitId":"-"},"content":" UUID ret \u003d UUID.randomUUID();"},{"lineNumber":363,"author":{"gitId":"-"},"content":" while (ret.equals(uuid)) {"},{"lineNumber":364,"author":{"gitId":"-"},"content":" ret \u003d UUID.randomUUID();"},{"lineNumber":365,"author":{"gitId":"-"},"content":" }"},{"lineNumber":366,"author":{"gitId":"-"},"content":" return ret;"},{"lineNumber":367,"author":{"gitId":"-"},"content":" }"},{"lineNumber":368,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":8,"yuanxi1":4,"dishenggg":2,"-":354}},{"path":"src/it/java/teammates/it/ui/webapi/AccountRequestSearchIndexingWorkerActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import java.util.UUID;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.ParamsNames;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.test.TestProperties;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.AccountRequestSearchIndexingWorkerAction;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * SUT: {@link AccountRequestSearchIndexingWorkerAction}."},{"lineNumber":21,"author":{"gitId":"-"},"content":" */"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":"public class AccountRequestSearchIndexingWorkerActionIT extends BaseActionIT\u003cAccountRequestSearchIndexingWorkerAction\u003e {"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" @BeforeMethod"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" protected void setUp() throws Exception {"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" super.setUp();"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.flushSession();"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":33,"author":{"gitId":"-"},"content":" protected String getActionUri() {"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" return Const.TaskQueue.ACCOUNT_REQUEST_SEARCH_INDEXING_WORKER_URL;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"-"},"content":" protected String getRequestMethod() {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" return POST;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":43,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":44,"author":{"gitId":"-"},"content":" public void testExecute() throws Exception {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" }"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d typicalBundle.accountRequests.get(\"instructor1\");"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" UUID accountRequestId \u003d accountRequest.getId();"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" ______TS(\"account request not yet indexed should not be searchable\");"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" List\u003cAccountRequest\u003e accountRequestsList \u003d"},{"lineNumber":55,"author":{"gitId":"-"},"content":" logic.searchAccountRequestsInWholeSystem(accountRequest.getEmail());"},{"lineNumber":56,"author":{"gitId":"-"},"content":" assertEquals(0, accountRequestsList.size());"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" ______TS(\"account request indexed should be searchable\");"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" ParamsNames.ACCOUNT_REQUEST_ID, accountRequestId.toString(),"},{"lineNumber":62,"author":{"gitId":"-"},"content":" };"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" AccountRequestSearchIndexingWorkerAction action \u003d getAction(submissionParams);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" getJsonResult(action);"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" accountRequestsList \u003d logic.searchAccountRequestsInWholeSystem(accountRequest.getEmail());"},{"lineNumber":68,"author":{"gitId":"-"},"content":" assertEquals(1, accountRequestsList.size());"},{"lineNumber":69,"author":{"gitId":"-"},"content":" assertEquals(accountRequest.getName(), accountRequestsList.get(0).getName());"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" protected void testAccessControl() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" verifyOnlyAdminCanAccess(course);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":29,"-":50}},{"path":"src/it/java/teammates/it/ui/webapi/BaseActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Arrays;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import jakarta.servlet.http.Cookie;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpDelete;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpGet;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpPost;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpPut;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPermissionRole;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPrivileges;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.UserInfo;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.logic.api.MockEmailSender;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.logic.api.MockLogsProcessor;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.logic.api.MockRecaptchaVerifier;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.logic.api.MockTaskQueuer;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.logic.api.MockUserProvision;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.sqllogic.api.Logic;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import teammates.test.MockHttpServletRequest;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"import teammates.ui.request.BasicRequest;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":41,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.Action;"},{"lineNumber":42,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.ActionFactory;"},{"lineNumber":43,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.ActionMappingException;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.ActionResult;"},{"lineNumber":45,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.EntityNotFoundException;"},{"lineNumber":46,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.InvalidHttpParameterException;"},{"lineNumber":47,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.InvalidOperationException;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":49,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.UnauthorizedAccessException;"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":52,"author":{"gitId":"-"},"content":" * Base class for all action tests."},{"lineNumber":53,"author":{"gitId":"-"},"content":" *"},{"lineNumber":54,"author":{"gitId":"-"},"content":" * \u003cp\u003eOn top of having a local database, these tests require proxy services to be"},{"lineNumber":55,"author":{"gitId":"-"},"content":" * running (to be more precise, mocked)."},{"lineNumber":56,"author":{"gitId":"-"},"content":" *"},{"lineNumber":57,"author":{"gitId":"-"},"content":" * @param \u003cT\u003e The action class being tested."},{"lineNumber":58,"author":{"gitId":"-"},"content":" */"},{"lineNumber":59,"author":{"gitId":"-"},"content":"public abstract class BaseActionIT\u003cT extends Action\u003e extends BaseTestCaseWithSqlDatabaseAccess {"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" static final String GET \u003d HttpGet.METHOD_NAME;"},{"lineNumber":62,"author":{"gitId":"-"},"content":" static final String POST \u003d HttpPost.METHOD_NAME;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" static final String PUT \u003d HttpPut.METHOD_NAME;"},{"lineNumber":64,"author":{"gitId":"-"},"content":" static final String DELETE \u003d HttpDelete.METHOD_NAME;"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" SqlDataBundle typicalBundle \u003d getTypicalSqlDataBundle();"},{"lineNumber":67,"author":{"gitId":"-"},"content":" Logic logic \u003d Logic.inst();"},{"lineNumber":68,"author":{"gitId":"-"},"content":" MockTaskQueuer mockTaskQueuer \u003d new MockTaskQueuer();"},{"lineNumber":69,"author":{"gitId":"-"},"content":" MockEmailSender mockEmailSender \u003d new MockEmailSender();"},{"lineNumber":70,"author":{"gitId":"-"},"content":" MockLogsProcessor mockLogsProcessor \u003d new MockLogsProcessor();"},{"lineNumber":71,"author":{"gitId":"-"},"content":" MockUserProvision mockUserProvision \u003d new MockUserProvision();"},{"lineNumber":72,"author":{"gitId":"-"},"content":" MockRecaptchaVerifier mockRecaptchaVerifier \u003d new MockRecaptchaVerifier();"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" Course testCourseOther;"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" abstract String getActionUri();"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" abstract String getRequestMethod();"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":81,"author":{"gitId":"-"},"content":" * Gets an action with empty request body."},{"lineNumber":82,"author":{"gitId":"-"},"content":" */"},{"lineNumber":83,"author":{"gitId":"-"},"content":" protected T getAction(String... params) {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" return getAction(null, null, params);"},{"lineNumber":85,"author":{"gitId":"-"},"content":" }"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":88,"author":{"gitId":"-"},"content":" * Gets an action with request body."},{"lineNumber":89,"author":{"gitId":"-"},"content":" */"},{"lineNumber":90,"author":{"gitId":"-"},"content":" protected T getAction(BasicRequest requestBody, String... params) {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" return getAction(JsonUtils.toCompactJson(requestBody), null, params);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":95,"author":{"gitId":"-"},"content":" * Gets an action with request body and cookie."},{"lineNumber":96,"author":{"gitId":"-"},"content":" */"},{"lineNumber":97,"author":{"gitId":"-"},"content":" protected T getAction(String body, List\u003cCookie\u003e cookies, String... params) {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" mockTaskQueuer.clearTasks();"},{"lineNumber":99,"author":{"gitId":"-"},"content":" mockEmailSender.clearEmails();"},{"lineNumber":100,"author":{"gitId":"-"},"content":" MockHttpServletRequest req \u003d new MockHttpServletRequest(getRequestMethod(), getActionUri());"},{"lineNumber":101,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c params.length; i \u003d i + 2) {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" req.addParam(params[i], params[i + 1]);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" }"},{"lineNumber":104,"author":{"gitId":"-"},"content":" if (body !\u003d null) {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" req.setBody(body);"},{"lineNumber":106,"author":{"gitId":"-"},"content":" }"},{"lineNumber":107,"author":{"gitId":"-"},"content":" if (cookies !\u003d null) {"},{"lineNumber":108,"author":{"gitId":"-"},"content":" for (Cookie cookie : cookies) {"},{"lineNumber":109,"author":{"gitId":"-"},"content":" req.addCookie(cookie);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" @SuppressWarnings(\"unchecked\")"},{"lineNumber":114,"author":{"gitId":"-"},"content":" T action \u003d (T) ActionFactory.getAction(req, getRequestMethod());"},{"lineNumber":115,"author":{"gitId":"-"},"content":" action.setTaskQueuer(mockTaskQueuer);"},{"lineNumber":116,"author":{"gitId":"-"},"content":" action.setEmailSender(mockEmailSender);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" action.setLogsProcessor(mockLogsProcessor);"},{"lineNumber":118,"author":{"gitId":"-"},"content":" action.setUserProvision(mockUserProvision);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" action.setRecaptchaVerifier(mockRecaptchaVerifier);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" action.init(req);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" return action;"},{"lineNumber":122,"author":{"gitId":"-"},"content":" } catch (ActionMappingException e) {"},{"lineNumber":123,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":124,"author":{"gitId":"-"},"content":" }"},{"lineNumber":125,"author":{"gitId":"-"},"content":" }"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":128,"author":{"gitId":"-"},"content":" * Gets an action with list of cookies."},{"lineNumber":129,"author":{"gitId":"-"},"content":" */"},{"lineNumber":130,"author":{"gitId":"-"},"content":" protected T getActionWithCookie(List\u003cCookie\u003e cookies, String... params) {"},{"lineNumber":131,"author":{"gitId":"-"},"content":" return getAction(null, cookies, params);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" }"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":135,"author":{"gitId":"-"},"content":" * Tests the {@link Action#execute()} method."},{"lineNumber":136,"author":{"gitId":"-"},"content":" *"},{"lineNumber":137,"author":{"gitId":"-"},"content":" * \u003cp\u003eSome actions, particularly those with large number of different outcomes,"},{"lineNumber":138,"author":{"gitId":"-"},"content":" * can alternatively separate each test case to different test blocks."},{"lineNumber":139,"author":{"gitId":"-"},"content":" */"},{"lineNumber":140,"author":{"gitId":"-"},"content":" protected abstract void testExecute() throws Exception;"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":143,"author":{"gitId":"-"},"content":" * Tests the {@link Action#checkAccessControl()} method."},{"lineNumber":144,"author":{"gitId":"-"},"content":" *"},{"lineNumber":145,"author":{"gitId":"-"},"content":" * \u003cp\u003eSome actions, particularly those with large number of different access"},{"lineNumber":146,"author":{"gitId":"-"},"content":" * control settings,"},{"lineNumber":147,"author":{"gitId":"-"},"content":" * can alternatively separate each test case to different test blocks."},{"lineNumber":148,"author":{"gitId":"-"},"content":" */"},{"lineNumber":149,"author":{"gitId":"-"},"content":" protected abstract void testAccessControl() throws Exception;"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":152,"author":{"gitId":"-"},"content":" * Returns The {@code params} array with the {@code userId}"},{"lineNumber":153,"author":{"gitId":"-"},"content":" * (together with the parameter name) inserted at the beginning."},{"lineNumber":154,"author":{"gitId":"-"},"content":" */"},{"lineNumber":155,"author":{"gitId":"-"},"content":" protected String[] addUserIdToParams(String userId, String[] params) {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" List\u003cString\u003e list \u003d new ArrayList\u003c\u003e();"},{"lineNumber":157,"author":{"gitId":"-"},"content":" list.add(Const.ParamsNames.USER_ID);"},{"lineNumber":158,"author":{"gitId":"-"},"content":" list.add(userId);"},{"lineNumber":159,"author":{"gitId":"-"},"content":" list.addAll(Arrays.asList(params));"},{"lineNumber":160,"author":{"gitId":"-"},"content":" return list.toArray(new String[0]);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" // The next few methods are for logging in as various user"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":166,"author":{"gitId":"-"},"content":" * Logs in the user to the test environment as an admin."},{"lineNumber":167,"author":{"gitId":"-"},"content":" */"},{"lineNumber":168,"author":{"gitId":"-"},"content":" protected void loginAsAdmin() {"},{"lineNumber":169,"author":{"gitId":"-"},"content":" UserInfo user \u003d mockUserProvision.loginAsAdmin(Config.APP_ADMINS.get(0));"},{"lineNumber":170,"author":{"gitId":"-"},"content":" assertTrue(user.isAdmin);"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":" * Logs in the user to the test environment as an admin."},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":" protected void loginAsAdminWithTransaction() {"},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" UserInfo user \u003d mockUserProvision.loginAsAdminWithTransaction(Config.APP_ADMINS.get(0));"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":" assertTrue(user.isAdmin);"},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":182,"author":{"gitId":"-"},"content":" * Logs in the user to the test environment as an unregistered user"},{"lineNumber":183,"author":{"gitId":"-"},"content":" * (without any right)."},{"lineNumber":184,"author":{"gitId":"-"},"content":" */"},{"lineNumber":185,"author":{"gitId":"-"},"content":" protected void loginAsUnregistered(String userId) {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" UserInfo user \u003d mockUserProvision.loginUser(userId);"},{"lineNumber":187,"author":{"gitId":"-"},"content":" assertFalse(user.isStudent);"},{"lineNumber":188,"author":{"gitId":"-"},"content":" assertFalse(user.isInstructor);"},{"lineNumber":189,"author":{"gitId":"-"},"content":" assertFalse(user.isAdmin);"},{"lineNumber":190,"author":{"gitId":"-"},"content":" }"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":" * Logs in the user to the test environment as an unregistered user"},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" * (without any right)."},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":" protected void loginAsUnregisteredWithTransaction(String userId) {"},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":" UserInfo user \u003d mockUserProvision.loginUserWithTransaction(userId);"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" assertFalse(user.isStudent);"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":" assertFalse(user.isInstructor);"},{"lineNumber":200,"author":{"gitId":"domoberzin"},"content":" assertFalse(user.isAdmin);"},{"lineNumber":201,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":202,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":204,"author":{"gitId":"-"},"content":" * Logs in the user to the test environment as an instructor"},{"lineNumber":205,"author":{"gitId":"-"},"content":" * (without admin rights or student rights)."},{"lineNumber":206,"author":{"gitId":"-"},"content":" */"},{"lineNumber":207,"author":{"gitId":"-"},"content":" protected void loginAsInstructor(String userId) {"},{"lineNumber":208,"author":{"gitId":"-"},"content":" UserInfo user \u003d mockUserProvision.loginUser(userId);"},{"lineNumber":209,"author":{"gitId":"-"},"content":" assertFalse(user.isStudent);"},{"lineNumber":210,"author":{"gitId":"-"},"content":" assertTrue(user.isInstructor);"},{"lineNumber":211,"author":{"gitId":"-"},"content":" assertFalse(user.isAdmin);"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":215,"author":{"gitId":"domoberzin"},"content":" * Logs in the user to the test environment as an instructor"},{"lineNumber":216,"author":{"gitId":"domoberzin"},"content":" * (without admin rights or student rights)."},{"lineNumber":217,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":218,"author":{"gitId":"domoberzin"},"content":" protected void loginAsInstructorWithTransaction(String userId) {"},{"lineNumber":219,"author":{"gitId":"domoberzin"},"content":" UserInfo user \u003d mockUserProvision.loginUserWithTransaction(userId);"},{"lineNumber":220,"author":{"gitId":"domoberzin"},"content":" assertFalse(user.isStudent);"},{"lineNumber":221,"author":{"gitId":"domoberzin"},"content":" assertTrue(user.isInstructor);"},{"lineNumber":222,"author":{"gitId":"domoberzin"},"content":" assertFalse(user.isAdmin);"},{"lineNumber":223,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":224,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":226,"author":{"gitId":"-"},"content":" * Logs in the user to the test environment as a student"},{"lineNumber":227,"author":{"gitId":"-"},"content":" * (without admin rights or instructor rights)."},{"lineNumber":228,"author":{"gitId":"-"},"content":" */"},{"lineNumber":229,"author":{"gitId":"-"},"content":" protected void loginAsStudent(String userId) {"},{"lineNumber":230,"author":{"gitId":"-"},"content":" UserInfo user \u003d mockUserProvision.loginUser(userId);"},{"lineNumber":231,"author":{"gitId":"-"},"content":" assertTrue(user.isStudent);"},{"lineNumber":232,"author":{"gitId":"-"},"content":" assertFalse(user.isInstructor);"},{"lineNumber":233,"author":{"gitId":"-"},"content":" assertFalse(user.isAdmin);"},{"lineNumber":234,"author":{"gitId":"-"},"content":" }"},{"lineNumber":235,"author":{"gitId":"-"},"content":""},{"lineNumber":236,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":237,"author":{"gitId":"domoberzin"},"content":" * Logs in the user to the test environment as a student"},{"lineNumber":238,"author":{"gitId":"domoberzin"},"content":" * (without admin rights or instructor rights)."},{"lineNumber":239,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":240,"author":{"gitId":"domoberzin"},"content":" protected void loginAsStudentWithTransaction(String userId) {"},{"lineNumber":241,"author":{"gitId":"domoberzin"},"content":" UserInfo user \u003d mockUserProvision.loginUserWithTransaction(userId);"},{"lineNumber":242,"author":{"gitId":"domoberzin"},"content":" assertTrue(user.isStudent);"},{"lineNumber":243,"author":{"gitId":"domoberzin"},"content":" assertFalse(user.isInstructor);"},{"lineNumber":244,"author":{"gitId":"domoberzin"},"content":" assertFalse(user.isAdmin);"},{"lineNumber":245,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":246,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":247,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":248,"author":{"gitId":"-"},"content":" * Logs in the user to the test environment as a student-instructor (without"},{"lineNumber":249,"author":{"gitId":"-"},"content":" * admin rights)."},{"lineNumber":250,"author":{"gitId":"-"},"content":" */"},{"lineNumber":251,"author":{"gitId":"-"},"content":" protected void loginAsStudentInstructor(String userId) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" UserInfo user \u003d mockUserProvision.loginUser(userId);"},{"lineNumber":253,"author":{"gitId":"-"},"content":" assertTrue(user.isStudent);"},{"lineNumber":254,"author":{"gitId":"-"},"content":" assertTrue(user.isInstructor);"},{"lineNumber":255,"author":{"gitId":"-"},"content":" assertFalse(user.isAdmin);"},{"lineNumber":256,"author":{"gitId":"-"},"content":" }"},{"lineNumber":257,"author":{"gitId":"-"},"content":""},{"lineNumber":258,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":259,"author":{"gitId":"-"},"content":" * Logs in the user to the test environment as a maintainer."},{"lineNumber":260,"author":{"gitId":"-"},"content":" */"},{"lineNumber":261,"author":{"gitId":"-"},"content":" protected void loginAsMaintainer() {"},{"lineNumber":262,"author":{"gitId":"-"},"content":" UserInfo user \u003d mockUserProvision.loginUser(Config.APP_MAINTAINERS.get(0));"},{"lineNumber":263,"author":{"gitId":"-"},"content":" assertTrue(user.isMaintainer);"},{"lineNumber":264,"author":{"gitId":"-"},"content":" }"},{"lineNumber":265,"author":{"gitId":"-"},"content":""},{"lineNumber":266,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":267,"author":{"gitId":"-"},"content":" * Logs the current user out of the test environment."},{"lineNumber":268,"author":{"gitId":"-"},"content":" */"},{"lineNumber":269,"author":{"gitId":"-"},"content":" protected void logoutUser() {"},{"lineNumber":270,"author":{"gitId":"-"},"content":" mockUserProvision.logoutUser();"},{"lineNumber":271,"author":{"gitId":"-"},"content":" }"},{"lineNumber":272,"author":{"gitId":"-"},"content":""},{"lineNumber":273,"author":{"gitId":"-"},"content":" void grantInstructorWithSectionPrivilege("},{"lineNumber":274,"author":{"gitId":"-"},"content":" Instructor instructor, String privilege, String[] sections)"},{"lineNumber":275,"author":{"gitId":"-"},"content":" throws Exception {"},{"lineNumber":276,"author":{"gitId":"-"},"content":" InstructorPrivileges instructorPrivileges \u003d new InstructorPrivileges();"},{"lineNumber":277,"author":{"gitId":"-"},"content":""},{"lineNumber":278,"author":{"gitId":"-"},"content":" for (String section : sections) {"},{"lineNumber":279,"author":{"gitId":"-"},"content":" instructorPrivileges.updatePrivilege(section, privilege, true);"},{"lineNumber":280,"author":{"gitId":"-"},"content":" }"},{"lineNumber":281,"author":{"gitId":"-"},"content":""},{"lineNumber":282,"author":{"gitId":"-"},"content":" instructor.setPrivileges(instructorPrivileges);"},{"lineNumber":283,"author":{"gitId":"-"},"content":" assert instructor.isValid();"},{"lineNumber":284,"author":{"gitId":"-"},"content":" }"},{"lineNumber":285,"author":{"gitId":"-"},"content":""},{"lineNumber":286,"author":{"gitId":"-"},"content":" // The next few methods are for testing access control"},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":" // \u0027High-level\u0027 access-control tests: here it tests access control of an action"},{"lineNumber":289,"author":{"gitId":"-"},"content":" // for the full range of user types."},{"lineNumber":290,"author":{"gitId":"-"},"content":""},{"lineNumber":291,"author":{"gitId":"-"},"content":" void verifyAnyUserCanAccess(String... params) {"},{"lineNumber":292,"author":{"gitId":"-"},"content":" verifyAccessibleWithoutLogin(params);"},{"lineNumber":293,"author":{"gitId":"-"},"content":" verifyAccessibleForUnregisteredUsers(params);"},{"lineNumber":294,"author":{"gitId":"-"},"content":" verifyAccessibleForAdmin(params);"},{"lineNumber":295,"author":{"gitId":"-"},"content":" }"},{"lineNumber":296,"author":{"gitId":"-"},"content":""},{"lineNumber":297,"author":{"gitId":"-"},"content":" void verifyAnyLoggedInUserCanAccess(String... params) {"},{"lineNumber":298,"author":{"gitId":"-"},"content":" verifyInaccessibleWithoutLogin(params);"},{"lineNumber":299,"author":{"gitId":"-"},"content":" verifyAccessibleForUnregisteredUsers(params);"},{"lineNumber":300,"author":{"gitId":"-"},"content":" verifyAccessibleForAdmin(params);"},{"lineNumber":301,"author":{"gitId":"-"},"content":" }"},{"lineNumber":302,"author":{"gitId":"-"},"content":""},{"lineNumber":303,"author":{"gitId":"-"},"content":" void verifyOnlyAdminCanAccess(Course course, String... params)"},{"lineNumber":304,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":305,"author":{"gitId":"-"},"content":" verifyInaccessibleWithoutLogin(params);"},{"lineNumber":306,"author":{"gitId":"-"},"content":" verifyInaccessibleForUnregisteredUsers(params);"},{"lineNumber":307,"author":{"gitId":"-"},"content":" verifyInaccessibleForStudents(course, params);"},{"lineNumber":308,"author":{"gitId":"-"},"content":" verifyInaccessibleForInstructors(course, params);"},{"lineNumber":309,"author":{"gitId":"-"},"content":" verifyAccessibleForAdmin(params);"},{"lineNumber":310,"author":{"gitId":"-"},"content":" }"},{"lineNumber":311,"author":{"gitId":"-"},"content":""},{"lineNumber":312,"author":{"gitId":"domoberzin"},"content":" void verifyOnlyAdminCanAccessWithTransaction(String... params)"},{"lineNumber":313,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":314,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":315,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":316,"author":{"gitId":"domoberzin"},"content":" course \u003d logic.createCourse(course);"},{"lineNumber":317,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":318,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":319,"author":{"gitId":"domoberzin"},"content":" verifyInaccessibleWithoutLogin(params);"},{"lineNumber":320,"author":{"gitId":"domoberzin"},"content":" verifyInaccessibleForUnregisteredUsersWithTransaction(params);"},{"lineNumber":321,"author":{"gitId":"domoberzin"},"content":" verifyInaccessibleForStudentsWithTransaction(course, params);"},{"lineNumber":322,"author":{"gitId":"domoberzin"},"content":" verifyInaccessibleForInstructorsWithTransaction(course, params);"},{"lineNumber":323,"author":{"gitId":"domoberzin"},"content":" verifyAccessibleForAdminWithTransaction(params);"},{"lineNumber":324,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":325,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":326,"author":{"gitId":"domoberzin"},"content":" logic.deleteCourseCascade(course.getId());"},{"lineNumber":327,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":328,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":329,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":330,"author":{"gitId":"-"},"content":" void verifyOnlyInstructorsCanAccess(Course course, String... params)"},{"lineNumber":331,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":332,"author":{"gitId":"-"},"content":" verifyInaccessibleWithoutLogin(params);"},{"lineNumber":333,"author":{"gitId":"-"},"content":" verifyInaccessibleForUnregisteredUsers(params);"},{"lineNumber":334,"author":{"gitId":"-"},"content":" verifyInaccessibleForStudents(course, params);"},{"lineNumber":335,"author":{"gitId":"-"},"content":" verifyAccessibleForInstructorsOfTheSameCourse(course, params);"},{"lineNumber":336,"author":{"gitId":"-"},"content":" verifyAccessibleForInstructorsOfOtherCourse(course, params);"},{"lineNumber":337,"author":{"gitId":"-"},"content":" verifyAccessibleForAdminToMasqueradeAsInstructor(course, params);"},{"lineNumber":338,"author":{"gitId":"-"},"content":" }"},{"lineNumber":339,"author":{"gitId":"-"},"content":""},{"lineNumber":340,"author":{"gitId":"-"},"content":" void verifyOnlyInstructorsOfTheSameCourseCanAccess(Course course, String[] submissionParams)"},{"lineNumber":341,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":342,"author":{"gitId":"-"},"content":" verifyInaccessibleWithoutLogin(submissionParams);"},{"lineNumber":343,"author":{"gitId":"-"},"content":" verifyInaccessibleForUnregisteredUsers(submissionParams);"},{"lineNumber":344,"author":{"gitId":"-"},"content":" verifyInaccessibleForStudents(course, submissionParams);"},{"lineNumber":345,"author":{"gitId":"-"},"content":" verifyInaccessibleForInstructorsOfOtherCourses(course, submissionParams);"},{"lineNumber":346,"author":{"gitId":"-"},"content":" verifyAccessibleForInstructorsOfTheSameCourse(course, submissionParams);"},{"lineNumber":347,"author":{"gitId":"-"},"content":" verifyAccessibleForAdminToMasqueradeAsInstructor(course, submissionParams);"},{"lineNumber":348,"author":{"gitId":"-"},"content":" }"},{"lineNumber":349,"author":{"gitId":"-"},"content":""},{"lineNumber":350,"author":{"gitId":"-"},"content":" void verifyOnlyInstructorsOfTheSameCourseWithCorrectCoursePrivilegeCanAccess("},{"lineNumber":351,"author":{"gitId":"-"},"content":" Course course, String privilege, String[] submissionParams) throws Exception {"},{"lineNumber":352,"author":{"gitId":"-"},"content":" verifyInaccessibleWithoutLogin(submissionParams);"},{"lineNumber":353,"author":{"gitId":"-"},"content":" verifyInaccessibleForUnregisteredUsers(submissionParams);"},{"lineNumber":354,"author":{"gitId":"-"},"content":" verifyInaccessibleForStudents(course, submissionParams);"},{"lineNumber":355,"author":{"gitId":"-"},"content":" verifyInaccessibleForInstructorsOfOtherCourses(course, submissionParams);"},{"lineNumber":356,"author":{"gitId":"-"},"content":" verifyInaccessibleWithoutCorrectCoursePrivilege(course, privilege, submissionParams);"},{"lineNumber":357,"author":{"gitId":"-"},"content":" }"},{"lineNumber":358,"author":{"gitId":"-"},"content":""},{"lineNumber":359,"author":{"gitId":"-"},"content":" // \u0027Mid-level\u0027 access control tests: here it tests access control of an action"},{"lineNumber":360,"author":{"gitId":"-"},"content":" // for one user type."},{"lineNumber":361,"author":{"gitId":"-"},"content":""},{"lineNumber":362,"author":{"gitId":"-"},"content":" void verifyAccessibleWithoutLogin(String... params) {"},{"lineNumber":363,"author":{"gitId":"-"},"content":" ______TS(\"Non-logged-in users can access\");"},{"lineNumber":364,"author":{"gitId":"-"},"content":""},{"lineNumber":365,"author":{"gitId":"-"},"content":" logoutUser();"},{"lineNumber":366,"author":{"gitId":"-"},"content":" verifyCanAccess(params);"},{"lineNumber":367,"author":{"gitId":"-"},"content":" }"},{"lineNumber":368,"author":{"gitId":"-"},"content":""},{"lineNumber":369,"author":{"gitId":"-"},"content":" void verifyInaccessibleWithoutLogin(String... params) {"},{"lineNumber":370,"author":{"gitId":"-"},"content":" ______TS(\"Non-logged-in users cannot access\");"},{"lineNumber":371,"author":{"gitId":"-"},"content":""},{"lineNumber":372,"author":{"gitId":"-"},"content":" logoutUser();"},{"lineNumber":373,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":374,"author":{"gitId":"-"},"content":" }"},{"lineNumber":375,"author":{"gitId":"-"},"content":""},{"lineNumber":376,"author":{"gitId":"-"},"content":" void verifyAccessibleForUnregisteredUsers(String... params) {"},{"lineNumber":377,"author":{"gitId":"-"},"content":" ______TS(\"Non-registered users can access\");"},{"lineNumber":378,"author":{"gitId":"-"},"content":""},{"lineNumber":379,"author":{"gitId":"-"},"content":" String unregUserId \u003d \"unreg.user\";"},{"lineNumber":380,"author":{"gitId":"-"},"content":" loginAsUnregistered(unregUserId);"},{"lineNumber":381,"author":{"gitId":"-"},"content":" verifyCanAccess(params);"},{"lineNumber":382,"author":{"gitId":"-"},"content":" }"},{"lineNumber":383,"author":{"gitId":"-"},"content":""},{"lineNumber":384,"author":{"gitId":"-"},"content":" void verifyInaccessibleForUnregisteredUsers(String... params) {"},{"lineNumber":385,"author":{"gitId":"-"},"content":" ______TS(\"Non-registered users cannot access\");"},{"lineNumber":386,"author":{"gitId":"-"},"content":""},{"lineNumber":387,"author":{"gitId":"-"},"content":" String unregUserId \u003d \"unreg.user\";"},{"lineNumber":388,"author":{"gitId":"-"},"content":" loginAsUnregistered(unregUserId);"},{"lineNumber":389,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":390,"author":{"gitId":"-"},"content":" }"},{"lineNumber":391,"author":{"gitId":"-"},"content":""},{"lineNumber":392,"author":{"gitId":"domoberzin"},"content":" void verifyInaccessibleForUnregisteredUsersWithTransaction(String... params) {"},{"lineNumber":393,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Non-registered users cannot access\");"},{"lineNumber":394,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":395,"author":{"gitId":"domoberzin"},"content":" String unregUserId \u003d \"unreg.user\";"},{"lineNumber":396,"author":{"gitId":"domoberzin"},"content":" loginAsUnregisteredWithTransaction(unregUserId);"},{"lineNumber":397,"author":{"gitId":"domoberzin"},"content":" verifyCannotAccess(params);"},{"lineNumber":398,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":399,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":400,"author":{"gitId":"-"},"content":" void verifyAccessibleForAdmin(String... params) {"},{"lineNumber":401,"author":{"gitId":"-"},"content":" ______TS(\"Admin can access\");"},{"lineNumber":402,"author":{"gitId":"-"},"content":""},{"lineNumber":403,"author":{"gitId":"-"},"content":" loginAsAdmin();"},{"lineNumber":404,"author":{"gitId":"-"},"content":" verifyCanAccess(params);"},{"lineNumber":405,"author":{"gitId":"-"},"content":" }"},{"lineNumber":406,"author":{"gitId":"-"},"content":""},{"lineNumber":407,"author":{"gitId":"domoberzin"},"content":" void verifyAccessibleForAdminWithTransaction(String... params) {"},{"lineNumber":408,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Admin can access\");"},{"lineNumber":409,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":410,"author":{"gitId":"domoberzin"},"content":" loginAsAdminWithTransaction();"},{"lineNumber":411,"author":{"gitId":"domoberzin"},"content":" verifyCanAccess(params);"},{"lineNumber":412,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":413,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":414,"author":{"gitId":"-"},"content":" void verifyInaccessibleForAdmin(String... params) {"},{"lineNumber":415,"author":{"gitId":"-"},"content":" ______TS(\"Admin cannot access\");"},{"lineNumber":416,"author":{"gitId":"-"},"content":""},{"lineNumber":417,"author":{"gitId":"-"},"content":" loginAsAdmin();"},{"lineNumber":418,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":419,"author":{"gitId":"-"},"content":" }"},{"lineNumber":420,"author":{"gitId":"-"},"content":""},{"lineNumber":421,"author":{"gitId":"-"},"content":" void verifyInaccessibleForStudents(Course course, String... params)"},{"lineNumber":422,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":423,"author":{"gitId":"-"},"content":" ______TS(\"Students cannot access\");"},{"lineNumber":424,"author":{"gitId":"-"},"content":" Student student \u003d createTypicalStudent(course, \"InaccessibleForStudents@teammates.tmt\");"},{"lineNumber":425,"author":{"gitId":"-"},"content":""},{"lineNumber":426,"author":{"gitId":"-"},"content":" loginAsStudent(student.getAccount().getGoogleId());"},{"lineNumber":427,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":428,"author":{"gitId":"-"},"content":""},{"lineNumber":429,"author":{"gitId":"-"},"content":" }"},{"lineNumber":430,"author":{"gitId":"-"},"content":""},{"lineNumber":431,"author":{"gitId":"domoberzin"},"content":" void verifyInaccessibleForStudentsWithTransaction(Course course, String... params)"},{"lineNumber":432,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":433,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Students cannot access\");"},{"lineNumber":434,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":435,"author":{"gitId":"domoberzin"},"content":" Student student \u003d createTypicalStudent(course, \"InaccessibleForStudents@teammates.tmt\");"},{"lineNumber":436,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":437,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":438,"author":{"gitId":"domoberzin"},"content":" loginAsStudentWithTransaction(student.getAccount().getGoogleId());"},{"lineNumber":439,"author":{"gitId":"domoberzin"},"content":" verifyCannotAccess(params);"},{"lineNumber":440,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":441,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":442,"author":{"gitId":"domoberzin"},"content":" logic.deleteAccountCascade(student.getAccount().getGoogleId());"},{"lineNumber":443,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":444,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":445,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":446,"author":{"gitId":"-"},"content":" void verifyInaccessibleForInstructors(Course course, String... params)"},{"lineNumber":447,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":448,"author":{"gitId":"-"},"content":" ______TS(\"Instructors cannot access\");"},{"lineNumber":449,"author":{"gitId":"-"},"content":" Instructor instructor \u003d createTypicalInstructor(course, \"InaccessibleForInstructors@teammates.tmt\");"},{"lineNumber":450,"author":{"gitId":"-"},"content":""},{"lineNumber":451,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getAccount().getGoogleId());"},{"lineNumber":452,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":453,"author":{"gitId":"-"},"content":""},{"lineNumber":454,"author":{"gitId":"-"},"content":" }"},{"lineNumber":455,"author":{"gitId":"-"},"content":""},{"lineNumber":456,"author":{"gitId":"domoberzin"},"content":" void verifyInaccessibleForInstructorsWithTransaction(Course course, String... params)"},{"lineNumber":457,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":458,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Instructors cannot access\");"},{"lineNumber":459,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":460,"author":{"gitId":"domoberzin"},"content":" Instructor instructor \u003d createTypicalInstructor(course, \"InaccessibleForInstructors@teammates.tmt\");"},{"lineNumber":461,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":462,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":463,"author":{"gitId":"domoberzin"},"content":" loginAsInstructorWithTransaction(instructor.getAccount().getGoogleId());"},{"lineNumber":464,"author":{"gitId":"domoberzin"},"content":" verifyCannotAccess(params);"},{"lineNumber":465,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":466,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":467,"author":{"gitId":"domoberzin"},"content":" logic.deleteAccountCascade(instructor.getAccount().getGoogleId());"},{"lineNumber":468,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":469,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":470,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":471,"author":{"gitId":"-"},"content":" void verifyAccessibleForAdminToMasqueradeAsInstructor("},{"lineNumber":472,"author":{"gitId":"-"},"content":" Instructor instructor, String[] submissionParams) {"},{"lineNumber":473,"author":{"gitId":"-"},"content":" ______TS(\"admin can access\");"},{"lineNumber":474,"author":{"gitId":"-"},"content":""},{"lineNumber":475,"author":{"gitId":"-"},"content":" loginAsAdmin();"},{"lineNumber":476,"author":{"gitId":"-"},"content":" // not checking for non-masquerade mode because admin may not be an instructor"},{"lineNumber":477,"author":{"gitId":"-"},"content":" verifyCanMasquerade(instructor.getAccount().getGoogleId(), submissionParams);"},{"lineNumber":478,"author":{"gitId":"-"},"content":" }"},{"lineNumber":479,"author":{"gitId":"-"},"content":""},{"lineNumber":480,"author":{"gitId":"-"},"content":" void verifyAccessibleForAdminToMasqueradeAsInstructor(Course course, String[] submissionParams)"},{"lineNumber":481,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":482,"author":{"gitId":"-"},"content":" ______TS(\"admin can access\");"},{"lineNumber":483,"author":{"gitId":"-"},"content":" Instructor instructor \u003d createTypicalInstructor(course,"},{"lineNumber":484,"author":{"gitId":"-"},"content":" \"AccessibleForAdminToMasqueradeAsInstructor@teammates.tmt\");"},{"lineNumber":485,"author":{"gitId":"-"},"content":""},{"lineNumber":486,"author":{"gitId":"-"},"content":" loginAsAdmin();"},{"lineNumber":487,"author":{"gitId":"-"},"content":" // not checking for non-masquerade mode because admin may not be an instructor"},{"lineNumber":488,"author":{"gitId":"-"},"content":" verifyCanMasquerade(instructor.getAccount().getGoogleId(), submissionParams);"},{"lineNumber":489,"author":{"gitId":"-"},"content":" }"},{"lineNumber":490,"author":{"gitId":"-"},"content":""},{"lineNumber":491,"author":{"gitId":"-"},"content":" void verifyInaccessibleWithoutModifySessionPrivilege(Course course, String[] submissionParams)"},{"lineNumber":492,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":493,"author":{"gitId":"-"},"content":" ______TS(\"without Modify-Session privilege cannot access\");"},{"lineNumber":494,"author":{"gitId":"-"},"content":""},{"lineNumber":495,"author":{"gitId":"-"},"content":" Instructor instructor \u003d createTypicalInstructor(course,"},{"lineNumber":496,"author":{"gitId":"-"},"content":" \"InaccessibleWithoutModifySessionPrivilege@teammates.tmt\");"},{"lineNumber":497,"author":{"gitId":"-"},"content":""},{"lineNumber":498,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getAccount().getGoogleId());"},{"lineNumber":499,"author":{"gitId":"-"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":500,"author":{"gitId":"-"},"content":" }"},{"lineNumber":501,"author":{"gitId":"-"},"content":""},{"lineNumber":502,"author":{"gitId":"-"},"content":" void verifyInaccessibleWithoutSubmitSessionInSectionsPrivilege(Course course, String[] submissionParams)"},{"lineNumber":503,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":504,"author":{"gitId":"-"},"content":" ______TS(\"without Submit-Session-In-Sections privilege cannot access\");"},{"lineNumber":505,"author":{"gitId":"-"},"content":""},{"lineNumber":506,"author":{"gitId":"-"},"content":" Instructor instructor \u003d createTypicalInstructor(course,"},{"lineNumber":507,"author":{"gitId":"-"},"content":" \"InaccessibleWithoutSubmitSessionInSectionsPrivilege@teammates.tmt\");"},{"lineNumber":508,"author":{"gitId":"-"},"content":""},{"lineNumber":509,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getAccount().getGoogleId());"},{"lineNumber":510,"author":{"gitId":"-"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":511,"author":{"gitId":"-"},"content":" }"},{"lineNumber":512,"author":{"gitId":"-"},"content":""},{"lineNumber":513,"author":{"gitId":"-"},"content":" void verifyInaccessibleWithoutCorrectCoursePrivilege(Course course, String privilege, String[] submissionParams)"},{"lineNumber":514,"author":{"gitId":"-"},"content":" throws Exception {"},{"lineNumber":515,"author":{"gitId":"-"},"content":" Instructor instructor \u003d createTypicalInstructor(course,"},{"lineNumber":516,"author":{"gitId":"-"},"content":" \"InaccessibleWithoutCorrectCoursePrivilege@teammates.tmt\");"},{"lineNumber":517,"author":{"gitId":"-"},"content":""},{"lineNumber":518,"author":{"gitId":"-"},"content":" ______TS(\"without correct course privilege cannot access\");"},{"lineNumber":519,"author":{"gitId":"-"},"content":""},{"lineNumber":520,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getAccount().getGoogleId());"},{"lineNumber":521,"author":{"gitId":"-"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":522,"author":{"gitId":"-"},"content":""},{"lineNumber":523,"author":{"gitId":"-"},"content":" ______TS(\"only instructor with correct course privilege should pass\");"},{"lineNumber":524,"author":{"gitId":"-"},"content":" InstructorPrivileges instructorPrivileges \u003d new InstructorPrivileges();"},{"lineNumber":525,"author":{"gitId":"-"},"content":""},{"lineNumber":526,"author":{"gitId":"-"},"content":" instructorPrivileges.updatePrivilege(privilege, true);"},{"lineNumber":527,"author":{"gitId":"-"},"content":" instructor.setPrivileges(instructorPrivileges);"},{"lineNumber":528,"author":{"gitId":"-"},"content":""},{"lineNumber":529,"author":{"gitId":"-"},"content":" verifyCanAccess(submissionParams);"},{"lineNumber":530,"author":{"gitId":"-"},"content":" verifyAccessibleForAdminToMasqueradeAsInstructor(instructor, submissionParams);"},{"lineNumber":531,"author":{"gitId":"-"},"content":" }"},{"lineNumber":532,"author":{"gitId":"-"},"content":""},{"lineNumber":533,"author":{"gitId":"-"},"content":" void verifyAccessibleForInstructorsOfTheSameCourse(Course course, String[] submissionParams)"},{"lineNumber":534,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":535,"author":{"gitId":"-"},"content":" ______TS(\"course instructor can access\");"},{"lineNumber":536,"author":{"gitId":"-"},"content":" Course courseOther \u003d createTestCourseOther();"},{"lineNumber":537,"author":{"gitId":"-"},"content":" assert !course.getId().equals(courseOther.getId());"},{"lineNumber":538,"author":{"gitId":"-"},"content":""},{"lineNumber":539,"author":{"gitId":"-"},"content":" Instructor instructorSameCourse \u003d createTypicalInstructor(course,"},{"lineNumber":540,"author":{"gitId":"-"},"content":" \"AccessibleForInstructorsOfTheSameCourse-instructor@teammates.tmt\");"},{"lineNumber":541,"author":{"gitId":"-"},"content":" Student studentSameCourse \u003d createTypicalStudent(course,"},{"lineNumber":542,"author":{"gitId":"-"},"content":" \"AccessibleForInstructorsOfTheSameCourse-student@teammates.tmt\");"},{"lineNumber":543,"author":{"gitId":"-"},"content":" Instructor instructorOtherCourse \u003d createTypicalInstructor(courseOther,"},{"lineNumber":544,"author":{"gitId":"-"},"content":" \"AccessibleForInstructorsOfTheSameCourse-OtherInstructor@teammates.tmt\");"},{"lineNumber":545,"author":{"gitId":"-"},"content":""},{"lineNumber":546,"author":{"gitId":"-"},"content":" loginAsInstructor(instructorSameCourse.getAccount().getGoogleId());"},{"lineNumber":547,"author":{"gitId":"-"},"content":" verifyCanAccess(submissionParams);"},{"lineNumber":548,"author":{"gitId":"-"},"content":""},{"lineNumber":549,"author":{"gitId":"-"},"content":" verifyCannotMasquerade(studentSameCourse.getAccount().getGoogleId(), submissionParams);"},{"lineNumber":550,"author":{"gitId":"-"},"content":" verifyCannotMasquerade(instructorOtherCourse.getAccount().getGoogleId(), submissionParams);"},{"lineNumber":551,"author":{"gitId":"-"},"content":""},{"lineNumber":552,"author":{"gitId":"-"},"content":" }"},{"lineNumber":553,"author":{"gitId":"-"},"content":""},{"lineNumber":554,"author":{"gitId":"-"},"content":" void verifyAccessibleForInstructorsOfOtherCourse(Course course, String[] submissionParams)"},{"lineNumber":555,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":556,"author":{"gitId":"-"},"content":" ______TS(\"other course\u0027s instructor can access\");"},{"lineNumber":557,"author":{"gitId":"-"},"content":" Course courseOther \u003d createTestCourseOther();"},{"lineNumber":558,"author":{"gitId":"-"},"content":" assert !course.getId().equals(courseOther.getId());"},{"lineNumber":559,"author":{"gitId":"-"},"content":""},{"lineNumber":560,"author":{"gitId":"-"},"content":" Instructor instructorSameCourse \u003d createTypicalInstructor(course,"},{"lineNumber":561,"author":{"gitId":"-"},"content":" \"AccessibleForInstructorsOfOtherCourse-instructor@teammates.tmt\");"},{"lineNumber":562,"author":{"gitId":"-"},"content":" Student studentSameCourse \u003d createTypicalStudent(course,"},{"lineNumber":563,"author":{"gitId":"-"},"content":" \"AccessibleForInstructorsOfOtherCourse-student@teammates.tmt\");"},{"lineNumber":564,"author":{"gitId":"-"},"content":" Instructor instructorOtherCourse \u003d createTypicalInstructor(courseOther,"},{"lineNumber":565,"author":{"gitId":"-"},"content":" \"AccessibleForInstructorsOfOtherCourse-OtherInstructor@teammates.tmt\");"},{"lineNumber":566,"author":{"gitId":"-"},"content":""},{"lineNumber":567,"author":{"gitId":"-"},"content":" loginAsInstructor(instructorOtherCourse.getAccount().getGoogleId());"},{"lineNumber":568,"author":{"gitId":"-"},"content":" verifyCanAccess(submissionParams);"},{"lineNumber":569,"author":{"gitId":"-"},"content":""},{"lineNumber":570,"author":{"gitId":"-"},"content":" verifyCannotMasquerade(studentSameCourse.getAccount().getGoogleId(), submissionParams);"},{"lineNumber":571,"author":{"gitId":"-"},"content":" verifyCannotMasquerade(instructorSameCourse.getAccount().getGoogleId(), submissionParams);"},{"lineNumber":572,"author":{"gitId":"-"},"content":" }"},{"lineNumber":573,"author":{"gitId":"-"},"content":""},{"lineNumber":574,"author":{"gitId":"-"},"content":" void verifyAccessibleForStudentsOfTheSameCourse(Course course, String[] submissionParams)"},{"lineNumber":575,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":576,"author":{"gitId":"-"},"content":" ______TS(\"course students can access\");"},{"lineNumber":577,"author":{"gitId":"-"},"content":" Student student \u003d createTypicalStudent(course, \"AccessibleForStudentsOfTheSameCourse@teammates.tmt\");"},{"lineNumber":578,"author":{"gitId":"-"},"content":" loginAsStudent(student.getAccount().getGoogleId());"},{"lineNumber":579,"author":{"gitId":"-"},"content":" verifyCanAccess(submissionParams);"},{"lineNumber":580,"author":{"gitId":"-"},"content":" }"},{"lineNumber":581,"author":{"gitId":"-"},"content":""},{"lineNumber":582,"author":{"gitId":"-"},"content":" void verifyInaccessibleForStudentsOfOtherCourse(Course course, String[] submissionParams)"},{"lineNumber":583,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":584,"author":{"gitId":"-"},"content":" ______TS(\"other course student cannot access\");"},{"lineNumber":585,"author":{"gitId":"-"},"content":" Course courseOther \u003d createTestCourseOther();"},{"lineNumber":586,"author":{"gitId":"-"},"content":" Student otherStudent \u003d createTypicalStudent(courseOther,"},{"lineNumber":587,"author":{"gitId":"-"},"content":" \"InaccessibleForStudentsOfOtherCourse-other@teammates.tmt\");"},{"lineNumber":588,"author":{"gitId":"-"},"content":" assert !course.getId().equals(courseOther.getId());"},{"lineNumber":589,"author":{"gitId":"-"},"content":""},{"lineNumber":590,"author":{"gitId":"-"},"content":" loginAsStudent(otherStudent.getAccount().getGoogleId());"},{"lineNumber":591,"author":{"gitId":"-"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":592,"author":{"gitId":"-"},"content":" }"},{"lineNumber":593,"author":{"gitId":"-"},"content":""},{"lineNumber":594,"author":{"gitId":"-"},"content":" void verifyInaccessibleForInstructorsOfOtherCourses(Course course, String[] submissionParams)"},{"lineNumber":595,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":596,"author":{"gitId":"-"},"content":" ______TS(\"other course instructor cannot access\");"},{"lineNumber":597,"author":{"gitId":"-"},"content":" Course courseOther \u003d createTestCourseOther();"},{"lineNumber":598,"author":{"gitId":"-"},"content":" Instructor otherInstructor \u003d createTypicalInstructor(courseOther,"},{"lineNumber":599,"author":{"gitId":"-"},"content":" \"InaccessibleForInstructorsOfOtherCourses@teammates.tmt\");"},{"lineNumber":600,"author":{"gitId":"-"},"content":" assert !course.getId().equals(courseOther.getId());"},{"lineNumber":601,"author":{"gitId":"-"},"content":""},{"lineNumber":602,"author":{"gitId":"-"},"content":" loginAsInstructor(otherInstructor.getAccount().getGoogleId());"},{"lineNumber":603,"author":{"gitId":"-"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":604,"author":{"gitId":"-"},"content":" }"},{"lineNumber":605,"author":{"gitId":"-"},"content":""},{"lineNumber":606,"author":{"gitId":"-"},"content":" void verifyAccessibleForMaintainers(String... params) {"},{"lineNumber":607,"author":{"gitId":"-"},"content":" ______TS(\"Maintainer can access\");"},{"lineNumber":608,"author":{"gitId":"-"},"content":""},{"lineNumber":609,"author":{"gitId":"-"},"content":" loginAsMaintainer();"},{"lineNumber":610,"author":{"gitId":"-"},"content":" verifyCanAccess(params);"},{"lineNumber":611,"author":{"gitId":"-"},"content":" }"},{"lineNumber":612,"author":{"gitId":"-"},"content":""},{"lineNumber":613,"author":{"gitId":"-"},"content":" // \u0027Low-level\u0027 access control tests: here it tests an action once with the given"},{"lineNumber":614,"author":{"gitId":"-"},"content":" // parameters."},{"lineNumber":615,"author":{"gitId":"-"},"content":" // These methods are not aware of the user type."},{"lineNumber":616,"author":{"gitId":"-"},"content":""},{"lineNumber":617,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":618,"author":{"gitId":"-"},"content":" * Verifies that the {@link Action} matching the {@code params} is accessible to"},{"lineNumber":619,"author":{"gitId":"-"},"content":" * the logged in user."},{"lineNumber":620,"author":{"gitId":"-"},"content":" */"},{"lineNumber":621,"author":{"gitId":"-"},"content":" protected void verifyCanAccess(String... params) {"},{"lineNumber":622,"author":{"gitId":"-"},"content":" Action c \u003d getAction(params);"},{"lineNumber":623,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":624,"author":{"gitId":"-"},"content":" c.checkAccessControl();"},{"lineNumber":625,"author":{"gitId":"-"},"content":" } catch (UnauthorizedAccessException e) {"},{"lineNumber":626,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":627,"author":{"gitId":"-"},"content":" }"},{"lineNumber":628,"author":{"gitId":"-"},"content":" }"},{"lineNumber":629,"author":{"gitId":"-"},"content":""},{"lineNumber":630,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":631,"author":{"gitId":"-"},"content":" * Verifies that the {@link Action} matching the {@code params} is not"},{"lineNumber":632,"author":{"gitId":"-"},"content":" * accessible to the user."},{"lineNumber":633,"author":{"gitId":"-"},"content":" */"},{"lineNumber":634,"author":{"gitId":"-"},"content":" protected void verifyCannotAccess(String... params) {"},{"lineNumber":635,"author":{"gitId":"-"},"content":" Action c \u003d getAction(params);"},{"lineNumber":636,"author":{"gitId":"-"},"content":" assertThrows(UnauthorizedAccessException.class, c::checkAccessControl);"},{"lineNumber":637,"author":{"gitId":"-"},"content":" }"},{"lineNumber":638,"author":{"gitId":"-"},"content":""},{"lineNumber":639,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":640,"author":{"gitId":"-"},"content":" * Verifies that the {@link Action} matching the {@code params} is"},{"lineNumber":641,"author":{"gitId":"-"},"content":" * accessible to the logged in user masquerading as another user with"},{"lineNumber":642,"author":{"gitId":"-"},"content":" * {@code userId}."},{"lineNumber":643,"author":{"gitId":"-"},"content":" */"},{"lineNumber":644,"author":{"gitId":"-"},"content":" protected void verifyCanMasquerade(String userId, String... params) {"},{"lineNumber":645,"author":{"gitId":"-"},"content":" verifyCanAccess(addUserIdToParams(userId, params));"},{"lineNumber":646,"author":{"gitId":"-"},"content":" }"},{"lineNumber":647,"author":{"gitId":"-"},"content":""},{"lineNumber":648,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":649,"author":{"gitId":"-"},"content":" * Verifies that the {@link Action} matching the {@code params} is not"},{"lineNumber":650,"author":{"gitId":"-"},"content":" * accessible to the logged in user masquerading as another user with"},{"lineNumber":651,"author":{"gitId":"-"},"content":" * {@code userId}."},{"lineNumber":652,"author":{"gitId":"-"},"content":" */"},{"lineNumber":653,"author":{"gitId":"-"},"content":" protected void verifyCannotMasquerade(String userId, String... params) {"},{"lineNumber":654,"author":{"gitId":"-"},"content":" assertThrows(UnauthorizedAccessException.class,"},{"lineNumber":655,"author":{"gitId":"-"},"content":" () -\u003e getAction(addUserIdToParams(userId, params)).checkAccessControl());"},{"lineNumber":656,"author":{"gitId":"-"},"content":" }"},{"lineNumber":657,"author":{"gitId":"-"},"content":""},{"lineNumber":658,"author":{"gitId":"-"},"content":" // The next few methods are for parsing results"},{"lineNumber":659,"author":{"gitId":"-"},"content":""},{"lineNumber":660,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":661,"author":{"gitId":"-"},"content":" * Executes the action, verifies the status code as 200 OK, and returns the"},{"lineNumber":662,"author":{"gitId":"-"},"content":" * result."},{"lineNumber":663,"author":{"gitId":"-"},"content":" *"},{"lineNumber":664,"author":{"gitId":"-"},"content":" * \u003cp\u003eAssumption: The action returns a {@link JsonResult}."},{"lineNumber":665,"author":{"gitId":"-"},"content":" */"},{"lineNumber":666,"author":{"gitId":"-"},"content":" protected JsonResult getJsonResult(Action a) {"},{"lineNumber":667,"author":{"gitId":"-"},"content":" return getJsonResult(a, HttpStatus.SC_OK);"},{"lineNumber":668,"author":{"gitId":"-"},"content":" }"},{"lineNumber":669,"author":{"gitId":"-"},"content":""},{"lineNumber":670,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":671,"author":{"gitId":"-"},"content":" * Executes the action, verifies the status code, and returns the result."},{"lineNumber":672,"author":{"gitId":"-"},"content":" *"},{"lineNumber":673,"author":{"gitId":"-"},"content":" * \u003cp\u003eAssumption: The action returns a {@link JsonResult}."},{"lineNumber":674,"author":{"gitId":"-"},"content":" */"},{"lineNumber":675,"author":{"gitId":"-"},"content":" protected JsonResult getJsonResult(Action a, int statusCode) {"},{"lineNumber":676,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":677,"author":{"gitId":"-"},"content":" ActionResult r \u003d a.execute();"},{"lineNumber":678,"author":{"gitId":"-"},"content":" assertEquals(statusCode, r.getStatusCode());"},{"lineNumber":679,"author":{"gitId":"-"},"content":" return (JsonResult) r;"},{"lineNumber":680,"author":{"gitId":"-"},"content":" } catch (InvalidOperationException | InvalidHttpRequestBodyException e) {"},{"lineNumber":681,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":682,"author":{"gitId":"-"},"content":" }"},{"lineNumber":683,"author":{"gitId":"-"},"content":" }"},{"lineNumber":684,"author":{"gitId":"-"},"content":""},{"lineNumber":685,"author":{"gitId":"-"},"content":" // The next few methods are for verifying action results"},{"lineNumber":686,"author":{"gitId":"-"},"content":""},{"lineNumber":687,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":688,"author":{"gitId":"-"},"content":" * Verifies that the executed action results in"},{"lineNumber":689,"author":{"gitId":"-"},"content":" * {@link InvalidHttpParameterException} being thrown."},{"lineNumber":690,"author":{"gitId":"-"},"content":" */"},{"lineNumber":691,"author":{"gitId":"-"},"content":" protected InvalidHttpParameterException verifyHttpParameterFailure(String... params) {"},{"lineNumber":692,"author":{"gitId":"-"},"content":" Action c \u003d getAction(params);"},{"lineNumber":693,"author":{"gitId":"-"},"content":" return assertThrows(InvalidHttpParameterException.class, c::execute);"},{"lineNumber":694,"author":{"gitId":"-"},"content":" }"},{"lineNumber":695,"author":{"gitId":"-"},"content":""},{"lineNumber":696,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":697,"author":{"gitId":"-"},"content":" * Verifies that the executed action results in"},{"lineNumber":698,"author":{"gitId":"-"},"content":" * {@link InvalidHttpParameterException} being thrown."},{"lineNumber":699,"author":{"gitId":"-"},"content":" */"},{"lineNumber":700,"author":{"gitId":"-"},"content":" protected InvalidHttpParameterException verifyHttpParameterFailure(BasicRequest requestBody, String... params) {"},{"lineNumber":701,"author":{"gitId":"-"},"content":" Action c \u003d getAction(requestBody, params);"},{"lineNumber":702,"author":{"gitId":"-"},"content":" return assertThrows(InvalidHttpParameterException.class, c::execute);"},{"lineNumber":703,"author":{"gitId":"-"},"content":" }"},{"lineNumber":704,"author":{"gitId":"-"},"content":""},{"lineNumber":705,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":706,"author":{"gitId":"-"},"content":" * Verifies that the action results in {@link InvalidHttpParameterException}"},{"lineNumber":707,"author":{"gitId":"-"},"content":" * being thrown"},{"lineNumber":708,"author":{"gitId":"-"},"content":" * when checking for access control."},{"lineNumber":709,"author":{"gitId":"-"},"content":" */"},{"lineNumber":710,"author":{"gitId":"-"},"content":" protected InvalidHttpParameterException verifyHttpParameterFailureAcl(String... params) {"},{"lineNumber":711,"author":{"gitId":"-"},"content":" Action c \u003d getAction(params);"},{"lineNumber":712,"author":{"gitId":"-"},"content":" return assertThrows(InvalidHttpParameterException.class, c::checkAccessControl);"},{"lineNumber":713,"author":{"gitId":"-"},"content":" }"},{"lineNumber":714,"author":{"gitId":"-"},"content":""},{"lineNumber":715,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":716,"author":{"gitId":"-"},"content":" * Verifies that the executed action results in"},{"lineNumber":717,"author":{"gitId":"-"},"content":" * {@link InvalidHttpRequestBodyException} being thrown."},{"lineNumber":718,"author":{"gitId":"-"},"content":" */"},{"lineNumber":719,"author":{"gitId":"-"},"content":" protected InvalidHttpRequestBodyException verifyHttpRequestBodyFailure(BasicRequest requestBody, String... params) {"},{"lineNumber":720,"author":{"gitId":"-"},"content":" Action c \u003d getAction(requestBody, params);"},{"lineNumber":721,"author":{"gitId":"-"},"content":" return assertThrows(InvalidHttpRequestBodyException.class, c::execute);"},{"lineNumber":722,"author":{"gitId":"-"},"content":" }"},{"lineNumber":723,"author":{"gitId":"-"},"content":""},{"lineNumber":724,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":725,"author":{"gitId":"-"},"content":" * Verifies that the executed action results in {@link EntityNotFoundException}"},{"lineNumber":726,"author":{"gitId":"-"},"content":" * being thrown."},{"lineNumber":727,"author":{"gitId":"-"},"content":" */"},{"lineNumber":728,"author":{"gitId":"-"},"content":" protected EntityNotFoundException verifyEntityNotFound(String... params) {"},{"lineNumber":729,"author":{"gitId":"-"},"content":" Action c \u003d getAction(params);"},{"lineNumber":730,"author":{"gitId":"-"},"content":" return assertThrows(EntityNotFoundException.class, c::execute);"},{"lineNumber":731,"author":{"gitId":"-"},"content":" }"},{"lineNumber":732,"author":{"gitId":"-"},"content":""},{"lineNumber":733,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":734,"author":{"gitId":"-"},"content":" * Verifies that the executed action results in {@link EntityNotFoundException}"},{"lineNumber":735,"author":{"gitId":"-"},"content":" * being thrown."},{"lineNumber":736,"author":{"gitId":"-"},"content":" */"},{"lineNumber":737,"author":{"gitId":"-"},"content":" protected EntityNotFoundException verifyEntityNotFound(BasicRequest requestBody, String... params) {"},{"lineNumber":738,"author":{"gitId":"-"},"content":" Action c \u003d getAction(requestBody, params);"},{"lineNumber":739,"author":{"gitId":"-"},"content":" return assertThrows(EntityNotFoundException.class, c::execute);"},{"lineNumber":740,"author":{"gitId":"-"},"content":" }"},{"lineNumber":741,"author":{"gitId":"-"},"content":""},{"lineNumber":742,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":743,"author":{"gitId":"-"},"content":" * Verifies that the action results in {@link EntityNotFoundException} being"},{"lineNumber":744,"author":{"gitId":"-"},"content":" * thrown when checking for access control."},{"lineNumber":745,"author":{"gitId":"-"},"content":" */"},{"lineNumber":746,"author":{"gitId":"-"},"content":" protected EntityNotFoundException verifyEntityNotFoundAcl(String... params) {"},{"lineNumber":747,"author":{"gitId":"-"},"content":" Action c \u003d getAction(params);"},{"lineNumber":748,"author":{"gitId":"-"},"content":" return assertThrows(EntityNotFoundException.class, c::checkAccessControl);"},{"lineNumber":749,"author":{"gitId":"-"},"content":" }"},{"lineNumber":750,"author":{"gitId":"-"},"content":""},{"lineNumber":751,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":752,"author":{"gitId":"-"},"content":" * Verifies that the executed action results in"},{"lineNumber":753,"author":{"gitId":"-"},"content":" * {@link InvalidOperationException} being thrown."},{"lineNumber":754,"author":{"gitId":"-"},"content":" */"},{"lineNumber":755,"author":{"gitId":"-"},"content":" protected InvalidOperationException verifyInvalidOperation(String... params) {"},{"lineNumber":756,"author":{"gitId":"-"},"content":" Action c \u003d getAction(params);"},{"lineNumber":757,"author":{"gitId":"-"},"content":" return assertThrows(InvalidOperationException.class, c::execute);"},{"lineNumber":758,"author":{"gitId":"-"},"content":" }"},{"lineNumber":759,"author":{"gitId":"-"},"content":""},{"lineNumber":760,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":761,"author":{"gitId":"-"},"content":" * Verifies that the executed action results in"},{"lineNumber":762,"author":{"gitId":"-"},"content":" * {@link InvalidOperationException} being thrown."},{"lineNumber":763,"author":{"gitId":"-"},"content":" */"},{"lineNumber":764,"author":{"gitId":"-"},"content":" protected InvalidOperationException verifyInvalidOperation(BasicRequest requestBody, String... params) {"},{"lineNumber":765,"author":{"gitId":"-"},"content":" Action c \u003d getAction(requestBody, params);"},{"lineNumber":766,"author":{"gitId":"-"},"content":" return assertThrows(InvalidOperationException.class, c::execute);"},{"lineNumber":767,"author":{"gitId":"-"},"content":" }"},{"lineNumber":768,"author":{"gitId":"-"},"content":""},{"lineNumber":769,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":770,"author":{"gitId":"-"},"content":" * Verifies that the executed action does not result in any background task"},{"lineNumber":771,"author":{"gitId":"-"},"content":" * being added."},{"lineNumber":772,"author":{"gitId":"-"},"content":" */"},{"lineNumber":773,"author":{"gitId":"-"},"content":" protected void verifyNoTasksAdded() {"},{"lineNumber":774,"author":{"gitId":"-"},"content":" Map\u003cString, Integer\u003e tasksAdded \u003d mockTaskQueuer.getNumberOfTasksAdded();"},{"lineNumber":775,"author":{"gitId":"-"},"content":" assertEquals(0, tasksAdded.keySet().size());"},{"lineNumber":776,"author":{"gitId":"-"},"content":" }"},{"lineNumber":777,"author":{"gitId":"-"},"content":""},{"lineNumber":778,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":779,"author":{"gitId":"-"},"content":" * Verifies that the executed action results in the specified background tasks"},{"lineNumber":780,"author":{"gitId":"-"},"content":" * being added."},{"lineNumber":781,"author":{"gitId":"-"},"content":" */"},{"lineNumber":782,"author":{"gitId":"-"},"content":" protected void verifySpecifiedTasksAdded(String taskName, int taskCount) {"},{"lineNumber":783,"author":{"gitId":"-"},"content":" Map\u003cString, Integer\u003e tasksAdded \u003d mockTaskQueuer.getNumberOfTasksAdded();"},{"lineNumber":784,"author":{"gitId":"-"},"content":" assertEquals(taskCount, tasksAdded.get(taskName).intValue());"},{"lineNumber":785,"author":{"gitId":"-"},"content":" }"},{"lineNumber":786,"author":{"gitId":"-"},"content":""},{"lineNumber":787,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":788,"author":{"gitId":"-"},"content":" * Verifies that the executed action does not result in any email being sent."},{"lineNumber":789,"author":{"gitId":"-"},"content":" */"},{"lineNumber":790,"author":{"gitId":"-"},"content":" protected void verifyNoEmailsSent() {"},{"lineNumber":791,"author":{"gitId":"-"},"content":" assertTrue(getEmailsSent().isEmpty());"},{"lineNumber":792,"author":{"gitId":"-"},"content":" }"},{"lineNumber":793,"author":{"gitId":"-"},"content":""},{"lineNumber":794,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":795,"author":{"gitId":"-"},"content":" * Returns the list of emails sent as part of the executed action."},{"lineNumber":796,"author":{"gitId":"-"},"content":" */"},{"lineNumber":797,"author":{"gitId":"-"},"content":" protected List\u003cEmailWrapper\u003e getEmailsSent() {"},{"lineNumber":798,"author":{"gitId":"-"},"content":" return mockEmailSender.getEmailsSent();"},{"lineNumber":799,"author":{"gitId":"-"},"content":" }"},{"lineNumber":800,"author":{"gitId":"-"},"content":""},{"lineNumber":801,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":802,"author":{"gitId":"-"},"content":" * Verifies that the executed action results in the specified number of emails"},{"lineNumber":803,"author":{"gitId":"-"},"content":" * being sent."},{"lineNumber":804,"author":{"gitId":"-"},"content":" */"},{"lineNumber":805,"author":{"gitId":"-"},"content":" protected void verifyNumberOfEmailsSent(int emailCount) {"},{"lineNumber":806,"author":{"gitId":"-"},"content":" assertEquals(emailCount, mockEmailSender.getEmailsSent().size());"},{"lineNumber":807,"author":{"gitId":"-"},"content":" }"},{"lineNumber":808,"author":{"gitId":"-"},"content":""},{"lineNumber":809,"author":{"gitId":"-"},"content":" private Course createTestCourseOther() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":810,"author":{"gitId":"-"},"content":" if (testCourseOther \u003d\u003d null) {"},{"lineNumber":811,"author":{"gitId":"-"},"content":" testCourseOther \u003d new Course(\"test-course-other-id\", \"test course other\", Const.DEFAULT_TIME_ZONE,"},{"lineNumber":812,"author":{"gitId":"-"},"content":" \"test-institute\");"},{"lineNumber":813,"author":{"gitId":"-"},"content":" logic.createCourse(testCourseOther);"},{"lineNumber":814,"author":{"gitId":"-"},"content":" }"},{"lineNumber":815,"author":{"gitId":"-"},"content":" return testCourseOther;"},{"lineNumber":816,"author":{"gitId":"-"},"content":" }"},{"lineNumber":817,"author":{"gitId":"-"},"content":""},{"lineNumber":818,"author":{"gitId":"-"},"content":" private Instructor createTypicalInstructor(Course course, String email)"},{"lineNumber":819,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":820,"author":{"gitId":"-"},"content":" Instructor instructor \u003d logic.getInstructorForEmail(course.getId(), email);"},{"lineNumber":821,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":822,"author":{"gitId":"-"},"content":" instructor \u003d new Instructor(course, \"instructor-name\", email, true, \"display-name\","},{"lineNumber":823,"author":{"gitId":"-"},"content":" InstructorPermissionRole.INSTRUCTOR_PERMISSION_ROLE_COOWNER, new InstructorPrivileges());"},{"lineNumber":824,"author":{"gitId":"-"},"content":" logic.createInstructor(instructor);"},{"lineNumber":825,"author":{"gitId":"-"},"content":""},{"lineNumber":826,"author":{"gitId":"-"},"content":" Account account \u003d new Account(email, \"account\", email);"},{"lineNumber":827,"author":{"gitId":"-"},"content":" logic.createAccount(account);"},{"lineNumber":828,"author":{"gitId":"-"},"content":" instructor.setAccount(account);"},{"lineNumber":829,"author":{"gitId":"-"},"content":" }"},{"lineNumber":830,"author":{"gitId":"-"},"content":" return instructor;"},{"lineNumber":831,"author":{"gitId":"-"},"content":" }"},{"lineNumber":832,"author":{"gitId":"-"},"content":""},{"lineNumber":833,"author":{"gitId":"-"},"content":" private Student createTypicalStudent(Course course, String email)"},{"lineNumber":834,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":835,"author":{"gitId":"-"},"content":" Student student \u003d logic.getStudentForEmail(course.getId(), email);"},{"lineNumber":836,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":837,"author":{"gitId":"-"},"content":" student \u003d new Student(course, \"student-name\", email, \"\");"},{"lineNumber":838,"author":{"gitId":"-"},"content":" logic.createStudent(student);"},{"lineNumber":839,"author":{"gitId":"-"},"content":""},{"lineNumber":840,"author":{"gitId":"-"},"content":" Account account \u003d new Account(email, \"account\", email);"},{"lineNumber":841,"author":{"gitId":"-"},"content":" logic.createAccount(account);"},{"lineNumber":842,"author":{"gitId":"-"},"content":" student.setAccount(account);"},{"lineNumber":843,"author":{"gitId":"-"},"content":" }"},{"lineNumber":844,"author":{"gitId":"-"},"content":" return student;"},{"lineNumber":845,"author":{"gitId":"-"},"content":" }"},{"lineNumber":846,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":105,"-":741}},{"path":"src/it/java/teammates/it/ui/webapi/CreateAccountRequestActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.AfterMethod;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailType;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.ui.output.AccountRequestData;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.ui.request.AccountCreateRequest;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.CreateAccountRequestAction;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":23,"author":{"gitId":"-"},"content":" * SUT: {@link CreateAccountRequestAction}."},{"lineNumber":24,"author":{"gitId":"-"},"content":" */"},{"lineNumber":25,"author":{"gitId":"-"},"content":"public class CreateAccountRequestActionIT extends BaseActionIT\u003cCreateAccountRequestAction\u003e {"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"-"},"content":" String getActionUri() {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" return Const.ResourceURIs.ACCOUNT_REQUEST;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":33,"author":{"gitId":"-"},"content":" String getRequestMethod() {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" return POST;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":38,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":39,"author":{"gitId":"-"},"content":" protected void setUp() {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" // CreateAccountRequestAction handles its own transactions;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" // There is thus no need to setup a transaction."},{"lineNumber":42,"author":{"gitId":"-"},"content":" }"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":45,"author":{"gitId":"-"},"content":" protected void testExecute() throws Exception {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" // This is separated into different test methods."},{"lineNumber":47,"author":{"gitId":"-"},"content":" }"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":50,"author":{"gitId":"-"},"content":" void testExecute_nullEmail_throwsInvalidHttpRequestBodyException() {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":52,"author":{"gitId":"-"},"content":" request.setInstructorName(\"Paul Atreides\");"},{"lineNumber":53,"author":{"gitId":"-"},"content":" request.setInstructorInstitution(\"House Atreides\");"},{"lineNumber":54,"author":{"gitId":"-"},"content":" InvalidHttpRequestBodyException ihrbException \u003d verifyHttpRequestBodyFailure(request);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" assertEquals(\"email cannot be null\", ihrbException.getMessage());"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":59,"author":{"gitId":"-"},"content":" void testExecute_nullName_throwsInvalidHttpRequestBodyException() {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":61,"author":{"gitId":"-"},"content":" request.setInstructorEmail(\"kwisatz.haderach@atreides.org\");"},{"lineNumber":62,"author":{"gitId":"-"},"content":" request.setInstructorInstitution(\"House Atreides\");"},{"lineNumber":63,"author":{"gitId":"-"},"content":" InvalidHttpRequestBodyException ihrbException \u003d verifyHttpRequestBodyFailure(request);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" assertEquals(\"name cannot be null\", ihrbException.getMessage());"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":68,"author":{"gitId":"-"},"content":" void testExecute_nullInstitute_throwsInvalidHttpRequestBodyException() {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":70,"author":{"gitId":"-"},"content":" request.setInstructorEmail(\"kwisatz.haderach@atreides.org\");"},{"lineNumber":71,"author":{"gitId":"-"},"content":" request.setInstructorName(\"Paul Atreides\");"},{"lineNumber":72,"author":{"gitId":"-"},"content":" InvalidHttpRequestBodyException ihrbException \u003d verifyHttpRequestBodyFailure(request);"},{"lineNumber":73,"author":{"gitId":"-"},"content":" assertEquals(\"institute cannot be null\", ihrbException.getMessage());"},{"lineNumber":74,"author":{"gitId":"-"},"content":" }"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":77,"author":{"gitId":"-"},"content":" void testExecute_invalidEmail_throwsInvalidHttpRequestBodyException() {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":79,"author":{"gitId":"-"},"content":" request.setInstructorEmail(\"invalid email address\");"},{"lineNumber":80,"author":{"gitId":"-"},"content":" request.setInstructorName(\"Paul Atreides\");"},{"lineNumber":81,"author":{"gitId":"-"},"content":" request.setInstructorInstitution(\"House Atreides\");"},{"lineNumber":82,"author":{"gitId":"-"},"content":" InvalidHttpRequestBodyException ihrbException \u003d verifyHttpRequestBodyFailure(request);"},{"lineNumber":83,"author":{"gitId":"-"},"content":" String expectedMessage \u003d \"\\\"invalid email address\\\" is not acceptable to TEAMMATES as a/an email because it is not \""},{"lineNumber":84,"author":{"gitId":"-"},"content":" + \"in the correct format. An email address contains some text followed by one \u0027@\u0027 sign followed by some \""},{"lineNumber":85,"author":{"gitId":"-"},"content":" + \"more text, and should end with a top level domain address like .com. It cannot be longer than 254 \""},{"lineNumber":86,"author":{"gitId":"-"},"content":" + \"characters, cannot be empty and cannot contain spaces.\";"},{"lineNumber":87,"author":{"gitId":"-"},"content":" assertEquals(expectedMessage, ihrbException.getMessage());"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":91,"author":{"gitId":"-"},"content":" void testExecute_invalidName_throwsInvalidHttpRequestBodyException() {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":93,"author":{"gitId":"-"},"content":" request.setInstructorEmail(\"kwisatz.haderach@atreides.org\");"},{"lineNumber":94,"author":{"gitId":"-"},"content":" request.setInstructorName(\"Pau| Atreides\");"},{"lineNumber":95,"author":{"gitId":"-"},"content":" request.setInstructorInstitution(\"House Atreides\");"},{"lineNumber":96,"author":{"gitId":"-"},"content":" InvalidHttpRequestBodyException ihrbException \u003d verifyHttpRequestBodyFailure(request);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" String expectedMessage \u003d \"\\\"Pau| Atreides\\\" is not acceptable to TEAMMATES as a/an person name because it contains \""},{"lineNumber":98,"author":{"gitId":"-"},"content":" + \"invalid characters. A/An person name must start with an alphanumeric character, and cannot contain any \""},{"lineNumber":99,"author":{"gitId":"-"},"content":" + \"vertical bar (|) or percent sign (%).\";"},{"lineNumber":100,"author":{"gitId":"-"},"content":" assertEquals(expectedMessage, ihrbException.getMessage());"},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":104,"author":{"gitId":"-"},"content":" void testExecute_invalidInstitute_throwsInvalidHttpRequestBodyException() {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":106,"author":{"gitId":"-"},"content":" request.setInstructorEmail(\"kwisatz.haderach@atreides.org\");"},{"lineNumber":107,"author":{"gitId":"-"},"content":" request.setInstructorName(\"Paul Atreides\");"},{"lineNumber":108,"author":{"gitId":"-"},"content":" request.setInstructorInstitution(\"House Atreide%\");"},{"lineNumber":109,"author":{"gitId":"-"},"content":" InvalidHttpRequestBodyException ihrbException \u003d verifyHttpRequestBodyFailure(request);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" String expectedMessage \u003d \"\\\"House Atreide%\\\" is not acceptable to TEAMMATES as a/an institute name because it \""},{"lineNumber":111,"author":{"gitId":"-"},"content":" + \"contains invalid characters. A/An institute name must start with an alphanumeric character, and cannot \""},{"lineNumber":112,"author":{"gitId":"-"},"content":" + \"contain any vertical bar (|) or percent sign (%).\";"},{"lineNumber":113,"author":{"gitId":"-"},"content":" assertEquals(expectedMessage, ihrbException.getMessage());"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":117,"author":{"gitId":"-"},"content":" void testExecute_typicalCase_createsSuccessfully() {"},{"lineNumber":118,"author":{"gitId":"-"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":119,"author":{"gitId":"-"},"content":" request.setInstructorEmail(\"kwisatz.haderach@atreides.org\");"},{"lineNumber":120,"author":{"gitId":"-"},"content":" request.setInstructorName(\"Paul Atreides\");"},{"lineNumber":121,"author":{"gitId":"-"},"content":" request.setInstructorInstitution(\"House Atreides\");"},{"lineNumber":122,"author":{"gitId":"-"},"content":" request.setInstructorComments(\"My road leads into the desert. I can see it.\");"},{"lineNumber":123,"author":{"gitId":"-"},"content":" CreateAccountRequestAction action \u003d getAction(request);"},{"lineNumber":124,"author":{"gitId":"-"},"content":" JsonResult result \u003d getJsonResult(action);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" AccountRequestData output \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":126,"author":{"gitId":"-"},"content":" assertEquals(\"kwisatz.haderach@atreides.org\", output.getEmail());"},{"lineNumber":127,"author":{"gitId":"-"},"content":" assertEquals(\"Paul Atreides\", output.getName());"},{"lineNumber":128,"author":{"gitId":"-"},"content":" assertEquals(\"House Atreides\", output.getInstitute());"},{"lineNumber":129,"author":{"gitId":"-"},"content":" assertEquals(AccountRequestStatus.PENDING, output.getStatus());"},{"lineNumber":130,"author":{"gitId":"-"},"content":" assertEquals(\"My road leads into the desert. I can see it.\", output.getComments());"},{"lineNumber":131,"author":{"gitId":"-"},"content":" assertNull(output.getRegisteredAt());"},{"lineNumber":132,"author":{"gitId":"-"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":133,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d logic.getAccountRequestByRegistrationKey(output.getRegistrationKey());"},{"lineNumber":134,"author":{"gitId":"-"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":135,"author":{"gitId":"-"},"content":" assertEquals(\"kwisatz.haderach@atreides.org\", accountRequest.getEmail());"},{"lineNumber":136,"author":{"gitId":"-"},"content":" assertEquals(\"Paul Atreides\", accountRequest.getName());"},{"lineNumber":137,"author":{"gitId":"-"},"content":" assertEquals(\"House Atreides\", accountRequest.getInstitute());"},{"lineNumber":138,"author":{"gitId":"-"},"content":" assertEquals(AccountRequestStatus.PENDING, accountRequest.getStatus());"},{"lineNumber":139,"author":{"gitId":"-"},"content":" assertEquals(\"My road leads into the desert. I can see it.\", accountRequest.getComments());"},{"lineNumber":140,"author":{"gitId":"-"},"content":" assertNull(accountRequest.getRegisteredAt());"},{"lineNumber":141,"author":{"gitId":"-"},"content":" verifySpecifiedTasksAdded(Const.TaskQueue.SEARCH_INDEXING_QUEUE_NAME, 1);"},{"lineNumber":142,"author":{"gitId":"xenosf"},"content":" verifyNumberOfEmailsSent(2);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" EmailWrapper sentAdminAlertEmail \u003d mockEmailSender.getEmailsSent().get(0);"},{"lineNumber":144,"author":{"gitId":"xenosf"},"content":" EmailWrapper sentAcknowledgementEmail \u003d mockEmailSender.getEmailsSent().get(1);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" assertEquals(EmailType.NEW_ACCOUNT_REQUEST_ADMIN_ALERT, sentAdminAlertEmail.getType());"},{"lineNumber":146,"author":{"gitId":"xenosf"},"content":" assertEquals(EmailType.NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT, sentAcknowledgementEmail.getType());"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":150,"author":{"gitId":"-"},"content":" void testExecute_leadingAndTrailingSpacesAndNullComments_createsSuccessfully() {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":152,"author":{"gitId":"-"},"content":" request.setInstructorEmail(\" kwisatz.haderach@atreides.org \");"},{"lineNumber":153,"author":{"gitId":"-"},"content":" request.setInstructorName(\" Paul Atreides \");"},{"lineNumber":154,"author":{"gitId":"-"},"content":" request.setInstructorInstitution(\" House Atreides \");"},{"lineNumber":155,"author":{"gitId":"-"},"content":" CreateAccountRequestAction action \u003d getAction(request);"},{"lineNumber":156,"author":{"gitId":"-"},"content":" JsonResult result \u003d getJsonResult(action);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" AccountRequestData output \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":158,"author":{"gitId":"-"},"content":" assertEquals(\"kwisatz.haderach@atreides.org\", output.getEmail());"},{"lineNumber":159,"author":{"gitId":"-"},"content":" assertEquals(\"Paul Atreides\", output.getName());"},{"lineNumber":160,"author":{"gitId":"-"},"content":" assertEquals(\"House Atreides\", output.getInstitute());"},{"lineNumber":161,"author":{"gitId":"-"},"content":" assertEquals(AccountRequestStatus.PENDING, output.getStatus());"},{"lineNumber":162,"author":{"gitId":"-"},"content":" assertNull(output.getComments());"},{"lineNumber":163,"author":{"gitId":"-"},"content":" assertNull(output.getRegisteredAt());"},{"lineNumber":164,"author":{"gitId":"-"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":165,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d logic.getAccountRequestByRegistrationKey(output.getRegistrationKey());"},{"lineNumber":166,"author":{"gitId":"-"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":167,"author":{"gitId":"-"},"content":" assertEquals(\"kwisatz.haderach@atreides.org\", accountRequest.getEmail());"},{"lineNumber":168,"author":{"gitId":"-"},"content":" assertEquals(\"Paul Atreides\", accountRequest.getName());"},{"lineNumber":169,"author":{"gitId":"-"},"content":" assertEquals(\"House Atreides\", accountRequest.getInstitute());"},{"lineNumber":170,"author":{"gitId":"-"},"content":" assertEquals(AccountRequestStatus.PENDING, accountRequest.getStatus());"},{"lineNumber":171,"author":{"gitId":"-"},"content":" assertNull(accountRequest.getComments());"},{"lineNumber":172,"author":{"gitId":"-"},"content":" assertNull(accountRequest.getRegisteredAt());"},{"lineNumber":173,"author":{"gitId":"-"},"content":" verifySpecifiedTasksAdded(Const.TaskQueue.SEARCH_INDEXING_QUEUE_NAME, 1);"},{"lineNumber":174,"author":{"gitId":"xenosf"},"content":" verifyNumberOfEmailsSent(2);"},{"lineNumber":175,"author":{"gitId":"-"},"content":" EmailWrapper sentAdminAlertEmail \u003d mockEmailSender.getEmailsSent().get(0);"},{"lineNumber":176,"author":{"gitId":"xenosf"},"content":" EmailWrapper sentAcknowledgementEmail \u003d mockEmailSender.getEmailsSent().get(1);"},{"lineNumber":177,"author":{"gitId":"-"},"content":" assertEquals(EmailType.NEW_ACCOUNT_REQUEST_ADMIN_ALERT, sentAdminAlertEmail.getType());"},{"lineNumber":178,"author":{"gitId":"xenosf"},"content":" assertEquals(EmailType.NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT, sentAcknowledgementEmail.getType());"},{"lineNumber":179,"author":{"gitId":"-"},"content":" }"},{"lineNumber":180,"author":{"gitId":"-"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":182,"author":{"gitId":"-"},"content":" void testExecute_accountRequestWithSameEmailAddressAndInstituteAlreadyExists_createsSuccessfully()"},{"lineNumber":183,"author":{"gitId":"-"},"content":" throws InvalidParametersException {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":185,"author":{"gitId":"-"},"content":" AccountRequest existingAccountRequest \u003d logic.createAccountRequest(\"Paul Atreides\","},{"lineNumber":186,"author":{"gitId":"-"},"content":" \"kwisatz.haderach@atreides.org\","},{"lineNumber":187,"author":{"gitId":"-"},"content":" \"House Atreides\", AccountRequestStatus.PENDING, \"My road leads into the desert. I can see it.\");"},{"lineNumber":188,"author":{"gitId":"-"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":189,"author":{"gitId":"-"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":190,"author":{"gitId":"-"},"content":" request.setInstructorEmail(\"kwisatz.haderach@atreides.org\");"},{"lineNumber":191,"author":{"gitId":"-"},"content":" request.setInstructorName(\"Paul Atreides\");"},{"lineNumber":192,"author":{"gitId":"-"},"content":" request.setInstructorInstitution(\"House Atreides\");"},{"lineNumber":193,"author":{"gitId":"-"},"content":" request.setInstructorComments(\"My road leads into the desert. I can see it.\");"},{"lineNumber":194,"author":{"gitId":"-"},"content":" CreateAccountRequestAction action \u003d getAction(request);"},{"lineNumber":195,"author":{"gitId":"-"},"content":" JsonResult result \u003d getJsonResult(action);"},{"lineNumber":196,"author":{"gitId":"-"},"content":" AccountRequestData output \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":197,"author":{"gitId":"-"},"content":" assertEquals(\"kwisatz.haderach@atreides.org\", output.getEmail());"},{"lineNumber":198,"author":{"gitId":"-"},"content":" assertEquals(\"Paul Atreides\", output.getName());"},{"lineNumber":199,"author":{"gitId":"-"},"content":" assertEquals(\"House Atreides\", output.getInstitute());"},{"lineNumber":200,"author":{"gitId":"-"},"content":" assertEquals(AccountRequestStatus.PENDING, output.getStatus());"},{"lineNumber":201,"author":{"gitId":"-"},"content":" assertEquals(\"My road leads into the desert. I can see it.\", output.getComments());"},{"lineNumber":202,"author":{"gitId":"-"},"content":" assertNull(output.getRegisteredAt());"},{"lineNumber":203,"author":{"gitId":"-"},"content":" assertNotEquals(output.getRegistrationKey(), existingAccountRequest.getRegistrationKey());"},{"lineNumber":204,"author":{"gitId":"-"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":205,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d logic.getAccountRequestByRegistrationKey(output.getRegistrationKey());"},{"lineNumber":206,"author":{"gitId":"-"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":207,"author":{"gitId":"-"},"content":" assertEquals(\"kwisatz.haderach@atreides.org\", accountRequest.getEmail());"},{"lineNumber":208,"author":{"gitId":"-"},"content":" assertEquals(\"Paul Atreides\", accountRequest.getName());"},{"lineNumber":209,"author":{"gitId":"-"},"content":" assertEquals(\"House Atreides\", accountRequest.getInstitute());"},{"lineNumber":210,"author":{"gitId":"-"},"content":" assertEquals(AccountRequestStatus.PENDING, accountRequest.getStatus());"},{"lineNumber":211,"author":{"gitId":"-"},"content":" assertEquals(\"My road leads into the desert. I can see it.\", accountRequest.getComments());"},{"lineNumber":212,"author":{"gitId":"-"},"content":" assertNull(accountRequest.getRegisteredAt());"},{"lineNumber":213,"author":{"gitId":"-"},"content":" verifySpecifiedTasksAdded(Const.TaskQueue.SEARCH_INDEXING_QUEUE_NAME, 1);"},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" verifyNumberOfEmailsSent(2);"},{"lineNumber":215,"author":{"gitId":"-"},"content":" EmailWrapper sentAdminAlertEmail \u003d mockEmailSender.getEmailsSent().get(0);"},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" EmailWrapper sentAcknowledgementEmail \u003d mockEmailSender.getEmailsSent().get(1);"},{"lineNumber":217,"author":{"gitId":"-"},"content":" assertEquals(EmailType.NEW_ACCOUNT_REQUEST_ADMIN_ALERT, sentAdminAlertEmail.getType());"},{"lineNumber":218,"author":{"gitId":"xenosf"},"content":" assertEquals(EmailType.NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT, sentAcknowledgementEmail.getType());"},{"lineNumber":219,"author":{"gitId":"-"},"content":" }"},{"lineNumber":220,"author":{"gitId":"-"},"content":""},{"lineNumber":221,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":222,"author":{"gitId":"xenosf"},"content":" void testExecute_typicalCaseAsAdmin_noEmailsSent() {"},{"lineNumber":223,"author":{"gitId":"xenosf"},"content":" loginAsAdminWithTransaction();"},{"lineNumber":224,"author":{"gitId":"xenosf"},"content":" AccountCreateRequest request \u003d new AccountCreateRequest();"},{"lineNumber":225,"author":{"gitId":"xenosf"},"content":" request.setInstructorEmail(\"kwisatz.haderach@atreides.org\");"},{"lineNumber":226,"author":{"gitId":"xenosf"},"content":" request.setInstructorName(\"Paul Atreides\");"},{"lineNumber":227,"author":{"gitId":"xenosf"},"content":" request.setInstructorInstitution(\"House Atreides\");"},{"lineNumber":228,"author":{"gitId":"xenosf"},"content":" request.setInstructorComments(\"My road leads into the desert. I can see it.\");"},{"lineNumber":229,"author":{"gitId":"xenosf"},"content":" CreateAccountRequestAction action \u003d getAction(request);"},{"lineNumber":230,"author":{"gitId":"xenosf"},"content":" JsonResult result \u003d getJsonResult(action);"},{"lineNumber":231,"author":{"gitId":"xenosf"},"content":" AccountRequestData output \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":232,"author":{"gitId":"xenosf"},"content":" assertNull(output.getRegisteredAt());"},{"lineNumber":233,"author":{"gitId":"xenosf"},"content":" verifyNoEmailsSent();"},{"lineNumber":234,"author":{"gitId":"xenosf"},"content":" logoutUser();"},{"lineNumber":235,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":236,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":237,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":238,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":239,"author":{"gitId":"-"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":240,"author":{"gitId":"-"},"content":" verifyAccessibleWithoutLogin();"},{"lineNumber":241,"author":{"gitId":"-"},"content":" }"},{"lineNumber":242,"author":{"gitId":"-"},"content":""},{"lineNumber":243,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":244,"author":{"gitId":"domoberzin"},"content":" @AfterMethod"},{"lineNumber":245,"author":{"gitId":"domoberzin"},"content":" protected void tearDown() {"},{"lineNumber":246,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":247,"author":{"gitId":"domoberzin"},"content":" List\u003cAccountRequest\u003e accountRequests \u003d logic.getPendingAccountRequests();"},{"lineNumber":248,"author":{"gitId":"domoberzin"},"content":" for (AccountRequest ar : accountRequests) {"},{"lineNumber":249,"author":{"gitId":"dishenggg"},"content":" logic.deleteAccountRequest(ar.getId());"},{"lineNumber":250,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":251,"author":{"gitId":"domoberzin"},"content":" accountRequests \u003d logic.getPendingAccountRequests();"},{"lineNumber":252,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":253,"author":{"gitId":"domoberzin"},"content":" assert accountRequests.isEmpty();"},{"lineNumber":254,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":255,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":14,"xenosf":25,"dishenggg":1,"-":215}},{"path":"src/it/java/teammates/it/ui/webapi/CreateFeedbackSessionLogActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.output.MessageOutput;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.webapi.CreateFeedbackSessionLogAction;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link CreateFeedbackSessionLogAction}."},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"public class CreateFeedbackSessionLogActionIT extends BaseActionIT\u003cCreateFeedbackSessionLogAction\u003e {"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" protected String getActionUri() {"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" return Const.ResourceURIs.SESSION_LOGS;"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" protected String getRequestMethod() {"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" return POST;"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" protected void testExecute() throws Exception {"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" Course course1 \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" String courseId1 \u003d course1.getId();"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" FeedbackSession fs1 \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" FeedbackSession fs2 \u003d typicalBundle.feedbackSessions.get(\"session2InTypicalCourse\");"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" Student student2 \u003d typicalBundle.students.get(\"student2InCourse1\");"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" Student student3 \u003d typicalBundle.students.get(\"student1InCourse3\");"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: not enough parameters\");"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure(Const.ParamsNames.COURSE_ID, courseId1);"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure("},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fs1.getName()"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" );"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure("},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fs1.getName(),"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail()"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" );"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure("},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fs1.getName(),"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail()"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" );"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure("},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fs2.getId().toString(),"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student2.getId().toString()"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" );"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: invalid log type\");"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" String[] paramsInvalid \u003d {"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fs1.getName(),"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, \"invalid log type\","},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fs1.getId().toString(),"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student1.getId().toString(),"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure(paramsInvalid);"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: typical access\");"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" String[] paramsSuccessfulAccess \u003d {"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fs1.getName(),"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fs1.getId().toString(),"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student1.getId().toString(),"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":" JsonResult response \u003d getJsonResult(getAction(paramsSuccessfulAccess));"},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" MessageOutput output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: typical submission\");"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":" String[] paramsSuccessfulSubmission \u003d {"},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fs2.getName(),"},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_EMAIL, student2.getEmail(),"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fs2.getId().toString(),"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student2.getId().toString(),"},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" response \u003d getJsonResult(getAction(paramsSuccessfulSubmission));"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":" output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: should create even for invalid parameters\");"},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" String[] paramsNonExistentCourseId \u003d {"},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, \"non-existent-course-id\","},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fs1.getName(),"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fs1.getId().toString(),"},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student1.getId().toString(),"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":" response \u003d getJsonResult(getAction(paramsNonExistentCourseId));"},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: should create even for invalid parameters\");"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" String[] paramsNonExistentFsName \u003d {"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, \"non-existent-feedback-session-name\","},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, UUID.randomUUID().toString(),"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student1.getId().toString(),"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" response \u003d getJsonResult(getAction(paramsNonExistentFsName));"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":" String[] paramsNonExistentStudentEmail \u003d {"},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fs1.getName(),"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_EMAIL, \"non-existent-student@email.com\","},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fs1.getId().toString(),"},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, UUID.randomUUID().toString(),"},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":" response \u003d getJsonResult(getAction(paramsNonExistentStudentEmail));"},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":" output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":141,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: should create even when student cannot access feedback session in course\");"},{"lineNumber":142,"author":{"gitId":"dishenggg"},"content":" String[] paramsWithoutAccess \u003d {"},{"lineNumber":143,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":144,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fs1.getName(),"},{"lineNumber":145,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":146,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_EMAIL, student3.getEmail(),"},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fs1.getId().toString(),"},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student3.getId().toString(),"},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":" response \u003d getJsonResult(getAction(paramsWithoutAccess));"},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":" output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":153,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":158,"author":{"gitId":"dishenggg"},"content":" verifyAnyUserCanAccess();"},{"lineNumber":159,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":160}},{"path":"src/it/java/teammates/it/ui/webapi/CreateInstructorActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"mingyuanc"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":3,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":4,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.Test;"},{"lineNumber":5,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":6,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.util.Const;"},{"lineNumber":7,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":8,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":9,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":10,"author":{"gitId":"mingyuanc"},"content":"import teammates.ui.output.InstructorData;"},{"lineNumber":11,"author":{"gitId":"mingyuanc"},"content":"import teammates.ui.request.InstructorCreateRequest;"},{"lineNumber":12,"author":{"gitId":"mingyuanc"},"content":"import teammates.ui.webapi.CreateInstructorAction;"},{"lineNumber":13,"author":{"gitId":"mingyuanc"},"content":"import teammates.ui.webapi.InvalidOperationException;"},{"lineNumber":14,"author":{"gitId":"mingyuanc"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":15,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":16,"author":{"gitId":"mingyuanc"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"mingyuanc"},"content":" * SUT: {@link CreateInstructorAction}."},{"lineNumber":18,"author":{"gitId":"mingyuanc"},"content":" */"},{"lineNumber":19,"author":{"gitId":"mingyuanc"},"content":"public class CreateInstructorActionIT extends BaseActionIT\u003cCreateInstructorAction\u003e {"},{"lineNumber":20,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":21,"author":{"gitId":"mingyuanc"},"content":" @BeforeMethod"},{"lineNumber":22,"author":{"gitId":"mingyuanc"},"content":" protected void setUp() throws Exception {"},{"lineNumber":23,"author":{"gitId":"mingyuanc"},"content":" super.setUp();"},{"lineNumber":24,"author":{"gitId":"mingyuanc"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":25,"author":{"gitId":"mingyuanc"},"content":" HibernateUtil.flushSession();"},{"lineNumber":26,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":27,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":28,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":29,"author":{"gitId":"mingyuanc"},"content":" protected String getActionUri() {"},{"lineNumber":30,"author":{"gitId":"mingyuanc"},"content":" return Const.ResourceURIs.INSTRUCTOR;"},{"lineNumber":31,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":32,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":33,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":34,"author":{"gitId":"mingyuanc"},"content":" protected String getRequestMethod() {"},{"lineNumber":35,"author":{"gitId":"mingyuanc"},"content":" return POST;"},{"lineNumber":36,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":37,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":38,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":39,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":40,"author":{"gitId":"mingyuanc"},"content":" protected void testExecute() {"},{"lineNumber":41,"author":{"gitId":"mingyuanc"},"content":" // see test cases below"},{"lineNumber":42,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":43,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":44,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":45,"author":{"gitId":"mingyuanc"},"content":" protected void testExecute_typicalCase_shouldPass() throws Exception {"},{"lineNumber":46,"author":{"gitId":"mingyuanc"},"content":" loginAsAdmin();"},{"lineNumber":47,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":48,"author":{"gitId":"mingyuanc"},"content":" Course course1 \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":49,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":50,"author":{"gitId":"mingyuanc"},"content":" String[] params \u003d {"},{"lineNumber":51,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.COURSE_ID, course1.getId(),"},{"lineNumber":52,"author":{"gitId":"mingyuanc"},"content":" };"},{"lineNumber":53,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":54,"author":{"gitId":"mingyuanc"},"content":" InstructorCreateRequest instructorCreateRequest \u003d new InstructorCreateRequest("},{"lineNumber":55,"author":{"gitId":"mingyuanc"},"content":" \"00000000-0000-4000-8000-000000000006\", \"newInstructorName\","},{"lineNumber":56,"author":{"gitId":"mingyuanc"},"content":" \"newInstructorEmail@mail.com\", Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_COOWNER,"},{"lineNumber":57,"author":{"gitId":"mingyuanc"},"content":" \"instructorDisplayName\", false);"},{"lineNumber":58,"author":{"gitId":"mingyuanc"},"content":" CreateInstructorAction action \u003d getAction(instructorCreateRequest, params);"},{"lineNumber":59,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":60,"author":{"gitId":"mingyuanc"},"content":" JsonResult response \u003d getJsonResult(action);"},{"lineNumber":61,"author":{"gitId":"mingyuanc"},"content":" InstructorData instructorData \u003d (InstructorData) response.getOutput();"},{"lineNumber":62,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":63,"author":{"gitId":"mingyuanc"},"content":" Instructor createdInstructor \u003d logic.getInstructorForEmail(course1.getId(), instructorCreateRequest.getEmail());"},{"lineNumber":64,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":65,"author":{"gitId":"mingyuanc"},"content":" assertEquals(createdInstructor.getName(), instructorCreateRequest.getName());"},{"lineNumber":66,"author":{"gitId":"mingyuanc"},"content":" assertEquals(createdInstructor.getEmail(), instructorCreateRequest.getEmail());"},{"lineNumber":67,"author":{"gitId":"mingyuanc"},"content":" assertEquals(createdInstructor.getName(), instructorData.getName());"},{"lineNumber":68,"author":{"gitId":"mingyuanc"},"content":" assertEquals(createdInstructor.getEmail(), instructorData.getEmail());"},{"lineNumber":69,"author":{"gitId":"mingyuanc"},"content":" assertFalse(createdInstructor.isDisplayedToStudents());"},{"lineNumber":70,"author":{"gitId":"mingyuanc"},"content":" assertTrue(createdInstructor.isAllowedForPrivilege(Const.InstructorPermissions.CAN_MODIFY_COURSE));"},{"lineNumber":71,"author":{"gitId":"mingyuanc"},"content":" assertTrue(createdInstructor.isAllowedForPrivilege(Const.InstructorPermissions.CAN_MODIFY_INSTRUCTOR));"},{"lineNumber":72,"author":{"gitId":"mingyuanc"},"content":" assertTrue(createdInstructor.isAllowedForPrivilege(Const.InstructorPermissions.CAN_MODIFY_SESSION));"},{"lineNumber":73,"author":{"gitId":"mingyuanc"},"content":" assertTrue(createdInstructor.isAllowedForPrivilege(Const.InstructorPermissions.CAN_MODIFY_STUDENT));"},{"lineNumber":74,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":75,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":76,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":77,"author":{"gitId":"mingyuanc"},"content":" protected void testExecute_uniqueEmailClash_shouldFail() throws Exception {"},{"lineNumber":78,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":79,"author":{"gitId":"mingyuanc"},"content":" Instructor instructor1OfCourse1 \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":80,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":81,"author":{"gitId":"mingyuanc"},"content":" loginAsAdmin();"},{"lineNumber":82,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":83,"author":{"gitId":"mingyuanc"},"content":" String[] params \u003d {"},{"lineNumber":84,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.COURSE_ID, instructor1OfCourse1.getCourseId(),"},{"lineNumber":85,"author":{"gitId":"mingyuanc"},"content":" };"},{"lineNumber":86,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":87,"author":{"gitId":"mingyuanc"},"content":" InstructorCreateRequest instructorCreateRequest \u003d new InstructorCreateRequest("},{"lineNumber":88,"author":{"gitId":"mingyuanc"},"content":" instructor1OfCourse1.getCourseId(), \"instructor3ofCourse1\","},{"lineNumber":89,"author":{"gitId":"mingyuanc"},"content":" instructor1OfCourse1.getEmail(), Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_TUTOR,"},{"lineNumber":90,"author":{"gitId":"mingyuanc"},"content":" \"instructor3ofCourse1\", false);"},{"lineNumber":91,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":92,"author":{"gitId":"mingyuanc"},"content":" CreateInstructorAction action \u003d getAction(instructorCreateRequest, params);"},{"lineNumber":93,"author":{"gitId":"mingyuanc"},"content":" assertThrows(InvalidOperationException.class, action::execute);"},{"lineNumber":94,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":95,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":96,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":97,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":98,"author":{"gitId":"mingyuanc"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":99,"author":{"gitId":"mingyuanc"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":100,"author":{"gitId":"mingyuanc"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor2OfCourse1\");"},{"lineNumber":101,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":102,"author":{"gitId":"mingyuanc"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":103,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.COURSE_ID, instructor.getCourseId(),"},{"lineNumber":104,"author":{"gitId":"mingyuanc"},"content":" };"},{"lineNumber":105,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":106,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"Admins can access\");"},{"lineNumber":107,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":108,"author":{"gitId":"mingyuanc"},"content":" verifyAccessibleForAdmin(submissionParams);"},{"lineNumber":109,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":110,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"only instructors of the same course can access\");"},{"lineNumber":111,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":112,"author":{"gitId":"mingyuanc"},"content":" verifyOnlyInstructorsOfTheSameCourseWithCorrectCoursePrivilegeCanAccess(course,"},{"lineNumber":113,"author":{"gitId":"mingyuanc"},"content":" Const.InstructorPermissions.CAN_MODIFY_INSTRUCTOR, submissionParams);"},{"lineNumber":114,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"instructors of other courses cannot access\");"},{"lineNumber":115,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":116,"author":{"gitId":"mingyuanc"},"content":" verifyInaccessibleForInstructorsOfOtherCourses(course, submissionParams);"},{"lineNumber":117,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":118,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":119,"author":{"gitId":"mingyuanc"},"content":"}"}],"authorContributionMap":{"mingyuanc":119}},{"path":"src/it/java/teammates/it/ui/webapi/DeleteStudentsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.DeleteStudentsAction;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * SUT: {@link DeleteStudentsAction}."},{"lineNumber":17,"author":{"gitId":"-"},"content":" */"},{"lineNumber":18,"author":{"gitId":"-"},"content":"public class DeleteStudentsActionIT extends BaseActionIT\u003cDeleteStudentsAction\u003e {"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":21,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":22,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":23,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":24,"author":{"gitId":"-"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":25,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":26,"author":{"gitId":"-"},"content":" }"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":29,"author":{"gitId":"-"},"content":" String getActionUri() {"},{"lineNumber":30,"author":{"gitId":"-"},"content":" return Const.ResourceURIs.STUDENTS;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" }"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":34,"author":{"gitId":"-"},"content":" String getRequestMethod() {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" return DELETE;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" }"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":39,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":40,"author":{"gitId":"-"},"content":" protected void testExecute() throws Exception {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":42,"author":{"gitId":"-"},"content":" String courseId \u003d instructor.getCourseId();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" // TODO Remove limit after migration completes"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" int deleteLimit \u003d 4;"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case delete a limited number of students\");"},{"lineNumber":47,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e studentsToDelete \u003d logic.getStudentsForCourse(courseId);"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"marquestye"},"content":" assertEquals(5, studentsToDelete.size());"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" String[] params \u003d new String[] {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" Const.ParamsNames.LIMIT, String.valueOf(deleteLimit),"},{"lineNumber":56,"author":{"gitId":"-"},"content":" };"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" DeleteStudentsAction deleteStudentsAction \u003d getAction(params);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" getJsonResult(deleteStudentsAction);"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" for (Student student : studentsToDelete) {"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" assertNull(logic.getStudentByRegistrationKey(student.getRegKey()));"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" ______TS(\"Random course given, fails silently\");"},{"lineNumber":66,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, \"non-existent-course-id\","},{"lineNumber":68,"author":{"gitId":"-"},"content":" Const.ParamsNames.LIMIT, String.valueOf(deleteLimit),"},{"lineNumber":69,"author":{"gitId":"-"},"content":" };"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" deleteStudentsAction \u003d getAction(params);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" getJsonResult(deleteStudentsAction);"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" ______TS(\"Invalid params\");"},{"lineNumber":75,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure();"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":79,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":80,"author":{"gitId":"-"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":81,"author":{"gitId":"-"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" String[] params \u003d new String[] {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":85,"author":{"gitId":"-"},"content":" };"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" verifyOnlyInstructorsOfTheSameCourseWithCorrectCoursePrivilegeCanAccess("},{"lineNumber":88,"author":{"gitId":"-"},"content":" course, Const.InstructorPermissions.CAN_MODIFY_STUDENT, params);"},{"lineNumber":89,"author":{"gitId":"-"},"content":" }"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":1,"dishenggg":2,"-":88}},{"path":"src/it/java/teammates/it/ui/webapi/EnrollStudentsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import java.util.Arrays;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.Test;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.Const;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.output.EnrollStudentsData;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.request.StudentsEnrollRequest;"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.EnrollStudentsAction;"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.InvalidOperationException;"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" * SUT: {@link EnrollStudentsAction}."},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":"public class EnrollStudentsActionIT extends BaseActionIT\u003cEnrollStudentsAction\u003e {"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" @BeforeMethod"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" protected void setUp() throws Exception {"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" super.setUp();"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.flushSession();"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" protected String getActionUri() {"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" return Const.ResourceURIs.STUDENTS;"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" protected String getRequestMethod() {"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" return PUT;"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" private StudentsEnrollRequest prepareRequest(List\u003cStudent\u003e students) {"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" List\u003cStudentsEnrollRequest.StudentEnrollRequest\u003e studentEnrollRequests \u003d new ArrayList\u003c\u003e();"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" students.forEach(student -\u003e {"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" studentEnrollRequests.add(new StudentsEnrollRequest.StudentEnrollRequest(student.getName(),"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" student.getEmail(), student.getTeam().getName(), student.getSection().getName(), student.getComments()));"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" return new StudentsEnrollRequest(studentEnrollRequests);"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" public void testExecute() throws Exception {"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d typicalBundle.students.get(\"student1InCourse1\").getCourseId();"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" Course course \u003d logic.getCourse(courseId);"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" Section section \u003d logic.getSection(courseId, \"Section 1\");"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":" Team team \u003d logic.getTeamOrCreate(section, \"Team 1\");"},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" Student newStudent \u003d new Student(course, \"Test Student\", \"test@email.com\", \"Test Comment\", team);"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" String[] params \u003d new String[] {"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e students \u003d new ArrayList\u003c\u003e(logic.getStudentsForCourse(courseId));"},{"lineNumber":76,"author":{"gitId":"marquestye"},"content":" assertEquals(5, students.size());"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Typical Success Case For Enrolling a Student\");"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" StudentsEnrollRequest request \u003d prepareRequest(Arrays.asList(newStudent));"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" EnrollStudentsAction enrollStudentsAction \u003d getAction(request, params);"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" JsonResult res \u003d getJsonResult(enrollStudentsAction);"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" EnrollStudentsData data \u003d (EnrollStudentsData) res.getOutput();"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" assertEquals(1, data.getStudentsData().getStudents().size());"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e studentsInCourse \u003d logic.getStudentsForCourse(courseId);"},{"lineNumber":86,"author":{"gitId":"marquestye"},"content":" assertEquals(6, studentsInCourse.size());"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Fail to enroll due to duplicate team name across sections\");"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" String expectedMessage \u003d \"Team \\\"%s\\\" is detected in both Section \\\"%s\\\" and Section \\\"%s\\\".\""},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" + \" Please use different team names in different sections.\";"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" Section newSection \u003d logic.getSection(courseId, \"Section 3\");"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":" Team newTeam \u003d new Team(newSection, \"Team 1\");"},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":" newStudent \u003d new Student(course, \"Test Student\", \"test@email.com\", \"Test Comment\", newTeam);"},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" Student secondStudent \u003d new Student(course, \"Test Student 2\", \"test2@email.com\", \"Test Comment\","},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" team);"},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":" StudentsEnrollRequest req \u003d prepareRequest(Arrays.asList(secondStudent, newStudent));"},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":" InvalidOperationException exception \u003d verifyInvalidOperation(req, params);"},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" assertEquals(String.format(expectedMessage, \"Team 1\", \"Section 3\", \"Section 1\"), exception.getMessage());"},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Typical Success Case For Changing Details (except email) of a Student\");"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":" Section section3 \u003d logic.getSection(courseId, \"Section 3\");"},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" Team team3 \u003d logic.getTeamOrCreate(section3, \"Team 3\");"},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" Student changedTeam \u003d new Student(course, \"Student 1\", \"student1@teammates.tmt\", \"Test Comment\", team3);"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" request \u003d prepareRequest(Arrays.asList(changedTeam));"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" enrollStudentsAction \u003d getAction(request, params);"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" res \u003d getJsonResult(enrollStudentsAction);"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" data \u003d (EnrollStudentsData) res.getOutput();"},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" assertEquals(1, data.getStudentsData().getStudents().size());"},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" studentsInCourse \u003d logic.getStudentsForCourse(courseId);"},{"lineNumber":114,"author":{"gitId":"marquestye"},"content":" assertEquals(6, studentsInCourse.size());"},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" // Verify that changes have cascaded to feedback responses"},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":" String giverEmail \u003d \"student1@teammates.tmt\";"},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackResponse\u003e responsesFromUser \u003d"},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" logic.getFeedbackResponsesFromGiverForCourse(courseId, giverEmail);"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" for (FeedbackResponse response : responsesFromUser) {"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":" assertEquals(logic.getSection(courseId, \"Section 3\"), response.getGiverSection());"},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackResponse\u003e responsesToUser \u003d"},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" logic.getFeedbackResponsesForRecipientForCourse(courseId, giverEmail);"},{"lineNumber":128,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":129,"author":{"gitId":"domoberzin"},"content":" for (FeedbackResponse response : responsesToUser) {"},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":" assertEquals(logic.getSection(courseId, \"Section 3\"), response.getRecipientSection());"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackResponseComment\u003e commentsFromUser \u003d logic.getFeedbackResponseCommentsForResponse(response.getId());"},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":" for (FeedbackResponseComment comment : commentsFromUser) {"},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" if (comment.getGiver().equals(giverEmail)) {"},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" assertEquals(logic.getSection(courseId, \"Section 3\"), comment.getGiverSection());"},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":137,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":140,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":145,"author":{"gitId":"domoberzin"},"content":" String[] params \u003d new String[] {"},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":147,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":148,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":149,"author":{"gitId":"domoberzin"},"content":" verifyOnlyInstructorsOfTheSameCourseWithCorrectCoursePrivilegeCanAccess("},{"lineNumber":150,"author":{"gitId":"domoberzin"},"content":" course, Const.InstructorPermissions.CAN_MODIFY_STUDENT, params);"},{"lineNumber":151,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":152,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":149,"marquestye":3}},{"path":"src/it/java/teammates/it/ui/webapi/FeedbackSessionClosingRemindersActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Duration;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.ui.output.MessageOutput;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.FeedbackSessionClosingRemindersAction;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * SUT: {@link FeedbackSessionClosingRemindersAction}."},{"lineNumber":23,"author":{"gitId":"-"},"content":" */"},{"lineNumber":24,"author":{"gitId":"-"},"content":"public class FeedbackSessionClosingRemindersActionIT extends BaseActionIT\u003cFeedbackSessionClosingRemindersAction\u003e {"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":27,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":28,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":30,"author":{"gitId":"-"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":32,"author":{"gitId":"-"},"content":" prepareSession();"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" private void prepareSession() {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" // DEADLINE EXTENSIONS"},{"lineNumber":37,"author":{"gitId":"-"},"content":" String[] deKeys \u003d {\"student1InCourse1Session1\", \"instructor1InCourse1Session1\"};"},{"lineNumber":38,"author":{"gitId":"-"},"content":" List\u003cDeadlineExtension\u003e exts \u003d new ArrayList\u003c\u003e();"},{"lineNumber":39,"author":{"gitId":"-"},"content":" for (String deKey : deKeys) {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" exts.add(typicalBundle.deadlineExtensions.get(deKey));"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" // FEEDBACK QUESTIONS"},{"lineNumber":44,"author":{"gitId":"-"},"content":" String[] fqKeys \u003d {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" \"qn1InSession1InCourse1\","},{"lineNumber":46,"author":{"gitId":"-"},"content":" \"qn2InSession1InCourse1\","},{"lineNumber":47,"author":{"gitId":"-"},"content":" \"qn3InSession1InCourse1\","},{"lineNumber":48,"author":{"gitId":"-"},"content":" \"qn4InSession1InCourse1\","},{"lineNumber":49,"author":{"gitId":"-"},"content":" \"qn5InSession1InCourse1\","},{"lineNumber":50,"author":{"gitId":"-"},"content":" \"qn6InSession1InCourse1NoResponses\","},{"lineNumber":51,"author":{"gitId":"-"},"content":" };"},{"lineNumber":52,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e qns \u003d new ArrayList\u003c\u003e();"},{"lineNumber":53,"author":{"gitId":"-"},"content":" for (String fqKey : fqKeys) {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" qns.add(typicalBundle.feedbackQuestions.get(fqKey));"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" FeedbackSession session \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":58,"author":{"gitId":"-"},"content":" session.setDeadlineExtensions(exts);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" session.setFeedbackQuestions(qns);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":63,"author":{"gitId":"-"},"content":" String getActionUri() {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" return Const.CronJobURIs.AUTOMATED_FEEDBACK_CLOSING_REMINDERS;"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":68,"author":{"gitId":"-"},"content":" String getRequestMethod() {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" return GET;"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":73,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":74,"author":{"gitId":"-"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":76,"author":{"gitId":"-"},"content":" verifyOnlyAdminCanAccess(course);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":80,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":81,"author":{"gitId":"-"},"content":" protected void testExecute() throws Exception {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" loginAsAdmin();"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case 1: email tasks added for 1 all users of 1 session\");"},{"lineNumber":85,"author":{"gitId":"-"},"content":" textExecute_typicalSuccess1();"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case 2: email tasks added for 1 all users of 1 session and 1 deadline extension\");"},{"lineNumber":88,"author":{"gitId":"-"},"content":" textExecute_typicalSuccess2();"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case 3: Only 1 email task queued -- \""},{"lineNumber":91,"author":{"gitId":"-"},"content":" + \"0 for session: already sent, \""},{"lineNumber":92,"author":{"gitId":"-"},"content":" + \"1 for deadline extension: closing-soon not sent yet\");"},{"lineNumber":93,"author":{"gitId":"-"},"content":" textExecute_typicalSuccess3();"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case 4: No tasks queued -- \""},{"lineNumber":96,"author":{"gitId":"-"},"content":" + \"both session and deadline extensions have already sent closing-soon emails\");"},{"lineNumber":97,"author":{"gitId":"-"},"content":" textExecute_typicalSuccess4();"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case 5: No tasks queued -- session\u0027s closing-soon email disabled\");"},{"lineNumber":100,"author":{"gitId":"-"},"content":" textExecute_typicalSuccess5();"},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" private void textExecute_typicalSuccess1() {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" long oneHour \u003d 60 * 60;"},{"lineNumber":105,"author":{"gitId":"-"},"content":" Instant now \u003d Instant.now();"},{"lineNumber":106,"author":{"gitId":"-"},"content":" Duration noGracePeriod \u003d Duration.between(now, now);"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" FeedbackSession session \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":109,"author":{"gitId":"-"},"content":" session.setClosingSoonEmailSent(false);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" session.setEndTime(now.plusSeconds((oneHour * 23) + 60));"},{"lineNumber":111,"author":{"gitId":"-"},"content":" session.setGracePeriod(noGracePeriod);"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" String[] params \u003d {};"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" FeedbackSessionClosingRemindersAction action1 \u003d getAction(params);"},{"lineNumber":116,"author":{"gitId":"-"},"content":" JsonResult actionOutput1 \u003d getJsonResult(action1);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" MessageOutput response1 \u003d (MessageOutput) actionOutput1.getOutput();"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" assertEquals(\"Successful\", response1.getMessage());"},{"lineNumber":120,"author":{"gitId":"-"},"content":" assertTrue(session.isClosingSoonEmailSent());"},{"lineNumber":121,"author":{"gitId":"-"},"content":" assertTrue(session.getDeadlineExtensions().stream().allMatch(de -\u003e !de.isClosingSoonEmailSent()));"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"marquestye"},"content":" // 7 email tasks queued:"},{"lineNumber":124,"author":{"gitId":"marquestye"},"content":" // 1 co-owner, 5 students and 3 instructors,"},{"lineNumber":125,"author":{"gitId":"-"},"content":" // but 1 student and 1 instructor have deadline extensions (should not receive email)"},{"lineNumber":126,"author":{"gitId":"marquestye"},"content":" verifySpecifiedTasksAdded(Const.TaskQueue.SEND_EMAIL_QUEUE_NAME, 7);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" private void textExecute_typicalSuccess2() {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" long oneHour \u003d 60 * 60;"},{"lineNumber":131,"author":{"gitId":"-"},"content":" Instant now \u003d Instant.now();"},{"lineNumber":132,"author":{"gitId":"-"},"content":" Duration noGracePeriod \u003d Duration.between(now, now);"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" FeedbackSession session \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":135,"author":{"gitId":"-"},"content":" session.setClosingSoonEmailSent(false);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" session.setEndTime(now.plusSeconds((oneHour * 23) + 60));"},{"lineNumber":137,"author":{"gitId":"-"},"content":" session.setGracePeriod(noGracePeriod);"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" DeadlineExtension de \u003d session.getDeadlineExtensions().get(0);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" de.setEndTime(now.plusSeconds(oneHour * 16));"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" String[] params \u003d {};"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" FeedbackSessionClosingRemindersAction action1 \u003d getAction(params);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" JsonResult actionOutput1 \u003d getJsonResult(action1);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" MessageOutput response1 \u003d (MessageOutput) actionOutput1.getOutput();"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" assertEquals(\"Successful\", response1.getMessage());"},{"lineNumber":149,"author":{"gitId":"-"},"content":" assertTrue(session.isClosingSoonEmailSent());"},{"lineNumber":150,"author":{"gitId":"-"},"content":" assertTrue(de.isClosingSoonEmailSent());"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"marquestye"},"content":" // 8 email tasks queued:"},{"lineNumber":153,"author":{"gitId":"marquestye"},"content":" // - 7 emails: 1 co-owner, 5 students and 3 instructors,"},{"lineNumber":154,"author":{"gitId":"-"},"content":" // but 1 student and 1 instructor have deadline extensions (should not receive email)"},{"lineNumber":155,"author":{"gitId":"-"},"content":" // - 1 email: 1 student deadline extension"},{"lineNumber":156,"author":{"gitId":"marquestye"},"content":" verifySpecifiedTasksAdded(Const.TaskQueue.SEND_EMAIL_QUEUE_NAME, 8);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" }"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" private void textExecute_typicalSuccess3() {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" long oneHour \u003d 60 * 60;"},{"lineNumber":161,"author":{"gitId":"-"},"content":" Instant now \u003d Instant.now();"},{"lineNumber":162,"author":{"gitId":"-"},"content":" Duration noGracePeriod \u003d Duration.between(now, now);"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" FeedbackSession session \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":165,"author":{"gitId":"-"},"content":" session.setClosingSoonEmailSent(true);"},{"lineNumber":166,"author":{"gitId":"-"},"content":" session.setEndTime(now.plusSeconds((oneHour * 23) + 60));"},{"lineNumber":167,"author":{"gitId":"-"},"content":" session.setGracePeriod(noGracePeriod);"},{"lineNumber":168,"author":{"gitId":"-"},"content":""},{"lineNumber":169,"author":{"gitId":"-"},"content":" DeadlineExtension de \u003d session.getDeadlineExtensions().get(0);"},{"lineNumber":170,"author":{"gitId":"-"},"content":" de.setEndTime(now.plusSeconds(oneHour * 16));"},{"lineNumber":171,"author":{"gitId":"-"},"content":" de.setClosingSoonEmailSent(false);"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" String[] params \u003d {};"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" FeedbackSessionClosingRemindersAction action1 \u003d getAction(params);"},{"lineNumber":176,"author":{"gitId":"-"},"content":" JsonResult actionOutput1 \u003d getJsonResult(action1);"},{"lineNumber":177,"author":{"gitId":"-"},"content":" MessageOutput response1 \u003d (MessageOutput) actionOutput1.getOutput();"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" assertEquals(\"Successful\", response1.getMessage());"},{"lineNumber":180,"author":{"gitId":"-"},"content":" assertTrue(session.isClosingSoonEmailSent());"},{"lineNumber":181,"author":{"gitId":"-"},"content":" assertTrue(de.isClosingSoonEmailSent());"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" // 1 email tasks queued:"},{"lineNumber":184,"author":{"gitId":"-"},"content":" // - 0 emails: session already sent closing-soon emails"},{"lineNumber":185,"author":{"gitId":"-"},"content":" // - 1 email: 1 student deadline extension where closing-soon email not sent yet"},{"lineNumber":186,"author":{"gitId":"-"},"content":" verifySpecifiedTasksAdded(Const.TaskQueue.SEND_EMAIL_QUEUE_NAME, 1);"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":" private void textExecute_typicalSuccess4() {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" long oneHour \u003d 60 * 60;"},{"lineNumber":191,"author":{"gitId":"-"},"content":" Instant now \u003d Instant.now();"},{"lineNumber":192,"author":{"gitId":"-"},"content":" Duration noGracePeriod \u003d Duration.between(now, now);"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"-"},"content":" FeedbackSession session \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":195,"author":{"gitId":"-"},"content":" session.setClosingSoonEmailSent(true);"},{"lineNumber":196,"author":{"gitId":"-"},"content":" session.setEndTime(now.plusSeconds((oneHour * 23) + 60));"},{"lineNumber":197,"author":{"gitId":"-"},"content":" session.setGracePeriod(noGracePeriod);"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" DeadlineExtension de \u003d session.getDeadlineExtensions().get(0);"},{"lineNumber":200,"author":{"gitId":"-"},"content":" de.setEndTime(now.plusSeconds(oneHour * 16));"},{"lineNumber":201,"author":{"gitId":"-"},"content":" de.setClosingSoonEmailSent(true);"},{"lineNumber":202,"author":{"gitId":"-"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":" String[] params \u003d {};"},{"lineNumber":204,"author":{"gitId":"-"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" FeedbackSessionClosingRemindersAction action1 \u003d getAction(params);"},{"lineNumber":206,"author":{"gitId":"-"},"content":" JsonResult actionOutput1 \u003d getJsonResult(action1);"},{"lineNumber":207,"author":{"gitId":"-"},"content":" MessageOutput response1 \u003d (MessageOutput) actionOutput1.getOutput();"},{"lineNumber":208,"author":{"gitId":"-"},"content":""},{"lineNumber":209,"author":{"gitId":"-"},"content":" assertEquals(\"Successful\", response1.getMessage());"},{"lineNumber":210,"author":{"gitId":"-"},"content":" assertTrue(session.isClosingSoonEmailSent());"},{"lineNumber":211,"author":{"gitId":"-"},"content":" assertTrue(de.isClosingSoonEmailSent());"},{"lineNumber":212,"author":{"gitId":"-"},"content":""},{"lineNumber":213,"author":{"gitId":"-"},"content":" verifyNoTasksAdded();"},{"lineNumber":214,"author":{"gitId":"-"},"content":" }"},{"lineNumber":215,"author":{"gitId":"-"},"content":""},{"lineNumber":216,"author":{"gitId":"-"},"content":" private void textExecute_typicalSuccess5() {"},{"lineNumber":217,"author":{"gitId":"-"},"content":" long oneHour \u003d 60 * 60;"},{"lineNumber":218,"author":{"gitId":"-"},"content":" Instant now \u003d Instant.now();"},{"lineNumber":219,"author":{"gitId":"-"},"content":" Duration noGracePeriod \u003d Duration.between(now, now);"},{"lineNumber":220,"author":{"gitId":"-"},"content":""},{"lineNumber":221,"author":{"gitId":"-"},"content":" FeedbackSession session \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":222,"author":{"gitId":"-"},"content":" session.setClosingEmailEnabled(false);"},{"lineNumber":223,"author":{"gitId":"-"},"content":" session.setClosingSoonEmailSent(false);"},{"lineNumber":224,"author":{"gitId":"-"},"content":" session.setEndTime(now.plusSeconds((oneHour * 23) + 60));"},{"lineNumber":225,"author":{"gitId":"-"},"content":" session.setGracePeriod(noGracePeriod);"},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"-"},"content":" DeadlineExtension de \u003d session.getDeadlineExtensions().get(0);"},{"lineNumber":228,"author":{"gitId":"-"},"content":" de.setEndTime(now.plusSeconds(oneHour * 16));"},{"lineNumber":229,"author":{"gitId":"-"},"content":" de.setClosingSoonEmailSent(false);"},{"lineNumber":230,"author":{"gitId":"-"},"content":""},{"lineNumber":231,"author":{"gitId":"-"},"content":" String[] params \u003d {};"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" FeedbackSessionClosingRemindersAction action1 \u003d getAction(params);"},{"lineNumber":234,"author":{"gitId":"-"},"content":" JsonResult actionOutput1 \u003d getJsonResult(action1);"},{"lineNumber":235,"author":{"gitId":"-"},"content":" MessageOutput response1 \u003d (MessageOutput) actionOutput1.getOutput();"},{"lineNumber":236,"author":{"gitId":"-"},"content":""},{"lineNumber":237,"author":{"gitId":"-"},"content":" assertEquals(\"Successful\", response1.getMessage());"},{"lineNumber":238,"author":{"gitId":"-"},"content":" assertTrue(!session.isClosingSoonEmailSent());"},{"lineNumber":239,"author":{"gitId":"-"},"content":" assertTrue(!de.isClosingSoonEmailSent());"},{"lineNumber":240,"author":{"gitId":"-"},"content":""},{"lineNumber":241,"author":{"gitId":"-"},"content":" verifyNoTasksAdded();"},{"lineNumber":242,"author":{"gitId":"-"},"content":" }"},{"lineNumber":243,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":6,"-":237}},{"path":"src/it/java/teammates/it/ui/webapi/GetCourseJoinStatusActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Const;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.output.JoinStatus;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.webapi.GetCourseJoinStatusAction;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link GetCourseJoinStatusAction}."},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"public class GetCourseJoinStatusActionIT extends BaseActionIT\u003cGetCourseJoinStatusAction\u003e {"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":" @BeforeMethod"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":" protected void setUp() throws Exception {"},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":" super.setUp();"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" this.typicalBundle \u003d loadSqlDataBundle(\"/typicalDataBundle.json\");"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":" HibernateUtil.flushSession();"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" protected String getActionUri() {"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" return Const.ResourceURIs.JOIN;"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" protected String getRequestMethod() {"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" return GET;"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" protected void testExecute() {"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" loginAsUnregistered(\"unreg.user\");"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Not enough parameters\");"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure();"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure("},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, \"regkey\""},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" );"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure("},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.STUDENT"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" );"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Normal case: student is already registered\");"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" String registeredStudentKey \u003d"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" logic.getStudentForEmail(\"course-1\", \"student1@teammates.tmt\").getRegKey();"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" String[] params \u003d new String[] {"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, registeredStudentKey,"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.STUDENT,"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" GetCourseJoinStatusAction getCourseJoinStatusAction \u003d getAction(params);"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" JsonResult result \u003d getJsonResult(getCourseJoinStatusAction);"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" JoinStatus output \u003d (JoinStatus) result.getOutput();"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" assertTrue(output.getHasJoined());"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Normal case: student is not registered\");"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" String unregisteredStudentKey \u003d"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" logic.getStudentForEmail(\"course-1\", \"unregisteredStudentInCourse1@teammates.tmt\").getRegKey();"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" params \u003d new String[] {"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, unregisteredStudentKey,"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.STUDENT,"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" getCourseJoinStatusAction \u003d getAction(params);"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" result \u003d getJsonResult(getCourseJoinStatusAction);"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" output \u003d (JoinStatus) result.getOutput();"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":" assertFalse(output.getHasJoined());"},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: regkey is not valid for student\");"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" params \u003d new String[] {"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, \"ANXKJZNZXNJCZXKJDNKSDA\","},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.STUDENT,"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" verifyEntityNotFound(params);"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Normal case: instructor is already registered\");"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" String registeredInstructorKey \u003d"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" logic.getInstructorForEmail(\"course-1\", \"instr1@teammates.tmt\").getRegKey();"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" params \u003d new String[] {"},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, registeredInstructorKey,"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" getCourseJoinStatusAction \u003d getAction(params);"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":" result \u003d getJsonResult(getCourseJoinStatusAction);"},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":" output \u003d (JoinStatus) result.getOutput();"},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" assertTrue(output.getHasJoined());"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Normal case: instructor is not registered\");"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" String unregisteredInstructorKey \u003d"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":" logic.getInstructorForEmail(\"course-1\", \"unregisteredInstructor@teammates.tmt\").getRegKey();"},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" params \u003d new String[] {"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, unregisteredInstructorKey,"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" getCourseJoinStatusAction \u003d getAction(params);"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" result \u003d getJsonResult(getCourseJoinStatusAction);"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" output \u003d (JoinStatus) result.getOutput();"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" assertFalse(output.getHasJoined());"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: regkey is not valid for instructor\");"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" params \u003d new String[] {"},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, \"ANXKJZNZXNJCZXKJDNKSDA\","},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" verifyEntityNotFound(params);"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Normal case: account request not used, instructor has not joined course\");"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" AccountRequest unregisteredInstructor1AccountRequest \u003d typicalBundle.accountRequests.get(\"unregisteredInstructor1\");"},{"lineNumber":136,"author":{"gitId":"-"},"content":" String accountRequestNotUsedKey \u003d unregisteredInstructor1AccountRequest.getRegistrationKey();"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":" params \u003d new String[] {"},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, accountRequestNotUsedKey,"},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":141,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.IS_CREATING_ACCOUNT, \"true\","},{"lineNumber":142,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":143,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":144,"author":{"gitId":"dishenggg"},"content":" getCourseJoinStatusAction \u003d getAction(params);"},{"lineNumber":145,"author":{"gitId":"dishenggg"},"content":" result \u003d getJsonResult(getCourseJoinStatusAction);"},{"lineNumber":146,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":" output \u003d (JoinStatus) result.getOutput();"},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":" assertFalse(output.getHasJoined());"},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Normal case: account request already used, instructor has joined course\");"},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" AccountRequest instructor1AccountRequest \u003d typicalBundle.accountRequests.get(\"instructor1\");"},{"lineNumber":153,"author":{"gitId":"-"},"content":" String accountRequestUsedKey \u003d instructor1AccountRequest.getRegistrationKey();"},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":" params \u003d new String[] {"},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, accountRequestUsedKey,"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":158,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.IS_CREATING_ACCOUNT, \"true\","},{"lineNumber":159,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":161,"author":{"gitId":"dishenggg"},"content":" getCourseJoinStatusAction \u003d getAction(params);"},{"lineNumber":162,"author":{"gitId":"dishenggg"},"content":" result \u003d getJsonResult(getCourseJoinStatusAction);"},{"lineNumber":163,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":164,"author":{"gitId":"dishenggg"},"content":" output \u003d (JoinStatus) result.getOutput();"},{"lineNumber":165,"author":{"gitId":"dishenggg"},"content":" assertTrue(output.getHasJoined());"},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":167,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: account request regkey is not valid\");"},{"lineNumber":168,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":" params \u003d new String[] {"},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, \"invalid-registration-key\","},{"lineNumber":171,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.IS_CREATING_ACCOUNT, \"true\","},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":175,"author":{"gitId":"dishenggg"},"content":" verifyEntityNotFound(params);"},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: invalid entity type\");"},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":179,"author":{"gitId":"dishenggg"},"content":" params \u003d new String[] {"},{"lineNumber":180,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.REGKEY, unregisteredStudentKey,"},{"lineNumber":181,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.ENTITY_TYPE, \"unknown\","},{"lineNumber":182,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure(params);"},{"lineNumber":185,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":186,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":187,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":188,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":189,"author":{"gitId":"dishenggg"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":190,"author":{"gitId":"dishenggg"},"content":" verifyAnyLoggedInUserCanAccess();"},{"lineNumber":191,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":192,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":187,"-":5}},{"path":"src/it/java/teammates/it/ui/webapi/GetFeedbackSessionLogsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionLogData;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionLogEntryData;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionLogsData;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.GetFeedbackSessionLogsAction;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":23,"author":{"gitId":"-"},"content":" * SUT: {@link GetFeedbackSessionLogsAction}."},{"lineNumber":24,"author":{"gitId":"-"},"content":" */"},{"lineNumber":25,"author":{"gitId":"-"},"content":"public class GetFeedbackSessionLogsActionIT extends BaseActionIT\u003cGetFeedbackSessionLogsAction\u003e {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":27,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":28,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":30,"author":{"gitId":"-"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":32,"author":{"gitId":"-"},"content":" }"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":35,"author":{"gitId":"-"},"content":" protected String getActionUri() {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" return Const.ResourceURIs.SESSION_LOGS;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" }"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":40,"author":{"gitId":"-"},"content":" protected String getRequestMethod() {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" return GET;"},{"lineNumber":42,"author":{"gitId":"-"},"content":" }"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":45,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":46,"author":{"gitId":"-"},"content":" protected void testExecute() {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" JsonResult actionOutput;"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":50,"author":{"gitId":"-"},"content":" String courseId \u003d course.getId();"},{"lineNumber":51,"author":{"gitId":"-"},"content":" FeedbackSession fsa1 \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":52,"author":{"gitId":"-"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":53,"author":{"gitId":"-"},"content":" Student student2 \u003d typicalBundle.students.get(\"student2InCourse1\");"},{"lineNumber":54,"author":{"gitId":"-"},"content":" String student1Email \u003d student1.getEmail();"},{"lineNumber":55,"author":{"gitId":"-"},"content":" String student2Email \u003d student2.getEmail();"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" long endTime \u003d Instant.parse(\"2012-01-02T12:00:00Z\").toEpochMilli();"},{"lineNumber":57,"author":{"gitId":"-"},"content":" long startTime \u003d endTime - (Const.LOGS_RETENTION_PERIOD.toDays() - 1) * 24 * 60 * 60 * 1000;"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: not enough parameters\");"},{"lineNumber":60,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure("},{"lineNumber":61,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId"},{"lineNumber":62,"author":{"gitId":"-"},"content":" );"},{"lineNumber":63,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure("},{"lineNumber":64,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime)"},{"lineNumber":66,"author":{"gitId":"-"},"content":" );"},{"lineNumber":67,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure("},{"lineNumber":68,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":69,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime)"},{"lineNumber":70,"author":{"gitId":"-"},"content":" );"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: invalid course id\");"},{"lineNumber":73,"author":{"gitId":"-"},"content":" String[] paramsInvalid1 \u003d {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, \"fake-course-id\","},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student1.getId().toString(),"},{"lineNumber":76,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":77,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":78,"author":{"gitId":"-"},"content":" };"},{"lineNumber":79,"author":{"gitId":"-"},"content":" verifyEntityNotFound(paramsInvalid1);"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: invalid student id\");"},{"lineNumber":82,"author":{"gitId":"-"},"content":" String[] paramsInvalid2 \u003d {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, \"00000000-0000-0000-0000-000000000000\","},{"lineNumber":85,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":86,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":87,"author":{"gitId":"-"},"content":" };"},{"lineNumber":88,"author":{"gitId":"-"},"content":" verifyEntityNotFound(paramsInvalid2);"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: invalid start or end times\");"},{"lineNumber":91,"author":{"gitId":"-"},"content":" String[] paramsInvalid3 \u003d {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":93,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, \"abc\","},{"lineNumber":94,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":95,"author":{"gitId":"-"},"content":" };"},{"lineNumber":96,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure(paramsInvalid3);"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" String[] paramsInvalid4 \u003d {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":100,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":101,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, \" \","},{"lineNumber":102,"author":{"gitId":"-"},"content":" };"},{"lineNumber":103,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure(paramsInvalid4);"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" ______TS(\"Success case: should group by feedback session\");"},{"lineNumber":106,"author":{"gitId":"-"},"content":" String[] paramsSuccessful1 \u003d {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":108,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":109,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":110,"author":{"gitId":"-"},"content":" };"},{"lineNumber":111,"author":{"gitId":"-"},"content":" actionOutput \u003d getJsonResult(getAction(paramsSuccessful1));"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" // The filtering by the logs processor cannot be tested directly, assume that it filters correctly"},{"lineNumber":114,"author":{"gitId":"-"},"content":" // Here, it simply returns all log entries"},{"lineNumber":115,"author":{"gitId":"-"},"content":" FeedbackSessionLogsData fslData \u003d (FeedbackSessionLogsData) actionOutput.getOutput();"},{"lineNumber":116,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogData\u003e fsLogs \u003d fslData.getFeedbackSessionLogs();"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" // Course has 6 feedback sessions, last 4 of which have no log entries"},{"lineNumber":119,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.size(), 6);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.get(2).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.get(3).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.get(4).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":123,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.get(5).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogEntryData\u003e fsLogEntries1 \u003d fsLogs.get(0).getFeedbackSessionLogEntries();"},{"lineNumber":126,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogEntryData\u003e fsLogEntries2 \u003d fsLogs.get(1).getFeedbackSessionLogEntries();"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.size(), 3);"},{"lineNumber":129,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(0).getStudentData().getEmail(), student1Email);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(1).getStudentData().getEmail(), student2Email);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(2).getStudentData().getEmail(), student2Email);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(2).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.size(), 2);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.get(0).getStudentData().getEmail(), student1Email);"},{"lineNumber":138,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.get(1).getStudentData().getEmail(), student1Email);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: should accept optional student Id\");"},{"lineNumber":143,"author":{"gitId":"-"},"content":" String[] paramsSuccessful2 \u003d {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":145,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student1.getId().toString(),"},{"lineNumber":146,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":147,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":148,"author":{"gitId":"-"},"content":" };"},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":" actionOutput \u003d getJsonResult(getAction(paramsSuccessful2));"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":" fslData \u003d (FeedbackSessionLogsData) actionOutput.getOutput();"},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":" fsLogs \u003d fslData.getFeedbackSessionLogs();"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":153,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.size(), 6);"},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(2).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(3).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(4).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(5).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":158,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":159,"author":{"gitId":"dishenggg"},"content":" fsLogEntries1 \u003d fsLogs.get(0).getFeedbackSessionLogEntries();"},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":" fsLogEntries2 \u003d fsLogs.get(1).getFeedbackSessionLogEntries();"},{"lineNumber":161,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":162,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.size(), 1);"},{"lineNumber":163,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getStudentData().getEmail(), student1Email);"},{"lineNumber":164,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":165,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.size(), 2);"},{"lineNumber":167,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(0).getStudentData().getEmail(), student1Email);"},{"lineNumber":168,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(1).getStudentData().getEmail(), student1Email);"},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":171,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: should accept optional feedback session\");"},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":" String[] paramsSuccessful3 \u003d {"},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":175,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fsa1.getId().toString(),"},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":179,"author":{"gitId":"dishenggg"},"content":" actionOutput \u003d getJsonResult(getAction(paramsSuccessful3));"},{"lineNumber":180,"author":{"gitId":"dishenggg"},"content":" fslData \u003d (FeedbackSessionLogsData) actionOutput.getOutput();"},{"lineNumber":181,"author":{"gitId":"dishenggg"},"content":" fsLogs \u003d fslData.getFeedbackSessionLogs();"},{"lineNumber":182,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.size(), 6);"},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(1).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":185,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(2).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":186,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(3).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":187,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(4).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":188,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(5).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":189,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":190,"author":{"gitId":"dishenggg"},"content":" fsLogEntries1 \u003d fsLogs.get(0).getFeedbackSessionLogEntries();"},{"lineNumber":191,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":192,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.size(), 3);"},{"lineNumber":193,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getStudentData().getEmail(), student1Email);"},{"lineNumber":194,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":195,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(1).getStudentData().getEmail(), student2Email);"},{"lineNumber":196,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":197,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(2).getStudentData().getEmail(), student2Email);"},{"lineNumber":198,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(2).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":199,"author":{"gitId":"-"},"content":""},{"lineNumber":200,"author":{"gitId":"-"},"content":" // TODO: if we restrict the range from start to end time, it should be tested here as well"},{"lineNumber":201,"author":{"gitId":"-"},"content":" }"},{"lineNumber":202,"author":{"gitId":"-"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":204,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":205,"author":{"gitId":"-"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":206,"author":{"gitId":"-"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":207,"author":{"gitId":"-"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":208,"author":{"gitId":"-"},"content":" String courseId \u003d course.getId();"},{"lineNumber":209,"author":{"gitId":"-"},"content":" Instructor helper \u003d typicalBundle.instructors.get(\"instructor2OfCourse1\");"},{"lineNumber":210,"author":{"gitId":"-"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":212,"author":{"gitId":"-"},"content":" };"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" ______TS(\"Only instructors with modify student, session and instructor privilege can access\");"},{"lineNumber":215,"author":{"gitId":"-"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":216,"author":{"gitId":"-"},"content":""},{"lineNumber":217,"author":{"gitId":"-"},"content":" loginAsInstructor(helper.getGoogleId());"},{"lineNumber":218,"author":{"gitId":"-"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" ______TS(\"Only instructors of the same course can access\");"},{"lineNumber":221,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":222,"author":{"gitId":"-"},"content":" verifyCanAccess(submissionParams);"},{"lineNumber":223,"author":{"gitId":"-"},"content":" }"},{"lineNumber":224,"author":{"gitId":"-"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":57,"-":168}},{"path":"src/it/java/teammates/it/ui/webapi/GetFeedbackSessionSubmittedGiverSetActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.Test;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import com.google.common.collect.Sets;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.output.FeedbackSessionSubmittedGiverSet;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.GetFeedbackSessionSubmittedGiverSetAction;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" * SUT: {@link GetFeedbackSessionSubmittedGiverSetAction}."},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":"public class GetFeedbackSessionSubmittedGiverSetActionIT extends BaseActionIT\u003cGetFeedbackSessionSubmittedGiverSetAction\u003e {"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" @BeforeMethod"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" protected void setUp() throws Exception {"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" super.setUp();"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.flushSession();"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" protected String getActionUri() {"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" return Const.ResourceURIs.SESSION_SUBMITTED_GIVER_SET;"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" protected String getRequestMethod() {"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" return GET;"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" protected void testExecute() {"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" Instructor instructor1OfCourse1 \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" String instructorId \u003d instructor1OfCourse1.getGoogleId();"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" FeedbackSession fsa \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" loginAsInstructor(instructorId);"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Not enough parameters\");"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" verifyHttpParameterFailure();"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Typical case\");"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fsa.getName(),"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" GetFeedbackSessionSubmittedGiverSetAction pageAction \u003d getAction(submissionParams);"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" JsonResult result \u003d getJsonResult(pageAction);"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" FeedbackSessionSubmittedGiverSet output \u003d (FeedbackSessionSubmittedGiverSet) result.getOutput();"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" assertEquals(Sets.newHashSet(\"student1@teammates.tmt\", \"student2@teammates.tmt\","},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" \"student3@teammates.tmt\"), output.getGiverIdentifiers());"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" FeedbackSession fsa \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fsa.getName(),"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" verifyOnlyInstructorsOfTheSameCourseCanAccess(course, submissionParams);"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":78}},{"path":"src/it/java/teammates/it/ui/webapi/GetInstructorsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.ui.output.InstructorData;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.ui.output.InstructorsData;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.ui.request.Intent;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.GetInstructorsAction;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * SUT: {@link GetInstructorsAction}."},{"lineNumber":20,"author":{"gitId":"-"},"content":" */"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public class GetInstructorsActionIT extends BaseActionIT\u003cGetInstructorsAction\u003e {"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":24,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":25,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":27,"author":{"gitId":"-"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":28,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":32,"author":{"gitId":"-"},"content":" protected String getActionUri() {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" return Const.ResourceURIs.INSTRUCTORS;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":37,"author":{"gitId":"-"},"content":" protected String getRequestMethod() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" return GET;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":42,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":43,"author":{"gitId":"-"},"content":" protected void testExecute() throws Exception {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case with FULL_DETAIL\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":" String[] params \u003d new String[] {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, instructor.getCourseId(),"},{"lineNumber":51,"author":{"gitId":"-"},"content":" Const.ParamsNames.INTENT, Intent.FULL_DETAIL.toString(),"},{"lineNumber":52,"author":{"gitId":"-"},"content":" };"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" GetInstructorsAction action \u003d getAction(params);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" JsonResult jsonResult \u003d getJsonResult(action);"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" InstructorsData output \u003d (InstructorsData) jsonResult.getOutput();"},{"lineNumber":58,"author":{"gitId":"-"},"content":" List\u003cInstructorData\u003e instructors \u003d output.getInstructors();"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" assertEquals(3, instructors.size());"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case with no intent\");"},{"lineNumber":63,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, instructor.getCourseId(),"},{"lineNumber":65,"author":{"gitId":"-"},"content":" Const.ParamsNames.INTENT, null,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" };"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" action \u003d getAction(params);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" jsonResult \u003d getJsonResult(action);"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" output \u003d (InstructorsData) jsonResult.getOutput();"},{"lineNumber":72,"author":{"gitId":"-"},"content":" instructors \u003d output.getInstructors();"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" assertEquals(3, instructors.size());"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" for (InstructorData instructorData : instructors) {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" assertNull(instructorData.getGoogleId());"},{"lineNumber":78,"author":{"gitId":"-"},"content":" assertNull(instructorData.getJoinState());"},{"lineNumber":79,"author":{"gitId":"-"},"content":" assertNull(instructorData.getIsDisplayedToStudents());"},{"lineNumber":80,"author":{"gitId":"-"},"content":" assertNull(instructorData.getRole());"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" ______TS(\"Unknown intent\");"},{"lineNumber":84,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, instructor.getCourseId(),"},{"lineNumber":86,"author":{"gitId":"-"},"content":" Const.ParamsNames.INTENT, \"Unknown\","},{"lineNumber":87,"author":{"gitId":"-"},"content":" };"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure(params);"},{"lineNumber":90,"author":{"gitId":"-"},"content":" }"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":93,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":94,"author":{"gitId":"-"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":96,"author":{"gitId":"-"},"content":" Student student \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" ______TS(\"Course not found, logged in as instructor, intent FULL_DETAIL\");"},{"lineNumber":99,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" String[] params \u003d new String[] {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, \"does-not-exist-id\","},{"lineNumber":103,"author":{"gitId":"-"},"content":" Const.ParamsNames.INTENT, Intent.FULL_DETAIL.toString(),"},{"lineNumber":104,"author":{"gitId":"-"},"content":" };"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" verifyEntityNotFoundAcl(params);"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" ______TS(\"Course not found, logged in as student, intent undefined\");"},{"lineNumber":109,"author":{"gitId":"-"},"content":" loginAsStudent(student.getGoogleId());"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, \"does-not-exist-id\","},{"lineNumber":113,"author":{"gitId":"-"},"content":" };"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" verifyEntityNotFoundAcl(params);"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" ______TS(\"Unknown login entity, intent FULL_DETAIL\");"},{"lineNumber":118,"author":{"gitId":"-"},"content":" loginAsUnregistered(\"unregistered\");"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, instructor.getCourseId(),"},{"lineNumber":122,"author":{"gitId":"-"},"content":" Const.ParamsNames.INTENT, Intent.FULL_DETAIL.toString(),"},{"lineNumber":123,"author":{"gitId":"-"},"content":" };"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" ______TS(\"Unknown login entity, intent undefined\");"},{"lineNumber":128,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":129,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, instructor.getCourseId(),"},{"lineNumber":130,"author":{"gitId":"-"},"content":" };"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" ______TS(\"Unknown intent, logged in as instructor\");"},{"lineNumber":135,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":138,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, instructor.getCourseId(),"},{"lineNumber":139,"author":{"gitId":"-"},"content":" Const.ParamsNames.INTENT, \"Unknown\","},{"lineNumber":140,"author":{"gitId":"-"},"content":" };"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" verifyHttpParameterFailureAcl(params);"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" ______TS(\"Intent FULL_DETAIL, should authenticate as instructor\");"},{"lineNumber":145,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":146,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, instructor.getCourseId(),"},{"lineNumber":147,"author":{"gitId":"-"},"content":" Const.ParamsNames.INTENT, Intent.FULL_DETAIL.toString(),"},{"lineNumber":148,"author":{"gitId":"-"},"content":" };"},{"lineNumber":149,"author":{"gitId":"-"},"content":""},{"lineNumber":150,"author":{"gitId":"-"},"content":" verifyOnlyInstructorsOfTheSameCourseCanAccess(instructor.getCourse(), params);"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" ______TS(\"Intent undefined, should authenticate as student, access own course\");"},{"lineNumber":153,"author":{"gitId":"-"},"content":" loginAsStudent(student.getGoogleId());"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, student.getCourseId(),"},{"lineNumber":157,"author":{"gitId":"-"},"content":" };"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" verifyCanAccess(params);"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" ______TS(\"Intent undefined, should authenticate as student, access other course\");"},{"lineNumber":162,"author":{"gitId":"-"},"content":" Student otherStudent \u003d typicalBundle.students.get(\"student1InCourse2\");"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" assertNotEquals(otherStudent.getCourse(), student.getCourse());"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, otherStudent.getCourseId(),"},{"lineNumber":168,"author":{"gitId":"-"},"content":" };"},{"lineNumber":169,"author":{"gitId":"-"},"content":""},{"lineNumber":170,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":2,"-":171}},{"path":"src/it/java/teammates/it/ui/webapi/GetSessionResponseStatsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.Test;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.Const;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.output.FeedbackSessionStatsData;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.GetSessionResponseStatsAction;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" * SUT: {@link GetSessionResponseStatsAction}."},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"public class GetSessionResponseStatsActionIT extends BaseActionIT\u003cGetSessionResponseStatsAction\u003e {"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" @BeforeMethod"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" protected void setUp() throws Exception {"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" super.setUp();"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.flushSession();"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" String getActionUri() {"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" return Const.ResourceURIs.SESSION_STATS;"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" String getRequestMethod() {"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" return GET;"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" protected void testExecute() {"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" ______TS(\"typical: instructor accesses feedback stats of his/her course\");"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" FeedbackSession accessibleFs \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, accessibleFs.getName(),"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.COURSE_ID, accessibleFs.getCourse().getId(),"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" GetSessionResponseStatsAction a \u003d getAction(submissionParams);"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" JsonResult r \u003d getJsonResult(a);"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" FeedbackSessionStatsData output \u003d (FeedbackSessionStatsData) r.getOutput();"},{"lineNumber":56,"author":{"gitId":"-"},"content":" assertEquals(8, output.getExpectedTotal());"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" assertEquals(3, output.getSubmittedTotal());"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" ______TS(\"fail: instructor accesses stats of non-existent feedback session\");"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" String nonexistentFeedbackSession \u003d \"nonexistentFeedbackSession\";"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, nonexistentFeedbackSession,"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.COURSE_ID, accessibleFs.getCourse().getId(),"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" verifyEntityNotFound(submissionParams);"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" ______TS(\"accessible for admin\");"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" verifyAccessibleForAdmin();"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" ______TS(\"accessible for authenticated instructor\");"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" Course course1 \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" FeedbackSession accessibleFs \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, accessibleFs.getName(),"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" Const.ParamsNames.COURSE_ID, accessibleFs.getCourse().getId(),"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" verifyOnlyInstructorsOfTheSameCourseCanAccess(course1, submissionParams);"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":85,"-":1}},{"path":"src/it/java/teammates/it/ui/webapi/GetSessionResultsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import java.util.HashSet;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import java.util.Set;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":"import org.testng.annotations.Test;"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.FeedbackResultFetchType;"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":15,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":"import teammates.ui.output.SessionResultsData;"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":"import teammates.ui.request.Intent;"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":"import teammates.ui.webapi.GetSessionResultsAction;"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" * SUT: {@link GetSessionResultsAction}."},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":"public class GetSessionResultsActionIT extends BaseActionIT\u003cGetSessionResultsAction\u003e {"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" protected String getActionUri() {"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" return Const.ResourceURIs.RESULT;"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" protected String getRequestMethod() {"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" return GET;"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" @BeforeMethod"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" protected void setUp() throws Exception {"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" super.setUp();"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" logoutUser();"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" HibernateUtil.flushSession();"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" HibernateUtil.clearSession();"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" protected void testExecute() {"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" ______TS(\"Typical: Instructor accesses results of their course\");"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" FeedbackSession accessibleFeedbackSession \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, accessibleFeedbackSession.getName(),"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.FULL_DETAIL.name(),"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":" GetSessionResultsAction a \u003d getAction(submissionParams);"},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":" JsonResult r \u003d getJsonResult(a);"},{"lineNumber":67,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":68,"author":{"gitId":"xenosf"},"content":" SessionResultsData output \u003d (SessionResultsData) r.getOutput();"},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":" SessionResultsData expectedResults \u003d SessionResultsData.initForInstructor("},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" logic.getSessionResultsForCourse(accessibleFeedbackSession,"},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":" instructor.getEmail(),"},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" null, null, FeedbackResultFetchType.BOTH));"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" assertTrue(isSessionResultsDataEqual(expectedResults, output));"},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" ______TS(\"Typical: Instructor accesses results of their course with breakdown\");"},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" Set\u003cSection\u003e sections \u003d new HashSet\u003c\u003e();"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":" typicalBundle.feedbackResponses.values().forEach(resp -\u003e {"},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":" sections.add(resp.getGiverSection());"},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" sections.add(resp.getRecipientSection());"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":" for (FeedbackResultFetchType fetchType : FeedbackResultFetchType.values()) {"},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":" for (Section section : sections) {"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, accessibleFeedbackSession.getName(),"},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.FULL_DETAIL.name(),"},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_RESULTS_GROUPBYSECTION, section.getName(),"},{"lineNumber":93,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_RESULTS_SECTION_BY_GIVER_RECEIVER, fetchType.name(),"},{"lineNumber":94,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":" a \u003d getAction(submissionParams);"},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" r \u003d getJsonResult(a);"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" output \u003d (SessionResultsData) r.getOutput();"},{"lineNumber":100,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":" expectedResults \u003d SessionResultsData.initForInstructor("},{"lineNumber":102,"author":{"gitId":"xenosf"},"content":" logic.getSessionResultsForCourse(accessibleFeedbackSession,"},{"lineNumber":103,"author":{"gitId":"xenosf"},"content":" accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":104,"author":{"gitId":"xenosf"},"content":" instructor.getEmail(),"},{"lineNumber":105,"author":{"gitId":"xenosf"},"content":" null, section.getName(), fetchType));"},{"lineNumber":106,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":107,"author":{"gitId":"xenosf"},"content":" assertTrue(isSessionResultsDataEqual(expectedResults, output));"},{"lineNumber":108,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":109,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":110,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":111,"author":{"gitId":"xenosf"},"content":" ______TS(\"Typical: Instructor previews session results as student\");"},{"lineNumber":112,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":113,"author":{"gitId":"xenosf"},"content":" Student student \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":114,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":115,"author":{"gitId":"xenosf"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, accessibleFeedbackSession.getName(),"},{"lineNumber":117,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":118,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.name(),"},{"lineNumber":119,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.PREVIEWAS, student.getEmail(),"},{"lineNumber":120,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":121,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":122,"author":{"gitId":"xenosf"},"content":" a \u003d getAction(submissionParams);"},{"lineNumber":123,"author":{"gitId":"xenosf"},"content":" r \u003d getJsonResult(a);"},{"lineNumber":124,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":125,"author":{"gitId":"xenosf"},"content":" output \u003d (SessionResultsData) r.getOutput();"},{"lineNumber":126,"author":{"gitId":"xenosf"},"content":" expectedResults \u003d SessionResultsData.initForStudent("},{"lineNumber":127,"author":{"gitId":"xenosf"},"content":" logic.getSessionResultsForUser(accessibleFeedbackSession,"},{"lineNumber":128,"author":{"gitId":"xenosf"},"content":" accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":129,"author":{"gitId":"xenosf"},"content":" student.getEmail(),"},{"lineNumber":130,"author":{"gitId":"xenosf"},"content":" false, null, true),"},{"lineNumber":131,"author":{"gitId":"xenosf"},"content":" student);"},{"lineNumber":132,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":133,"author":{"gitId":"xenosf"},"content":" assertTrue(isSessionResultsDataEqual(expectedResults, output));"},{"lineNumber":134,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":135,"author":{"gitId":"xenosf"},"content":" ______TS(\"Typical: Student accesses results of their course\");"},{"lineNumber":136,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":137,"author":{"gitId":"xenosf"},"content":" loginAsStudent(student.getGoogleId());"},{"lineNumber":138,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":139,"author":{"gitId":"xenosf"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":140,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, accessibleFeedbackSession.getName(),"},{"lineNumber":141,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":142,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.name(),"},{"lineNumber":143,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":144,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":145,"author":{"gitId":"xenosf"},"content":" a \u003d getAction(submissionParams);"},{"lineNumber":146,"author":{"gitId":"xenosf"},"content":" r \u003d getJsonResult(a);"},{"lineNumber":147,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":148,"author":{"gitId":"xenosf"},"content":" output \u003d (SessionResultsData) r.getOutput();"},{"lineNumber":149,"author":{"gitId":"xenosf"},"content":" expectedResults \u003d SessionResultsData.initForStudent("},{"lineNumber":150,"author":{"gitId":"xenosf"},"content":" logic.getSessionResultsForUser(accessibleFeedbackSession,"},{"lineNumber":151,"author":{"gitId":"xenosf"},"content":" accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":152,"author":{"gitId":"xenosf"},"content":" student.getEmail(),"},{"lineNumber":153,"author":{"gitId":"xenosf"},"content":" false, null, false),"},{"lineNumber":154,"author":{"gitId":"xenosf"},"content":" student);"},{"lineNumber":155,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":156,"author":{"gitId":"xenosf"},"content":" assertTrue(isSessionResultsDataEqual(expectedResults, output));"},{"lineNumber":157,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":158,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"Typical: Student accesses results of their course by questionId\");"},{"lineNumber":159,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":160,"author":{"gitId":"mingyuanc"},"content":" loginAsStudent(student.getGoogleId());"},{"lineNumber":161,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":162,"author":{"gitId":"mingyuanc"},"content":" FeedbackQuestion question \u003d typicalBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":163,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":164,"author":{"gitId":"mingyuanc"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":165,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, accessibleFeedbackSession.getName(),"},{"lineNumber":166,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.COURSE_ID, accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":167,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.FEEDBACK_QUESTION_ID, question.getId().toString(),"},{"lineNumber":168,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.name(),"},{"lineNumber":169,"author":{"gitId":"mingyuanc"},"content":" };"},{"lineNumber":170,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":171,"author":{"gitId":"mingyuanc"},"content":" a \u003d getAction(submissionParams);"},{"lineNumber":172,"author":{"gitId":"mingyuanc"},"content":" r \u003d getJsonResult(a);"},{"lineNumber":173,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":174,"author":{"gitId":"mingyuanc"},"content":" output \u003d (SessionResultsData) r.getOutput();"},{"lineNumber":175,"author":{"gitId":"mingyuanc"},"content":" expectedResults \u003d SessionResultsData.initForStudent("},{"lineNumber":176,"author":{"gitId":"mingyuanc"},"content":" logic.getSessionResultsForUser(accessibleFeedbackSession,"},{"lineNumber":177,"author":{"gitId":"mingyuanc"},"content":" accessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":178,"author":{"gitId":"mingyuanc"},"content":" student.getEmail(),"},{"lineNumber":179,"author":{"gitId":"mingyuanc"},"content":" false, question.getId(), false),"},{"lineNumber":180,"author":{"gitId":"mingyuanc"},"content":" student);"},{"lineNumber":181,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":182,"author":{"gitId":"mingyuanc"},"content":" assertTrue(isSessionResultsDataEqual(expectedResults, output));"},{"lineNumber":183,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":184,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":185,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":186,"author":{"gitId":"xenosf"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":187,"author":{"gitId":"xenosf"},"content":" String[] submissionParams;"},{"lineNumber":188,"author":{"gitId":"xenosf"},"content":" FeedbackSession publishedFeedbackSession \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":189,"author":{"gitId":"xenosf"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":190,"author":{"gitId":"xenosf"},"content":" FeedbackSession inaccessibleFeedbackSession \u003d typicalBundle.feedbackSessions.get("},{"lineNumber":191,"author":{"gitId":"xenosf"},"content":" \"unpublishedSession1InTypicalCourse\");"},{"lineNumber":192,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":193,"author":{"gitId":"xenosf"},"content":" ______TS(\"Inaccessible for authenticated instructor when unpublished\");"},{"lineNumber":194,"author":{"gitId":"xenosf"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":195,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, inaccessibleFeedbackSession.getName(),"},{"lineNumber":196,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, inaccessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":197,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.INSTRUCTOR_RESULT.name(),"},{"lineNumber":198,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":199,"author":{"gitId":"xenosf"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":200,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":201,"author":{"gitId":"xenosf"},"content":" ______TS(\"Inaccessible for authenticated student when unpublished\");"},{"lineNumber":202,"author":{"gitId":"xenosf"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":203,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, inaccessibleFeedbackSession.getName(),"},{"lineNumber":204,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, inaccessibleFeedbackSession.getCourse().getId(),"},{"lineNumber":205,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.name(),"},{"lineNumber":206,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":207,"author":{"gitId":"xenosf"},"content":" Student student1InCourse1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":208,"author":{"gitId":"xenosf"},"content":" loginAsStudent(student1InCourse1.getGoogleId());"},{"lineNumber":209,"author":{"gitId":"xenosf"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":210,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":211,"author":{"gitId":"xenosf"},"content":" ______TS(\"Accessible for authenticated instructor when published\");"},{"lineNumber":212,"author":{"gitId":"xenosf"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":213,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, publishedFeedbackSession.getName(),"},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.INSTRUCTOR_RESULT.name(),"},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":217,"author":{"gitId":"xenosf"},"content":" verifyAccessibleForInstructorsOfTheSameCourse(course, submissionParams);"},{"lineNumber":218,"author":{"gitId":"xenosf"},"content":" verifyInaccessibleForInstructorsOfOtherCourses(course, submissionParams);"},{"lineNumber":219,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":220,"author":{"gitId":"xenosf"},"content":" ______TS(\"Accessible for authenticated student when published\");"},{"lineNumber":221,"author":{"gitId":"xenosf"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":222,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, publishedFeedbackSession.getName(),"},{"lineNumber":223,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":224,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.name(),"},{"lineNumber":225,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":226,"author":{"gitId":"xenosf"},"content":" verifyAccessibleForStudentsOfTheSameCourse(course, submissionParams);"},{"lineNumber":227,"author":{"gitId":"xenosf"},"content":" verifyInaccessibleForStudentsOfOtherCourse(course, submissionParams);"},{"lineNumber":228,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":229,"author":{"gitId":"xenosf"},"content":" ______TS(\"Invalid intent\");"},{"lineNumber":230,"author":{"gitId":"xenosf"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":231,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, publishedFeedbackSession.getName(),"},{"lineNumber":232,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, publishedFeedbackSession.getCourse().getId(),"},{"lineNumber":233,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.INSTRUCTOR_SUBMISSION.name(),"},{"lineNumber":234,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":235,"author":{"gitId":"xenosf"},"content":" verifyHttpParameterFailure(submissionParams);"},{"lineNumber":236,"author":{"gitId":"xenosf"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":237,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, publishedFeedbackSession.getName(),"},{"lineNumber":238,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, publishedFeedbackSession.getCourse().getId(),"},{"lineNumber":239,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_SUBMISSION.name(),"},{"lineNumber":240,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":241,"author":{"gitId":"xenosf"},"content":" verifyHttpParameterFailure(submissionParams);"},{"lineNumber":242,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":243,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":244,"author":{"gitId":"xenosf"},"content":" private boolean isSessionResultsDataEqual(SessionResultsData self, SessionResultsData other) {"},{"lineNumber":245,"author":{"gitId":"xenosf"},"content":" List\u003cSessionResultsData.QuestionOutput\u003e thisQuestions \u003d self.getQuestions();"},{"lineNumber":246,"author":{"gitId":"xenosf"},"content":" List\u003cSessionResultsData.QuestionOutput\u003e otherQuestions \u003d other.getQuestions();"},{"lineNumber":247,"author":{"gitId":"xenosf"},"content":" if (thisQuestions.size() !\u003d otherQuestions.size()) {"},{"lineNumber":248,"author":{"gitId":"xenosf"},"content":" return false;"},{"lineNumber":249,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":250,"author":{"gitId":"xenosf"},"content":" for (int i \u003d 0; i \u003c thisQuestions.size(); i++) {"},{"lineNumber":251,"author":{"gitId":"xenosf"},"content":" SessionResultsData.QuestionOutput thisQuestion \u003d thisQuestions.get(i);"},{"lineNumber":252,"author":{"gitId":"xenosf"},"content":" SessionResultsData.QuestionOutput otherQuestion \u003d otherQuestions.get(i);"},{"lineNumber":253,"author":{"gitId":"xenosf"},"content":" if (!isQuestionOutputEqual(thisQuestion, otherQuestion)) {"},{"lineNumber":254,"author":{"gitId":"xenosf"},"content":" return false;"},{"lineNumber":255,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":256,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":257,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":258,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":259,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":260,"author":{"gitId":"xenosf"},"content":" private boolean isQuestionOutputEqual(SessionResultsData.QuestionOutput self,"},{"lineNumber":261,"author":{"gitId":"xenosf"},"content":" SessionResultsData.QuestionOutput other) {"},{"lineNumber":262,"author":{"gitId":"xenosf"},"content":" if (!JsonUtils.toJson(self.getFeedbackQuestion()).equals(JsonUtils.toJson(other.getFeedbackQuestion()))"},{"lineNumber":263,"author":{"gitId":"xenosf"},"content":" || !self.getQuestionStatistics().equals(other.getQuestionStatistics())"},{"lineNumber":264,"author":{"gitId":"xenosf"},"content":" || self.getHasResponseButNotVisibleForPreview() !\u003d other.getHasResponseButNotVisibleForPreview()"},{"lineNumber":265,"author":{"gitId":"xenosf"},"content":" || self.getHasCommentNotVisibleForPreview() !\u003d other.getHasCommentNotVisibleForPreview()) {"},{"lineNumber":266,"author":{"gitId":"xenosf"},"content":" return false;"},{"lineNumber":267,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":268,"author":{"gitId":"xenosf"},"content":" List\u003cSessionResultsData.ResponseOutput\u003e thisResponses;"},{"lineNumber":269,"author":{"gitId":"xenosf"},"content":" List\u003cSessionResultsData.ResponseOutput\u003e otherResponses;"},{"lineNumber":270,"author":{"gitId":"xenosf"},"content":" thisResponses \u003d self.getAllResponses();"},{"lineNumber":271,"author":{"gitId":"xenosf"},"content":" otherResponses \u003d other.getAllResponses();"},{"lineNumber":272,"author":{"gitId":"xenosf"},"content":" if (thisResponses.size() !\u003d otherResponses.size()) {"},{"lineNumber":273,"author":{"gitId":"xenosf"},"content":" return false;"},{"lineNumber":274,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":275,"author":{"gitId":"xenosf"},"content":" for (int j \u003d 0; j \u003c thisResponses.size(); j++) {"},{"lineNumber":276,"author":{"gitId":"xenosf"},"content":" if (!isResponseOutputEqual(thisResponses.get(j), otherResponses.get(j))) {"},{"lineNumber":277,"author":{"gitId":"xenosf"},"content":" return false;"},{"lineNumber":278,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":279,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":280,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":281,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":282,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":283,"author":{"gitId":"xenosf"},"content":" private boolean isResponseOutputEqual(SessionResultsData.ResponseOutput self,"},{"lineNumber":284,"author":{"gitId":"xenosf"},"content":" SessionResultsData.ResponseOutput other) {"},{"lineNumber":285,"author":{"gitId":"xenosf"},"content":" return self.getGiver().equals(other.getGiver())"},{"lineNumber":286,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 self.getGiverTeam().equals(other.getGiverTeam())"},{"lineNumber":287,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 self.getGiverSection().equals(other.getGiverSection())"},{"lineNumber":288,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 self.getRecipient().equals(other.getRecipient())"},{"lineNumber":289,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 self.getRecipientTeam().equals(other.getRecipientTeam())"},{"lineNumber":290,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 self.getRecipientSection().equals(other.getRecipientSection())"},{"lineNumber":291,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 self.getResponseDetails().getJsonString().equals(other.getResponseDetails().getJsonString());"},{"lineNumber":292,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":293,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":294,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":295,"author":{"gitId":"xenosf"},"content":" public void testAccessControl_withoutCorrectAuthInfoAccessStudentResult_shouldFail() throws Exception {"},{"lineNumber":296,"author":{"gitId":"xenosf"},"content":" Course typicalCourse1 \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":297,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":298,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":299,"author":{"gitId":"xenosf"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":300,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, typicalCourse1.getId(),"},{"lineNumber":301,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSession.getName(),"},{"lineNumber":302,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.toString(),"},{"lineNumber":303,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":304,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":305,"author":{"gitId":"xenosf"},"content":" verifyInaccessibleForUnregisteredUsers(submissionParams);"},{"lineNumber":306,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":307,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":308,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":309,"author":{"gitId":"xenosf"},"content":" public void testAccessControl_studentAccessOwnCourseSessionResult_shouldPass() throws Exception {"},{"lineNumber":310,"author":{"gitId":"xenosf"},"content":" Student student1InCourse1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":311,"author":{"gitId":"xenosf"},"content":" Course typicalCourse1 \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":312,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":313,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":314,"author":{"gitId":"xenosf"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":315,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, typicalCourse1.getId(),"},{"lineNumber":316,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSession.getName(),"},{"lineNumber":317,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.toString(),"},{"lineNumber":318,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":319,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":320,"author":{"gitId":"xenosf"},"content":" loginAsStudent(student1InCourse1.getGoogleId());"},{"lineNumber":321,"author":{"gitId":"xenosf"},"content":" verifyCanAccess(submissionParams);"},{"lineNumber":322,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":323,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":324,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":325,"author":{"gitId":"xenosf"},"content":" public void testAccessControl_studentAccessUnpublishedSessionStudentResult_shouldFail() {"},{"lineNumber":326,"author":{"gitId":"xenosf"},"content":" Student student1InCourse1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":327,"author":{"gitId":"xenosf"},"content":" Course typicalCourse \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":328,"author":{"gitId":"xenosf"},"content":" FeedbackSession unpublishedFeedbackSession \u003d typicalBundle.feedbackSessions.get(\"session2InTypicalCourse\");"},{"lineNumber":329,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":330,"author":{"gitId":"xenosf"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":331,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, typicalCourse.getId(),"},{"lineNumber":332,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, unpublishedFeedbackSession.getName(),"},{"lineNumber":333,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.toString(),"},{"lineNumber":334,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":335,"author":{"gitId":"xenosf"},"content":" loginAsStudent(student1InCourse1.getGoogleId());"},{"lineNumber":336,"author":{"gitId":"xenosf"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":337,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":338,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":339,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":340,"author":{"gitId":"xenosf"},"content":" public void testAccessControl_accessStudentSessionResultWithMasqueradeMode_shouldPass() throws Exception {"},{"lineNumber":341,"author":{"gitId":"xenosf"},"content":" Student student1InCourse1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":342,"author":{"gitId":"xenosf"},"content":" Course typicalCourse1 \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":343,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":344,"author":{"gitId":"xenosf"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":345,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, typicalCourse1.getId(),"},{"lineNumber":346,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSession.getName(),"},{"lineNumber":347,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.toString(),"},{"lineNumber":348,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":349,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":350,"author":{"gitId":"xenosf"},"content":" loginAsAdmin();"},{"lineNumber":351,"author":{"gitId":"xenosf"},"content":" verifyCanMasquerade(student1InCourse1.getGoogleId(), submissionParams);"},{"lineNumber":352,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":353,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":354,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":355,"author":{"gitId":"xenosf"},"content":" public void testAccessControl_studentAccessOtherCourseSessionResult_shouldFail() {"},{"lineNumber":356,"author":{"gitId":"xenosf"},"content":" Student studentInOtherCourse \u003d typicalBundle.students.get(\"student2InCourse1\");"},{"lineNumber":357,"author":{"gitId":"xenosf"},"content":" Course otherCourse \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":358,"author":{"gitId":"xenosf"},"content":" Course course \u003d typicalBundle.courses.get(\"course3\");"},{"lineNumber":359,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession \u003d typicalBundle.feedbackSessions.get(\"ongoingSession1InCourse3\");"},{"lineNumber":360,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":361,"author":{"gitId":"xenosf"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":362,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":363,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSession.getName(),"},{"lineNumber":364,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.STUDENT_RESULT.toString(),"},{"lineNumber":365,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":366,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":367,"author":{"gitId":"xenosf"},"content":" loginAsStudent(studentInOtherCourse.getGoogleId());"},{"lineNumber":368,"author":{"gitId":"xenosf"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":369,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":370,"author":{"gitId":"xenosf"},"content":" // Malicious api call using course Id of the student to bypass the check"},{"lineNumber":371,"author":{"gitId":"xenosf"},"content":" submissionParams[1] \u003d otherCourse.getId();"},{"lineNumber":372,"author":{"gitId":"xenosf"},"content":" verifyEntityNotFoundAcl(submissionParams);"},{"lineNumber":373,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":374,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":375,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":376,"author":{"gitId":"xenosf"},"content":" public void testAccessControl_instructorAccessHisCourseFullDetail_shouldPass() throws Exception {"},{"lineNumber":377,"author":{"gitId":"xenosf"},"content":" Course typicalCourse1 \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":378,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":379,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":380,"author":{"gitId":"xenosf"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":381,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.COURSE_ID, typicalCourse1.getId(),"},{"lineNumber":382,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSession.getName(),"},{"lineNumber":383,"author":{"gitId":"xenosf"},"content":" Const.ParamsNames.INTENT, Intent.FULL_DETAIL.toString(),"},{"lineNumber":384,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":385,"author":{"gitId":"xenosf"},"content":" verifyOnlyInstructorsOfTheSameCourseCanAccess(typicalCourse1, submissionParams);"},{"lineNumber":386,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":387,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":388,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":361,"mingyuanc":27}},{"path":"src/it/java/teammates/it/ui/webapi/GetStudentsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.ui.output.StudentData;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.ui.output.StudentsData;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.GetStudentsAction;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * SUT: {@link GetStudentsAction}."},{"lineNumber":20,"author":{"gitId":"-"},"content":" */"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public class GetStudentsActionIT extends BaseActionIT\u003cGetStudentsAction\u003e {"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":24,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":25,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" super.setUp();"},{"lineNumber":27,"author":{"gitId":"-"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":28,"author":{"gitId":"-"},"content":" HibernateUtil.flushSession();"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":32,"author":{"gitId":"-"},"content":" String getActionUri() {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" return Const.ResourceURIs.STUDENTS;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":37,"author":{"gitId":"-"},"content":" String getRequestMethod() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" return GET;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":42,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":43,"author":{"gitId":"-"},"content":" protected void testExecute() throws Exception {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":45,"author":{"gitId":"-"},"content":" Student student \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":46,"author":{"gitId":"-"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case with only course id, logged in as instructor\");"},{"lineNumber":51,"author":{"gitId":"-"},"content":" String[] params \u003d new String[] {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":53,"author":{"gitId":"-"},"content":" };"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" GetStudentsAction getStudentsAction \u003d getAction(params);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" JsonResult jsonResult \u003d getJsonResult(getStudentsAction);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" StudentsData response \u003d (StudentsData) jsonResult.getOutput();"},{"lineNumber":58,"author":{"gitId":"-"},"content":" List\u003cStudentData\u003e students \u003d response.getStudents();"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"marquestye"},"content":" assertEquals(5, students.size());"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" StudentData firstStudentInStudents \u003d students.get(0);"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" assertNull(firstStudentInStudents.getGoogleId());"},{"lineNumber":65,"author":{"gitId":"-"},"content":" assertNull(firstStudentInStudents.getKey());"},{"lineNumber":66,"author":{"gitId":"-"},"content":" assertEquals(student.getName(), firstStudentInStudents.getName());"},{"lineNumber":67,"author":{"gitId":"-"},"content":" assertEquals(student.getCourseId(), firstStudentInStudents.getCourseId());"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" logoutUser();"},{"lineNumber":70,"author":{"gitId":"-"},"content":" loginAsStudent(student.getGoogleId());"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" ______TS(\"Typical Success Case with course id and team name, logged in as student\");"},{"lineNumber":73,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":75,"author":{"gitId":"-"},"content":" Const.ParamsNames.TEAM_NAME, student.getTeamName(),"},{"lineNumber":76,"author":{"gitId":"-"},"content":" };"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" getStudentsAction \u003d getAction(params);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" jsonResult \u003d getJsonResult(getStudentsAction);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" response \u003d (StudentsData) jsonResult.getOutput();"},{"lineNumber":81,"author":{"gitId":"-"},"content":" students \u003d response.getStudents();"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" Student expectedOtherTeamMember \u003d typicalBundle.students.get(\"student2InCourse1\");"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" assertEquals(4, students.size());"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" StudentData actualOtherTeamMember \u003d students.get(1);"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" assertNull(actualOtherTeamMember.getGoogleId());"},{"lineNumber":90,"author":{"gitId":"-"},"content":" assertNull(actualOtherTeamMember.getKey());"},{"lineNumber":91,"author":{"gitId":"-"},"content":" assertEquals(expectedOtherTeamMember.getName(), actualOtherTeamMember.getName());"},{"lineNumber":92,"author":{"gitId":"-"},"content":" assertEquals(expectedOtherTeamMember.getCourseId(), actualOtherTeamMember.getCourseId());"},{"lineNumber":93,"author":{"gitId":"-"},"content":" }"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":96,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":97,"author":{"gitId":"-"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":99,"author":{"gitId":"-"},"content":" Student student \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":100,"author":{"gitId":"-"},"content":" Instructor instructor \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" ______TS(\"Only instructors with correct privilege can access\");"},{"lineNumber":103,"author":{"gitId":"-"},"content":" String[] params \u003d new String[] {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":105,"author":{"gitId":"-"},"content":" };"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" verifyCanAccess(params);"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" ______TS(\"Student to view team members\");"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":114,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":115,"author":{"gitId":"-"},"content":" Const.ParamsNames.TEAM_NAME, student.getTeamName(),"},{"lineNumber":116,"author":{"gitId":"-"},"content":" };"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" loginAsStudent(student.getGoogleId());"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" verifyCanAccess(params);"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" ______TS(\"Unknown login entity\");"},{"lineNumber":123,"author":{"gitId":"-"},"content":" loginAsUnregistered(\"does-not-exist-id\");"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":126,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":127,"author":{"gitId":"-"},"content":" };"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" params \u003d new String[] {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":133,"author":{"gitId":"-"},"content":" Const.ParamsNames.TEAM_NAME, student.getTeamName(),"},{"lineNumber":134,"author":{"gitId":"-"},"content":" };"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" verifyCannotAccess(params);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":1,"dishenggg":1,"-":137}},{"path":"src/it/java/teammates/it/ui/webapi/InstructorSearchIndexingWorkerActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"mingyuanc"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":3,"author":{"gitId":"mingyuanc"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":5,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":6,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":8,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":9,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":10,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.util.Const;"},{"lineNumber":11,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":12,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":13,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":14,"author":{"gitId":"mingyuanc"},"content":"import teammates.test.TestProperties;"},{"lineNumber":15,"author":{"gitId":"mingyuanc"},"content":"import teammates.ui.webapi.InstructorSearchIndexingWorkerAction;"},{"lineNumber":16,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":17,"author":{"gitId":"mingyuanc"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"mingyuanc"},"content":" * SUT: {@link InstructorSearchIndexingWorkerAction}."},{"lineNumber":19,"author":{"gitId":"mingyuanc"},"content":" */"},{"lineNumber":20,"author":{"gitId":"mingyuanc"},"content":"public class InstructorSearchIndexingWorkerActionIT extends BaseActionIT\u003cInstructorSearchIndexingWorkerAction\u003e {"},{"lineNumber":21,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":22,"author":{"gitId":"mingyuanc"},"content":" @BeforeMethod"},{"lineNumber":23,"author":{"gitId":"mingyuanc"},"content":" protected void setUp() throws Exception {"},{"lineNumber":24,"author":{"gitId":"mingyuanc"},"content":" super.setUp();"},{"lineNumber":25,"author":{"gitId":"mingyuanc"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":26,"author":{"gitId":"mingyuanc"},"content":" HibernateUtil.flushSession();"},{"lineNumber":27,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":28,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":29,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":30,"author":{"gitId":"mingyuanc"},"content":" protected String getActionUri() {"},{"lineNumber":31,"author":{"gitId":"mingyuanc"},"content":" return Const.TaskQueue.INSTRUCTOR_SEARCH_INDEXING_WORKER_URL;"},{"lineNumber":32,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":33,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":34,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":35,"author":{"gitId":"mingyuanc"},"content":" protected String getRequestMethod() {"},{"lineNumber":36,"author":{"gitId":"mingyuanc"},"content":" return POST;"},{"lineNumber":37,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":38,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":39,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":40,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":41,"author":{"gitId":"mingyuanc"},"content":" public void testExecute() throws Exception {"},{"lineNumber":42,"author":{"gitId":"mingyuanc"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":43,"author":{"gitId":"mingyuanc"},"content":" return;"},{"lineNumber":44,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":45,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":46,"author":{"gitId":"mingyuanc"},"content":" Instructor instructor1 \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":47,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":48,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"instructor not yet indexed should not be searchable\");"},{"lineNumber":49,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":50,"author":{"gitId":"mingyuanc"},"content":" List\u003cInstructor\u003e instructorList \u003d logic.searchInstructorsInWholeSystem(instructor1.getEmail());"},{"lineNumber":51,"author":{"gitId":"mingyuanc"},"content":" assertEquals(0, instructorList.size());"},{"lineNumber":52,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":53,"author":{"gitId":"mingyuanc"},"content":" ______TS(\"instructor indexed should be searchable\");"},{"lineNumber":54,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":55,"author":{"gitId":"mingyuanc"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":56,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.COURSE_ID, instructor1.getCourseId(),"},{"lineNumber":57,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.INSTRUCTOR_EMAIL, instructor1.getEmail(),"},{"lineNumber":58,"author":{"gitId":"mingyuanc"},"content":" };"},{"lineNumber":59,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":60,"author":{"gitId":"mingyuanc"},"content":" InstructorSearchIndexingWorkerAction action \u003d getAction(submissionParams);"},{"lineNumber":61,"author":{"gitId":"mingyuanc"},"content":" getJsonResult(action);"},{"lineNumber":62,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":63,"author":{"gitId":"mingyuanc"},"content":" instructorList \u003d logic.searchInstructorsInWholeSystem(instructor1.getEmail());"},{"lineNumber":64,"author":{"gitId":"mingyuanc"},"content":" assertEquals(1, instructorList.size());"},{"lineNumber":65,"author":{"gitId":"mingyuanc"},"content":" assertEquals(instructor1.getId(), instructorList.get(0).getId());"},{"lineNumber":66,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":67,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":68,"author":{"gitId":"mingyuanc"},"content":" @Override"},{"lineNumber":69,"author":{"gitId":"mingyuanc"},"content":" protected void testAccessControl() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":70,"author":{"gitId":"mingyuanc"},"content":" Instructor instructor1 \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":71,"author":{"gitId":"mingyuanc"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":72,"author":{"gitId":"mingyuanc"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":73,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.COURSE_ID, instructor1.getCourseId(),"},{"lineNumber":74,"author":{"gitId":"mingyuanc"},"content":" Const.ParamsNames.INSTRUCTOR_EMAIL, instructor1.getEmail(),"},{"lineNumber":75,"author":{"gitId":"mingyuanc"},"content":" };"},{"lineNumber":76,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":77,"author":{"gitId":"mingyuanc"},"content":" verifyOnlyAdminCanAccess(course, submissionParams);"},{"lineNumber":78,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":79,"author":{"gitId":"mingyuanc"},"content":"}"}],"authorContributionMap":{"mingyuanc":79}},{"path":"src/it/java/teammates/it/ui/webapi/JoinCourseActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"yuanxi1"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":3,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":4,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.Test;"},{"lineNumber":5,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":6,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.Const;"},{"lineNumber":7,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.EmailType;"},{"lineNumber":8,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":9,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":10,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":11,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":12,"author":{"gitId":"yuanxi1"},"content":"import teammates.ui.webapi.InvalidOperationException;"},{"lineNumber":13,"author":{"gitId":"yuanxi1"},"content":"import teammates.ui.webapi.JoinCourseAction;"},{"lineNumber":14,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":15,"author":{"gitId":"yuanxi1"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"yuanxi1"},"content":" * SUT: {@link JoinCourseAction}."},{"lineNumber":17,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":18,"author":{"gitId":"yuanxi1"},"content":"public class JoinCourseActionIT extends BaseActionIT\u003cJoinCourseAction\u003e {"},{"lineNumber":19,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":20,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":21,"author":{"gitId":"yuanxi1"},"content":" @BeforeMethod"},{"lineNumber":22,"author":{"gitId":"yuanxi1"},"content":" protected void setUp() throws Exception {"},{"lineNumber":23,"author":{"gitId":"yuanxi1"},"content":" super.setUp();"},{"lineNumber":24,"author":{"gitId":"yuanxi1"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":25,"author":{"gitId":"yuanxi1"},"content":" HibernateUtil.flushSession();"},{"lineNumber":26,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":27,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":28,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":29,"author":{"gitId":"yuanxi1"},"content":" String getActionUri() {"},{"lineNumber":30,"author":{"gitId":"yuanxi1"},"content":" return Const.ResourceURIs.JOIN;"},{"lineNumber":31,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":32,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":33,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":34,"author":{"gitId":"yuanxi1"},"content":" String getRequestMethod() {"},{"lineNumber":35,"author":{"gitId":"yuanxi1"},"content":" return PUT;"},{"lineNumber":36,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":37,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":38,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":39,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":40,"author":{"gitId":"yuanxi1"},"content":" protected void testExecute() throws Exception {"},{"lineNumber":41,"author":{"gitId":"yuanxi1"},"content":" Student studentYetToJoinCourse \u003d typicalBundle.students.get(\"student2YetToJoinCourse4\");"},{"lineNumber":42,"author":{"gitId":"yuanxi1"},"content":" String student1RegKey \u003d"},{"lineNumber":43,"author":{"gitId":"yuanxi1"},"content":" getRegKeyForStudent(studentYetToJoinCourse.getCourseId(), studentYetToJoinCourse.getEmail());"},{"lineNumber":44,"author":{"gitId":"yuanxi1"},"content":" String loggedInGoogleIdStu \u003d \"AccLogicT.student.id\";"},{"lineNumber":45,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":46,"author":{"gitId":"yuanxi1"},"content":" Instructor instructorYetToJoinCourse \u003d typicalBundle.instructors.get(\"instructor2YetToJoinCourse4\");"},{"lineNumber":47,"author":{"gitId":"yuanxi1"},"content":" String instructor1RegKey \u003d"},{"lineNumber":48,"author":{"gitId":"yuanxi1"},"content":" getRegKeyForInstructor(instructorYetToJoinCourse.getCourseId(), instructorYetToJoinCourse.getEmail());"},{"lineNumber":49,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":50,"author":{"gitId":"yuanxi1"},"content":" String loggedInGoogleIdInst \u003d \"AccLogicT.instr.id\";"},{"lineNumber":51,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":52,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: student joins course\");"},{"lineNumber":53,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":54,"author":{"gitId":"yuanxi1"},"content":" loginAsUnregistered(loggedInGoogleIdStu);"},{"lineNumber":55,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":56,"author":{"gitId":"yuanxi1"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":57,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.REGKEY, student1RegKey,"},{"lineNumber":58,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.STUDENT,"},{"lineNumber":59,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":60,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":61,"author":{"gitId":"yuanxi1"},"content":" JoinCourseAction joinCourseAction \u003d getAction(submissionParams);"},{"lineNumber":62,"author":{"gitId":"yuanxi1"},"content":" getJsonResult(joinCourseAction);"},{"lineNumber":63,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":64,"author":{"gitId":"yuanxi1"},"content":" verifyNumberOfEmailsSent(1);"},{"lineNumber":65,"author":{"gitId":"yuanxi1"},"content":" EmailWrapper email \u003d mockEmailSender.getEmailsSent().get(0);"},{"lineNumber":66,"author":{"gitId":"yuanxi1"},"content":" assertEquals("},{"lineNumber":67,"author":{"gitId":"yuanxi1"},"content":" String.format(EmailType.USER_COURSE_REGISTER.getSubject(), \"Typical Course 4\", \"course-4\"),"},{"lineNumber":68,"author":{"gitId":"yuanxi1"},"content":" email.getSubject());"},{"lineNumber":69,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":70,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: student is already registered\");"},{"lineNumber":71,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":72,"author":{"gitId":"yuanxi1"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":73,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.REGKEY, student1RegKey,"},{"lineNumber":74,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.STUDENT,"},{"lineNumber":75,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":76,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":77,"author":{"gitId":"yuanxi1"},"content":" InvalidOperationException ioe \u003d verifyInvalidOperation(submissionParams);"},{"lineNumber":78,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"Student has already joined course\", ioe.getMessage());"},{"lineNumber":79,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":80,"author":{"gitId":"yuanxi1"},"content":" verifyNoEmailsSent();"},{"lineNumber":81,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":82,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"success: instructor joins course\");"},{"lineNumber":83,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":84,"author":{"gitId":"yuanxi1"},"content":" loginAsUnregistered(loggedInGoogleIdInst);"},{"lineNumber":85,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":86,"author":{"gitId":"yuanxi1"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":87,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.REGKEY, instructor1RegKey,"},{"lineNumber":88,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":89,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":90,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":91,"author":{"gitId":"yuanxi1"},"content":" joinCourseAction \u003d getAction(submissionParams);"},{"lineNumber":92,"author":{"gitId":"yuanxi1"},"content":" getJsonResult(joinCourseAction);"},{"lineNumber":93,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":94,"author":{"gitId":"yuanxi1"},"content":" verifyNumberOfEmailsSent(1);"},{"lineNumber":95,"author":{"gitId":"yuanxi1"},"content":" email \u003d mockEmailSender.getEmailsSent().get(0);"},{"lineNumber":96,"author":{"gitId":"yuanxi1"},"content":" assertEquals("},{"lineNumber":97,"author":{"gitId":"yuanxi1"},"content":" String.format(EmailType.USER_COURSE_REGISTER.getSubject(), \"Typical Course 4\", \"course-4\"),"},{"lineNumber":98,"author":{"gitId":"yuanxi1"},"content":" email.getSubject());"},{"lineNumber":99,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":100,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: instructor is already registered\");"},{"lineNumber":101,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":102,"author":{"gitId":"yuanxi1"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":103,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.REGKEY, instructor1RegKey,"},{"lineNumber":104,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":105,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":106,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":107,"author":{"gitId":"yuanxi1"},"content":" ioe \u003d verifyInvalidOperation(submissionParams);"},{"lineNumber":108,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"Instructor has already joined course\", ioe.getMessage());"},{"lineNumber":109,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":110,"author":{"gitId":"yuanxi1"},"content":" verifyNoEmailsSent();"},{"lineNumber":111,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":112,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: invalid regkey\");"},{"lineNumber":113,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":114,"author":{"gitId":"yuanxi1"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":115,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.REGKEY, \"ANXKJZNZXNJCZXKJDNKSDA\","},{"lineNumber":116,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.STUDENT,"},{"lineNumber":117,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":118,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":119,"author":{"gitId":"yuanxi1"},"content":" verifyEntityNotFound(submissionParams);"},{"lineNumber":120,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":121,"author":{"gitId":"yuanxi1"},"content":" verifyNoEmailsSent();"},{"lineNumber":122,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":123,"author":{"gitId":"yuanxi1"},"content":" ______TS(\"failure: invalid entity type\");"},{"lineNumber":124,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":125,"author":{"gitId":"yuanxi1"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":126,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.REGKEY, student1RegKey,"},{"lineNumber":127,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, \"invalid_entity_type\","},{"lineNumber":128,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":129,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":130,"author":{"gitId":"yuanxi1"},"content":" verifyHttpParameterFailure(submissionParams);"},{"lineNumber":131,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":132,"author":{"gitId":"yuanxi1"},"content":" verifyNoEmailsSent();"},{"lineNumber":133,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":134,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":135,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":136,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":137,"author":{"gitId":"yuanxi1"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":138,"author":{"gitId":"yuanxi1"},"content":" verifyAnyLoggedInUserCanAccess();"},{"lineNumber":139,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":140,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":141,"author":{"gitId":"yuanxi1"},"content":" private String getRegKeyForStudent(String courseId, String email) {"},{"lineNumber":142,"author":{"gitId":"yuanxi1"},"content":" return logic.getStudentForEmail(courseId, email).getRegKey();"},{"lineNumber":143,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":144,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":145,"author":{"gitId":"yuanxi1"},"content":" private String getRegKeyForInstructor(String courseId, String email) {"},{"lineNumber":146,"author":{"gitId":"yuanxi1"},"content":" return logic.getInstructorForEmail(courseId, email).getRegKey();"},{"lineNumber":147,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":148,"author":{"gitId":"yuanxi1"},"content":"}"}],"authorContributionMap":{"yuanxi1":148}},{"path":"src/it/java/teammates/it/ui/webapi/RejectAccountRequestActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import java.util.UUID;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.AfterMethod;"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":"import org.testng.annotations.Test;"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Config;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const;"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.EmailType;"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":"import teammates.ui.output.AccountRequestData;"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":"import teammates.ui.request.AccountRequestRejectionRequest;"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":"import teammates.ui.webapi.EntityNotFoundException;"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":"import teammates.ui.webapi.InvalidHttpParameterException;"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":"import teammates.ui.webapi.InvalidOperationException;"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":"import teammates.ui.webapi.RejectAccountRequestAction;"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" * SUT: {@link RejectAccountRequestAction}."},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":"public class RejectAccountRequestActionIT extends BaseActionIT\u003cRejectAccountRequestAction\u003e {"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" private static final String TYPICAL_TITLE \u003d \"We are Unable to Create an Account for you\";"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" private static final String TYPICAL_BODY \u003d new StringBuilder()"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003eHi, Example\u003c/p\u003e\\n\")"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003eThanks for your interest in using TEAMMATES. \")"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" .append(\"We are unable to create a TEAMMATES instructor account for you.\u003c/p\u003e\\n\\n\")"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003e\\n\")"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" .append(\" \u003cstrong\u003eReason:\u003c/strong\u003e The email address you provided \")"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" .append(\"is not an \u0027official\u0027 email address provided by your institution.\u003cbr /\u003e\\n\")"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" .append(\" \u003cstrong\u003eRemedy:\u003c/strong\u003e \")"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" .append(\"Please re-submit an account request with your \u0027official\u0027 institution email address.\\n\")"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" .append(\"\u003c/p\u003e\\n\\n\")"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003eIf you need further clarification or would like to appeal this decision, \")"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" .append(\"please feel free to contact us at teammates@comp.nus.edu.sg.\u003c/p\u003e\\n\")"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003eRegards,\u003cbr /\u003eTEAMMATES Team.\u003c/p\u003e\\n\")"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" .toString();"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" @BeforeMethod"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" protected void setUp() throws Exception {"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" // no need to call super.setUp() because the action handles its own transactions"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" protected String getActionUri() {"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" return Const.ResourceURIs.ACCOUNT_REQUEST_REJECTION;"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" protected String getRequestMethod() {"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" return POST;"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":67,"author":{"gitId":"xenosf"},"content":" public void testExecute() throws Exception {"},{"lineNumber":68,"author":{"gitId":"xenosf"},"content":" // See individual test methods below"},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" protected void testExecute_withReasonTitleAndBody_shouldRejectWithEmail()"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" throws InvalidOperationException, InvalidHttpRequestBodyException, InvalidParametersException {"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" AccountRequest bundleAccountRequest \u003d typicalBundle.accountRequests.get(\"unregisteredInstructor1\");"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d logic.createAccountRequestWithTransaction(bundleAccountRequest.getName(),"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" bundleAccountRequest.getEmail(), bundleAccountRequest.getInstitute(),"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" AccountRequestStatus.PENDING, bundleAccountRequest.getComments());"},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" UUID id \u003d accountRequest.getId();"},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest requestBody \u003d new AccountRequestRejectionRequest(TYPICAL_TITLE, TYPICAL_BODY);"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":" String[] params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" RejectAccountRequestAction action \u003d getAction(requestBody, params);"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":" JsonResult result \u003d action.execute();"},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":" assertEquals(200, result.getStatusCode());"},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" AccountRequestData data \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getName(), data.getName());"},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getEmail(), data.getEmail());"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getInstitute(), data.getInstitute());"},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":" assertEquals(AccountRequestStatus.REJECTED, data.getStatus());"},{"lineNumber":93,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getComments(), data.getComments());"},{"lineNumber":94,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":" verifyNumberOfEmailsSent(1);"},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":" EmailWrapper sentEmail \u003d mockEmailSender.getEmailsSent().get(0);"},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" assertEquals(EmailType.ACCOUNT_REQUEST_REJECTION, sentEmail.getType());"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" assertEquals(Config.SUPPORT_EMAIL, sentEmail.getBcc());"},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getEmail(), sentEmail.getRecipient());"},{"lineNumber":100,"author":{"gitId":"xenosf"},"content":" assertEquals(SanitizationHelper.sanitizeForRichText(TYPICAL_BODY), sentEmail.getContent());"},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":" assertEquals(\"TEAMMATES: \" + TYPICAL_TITLE, sentEmail.getSubject());"},{"lineNumber":102,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":103,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":104,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":105,"author":{"gitId":"xenosf"},"content":" protected void testExecute_withoutReasonTitleAndBody_shouldRejectWithoutEmail()"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" throws InvalidOperationException, InvalidHttpRequestBodyException, InvalidParametersException {"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" AccountRequest bundleAccountRequest \u003d typicalBundle.accountRequests.get(\"unregisteredInstructor1\");"},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d logic.createAccountRequestWithTransaction(bundleAccountRequest.getName(),"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" bundleAccountRequest.getEmail(), bundleAccountRequest.getInstitute(),"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" AccountRequestStatus.PENDING, bundleAccountRequest.getComments());"},{"lineNumber":111,"author":{"gitId":"xenosf"},"content":" UUID id \u003d accountRequest.getId();"},{"lineNumber":112,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":113,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest requestBody \u003d new AccountRequestRejectionRequest(null, null);"},{"lineNumber":114,"author":{"gitId":"xenosf"},"content":" String[] params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":115,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" RejectAccountRequestAction action \u003d getAction(requestBody, params);"},{"lineNumber":117,"author":{"gitId":"xenosf"},"content":" JsonResult result \u003d action.execute();"},{"lineNumber":118,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":119,"author":{"gitId":"xenosf"},"content":" assertEquals(200, result.getStatusCode());"},{"lineNumber":120,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":121,"author":{"gitId":"xenosf"},"content":" AccountRequestData data \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":122,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getName(), data.getName());"},{"lineNumber":123,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getEmail(), data.getEmail());"},{"lineNumber":124,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getInstitute(), data.getInstitute());"},{"lineNumber":125,"author":{"gitId":"xenosf"},"content":" assertEquals(AccountRequestStatus.REJECTED, data.getStatus());"},{"lineNumber":126,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getComments(), data.getComments());"},{"lineNumber":127,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":128,"author":{"gitId":"xenosf"},"content":" verifyNoEmailsSent();"},{"lineNumber":129,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":130,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":131,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":" protected void testExecute_withReasonBodyButNoTitle_shouldThrow() throws InvalidParametersException {"},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" AccountRequest bundleAccountRequest \u003d typicalBundle.accountRequests.get(\"unregisteredInstructor1\");"},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d logic.createAccountRequestWithTransaction(bundleAccountRequest.getName(),"},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":" bundleAccountRequest.getEmail(), bundleAccountRequest.getInstitute(),"},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" bundleAccountRequest.getStatus(), bundleAccountRequest.getComments());"},{"lineNumber":137,"author":{"gitId":"xenosf"},"content":" UUID id \u003d accountRequest.getId();"},{"lineNumber":138,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":139,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest requestBody \u003d new AccountRequestRejectionRequest(null, TYPICAL_BODY);"},{"lineNumber":140,"author":{"gitId":"xenosf"},"content":" String[] params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":141,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":142,"author":{"gitId":"xenosf"},"content":" InvalidHttpRequestBodyException ihrbe \u003d verifyHttpRequestBodyFailure(requestBody, params);"},{"lineNumber":143,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":144,"author":{"gitId":"xenosf"},"content":" assertEquals(\"Both reason body and title need to be null to reject silently\", ihrbe.getMessage());"},{"lineNumber":145,"author":{"gitId":"xenosf"},"content":" verifyNoEmailsSent();"},{"lineNumber":146,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":147,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":148,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":149,"author":{"gitId":"domoberzin"},"content":" protected void testExecute_withReasonTitleButNoBody_shouldThrow() throws InvalidParametersException {"},{"lineNumber":150,"author":{"gitId":"domoberzin"},"content":" AccountRequest bundleAccountRequest \u003d typicalBundle.accountRequests.get(\"unregisteredInstructor1\");"},{"lineNumber":151,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d logic.createAccountRequestWithTransaction(bundleAccountRequest.getName(),"},{"lineNumber":152,"author":{"gitId":"domoberzin"},"content":" bundleAccountRequest.getEmail(), bundleAccountRequest.getInstitute(),"},{"lineNumber":153,"author":{"gitId":"domoberzin"},"content":" bundleAccountRequest.getStatus(), bundleAccountRequest.getComments());"},{"lineNumber":154,"author":{"gitId":"xenosf"},"content":" UUID id \u003d accountRequest.getId();"},{"lineNumber":155,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":156,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest requestBody \u003d new AccountRequestRejectionRequest(TYPICAL_TITLE, null);"},{"lineNumber":157,"author":{"gitId":"xenosf"},"content":" String[] params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":158,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":159,"author":{"gitId":"xenosf"},"content":" InvalidHttpRequestBodyException ihrbe \u003d verifyHttpRequestBodyFailure(requestBody, params);"},{"lineNumber":160,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":161,"author":{"gitId":"xenosf"},"content":" assertEquals(\"Both reason body and title need to be null to reject silently\", ihrbe.getMessage());"},{"lineNumber":162,"author":{"gitId":"xenosf"},"content":" verifyNoEmailsSent();"},{"lineNumber":163,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":164,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":165,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":166,"author":{"gitId":"xenosf"},"content":" protected void testExecute_alreadyRejected_shouldNotSendEmail()"},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" throws InvalidOperationException, InvalidHttpRequestBodyException, InvalidParametersException {"},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":" AccountRequest bundleAccountRequest \u003d typicalBundle.accountRequests.get(\"unregisteredInstructor1\");"},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d logic.createAccountRequestWithTransaction(bundleAccountRequest.getName(),"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" bundleAccountRequest.getEmail(), bundleAccountRequest.getInstitute(),"},{"lineNumber":171,"author":{"gitId":"domoberzin"},"content":" AccountRequestStatus.REJECTED, bundleAccountRequest.getComments());"},{"lineNumber":172,"author":{"gitId":"xenosf"},"content":" UUID id \u003d accountRequest.getId();"},{"lineNumber":173,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":174,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest requestBody \u003d new AccountRequestRejectionRequest(TYPICAL_TITLE, TYPICAL_BODY);"},{"lineNumber":175,"author":{"gitId":"xenosf"},"content":" String[] params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":176,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":177,"author":{"gitId":"xenosf"},"content":" RejectAccountRequestAction action \u003d getAction(requestBody, params);"},{"lineNumber":178,"author":{"gitId":"xenosf"},"content":" JsonResult result \u003d action.execute();"},{"lineNumber":179,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":180,"author":{"gitId":"xenosf"},"content":" assertEquals(result.getStatusCode(), 200);"},{"lineNumber":181,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":182,"author":{"gitId":"xenosf"},"content":" AccountRequestData data \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":183,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getName(), data.getName());"},{"lineNumber":184,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getEmail(), data.getEmail());"},{"lineNumber":185,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getInstitute(), data.getInstitute());"},{"lineNumber":186,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getStatus(), data.getStatus());"},{"lineNumber":187,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest.getComments(), data.getComments());"},{"lineNumber":188,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":189,"author":{"gitId":"xenosf"},"content":" verifyNoEmailsSent();"},{"lineNumber":190,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":191,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":192,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":" protected void testExecute_invalidUuid_shouldThrow() throws InvalidParametersException {"},{"lineNumber":194,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest requestBody \u003d new AccountRequestRejectionRequest(null, null);"},{"lineNumber":195,"author":{"gitId":"xenosf"},"content":" String[] params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, \"invalid\"};"},{"lineNumber":196,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":197,"author":{"gitId":"xenosf"},"content":" InvalidHttpParameterException ihpe \u003d verifyHttpParameterFailure(requestBody, params);"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"Expected UUID value for id parameter, but found: [invalid]\", ihpe.getMessage());"},{"lineNumber":199,"author":{"gitId":"xenosf"},"content":" verifyNoEmailsSent();"},{"lineNumber":200,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":201,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":202,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":203,"author":{"gitId":"xenosf"},"content":" protected void testExecute_accountRequestNotFound_shouldThrow() {"},{"lineNumber":204,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest requestBody \u003d new AccountRequestRejectionRequest(null, null);"},{"lineNumber":205,"author":{"gitId":"xenosf"},"content":" String uuid \u003d UUID.randomUUID().toString();"},{"lineNumber":206,"author":{"gitId":"xenosf"},"content":" String[] params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, uuid};"},{"lineNumber":207,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":208,"author":{"gitId":"xenosf"},"content":" EntityNotFoundException enfe \u003d verifyEntityNotFound(requestBody, params);"},{"lineNumber":209,"author":{"gitId":"xenosf"},"content":" assertEquals(String.format(\"Account request with id \u003d %s not found\", uuid), enfe.getMessage());"},{"lineNumber":210,"author":{"gitId":"xenosf"},"content":" verifyNoEmailsSent();"},{"lineNumber":211,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":212,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":213,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" protected void testAccessControl() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":216,"author":{"gitId":"domoberzin"},"content":" verifyOnlyAdminCanAccessWithTransaction();"},{"lineNumber":217,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":218,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":219,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":220,"author":{"gitId":"domoberzin"},"content":" @AfterMethod"},{"lineNumber":221,"author":{"gitId":"domoberzin"},"content":" protected void tearDown() {"},{"lineNumber":222,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":223,"author":{"gitId":"domoberzin"},"content":" List\u003cAccountRequest\u003e accountRequests \u003d logic.getAllAccountRequests();"},{"lineNumber":224,"author":{"gitId":"domoberzin"},"content":" for (AccountRequest ar : accountRequests) {"},{"lineNumber":225,"author":{"gitId":"-"},"content":" logic.deleteAccountRequest(ar.getId());"},{"lineNumber":226,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":227,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":228,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":229,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"domoberzin":41,"xenosf":187,"-":1}},{"path":"src/it/java/teammates/it/ui/webapi/SearchAccountRequestsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.Test;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.Const;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import teammates.test.TestProperties;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.output.AccountRequestsData;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.output.MessageOutput;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.SearchAccountRequestsAction;"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" * SUT: {@link SearchAccountRequestsAction}."},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":"public class SearchAccountRequestsActionIT extends BaseActionIT\u003cSearchAccountRequestsAction\u003e {"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" protected void testAccessControl() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" verifyOnlyAdminCanAccess(course);"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" @BeforeMethod"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" protected void setUp() throws Exception {"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" super.setUp();"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" putDocuments(typicalBundle);"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.flushSession();"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" protected String getActionUri() {"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" return Const.ResourceURIs.SEARCH_ACCOUNT_REQUESTS;"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" protected String getRequestMethod() {"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" return GET;"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" protected void testExecute() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Search with SearchService disabled\");"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" String[] submissionParams \u003d new String[] { Const.ParamsNames.SEARCH_KEY, \"randomString123\" };"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" SearchAccountRequestsAction action \u003d getAction(submissionParams);"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" JsonResult result \u003d getJsonResult(action, HttpStatus.SC_NOT_IMPLEMENTED);"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" MessageOutput output \u003d (MessageOutput) result.getOutput();"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"Full-text search is not available.\", output.getMessage());"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" return;"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d typicalBundle.accountRequests.get(\"instructor1\");"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" loginAsAdmin();"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Search via Email\");"},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" String[] submissionParams \u003d new String[] { Const.ParamsNames.SEARCH_KEY, accountRequest.getEmail() };"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":" SearchAccountRequestsAction action \u003d getAction(submissionParams);"},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" JsonResult result \u003d getJsonResult(action, 200);"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" AccountRequestsData response \u003d (AccountRequestsData) result.getOutput();"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" assertTrue(response.getAccountRequests().stream()"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" .filter(i -\u003e i.getName().equals(accountRequest.getName()))"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" .findAny()"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" .isPresent());"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" assertTrue(response.getAccountRequests().get(0).getRegistrationKey() !\u003d null);"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Search via Institute\");"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" submissionParams \u003d new String[] { Const.ParamsNames.SEARCH_KEY, accountRequest.getInstitute() };"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" action \u003d getAction(submissionParams);"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" result \u003d getJsonResult(action, 200);"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" response \u003d (AccountRequestsData) result.getOutput();"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" assertTrue(response.getAccountRequests().stream()"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" .filter(i -\u003e i.getName().equals(accountRequest.getName()))"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" .findAny()"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" .isPresent());"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":" assertTrue(response.getAccountRequests().get(0).getRegistrationKey() !\u003d null);"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Search via Name\");"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" submissionParams \u003d new String[] { Const.ParamsNames.SEARCH_KEY, accountRequest.getName() };"},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" action \u003d getAction(submissionParams);"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" result \u003d getJsonResult(action, 200);"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" response \u003d (AccountRequestsData) result.getOutput();"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":" assertTrue(response.getAccountRequests().stream()"},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":" .filter(i -\u003e i.getName().equals(accountRequest.getName()))"},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" .findAny()"},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" .isPresent());"},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":" assertTrue(response.getAccountRequests().get(0).getRegistrationKey() !\u003d null);"},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Search Duplicate Name\");"},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":" submissionParams \u003d new String[] { Const.ParamsNames.SEARCH_KEY, \"Instructor\" };"},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" action \u003d getAction(submissionParams);"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" result \u003d getJsonResult(action, 200);"},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":" response \u003d (AccountRequestsData) result.getOutput();"},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" assertTrue(response.getAccountRequests().get(0).getRegistrationKey() !\u003d null);"},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" assertEquals(11, response.getAccountRequests().size());"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" ______TS(\"Search result with 0 matches\");"},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" submissionParams \u003d new String[] { Const.ParamsNames.SEARCH_KEY, \"randomString123\" };"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" action \u003d getAction(submissionParams);"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" result \u003d getJsonResult(action, 200);"},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" response \u003d (AccountRequestsData) result.getOutput();"},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" assertEquals(0, response.getAccountRequests().size());"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":115}},{"path":"src/it/java/teammates/it/ui/webapi/SearchStudentsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"yuanxi1"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":3,"author":{"gitId":"yuanxi1"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":4,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":5,"author":{"gitId":"yuanxi1"},"content":"import org.testng.annotations.Test;"},{"lineNumber":6,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":7,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":8,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":9,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.Const;"},{"lineNumber":10,"author":{"gitId":"yuanxi1"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":11,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":12,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":13,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":14,"author":{"gitId":"yuanxi1"},"content":"import teammates.test.TestProperties;"},{"lineNumber":15,"author":{"gitId":"yuanxi1"},"content":"import teammates.ui.output.MessageOutput;"},{"lineNumber":16,"author":{"gitId":"yuanxi1"},"content":"import teammates.ui.output.StudentsData;"},{"lineNumber":17,"author":{"gitId":"yuanxi1"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":18,"author":{"gitId":"yuanxi1"},"content":"import teammates.ui.webapi.SearchStudentsAction;"},{"lineNumber":19,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":20,"author":{"gitId":"yuanxi1"},"content":"/**"},{"lineNumber":21,"author":{"gitId":"yuanxi1"},"content":" * SUT: {@link SearchStudentsAction}."},{"lineNumber":22,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":23,"author":{"gitId":"yuanxi1"},"content":"public class SearchStudentsActionIT extends BaseActionIT\u003cSearchStudentsAction\u003e {"},{"lineNumber":24,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":25,"author":{"gitId":"yuanxi1"},"content":" private final Student student1InCourse1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":26,"author":{"gitId":"yuanxi1"},"content":" private final Instructor instructor1OfCourse1 \u003d typicalBundle.instructors.get(\"instructor1OfCourse1\");"},{"lineNumber":27,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":28,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":29,"author":{"gitId":"yuanxi1"},"content":" @BeforeMethod"},{"lineNumber":30,"author":{"gitId":"yuanxi1"},"content":" protected void setUp() throws Exception {"},{"lineNumber":31,"author":{"gitId":"yuanxi1"},"content":" super.setUp();"},{"lineNumber":32,"author":{"gitId":"yuanxi1"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":33,"author":{"gitId":"yuanxi1"},"content":" putDocuments(typicalBundle);"},{"lineNumber":34,"author":{"gitId":"yuanxi1"},"content":" HibernateUtil.flushSession();"},{"lineNumber":35,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":36,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":37,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"yuanxi1"},"content":" protected String getActionUri() {"},{"lineNumber":39,"author":{"gitId":"yuanxi1"},"content":" return Const.ResourceURIs.SEARCH_STUDENTS;"},{"lineNumber":40,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":41,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":42,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":43,"author":{"gitId":"yuanxi1"},"content":" protected String getRequestMethod() {"},{"lineNumber":44,"author":{"gitId":"yuanxi1"},"content":" return GET;"},{"lineNumber":45,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":46,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":47,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":48,"author":{"gitId":"yuanxi1"},"content":" protected void testExecute() {"},{"lineNumber":49,"author":{"gitId":"yuanxi1"},"content":" // See test cases below."},{"lineNumber":50,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":51,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":52,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":53,"author":{"gitId":"yuanxi1"},"content":" public void execute_invalidParameters_parameterFailure() {"},{"lineNumber":54,"author":{"gitId":"yuanxi1"},"content":" loginAsAdmin();"},{"lineNumber":55,"author":{"gitId":"yuanxi1"},"content":" verifyHttpParameterFailure();"},{"lineNumber":56,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":57,"author":{"gitId":"yuanxi1"},"content":" String[] notEnoughParams \u003d new String[] {"},{"lineNumber":58,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, \"dummy\","},{"lineNumber":59,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":60,"author":{"gitId":"yuanxi1"},"content":" verifyHttpParameterFailure(notEnoughParams);"},{"lineNumber":61,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":62,"author":{"gitId":"yuanxi1"},"content":" String[] invalidEntityParams \u003d new String[] {"},{"lineNumber":63,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, \"dummy\","},{"lineNumber":64,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, \"dummy\","},{"lineNumber":65,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":66,"author":{"gitId":"yuanxi1"},"content":" verifyHttpParameterFailure(invalidEntityParams);"},{"lineNumber":67,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":68,"author":{"gitId":"yuanxi1"},"content":" String[] adminParams \u003d new String[] {"},{"lineNumber":69,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, \"dummy\","},{"lineNumber":70,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.ADMIN,"},{"lineNumber":71,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":72,"author":{"gitId":"yuanxi1"},"content":" String[] instructorParams \u003d new String[] {"},{"lineNumber":73,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, \"dummy\","},{"lineNumber":74,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":75,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":76,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":77,"author":{"gitId":"yuanxi1"},"content":" loginAsAdmin();"},{"lineNumber":78,"author":{"gitId":"yuanxi1"},"content":" verifyHttpParameterFailure(instructorParams);"},{"lineNumber":79,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":80,"author":{"gitId":"yuanxi1"},"content":" loginAsInstructor(instructor1OfCourse1.getGoogleId());"},{"lineNumber":81,"author":{"gitId":"yuanxi1"},"content":" verifyHttpParameterFailure(adminParams);"},{"lineNumber":82,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":83,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":84,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":85,"author":{"gitId":"yuanxi1"},"content":" public void execute_adminSearchName_success() {"},{"lineNumber":86,"author":{"gitId":"yuanxi1"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":87,"author":{"gitId":"yuanxi1"},"content":" return;"},{"lineNumber":88,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":89,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":90,"author":{"gitId":"yuanxi1"},"content":" loginAsAdmin();"},{"lineNumber":91,"author":{"gitId":"yuanxi1"},"content":" String[] accNameParams \u003d new String[] {"},{"lineNumber":92,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, student1InCourse1.getName(),"},{"lineNumber":93,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.ADMIN,"},{"lineNumber":94,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":95,"author":{"gitId":"yuanxi1"},"content":" SearchStudentsAction a \u003d getAction(accNameParams);"},{"lineNumber":96,"author":{"gitId":"yuanxi1"},"content":" JsonResult result \u003d getJsonResult(a);"},{"lineNumber":97,"author":{"gitId":"yuanxi1"},"content":" StudentsData response \u003d (StudentsData) result.getOutput();"},{"lineNumber":98,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":99,"author":{"gitId":"marquestye"},"content":" assertEquals(11, response.getStudents().size());"},{"lineNumber":100,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":101,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":102,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":103,"author":{"gitId":"yuanxi1"},"content":" public void execute_adminSearchCourseId_success() {"},{"lineNumber":104,"author":{"gitId":"yuanxi1"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":105,"author":{"gitId":"yuanxi1"},"content":" return;"},{"lineNumber":106,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":107,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":108,"author":{"gitId":"yuanxi1"},"content":" loginAsAdmin();"},{"lineNumber":109,"author":{"gitId":"yuanxi1"},"content":" String[] accCourseIdParams \u003d new String[] {"},{"lineNumber":110,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, student1InCourse1.getCourseId(),"},{"lineNumber":111,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.ADMIN,"},{"lineNumber":112,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":113,"author":{"gitId":"yuanxi1"},"content":" SearchStudentsAction a \u003d getAction(accCourseIdParams);"},{"lineNumber":114,"author":{"gitId":"yuanxi1"},"content":" JsonResult result \u003d getJsonResult(a);"},{"lineNumber":115,"author":{"gitId":"yuanxi1"},"content":" StudentsData response \u003d (StudentsData) result.getOutput();"},{"lineNumber":116,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":117,"author":{"gitId":"marquestye"},"content":" assertEquals(11, response.getStudents().size());"},{"lineNumber":118,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":119,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":120,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":121,"author":{"gitId":"yuanxi1"},"content":" public void execute_adminSearchEmail_success() {"},{"lineNumber":122,"author":{"gitId":"yuanxi1"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":123,"author":{"gitId":"yuanxi1"},"content":" return;"},{"lineNumber":124,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":125,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":126,"author":{"gitId":"yuanxi1"},"content":" loginAsAdmin();"},{"lineNumber":127,"author":{"gitId":"yuanxi1"},"content":" String[] emailParams \u003d new String[] {"},{"lineNumber":128,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, student1InCourse1.getEmail(),"},{"lineNumber":129,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.ADMIN,"},{"lineNumber":130,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":131,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":132,"author":{"gitId":"yuanxi1"},"content":" SearchStudentsAction a \u003d getAction(emailParams);"},{"lineNumber":133,"author":{"gitId":"yuanxi1"},"content":" JsonResult result \u003d getJsonResult(a);"},{"lineNumber":134,"author":{"gitId":"yuanxi1"},"content":" StudentsData response \u003d (StudentsData) result.getOutput();"},{"lineNumber":135,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" assertEquals(4, response.getStudents().size());"},{"lineNumber":137,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":138,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":139,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":140,"author":{"gitId":"yuanxi1"},"content":" public void execute_adminSearchNoMatch_noMatch() {"},{"lineNumber":141,"author":{"gitId":"yuanxi1"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":142,"author":{"gitId":"yuanxi1"},"content":" return;"},{"lineNumber":143,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":144,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":145,"author":{"gitId":"yuanxi1"},"content":" loginAsAdmin();"},{"lineNumber":146,"author":{"gitId":"yuanxi1"},"content":" String[] accNameParams \u003d new String[] {"},{"lineNumber":147,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, \"minuscoronavirus\","},{"lineNumber":148,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.ADMIN,"},{"lineNumber":149,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":150,"author":{"gitId":"yuanxi1"},"content":" SearchStudentsAction a \u003d getAction(accNameParams);"},{"lineNumber":151,"author":{"gitId":"yuanxi1"},"content":" JsonResult result \u003d getJsonResult(a);"},{"lineNumber":152,"author":{"gitId":"yuanxi1"},"content":" StudentsData response \u003d (StudentsData) result.getOutput();"},{"lineNumber":153,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":154,"author":{"gitId":"yuanxi1"},"content":" assertEquals(0, response.getStudents().size());"},{"lineNumber":155,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":156,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":157,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":158,"author":{"gitId":"yuanxi1"},"content":" public void execute_instructorSearchGoogleId_matchOnlyStudentsInCourse() {"},{"lineNumber":159,"author":{"gitId":"yuanxi1"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":160,"author":{"gitId":"yuanxi1"},"content":" return;"},{"lineNumber":161,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":162,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":163,"author":{"gitId":"yuanxi1"},"content":" loginAsInstructor(instructor1OfCourse1.getGoogleId());"},{"lineNumber":164,"author":{"gitId":"yuanxi1"},"content":" String[] googleIdParams \u003d new String[] {"},{"lineNumber":165,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, \"student1\","},{"lineNumber":166,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":167,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":168,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":169,"author":{"gitId":"yuanxi1"},"content":" SearchStudentsAction a \u003d getAction(googleIdParams);"},{"lineNumber":170,"author":{"gitId":"yuanxi1"},"content":" JsonResult result \u003d getJsonResult(a);"},{"lineNumber":171,"author":{"gitId":"yuanxi1"},"content":" StudentsData response \u003d (StudentsData) result.getOutput();"},{"lineNumber":172,"author":{"gitId":"-"},"content":" assertEquals(3, response.getStudents().size());"},{"lineNumber":173,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":174,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":175,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":176,"author":{"gitId":"yuanxi1"},"content":" public void execute_noSearchService_shouldReturn501() {"},{"lineNumber":177,"author":{"gitId":"yuanxi1"},"content":" if (TestProperties.isSearchServiceActive()) {"},{"lineNumber":178,"author":{"gitId":"yuanxi1"},"content":" return;"},{"lineNumber":179,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":180,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":181,"author":{"gitId":"yuanxi1"},"content":" loginAsInstructor(instructor1OfCourse1.getGoogleId());"},{"lineNumber":182,"author":{"gitId":"yuanxi1"},"content":" String[] params \u003d new String[] {"},{"lineNumber":183,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, \"anything\","},{"lineNumber":184,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR,"},{"lineNumber":185,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":186,"author":{"gitId":"yuanxi1"},"content":" SearchStudentsAction a \u003d getAction(params);"},{"lineNumber":187,"author":{"gitId":"yuanxi1"},"content":" JsonResult result \u003d getJsonResult(a, HttpStatus.SC_NOT_IMPLEMENTED);"},{"lineNumber":188,"author":{"gitId":"yuanxi1"},"content":" MessageOutput output \u003d (MessageOutput) result.getOutput();"},{"lineNumber":189,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":190,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"Full-text search is not available.\", output.getMessage());"},{"lineNumber":191,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":192,"author":{"gitId":"yuanxi1"},"content":" loginAsAdmin();"},{"lineNumber":193,"author":{"gitId":"yuanxi1"},"content":" params \u003d new String[] {"},{"lineNumber":194,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.SEARCH_KEY, \"anything\","},{"lineNumber":195,"author":{"gitId":"yuanxi1"},"content":" Const.ParamsNames.ENTITY_TYPE, Const.EntityType.ADMIN,"},{"lineNumber":196,"author":{"gitId":"yuanxi1"},"content":" };"},{"lineNumber":197,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":198,"author":{"gitId":"yuanxi1"},"content":" a \u003d getAction(params);"},{"lineNumber":199,"author":{"gitId":"yuanxi1"},"content":" result \u003d getJsonResult(a, HttpStatus.SC_NOT_IMPLEMENTED);"},{"lineNumber":200,"author":{"gitId":"yuanxi1"},"content":" output \u003d (MessageOutput) result.getOutput();"},{"lineNumber":201,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":202,"author":{"gitId":"yuanxi1"},"content":" assertEquals(\"Full-text search is not available.\", output.getMessage());"},{"lineNumber":203,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":204,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":205,"author":{"gitId":"yuanxi1"},"content":" @Override"},{"lineNumber":206,"author":{"gitId":"yuanxi1"},"content":" @Test"},{"lineNumber":207,"author":{"gitId":"yuanxi1"},"content":" protected void testAccessControl() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":208,"author":{"gitId":"yuanxi1"},"content":" verifyAccessibleForAdmin();"},{"lineNumber":209,"author":{"gitId":"yuanxi1"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":210,"author":{"gitId":"yuanxi1"},"content":" verifyOnlyInstructorsCanAccess(course);"},{"lineNumber":211,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":212,"author":{"gitId":"yuanxi1"},"content":"}"}],"authorContributionMap":{"yuanxi1":208,"marquestye":2,"-":2}},{"path":"src/it/java/teammates/it/ui/webapi/StudentSearchIndexingWorkerActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const.ParamsNames;"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const.TaskQueue;"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlsearch.SearchManagerFactory;"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":"import teammates.test.TestProperties;"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":"import teammates.ui.webapi.StudentSearchIndexingWorkerAction;"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" * SUT: {@link StudentSearchIndexingWorkerAction}."},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":"public class StudentSearchIndexingWorkerActionIT extends BaseActionIT\u003cStudentSearchIndexingWorkerAction\u003e {"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" private final Student student \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" @BeforeMethod"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" protected void setUp() throws Exception {"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" super.setUp();"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" HibernateUtil.flushSession();"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" SearchManagerFactory.getStudentSearchManager().resetCollections();"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" protected String getActionUri() {"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" return TaskQueue.STUDENT_SEARCH_INDEXING_WORKER_URL;"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" protected String getRequestMethod() {"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" return POST;"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" protected void testExecute() throws Exception {"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" // See test cases below"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" protected void testExecute_studentNotYetIndexed_shouldNotBeSearchable() throws Exception {"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" return;"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" List\u003cStudent\u003e studentList \u003d logic.searchStudentsInWholeSystem(student.getEmail());"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" assertEquals(0, studentList.size());"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" protected void testExecute_studentIndexed_shouldBeSearchable() throws Exception {"},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" if (!TestProperties.isSearchServiceActive()) {"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" return;"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":67,"author":{"gitId":"xenosf"},"content":" ParamsNames.COURSE_ID, student.getCourseId(),"},{"lineNumber":68,"author":{"gitId":"xenosf"},"content":" ParamsNames.STUDENT_EMAIL, student.getEmail(),"},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" StudentSearchIndexingWorkerAction action \u003d getAction(submissionParams);"},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" getJsonResult(action);"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" List\u003cStudent\u003e studentList \u003d logic.searchStudentsInWholeSystem(student.getEmail());"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" assertEquals(1, studentList.size());"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" assertEquals(student.getName(), studentList.get(0).getName());"},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":" protected void testAccessControl() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" verifyOnlyAdminCanAccess(course);"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":85}},{"path":"src/it/java/teammates/it/ui/webapi/UpdateAccountRequestActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import java.util.UUID;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.AfterMethod;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import org.testng.annotations.Test;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.Const;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.StringHelperExtension;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.output.AccountRequestData;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.request.AccountRequestUpdateRequest;"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.EntityNotFoundException;"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.InvalidHttpParameterException;"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.InvalidOperationException;"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.webapi.UpdateAccountRequestAction;"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" * SUT: {@link UpdateAccountRequestAction}."},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":"public class UpdateAccountRequestActionIT extends BaseActionIT\u003cUpdateAccountRequestAction\u003e {"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" @BeforeMethod"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" protected void setUp() throws Exception {"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" // no need to call super.setUp() because the action handles its own transactions"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" protected String getActionUri() {"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" return Const.ResourceURIs.ACCOUNT_REQUEST;"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" protected String getRequestMethod() {"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" return PUT;"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" public void testExecute() throws Exception {"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" ______TS(\"edit fields of an account request\");"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d logic.createAccountRequestWithTransaction(\"name\", \"email@email.com\","},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" UUID id \u003d accountRequest.getId();"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" String name \u003d \"newName\";"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" String email \u003d \"newEmail@email.com\";"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" String institute \u003d \"newInstitute\";"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" String comments \u003d \"newComments\";"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" AccountRequestStatus status \u003d accountRequest.getStatus();"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" AccountRequestUpdateRequest requestBody \u003d new AccountRequestUpdateRequest(name, email, institute, status, comments);"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" String[] params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" UpdateAccountRequestAction action \u003d getAction(requestBody, params);"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":" JsonResult result \u003d action.execute();"},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":" assertEquals(result.getStatusCode(), 200);"},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" AccountRequestData data \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" assertEquals(name, data.getName());"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" assertEquals(email, data.getEmail());"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" assertEquals(institute, data.getInstitute());"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" assertEquals(status, data.getStatus());"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" assertEquals(comments, data.getComments());"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" verifyNoEmailsSent();"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" ______TS(\"approve a pending account request\");"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d logic.createAccountRequestWithTransaction(\"name\", \"email@email.com\","},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(accountRequest.getName(), accountRequest.getEmail(),"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" accountRequest.getInstitute(), AccountRequestStatus.APPROVED, accountRequest.getComments());"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, accountRequest.getId().toString()};"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" action \u003d getAction(requestBody, params);"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" result \u003d getJsonResult(action, 200);"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":" data \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" assertEquals(accountRequest.getName(), data.getName());"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" assertEquals(accountRequest.getEmail(), data.getEmail());"},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" assertEquals(accountRequest.getInstitute(), data.getInstitute());"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" assertEquals(AccountRequestStatus.APPROVED, data.getStatus());"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" assertEquals(accountRequest.getComments(), data.getComments());"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":" verifyNumberOfEmailsSent(1);"},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" ______TS(\"already registered account request has no email sent when approved\");"},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d logic.createAccountRequestWithTransaction(\"name\", \"email@email.com\","},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":" \"institute\", AccountRequestStatus.REGISTERED, \"comments\");"},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(name, email, institute, AccountRequestStatus.APPROVED, comments);"},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, accountRequest.getId().toString()};"},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" action \u003d getAction(requestBody, params);"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" result \u003d getJsonResult(action, 200);"},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":" data \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" assertEquals(name, data.getName());"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" assertEquals(email, data.getEmail());"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" assertEquals(institute, data.getInstitute());"},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" assertEquals(AccountRequestStatus.REGISTERED, data.getStatus());"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" assertEquals(comments, data.getComments());"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" verifyNumberOfEmailsSent(0);"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" ______TS(\"email with existing account throws exception\");"},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" Account account \u003d logic.createAccountWithTransaction(getTypicalAccount());"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d logic.createAccountRequestWithTransaction(\"name\", account.getEmail(),"},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(name, email, institute, AccountRequestStatus.APPROVED, comments);"},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, accountRequest.getId().toString()};"},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" InvalidOperationException ipe \u003d verifyInvalidOperation(requestBody, params);"},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":" assertEquals(String.format(\"An account with email %s already exists. \""},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" + \"Please reject or delete the account request instead.\", account.getEmail()), ipe.getMessage());"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" ______TS(\"non-existent but valid uuid\");"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(\"name\", \"email\","},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" String validUuid \u003d UUID.randomUUID().toString();"},{"lineNumber":128,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, validUuid};"},{"lineNumber":129,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":" EntityNotFoundException enfe \u003d verifyEntityNotFound(requestBody, params);"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":" assertEquals(String.format(\"Account request with id \u003d %s not found\", validUuid), enfe.getMessage());"},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" ______TS(\"invalid uuid\");"},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(\"name\", \"email\","},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":137,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, \"invalid\"};"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":" InvalidHttpParameterException ihpe \u003d verifyHttpParameterFailure(requestBody, params);"},{"lineNumber":140,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"Expected UUID value for id parameter, but found: [invalid]\", ihpe.getMessage());"},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":" ______TS(\"invalid email\");"},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d logic.createAccountRequestWithTransaction(\"name\", \"email@email.com\","},{"lineNumber":145,"author":{"gitId":"domoberzin"},"content":" \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":" id \u003d accountRequest.getId();"},{"lineNumber":147,"author":{"gitId":"domoberzin"},"content":" email \u003d \"newEmail\";"},{"lineNumber":148,"author":{"gitId":"domoberzin"},"content":" status \u003d accountRequest.getStatus();"},{"lineNumber":149,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":150,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(name, email, institute, status, comments);"},{"lineNumber":151,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":152,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":153,"author":{"gitId":"domoberzin"},"content":" InvalidHttpRequestBodyException ihrbe \u003d verifyHttpRequestBodyFailure(requestBody, params);"},{"lineNumber":154,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":155,"author":{"gitId":"domoberzin"},"content":" assertEquals(getPopulatedErrorMessage(FieldValidator.EMAIL_ERROR_MESSAGE, email,"},{"lineNumber":156,"author":{"gitId":"domoberzin"},"content":" FieldValidator.EMAIL_FIELD_NAME, FieldValidator.REASON_INCORRECT_FORMAT, FieldValidator.EMAIL_MAX_LENGTH),"},{"lineNumber":157,"author":{"gitId":"domoberzin"},"content":" ihrbe.getMessage());"},{"lineNumber":158,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":159,"author":{"gitId":"domoberzin"},"content":" ______TS(\"invalid name alphanumeric\");"},{"lineNumber":160,"author":{"gitId":"domoberzin"},"content":" name \u003d \"@$@#$#@#@$#@$\";"},{"lineNumber":161,"author":{"gitId":"domoberzin"},"content":" email \u003d \"newEmail@email.com\";"},{"lineNumber":162,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":163,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(name, email, institute, status, comments);"},{"lineNumber":164,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":165,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":" ihrbe \u003d verifyHttpRequestBodyFailure(requestBody, params);"},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":" assertEquals(getPopulatedErrorMessage(FieldValidator.INVALID_NAME_ERROR_MESSAGE, name,"},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" FieldValidator.PERSON_NAME_FIELD_NAME, FieldValidator.REASON_START_WITH_NON_ALPHANUMERIC_CHAR),"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" ihrbe.getMessage());"},{"lineNumber":171,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":172,"author":{"gitId":"domoberzin"},"content":" ______TS(\"invalid name too long\");"},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":" name \u003d StringHelperExtension.generateStringOfLength(FieldValidator.PERSON_NAME_MAX_LENGTH + 1);"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(name, email, institute, status, comments);"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":" ihrbe \u003d verifyHttpRequestBodyFailure(requestBody, params);"},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" assertEquals(getPopulatedErrorMessage(FieldValidator.SIZE_CAPPED_NON_EMPTY_STRING_ERROR_MESSAGE, name,"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":" FieldValidator.PERSON_NAME_FIELD_NAME, FieldValidator.REASON_TOO_LONG,"},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":" FieldValidator.PERSON_NAME_MAX_LENGTH), ihrbe.getMessage());"},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":184,"author":{"gitId":"domoberzin"},"content":" ______TS(\"null email value\");"},{"lineNumber":185,"author":{"gitId":"domoberzin"},"content":" name \u003d \"newName\";"},{"lineNumber":186,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":187,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(name, null, institute, status, comments);"},{"lineNumber":188,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":189,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":190,"author":{"gitId":"domoberzin"},"content":" ihrbe \u003d verifyHttpRequestBodyFailure(requestBody, params);"},{"lineNumber":191,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":192,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"email cannot be null\", ihrbe.getMessage());"},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" ______TS(\"null name value\");"},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(null, email, institute, status, comments);"},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" ihrbe \u003d verifyHttpRequestBodyFailure(requestBody, params);"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":200,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"name cannot be null\", ihrbe.getMessage());"},{"lineNumber":201,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":202,"author":{"gitId":"domoberzin"},"content":" ______TS(\"null status value\");"},{"lineNumber":203,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(name, email, institute, null, comments);"},{"lineNumber":204,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":205,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":206,"author":{"gitId":"domoberzin"},"content":" ihrbe \u003d verifyHttpRequestBodyFailure(requestBody, params);"},{"lineNumber":207,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":208,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"status cannot be null\", ihrbe.getMessage());"},{"lineNumber":209,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":210,"author":{"gitId":"domoberzin"},"content":" ______TS(\"null institute value\");"},{"lineNumber":211,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(name, email, null, status, comments);"},{"lineNumber":212,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":213,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":214,"author":{"gitId":"domoberzin"},"content":" ihrbe \u003d verifyHttpRequestBodyFailure(requestBody, params);"},{"lineNumber":215,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":216,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"institute cannot be null\", ihrbe.getMessage());"},{"lineNumber":217,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":218,"author":{"gitId":"domoberzin"},"content":" ______TS(\"allow null comments in request\");"},{"lineNumber":219,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(name, email, institute, status, null);"},{"lineNumber":220,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()};"},{"lineNumber":221,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":222,"author":{"gitId":"domoberzin"},"content":" action \u003d getAction(requestBody, params);"},{"lineNumber":223,"author":{"gitId":"domoberzin"},"content":" result \u003d getJsonResult(action, 200);"},{"lineNumber":224,"author":{"gitId":"domoberzin"},"content":" data \u003d (AccountRequestData) result.getOutput();"},{"lineNumber":225,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":226,"author":{"gitId":"domoberzin"},"content":" assertEquals(name, data.getName());"},{"lineNumber":227,"author":{"gitId":"domoberzin"},"content":" assertEquals(email, data.getEmail());"},{"lineNumber":228,"author":{"gitId":"domoberzin"},"content":" assertEquals(institute, data.getInstitute());"},{"lineNumber":229,"author":{"gitId":"domoberzin"},"content":" assertEquals(null, data.getComments());"},{"lineNumber":230,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":231,"author":{"gitId":"domoberzin"},"content":" ______TS(\"email with approved account request throws exception\");"},{"lineNumber":232,"author":{"gitId":"domoberzin"},"content":" logic.createAccountRequestWithTransaction(\"test\", \"test@email.com\","},{"lineNumber":233,"author":{"gitId":"domoberzin"},"content":" \"institute\", AccountRequestStatus.APPROVED, \"comments\");"},{"lineNumber":234,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d logic.createAccountRequestWithTransaction(\"test\", \"test@email.com\","},{"lineNumber":235,"author":{"gitId":"domoberzin"},"content":" \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":236,"author":{"gitId":"domoberzin"},"content":" requestBody \u003d new AccountRequestUpdateRequest(accountRequest.getName(), accountRequest.getEmail(),"},{"lineNumber":237,"author":{"gitId":"domoberzin"},"content":" accountRequest.getInstitute(), AccountRequestStatus.APPROVED, comments);"},{"lineNumber":238,"author":{"gitId":"domoberzin"},"content":" params \u003d new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, accountRequest.getId().toString()};"},{"lineNumber":239,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":240,"author":{"gitId":"domoberzin"},"content":" ipe \u003d verifyInvalidOperation(requestBody, params);"},{"lineNumber":241,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":242,"author":{"gitId":"domoberzin"},"content":" assertEquals(String.format(\"An account request with email %s has already been approved. \""},{"lineNumber":243,"author":{"gitId":"domoberzin"},"content":" + \"Please reject or delete the account request instead.\", accountRequest.getEmail()), ipe.getMessage());"},{"lineNumber":244,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":245,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":246,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":247,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":248,"author":{"gitId":"domoberzin"},"content":" protected void testAccessControl() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":249,"author":{"gitId":"domoberzin"},"content":" verifyOnlyAdminCanAccessWithTransaction();"},{"lineNumber":250,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":251,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":252,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":253,"author":{"gitId":"domoberzin"},"content":" @AfterMethod"},{"lineNumber":254,"author":{"gitId":"domoberzin"},"content":" protected void tearDown() {"},{"lineNumber":255,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":256,"author":{"gitId":"domoberzin"},"content":" List\u003cAccountRequest\u003e accountRequests \u003d logic.getAllAccountRequests();"},{"lineNumber":257,"author":{"gitId":"domoberzin"},"content":" for (AccountRequest ar : accountRequests) {"},{"lineNumber":258,"author":{"gitId":"dishenggg"},"content":" logic.deleteAccountRequest(ar.getId());"},{"lineNumber":259,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":260,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":261,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":262,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":261,"dishenggg":1}},{"path":"src/it/java/teammates/it/ui/webapi/UpdateFeedbackSessionLogsActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.time.temporal.ChronoUnit;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Const;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlsearch.SearchManagerFactory;"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.webapi.UpdateFeedbackSessionLogsAction;"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link UpdateFeedbackSessionLogsAction}."},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":"public class UpdateFeedbackSessionLogsActionIT extends BaseActionIT\u003cUpdateFeedbackSessionLogsAction\u003e {"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" static final long COLLECTION_TIME_PERIOD \u003d Const.STUDENT_ACTIVITY_LOGS_UPDATE_INTERVAL.toMinutes();"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" static final long SPAM_FILTER \u003d Const.STUDENT_ACTIVITY_LOGS_FILTER_WINDOW.toMillis();"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" Student student1InCourse1;"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" Student student2InCourse1;"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" Student student1InCourse3;"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" Course course1;"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" Course course3;"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" FeedbackSession session1InCourse1;"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" FeedbackSession session2InCourse1;"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" FeedbackSession session1InCourse3;"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" Instant endTime;"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" Instant startTime;"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" @BeforeMethod"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" protected void setUp() throws Exception {"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" super.setUp();"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" HibernateUtil.flushSession();"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" SearchManagerFactory.getStudentSearchManager().resetCollections();"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" endTime \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.now());"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" startTime \u003d endTime.minus(COLLECTION_TIME_PERIOD, ChronoUnit.MINUTES);"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" course1 \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" course3 \u003d typicalBundle.courses.get(\"course3\");"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" student1InCourse1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" student2InCourse1 \u003d typicalBundle.students.get(\"student2InCourse1\");"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" student1InCourse3 \u003d typicalBundle.students.get(\"student1InCourse3\");"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" session1InCourse1 \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" session2InCourse1 \u003d typicalBundle.feedbackSessions.get(\"session2InTypicalCourse\");"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" session1InCourse3 \u003d typicalBundle.feedbackSessions.get(\"ongoingSession1InCourse3\");"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.getOrderedFeedbackSessionLogs(\"\", \"\", 0, 0, \"\").clear();"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" String getActionUri() {"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" return Const.CronJobURIs.AUTOMATED_FEEDBACK_SESSION_LOGS_PROCESSING;"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" String getRequestMethod() {"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" return GET;"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" protected void testExecute() {"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" ______TS(\"No spam all logs added\");"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" // Different Types"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(100).toEpochMilli());"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(100).toEpochMilli());"},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.VIEW_RESULT.getLabel(),"},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(100).toEpochMilli());"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" // Different feedback sessions"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(200).toEpochMilli());"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":" session2InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(200).toEpochMilli());"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" // Different Student"},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(300).toEpochMilli());"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student2InCourse1.getId(),"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(300).toEpochMilli());"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":" // Different course"},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(400).toEpochMilli());"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course3.getId(), student1InCourse3.getId(),"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" session1InCourse3.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(400).toEpochMilli());"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" // Gap is larger than spam filter"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(), startTime.toEpochMilli());"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" startTime.plusMillis(SPAM_FILTER + 1).toEpochMilli());"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" UpdateFeedbackSessionLogsAction action \u003d getAction();"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":" getJsonResult(action);"},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":" // method returns all logs regardless of params"},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntry\u003e expected \u003d mockLogsProcessor.getOrderedFeedbackSessionLogs(\"\", \"\", 0, 0, \"\");"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e actual \u003d logic.getOrderedFeedbackSessionLogs(course1.getId(), null, null, startTime,"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" endTime);"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e actualCourse3 \u003d logic.getOrderedFeedbackSessionLogs(course3.getId(), null, null,"},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":" startTime, endTime);"},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" actual.addAll(actualCourse3);"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":" assertTrue(isEqual(expected, actual));"},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":141,"author":{"gitId":"dishenggg"},"content":" protected void testExecute_recentLogsWithSpam_someLogsCreated() {"},{"lineNumber":142,"author":{"gitId":"dishenggg"},"content":" // Gap is smaller than spam filter"},{"lineNumber":143,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":144,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(), startTime.toEpochMilli());"},{"lineNumber":145,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":146,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":" startTime.plusMillis(SPAM_FILTER - 2).toEpochMilli());"},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":" // Filters multiple logs within one spam window"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":" startTime.plusMillis(SPAM_FILTER - 1).toEpochMilli());"},{"lineNumber":153,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":" // Correctly adds new log after filtering"},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":" startTime.plusMillis(SPAM_FILTER + 1).toEpochMilli());"},{"lineNumber":158,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":159,"author":{"gitId":"dishenggg"},"content":" // Filters out spam in the new window"},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":161,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":162,"author":{"gitId":"dishenggg"},"content":" startTime.plusMillis(SPAM_FILTER + 2).toEpochMilli());"},{"lineNumber":163,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":164,"author":{"gitId":"dishenggg"},"content":" UpdateFeedbackSessionLogsAction action \u003d getAction();"},{"lineNumber":165,"author":{"gitId":"dishenggg"},"content":" action.execute();"},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":167,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntry\u003e expected \u003d new ArrayList\u003c\u003e();"},{"lineNumber":168,"author":{"gitId":"dishenggg"},"content":" expected.add(new FeedbackSessionLogEntry(course1.getId(), student1InCourse1.getId(), session1InCourse1.getId(),"},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.toEpochMilli()));"},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" expected.add(new FeedbackSessionLogEntry(course1.getId(), student1InCourse1.getId(), session1InCourse1.getId(),"},{"lineNumber":171,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusMillis(SPAM_FILTER + 1).toEpochMilli()));"},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e actual \u003d logic.getOrderedFeedbackSessionLogs(course1.getId(), null, null, startTime,"},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":" endTime);"},{"lineNumber":175,"author":{"gitId":"dishenggg"},"content":" assertTrue(isEqual(expected, actual));"},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":179,"author":{"gitId":"dishenggg"},"content":" protected void testExecute_badLogs_otherLogsCreated() {"},{"lineNumber":180,"author":{"gitId":"dishenggg"},"content":" UUID badUuid \u003d UUID.fromString(\"00000000-0000-0000-0000-000000000000\");"},{"lineNumber":181,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":182,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(100).toEpochMilli());"},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(),"},{"lineNumber":185,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.getId(), FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":186,"author":{"gitId":"dishenggg"},"content":" startTime.plusSeconds(300).toEpochMilli());"},{"lineNumber":187,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":188,"author":{"gitId":"dishenggg"},"content":" // bad student id"},{"lineNumber":189,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), badUuid, session1InCourse1.getId(),"},{"lineNumber":190,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(200).toEpochMilli());"},{"lineNumber":191,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":192,"author":{"gitId":"dishenggg"},"content":" // bad session id"},{"lineNumber":193,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1InCourse1.getId(), badUuid,"},{"lineNumber":194,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(200).toEpochMilli());"},{"lineNumber":195,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":196,"author":{"gitId":"dishenggg"},"content":" UpdateFeedbackSessionLogsAction action \u003d getAction();"},{"lineNumber":197,"author":{"gitId":"dishenggg"},"content":" action.execute();"},{"lineNumber":198,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":199,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntry\u003e expected \u003d new ArrayList\u003c\u003e();"},{"lineNumber":200,"author":{"gitId":"dishenggg"},"content":" expected.add(new FeedbackSessionLogEntry(course1.getId(), student1InCourse1.getId(), session1InCourse1.getId(),"},{"lineNumber":201,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(100).toEpochMilli()));"},{"lineNumber":202,"author":{"gitId":"dishenggg"},"content":" expected.add(new FeedbackSessionLogEntry(course1.getId(), student1InCourse1.getId(), session1InCourse1.getId(),"},{"lineNumber":203,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(300).toEpochMilli()));"},{"lineNumber":204,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":205,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e actual \u003d logic.getOrderedFeedbackSessionLogs(course1.getId(), null, null, startTime,"},{"lineNumber":206,"author":{"gitId":"dishenggg"},"content":" endTime);"},{"lineNumber":207,"author":{"gitId":"dishenggg"},"content":" assertTrue(isEqual(expected, actual));"},{"lineNumber":208,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":209,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":210,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":211,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":212,"author":{"gitId":"dishenggg"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":213,"author":{"gitId":"dishenggg"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":214,"author":{"gitId":"dishenggg"},"content":" verifyOnlyAdminCanAccess(course);"},{"lineNumber":215,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":216,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":217,"author":{"gitId":"dishenggg"},"content":" private Boolean isEqual(List\u003cFeedbackSessionLogEntry\u003e expected, List\u003cFeedbackSessionLog\u003e actual) {"},{"lineNumber":218,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":219,"author":{"gitId":"dishenggg"},"content":" assertEquals(expected.size(), actual.size());"},{"lineNumber":220,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":221,"author":{"gitId":"dishenggg"},"content":" for (int i \u003d 0; i \u003c expected.size(); i++) {"},{"lineNumber":222,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogEntry expectedEntry \u003d expected.get(i);"},{"lineNumber":223,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog actualLog \u003d actual.get(i);"},{"lineNumber":224,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":225,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedEntry.getStudentId(), actualLog.getStudent().getId());"},{"lineNumber":226,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":227,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedEntry.getFeedbackSessionId(), actualLog.getFeedbackSession().getId());"},{"lineNumber":228,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":229,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedEntry.getFeedbackSessionLogType(), actualLog.getFeedbackSessionLogType().getLabel());"},{"lineNumber":230,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":231,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedEntry.getTimestamp(), actualLog.getTimestamp().toEpochMilli());"},{"lineNumber":232,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":233,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":234,"author":{"gitId":"dishenggg"},"content":" return true;"},{"lineNumber":235,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":236,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":236}},{"path":"src/it/java/teammates/it/ui/webapi/UpdateStudentActionIT.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"marquestye"},"content":"package teammates.it.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":3,"author":{"gitId":"marquestye"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"marquestye"},"content":"import java.util.UUID;"},{"lineNumber":5,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":6,"author":{"gitId":"marquestye"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":7,"author":{"gitId":"marquestye"},"content":"import org.testng.annotations.Test;"},{"lineNumber":8,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":9,"author":{"gitId":"marquestye"},"content":"import teammates.common.util.Const;"},{"lineNumber":10,"author":{"gitId":"marquestye"},"content":"import teammates.common.util.EmailType;"},{"lineNumber":11,"author":{"gitId":"marquestye"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":12,"author":{"gitId":"marquestye"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":13,"author":{"gitId":"marquestye"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":14,"author":{"gitId":"marquestye"},"content":"import teammates.common.util.StringHelperExtension;"},{"lineNumber":15,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":16,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":17,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":18,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":19,"author":{"gitId":"marquestye"},"content":"import teammates.ui.output.MessageOutput;"},{"lineNumber":20,"author":{"gitId":"marquestye"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":21,"author":{"gitId":"marquestye"},"content":"import teammates.ui.request.StudentUpdateRequest;"},{"lineNumber":22,"author":{"gitId":"marquestye"},"content":"import teammates.ui.webapi.EntityNotFoundException;"},{"lineNumber":23,"author":{"gitId":"marquestye"},"content":"import teammates.ui.webapi.InvalidOperationException;"},{"lineNumber":24,"author":{"gitId":"marquestye"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":25,"author":{"gitId":"marquestye"},"content":"import teammates.ui.webapi.UpdateStudentAction;"},{"lineNumber":26,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":27,"author":{"gitId":"marquestye"},"content":"/**"},{"lineNumber":28,"author":{"gitId":"marquestye"},"content":" * SUT: {@link UpdateStudentAction}."},{"lineNumber":29,"author":{"gitId":"marquestye"},"content":" */"},{"lineNumber":30,"author":{"gitId":"marquestye"},"content":"public class UpdateStudentActionIT extends BaseActionIT\u003cUpdateStudentAction\u003e {"},{"lineNumber":31,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":32,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":33,"author":{"gitId":"marquestye"},"content":" @BeforeMethod"},{"lineNumber":34,"author":{"gitId":"marquestye"},"content":" protected void setUp() throws Exception {"},{"lineNumber":35,"author":{"gitId":"marquestye"},"content":" super.setUp();"},{"lineNumber":36,"author":{"gitId":"marquestye"},"content":" persistDataBundle(typicalBundle);"},{"lineNumber":37,"author":{"gitId":"marquestye"},"content":" HibernateUtil.flushSession();"},{"lineNumber":38,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":39,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":40,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":41,"author":{"gitId":"marquestye"},"content":" protected String getActionUri() {"},{"lineNumber":42,"author":{"gitId":"marquestye"},"content":" return Const.ResourceURIs.STUDENT;"},{"lineNumber":43,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":44,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":45,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":46,"author":{"gitId":"marquestye"},"content":" protected String getRequestMethod() {"},{"lineNumber":47,"author":{"gitId":"marquestye"},"content":" return PUT;"},{"lineNumber":48,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":49,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":50,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":51,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":52,"author":{"gitId":"marquestye"},"content":" public void testExecute() throws Exception {"},{"lineNumber":53,"author":{"gitId":"marquestye"},"content":" assert true;"},{"lineNumber":54,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":55,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":56,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":57,"author":{"gitId":"marquestye"},"content":" public void testExecute_invalidParameters_failure() throws Exception {"},{"lineNumber":58,"author":{"gitId":"marquestye"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":59,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":60,"author":{"gitId":"marquestye"},"content":" ______TS(\"no parameters\");"},{"lineNumber":61,"author":{"gitId":"marquestye"},"content":" verifyHttpParameterFailure();"},{"lineNumber":62,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":63,"author":{"gitId":"marquestye"},"content":" ______TS(\"null student email\");"},{"lineNumber":64,"author":{"gitId":"marquestye"},"content":" String[] invalidParams \u003d new String[] {"},{"lineNumber":65,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, student1.getCourseId(),"},{"lineNumber":66,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":67,"author":{"gitId":"marquestye"},"content":" verifyHttpParameterFailure(invalidParams);"},{"lineNumber":68,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":69,"author":{"gitId":"marquestye"},"content":" ______TS(\"null course id\");"},{"lineNumber":70,"author":{"gitId":"marquestye"},"content":" invalidParams \u003d new String[] {"},{"lineNumber":71,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":72,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":73,"author":{"gitId":"marquestye"},"content":" verifyHttpParameterFailure(invalidParams);"},{"lineNumber":74,"author":{"gitId":"marquestye"},"content":" verifyNoTasksAdded();"},{"lineNumber":75,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":76,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":77,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":78,"author":{"gitId":"marquestye"},"content":" public void testExecute_typicalCase_success() throws Exception {"},{"lineNumber":79,"author":{"gitId":"marquestye"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":80,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":81,"author":{"gitId":"marquestye"},"content":" String originalEmail \u003d student1.getEmail();"},{"lineNumber":82,"author":{"gitId":"marquestye"},"content":" Team originalTeam \u003d student1.getTeam();"},{"lineNumber":83,"author":{"gitId":"marquestye"},"content":" String originalComments \u003d student1.getComments();"},{"lineNumber":84,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":85,"author":{"gitId":"marquestye"},"content":" String newStudentEmail \u003d \"newemail@gmail.tmt\";"},{"lineNumber":86,"author":{"gitId":"marquestye"},"content":" String newStudentTeam \u003d \"new student\u0027s team\";"},{"lineNumber":87,"author":{"gitId":"marquestye"},"content":" String newStudentComments \u003d \"this is new comment after editing\";"},{"lineNumber":88,"author":{"gitId":"marquestye"},"content":" StudentUpdateRequest updateRequest \u003d new StudentUpdateRequest(student1.getName(), newStudentEmail,"},{"lineNumber":89,"author":{"gitId":"marquestye"},"content":" newStudentTeam, student1.getSectionName(), newStudentComments, true);"},{"lineNumber":90,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":91,"author":{"gitId":"marquestye"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":92,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, student1.getCourseId(),"},{"lineNumber":93,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":94,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":95,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":96,"author":{"gitId":"marquestye"},"content":" UpdateStudentAction updateAction \u003d getAction(updateRequest, submissionParams);"},{"lineNumber":97,"author":{"gitId":"marquestye"},"content":" JsonResult actionOutput \u003d getJsonResult(updateAction);"},{"lineNumber":98,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":99,"author":{"gitId":"marquestye"},"content":" MessageOutput msgOutput \u003d (MessageOutput) actionOutput.getOutput();"},{"lineNumber":100,"author":{"gitId":"marquestye"},"content":" assertEquals(\"Student has been updated and email sent\", msgOutput.getMessage());"},{"lineNumber":101,"author":{"gitId":"marquestye"},"content":" verifyNumberOfEmailsSent(1);"},{"lineNumber":102,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":103,"author":{"gitId":"marquestye"},"content":" Student updatedStudent \u003d logic.getStudent(student1.getId());"},{"lineNumber":104,"author":{"gitId":"marquestye"},"content":" assertEquals(updatedStudent.getEmail(), newStudentEmail);"},{"lineNumber":105,"author":{"gitId":"marquestye"},"content":" assertEquals(updatedStudent.getTeamName(), newStudentTeam);"},{"lineNumber":106,"author":{"gitId":"marquestye"},"content":" assertEquals(updatedStudent.getComments(), newStudentComments);"},{"lineNumber":107,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":108,"author":{"gitId":"marquestye"},"content":" EmailWrapper email \u003d getEmailsSent().get(0);"},{"lineNumber":109,"author":{"gitId":"marquestye"},"content":" String courseName \u003d logic.getCourse(student1.getCourseId()).getName();"},{"lineNumber":110,"author":{"gitId":"marquestye"},"content":" assertEquals(String.format(EmailType.STUDENT_EMAIL_CHANGED.getSubject(), courseName,"},{"lineNumber":111,"author":{"gitId":"marquestye"},"content":" student1.getCourseId()), email.getSubject());"},{"lineNumber":112,"author":{"gitId":"marquestye"},"content":" assertEquals(newStudentEmail, email.getRecipient());"},{"lineNumber":113,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":114,"author":{"gitId":"marquestye"},"content":" verifySpecifiedTasksAdded(Const.TaskQueue.SEARCH_INDEXING_QUEUE_NAME, 1);"},{"lineNumber":115,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":116,"author":{"gitId":"marquestye"},"content":" resetStudent(student1.getId(), originalEmail, originalTeam, originalComments);"},{"lineNumber":117,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":118,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":119,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":120,"author":{"gitId":"marquestye"},"content":" public void testExecute_studentDetailsWithWhitespace_success() throws Exception {"},{"lineNumber":121,"author":{"gitId":"marquestye"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":122,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":123,"author":{"gitId":"marquestye"},"content":" String originalEmail \u003d student1.getEmail();"},{"lineNumber":124,"author":{"gitId":"marquestye"},"content":" Team originalTeam \u003d student1.getTeam();"},{"lineNumber":125,"author":{"gitId":"marquestye"},"content":" String originalComments \u003d student1.getComments();"},{"lineNumber":126,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":127,"author":{"gitId":"marquestye"},"content":" String newStudentEmailToBeTrimmed \u003d \" student1@teammates.tmt \"; // after trim, this is equal to originalEmail"},{"lineNumber":128,"author":{"gitId":"marquestye"},"content":" String newStudentTeamToBeTrimmed \u003d \" New team \";"},{"lineNumber":129,"author":{"gitId":"marquestye"},"content":" String newStudentCommentsToBeTrimmed \u003d \" this is new comment after editing \";"},{"lineNumber":130,"author":{"gitId":"marquestye"},"content":" StudentUpdateRequest updateRequest \u003d new StudentUpdateRequest(student1.getName(), newStudentEmailToBeTrimmed,"},{"lineNumber":131,"author":{"gitId":"marquestye"},"content":" newStudentTeamToBeTrimmed, student1.getSectionName(), newStudentCommentsToBeTrimmed, true);"},{"lineNumber":132,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":133,"author":{"gitId":"marquestye"},"content":" String[] submissionParamsToBeTrimmed \u003d new String[] {"},{"lineNumber":134,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, student1.getCourseId(),"},{"lineNumber":135,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":136,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":137,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":138,"author":{"gitId":"marquestye"},"content":" UpdateStudentAction actionToBeTrimmed \u003d getAction(updateRequest, submissionParamsToBeTrimmed);"},{"lineNumber":139,"author":{"gitId":"marquestye"},"content":" JsonResult outputToBeTrimmed \u003d getJsonResult(actionToBeTrimmed);"},{"lineNumber":140,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":141,"author":{"gitId":"marquestye"},"content":" MessageOutput msgTrimmedOutput \u003d (MessageOutput) outputToBeTrimmed.getOutput();"},{"lineNumber":142,"author":{"gitId":"marquestye"},"content":" assertEquals(\"Student has been updated\", msgTrimmedOutput.getMessage());"},{"lineNumber":143,"author":{"gitId":"marquestye"},"content":" verifyNoEmailsSent();"},{"lineNumber":144,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":145,"author":{"gitId":"marquestye"},"content":" resetStudent(student1.getId(), originalEmail, originalTeam, originalComments);"},{"lineNumber":146,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":147,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":148,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":149,"author":{"gitId":"marquestye"},"content":" public void testExecute_emailHasTooManyCharacters_failure() throws Exception {"},{"lineNumber":150,"author":{"gitId":"marquestye"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":151,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":152,"author":{"gitId":"marquestye"},"content":" String invalidStudentEmail \u003d StringHelperExtension.generateStringOfLength(255 - \"@gmail.tmt\".length())"},{"lineNumber":153,"author":{"gitId":"marquestye"},"content":" + \"@gmail.tmt\";"},{"lineNumber":154,"author":{"gitId":"marquestye"},"content":" assertEquals(FieldValidator.EMAIL_MAX_LENGTH + 1, invalidStudentEmail.length());"},{"lineNumber":155,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":156,"author":{"gitId":"marquestye"},"content":" StudentUpdateRequest updateRequest \u003d new StudentUpdateRequest(student1.getName(), invalidStudentEmail,"},{"lineNumber":157,"author":{"gitId":"marquestye"},"content":" student1.getTeamName(), student1.getSectionName(), student1.getComments(), false);"},{"lineNumber":158,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":159,"author":{"gitId":"marquestye"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":160,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, student1.getCourseId(),"},{"lineNumber":161,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":162,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":163,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":164,"author":{"gitId":"marquestye"},"content":" InvalidHttpRequestBodyException ihrbe \u003d verifyHttpRequestBodyFailure(updateRequest, submissionParams);"},{"lineNumber":165,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":166,"author":{"gitId":"marquestye"},"content":" assertEquals(getPopulatedErrorMessage(FieldValidator.EMAIL_ERROR_MESSAGE, invalidStudentEmail,"},{"lineNumber":167,"author":{"gitId":"marquestye"},"content":" FieldValidator.EMAIL_FIELD_NAME, FieldValidator.REASON_TOO_LONG,"},{"lineNumber":168,"author":{"gitId":"marquestye"},"content":" FieldValidator.EMAIL_MAX_LENGTH),"},{"lineNumber":169,"author":{"gitId":"marquestye"},"content":" ihrbe.getMessage());"},{"lineNumber":170,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":171,"author":{"gitId":"marquestye"},"content":" verifyNoTasksAdded();"},{"lineNumber":172,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":173,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":174,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":175,"author":{"gitId":"marquestye"},"content":" public void testExecute_emailTakenByOthers_failure() {"},{"lineNumber":176,"author":{"gitId":"marquestye"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":177,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":178,"author":{"gitId":"marquestye"},"content":" Student student2 \u003d typicalBundle.students.get(\"student2InCourse1\");"},{"lineNumber":179,"author":{"gitId":"marquestye"},"content":" String takenStudentEmail \u003d student2.getEmail();"},{"lineNumber":180,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":181,"author":{"gitId":"marquestye"},"content":" StudentUpdateRequest updateRequest \u003d new StudentUpdateRequest(student1.getName(), takenStudentEmail,"},{"lineNumber":182,"author":{"gitId":"marquestye"},"content":" student1.getTeamName(), student1.getSectionName(), student1.getComments(), false);"},{"lineNumber":183,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":184,"author":{"gitId":"marquestye"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":185,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, student1.getCourseId(),"},{"lineNumber":186,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":187,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":188,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":189,"author":{"gitId":"marquestye"},"content":" InvalidOperationException ioe \u003d verifyInvalidOperation(updateRequest, submissionParams);"},{"lineNumber":190,"author":{"gitId":"marquestye"},"content":" assertEquals(\"Trying to update to an email that is already in use\", ioe.getMessage());"},{"lineNumber":191,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":192,"author":{"gitId":"marquestye"},"content":" verifyNoTasksAdded();"},{"lineNumber":193,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":194,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":195,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":196,"author":{"gitId":"marquestye"},"content":" public void testExecute_studentDoesNotExist_failure() {"},{"lineNumber":197,"author":{"gitId":"marquestye"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":198,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":199,"author":{"gitId":"marquestye"},"content":" StudentUpdateRequest updateRequest \u003d new StudentUpdateRequest(student1.getName(), student1.getEmail(),"},{"lineNumber":200,"author":{"gitId":"marquestye"},"content":" student1.getTeamName(), student1.getSectionName(), student1.getComments(), false);"},{"lineNumber":201,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":202,"author":{"gitId":"marquestye"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":203,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, student1.getCourseId(),"},{"lineNumber":204,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, \"notinuseemail@gmail.tmt\","},{"lineNumber":205,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":206,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":207,"author":{"gitId":"marquestye"},"content":" EntityNotFoundException enfe \u003d verifyEntityNotFound(updateRequest, submissionParams);"},{"lineNumber":208,"author":{"gitId":"marquestye"},"content":" assertEquals(\"The student you tried to edit does not exist. \""},{"lineNumber":209,"author":{"gitId":"marquestye"},"content":" + \"If the student was created during the last few minutes, \""},{"lineNumber":210,"author":{"gitId":"marquestye"},"content":" + \"try again in a few more minutes as the student may still be being saved.\","},{"lineNumber":211,"author":{"gitId":"marquestye"},"content":" enfe.getMessage());"},{"lineNumber":212,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":213,"author":{"gitId":"marquestye"},"content":" verifyNoTasksAdded();"},{"lineNumber":214,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":215,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":216,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":217,"author":{"gitId":"marquestye"},"content":" public void testExecute_studentTeamExistsInAnotherSection_failure() throws Exception {"},{"lineNumber":218,"author":{"gitId":"marquestye"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":219,"author":{"gitId":"marquestye"},"content":" Student student4 \u003d typicalBundle.students.get(\"student4InCourse1\");"},{"lineNumber":220,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":221,"author":{"gitId":"marquestye"},"content":" assertNotEquals(student1.getSection(), student4.getSection());"},{"lineNumber":222,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":223,"author":{"gitId":"marquestye"},"content":" StudentUpdateRequest updateRequest \u003d new StudentUpdateRequest(student1.getName(), student1.getEmail(),"},{"lineNumber":224,"author":{"gitId":"marquestye"},"content":" student4.getTeamName(), student1.getSectionName(), student1.getComments(), true);"},{"lineNumber":225,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":226,"author":{"gitId":"marquestye"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":227,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, student1.getCourseId(),"},{"lineNumber":228,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":229,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":230,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":231,"author":{"gitId":"marquestye"},"content":" InvalidOperationException ioe \u003d verifyInvalidOperation(updateRequest, submissionParams);"},{"lineNumber":232,"author":{"gitId":"marquestye"},"content":" String expectedErrorMessage \u003d String.format(\"Team \\\"%s\\\" is detected in both Section \\\"%s\\\" and Section \\\"%s\\\".\""},{"lineNumber":233,"author":{"gitId":"marquestye"},"content":" + \" Please use different team names in different sections.\", student4.getTeamName(),"},{"lineNumber":234,"author":{"gitId":"marquestye"},"content":" student1.getSectionName(), student4.getSectionName());"},{"lineNumber":235,"author":{"gitId":"marquestye"},"content":" assertEquals(expectedErrorMessage, ioe.getMessage());"},{"lineNumber":236,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":237,"author":{"gitId":"marquestye"},"content":" verifyNoTasksAdded();"},{"lineNumber":238,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":239,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":240,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":241,"author":{"gitId":"marquestye"},"content":" public void testExecute_sectionFull_failure() throws Exception {"},{"lineNumber":242,"author":{"gitId":"marquestye"},"content":" Student studentToJoinMaxSection \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":243,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":244,"author":{"gitId":"marquestye"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":245,"author":{"gitId":"marquestye"},"content":" String courseId \u003d studentToJoinMaxSection.getCourseId();"},{"lineNumber":246,"author":{"gitId":"marquestye"},"content":" String sectionInMaxCapacity \u003d \"sectionInMaxCapacity\";"},{"lineNumber":247,"author":{"gitId":"marquestye"},"content":" Section section \u003d logic.getSectionOrCreate(courseId, sectionInMaxCapacity);"},{"lineNumber":248,"author":{"gitId":"marquestye"},"content":" Team team \u003d logic.getTeamOrCreate(section, \"randomTeamName\");"},{"lineNumber":249,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":250,"author":{"gitId":"marquestye"},"content":" for (int i \u003d 0; i \u003c Const.SECTION_SIZE_LIMIT; i++) {"},{"lineNumber":251,"author":{"gitId":"marquestye"},"content":" Student addedStudent \u003d new Student(course, \"Name \" + i, i + \"email@test.com\", \"cmt\" + i, team);"},{"lineNumber":252,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":253,"author":{"gitId":"marquestye"},"content":" logic.createStudent(addedStudent);"},{"lineNumber":254,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":255,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":256,"author":{"gitId":"marquestye"},"content":" List\u003cStudent\u003e studentList \u003d logic.getStudentsForCourse(courseId);"},{"lineNumber":257,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":258,"author":{"gitId":"marquestye"},"content":" assertEquals(Const.SECTION_SIZE_LIMIT,"},{"lineNumber":259,"author":{"gitId":"marquestye"},"content":" studentList.stream().filter(student -\u003e student.getSectionName().equals(sectionInMaxCapacity)).count());"},{"lineNumber":260,"author":{"gitId":"marquestye"},"content":" assertEquals(courseId, studentToJoinMaxSection.getCourseId());"},{"lineNumber":261,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":262,"author":{"gitId":"marquestye"},"content":" StudentUpdateRequest updateRequest \u003d"},{"lineNumber":263,"author":{"gitId":"marquestye"},"content":" new StudentUpdateRequest(studentToJoinMaxSection.getName(), studentToJoinMaxSection.getEmail(),"},{"lineNumber":264,"author":{"gitId":"marquestye"},"content":" \"randomTeamName\", sectionInMaxCapacity,"},{"lineNumber":265,"author":{"gitId":"marquestye"},"content":" studentToJoinMaxSection.getComments(), true);"},{"lineNumber":266,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":267,"author":{"gitId":"marquestye"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":268,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, studentToJoinMaxSection.getCourseId(),"},{"lineNumber":269,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, studentToJoinMaxSection.getEmail(),"},{"lineNumber":270,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":271,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":272,"author":{"gitId":"marquestye"},"content":" InvalidOperationException ioe \u003d verifyInvalidOperation(updateRequest, submissionParams);"},{"lineNumber":273,"author":{"gitId":"marquestye"},"content":" String expectedErrorMessage \u003d String.format(\"You are trying enroll more than %d students in section \\\"%s\\\". \""},{"lineNumber":274,"author":{"gitId":"marquestye"},"content":" + \"To avoid performance problems, please do not enroll more than %d students in a single section.\","},{"lineNumber":275,"author":{"gitId":"marquestye"},"content":" Const.SECTION_SIZE_LIMIT, sectionInMaxCapacity, Const.SECTION_SIZE_LIMIT);"},{"lineNumber":276,"author":{"gitId":"marquestye"},"content":" assertEquals(expectedErrorMessage, ioe.getMessage());"},{"lineNumber":277,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":278,"author":{"gitId":"marquestye"},"content":" verifyNoTasksAdded();"},{"lineNumber":279,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":280,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":281,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":282,"author":{"gitId":"marquestye"},"content":" public void testExecute_renameEmptySectionNameToDefault_success() {"},{"lineNumber":283,"author":{"gitId":"marquestye"},"content":" Student student4 \u003d typicalBundle.students.get(\"student4InCourse1\");"},{"lineNumber":284,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":285,"author":{"gitId":"marquestye"},"content":" Team originalTeam \u003d student4.getTeam();"},{"lineNumber":286,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":287,"author":{"gitId":"marquestye"},"content":" StudentUpdateRequest emptySectionUpdateRequest \u003d new StudentUpdateRequest(student4.getName(), student4.getEmail(),"},{"lineNumber":288,"author":{"gitId":"marquestye"},"content":" student4.getTeamName(), \"\", student4.getComments(), true);"},{"lineNumber":289,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":290,"author":{"gitId":"marquestye"},"content":" String[] emptySectionSubmissionParams \u003d new String[] {"},{"lineNumber":291,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, student4.getCourseId(),"},{"lineNumber":292,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, student4.getEmail(),"},{"lineNumber":293,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":294,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":295,"author":{"gitId":"marquestye"},"content":" UpdateStudentAction updateEmptySectionAction \u003d getAction(emptySectionUpdateRequest, emptySectionSubmissionParams);"},{"lineNumber":296,"author":{"gitId":"marquestye"},"content":" JsonResult emptySectionActionOutput \u003d getJsonResult(updateEmptySectionAction);"},{"lineNumber":297,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":298,"author":{"gitId":"marquestye"},"content":" MessageOutput emptySectionMsgOutput \u003d (MessageOutput) emptySectionActionOutput.getOutput();"},{"lineNumber":299,"author":{"gitId":"marquestye"},"content":" assertEquals(\"Student has been updated\", emptySectionMsgOutput.getMessage());"},{"lineNumber":300,"author":{"gitId":"marquestye"},"content":" verifyNoEmailsSent();"},{"lineNumber":301,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":302,"author":{"gitId":"marquestye"},"content":" // verify student in database"},{"lineNumber":303,"author":{"gitId":"marquestye"},"content":" Student actualStudent \u003d"},{"lineNumber":304,"author":{"gitId":"marquestye"},"content":" logic.getStudentForEmail(student4.getCourseId(), student4.getEmail());"},{"lineNumber":305,"author":{"gitId":"marquestye"},"content":" assertEquals(student4.getCourse(), actualStudent.getCourse());"},{"lineNumber":306,"author":{"gitId":"marquestye"},"content":" assertEquals(student4.getName(), actualStudent.getName());"},{"lineNumber":307,"author":{"gitId":"marquestye"},"content":" assertEquals(student4.getEmail(), actualStudent.getEmail());"},{"lineNumber":308,"author":{"gitId":"marquestye"},"content":" assertEquals(student4.getTeam(), actualStudent.getTeam());"},{"lineNumber":309,"author":{"gitId":"marquestye"},"content":" assertEquals(Const.DEFAULT_SECTION, actualStudent.getSectionName());"},{"lineNumber":310,"author":{"gitId":"marquestye"},"content":" assertEquals(student4.getComments(), actualStudent.getComments());"},{"lineNumber":311,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":312,"author":{"gitId":"marquestye"},"content":" resetStudent(student4.getId(), student4.getEmail(), originalTeam, student4.getComments());"},{"lineNumber":313,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":314,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":315,"author":{"gitId":"marquestye"},"content":" @Override"},{"lineNumber":316,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":317,"author":{"gitId":"marquestye"},"content":" protected void testAccessControl() throws Exception {"},{"lineNumber":318,"author":{"gitId":"marquestye"},"content":" Student student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":319,"author":{"gitId":"marquestye"},"content":" Course course \u003d typicalBundle.courses.get(\"course1\");"},{"lineNumber":320,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":321,"author":{"gitId":"marquestye"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":322,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.COURSE_ID, student1.getCourseId(),"},{"lineNumber":323,"author":{"gitId":"marquestye"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":324,"author":{"gitId":"marquestye"},"content":" };"},{"lineNumber":325,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":326,"author":{"gitId":"marquestye"},"content":" verifyOnlyInstructorsOfTheSameCourseWithCorrectCoursePrivilegeCanAccess("},{"lineNumber":327,"author":{"gitId":"marquestye"},"content":" course, Const.InstructorPermissions.CAN_MODIFY_STUDENT, submissionParams);"},{"lineNumber":328,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":329,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":330,"author":{"gitId":"marquestye"},"content":" private void resetStudent(UUID studentId, String originalEmail, Team originalTeam, String originalComments) {"},{"lineNumber":331,"author":{"gitId":"marquestye"},"content":" Student updatedStudent \u003d logic.getStudent(studentId);"},{"lineNumber":332,"author":{"gitId":"marquestye"},"content":" updatedStudent.setEmail(originalEmail);"},{"lineNumber":333,"author":{"gitId":"marquestye"},"content":" updatedStudent.setTeam(originalTeam);"},{"lineNumber":334,"author":{"gitId":"marquestye"},"content":" updatedStudent.setComments(originalComments);"},{"lineNumber":335,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":336,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":337,"author":{"gitId":"marquestye"},"content":"}"}],"authorContributionMap":{"marquestye":337}},{"path":"src/main/java/teammates/common/datatransfer/FeedbackSessionLogEntry.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.datatransfer;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":6,"author":{"gitId":"-"},"content":" * Represents a log entry of a feedback session."},{"lineNumber":7,"author":{"gitId":"-"},"content":" */"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"public class FeedbackSessionLogEntry implements Comparable\u003cFeedbackSessionLogEntry\u003e {"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":" private final String courseId;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":" private final UUID studentId;"},{"lineNumber":11,"author":{"gitId":"-"},"content":" private final String studentEmail;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":" private final UUID feedbackSessionId;"},{"lineNumber":13,"author":{"gitId":"-"},"content":" private final String feedbackSessionName;"},{"lineNumber":14,"author":{"gitId":"-"},"content":" private final String feedbackSessionLogType;"},{"lineNumber":15,"author":{"gitId":"-"},"content":" private final long timestamp;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":" public FeedbackSessionLogEntry(String courseId, String studentEmail,"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" String feedbackSessionName, String feedbackSessionLogType, long timestamp) {"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":" this.courseId \u003d courseId;"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":" this.studentId \u003d null;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" this.studentEmail \u003d studentEmail;"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionId \u003d null;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" this.feedbackSessionName \u003d feedbackSessionName;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" this.feedbackSessionLogType \u003d feedbackSessionLogType;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" this.timestamp \u003d timestamp;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" }"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" public FeedbackSessionLogEntry(String courseId, UUID studentId, UUID feedbackSessionId,"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" String feedbackSessionLogType, long timestamp) {"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" this.courseId \u003d courseId;"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" this.studentId \u003d studentId;"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" this.studentEmail \u003d null;"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionId \u003d feedbackSessionId;"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionName \u003d null;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" this.feedbackSessionLogType \u003d feedbackSessionLogType;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" this.timestamp \u003d timestamp;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" }"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" public String getCourseId() {"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" return courseId;"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" public UUID getStudentId() {"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" return studentId;"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" public String getStudentEmail() {"},{"lineNumber":48,"author":{"gitId":"-"},"content":" return studentEmail;"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" public UUID getFeedbackSessionId() {"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" return feedbackSessionId;"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" public String getFeedbackSessionName() {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" return feedbackSessionName;"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" public String getFeedbackSessionLogType() {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" return this.feedbackSessionLogType;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" public long getTimestamp() {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" return this.timestamp;"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" public int compareTo(FeedbackSessionLogEntry o) {"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" return Long.compare(this.getTimestamp(), o.getTimestamp());"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":35,"-":36}},{"path":"src/main/java/teammates/common/datatransfer/SqlDataBundle.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.datatransfer;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.LinkedHashMap;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.ReadNotification;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":23,"author":{"gitId":"-"},"content":" * Holds a bundle of entities."},{"lineNumber":24,"author":{"gitId":"-"},"content":" *"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * \u003cp\u003eThis class is mainly used for serializing JSON strings."},{"lineNumber":26,"author":{"gitId":"-"},"content":" */"},{"lineNumber":27,"author":{"gitId":"-"},"content":"// CHECKSTYLE.OFF:JavadocVariable each field represents different entity types"},{"lineNumber":28,"author":{"gitId":"-"},"content":"public class SqlDataBundle {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" public Map\u003cString, Account\u003e accounts \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":30,"author":{"gitId":"-"},"content":" public Map\u003cString, AccountRequest\u003e accountRequests \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":31,"author":{"gitId":"-"},"content":" public Map\u003cString, Course\u003e courses \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":32,"author":{"gitId":"-"},"content":" public Map\u003cString, Section\u003e sections \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":33,"author":{"gitId":"-"},"content":" public Map\u003cString, Team\u003e teams \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":34,"author":{"gitId":"-"},"content":" public Map\u003cString, DeadlineExtension\u003e deadlineExtensions \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":35,"author":{"gitId":"-"},"content":" public Map\u003cString, Instructor\u003e instructors \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":36,"author":{"gitId":"-"},"content":" public Map\u003cString, Student\u003e students \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":37,"author":{"gitId":"-"},"content":" public Map\u003cString, FeedbackSession\u003e feedbackSessions \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":38,"author":{"gitId":"-"},"content":" public Map\u003cString, FeedbackQuestion\u003e feedbackQuestions \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":39,"author":{"gitId":"-"},"content":" public Map\u003cString, FeedbackResponse\u003e feedbackResponses \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":40,"author":{"gitId":"-"},"content":" public Map\u003cString, FeedbackResponseComment\u003e feedbackResponseComments \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" public Map\u003cString, FeedbackSessionLog\u003e feedbackSessionLogs \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":42,"author":{"gitId":"-"},"content":" public Map\u003cString, Notification\u003e notifications \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" public Map\u003cString, ReadNotification\u003e readNotifications \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":44,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":2,"-":42}},{"path":"src/main/java/teammates/common/datatransfer/SqlSessionResultsBundle.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.common.datatransfer;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import java.util.LinkedHashMap;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import java.util.Map;"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import java.util.Set;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const;"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.StringHelper;"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" * Represents detailed results for a feedback session."},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":"public class SqlSessionResultsBundle {"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" private final List\u003cFeedbackQuestion\u003e questions;"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" private final Set\u003cFeedbackQuestion\u003e questionsNotVisibleForPreviewSet;"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" private final Set\u003cFeedbackQuestion\u003e questionsWithCommentNotVisibleForPreviewSet;"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" private final Map\u003cFeedbackQuestion, List\u003cFeedbackResponse\u003e\u003e questionResponseMap;"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" private final Map\u003cFeedbackQuestion, List\u003cFeedbackResponse\u003e\u003e questionMissingResponseMap;"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" private final Map\u003cFeedbackResponse, List\u003cFeedbackResponseComment\u003e\u003e responseCommentsMap;"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" private final Map\u003cFeedbackResponse, Boolean\u003e responseGiverVisibilityTable;"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" private final Map\u003cFeedbackResponse, Boolean\u003e responseRecipientVisibilityTable;"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" private final Map\u003cLong, Boolean\u003e commentGiverVisibilityTable;"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" private final SqlCourseRoster roster;"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" public SqlSessionResultsBundle(List\u003cFeedbackQuestion\u003e questions,"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" Set\u003cFeedbackQuestion\u003e questionsNotVisibleForPreviewSet,"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" Set\u003cFeedbackQuestion\u003e questionsWithCommentNotVisibleForPreviewSet,"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e responses,"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e missingResponses,"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackResponse, Boolean\u003e responseGiverVisibilityTable,"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackResponse, Boolean\u003e responseRecipientVisibilityTable,"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackResponse, List\u003cFeedbackResponseComment\u003e\u003e responseCommentsMap,"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" Map\u003cLong, Boolean\u003e commentGiverVisibilityTable,"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" SqlCourseRoster roster) {"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" this.questions \u003d questions;"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" this.questionsNotVisibleForPreviewSet \u003d questionsNotVisibleForPreviewSet;"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" this.questionsWithCommentNotVisibleForPreviewSet \u003d questionsWithCommentNotVisibleForPreviewSet;"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" this.responseCommentsMap \u003d responseCommentsMap;"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" this.responseGiverVisibilityTable \u003d responseGiverVisibilityTable;"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" this.responseRecipientVisibilityTable \u003d responseRecipientVisibilityTable;"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" this.commentGiverVisibilityTable \u003d commentGiverVisibilityTable;"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" this.roster \u003d roster;"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" this.questionResponseMap \u003d buildQuestionToResponseMap(responses);"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" this.questionMissingResponseMap \u003d buildQuestionToResponseMap(missingResponses);"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" private Map\u003cFeedbackQuestion, List\u003cFeedbackResponse\u003e\u003e buildQuestionToResponseMap("},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e responses) {"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" // build question to response map"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackQuestion, List\u003cFeedbackResponse\u003e\u003e questionToResponseMap \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" for (FeedbackQuestion question : questions) {"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" questionToResponseMap.put(question, new ArrayList\u003c\u003e());"},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" for (FeedbackResponse response : responses) {"},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question \u003d response.getFeedbackQuestion();"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e responsesForQuestion \u003d questionToResponseMap.get(question);"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" responsesForQuestion.add(response);"},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":" return questionToResponseMap;"},{"lineNumber":67,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":68,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":" * Returns true if the giver of a response is visible to the current user."},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" * Returns false otherwise."},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":" public boolean isResponseGiverVisible(FeedbackResponse response) {"},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" return isResponseParticipantVisible(true, response);"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" * Returns true if the recipient of a response is visible to the current user."},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":" * Returns false otherwise."},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":" public boolean isResponseRecipientVisible(FeedbackResponse response) {"},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":" return isResponseParticipantVisible(false, response);"},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":" * Checks if the giver/recipient for a response is visible/hidden from the current user."},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" private boolean isResponseParticipantVisible(boolean isGiver, FeedbackResponse response) {"},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question \u003d response.getFeedbackQuestion();"},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" FeedbackParticipantType participantType;"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":" boolean isVisible;"},{"lineNumber":93,"author":{"gitId":"xenosf"},"content":" if (isGiver) {"},{"lineNumber":94,"author":{"gitId":"xenosf"},"content":" isVisible \u003d responseGiverVisibilityTable.get(response);"},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":" participantType \u003d question.getGiverType();"},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" isVisible \u003d responseRecipientVisibilityTable.get(response);"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" participantType \u003d question.getRecipientType();"},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":100,"author":{"gitId":"xenosf"},"content":" boolean isTypeNone \u003d participantType \u003d\u003d FeedbackParticipantType.NONE;"},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":102,"author":{"gitId":"xenosf"},"content":" return isVisible || isTypeNone;"},{"lineNumber":103,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":104,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":105,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":106,"author":{"gitId":"xenosf"},"content":" * Returns true if the giver of a comment is visible to the current user."},{"lineNumber":107,"author":{"gitId":"xenosf"},"content":" * Returns false otherwise."},{"lineNumber":108,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":109,"author":{"gitId":"xenosf"},"content":" public boolean isCommentGiverVisible(FeedbackResponseComment comment) {"},{"lineNumber":110,"author":{"gitId":"xenosf"},"content":" return commentGiverVisibilityTable.get(comment.getId());"},{"lineNumber":111,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":112,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":113,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":114,"author":{"gitId":"xenosf"},"content":" * Gets the anonymous name for a given name."},{"lineNumber":115,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" * \u003cp\u003eThe anonymous name will be deterministic based on {@code name}."},{"lineNumber":117,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":118,"author":{"gitId":"xenosf"},"content":" public static String getAnonName(FeedbackParticipantType type, String name) {"},{"lineNumber":119,"author":{"gitId":"xenosf"},"content":" String hashedEncryptedName \u003d getHashOfName(getEncryptedName(name));"},{"lineNumber":120,"author":{"gitId":"xenosf"},"content":" String participantType \u003d type.toSingularFormString();"},{"lineNumber":121,"author":{"gitId":"xenosf"},"content":" return String.format("},{"lineNumber":122,"author":{"gitId":"xenosf"},"content":" Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT + \" %s %s\", participantType, hashedEncryptedName);"},{"lineNumber":123,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":124,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":125,"author":{"gitId":"xenosf"},"content":" public Map\u003cFeedbackQuestion, List\u003cFeedbackResponse\u003e\u003e getQuestionResponseMap() {"},{"lineNumber":126,"author":{"gitId":"xenosf"},"content":" return questionResponseMap;"},{"lineNumber":127,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":128,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":129,"author":{"gitId":"xenosf"},"content":" public Map\u003cFeedbackQuestion, List\u003cFeedbackResponse\u003e\u003e getQuestionMissingResponseMap() {"},{"lineNumber":130,"author":{"gitId":"xenosf"},"content":" return questionMissingResponseMap;"},{"lineNumber":131,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":132,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":133,"author":{"gitId":"xenosf"},"content":" private static String getEncryptedName(String name) {"},{"lineNumber":134,"author":{"gitId":"xenosf"},"content":" return StringHelper.encrypt(name);"},{"lineNumber":135,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":136,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":137,"author":{"gitId":"xenosf"},"content":" private static String getHashOfName(String name) {"},{"lineNumber":138,"author":{"gitId":"xenosf"},"content":" return Long.toString(Math.abs((long) name.hashCode()));"},{"lineNumber":139,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":140,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":141,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackQuestion\u003e getQuestions() {"},{"lineNumber":142,"author":{"gitId":"xenosf"},"content":" return questions;"},{"lineNumber":143,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":144,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":145,"author":{"gitId":"xenosf"},"content":" public Map\u003cFeedbackResponse, List\u003cFeedbackResponseComment\u003e\u003e getResponseCommentsMap() {"},{"lineNumber":146,"author":{"gitId":"xenosf"},"content":" return responseCommentsMap;"},{"lineNumber":147,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":148,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":149,"author":{"gitId":"xenosf"},"content":" public SqlCourseRoster getRoster() {"},{"lineNumber":150,"author":{"gitId":"xenosf"},"content":" return roster;"},{"lineNumber":151,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":152,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":153,"author":{"gitId":"xenosf"},"content":" public Map\u003cFeedbackResponse, Boolean\u003e getResponseGiverVisibilityTable() {"},{"lineNumber":154,"author":{"gitId":"xenosf"},"content":" return responseGiverVisibilityTable;"},{"lineNumber":155,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":156,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":157,"author":{"gitId":"xenosf"},"content":" public Map\u003cFeedbackResponse, Boolean\u003e getResponseRecipientVisibilityTable() {"},{"lineNumber":158,"author":{"gitId":"xenosf"},"content":" return responseRecipientVisibilityTable;"},{"lineNumber":159,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":160,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":161,"author":{"gitId":"xenosf"},"content":" public Map\u003cLong, Boolean\u003e getCommentGiverVisibilityTable() {"},{"lineNumber":162,"author":{"gitId":"xenosf"},"content":" return commentGiverVisibilityTable;"},{"lineNumber":163,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":164,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":165,"author":{"gitId":"xenosf"},"content":" public Set\u003cFeedbackQuestion\u003e getQuestionsNotVisibleForPreviewSet() {"},{"lineNumber":166,"author":{"gitId":"xenosf"},"content":" return questionsNotVisibleForPreviewSet;"},{"lineNumber":167,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":168,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":169,"author":{"gitId":"xenosf"},"content":" public Set\u003cFeedbackQuestion\u003e getQuestionsWithCommentNotVisibleForPreviewSet() {"},{"lineNumber":170,"author":{"gitId":"xenosf"},"content":" return questionsWithCommentNotVisibleForPreviewSet;"},{"lineNumber":171,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":172,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":172}},{"path":"src/main/java/teammates/common/datatransfer/attributes/StudentAttributes.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.datatransfer.attributes;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.Comparator;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.Objects;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.entity.CourseStudent;"},{"lineNumber":14,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * The data transfer object for {@link CourseStudent} entities."},{"lineNumber":18,"author":{"gitId":"-"},"content":" */"},{"lineNumber":19,"author":{"gitId":"-"},"content":"public final class StudentAttributes extends EntityAttributes\u003cCourseStudent\u003e {"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" private String email;"},{"lineNumber":22,"author":{"gitId":"-"},"content":" private String course;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" private String name;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" private String googleId;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" private String comments;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" private String team;"},{"lineNumber":27,"author":{"gitId":"-"},"content":" private String section;"},{"lineNumber":28,"author":{"gitId":"-"},"content":" private transient String key;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" private transient Instant createdAt;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" private transient Instant updatedAt;"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" private StudentAttributes(String courseId, String email) {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" this.course \u003d courseId;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" this.email \u003d email;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" this.googleId \u003d \"\";"},{"lineNumber":37,"author":{"gitId":"-"},"content":" this.section \u003d Const.DEFAULT_SECTION;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" this.createdAt \u003d Const.TIME_REPRESENTS_DEFAULT_TIMESTAMP;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.updatedAt \u003d Const.TIME_REPRESENTS_DEFAULT_TIMESTAMP;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":43,"author":{"gitId":"-"},"content":" * Gets the {@link StudentAttributes} instance of the given {@link CourseStudent}."},{"lineNumber":44,"author":{"gitId":"-"},"content":" */"},{"lineNumber":45,"author":{"gitId":"-"},"content":" public static StudentAttributes valueOf(CourseStudent student) {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" StudentAttributes studentAttributes \u003d new StudentAttributes(student.getCourseId(), student.getEmail());"},{"lineNumber":47,"author":{"gitId":"-"},"content":" studentAttributes.name \u003d student.getName();"},{"lineNumber":48,"author":{"gitId":"-"},"content":" if (student.getGoogleId() !\u003d null) {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" studentAttributes.googleId \u003d student.getGoogleId();"},{"lineNumber":50,"author":{"gitId":"-"},"content":" }"},{"lineNumber":51,"author":{"gitId":"-"},"content":" studentAttributes.team \u003d student.getTeamName();"},{"lineNumber":52,"author":{"gitId":"-"},"content":" if (student.getSectionName() !\u003d null) {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" studentAttributes.section \u003d student.getSectionName();"},{"lineNumber":54,"author":{"gitId":"-"},"content":" }"},{"lineNumber":55,"author":{"gitId":"-"},"content":" studentAttributes.comments \u003d student.getComments();"},{"lineNumber":56,"author":{"gitId":"-"},"content":" studentAttributes.key \u003d student.getRegistrationKey();"},{"lineNumber":57,"author":{"gitId":"-"},"content":" if (student.getCreatedAt() !\u003d null) {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" studentAttributes.createdAt \u003d student.getCreatedAt();"},{"lineNumber":59,"author":{"gitId":"-"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":" if (student.getUpdatedAt() !\u003d null) {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" studentAttributes.updatedAt \u003d student.getUpdatedAt();"},{"lineNumber":62,"author":{"gitId":"-"},"content":" }"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" return studentAttributes;"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"marquestye"},"content":" /**"},{"lineNumber":68,"author":{"gitId":"marquestye"},"content":" * Gets the {@link StudentAttributes} instance of the given {@link Student}."},{"lineNumber":69,"author":{"gitId":"marquestye"},"content":" */"},{"lineNumber":70,"author":{"gitId":"marquestye"},"content":" public static StudentAttributes valueOf(Student student) {"},{"lineNumber":71,"author":{"gitId":"marquestye"},"content":" StudentAttributes studentAttributes \u003d new StudentAttributes(student.getCourseId(), student.getEmail());"},{"lineNumber":72,"author":{"gitId":"marquestye"},"content":" studentAttributes.name \u003d student.getName();"},{"lineNumber":73,"author":{"gitId":"marquestye"},"content":" if (student.getGoogleId() !\u003d null) {"},{"lineNumber":74,"author":{"gitId":"marquestye"},"content":" studentAttributes.googleId \u003d student.getGoogleId();"},{"lineNumber":75,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":76,"author":{"gitId":"marquestye"},"content":" studentAttributes.team \u003d student.getTeamName();"},{"lineNumber":77,"author":{"gitId":"marquestye"},"content":" if (student.getSectionName() !\u003d null) {"},{"lineNumber":78,"author":{"gitId":"marquestye"},"content":" studentAttributes.section \u003d student.getSectionName();"},{"lineNumber":79,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":80,"author":{"gitId":"marquestye"},"content":" studentAttributes.comments \u003d student.getComments();"},{"lineNumber":81,"author":{"gitId":"marquestye"},"content":" // studentAttributes.key \u003d student.getRegistrationKey();"},{"lineNumber":82,"author":{"gitId":"marquestye"},"content":" if (student.getCreatedAt() !\u003d null) {"},{"lineNumber":83,"author":{"gitId":"marquestye"},"content":" studentAttributes.createdAt \u003d student.getCreatedAt();"},{"lineNumber":84,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":85,"author":{"gitId":"marquestye"},"content":" if (student.getUpdatedAt() !\u003d null) {"},{"lineNumber":86,"author":{"gitId":"marquestye"},"content":" studentAttributes.updatedAt \u003d student.getUpdatedAt();"},{"lineNumber":87,"author":{"gitId":"-"},"content":" }"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" return studentAttributes;"},{"lineNumber":90,"author":{"gitId":"-"},"content":" }"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":93,"author":{"gitId":"-"},"content":" * Return a builder for {@link StudentAttributes}."},{"lineNumber":94,"author":{"gitId":"-"},"content":" */"},{"lineNumber":95,"author":{"gitId":"-"},"content":" public static Builder builder(String courseId, String email) {"},{"lineNumber":96,"author":{"gitId":"-"},"content":" return new Builder(courseId, email);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" }"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":100,"author":{"gitId":"-"},"content":" * Gets a deep copy of this object."},{"lineNumber":101,"author":{"gitId":"-"},"content":" */"},{"lineNumber":102,"author":{"gitId":"-"},"content":" public StudentAttributes getCopy() {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" StudentAttributes studentAttributes \u003d new StudentAttributes(course, email);"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" studentAttributes.name \u003d name;"},{"lineNumber":106,"author":{"gitId":"-"},"content":" studentAttributes.googleId \u003d googleId;"},{"lineNumber":107,"author":{"gitId":"-"},"content":" studentAttributes.team \u003d team;"},{"lineNumber":108,"author":{"gitId":"-"},"content":" studentAttributes.section \u003d section;"},{"lineNumber":109,"author":{"gitId":"-"},"content":" studentAttributes.comments \u003d comments;"},{"lineNumber":110,"author":{"gitId":"-"},"content":" studentAttributes.key \u003d key;"},{"lineNumber":111,"author":{"gitId":"-"},"content":" studentAttributes.createdAt \u003d createdAt;"},{"lineNumber":112,"author":{"gitId":"-"},"content":" studentAttributes.updatedAt \u003d updatedAt;"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" return studentAttributes;"},{"lineNumber":115,"author":{"gitId":"-"},"content":" }"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" public boolean isRegistered() {"},{"lineNumber":118,"author":{"gitId":"-"},"content":" return googleId !\u003d null \u0026\u0026 !googleId.trim().isEmpty();"},{"lineNumber":119,"author":{"gitId":"-"},"content":" }"},{"lineNumber":120,"author":{"gitId":"-"},"content":""},{"lineNumber":121,"author":{"gitId":"-"},"content":" public String getRegistrationUrl() {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" return Config.getFrontEndAppUrl(Const.WebPageURIs.JOIN_PAGE)"},{"lineNumber":123,"author":{"gitId":"-"},"content":" .withRegistrationKey(key)"},{"lineNumber":124,"author":{"gitId":"-"},"content":" .withEntityType(Const.EntityType.STUDENT)"},{"lineNumber":125,"author":{"gitId":"-"},"content":" .toString();"},{"lineNumber":126,"author":{"gitId":"-"},"content":" }"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" public String getName() {"},{"lineNumber":129,"author":{"gitId":"-"},"content":" return name;"},{"lineNumber":130,"author":{"gitId":"-"},"content":" }"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":" public void setName(String name) {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" this.name \u003d name;"},{"lineNumber":134,"author":{"gitId":"-"},"content":" }"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" public String getEmail() {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" public void setEmail(String email) {"},{"lineNumber":141,"author":{"gitId":"-"},"content":" this.email \u003d email;"},{"lineNumber":142,"author":{"gitId":"-"},"content":" }"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" public String getCourse() {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" return course;"},{"lineNumber":146,"author":{"gitId":"-"},"content":" }"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" public void setCourse(String course) {"},{"lineNumber":149,"author":{"gitId":"-"},"content":" this.course \u003d course;"},{"lineNumber":150,"author":{"gitId":"-"},"content":" }"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" public String getGoogleId() {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" return googleId;"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" public void setGoogleId(String googleId) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" this.googleId \u003d googleId;"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" public String getKey() {"},{"lineNumber":161,"author":{"gitId":"-"},"content":" return key;"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" public void setKey(String key) {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" this.key \u003d key;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" }"},{"lineNumber":167,"author":{"gitId":"-"},"content":""},{"lineNumber":168,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":169,"author":{"gitId":"-"},"content":" * Format: email%courseId e.g., adam@gmail.com%cs1101."},{"lineNumber":170,"author":{"gitId":"-"},"content":" */"},{"lineNumber":171,"author":{"gitId":"-"},"content":" public String getId() {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" return email + \"%\" + course;"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" public String getSection() {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" return section;"},{"lineNumber":177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" public void setSection(String section) {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" this.section \u003d section;"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" public String getTeam() {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" return team;"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" public void setTeam(String team) {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" this.team \u003d team;"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" public String getComments() {"},{"lineNumber":192,"author":{"gitId":"-"},"content":" return comments;"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"-"},"content":" public void setComments(String comments) {"},{"lineNumber":196,"author":{"gitId":"-"},"content":" this.comments \u003d comments;"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":200,"author":{"gitId":"-"},"content":" public boolean equals(Object other) {"},{"lineNumber":201,"author":{"gitId":"-"},"content":" if (other \u003d\u003d null) {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":203,"author":{"gitId":"-"},"content":" } else if (this \u003d\u003d other) {"},{"lineNumber":204,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":205,"author":{"gitId":"-"},"content":" } else if (this.getClass() \u003d\u003d other.getClass()) {"},{"lineNumber":206,"author":{"gitId":"-"},"content":" StudentAttributes otherStudent \u003d (StudentAttributes) other;"},{"lineNumber":207,"author":{"gitId":"-"},"content":" return Objects.equals(this.course, otherStudent.course)"},{"lineNumber":208,"author":{"gitId":"-"},"content":" \u0026\u0026 Objects.equals(this.name, otherStudent.name)"},{"lineNumber":209,"author":{"gitId":"-"},"content":" \u0026\u0026 Objects.equals(this.email, otherStudent.email)"},{"lineNumber":210,"author":{"gitId":"-"},"content":" \u0026\u0026 Objects.equals(this.googleId, otherStudent.googleId)"},{"lineNumber":211,"author":{"gitId":"-"},"content":" \u0026\u0026 Objects.equals(this.comments, otherStudent.comments)"},{"lineNumber":212,"author":{"gitId":"-"},"content":" \u0026\u0026 Objects.equals(this.team, otherStudent.team)"},{"lineNumber":213,"author":{"gitId":"-"},"content":" \u0026\u0026 Objects.equals(this.section, otherStudent.section);"},{"lineNumber":214,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":216,"author":{"gitId":"-"},"content":" }"},{"lineNumber":217,"author":{"gitId":"-"},"content":" }"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":220,"author":{"gitId":"-"},"content":" public List\u003cString\u003e getInvalidityInfo() {"},{"lineNumber":221,"author":{"gitId":"-"},"content":" // id is allowed to be null when the student is not registered"},{"lineNumber":222,"author":{"gitId":"-"},"content":" assert team !\u003d null;"},{"lineNumber":223,"author":{"gitId":"-"},"content":" assert comments !\u003d null;"},{"lineNumber":224,"author":{"gitId":"-"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":" List\u003cString\u003e errors \u003d new ArrayList\u003c\u003e();"},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"-"},"content":" if (isRegistered()) {"},{"lineNumber":228,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForGoogleId(googleId), errors);"},{"lineNumber":229,"author":{"gitId":"-"},"content":" }"},{"lineNumber":230,"author":{"gitId":"-"},"content":""},{"lineNumber":231,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForCourseId(course), errors);"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForEmail(email), errors);"},{"lineNumber":234,"author":{"gitId":"-"},"content":""},{"lineNumber":235,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForTeamName(team), errors);"},{"lineNumber":236,"author":{"gitId":"-"},"content":""},{"lineNumber":237,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForSectionName(section), errors);"},{"lineNumber":238,"author":{"gitId":"-"},"content":""},{"lineNumber":239,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForStudentRoleComments(comments), errors);"},{"lineNumber":240,"author":{"gitId":"-"},"content":""},{"lineNumber":241,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForPersonName(name), errors);"},{"lineNumber":242,"author":{"gitId":"-"},"content":""},{"lineNumber":243,"author":{"gitId":"-"},"content":" return errors;"},{"lineNumber":244,"author":{"gitId":"-"},"content":" }"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":247,"author":{"gitId":"-"},"content":" * Sorts the list of students by the section name, then team name, then name."},{"lineNumber":248,"author":{"gitId":"-"},"content":" */"},{"lineNumber":249,"author":{"gitId":"-"},"content":" public static void sortBySectionName(List\u003cStudentAttributes\u003e students) {"},{"lineNumber":250,"author":{"gitId":"-"},"content":" students.sort(Comparator.comparing((StudentAttributes student) -\u003e student.section)"},{"lineNumber":251,"author":{"gitId":"-"},"content":" .thenComparing(student -\u003e student.team)"},{"lineNumber":252,"author":{"gitId":"-"},"content":" .thenComparing(student -\u003e student.name));"},{"lineNumber":253,"author":{"gitId":"-"},"content":" }"},{"lineNumber":254,"author":{"gitId":"-"},"content":""},{"lineNumber":255,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":256,"author":{"gitId":"-"},"content":" * Sorts the list of students by the team name, then name."},{"lineNumber":257,"author":{"gitId":"-"},"content":" */"},{"lineNumber":258,"author":{"gitId":"-"},"content":" public static void sortByTeamName(List\u003cStudentAttributes\u003e students) {"},{"lineNumber":259,"author":{"gitId":"-"},"content":" students.sort(Comparator.comparing((StudentAttributes student) -\u003e student.team)"},{"lineNumber":260,"author":{"gitId":"-"},"content":" .thenComparing(student -\u003e student.name));"},{"lineNumber":261,"author":{"gitId":"-"},"content":" }"},{"lineNumber":262,"author":{"gitId":"-"},"content":""},{"lineNumber":263,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":264,"author":{"gitId":"-"},"content":" public CourseStudent toEntity() {"},{"lineNumber":265,"author":{"gitId":"-"},"content":" return new CourseStudent(email, name, googleId, comments, course, team, section);"},{"lineNumber":266,"author":{"gitId":"-"},"content":" }"},{"lineNumber":267,"author":{"gitId":"-"},"content":""},{"lineNumber":268,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":269,"author":{"gitId":"-"},"content":" public int hashCode() {"},{"lineNumber":270,"author":{"gitId":"-"},"content":" StringBuilder stringBuilder \u003d new StringBuilder();"},{"lineNumber":271,"author":{"gitId":"-"},"content":" stringBuilder.append(this.email).append(this.name).append(this.course)"},{"lineNumber":272,"author":{"gitId":"-"},"content":" .append(this.googleId).append(this.team).append(this.section).append(this.comments);"},{"lineNumber":273,"author":{"gitId":"-"},"content":" return stringBuilder.toString().hashCode();"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":277,"author":{"gitId":"-"},"content":" public String toString() {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" return \"Student:\" + name + \"[\" + email + \"]\";"},{"lineNumber":279,"author":{"gitId":"-"},"content":" }"},{"lineNumber":280,"author":{"gitId":"-"},"content":""},{"lineNumber":281,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":282,"author":{"gitId":"-"},"content":" public void sanitizeForSaving() {"},{"lineNumber":283,"author":{"gitId":"-"},"content":" googleId \u003d SanitizationHelper.sanitizeGoogleId(googleId);"},{"lineNumber":284,"author":{"gitId":"-"},"content":" name \u003d SanitizationHelper.sanitizeName(name);"},{"lineNumber":285,"author":{"gitId":"-"},"content":" comments \u003d SanitizationHelper.sanitizeTextField(comments);"},{"lineNumber":286,"author":{"gitId":"-"},"content":" }"},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":" public Instant getCreatedAt() {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" return createdAt;"},{"lineNumber":290,"author":{"gitId":"-"},"content":" }"},{"lineNumber":291,"author":{"gitId":"-"},"content":""},{"lineNumber":292,"author":{"gitId":"-"},"content":" public Instant getUpdatedAt() {"},{"lineNumber":293,"author":{"gitId":"-"},"content":" return updatedAt;"},{"lineNumber":294,"author":{"gitId":"-"},"content":" }"},{"lineNumber":295,"author":{"gitId":"-"},"content":""},{"lineNumber":296,"author":{"gitId":"-"},"content":" public void setCreatedAt(Instant createdAt) {"},{"lineNumber":297,"author":{"gitId":"-"},"content":" this.createdAt \u003d createdAt;"},{"lineNumber":298,"author":{"gitId":"-"},"content":" }"},{"lineNumber":299,"author":{"gitId":"-"},"content":""},{"lineNumber":300,"author":{"gitId":"-"},"content":" public void setUpdatedAt(Instant updatedAt) {"},{"lineNumber":301,"author":{"gitId":"-"},"content":" this.updatedAt \u003d updatedAt;"},{"lineNumber":302,"author":{"gitId":"-"},"content":" }"},{"lineNumber":303,"author":{"gitId":"-"},"content":""},{"lineNumber":304,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":305,"author":{"gitId":"-"},"content":" * Updates with {@link UpdateOptions}."},{"lineNumber":306,"author":{"gitId":"-"},"content":" */"},{"lineNumber":307,"author":{"gitId":"-"},"content":" public void update(UpdateOptions updateOptions) {"},{"lineNumber":308,"author":{"gitId":"-"},"content":" updateOptions.newEmailOption.ifPresent(s -\u003e email \u003d s);"},{"lineNumber":309,"author":{"gitId":"-"},"content":" updateOptions.nameOption.ifPresent(s -\u003e name \u003d s);"},{"lineNumber":310,"author":{"gitId":"-"},"content":" updateOptions.commentOption.ifPresent(s -\u003e comments \u003d s);"},{"lineNumber":311,"author":{"gitId":"-"},"content":" updateOptions.googleIdOption.ifPresent(s -\u003e googleId \u003d s);"},{"lineNumber":312,"author":{"gitId":"-"},"content":" updateOptions.teamNameOption.ifPresent(s -\u003e team \u003d s);"},{"lineNumber":313,"author":{"gitId":"-"},"content":" updateOptions.sectionNameOption.ifPresent(s -\u003e section \u003d s);"},{"lineNumber":314,"author":{"gitId":"-"},"content":" }"},{"lineNumber":315,"author":{"gitId":"-"},"content":""},{"lineNumber":316,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":317,"author":{"gitId":"-"},"content":" * Returns a {@link UpdateOptions.Builder} to build {@link UpdateOptions} for a student."},{"lineNumber":318,"author":{"gitId":"-"},"content":" */"},{"lineNumber":319,"author":{"gitId":"-"},"content":" public static UpdateOptions.Builder updateOptionsBuilder(String courseId, String email) {"},{"lineNumber":320,"author":{"gitId":"-"},"content":" return new UpdateOptions.Builder(courseId, email);"},{"lineNumber":321,"author":{"gitId":"-"},"content":" }"},{"lineNumber":322,"author":{"gitId":"-"},"content":""},{"lineNumber":323,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":324,"author":{"gitId":"-"},"content":" * A builder class for {@link StudentAttributes}."},{"lineNumber":325,"author":{"gitId":"-"},"content":" */"},{"lineNumber":326,"author":{"gitId":"-"},"content":" public static final class Builder extends BasicBuilder\u003cStudentAttributes, Builder\u003e {"},{"lineNumber":327,"author":{"gitId":"-"},"content":""},{"lineNumber":328,"author":{"gitId":"-"},"content":" private final StudentAttributes studentAttributes;"},{"lineNumber":329,"author":{"gitId":"-"},"content":""},{"lineNumber":330,"author":{"gitId":"-"},"content":" private Builder(String courseId, String email) {"},{"lineNumber":331,"author":{"gitId":"-"},"content":" super(new UpdateOptions(courseId, email));"},{"lineNumber":332,"author":{"gitId":"-"},"content":" thisBuilder \u003d this;"},{"lineNumber":333,"author":{"gitId":"-"},"content":""},{"lineNumber":334,"author":{"gitId":"-"},"content":" studentAttributes \u003d new StudentAttributes(courseId, email);"},{"lineNumber":335,"author":{"gitId":"-"},"content":" }"},{"lineNumber":336,"author":{"gitId":"-"},"content":""},{"lineNumber":337,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":338,"author":{"gitId":"-"},"content":" public StudentAttributes build() {"},{"lineNumber":339,"author":{"gitId":"-"},"content":" studentAttributes.update(updateOptions);"},{"lineNumber":340,"author":{"gitId":"-"},"content":""},{"lineNumber":341,"author":{"gitId":"-"},"content":" return studentAttributes;"},{"lineNumber":342,"author":{"gitId":"-"},"content":" }"},{"lineNumber":343,"author":{"gitId":"-"},"content":" }"},{"lineNumber":344,"author":{"gitId":"-"},"content":""},{"lineNumber":345,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":346,"author":{"gitId":"-"},"content":" * Helper class to specify the fields to update in {@link StudentAttributes}."},{"lineNumber":347,"author":{"gitId":"-"},"content":" */"},{"lineNumber":348,"author":{"gitId":"-"},"content":" public static final class UpdateOptions {"},{"lineNumber":349,"author":{"gitId":"-"},"content":" private String courseId;"},{"lineNumber":350,"author":{"gitId":"-"},"content":" private String email;"},{"lineNumber":351,"author":{"gitId":"-"},"content":""},{"lineNumber":352,"author":{"gitId":"-"},"content":" private UpdateOption\u003cString\u003e newEmailOption \u003d UpdateOption.empty();"},{"lineNumber":353,"author":{"gitId":"-"},"content":" private UpdateOption\u003cString\u003e nameOption \u003d UpdateOption.empty();"},{"lineNumber":354,"author":{"gitId":"-"},"content":" private UpdateOption\u003cString\u003e commentOption \u003d UpdateOption.empty();"},{"lineNumber":355,"author":{"gitId":"-"},"content":" private UpdateOption\u003cString\u003e googleIdOption \u003d UpdateOption.empty();"},{"lineNumber":356,"author":{"gitId":"-"},"content":" private UpdateOption\u003cString\u003e teamNameOption \u003d UpdateOption.empty();"},{"lineNumber":357,"author":{"gitId":"-"},"content":" private UpdateOption\u003cString\u003e sectionNameOption \u003d UpdateOption.empty();"},{"lineNumber":358,"author":{"gitId":"-"},"content":""},{"lineNumber":359,"author":{"gitId":"-"},"content":" private UpdateOptions(String courseId, String email) {"},{"lineNumber":360,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":361,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":362,"author":{"gitId":"-"},"content":""},{"lineNumber":363,"author":{"gitId":"-"},"content":" this.courseId \u003d courseId;"},{"lineNumber":364,"author":{"gitId":"-"},"content":" this.email \u003d email;"},{"lineNumber":365,"author":{"gitId":"-"},"content":" }"},{"lineNumber":366,"author":{"gitId":"-"},"content":""},{"lineNumber":367,"author":{"gitId":"-"},"content":" public String getCourseId() {"},{"lineNumber":368,"author":{"gitId":"-"},"content":" return courseId;"},{"lineNumber":369,"author":{"gitId":"-"},"content":" }"},{"lineNumber":370,"author":{"gitId":"-"},"content":""},{"lineNumber":371,"author":{"gitId":"-"},"content":" public String getEmail() {"},{"lineNumber":372,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":373,"author":{"gitId":"-"},"content":" }"},{"lineNumber":374,"author":{"gitId":"-"},"content":""},{"lineNumber":375,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":376,"author":{"gitId":"-"},"content":" public String toString() {"},{"lineNumber":377,"author":{"gitId":"-"},"content":" return \"StudentAttributes.UpdateOptions [\""},{"lineNumber":378,"author":{"gitId":"-"},"content":" + \"courseId \u003d \" + courseId"},{"lineNumber":379,"author":{"gitId":"-"},"content":" + \", email \u003d \" + email"},{"lineNumber":380,"author":{"gitId":"-"},"content":" + \", newEmail \u003d \" + newEmailOption"},{"lineNumber":381,"author":{"gitId":"-"},"content":" + \", name \u003d \" + nameOption"},{"lineNumber":382,"author":{"gitId":"-"},"content":" + \", comment \u003d \" + commentOption"},{"lineNumber":383,"author":{"gitId":"-"},"content":" + \", googleId \u003d \" + googleIdOption"},{"lineNumber":384,"author":{"gitId":"-"},"content":" + \", teamName \u003d \" + teamNameOption"},{"lineNumber":385,"author":{"gitId":"-"},"content":" + \", sectionName \u003d \" + sectionNameOption"},{"lineNumber":386,"author":{"gitId":"-"},"content":" + \"]\";"},{"lineNumber":387,"author":{"gitId":"-"},"content":" }"},{"lineNumber":388,"author":{"gitId":"-"},"content":""},{"lineNumber":389,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":390,"author":{"gitId":"-"},"content":" * Builder class to build {@link UpdateOptions}."},{"lineNumber":391,"author":{"gitId":"-"},"content":" */"},{"lineNumber":392,"author":{"gitId":"-"},"content":" public static final class Builder extends BasicBuilder\u003cUpdateOptions, Builder\u003e {"},{"lineNumber":393,"author":{"gitId":"-"},"content":""},{"lineNumber":394,"author":{"gitId":"-"},"content":" private Builder(String courseId, String email) {"},{"lineNumber":395,"author":{"gitId":"-"},"content":" super(new UpdateOptions(courseId, email));"},{"lineNumber":396,"author":{"gitId":"-"},"content":" thisBuilder \u003d this;"},{"lineNumber":397,"author":{"gitId":"-"},"content":" }"},{"lineNumber":398,"author":{"gitId":"-"},"content":""},{"lineNumber":399,"author":{"gitId":"-"},"content":" public Builder withNewEmail(String email) {"},{"lineNumber":400,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":401,"author":{"gitId":"-"},"content":""},{"lineNumber":402,"author":{"gitId":"-"},"content":" updateOptions.newEmailOption \u003d UpdateOption.of(email);"},{"lineNumber":403,"author":{"gitId":"-"},"content":" return thisBuilder;"},{"lineNumber":404,"author":{"gitId":"-"},"content":" }"},{"lineNumber":405,"author":{"gitId":"-"},"content":""},{"lineNumber":406,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":407,"author":{"gitId":"-"},"content":" public UpdateOptions build() {"},{"lineNumber":408,"author":{"gitId":"-"},"content":" return updateOptions;"},{"lineNumber":409,"author":{"gitId":"-"},"content":" }"},{"lineNumber":410,"author":{"gitId":"-"},"content":""},{"lineNumber":411,"author":{"gitId":"-"},"content":" }"},{"lineNumber":412,"author":{"gitId":"-"},"content":""},{"lineNumber":413,"author":{"gitId":"-"},"content":" }"},{"lineNumber":414,"author":{"gitId":"-"},"content":""},{"lineNumber":415,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":416,"author":{"gitId":"-"},"content":" * Basic builder to build {@link StudentAttributes} related classes."},{"lineNumber":417,"author":{"gitId":"-"},"content":" *"},{"lineNumber":418,"author":{"gitId":"-"},"content":" * @param \u003cT\u003e type to be built"},{"lineNumber":419,"author":{"gitId":"-"},"content":" * @param \u003cB\u003e type of the builder"},{"lineNumber":420,"author":{"gitId":"-"},"content":" */"},{"lineNumber":421,"author":{"gitId":"-"},"content":" private abstract static class BasicBuilder\u003cT, B extends BasicBuilder\u003cT, B\u003e\u003e {"},{"lineNumber":422,"author":{"gitId":"-"},"content":""},{"lineNumber":423,"author":{"gitId":"-"},"content":" UpdateOptions updateOptions;"},{"lineNumber":424,"author":{"gitId":"-"},"content":" B thisBuilder;"},{"lineNumber":425,"author":{"gitId":"-"},"content":""},{"lineNumber":426,"author":{"gitId":"-"},"content":" BasicBuilder(UpdateOptions updateOptions) {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" this.updateOptions \u003d updateOptions;"},{"lineNumber":428,"author":{"gitId":"-"},"content":" }"},{"lineNumber":429,"author":{"gitId":"-"},"content":""},{"lineNumber":430,"author":{"gitId":"-"},"content":" public B withName(String name) {"},{"lineNumber":431,"author":{"gitId":"-"},"content":" assert name !\u003d null;"},{"lineNumber":432,"author":{"gitId":"-"},"content":""},{"lineNumber":433,"author":{"gitId":"-"},"content":" updateOptions.nameOption \u003d UpdateOption.of(name);"},{"lineNumber":434,"author":{"gitId":"-"},"content":" return thisBuilder;"},{"lineNumber":435,"author":{"gitId":"-"},"content":" }"},{"lineNumber":436,"author":{"gitId":"-"},"content":""},{"lineNumber":437,"author":{"gitId":"-"},"content":" public B withComment(String comment) {"},{"lineNumber":438,"author":{"gitId":"-"},"content":" assert comment !\u003d null;"},{"lineNumber":439,"author":{"gitId":"-"},"content":""},{"lineNumber":440,"author":{"gitId":"-"},"content":" updateOptions.commentOption \u003d UpdateOption.of(comment);"},{"lineNumber":441,"author":{"gitId":"-"},"content":" return thisBuilder;"},{"lineNumber":442,"author":{"gitId":"-"},"content":" }"},{"lineNumber":443,"author":{"gitId":"-"},"content":""},{"lineNumber":444,"author":{"gitId":"-"},"content":" public B withGoogleId(String googleId) {"},{"lineNumber":445,"author":{"gitId":"-"},"content":" // google id can be set to null"},{"lineNumber":446,"author":{"gitId":"-"},"content":" updateOptions.googleIdOption \u003d UpdateOption.of(googleId);"},{"lineNumber":447,"author":{"gitId":"-"},"content":" return thisBuilder;"},{"lineNumber":448,"author":{"gitId":"-"},"content":" }"},{"lineNumber":449,"author":{"gitId":"-"},"content":""},{"lineNumber":450,"author":{"gitId":"-"},"content":" public B withTeamName(String teamName) {"},{"lineNumber":451,"author":{"gitId":"-"},"content":" assert teamName !\u003d null;"},{"lineNumber":452,"author":{"gitId":"-"},"content":""},{"lineNumber":453,"author":{"gitId":"-"},"content":" updateOptions.teamNameOption \u003d UpdateOption.of(teamName);"},{"lineNumber":454,"author":{"gitId":"-"},"content":" return thisBuilder;"},{"lineNumber":455,"author":{"gitId":"-"},"content":" }"},{"lineNumber":456,"author":{"gitId":"-"},"content":""},{"lineNumber":457,"author":{"gitId":"-"},"content":" public B withSectionName(String sectionName) {"},{"lineNumber":458,"author":{"gitId":"-"},"content":" assert sectionName !\u003d null;"},{"lineNumber":459,"author":{"gitId":"-"},"content":""},{"lineNumber":460,"author":{"gitId":"-"},"content":" updateOptions.sectionNameOption \u003d UpdateOption.of(sectionName);"},{"lineNumber":461,"author":{"gitId":"-"},"content":" return thisBuilder;"},{"lineNumber":462,"author":{"gitId":"-"},"content":" }"},{"lineNumber":463,"author":{"gitId":"-"},"content":""},{"lineNumber":464,"author":{"gitId":"-"},"content":" public abstract T build();"},{"lineNumber":465,"author":{"gitId":"-"},"content":""},{"lineNumber":466,"author":{"gitId":"-"},"content":" }"},{"lineNumber":467,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":21,"-":446}},{"path":"src/main/java/teammates/common/datatransfer/logs/FeedbackSessionAuditLogDetails.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.datatransfer.logs;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":6,"author":{"gitId":"-"},"content":" * Contains specific structure and processing logic for feedback session audit log."},{"lineNumber":7,"author":{"gitId":"-"},"content":" */"},{"lineNumber":8,"author":{"gitId":"-"},"content":"public class FeedbackSessionAuditLogDetails extends LogDetails {"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":11,"author":{"gitId":"-"},"content":" private String courseId;"},{"lineNumber":12,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":" private String feedbackSessionId;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":" @Nullable"},{"lineNumber":15,"author":{"gitId":"-"},"content":" private String feedbackSessionName;"},{"lineNumber":16,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":" private String studentId;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" @Nullable"},{"lineNumber":19,"author":{"gitId":"-"},"content":" private String studentEmail;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" private String accessType;"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" public FeedbackSessionAuditLogDetails() {"},{"lineNumber":23,"author":{"gitId":"-"},"content":" super(LogEvent.FEEDBACK_SESSION_AUDIT);"},{"lineNumber":24,"author":{"gitId":"-"},"content":" }"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" public String getCourseId() {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" return courseId;"},{"lineNumber":28,"author":{"gitId":"-"},"content":" }"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" public void setCourseId(String courseId) {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" this.courseId \u003d courseId;"},{"lineNumber":32,"author":{"gitId":"-"},"content":" }"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" public String getFeedbackSessionName() {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" return feedbackSessionName;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" }"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" public void setFeedbackSessionName(String feedbackSessionName) {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.feedbackSessionName \u003d feedbackSessionName;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" public String getStudentEmail() {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" return studentEmail;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" }"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" public void setStudentEmail(String studentEmail) {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" this.studentEmail \u003d studentEmail;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" }"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" public String getAccessType() {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" return accessType;"},{"lineNumber":52,"author":{"gitId":"-"},"content":" }"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" public void setAccessType(String accessType) {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" this.accessType \u003d accessType;"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" public String getFeedbackSessionId() {"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" return feedbackSessionId;"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" public void setFeedbackSessionId(String feedbackSessionId) {"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionId \u003d feedbackSessionId;"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" public String getStudentId() {"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" return studentId;"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" public void setStudentId(String studentId) {"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" this.studentId \u003d studentId;"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public void hideSensitiveInformation() {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" courseId \u003d null;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" feedbackSessionName \u003d null;"},{"lineNumber":78,"author":{"gitId":"-"},"content":" studentEmail \u003d null;"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" studentId \u003d null;"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" feedbackSessionId \u003d null;"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":22,"-":61}},{"path":"src/main/java/teammates/common/datatransfer/questions/FeedbackQuestionDetails.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.datatransfer.questions;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SessionResultsBundle;"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.SqlSessionResultsBundle;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * A class holding the details for a specific question type."},{"lineNumber":14,"author":{"gitId":"-"},"content":" * This abstract class is inherited by concrete Feedback*QuestionDetails"},{"lineNumber":15,"author":{"gitId":"-"},"content":" * classes which provides the implementation for the various abstract methods"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * such that pages can render the correct information/forms depending on the"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * question type"},{"lineNumber":18,"author":{"gitId":"-"},"content":" */"},{"lineNumber":19,"author":{"gitId":"-"},"content":"public abstract class FeedbackQuestionDetails {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" private FeedbackQuestionType questionType;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" private String questionText;"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" protected FeedbackQuestionDetails(FeedbackQuestionType questionType) {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" this.questionType \u003d questionType;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" protected FeedbackQuestionDetails(FeedbackQuestionType questionType, String questionText) {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" this.questionType \u003d questionType;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" this.questionText \u003d questionText;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":33,"author":{"gitId":"-"},"content":" * Get question result statistics as JSON string."},{"lineNumber":34,"author":{"gitId":"-"},"content":" */"},{"lineNumber":35,"author":{"gitId":"-"},"content":" @SuppressWarnings(\"PMD.EmptyMethodInAbstractClassShouldBeAbstract\")"},{"lineNumber":36,"author":{"gitId":"-"},"content":" public String getQuestionResultStatisticsJson("},{"lineNumber":37,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes question, String studentEmail, SessionResultsBundle bundle) {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" // Statistics are calculated in the front-end as it is dependent on the responses being filtered."},{"lineNumber":39,"author":{"gitId":"-"},"content":" // The only exception is contribution question, where there is only one statistics for the entire question."},{"lineNumber":40,"author":{"gitId":"-"},"content":" // It is also necessary to calculate contribution question statistics here"},{"lineNumber":41,"author":{"gitId":"-"},"content":" // to be displayed in student result page as students are not supposed to be able to see the exact responses."},{"lineNumber":42,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":43,"author":{"gitId":"-"},"content":" }"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" * Get question result statistics as JSON string."},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" @SuppressWarnings(\"PMD.EmptyMethodInAbstractClassShouldBeAbstract\")"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" public String getQuestionResultStatisticsJson("},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question, String studentEmail, SqlSessionResultsBundle bundle) {"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" // Statistics are calculated in the front-end as it is dependent on the responses being filtered."},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" // The only exception is contribution question, where there is only one statistics for the entire question."},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" // It is also necessary to calculate contribution question statistics here"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" // to be displayed in student result page as students are not supposed to be able to see the exact responses."},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":" return \"\";"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":59,"author":{"gitId":"-"},"content":" * Checks whether the changes to the question details require deletion of corresponding responses."},{"lineNumber":60,"author":{"gitId":"-"},"content":" */"},{"lineNumber":61,"author":{"gitId":"-"},"content":" public abstract boolean shouldChangesRequireResponseDeletion(FeedbackQuestionDetails newDetails);"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":64,"author":{"gitId":"-"},"content":" * Individual responses are shown by default."},{"lineNumber":65,"author":{"gitId":"-"},"content":" * Override for specific question types if necessary."},{"lineNumber":66,"author":{"gitId":"-"},"content":" *"},{"lineNumber":67,"author":{"gitId":"-"},"content":" * @return boolean indicating if individual responses are to be shown to students."},{"lineNumber":68,"author":{"gitId":"-"},"content":" */"},{"lineNumber":69,"author":{"gitId":"-"},"content":" public boolean isIndividualResponsesShownToStudents() {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":74,"author":{"gitId":"-"},"content":" * Validates the question details."},{"lineNumber":75,"author":{"gitId":"-"},"content":" * @return A {@code List\u003cString\u003e} of error messages (to show as status message to user) if any, or an"},{"lineNumber":76,"author":{"gitId":"-"},"content":" * empty list if question details are valid."},{"lineNumber":77,"author":{"gitId":"-"},"content":" */"},{"lineNumber":78,"author":{"gitId":"-"},"content":" public abstract List\u003cString\u003e validateQuestionDetails();"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":81,"author":{"gitId":"-"},"content":" * Validates the list of response details."},{"lineNumber":82,"author":{"gitId":"-"},"content":" * @return A {@code List\u003cString\u003e} of error messages (to show as status message to user) if any, or an"},{"lineNumber":83,"author":{"gitId":"-"},"content":" * empty list if all response details are valid."},{"lineNumber":84,"author":{"gitId":"-"},"content":" */"},{"lineNumber":85,"author":{"gitId":"-"},"content":" public abstract List\u003cString\u003e validateResponsesDetails(List\u003cFeedbackResponseDetails\u003e responseDetails, int numRecipients);"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":88,"author":{"gitId":"-"},"content":" * Validates if giverType and recipientType are valid for the question type."},{"lineNumber":89,"author":{"gitId":"-"},"content":" * Validates visibility options as well."},{"lineNumber":90,"author":{"gitId":"-"},"content":" *"},{"lineNumber":91,"author":{"gitId":"-"},"content":" * \u003cp\u003eOverride in Feedback*QuestionDetails if necessary."},{"lineNumber":92,"author":{"gitId":"-"},"content":" * @return error message detailing the error, or an empty string if valid."},{"lineNumber":93,"author":{"gitId":"-"},"content":" */"},{"lineNumber":94,"author":{"gitId":"-"},"content":" public abstract String validateGiverRecipientVisibility(FeedbackQuestionAttributes feedbackQuestionAttributes);"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":97,"author":{"gitId":"-"},"content":" * Validates if giverType and recipientType are valid for the question type."},{"lineNumber":98,"author":{"gitId":"-"},"content":" * Validates visibility options as well."},{"lineNumber":99,"author":{"gitId":"-"},"content":" *"},{"lineNumber":100,"author":{"gitId":"-"},"content":" * \u003cp\u003eOverride in Feedback*QuestionDetails if necessary."},{"lineNumber":101,"author":{"gitId":"-"},"content":" * @return error message detailing the error, or an empty string if valid."},{"lineNumber":102,"author":{"gitId":"-"},"content":" */"},{"lineNumber":103,"author":{"gitId":"-"},"content":" public abstract String validateGiverRecipientVisibility(FeedbackQuestion feedbackQuestion);"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":106,"author":{"gitId":"-"},"content":" * Checks whether instructor comments are allowed for the question."},{"lineNumber":107,"author":{"gitId":"-"},"content":" */"},{"lineNumber":108,"author":{"gitId":"-"},"content":" public boolean isInstructorCommentsOnResponsesAllowed() {"},{"lineNumber":109,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":113,"author":{"gitId":"-"},"content":" * Checks whether missing responses should be generated."},{"lineNumber":114,"author":{"gitId":"-"},"content":" */"},{"lineNumber":115,"author":{"gitId":"-"},"content":" public boolean shouldGenerateMissingResponses(FeedbackQuestionAttributes question) {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" // generate combinations against all students/teams are meaningless"},{"lineNumber":117,"author":{"gitId":"-"},"content":" return question.getRecipientType() !\u003d FeedbackParticipantType.STUDENTS"},{"lineNumber":118,"author":{"gitId":"-"},"content":" \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.STUDENTS_EXCLUDING_SELF"},{"lineNumber":119,"author":{"gitId":"-"},"content":" \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":120,"author":{"gitId":"-"},"content":" \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.TEAMS_EXCLUDING_SELF;"},{"lineNumber":121,"author":{"gitId":"-"},"content":" }"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":124,"author":{"gitId":"xenosf"},"content":" * Checks whether missing responses should be generated."},{"lineNumber":125,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":126,"author":{"gitId":"xenosf"},"content":" public boolean shouldGenerateMissingResponses(FeedbackQuestion question) {"},{"lineNumber":127,"author":{"gitId":"xenosf"},"content":" // generate combinations against all students/teams are meaningless"},{"lineNumber":128,"author":{"gitId":"xenosf"},"content":" return question.getRecipientType() !\u003d FeedbackParticipantType.STUDENTS"},{"lineNumber":129,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.STUDENTS_EXCLUDING_SELF"},{"lineNumber":130,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":131,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.TEAMS_EXCLUDING_SELF;"},{"lineNumber":132,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":133,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":135,"author":{"gitId":"-"},"content":" public boolean equals(Object obj) {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" if (this \u003d\u003d obj) {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" if (obj \u003d\u003d null || obj.getClass() !\u003d this.getClass()) {"},{"lineNumber":141,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":142,"author":{"gitId":"-"},"content":" }"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" // Json string contains all attributes of a `FeedbackQuestionDetails` object,"},{"lineNumber":145,"author":{"gitId":"-"},"content":" // so it is sufficient to use it to compare two `FeedbackQuestionDetails` objects."},{"lineNumber":146,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails other \u003d (FeedbackQuestionDetails) obj;"},{"lineNumber":147,"author":{"gitId":"-"},"content":" return this.getJsonString().equals(other.getJsonString());"},{"lineNumber":148,"author":{"gitId":"-"},"content":" }"},{"lineNumber":149,"author":{"gitId":"-"},"content":""},{"lineNumber":150,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":151,"author":{"gitId":"-"},"content":" public int hashCode() {"},{"lineNumber":152,"author":{"gitId":"-"},"content":" return this.getJsonString().hashCode();"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":156,"author":{"gitId":"-"},"content":" * Returns a JSON string representation of the question details."},{"lineNumber":157,"author":{"gitId":"-"},"content":" */"},{"lineNumber":158,"author":{"gitId":"-"},"content":" public String getJsonString() {"},{"lineNumber":159,"author":{"gitId":"-"},"content":" assert questionType !\u003d null;"},{"lineNumber":160,"author":{"gitId":"-"},"content":" return JsonUtils.toJson(this, questionType.getQuestionDetailsClass());"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":164,"author":{"gitId":"-"},"content":" * Returns a deep copy of the question details."},{"lineNumber":165,"author":{"gitId":"-"},"content":" */"},{"lineNumber":166,"author":{"gitId":"-"},"content":" public FeedbackQuestionDetails getDeepCopy() {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" assert questionType !\u003d null;"},{"lineNumber":168,"author":{"gitId":"-"},"content":" String serializedDetails \u003d getJsonString();"},{"lineNumber":169,"author":{"gitId":"-"},"content":" return JsonUtils.fromJson(serializedDetails, questionType.getQuestionDetailsClass());"},{"lineNumber":170,"author":{"gitId":"-"},"content":" }"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" public FeedbackQuestionType getQuestionType() {"},{"lineNumber":173,"author":{"gitId":"-"},"content":" return questionType;"},{"lineNumber":174,"author":{"gitId":"-"},"content":" }"},{"lineNumber":175,"author":{"gitId":"-"},"content":""},{"lineNumber":176,"author":{"gitId":"-"},"content":" public void setQuestionType(FeedbackQuestionType questionType) {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" this.questionType \u003d questionType;"},{"lineNumber":178,"author":{"gitId":"-"},"content":" }"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" public String getQuestionText() {"},{"lineNumber":181,"author":{"gitId":"-"},"content":" return questionText;"},{"lineNumber":182,"author":{"gitId":"-"},"content":" }"},{"lineNumber":183,"author":{"gitId":"-"},"content":""},{"lineNumber":184,"author":{"gitId":"-"},"content":" public void setQuestionText(String questionText) {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" this.questionText \u003d questionText;"},{"lineNumber":186,"author":{"gitId":"-"},"content":" }"},{"lineNumber":187,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":25,"-":162}},{"path":"src/main/java/teammates/common/util/Const.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.util;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.nio.charset.Charset;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.nio.charset.StandardCharsets;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.Duration;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * Stores constants that are widely used across classes."},{"lineNumber":12,"author":{"gitId":"-"},"content":" * this class contains several nested classes, each containing a specific"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * category of constants."},{"lineNumber":14,"author":{"gitId":"-"},"content":" */"},{"lineNumber":15,"author":{"gitId":"-"},"content":"public final class Const {"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":" // This section holds constants that are defined as constants primarily because they are repeated in many places."},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":" public static final String USER_NOBODY_TEXT \u003d \"-\";"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" public static final String USER_TEAM_FOR_INSTRUCTOR \u003d \"Instructors\";"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" public static final String DEFAULT_DISPLAY_NAME_FOR_INSTRUCTOR \u003d \"Instructor\";"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" public static final String DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT \u003d \"Anonymous\";"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" public static final int SECTION_SIZE_LIMIT \u003d 100;"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" public static final String DEFAULT_SECTION \u003d \"None\";"},{"lineNumber":30,"author":{"gitId":"-"},"content":" public static final Section DEFAULT_SQL_SECTION \u003d null;"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" public static final String UNKNOWN_INSTITUTION \u003d \"Unknown Institution\";"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" public static final String DEFAULT_TIME_ZONE \u003d \"UTC\";"},{"lineNumber":35,"author":{"gitId":"-"},"content":" public static final Charset ENCODING \u003d StandardCharsets.UTF_8;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" public static final Duration FEEDBACK_SESSIONS_SEARCH_WINDOW \u003d Duration.ofDays(30);"},{"lineNumber":38,"author":{"gitId":"-"},"content":" public static final Duration LOGS_RETENTION_PERIOD \u003d Duration.ofDays(30);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" public static final Duration COOKIE_VALIDITY_PERIOD \u003d Duration.ofDays(7);"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" public static final int SEARCH_QUERY_SIZE_LIMIT \u003d 50;"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" public static final String ERROR_CREATE_ENTITY_ALREADY_EXISTS \u003d \"Trying to create an entity that exists: %s\";"},{"lineNumber":44,"author":{"gitId":"-"},"content":" public static final String ERROR_UPDATE_NON_EXISTENT \u003d \"Trying to update non-existent Entity: \";"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" public static final String MISSING_RESPONSE_TEXT \u003d \"No Response\";"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" public static final Duration STUDENT_ACTIVITY_LOGS_UPDATE_INTERVAL \u003d Duration.ofMinutes(15);"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" public static final Duration STUDENT_ACTIVITY_LOGS_FILTER_WINDOW \u003d Duration.ofSeconds(2);"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" public static final String ACCOUNT_REQUEST_NOT_FOUND \u003d \"Account request with id \u003d %s not found\";"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" // These constants are used as variable values to mean that the variable is in a \u0027special\u0027 state."},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" public static final int INT_UNINITIALIZED \u003d -9999;"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" public static final int MAX_POSSIBLE_RECIPIENTS \u003d -100;"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" public static final int POINTS_EQUAL_SHARE \u003d 100;"},{"lineNumber":60,"author":{"gitId":"-"},"content":" public static final int POINTS_NOT_SURE \u003d -101;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" public static final int POINTS_NOT_SUBMITTED \u003d -999;"},{"lineNumber":62,"author":{"gitId":"-"},"content":" public static final int POINTS_NO_VALUE \u003d Integer.MIN_VALUE;"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" public static final String GENERAL_QUESTION \u003d \"%GENERAL%\";"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" public static final Instant TIME_REPRESENTS_FOLLOW_OPENING;"},{"lineNumber":67,"author":{"gitId":"-"},"content":" public static final Instant TIME_REPRESENTS_FOLLOW_VISIBLE;"},{"lineNumber":68,"author":{"gitId":"-"},"content":" public static final Instant TIME_REPRESENTS_LATER;"},{"lineNumber":69,"author":{"gitId":"-"},"content":" public static final Instant TIME_REPRESENTS_NOW;"},{"lineNumber":70,"author":{"gitId":"-"},"content":" public static final Instant TIME_REPRESENTS_DEFAULT_TIMESTAMP;"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" static {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" TIME_REPRESENTS_FOLLOW_OPENING \u003d TimeHelper.parseInstant(\"1970-12-31T00:00:00Z\");"},{"lineNumber":74,"author":{"gitId":"-"},"content":" TIME_REPRESENTS_FOLLOW_VISIBLE \u003d TimeHelper.parseInstant(\"1970-06-22T00:00:00Z\");"},{"lineNumber":75,"author":{"gitId":"-"},"content":" TIME_REPRESENTS_LATER \u003d TimeHelper.parseInstant(\"1970-01-01T00:00:00Z\");"},{"lineNumber":76,"author":{"gitId":"-"},"content":" TIME_REPRESENTS_NOW \u003d TimeHelper.parseInstant(\"1970-02-14T00:00:00Z\");"},{"lineNumber":77,"author":{"gitId":"-"},"content":" TIME_REPRESENTS_DEFAULT_TIMESTAMP \u003d TimeHelper.parseInstant(\"2011-01-01T00:00:00Z\");"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" public static final String TEST_EMAIL_DOMAIN \u003d \"@gmail.tmt\";"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" // Other Constants"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" private Const() {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" // Utility class containing constants"},{"lineNumber":86,"author":{"gitId":"-"},"content":" }"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":89,"author":{"gitId":"-"},"content":" * Represents role names for instructors based on their permission settings."},{"lineNumber":90,"author":{"gitId":"-"},"content":" */"},{"lineNumber":91,"author":{"gitId":"-"},"content":" public static class InstructorPermissionRoleNames {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_PERMISSION_ROLE_COOWNER \u003d \"Co-owner\";"},{"lineNumber":93,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_PERMISSION_ROLE_MANAGER \u003d \"Manager\";"},{"lineNumber":94,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_PERMISSION_ROLE_OBSERVER \u003d \"Observer\";"},{"lineNumber":95,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_PERMISSION_ROLE_TUTOR \u003d \"Tutor\";"},{"lineNumber":96,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_PERMISSION_ROLE_CUSTOM \u003d \"Custom\";"},{"lineNumber":97,"author":{"gitId":"-"},"content":" }"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":100,"author":{"gitId":"-"},"content":" * Represents atomic permission for instructors."},{"lineNumber":101,"author":{"gitId":"-"},"content":" */"},{"lineNumber":102,"author":{"gitId":"-"},"content":" public static class InstructorPermissions {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" public static final String CAN_MODIFY_COURSE \u003d \"canmodifycourse\";"},{"lineNumber":104,"author":{"gitId":"-"},"content":" public static final String CAN_MODIFY_INSTRUCTOR \u003d \"canmodifyinstructor\";"},{"lineNumber":105,"author":{"gitId":"-"},"content":" public static final String CAN_MODIFY_SESSION \u003d \"canmodifysession\";"},{"lineNumber":106,"author":{"gitId":"-"},"content":" public static final String CAN_MODIFY_STUDENT \u003d \"canmodifystudent\";"},{"lineNumber":107,"author":{"gitId":"-"},"content":" public static final String CAN_VIEW_STUDENT_IN_SECTIONS \u003d \"canviewstudentinsection\";"},{"lineNumber":108,"author":{"gitId":"-"},"content":" public static final String CAN_VIEW_SESSION_IN_SECTIONS \u003d \"canviewsessioninsection\";"},{"lineNumber":109,"author":{"gitId":"-"},"content":" public static final String CAN_SUBMIT_SESSION_IN_SECTIONS \u003d \"cansubmitsessioninsection\";"},{"lineNumber":110,"author":{"gitId":"-"},"content":" public static final String CAN_MODIFY_SESSION_COMMENT_IN_SECTIONS \u003d \"canmodifysessioncommentinsection\";"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":114,"author":{"gitId":"-"},"content":" * Represents keys for HTTP requests to the API layer."},{"lineNumber":115,"author":{"gitId":"-"},"content":" */"},{"lineNumber":116,"author":{"gitId":"-"},"content":" public static class ParamsNames {"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" public static final String IS_IN_RECYCLE_BIN \u003d \"isinrecyclebin\";"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" public static final String IS_STUDENT_REJOINING \u003d \"isstudentrejoining\";"},{"lineNumber":121,"author":{"gitId":"-"},"content":" public static final String IS_INSTRUCTOR_REJOINING \u003d \"isinstructorrejoining\";"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" public static final String COURSE_ID \u003d \"courseid\";"},{"lineNumber":124,"author":{"gitId":"-"},"content":" public static final String COURSE_STATUS \u003d \"coursestatus\";"},{"lineNumber":125,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_ID \u003d \"instructorid\";"},{"lineNumber":126,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_EMAIL \u003d \"instructoremail\";"},{"lineNumber":127,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_INSTITUTION \u003d \"instructorinstitution\";"},{"lineNumber":128,"author":{"gitId":"-"},"content":" public static final String IS_CREATING_ACCOUNT \u003d \"iscreatingaccount\";"},{"lineNumber":129,"author":{"gitId":"-"},"content":" public static final String IS_INSTRUCTOR \u003d \"isinstructor\";"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" public static final String FEEDBACK_SESSION_ID \u003d \"fsid\";"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" public static final String ACCOUNT_REQUEST_ID \u003d \"id\";"},{"lineNumber":134,"author":{"gitId":"-"},"content":" public static final String ACCOUNT_REQUEST_STATUS \u003d \"status\";"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_NAME \u003d \"fsname\";"},{"lineNumber":137,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_STARTTIME \u003d \"starttime\";"},{"lineNumber":138,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_ENDTIME \u003d \"endtime\";"},{"lineNumber":139,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_MODERATED_PERSON \u003d \"moderatedperson\";"},{"lineNumber":140,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_LOG_TYPE \u003d \"fsltype\";"},{"lineNumber":141,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_LOG_STARTTIME \u003d \"fslstarttime\";"},{"lineNumber":142,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_LOG_ENDTIME \u003d \"fslendtime\";"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_QUESTION_ID \u003d \"questionid\";"},{"lineNumber":145,"author":{"gitId":"-"},"content":" public static final String SINGLE_RECIPIENT_ID_FOR_SUBMISSION \u003d \"singlerecipientidforsubmission\";"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_RESPONSE_ID \u003d \"responseid\";"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_RESPONSE_COMMENT_ID \u003d \"responsecommentid\";"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_RESULTS_GROUPBYSECTION \u003d \"frgroupbysection\";"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_RESULTS_SECTION_BY_GIVER_RECEIVER \u003d \"frsessionbygiverreceiver\";"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" public static final String PREVIEWAS \u003d \"previewas\";"},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":" public static final String STUDENT_SQL_ID \u003d \"studentid\";"},{"lineNumber":158,"author":{"gitId":"-"},"content":" public static final String STUDENT_ID \u003d \"googleid\";"},{"lineNumber":159,"author":{"gitId":"-"},"content":" public static final String INVITER_ID \u003d \"invitergoogleid\";"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" public static final String REGKEY \u003d \"key\";"},{"lineNumber":162,"author":{"gitId":"-"},"content":" public static final String STUDENT_EMAIL \u003d \"studentemail\";"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" public static final String SECTION_NAME \u003d \"sectionname\";"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" public static final String TEAM_NAME \u003d \"teamname\";"},{"lineNumber":167,"author":{"gitId":"-"},"content":""},{"lineNumber":168,"author":{"gitId":"-"},"content":" public static final String ERROR \u003d \"error\";"},{"lineNumber":169,"author":{"gitId":"-"},"content":" public static final String USER_ID \u003d \"user\";"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" public static final String SEARCH_KEY \u003d \"searchkey\";"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" public static final String USER_CAPTCHA_RESPONSE \u003d \"captcharesponse\";"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" public static final String EMAIL_TYPE \u003d \"emailtype\";"},{"lineNumber":176,"author":{"gitId":"-"},"content":" public static final String USER_EMAIL \u003d \"useremail\";"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" public static final String ENTITY_TYPE \u003d \"entitytype\";"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" public static final String INTENT \u003d \"intent\";"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" public static final String TIMEZONE \u003d \"timezone\";"},{"lineNumber":183,"author":{"gitId":"-"},"content":""},{"lineNumber":184,"author":{"gitId":"-"},"content":" public static final String NOTIFY_ABOUT_DEADLINES \u003d \"notifydeadlines\";"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_STARTTIME \u003d \"starttime\";"},{"lineNumber":187,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_ENDTIME \u003d \"endtime\";"},{"lineNumber":188,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_SEVERITY \u003d \"severity\";"},{"lineNumber":189,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_MIN_SEVERITY \u003d \"minseverity\";"},{"lineNumber":190,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_TRACE \u003d \"traceid\";"},{"lineNumber":191,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_ACTION_CLASS \u003d \"actionclass\";"},{"lineNumber":192,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_EMAIL \u003d \"email\";"},{"lineNumber":193,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_EVENT \u003d \"logevent\";"},{"lineNumber":194,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_SOURCE_LOCATION_FILE \u003d \"sourcelocationfile\";"},{"lineNumber":195,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_SOURCE_LOCATION_FUNCTION \u003d \"sourcelocationfunction\";"},{"lineNumber":196,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_EXCEPTION_CLASS \u003d \"exceptionclass\";"},{"lineNumber":197,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_LATENCY \u003d \"latency\";"},{"lineNumber":198,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_STATUS \u003d \"status\";"},{"lineNumber":199,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_VERSION \u003d \"version\";"},{"lineNumber":200,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_EXTRA_FILTERS \u003d \"extrafilters\";"},{"lineNumber":201,"author":{"gitId":"-"},"content":" public static final String QUERY_LOGS_ORDER \u003d \"order\";"},{"lineNumber":202,"author":{"gitId":"-"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":" public static final String LIMIT \u003d \"limit\";"},{"lineNumber":204,"author":{"gitId":"-"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_ID \u003d \"notificationid\";"},{"lineNumber":206,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_TARGET_USER \u003d \"usertype\";"},{"lineNumber":207,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_IS_FETCHING_ALL \u003d \"isfetchingall\";"},{"lineNumber":208,"author":{"gitId":"-"},"content":" public static final String NOTFICATION_END_TIME \u003d \"endtime\";"},{"lineNumber":209,"author":{"gitId":"-"},"content":" public static final String CONTINUE_URL \u003d \"continueurl\";"},{"lineNumber":210,"author":{"gitId":"-"},"content":" }"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":213,"author":{"gitId":"-"},"content":" * Represents custom header names used by the system."},{"lineNumber":214,"author":{"gitId":"-"},"content":" */"},{"lineNumber":215,"author":{"gitId":"-"},"content":" public static class HeaderNames {"},{"lineNumber":216,"author":{"gitId":"-"},"content":" public static final String BACKDOOR_KEY \u003d \"Backdoor-Key\";"},{"lineNumber":217,"author":{"gitId":"-"},"content":" public static final String CSRF_KEY \u003d \"CSRF-Key\";"},{"lineNumber":218,"author":{"gitId":"-"},"content":" public static final String WEB_VERSION \u003d \"X-WEB-VERSION\";"},{"lineNumber":219,"author":{"gitId":"-"},"content":" public static final String CSRF_TOKEN \u003d \"X-CSRF-TOKEN\";"},{"lineNumber":220,"author":{"gitId":"-"},"content":" }"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":223,"author":{"gitId":"-"},"content":" * The course status respect to the instructor\u0027s point of view."},{"lineNumber":224,"author":{"gitId":"-"},"content":" * This parameter is used to get a course list for instructor."},{"lineNumber":225,"author":{"gitId":"-"},"content":" */"},{"lineNumber":226,"author":{"gitId":"-"},"content":" public static class CourseStatus {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" public static final String ACTIVE \u003d \"active\";"},{"lineNumber":228,"author":{"gitId":"-"},"content":" public static final String ARCHIVED \u003d \"archived\";"},{"lineNumber":229,"author":{"gitId":"-"},"content":" public static final String SOFT_DELETED \u003d \"softDeleted\";"},{"lineNumber":230,"author":{"gitId":"-"},"content":" }"},{"lineNumber":231,"author":{"gitId":"-"},"content":""},{"lineNumber":232,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":233,"author":{"gitId":"-"},"content":" * Represents user types."},{"lineNumber":234,"author":{"gitId":"-"},"content":" */"},{"lineNumber":235,"author":{"gitId":"-"},"content":" public static class EntityType {"},{"lineNumber":236,"author":{"gitId":"-"},"content":""},{"lineNumber":237,"author":{"gitId":"-"},"content":" public static final String STUDENT \u003d \"student\";"},{"lineNumber":238,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR \u003d \"instructor\";"},{"lineNumber":239,"author":{"gitId":"-"},"content":" public static final String ADMIN \u003d \"admin\";"},{"lineNumber":240,"author":{"gitId":"-"},"content":" public static final String MAINTAINER \u003d \"maintainer\";"},{"lineNumber":241,"author":{"gitId":"-"},"content":""},{"lineNumber":242,"author":{"gitId":"-"},"content":" }"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":245,"author":{"gitId":"-"},"content":" * Represents security-related configuration."},{"lineNumber":246,"author":{"gitId":"-"},"content":" */"},{"lineNumber":247,"author":{"gitId":"-"},"content":" public static class SecurityConfig {"},{"lineNumber":248,"author":{"gitId":"-"},"content":""},{"lineNumber":249,"author":{"gitId":"-"},"content":" public static final String CSRF_COOKIE_NAME \u003d \"CSRF-TOKEN\";"},{"lineNumber":250,"author":{"gitId":"-"},"content":" public static final String AUTH_COOKIE_NAME \u003d \"AUTH-TOKEN\";"},{"lineNumber":251,"author":{"gitId":"-"},"content":""},{"lineNumber":252,"author":{"gitId":"-"},"content":" }"},{"lineNumber":253,"author":{"gitId":"-"},"content":""},{"lineNumber":254,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":255,"author":{"gitId":"-"},"content":" * Represents URIs of accessible pages in the front-end in past versions (V6 and before)."},{"lineNumber":256,"author":{"gitId":"-"},"content":" */"},{"lineNumber":257,"author":{"gitId":"-"},"content":" @Deprecated"},{"lineNumber":258,"author":{"gitId":"-"},"content":" public static class LegacyURIs {"},{"lineNumber":259,"author":{"gitId":"-"},"content":""},{"lineNumber":260,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_COURSE_JOIN \u003d \"/page/instructorCourseJoin\";"},{"lineNumber":261,"author":{"gitId":"-"},"content":" public static final String STUDENT_COURSE_JOIN \u003d \"/page/studentCourseJoin\";"},{"lineNumber":262,"author":{"gitId":"-"},"content":" public static final String STUDENT_COURSE_JOIN_NEW \u003d \"/page/studentCourseJoinAuthentication\";"},{"lineNumber":263,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_HOME_PAGE \u003d \"/page/instructorHomePage\";"},{"lineNumber":264,"author":{"gitId":"-"},"content":" public static final String STUDENT_HOME_PAGE \u003d \"/page/studentHomePage\";"},{"lineNumber":265,"author":{"gitId":"-"},"content":" public static final String STUDENT_FEEDBACK_SUBMISSION_EDIT_PAGE \u003d \"/page/studentFeedbackSubmissionEditPage\";"},{"lineNumber":266,"author":{"gitId":"-"},"content":" public static final String STUDENT_FEEDBACK_RESULTS_PAGE \u003d \"/page/studentFeedbackResultsPage\";"},{"lineNumber":267,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_FEEDBACK_SUBMISSION_EDIT_PAGE \u003d \"/page/instructorFeedbackSubmissionEditPage\";"},{"lineNumber":268,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_FEEDBACK_RESULTS_PAGE \u003d \"/page/instructorFeedbackResultsPage\";"},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":273,"author":{"gitId":"-"},"content":" * Represents URIs of accessible pages in the front-end."},{"lineNumber":274,"author":{"gitId":"-"},"content":" */"},{"lineNumber":275,"author":{"gitId":"-"},"content":" public static class WebPageURIs {"},{"lineNumber":276,"author":{"gitId":"-"},"content":" public static final String LOGIN \u003d \"/login\";"},{"lineNumber":277,"author":{"gitId":"-"},"content":" public static final String LOGOUT \u003d \"/logout\";"},{"lineNumber":278,"author":{"gitId":"-"},"content":" private static final String URI_PREFIX \u003d \"/web\";"},{"lineNumber":279,"author":{"gitId":"-"},"content":""},{"lineNumber":280,"author":{"gitId":"-"},"content":" private static final String STUDENT_PAGE \u003d URI_PREFIX + \"/\" + EntityType.STUDENT;"},{"lineNumber":281,"author":{"gitId":"-"},"content":" private static final String INSTRUCTOR_PAGE \u003d URI_PREFIX + \"/\" + EntityType.INSTRUCTOR;"},{"lineNumber":282,"author":{"gitId":"-"},"content":" private static final String ADMIN_PAGE \u003d URI_PREFIX + \"/\" + EntityType.ADMIN;"},{"lineNumber":283,"author":{"gitId":"-"},"content":" private static final String MAINTAINER_PAGE \u003d URI_PREFIX + \"/\" + EntityType.MAINTAINER;"},{"lineNumber":284,"author":{"gitId":"-"},"content":" private static final String FRONT_PAGE \u003d URI_PREFIX + \"/front\";"},{"lineNumber":285,"author":{"gitId":"-"},"content":" public static final String JOIN_PAGE \u003d URI_PREFIX + \"/join\";"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"-"},"content":" public static final String ADMIN_HOME_PAGE \u003d ADMIN_PAGE + \"/home\";"},{"lineNumber":288,"author":{"gitId":"-"},"content":" public static final String ADMIN_ACCOUNTS_PAGE \u003d ADMIN_PAGE + \"/accounts\";"},{"lineNumber":289,"author":{"gitId":"-"},"content":" public static final String ADMIN_SEARCH_PAGE \u003d ADMIN_PAGE + \"/search\";"},{"lineNumber":290,"author":{"gitId":"-"},"content":" public static final String ADMIN_SESSIONS_PAGE \u003d ADMIN_PAGE + \"/sessions\";"},{"lineNumber":291,"author":{"gitId":"-"},"content":" public static final String ADMIN_TIMEZONE_PAGE \u003d ADMIN_PAGE + \"/timezone\";"},{"lineNumber":292,"author":{"gitId":"-"},"content":" public static final String ADMIN_LOGS_PAGE \u003d ADMIN_PAGE + \"/logs\";"},{"lineNumber":293,"author":{"gitId":"-"},"content":" public static final String ADMIN_NOTIFICATIONS_PAGE \u003d ADMIN_PAGE + \"/notifications\";"},{"lineNumber":294,"author":{"gitId":"-"},"content":""},{"lineNumber":295,"author":{"gitId":"-"},"content":" public static final String MAINTAINER_HOME_PAGE \u003d MAINTAINER_PAGE + \"/home\";"},{"lineNumber":296,"author":{"gitId":"-"},"content":""},{"lineNumber":297,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_HOME_PAGE \u003d INSTRUCTOR_PAGE + \"/home\";"},{"lineNumber":298,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_SEARCH_PAGE \u003d INSTRUCTOR_PAGE + \"/search\";"},{"lineNumber":299,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_SESSIONS_PAGE \u003d INSTRUCTOR_PAGE + \"/sessions\";"},{"lineNumber":300,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_SESSION_SUBMISSION_PAGE \u003d INSTRUCTOR_PAGE + \"/sessions/submission\";"},{"lineNumber":301,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_SESSION_EDIT_PAGE \u003d INSTRUCTOR_PAGE + \"/sessions/edit\";"},{"lineNumber":302,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_SESSION_INDIVIDUAL_EXTENSION_PAGE \u003d INSTRUCTOR_PAGE"},{"lineNumber":303,"author":{"gitId":"-"},"content":" + \"/sessions/individual-extension\";"},{"lineNumber":304,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_SESSION_RESULTS_PAGE \u003d INSTRUCTOR_PAGE + \"/sessions/result\";"},{"lineNumber":305,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_SESSION_REPORT_PAGE \u003d INSTRUCTOR_PAGE + \"/sessions/report\";"},{"lineNumber":306,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_COURSES_PAGE \u003d INSTRUCTOR_PAGE + \"/courses\";"},{"lineNumber":307,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_COURSE_DETAILS_PAGE \u003d INSTRUCTOR_PAGE + \"/courses/details\";"},{"lineNumber":308,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_COURSE_EDIT_PAGE \u003d INSTRUCTOR_PAGE + \"/courses/edit\";"},{"lineNumber":309,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_COURSE_ENROLL_PAGE \u003d INSTRUCTOR_PAGE + \"/courses/enroll\";"},{"lineNumber":310,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_COURSE_STUDENT_DETAILS_PAGE \u003d INSTRUCTOR_PAGE + \"/courses/student/details\";"},{"lineNumber":311,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_COURSE_STUDENT_DETAILS_EDIT_PAGE \u003d INSTRUCTOR_PAGE + \"/courses/student/edit\";"},{"lineNumber":312,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_STUDENT_LIST_PAGE \u003d INSTRUCTOR_PAGE + \"/students\";"},{"lineNumber":313,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_STUDENT_RECORDS_PAGE \u003d INSTRUCTOR_PAGE + \"/students/records\";"},{"lineNumber":314,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_STUDENT_ACTIVITY_LOGS_PAGE \u003d INSTRUCTOR_PAGE"},{"lineNumber":315,"author":{"gitId":"-"},"content":" + \"/courses/student-activity-logs\";"},{"lineNumber":316,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_NOTIFICATIONS_PAGE \u003d INSTRUCTOR_PAGE + \"/notifications\";"},{"lineNumber":317,"author":{"gitId":"-"},"content":""},{"lineNumber":318,"author":{"gitId":"-"},"content":" public static final String STUDENT_HOME_PAGE \u003d STUDENT_PAGE + \"/home\";"},{"lineNumber":319,"author":{"gitId":"-"},"content":" public static final String STUDENT_COURSE_DETAILS_PAGE \u003d STUDENT_PAGE + \"/course\";"},{"lineNumber":320,"author":{"gitId":"-"},"content":" public static final String STUDENT_SESSION_SUBMISSION_PAGE \u003d STUDENT_PAGE + \"/sessions/submission\";"},{"lineNumber":321,"author":{"gitId":"-"},"content":" public static final String STUDENT_SESSION_RESULTS_PAGE \u003d STUDENT_PAGE + \"/sessions/result\";"},{"lineNumber":322,"author":{"gitId":"-"},"content":" public static final String STUDENT_NOTIFICATIONS_PAGE \u003d STUDENT_PAGE + \"/notifications\";"},{"lineNumber":323,"author":{"gitId":"-"},"content":""},{"lineNumber":324,"author":{"gitId":"-"},"content":" public static final String SESSION_RESULTS_PAGE \u003d URI_PREFIX + \"/sessions/result\";"},{"lineNumber":325,"author":{"gitId":"-"},"content":" public static final String SESSION_SUBMISSION_PAGE \u003d URI_PREFIX + \"/sessions/submission\";"},{"lineNumber":326,"author":{"gitId":"-"},"content":" public static final String SESSIONS_LINK_RECOVERY_PAGE \u003d FRONT_PAGE + \"/help/session-links-recovery\";"},{"lineNumber":327,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":328,"author":{"gitId":"dishenggg"},"content":" public static final String ACCOUNT_REQUEST_PAGE \u003d FRONT_PAGE + \"/request\";"},{"lineNumber":329,"author":{"gitId":"-"},"content":" }"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":332,"author":{"gitId":"-"},"content":" * Represents URIs of resource endpoints."},{"lineNumber":333,"author":{"gitId":"-"},"content":" */"},{"lineNumber":334,"author":{"gitId":"-"},"content":" public static class ResourceURIs {"},{"lineNumber":335,"author":{"gitId":"-"},"content":" private static final String URI_PREFIX \u003d \"/webapi\";"},{"lineNumber":336,"author":{"gitId":"-"},"content":""},{"lineNumber":337,"author":{"gitId":"-"},"content":" public static final String DATABUNDLE \u003d URI_PREFIX + \"/databundle\";"},{"lineNumber":338,"author":{"gitId":"-"},"content":" public static final String SQL_DATABUNDLE \u003d URI_PREFIX + \"/databundle/sql\";"},{"lineNumber":339,"author":{"gitId":"-"},"content":" public static final String DATABUNDLE_DOCUMENTS \u003d URI_PREFIX + \"/databundle/documents\";"},{"lineNumber":340,"author":{"gitId":"-"},"content":" public static final String DEADLINE_EXTENSION \u003d URI_PREFIX + \"/deadlineextension\";"},{"lineNumber":341,"author":{"gitId":"-"},"content":" public static final String EXCEPTION \u003d URI_PREFIX + \"/exception\";"},{"lineNumber":342,"author":{"gitId":"-"},"content":" public static final String ERROR_REPORT \u003d URI_PREFIX + \"/errorreport\";"},{"lineNumber":343,"author":{"gitId":"-"},"content":" public static final String AUTH \u003d URI_PREFIX + \"/auth\";"},{"lineNumber":344,"author":{"gitId":"-"},"content":" public static final String AUTH_REGKEY \u003d URI_PREFIX + \"/auth/regkey\";"},{"lineNumber":345,"author":{"gitId":"-"},"content":" public static final String ACCOUNT \u003d URI_PREFIX + \"/account\";"},{"lineNumber":346,"author":{"gitId":"-"},"content":" public static final String ACCOUNT_RESET \u003d URI_PREFIX + \"/account/reset\";"},{"lineNumber":347,"author":{"gitId":"-"},"content":" public static final String ACCOUNT_REQUEST \u003d URI_PREFIX + \"/account/request\";"},{"lineNumber":348,"author":{"gitId":"-"},"content":" public static final String ACCOUNT_REQUESTS \u003d URI_PREFIX + \"/account/requests\";"},{"lineNumber":349,"author":{"gitId":"-"},"content":" public static final String ACCOUNT_REQUEST_RESET \u003d ACCOUNT_REQUEST + \"/reset\";"},{"lineNumber":350,"author":{"gitId":"xenosf"},"content":" public static final String ACCOUNT_REQUEST_REJECTION \u003d ACCOUNT_REQUEST + \"/rejection\";"},{"lineNumber":351,"author":{"gitId":"-"},"content":" public static final String ACCOUNTS \u003d URI_PREFIX + \"/accounts\";"},{"lineNumber":352,"author":{"gitId":"-"},"content":" public static final String RESPONSE_COMMENT \u003d URI_PREFIX + \"/responsecomment\";"},{"lineNumber":353,"author":{"gitId":"-"},"content":" public static final String COURSE \u003d URI_PREFIX + \"/course\";"},{"lineNumber":354,"author":{"gitId":"-"},"content":" public static final String COURSE_ARCHIVE \u003d URI_PREFIX + \"/course/archive\";"},{"lineNumber":355,"author":{"gitId":"-"},"content":" public static final String BIN_COURSE \u003d URI_PREFIX + \"/bin/course\";"},{"lineNumber":356,"author":{"gitId":"-"},"content":" public static final String COURSE_SECTIONS \u003d URI_PREFIX + \"/course/sections\";"},{"lineNumber":357,"author":{"gitId":"-"},"content":" public static final String COURSES \u003d URI_PREFIX + \"/courses\";"},{"lineNumber":358,"author":{"gitId":"-"},"content":" public static final String INSTRUCTORS \u003d URI_PREFIX + \"/instructors\";"},{"lineNumber":359,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR \u003d URI_PREFIX + \"/instructor\";"},{"lineNumber":360,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_PRIVILEGE \u003d URI_PREFIX + \"/instructor/privilege\";"},{"lineNumber":361,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_KEY \u003d URI_PREFIX + \"/instructor/key\";"},{"lineNumber":362,"author":{"gitId":"-"},"content":" public static final String RESULT \u003d URI_PREFIX + \"/result\";"},{"lineNumber":363,"author":{"gitId":"-"},"content":" public static final String STUDENTS \u003d URI_PREFIX + \"/students\";"},{"lineNumber":364,"author":{"gitId":"-"},"content":" public static final String STUDENT \u003d URI_PREFIX + \"/student\";"},{"lineNumber":365,"author":{"gitId":"-"},"content":" public static final String STUDENT_KEY \u003d URI_PREFIX + \"/student/key\";"},{"lineNumber":366,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION \u003d URI_PREFIX + \"/notification\";"},{"lineNumber":367,"author":{"gitId":"-"},"content":" public static final String NOTIFICATIONS \u003d URI_PREFIX + \"/notifications\";"},{"lineNumber":368,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_READ \u003d URI_PREFIX + \"/notification/read\";"},{"lineNumber":369,"author":{"gitId":"-"},"content":" public static final String SESSIONS_ONGOING \u003d URI_PREFIX + \"/sessions/ongoing\";"},{"lineNumber":370,"author":{"gitId":"-"},"content":" public static final String SESSION \u003d URI_PREFIX + \"/session\";"},{"lineNumber":371,"author":{"gitId":"-"},"content":" public static final String SESSION_PUBLISH \u003d URI_PREFIX + \"/session/publish\";"},{"lineNumber":372,"author":{"gitId":"-"},"content":" public static final String SESSION_REMIND_SUBMISSION \u003d URI_PREFIX + \"/session/remind/submission\";"},{"lineNumber":373,"author":{"gitId":"-"},"content":" public static final String SESSION_REMIND_RESULT \u003d URI_PREFIX + \"/session/remind/result\";"},{"lineNumber":374,"author":{"gitId":"-"},"content":" public static final String SESSION_STATS \u003d URI_PREFIX + \"/session/stats\";"},{"lineNumber":375,"author":{"gitId":"-"},"content":" public static final String SESSION_SUBMITTED_GIVER_SET \u003d URI_PREFIX + \"/session/submitted/giverset\";"},{"lineNumber":376,"author":{"gitId":"-"},"content":" public static final String SESSIONS \u003d URI_PREFIX + \"/sessions\";"},{"lineNumber":377,"author":{"gitId":"-"},"content":" public static final String SEARCH_ACCOUNT_REQUESTS \u003d URI_PREFIX + \"/search/accountrequests\";"},{"lineNumber":378,"author":{"gitId":"-"},"content":" public static final String SEARCH_INSTRUCTORS \u003d URI_PREFIX + \"/search/instructors\";"},{"lineNumber":379,"author":{"gitId":"-"},"content":" public static final String SEARCH_STUDENTS \u003d URI_PREFIX + \"/search/students\";"},{"lineNumber":380,"author":{"gitId":"-"},"content":" public static final String BIN_SESSION \u003d URI_PREFIX + \"/bin/session\";"},{"lineNumber":381,"author":{"gitId":"-"},"content":" public static final String QUESTIONS \u003d URI_PREFIX + \"/questions\";"},{"lineNumber":382,"author":{"gitId":"-"},"content":" public static final String QUESTION \u003d URI_PREFIX + \"/question\";"},{"lineNumber":383,"author":{"gitId":"-"},"content":" public static final String QUESTION_RECIPIENTS \u003d URI_PREFIX + \"/question/recipients\";"},{"lineNumber":384,"author":{"gitId":"-"},"content":" public static final String RESPONSES \u003d URI_PREFIX + \"/responses\";"},{"lineNumber":385,"author":{"gitId":"-"},"content":" public static final String USAGE_STATISTICS \u003d URI_PREFIX + \"/usagestats\";"},{"lineNumber":386,"author":{"gitId":"-"},"content":" public static final String HAS_RESPONSES \u003d URI_PREFIX + \"/hasResponses\";"},{"lineNumber":387,"author":{"gitId":"-"},"content":" public static final String JOIN \u003d URI_PREFIX + \"/join\";"},{"lineNumber":388,"author":{"gitId":"-"},"content":" public static final String JOIN_REMIND \u003d URI_PREFIX + \"/join/remind\";"},{"lineNumber":389,"author":{"gitId":"-"},"content":" public static final String TIMEZONE \u003d URI_PREFIX + \"/timezone\";"},{"lineNumber":390,"author":{"gitId":"-"},"content":" public static final String SESSION_LINKS_RECOVERY \u003d URI_PREFIX + \"/sessionlinksrecovery\";"},{"lineNumber":391,"author":{"gitId":"-"},"content":" public static final String EMAIL \u003d URI_PREFIX + \"/email\";"},{"lineNumber":392,"author":{"gitId":"-"},"content":" public static final String LOGIN_EMAIL \u003d URI_PREFIX + \"/email/login\";"},{"lineNumber":393,"author":{"gitId":"-"},"content":" public static final String SESSION_LOGS \u003d URI_PREFIX + \"/logs/session\";"},{"lineNumber":394,"author":{"gitId":"-"},"content":" public static final String LOGS \u003d URI_PREFIX + \"/logs/query\";"},{"lineNumber":395,"author":{"gitId":"-"},"content":" public static final String ACTION_CLASS \u003d URI_PREFIX + \"/actionclass\";"},{"lineNumber":396,"author":{"gitId":"-"},"content":" public static final String USER_COOKIE \u003d URI_PREFIX + \"/cookie\";"},{"lineNumber":397,"author":{"gitId":"-"},"content":" }"},{"lineNumber":398,"author":{"gitId":"-"},"content":""},{"lineNumber":399,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":400,"author":{"gitId":"-"},"content":" * Represents URIs of endpoints used by cron jobs."},{"lineNumber":401,"author":{"gitId":"-"},"content":" */"},{"lineNumber":402,"author":{"gitId":"-"},"content":" public static class CronJobURIs {"},{"lineNumber":403,"author":{"gitId":"-"},"content":" private static final String URI_PREFIX \u003d \"/auto\";"},{"lineNumber":404,"author":{"gitId":"-"},"content":""},{"lineNumber":405,"author":{"gitId":"-"},"content":" public static final String AUTOMATED_LOG_COMPILATION \u003d URI_PREFIX + \"/compileLogs\";"},{"lineNumber":406,"author":{"gitId":"-"},"content":" public static final String AUTOMATED_DATASTORE_BACKUP \u003d URI_PREFIX + \"/datastoreBackup\";"},{"lineNumber":407,"author":{"gitId":"-"},"content":" public static final String AUTOMATED_FEEDBACK_OPENING_SOON_REMINDERS \u003d"},{"lineNumber":408,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/feedbackSessionOpeningSoonReminders\";"},{"lineNumber":409,"author":{"gitId":"-"},"content":" public static final String AUTOMATED_FEEDBACK_OPENING_REMINDERS \u003d"},{"lineNumber":410,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/feedbackSessionOpeningReminders\";"},{"lineNumber":411,"author":{"gitId":"-"},"content":" public static final String AUTOMATED_FEEDBACK_CLOSED_REMINDERS \u003d"},{"lineNumber":412,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/feedbackSessionClosedReminders\";"},{"lineNumber":413,"author":{"gitId":"-"},"content":" public static final String AUTOMATED_FEEDBACK_CLOSING_REMINDERS \u003d"},{"lineNumber":414,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/feedbackSessionClosingReminders\";"},{"lineNumber":415,"author":{"gitId":"-"},"content":" public static final String AUTOMATED_FEEDBACK_PUBLISHED_REMINDERS \u003d"},{"lineNumber":416,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/feedbackSessionPublishedReminders\";"},{"lineNumber":417,"author":{"gitId":"-"},"content":" public static final String AUTOMATED_USAGE_STATISTICS_COLLECTION \u003d"},{"lineNumber":418,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/calculateUsageStatistics\";"},{"lineNumber":419,"author":{"gitId":"dishenggg"},"content":" public static final String AUTOMATED_FEEDBACK_SESSION_LOGS_PROCESSING \u003d"},{"lineNumber":420,"author":{"gitId":"dishenggg"},"content":" URI_PREFIX + \"/updateFeedbackSessionLogs\";"},{"lineNumber":421,"author":{"gitId":"-"},"content":" }"},{"lineNumber":422,"author":{"gitId":"-"},"content":""},{"lineNumber":423,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":424,"author":{"gitId":"-"},"content":" * Configurations for task queue."},{"lineNumber":425,"author":{"gitId":"-"},"content":" */"},{"lineNumber":426,"author":{"gitId":"-"},"content":" public static class TaskQueue {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" public static final String URI_PREFIX \u003d \"/worker\";"},{"lineNumber":428,"author":{"gitId":"-"},"content":""},{"lineNumber":429,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_PUBLISHED_EMAIL_QUEUE_NAME \u003d"},{"lineNumber":430,"author":{"gitId":"-"},"content":" \"feedback-session-published-email-queue\";"},{"lineNumber":431,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_PUBLISHED_EMAIL_WORKER_URL \u003d"},{"lineNumber":432,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/feedbackSessionPublishedEmail\";"},{"lineNumber":433,"author":{"gitId":"-"},"content":""},{"lineNumber":434,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_RESEND_PUBLISHED_EMAIL_QUEUE_NAME \u003d"},{"lineNumber":435,"author":{"gitId":"-"},"content":" \"feedback-session-resend-published-email-queue\";"},{"lineNumber":436,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_RESEND_PUBLISHED_EMAIL_WORKER_URL \u003d"},{"lineNumber":437,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/feedbackSessionResendPublishedEmail\";"},{"lineNumber":438,"author":{"gitId":"-"},"content":""},{"lineNumber":439,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_REMIND_EMAIL_QUEUE_NAME \u003d \"feedback-session-remind-email-queue\";"},{"lineNumber":440,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_REMIND_EMAIL_WORKER_URL \u003d URI_PREFIX + \"/feedbackSessionRemindEmail\";"},{"lineNumber":441,"author":{"gitId":"-"},"content":""},{"lineNumber":442,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_REMIND_PARTICULAR_USERS_EMAIL_QUEUE_NAME \u003d"},{"lineNumber":443,"author":{"gitId":"-"},"content":" \"feedback-session-remind-particular-users-email-queue\";"},{"lineNumber":444,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_REMIND_PARTICULAR_USERS_EMAIL_WORKER_URL \u003d"},{"lineNumber":445,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/feedbackSessionRemindParticularUsersEmail\";"},{"lineNumber":446,"author":{"gitId":"-"},"content":""},{"lineNumber":447,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_UNPUBLISHED_EMAIL_QUEUE_NAME \u003d"},{"lineNumber":448,"author":{"gitId":"-"},"content":" \"feedback-session-unpublished-email-queue\";"},{"lineNumber":449,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_UNPUBLISHED_EMAIL_WORKER_URL \u003d"},{"lineNumber":450,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/feedbackSessionUnpublishedEmail\";"},{"lineNumber":451,"author":{"gitId":"-"},"content":""},{"lineNumber":452,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_COURSE_JOIN_EMAIL_QUEUE_NAME \u003d \"instructor-course-join-email-queue\";"},{"lineNumber":453,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_COURSE_JOIN_EMAIL_WORKER_URL \u003d URI_PREFIX + \"/instructorCourseJoinEmail\";"},{"lineNumber":454,"author":{"gitId":"-"},"content":""},{"lineNumber":455,"author":{"gitId":"-"},"content":" public static final String SEND_EMAIL_QUEUE_NAME \u003d \"send-email-queue\";"},{"lineNumber":456,"author":{"gitId":"-"},"content":" public static final String SEND_EMAIL_WORKER_URL \u003d URI_PREFIX + \"/sendEmail\";"},{"lineNumber":457,"author":{"gitId":"-"},"content":""},{"lineNumber":458,"author":{"gitId":"-"},"content":" public static final String STUDENT_COURSE_JOIN_EMAIL_QUEUE_NAME \u003d \"student-course-join-email-queue\";"},{"lineNumber":459,"author":{"gitId":"-"},"content":" public static final String STUDENT_COURSE_JOIN_EMAIL_WORKER_URL \u003d URI_PREFIX + \"/studentCourseJoinEmail\";"},{"lineNumber":460,"author":{"gitId":"-"},"content":""},{"lineNumber":461,"author":{"gitId":"-"},"content":" public static final String SEARCH_INDEXING_QUEUE_NAME \u003d \"search-indexing-queue\";"},{"lineNumber":462,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_SEARCH_INDEXING_WORKER_URL \u003d URI_PREFIX + \"/instructorSearchIndexing\";"},{"lineNumber":463,"author":{"gitId":"-"},"content":" public static final String ACCOUNT_REQUEST_SEARCH_INDEXING_WORKER_URL \u003d"},{"lineNumber":464,"author":{"gitId":"-"},"content":" URI_PREFIX + \"/accountRequestSearchIndexing\";"},{"lineNumber":465,"author":{"gitId":"-"},"content":" public static final String STUDENT_SEARCH_INDEXING_WORKER_URL \u003d URI_PREFIX + \"/studentSearchIndexing\";"},{"lineNumber":466,"author":{"gitId":"-"},"content":" }"},{"lineNumber":467,"author":{"gitId":"-"},"content":""},{"lineNumber":468,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":5,"dishenggg":9,"-":454}},{"path":"src/main/java/teammates/common/util/EmailType.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.util;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":4,"author":{"gitId":"-"},"content":" * The type object that defines an email based on its purpose."},{"lineNumber":5,"author":{"gitId":"-"},"content":" */"},{"lineNumber":6,"author":{"gitId":"-"},"content":"public enum EmailType {"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":" // CHECKSTYLE.OFF:JavadocVariable enum names are self-documenting"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":" DEADLINE_EXTENSION_GRANTED(\"TEAMMATES: Deadline extension granted [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":11,"author":{"gitId":"-"},"content":" DEADLINE_EXTENSION_UPDATED(\"TEAMMATES: Deadline extension updated [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":12,"author":{"gitId":"-"},"content":" DEADLINE_EXTENSION_REVOKED(\"TEAMMATES: Deadline extension revoked [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":13,"author":{"gitId":"-"},"content":" FEEDBACK_OPENING_SOON(\"TEAMMATES: Feedback session opening soon [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":14,"author":{"gitId":"-"},"content":" FEEDBACK_OPENING(\"TEAMMATES: Feedback session now open [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":15,"author":{"gitId":"-"},"content":" FEEDBACK_SESSION_REMINDER(\"TEAMMATES: Feedback session reminder [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":16,"author":{"gitId":"-"},"content":" FEEDBACK_CLOSING(\"TEAMMATES: Feedback session closing soon [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":17,"author":{"gitId":"-"},"content":" FEEDBACK_CLOSED(\"TEAMMATES: Feedback session closed [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":18,"author":{"gitId":"-"},"content":" FEEDBACK_PUBLISHED(\"TEAMMATES: Feedback session results published [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":19,"author":{"gitId":"-"},"content":" FEEDBACK_UNPUBLISHED(\"TEAMMATES: Feedback session results unpublished [Course: %s][Feedback Session: %s]\"),"},{"lineNumber":20,"author":{"gitId":"-"},"content":" STUDENT_EMAIL_CHANGED(\"TEAMMATES: Summary of course [%s][Course ID: %s]\"),"},{"lineNumber":21,"author":{"gitId":"-"},"content":" STUDENT_COURSE_LINKS_REGENERATED(\"TEAMMATES: Your updated links for course [%s][Course ID: %s]\"),"},{"lineNumber":22,"author":{"gitId":"-"},"content":" INSTRUCTOR_COURSE_LINKS_REGENERATED(\"TEAMMATES: Your updated links for course [%s][Course ID: %s]\"),"},{"lineNumber":23,"author":{"gitId":"-"},"content":" NEW_INSTRUCTOR_ACCOUNT(\"TEAMMATES: Welcome to TEAMMATES! %s\"),"},{"lineNumber":24,"author":{"gitId":"-"},"content":" STUDENT_COURSE_JOIN(\"TEAMMATES: Invitation to join course [%s][Course ID: %s]\"),"},{"lineNumber":25,"author":{"gitId":"-"},"content":" STUDENT_COURSE_REJOIN_AFTER_GOOGLE_ID_RESET(\"TEAMMATES: Your account has been reset for course [%s][Course ID: %s]\"),"},{"lineNumber":26,"author":{"gitId":"-"},"content":" NEW_ACCOUNT_REQUEST_ADMIN_ALERT(\"TEAMMATES (Action Needed): New Account Request Received\"),"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT(\"TEAMMATES: Acknowledgement of Instructor Account Request\"),"},{"lineNumber":28,"author":{"gitId":"-"},"content":" ACCOUNT_REQUEST_REJECTION(\"TEAMMATES: %s\"),"},{"lineNumber":29,"author":{"gitId":"-"},"content":" INSTRUCTOR_COURSE_JOIN(\"TEAMMATES: Invitation to join course as an instructor [%s][Course ID: %s]\"),"},{"lineNumber":30,"author":{"gitId":"-"},"content":" INSTRUCTOR_COURSE_REJOIN_AFTER_GOOGLE_ID_RESET(\"TEAMMATES: Your account has been reset for course [%s][Course ID: %s]\"),"},{"lineNumber":31,"author":{"gitId":"-"},"content":" USER_COURSE_REGISTER(\"TEAMMATES: Registered for Course [%s][Course ID: %s]\"),"},{"lineNumber":32,"author":{"gitId":"-"},"content":" SEVERE_LOGS_COMPILATION(\"TEAMMATES (%s): Severe Error Logs Compilation\"),"},{"lineNumber":33,"author":{"gitId":"-"},"content":" SESSION_LINKS_RECOVERY(\"TEAMMATES: Access links for recent feedback sessions\"),"},{"lineNumber":34,"author":{"gitId":"-"},"content":" LOGIN(\"TEAMMATES: Log in to TEAMMATES\");"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" private final String subject;"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" EmailType(String subject) {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.subject \u003d subject;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":43,"author":{"gitId":"-"},"content":" * Gets the subject heading of this email type."},{"lineNumber":44,"author":{"gitId":"-"},"content":" */"},{"lineNumber":45,"author":{"gitId":"-"},"content":" public String getSubject() {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" return subject;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" }"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":1,"-":48}},{"path":"src/main/java/teammates/common/util/FieldValidator.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.util;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Duration;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.LocalDateTime;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.time.ZoneId;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.Arrays;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.Collection;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.Collections;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.HashSet;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import java.util.LinkedList;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import java.util.Set;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import java.util.function.BiPredicate;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationStyle;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationTargetUser;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * Used to handle the data validation aspect e.g. validate emails, names, etc."},{"lineNumber":25,"author":{"gitId":"-"},"content":" */"},{"lineNumber":26,"author":{"gitId":"-"},"content":"public final class FieldValidator {"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" /////////////////"},{"lineNumber":29,"author":{"gitId":"-"},"content":" // FIELD TYPES //"},{"lineNumber":30,"author":{"gitId":"-"},"content":" /////////////////"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" // name-related"},{"lineNumber":33,"author":{"gitId":"-"},"content":" public static final String PERSON_NAME_FIELD_NAME \u003d \"person name\";"},{"lineNumber":34,"author":{"gitId":"-"},"content":" public static final int PERSON_NAME_MAX_LENGTH \u003d 100;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" public static final String COURSE_NAME_FIELD_NAME \u003d \"course name\";"},{"lineNumber":37,"author":{"gitId":"-"},"content":" public static final int COURSE_NAME_MAX_LENGTH \u003d 80;"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" public static final String FEEDBACK_SESSION_NAME_FIELD_NAME \u003d \"feedback session name\";"},{"lineNumber":40,"author":{"gitId":"-"},"content":" public static final int FEEDBACK_SESSION_NAME_MAX_LENGTH \u003d 64;"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" public static final String TEAM_NAME_FIELD_NAME \u003d \"team name\";"},{"lineNumber":43,"author":{"gitId":"-"},"content":" public static final int TEAM_NAME_MAX_LENGTH \u003d 60;"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" public static final String SECTION_NAME_FIELD_NAME \u003d \"section name\";"},{"lineNumber":46,"author":{"gitId":"-"},"content":" public static final int SECTION_NAME_MAX_LENGTH \u003d 60;"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" public static final String INSTITUTE_NAME_FIELD_NAME \u003d \"institute name\";"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" public static final int INSTITUTE_NAME_MAX_LENGTH \u003d 128;"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" // email-related"},{"lineNumber":52,"author":{"gitId":"-"},"content":" public static final String EMAIL_FIELD_NAME \u003d \"email\";"},{"lineNumber":53,"author":{"gitId":"-"},"content":" public static final int EMAIL_MAX_LENGTH \u003d 254;"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" // notification-related"},{"lineNumber":56,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_TITLE_FIELD_NAME \u003d \"notification title\";"},{"lineNumber":57,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_MESSAGE_FIELD_NAME \u003d \"notification message\";"},{"lineNumber":58,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_NAME \u003d \"notification\";"},{"lineNumber":59,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_VISIBLE_TIME_FIELD_NAME \u003d \"time when the notification will be visible\";"},{"lineNumber":60,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_EXPIRY_TIME_FIELD_NAME \u003d \"time when the notification will expire\";"},{"lineNumber":61,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_STYLE_FIELD_NAME \u003d \"notification style\";"},{"lineNumber":62,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_TARGET_USER_FIELD_NAME \u003d \"notification target user\";"},{"lineNumber":63,"author":{"gitId":"-"},"content":" public static final int NOTIFICATION_TITLE_MAX_LENGTH \u003d 80;"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" public static final List\u003cString\u003e NOTIFICATION_STYLE_ACCEPTED_VALUES \u003d"},{"lineNumber":66,"author":{"gitId":"-"},"content":" Collections.unmodifiableList("},{"lineNumber":67,"author":{"gitId":"-"},"content":" Arrays.stream("},{"lineNumber":68,"author":{"gitId":"-"},"content":" NotificationStyle.values())"},{"lineNumber":69,"author":{"gitId":"-"},"content":" .map(NotificationStyle::toString)"},{"lineNumber":70,"author":{"gitId":"-"},"content":" .collect(Collectors.toList())"},{"lineNumber":71,"author":{"gitId":"-"},"content":" );"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" public static final List\u003cString\u003e NOTIFICATION_TARGET_USER_ACCEPTED_VALUES \u003d"},{"lineNumber":74,"author":{"gitId":"-"},"content":" Collections.unmodifiableList("},{"lineNumber":75,"author":{"gitId":"-"},"content":" Arrays.stream("},{"lineNumber":76,"author":{"gitId":"-"},"content":" NotificationTargetUser.values())"},{"lineNumber":77,"author":{"gitId":"-"},"content":" .map(NotificationTargetUser::toString)"},{"lineNumber":78,"author":{"gitId":"-"},"content":" .collect(Collectors.toList())"},{"lineNumber":79,"author":{"gitId":"-"},"content":" );"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" // others"},{"lineNumber":82,"author":{"gitId":"-"},"content":" public static final String STUDENT_ROLE_COMMENTS_FIELD_NAME \u003d \"comments about a student enrolled in a course\";"},{"lineNumber":83,"author":{"gitId":"-"},"content":" public static final int STUDENT_ROLE_COMMENTS_MAX_LENGTH \u003d 500;"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" /*"},{"lineNumber":86,"author":{"gitId":"-"},"content":" * \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"lineNumber":87,"author":{"gitId":"-"},"content":" * Field: Course ID"},{"lineNumber":88,"author":{"gitId":"-"},"content":" * Unique: system-wide, not just among the course of that instructor."},{"lineNumber":89,"author":{"gitId":"-"},"content":" * Technically, we can get rid of CourseID field and enforce users to use"},{"lineNumber":90,"author":{"gitId":"-"},"content":" * CourseName as a unique ID. In that case, we have to enforce CourseName"},{"lineNumber":91,"author":{"gitId":"-"},"content":" * must be unique across the full system. However, users expect names to be"},{"lineNumber":92,"author":{"gitId":"-"},"content":" * non-unique and more tolerant of enforcing uniqueness on an ID. Whenever"},{"lineNumber":93,"author":{"gitId":"-"},"content":" * possible, must be displayed in the same case as user entered. This is"},{"lineNumber":94,"author":{"gitId":"-"},"content":" * because the case of the letters can mean something. Furthermore,"},{"lineNumber":95,"author":{"gitId":"-"},"content":" * converting to same case can reduce readability."},{"lineNumber":96,"author":{"gitId":"-"},"content":" *"},{"lineNumber":97,"author":{"gitId":"-"},"content":" * Course ID is necessary because the course name is not unique enough to"},{"lineNumber":98,"author":{"gitId":"-"},"content":" * distinguish between courses because the same course can be offered"},{"lineNumber":99,"author":{"gitId":"-"},"content":" * multiple times and courses can be shared between instructors and many"},{"lineNumber":100,"author":{"gitId":"-"},"content":" * students. Allowing same Course ID among different instructors could be"},{"lineNumber":101,"author":{"gitId":"-"},"content":" * problematic if we allow multiple instructors for a single course."},{"lineNumber":102,"author":{"gitId":"-"},"content":" * TODO: make case insensitive"},{"lineNumber":103,"author":{"gitId":"-"},"content":" */"},{"lineNumber":104,"author":{"gitId":"-"},"content":" public static final String COURSE_ID_FIELD_NAME \u003d \"course ID\";"},{"lineNumber":105,"author":{"gitId":"-"},"content":" public static final int COURSE_ID_MAX_LENGTH \u003d 64;"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" public static final String SESSION_NAME \u003d \"feedback session\";"},{"lineNumber":108,"author":{"gitId":"-"},"content":" public static final String SESSION_START_TIME_FIELD_NAME \u003d \"start time\";"},{"lineNumber":109,"author":{"gitId":"-"},"content":" public static final String SESSION_END_TIME_FIELD_NAME \u003d \"end time\";"},{"lineNumber":110,"author":{"gitId":"-"},"content":" public static final String TIME_ZONE_FIELD_NAME \u003d \"time zone\";"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" public static final String GOOGLE_ID_FIELD_NAME \u003d \"Google ID\";"},{"lineNumber":113,"author":{"gitId":"-"},"content":" public static final int GOOGLE_ID_MAX_LENGTH \u003d 254;"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" public static final String ROLE_FIELD_NAME \u003d \"access-level\";"},{"lineNumber":116,"author":{"gitId":"-"},"content":" public static final List\u003cString\u003e ROLE_ACCEPTED_VALUES \u003d"},{"lineNumber":117,"author":{"gitId":"-"},"content":" Collections.unmodifiableList("},{"lineNumber":118,"author":{"gitId":"-"},"content":" Arrays.asList(Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_COOWNER,"},{"lineNumber":119,"author":{"gitId":"-"},"content":" Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_MANAGER,"},{"lineNumber":120,"author":{"gitId":"-"},"content":" Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_OBSERVER,"},{"lineNumber":121,"author":{"gitId":"-"},"content":" Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_TUTOR,"},{"lineNumber":122,"author":{"gitId":"-"},"content":" Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_CUSTOM));"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" public static final String GIVER_TYPE_NAME \u003d \"feedback giver\";"},{"lineNumber":125,"author":{"gitId":"-"},"content":" public static final String RECIPIENT_TYPE_NAME \u003d \"feedback recipient\";"},{"lineNumber":126,"author":{"gitId":"-"},"content":" public static final String VIEWER_TYPE_NAME \u003d \"feedback viewer\";"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" public static final String EXTENDED_DEADLINES_FIELD_NAME \u003d \"extended deadlines\";"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" ////////////////////"},{"lineNumber":131,"author":{"gitId":"-"},"content":" // ERROR MESSAGES //"},{"lineNumber":132,"author":{"gitId":"-"},"content":" ////////////////////"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" public static final String REASON_TOO_LONG \u003d \"is too long\";"},{"lineNumber":135,"author":{"gitId":"-"},"content":" public static final String REASON_INCORRECT_FORMAT \u003d \"is not in the correct format\";"},{"lineNumber":136,"author":{"gitId":"-"},"content":" public static final String REASON_CONTAINS_INVALID_CHAR \u003d \"contains invalid characters\";"},{"lineNumber":137,"author":{"gitId":"-"},"content":" public static final String REASON_START_WITH_NON_ALPHANUMERIC_CHAR \u003d \"starts with a non-alphanumeric character\";"},{"lineNumber":138,"author":{"gitId":"-"},"content":" public static final String REASON_UNAVAILABLE_AS_CHOICE \u003d \"is not available as a choice\";"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" // error message components"},{"lineNumber":141,"author":{"gitId":"-"},"content":" public static final String EMPTY_STRING_ERROR_INFO \u003d"},{"lineNumber":142,"author":{"gitId":"-"},"content":" \"The field \u0027${fieldName}\u0027 is empty.\";"},{"lineNumber":143,"author":{"gitId":"-"},"content":" public static final String ERROR_INFO \u003d"},{"lineNumber":144,"author":{"gitId":"-"},"content":" \"\\\"${userInput}\\\" is not acceptable to TEAMMATES as a/an ${fieldName} because it ${reason}.\";"},{"lineNumber":145,"author":{"gitId":"-"},"content":" public static final String HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_POSSIBLY_EMPTY \u003d"},{"lineNumber":146,"author":{"gitId":"-"},"content":" \"The value of a/an ${fieldName} should be no longer than ${maxLength} characters.\";"},{"lineNumber":147,"author":{"gitId":"-"},"content":" public static final String HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_NON_EMPTY \u003d"},{"lineNumber":148,"author":{"gitId":"-"},"content":" HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_POSSIBLY_EMPTY + \" It should not be empty.\";"},{"lineNumber":149,"author":{"gitId":"-"},"content":" public static final String HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_NON_EMPTY_NO_SPACES \u003d"},{"lineNumber":150,"author":{"gitId":"-"},"content":" \"It cannot be longer than ${maxLength} characters, cannot be empty and cannot contain spaces.\";"},{"lineNumber":151,"author":{"gitId":"-"},"content":" public static final String HINT_FOR_CORRECT_FORMAT_FOR_INVALID_NAME \u003d"},{"lineNumber":152,"author":{"gitId":"-"},"content":" \"A/An ${fieldName} must start with an alphanumeric character, and cannot contain any vertical bar \""},{"lineNumber":153,"author":{"gitId":"-"},"content":" + \"(|) or percent sign (%).\";"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" // generic (i.e., not specific to any field) error messages"},{"lineNumber":156,"author":{"gitId":"-"},"content":" public static final String SIZE_CAPPED_NON_EMPTY_STRING_ERROR_MESSAGE \u003d"},{"lineNumber":157,"author":{"gitId":"-"},"content":" ERROR_INFO + \" \" + HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_NON_EMPTY;"},{"lineNumber":158,"author":{"gitId":"-"},"content":" public static final String SIZE_CAPPED_NON_EMPTY_STRING_ERROR_MESSAGE_EMPTY_STRING \u003d"},{"lineNumber":159,"author":{"gitId":"-"},"content":" EMPTY_STRING_ERROR_INFO + \" \" + HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_NON_EMPTY;"},{"lineNumber":160,"author":{"gitId":"-"},"content":" public static final String SIZE_CAPPED_POSSIBLY_EMPTY_STRING_ERROR_MESSAGE \u003d"},{"lineNumber":161,"author":{"gitId":"-"},"content":" ERROR_INFO + \" \" + HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_POSSIBLY_EMPTY;"},{"lineNumber":162,"author":{"gitId":"-"},"content":" public static final String SIZE_CAPPED_NON_EMPTY_STRING_ERROR_MESSAGE_EMPTY_STRING_FOR_SESSION_NAME \u003d"},{"lineNumber":163,"author":{"gitId":"-"},"content":" \"The field \u0027${fieldName}\u0027 should not be empty.\" + \" \""},{"lineNumber":164,"author":{"gitId":"-"},"content":" + \"The value of \u0027${fieldName}\u0027 field should be no longer than ${maxLength} characters.\";"},{"lineNumber":165,"author":{"gitId":"-"},"content":" public static final String INVALID_NAME_ERROR_MESSAGE \u003d"},{"lineNumber":166,"author":{"gitId":"-"},"content":" ERROR_INFO + \" \" + HINT_FOR_CORRECT_FORMAT_FOR_INVALID_NAME;"},{"lineNumber":167,"author":{"gitId":"-"},"content":" public static final String TEAM_NAME_IS_VALID_EMAIL_ERROR_MESSAGE \u003d"},{"lineNumber":168,"author":{"gitId":"-"},"content":" \"The field \" + TEAM_NAME_FIELD_NAME + \" is not acceptable to TEAMMATES as the suggested value for \""},{"lineNumber":169,"author":{"gitId":"-"},"content":" + TEAM_NAME_FIELD_NAME + \" can be mis-interpreted as an email.\";"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" public static final String WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE \u003d"},{"lineNumber":172,"author":{"gitId":"-"},"content":" \"The provided ${fieldName} is not acceptable to TEAMMATES as it contains only whitespace \""},{"lineNumber":173,"author":{"gitId":"-"},"content":" + \"or contains extra spaces at the beginning or at the end of the text.\";"},{"lineNumber":174,"author":{"gitId":"-"},"content":" public static final String NON_HTML_FIELD_ERROR_MESSAGE \u003d"},{"lineNumber":175,"author":{"gitId":"-"},"content":" \"The provided ${fieldName} is not acceptable to TEAMMATES \""},{"lineNumber":176,"author":{"gitId":"-"},"content":" + \"as it cannot contain the following special html characters\""},{"lineNumber":177,"author":{"gitId":"-"},"content":" + \" in brackets: (\u003c \u003e \\\" / \u0027 \u0026)\";"},{"lineNumber":178,"author":{"gitId":"-"},"content":" public static final String NON_NULL_FIELD_ERROR_MESSAGE \u003d"},{"lineNumber":179,"author":{"gitId":"-"},"content":" \"The provided ${fieldName} is not acceptable to TEAMMATES as it cannot be empty.\";"},{"lineNumber":180,"author":{"gitId":"-"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":" // field-specific error messages"},{"lineNumber":182,"author":{"gitId":"-"},"content":" public static final String HINT_FOR_CORRECT_EMAIL \u003d"},{"lineNumber":183,"author":{"gitId":"-"},"content":" \"An email address contains some text followed by one \u0027@\u0027 sign followed by some more text, and should end \""},{"lineNumber":184,"author":{"gitId":"-"},"content":" + \"with a top level domain address like .com. \""},{"lineNumber":185,"author":{"gitId":"-"},"content":" + HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_NON_EMPTY_NO_SPACES;"},{"lineNumber":186,"author":{"gitId":"-"},"content":" public static final String EMAIL_ERROR_MESSAGE \u003d"},{"lineNumber":187,"author":{"gitId":"-"},"content":" ERROR_INFO + \" \" + HINT_FOR_CORRECT_EMAIL;"},{"lineNumber":188,"author":{"gitId":"-"},"content":" public static final String EMAIL_ERROR_MESSAGE_EMPTY_STRING \u003d"},{"lineNumber":189,"author":{"gitId":"-"},"content":" EMPTY_STRING_ERROR_INFO + \" \" + HINT_FOR_CORRECT_EMAIL;"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" public static final String HINT_FOR_CORRECT_COURSE_ID \u003d"},{"lineNumber":192,"author":{"gitId":"-"},"content":" \"A course ID can contain letters, numbers, fullstops, hyphens, underscores, and dollar signs. \""},{"lineNumber":193,"author":{"gitId":"-"},"content":" + HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_NON_EMPTY_NO_SPACES;"},{"lineNumber":194,"author":{"gitId":"-"},"content":" public static final String COURSE_ID_ERROR_MESSAGE \u003d"},{"lineNumber":195,"author":{"gitId":"-"},"content":" ERROR_INFO + \" \" + HINT_FOR_CORRECT_COURSE_ID;"},{"lineNumber":196,"author":{"gitId":"-"},"content":" public static final String COURSE_ID_ERROR_MESSAGE_EMPTY_STRING \u003d"},{"lineNumber":197,"author":{"gitId":"-"},"content":" EMPTY_STRING_ERROR_INFO + \" \" + HINT_FOR_CORRECT_COURSE_ID;"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" public static final String HINT_FOR_CORRECT_FORMAT_OF_GOOGLE_ID \u003d"},{"lineNumber":200,"author":{"gitId":"-"},"content":" \"A Google ID must be a valid id already registered with Google. \""},{"lineNumber":201,"author":{"gitId":"-"},"content":" + HINT_FOR_CORRECT_FORMAT_FOR_SIZE_CAPPED_NON_EMPTY_NO_SPACES;"},{"lineNumber":202,"author":{"gitId":"-"},"content":" public static final String GOOGLE_ID_ERROR_MESSAGE \u003d"},{"lineNumber":203,"author":{"gitId":"-"},"content":" ERROR_INFO + \" \" + HINT_FOR_CORRECT_FORMAT_OF_GOOGLE_ID;"},{"lineNumber":204,"author":{"gitId":"-"},"content":" public static final String GOOGLE_ID_ERROR_MESSAGE_EMPTY_STRING \u003d"},{"lineNumber":205,"author":{"gitId":"-"},"content":" EMPTY_STRING_ERROR_INFO + \" \" + HINT_FOR_CORRECT_FORMAT_OF_GOOGLE_ID;"},{"lineNumber":206,"author":{"gitId":"-"},"content":""},{"lineNumber":207,"author":{"gitId":"-"},"content":" public static final String HINT_FOR_CORRECT_TIME_ZONE \u003d"},{"lineNumber":208,"author":{"gitId":"-"},"content":" \"The value must be one of the values from the time zone dropdown selector.\";"},{"lineNumber":209,"author":{"gitId":"-"},"content":" public static final String TIME_ZONE_ERROR_MESSAGE \u003d"},{"lineNumber":210,"author":{"gitId":"-"},"content":" ERROR_INFO + \" \" + HINT_FOR_CORRECT_TIME_ZONE;"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" public static final String HINT_FOR_CORRECT_GRACE_PERIOD \u003d"},{"lineNumber":213,"author":{"gitId":"-"},"content":" \"The value must be one of the options in the grace period dropdown selector.\";"},{"lineNumber":214,"author":{"gitId":"-"},"content":" public static final String GRACE_PERIOD_NEGATIVE_ERROR_MESSAGE \u003d \"Grace period should not be negative.\" + \" \""},{"lineNumber":215,"author":{"gitId":"-"},"content":" + HINT_FOR_CORRECT_GRACE_PERIOD;"},{"lineNumber":216,"author":{"gitId":"-"},"content":""},{"lineNumber":217,"author":{"gitId":"-"},"content":" public static final String ROLE_ERROR_MESSAGE \u003d"},{"lineNumber":218,"author":{"gitId":"-"},"content":" \"\\\"%s\\\" is not an accepted \" + ROLE_FIELD_NAME + \" to TEAMMATES. \";"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_STYLE_ERROR_MESSAGE \u003d"},{"lineNumber":221,"author":{"gitId":"-"},"content":" \"\\\"%s\\\" is not an accepted \" + NOTIFICATION_STYLE_FIELD_NAME + \" to TEAMMATES. \";"},{"lineNumber":222,"author":{"gitId":"-"},"content":""},{"lineNumber":223,"author":{"gitId":"-"},"content":" public static final String NOTIFICATION_TARGET_USER_ERROR_MESSAGE \u003d"},{"lineNumber":224,"author":{"gitId":"-"},"content":" \"\\\"%s\\\" is not an accepted \" + NOTIFICATION_TARGET_USER_FIELD_NAME + \" to TEAMMATES. \";"},{"lineNumber":225,"author":{"gitId":"-"},"content":""},{"lineNumber":226,"author":{"gitId":"-"},"content":" public static final String SESSION_VISIBLE_TIME_FIELD_NAME \u003d \"time when the session will be visible\";"},{"lineNumber":227,"author":{"gitId":"-"},"content":" public static final String RESULTS_VISIBLE_TIME_FIELD_NAME \u003d \"time when the results will be visible\";"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" public static final String TIME_BEFORE_ERROR_MESSAGE \u003d"},{"lineNumber":230,"author":{"gitId":"-"},"content":" \"The %s for this %s cannot be earlier than the %s.\";"},{"lineNumber":231,"author":{"gitId":"-"},"content":" public static final String TIME_BEFORE_OR_EQUAL_ERROR_MESSAGE \u003d"},{"lineNumber":232,"author":{"gitId":"-"},"content":" \"The %s for this %s cannot be earlier than or at the same time as the %s.\";"},{"lineNumber":233,"author":{"gitId":"-"},"content":""},{"lineNumber":234,"author":{"gitId":"-"},"content":" public static final String PARTICIPANT_TYPE_ERROR_MESSAGE \u003d \"%s is not a valid %s.\";"},{"lineNumber":235,"author":{"gitId":"-"},"content":" public static final String PARTICIPANT_TYPE_TEAM_ERROR_MESSAGE \u003d"},{"lineNumber":236,"author":{"gitId":"-"},"content":" \"The feedback recipients cannot be \\\"%s\\\" when the feedback giver is \\\"%s\\\". \""},{"lineNumber":237,"author":{"gitId":"-"},"content":" + \"Did you mean to use \\\"Self\\\" instead?\";"},{"lineNumber":238,"author":{"gitId":"-"},"content":""},{"lineNumber":239,"author":{"gitId":"-"},"content":" public static final String NOT_EXACT_HOUR_ERROR_MESSAGE \u003d \"The %s for this feedback session must be at exact hour mark.\";"},{"lineNumber":240,"author":{"gitId":"-"},"content":""},{"lineNumber":241,"author":{"gitId":"-"},"content":" ///////////////////////////////////////"},{"lineNumber":242,"author":{"gitId":"-"},"content":" // VALIDATION REGEX FOR INTERNAL USE //"},{"lineNumber":243,"author":{"gitId":"-"},"content":" ///////////////////////////////////////"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":246,"author":{"gitId":"-"},"content":" * Must start with alphanumeric character, cannot contain vertical bar(|) or percent sign(%)."},{"lineNumber":247,"author":{"gitId":"-"},"content":" */"},{"lineNumber":248,"author":{"gitId":"-"},"content":" public static final String REGEX_NAME \u003d \"^[\\\\p{IsL}\\\\p{IsN}][^|%]*+$\";"},{"lineNumber":249,"author":{"gitId":"-"},"content":""},{"lineNumber":250,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":251,"author":{"gitId":"-"},"content":" * Allows English alphabet, numbers, underscore, dot, dollar sign and hyphen."},{"lineNumber":252,"author":{"gitId":"-"},"content":" */"},{"lineNumber":253,"author":{"gitId":"-"},"content":" public static final String REGEX_COURSE_ID \u003d \"[a-zA-Z0-9_.$-]+\";"},{"lineNumber":254,"author":{"gitId":"-"},"content":""},{"lineNumber":255,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":256,"author":{"gitId":"-"},"content":" * Local part:"},{"lineNumber":257,"author":{"gitId":"-"},"content":" * \u003cli\u003eCan only start with letters, digits, hyphen or plus sign;"},{"lineNumber":258,"author":{"gitId":"-"},"content":" * \u003cli\u003eSpecial characters allowed are ! # $ % \u0026 \u0027 * + - / \u003d ? ^ _ ` { } ~"},{"lineNumber":259,"author":{"gitId":"-"},"content":" * \u003cli\u003eDot can only appear between any 2 characters and cannot appear continuously\u003cbr\u003e"},{"lineNumber":260,"author":{"gitId":"-"},"content":" * Domain part:"},{"lineNumber":261,"author":{"gitId":"-"},"content":" * \u003cli\u003eOnly allow letters, digits, hyphen and dot; Must end with letters; Must have TLD"},{"lineNumber":262,"author":{"gitId":"-"},"content":" */"},{"lineNumber":263,"author":{"gitId":"-"},"content":" public static final String REGEX_EMAIL \u003d \"^[\\\\w+-][\\\\w+!#$%\u0026\u0027*/\u003d?^_`{}~-]*+(\\\\.[\\\\w+!#$%\u0026\u0027*/\u003d?^_`{}~-]+)*+\""},{"lineNumber":264,"author":{"gitId":"-"},"content":" + \"@([A-Za-z0-9-]+\\\\.)+[A-Za-z]+$\";"},{"lineNumber":265,"author":{"gitId":"-"},"content":""},{"lineNumber":266,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":267,"author":{"gitId":"-"},"content":" * Allows English alphabet, numbers, underscore, dot and hyphen."},{"lineNumber":268,"author":{"gitId":"-"},"content":" */"},{"lineNumber":269,"author":{"gitId":"-"},"content":" public static final String REGEX_GOOGLE_ID_NON_EMAIL \u003d \"[a-zA-Z0-9_.-]+\";"},{"lineNumber":270,"author":{"gitId":"-"},"content":""},{"lineNumber":271,"author":{"gitId":"-"},"content":" private FieldValidator() {"},{"lineNumber":272,"author":{"gitId":"-"},"content":" // utility class"},{"lineNumber":273,"author":{"gitId":"-"},"content":" // Intentional private constructor to prevent instantiation."},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" /////////////////////////////////////////"},{"lineNumber":277,"author":{"gitId":"-"},"content":" // VALIDATION METHODS FOR EXTERNAL USE //"},{"lineNumber":278,"author":{"gitId":"-"},"content":" /////////////////////////////////////////"},{"lineNumber":279,"author":{"gitId":"-"},"content":""},{"lineNumber":280,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":281,"author":{"gitId":"-"},"content":" * Checks if {@code email} is not null, not empty, not longer than {@code EMAIL_MAX_LENGTH}, and is a"},{"lineNumber":282,"author":{"gitId":"-"},"content":" * valid email address according to {@code REGEX_EMAIL}."},{"lineNumber":283,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code email} is not acceptable."},{"lineNumber":284,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code email} is acceptable."},{"lineNumber":285,"author":{"gitId":"-"},"content":" */"},{"lineNumber":286,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForEmail(String email) {"},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":289,"author":{"gitId":"-"},"content":""},{"lineNumber":290,"author":{"gitId":"-"},"content":" if (email.isEmpty()) {"},{"lineNumber":291,"author":{"gitId":"-"},"content":" return getPopulatedEmptyStringErrorMessage(EMAIL_ERROR_MESSAGE_EMPTY_STRING, EMAIL_FIELD_NAME,"},{"lineNumber":292,"author":{"gitId":"-"},"content":" EMAIL_MAX_LENGTH);"},{"lineNumber":293,"author":{"gitId":"-"},"content":" } else if (isUntrimmed(email)) {"},{"lineNumber":294,"author":{"gitId":"-"},"content":" return WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace(\"${fieldName}\", EMAIL_FIELD_NAME);"},{"lineNumber":295,"author":{"gitId":"-"},"content":" } else if (email.length() \u003e EMAIL_MAX_LENGTH) {"},{"lineNumber":296,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(EMAIL_ERROR_MESSAGE, email, EMAIL_FIELD_NAME,"},{"lineNumber":297,"author":{"gitId":"-"},"content":" REASON_TOO_LONG, EMAIL_MAX_LENGTH);"},{"lineNumber":298,"author":{"gitId":"-"},"content":" } else if (!isValidEmailAddress(email)) {"},{"lineNumber":299,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(EMAIL_ERROR_MESSAGE, email, EMAIL_FIELD_NAME,"},{"lineNumber":300,"author":{"gitId":"-"},"content":" REASON_INCORRECT_FORMAT, EMAIL_MAX_LENGTH);"},{"lineNumber":301,"author":{"gitId":"-"},"content":" }"},{"lineNumber":302,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":303,"author":{"gitId":"-"},"content":" }"},{"lineNumber":304,"author":{"gitId":"-"},"content":""},{"lineNumber":305,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":306,"author":{"gitId":"-"},"content":" * Checks if {@code gracePeriod} is not negative."},{"lineNumber":307,"author":{"gitId":"-"},"content":" * @return An explanation why the {@code gracePeriod} is not acceptable."},{"lineNumber":308,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code gracePeriod} is acceptable."},{"lineNumber":309,"author":{"gitId":"-"},"content":" */"},{"lineNumber":310,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForGracePeriod(Duration gracePeriod) {"},{"lineNumber":311,"author":{"gitId":"-"},"content":" if (gracePeriod.isNegative()) {"},{"lineNumber":312,"author":{"gitId":"-"},"content":" return GRACE_PERIOD_NEGATIVE_ERROR_MESSAGE;"},{"lineNumber":313,"author":{"gitId":"-"},"content":" }"},{"lineNumber":314,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":315,"author":{"gitId":"-"},"content":" }"},{"lineNumber":316,"author":{"gitId":"-"},"content":""},{"lineNumber":317,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":318,"author":{"gitId":"-"},"content":" * Checks if {@code googleId} is not null, not empty, not longer than {@code GOOGLE_ID_MAX_LENGTH}, does"},{"lineNumber":319,"author":{"gitId":"-"},"content":" * not contain any invalid characters (| or %), AND is either a Google username (without the \"@gmail.com\")"},{"lineNumber":320,"author":{"gitId":"-"},"content":" * or a valid email address."},{"lineNumber":321,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code googleId} is not acceptable."},{"lineNumber":322,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code googleId} is acceptable."},{"lineNumber":323,"author":{"gitId":"-"},"content":" */"},{"lineNumber":324,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForGoogleId(String googleId) {"},{"lineNumber":325,"author":{"gitId":"-"},"content":""},{"lineNumber":326,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":327,"author":{"gitId":"-"},"content":""},{"lineNumber":328,"author":{"gitId":"-"},"content":" boolean isValidFullEmail \u003d isValidEmailAddress(googleId);"},{"lineNumber":329,"author":{"gitId":"-"},"content":" boolean isValidEmailWithoutDomain \u003d StringHelper.isMatching(googleId, REGEX_GOOGLE_ID_NON_EMAIL);"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" if (googleId.isEmpty()) {"},{"lineNumber":332,"author":{"gitId":"-"},"content":" return getPopulatedEmptyStringErrorMessage(GOOGLE_ID_ERROR_MESSAGE_EMPTY_STRING,"},{"lineNumber":333,"author":{"gitId":"-"},"content":" GOOGLE_ID_FIELD_NAME, GOOGLE_ID_MAX_LENGTH);"},{"lineNumber":334,"author":{"gitId":"-"},"content":" } else if (isUntrimmed(googleId)) {"},{"lineNumber":335,"author":{"gitId":"-"},"content":" return WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace(\"${fieldName}\", GOOGLE_ID_FIELD_NAME);"},{"lineNumber":336,"author":{"gitId":"-"},"content":" } else if (googleId.length() \u003e GOOGLE_ID_MAX_LENGTH) {"},{"lineNumber":337,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(GOOGLE_ID_ERROR_MESSAGE, googleId, GOOGLE_ID_FIELD_NAME,"},{"lineNumber":338,"author":{"gitId":"-"},"content":" REASON_TOO_LONG, GOOGLE_ID_MAX_LENGTH);"},{"lineNumber":339,"author":{"gitId":"-"},"content":" } else if (!(isValidFullEmail || isValidEmailWithoutDomain)) {"},{"lineNumber":340,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(GOOGLE_ID_ERROR_MESSAGE, googleId, GOOGLE_ID_FIELD_NAME,"},{"lineNumber":341,"author":{"gitId":"-"},"content":" REASON_INCORRECT_FORMAT, GOOGLE_ID_MAX_LENGTH);"},{"lineNumber":342,"author":{"gitId":"-"},"content":" }"},{"lineNumber":343,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":344,"author":{"gitId":"-"},"content":" }"},{"lineNumber":345,"author":{"gitId":"-"},"content":""},{"lineNumber":346,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":347,"author":{"gitId":"-"},"content":" * Checks if {@code courseId} is not null, not empty, has no surrounding whitespaces, not longer than"},{"lineNumber":348,"author":{"gitId":"-"},"content":" * {@code COURSE_ID_MAX_LENGTH}, is sanitized for HTML, and match the REGEX {@code REGEX_COURSE_ID}."},{"lineNumber":349,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code courseId} is not acceptable."},{"lineNumber":350,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code courseId} is acceptable."},{"lineNumber":351,"author":{"gitId":"-"},"content":" */"},{"lineNumber":352,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForCourseId(String courseId) {"},{"lineNumber":353,"author":{"gitId":"-"},"content":""},{"lineNumber":354,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":355,"author":{"gitId":"-"},"content":""},{"lineNumber":356,"author":{"gitId":"-"},"content":" if (courseId.isEmpty()) {"},{"lineNumber":357,"author":{"gitId":"-"},"content":" return getPopulatedEmptyStringErrorMessage(COURSE_ID_ERROR_MESSAGE_EMPTY_STRING,"},{"lineNumber":358,"author":{"gitId":"-"},"content":" COURSE_ID_FIELD_NAME, COURSE_ID_MAX_LENGTH);"},{"lineNumber":359,"author":{"gitId":"-"},"content":" }"},{"lineNumber":360,"author":{"gitId":"-"},"content":" if (isUntrimmed(courseId)) {"},{"lineNumber":361,"author":{"gitId":"-"},"content":" return WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace(\"${fieldName}\","},{"lineNumber":362,"author":{"gitId":"-"},"content":" COURSE_ID_FIELD_NAME);"},{"lineNumber":363,"author":{"gitId":"-"},"content":" }"},{"lineNumber":364,"author":{"gitId":"-"},"content":" if (courseId.length() \u003e COURSE_ID_MAX_LENGTH) {"},{"lineNumber":365,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(COURSE_ID_ERROR_MESSAGE, courseId, COURSE_ID_FIELD_NAME,"},{"lineNumber":366,"author":{"gitId":"-"},"content":" REASON_TOO_LONG, COURSE_ID_MAX_LENGTH);"},{"lineNumber":367,"author":{"gitId":"-"},"content":" }"},{"lineNumber":368,"author":{"gitId":"-"},"content":" if (!StringHelper.isMatching(courseId, REGEX_COURSE_ID)) {"},{"lineNumber":369,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(COURSE_ID_ERROR_MESSAGE, courseId, COURSE_ID_FIELD_NAME,"},{"lineNumber":370,"author":{"gitId":"-"},"content":" REASON_INCORRECT_FORMAT, COURSE_ID_MAX_LENGTH);"},{"lineNumber":371,"author":{"gitId":"-"},"content":" }"},{"lineNumber":372,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":373,"author":{"gitId":"-"},"content":" }"},{"lineNumber":374,"author":{"gitId":"-"},"content":""},{"lineNumber":375,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":376,"author":{"gitId":"-"},"content":" * Checks if {@code sectionName} is a non-null non-empty string no longer than the specified length"},{"lineNumber":377,"author":{"gitId":"-"},"content":" * {@code SECTION_NAME_MAX_LENGTH}, and also does not contain any invalid characters (| or %)."},{"lineNumber":378,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code sectionName} is not acceptable."},{"lineNumber":379,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code sectionName} is acceptable."},{"lineNumber":380,"author":{"gitId":"-"},"content":" */"},{"lineNumber":381,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForSectionName(String sectionName) {"},{"lineNumber":382,"author":{"gitId":"-"},"content":" return getValidityInfoForAllowedName(SECTION_NAME_FIELD_NAME, SECTION_NAME_MAX_LENGTH, sectionName);"},{"lineNumber":383,"author":{"gitId":"-"},"content":" }"},{"lineNumber":384,"author":{"gitId":"-"},"content":""},{"lineNumber":385,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":386,"author":{"gitId":"-"},"content":" * Checks if {@code teamName} is a non-null non-empty string no longer than the specified length"},{"lineNumber":387,"author":{"gitId":"-"},"content":" * {@code TEAM_NAME_MAX_LENGTH}, does not contain any invalid characters (| or %) and is not a valid email."},{"lineNumber":388,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code teamName} is not acceptable."},{"lineNumber":389,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code teamName} is acceptable."},{"lineNumber":390,"author":{"gitId":"-"},"content":" */"},{"lineNumber":391,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForTeamName(String teamName) {"},{"lineNumber":392,"author":{"gitId":"-"},"content":" boolean isValidEmail \u003d isValidEmailAddress(teamName);"},{"lineNumber":393,"author":{"gitId":"-"},"content":" if (isValidEmail) {"},{"lineNumber":394,"author":{"gitId":"-"},"content":" return TEAM_NAME_IS_VALID_EMAIL_ERROR_MESSAGE;"},{"lineNumber":395,"author":{"gitId":"-"},"content":" }"},{"lineNumber":396,"author":{"gitId":"-"},"content":" return getValidityInfoForAllowedName(TEAM_NAME_FIELD_NAME, TEAM_NAME_MAX_LENGTH, teamName);"},{"lineNumber":397,"author":{"gitId":"-"},"content":" }"},{"lineNumber":398,"author":{"gitId":"-"},"content":""},{"lineNumber":399,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":400,"author":{"gitId":"-"},"content":" * Checks if the given studentRoleComments is a non-null string no longer than"},{"lineNumber":401,"author":{"gitId":"-"},"content":" * the specified length {@code STUDENT_ROLE_COMMENTS_MAX_LENGTH}. However, this string can be empty."},{"lineNumber":402,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code studentRoleComments} is not acceptable."},{"lineNumber":403,"author":{"gitId":"-"},"content":" * Returns an empty string \"\" if the {@code studentRoleComments} is acceptable."},{"lineNumber":404,"author":{"gitId":"-"},"content":" */"},{"lineNumber":405,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForStudentRoleComments(String studentRoleComments) {"},{"lineNumber":406,"author":{"gitId":"-"},"content":" return getValidityInfoForSizeCappedPossiblyEmptyString(STUDENT_ROLE_COMMENTS_FIELD_NAME,"},{"lineNumber":407,"author":{"gitId":"-"},"content":" STUDENT_ROLE_COMMENTS_MAX_LENGTH,"},{"lineNumber":408,"author":{"gitId":"-"},"content":" studentRoleComments);"},{"lineNumber":409,"author":{"gitId":"-"},"content":" }"},{"lineNumber":410,"author":{"gitId":"-"},"content":""},{"lineNumber":411,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":412,"author":{"gitId":"-"},"content":" * Checks if {@code feedbackSessionName} is a non-null non-empty string no longer than the specified length"},{"lineNumber":413,"author":{"gitId":"-"},"content":" * {@code FEEDBACK_SESSION_NAME_MAX_LENGTH}, does not contain any invalid characters (| or %), and has no"},{"lineNumber":414,"author":{"gitId":"-"},"content":" * unsanitized HTML characters."},{"lineNumber":415,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code feedbackSessionName} is not acceptable."},{"lineNumber":416,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code feedbackSessionName} is acceptable."},{"lineNumber":417,"author":{"gitId":"-"},"content":" */"},{"lineNumber":418,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForFeedbackSessionName(String feedbackSessionName) {"},{"lineNumber":419,"author":{"gitId":"-"},"content":" String errorsFromAllowedNameValidation \u003d getValidityInfoForAllowedName("},{"lineNumber":420,"author":{"gitId":"-"},"content":" FEEDBACK_SESSION_NAME_FIELD_NAME, FEEDBACK_SESSION_NAME_MAX_LENGTH, feedbackSessionName);"},{"lineNumber":421,"author":{"gitId":"-"},"content":""},{"lineNumber":422,"author":{"gitId":"-"},"content":" // return early if error already exists because session name is too long etc."},{"lineNumber":423,"author":{"gitId":"-"},"content":" if (!errorsFromAllowedNameValidation.isEmpty()) {"},{"lineNumber":424,"author":{"gitId":"-"},"content":" return errorsFromAllowedNameValidation;"},{"lineNumber":425,"author":{"gitId":"-"},"content":" }"},{"lineNumber":426,"author":{"gitId":"-"},"content":""},{"lineNumber":427,"author":{"gitId":"-"},"content":" // checks for unsanitized HTML characters"},{"lineNumber":428,"author":{"gitId":"-"},"content":" return getValidityInfoForNonHtmlField(FEEDBACK_SESSION_NAME_FIELD_NAME, feedbackSessionName);"},{"lineNumber":429,"author":{"gitId":"-"},"content":" }"},{"lineNumber":430,"author":{"gitId":"-"},"content":""},{"lineNumber":431,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":432,"author":{"gitId":"-"},"content":" * Checks if {@code courseName} is a non-null non-empty string no longer than the specified length"},{"lineNumber":433,"author":{"gitId":"-"},"content":" * {@code COURSE_NAME_MAX_LENGTH}, and also does not contain any invalid characters (| or %)."},{"lineNumber":434,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code courseName} is not acceptable."},{"lineNumber":435,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code courseName} is acceptable."},{"lineNumber":436,"author":{"gitId":"-"},"content":" */"},{"lineNumber":437,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForCourseName(String courseName) {"},{"lineNumber":438,"author":{"gitId":"-"},"content":" return getValidityInfoForAllowedName(COURSE_NAME_FIELD_NAME, COURSE_NAME_MAX_LENGTH, courseName);"},{"lineNumber":439,"author":{"gitId":"-"},"content":" }"},{"lineNumber":440,"author":{"gitId":"-"},"content":""},{"lineNumber":441,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":442,"author":{"gitId":"-"},"content":" * Checks if {@code instituteName} is a non-null non-empty string no longer than the specified length"},{"lineNumber":443,"author":{"gitId":"-"},"content":" * {@code INSTITUTE_NAME_MAX_LENGTH}, and also does not contain any invalid characters (| or %)."},{"lineNumber":444,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code instituteName} is not acceptable."},{"lineNumber":445,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code instituteName} is acceptable."},{"lineNumber":446,"author":{"gitId":"-"},"content":" */"},{"lineNumber":447,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForInstituteName(String instituteName) {"},{"lineNumber":448,"author":{"gitId":"-"},"content":" return getValidityInfoForAllowedName(INSTITUTE_NAME_FIELD_NAME, INSTITUTE_NAME_MAX_LENGTH,"},{"lineNumber":449,"author":{"gitId":"-"},"content":" instituteName);"},{"lineNumber":450,"author":{"gitId":"-"},"content":" }"},{"lineNumber":451,"author":{"gitId":"-"},"content":""},{"lineNumber":452,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":453,"author":{"gitId":"-"},"content":" * Checks if {@code personName} is a non-null non-empty string no longer than the specified length"},{"lineNumber":454,"author":{"gitId":"-"},"content":" * {@code PERSON_NAME_MAX_LENGTH}, and also does not contain any invalid characters (| or %)."},{"lineNumber":455,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code personName} is not acceptable."},{"lineNumber":456,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code personName} is acceptable."},{"lineNumber":457,"author":{"gitId":"-"},"content":" */"},{"lineNumber":458,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForPersonName(String personName) {"},{"lineNumber":459,"author":{"gitId":"-"},"content":" return getValidityInfoForAllowedName(PERSON_NAME_FIELD_NAME, PERSON_NAME_MAX_LENGTH, personName);"},{"lineNumber":460,"author":{"gitId":"-"},"content":" }"},{"lineNumber":461,"author":{"gitId":"-"},"content":""},{"lineNumber":462,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":463,"author":{"gitId":"-"},"content":" * Checks if the given string is a non-null string contained in Java\u0027s list of"},{"lineNumber":464,"author":{"gitId":"-"},"content":" * regional time zone IDs."},{"lineNumber":465,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code timeZoneValue} is not acceptable."},{"lineNumber":466,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code timeZoneValue} is acceptable."},{"lineNumber":467,"author":{"gitId":"-"},"content":" */"},{"lineNumber":468,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForTimeZone(String timeZoneValue) {"},{"lineNumber":469,"author":{"gitId":"-"},"content":" assert timeZoneValue !\u003d null;"},{"lineNumber":470,"author":{"gitId":"-"},"content":" if (!ZoneId.getAvailableZoneIds().contains(timeZoneValue)) {"},{"lineNumber":471,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(TIME_ZONE_ERROR_MESSAGE,"},{"lineNumber":472,"author":{"gitId":"-"},"content":" timeZoneValue, TIME_ZONE_FIELD_NAME, REASON_UNAVAILABLE_AS_CHOICE);"},{"lineNumber":473,"author":{"gitId":"-"},"content":" }"},{"lineNumber":474,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":475,"author":{"gitId":"-"},"content":" }"},{"lineNumber":476,"author":{"gitId":"-"},"content":""},{"lineNumber":477,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":478,"author":{"gitId":"-"},"content":" * Checks if {@code role} is one of the recognized roles {@link #ROLE_ACCEPTED_VALUES}."},{"lineNumber":479,"author":{"gitId":"-"},"content":" *"},{"lineNumber":480,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code role} is not acceptable."},{"lineNumber":481,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code role} is acceptable."},{"lineNumber":482,"author":{"gitId":"-"},"content":" */"},{"lineNumber":483,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForRole(String role) {"},{"lineNumber":484,"author":{"gitId":"-"},"content":" assert role !\u003d null;"},{"lineNumber":485,"author":{"gitId":"-"},"content":""},{"lineNumber":486,"author":{"gitId":"-"},"content":" if (!ROLE_ACCEPTED_VALUES.contains(role)) {"},{"lineNumber":487,"author":{"gitId":"-"},"content":" return String.format(ROLE_ERROR_MESSAGE, role);"},{"lineNumber":488,"author":{"gitId":"-"},"content":" }"},{"lineNumber":489,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":490,"author":{"gitId":"-"},"content":" }"},{"lineNumber":491,"author":{"gitId":"-"},"content":""},{"lineNumber":492,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":493,"author":{"gitId":"-"},"content":" * Checks if the given name (including person name, institute name, course name, feedback session and team name)"},{"lineNumber":494,"author":{"gitId":"-"},"content":" * is a non-null non-empty string no longer than the specified length {@code maxLength},"},{"lineNumber":495,"author":{"gitId":"-"},"content":" * and also does not contain any invalid characters (| or %)."},{"lineNumber":496,"author":{"gitId":"-"},"content":" *"},{"lineNumber":497,"author":{"gitId":"-"},"content":" * @param fieldName"},{"lineNumber":498,"author":{"gitId":"-"},"content":" * A descriptive name of the field e.g., \"student name\", to be"},{"lineNumber":499,"author":{"gitId":"-"},"content":" * used in the return value to make the explanation more"},{"lineNumber":500,"author":{"gitId":"-"},"content":" * descriptive."},{"lineNumber":501,"author":{"gitId":"-"},"content":" * @param value"},{"lineNumber":502,"author":{"gitId":"-"},"content":" * The string to be checked."},{"lineNumber":503,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code value} is not acceptable."},{"lineNumber":504,"author":{"gitId":"-"},"content":" * Returns an empty string \"\" if the {@code value} is acceptable."},{"lineNumber":505,"author":{"gitId":"-"},"content":" */"},{"lineNumber":506,"author":{"gitId":"-"},"content":" static String getValidityInfoForAllowedName(String fieldName, int maxLength, String value) {"},{"lineNumber":507,"author":{"gitId":"-"},"content":""},{"lineNumber":508,"author":{"gitId":"-"},"content":" assert value !\u003d null : \"Non-null value expected for \" + fieldName;"},{"lineNumber":509,"author":{"gitId":"-"},"content":""},{"lineNumber":510,"author":{"gitId":"-"},"content":" if (value.isEmpty()) {"},{"lineNumber":511,"author":{"gitId":"-"},"content":" if (FEEDBACK_SESSION_NAME_FIELD_NAME.equals(fieldName)) {"},{"lineNumber":512,"author":{"gitId":"-"},"content":" return getPopulatedEmptyStringErrorMessage("},{"lineNumber":513,"author":{"gitId":"-"},"content":" SIZE_CAPPED_NON_EMPTY_STRING_ERROR_MESSAGE_EMPTY_STRING_FOR_SESSION_NAME,"},{"lineNumber":514,"author":{"gitId":"-"},"content":" fieldName, maxLength);"},{"lineNumber":515,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":516,"author":{"gitId":"-"},"content":" return getPopulatedEmptyStringErrorMessage(SIZE_CAPPED_NON_EMPTY_STRING_ERROR_MESSAGE_EMPTY_STRING,"},{"lineNumber":517,"author":{"gitId":"-"},"content":" fieldName, maxLength);"},{"lineNumber":518,"author":{"gitId":"-"},"content":" }"},{"lineNumber":519,"author":{"gitId":"-"},"content":" }"},{"lineNumber":520,"author":{"gitId":"-"},"content":" if (isUntrimmed(value)) {"},{"lineNumber":521,"author":{"gitId":"-"},"content":" return WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace(\"${fieldName}\", fieldName);"},{"lineNumber":522,"author":{"gitId":"-"},"content":" }"},{"lineNumber":523,"author":{"gitId":"-"},"content":" if (value.length() \u003e maxLength) {"},{"lineNumber":524,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(SIZE_CAPPED_NON_EMPTY_STRING_ERROR_MESSAGE, value,"},{"lineNumber":525,"author":{"gitId":"-"},"content":" fieldName, REASON_TOO_LONG, maxLength);"},{"lineNumber":526,"author":{"gitId":"-"},"content":" }"},{"lineNumber":527,"author":{"gitId":"-"},"content":" if (!Character.isLetterOrDigit(value.codePointAt(0))) {"},{"lineNumber":528,"author":{"gitId":"-"},"content":" boolean hasStartingBrace \u003d value.charAt(0) \u003d\u003d \u0027{\u0027 \u0026\u0026 value.contains(\"}\");"},{"lineNumber":529,"author":{"gitId":"-"},"content":" if (!hasStartingBrace) {"},{"lineNumber":530,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(INVALID_NAME_ERROR_MESSAGE, value,"},{"lineNumber":531,"author":{"gitId":"-"},"content":" fieldName, REASON_START_WITH_NON_ALPHANUMERIC_CHAR);"},{"lineNumber":532,"author":{"gitId":"-"},"content":" }"},{"lineNumber":533,"author":{"gitId":"-"},"content":" if (!StringHelper.isMatching(value.substring(1), REGEX_NAME)) {"},{"lineNumber":534,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(INVALID_NAME_ERROR_MESSAGE, value, fieldName,"},{"lineNumber":535,"author":{"gitId":"-"},"content":" REASON_CONTAINS_INVALID_CHAR);"},{"lineNumber":536,"author":{"gitId":"-"},"content":" }"},{"lineNumber":537,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":538,"author":{"gitId":"-"},"content":" }"},{"lineNumber":539,"author":{"gitId":"-"},"content":" if (!StringHelper.isMatching(value, REGEX_NAME)) {"},{"lineNumber":540,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(INVALID_NAME_ERROR_MESSAGE, value, fieldName,"},{"lineNumber":541,"author":{"gitId":"-"},"content":" REASON_CONTAINS_INVALID_CHAR);"},{"lineNumber":542,"author":{"gitId":"-"},"content":" }"},{"lineNumber":543,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":544,"author":{"gitId":"-"},"content":" }"},{"lineNumber":545,"author":{"gitId":"-"},"content":""},{"lineNumber":546,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":547,"author":{"gitId":"-"},"content":" * Checks if the notification title is a non-null non-empty string."},{"lineNumber":548,"author":{"gitId":"-"},"content":" *"},{"lineNumber":549,"author":{"gitId":"-"},"content":" * @param notificationTitle The title of the notification."},{"lineNumber":550,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code notificationTitle} is not acceptable."},{"lineNumber":551,"author":{"gitId":"-"},"content":" * Returns an empty string \"\" if the {@code notificationTitle} is acceptable."},{"lineNumber":552,"author":{"gitId":"-"},"content":" */"},{"lineNumber":553,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForNotificationTitle(String notificationTitle) {"},{"lineNumber":554,"author":{"gitId":"-"},"content":""},{"lineNumber":555,"author":{"gitId":"-"},"content":" assert notificationTitle !\u003d null : \"Non-null value expected for notification title\";"},{"lineNumber":556,"author":{"gitId":"-"},"content":""},{"lineNumber":557,"author":{"gitId":"-"},"content":" if (notificationTitle.isEmpty()) {"},{"lineNumber":558,"author":{"gitId":"-"},"content":" return getPopulatedEmptyStringErrorMessage(EMPTY_STRING_ERROR_INFO,"},{"lineNumber":559,"author":{"gitId":"-"},"content":" NOTIFICATION_TITLE_FIELD_NAME, NOTIFICATION_TITLE_MAX_LENGTH);"},{"lineNumber":560,"author":{"gitId":"-"},"content":" } else if (notificationTitle.length() \u003e NOTIFICATION_TITLE_MAX_LENGTH) {"},{"lineNumber":561,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(SIZE_CAPPED_NON_EMPTY_STRING_ERROR_MESSAGE, notificationTitle,"},{"lineNumber":562,"author":{"gitId":"-"},"content":" NOTIFICATION_TITLE_FIELD_NAME, REASON_TOO_LONG, NOTIFICATION_TITLE_MAX_LENGTH);"},{"lineNumber":563,"author":{"gitId":"-"},"content":" }"},{"lineNumber":564,"author":{"gitId":"-"},"content":""},{"lineNumber":565,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":566,"author":{"gitId":"-"},"content":" }"},{"lineNumber":567,"author":{"gitId":"-"},"content":""},{"lineNumber":568,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":569,"author":{"gitId":"-"},"content":" * Checks if the notification message is a non-null non-empty string."},{"lineNumber":570,"author":{"gitId":"-"},"content":" *"},{"lineNumber":571,"author":{"gitId":"-"},"content":" * @param notificationMessage The notification message."},{"lineNumber":572,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code notificationMessage} is not acceptable."},{"lineNumber":573,"author":{"gitId":"-"},"content":" * Returns an empty string \"\" if the {@code notificationMessage} is acceptable."},{"lineNumber":574,"author":{"gitId":"-"},"content":" */"},{"lineNumber":575,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForNotificationBody(String notificationMessage) {"},{"lineNumber":576,"author":{"gitId":"-"},"content":""},{"lineNumber":577,"author":{"gitId":"-"},"content":" assert notificationMessage !\u003d null : \"Non-null value expected for notification message\";"},{"lineNumber":578,"author":{"gitId":"-"},"content":""},{"lineNumber":579,"author":{"gitId":"-"},"content":" if (notificationMessage.isEmpty()) {"},{"lineNumber":580,"author":{"gitId":"-"},"content":" return getPopulatedEmptyStringErrorMessage(EMPTY_STRING_ERROR_INFO, NOTIFICATION_MESSAGE_FIELD_NAME, 0);"},{"lineNumber":581,"author":{"gitId":"-"},"content":" }"},{"lineNumber":582,"author":{"gitId":"-"},"content":""},{"lineNumber":583,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":584,"author":{"gitId":"-"},"content":" }"},{"lineNumber":585,"author":{"gitId":"-"},"content":""},{"lineNumber":586,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":587,"author":{"gitId":"-"},"content":" * Checks if {@code style} is one of the recognized notification style {@link #NOTIFICATION_STYLE_ACCEPTED_VALUES}."},{"lineNumber":588,"author":{"gitId":"-"},"content":" *"},{"lineNumber":589,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code style} is not acceptable."},{"lineNumber":590,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code style} is acceptable."},{"lineNumber":591,"author":{"gitId":"-"},"content":" */"},{"lineNumber":592,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForNotificationStyle(String style) {"},{"lineNumber":593,"author":{"gitId":"-"},"content":" assert style !\u003d null;"},{"lineNumber":594,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":595,"author":{"gitId":"-"},"content":" NotificationStyle.valueOf(style);"},{"lineNumber":596,"author":{"gitId":"-"},"content":" } catch (IllegalArgumentException e) {"},{"lineNumber":597,"author":{"gitId":"-"},"content":" return String.format(NOTIFICATION_STYLE_ERROR_MESSAGE, style);"},{"lineNumber":598,"author":{"gitId":"-"},"content":" }"},{"lineNumber":599,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":600,"author":{"gitId":"-"},"content":" }"},{"lineNumber":601,"author":{"gitId":"-"},"content":""},{"lineNumber":602,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":603,"author":{"gitId":"-"},"content":" * Checks if {@code targetUser} is one of the"},{"lineNumber":604,"author":{"gitId":"-"},"content":" * recognized notification target user groups {@link #NOTIFICATION_TARGET_USER_ACCEPTED_VALUES}."},{"lineNumber":605,"author":{"gitId":"-"},"content":" *"},{"lineNumber":606,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code targetUser} is not acceptable."},{"lineNumber":607,"author":{"gitId":"-"},"content":" * Returns an empty string if the {@code targetUser} is acceptable."},{"lineNumber":608,"author":{"gitId":"-"},"content":" */"},{"lineNumber":609,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForNotificationTargetUser(String targetUser) {"},{"lineNumber":610,"author":{"gitId":"-"},"content":" assert targetUser !\u003d null;"},{"lineNumber":611,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":612,"author":{"gitId":"-"},"content":" NotificationTargetUser.valueOf(targetUser);"},{"lineNumber":613,"author":{"gitId":"-"},"content":" } catch (IllegalArgumentException e) {"},{"lineNumber":614,"author":{"gitId":"-"},"content":" return String.format(NOTIFICATION_TARGET_USER_ERROR_MESSAGE, targetUser);"},{"lineNumber":615,"author":{"gitId":"-"},"content":" }"},{"lineNumber":616,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":617,"author":{"gitId":"-"},"content":" }"},{"lineNumber":618,"author":{"gitId":"-"},"content":""},{"lineNumber":619,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":620,"author":{"gitId":"-"},"content":" * Checks if the given string is a non-null string no longer than"},{"lineNumber":621,"author":{"gitId":"-"},"content":" * the specified length {@code maxLength}. However, this string can be empty."},{"lineNumber":622,"author":{"gitId":"-"},"content":" *"},{"lineNumber":623,"author":{"gitId":"-"},"content":" * @param fieldName"},{"lineNumber":624,"author":{"gitId":"-"},"content":" * A descriptive name of the field e.g., \"student name\", to be"},{"lineNumber":625,"author":{"gitId":"-"},"content":" * used in the return value to make the explanation more"},{"lineNumber":626,"author":{"gitId":"-"},"content":" * descriptive."},{"lineNumber":627,"author":{"gitId":"-"},"content":" * @param value"},{"lineNumber":628,"author":{"gitId":"-"},"content":" * The string to be checked."},{"lineNumber":629,"author":{"gitId":"-"},"content":" * @return An explanation of why the {@code value} is not acceptable."},{"lineNumber":630,"author":{"gitId":"-"},"content":" * Returns an empty string \"\" if the {@code value} is acceptable."},{"lineNumber":631,"author":{"gitId":"-"},"content":" */"},{"lineNumber":632,"author":{"gitId":"-"},"content":" static String getValidityInfoForSizeCappedPossiblyEmptyString(String fieldName, int maxLength, String value) {"},{"lineNumber":633,"author":{"gitId":"-"},"content":" assert value !\u003d null : \"Non-null value expected for \" + fieldName;"},{"lineNumber":634,"author":{"gitId":"-"},"content":""},{"lineNumber":635,"author":{"gitId":"-"},"content":" if (isUntrimmed(value)) {"},{"lineNumber":636,"author":{"gitId":"-"},"content":" return WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace(\"${fieldName}\", fieldName);"},{"lineNumber":637,"author":{"gitId":"-"},"content":" }"},{"lineNumber":638,"author":{"gitId":"-"},"content":" if (value.length() \u003e maxLength) {"},{"lineNumber":639,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(SIZE_CAPPED_POSSIBLY_EMPTY_STRING_ERROR_MESSAGE, value,"},{"lineNumber":640,"author":{"gitId":"-"},"content":" fieldName, REASON_TOO_LONG, maxLength);"},{"lineNumber":641,"author":{"gitId":"-"},"content":" }"},{"lineNumber":642,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":643,"author":{"gitId":"-"},"content":" }"},{"lineNumber":644,"author":{"gitId":"-"},"content":""},{"lineNumber":645,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":646,"author":{"gitId":"-"},"content":" * Checks if the {@code startTime} is valid to be used as a session start time."},{"lineNumber":647,"author":{"gitId":"-"},"content":" * Returns an empty string if it is valid, or an error message otherwise."},{"lineNumber":648,"author":{"gitId":"-"},"content":" *"},{"lineNumber":649,"author":{"gitId":"-"},"content":" * \u003cp\u003eThe {@code startTime} is valid if it is after 2 hours before now, before 12 months from now"},{"lineNumber":650,"author":{"gitId":"-"},"content":" * and at exact hour mark."},{"lineNumber":651,"author":{"gitId":"-"},"content":" */"},{"lineNumber":652,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForNewStartTime(Instant startTime, String timeZone) {"},{"lineNumber":653,"author":{"gitId":"-"},"content":" Instant twoHoursBeforeNow \u003d TimeHelper.getInstantHoursOffsetFromNow(-2);"},{"lineNumber":654,"author":{"gitId":"-"},"content":" String earlierThanThreeHoursBeforeNowError \u003d getInvalidityInfoForFirstTimeComparedToSecondTime("},{"lineNumber":655,"author":{"gitId":"-"},"content":" twoHoursBeforeNow, startTime, SESSION_NAME,"},{"lineNumber":656,"author":{"gitId":"-"},"content":" \"2 hours before now\", SESSION_START_TIME_FIELD_NAME,"},{"lineNumber":657,"author":{"gitId":"-"},"content":" (firstTime, secondTime) -\u003e firstTime.isBefore(secondTime) || firstTime.equals(secondTime),"},{"lineNumber":658,"author":{"gitId":"-"},"content":" \"The %s for this %s cannot be earlier than %s.\");"},{"lineNumber":659,"author":{"gitId":"-"},"content":""},{"lineNumber":660,"author":{"gitId":"-"},"content":" if (!earlierThanThreeHoursBeforeNowError.isEmpty()) {"},{"lineNumber":661,"author":{"gitId":"-"},"content":" return earlierThanThreeHoursBeforeNowError;"},{"lineNumber":662,"author":{"gitId":"-"},"content":" }"},{"lineNumber":663,"author":{"gitId":"-"},"content":""},{"lineNumber":664,"author":{"gitId":"-"},"content":" Instant twelveMonthsFromNow \u003d TimeHelper.getInstantMonthsOffsetFromNow(12, timeZone);"},{"lineNumber":665,"author":{"gitId":"-"},"content":" String laterThanTwelveMonthsFromNowError \u003d getInvalidityInfoForFirstTimeComparedToSecondTime("},{"lineNumber":666,"author":{"gitId":"-"},"content":" twelveMonthsFromNow, startTime, SESSION_NAME,"},{"lineNumber":667,"author":{"gitId":"-"},"content":" \"12 months from now\", SESSION_START_TIME_FIELD_NAME,"},{"lineNumber":668,"author":{"gitId":"-"},"content":" (firstTime, secondTime) -\u003e firstTime.isAfter(secondTime) || firstTime.equals(secondTime),"},{"lineNumber":669,"author":{"gitId":"-"},"content":" \"The %s for this %s cannot be later than %s.\");"},{"lineNumber":670,"author":{"gitId":"-"},"content":""},{"lineNumber":671,"author":{"gitId":"-"},"content":" if (!laterThanTwelveMonthsFromNowError.isEmpty()) {"},{"lineNumber":672,"author":{"gitId":"-"},"content":" return laterThanTwelveMonthsFromNowError;"},{"lineNumber":673,"author":{"gitId":"-"},"content":" }"},{"lineNumber":674,"author":{"gitId":"-"},"content":""},{"lineNumber":675,"author":{"gitId":"-"},"content":" String notExactHourError \u003d getInvalidityInfoForExactHourTime(startTime, timeZone, \"start time\");"},{"lineNumber":676,"author":{"gitId":"-"},"content":" if (!notExactHourError.isEmpty()) {"},{"lineNumber":677,"author":{"gitId":"-"},"content":" return notExactHourError;"},{"lineNumber":678,"author":{"gitId":"-"},"content":" }"},{"lineNumber":679,"author":{"gitId":"-"},"content":""},{"lineNumber":680,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":681,"author":{"gitId":"-"},"content":" }"},{"lineNumber":682,"author":{"gitId":"-"},"content":""},{"lineNumber":683,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":684,"author":{"gitId":"-"},"content":" * Checks if the {@code endTime} is valid to be used as a session end time."},{"lineNumber":685,"author":{"gitId":"-"},"content":" * Returns an empty string if it is valid, or an error message otherwise."},{"lineNumber":686,"author":{"gitId":"-"},"content":" *"},{"lineNumber":687,"author":{"gitId":"-"},"content":" * \u003cp\u003eThe {@code endTime} is valid if it is after 1 hour before now, before 12 months from now"},{"lineNumber":688,"author":{"gitId":"-"},"content":" * and at exact hour mark."},{"lineNumber":689,"author":{"gitId":"-"},"content":" */"},{"lineNumber":690,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForNewEndTime(Instant endTime, String timeZone) {"},{"lineNumber":691,"author":{"gitId":"-"},"content":" Instant oneHourBeforeNow \u003d TimeHelper.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":692,"author":{"gitId":"-"},"content":" String earlierThanThreeHoursBeforeNowError \u003d getInvalidityInfoForFirstTimeComparedToSecondTime("},{"lineNumber":693,"author":{"gitId":"-"},"content":" oneHourBeforeNow, endTime, SESSION_NAME,"},{"lineNumber":694,"author":{"gitId":"-"},"content":" \"1 hour before now\", SESSION_END_TIME_FIELD_NAME,"},{"lineNumber":695,"author":{"gitId":"-"},"content":" (firstTime, secondTime) -\u003e firstTime.isBefore(secondTime) || firstTime.equals(secondTime),"},{"lineNumber":696,"author":{"gitId":"-"},"content":" \"The %s for this %s cannot be earlier than %s.\");"},{"lineNumber":697,"author":{"gitId":"-"},"content":" if (!earlierThanThreeHoursBeforeNowError.isEmpty()) {"},{"lineNumber":698,"author":{"gitId":"-"},"content":" return earlierThanThreeHoursBeforeNowError;"},{"lineNumber":699,"author":{"gitId":"-"},"content":" }"},{"lineNumber":700,"author":{"gitId":"-"},"content":""},{"lineNumber":701,"author":{"gitId":"-"},"content":" Instant twelveMonthsFromNow \u003d TimeHelper.getInstantMonthsOffsetFromNow(12, timeZone);"},{"lineNumber":702,"author":{"gitId":"-"},"content":" String laterThanTwelveMonthsError \u003d getInvalidityInfoForFirstTimeComparedToSecondTime("},{"lineNumber":703,"author":{"gitId":"-"},"content":" twelveMonthsFromNow, endTime, SESSION_NAME,"},{"lineNumber":704,"author":{"gitId":"-"},"content":" \"12 months from now\", SESSION_END_TIME_FIELD_NAME,"},{"lineNumber":705,"author":{"gitId":"-"},"content":" (firstTime, secondTime) -\u003e firstTime.isAfter(secondTime) || firstTime.equals(secondTime),"},{"lineNumber":706,"author":{"gitId":"-"},"content":" \"The %s for this %s cannot be later than %s.\");"},{"lineNumber":707,"author":{"gitId":"-"},"content":" if (!laterThanTwelveMonthsError.isEmpty()) {"},{"lineNumber":708,"author":{"gitId":"-"},"content":" return laterThanTwelveMonthsError;"},{"lineNumber":709,"author":{"gitId":"-"},"content":" }"},{"lineNumber":710,"author":{"gitId":"-"},"content":""},{"lineNumber":711,"author":{"gitId":"-"},"content":" String notExactHourError \u003d getInvalidityInfoForExactHourTime(endTime, timeZone, \"end time\");"},{"lineNumber":712,"author":{"gitId":"-"},"content":" if (!notExactHourError.isEmpty()) {"},{"lineNumber":713,"author":{"gitId":"-"},"content":" return notExactHourError;"},{"lineNumber":714,"author":{"gitId":"-"},"content":" }"},{"lineNumber":715,"author":{"gitId":"-"},"content":""},{"lineNumber":716,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":717,"author":{"gitId":"-"},"content":" }"},{"lineNumber":718,"author":{"gitId":"-"},"content":""},{"lineNumber":719,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":720,"author":{"gitId":"-"},"content":" * Checks if Session Start Time is before Session End Time."},{"lineNumber":721,"author":{"gitId":"-"},"content":" * @return Error string if {@code sessionStart} is before {@code sessionEnd}"},{"lineNumber":722,"author":{"gitId":"-"},"content":" * Empty string if {@code sessionStart} is after {@code sessionEnd}"},{"lineNumber":723,"author":{"gitId":"-"},"content":" */"},{"lineNumber":724,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForTimeForSessionStartAndEnd(Instant sessionStart, Instant sessionEnd) {"},{"lineNumber":725,"author":{"gitId":"-"},"content":" return getInvalidityInfoForFirstTimeIsBeforeSecondTime("},{"lineNumber":726,"author":{"gitId":"-"},"content":" sessionStart, sessionEnd, SESSION_NAME, SESSION_START_TIME_FIELD_NAME, SESSION_END_TIME_FIELD_NAME);"},{"lineNumber":727,"author":{"gitId":"-"},"content":" }"},{"lineNumber":728,"author":{"gitId":"-"},"content":""},{"lineNumber":729,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":730,"author":{"gitId":"-"},"content":" * Checks if Session Visibility Start Time is before Session Start Time."},{"lineNumber":731,"author":{"gitId":"-"},"content":" * @return Error string if {@code visibilityStart} is before {@code sessionStart}"},{"lineNumber":732,"author":{"gitId":"-"},"content":" * Empty string if {@code visibilityStart} is after {@code sessionStart}"},{"lineNumber":733,"author":{"gitId":"-"},"content":" */"},{"lineNumber":734,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForTimeForVisibilityStartAndSessionStart("},{"lineNumber":735,"author":{"gitId":"-"},"content":" Instant visibilityStart, Instant sessionStart) {"},{"lineNumber":736,"author":{"gitId":"-"},"content":" return getInvalidityInfoForFirstTimeIsBeforeSecondTime(visibilityStart, sessionStart,"},{"lineNumber":737,"author":{"gitId":"-"},"content":" SESSION_NAME, SESSION_VISIBLE_TIME_FIELD_NAME, SESSION_START_TIME_FIELD_NAME);"},{"lineNumber":738,"author":{"gitId":"-"},"content":" }"},{"lineNumber":739,"author":{"gitId":"-"},"content":""},{"lineNumber":740,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":741,"author":{"gitId":"-"},"content":" * Checks if the {@code visibilityStart} is valid to be used as a session visible start time."},{"lineNumber":742,"author":{"gitId":"-"},"content":" * Returns an empty string if it is valid, or an error message otherwise."},{"lineNumber":743,"author":{"gitId":"-"},"content":" *"},{"lineNumber":744,"author":{"gitId":"-"},"content":" * \u003cp\u003eThe {@code visibilityStart} is valid if it is less than 30 days before {@code sessionStart}."},{"lineNumber":745,"author":{"gitId":"-"},"content":" */"},{"lineNumber":746,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForTimeForNewVisibilityStart(Instant visibilityStart, Instant sessionStart) {"},{"lineNumber":747,"author":{"gitId":"-"},"content":" Instant visibilityStartThirtyDaysBeforeSessionStart \u003d sessionStart.minus(Duration.ofDays(30));"},{"lineNumber":748,"author":{"gitId":"-"},"content":" String visibilityStartMoreThanThirtyDaysBeforeSessionStartError \u003d"},{"lineNumber":749,"author":{"gitId":"-"},"content":" getInvalidityInfoForFirstTimeComparedToSecondTime("},{"lineNumber":750,"author":{"gitId":"-"},"content":" visibilityStartThirtyDaysBeforeSessionStart, visibilityStart, SESSION_NAME,"},{"lineNumber":751,"author":{"gitId":"-"},"content":" \"30 days before start time\", SESSION_VISIBLE_TIME_FIELD_NAME,"},{"lineNumber":752,"author":{"gitId":"-"},"content":" (firstTime, secondTime) -\u003e firstTime.isBefore(secondTime) || firstTime.equals(secondTime),"},{"lineNumber":753,"author":{"gitId":"-"},"content":" \"The %s for this %s cannot be earlier than %s.\");"},{"lineNumber":754,"author":{"gitId":"-"},"content":" if (!visibilityStartMoreThanThirtyDaysBeforeSessionStartError.isEmpty()) {"},{"lineNumber":755,"author":{"gitId":"-"},"content":" return visibilityStartMoreThanThirtyDaysBeforeSessionStartError;"},{"lineNumber":756,"author":{"gitId":"-"},"content":" }"},{"lineNumber":757,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":758,"author":{"gitId":"-"},"content":" }"},{"lineNumber":759,"author":{"gitId":"-"},"content":""},{"lineNumber":760,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":761,"author":{"gitId":"-"},"content":" * Checks if Visibility Start Time is before Results Publish Time."},{"lineNumber":762,"author":{"gitId":"-"},"content":" * @return Error string if {@code visibilityStart} is before {@code resultsPublish}"},{"lineNumber":763,"author":{"gitId":"-"},"content":" * Empty string if {@code visibilityStart} is after {@code resultsPublish}"},{"lineNumber":764,"author":{"gitId":"-"},"content":" */"},{"lineNumber":765,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForTimeForVisibilityStartAndResultsPublish("},{"lineNumber":766,"author":{"gitId":"-"},"content":" Instant visibilityStart, Instant resultsPublish) {"},{"lineNumber":767,"author":{"gitId":"-"},"content":" return getInvalidityInfoForFirstTimeIsBeforeSecondTime(visibilityStart, resultsPublish,"},{"lineNumber":768,"author":{"gitId":"-"},"content":" SESSION_NAME, SESSION_VISIBLE_TIME_FIELD_NAME, RESULTS_VISIBLE_TIME_FIELD_NAME);"},{"lineNumber":769,"author":{"gitId":"-"},"content":" }"},{"lineNumber":770,"author":{"gitId":"-"},"content":""},{"lineNumber":771,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":772,"author":{"gitId":"-"},"content":" * Checks if the session end time is before all extended deadlines."},{"lineNumber":773,"author":{"gitId":"-"},"content":" * @return Error string if any deadline in {@code deadlines} is before {@code sessionEnd}, an empty one otherwise."},{"lineNumber":774,"author":{"gitId":"-"},"content":" */"},{"lineNumber":775,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForTimeForSessionEndAndExtendedDeadlines("},{"lineNumber":776,"author":{"gitId":"-"},"content":" Instant sessionEnd, Map\u003cString, Instant\u003e deadlines) {"},{"lineNumber":777,"author":{"gitId":"-"},"content":" return deadlines.entrySet()"},{"lineNumber":778,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":779,"author":{"gitId":"-"},"content":" .map(entry -\u003e getInvalidityInfoForFirstTimeIsStrictlyBeforeSecondTime(sessionEnd, entry.getValue(),"},{"lineNumber":780,"author":{"gitId":"-"},"content":" SESSION_NAME, SESSION_END_TIME_FIELD_NAME, EXTENDED_DEADLINES_FIELD_NAME))"},{"lineNumber":781,"author":{"gitId":"-"},"content":" .filter(invalidityInfo -\u003e !invalidityInfo.isEmpty())"},{"lineNumber":782,"author":{"gitId":"-"},"content":" .findFirst()"},{"lineNumber":783,"author":{"gitId":"-"},"content":" .orElse(\"\");"},{"lineNumber":784,"author":{"gitId":"-"},"content":" }"},{"lineNumber":785,"author":{"gitId":"-"},"content":""},{"lineNumber":786,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":787,"author":{"gitId":"-"},"content":" * Checks if the session end time is before all extended deadlines."},{"lineNumber":788,"author":{"gitId":"-"},"content":" * @return Error string if any deadline in {@code deadlines} is before {@code sessionEnd}, an empty one otherwise."},{"lineNumber":789,"author":{"gitId":"-"},"content":" */"},{"lineNumber":790,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForTimeForSessionEndAndExtendedDeadlines("},{"lineNumber":791,"author":{"gitId":"-"},"content":" Instant sessionEnd, List\u003cDeadlineExtension\u003e deadlineExtensions) {"},{"lineNumber":792,"author":{"gitId":"-"},"content":" for (DeadlineExtension de : deadlineExtensions) {"},{"lineNumber":793,"author":{"gitId":"-"},"content":" String err \u003d getInvalidityInfoForFirstTimeIsStrictlyBeforeSecondTime(sessionEnd, de.getEndTime(),"},{"lineNumber":794,"author":{"gitId":"-"},"content":" SESSION_NAME, SESSION_END_TIME_FIELD_NAME, EXTENDED_DEADLINES_FIELD_NAME);"},{"lineNumber":795,"author":{"gitId":"-"},"content":""},{"lineNumber":796,"author":{"gitId":"-"},"content":" if (!err.isEmpty()) {"},{"lineNumber":797,"author":{"gitId":"-"},"content":" return err;"},{"lineNumber":798,"author":{"gitId":"-"},"content":" }"},{"lineNumber":799,"author":{"gitId":"-"},"content":" }"},{"lineNumber":800,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":801,"author":{"gitId":"-"},"content":" }"},{"lineNumber":802,"author":{"gitId":"-"},"content":""},{"lineNumber":803,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":804,"author":{"gitId":"-"},"content":" * Checks if Notification Start Time is before Notification End Time."},{"lineNumber":805,"author":{"gitId":"-"},"content":" * @return Error string if {@code notificationStart} is before {@code notificationEnd}"},{"lineNumber":806,"author":{"gitId":"-"},"content":" * Empty string if {@code notificationStart} is after {@code notificationEnd}"},{"lineNumber":807,"author":{"gitId":"-"},"content":" */"},{"lineNumber":808,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForTimeForNotificationStartAndEnd("},{"lineNumber":809,"author":{"gitId":"-"},"content":" Instant notificationStart, Instant notificationExpiry) {"},{"lineNumber":810,"author":{"gitId":"-"},"content":" return getInvalidityInfoForFirstTimeIsBeforeSecondTime(notificationStart, notificationExpiry,"},{"lineNumber":811,"author":{"gitId":"-"},"content":" NOTIFICATION_NAME, NOTIFICATION_VISIBLE_TIME_FIELD_NAME, NOTIFICATION_EXPIRY_TIME_FIELD_NAME);"},{"lineNumber":812,"author":{"gitId":"-"},"content":" }"},{"lineNumber":813,"author":{"gitId":"-"},"content":""},{"lineNumber":814,"author":{"gitId":"-"},"content":" private static String getInvalidityInfoForFirstTimeIsBeforeSecondTime(Instant earlierTime, Instant laterTime,"},{"lineNumber":815,"author":{"gitId":"-"},"content":" String entityName, String earlierTimeFieldName, String laterTimeFieldName) {"},{"lineNumber":816,"author":{"gitId":"-"},"content":" return getInvalidityInfoForFirstTimeComparedToSecondTime(earlierTime, laterTime, entityName,"},{"lineNumber":817,"author":{"gitId":"-"},"content":" earlierTimeFieldName, laterTimeFieldName,"},{"lineNumber":818,"author":{"gitId":"-"},"content":" (firstTime, secondTime) -\u003e firstTime.isBefore(secondTime) || firstTime.equals(secondTime),"},{"lineNumber":819,"author":{"gitId":"-"},"content":" TIME_BEFORE_ERROR_MESSAGE);"},{"lineNumber":820,"author":{"gitId":"-"},"content":" }"},{"lineNumber":821,"author":{"gitId":"-"},"content":""},{"lineNumber":822,"author":{"gitId":"-"},"content":" private static String getInvalidityInfoForFirstTimeIsStrictlyBeforeSecondTime("},{"lineNumber":823,"author":{"gitId":"-"},"content":" Instant earlierTime, Instant laterTime, String entityName, String earlierTimeFieldName,"},{"lineNumber":824,"author":{"gitId":"-"},"content":" String laterTimeFieldName) {"},{"lineNumber":825,"author":{"gitId":"-"},"content":" return getInvalidityInfoForFirstTimeComparedToSecondTime(earlierTime, laterTime, entityName,"},{"lineNumber":826,"author":{"gitId":"-"},"content":" earlierTimeFieldName, laterTimeFieldName, Instant::isBefore,"},{"lineNumber":827,"author":{"gitId":"-"},"content":" TIME_BEFORE_OR_EQUAL_ERROR_MESSAGE);"},{"lineNumber":828,"author":{"gitId":"-"},"content":" }"},{"lineNumber":829,"author":{"gitId":"-"},"content":""},{"lineNumber":830,"author":{"gitId":"-"},"content":" private static String getInvalidityInfoForFirstTimeComparedToSecondTime(Instant earlierTime, Instant laterTime,"},{"lineNumber":831,"author":{"gitId":"-"},"content":" String entityName, String earlierTimeFieldName, String laterTimeFieldName,"},{"lineNumber":832,"author":{"gitId":"-"},"content":" BiPredicate\u003cInstant, Instant\u003e validityChecker,"},{"lineNumber":833,"author":{"gitId":"-"},"content":" String invalidityInfoTemplate) {"},{"lineNumber":834,"author":{"gitId":"-"},"content":""},{"lineNumber":835,"author":{"gitId":"-"},"content":" assert earlierTime !\u003d null;"},{"lineNumber":836,"author":{"gitId":"-"},"content":" assert laterTime !\u003d null;"},{"lineNumber":837,"author":{"gitId":"-"},"content":""},{"lineNumber":838,"author":{"gitId":"-"},"content":" if (TimeHelper.isSpecialTime(earlierTime) || TimeHelper.isSpecialTime(laterTime)) {"},{"lineNumber":839,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":840,"author":{"gitId":"-"},"content":" }"},{"lineNumber":841,"author":{"gitId":"-"},"content":""},{"lineNumber":842,"author":{"gitId":"-"},"content":" if (!validityChecker.test(earlierTime, laterTime)) {"},{"lineNumber":843,"author":{"gitId":"-"},"content":" return String.format(invalidityInfoTemplate, laterTimeFieldName, entityName, earlierTimeFieldName);"},{"lineNumber":844,"author":{"gitId":"-"},"content":" }"},{"lineNumber":845,"author":{"gitId":"-"},"content":""},{"lineNumber":846,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":847,"author":{"gitId":"-"},"content":" }"},{"lineNumber":848,"author":{"gitId":"-"},"content":""},{"lineNumber":849,"author":{"gitId":"-"},"content":" private static String getInvalidityInfoForExactHourTime(Instant time, String timeZone, String timeName) {"},{"lineNumber":850,"author":{"gitId":"-"},"content":" // Timezone offsets are usually a whole number of hours, but a few zones are offset by"},{"lineNumber":851,"author":{"gitId":"-"},"content":" // an additional 30 or 45 minutes, such as in India, South Australia and Nepal."},{"lineNumber":852,"author":{"gitId":"-"},"content":" boolean isExactHour \u003d LocalDateTime.ofInstant(time, ZoneId.of(timeZone)).getMinute() \u003d\u003d 0;"},{"lineNumber":853,"author":{"gitId":"-"},"content":" if (!isExactHour) {"},{"lineNumber":854,"author":{"gitId":"-"},"content":" return String.format(NOT_EXACT_HOUR_ERROR_MESSAGE, timeName);"},{"lineNumber":855,"author":{"gitId":"-"},"content":" }"},{"lineNumber":856,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":857,"author":{"gitId":"-"},"content":" }"},{"lineNumber":858,"author":{"gitId":"-"},"content":""},{"lineNumber":859,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":860,"author":{"gitId":"-"},"content":" * Checks if both the giver type and recipient type for the feedback question is valid."},{"lineNumber":861,"author":{"gitId":"-"},"content":" *"},{"lineNumber":862,"author":{"gitId":"-"},"content":" * @param giverType feedback question giver type to be checked."},{"lineNumber":863,"author":{"gitId":"-"},"content":" * @param recipientType feedback question recipient type to be checked."},{"lineNumber":864,"author":{"gitId":"-"},"content":" * @return Error string if either type is invalid, otherwise empty string."},{"lineNumber":865,"author":{"gitId":"-"},"content":" */"},{"lineNumber":866,"author":{"gitId":"-"},"content":" public static List\u003cString\u003e getValidityInfoForFeedbackParticipantType("},{"lineNumber":867,"author":{"gitId":"-"},"content":" FeedbackParticipantType giverType, FeedbackParticipantType recipientType) {"},{"lineNumber":868,"author":{"gitId":"-"},"content":""},{"lineNumber":869,"author":{"gitId":"-"},"content":" assert giverType !\u003d null;"},{"lineNumber":870,"author":{"gitId":"-"},"content":" assert recipientType !\u003d null;"},{"lineNumber":871,"author":{"gitId":"-"},"content":""},{"lineNumber":872,"author":{"gitId":"-"},"content":" List\u003cString\u003e errors \u003d new LinkedList\u003c\u003e();"},{"lineNumber":873,"author":{"gitId":"-"},"content":" if (!giverType.isValidGiver()) {"},{"lineNumber":874,"author":{"gitId":"-"},"content":" errors.add(String.format(PARTICIPANT_TYPE_ERROR_MESSAGE, giverType.toString(), GIVER_TYPE_NAME));"},{"lineNumber":875,"author":{"gitId":"-"},"content":" }"},{"lineNumber":876,"author":{"gitId":"-"},"content":" if (!recipientType.isValidRecipient()) {"},{"lineNumber":877,"author":{"gitId":"-"},"content":" errors.add(String.format(PARTICIPANT_TYPE_ERROR_MESSAGE, recipientType.toString(), RECIPIENT_TYPE_NAME));"},{"lineNumber":878,"author":{"gitId":"-"},"content":" }"},{"lineNumber":879,"author":{"gitId":"-"},"content":" if (giverType \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":880,"author":{"gitId":"-"},"content":" \u0026\u0026 (recipientType \u003d\u003d FeedbackParticipantType.OWN_TEAM"},{"lineNumber":881,"author":{"gitId":"-"},"content":" || recipientType \u003d\u003d FeedbackParticipantType.OWN_TEAM_MEMBERS)) {"},{"lineNumber":882,"author":{"gitId":"-"},"content":" String displayRecipientName \u003d recipientType \u003d\u003d FeedbackParticipantType.OWN_TEAM"},{"lineNumber":883,"author":{"gitId":"-"},"content":" ? \"Giver\u0027s team\" : \"Giver\u0027s team members\";"},{"lineNumber":884,"author":{"gitId":"-"},"content":" errors.add(String.format(PARTICIPANT_TYPE_TEAM_ERROR_MESSAGE,"},{"lineNumber":885,"author":{"gitId":"-"},"content":" displayRecipientName,"},{"lineNumber":886,"author":{"gitId":"-"},"content":" \"Teams in this course\"));"},{"lineNumber":887,"author":{"gitId":"-"},"content":" }"},{"lineNumber":888,"author":{"gitId":"-"},"content":""},{"lineNumber":889,"author":{"gitId":"-"},"content":" return errors;"},{"lineNumber":890,"author":{"gitId":"-"},"content":" }"},{"lineNumber":891,"author":{"gitId":"-"},"content":""},{"lineNumber":892,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":893,"author":{"gitId":"-"},"content":" * Checks if comment giver type is either instructor, student or team."},{"lineNumber":894,"author":{"gitId":"-"},"content":" *"},{"lineNumber":895,"author":{"gitId":"-"},"content":" * @param commentGiverType comment giver type to be checked."},{"lineNumber":896,"author":{"gitId":"-"},"content":" * @return Error string if type is invalid, otherwise empty string."},{"lineNumber":897,"author":{"gitId":"-"},"content":" */"},{"lineNumber":898,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForCommentGiverType(FeedbackParticipantType commentGiverType) {"},{"lineNumber":899,"author":{"gitId":"-"},"content":" assert commentGiverType !\u003d null;"},{"lineNumber":900,"author":{"gitId":"-"},"content":" if (!commentGiverType.equals(FeedbackParticipantType.STUDENTS)"},{"lineNumber":901,"author":{"gitId":"-"},"content":" \u0026\u0026 !commentGiverType.equals(FeedbackParticipantType.INSTRUCTORS)"},{"lineNumber":902,"author":{"gitId":"-"},"content":" \u0026\u0026 !commentGiverType.equals(FeedbackParticipantType.TEAMS)) {"},{"lineNumber":903,"author":{"gitId":"-"},"content":" return \"Invalid comment giver type: \" + commentGiverType;"},{"lineNumber":904,"author":{"gitId":"-"},"content":" }"},{"lineNumber":905,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":906,"author":{"gitId":"-"},"content":" }"},{"lineNumber":907,"author":{"gitId":"-"},"content":""},{"lineNumber":908,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":909,"author":{"gitId":"-"},"content":" * Checks if visibility of comment is following question when comment is from a feedback participant."},{"lineNumber":910,"author":{"gitId":"-"},"content":" *"},{"lineNumber":911,"author":{"gitId":"-"},"content":" * @param isCommentFromFeedbackParticipant true if comment is from feedback participant."},{"lineNumber":912,"author":{"gitId":"-"},"content":" * @param isVisibilityFollowingFeedbackQuestion true if visibility of comment follows question."},{"lineNumber":913,"author":{"gitId":"-"},"content":" * @return Error string if condition is not met, otherwise empty string."},{"lineNumber":914,"author":{"gitId":"-"},"content":" */"},{"lineNumber":915,"author":{"gitId":"-"},"content":" public static String getInvalidityInfoForVisibilityOfFeedbackParticipantComments("},{"lineNumber":916,"author":{"gitId":"-"},"content":" boolean isCommentFromFeedbackParticipant,"},{"lineNumber":917,"author":{"gitId":"-"},"content":" boolean isVisibilityFollowingFeedbackQuestion) {"},{"lineNumber":918,"author":{"gitId":"-"},"content":" if (isCommentFromFeedbackParticipant \u0026\u0026 !isVisibilityFollowingFeedbackQuestion) {"},{"lineNumber":919,"author":{"gitId":"-"},"content":" return \"Comment by feedback participant not following visibility setting of the question.\";"},{"lineNumber":920,"author":{"gitId":"-"},"content":" }"},{"lineNumber":921,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":922,"author":{"gitId":"-"},"content":" }"},{"lineNumber":923,"author":{"gitId":"-"},"content":""},{"lineNumber":924,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":925,"author":{"gitId":"-"},"content":" * Checks if all the given participant types are valid for the purpose of"},{"lineNumber":926,"author":{"gitId":"-"},"content":" * showing different fields of a feedback response."},{"lineNumber":927,"author":{"gitId":"-"},"content":" *"},{"lineNumber":928,"author":{"gitId":"-"},"content":" * @param showResponsesTo the list of participant types to whom responses can be shown"},{"lineNumber":929,"author":{"gitId":"-"},"content":" * @param showGiverNameTo the list of participant types to whom giver name can be shown"},{"lineNumber":930,"author":{"gitId":"-"},"content":" * @param showRecipientNameTo the list of participant types to whom recipient name can be shown"},{"lineNumber":931,"author":{"gitId":"-"},"content":" * @return Error string if any type in any list is invalid, otherwise empty string."},{"lineNumber":932,"author":{"gitId":"-"},"content":" */"},{"lineNumber":933,"author":{"gitId":"-"},"content":" public static List\u003cString\u003e getValidityInfoForFeedbackResponseVisibility("},{"lineNumber":934,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showResponsesTo,"},{"lineNumber":935,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showGiverNameTo,"},{"lineNumber":936,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showRecipientNameTo) {"},{"lineNumber":937,"author":{"gitId":"-"},"content":""},{"lineNumber":938,"author":{"gitId":"-"},"content":" assert showResponsesTo !\u003d null;"},{"lineNumber":939,"author":{"gitId":"-"},"content":" assert showGiverNameTo !\u003d null;"},{"lineNumber":940,"author":{"gitId":"-"},"content":" assert showRecipientNameTo !\u003d null;"},{"lineNumber":941,"author":{"gitId":"-"},"content":" assert !showResponsesTo.contains(null);"},{"lineNumber":942,"author":{"gitId":"-"},"content":" assert !showGiverNameTo.contains(null);"},{"lineNumber":943,"author":{"gitId":"-"},"content":" assert !showRecipientNameTo.contains(null);"},{"lineNumber":944,"author":{"gitId":"-"},"content":""},{"lineNumber":945,"author":{"gitId":"-"},"content":" List\u003cString\u003e errors \u003d new LinkedList\u003c\u003e();"},{"lineNumber":946,"author":{"gitId":"-"},"content":""},{"lineNumber":947,"author":{"gitId":"-"},"content":" for (FeedbackParticipantType type : showGiverNameTo) {"},{"lineNumber":948,"author":{"gitId":"-"},"content":" if (!type.isValidViewer()) {"},{"lineNumber":949,"author":{"gitId":"-"},"content":" errors.add(String.format(PARTICIPANT_TYPE_ERROR_MESSAGE,"},{"lineNumber":950,"author":{"gitId":"-"},"content":" type.toString(), VIEWER_TYPE_NAME));"},{"lineNumber":951,"author":{"gitId":"-"},"content":" }"},{"lineNumber":952,"author":{"gitId":"-"},"content":" if (!showResponsesTo.contains(type)) {"},{"lineNumber":953,"author":{"gitId":"-"},"content":" errors.add(\"Trying to show giver name to \""},{"lineNumber":954,"author":{"gitId":"-"},"content":" + type.toString()"},{"lineNumber":955,"author":{"gitId":"-"},"content":" + \" without showing response first.\");"},{"lineNumber":956,"author":{"gitId":"-"},"content":" }"},{"lineNumber":957,"author":{"gitId":"-"},"content":" }"},{"lineNumber":958,"author":{"gitId":"-"},"content":""},{"lineNumber":959,"author":{"gitId":"-"},"content":" for (FeedbackParticipantType type : showRecipientNameTo) {"},{"lineNumber":960,"author":{"gitId":"-"},"content":" if (!type.isValidViewer()) {"},{"lineNumber":961,"author":{"gitId":"-"},"content":" errors.add(String.format(PARTICIPANT_TYPE_ERROR_MESSAGE,"},{"lineNumber":962,"author":{"gitId":"-"},"content":" type.toString(), VIEWER_TYPE_NAME));"},{"lineNumber":963,"author":{"gitId":"-"},"content":" }"},{"lineNumber":964,"author":{"gitId":"-"},"content":" if (!showResponsesTo.contains(type)) {"},{"lineNumber":965,"author":{"gitId":"-"},"content":" errors.add(\"Trying to show recipient name to \""},{"lineNumber":966,"author":{"gitId":"-"},"content":" + type.toString()"},{"lineNumber":967,"author":{"gitId":"-"},"content":" + \" without showing response first.\");"},{"lineNumber":968,"author":{"gitId":"-"},"content":" }"},{"lineNumber":969,"author":{"gitId":"-"},"content":" }"},{"lineNumber":970,"author":{"gitId":"-"},"content":""},{"lineNumber":971,"author":{"gitId":"-"},"content":" for (FeedbackParticipantType type : showResponsesTo) {"},{"lineNumber":972,"author":{"gitId":"-"},"content":" if (!type.isValidViewer()) {"},{"lineNumber":973,"author":{"gitId":"-"},"content":" errors.add(String.format(PARTICIPANT_TYPE_ERROR_MESSAGE,"},{"lineNumber":974,"author":{"gitId":"-"},"content":" type.toString(), VIEWER_TYPE_NAME));"},{"lineNumber":975,"author":{"gitId":"-"},"content":" }"},{"lineNumber":976,"author":{"gitId":"-"},"content":" }"},{"lineNumber":977,"author":{"gitId":"-"},"content":""},{"lineNumber":978,"author":{"gitId":"-"},"content":" return errors;"},{"lineNumber":979,"author":{"gitId":"-"},"content":" }"},{"lineNumber":980,"author":{"gitId":"-"},"content":""},{"lineNumber":981,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":982,"author":{"gitId":"-"},"content":" * Checks if the given {@code value} has no HTML code."},{"lineNumber":983,"author":{"gitId":"-"},"content":" */"},{"lineNumber":984,"author":{"gitId":"-"},"content":" static String getValidityInfoForNonHtmlField(String fieldName, String value) {"},{"lineNumber":985,"author":{"gitId":"-"},"content":" String sanitizedValue \u003d SanitizationHelper.sanitizeForHtml(value);"},{"lineNumber":986,"author":{"gitId":"-"},"content":" //Fails if sanitized value is not same as value"},{"lineNumber":987,"author":{"gitId":"-"},"content":" return value.equals(sanitizedValue) ? \"\" : NON_HTML_FIELD_ERROR_MESSAGE.replace(\"${fieldName}\", fieldName);"},{"lineNumber":988,"author":{"gitId":"-"},"content":" }"},{"lineNumber":989,"author":{"gitId":"-"},"content":""},{"lineNumber":990,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":991,"author":{"gitId":"-"},"content":" * Checks if the given {@code value} is not null."},{"lineNumber":992,"author":{"gitId":"-"},"content":" */"},{"lineNumber":993,"author":{"gitId":"-"},"content":" public static String getValidityInfoForNonNullField(String fieldName, Object value) {"},{"lineNumber":994,"author":{"gitId":"-"},"content":" return value \u003d\u003d null ? NON_NULL_FIELD_ERROR_MESSAGE.replace(\"${fieldName}\", fieldName) : \"\";"},{"lineNumber":995,"author":{"gitId":"-"},"content":" }"},{"lineNumber":996,"author":{"gitId":"-"},"content":""},{"lineNumber":997,"author":{"gitId":"-"},"content":" private static boolean isUntrimmed(String value) {"},{"lineNumber":998,"author":{"gitId":"-"},"content":" return value.length() !\u003d value.trim().length();"},{"lineNumber":999,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1000,"author":{"gitId":"-"},"content":""},{"lineNumber":1001,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1002,"author":{"gitId":"-"},"content":" * Checks whether a given text input represents a format of a valid email address."},{"lineNumber":1003,"author":{"gitId":"-"},"content":" * @param email text input which needs the validation"},{"lineNumber":1004,"author":{"gitId":"-"},"content":" * @return true if it is a valid email address, else false."},{"lineNumber":1005,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1006,"author":{"gitId":"-"},"content":" private static boolean isValidEmailAddress(String email) {"},{"lineNumber":1007,"author":{"gitId":"-"},"content":" return StringHelper.isMatching(email, REGEX_EMAIL);"},{"lineNumber":1008,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1009,"author":{"gitId":"-"},"content":""},{"lineNumber":1010,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1011,"author":{"gitId":"-"},"content":" * Checks whether all the elements in a Collection are unique."},{"lineNumber":1012,"author":{"gitId":"-"},"content":" * @param elements The Collection of elements to be checked."},{"lineNumber":1013,"author":{"gitId":"-"},"content":" * @return true if all elements are unique, else false."},{"lineNumber":1014,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1015,"author":{"gitId":"-"},"content":" public static \u003cT\u003e boolean areElementsUnique(Collection\u003cT\u003e elements) {"},{"lineNumber":1016,"author":{"gitId":"-"},"content":" Set\u003cT\u003e uniqueElements \u003d new HashSet\u003c\u003e(elements);"},{"lineNumber":1017,"author":{"gitId":"-"},"content":" return uniqueElements.size() \u003d\u003d elements.size();"},{"lineNumber":1018,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1019,"author":{"gitId":"-"},"content":""},{"lineNumber":1020,"author":{"gitId":"-"},"content":" private static String getPopulatedErrorMessage("},{"lineNumber":1021,"author":{"gitId":"-"},"content":" String messageTemplate, String userInput, String fieldName, String errorReason, int maxLength) {"},{"lineNumber":1022,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(messageTemplate, userInput, fieldName, errorReason)"},{"lineNumber":1023,"author":{"gitId":"-"},"content":" .replace(\"${maxLength}\", String.valueOf(maxLength));"},{"lineNumber":1024,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1025,"author":{"gitId":"-"},"content":""},{"lineNumber":1026,"author":{"gitId":"-"},"content":" private static String getPopulatedErrorMessage("},{"lineNumber":1027,"author":{"gitId":"-"},"content":" String messageTemplate, String userInput, String fieldName, String errorReason) {"},{"lineNumber":1028,"author":{"gitId":"-"},"content":" return messageTemplate.replace(\"${userInput}\", userInput)"},{"lineNumber":1029,"author":{"gitId":"-"},"content":" .replace(\"${fieldName}\", fieldName)"},{"lineNumber":1030,"author":{"gitId":"-"},"content":" .replace(\"${reason}\", errorReason);"},{"lineNumber":1031,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1032,"author":{"gitId":"-"},"content":""},{"lineNumber":1033,"author":{"gitId":"-"},"content":" private static String getPopulatedEmptyStringErrorMessage(String messageTemplate,"},{"lineNumber":1034,"author":{"gitId":"-"},"content":" String fieldName, int maxLength) {"},{"lineNumber":1035,"author":{"gitId":"-"},"content":" return messageTemplate.replace(\"${fieldName}\", fieldName)"},{"lineNumber":1036,"author":{"gitId":"-"},"content":" .replace(\"${maxLength}\", String.valueOf(maxLength));"},{"lineNumber":1037,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1038,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":1,"-":1037}},{"path":"src/main/java/teammates/common/util/HibernateUtil.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.util;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import jakarta.persistence.TypedQuery;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaBuilder;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaDelete;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaQuery;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.hibernate.Session;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import org.hibernate.SessionFactory;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.hibernate.Transaction;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import org.hibernate.cfg.Configuration;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import org.hibernate.query.MutationQuery;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import org.hibernate.resource.transaction.spi.TransactionStatus;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.BaseEntity;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.ReadNotification;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.UsageStatistics;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.User;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackConstantSumQuestion;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackContributionQuestion;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackMcqQuestion;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackMsqQuestion;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackNumericalScaleQuestion;"},{"lineNumber":41,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackRankOptionsQuestion;"},{"lineNumber":42,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackRankRecipientsQuestion;"},{"lineNumber":43,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackRubricQuestion;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackTextQuestion;"},{"lineNumber":45,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackConstantSumResponse;"},{"lineNumber":46,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackContributionResponse;"},{"lineNumber":47,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackMcqResponse;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackMsqResponse;"},{"lineNumber":49,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackNumericalScaleResponse;"},{"lineNumber":50,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackRankOptionsResponse;"},{"lineNumber":51,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackRankRecipientsResponse;"},{"lineNumber":52,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackRubricResponse;"},{"lineNumber":53,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackTextResponse;"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":56,"author":{"gitId":"-"},"content":" * Utility class for Hibernate related methods."},{"lineNumber":57,"author":{"gitId":"-"},"content":" */"},{"lineNumber":58,"author":{"gitId":"-"},"content":"public final class HibernateUtil {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" private static SessionFactory sessionFactory;"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" private static final List\u003cClass\u003c? extends BaseEntity\u003e\u003e ANNOTATED_CLASSES \u003d List.of("},{"lineNumber":62,"author":{"gitId":"-"},"content":" AccountRequest.class,"},{"lineNumber":63,"author":{"gitId":"-"},"content":" Course.class,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" FeedbackSession.class,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" Account.class,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" Notification.class,"},{"lineNumber":67,"author":{"gitId":"-"},"content":" ReadNotification.class,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" User.class,"},{"lineNumber":69,"author":{"gitId":"-"},"content":" Instructor.class,"},{"lineNumber":70,"author":{"gitId":"-"},"content":" Student.class,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" UsageStatistics.class,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" Section.class,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" Team.class,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" FeedbackQuestion.class,"},{"lineNumber":75,"author":{"gitId":"-"},"content":" FeedbackConstantSumQuestion.class,"},{"lineNumber":76,"author":{"gitId":"-"},"content":" FeedbackContributionQuestion.class,"},{"lineNumber":77,"author":{"gitId":"-"},"content":" FeedbackMcqQuestion.class,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" FeedbackMsqQuestion.class,"},{"lineNumber":79,"author":{"gitId":"-"},"content":" FeedbackNumericalScaleQuestion.class,"},{"lineNumber":80,"author":{"gitId":"-"},"content":" FeedbackRankOptionsQuestion.class,"},{"lineNumber":81,"author":{"gitId":"-"},"content":" FeedbackRankRecipientsQuestion.class,"},{"lineNumber":82,"author":{"gitId":"-"},"content":" FeedbackRubricQuestion.class,"},{"lineNumber":83,"author":{"gitId":"-"},"content":" FeedbackTextQuestion.class,"},{"lineNumber":84,"author":{"gitId":"-"},"content":" DeadlineExtension.class,"},{"lineNumber":85,"author":{"gitId":"-"},"content":" FeedbackResponse.class,"},{"lineNumber":86,"author":{"gitId":"-"},"content":" FeedbackConstantSumResponse.class,"},{"lineNumber":87,"author":{"gitId":"-"},"content":" FeedbackContributionResponse.class,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" FeedbackMcqResponse.class,"},{"lineNumber":89,"author":{"gitId":"-"},"content":" FeedbackMsqResponse.class,"},{"lineNumber":90,"author":{"gitId":"-"},"content":" FeedbackNumericalScaleResponse.class,"},{"lineNumber":91,"author":{"gitId":"-"},"content":" FeedbackRankOptionsResponse.class,"},{"lineNumber":92,"author":{"gitId":"-"},"content":" FeedbackRankRecipientsResponse.class,"},{"lineNumber":93,"author":{"gitId":"-"},"content":" FeedbackRubricResponse.class,"},{"lineNumber":94,"author":{"gitId":"-"},"content":" FeedbackTextResponse.class,"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" FeedbackResponseComment.class,"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog.class);"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" private HibernateUtil() {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" // Utility class"},{"lineNumber":100,"author":{"gitId":"-"},"content":" // Intentional private constructor to prevent instantiation."},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":104,"author":{"gitId":"-"},"content":" * Builds a session factory if it does not already exist."},{"lineNumber":105,"author":{"gitId":"-"},"content":" */"},{"lineNumber":106,"author":{"gitId":"-"},"content":" public static void buildSessionFactory(String dbUrl, String username, String password) {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" synchronized (HibernateUtil.class) {"},{"lineNumber":108,"author":{"gitId":"-"},"content":" if (sessionFactory !\u003d null) {"},{"lineNumber":109,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" Configuration config \u003d new Configuration()"},{"lineNumber":114,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.dialect\", \"org.hibernate.dialect.PostgreSQLDialect\")"},{"lineNumber":115,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.connection.driver_class\", \"org.postgresql.Driver\")"},{"lineNumber":116,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.connection.provider_class\","},{"lineNumber":117,"author":{"gitId":"-"},"content":" \"org.hibernate.hikaricp.internal.HikariCPConnectionProvider\")"},{"lineNumber":118,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.connection.username\", username)"},{"lineNumber":119,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.connection.password\", password)"},{"lineNumber":120,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.connection.url\", dbUrl)"},{"lineNumber":121,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.hbm2ddl.auto\", \"validate\")"},{"lineNumber":122,"author":{"gitId":"-"},"content":" .setProperty(\"show_sql\", \"true\")"},{"lineNumber":123,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.current_session_context_class\", \"thread\")"},{"lineNumber":124,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.hikari.minimumIdle\", \"10\")"},{"lineNumber":125,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.hikari.maximumPoolSize\", \"30\")"},{"lineNumber":126,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.hikari.idleTimeout\", \"300000\")"},{"lineNumber":127,"author":{"gitId":"-"},"content":" .setProperty(\"hibernate.hikari.connectionTimeout\", \"30000\")"},{"lineNumber":128,"author":{"gitId":"-"},"content":" // Uncomment only during migration for optimized batch-insertion, batch-update, and batch-fetch."},{"lineNumber":129,"author":{"gitId":"-"},"content":" // .setProperty(\"hibernate.jdbc.batch_size\", \"50\")"},{"lineNumber":130,"author":{"gitId":"-"},"content":" // .setProperty(\"hibernate.order_updates\", \"true\")"},{"lineNumber":131,"author":{"gitId":"-"},"content":" // .setProperty(\"hibernate.batch_versioned_data\", \"true\")"},{"lineNumber":132,"author":{"gitId":"-"},"content":" // .setProperty(\"hibernate.jdbc.fetch_size\", \"50\")"},{"lineNumber":133,"author":{"gitId":"-"},"content":" .addPackage(\"teammates.storage.sqlentity\");"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" if (Config.IS_DEV_SERVER) {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" config.setProperty(\"hibernate.hbm2ddl.auto\", \"update\");"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" for (Class\u003c? extends BaseEntity\u003e cls : ANNOTATED_CLASSES) {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" config \u003d config.addAnnotatedClass(cls);"},{"lineNumber":141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":142,"author":{"gitId":"-"},"content":" config.setPhysicalNamingStrategy(new CamelCaseToUnderscoresNamingStrategy());"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" setSessionFactory(config.buildSessionFactory());"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":148,"author":{"gitId":"-"},"content":" * Returns the SessionFactory."},{"lineNumber":149,"author":{"gitId":"-"},"content":" */"},{"lineNumber":150,"author":{"gitId":"-"},"content":" private static SessionFactory getSessionFactory() {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" assert sessionFactory !\u003d null;"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":" return sessionFactory;"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":157,"author":{"gitId":"-"},"content":" * Returns the current hibernate session."},{"lineNumber":158,"author":{"gitId":"-"},"content":" * @see SessionFactory#getCurrentSession()"},{"lineNumber":159,"author":{"gitId":"-"},"content":" */"},{"lineNumber":160,"author":{"gitId":"-"},"content":" private static Session getCurrentSession() {"},{"lineNumber":161,"author":{"gitId":"-"},"content":" return getSessionFactory().getCurrentSession();"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":165,"author":{"gitId":"-"},"content":" * Returns a CriteriaBuilder object."},{"lineNumber":166,"author":{"gitId":"-"},"content":" * @see SessionFactory#getCriteriaBuilder()"},{"lineNumber":167,"author":{"gitId":"-"},"content":" */"},{"lineNumber":168,"author":{"gitId":"-"},"content":" public static CriteriaBuilder getCriteriaBuilder() {"},{"lineNumber":169,"author":{"gitId":"-"},"content":" return getCurrentSession().getCriteriaBuilder();"},{"lineNumber":170,"author":{"gitId":"-"},"content":" }"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":173,"author":{"gitId":"-"},"content":" * Returns a generic typed TypedQuery object."},{"lineNumber":174,"author":{"gitId":"-"},"content":" * @see Session#createQuery(CriteriaQuery)"},{"lineNumber":175,"author":{"gitId":"-"},"content":" */"},{"lineNumber":176,"author":{"gitId":"-"},"content":" public static \u003cT\u003e TypedQuery\u003cT\u003e createQuery(CriteriaQuery\u003cT\u003e cr) {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" return getCurrentSession().createQuery(cr);"},{"lineNumber":178,"author":{"gitId":"-"},"content":" }"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":181,"author":{"gitId":"-"},"content":" * Returns a MutationQuery object."},{"lineNumber":182,"author":{"gitId":"-"},"content":" * @see Session#createMutationQuery(CriteriaDelete)"},{"lineNumber":183,"author":{"gitId":"-"},"content":" */"},{"lineNumber":184,"author":{"gitId":"-"},"content":" public static \u003cT\u003e MutationQuery createMutationQuery(CriteriaDelete\u003cT\u003e cd) {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" return getCurrentSession().createMutationQuery(cd);"},{"lineNumber":186,"author":{"gitId":"-"},"content":" }"},{"lineNumber":187,"author":{"gitId":"-"},"content":""},{"lineNumber":188,"author":{"gitId":"-"},"content":" public static void setSessionFactory(SessionFactory sessionFactory) {"},{"lineNumber":189,"author":{"gitId":"-"},"content":" HibernateUtil.sessionFactory \u003d sessionFactory;"},{"lineNumber":190,"author":{"gitId":"-"},"content":" }"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":193,"author":{"gitId":"-"},"content":" * Start a resource transaction."},{"lineNumber":194,"author":{"gitId":"-"},"content":" * @see Transaction#begin()"},{"lineNumber":195,"author":{"gitId":"-"},"content":" */"},{"lineNumber":196,"author":{"gitId":"-"},"content":" public static void beginTransaction() {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" Transaction transaction \u003d getCurrentSession().getTransaction();"},{"lineNumber":198,"author":{"gitId":"-"},"content":" transaction.begin();"},{"lineNumber":199,"author":{"gitId":"-"},"content":" }"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":202,"author":{"gitId":"-"},"content":" * Roll back the current resource transaction if needed."},{"lineNumber":203,"author":{"gitId":"-"},"content":" * @see Transaction#rollback()"},{"lineNumber":204,"author":{"gitId":"-"},"content":" */"},{"lineNumber":205,"author":{"gitId":"-"},"content":" public static void rollbackTransaction() {"},{"lineNumber":206,"author":{"gitId":"-"},"content":" Session session \u003d getCurrentSession();"},{"lineNumber":207,"author":{"gitId":"-"},"content":" if (session.getTransaction().getStatus() \u003d\u003d TransactionStatus.ACTIVE"},{"lineNumber":208,"author":{"gitId":"-"},"content":" || session.getTransaction().getStatus() \u003d\u003d TransactionStatus.MARKED_ROLLBACK) {"},{"lineNumber":209,"author":{"gitId":"-"},"content":" session.getTransaction().rollback();"},{"lineNumber":210,"author":{"gitId":"-"},"content":" }"},{"lineNumber":211,"author":{"gitId":"-"},"content":" }"},{"lineNumber":212,"author":{"gitId":"-"},"content":""},{"lineNumber":213,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":214,"author":{"gitId":"-"},"content":" * Commit the current resource transaction, writing any unflushed changes to the database."},{"lineNumber":215,"author":{"gitId":"-"},"content":" * @see Transaction#commit()"},{"lineNumber":216,"author":{"gitId":"-"},"content":" */"},{"lineNumber":217,"author":{"gitId":"-"},"content":" public static void commitTransaction() {"},{"lineNumber":218,"author":{"gitId":"-"},"content":" Transaction transaction \u003d getCurrentSession().getTransaction();"},{"lineNumber":219,"author":{"gitId":"-"},"content":" transaction.commit();"},{"lineNumber":220,"author":{"gitId":"-"},"content":" }"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":223,"author":{"gitId":"-"},"content":" * Force this session to flush. Must be called at the end of a unit of work, before the transaction is committed."},{"lineNumber":224,"author":{"gitId":"-"},"content":" * @see Session#flush()"},{"lineNumber":225,"author":{"gitId":"-"},"content":" */"},{"lineNumber":226,"author":{"gitId":"-"},"content":" public static void flushSession() {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" getCurrentSession().flush();"},{"lineNumber":228,"author":{"gitId":"-"},"content":" }"},{"lineNumber":229,"author":{"gitId":"-"},"content":""},{"lineNumber":230,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":231,"author":{"gitId":"-"},"content":" * Force this session to clear. Usually called together with flush."},{"lineNumber":232,"author":{"gitId":"-"},"content":" * @see Session#clear()"},{"lineNumber":233,"author":{"gitId":"-"},"content":" */"},{"lineNumber":234,"author":{"gitId":"-"},"content":" public static void clearSession() {"},{"lineNumber":235,"author":{"gitId":"-"},"content":" getCurrentSession().clear();"},{"lineNumber":236,"author":{"gitId":"-"},"content":" }"},{"lineNumber":237,"author":{"gitId":"-"},"content":""},{"lineNumber":238,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":239,"author":{"gitId":"-"},"content":" * Return the persistent instance of the given entity class with the given identifier,"},{"lineNumber":240,"author":{"gitId":"-"},"content":" * or null if there is no such persistent instance."},{"lineNumber":241,"author":{"gitId":"-"},"content":" * @see Session#get(Class, Object)"},{"lineNumber":242,"author":{"gitId":"-"},"content":" */"},{"lineNumber":243,"author":{"gitId":"-"},"content":" public static \u003cT extends BaseEntity\u003e T get(Class\u003cT\u003e entityType, Object id) {"},{"lineNumber":244,"author":{"gitId":"-"},"content":" return getCurrentSession().get(entityType, id);"},{"lineNumber":245,"author":{"gitId":"-"},"content":" }"},{"lineNumber":246,"author":{"gitId":"-"},"content":""},{"lineNumber":247,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":248,"author":{"gitId":"-"},"content":" * Return the persistent instance of the given entity class with the given natural id,"},{"lineNumber":249,"author":{"gitId":"-"},"content":" * or null if there is no such persistent instance."},{"lineNumber":250,"author":{"gitId":"-"},"content":" * @see Session#get(Class, Object)"},{"lineNumber":251,"author":{"gitId":"-"},"content":" */"},{"lineNumber":252,"author":{"gitId":"-"},"content":" public static \u003cT extends BaseEntity\u003e T getBySimpleNaturalId(Class\u003cT\u003e entityType, Object id) {"},{"lineNumber":253,"author":{"gitId":"-"},"content":" return getCurrentSession().bySimpleNaturalId(entityType).load(id);"},{"lineNumber":254,"author":{"gitId":"-"},"content":" }"},{"lineNumber":255,"author":{"gitId":"-"},"content":""},{"lineNumber":256,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":257,"author":{"gitId":"-"},"content":" * Copy the state of the given object onto the persistent object with the same identifier."},{"lineNumber":258,"author":{"gitId":"-"},"content":" * @see Session#merge(E)"},{"lineNumber":259,"author":{"gitId":"-"},"content":" */"},{"lineNumber":260,"author":{"gitId":"-"},"content":" public static \u003cE\u003e E merge(E object) {"},{"lineNumber":261,"author":{"gitId":"-"},"content":" return getCurrentSession().merge(object);"},{"lineNumber":262,"author":{"gitId":"-"},"content":" }"},{"lineNumber":263,"author":{"gitId":"-"},"content":""},{"lineNumber":264,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":265,"author":{"gitId":"-"},"content":" * Make a transient instance persistent and mark it for later insertion in the database."},{"lineNumber":266,"author":{"gitId":"-"},"content":" * @see Session#persist(Object)"},{"lineNumber":267,"author":{"gitId":"-"},"content":" */"},{"lineNumber":268,"author":{"gitId":"-"},"content":" public static void persist(BaseEntity entity) {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" getCurrentSession().persist(entity);"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":273,"author":{"gitId":"-"},"content":" * Mark a persistence instance associated with this session for removal from the underlying database."},{"lineNumber":274,"author":{"gitId":"-"},"content":" * @see Session#remove(Object)"},{"lineNumber":275,"author":{"gitId":"-"},"content":" */"},{"lineNumber":276,"author":{"gitId":"-"},"content":" public static void remove(BaseEntity entity) {"},{"lineNumber":277,"author":{"gitId":"-"},"content":" getCurrentSession().remove(entity);"},{"lineNumber":278,"author":{"gitId":"-"},"content":" }"},{"lineNumber":279,"author":{"gitId":"-"},"content":""},{"lineNumber":280,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":281,"author":{"gitId":"-"},"content":" * Create and execute a {@code MutationQuery} for the given delete criteria tree."},{"lineNumber":282,"author":{"gitId":"-"},"content":" */"},{"lineNumber":283,"author":{"gitId":"-"},"content":" public static \u003cT\u003e void executeDelete(CriteriaDelete\u003cT\u003e cd) {"},{"lineNumber":284,"author":{"gitId":"-"},"content":" getCurrentSession().createMutationQuery(cd).executeUpdate();"},{"lineNumber":285,"author":{"gitId":"-"},"content":" }"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":288,"author":{"gitId":"dishenggg"},"content":" * Return a reference to the persistent instance with the given class and"},{"lineNumber":289,"author":{"gitId":"dishenggg"},"content":" * identifier,making the assumption that the instance is still persistent in the"},{"lineNumber":290,"author":{"gitId":"dishenggg"},"content":" * database."},{"lineNumber":291,"author":{"gitId":"dishenggg"},"content":" * @see Session#getReference(Class, Object)"},{"lineNumber":292,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":293,"author":{"gitId":"dishenggg"},"content":" public static \u003cT\u003e T getReference(Class\u003cT\u003e entityType, Object id) {"},{"lineNumber":294,"author":{"gitId":"-"},"content":" return getCurrentSession().getReference(entityType, id);"},{"lineNumber":295,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":296,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":297,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":12,"-":285}},{"path":"src/main/java/teammates/common/util/Templates.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.util;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":4,"author":{"gitId":"-"},"content":" * Contains utility methods for creating strings from given templates."},{"lineNumber":5,"author":{"gitId":"-"},"content":" */"},{"lineNumber":6,"author":{"gitId":"-"},"content":"public final class Templates {"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":" public static final String INSTRUCTOR_SAMPLE_DATA \u003d FileHelper.readResourceFile(\"InstructorSampleData.json\");"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":" private Templates() {"},{"lineNumber":11,"author":{"gitId":"-"},"content":" // utility class"},{"lineNumber":12,"author":{"gitId":"-"},"content":" }"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":15,"author":{"gitId":"-"},"content":" * Populates the HTML templates by replacing variables in the template string"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * with the given value strings."},{"lineNumber":17,"author":{"gitId":"-"},"content":" * @param template The template html to be populated"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * @param keyValuePairs Array of a variable, even number of key-value pairs:"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * { \"key1\", \"val1\", \"key2\", \"val2\", ... }"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * @return The populated template"},{"lineNumber":21,"author":{"gitId":"-"},"content":" */"},{"lineNumber":22,"author":{"gitId":"-"},"content":" public static String populateTemplate(String template, String... keyValuePairs) {"},{"lineNumber":23,"author":{"gitId":"-"},"content":" assert keyValuePairs.length % 2 \u003d\u003d 0 : \"The number of elements in keyValuePairs passed in must be even\";"},{"lineNumber":24,"author":{"gitId":"-"},"content":" String populatedTemplate \u003d template;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c keyValuePairs.length; i +\u003d 2) {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" populatedTemplate \u003d populatedTemplate.replace(keyValuePairs[i], keyValuePairs[i + 1]);"},{"lineNumber":27,"author":{"gitId":"-"},"content":" }"},{"lineNumber":28,"author":{"gitId":"-"},"content":" return populatedTemplate;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":32,"author":{"gitId":"-"},"content":" * Collection of templates of emails to be sent by the system."},{"lineNumber":33,"author":{"gitId":"-"},"content":" */"},{"lineNumber":34,"author":{"gitId":"-"},"content":" public static class EmailTemplates {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" public static final String ADMIN_NEW_ACCOUNT_REQUEST_ALERT \u003d"},{"lineNumber":36,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"adminEmailTemplate-newAccountRequestAlert.html\");"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" public static final String INSTRUCTOR_NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT \u003d"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" FileHelper.readResourceFile(\"instructorEmailTemplate-newAccountRequestAcknowledgement.html\");"},{"lineNumber":39,"author":{"gitId":"-"},"content":" public static final String USER_COURSE_JOIN \u003d"},{"lineNumber":40,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplate-courseJoin.html\");"},{"lineNumber":41,"author":{"gitId":"-"},"content":" public static final String USER_COURSE_REGISTER \u003d"},{"lineNumber":42,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplate-userRegisterForCourse.html\");"},{"lineNumber":43,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_STUDENT_COURSE_JOIN \u003d"},{"lineNumber":44,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"studentEmailFragment-courseJoin.html\");"},{"lineNumber":45,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_STUDENT_COURSE_REJOIN_AFTER_GOOGLE_ID_RESET \u003d"},{"lineNumber":46,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"studentEmailFragment-googleIdReset.html\");"},{"lineNumber":47,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_STUDENT_COURSE_REJOIN_AFTER_REGKEY_RESET \u003d"},{"lineNumber":48,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"studentEmailFragment-registrationKeyReset.html\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_INSTRUCTOR_COPY_PREAMBLE \u003d"},{"lineNumber":50,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"instructorEmailFragment-instructorCopyPreamble.html\");"},{"lineNumber":51,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_INSTRUCTOR_COURSE_JOIN \u003d"},{"lineNumber":52,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"instructorEmailFragment-courseJoin.html\");"},{"lineNumber":53,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_INSTRUCTOR_COURSE_REJOIN_AFTER_GOOGLE_ID_RESET \u003d"},{"lineNumber":54,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"instructorEmailFragment-googleIdReset.html\");"},{"lineNumber":55,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_INSTRUCTOR_COURSE_REJOIN_AFTER_REGKEY_RESET \u003d"},{"lineNumber":56,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"instructorEmailFragment-registrationKeyReset.html\");"},{"lineNumber":57,"author":{"gitId":"-"},"content":" public static final String USER_FEEDBACK_SESSION \u003d"},{"lineNumber":58,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplate-feedbackSession.html\");"},{"lineNumber":59,"author":{"gitId":"-"},"content":" public static final String USER_FEEDBACK_SESSION_OPENING \u003d"},{"lineNumber":60,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplate-feedbackSessionOpening.html\");"},{"lineNumber":61,"author":{"gitId":"-"},"content":" public static final String USER_FEEDBACK_SESSION_PUBLISHED \u003d"},{"lineNumber":62,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplate-feedbackSessionPublished.html\");"},{"lineNumber":63,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_SESSION_LINKS_RECOVERY_ACCESS_LINKS_BY_SESSION \u003d"},{"lineNumber":64,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"sessionLinksRecoveryEmailTemplateFragment-sessionAccessLinksBySession.html\");"},{"lineNumber":65,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_SESSION_LINKS_RECOVERY_ACCESS_LINKS_BY_COURSE \u003d"},{"lineNumber":66,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"sessionLinksRecoveryEmailTemplateFragment-sessionAccessLinksByCourse.html\");"},{"lineNumber":67,"author":{"gitId":"-"},"content":" public static final String SESSION_LINKS_RECOVERY_ACCESS_LINKS \u003d"},{"lineNumber":68,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"sessionLinksRecoveryEmailTemplate-feedbackSessionAccessLinks.html\");"},{"lineNumber":69,"author":{"gitId":"-"},"content":" public static final String SESSION_LINKS_RECOVERY_ACCESS_LINKS_NONE \u003d"},{"lineNumber":70,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"sessionLinksRecoveryEmailTemplate-feedbackSessionAccessLinksNone.html\");"},{"lineNumber":71,"author":{"gitId":"-"},"content":" public static final String SESSION_LINKS_RECOVERY_EMAIL_NOT_FOUND \u003d"},{"lineNumber":72,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"sessionLinksRecoveryEmailTemplate-emailNotFound.html\");"},{"lineNumber":73,"author":{"gitId":"-"},"content":" public static final String USER_FEEDBACK_SESSION_UNPUBLISHED \u003d"},{"lineNumber":74,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplate-feedbackSessionUnpublished.html\");"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_SINGLE_FEEDBACK_SESSION_LINKS \u003d"},{"lineNumber":76,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplateFragment-feedbackSessionResendAllLinks.html\");"},{"lineNumber":77,"author":{"gitId":"-"},"content":" public static final String USER_FEEDBACK_SESSION_RESEND_ALL_LINKS \u003d"},{"lineNumber":78,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplate-feedbackSessionResendAllLinks.html\");"},{"lineNumber":79,"author":{"gitId":"-"},"content":" public static final String USER_REGKEY_REGENERATION_RESEND_ALL_COURSE_LINKS \u003d"},{"lineNumber":80,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplate-regenerateLinksResendAllCourseLinks.html\");"},{"lineNumber":81,"author":{"gitId":"-"},"content":" public static final String SEVERE_ERROR_LOG_LINE \u003d"},{"lineNumber":82,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"severeErrorLogLine.html\");"},{"lineNumber":83,"author":{"gitId":"-"},"content":" public static final String LOGIN_EMAIL \u003d"},{"lineNumber":84,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"loginEmail.html\");"},{"lineNumber":85,"author":{"gitId":"-"},"content":" public static final String NEW_INSTRUCTOR_ACCOUNT_WELCOME \u003d"},{"lineNumber":86,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"newInstructorAccountWelcome.html\");"},{"lineNumber":87,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_SESSION_ADDITIONAL_CONTACT_INFORMATION \u003d"},{"lineNumber":88,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailFragment-sessionAdditionalContactInformationFragment.html\");"},{"lineNumber":89,"author":{"gitId":"-"},"content":" public static final String OWNER_FEEDBACK_SESSION \u003d"},{"lineNumber":90,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"ownerEmailTemplate-feedbackSession.html\");"},{"lineNumber":91,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_OPENING_SOON_EDIT_DETAILS \u003d"},{"lineNumber":92,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"ownerEmailFragment-editDetails.html\");"},{"lineNumber":93,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_OPENING_SOON_JOIN_COURSE_BEFORE_EDIT_DETAILS \u003d"},{"lineNumber":94,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"ownerEmailFragment-joinCourseBeforeEditDetails.html\");"},{"lineNumber":95,"author":{"gitId":"-"},"content":" public static final String FRAGMENT_CLOSED_VIEW_RESPONSES \u003d"},{"lineNumber":96,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"ownerEmailFragment-viewResponses.html\");"},{"lineNumber":97,"author":{"gitId":"-"},"content":" public static final String USER_DEADLINE_EXTENSION \u003d"},{"lineNumber":98,"author":{"gitId":"-"},"content":" FileHelper.readResourceFile(\"userEmailTemplate-deadlineExtension.html\");"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":2,"-":99}},{"path":"src/main/java/teammates/common/util/TimeHelper.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.util;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Duration;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.OffsetDateTime;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.time.ZoneId;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.time.ZonedDateTime;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.time.format.DateTimeFormatter;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.time.format.DateTimeParseException;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":12,"author":{"gitId":"-"},"content":" * A helper class to hold time-related functions (e.g., converting dates to strings etc.)."},{"lineNumber":13,"author":{"gitId":"-"},"content":" *"},{"lineNumber":14,"author":{"gitId":"-"},"content":" * \u003cp\u003eTime zone is assumed as UTC unless specifically mentioned."},{"lineNumber":15,"author":{"gitId":"-"},"content":" */"},{"lineNumber":16,"author":{"gitId":"-"},"content":"public final class TimeHelper {"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":" private TimeHelper() {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" // utility class"},{"lineNumber":20,"author":{"gitId":"-"},"content":" }"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":23,"author":{"gitId":"-"},"content":" * Returns an Instant that represents the nearest hour before the given object."},{"lineNumber":24,"author":{"gitId":"-"},"content":" *"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * \u003cp\u003eThe time zone used is assumed to be the default timezone, namely UTC."},{"lineNumber":26,"author":{"gitId":"-"},"content":" */"},{"lineNumber":27,"author":{"gitId":"-"},"content":" public static Instant getInstantNearestHourBefore(Instant instant) {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" String nearestHourString \u003d formatInstant(instant, Const.DEFAULT_TIME_ZONE, \"yyyy-MM-dd\u0027T\u0027HH:00:00.00\u0027Z\u0027\");"},{"lineNumber":29,"author":{"gitId":"-"},"content":" return parseInstant(nearestHourString);"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" * Returns an Instant that represents the nearest quarter hour before the given object."},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" * \u003cp\u003eThe time zone used is assumed to be the default timezone, namely UTC."},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" public static Instant getInstantNearestQuarterHourBefore(Instant instant) {"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" ZonedDateTime zdt \u003d instant.atZone(ZoneId.of(Const.DEFAULT_TIME_ZONE));"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" int minutesPastQuarter \u003d zdt.getMinute() % 15;"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" ZonedDateTime nearestQuarterZdt \u003d zdt.minusMinutes(minutesPastQuarter).withSecond(0).withNano(0);"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" return nearestQuarterZdt.toInstant();"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":45,"author":{"gitId":"-"},"content":" * Returns an Instant that is offset by a number of days from now."},{"lineNumber":46,"author":{"gitId":"-"},"content":" *"},{"lineNumber":47,"author":{"gitId":"-"},"content":" * @param offsetInDays integer number of days to offset by"},{"lineNumber":48,"author":{"gitId":"-"},"content":" * @return an Instant offset by {@code offsetInDays} days"},{"lineNumber":49,"author":{"gitId":"-"},"content":" */"},{"lineNumber":50,"author":{"gitId":"-"},"content":" public static Instant getInstantDaysOffsetFromNow(long offsetInDays) {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" return Instant.now().plus(Duration.ofDays(offsetInDays));"},{"lineNumber":52,"author":{"gitId":"-"},"content":" }"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":55,"author":{"gitId":"-"},"content":" * Returns an Instant that is offset by a number of months from now."},{"lineNumber":56,"author":{"gitId":"-"},"content":" *"},{"lineNumber":57,"author":{"gitId":"-"},"content":" * @param offsetInMonths integer number of months to offset by"},{"lineNumber":58,"author":{"gitId":"-"},"content":" * @param timeZone string representing the time zone to compute local datetime"},{"lineNumber":59,"author":{"gitId":"-"},"content":" * @return an Instant offset by {@code offsetInMonths} days"},{"lineNumber":60,"author":{"gitId":"-"},"content":" */"},{"lineNumber":61,"author":{"gitId":"-"},"content":" public static Instant getInstantMonthsOffsetFromNow(long offsetInMonths, String timeZone) {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" Instant now \u003d Instant.now();"},{"lineNumber":63,"author":{"gitId":"-"},"content":" ZonedDateTime zdt \u003d now.atZone(ZoneId.of(timeZone));"},{"lineNumber":64,"author":{"gitId":"-"},"content":" ZonedDateTime offsetZdt \u003d zdt.plusMonths(offsetInMonths);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" return offsetZdt.toInstant();"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":69,"author":{"gitId":"-"},"content":" * Returns an Instant that is offset by a number of days before now."},{"lineNumber":70,"author":{"gitId":"-"},"content":" *"},{"lineNumber":71,"author":{"gitId":"-"},"content":" * @param offsetInDays integer number of days to offset by"},{"lineNumber":72,"author":{"gitId":"-"},"content":" * @return an Instant offset by {@code offsetInDays} days"},{"lineNumber":73,"author":{"gitId":"-"},"content":" */"},{"lineNumber":74,"author":{"gitId":"-"},"content":" public static Instant getInstantDaysOffsetBeforeNow(long offsetInDays) {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" return Instant.now().minus(Duration.ofDays(offsetInDays));"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":79,"author":{"gitId":"-"},"content":" * Returns an Instant that is offset by a number of hours from now."},{"lineNumber":80,"author":{"gitId":"-"},"content":" *"},{"lineNumber":81,"author":{"gitId":"-"},"content":" * @param offsetInHours integer number of hours to offset by"},{"lineNumber":82,"author":{"gitId":"-"},"content":" * @return an Instant offset by {@code offsetInHours} hours"},{"lineNumber":83,"author":{"gitId":"-"},"content":" */"},{"lineNumber":84,"author":{"gitId":"-"},"content":" public static Instant getInstantHoursOffsetFromNow(long offsetInHours) {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" return Instant.now().plus(Duration.ofHours(offsetInHours));"},{"lineNumber":86,"author":{"gitId":"-"},"content":" }"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":89,"author":{"gitId":"-"},"content":" * Formats a datetime stamp from an {@code instant} using a formatting pattern."},{"lineNumber":90,"author":{"gitId":"-"},"content":" *"},{"lineNumber":91,"author":{"gitId":"-"},"content":" * \u003cp\u003eNote: a formatting pattern containing \u0027a\u0027 (for the period; AM/PM) is treated differently at noon/midday."},{"lineNumber":92,"author":{"gitId":"-"},"content":" * Using that pattern with a datetime whose time falls on \"12:00 PM\" will cause it to be formatted as \"12:00 NOON\".\u003c/p\u003e"},{"lineNumber":93,"author":{"gitId":"-"},"content":" *"},{"lineNumber":94,"author":{"gitId":"-"},"content":" * @param instant the instant to be formatted"},{"lineNumber":95,"author":{"gitId":"-"},"content":" * @param timeZone the time zone to compute local datetime"},{"lineNumber":96,"author":{"gitId":"-"},"content":" * @param pattern formatting pattern, see Oracle docs for DateTimeFormatter for pattern table"},{"lineNumber":97,"author":{"gitId":"-"},"content":" * @return the formatted datetime stamp string"},{"lineNumber":98,"author":{"gitId":"-"},"content":" */"},{"lineNumber":99,"author":{"gitId":"-"},"content":" public static String formatInstant(Instant instant, String timeZone, String pattern) {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" if (instant \u003d\u003d null || timeZone \u003d\u003d null || pattern \u003d\u003d null) {"},{"lineNumber":101,"author":{"gitId":"-"},"content":" return \"\";"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"-"},"content":" ZonedDateTime zonedDateTime \u003d instant.atZone(ZoneId.of(timeZone));"},{"lineNumber":104,"author":{"gitId":"-"},"content":" String processedPattern \u003d pattern;"},{"lineNumber":105,"author":{"gitId":"-"},"content":" if (zonedDateTime.getHour() \u003d\u003d 12 \u0026\u0026 zonedDateTime.getMinute() \u003d\u003d 0) {"},{"lineNumber":106,"author":{"gitId":"-"},"content":" processedPattern \u003d pattern.replace(\"a\", \"\u0027NOON\u0027\");"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":" DateTimeFormatter formatter \u003d DateTimeFormatter.ofPattern(processedPattern);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" return zonedDateTime.format(formatter);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":113,"author":{"gitId":"-"},"content":" * Gets an Instant which is adjusted for midnight time (23:59 and 00:00) at the specified time zone."},{"lineNumber":114,"author":{"gitId":"-"},"content":" * The direction of adjustment (23:59 to 00:00 or vice versa) is determined by {@code isForward} parameter."},{"lineNumber":115,"author":{"gitId":"-"},"content":" */"},{"lineNumber":116,"author":{"gitId":"-"},"content":" public static Instant getMidnightAdjustedInstantBasedOnZone(Instant instant, String timeZone, boolean isForward) {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" if (isSpecialTime(instant)) {"},{"lineNumber":118,"author":{"gitId":"-"},"content":" return instant;"},{"lineNumber":119,"author":{"gitId":"-"},"content":" }"},{"lineNumber":120,"author":{"gitId":"-"},"content":" ZonedDateTime zonedDateTime \u003d instant.atZone(ZoneId.of(timeZone));"},{"lineNumber":121,"author":{"gitId":"-"},"content":" if (isForward \u0026\u0026 zonedDateTime.getHour() \u003d\u003d 23 \u0026\u0026 zonedDateTime.getMinute() \u003d\u003d 59) {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" zonedDateTime \u003d zonedDateTime.plusMinutes(1L);"},{"lineNumber":123,"author":{"gitId":"-"},"content":" } else if (!isForward \u0026\u0026 zonedDateTime.getHour() \u003d\u003d 0 \u0026\u0026 zonedDateTime.getMinute() \u003d\u003d 0) {"},{"lineNumber":124,"author":{"gitId":"-"},"content":" zonedDateTime \u003d zonedDateTime.minusMinutes(1L);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" }"},{"lineNumber":126,"author":{"gitId":"-"},"content":" return zonedDateTime.toInstant();"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":130,"author":{"gitId":"-"},"content":" * Returns whether the given {@code instant} is being used as a special representation, signifying its face value"},{"lineNumber":131,"author":{"gitId":"-"},"content":" * should not be used without proper processing."},{"lineNumber":132,"author":{"gitId":"-"},"content":" *"},{"lineNumber":133,"author":{"gitId":"-"},"content":" * \u003cp\u003eA {@code null} instant is not a special time.\u003c/p\u003e"},{"lineNumber":134,"author":{"gitId":"-"},"content":" *"},{"lineNumber":135,"author":{"gitId":"-"},"content":" * @param instant the instant to test"},{"lineNumber":136,"author":{"gitId":"-"},"content":" * @return {@code true} if the given instant is used as a special representation, {@code false} otherwise"},{"lineNumber":137,"author":{"gitId":"-"},"content":" */"},{"lineNumber":138,"author":{"gitId":"-"},"content":" public static boolean isSpecialTime(Instant instant) {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" if (instant \u003d\u003d null) {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" return instant.equals(Const.TIME_REPRESENTS_FOLLOW_OPENING)"},{"lineNumber":144,"author":{"gitId":"-"},"content":" || instant.equals(Const.TIME_REPRESENTS_FOLLOW_VISIBLE)"},{"lineNumber":145,"author":{"gitId":"-"},"content":" || instant.equals(Const.TIME_REPRESENTS_LATER)"},{"lineNumber":146,"author":{"gitId":"-"},"content":" || instant.equals(Const.TIME_REPRESENTS_NOW);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":150,"author":{"gitId":"-"},"content":" * Parses an {@code Instant} object from a datetime string in the ISO 8601 format."},{"lineNumber":151,"author":{"gitId":"-"},"content":" *"},{"lineNumber":152,"author":{"gitId":"-"},"content":" * @return the parsed {@code Instant} object"},{"lineNumber":153,"author":{"gitId":"-"},"content":" * @throws AssertionError if there is a parsing error"},{"lineNumber":154,"author":{"gitId":"-"},"content":" * @see \u003ca href\u003d\"https://www.w3.org/TR/NOTE-datetime\"\u003ehttps://www.w3.org/TR/NOTE-datetime\u003c/a\u003e"},{"lineNumber":155,"author":{"gitId":"-"},"content":" */"},{"lineNumber":156,"author":{"gitId":"-"},"content":" public static Instant parseInstant(String dateTimeString) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" return OffsetDateTime.parse(dateTimeString).toInstant();"},{"lineNumber":159,"author":{"gitId":"-"},"content":" } catch (DateTimeParseException e) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" assert false : \"Date in String is in wrong format.\";"},{"lineNumber":161,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":12,"-":153}},{"path":"src/main/java/teammates/logic/api/LogsProcessor.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.logic.api;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.QueryLogsResults;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.GeneralLogEntry;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.LogEvent;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.QueryLogsParams;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.logic.external.GoogleCloudLoggingService;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.logic.external.LocalLoggingService;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.logic.external.LogService;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * Handles operations related to logs reading/writing."},{"lineNumber":19,"author":{"gitId":"-"},"content":" *"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * \u003cp\u003eNote that while this interface should support writing logs, most of the application/system logs"},{"lineNumber":21,"author":{"gitId":"-"},"content":" * should be written via the standard Logger class."},{"lineNumber":22,"author":{"gitId":"-"},"content":" */"},{"lineNumber":23,"author":{"gitId":"-"},"content":"public class LogsProcessor {"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" private static final LogsProcessor instance \u003d new LogsProcessor();"},{"lineNumber":26,"author":{"gitId":"-"},"content":" private final LogService service;"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" LogsProcessor() {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" if (Config.IS_DEV_SERVER) {"},{"lineNumber":30,"author":{"gitId":"-"},"content":" service \u003d new LocalLoggingService();"},{"lineNumber":31,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" service \u003d new GoogleCloudLoggingService();"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" public static LogsProcessor inst() {"},{"lineNumber":37,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" }"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":41,"author":{"gitId":"-"},"content":" * Queries and retrieves logs with given parameters."},{"lineNumber":42,"author":{"gitId":"-"},"content":" */"},{"lineNumber":43,"author":{"gitId":"-"},"content":" public QueryLogsResults queryLogs(QueryLogsParams queryLogsParams) {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return service.queryLogs(queryLogsParams);"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":48,"author":{"gitId":"-"},"content":" * Creates a feedback session log."},{"lineNumber":49,"author":{"gitId":"-"},"content":" */"},{"lineNumber":50,"author":{"gitId":"-"},"content":" public void createFeedbackSessionLog(String courseId, String email, String fsName, String fslType) {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" service.createFeedbackSessionLog(courseId, email, fsName, fslType);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" }"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" * Creates a feedback session log."},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" public void createFeedbackSessionLog(String courseId, UUID studentId, UUID fsId, String fslType) {"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" service.createFeedbackSessionLog(courseId, studentId, fsId, fslType);"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" * Gets the feedback session logs as filtered by the given parameters ordered by ascending timestamp."},{"lineNumber":63,"author":{"gitId":"-"},"content":" * @param email Can be null"},{"lineNumber":64,"author":{"gitId":"-"},"content":" */"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" public List\u003cFeedbackSessionLogEntry\u003e getOrderedFeedbackSessionLogs(String courseId, String email,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" long startTime, long endTime, String fsName) {"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" return service.getOrderedFeedbackSessionLogs(courseId, email, startTime, endTime, fsName);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" }"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":71,"author":{"gitId":"-"},"content":" * Gets the number of logs for the event type and extra filters."},{"lineNumber":72,"author":{"gitId":"-"},"content":" */"},{"lineNumber":73,"author":{"gitId":"-"},"content":" public int getNumberOfLogsForEvent(Instant startTime, Instant endTime, LogEvent logEvent, String extraFilters) {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" int total \u003d 0;"},{"lineNumber":75,"author":{"gitId":"-"},"content":" long logStartTime \u003d startTime.toEpochMilli();"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" while (true) {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" QueryLogsParams logsParams \u003d QueryLogsParams.builder(logStartTime, endTime.toEpochMilli())"},{"lineNumber":79,"author":{"gitId":"-"},"content":" .withLogEvent(logEvent.name())"},{"lineNumber":80,"author":{"gitId":"-"},"content":" .withExtraFilters(extraFilters)"},{"lineNumber":81,"author":{"gitId":"-"},"content":" .withOrder(\"asc\")"},{"lineNumber":82,"author":{"gitId":"-"},"content":" .withPageSize(300)"},{"lineNumber":83,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":84,"author":{"gitId":"-"},"content":" QueryLogsResults logFetchResults \u003d queryLogs(logsParams);"},{"lineNumber":85,"author":{"gitId":"-"},"content":" List\u003cGeneralLogEntry\u003e logs \u003d logFetchResults.getLogEntries();"},{"lineNumber":86,"author":{"gitId":"-"},"content":" total +\u003d logs.size();"},{"lineNumber":87,"author":{"gitId":"-"},"content":" if (logFetchResults.getHasNextPage()) {"},{"lineNumber":88,"author":{"gitId":"-"},"content":" logStartTime \u003d logs.get(logs.size() - 1).getTimestamp();"},{"lineNumber":89,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":90,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":91,"author":{"gitId":"-"},"content":" }"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":" return total;"},{"lineNumber":94,"author":{"gitId":"-"},"content":" }"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":10,"-":86}},{"path":"src/main/java/teammates/logic/api/TaskQueuer.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.logic.api;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.ParamsNames;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.TaskQueue;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.TaskWrapper;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.logic.external.GoogleCloudTasksService;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.logic.external.LocalTaskQueueService;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.logic.external.TaskQueueService;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.ui.request.FeedbackSessionRemindRequest;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.ui.request.SendEmailRequest;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * Allows for adding specific type of tasks to the task queue."},{"lineNumber":21,"author":{"gitId":"-"},"content":" */"},{"lineNumber":22,"author":{"gitId":"-"},"content":"public class TaskQueuer {"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" private static final TaskQueuer instance \u003d new TaskQueuer();"},{"lineNumber":27,"author":{"gitId":"-"},"content":" private final TaskQueueService service;"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" TaskQueuer() {"},{"lineNumber":30,"author":{"gitId":"-"},"content":" if (Config.IS_DEV_SERVER) {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" service \u003d new LocalTaskQueueService();"},{"lineNumber":32,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" service \u003d new GoogleCloudTasksService();"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" public static TaskQueuer inst() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" // The following methods are facades to the actual logic for adding tasks to the queue."},{"lineNumber":42,"author":{"gitId":"-"},"content":" // Using this method, the actual logic can still be black-boxed"},{"lineNumber":43,"author":{"gitId":"-"},"content":" // while at the same time allowing this API to be mocked during test."},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" private void addTask(String queueName, String workerUrl, Map\u003cString, String\u003e paramMap, Object requestBody) {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" addDeferredTask(queueName, workerUrl, paramMap, requestBody, 0);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" }"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" void addDeferredTask(String queueName, String workerUrl, Map\u003cString, String\u003e paramMap, Object requestBody,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" long countdownTime) {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" TaskWrapper task \u003d new TaskWrapper(queueName, workerUrl, paramMap, requestBody);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" service.addDeferredTask(task, countdownTime);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" // The following methods are the actual API methods to be used by the client classes"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":58,"author":{"gitId":"-"},"content":" * Schedules for feedback session reminders (i.e. student has not submitted responses yet)"},{"lineNumber":59,"author":{"gitId":"-"},"content":" * for the specified feedback session."},{"lineNumber":60,"author":{"gitId":"-"},"content":" *"},{"lineNumber":61,"author":{"gitId":"-"},"content":" * @param courseId the course ID of the feedback session"},{"lineNumber":62,"author":{"gitId":"-"},"content":" * @param feedbackSessionName the name of the feedback session"},{"lineNumber":63,"author":{"gitId":"-"},"content":" */"},{"lineNumber":64,"author":{"gitId":"-"},"content":" public void scheduleFeedbackSessionReminders(String courseId, String feedbackSessionName,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" String googleIdOfRequestingInstructor) {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e paramMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":67,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.INSTRUCTOR_ID, googleIdOfRequestingInstructor);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.FEEDBACK_SESSION_NAME, feedbackSessionName);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.COURSE_ID, courseId);"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" addTask(TaskQueue.FEEDBACK_SESSION_REMIND_EMAIL_QUEUE_NAME,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" TaskQueue.FEEDBACK_SESSION_REMIND_EMAIL_WORKER_URL, paramMap, null);"},{"lineNumber":73,"author":{"gitId":"-"},"content":" }"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":76,"author":{"gitId":"-"},"content":" * Schedules for feedback session reminders (i.e. student/instructor has not submitted responses yet)"},{"lineNumber":77,"author":{"gitId":"-"},"content":" * for the specified feedback session for the specified group of users."},{"lineNumber":78,"author":{"gitId":"-"},"content":" *"},{"lineNumber":79,"author":{"gitId":"-"},"content":" * @param courseId the course ID of the feedback session"},{"lineNumber":80,"author":{"gitId":"-"},"content":" * @param feedbackSessionName the name of the feedback session"},{"lineNumber":81,"author":{"gitId":"-"},"content":" * @param usersToRemind the group of users to send the reminders to"},{"lineNumber":82,"author":{"gitId":"-"},"content":" * @param requestingInstructorId the ID of the instructor who sends the reminder"},{"lineNumber":83,"author":{"gitId":"-"},"content":" * @param isSendingCopyToInstructor the indicator of whether to send an email copy to the requesting instructor"},{"lineNumber":84,"author":{"gitId":"-"},"content":" */"},{"lineNumber":85,"author":{"gitId":"-"},"content":" public void scheduleFeedbackSessionRemindersForParticularUsers(String courseId, String feedbackSessionName,"},{"lineNumber":86,"author":{"gitId":"-"},"content":" String[] usersToRemind,"},{"lineNumber":87,"author":{"gitId":"-"},"content":" String requestingInstructorId,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" boolean isSendingCopyToInstructor) {"},{"lineNumber":89,"author":{"gitId":"-"},"content":" FeedbackSessionRemindRequest remindRequest \u003d"},{"lineNumber":90,"author":{"gitId":"-"},"content":" new FeedbackSessionRemindRequest(courseId, feedbackSessionName, requestingInstructorId, usersToRemind,"},{"lineNumber":91,"author":{"gitId":"-"},"content":" isSendingCopyToInstructor);"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" addTask(TaskQueue.FEEDBACK_SESSION_REMIND_PARTICULAR_USERS_EMAIL_QUEUE_NAME,"},{"lineNumber":94,"author":{"gitId":"-"},"content":" TaskQueue.FEEDBACK_SESSION_REMIND_PARTICULAR_USERS_EMAIL_WORKER_URL, new HashMap\u003c\u003e(), remindRequest);"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":98,"author":{"gitId":"-"},"content":" * Schedules for feedback session published email to be sent."},{"lineNumber":99,"author":{"gitId":"-"},"content":" *"},{"lineNumber":100,"author":{"gitId":"-"},"content":" * @param courseId the course ID of the feedback session"},{"lineNumber":101,"author":{"gitId":"-"},"content":" * @param feedbackSessionName the name of the feedback session"},{"lineNumber":102,"author":{"gitId":"-"},"content":" */"},{"lineNumber":103,"author":{"gitId":"-"},"content":" public void scheduleFeedbackSessionPublishedEmail(String courseId, String feedbackSessionName) {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e paramMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":105,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.COURSE_ID, courseId);"},{"lineNumber":106,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.FEEDBACK_SESSION_NAME, feedbackSessionName);"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" addTask(TaskQueue.FEEDBACK_SESSION_PUBLISHED_EMAIL_QUEUE_NAME,"},{"lineNumber":109,"author":{"gitId":"-"},"content":" TaskQueue.FEEDBACK_SESSION_PUBLISHED_EMAIL_WORKER_URL, paramMap, null);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":113,"author":{"gitId":"-"},"content":" * Schedules for feedback session publication reminders"},{"lineNumber":114,"author":{"gitId":"-"},"content":" * for the specified feedback session for the specified group of users."},{"lineNumber":115,"author":{"gitId":"-"},"content":" *"},{"lineNumber":116,"author":{"gitId":"-"},"content":" * @param courseId the course ID of the feedback session"},{"lineNumber":117,"author":{"gitId":"-"},"content":" * @param feedbackSessionName the name of the feedback session"},{"lineNumber":118,"author":{"gitId":"-"},"content":" * @param usersToEmail the group of users to send the reminders to"},{"lineNumber":119,"author":{"gitId":"-"},"content":" * @param requestingInstructorId the ID of the instructor who sends the reminder"},{"lineNumber":120,"author":{"gitId":"-"},"content":" */"},{"lineNumber":121,"author":{"gitId":"-"},"content":" public void scheduleFeedbackSessionResendPublishedEmail(String courseId, String feedbackSessionName,"},{"lineNumber":122,"author":{"gitId":"-"},"content":" String[] usersToEmail, String requestingInstructorId) {"},{"lineNumber":123,"author":{"gitId":"-"},"content":" FeedbackSessionRemindRequest remindRequest \u003d"},{"lineNumber":124,"author":{"gitId":"-"},"content":" new FeedbackSessionRemindRequest(courseId, feedbackSessionName, requestingInstructorId, usersToEmail, true);"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" addTask(TaskQueue.FEEDBACK_SESSION_RESEND_PUBLISHED_EMAIL_QUEUE_NAME,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" TaskQueue.FEEDBACK_SESSION_RESEND_PUBLISHED_EMAIL_WORKER_URL, new HashMap\u003c\u003e(), remindRequest);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":131,"author":{"gitId":"-"},"content":" * Schedules for feedback session unpublished email to be sent."},{"lineNumber":132,"author":{"gitId":"-"},"content":" *"},{"lineNumber":133,"author":{"gitId":"-"},"content":" * @param courseId the course ID of the feedback session"},{"lineNumber":134,"author":{"gitId":"-"},"content":" * @param feedbackSessionName the name of the feedback session"},{"lineNumber":135,"author":{"gitId":"-"},"content":" */"},{"lineNumber":136,"author":{"gitId":"-"},"content":" public void scheduleFeedbackSessionUnpublishedEmail(String courseId, String feedbackSessionName) {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e paramMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":138,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.COURSE_ID, courseId);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.FEEDBACK_SESSION_NAME, feedbackSessionName);"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" addTask(TaskQueue.FEEDBACK_SESSION_UNPUBLISHED_EMAIL_QUEUE_NAME,"},{"lineNumber":142,"author":{"gitId":"-"},"content":" TaskQueue.FEEDBACK_SESSION_UNPUBLISHED_EMAIL_WORKER_URL, paramMap, null);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" }"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":146,"author":{"gitId":"-"},"content":" * Schedules for course registration to be sent to the specified instructor."},{"lineNumber":147,"author":{"gitId":"-"},"content":" *"},{"lineNumber":148,"author":{"gitId":"-"},"content":" * @param inviterGoogleId googleId of instructor or administrator who sends the invitation"},{"lineNumber":149,"author":{"gitId":"-"},"content":" * @param courseId the target course ID"},{"lineNumber":150,"author":{"gitId":"-"},"content":" * @param instructorEmail the email address of the invited instructor"},{"lineNumber":151,"author":{"gitId":"-"},"content":" */"},{"lineNumber":152,"author":{"gitId":"-"},"content":" public void scheduleCourseRegistrationInviteToInstructor(String inviterGoogleId,"},{"lineNumber":153,"author":{"gitId":"-"},"content":" String instructorEmail, String courseId, boolean isRejoining) {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e paramMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":155,"author":{"gitId":"-"},"content":" if (inviterGoogleId !\u003d null) {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.INVITER_ID, inviterGoogleId);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" }"},{"lineNumber":158,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.INSTRUCTOR_EMAIL, instructorEmail);"},{"lineNumber":159,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.COURSE_ID, courseId);"},{"lineNumber":160,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.IS_INSTRUCTOR_REJOINING, String.valueOf(isRejoining));"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"-"},"content":" addTask(TaskQueue.INSTRUCTOR_COURSE_JOIN_EMAIL_QUEUE_NAME,"},{"lineNumber":163,"author":{"gitId":"-"},"content":" TaskQueue.INSTRUCTOR_COURSE_JOIN_EMAIL_WORKER_URL, paramMap, null);"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":167,"author":{"gitId":"-"},"content":" * Schedules for course registration to be sent to the specified student."},{"lineNumber":168,"author":{"gitId":"-"},"content":" *"},{"lineNumber":169,"author":{"gitId":"-"},"content":" * @param courseId the target course ID"},{"lineNumber":170,"author":{"gitId":"-"},"content":" * @param studentEmail the email address of the student"},{"lineNumber":171,"author":{"gitId":"-"},"content":" */"},{"lineNumber":172,"author":{"gitId":"-"},"content":" public void scheduleCourseRegistrationInviteToStudent(String courseId, String studentEmail, boolean isRejoining) {"},{"lineNumber":173,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e paramMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":174,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.COURSE_ID, courseId);"},{"lineNumber":175,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.STUDENT_EMAIL, studentEmail);"},{"lineNumber":176,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.IS_STUDENT_REJOINING, String.valueOf(isRejoining));"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" addTask(TaskQueue.STUDENT_COURSE_JOIN_EMAIL_QUEUE_NAME,"},{"lineNumber":179,"author":{"gitId":"-"},"content":" TaskQueue.STUDENT_COURSE_JOIN_EMAIL_WORKER_URL, paramMap, null);"},{"lineNumber":180,"author":{"gitId":"-"},"content":" }"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":183,"author":{"gitId":"-"},"content":" * Schedules for the given list of emails to be sent."},{"lineNumber":184,"author":{"gitId":"-"},"content":" *"},{"lineNumber":185,"author":{"gitId":"-"},"content":" * @param emails the list of emails to be sent"},{"lineNumber":186,"author":{"gitId":"-"},"content":" */"},{"lineNumber":187,"author":{"gitId":"-"},"content":" public void scheduleEmailsForSending(List\u003cEmailWrapper\u003e emails) {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" if (emails.isEmpty()) {"},{"lineNumber":189,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":190,"author":{"gitId":"-"},"content":" }"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"-"},"content":" // Equally spread out the emails to be sent over 1 hour"},{"lineNumber":193,"author":{"gitId":"-"},"content":" // Sets interval to a maximum of 5 seconds if the interval is too large"},{"lineNumber":194,"author":{"gitId":"-"},"content":" int oneHourInMillis \u003d 60 * 60 * 1000;"},{"lineNumber":195,"author":{"gitId":"-"},"content":" int emailIntervalMillis \u003d Math.min(5000, oneHourInMillis / emails.size());"},{"lineNumber":196,"author":{"gitId":"-"},"content":""},{"lineNumber":197,"author":{"gitId":"-"},"content":" long numberOfEmailsSent \u003d 0L;"},{"lineNumber":198,"author":{"gitId":"-"},"content":" for (EmailWrapper email : emails) {"},{"lineNumber":199,"author":{"gitId":"-"},"content":" long emailDelayTimer \u003d numberOfEmailsSent * emailIntervalMillis;"},{"lineNumber":200,"author":{"gitId":"-"},"content":" scheduleEmailForSending(email, emailDelayTimer);"},{"lineNumber":201,"author":{"gitId":"-"},"content":" numberOfEmailsSent++;"},{"lineNumber":202,"author":{"gitId":"-"},"content":" }"},{"lineNumber":203,"author":{"gitId":"-"},"content":" }"},{"lineNumber":204,"author":{"gitId":"-"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":206,"author":{"gitId":"-"},"content":" * Schedules for the search indexing of the instructor identified by {@code courseId} and {@code email}."},{"lineNumber":207,"author":{"gitId":"-"},"content":" *"},{"lineNumber":208,"author":{"gitId":"-"},"content":" * @param courseId the course ID of the instructor"},{"lineNumber":209,"author":{"gitId":"-"},"content":" * @param email the email of the instructor"},{"lineNumber":210,"author":{"gitId":"-"},"content":" */"},{"lineNumber":211,"author":{"gitId":"-"},"content":" public void scheduleInstructorForSearchIndexing(String courseId, String email) {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e paramMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":213,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.COURSE_ID, courseId);"},{"lineNumber":214,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.INSTRUCTOR_EMAIL, email);"},{"lineNumber":215,"author":{"gitId":"-"},"content":""},{"lineNumber":216,"author":{"gitId":"-"},"content":" addTask(TaskQueue.SEARCH_INDEXING_QUEUE_NAME, TaskQueue.INSTRUCTOR_SEARCH_INDEXING_WORKER_URL,"},{"lineNumber":217,"author":{"gitId":"-"},"content":" paramMap, null);"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":221,"author":{"gitId":"domoberzin"},"content":" * Schedules for the search indexing of the account request identified by {@code id}."},{"lineNumber":222,"author":{"gitId":"-"},"content":" *"},{"lineNumber":223,"author":{"gitId":"domoberzin"},"content":" * @param id the id associated with the account request"},{"lineNumber":224,"author":{"gitId":"-"},"content":" */"},{"lineNumber":225,"author":{"gitId":"domoberzin"},"content":" public void scheduleAccountRequestForSearchIndexing(String id) {"},{"lineNumber":226,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e paramMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":227,"author":{"gitId":"domoberzin"},"content":" paramMap.put(ParamsNames.ACCOUNT_REQUEST_ID, id);"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" addTask(TaskQueue.SEARCH_INDEXING_QUEUE_NAME, TaskQueue.ACCOUNT_REQUEST_SEARCH_INDEXING_WORKER_URL,"},{"lineNumber":230,"author":{"gitId":"-"},"content":" paramMap, null);"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":234,"author":{"gitId":"-"},"content":" * Schedules for the search indexing of the student identified by {@code courseId} and {@code email}."},{"lineNumber":235,"author":{"gitId":"-"},"content":" *"},{"lineNumber":236,"author":{"gitId":"-"},"content":" * @param courseId the course ID of the student"},{"lineNumber":237,"author":{"gitId":"-"},"content":" * @param email the email of the student"},{"lineNumber":238,"author":{"gitId":"-"},"content":" */"},{"lineNumber":239,"author":{"gitId":"-"},"content":" public void scheduleStudentForSearchIndexing(String courseId, String email) {"},{"lineNumber":240,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e paramMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":241,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.COURSE_ID, courseId);"},{"lineNumber":242,"author":{"gitId":"-"},"content":" paramMap.put(ParamsNames.STUDENT_EMAIL, email);"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" addTask(TaskQueue.SEARCH_INDEXING_QUEUE_NAME, TaskQueue.STUDENT_SEARCH_INDEXING_WORKER_URL,"},{"lineNumber":245,"author":{"gitId":"-"},"content":" paramMap, null);"},{"lineNumber":246,"author":{"gitId":"-"},"content":" }"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" private void scheduleEmailForSending(EmailWrapper email, long emailDelayTimer) {"},{"lineNumber":249,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":250,"author":{"gitId":"-"},"content":" SendEmailRequest request \u003d new SendEmailRequest(email);"},{"lineNumber":251,"author":{"gitId":"-"},"content":""},{"lineNumber":252,"author":{"gitId":"-"},"content":" addDeferredTask(TaskQueue.SEND_EMAIL_QUEUE_NAME, TaskQueue.SEND_EMAIL_WORKER_URL,"},{"lineNumber":253,"author":{"gitId":"-"},"content":" new HashMap\u003c\u003e(), request, emailDelayTimer);"},{"lineNumber":254,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" String emailSubject \u003d email.getSubject();"},{"lineNumber":256,"author":{"gitId":"-"},"content":" String emailSenderName \u003d email.getSenderName();"},{"lineNumber":257,"author":{"gitId":"-"},"content":" String emailSender \u003d email.getSenderEmail();"},{"lineNumber":258,"author":{"gitId":"-"},"content":" String emailReceiver \u003d email.getRecipient();"},{"lineNumber":259,"author":{"gitId":"-"},"content":" String emailReplyToAddress \u003d email.getReplyTo();"},{"lineNumber":260,"author":{"gitId":"-"},"content":""},{"lineNumber":261,"author":{"gitId":"-"},"content":" log.severe(\"Error when adding email to task queue: \" + e.getMessage() + \"\\n\""},{"lineNumber":262,"author":{"gitId":"-"},"content":" + \"Email sender: \" + emailSender + \"\\n\""},{"lineNumber":263,"author":{"gitId":"-"},"content":" + \"Email sender name: \" + emailSenderName + \"\\n\""},{"lineNumber":264,"author":{"gitId":"-"},"content":" + \"Email receiver: \" + emailReceiver + \"\\n\""},{"lineNumber":265,"author":{"gitId":"-"},"content":" + \"Email subject: \" + emailSubject + \"\\n\""},{"lineNumber":266,"author":{"gitId":"-"},"content":" + \"Email reply-to address: \" + emailReplyToAddress);"},{"lineNumber":267,"author":{"gitId":"-"},"content":" }"},{"lineNumber":268,"author":{"gitId":"-"},"content":" }"},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":4,"-":266}},{"path":"src/main/java/teammates/logic/external/GoogleCloudLoggingService.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.logic.external;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import com.google.api.gax.paging.Page;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import com.google.cloud.logging.LogEntry;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import com.google.cloud.logging.Logging;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import com.google.cloud.logging.Logging.EntryListOption;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import com.google.cloud.logging.Logging.SortingField;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import com.google.cloud.logging.Logging.SortingOrder;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import com.google.cloud.logging.LoggingOptions;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import com.google.cloud.logging.Payload;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import com.google.cloud.logging.Severity;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.QueryLogsResults;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionAuditLogDetails;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.GeneralLogEntry;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.LogDetails;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.LogEvent;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.LogSeverity;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.QueryLogsParams;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.SourceLocation;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":33,"author":{"gitId":"-"},"content":" * Holds functions for operations related to Google Cloud Logging."},{"lineNumber":34,"author":{"gitId":"-"},"content":" */"},{"lineNumber":35,"author":{"gitId":"-"},"content":"public class GoogleCloudLoggingService implements LogService {"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" private static final String RESOURCE_TYPE_GAE_APP \u003d \"gae_app\";"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" private static final String STDOUT_LOG_NAME \u003d \"stdout\";"},{"lineNumber":40,"author":{"gitId":"-"},"content":" private static final String STDERR_LOG_NAME \u003d \"stderr\";"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" private static final String ASCENDING_ORDER \u003d \"asc\";"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" private static final String TRACE_PREFIX \u003d String.format(\"projects/%s/traces/\", Config.APP_ID);"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":47,"author":{"gitId":"-"},"content":" public QueryLogsResults queryLogs(QueryLogsParams queryLogsParams) {"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" LogSearchParams logSearchParams \u003d LogSearchParams.from(queryLogsParams)"},{"lineNumber":50,"author":{"gitId":"-"},"content":" .addLogName(STDOUT_LOG_NAME)"},{"lineNumber":51,"author":{"gitId":"-"},"content":" .addLogName(STDERR_LOG_NAME)"},{"lineNumber":52,"author":{"gitId":"-"},"content":" .setResourceType(RESOURCE_TYPE_GAE_APP);"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" Page\u003cLogEntry\u003e logEntriesInPage \u003d getPageLogEntries(logSearchParams, queryLogsParams.getPageSize());"},{"lineNumber":55,"author":{"gitId":"-"},"content":" List\u003cGeneralLogEntry\u003e logEntries \u003d new ArrayList\u003c\u003e();"},{"lineNumber":56,"author":{"gitId":"-"},"content":" for (LogEntry entry : logEntriesInPage.getValues()) {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" Severity severity \u003d entry.getSeverity();"},{"lineNumber":58,"author":{"gitId":"-"},"content":" String trace \u003d entry.getTrace();"},{"lineNumber":59,"author":{"gitId":"-"},"content":" if (trace !\u003d null) {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" trace \u003d trace.replace(TRACE_PREFIX, \"\");"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":" String insertId \u003d entry.getInsertId();"},{"lineNumber":63,"author":{"gitId":"-"},"content":" com.google.cloud.logging.SourceLocation sourceLocation \u003d entry.getSourceLocation();"},{"lineNumber":64,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e resourceIdentifier \u003d entry.getResource().getLabels();"},{"lineNumber":65,"author":{"gitId":"-"},"content":" Payload\u003c?\u003e payload \u003d entry.getPayload();"},{"lineNumber":66,"author":{"gitId":"-"},"content":" long timestamp \u003d entry.getInstantTimestamp().toEpochMilli();"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" String file \u003d \"\";"},{"lineNumber":69,"author":{"gitId":"-"},"content":" Long line \u003d 0L;"},{"lineNumber":70,"author":{"gitId":"-"},"content":" String function \u003d \"\";"},{"lineNumber":71,"author":{"gitId":"-"},"content":" if (sourceLocation !\u003d null) {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" file \u003d sourceLocation.getFile();"},{"lineNumber":73,"author":{"gitId":"-"},"content":" line \u003d sourceLocation.getLine();"},{"lineNumber":74,"author":{"gitId":"-"},"content":" function \u003d sourceLocation.getFunction();"},{"lineNumber":75,"author":{"gitId":"-"},"content":" }"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" GeneralLogEntry logEntry \u003d new GeneralLogEntry(convertSeverity(severity), trace, insertId,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" resourceIdentifier, new SourceLocation(file, line, function), timestamp);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" if (payload.getType() \u003d\u003d Payload.Type.JSON) {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" Map\u003cString, Object\u003e jsonPayloadMap \u003d ((Payload.JsonPayload) payload).getDataAsMap();"},{"lineNumber":81,"author":{"gitId":"-"},"content":" logEntry.setDetails(JsonUtils.fromJson(JsonUtils.toCompactJson(jsonPayloadMap), LogDetails.class));"},{"lineNumber":82,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" String textPayloadMessage \u003d ((Payload.StringPayload) payload).getData();"},{"lineNumber":84,"author":{"gitId":"-"},"content":" logEntry.setMessage(textPayloadMessage);"},{"lineNumber":85,"author":{"gitId":"-"},"content":" }"},{"lineNumber":86,"author":{"gitId":"-"},"content":" logEntries.add(logEntry);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" }"},{"lineNumber":88,"author":{"gitId":"-"},"content":" boolean hasNextPage \u003d logEntriesInPage.getNextPageToken() !\u003d null;"},{"lineNumber":89,"author":{"gitId":"-"},"content":" return new QueryLogsResults(logEntries, hasNextPage);"},{"lineNumber":90,"author":{"gitId":"-"},"content":" }"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" private LogSeverity convertSeverity(Severity severity) {"},{"lineNumber":93,"author":{"gitId":"-"},"content":" if (severity \u003d\u003d Severity.ERROR) {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" return LogSeverity.ERROR;"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":" if (severity \u003d\u003d Severity.WARNING) {"},{"lineNumber":97,"author":{"gitId":"-"},"content":" return LogSeverity.WARNING;"},{"lineNumber":98,"author":{"gitId":"-"},"content":" }"},{"lineNumber":99,"author":{"gitId":"-"},"content":" if (severity \u003d\u003d Severity.INFO || severity \u003d\u003d Severity.NOTICE) {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" return LogSeverity.INFO;"},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":" if (severity \u003d\u003d Severity.CRITICAL || severity \u003d\u003d Severity.ALERT || severity \u003d\u003d Severity.EMERGENCY) {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" return LogSeverity.CRITICAL;"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":" if (severity \u003d\u003d Severity.DEBUG) {"},{"lineNumber":106,"author":{"gitId":"-"},"content":" return LogSeverity.DEBUG;"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":" return LogSeverity.DEFAULT;"},{"lineNumber":109,"author":{"gitId":"-"},"content":" }"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":112,"author":{"gitId":"-"},"content":" public void createFeedbackSessionLog(String courseId, String email, String fsName, String fslType) {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" // This method is not necessary for production usage because a feedback session log"},{"lineNumber":114,"author":{"gitId":"-"},"content":" // is already separately created through the standardized logging infrastructure."},{"lineNumber":115,"author":{"gitId":"-"},"content":" // However, this method is not removed as it is necessary to assist in local testing."},{"lineNumber":116,"author":{"gitId":"-"},"content":" }"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" public void createFeedbackSessionLog(String courseId, UUID studentId, UUID fsId, String fslType) {"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" // This method is not necessary for production usage because a feedback session log"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" // is already separately created through the standardized logging infrastructure."},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" // However, this method is not removed as it is necessary to assist in local testing."},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" public List\u003cFeedbackSessionLogEntry\u003e getOrderedFeedbackSessionLogs(String courseId, String email,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" long startTime, long endTime, String fsName) {"},{"lineNumber":128,"author":{"gitId":"-"},"content":" List\u003cString\u003e filters \u003d new ArrayList\u003c\u003e();"},{"lineNumber":129,"author":{"gitId":"-"},"content":" if (courseId !\u003d null) {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" filters.add(\"jsonPayload.courseId\u003d\\\"\" + courseId + \"\\\"\");"},{"lineNumber":131,"author":{"gitId":"-"},"content":" }"},{"lineNumber":132,"author":{"gitId":"-"},"content":" if (email !\u003d null) {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" filters.add(\"jsonPayload.studentEmail\u003d\\\"\" + email + \"\\\"\");"},{"lineNumber":134,"author":{"gitId":"-"},"content":" }"},{"lineNumber":135,"author":{"gitId":"-"},"content":" if (fsName !\u003d null) {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" filters.add(\"jsonPayload.feedbackSessionName\u003d\\\"\" + fsName + \"\\\"\");"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":" QueryLogsParams queryLogsParams \u003d QueryLogsParams.builder(startTime, endTime)"},{"lineNumber":139,"author":{"gitId":"-"},"content":" .withLogEvent(LogEvent.FEEDBACK_SESSION_AUDIT.name())"},{"lineNumber":140,"author":{"gitId":"-"},"content":" .withSeverityLevel(LogSeverity.INFO)"},{"lineNumber":141,"author":{"gitId":"-"},"content":" .withExtraFilters(String.join(\"\\n\", filters))"},{"lineNumber":142,"author":{"gitId":"dishenggg"},"content":" .withOrder(ASCENDING_ORDER)"},{"lineNumber":143,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":144,"author":{"gitId":"-"},"content":" LogSearchParams logSearchParams \u003d LogSearchParams.from(queryLogsParams)"},{"lineNumber":145,"author":{"gitId":"-"},"content":" .addLogName(STDOUT_LOG_NAME)"},{"lineNumber":146,"author":{"gitId":"-"},"content":" .setResourceType(RESOURCE_TYPE_GAE_APP);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" List\u003cLogEntry\u003e logEntries \u003d getAllLogEntries(logSearchParams);"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogEntry\u003e fsLogEntries \u003d new ArrayList\u003c\u003e();"},{"lineNumber":150,"author":{"gitId":"-"},"content":" for (LogEntry entry : logEntries) {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" long timestamp \u003d entry.getInstantTimestamp().toEpochMilli();"},{"lineNumber":152,"author":{"gitId":"-"},"content":" Payload\u003c?\u003e payload \u003d entry.getPayload();"},{"lineNumber":153,"author":{"gitId":"-"},"content":" FeedbackSessionAuditLogDetails details;"},{"lineNumber":154,"author":{"gitId":"-"},"content":" if (payload.getType() \u003d\u003d Payload.Type.JSON) {"},{"lineNumber":155,"author":{"gitId":"-"},"content":" Map\u003cString, Object\u003e jsonPayloadMap \u003d ((Payload.JsonPayload) payload).getDataAsMap();"},{"lineNumber":156,"author":{"gitId":"-"},"content":" LogDetails logDetails \u003d JsonUtils.fromJson(JsonUtils.toCompactJson(jsonPayloadMap), LogDetails.class);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" if (!(logDetails instanceof FeedbackSessionAuditLogDetails)) {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"-"},"content":" details \u003d (FeedbackSessionAuditLogDetails) logDetails;"},{"lineNumber":161,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"dishenggg"},"content":" UUID studentId \u003d details.getStudentId() !\u003d null ? UUID.fromString(details.getStudentId()) : null;"},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":" UUID fsId \u003d details.getFeedbackSessionId() !\u003d null ? UUID.fromString(details.getFeedbackSessionId()) : null;"},{"lineNumber":167,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogEntry fslEntry;"},{"lineNumber":168,"author":{"gitId":"dishenggg"},"content":" if (fsId !\u003d null \u0026\u0026 studentId !\u003d null) {"},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":" fslEntry \u003d new FeedbackSessionLogEntry(details.getCourseId(), studentId, fsId, details.getAccessType(),"},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" timestamp);"},{"lineNumber":171,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":" fslEntry \u003d new FeedbackSessionLogEntry(details.getCourseId(), details.getStudentEmail(),"},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":" details.getFeedbackSessionName(), details.getAccessType(), timestamp);"},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":175,"author":{"gitId":"-"},"content":" fsLogEntries.add(fslEntry);"},{"lineNumber":176,"author":{"gitId":"-"},"content":" }"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" return fsLogEntries;"},{"lineNumber":179,"author":{"gitId":"-"},"content":" }"},{"lineNumber":180,"author":{"gitId":"-"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":" private List\u003cLogEntry\u003e getAllLogEntries(LogSearchParams logSearchParams) {"},{"lineNumber":182,"author":{"gitId":"-"},"content":" Logging logging \u003d LoggingOptions.getDefaultInstance().getService();"},{"lineNumber":183,"author":{"gitId":"-"},"content":" List\u003cEntryListOption\u003e entryListOptions \u003d convertLogSearchParams(logSearchParams, 0);"},{"lineNumber":184,"author":{"gitId":"-"},"content":" Page\u003cLogEntry\u003e entries \u003d logging.listLogEntries(entryListOptions.toArray(new EntryListOption[] {}));"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" List\u003cLogEntry\u003e logEntries \u003d new ArrayList\u003c\u003e();"},{"lineNumber":187,"author":{"gitId":"-"},"content":" for (LogEntry entry : entries.iterateAll()) {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" logEntries.add(entry);"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":192,"author":{"gitId":"-"},"content":" logging.close();"},{"lineNumber":193,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":194,"author":{"gitId":"-"},"content":" // ignore exception when closing resource"},{"lineNumber":195,"author":{"gitId":"-"},"content":" }"},{"lineNumber":196,"author":{"gitId":"-"},"content":" return logEntries;"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" private Page\u003cLogEntry\u003e getPageLogEntries(LogSearchParams logSearchParams, int pageSize) {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" Logging logging \u003d LoggingOptions.getDefaultInstance().getService();"},{"lineNumber":201,"author":{"gitId":"-"},"content":" List\u003cEntryListOption\u003e entryListOptions \u003d convertLogSearchParams(logSearchParams, pageSize);"},{"lineNumber":202,"author":{"gitId":"-"},"content":" Page\u003cLogEntry\u003e entries \u003d logging.listLogEntries(entryListOptions.toArray(new EntryListOption[] {}));"},{"lineNumber":203,"author":{"gitId":"-"},"content":""},{"lineNumber":204,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" logging.close();"},{"lineNumber":206,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":207,"author":{"gitId":"-"},"content":" // ignore exception when closing resource"},{"lineNumber":208,"author":{"gitId":"-"},"content":" }"},{"lineNumber":209,"author":{"gitId":"-"},"content":" return entries;"},{"lineNumber":210,"author":{"gitId":"-"},"content":" }"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" private List\u003cEntryListOption\u003e convertLogSearchParams(LogSearchParams s, int pageSize) {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" LoggingOptions options \u003d LoggingOptions.getDefaultInstance();"},{"lineNumber":214,"author":{"gitId":"-"},"content":" QueryLogsParams q \u003d s.queryLogsParams;"},{"lineNumber":215,"author":{"gitId":"-"},"content":""},{"lineNumber":216,"author":{"gitId":"-"},"content":" List\u003cString\u003e logFilters \u003d new ArrayList\u003c\u003e();"},{"lineNumber":217,"author":{"gitId":"-"},"content":" logFilters.add(\"timestamp\u003e\\\"\" + Instant.ofEpochMilli(q.getStartTime()).toString() + \"\\\"\");"},{"lineNumber":218,"author":{"gitId":"-"},"content":" logFilters.add(\"timestamp\u003c\u003d\\\"\" + Instant.ofEpochMilli(q.getEndTime()).toString() + \"\\\"\");"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" if (!s.logName.isEmpty()) {"},{"lineNumber":221,"author":{"gitId":"-"},"content":" String logNameFilter \u003d s.logName.stream()"},{"lineNumber":222,"author":{"gitId":"-"},"content":" .map(str -\u003e \"\\\"projects/\" + options.getProjectId() + \"/logs/\" + str + \"\\\"\")"},{"lineNumber":223,"author":{"gitId":"-"},"content":" .collect(Collectors.joining(\" OR \"));"},{"lineNumber":224,"author":{"gitId":"-"},"content":" logFilters.add(\"logName\u003d(\" + logNameFilter + \")\");"},{"lineNumber":225,"author":{"gitId":"-"},"content":" }"},{"lineNumber":226,"author":{"gitId":"-"},"content":" if (s.resourceType !\u003d null) {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" logFilters.add(\"resource.type\u003d\\\"\" + s.resourceType + \"\\\"\");"},{"lineNumber":228,"author":{"gitId":"-"},"content":" }"},{"lineNumber":229,"author":{"gitId":"-"},"content":" if (q.getSeverity() !\u003d null) {"},{"lineNumber":230,"author":{"gitId":"-"},"content":" logFilters.add(\"severity\u003d\" + q.getSeverity());"},{"lineNumber":231,"author":{"gitId":"-"},"content":" } else if (q.getMinSeverity() !\u003d null \u0026\u0026 q.getSeverity() \u003d\u003d null) {"},{"lineNumber":232,"author":{"gitId":"-"},"content":" logFilters.add(\"severity\u003e\u003d\" + q.getMinSeverity());"},{"lineNumber":233,"author":{"gitId":"-"},"content":" }"},{"lineNumber":234,"author":{"gitId":"-"},"content":" if (q.getTraceId() !\u003d null) {"},{"lineNumber":235,"author":{"gitId":"-"},"content":" logFilters.add(\"trace\u003d\\\"\" + TRACE_PREFIX + q.getTraceId() + \"\\\"\");"},{"lineNumber":236,"author":{"gitId":"-"},"content":" }"},{"lineNumber":237,"author":{"gitId":"-"},"content":" if (q.getActionClass() !\u003d null) {"},{"lineNumber":238,"author":{"gitId":"-"},"content":" logFilters.add(\"jsonPayload.actionClass\u003d\\\"\" + q.getActionClass() + \"\\\"\");"},{"lineNumber":239,"author":{"gitId":"-"},"content":" }"},{"lineNumber":240,"author":{"gitId":"-"},"content":" if (q.getUserInfoParams() !\u003d null) {"},{"lineNumber":241,"author":{"gitId":"-"},"content":" if (q.getUserInfoParams().getGoogleId() !\u003d null) {"},{"lineNumber":242,"author":{"gitId":"-"},"content":" logFilters.add(\"jsonPayload.userInfo.googleId\u003d\\\"\" + q.getUserInfoParams().getGoogleId() + \"\\\"\");"},{"lineNumber":243,"author":{"gitId":"-"},"content":" }"},{"lineNumber":244,"author":{"gitId":"-"},"content":" if (q.getUserInfoParams().getRegkey() !\u003d null) {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" logFilters.add(\"jsonPayload.userInfo.regkey\u003d\\\"\" + q.getUserInfoParams().getRegkey() + \"\\\"\");"},{"lineNumber":246,"author":{"gitId":"-"},"content":" }"},{"lineNumber":247,"author":{"gitId":"-"},"content":" if (q.getUserInfoParams().getEmail() !\u003d null) {"},{"lineNumber":248,"author":{"gitId":"-"},"content":" logFilters.add(\"jsonPayload.userInfo.email\u003d\\\"\" + q.getUserInfoParams().getEmail() + \"\\\"\");"},{"lineNumber":249,"author":{"gitId":"-"},"content":" }"},{"lineNumber":250,"author":{"gitId":"-"},"content":" }"},{"lineNumber":251,"author":{"gitId":"-"},"content":" if (q.getLogEvent() !\u003d null) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" logFilters.add(\"jsonPayload.event\u003d\\\"\" + q.getLogEvent() + \"\\\"\");"},{"lineNumber":253,"author":{"gitId":"-"},"content":" }"},{"lineNumber":254,"author":{"gitId":"-"},"content":" if (q.getSourceLocation() !\u003d null \u0026\u0026 q.getSourceLocation().getFile() !\u003d null) {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" if (q.getSourceLocation().getFunction() \u003d\u003d null) {"},{"lineNumber":256,"author":{"gitId":"-"},"content":" logFilters.add(\"sourceLocation.file\u003d\\\"\" + q.getSourceLocation().getFile() + \"\\\"\");"},{"lineNumber":257,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" logFilters.add(\"sourceLocation.file\u003d\\\"\" + q.getSourceLocation().getFile()"},{"lineNumber":259,"author":{"gitId":"-"},"content":" + \"\\\" AND sourceLocation.function\u003d\\\"\" + q.getSourceLocation().getFunction() + \"\\\"\");"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":" }"},{"lineNumber":262,"author":{"gitId":"-"},"content":" if (q.getExceptionClass() !\u003d null) {"},{"lineNumber":263,"author":{"gitId":"-"},"content":" logFilters.add(\"jsonPayload.exceptionClass\u003d\\\"\" + q.getExceptionClass() + \"\\\"\");"},{"lineNumber":264,"author":{"gitId":"-"},"content":" }"},{"lineNumber":265,"author":{"gitId":"-"},"content":" if (q.getLatency() !\u003d null) {"},{"lineNumber":266,"author":{"gitId":"-"},"content":" logFilters.add(\"jsonPayload.responseTime\" + q.getLatency());"},{"lineNumber":267,"author":{"gitId":"-"},"content":" }"},{"lineNumber":268,"author":{"gitId":"-"},"content":" if (q.getStatus() !\u003d null) {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" logFilters.add(\"jsonPayload.responseStatus\u003d\" + q.getStatus());"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":" if (q.getVersion() !\u003d null) {"},{"lineNumber":272,"author":{"gitId":"-"},"content":" logFilters.add(\"jsonPayload.webVersion\u003d\\\"\" + q.getVersion() + \"\\\"\");"},{"lineNumber":273,"author":{"gitId":"-"},"content":" }"},{"lineNumber":274,"author":{"gitId":"-"},"content":" if (q.getExtraFilters() !\u003d null) {"},{"lineNumber":275,"author":{"gitId":"-"},"content":" logFilters.add(q.getExtraFilters());"},{"lineNumber":276,"author":{"gitId":"-"},"content":" }"},{"lineNumber":277,"author":{"gitId":"-"},"content":" String logFilter \u003d String.join(\"\\n\", logFilters);"},{"lineNumber":278,"author":{"gitId":"-"},"content":""},{"lineNumber":279,"author":{"gitId":"-"},"content":" List\u003cEntryListOption\u003e entryListOptions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":280,"author":{"gitId":"-"},"content":""},{"lineNumber":281,"author":{"gitId":"-"},"content":" entryListOptions.add(EntryListOption.filter(logFilter));"},{"lineNumber":282,"author":{"gitId":"-"},"content":""},{"lineNumber":283,"author":{"gitId":"-"},"content":" if (pageSize \u003e 0) {"},{"lineNumber":284,"author":{"gitId":"-"},"content":" entryListOptions.add(EntryListOption.pageSize(pageSize));"},{"lineNumber":285,"author":{"gitId":"-"},"content":" }"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"-"},"content":" if (q.getOrder() !\u003d null) {"},{"lineNumber":288,"author":{"gitId":"-"},"content":" if (ASCENDING_ORDER.equals(q.getOrder())) {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" entryListOptions.add(EntryListOption.sortOrder(SortingField.TIMESTAMP, SortingOrder.ASCENDING));"},{"lineNumber":290,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":291,"author":{"gitId":"-"},"content":" entryListOptions.add(EntryListOption.sortOrder(SortingField.TIMESTAMP, SortingOrder.DESCENDING));"},{"lineNumber":292,"author":{"gitId":"-"},"content":" }"},{"lineNumber":293,"author":{"gitId":"-"},"content":" }"},{"lineNumber":294,"author":{"gitId":"-"},"content":""},{"lineNumber":295,"author":{"gitId":"-"},"content":" return entryListOptions;"},{"lineNumber":296,"author":{"gitId":"-"},"content":" }"},{"lineNumber":297,"author":{"gitId":"-"},"content":""},{"lineNumber":298,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":299,"author":{"gitId":"-"},"content":" * Contains params to be used for the searching of logs."},{"lineNumber":300,"author":{"gitId":"-"},"content":" */"},{"lineNumber":301,"author":{"gitId":"-"},"content":" private static final class LogSearchParams {"},{"lineNumber":302,"author":{"gitId":"-"},"content":" private final List\u003cString\u003e logName \u003d new ArrayList\u003c\u003e();"},{"lineNumber":303,"author":{"gitId":"-"},"content":" private String resourceType;"},{"lineNumber":304,"author":{"gitId":"-"},"content":" private QueryLogsParams queryLogsParams;"},{"lineNumber":305,"author":{"gitId":"-"},"content":""},{"lineNumber":306,"author":{"gitId":"-"},"content":" static LogSearchParams from(QueryLogsParams queryLogsParams) {"},{"lineNumber":307,"author":{"gitId":"-"},"content":" return new LogSearchParams().setQueryLogsParams(queryLogsParams);"},{"lineNumber":308,"author":{"gitId":"-"},"content":" }"},{"lineNumber":309,"author":{"gitId":"-"},"content":""},{"lineNumber":310,"author":{"gitId":"-"},"content":" LogSearchParams addLogName(String logName) {"},{"lineNumber":311,"author":{"gitId":"-"},"content":" this.logName.add(logName);"},{"lineNumber":312,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":313,"author":{"gitId":"-"},"content":" }"},{"lineNumber":314,"author":{"gitId":"-"},"content":""},{"lineNumber":315,"author":{"gitId":"-"},"content":" LogSearchParams setResourceType(String resourceType) {"},{"lineNumber":316,"author":{"gitId":"-"},"content":" this.resourceType \u003d resourceType;"},{"lineNumber":317,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":318,"author":{"gitId":"-"},"content":" }"},{"lineNumber":319,"author":{"gitId":"-"},"content":""},{"lineNumber":320,"author":{"gitId":"-"},"content":" private LogSearchParams setQueryLogsParams(QueryLogsParams queryLogsParams) {"},{"lineNumber":321,"author":{"gitId":"-"},"content":" this.queryLogsParams \u003d queryLogsParams;"},{"lineNumber":322,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":323,"author":{"gitId":"-"},"content":" }"},{"lineNumber":324,"author":{"gitId":"-"},"content":" }"},{"lineNumber":325,"author":{"gitId":"-"},"content":""},{"lineNumber":326,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":19,"-":307}},{"path":"src/main/java/teammates/logic/external/LocalLoggingService.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.logic.external;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.lang.reflect.Type;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Collection;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.concurrent.ConcurrentHashMap;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import java.util.regex.Matcher;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import java.util.regex.Pattern;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"import org.apache.commons.math3.random.RandomDataGenerator;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"import com.google.common.reflect.TypeToken;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import com.google.gson.JsonParseException;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.QueryLogsResults;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.ExceptionLogDetails;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.GeneralLogEntry;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.LogDetails;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.LogEvent;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.QueryLogsParams;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.RequestLogDetails;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.RequestLogUser;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.common.util.FileHelper;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":33,"author":{"gitId":"-"},"content":" * Holds functions for operations related to logs reading/writing in local dev environment."},{"lineNumber":34,"author":{"gitId":"-"},"content":" *"},{"lineNumber":35,"author":{"gitId":"-"},"content":" * \u003cp\u003eThe current implementation uses an in-memory storage of logs to simulate the logs"},{"lineNumber":36,"author":{"gitId":"-"},"content":" * retention locally for feedback session logs only. It is not meant as a replacement but"},{"lineNumber":37,"author":{"gitId":"-"},"content":" * merely for testing purposes."},{"lineNumber":38,"author":{"gitId":"-"},"content":" */"},{"lineNumber":39,"author":{"gitId":"-"},"content":"public class LocalLoggingService implements LogService {"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" private static final Map\u003cString, List\u003cFeedbackSessionLogEntry\u003e\u003e FEEDBACK_SESSION_LOG_ENTRIES \u003d new ConcurrentHashMap\u003c\u003e();"},{"lineNumber":42,"author":{"gitId":"-"},"content":" private static final List\u003cGeneralLogEntry\u003e LOCAL_LOG_ENTRIES \u003d loadLocalLogEntries();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" private static final String ASCENDING_ORDER \u003d \"asc\";"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" private static List\u003cGeneralLogEntry\u003e loadLocalLogEntries() {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" // Timestamp of logs are randomly created to be within the last one hour"},{"lineNumber":47,"author":{"gitId":"-"},"content":" long currentTimestamp \u003d Instant.now().toEpochMilli();"},{"lineNumber":48,"author":{"gitId":"-"},"content":" long earliestTimestamp \u003d currentTimestamp - 60 * 60 * 1000;"},{"lineNumber":49,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" String jsonString \u003d FileHelper.readResourceFile(\"logsForLocalDev.json\");"},{"lineNumber":51,"author":{"gitId":"-"},"content":" Type type \u003d new TypeToken\u003cCollection\u003cGeneralLogEntry\u003e\u003e(){}.getType();"},{"lineNumber":52,"author":{"gitId":"-"},"content":" Collection\u003cGeneralLogEntry\u003e logEntriesCollection \u003d JsonUtils.fromJson(jsonString, type);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" return logEntriesCollection.stream()"},{"lineNumber":54,"author":{"gitId":"-"},"content":" .map(log -\u003e {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" long timestamp \u003d new RandomDataGenerator().nextLong(earliestTimestamp, currentTimestamp);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" GeneralLogEntry logEntryWithUpdatedTimestamp \u003d new GeneralLogEntry("},{"lineNumber":57,"author":{"gitId":"-"},"content":" log.getSeverity(), log.getTrace(), log.getInsertId(), log.getResourceIdentifier(),"},{"lineNumber":58,"author":{"gitId":"-"},"content":" log.getSourceLocation(), timestamp);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" logEntryWithUpdatedTimestamp.setDetails(log.getDetails());"},{"lineNumber":60,"author":{"gitId":"-"},"content":" logEntryWithUpdatedTimestamp.setMessage(log.getMessage());"},{"lineNumber":61,"author":{"gitId":"-"},"content":" return logEntryWithUpdatedTimestamp;"},{"lineNumber":62,"author":{"gitId":"-"},"content":" })"},{"lineNumber":63,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":64,"author":{"gitId":"-"},"content":" } catch (JsonParseException e) {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" return new ArrayList\u003c\u003e();"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":70,"author":{"gitId":"-"},"content":" public QueryLogsResults queryLogs(QueryLogsParams queryLogsParams) {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" // Page size is set as a small value to test loading of more logs"},{"lineNumber":72,"author":{"gitId":"-"},"content":" int pageSize \u003d 10;"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" List\u003cGeneralLogEntry\u003e result \u003d LOCAL_LOG_ENTRIES.stream()"},{"lineNumber":75,"author":{"gitId":"-"},"content":" .sorted((x, y) -\u003e {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" String order \u003d queryLogsParams.getOrder();"},{"lineNumber":77,"author":{"gitId":"-"},"content":" if (ASCENDING_ORDER.equals(order)) {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" return Long.compare(x.getTimestamp(), y.getTimestamp());"},{"lineNumber":79,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" return Long.compare(y.getTimestamp(), x.getTimestamp());"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":" })"},{"lineNumber":83,"author":{"gitId":"-"},"content":" .filter(log -\u003e queryLogsParams.getSeverity() \u003d\u003d null"},{"lineNumber":84,"author":{"gitId":"-"},"content":" || log.getSeverity().equals(queryLogsParams.getSeverity()))"},{"lineNumber":85,"author":{"gitId":"-"},"content":" .filter(log -\u003e queryLogsParams.getMinSeverity() \u003d\u003d null"},{"lineNumber":86,"author":{"gitId":"-"},"content":" || log.getSeverity().getSeverityLevel()"},{"lineNumber":87,"author":{"gitId":"-"},"content":" \u003e\u003d queryLogsParams.getMinSeverity().getSeverityLevel())"},{"lineNumber":88,"author":{"gitId":"-"},"content":" .filter(log -\u003e log.getTimestamp() \u003e queryLogsParams.getStartTime())"},{"lineNumber":89,"author":{"gitId":"-"},"content":" .filter(log -\u003e log.getTimestamp() \u003c\u003d queryLogsParams.getEndTime())"},{"lineNumber":90,"author":{"gitId":"-"},"content":" .filter(log -\u003e queryLogsParams.getTraceId() \u003d\u003d null"},{"lineNumber":91,"author":{"gitId":"-"},"content":" || queryLogsParams.getTraceId().equals(log.getTrace()))"},{"lineNumber":92,"author":{"gitId":"-"},"content":" .filter(log -\u003e queryLogsParams.getVersion() \u003d\u003d null"},{"lineNumber":93,"author":{"gitId":"-"},"content":" || queryLogsParams.getVersion().equals(log.getResourceIdentifier().get(\"version_id\")))"},{"lineNumber":94,"author":{"gitId":"-"},"content":" .filter(log -\u003e queryLogsParams.getSourceLocation().getFile() \u003d\u003d null"},{"lineNumber":95,"author":{"gitId":"-"},"content":" || log.getSourceLocation().getFile().equals(queryLogsParams.getSourceLocation().getFile()))"},{"lineNumber":96,"author":{"gitId":"-"},"content":" .filter(log -\u003e queryLogsParams.getSourceLocation().getFunction() \u003d\u003d null"},{"lineNumber":97,"author":{"gitId":"-"},"content":" || log.getSourceLocation().getFunction().equals(queryLogsParams.getSourceLocation().getFunction()))"},{"lineNumber":98,"author":{"gitId":"-"},"content":" .filter(log -\u003e isEventBasedFilterSatisfied(log, queryLogsParams))"},{"lineNumber":99,"author":{"gitId":"-"},"content":" .limit(pageSize)"},{"lineNumber":100,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" List\u003cGeneralLogEntry\u003e copiedResults \u003d deepCopyLogEntries(result);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" boolean hasNextPage \u003d copiedResults.size() \u003d\u003d pageSize;"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" return new QueryLogsResults(copiedResults, hasNextPage);"},{"lineNumber":106,"author":{"gitId":"-"},"content":" }"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" private boolean isEventBasedFilterSatisfied(GeneralLogEntry log, QueryLogsParams queryLogsParams) {"},{"lineNumber":109,"author":{"gitId":"-"},"content":" String actionClassFilter \u003d queryLogsParams.getActionClass();"},{"lineNumber":110,"author":{"gitId":"-"},"content":" String exceptionClassFilter \u003d queryLogsParams.getExceptionClass();"},{"lineNumber":111,"author":{"gitId":"-"},"content":" String logEventFilter \u003d queryLogsParams.getLogEvent();"},{"lineNumber":112,"author":{"gitId":"-"},"content":" String latencyFilter \u003d queryLogsParams.getLatency();"},{"lineNumber":113,"author":{"gitId":"-"},"content":" String statusFilter \u003d queryLogsParams.getStatus();"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" RequestLogUser userInfoFilter \u003d queryLogsParams.getUserInfoParams();"},{"lineNumber":116,"author":{"gitId":"-"},"content":" String regkeyFilter \u003d userInfoFilter.getRegkey();"},{"lineNumber":117,"author":{"gitId":"-"},"content":" String emailFilter \u003d userInfoFilter.getEmail();"},{"lineNumber":118,"author":{"gitId":"-"},"content":" String googleIdFilter \u003d userInfoFilter.getGoogleId();"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" if (actionClassFilter \u003d\u003d null \u0026\u0026 exceptionClassFilter \u003d\u003d null \u0026\u0026 logEventFilter \u003d\u003d null"},{"lineNumber":121,"author":{"gitId":"-"},"content":" \u0026\u0026 latencyFilter \u003d\u003d null \u0026\u0026 statusFilter \u003d\u003d null \u0026\u0026 regkeyFilter \u003d\u003d null"},{"lineNumber":122,"author":{"gitId":"-"},"content":" \u0026\u0026 emailFilter \u003d\u003d null \u0026\u0026 googleIdFilter \u003d\u003d null) {"},{"lineNumber":123,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":124,"author":{"gitId":"-"},"content":" }"},{"lineNumber":125,"author":{"gitId":"-"},"content":" LogDetails details \u003d log.getDetails();"},{"lineNumber":126,"author":{"gitId":"-"},"content":" if (details \u003d\u003d null) {"},{"lineNumber":127,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":" if (logEventFilter !\u003d null \u0026\u0026 !details.getEvent().name().equals(logEventFilter)) {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":131,"author":{"gitId":"-"},"content":" }"},{"lineNumber":132,"author":{"gitId":"-"},"content":" if (!isExceptionFilterSatisfied(details, exceptionClassFilter)) {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":134,"author":{"gitId":"-"},"content":" }"},{"lineNumber":135,"author":{"gitId":"-"},"content":" return isRequestFilterSatisfied(details, actionClassFilter, latencyFilter, statusFilter,"},{"lineNumber":136,"author":{"gitId":"-"},"content":" regkeyFilter, emailFilter, googleIdFilter);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" private boolean isExceptionFilterSatisfied(LogDetails details, String exceptionClassFilter) {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" if (exceptionClassFilter \u003d\u003d null) {"},{"lineNumber":141,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":142,"author":{"gitId":"-"},"content":" }"},{"lineNumber":143,"author":{"gitId":"-"},"content":" if (details.getEvent() !\u003d LogEvent.EXCEPTION_LOG) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":" ExceptionLogDetails exceptionDetails \u003d (ExceptionLogDetails) details;"},{"lineNumber":147,"author":{"gitId":"-"},"content":" return exceptionDetails.getExceptionClass().equals(exceptionClassFilter);"},{"lineNumber":148,"author":{"gitId":"-"},"content":" }"},{"lineNumber":149,"author":{"gitId":"-"},"content":""},{"lineNumber":150,"author":{"gitId":"-"},"content":" private boolean isRequestFilterSatisfied(LogDetails details, String actionClassFilter,"},{"lineNumber":151,"author":{"gitId":"-"},"content":" String latencyFilter, String statusFilter, String regkeyFilter, String emailFilter, String googleIdFilter) {"},{"lineNumber":152,"author":{"gitId":"-"},"content":" if (actionClassFilter \u003d\u003d null \u0026\u0026 latencyFilter \u003d\u003d null \u0026\u0026 statusFilter \u003d\u003d null"},{"lineNumber":153,"author":{"gitId":"-"},"content":" \u0026\u0026 regkeyFilter \u003d\u003d null \u0026\u0026 emailFilter \u003d\u003d null \u0026\u0026 googleIdFilter \u003d\u003d null) {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":155,"author":{"gitId":"-"},"content":" }"},{"lineNumber":156,"author":{"gitId":"-"},"content":" if (details.getEvent() !\u003d LogEvent.REQUEST_LOG) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":" RequestLogDetails requestDetails \u003d (RequestLogDetails) details;"},{"lineNumber":160,"author":{"gitId":"-"},"content":" if (actionClassFilter !\u003d null \u0026\u0026 !actionClassFilter.equals(requestDetails.getActionClass())) {"},{"lineNumber":161,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":" if (statusFilter !\u003d null \u0026\u0026 !statusFilter.equals(String.valueOf(requestDetails.getResponseStatus()))) {"},{"lineNumber":164,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":" if (latencyFilter !\u003d null) {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" Pattern p \u003d Pattern.compile(\"^(\u003e|\u003e\u003d|\u003c|\u003c\u003d) *(\\\\d+)$\");"},{"lineNumber":168,"author":{"gitId":"-"},"content":" Matcher m \u003d p.matcher(latencyFilter);"},{"lineNumber":169,"author":{"gitId":"-"},"content":" long logLatency \u003d ((RequestLogDetails) details).getResponseTime();"},{"lineNumber":170,"author":{"gitId":"-"},"content":" boolean isFilterSatisfied \u003d false;"},{"lineNumber":171,"author":{"gitId":"-"},"content":" if (m.matches()) {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" int time \u003d Integer.parseInt(m.group(2));"},{"lineNumber":173,"author":{"gitId":"-"},"content":" switch (m.group(1)) {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" case \"\u003e\":"},{"lineNumber":175,"author":{"gitId":"-"},"content":" isFilterSatisfied \u003d logLatency \u003e time;"},{"lineNumber":176,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":177,"author":{"gitId":"-"},"content":" case \"\u003e\u003d\":"},{"lineNumber":178,"author":{"gitId":"-"},"content":" isFilterSatisfied \u003d logLatency \u003e\u003d time;"},{"lineNumber":179,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":180,"author":{"gitId":"-"},"content":" case \"\u003c\":"},{"lineNumber":181,"author":{"gitId":"-"},"content":" isFilterSatisfied \u003d logLatency \u003c time;"},{"lineNumber":182,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":183,"author":{"gitId":"-"},"content":" case \"\u003c\u003d\":"},{"lineNumber":184,"author":{"gitId":"-"},"content":" isFilterSatisfied \u003d logLatency \u003c\u003d time;"},{"lineNumber":185,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":186,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":187,"author":{"gitId":"-"},"content":" assert false : \"Unreachable case\";"},{"lineNumber":188,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":" }"},{"lineNumber":191,"author":{"gitId":"-"},"content":" if (!isFilterSatisfied) {"},{"lineNumber":192,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":" }"},{"lineNumber":195,"author":{"gitId":"-"},"content":" RequestLogUser userInfo \u003d requestDetails.getUserInfo();"},{"lineNumber":196,"author":{"gitId":"-"},"content":" if (regkeyFilter !\u003d null \u0026\u0026 (userInfo \u003d\u003d null || !regkeyFilter.equals(userInfo.getRegkey()))) {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":198,"author":{"gitId":"-"},"content":" }"},{"lineNumber":199,"author":{"gitId":"-"},"content":" if (emailFilter !\u003d null \u0026\u0026 (userInfo \u003d\u003d null || !emailFilter.equals(userInfo.getEmail()))) {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":201,"author":{"gitId":"-"},"content":" }"},{"lineNumber":202,"author":{"gitId":"-"},"content":" return googleIdFilter \u003d\u003d null || userInfo !\u003d null \u0026\u0026 googleIdFilter.equals(userInfo.getGoogleId());"},{"lineNumber":203,"author":{"gitId":"-"},"content":" }"},{"lineNumber":204,"author":{"gitId":"-"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":206,"author":{"gitId":"-"},"content":" public void createFeedbackSessionLog(String courseId, String email, String fsName, String fslType) {"},{"lineNumber":207,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogEntry logEntry \u003d new FeedbackSessionLogEntry(courseId, email,"},{"lineNumber":208,"author":{"gitId":"dishenggg"},"content":" fsName, fslType, Instant.now().toEpochMilli());"},{"lineNumber":209,"author":{"gitId":"dishenggg"},"content":" FEEDBACK_SESSION_LOG_ENTRIES.computeIfAbsent(courseId, k -\u003e new ArrayList\u003c\u003e()).add(logEntry);"},{"lineNumber":210,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":211,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":212,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":213,"author":{"gitId":"dishenggg"},"content":" public void createFeedbackSessionLog(String courseId, UUID studentId, UUID fsId, String fslType) {"},{"lineNumber":214,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogEntry logEntry \u003d new FeedbackSessionLogEntry(courseId, studentId, fsId,"},{"lineNumber":215,"author":{"gitId":"-"},"content":" fslType, Instant.now().toEpochMilli());"},{"lineNumber":216,"author":{"gitId":"-"},"content":" FEEDBACK_SESSION_LOG_ENTRIES.computeIfAbsent(courseId, k -\u003e new ArrayList\u003c\u003e()).add(logEntry);"},{"lineNumber":217,"author":{"gitId":"-"},"content":" }"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":220,"author":{"gitId":"dishenggg"},"content":" public List\u003cFeedbackSessionLogEntry\u003e getOrderedFeedbackSessionLogs(String courseId, String email,"},{"lineNumber":221,"author":{"gitId":"-"},"content":" long startTime, long endTime, String fsName) {"},{"lineNumber":222,"author":{"gitId":"-"},"content":" return FEEDBACK_SESSION_LOG_ENTRIES"},{"lineNumber":223,"author":{"gitId":"-"},"content":" .getOrDefault(courseId, new ArrayList\u003c\u003e())"},{"lineNumber":224,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":225,"author":{"gitId":"-"},"content":" .filter(log -\u003e email \u003d\u003d null || log.getStudentEmail().equals(email))"},{"lineNumber":226,"author":{"gitId":"-"},"content":" .filter(log -\u003e fsName \u003d\u003d null || log.getFeedbackSessionName().equals(fsName))"},{"lineNumber":227,"author":{"gitId":"-"},"content":" .filter(log -\u003e log.getTimestamp() \u003e\u003d startTime)"},{"lineNumber":228,"author":{"gitId":"-"},"content":" .filter(log -\u003e log.getTimestamp() \u003c\u003d endTime)"},{"lineNumber":229,"author":{"gitId":"dishenggg"},"content":" .sorted()"},{"lineNumber":230,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" private List\u003cGeneralLogEntry\u003e deepCopyLogEntries(List\u003cGeneralLogEntry\u003e logEntries) {"},{"lineNumber":234,"author":{"gitId":"-"},"content":" List\u003cGeneralLogEntry\u003e result \u003d new ArrayList\u003c\u003e();"},{"lineNumber":235,"author":{"gitId":"-"},"content":" for (GeneralLogEntry logEntry : logEntries) {"},{"lineNumber":236,"author":{"gitId":"-"},"content":" GeneralLogEntry copiedEntry \u003d new GeneralLogEntry(logEntry.getSeverity(),"},{"lineNumber":237,"author":{"gitId":"-"},"content":" logEntry.getTrace(), logEntry.getInsertId(), logEntry.getResourceIdentifier(),"},{"lineNumber":238,"author":{"gitId":"-"},"content":" logEntry.getSourceLocation(), logEntry.getTimestamp());"},{"lineNumber":239,"author":{"gitId":"-"},"content":" copiedEntry.setDetails(JsonUtils.fromJson(JsonUtils.toCompactJson(logEntry.getDetails()), LogDetails.class));"},{"lineNumber":240,"author":{"gitId":"-"},"content":" copiedEntry.setMessage(logEntry.getMessage());"},{"lineNumber":241,"author":{"gitId":"-"},"content":" result.add(copiedEntry);"},{"lineNumber":242,"author":{"gitId":"-"},"content":" }"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" return result;"},{"lineNumber":245,"author":{"gitId":"-"},"content":" }"},{"lineNumber":246,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":11,"-":235}},{"path":"src/main/java/teammates/logic/external/LogService.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.logic.external;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.QueryLogsResults;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.QueryLogsParams;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * An interface used for logs operations such as reading/writing."},{"lineNumber":12,"author":{"gitId":"-"},"content":" */"},{"lineNumber":13,"author":{"gitId":"-"},"content":"public interface LogService {"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * Gets the list of logs satisfying the given criteria."},{"lineNumber":17,"author":{"gitId":"-"},"content":" */"},{"lineNumber":18,"author":{"gitId":"-"},"content":" QueryLogsResults queryLogs(QueryLogsParams queryLogsParams);"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":21,"author":{"gitId":"-"},"content":" * Creates a feedback session log."},{"lineNumber":22,"author":{"gitId":"-"},"content":" */"},{"lineNumber":23,"author":{"gitId":"-"},"content":" void createFeedbackSessionLog(String courseId, String email, String fsName, String fslType);"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" * Creates a feedback session log for migrated courses."},{"lineNumber":27,"author":{"gitId":"-"},"content":" */"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" void createFeedbackSessionLog(String courseId, UUID studentId, UUID fsId, String fslType);"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" * Gets the feedback session logs as filtered by the given parameters ordered by ascending timestamp."},{"lineNumber":32,"author":{"gitId":"-"},"content":" */"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntry\u003e getOrderedFeedbackSessionLogs(String courseId, String email,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" long startTime, long endTime, String fsName);"},{"lineNumber":35,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":6,"-":29}},{"path":"src/main/java/teammates/sqllogic/api/Logic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.api;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Set;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackQuestionRecipient;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.FeedbackResultFetchType;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationStyle;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationTargetUser;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.SqlSessionResultsBundle;"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EnrollException;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.exception.InstructorUpdateException;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.exception.StudentUpdateException;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.AccountRequestsLogic;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.AccountsLogic;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.CoursesLogic;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.DataBundleLogic;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.DeadlineExtensionsLogic;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.FeedbackQuestionsLogic;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.FeedbackResponseCommentsLogic;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.FeedbackResponsesLogic;"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":"import teammates.sqllogic.core.FeedbackSessionLogsLogic;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.FeedbackSessionsLogic;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.NotificationsLogic;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.UsageStatisticsLogic;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.UsersLogic;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":41,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":42,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":43,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":45,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":47,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":49,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":50,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":52,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.UsageStatistics;"},{"lineNumber":53,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.User;"},{"lineNumber":54,"author":{"gitId":"-"},"content":"import teammates.ui.request.FeedbackQuestionUpdateRequest;"},{"lineNumber":55,"author":{"gitId":"-"},"content":"import teammates.ui.request.FeedbackResponseCommentUpdateRequest;"},{"lineNumber":56,"author":{"gitId":"-"},"content":"import teammates.ui.request.InstructorCreateRequest;"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":59,"author":{"gitId":"-"},"content":" * Provides the business logic for production usage of the system."},{"lineNumber":60,"author":{"gitId":"-"},"content":" *"},{"lineNumber":61,"author":{"gitId":"-"},"content":" * \u003cp\u003eThis is a Facade class which simply forwards the method to internal classes."},{"lineNumber":62,"author":{"gitId":"-"},"content":" */"},{"lineNumber":63,"author":{"gitId":"-"},"content":"public class Logic {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" private static final Logic instance \u003d new Logic();"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" final AccountsLogic accountsLogic \u003d AccountsLogic.inst();"},{"lineNumber":67,"author":{"gitId":"-"},"content":" final AccountRequestsLogic accountRequestLogic \u003d AccountRequestsLogic.inst();"},{"lineNumber":68,"author":{"gitId":"-"},"content":" final CoursesLogic coursesLogic \u003d CoursesLogic.inst();"},{"lineNumber":69,"author":{"gitId":"-"},"content":" final DeadlineExtensionsLogic deadlineExtensionsLogic \u003d DeadlineExtensionsLogic.inst();"},{"lineNumber":70,"author":{"gitId":"-"},"content":" final FeedbackQuestionsLogic feedbackQuestionsLogic \u003d FeedbackQuestionsLogic.inst();"},{"lineNumber":71,"author":{"gitId":"-"},"content":" final FeedbackResponsesLogic feedbackResponsesLogic \u003d FeedbackResponsesLogic.inst();"},{"lineNumber":72,"author":{"gitId":"-"},"content":" final FeedbackResponseCommentsLogic feedbackResponseCommentsLogic \u003d FeedbackResponseCommentsLogic.inst();"},{"lineNumber":73,"author":{"gitId":"-"},"content":" final FeedbackSessionsLogic feedbackSessionsLogic \u003d FeedbackSessionsLogic.inst();"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" final FeedbackSessionLogsLogic feedbackSessionLogsLogic \u003d FeedbackSessionLogsLogic.inst();"},{"lineNumber":75,"author":{"gitId":"-"},"content":" final UsageStatisticsLogic usageStatisticsLogic \u003d UsageStatisticsLogic.inst();"},{"lineNumber":76,"author":{"gitId":"-"},"content":" final UsersLogic usersLogic \u003d UsersLogic.inst();"},{"lineNumber":77,"author":{"gitId":"-"},"content":" final NotificationsLogic notificationsLogic \u003d NotificationsLogic.inst();"},{"lineNumber":78,"author":{"gitId":"-"},"content":" final DataBundleLogic dataBundleLogic \u003d DataBundleLogic.inst();"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" Logic() {"},{"lineNumber":81,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":82,"author":{"gitId":"-"},"content":" }"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" public static Logic inst() {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" }"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":89,"author":{"gitId":"-"},"content":" * Creates an account request."},{"lineNumber":90,"author":{"gitId":"-"},"content":" *"},{"lineNumber":91,"author":{"gitId":"-"},"content":" * @return newly created account request."},{"lineNumber":92,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the account request details are invalid."},{"lineNumber":93,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the account request already exists."},{"lineNumber":94,"author":{"gitId":"-"},"content":" */"},{"lineNumber":95,"author":{"gitId":"-"},"content":" public AccountRequest createAccountRequest(String name, String email, String institute, AccountRequestStatus status,"},{"lineNumber":96,"author":{"gitId":"-"},"content":" String comments) throws InvalidParametersException {"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" return accountRequestLogic.createAccountRequest(name, email, institute, status, comments);"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":102,"author":{"gitId":"-"},"content":" * Gets the account request with the given {@code id}."},{"lineNumber":103,"author":{"gitId":"-"},"content":" *"},{"lineNumber":104,"author":{"gitId":"-"},"content":" * @return account request with the given {@code id}."},{"lineNumber":105,"author":{"gitId":"-"},"content":" */"},{"lineNumber":106,"author":{"gitId":"-"},"content":" public AccountRequest getAccountRequest(UUID id) {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" return accountRequestLogic.getAccountRequest(id);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" * Gets the account request with the given {@code id}."},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" * @return account request with the given {@code id}."},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" public AccountRequest getAccountRequestWithTransaction(UUID id) {"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" return accountRequestLogic.getAccountRequestWithTransaction(id);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" }"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":120,"author":{"gitId":"-"},"content":" * Creates a or gets an account request."},{"lineNumber":121,"author":{"gitId":"-"},"content":" *"},{"lineNumber":122,"author":{"gitId":"-"},"content":" * @return newly created account request."},{"lineNumber":123,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the account request details are invalid."},{"lineNumber":124,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the account request already exists."},{"lineNumber":125,"author":{"gitId":"-"},"content":" */"},{"lineNumber":126,"author":{"gitId":"-"},"content":" public AccountRequest createAccountRequestWithTransaction(String name, String email, String institute,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" AccountRequestStatus status, String comments) throws InvalidParametersException {"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" return accountRequestLogic.createOrGetAccountRequestWithTransaction(name, email, institute, status, comments);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" }"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" * Gets the account request with the associated {@code regkey}."},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":" * @return account request with the associated {@code regkey}."},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":" public AccountRequest getAccountRequestByRegistrationKey(String regkey) {"},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":" return accountRequestLogic.getAccountRequestByRegistrationKey(regkey);"},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":142,"author":{"gitId":"-"},"content":" * Updates the given account request."},{"lineNumber":143,"author":{"gitId":"-"},"content":" *"},{"lineNumber":144,"author":{"gitId":"-"},"content":" * @return the updated account request."},{"lineNumber":145,"author":{"gitId":"-"},"content":" */"},{"lineNumber":146,"author":{"gitId":"-"},"content":" public AccountRequest updateAccountRequest(AccountRequest accountRequest)"},{"lineNumber":147,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" return accountRequestLogic.updateAccountRequest(accountRequest);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" }"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":152,"author":{"gitId":"domoberzin"},"content":" * Updates the given account request."},{"lineNumber":153,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":154,"author":{"gitId":"domoberzin"},"content":" * @return the updated account request."},{"lineNumber":155,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":156,"author":{"gitId":"domoberzin"},"content":" public AccountRequest updateAccountRequestWithTransaction(AccountRequest accountRequest)"},{"lineNumber":157,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":158,"author":{"gitId":"domoberzin"},"content":" return accountRequestLogic.updateAccountRequestWithTransaction(accountRequest);"},{"lineNumber":159,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":160,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":162,"author":{"gitId":"dishenggg"},"content":" * Creates/Resets the account request with the given id"},{"lineNumber":163,"author":{"gitId":"-"},"content":" * such that it is not registered."},{"lineNumber":164,"author":{"gitId":"-"},"content":" *"},{"lineNumber":165,"author":{"gitId":"-"},"content":" * @return account request that is unregistered with the"},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":" * id."},{"lineNumber":167,"author":{"gitId":"-"},"content":" */"},{"lineNumber":168,"author":{"gitId":"dishenggg"},"content":" public AccountRequest resetAccountRequest(UUID id)"},{"lineNumber":169,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, InvalidParametersException {"},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" return accountRequestLogic.resetAccountRequest(id);"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":" * Deletes account request by id."},{"lineNumber":175,"author":{"gitId":"-"},"content":" *"},{"lineNumber":176,"author":{"gitId":"-"},"content":" * \u003cul\u003e"},{"lineNumber":177,"author":{"gitId":"-"},"content":" * \u003cli\u003eFails silently if no such account request.\u003c/li\u003e"},{"lineNumber":178,"author":{"gitId":"-"},"content":" * \u003c/ul\u003e"},{"lineNumber":179,"author":{"gitId":"-"},"content":" *"},{"lineNumber":180,"author":{"gitId":"-"},"content":" * \u003cp\u003ePreconditions:\u003c/p\u003e"},{"lineNumber":181,"author":{"gitId":"-"},"content":" * All parameters are non-null."},{"lineNumber":182,"author":{"gitId":"-"},"content":" */"},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":" public void deleteAccountRequest(UUID id) {"},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":" accountRequestLogic.deleteAccountRequest(id);"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":188,"author":{"gitId":"-"},"content":" * Gets all pending account requests."},{"lineNumber":189,"author":{"gitId":"-"},"content":" */"},{"lineNumber":190,"author":{"gitId":"-"},"content":" public List\u003cAccountRequest\u003e getPendingAccountRequests() {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" return accountRequestLogic.getPendingAccountRequests();"},{"lineNumber":192,"author":{"gitId":"-"},"content":" }"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" * Gets all pending account requests."},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccountRequest\u003e getAllAccountRequests() {"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" return accountRequestLogic.getAllAccountRequests();"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":200,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":201,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":202,"author":{"gitId":"domoberzin"},"content":" * Get a list of account requests associated with email provided."},{"lineNumber":203,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":204,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccountRequest\u003e getApprovedAccountRequestsForEmailWithTransaction(String email) {"},{"lineNumber":205,"author":{"gitId":"domoberzin"},"content":" return accountRequestLogic.getApprovedAccountRequestsForEmailWithTransaction(email);"},{"lineNumber":206,"author":{"gitId":"-"},"content":" }"},{"lineNumber":207,"author":{"gitId":"-"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":209,"author":{"gitId":"-"},"content":" * Gets an account."},{"lineNumber":210,"author":{"gitId":"-"},"content":" */"},{"lineNumber":211,"author":{"gitId":"-"},"content":" public Account getAccount(UUID id) {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" return accountsLogic.getAccount(id);"},{"lineNumber":213,"author":{"gitId":"-"},"content":" }"},{"lineNumber":214,"author":{"gitId":"-"},"content":""},{"lineNumber":215,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":216,"author":{"gitId":"-"},"content":" * Gets an account by googleId."},{"lineNumber":217,"author":{"gitId":"-"},"content":" */"},{"lineNumber":218,"author":{"gitId":"-"},"content":" public Account getAccountForGoogleId(String googleId) {"},{"lineNumber":219,"author":{"gitId":"-"},"content":" return accountsLogic.getAccountForGoogleId(googleId);"},{"lineNumber":220,"author":{"gitId":"-"},"content":" }"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":223,"author":{"gitId":"-"},"content":" * Get a list of accounts associated with email provided."},{"lineNumber":224,"author":{"gitId":"-"},"content":" */"},{"lineNumber":225,"author":{"gitId":"-"},"content":" public List\u003cAccount\u003e getAccountsForEmail(String email) {"},{"lineNumber":226,"author":{"gitId":"-"},"content":" return accountsLogic.getAccountsForEmail(email);"},{"lineNumber":227,"author":{"gitId":"-"},"content":" }"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":230,"author":{"gitId":"domoberzin"},"content":" * Get a list of accounts associated with email provided."},{"lineNumber":231,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":232,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccount\u003e getAccountsForEmailWithTransaction(String email) {"},{"lineNumber":233,"author":{"gitId":"domoberzin"},"content":" return accountsLogic.getAccountsForEmailWithTransaction(email);"},{"lineNumber":234,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":235,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":236,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":237,"author":{"gitId":"-"},"content":" * Creates an account."},{"lineNumber":238,"author":{"gitId":"-"},"content":" *"},{"lineNumber":239,"author":{"gitId":"-"},"content":" * @return the created account"},{"lineNumber":240,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the account is not valid"},{"lineNumber":241,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the account already exists in the database."},{"lineNumber":242,"author":{"gitId":"-"},"content":" */"},{"lineNumber":243,"author":{"gitId":"-"},"content":" public Account createAccount(Account account)"},{"lineNumber":244,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" return accountsLogic.createAccount(account);"},{"lineNumber":246,"author":{"gitId":"-"},"content":" }"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":249,"author":{"gitId":"domoberzin"},"content":" * Creates an account."},{"lineNumber":250,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":251,"author":{"gitId":"domoberzin"},"content":" * @return the created account"},{"lineNumber":252,"author":{"gitId":"domoberzin"},"content":" * @throws InvalidParametersException if the account is not valid"},{"lineNumber":253,"author":{"gitId":"domoberzin"},"content":" * @throws EntityAlreadyExistsException if the account already exists in the database."},{"lineNumber":254,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":255,"author":{"gitId":"domoberzin"},"content":" public Account createAccountWithTransaction(Account account)"},{"lineNumber":256,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":257,"author":{"gitId":"domoberzin"},"content":" return accountsLogic.createAccountWithTransaction(account);"},{"lineNumber":258,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":259,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":260,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":261,"author":{"gitId":"-"},"content":" * Deletes account by googleId."},{"lineNumber":262,"author":{"gitId":"-"},"content":" *"},{"lineNumber":263,"author":{"gitId":"-"},"content":" * \u003cul\u003e"},{"lineNumber":264,"author":{"gitId":"-"},"content":" * \u003cli\u003eFails silently if no such account.\u003c/li\u003e"},{"lineNumber":265,"author":{"gitId":"-"},"content":" * \u003c/ul\u003e"},{"lineNumber":266,"author":{"gitId":"-"},"content":" *"},{"lineNumber":267,"author":{"gitId":"-"},"content":" * \u003cp\u003ePreconditions:\u003c/p\u003e"},{"lineNumber":268,"author":{"gitId":"-"},"content":" * All parameters are non-null."},{"lineNumber":269,"author":{"gitId":"-"},"content":" */"},{"lineNumber":270,"author":{"gitId":"-"},"content":" public void deleteAccount(String googleId) {"},{"lineNumber":271,"author":{"gitId":"-"},"content":" accountsLogic.deleteAccount(googleId);"},{"lineNumber":272,"author":{"gitId":"-"},"content":" }"},{"lineNumber":273,"author":{"gitId":"-"},"content":""},{"lineNumber":274,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":275,"author":{"gitId":"-"},"content":" * Deletes account and all users by googleId."},{"lineNumber":276,"author":{"gitId":"-"},"content":" *"},{"lineNumber":277,"author":{"gitId":"-"},"content":" * \u003cul\u003e"},{"lineNumber":278,"author":{"gitId":"-"},"content":" * \u003cli\u003eFails silently if no such account.\u003c/li\u003e"},{"lineNumber":279,"author":{"gitId":"-"},"content":" * \u003c/ul\u003e"},{"lineNumber":280,"author":{"gitId":"-"},"content":" *"},{"lineNumber":281,"author":{"gitId":"-"},"content":" * \u003cp\u003ePreconditions:\u003c/p\u003e"},{"lineNumber":282,"author":{"gitId":"-"},"content":" * All parameters are non-null."},{"lineNumber":283,"author":{"gitId":"-"},"content":" */"},{"lineNumber":284,"author":{"gitId":"-"},"content":" public void deleteAccountCascade(String googleId) {"},{"lineNumber":285,"author":{"gitId":"-"},"content":" accountsLogic.deleteAccountCascade(googleId);"},{"lineNumber":286,"author":{"gitId":"-"},"content":" }"},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":289,"author":{"gitId":"-"},"content":" * Gets all students associated with a googleId."},{"lineNumber":290,"author":{"gitId":"-"},"content":" */"},{"lineNumber":291,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsByGoogleId(String googleId) {"},{"lineNumber":292,"author":{"gitId":"-"},"content":" return usersLogic.getStudentsByGoogleId(googleId);"},{"lineNumber":293,"author":{"gitId":"-"},"content":" }"},{"lineNumber":294,"author":{"gitId":"-"},"content":""},{"lineNumber":295,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":296,"author":{"gitId":"-"},"content":" * Gets a course by course id."},{"lineNumber":297,"author":{"gitId":"-"},"content":" * @param courseId courseId of the course."},{"lineNumber":298,"author":{"gitId":"-"},"content":" * @return the specified course."},{"lineNumber":299,"author":{"gitId":"-"},"content":" */"},{"lineNumber":300,"author":{"gitId":"-"},"content":" public Course getCourse(String courseId) {"},{"lineNumber":301,"author":{"gitId":"-"},"content":" return coursesLogic.getCourse(courseId);"},{"lineNumber":302,"author":{"gitId":"-"},"content":" }"},{"lineNumber":303,"author":{"gitId":"-"},"content":""},{"lineNumber":304,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":305,"author":{"gitId":"domoberzin"},"content":" * Gets a section from a course by section name."},{"lineNumber":306,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":307,"author":{"gitId":"domoberzin"},"content":" public Section getSection(String courseId, String section) {"},{"lineNumber":308,"author":{"gitId":"domoberzin"},"content":" return usersLogic.getSection(courseId, section);"},{"lineNumber":309,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":310,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":311,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":312,"author":{"gitId":"-"},"content":" * Gets courses associated with student."},{"lineNumber":313,"author":{"gitId":"-"},"content":" * Preconditions: \u003cbr\u003e"},{"lineNumber":314,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":315,"author":{"gitId":"-"},"content":" */"},{"lineNumber":316,"author":{"gitId":"-"},"content":" public List\u003cCourse\u003e getCoursesForStudentAccount(String googleId) {"},{"lineNumber":317,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":318,"author":{"gitId":"-"},"content":""},{"lineNumber":319,"author":{"gitId":"-"},"content":" return coursesLogic.getCoursesForStudentAccount(googleId);"},{"lineNumber":320,"author":{"gitId":"-"},"content":" }"},{"lineNumber":321,"author":{"gitId":"-"},"content":""},{"lineNumber":322,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":323,"author":{"gitId":"-"},"content":" * Gets courses associated with instructors."},{"lineNumber":324,"author":{"gitId":"-"},"content":" * Preconditions: \u003cbr\u003e"},{"lineNumber":325,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":326,"author":{"gitId":"-"},"content":" *"},{"lineNumber":327,"author":{"gitId":"-"},"content":" * @return Courses the given instructors is in except for courses in Recycle Bin."},{"lineNumber":328,"author":{"gitId":"-"},"content":" */"},{"lineNumber":329,"author":{"gitId":"-"},"content":" public List\u003cCourse\u003e getCoursesForInstructors(List\u003cInstructor\u003e instructorsList) {"},{"lineNumber":330,"author":{"gitId":"-"},"content":" assert instructorsList !\u003d null;"},{"lineNumber":331,"author":{"gitId":"-"},"content":""},{"lineNumber":332,"author":{"gitId":"-"},"content":" return coursesLogic.getCoursesForInstructors(instructorsList);"},{"lineNumber":333,"author":{"gitId":"-"},"content":" }"},{"lineNumber":334,"author":{"gitId":"-"},"content":""},{"lineNumber":335,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":336,"author":{"gitId":"-"},"content":" * Gets courses associated with instructors that are soft deleted."},{"lineNumber":337,"author":{"gitId":"-"},"content":" * Preconditions: \u003cbr\u003e"},{"lineNumber":338,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":339,"author":{"gitId":"-"},"content":" *"},{"lineNumber":340,"author":{"gitId":"-"},"content":" * @return Courses in Recycle Bin that the given instructors is in."},{"lineNumber":341,"author":{"gitId":"-"},"content":" */"},{"lineNumber":342,"author":{"gitId":"-"},"content":" public List\u003cCourse\u003e getSoftDeletedCoursesForInstructors(List\u003cInstructor\u003e instructorsList) {"},{"lineNumber":343,"author":{"gitId":"-"},"content":" assert instructorsList !\u003d null;"},{"lineNumber":344,"author":{"gitId":"-"},"content":""},{"lineNumber":345,"author":{"gitId":"-"},"content":" return coursesLogic.getSoftDeletedCoursesForInstructors(instructorsList);"},{"lineNumber":346,"author":{"gitId":"-"},"content":" }"},{"lineNumber":347,"author":{"gitId":"-"},"content":""},{"lineNumber":348,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":349,"author":{"gitId":"yuanxi1"},"content":" * Gets the institute of the course."},{"lineNumber":350,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":351,"author":{"gitId":"yuanxi1"},"content":" public String getCourseInstitute(String courseId) {"},{"lineNumber":352,"author":{"gitId":"yuanxi1"},"content":" return coursesLogic.getCourseInstitute(courseId);"},{"lineNumber":353,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":354,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":355,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":356,"author":{"gitId":"-"},"content":" * Creates a course."},{"lineNumber":357,"author":{"gitId":"-"},"content":" * @param course the course to create."},{"lineNumber":358,"author":{"gitId":"-"},"content":" * @return the created course."},{"lineNumber":359,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the course is not valid."},{"lineNumber":360,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the course already exists."},{"lineNumber":361,"author":{"gitId":"-"},"content":" */"},{"lineNumber":362,"author":{"gitId":"-"},"content":" public Course createCourse(Course course) throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":363,"author":{"gitId":"-"},"content":" return coursesLogic.createCourse(course);"},{"lineNumber":364,"author":{"gitId":"-"},"content":" }"},{"lineNumber":365,"author":{"gitId":"-"},"content":""},{"lineNumber":366,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":367,"author":{"gitId":"-"},"content":" * Deletes a course by course id."},{"lineNumber":368,"author":{"gitId":"-"},"content":" * @param courseId of course."},{"lineNumber":369,"author":{"gitId":"-"},"content":" */"},{"lineNumber":370,"author":{"gitId":"-"},"content":" public void deleteCourseCascade(String courseId) {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" coursesLogic.deleteCourseCascade(courseId);"},{"lineNumber":372,"author":{"gitId":"-"},"content":" }"},{"lineNumber":373,"author":{"gitId":"-"},"content":""},{"lineNumber":374,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":375,"author":{"gitId":"domoberzin"},"content":" * Updates a student by {@link Student}."},{"lineNumber":376,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":377,"author":{"gitId":"domoberzin"},"content":" * \u003cp\u003eIf email changed, update by recreating the student and cascade update all responses"},{"lineNumber":378,"author":{"gitId":"marquestye"},"content":" * and comments the student gives/receives."},{"lineNumber":379,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":380,"author":{"gitId":"domoberzin"},"content":" * \u003cp\u003eIf team changed, cascade delete all responses the student gives/receives within that team."},{"lineNumber":381,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":382,"author":{"gitId":"domoberzin"},"content":" * \u003cp\u003eIf section changed, cascade update all responses the student gives/receives."},{"lineNumber":383,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":384,"author":{"gitId":"domoberzin"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":385,"author":{"gitId":"marquestye"},"content":" * * Student parameter is non-null."},{"lineNumber":386,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":387,"author":{"gitId":"domoberzin"},"content":" * @return updated student"},{"lineNumber":388,"author":{"gitId":"domoberzin"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":389,"author":{"gitId":"domoberzin"},"content":" * @throws EntityDoesNotExistException if the student cannot be found"},{"lineNumber":390,"author":{"gitId":"domoberzin"},"content":" * @throws EntityAlreadyExistsException if the student cannot be updated"},{"lineNumber":391,"author":{"gitId":"domoberzin"},"content":" * by recreation because of an existent student"},{"lineNumber":392,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":393,"author":{"gitId":"domoberzin"},"content":" public Student updateStudentCascade(Student student)"},{"lineNumber":394,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException, EntityAlreadyExistsException {"},{"lineNumber":395,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":396,"author":{"gitId":"domoberzin"},"content":" assert student !\u003d null;"},{"lineNumber":397,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":398,"author":{"gitId":"domoberzin"},"content":" return usersLogic.updateStudentCascade(student);"},{"lineNumber":399,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":400,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":401,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":402,"author":{"gitId":"-"},"content":" * Moves a course to Recycle Bin by its given corresponding ID."},{"lineNumber":403,"author":{"gitId":"-"},"content":" * @return the deletion timestamp assigned to the course."},{"lineNumber":404,"author":{"gitId":"-"},"content":" */"},{"lineNumber":405,"author":{"gitId":"-"},"content":" public Course moveCourseToRecycleBin(String courseId) throws EntityDoesNotExistException {"},{"lineNumber":406,"author":{"gitId":"-"},"content":" return coursesLogic.moveCourseToRecycleBin(courseId);"},{"lineNumber":407,"author":{"gitId":"-"},"content":" }"},{"lineNumber":408,"author":{"gitId":"-"},"content":""},{"lineNumber":409,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":410,"author":{"gitId":"-"},"content":" * Restores a course and all data related to the course from Recycle Bin by"},{"lineNumber":411,"author":{"gitId":"-"},"content":" * its given corresponding ID."},{"lineNumber":412,"author":{"gitId":"-"},"content":" */"},{"lineNumber":413,"author":{"gitId":"-"},"content":" public void restoreCourseFromRecycleBin(String courseId) throws EntityDoesNotExistException {"},{"lineNumber":414,"author":{"gitId":"-"},"content":" coursesLogic.restoreCourseFromRecycleBin(courseId);"},{"lineNumber":415,"author":{"gitId":"-"},"content":" }"},{"lineNumber":416,"author":{"gitId":"-"},"content":""},{"lineNumber":417,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":418,"author":{"gitId":"-"},"content":" * Updates a course."},{"lineNumber":419,"author":{"gitId":"-"},"content":" *"},{"lineNumber":420,"author":{"gitId":"-"},"content":" * @return updated course"},{"lineNumber":421,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":422,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the course cannot be found"},{"lineNumber":423,"author":{"gitId":"-"},"content":" */"},{"lineNumber":424,"author":{"gitId":"-"},"content":" public Course updateCourse(String courseId, String name, String timezone)"},{"lineNumber":425,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":426,"author":{"gitId":"-"},"content":" return coursesLogic.updateCourse(courseId, name, timezone);"},{"lineNumber":427,"author":{"gitId":"-"},"content":" }"},{"lineNumber":428,"author":{"gitId":"-"},"content":""},{"lineNumber":429,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":430,"author":{"gitId":"-"},"content":" * Gets a list of section names for the given {@code courseId}."},{"lineNumber":431,"author":{"gitId":"-"},"content":" */"},{"lineNumber":432,"author":{"gitId":"-"},"content":" public List\u003cString\u003e getSectionNamesForCourse(String courseId)"},{"lineNumber":433,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":434,"author":{"gitId":"-"},"content":" return coursesLogic.getSectionNamesForCourse(courseId);"},{"lineNumber":435,"author":{"gitId":"-"},"content":" }"},{"lineNumber":436,"author":{"gitId":"-"},"content":""},{"lineNumber":437,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":438,"author":{"gitId":"-"},"content":" * Get section by {@code courseId} and {@code teamName}."},{"lineNumber":439,"author":{"gitId":"-"},"content":" */"},{"lineNumber":440,"author":{"gitId":"-"},"content":" public Section getSectionByCourseIdAndTeam(String courseId, String teamName) {"},{"lineNumber":441,"author":{"gitId":"-"},"content":" return coursesLogic.getSectionByCourseIdAndTeam(courseId, teamName);"},{"lineNumber":442,"author":{"gitId":"-"},"content":" }"},{"lineNumber":443,"author":{"gitId":"-"},"content":""},{"lineNumber":444,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":445,"author":{"gitId":"-"},"content":" * Creates a deadline extension."},{"lineNumber":446,"author":{"gitId":"-"},"content":" *"},{"lineNumber":447,"author":{"gitId":"-"},"content":" * @return created deadline extension"},{"lineNumber":448,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the deadline extension is not valid"},{"lineNumber":449,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the deadline extension already exist"},{"lineNumber":450,"author":{"gitId":"-"},"content":" */"},{"lineNumber":451,"author":{"gitId":"-"},"content":" public DeadlineExtension createDeadlineExtension(DeadlineExtension deadlineExtension)"},{"lineNumber":452,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":453,"author":{"gitId":"-"},"content":" return deadlineExtensionsLogic.createDeadlineExtension(deadlineExtension);"},{"lineNumber":454,"author":{"gitId":"-"},"content":" }"},{"lineNumber":455,"author":{"gitId":"-"},"content":""},{"lineNumber":456,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":457,"author":{"gitId":"-"},"content":" * Updates a deadline extension."},{"lineNumber":458,"author":{"gitId":"-"},"content":" *"},{"lineNumber":459,"author":{"gitId":"-"},"content":" * @return updated deadline extension"},{"lineNumber":460,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the deadline extension does not exist"},{"lineNumber":461,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the deadline extension is not valid"},{"lineNumber":462,"author":{"gitId":"-"},"content":" *"},{"lineNumber":463,"author":{"gitId":"-"},"content":" */"},{"lineNumber":464,"author":{"gitId":"-"},"content":" public DeadlineExtension updateDeadlineExtension(DeadlineExtension de)"},{"lineNumber":465,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":466,"author":{"gitId":"-"},"content":" return deadlineExtensionsLogic.updateDeadlineExtension(de);"},{"lineNumber":467,"author":{"gitId":"-"},"content":" }"},{"lineNumber":468,"author":{"gitId":"-"},"content":""},{"lineNumber":469,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":470,"author":{"gitId":"-"},"content":" * Deletes a deadline extension."},{"lineNumber":471,"author":{"gitId":"-"},"content":" */"},{"lineNumber":472,"author":{"gitId":"-"},"content":" public void deleteDeadlineExtension(DeadlineExtension de) {"},{"lineNumber":473,"author":{"gitId":"-"},"content":" deadlineExtensionsLogic.deleteDeadlineExtension(de);"},{"lineNumber":474,"author":{"gitId":"-"},"content":" }"},{"lineNumber":475,"author":{"gitId":"-"},"content":""},{"lineNumber":476,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":477,"author":{"gitId":"-"},"content":" * Fetch the deadline extension for a given user and session feedback."},{"lineNumber":478,"author":{"gitId":"-"},"content":" *"},{"lineNumber":479,"author":{"gitId":"-"},"content":" * @return deadline extension instant if exists, else the default end time instant"},{"lineNumber":480,"author":{"gitId":"-"},"content":" * for the session feedback."},{"lineNumber":481,"author":{"gitId":"-"},"content":" */"},{"lineNumber":482,"author":{"gitId":"-"},"content":" public Instant getDeadlineForUser(FeedbackSession session, User user) {"},{"lineNumber":483,"author":{"gitId":"-"},"content":" return deadlineExtensionsLogic.getDeadlineForUser(session, user);"},{"lineNumber":484,"author":{"gitId":"-"},"content":" }"},{"lineNumber":485,"author":{"gitId":"-"},"content":""},{"lineNumber":486,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":487,"author":{"gitId":"-"},"content":" * Fetch the deadline extension for a given user and session feedback."},{"lineNumber":488,"author":{"gitId":"-"},"content":" *"},{"lineNumber":489,"author":{"gitId":"-"},"content":" * @return deadline extension instant if exists, else return null since no deadline extensions."},{"lineNumber":490,"author":{"gitId":"-"},"content":" */"},{"lineNumber":491,"author":{"gitId":"-"},"content":" public Instant getExtendedDeadlineForUser(FeedbackSession session, User user) {"},{"lineNumber":492,"author":{"gitId":"-"},"content":" return deadlineExtensionsLogic.getExtendedDeadlineForUser(session, user);"},{"lineNumber":493,"author":{"gitId":"-"},"content":" }"},{"lineNumber":494,"author":{"gitId":"-"},"content":""},{"lineNumber":495,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":496,"author":{"gitId":"-"},"content":" * Gets a list of deadline extensions with endTime coming up soon"},{"lineNumber":497,"author":{"gitId":"-"},"content":" * and possibly need a closing email to be sent."},{"lineNumber":498,"author":{"gitId":"-"},"content":" */"},{"lineNumber":499,"author":{"gitId":"-"},"content":" public List\u003cDeadlineExtension\u003e getDeadlineExtensionsPossiblyNeedingClosingEmail() {"},{"lineNumber":500,"author":{"gitId":"-"},"content":" return deadlineExtensionsLogic.getDeadlineExtensionsPossiblyNeedingClosingEmail();"},{"lineNumber":501,"author":{"gitId":"-"},"content":" }"},{"lineNumber":502,"author":{"gitId":"-"},"content":""},{"lineNumber":503,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":504,"author":{"gitId":"-"},"content":" * Gets a feedback session."},{"lineNumber":505,"author":{"gitId":"-"},"content":" *"},{"lineNumber":506,"author":{"gitId":"-"},"content":" * @return null if not found."},{"lineNumber":507,"author":{"gitId":"-"},"content":" */"},{"lineNumber":508,"author":{"gitId":"-"},"content":" public FeedbackSession getFeedbackSession(UUID id) {"},{"lineNumber":509,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSession(id);"},{"lineNumber":510,"author":{"gitId":"-"},"content":" }"},{"lineNumber":511,"author":{"gitId":"-"},"content":""},{"lineNumber":512,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":513,"author":{"gitId":"-"},"content":" * Gets a feedback session for {@code feedbackSessionName} and {@code courseId}."},{"lineNumber":514,"author":{"gitId":"-"},"content":" *"},{"lineNumber":515,"author":{"gitId":"-"},"content":" * @return null if not found."},{"lineNumber":516,"author":{"gitId":"-"},"content":" */"},{"lineNumber":517,"author":{"gitId":"-"},"content":" public FeedbackSession getFeedbackSession(String feedbackSessionName, String courseId) {"},{"lineNumber":518,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":519,"author":{"gitId":"-"},"content":" }"},{"lineNumber":520,"author":{"gitId":"-"},"content":""},{"lineNumber":521,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":522,"author":{"gitId":"dishenggg"},"content":" * Gets a feedback session reference."},{"lineNumber":523,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":524,"author":{"gitId":"dishenggg"},"content":" * @return Returns a proxy for the feedback session."},{"lineNumber":525,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":526,"author":{"gitId":"dishenggg"},"content":" public FeedbackSession getFeedbackSessionReference(UUID id) {"},{"lineNumber":527,"author":{"gitId":"dishenggg"},"content":" return feedbackSessionsLogic.getFeedbackSessionReference(id);"},{"lineNumber":528,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":529,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":530,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":531,"author":{"gitId":"-"},"content":" * Gets a feedback session from the recycle bin."},{"lineNumber":532,"author":{"gitId":"-"},"content":" *"},{"lineNumber":533,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":534,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":535,"author":{"gitId":"-"},"content":" *"},{"lineNumber":536,"author":{"gitId":"-"},"content":" * @return null if not found."},{"lineNumber":537,"author":{"gitId":"-"},"content":" */"},{"lineNumber":538,"author":{"gitId":"-"},"content":" public FeedbackSession getFeedbackSessionFromRecycleBin(String feedbackSessionName, String courseId) {"},{"lineNumber":539,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":540,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":541,"author":{"gitId":"-"},"content":""},{"lineNumber":542,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSessionFromRecycleBin(feedbackSessionName, courseId);"},{"lineNumber":543,"author":{"gitId":"-"},"content":" }"},{"lineNumber":544,"author":{"gitId":"-"},"content":""},{"lineNumber":545,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":546,"author":{"gitId":"-"},"content":" * Returns a {@code List} of feedback sessions in the Recycle Bin for the instructors."},{"lineNumber":547,"author":{"gitId":"-"},"content":" * \u003cbr\u003e"},{"lineNumber":548,"author":{"gitId":"-"},"content":" * Omits sessions if the corresponding courses are archived or in Recycle Bin"},{"lineNumber":549,"author":{"gitId":"-"},"content":" */"},{"lineNumber":550,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getSoftDeletedFeedbackSessionsForInstructors("},{"lineNumber":551,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorList) {"},{"lineNumber":552,"author":{"gitId":"-"},"content":" assert instructorList !\u003d null;"},{"lineNumber":553,"author":{"gitId":"-"},"content":""},{"lineNumber":554,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getSoftDeletedFeedbackSessionsForInstructors(instructorList);"},{"lineNumber":555,"author":{"gitId":"-"},"content":" }"},{"lineNumber":556,"author":{"gitId":"-"},"content":""},{"lineNumber":557,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":558,"author":{"gitId":"-"},"content":" * Gets a list of feedback sessions for instructors."},{"lineNumber":559,"author":{"gitId":"-"},"content":" */"},{"lineNumber":560,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsForInstructors("},{"lineNumber":561,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorList) {"},{"lineNumber":562,"author":{"gitId":"-"},"content":" assert instructorList !\u003d null;"},{"lineNumber":563,"author":{"gitId":"-"},"content":""},{"lineNumber":564,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSessionsForInstructors(instructorList);"},{"lineNumber":565,"author":{"gitId":"-"},"content":" }"},{"lineNumber":566,"author":{"gitId":"-"},"content":""},{"lineNumber":567,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":568,"author":{"gitId":"-"},"content":" * Gets all and only the feedback sessions ongoing within a range of time."},{"lineNumber":569,"author":{"gitId":"-"},"content":" */"},{"lineNumber":570,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getOngoingSessions(Instant rangeStart, Instant rangeEnd) {"},{"lineNumber":571,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getOngoingSessions(rangeStart, rangeEnd);"},{"lineNumber":572,"author":{"gitId":"-"},"content":" }"},{"lineNumber":573,"author":{"gitId":"-"},"content":""},{"lineNumber":574,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":575,"author":{"gitId":"-"},"content":" * Gets a set of giver identifiers that has at least one response under a feedback session."},{"lineNumber":576,"author":{"gitId":"-"},"content":" */"},{"lineNumber":577,"author":{"gitId":"-"},"content":" public Set\u003cString\u003e getGiverSetThatAnsweredFeedbackSession(String feedbackSessionName, String courseId) {"},{"lineNumber":578,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":579,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":580,"author":{"gitId":"-"},"content":""},{"lineNumber":581,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getGiverSetThatAnsweredFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":582,"author":{"gitId":"-"},"content":" }"},{"lineNumber":583,"author":{"gitId":"-"},"content":""},{"lineNumber":584,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":585,"author":{"gitId":"-"},"content":" * Updates a feedback session."},{"lineNumber":586,"author":{"gitId":"-"},"content":" *"},{"lineNumber":587,"author":{"gitId":"-"},"content":" * @return returns the updated feedback session."},{"lineNumber":588,"author":{"gitId":"-"},"content":" */"},{"lineNumber":589,"author":{"gitId":"-"},"content":" public FeedbackSession updateFeedbackSession(FeedbackSession feedbackSession)"},{"lineNumber":590,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":591,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.updateFeedbackSession(feedbackSession);"},{"lineNumber":592,"author":{"gitId":"-"},"content":" }"},{"lineNumber":593,"author":{"gitId":"-"},"content":""},{"lineNumber":594,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":595,"author":{"gitId":"-"},"content":" * Returns a list of sessions that require automated emails to be sent as they are published."},{"lineNumber":596,"author":{"gitId":"-"},"content":" */"},{"lineNumber":597,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsWhichNeedAutomatedPublishedEmailsToBeSent() {"},{"lineNumber":598,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSessionsWhichNeedAutomatedPublishedEmailsToBeSent();"},{"lineNumber":599,"author":{"gitId":"-"},"content":" }"},{"lineNumber":600,"author":{"gitId":"-"},"content":""},{"lineNumber":601,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":602,"author":{"gitId":"-"},"content":" * Creates a feedback session."},{"lineNumber":603,"author":{"gitId":"-"},"content":" *"},{"lineNumber":604,"author":{"gitId":"-"},"content":" * @return returns the created feedback session."},{"lineNumber":605,"author":{"gitId":"-"},"content":" */"},{"lineNumber":606,"author":{"gitId":"-"},"content":" public FeedbackSession createFeedbackSession(FeedbackSession feedbackSession)"},{"lineNumber":607,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":608,"author":{"gitId":"-"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":609,"author":{"gitId":"-"},"content":" assert feedbackSession.getCourse() !\u003d null \u0026\u0026 feedbackSession.getCourse().getId() !\u003d null;"},{"lineNumber":610,"author":{"gitId":"-"},"content":""},{"lineNumber":611,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.createFeedbackSession(feedbackSession);"},{"lineNumber":612,"author":{"gitId":"-"},"content":" }"},{"lineNumber":613,"author":{"gitId":"-"},"content":""},{"lineNumber":614,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":615,"author":{"gitId":"-"},"content":" * Gets all feedback sessions of a course, except those that are soft-deleted."},{"lineNumber":616,"author":{"gitId":"-"},"content":" */"},{"lineNumber":617,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsForCourse(String courseId) {"},{"lineNumber":618,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSessionsForCourse(courseId);"},{"lineNumber":619,"author":{"gitId":"-"},"content":" }"},{"lineNumber":620,"author":{"gitId":"-"},"content":""},{"lineNumber":621,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":622,"author":{"gitId":"-"},"content":" * Creates a new feedback question."},{"lineNumber":623,"author":{"gitId":"-"},"content":" *"},{"lineNumber":624,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":625,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":626,"author":{"gitId":"-"},"content":" *"},{"lineNumber":627,"author":{"gitId":"-"},"content":" * @return the created question"},{"lineNumber":628,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the question is invalid"},{"lineNumber":629,"author":{"gitId":"marquestye"},"content":" * @throws EntityAlreadyExistsException if the question already exists"},{"lineNumber":630,"author":{"gitId":"-"},"content":" */"},{"lineNumber":631,"author":{"gitId":"marquestye"},"content":" public FeedbackQuestion createFeedbackQuestion(FeedbackQuestion feedbackQuestion)"},{"lineNumber":632,"author":{"gitId":"marquestye"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":633,"author":{"gitId":"-"},"content":" return feedbackQuestionsLogic.createFeedbackQuestion(feedbackQuestion);"},{"lineNumber":634,"author":{"gitId":"-"},"content":" }"},{"lineNumber":635,"author":{"gitId":"-"},"content":""},{"lineNumber":636,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":637,"author":{"gitId":"-"},"content":" * Publishes a feedback session."},{"lineNumber":638,"author":{"gitId":"-"},"content":" * @return the published feedback session"},{"lineNumber":639,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the feedback session cannot be found"},{"lineNumber":640,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if session is already published"},{"lineNumber":641,"author":{"gitId":"-"},"content":" */"},{"lineNumber":642,"author":{"gitId":"-"},"content":" public FeedbackSession publishFeedbackSession(String feedbackSessionName, String courseId)"},{"lineNumber":643,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, InvalidParametersException {"},{"lineNumber":644,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":645,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":646,"author":{"gitId":"-"},"content":""},{"lineNumber":647,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.publishFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":648,"author":{"gitId":"-"},"content":" }"},{"lineNumber":649,"author":{"gitId":"-"},"content":""},{"lineNumber":650,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":651,"author":{"gitId":"-"},"content":" * Checks whether a student has attempted a feedback session."},{"lineNumber":652,"author":{"gitId":"-"},"content":" *"},{"lineNumber":653,"author":{"gitId":"-"},"content":" * \u003cp\u003eIf there is no question for students, the feedback session is considered as attempted.\u003c/p\u003e"},{"lineNumber":654,"author":{"gitId":"-"},"content":" */"},{"lineNumber":655,"author":{"gitId":"-"},"content":" public boolean isFeedbackSessionAttemptedByStudent(FeedbackSession session, String userEmail, String userTeam) {"},{"lineNumber":656,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.isFeedbackSessionAttemptedByStudent(session, userEmail, userTeam);"},{"lineNumber":657,"author":{"gitId":"-"},"content":" }"},{"lineNumber":658,"author":{"gitId":"-"},"content":""},{"lineNumber":659,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":660,"author":{"gitId":"-"},"content":" * Checks whether an instructor has attempted a feedback session."},{"lineNumber":661,"author":{"gitId":"-"},"content":" *"},{"lineNumber":662,"author":{"gitId":"-"},"content":" * \u003cp\u003eIf there is no question for instructors, the feedback session is considered as attempted.\u003c/p\u003e"},{"lineNumber":663,"author":{"gitId":"-"},"content":" */"},{"lineNumber":664,"author":{"gitId":"-"},"content":" public boolean isFeedbackSessionAttemptedByInstructor(FeedbackSession session, String userEmail) {"},{"lineNumber":665,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.isFeedbackSessionAttemptedByInstructor(session, userEmail);"},{"lineNumber":666,"author":{"gitId":"-"},"content":" }"},{"lineNumber":667,"author":{"gitId":"-"},"content":""},{"lineNumber":668,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":669,"author":{"gitId":"-"},"content":" * Deletes a feedback session cascade to its associated questions, responses, deadline extensions and comments."},{"lineNumber":670,"author":{"gitId":"-"},"content":" *"},{"lineNumber":671,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":672,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":673,"author":{"gitId":"-"},"content":" */"},{"lineNumber":674,"author":{"gitId":"-"},"content":" public void deleteFeedbackSessionCascade(String feedbackSessionName, String courseId) {"},{"lineNumber":675,"author":{"gitId":"-"},"content":" feedbackSessionsLogic.deleteFeedbackSessionCascade(feedbackSessionName, courseId);"},{"lineNumber":676,"author":{"gitId":"-"},"content":" }"},{"lineNumber":677,"author":{"gitId":"-"},"content":""},{"lineNumber":678,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":679,"author":{"gitId":"-"},"content":" * Soft-deletes a specific session to Recycle Bin."},{"lineNumber":680,"author":{"gitId":"-"},"content":" */"},{"lineNumber":681,"author":{"gitId":"-"},"content":" public FeedbackSession moveFeedbackSessionToRecycleBin(String feedbackSessionName, String courseId)"},{"lineNumber":682,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":683,"author":{"gitId":"-"},"content":""},{"lineNumber":684,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":685,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":686,"author":{"gitId":"-"},"content":""},{"lineNumber":687,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.moveFeedbackSessionToRecycleBin(feedbackSessionName, courseId);"},{"lineNumber":688,"author":{"gitId":"-"},"content":" }"},{"lineNumber":689,"author":{"gitId":"-"},"content":""},{"lineNumber":690,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":691,"author":{"gitId":"-"},"content":" * Restores a specific session from Recycle Bin to feedback sessions table."},{"lineNumber":692,"author":{"gitId":"-"},"content":" */"},{"lineNumber":693,"author":{"gitId":"-"},"content":" public void restoreFeedbackSessionFromRecycleBin(String feedbackSessionName, String courseId)"},{"lineNumber":694,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":695,"author":{"gitId":"-"},"content":""},{"lineNumber":696,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":697,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":698,"author":{"gitId":"-"},"content":""},{"lineNumber":699,"author":{"gitId":"-"},"content":" feedbackSessionsLogic.restoreFeedbackSessionFromRecycleBin(feedbackSessionName, courseId);"},{"lineNumber":700,"author":{"gitId":"-"},"content":" }"},{"lineNumber":701,"author":{"gitId":"-"},"content":""},{"lineNumber":702,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":703,"author":{"gitId":"-"},"content":" * Unpublishes a feedback session."},{"lineNumber":704,"author":{"gitId":"-"},"content":" * @return the unpublished feedback session"},{"lineNumber":705,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the feedback session cannot be found"},{"lineNumber":706,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException"},{"lineNumber":707,"author":{"gitId":"-"},"content":" * if the feedback session is not ready to be unpublished."},{"lineNumber":708,"author":{"gitId":"-"},"content":" */"},{"lineNumber":709,"author":{"gitId":"-"},"content":" public FeedbackSession unpublishFeedbackSession(String feedbackSessionName, String courseId)"},{"lineNumber":710,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, InvalidParametersException {"},{"lineNumber":711,"author":{"gitId":"-"},"content":""},{"lineNumber":712,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":713,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":714,"author":{"gitId":"-"},"content":""},{"lineNumber":715,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.unpublishFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":716,"author":{"gitId":"-"},"content":" }"},{"lineNumber":717,"author":{"gitId":"-"},"content":""},{"lineNumber":718,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":719,"author":{"gitId":"-"},"content":" * After an update to feedback session\u0027s fields, may need to adjust the email status of the session."},{"lineNumber":720,"author":{"gitId":"-"},"content":" * @param session recently updated session."},{"lineNumber":721,"author":{"gitId":"-"},"content":" */"},{"lineNumber":722,"author":{"gitId":"-"},"content":" public void adjustFeedbackSessionEmailStatusAfterUpdate(FeedbackSession session) {"},{"lineNumber":723,"author":{"gitId":"-"},"content":" assert session !\u003d null;"},{"lineNumber":724,"author":{"gitId":"-"},"content":" feedbackSessionsLogic.adjustFeedbackSessionEmailStatusAfterUpdate(session);"},{"lineNumber":725,"author":{"gitId":"-"},"content":" }"},{"lineNumber":726,"author":{"gitId":"-"},"content":""},{"lineNumber":727,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":728,"author":{"gitId":"domoberzin"},"content":" * Gets the expected number of submissions for a feedback session."},{"lineNumber":729,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":730,"author":{"gitId":"domoberzin"},"content":" * \u003cbr\u003ePreconditions: \u003cbr\u003e"},{"lineNumber":731,"author":{"gitId":"domoberzin"},"content":" * * All parameters are non-null."},{"lineNumber":732,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":733,"author":{"gitId":"domoberzin"},"content":" public int getExpectedTotalSubmission(FeedbackSession fs) {"},{"lineNumber":734,"author":{"gitId":"domoberzin"},"content":" assert fs !\u003d null;"},{"lineNumber":735,"author":{"gitId":"domoberzin"},"content":" return feedbackSessionsLogic.getExpectedTotalSubmission(fs);"},{"lineNumber":736,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":737,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":738,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":739,"author":{"gitId":"domoberzin"},"content":" * Gets the actual number of submissions for a feedback session."},{"lineNumber":740,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":741,"author":{"gitId":"domoberzin"},"content":" * \u003cbr\u003ePreconditions: \u003cbr\u003e"},{"lineNumber":742,"author":{"gitId":"domoberzin"},"content":" * * All parameters are non-null."},{"lineNumber":743,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":744,"author":{"gitId":"domoberzin"},"content":" public int getActualTotalSubmission(FeedbackSession fs) {"},{"lineNumber":745,"author":{"gitId":"domoberzin"},"content":" assert fs !\u003d null;"},{"lineNumber":746,"author":{"gitId":"domoberzin"},"content":" return feedbackSessionsLogic.getActualTotalSubmission(fs);"},{"lineNumber":747,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":748,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":749,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":750,"author":{"gitId":"-"},"content":" * Get usage statistics within a time range."},{"lineNumber":751,"author":{"gitId":"-"},"content":" */"},{"lineNumber":752,"author":{"gitId":"-"},"content":" public List\u003cUsageStatistics\u003e getUsageStatisticsForTimeRange(Instant startTime, Instant endTime) {"},{"lineNumber":753,"author":{"gitId":"-"},"content":" return usageStatisticsLogic.getUsageStatisticsForTimeRange(startTime, endTime);"},{"lineNumber":754,"author":{"gitId":"-"},"content":" }"},{"lineNumber":755,"author":{"gitId":"-"},"content":""},{"lineNumber":756,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":757,"author":{"gitId":"-"},"content":" * Calculate usage statistics within a time range."},{"lineNumber":758,"author":{"gitId":"-"},"content":" */"},{"lineNumber":759,"author":{"gitId":"-"},"content":" public UsageStatistics calculateEntitiesStatisticsForTimeRange(Instant startTime, Instant endTime) {"},{"lineNumber":760,"author":{"gitId":"-"},"content":" return usageStatisticsLogic.calculateEntitiesStatisticsForTimeRange(startTime, endTime);"},{"lineNumber":761,"author":{"gitId":"-"},"content":" }"},{"lineNumber":762,"author":{"gitId":"-"},"content":""},{"lineNumber":763,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":764,"author":{"gitId":"-"},"content":" * Create usage statistics within a time range."},{"lineNumber":765,"author":{"gitId":"-"},"content":" */"},{"lineNumber":766,"author":{"gitId":"-"},"content":" public void createUsageStatistics(UsageStatistics attributes)"},{"lineNumber":767,"author":{"gitId":"-"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":768,"author":{"gitId":"-"},"content":" usageStatisticsLogic.createUsageStatistics(attributes);"},{"lineNumber":769,"author":{"gitId":"-"},"content":" }"},{"lineNumber":770,"author":{"gitId":"-"},"content":""},{"lineNumber":771,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":772,"author":{"gitId":"-"},"content":" * Creates a notification."},{"lineNumber":773,"author":{"gitId":"-"},"content":" *"},{"lineNumber":774,"author":{"gitId":"-"},"content":" * \u003cp\u003ePreconditions:\u003c/p\u003e"},{"lineNumber":775,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":776,"author":{"gitId":"-"},"content":" *"},{"lineNumber":777,"author":{"gitId":"-"},"content":" * @return created notification"},{"lineNumber":778,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the notification is not valid"},{"lineNumber":779,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the notification exists in the database"},{"lineNumber":780,"author":{"gitId":"-"},"content":" */"},{"lineNumber":781,"author":{"gitId":"-"},"content":" public Notification createNotification(Notification notification) throws"},{"lineNumber":782,"author":{"gitId":"-"},"content":" InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":783,"author":{"gitId":"-"},"content":" return notificationsLogic.createNotification(notification);"},{"lineNumber":784,"author":{"gitId":"-"},"content":" }"},{"lineNumber":785,"author":{"gitId":"-"},"content":""},{"lineNumber":786,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":787,"author":{"gitId":"-"},"content":" * Gets a notification by ID."},{"lineNumber":788,"author":{"gitId":"-"},"content":" *"},{"lineNumber":789,"author":{"gitId":"-"},"content":" * \u003cp\u003ePreconditions:\u003c/p\u003e"},{"lineNumber":790,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":791,"author":{"gitId":"-"},"content":" *"},{"lineNumber":792,"author":{"gitId":"-"},"content":" * @return Null if no match found."},{"lineNumber":793,"author":{"gitId":"-"},"content":" */"},{"lineNumber":794,"author":{"gitId":"-"},"content":" public Notification getNotification(UUID notificationId) {"},{"lineNumber":795,"author":{"gitId":"-"},"content":" return notificationsLogic.getNotification(notificationId);"},{"lineNumber":796,"author":{"gitId":"-"},"content":" }"},{"lineNumber":797,"author":{"gitId":"-"},"content":""},{"lineNumber":798,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":799,"author":{"gitId":"-"},"content":" * Updates a notification."},{"lineNumber":800,"author":{"gitId":"-"},"content":" *"},{"lineNumber":801,"author":{"gitId":"-"},"content":" * \u003cp\u003ePreconditions:\u003c/p\u003e"},{"lineNumber":802,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":803,"author":{"gitId":"-"},"content":" * @return updated notification"},{"lineNumber":804,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the notification is not valid"},{"lineNumber":805,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the notification does not exist in the database"},{"lineNumber":806,"author":{"gitId":"-"},"content":" */"},{"lineNumber":807,"author":{"gitId":"-"},"content":" public Notification updateNotification(UUID notificationId, Instant startTime, Instant endTime,"},{"lineNumber":808,"author":{"gitId":"-"},"content":" NotificationStyle style, NotificationTargetUser targetUser, String title,"},{"lineNumber":809,"author":{"gitId":"-"},"content":" String message) throws"},{"lineNumber":810,"author":{"gitId":"-"},"content":" InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":811,"author":{"gitId":"-"},"content":" return notificationsLogic.updateNotification(notificationId, startTime, endTime, style, targetUser, title, message);"},{"lineNumber":812,"author":{"gitId":"-"},"content":" }"},{"lineNumber":813,"author":{"gitId":"-"},"content":""},{"lineNumber":814,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":815,"author":{"gitId":"-"},"content":" * Deletes notification by ID."},{"lineNumber":816,"author":{"gitId":"-"},"content":" *"},{"lineNumber":817,"author":{"gitId":"-"},"content":" * \u003cul\u003e"},{"lineNumber":818,"author":{"gitId":"-"},"content":" * \u003cli\u003eFails silently if no such notification.\u003c/li\u003e"},{"lineNumber":819,"author":{"gitId":"-"},"content":" * \u003c/ul\u003e"},{"lineNumber":820,"author":{"gitId":"-"},"content":" *"},{"lineNumber":821,"author":{"gitId":"-"},"content":" * \u003cp\u003ePreconditions:\u003c/p\u003e"},{"lineNumber":822,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":823,"author":{"gitId":"-"},"content":" */"},{"lineNumber":824,"author":{"gitId":"-"},"content":" public void deleteNotification(UUID notificationId) {"},{"lineNumber":825,"author":{"gitId":"-"},"content":" notificationsLogic.deleteNotification(notificationId);"},{"lineNumber":826,"author":{"gitId":"-"},"content":" }"},{"lineNumber":827,"author":{"gitId":"-"},"content":""},{"lineNumber":828,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":829,"author":{"gitId":"-"},"content":" * Get a list of IDs of the read notifications of the account."},{"lineNumber":830,"author":{"gitId":"-"},"content":" */"},{"lineNumber":831,"author":{"gitId":"-"},"content":" public List\u003cUUID\u003e getReadNotificationsId(String id) {"},{"lineNumber":832,"author":{"gitId":"-"},"content":" return accountsLogic.getReadNotificationsId(id);"},{"lineNumber":833,"author":{"gitId":"-"},"content":" }"},{"lineNumber":834,"author":{"gitId":"-"},"content":""},{"lineNumber":835,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":836,"author":{"gitId":"-"},"content":" * Updates user read status for notification with ID {@code notificationId} and expiry time {@code endTime}."},{"lineNumber":837,"author":{"gitId":"-"},"content":" *"},{"lineNumber":838,"author":{"gitId":"-"},"content":" * \u003cp\u003ePreconditions:\u003c/p\u003e"},{"lineNumber":839,"author":{"gitId":"-"},"content":" * * All parameters are non-null. {@code endTime} must be after current moment."},{"lineNumber":840,"author":{"gitId":"-"},"content":" */"},{"lineNumber":841,"author":{"gitId":"-"},"content":" public List\u003cUUID\u003e updateReadNotifications(String id, UUID notificationId, Instant endTime)"},{"lineNumber":842,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":843,"author":{"gitId":"-"},"content":" return accountsLogic.updateReadNotifications(id, notificationId, endTime);"},{"lineNumber":844,"author":{"gitId":"-"},"content":" }"},{"lineNumber":845,"author":{"gitId":"-"},"content":""},{"lineNumber":846,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":847,"author":{"gitId":"-"},"content":" * Gets instructor associated with {@code id}."},{"lineNumber":848,"author":{"gitId":"-"},"content":" *"},{"lineNumber":849,"author":{"gitId":"-"},"content":" * @param id Id of Instructor."},{"lineNumber":850,"author":{"gitId":"-"},"content":" * @return Returns Instructor if found else null."},{"lineNumber":851,"author":{"gitId":"-"},"content":" */"},{"lineNumber":852,"author":{"gitId":"-"},"content":" public Instructor getInstructor(UUID id) {"},{"lineNumber":853,"author":{"gitId":"-"},"content":" return usersLogic.getInstructor(id);"},{"lineNumber":854,"author":{"gitId":"-"},"content":" }"},{"lineNumber":855,"author":{"gitId":"-"},"content":""},{"lineNumber":856,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":857,"author":{"gitId":"-"},"content":" * Gets instructor associated with {@code courseId} and {@code email}."},{"lineNumber":858,"author":{"gitId":"-"},"content":" */"},{"lineNumber":859,"author":{"gitId":"-"},"content":" public Instructor getInstructorForEmail(String courseId, String email) {"},{"lineNumber":860,"author":{"gitId":"-"},"content":" return usersLogic.getInstructorForEmail(courseId, email);"},{"lineNumber":861,"author":{"gitId":"-"},"content":" }"},{"lineNumber":862,"author":{"gitId":"-"},"content":""},{"lineNumber":863,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":864,"author":{"gitId":"-"},"content":" * Gets an instructor by associated {@code regkey}."},{"lineNumber":865,"author":{"gitId":"-"},"content":" */"},{"lineNumber":866,"author":{"gitId":"-"},"content":" public Instructor getInstructorByRegistrationKey(String regKey) {"},{"lineNumber":867,"author":{"gitId":"-"},"content":" return usersLogic.getInstructorByRegistrationKey(regKey);"},{"lineNumber":868,"author":{"gitId":"-"},"content":" }"},{"lineNumber":869,"author":{"gitId":"-"},"content":""},{"lineNumber":870,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":871,"author":{"gitId":"-"},"content":" * Gets an instructor by associated {@code googleId}."},{"lineNumber":872,"author":{"gitId":"-"},"content":" */"},{"lineNumber":873,"author":{"gitId":"-"},"content":" public Instructor getInstructorByGoogleId(String courseId, String googleId) {"},{"lineNumber":874,"author":{"gitId":"-"},"content":" return usersLogic.getInstructorByGoogleId(courseId, googleId);"},{"lineNumber":875,"author":{"gitId":"-"},"content":" }"},{"lineNumber":876,"author":{"gitId":"-"},"content":""},{"lineNumber":877,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":878,"author":{"gitId":"-"},"content":" * Gets list of instructors by {@code googleId}."},{"lineNumber":879,"author":{"gitId":"-"},"content":" */"},{"lineNumber":880,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getInstructorsForGoogleId(String googleId) {"},{"lineNumber":881,"author":{"gitId":"-"},"content":" return usersLogic.getInstructorsForGoogleId(googleId);"},{"lineNumber":882,"author":{"gitId":"-"},"content":" }"},{"lineNumber":883,"author":{"gitId":"-"},"content":""},{"lineNumber":884,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":885,"author":{"gitId":"-"},"content":" * Gets instructors by associated {@code courseId}."},{"lineNumber":886,"author":{"gitId":"-"},"content":" */"},{"lineNumber":887,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getInstructorsByCourse(String courseId) {"},{"lineNumber":888,"author":{"gitId":"-"},"content":" return usersLogic.getInstructorsForCourse(courseId);"},{"lineNumber":889,"author":{"gitId":"-"},"content":" }"},{"lineNumber":890,"author":{"gitId":"-"},"content":""},{"lineNumber":891,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":892,"author":{"gitId":"-"},"content":" * Creates an instructor."},{"lineNumber":893,"author":{"gitId":"-"},"content":" */"},{"lineNumber":894,"author":{"gitId":"-"},"content":" public Instructor createInstructor(Instructor instructor)"},{"lineNumber":895,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":896,"author":{"gitId":"-"},"content":" return usersLogic.createInstructor(instructor);"},{"lineNumber":897,"author":{"gitId":"-"},"content":" }"},{"lineNumber":898,"author":{"gitId":"-"},"content":""},{"lineNumber":899,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":900,"author":{"gitId":"-"},"content":" * Make the instructor join the course, i.e. associate the Google ID to the instructor.\u003cbr\u003e"},{"lineNumber":901,"author":{"gitId":"-"},"content":" * Creates an account for the instructor if no existing account is found."},{"lineNumber":902,"author":{"gitId":"-"},"content":" * Preconditions: \u003cbr\u003e"},{"lineNumber":903,"author":{"gitId":"-"},"content":" * * Parameters regkey and googleId are non-null."},{"lineNumber":904,"author":{"gitId":"-"},"content":" */"},{"lineNumber":905,"author":{"gitId":"-"},"content":" public Instructor joinCourseForInstructor(String regkey, String googleId)"},{"lineNumber":906,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException, EntityAlreadyExistsException {"},{"lineNumber":907,"author":{"gitId":"-"},"content":""},{"lineNumber":908,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":909,"author":{"gitId":"-"},"content":" assert regkey !\u003d null;"},{"lineNumber":910,"author":{"gitId":"-"},"content":""},{"lineNumber":911,"author":{"gitId":"-"},"content":" return accountsLogic.joinCourseForInstructor(regkey, googleId);"},{"lineNumber":912,"author":{"gitId":"-"},"content":" }"},{"lineNumber":913,"author":{"gitId":"-"},"content":""},{"lineNumber":914,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":915,"author":{"gitId":"-"},"content":" * Validates that the join course request is valid, then"},{"lineNumber":916,"author":{"gitId":"-"},"content":" * makes the instructor join the course, i.e. associate an account to the instructor with the given googleId."},{"lineNumber":917,"author":{"gitId":"-"},"content":" * Creates an account for the instructor if no existing account is found."},{"lineNumber":918,"author":{"gitId":"-"},"content":" * Preconditions:"},{"lineNumber":919,"author":{"gitId":"-"},"content":" * Parameters regkey and googleId are non-null."},{"lineNumber":920,"author":{"gitId":"-"},"content":" */"},{"lineNumber":921,"author":{"gitId":"-"},"content":" public Instructor joinCourseForInstructor(String googleId, Instructor instructor)"},{"lineNumber":922,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException, EntityDoesNotExistException {"},{"lineNumber":923,"author":{"gitId":"-"},"content":" if (googleId \u003d\u003d null) {"},{"lineNumber":924,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(\"Instructor\u0027s googleId cannot be null\");"},{"lineNumber":925,"author":{"gitId":"-"},"content":" }"},{"lineNumber":926,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":927,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(\"Instructor cannot be null\");"},{"lineNumber":928,"author":{"gitId":"-"},"content":" }"},{"lineNumber":929,"author":{"gitId":"-"},"content":""},{"lineNumber":930,"author":{"gitId":"-"},"content":" validateJoinCourseRequest(googleId, instructor);"},{"lineNumber":931,"author":{"gitId":"-"},"content":" return usersLogic.joinCourseForInstructor(googleId, instructor);"},{"lineNumber":932,"author":{"gitId":"-"},"content":" }"},{"lineNumber":933,"author":{"gitId":"-"},"content":""},{"lineNumber":934,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":935,"author":{"gitId":"-"},"content":" * Validates that the instructor can join the course it has as courseId field."},{"lineNumber":936,"author":{"gitId":"-"},"content":" *"},{"lineNumber":937,"author":{"gitId":"-"},"content":" * @return true if the instructor can join the course."},{"lineNumber":938,"author":{"gitId":"-"},"content":" * @throws Exception if the instructor cannot join the course."},{"lineNumber":939,"author":{"gitId":"-"},"content":" */"},{"lineNumber":940,"author":{"gitId":"-"},"content":" private boolean validateJoinCourseRequest(String googleId, Instructor instructor)"},{"lineNumber":941,"author":{"gitId":"-"},"content":" throws EntityAlreadyExistsException, EntityDoesNotExistException {"},{"lineNumber":942,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":943,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Instructor not found\");"},{"lineNumber":944,"author":{"gitId":"-"},"content":" }"},{"lineNumber":945,"author":{"gitId":"-"},"content":""},{"lineNumber":946,"author":{"gitId":"-"},"content":" // check course exists and has not been deleted"},{"lineNumber":947,"author":{"gitId":"-"},"content":" Course course \u003d getCourse(instructor.getCourseId());"},{"lineNumber":948,"author":{"gitId":"-"},"content":""},{"lineNumber":949,"author":{"gitId":"-"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":950,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Course with id \" + instructor.getCourseId() + \" does not exist\");"},{"lineNumber":951,"author":{"gitId":"-"},"content":" }"},{"lineNumber":952,"author":{"gitId":"-"},"content":" if (course.isCourseDeleted()) {"},{"lineNumber":953,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"The course you are trying to join has been deleted by an instructor\");"},{"lineNumber":954,"author":{"gitId":"-"},"content":" }"},{"lineNumber":955,"author":{"gitId":"-"},"content":""},{"lineNumber":956,"author":{"gitId":"-"},"content":" if (instructor.isRegistered()) {"},{"lineNumber":957,"author":{"gitId":"-"},"content":" throw new EntityAlreadyExistsException(\"Instructor has already joined course\");"},{"lineNumber":958,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":959,"author":{"gitId":"-"},"content":" // Check if this Google ID has already joined this course with courseId"},{"lineNumber":960,"author":{"gitId":"-"},"content":" Instructor existingInstructor \u003d"},{"lineNumber":961,"author":{"gitId":"-"},"content":" usersLogic.getInstructorByGoogleId(instructor.getCourseId(), googleId);"},{"lineNumber":962,"author":{"gitId":"-"},"content":" if (existingInstructor !\u003d null) {"},{"lineNumber":963,"author":{"gitId":"-"},"content":" throw new EntityAlreadyExistsException(\"Instructor has already joined course\");"},{"lineNumber":964,"author":{"gitId":"-"},"content":" }"},{"lineNumber":965,"author":{"gitId":"-"},"content":" }"},{"lineNumber":966,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":967,"author":{"gitId":"-"},"content":" }"},{"lineNumber":968,"author":{"gitId":"-"},"content":""},{"lineNumber":969,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":970,"author":{"gitId":"-"},"content":" * Searches instructors in the whole system. Used by admin only."},{"lineNumber":971,"author":{"gitId":"-"},"content":" *"},{"lineNumber":972,"author":{"gitId":"-"},"content":" * @return List of found instructors in the whole system. Null if no result found."},{"lineNumber":973,"author":{"gitId":"-"},"content":" */"},{"lineNumber":974,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e searchInstructorsInWholeSystem(String queryString)"},{"lineNumber":975,"author":{"gitId":"-"},"content":" throws SearchServiceException {"},{"lineNumber":976,"author":{"gitId":"-"},"content":" assert queryString !\u003d null;"},{"lineNumber":977,"author":{"gitId":"-"},"content":""},{"lineNumber":978,"author":{"gitId":"-"},"content":" return usersLogic.searchInstructorsInWholeSystem(queryString);"},{"lineNumber":979,"author":{"gitId":"-"},"content":" }"},{"lineNumber":980,"author":{"gitId":"-"},"content":""},{"lineNumber":981,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":982,"author":{"gitId":"-"},"content":" * Updates an instructor and cascades to responses and comments if needed."},{"lineNumber":983,"author":{"gitId":"-"},"content":" *"},{"lineNumber":984,"author":{"gitId":"-"},"content":" * @return updated instructor"},{"lineNumber":985,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the instructor update request is invalid"},{"lineNumber":986,"author":{"gitId":"-"},"content":" * @throws InstructorUpdateException if the update violates instructor validity"},{"lineNumber":987,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the instructor does not exist in the database"},{"lineNumber":988,"author":{"gitId":"-"},"content":" */"},{"lineNumber":989,"author":{"gitId":"-"},"content":" public Instructor updateInstructorCascade(String courseId, InstructorCreateRequest instructorRequest) throws"},{"lineNumber":990,"author":{"gitId":"-"},"content":" InvalidParametersException, InstructorUpdateException, EntityDoesNotExistException {"},{"lineNumber":991,"author":{"gitId":"-"},"content":" return usersLogic.updateInstructorCascade(courseId, instructorRequest);"},{"lineNumber":992,"author":{"gitId":"-"},"content":" }"},{"lineNumber":993,"author":{"gitId":"-"},"content":""},{"lineNumber":994,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":995,"author":{"gitId":"-"},"content":" * Checks if an instructor with {@code googleId} can create a course with {@code institute}."},{"lineNumber":996,"author":{"gitId":"-"},"content":" */"},{"lineNumber":997,"author":{"gitId":"-"},"content":" public boolean canInstructorCreateCourse(String googleId, String institute) {"},{"lineNumber":998,"author":{"gitId":"-"},"content":" return usersLogic.canInstructorCreateCourse(googleId, institute);"},{"lineNumber":999,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1000,"author":{"gitId":"-"},"content":""},{"lineNumber":1001,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1002,"author":{"gitId":"-"},"content":" * Gets student associated with {@code id}."},{"lineNumber":1003,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1004,"author":{"gitId":"-"},"content":" * @param id Id of Student."},{"lineNumber":1005,"author":{"gitId":"-"},"content":" * @return Returns Student if found else null."},{"lineNumber":1006,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1007,"author":{"gitId":"-"},"content":" public Student getStudent(UUID id) {"},{"lineNumber":1008,"author":{"gitId":"-"},"content":" return usersLogic.getStudent(id);"},{"lineNumber":1009,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1010,"author":{"gitId":"-"},"content":""},{"lineNumber":1011,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":1012,"author":{"gitId":"dishenggg"},"content":" * Gets student reference associated with {@code id}."},{"lineNumber":1013,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":1014,"author":{"gitId":"dishenggg"},"content":" * @param id Id of Student."},{"lineNumber":1015,"author":{"gitId":"dishenggg"},"content":" * @return Returns a proxy for the Student."},{"lineNumber":1016,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":1017,"author":{"gitId":"dishenggg"},"content":" public Student getStudentReference(UUID id) {"},{"lineNumber":1018,"author":{"gitId":"dishenggg"},"content":" return usersLogic.getStudentReference(id);"},{"lineNumber":1019,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":1020,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":1021,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1022,"author":{"gitId":"-"},"content":" * Gets student associated with {@code courseId} and {@code email}."},{"lineNumber":1023,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1024,"author":{"gitId":"-"},"content":" public Student getStudentForEmail(String courseId, String email) {"},{"lineNumber":1025,"author":{"gitId":"-"},"content":" return usersLogic.getStudentForEmail(courseId, email);"},{"lineNumber":1026,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1027,"author":{"gitId":"-"},"content":""},{"lineNumber":1028,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1029,"author":{"gitId":"-"},"content":" * Check if the students with the provided emails exist in the course."},{"lineNumber":1030,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1031,"author":{"gitId":"-"},"content":" public boolean verifyStudentsExistInCourse(String courseId, List\u003cString\u003e emails) {"},{"lineNumber":1032,"author":{"gitId":"-"},"content":" return usersLogic.verifyStudentsExistInCourse(courseId, emails);"},{"lineNumber":1033,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1034,"author":{"gitId":"-"},"content":""},{"lineNumber":1035,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1036,"author":{"gitId":"-"},"content":" * Check if the instructors with the provided emails exist in the course."},{"lineNumber":1037,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1038,"author":{"gitId":"-"},"content":" public boolean verifyInstructorsExistInCourse(String courseId, List\u003cString\u003e emails) {"},{"lineNumber":1039,"author":{"gitId":"-"},"content":" return usersLogic.verifyInstructorsExistInCourse(courseId, emails);"},{"lineNumber":1040,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1041,"author":{"gitId":"-"},"content":""},{"lineNumber":1042,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1043,"author":{"gitId":"-"},"content":" * Preconditions: \u003cbr\u003e"},{"lineNumber":1044,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1045,"author":{"gitId":"-"},"content":" * @return Empty list if none found."},{"lineNumber":1046,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1047,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsForCourse(String courseId) {"},{"lineNumber":1048,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":1049,"author":{"gitId":"-"},"content":" return usersLogic.getStudentsForCourse(courseId);"},{"lineNumber":1050,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1051,"author":{"gitId":"-"},"content":""},{"lineNumber":1052,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1053,"author":{"gitId":"-"},"content":" * Preconditions: \u003cbr\u003e"},{"lineNumber":1054,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1055,"author":{"gitId":"-"},"content":" * @return Empty list if none found."},{"lineNumber":1056,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1057,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getUnregisteredStudentsForCourse(String courseId) {"},{"lineNumber":1058,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":1059,"author":{"gitId":"-"},"content":" return usersLogic.getUnregisteredStudentsForCourse(courseId);"},{"lineNumber":1060,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1061,"author":{"gitId":"-"},"content":""},{"lineNumber":1062,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1063,"author":{"gitId":"-"},"content":" * Gets a student by associated {@code regkey}."},{"lineNumber":1064,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1065,"author":{"gitId":"-"},"content":" public Student getStudentByRegistrationKey(String regKey) {"},{"lineNumber":1066,"author":{"gitId":"-"},"content":" return usersLogic.getStudentByRegistrationKey(regKey);"},{"lineNumber":1067,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1068,"author":{"gitId":"-"},"content":""},{"lineNumber":1069,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1070,"author":{"gitId":"-"},"content":" * Gets a student by associated {@code googleId}."},{"lineNumber":1071,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1072,"author":{"gitId":"-"},"content":" public Student getStudentByGoogleId(String courseId, String googleId) {"},{"lineNumber":1073,"author":{"gitId":"-"},"content":" return usersLogic.getStudentByGoogleId(courseId, googleId);"},{"lineNumber":1074,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1075,"author":{"gitId":"-"},"content":""},{"lineNumber":1076,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1077,"author":{"gitId":"-"},"content":" * Gets students by associated {@code teamName} and {@code courseId}."},{"lineNumber":1078,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1079,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsByTeamName(String teamName, String courseId) {"},{"lineNumber":1080,"author":{"gitId":"-"},"content":" return usersLogic.getStudentsForTeam(teamName, courseId);"},{"lineNumber":1081,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1082,"author":{"gitId":"-"},"content":""},{"lineNumber":1083,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":1084,"author":{"gitId":"domoberzin"},"content":" * Gets a team by associated {@code courseId} and {@code sectionName}."},{"lineNumber":1085,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":1086,"author":{"gitId":"domoberzin"},"content":" public Section getSectionOrCreate(String courseId, String sectionName) {"},{"lineNumber":1087,"author":{"gitId":"domoberzin"},"content":" return usersLogic.getSectionOrCreate(courseId, sectionName);"},{"lineNumber":1088,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":1089,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1090,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":1091,"author":{"gitId":"domoberzin"},"content":" * Gets a team by associated {@code section} and {@code teamName}."},{"lineNumber":1092,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":1093,"author":{"gitId":"domoberzin"},"content":" public Team getTeamOrCreate(Section section, String teamName) {"},{"lineNumber":1094,"author":{"gitId":"domoberzin"},"content":" return usersLogic.getTeamOrCreate(section, teamName);"},{"lineNumber":1095,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":1096,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1097,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1098,"author":{"gitId":"-"},"content":" * Creates a student."},{"lineNumber":1099,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1100,"author":{"gitId":"-"},"content":" * @return the created student"},{"lineNumber":1101,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the student is not valid"},{"lineNumber":1102,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the student already exists in the database."},{"lineNumber":1103,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1104,"author":{"gitId":"-"},"content":" public Student createStudent(Student student) throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":1105,"author":{"gitId":"-"},"content":" return usersLogic.createStudent(student);"},{"lineNumber":1106,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1107,"author":{"gitId":"-"},"content":""},{"lineNumber":1108,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":1109,"author":{"gitId":"yuanxi1"},"content":" * Search for students. Preconditions: all parameters are non-null."},{"lineNumber":1110,"author":{"gitId":"yuanxi1"},"content":" * @param instructors a list of Instructors associated to a googleId,"},{"lineNumber":1111,"author":{"gitId":"yuanxi1"},"content":" * used for filtering of search result"},{"lineNumber":1112,"author":{"gitId":"yuanxi1"},"content":" * @return Null if no match found"},{"lineNumber":1113,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":1114,"author":{"gitId":"yuanxi1"},"content":" public List\u003cStudent\u003e searchStudents(String queryString, List\u003cInstructor\u003e instructors)"},{"lineNumber":1115,"author":{"gitId":"yuanxi1"},"content":" throws SearchServiceException {"},{"lineNumber":1116,"author":{"gitId":"yuanxi1"},"content":" assert queryString !\u003d null;"},{"lineNumber":1117,"author":{"gitId":"yuanxi1"},"content":" assert instructors !\u003d null;"},{"lineNumber":1118,"author":{"gitId":"yuanxi1"},"content":" return usersLogic.searchStudents(queryString, instructors);"},{"lineNumber":1119,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":1120,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":1121,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":1122,"author":{"gitId":"yuanxi1"},"content":" * This method should be used by admin only since the searching does not restrict the"},{"lineNumber":1123,"author":{"gitId":"yuanxi1"},"content":" * visibility according to the logged-in user\u0027s google ID. This is used by admin to"},{"lineNumber":1124,"author":{"gitId":"yuanxi1"},"content":" * search students in the whole system."},{"lineNumber":1125,"author":{"gitId":"yuanxi1"},"content":" * @return Null if no match found."},{"lineNumber":1126,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":1127,"author":{"gitId":"yuanxi1"},"content":" public List\u003cStudent\u003e searchStudentsInWholeSystem(String queryString)"},{"lineNumber":1128,"author":{"gitId":"yuanxi1"},"content":" throws SearchServiceException {"},{"lineNumber":1129,"author":{"gitId":"yuanxi1"},"content":" assert queryString !\u003d null;"},{"lineNumber":1130,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":1131,"author":{"gitId":"yuanxi1"},"content":" return usersLogic.searchStudentsInWholeSystem(queryString);"},{"lineNumber":1132,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":1133,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":1134,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1135,"author":{"gitId":"-"},"content":" * Deletes a student cascade its associated feedback responses, deadline"},{"lineNumber":1136,"author":{"gitId":"-"},"content":" * extensions and comments."},{"lineNumber":1137,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1138,"author":{"gitId":"-"},"content":" * \u003cp\u003eFails silently if the student does not exist."},{"lineNumber":1139,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1140,"author":{"gitId":"-"},"content":" * \u003cbr/\u003e"},{"lineNumber":1141,"author":{"gitId":"-"},"content":" * Preconditions: \u003cbr/\u003e"},{"lineNumber":1142,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1143,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1144,"author":{"gitId":"-"},"content":" public void deleteStudentCascade(String courseId, String studentEmail) {"},{"lineNumber":1145,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":1146,"author":{"gitId":"-"},"content":" assert studentEmail !\u003d null;"},{"lineNumber":1147,"author":{"gitId":"-"},"content":""},{"lineNumber":1148,"author":{"gitId":"-"},"content":" usersLogic.deleteStudentCascade(courseId, studentEmail);"},{"lineNumber":1149,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1150,"author":{"gitId":"-"},"content":""},{"lineNumber":1151,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1152,"author":{"gitId":"-"},"content":" * Deletes all the students in the course cascade their associated responses, deadline extensions and comments."},{"lineNumber":1153,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1154,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr\u003e"},{"lineNumber":1155,"author":{"gitId":"-"},"content":" * Parameter is non-null."},{"lineNumber":1156,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1157,"author":{"gitId":"-"},"content":" public void deleteStudentsInCourseCascade(String courseId) {"},{"lineNumber":1158,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":1159,"author":{"gitId":"-"},"content":""},{"lineNumber":1160,"author":{"gitId":"-"},"content":" usersLogic.deleteStudentsInCourseCascade(courseId);"},{"lineNumber":1161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1162,"author":{"gitId":"-"},"content":""},{"lineNumber":1163,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":1164,"author":{"gitId":"yuanxi1"},"content":" * Make the student join the course, i.e. associate the Google ID to the student.\u003cbr\u003e"},{"lineNumber":1165,"author":{"gitId":"yuanxi1"},"content":" * Create an account for the student if no existing account is found."},{"lineNumber":1166,"author":{"gitId":"yuanxi1"},"content":" * Preconditions: \u003cbr\u003e"},{"lineNumber":1167,"author":{"gitId":"yuanxi1"},"content":" * * All parameters are non-null."},{"lineNumber":1168,"author":{"gitId":"yuanxi1"},"content":" * @param key the registration key"},{"lineNumber":1169,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":1170,"author":{"gitId":"yuanxi1"},"content":" public Student joinCourseForStudent(String key, String googleId)"},{"lineNumber":1171,"author":{"gitId":"yuanxi1"},"content":" throws InvalidParametersException, EntityDoesNotExistException, EntityAlreadyExistsException {"},{"lineNumber":1172,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":1173,"author":{"gitId":"yuanxi1"},"content":" assert googleId !\u003d null;"},{"lineNumber":1174,"author":{"gitId":"yuanxi1"},"content":" assert key !\u003d null;"},{"lineNumber":1175,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":1176,"author":{"gitId":"yuanxi1"},"content":" return accountsLogic.joinCourseForStudent(key, googleId);"},{"lineNumber":1177,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":1178,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":1179,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":1180,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1181,"author":{"gitId":"-"},"content":" * Gets all instructors and students by associated {@code googleId}."},{"lineNumber":1182,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1183,"author":{"gitId":"-"},"content":" public List\u003cUser\u003e getAllUsersByGoogleId(String googleId) {"},{"lineNumber":1184,"author":{"gitId":"-"},"content":" return usersLogic.getAllUsersByGoogleId(googleId);"},{"lineNumber":1185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1186,"author":{"gitId":"-"},"content":""},{"lineNumber":1187,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1188,"author":{"gitId":"-"},"content":" * Deletes a user."},{"lineNumber":1189,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1190,"author":{"gitId":"-"},"content":" * \u003cp\u003eFails silently if the user does not exist.\u003c/p\u003e"},{"lineNumber":1191,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1192,"author":{"gitId":"-"},"content":" public \u003cT extends User\u003e void deleteUser(T user) {"},{"lineNumber":1193,"author":{"gitId":"-"},"content":" usersLogic.deleteUser(user);"},{"lineNumber":1194,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1195,"author":{"gitId":"-"},"content":""},{"lineNumber":1196,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1197,"author":{"gitId":"-"},"content":" * Deletes an instructor and cascades deletion to"},{"lineNumber":1198,"author":{"gitId":"-"},"content":" * associated feedback responses, deadline extensions and comments."},{"lineNumber":1199,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1200,"author":{"gitId":"-"},"content":" * \u003cp\u003eFails silently if the instructor does not exist."},{"lineNumber":1201,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1202,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":1203,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1204,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1205,"author":{"gitId":"-"},"content":" public void deleteInstructorCascade(String courseId, String email) {"},{"lineNumber":1206,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":1207,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":1208,"author":{"gitId":"-"},"content":""},{"lineNumber":1209,"author":{"gitId":"-"},"content":" usersLogic.deleteInstructorCascade(courseId, email);"},{"lineNumber":1210,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1211,"author":{"gitId":"-"},"content":""},{"lineNumber":1212,"author":{"gitId":"-"},"content":" public List\u003cNotification\u003e getAllNotifications() {"},{"lineNumber":1213,"author":{"gitId":"-"},"content":" return notificationsLogic.getAllNotifications();"},{"lineNumber":1214,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1215,"author":{"gitId":"-"},"content":""},{"lineNumber":1216,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1217,"author":{"gitId":"-"},"content":" * Resets the googleId associated with the instructor."},{"lineNumber":1218,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1219,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":1220,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1221,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1222,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException If instructor cannot be found with given email and courseId."},{"lineNumber":1223,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1224,"author":{"gitId":"-"},"content":" public void resetInstructorGoogleId(String email, String courseId, String googleId)"},{"lineNumber":1225,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":1226,"author":{"gitId":"-"},"content":" usersLogic.resetInstructorGoogleId(email, courseId, googleId);"},{"lineNumber":1227,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1228,"author":{"gitId":"-"},"content":""},{"lineNumber":1229,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1230,"author":{"gitId":"-"},"content":" * Resets the googleId associated with the student."},{"lineNumber":1231,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1232,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":1233,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1234,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1235,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException If student cannot be found with given email and courseId."},{"lineNumber":1236,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1237,"author":{"gitId":"-"},"content":" public void resetStudentGoogleId(String email, String courseId, String googleId)"},{"lineNumber":1238,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":1239,"author":{"gitId":"-"},"content":" usersLogic.resetStudentGoogleId(email, courseId, googleId);"},{"lineNumber":1240,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1241,"author":{"gitId":"-"},"content":""},{"lineNumber":1242,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1243,"author":{"gitId":"-"},"content":" * Regenerates the registration key for the instructor with email address {@code email} in course {@code courseId}."},{"lineNumber":1244,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1245,"author":{"gitId":"-"},"content":" * @return the instructor with the new registration key."},{"lineNumber":1246,"author":{"gitId":"-"},"content":" * @throws InstructorUpdateException if system was unable to generate a new registration key."},{"lineNumber":1247,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the instructor does not exist."},{"lineNumber":1248,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1249,"author":{"gitId":"-"},"content":" public Instructor regenerateInstructorRegistrationKey(String courseId, String email)"},{"lineNumber":1250,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, InstructorUpdateException {"},{"lineNumber":1251,"author":{"gitId":"-"},"content":""},{"lineNumber":1252,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":1253,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":1254,"author":{"gitId":"-"},"content":""},{"lineNumber":1255,"author":{"gitId":"-"},"content":" return usersLogic.regenerateInstructorRegistrationKey(courseId, email);"},{"lineNumber":1256,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1257,"author":{"gitId":"-"},"content":""},{"lineNumber":1258,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1259,"author":{"gitId":"-"},"content":" * Regenerates the registration key for the student with email address {@code email} in course {@code courseId}."},{"lineNumber":1260,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1261,"author":{"gitId":"-"},"content":" * @return the student with the new registration key."},{"lineNumber":1262,"author":{"gitId":"-"},"content":" * @throws StudentUpdateException if system was unable to generate a new registration key."},{"lineNumber":1263,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the student does not exist."},{"lineNumber":1264,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1265,"author":{"gitId":"-"},"content":" public Student regenerateStudentRegistrationKey(String courseId, String email)"},{"lineNumber":1266,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, StudentUpdateException {"},{"lineNumber":1267,"author":{"gitId":"-"},"content":""},{"lineNumber":1268,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":1269,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":1270,"author":{"gitId":"-"},"content":""},{"lineNumber":1271,"author":{"gitId":"-"},"content":" return usersLogic.regenerateStudentRegistrationKey(courseId, email);"},{"lineNumber":1272,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1273,"author":{"gitId":"-"},"content":""},{"lineNumber":1274,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1275,"author":{"gitId":"-"},"content":" * Updates the instructor being edited to ensure validity of instructors for the course."},{"lineNumber":1276,"author":{"gitId":"-"},"content":" * * Preconditions: \u003cbr\u003e"},{"lineNumber":1277,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1278,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1279,"author":{"gitId":"-"},"content":" * @see UsersLogic#updateToEnsureValidityOfInstructorsForTheCourse(String, Instructor)"},{"lineNumber":1280,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1281,"author":{"gitId":"-"},"content":" public void updateToEnsureValidityOfInstructorsForTheCourse(String courseId, Instructor instructorToEdit) {"},{"lineNumber":1282,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":1283,"author":{"gitId":"-"},"content":" assert instructorToEdit !\u003d null;"},{"lineNumber":1284,"author":{"gitId":"-"},"content":""},{"lineNumber":1285,"author":{"gitId":"-"},"content":" usersLogic.updateToEnsureValidityOfInstructorsForTheCourse(courseId, instructorToEdit);"},{"lineNumber":1286,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1287,"author":{"gitId":"-"},"content":""},{"lineNumber":1288,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1289,"author":{"gitId":"-"},"content":" * Returns active notification for general users and the specified {@code targetUser}."},{"lineNumber":1290,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1291,"author":{"gitId":"-"},"content":" public List\u003cNotification\u003e getActiveNotificationsByTargetUser(NotificationTargetUser targetUser) {"},{"lineNumber":1292,"author":{"gitId":"-"},"content":" return notificationsLogic.getActiveNotificationsByTargetUser(targetUser);"},{"lineNumber":1293,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1294,"author":{"gitId":"-"},"content":""},{"lineNumber":1295,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1296,"author":{"gitId":"-"},"content":" * Gets all questions for a feedback session.\u003cbr\u003e"},{"lineNumber":1297,"author":{"gitId":"-"},"content":" * Returns an empty list if they are no questions"},{"lineNumber":1298,"author":{"gitId":"-"},"content":" * for the session."},{"lineNumber":1299,"author":{"gitId":"-"},"content":" * Preconditions: \u003cbr\u003e"},{"lineNumber":1300,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1301,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1302,"author":{"gitId":"-"},"content":" public List\u003cFeedbackQuestion\u003e getFeedbackQuestionsForSession(FeedbackSession feedbackSession) {"},{"lineNumber":1303,"author":{"gitId":"-"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":1304,"author":{"gitId":"-"},"content":""},{"lineNumber":1305,"author":{"gitId":"-"},"content":" return feedbackQuestionsLogic.getFeedbackQuestionsForSession(feedbackSession);"},{"lineNumber":1306,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1307,"author":{"gitId":"-"},"content":""},{"lineNumber":1308,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1309,"author":{"gitId":"-"},"content":" * Gets a list of all questions for the given session that"},{"lineNumber":1310,"author":{"gitId":"-"},"content":" * students can view/submit."},{"lineNumber":1311,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1312,"author":{"gitId":"-"},"content":" public List\u003cFeedbackQuestion\u003e getFeedbackQuestionsForStudents(FeedbackSession feedbackSession) {"},{"lineNumber":1313,"author":{"gitId":"-"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":1314,"author":{"gitId":"-"},"content":""},{"lineNumber":1315,"author":{"gitId":"-"},"content":" return feedbackQuestionsLogic.getFeedbackQuestionsForStudents(feedbackSession);"},{"lineNumber":1316,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1317,"author":{"gitId":"-"},"content":""},{"lineNumber":1318,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1319,"author":{"gitId":"-"},"content":" * Gets a {@code List} of all questions for the given session that"},{"lineNumber":1320,"author":{"gitId":"-"},"content":" * instructor can view/submit."},{"lineNumber":1321,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1322,"author":{"gitId":"-"},"content":" public List\u003cFeedbackQuestion\u003e getFeedbackQuestionsForInstructors("},{"lineNumber":1323,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession, String instructorEmail) {"},{"lineNumber":1324,"author":{"gitId":"-"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":1325,"author":{"gitId":"-"},"content":""},{"lineNumber":1326,"author":{"gitId":"-"},"content":" return feedbackQuestionsLogic.getFeedbackQuestionsForInstructors(feedbackSession, instructorEmail);"},{"lineNumber":1327,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1328,"author":{"gitId":"-"},"content":""},{"lineNumber":1329,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1330,"author":{"gitId":"xenosf"},"content":" * Gets the session result for a feedback session."},{"lineNumber":1331,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":1332,"author":{"gitId":"xenosf"},"content":" * @see FeedbackResponsesLogic#getSessionResultsForCourse("},{"lineNumber":1333,"author":{"gitId":"xenosf"},"content":" * FeedbackSession, String, String, String, Section, FeedbackResultFetchType)"},{"lineNumber":1334,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1335,"author":{"gitId":"xenosf"},"content":" public SqlSessionResultsBundle getSessionResultsForCourse("},{"lineNumber":1336,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession, String courseId, String userEmail,"},{"lineNumber":1337,"author":{"gitId":"xenosf"},"content":" @Nullable UUID questionId, @Nullable String sectionName, @Nullable FeedbackResultFetchType fetchType) {"},{"lineNumber":1338,"author":{"gitId":"xenosf"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":1339,"author":{"gitId":"xenosf"},"content":" assert courseId !\u003d null;"},{"lineNumber":1340,"author":{"gitId":"xenosf"},"content":" assert userEmail !\u003d null;"},{"lineNumber":1341,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1342,"author":{"gitId":"xenosf"},"content":" return feedbackResponsesLogic.getSessionResultsForCourse("},{"lineNumber":1343,"author":{"gitId":"xenosf"},"content":" feedbackSession, courseId, userEmail, questionId, sectionName, fetchType);"},{"lineNumber":1344,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1345,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1346,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1347,"author":{"gitId":"xenosf"},"content":" * Gets the session result for a feedback session for the given user."},{"lineNumber":1348,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":1349,"author":{"gitId":"xenosf"},"content":" * @see FeedbackResponsesLogic#getSessionResultsForUser(FeedbackSession, String, String, boolean, String)"},{"lineNumber":1350,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1351,"author":{"gitId":"xenosf"},"content":" public SqlSessionResultsBundle getSessionResultsForUser("},{"lineNumber":1352,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession, String courseId, String userEmail, boolean isInstructor,"},{"lineNumber":1353,"author":{"gitId":"xenosf"},"content":" @Nullable UUID questionId, boolean isPreviewResults) {"},{"lineNumber":1354,"author":{"gitId":"xenosf"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":1355,"author":{"gitId":"xenosf"},"content":" assert courseId !\u003d null;"},{"lineNumber":1356,"author":{"gitId":"xenosf"},"content":" assert userEmail !\u003d null;"},{"lineNumber":1357,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1358,"author":{"gitId":"xenosf"},"content":" return feedbackResponsesLogic.getSessionResultsForUser("},{"lineNumber":1359,"author":{"gitId":"xenosf"},"content":" feedbackSession, courseId, userEmail, isInstructor, questionId, isPreviewResults);"},{"lineNumber":1360,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1361,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1362,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1363,"author":{"gitId":"-"},"content":" * Persists the given data bundle to the database."},{"lineNumber":1364,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1365,"author":{"gitId":"-"},"content":" public SqlDataBundle persistDataBundle(SqlDataBundle dataBundle)"},{"lineNumber":1366,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException, EntityDoesNotExistException {"},{"lineNumber":1367,"author":{"gitId":"-"},"content":" return dataBundleLogic.persistDataBundle(dataBundle);"},{"lineNumber":1368,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1369,"author":{"gitId":"-"},"content":""},{"lineNumber":1370,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1371,"author":{"gitId":"-"},"content":" * Puts searchable documents from the data bundle to the database."},{"lineNumber":1372,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1373,"author":{"gitId":"-"},"content":" * @see DataBundleLogic#putDocuments(DataBundle)"},{"lineNumber":1374,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1375,"author":{"gitId":"-"},"content":" public void putDocuments(SqlDataBundle dataBundle) throws SearchServiceException {"},{"lineNumber":1376,"author":{"gitId":"-"},"content":" dataBundleLogic.putDocuments(dataBundle);"},{"lineNumber":1377,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1378,"author":{"gitId":"-"},"content":""},{"lineNumber":1379,"author":{"gitId":"mingyuanc"},"content":" /**"},{"lineNumber":1380,"author":{"gitId":"mingyuanc"},"content":" * Puts searchable instructor to the database."},{"lineNumber":1381,"author":{"gitId":"mingyuanc"},"content":" */"},{"lineNumber":1382,"author":{"gitId":"mingyuanc"},"content":" public void putInstructorDocument(Instructor instructor) throws SearchServiceException {"},{"lineNumber":1383,"author":{"gitId":"mingyuanc"},"content":" usersLogic.putInstructorDocument(instructor);"},{"lineNumber":1384,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":1385,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":1386,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":1387,"author":{"gitId":"domoberzin"},"content":" * Creates or updates search document for the given account request."},{"lineNumber":1388,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":1389,"author":{"gitId":"domoberzin"},"content":" * @see AccountRequestsLogic#putDocument(AccountRequest)"},{"lineNumber":1390,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":1391,"author":{"gitId":"domoberzin"},"content":" public void putAccountRequestDocument(AccountRequest accountRequest) throws SearchServiceException {"},{"lineNumber":1392,"author":{"gitId":"domoberzin"},"content":" accountRequestLogic.putDocument(accountRequest);"},{"lineNumber":1393,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":1394,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1395,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1396,"author":{"gitId":"-"},"content":" * Removes the given data bundle from the database."},{"lineNumber":1397,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1398,"author":{"gitId":"-"},"content":" public void removeDataBundle(SqlDataBundle dataBundle) throws InvalidParametersException {"},{"lineNumber":1399,"author":{"gitId":"-"},"content":" dataBundleLogic.removeDataBundle(dataBundle);"},{"lineNumber":1400,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1401,"author":{"gitId":"-"},"content":""},{"lineNumber":1402,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1403,"author":{"gitId":"-"},"content":" * Populates fields that need dynamic generation in a question."},{"lineNumber":1404,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1405,"author":{"gitId":"-"},"content":" * \u003cp\u003eCurrently, only MCQ/MSQ needs to generate choices dynamically.\u003c/p\u003e"},{"lineNumber":1406,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1407,"author":{"gitId":"-"},"content":" * @param feedbackQuestion the question to populate"},{"lineNumber":1408,"author":{"gitId":"-"},"content":" * @param courseId the ID of the course"},{"lineNumber":1409,"author":{"gitId":"-"},"content":" * @param emailOfEntityDoingQuestion the email of the entity doing the question"},{"lineNumber":1410,"author":{"gitId":"-"},"content":" * @param teamOfEntityDoingQuestion the team of the entity doing the question. If the entity is an instructor,"},{"lineNumber":1411,"author":{"gitId":"-"},"content":" * it can be {@code null}."},{"lineNumber":1412,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1413,"author":{"gitId":"-"},"content":" public void populateFieldsToGenerateInQuestion(FeedbackQuestion feedbackQuestion,"},{"lineNumber":1414,"author":{"gitId":"-"},"content":" String courseId, String emailOfEntityDoingQuestion,"},{"lineNumber":1415,"author":{"gitId":"-"},"content":" String teamOfEntityDoingQuestion) {"},{"lineNumber":1416,"author":{"gitId":"-"},"content":" assert feedbackQuestion !\u003d null;"},{"lineNumber":1417,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":1418,"author":{"gitId":"-"},"content":" assert emailOfEntityDoingQuestion !\u003d null;"},{"lineNumber":1419,"author":{"gitId":"-"},"content":""},{"lineNumber":1420,"author":{"gitId":"-"},"content":" feedbackQuestionsLogic.populateFieldsToGenerateInQuestion("},{"lineNumber":1421,"author":{"gitId":"-"},"content":" feedbackQuestion, courseId, emailOfEntityDoingQuestion, teamOfEntityDoingQuestion);"},{"lineNumber":1422,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1423,"author":{"gitId":"-"},"content":""},{"lineNumber":1424,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1425,"author":{"gitId":"-"},"content":" * Gets a feedback question."},{"lineNumber":1426,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1427,"author":{"gitId":"-"},"content":" * @return null if not found."},{"lineNumber":1428,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1429,"author":{"gitId":"-"},"content":" public FeedbackQuestion getFeedbackQuestion(UUID id) {"},{"lineNumber":1430,"author":{"gitId":"-"},"content":" return feedbackQuestionsLogic.getFeedbackQuestion(id);"},{"lineNumber":1431,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1432,"author":{"gitId":"-"},"content":""},{"lineNumber":1433,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1434,"author":{"gitId":"-"},"content":" * Deletes a feedback question cascade its responses and comments."},{"lineNumber":1435,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1436,"author":{"gitId":"-"},"content":" * \u003cp\u003eSilently fail if question does not exist."},{"lineNumber":1437,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1438,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":1439,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1440,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1441,"author":{"gitId":"-"},"content":" public void deleteFeedbackQuestionCascade(UUID questionId) {"},{"lineNumber":1442,"author":{"gitId":"-"},"content":" feedbackQuestionsLogic.deleteFeedbackQuestionCascade(questionId);"},{"lineNumber":1443,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1444,"author":{"gitId":"-"},"content":""},{"lineNumber":1445,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1446,"author":{"gitId":"-"},"content":" * Gets the recipients of a feedback question for student."},{"lineNumber":1447,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1448,"author":{"gitId":"-"},"content":" * @see FeedbackQuestionsLogic#getRecipientsOfQuestion"},{"lineNumber":1449,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1450,"author":{"gitId":"-"},"content":" public Map\u003cString, FeedbackQuestionRecipient\u003e getRecipientsOfQuestion("},{"lineNumber":1451,"author":{"gitId":"-"},"content":" FeedbackQuestion question,"},{"lineNumber":1452,"author":{"gitId":"-"},"content":" @Nullable Instructor instructorGiver, @Nullable Student studentGiver) {"},{"lineNumber":1453,"author":{"gitId":"-"},"content":" assert question !\u003d null;"},{"lineNumber":1454,"author":{"gitId":"-"},"content":""},{"lineNumber":1455,"author":{"gitId":"-"},"content":" return feedbackQuestionsLogic.getRecipientsOfQuestion(question, instructorGiver, studentGiver, null);"},{"lineNumber":1456,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1457,"author":{"gitId":"-"},"content":""},{"lineNumber":1458,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1459,"author":{"gitId":"-"},"content":" * Gets a feedbackResponse or null if it does not exist."},{"lineNumber":1460,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1461,"author":{"gitId":"-"},"content":" public FeedbackResponse getFeedbackResponse(UUID frId) {"},{"lineNumber":1462,"author":{"gitId":"-"},"content":" return feedbackResponsesLogic.getFeedbackResponse(frId);"},{"lineNumber":1463,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1464,"author":{"gitId":"-"},"content":""},{"lineNumber":1465,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1466,"author":{"gitId":"-"},"content":" * Creates a feedback response."},{"lineNumber":1467,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1468,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":1469,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1470,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1471,"author":{"gitId":"-"},"content":" * @return created feedback response"},{"lineNumber":1472,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the response is not valid"},{"lineNumber":1473,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the response already exist"},{"lineNumber":1474,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1475,"author":{"gitId":"-"},"content":" public FeedbackResponse createFeedbackResponse(FeedbackResponse feedbackResponse)"},{"lineNumber":1476,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":1477,"author":{"gitId":"-"},"content":" assert feedbackResponse !\u003d null;"},{"lineNumber":1478,"author":{"gitId":"-"},"content":" return feedbackResponsesLogic.createFeedbackResponse(feedbackResponse);"},{"lineNumber":1479,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1480,"author":{"gitId":"-"},"content":""},{"lineNumber":1481,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1482,"author":{"gitId":"-"},"content":" * Deletes a feedback response and cascades its associated comments."},{"lineNumber":1483,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1484,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":1485,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1486,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1487,"author":{"gitId":"-"},"content":" public void deleteFeedbackResponsesAndCommentsCascade(FeedbackResponse feedbackResponse) {"},{"lineNumber":1488,"author":{"gitId":"-"},"content":" assert feedbackResponse !\u003d null;"},{"lineNumber":1489,"author":{"gitId":"-"},"content":" feedbackResponsesLogic.deleteFeedbackResponsesAndCommentsCascade(feedbackResponse);"},{"lineNumber":1490,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1491,"author":{"gitId":"-"},"content":""},{"lineNumber":1492,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1493,"author":{"gitId":"-"},"content":" * Get existing feedback responses from instructor for the given question."},{"lineNumber":1494,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1495,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesFromInstructorForQuestion("},{"lineNumber":1496,"author":{"gitId":"-"},"content":" FeedbackQuestion question, Instructor instructor) {"},{"lineNumber":1497,"author":{"gitId":"-"},"content":" return feedbackResponsesLogic.getFeedbackResponsesFromInstructorForQuestion("},{"lineNumber":1498,"author":{"gitId":"-"},"content":" question, instructor);"},{"lineNumber":1499,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1500,"author":{"gitId":"-"},"content":""},{"lineNumber":1501,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1502,"author":{"gitId":"-"},"content":" * Get existing feedback responses from student or his team for the given"},{"lineNumber":1503,"author":{"gitId":"-"},"content":" * question."},{"lineNumber":1504,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1505,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesFromStudentOrTeamForQuestion("},{"lineNumber":1506,"author":{"gitId":"-"},"content":" FeedbackQuestion question, Student student) {"},{"lineNumber":1507,"author":{"gitId":"-"},"content":" return feedbackResponsesLogic.getFeedbackResponsesFromStudentOrTeamForQuestion("},{"lineNumber":1508,"author":{"gitId":"-"},"content":" question, student);"},{"lineNumber":1509,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1510,"author":{"gitId":"-"},"content":""},{"lineNumber":1511,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1512,"author":{"gitId":"-"},"content":" * Gets an feedback response comment by feedback response comment id."},{"lineNumber":1513,"author":{"gitId":"-"},"content":" * @param id of feedback response comment."},{"lineNumber":1514,"author":{"gitId":"-"},"content":" * @return the specified feedback response comment."},{"lineNumber":1515,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1516,"author":{"gitId":"-"},"content":" public FeedbackResponseComment getFeedbackResponseComment(Long id) {"},{"lineNumber":1517,"author":{"gitId":"-"},"content":" return feedbackResponseCommentsLogic.getFeedbackResponseComment(id);"},{"lineNumber":1518,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1519,"author":{"gitId":"-"},"content":""},{"lineNumber":1520,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1521,"author":{"gitId":"-"},"content":" * Updates a feedback response comment."},{"lineNumber":1522,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the comment does not exist"},{"lineNumber":1523,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1524,"author":{"gitId":"-"},"content":" public FeedbackResponseComment updateFeedbackResponseComment(Long frcId,"},{"lineNumber":1525,"author":{"gitId":"-"},"content":" FeedbackResponseCommentUpdateRequest updateRequest, String updaterEmail)"},{"lineNumber":1526,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":1527,"author":{"gitId":"-"},"content":" return feedbackResponseCommentsLogic.updateFeedbackResponseComment(frcId, updateRequest, updaterEmail);"},{"lineNumber":1528,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1529,"author":{"gitId":"-"},"content":""},{"lineNumber":1530,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1531,"author":{"gitId":"-"},"content":" * Updates a feedback response and comments by {@link FeedbackResponse}."},{"lineNumber":1532,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1533,"author":{"gitId":"-"},"content":" * \u003cp\u003eCascade updates its associated feedback response comment"},{"lineNumber":1534,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1535,"author":{"gitId":"-"},"content":" * \u003cbr/\u003ePreconditions: \u003cbr/\u003e"},{"lineNumber":1536,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1537,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1538,"author":{"gitId":"-"},"content":" * @return updated feedback response"},{"lineNumber":1539,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":1540,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the comment cannot be found"},{"lineNumber":1541,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1542,"author":{"gitId":"-"},"content":" public FeedbackResponse updateFeedbackResponseCascade(FeedbackResponse feedbackResponse)"},{"lineNumber":1543,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":1544,"author":{"gitId":"-"},"content":" assert feedbackResponse !\u003d null;"},{"lineNumber":1545,"author":{"gitId":"-"},"content":""},{"lineNumber":1546,"author":{"gitId":"-"},"content":" return feedbackResponsesLogic.updateFeedbackResponseCascade(feedbackResponse);"},{"lineNumber":1547,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1548,"author":{"gitId":"-"},"content":""},{"lineNumber":1549,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1550,"author":{"gitId":"-"},"content":" * Checks whether there are responses for a question."},{"lineNumber":1551,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1552,"author":{"gitId":"-"},"content":" public boolean areThereResponsesForQuestion(UUID questionId) {"},{"lineNumber":1553,"author":{"gitId":"-"},"content":" return feedbackResponsesLogic.areThereResponsesForQuestion(questionId);"},{"lineNumber":1554,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1555,"author":{"gitId":"-"},"content":""},{"lineNumber":1556,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1557,"author":{"gitId":"-"},"content":" * Checks whether there are responses for a course."},{"lineNumber":1558,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1559,"author":{"gitId":"-"},"content":" public boolean hasResponsesForCourse(String courseId) {"},{"lineNumber":1560,"author":{"gitId":"-"},"content":" return feedbackResponsesLogic.hasResponsesForCourse(courseId);"},{"lineNumber":1561,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1562,"author":{"gitId":"-"},"content":""},{"lineNumber":1563,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1564,"author":{"gitId":"-"},"content":" * Gets the comment associated with the response."},{"lineNumber":1565,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1566,"author":{"gitId":"-"},"content":" public FeedbackResponseComment getFeedbackResponseCommentForResponseFromParticipant("},{"lineNumber":1567,"author":{"gitId":"-"},"content":" UUID feedbackResponseId) {"},{"lineNumber":1568,"author":{"gitId":"-"},"content":" return feedbackResponseCommentsLogic.getFeedbackResponseCommentForResponseFromParticipant(feedbackResponseId);"},{"lineNumber":1569,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1570,"author":{"gitId":"-"},"content":""},{"lineNumber":1571,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1572,"author":{"gitId":"-"},"content":" * Creates a feedback response comment."},{"lineNumber":1573,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the comment alreadty exists"},{"lineNumber":1574,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the comment is invalid"},{"lineNumber":1575,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1576,"author":{"gitId":"-"},"content":" public FeedbackResponseComment createFeedbackResponseComment(FeedbackResponseComment frc)"},{"lineNumber":1577,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":1578,"author":{"gitId":"-"},"content":" return feedbackResponseCommentsLogic.createFeedbackResponseComment(frc);"},{"lineNumber":1579,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1580,"author":{"gitId":"-"},"content":""},{"lineNumber":1581,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1582,"author":{"gitId":"-"},"content":" * Deletes a feedbackResponseComment."},{"lineNumber":1583,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1584,"author":{"gitId":"-"},"content":" public void deleteFeedbackResponseComment(Long frcId) {"},{"lineNumber":1585,"author":{"gitId":"-"},"content":" feedbackResponseCommentsLogic.deleteFeedbackResponseComment(frcId);"},{"lineNumber":1586,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1587,"author":{"gitId":"-"},"content":""},{"lineNumber":1588,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1589,"author":{"gitId":"domoberzin"},"content":" * Gets all feedback responses from a giver for a question."},{"lineNumber":1590,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":1591,"author":{"gitId":"domoberzin"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesFromGiverForCourse(String courseId, String giverEmail) {"},{"lineNumber":1592,"author":{"gitId":"domoberzin"},"content":" return feedbackResponsesLogic.getFeedbackResponsesFromGiverForCourse(courseId, giverEmail);"},{"lineNumber":1593,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":1594,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1595,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":1596,"author":{"gitId":"domoberzin"},"content":" * Gets all feedback responses for a recipient for a course."},{"lineNumber":1597,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":1598,"author":{"gitId":"domoberzin"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForRecipientForCourse(String courseId, String recipientEmail) {"},{"lineNumber":1599,"author":{"gitId":"domoberzin"},"content":" return feedbackResponsesLogic.getFeedbackResponsesForRecipientForCourse(courseId, recipientEmail);"},{"lineNumber":1600,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":1601,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1602,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":1603,"author":{"gitId":"domoberzin"},"content":" * Gets all feedback response comments for a feedback response."},{"lineNumber":1604,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":1605,"author":{"gitId":"domoberzin"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentsForResponse(UUID feedbackResponse) {"},{"lineNumber":1606,"author":{"gitId":"domoberzin"},"content":" return feedbackResponseCommentsLogic.getFeedbackResponseCommentsForResponse(feedbackResponse);"},{"lineNumber":1607,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":1608,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1609,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":1610,"author":{"gitId":"domoberzin"},"content":" * Validates sections for any limit violations and teams for any team name violations."},{"lineNumber":1611,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":1612,"author":{"gitId":"domoberzin"},"content":" * \u003cp\u003ePreconditions: \u003cbr\u003e"},{"lineNumber":1613,"author":{"gitId":"domoberzin"},"content":" * * All parameters are non-null."},{"lineNumber":1614,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":1615,"author":{"gitId":"domoberzin"},"content":" * @see StudentsLogic#validateSectionsAndTeams(List, String)"},{"lineNumber":1616,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":1617,"author":{"gitId":"domoberzin"},"content":" public void validateSectionsAndTeams("},{"lineNumber":1618,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e studentList, String courseId) throws EnrollException {"},{"lineNumber":1619,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1620,"author":{"gitId":"domoberzin"},"content":" assert studentList !\u003d null;"},{"lineNumber":1621,"author":{"gitId":"domoberzin"},"content":" assert courseId !\u003d null;"},{"lineNumber":1622,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1623,"author":{"gitId":"domoberzin"},"content":" usersLogic.validateSectionsAndTeams(studentList, courseId);"},{"lineNumber":1624,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":1625,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1626,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":1627,"author":{"gitId":"domoberzin"},"content":" * Updates a feedback question by {@code FeedbackQuestionUpdateRequest}."},{"lineNumber":1628,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1629,"author":{"gitId":"-"},"content":" * \u003cp\u003eCascade adjust the question number of questions in the same session."},{"lineNumber":1630,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1631,"author":{"gitId":"-"},"content":" * \u003cp\u003eCascade adjust the existing response of the question."},{"lineNumber":1632,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1633,"author":{"gitId":"-"},"content":" * \u003cbr/\u003e Preconditions: \u003cbr/\u003e"},{"lineNumber":1634,"author":{"gitId":"-"},"content":" * * All parameters are non-null."},{"lineNumber":1635,"author":{"gitId":"-"},"content":" *"},{"lineNumber":1636,"author":{"gitId":"-"},"content":" * @return updated feedback question"},{"lineNumber":1637,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":1638,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the feedback question cannot be found"},{"lineNumber":1639,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1640,"author":{"gitId":"-"},"content":" public FeedbackQuestion updateFeedbackQuestionCascade(UUID questionId, FeedbackQuestionUpdateRequest updateRequest)"},{"lineNumber":1641,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":1642,"author":{"gitId":"-"},"content":" return feedbackQuestionsLogic.updateFeedbackQuestionCascade(questionId, updateRequest);"},{"lineNumber":1643,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1644,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1645,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1646,"author":{"gitId":"-"},"content":" * Returns a list of feedback sessions that need an \"Open\" email to be sent."},{"lineNumber":1647,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1648,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsWhichNeedOpenEmailsToBeSent() {"},{"lineNumber":1649,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSessionsWhichNeedOpenEmailsToBeSent();"},{"lineNumber":1650,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1651,"author":{"gitId":"-"},"content":""},{"lineNumber":1652,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1653,"author":{"gitId":"-"},"content":" * Returns a list of sessions that were closed within past hour."},{"lineNumber":1654,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1655,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsClosedWithinThePastHour() {"},{"lineNumber":1656,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSessionsClosedWithinThePastHour();"},{"lineNumber":1657,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1658,"author":{"gitId":"-"},"content":""},{"lineNumber":1659,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1660,"author":{"gitId":"xenosf"},"content":" * Creates or updates search document for the given student."},{"lineNumber":1661,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":1662,"author":{"gitId":"xenosf"},"content":" * @see UsersLogic#putStudentDocument(Student)"},{"lineNumber":1663,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1664,"author":{"gitId":"xenosf"},"content":" public void putStudentDocument(Student student) throws SearchServiceException {"},{"lineNumber":1665,"author":{"gitId":"xenosf"},"content":" usersLogic.putStudentDocument(student);"},{"lineNumber":1666,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1667,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1668,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":1669,"author":{"gitId":"domoberzin"},"content":" * This is used by admin to search account requests in the whole system."},{"lineNumber":1670,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":1671,"author":{"gitId":"domoberzin"},"content":" * @return A list of {@link AccountRequest} or {@code null} if no match found."},{"lineNumber":1672,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":1673,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccountRequest\u003e searchAccountRequestsInWholeSystem(String queryString)"},{"lineNumber":1674,"author":{"gitId":"domoberzin"},"content":" throws SearchServiceException {"},{"lineNumber":1675,"author":{"gitId":"domoberzin"},"content":" assert queryString !\u003d null;"},{"lineNumber":1676,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":1677,"author":{"gitId":"domoberzin"},"content":" return accountRequestLogic.searchAccountRequestsInWholeSystem(queryString);"},{"lineNumber":1678,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":1679,"author":{"gitId":"-"},"content":""},{"lineNumber":1680,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1681,"author":{"gitId":"-"},"content":" * Returns a list of sessions that are going to close soon."},{"lineNumber":1682,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1683,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsClosingWithinTimeLimit() {"},{"lineNumber":1684,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSessionsClosingWithinTimeLimit();"},{"lineNumber":1685,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1686,"author":{"gitId":"-"},"content":""},{"lineNumber":1687,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1688,"author":{"gitId":"-"},"content":" * Returns a list of sessions that are going to open soon."},{"lineNumber":1689,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1690,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsOpeningWithinTimeLimit() {"},{"lineNumber":1691,"author":{"gitId":"-"},"content":" return feedbackSessionsLogic.getFeedbackSessionsOpeningWithinTimeLimit();"},{"lineNumber":1692,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1693,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":1694,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":1695,"author":{"gitId":"dishenggg"},"content":" * Create feedback session logs."},{"lineNumber":1696,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":1697,"author":{"gitId":"dishenggg"},"content":" public void createFeedbackSessionLogs(List\u003cFeedbackSessionLog\u003e feedbackSessionLogs) {"},{"lineNumber":1698,"author":{"gitId":"dishenggg"},"content":" feedbackSessionLogsLogic.createFeedbackSessionLogs(feedbackSessionLogs);"},{"lineNumber":1699,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":1700,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":1701,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":1702,"author":{"gitId":"dishenggg"},"content":" * Gets the feedback session logs as filtered by the given parameters ordered by"},{"lineNumber":1703,"author":{"gitId":"dishenggg"},"content":" * ascending timestamp. Logs with the same timestamp will be ordered by the"},{"lineNumber":1704,"author":{"gitId":"dishenggg"},"content":" * student\u0027s email."},{"lineNumber":1705,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":1706,"author":{"gitId":"dishenggg"},"content":" * @param studentId Can be null"},{"lineNumber":1707,"author":{"gitId":"dishenggg"},"content":" * @param feedbackSessionId Can be null"},{"lineNumber":1708,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":1709,"author":{"gitId":"dishenggg"},"content":" public List\u003cFeedbackSessionLog\u003e getOrderedFeedbackSessionLogs(String courseId, UUID studentId,"},{"lineNumber":1710,"author":{"gitId":"dishenggg"},"content":" UUID feedbackSessionId, Instant startTime, Instant endTime) {"},{"lineNumber":1711,"author":{"gitId":"dishenggg"},"content":" return feedbackSessionLogsLogic.getOrderedFeedbackSessionLogs(courseId, studentId, feedbackSessionId, startTime,"},{"lineNumber":1712,"author":{"gitId":"dishenggg"},"content":" endTime);"},{"lineNumber":1713,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":1714,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":177,"yuanxi1":50,"marquestye":5,"xenosf":44,"dishenggg":59,"mingyuanc":7,"-":1372}},{"path":"src/main/java/teammates/sqllogic/api/SqlEmailGenerator.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.api;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.Collections;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.Set;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.ErrorLogEntry;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailType;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.util.RequestTracer;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.util.Templates;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.util.Templates.EmailTemplates;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.CoursesLogic;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.DeadlineExtensionsLogic;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.FeedbackSessionsLogic;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.UsersLogic;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":37,"author":{"gitId":"-"},"content":" * Handles operations related to generating emails to be sent from provided templates."},{"lineNumber":38,"author":{"gitId":"-"},"content":" *"},{"lineNumber":39,"author":{"gitId":"-"},"content":" * @see EmailTemplates"},{"lineNumber":40,"author":{"gitId":"-"},"content":" * @see EmailType"},{"lineNumber":41,"author":{"gitId":"-"},"content":" * @see EmailWrapper"},{"lineNumber":42,"author":{"gitId":"-"},"content":" */"},{"lineNumber":43,"author":{"gitId":"-"},"content":"public final class SqlEmailGenerator {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" // feedback action strings"},{"lineNumber":45,"author":{"gitId":"-"},"content":" private static final String FEEDBACK_ACTION_SUBMIT_EDIT_OR_VIEW \u003d \"submit, edit or view\";"},{"lineNumber":46,"author":{"gitId":"-"},"content":" private static final String FEEDBACK_ACTION_VIEW \u003d \"view\";"},{"lineNumber":47,"author":{"gitId":"-"},"content":" private static final String FEEDBACK_ACTION_SUBMIT_OR_UPDATE \u003d"},{"lineNumber":48,"author":{"gitId":"-"},"content":" \", in case you have not submitted yet or wish to update your submission. \";"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private static final String HTML_NO_ACTION_REQUIRED \u003d \"\u003cmark\u003eNo action is required if you have already submitted\u003c/mark\u003e\";"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" // status-related strings"},{"lineNumber":52,"author":{"gitId":"-"},"content":" private static final String FEEDBACK_STATUS_SESSION_OPEN \u003d \"is still open for submissions\""},{"lineNumber":53,"author":{"gitId":"-"},"content":" + FEEDBACK_ACTION_SUBMIT_OR_UPDATE + HTML_NO_ACTION_REQUIRED;"},{"lineNumber":54,"author":{"gitId":"-"},"content":" private static final String FEEDBACK_STATUS_SESSION_OPENING \u003d \"is now open\";"},{"lineNumber":55,"author":{"gitId":"-"},"content":" private static final String FEEDBACK_STATUS_SESSION_CLOSING \u003d \"is closing soon\""},{"lineNumber":56,"author":{"gitId":"-"},"content":" + FEEDBACK_ACTION_SUBMIT_OR_UPDATE + HTML_NO_ACTION_REQUIRED;"},{"lineNumber":57,"author":{"gitId":"-"},"content":" private static final String FEEDBACK_STATUS_SESSION_CLOSED \u003d \"is now closed for submission\";"},{"lineNumber":58,"author":{"gitId":"-"},"content":" private static final String FEEDBACK_STATUS_SESSION_OPENING_SOON \u003d \"is due to open soon\";"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" private static final String DATETIME_DISPLAY_FORMAT \u003d \"EEE, dd MMM yyyy, hh:mm a z\";"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" private static final long SESSION_LINK_RECOVERY_DURATION_IN_DAYS \u003d 90;"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" private static final SqlEmailGenerator instance \u003d new SqlEmailGenerator();"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" private final CoursesLogic coursesLogic \u003d CoursesLogic.inst();"},{"lineNumber":67,"author":{"gitId":"-"},"content":" private final DeadlineExtensionsLogic deLogic \u003d DeadlineExtensionsLogic.inst();"},{"lineNumber":68,"author":{"gitId":"-"},"content":" private final FeedbackSessionsLogic fsLogic \u003d FeedbackSessionsLogic.inst();"},{"lineNumber":69,"author":{"gitId":"-"},"content":" private final UsersLogic usersLogic \u003d UsersLogic.inst();"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" private SqlEmailGenerator() {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":73,"author":{"gitId":"-"},"content":" }"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" public static SqlEmailGenerator inst() {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":80,"author":{"gitId":"-"},"content":" * Generate Feedback Session Opening emails."},{"lineNumber":81,"author":{"gitId":"-"},"content":" */"},{"lineNumber":82,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateFeedbackSessionOpeningEmails(FeedbackSession session) {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" return generateFeedbackSessionOpeningOrClosingEmails(session, EmailType.FEEDBACK_OPENING);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" private List\u003cEmailWrapper\u003e generateFeedbackSessionOpeningOrClosingEmails("},{"lineNumber":87,"author":{"gitId":"-"},"content":" FeedbackSession session, EmailType emailType) {"},{"lineNumber":88,"author":{"gitId":"-"},"content":" Course course \u003d session.getCourse();"},{"lineNumber":89,"author":{"gitId":"-"},"content":" boolean isEmailNeededForStudents \u003d fsLogic.isFeedbackSessionForUserTypeToAnswer(session, false);"},{"lineNumber":90,"author":{"gitId":"-"},"content":" boolean isEmailNeededForInstructors \u003d fsLogic.isFeedbackSessionForUserTypeToAnswer(session, true);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorsToNotify \u003d isEmailNeededForStudents"},{"lineNumber":92,"author":{"gitId":"-"},"content":" ? usersLogic.getCoOwnersForCourse(course.getId())"},{"lineNumber":93,"author":{"gitId":"-"},"content":" : new ArrayList\u003c\u003e();"},{"lineNumber":94,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e students \u003d isEmailNeededForStudents"},{"lineNumber":95,"author":{"gitId":"-"},"content":" ? usersLogic.getStudentsForCourse(course.getId())"},{"lineNumber":96,"author":{"gitId":"-"},"content":" : new ArrayList\u003c\u003e();"},{"lineNumber":97,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors \u003d isEmailNeededForInstructors"},{"lineNumber":98,"author":{"gitId":"-"},"content":" ? usersLogic.getInstructorsForCourse(course.getId())"},{"lineNumber":99,"author":{"gitId":"-"},"content":" : new ArrayList\u003c\u003e();"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" if (emailType \u003d\u003d EmailType.FEEDBACK_CLOSING) {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" List\u003cDeadlineExtension\u003e deadlines \u003d session.getDeadlineExtensions();"},{"lineNumber":103,"author":{"gitId":"-"},"content":" Set\u003cUUID\u003e userIds \u003d deadlines.stream()"},{"lineNumber":104,"author":{"gitId":"-"},"content":" .map(d -\u003e d.getUser().getId())"},{"lineNumber":105,"author":{"gitId":"-"},"content":" .collect(Collectors.toSet());"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" // student."},{"lineNumber":108,"author":{"gitId":"-"},"content":" students \u003d students.stream()"},{"lineNumber":109,"author":{"gitId":"-"},"content":" .filter(x -\u003e !userIds.contains(x.getId()))"},{"lineNumber":110,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" // instructor."},{"lineNumber":113,"author":{"gitId":"-"},"content":" instructors \u003d instructors.stream()"},{"lineNumber":114,"author":{"gitId":"-"},"content":" .filter(x -\u003e !userIds.contains(x.getId()))"},{"lineNumber":115,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":116,"author":{"gitId":"-"},"content":" }"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" String status \u003d emailType \u003d\u003d EmailType.FEEDBACK_OPENING"},{"lineNumber":119,"author":{"gitId":"-"},"content":" ? FEEDBACK_STATUS_SESSION_OPENING"},{"lineNumber":120,"author":{"gitId":"-"},"content":" : FEEDBACK_STATUS_SESSION_CLOSING;"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" String template \u003d emailType \u003d\u003d EmailType.FEEDBACK_OPENING"},{"lineNumber":123,"author":{"gitId":"-"},"content":" ? EmailTemplates.USER_FEEDBACK_SESSION_OPENING.replace(\"${status}\", status)"},{"lineNumber":124,"author":{"gitId":"-"},"content":" : EmailTemplates.USER_FEEDBACK_SESSION.replace(\"${status}\", status);"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" return generateFeedbackSessionEmailBases(course, session, students, instructors, instructorsToNotify, template,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" emailType, FEEDBACK_ACTION_SUBMIT_EDIT_OR_VIEW);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":131,"author":{"gitId":"-"},"content":" * Generates the feedback session opening soon emails for the given {@code session}."},{"lineNumber":132,"author":{"gitId":"-"},"content":" *"},{"lineNumber":133,"author":{"gitId":"-"},"content":" * \u003cp\u003eThis is useful for e.g. in case the feedback session opening info was set wrongly."},{"lineNumber":134,"author":{"gitId":"-"},"content":" */"},{"lineNumber":135,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateFeedbackSessionOpeningSoonEmails(FeedbackSession session) {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" return generateFeedbackSessionOpeningSoonOrClosedEmails(session, EmailType.FEEDBACK_OPENING_SOON);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" private List\u003cEmailWrapper\u003e generateFeedbackSessionOpeningSoonOrClosedEmails("},{"lineNumber":140,"author":{"gitId":"-"},"content":" FeedbackSession session, EmailType emailType) {"},{"lineNumber":141,"author":{"gitId":"-"},"content":" Course course \u003d session.getCourse();"},{"lineNumber":142,"author":{"gitId":"-"},"content":" // Notify only course co-owners"},{"lineNumber":143,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e coOwners \u003d usersLogic.getCoOwnersForCourse(course.getId());"},{"lineNumber":144,"author":{"gitId":"-"},"content":" return coOwners.stream()"},{"lineNumber":145,"author":{"gitId":"-"},"content":" .map(coOwner -\u003e generateFeedbackSessionEmailBaseForCoowner(course, session, coOwner, emailType))"},{"lineNumber":146,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" private EmailWrapper generateFeedbackSessionEmailBaseForCoowner("},{"lineNumber":150,"author":{"gitId":"-"},"content":" Course course, FeedbackSession session, Instructor coOwner, EmailType emailType) {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" String additionalNotes;"},{"lineNumber":152,"author":{"gitId":"-"},"content":" String status;"},{"lineNumber":153,"author":{"gitId":"-"},"content":" if (emailType \u003d\u003d EmailType.FEEDBACK_OPENING_SOON) {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" String editUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.INSTRUCTOR_SESSION_EDIT_PAGE)"},{"lineNumber":155,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":156,"author":{"gitId":"-"},"content":" .withSessionName(session.getName())"},{"lineNumber":157,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":158,"author":{"gitId":"-"},"content":" // If instructor has not joined the course, populate additional notes with information to join course."},{"lineNumber":159,"author":{"gitId":"-"},"content":" if (coOwner.isRegistered()) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" additionalNotes \u003d fillUpEditFeedbackSessionDetailsFragment(editUrl);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" additionalNotes \u003d fillUpJoinCourseBeforeEditFeedbackSessionDetailsFragment(editUrl,"},{"lineNumber":163,"author":{"gitId":"-"},"content":" getInstructorCourseJoinUrl(coOwner));"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":" status \u003d FEEDBACK_STATUS_SESSION_OPENING_SOON;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" String reportUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.INSTRUCTOR_SESSION_REPORT_PAGE)"},{"lineNumber":168,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":169,"author":{"gitId":"-"},"content":" .withSessionName(session.getName())"},{"lineNumber":170,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":171,"author":{"gitId":"-"},"content":" additionalNotes \u003d fillUpViewResponsesDetailsFragment(reportUrl);"},{"lineNumber":172,"author":{"gitId":"-"},"content":" status \u003d FEEDBACK_STATUS_SESSION_CLOSED;"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" Instant startTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":176,"author":{"gitId":"-"},"content":" session.getStartTime(), session.getCourse().getTimeZone(), false);"},{"lineNumber":177,"author":{"gitId":"-"},"content":" Instant endTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":178,"author":{"gitId":"-"},"content":" session.getEndTime(), session.getCourse().getTimeZone(), false);"},{"lineNumber":179,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate(EmailTemplates.OWNER_FEEDBACK_SESSION,"},{"lineNumber":180,"author":{"gitId":"-"},"content":" \"${status}\", status,"},{"lineNumber":181,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(coOwner.getName()),"},{"lineNumber":182,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":183,"author":{"gitId":"-"},"content":" \"${courseId}\", SanitizationHelper.sanitizeForHtml(course.getId()),"},{"lineNumber":184,"author":{"gitId":"-"},"content":" \"${feedbackSessionName}\", SanitizationHelper.sanitizeForHtml(session.getName()),"},{"lineNumber":185,"author":{"gitId":"-"},"content":" \"${deadline}\", SanitizationHelper.sanitizeForHtml("},{"lineNumber":186,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(endTime, session.getCourse().getTimeZone(), DATETIME_DISPLAY_FORMAT)),"},{"lineNumber":187,"author":{"gitId":"-"},"content":" \"${sessionInstructions}\", session.getInstructionsString(),"},{"lineNumber":188,"author":{"gitId":"-"},"content":" \"${startTime}\", SanitizationHelper.sanitizeForHtml("},{"lineNumber":189,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(startTime, session.getCourse().getTimeZone(), DATETIME_DISPLAY_FORMAT)),"},{"lineNumber":190,"author":{"gitId":"-"},"content":" \"${additionalNotes}\", additionalNotes);"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(coOwner.getEmail());"},{"lineNumber":193,"author":{"gitId":"-"},"content":" email.setType(emailType);"},{"lineNumber":194,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), session.getName());"},{"lineNumber":195,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":196,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":200,"author":{"gitId":"-"},"content":" * Generates the fragment for instructions on how to edit details for feedback session at {@code editUrl}."},{"lineNumber":201,"author":{"gitId":"-"},"content":" */"},{"lineNumber":202,"author":{"gitId":"-"},"content":" private String fillUpEditFeedbackSessionDetailsFragment(String editUrl) {"},{"lineNumber":203,"author":{"gitId":"-"},"content":" return Templates.populateTemplate(EmailTemplates.FRAGMENT_OPENING_SOON_EDIT_DETAILS,"},{"lineNumber":204,"author":{"gitId":"-"},"content":" \"${sessionEditUrl}\", editUrl);"},{"lineNumber":205,"author":{"gitId":"-"},"content":" }"},{"lineNumber":206,"author":{"gitId":"-"},"content":""},{"lineNumber":207,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":208,"author":{"gitId":"-"},"content":" * Generates the fragment for instructions on how to view responses for feedback session at {@code reportUrl}."},{"lineNumber":209,"author":{"gitId":"-"},"content":" */"},{"lineNumber":210,"author":{"gitId":"-"},"content":" private String fillUpViewResponsesDetailsFragment(String reportUrl) {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" return Templates.populateTemplate(EmailTemplates.FRAGMENT_CLOSED_VIEW_RESPONSES,"},{"lineNumber":212,"author":{"gitId":"-"},"content":" \"${reportUrl}\", reportUrl);"},{"lineNumber":213,"author":{"gitId":"-"},"content":" }"},{"lineNumber":214,"author":{"gitId":"-"},"content":""},{"lineNumber":215,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":216,"author":{"gitId":"-"},"content":" * Generates the fragment for instructions on how to edit details for feedback session at {@code editUrl} and"},{"lineNumber":217,"author":{"gitId":"-"},"content":" * how to join the course at {@code joinUrl}."},{"lineNumber":218,"author":{"gitId":"-"},"content":" */"},{"lineNumber":219,"author":{"gitId":"-"},"content":" private String fillUpJoinCourseBeforeEditFeedbackSessionDetailsFragment(String editUrl, String joinUrl) {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" return Templates.populateTemplate(EmailTemplates.FRAGMENT_OPENING_SOON_JOIN_COURSE_BEFORE_EDIT_DETAILS,"},{"lineNumber":221,"author":{"gitId":"-"},"content":" \"${sessionEditUrl}\", editUrl,"},{"lineNumber":222,"author":{"gitId":"-"},"content":" \"${joinUrl}\", joinUrl"},{"lineNumber":223,"author":{"gitId":"-"},"content":" );"},{"lineNumber":224,"author":{"gitId":"-"},"content":" }"},{"lineNumber":225,"author":{"gitId":"-"},"content":""},{"lineNumber":226,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":227,"author":{"gitId":"-"},"content":" * Generates the feedback session reminder emails for the given {@code session} for {@code students}"},{"lineNumber":228,"author":{"gitId":"-"},"content":" * and {@code instructorsToRemind}. In addition, the emails will also be forwarded to {@code instructorsToNotify}."},{"lineNumber":229,"author":{"gitId":"-"},"content":" */"},{"lineNumber":230,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateFeedbackSessionReminderEmails("},{"lineNumber":231,"author":{"gitId":"-"},"content":" FeedbackSession session, List\u003cStudent\u003e students,"},{"lineNumber":232,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorsToRemind, Instructor instructorToNotify) {"},{"lineNumber":233,"author":{"gitId":"-"},"content":""},{"lineNumber":234,"author":{"gitId":"-"},"content":" Course course \u003d session.getCourse();"},{"lineNumber":235,"author":{"gitId":"-"},"content":" String template \u003d EmailTemplates.USER_FEEDBACK_SESSION.replace(\"${status}\", FEEDBACK_STATUS_SESSION_OPEN);"},{"lineNumber":236,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorToNotifyAsList \u003d new ArrayList\u003c\u003e();"},{"lineNumber":237,"author":{"gitId":"-"},"content":" if (instructorToNotify !\u003d null) {"},{"lineNumber":238,"author":{"gitId":"-"},"content":" instructorToNotifyAsList.add(instructorToNotify);"},{"lineNumber":239,"author":{"gitId":"-"},"content":" }"},{"lineNumber":240,"author":{"gitId":"-"},"content":""},{"lineNumber":241,"author":{"gitId":"-"},"content":" return generateFeedbackSessionEmailBases(course, session, students, instructorsToRemind, instructorToNotifyAsList,"},{"lineNumber":242,"author":{"gitId":"-"},"content":" template, EmailType.FEEDBACK_SESSION_REMINDER, FEEDBACK_ACTION_SUBMIT_EDIT_OR_VIEW);"},{"lineNumber":243,"author":{"gitId":"-"},"content":" }"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":246,"author":{"gitId":"-"},"content":" * Generates the email containing the summary of the feedback sessions"},{"lineNumber":247,"author":{"gitId":"-"},"content":" * email for the given {@code courseId} for {@code userEmail}."},{"lineNumber":248,"author":{"gitId":"-"},"content":" * @param courseId - ID of the course"},{"lineNumber":249,"author":{"gitId":"-"},"content":" * @param userEmail - Email of student to send feedback session summary to"},{"lineNumber":250,"author":{"gitId":"-"},"content":" * @param emailType - The email type which corresponds to the reason behind why the links are being resent"},{"lineNumber":251,"author":{"gitId":"-"},"content":" */"},{"lineNumber":252,"author":{"gitId":"-"},"content":" public EmailWrapper generateFeedbackSessionSummaryOfCourse("},{"lineNumber":253,"author":{"gitId":"-"},"content":" String courseId, String userEmail, EmailType emailType) {"},{"lineNumber":254,"author":{"gitId":"-"},"content":" assert emailType \u003d\u003d EmailType.STUDENT_EMAIL_CHANGED"},{"lineNumber":255,"author":{"gitId":"-"},"content":" || emailType \u003d\u003d EmailType.STUDENT_COURSE_LINKS_REGENERATED"},{"lineNumber":256,"author":{"gitId":"-"},"content":" || emailType \u003d\u003d EmailType.INSTRUCTOR_COURSE_LINKS_REGENERATED;"},{"lineNumber":257,"author":{"gitId":"-"},"content":""},{"lineNumber":258,"author":{"gitId":"-"},"content":" Course course \u003d coursesLogic.getCourse(courseId);"},{"lineNumber":259,"author":{"gitId":"-"},"content":" boolean isInstructor \u003d emailType \u003d\u003d EmailType.INSTRUCTOR_COURSE_LINKS_REGENERATED;"},{"lineNumber":260,"author":{"gitId":"-"},"content":" Student student \u003d usersLogic.getStudentForEmail(courseId, userEmail);"},{"lineNumber":261,"author":{"gitId":"-"},"content":" Instructor instructor \u003d null;"},{"lineNumber":262,"author":{"gitId":"-"},"content":" if (isInstructor) {"},{"lineNumber":263,"author":{"gitId":"-"},"content":" instructor \u003d usersLogic.getInstructorForEmail(courseId, userEmail);"},{"lineNumber":264,"author":{"gitId":"-"},"content":" }"},{"lineNumber":265,"author":{"gitId":"-"},"content":""},{"lineNumber":266,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e sessions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":267,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e fsInCourse \u003d fsLogic.getFeedbackSessionsForCourse(courseId);"},{"lineNumber":268,"author":{"gitId":"-"},"content":""},{"lineNumber":269,"author":{"gitId":"-"},"content":" for (FeedbackSession fs : fsInCourse) {"},{"lineNumber":270,"author":{"gitId":"-"},"content":" if (fs.isOpenEmailSent() || fs.isPublishedEmailSent()) {"},{"lineNumber":271,"author":{"gitId":"-"},"content":" sessions.add(fs);"},{"lineNumber":272,"author":{"gitId":"-"},"content":" }"},{"lineNumber":273,"author":{"gitId":"-"},"content":" }"},{"lineNumber":274,"author":{"gitId":"-"},"content":""},{"lineNumber":275,"author":{"gitId":"-"},"content":" StringBuilder linksFragmentValue \u003d new StringBuilder(1000);"},{"lineNumber":276,"author":{"gitId":"-"},"content":" String joinUrl \u003d Config.getFrontEndAppUrl("},{"lineNumber":277,"author":{"gitId":"-"},"content":" isInstructor ? instructor.getRegistrationUrl() : student.getRegistrationUrl()).toAbsoluteString();"},{"lineNumber":278,"author":{"gitId":"-"},"content":" boolean isYetToJoinCourse \u003d isInstructor ? isYetToJoinCourse(instructor) : isYetToJoinCourse(student);"},{"lineNumber":279,"author":{"gitId":"-"},"content":" String joinFragmentTemplate \u003d isInstructor"},{"lineNumber":280,"author":{"gitId":"-"},"content":" ? EmailTemplates.FRAGMENT_INSTRUCTOR_COURSE_REJOIN_AFTER_REGKEY_RESET"},{"lineNumber":281,"author":{"gitId":"-"},"content":" : emailType \u003d\u003d EmailType.STUDENT_EMAIL_CHANGED"},{"lineNumber":282,"author":{"gitId":"-"},"content":" ? EmailTemplates.FRAGMENT_STUDENT_COURSE_JOIN"},{"lineNumber":283,"author":{"gitId":"-"},"content":" : EmailTemplates.FRAGMENT_STUDENT_COURSE_REJOIN_AFTER_REGKEY_RESET;"},{"lineNumber":284,"author":{"gitId":"-"},"content":""},{"lineNumber":285,"author":{"gitId":"-"},"content":" String joinFragmentValue \u003d isYetToJoinCourse"},{"lineNumber":286,"author":{"gitId":"-"},"content":" ? Templates.populateTemplate(joinFragmentTemplate,"},{"lineNumber":287,"author":{"gitId":"-"},"content":" \"${joinUrl}\", joinUrl,"},{"lineNumber":288,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":289,"author":{"gitId":"-"},"content":" \"${coOwnersEmails}\", generateCoOwnersEmailsLine(course.getId()),"},{"lineNumber":290,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL)"},{"lineNumber":291,"author":{"gitId":"-"},"content":" : \"\";"},{"lineNumber":292,"author":{"gitId":"-"},"content":""},{"lineNumber":293,"author":{"gitId":"-"},"content":" for (FeedbackSession fs : sessions) {"},{"lineNumber":294,"author":{"gitId":"-"},"content":" String submitUrlHtml \u003d \"(Feedback session is not yet opened)\";"},{"lineNumber":295,"author":{"gitId":"-"},"content":" String reportUrlHtml \u003d \"(Feedback session is not yet published)\";"},{"lineNumber":296,"author":{"gitId":"-"},"content":""},{"lineNumber":297,"author":{"gitId":"-"},"content":" String userKey \u003d isInstructor ? instructor.getRegKey() : student.getRegKey();"},{"lineNumber":298,"author":{"gitId":"-"},"content":""},{"lineNumber":299,"author":{"gitId":"-"},"content":" if (fs.isOpened() || fs.isClosed()) {"},{"lineNumber":300,"author":{"gitId":"-"},"content":" String submitUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSION_SUBMISSION_PAGE)"},{"lineNumber":301,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":302,"author":{"gitId":"-"},"content":" .withSessionName(fs.getName())"},{"lineNumber":303,"author":{"gitId":"-"},"content":" .withRegistrationKey(userKey)"},{"lineNumber":304,"author":{"gitId":"-"},"content":" .withEntityType(isInstructor ? Const.EntityType.INSTRUCTOR : \"\")"},{"lineNumber":305,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":306,"author":{"gitId":"-"},"content":" submitUrlHtml \u003d \"\u003ca href\u003d\\\"\" + submitUrl + \"\\\"\u003e\" + submitUrl + \"\u003c/a\u003e\";"},{"lineNumber":307,"author":{"gitId":"-"},"content":" }"},{"lineNumber":308,"author":{"gitId":"-"},"content":""},{"lineNumber":309,"author":{"gitId":"-"},"content":" if (fs.isPublished()) {"},{"lineNumber":310,"author":{"gitId":"-"},"content":" String reportUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSION_RESULTS_PAGE)"},{"lineNumber":311,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":312,"author":{"gitId":"-"},"content":" .withSessionName(fs.getName())"},{"lineNumber":313,"author":{"gitId":"-"},"content":" .withRegistrationKey(userKey)"},{"lineNumber":314,"author":{"gitId":"-"},"content":" .withEntityType(isInstructor ? Const.EntityType.INSTRUCTOR : \"\")"},{"lineNumber":315,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":316,"author":{"gitId":"-"},"content":" reportUrlHtml \u003d \"\u003ca href\u003d\\\"\" + reportUrl + \"\\\"\u003e\" + reportUrl + \"\u003c/a\u003e\";"},{"lineNumber":317,"author":{"gitId":"-"},"content":" }"},{"lineNumber":318,"author":{"gitId":"-"},"content":""},{"lineNumber":319,"author":{"gitId":"-"},"content":" Instant endTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":320,"author":{"gitId":"-"},"content":" fs.getEndTime(), fs.getCourse().getTimeZone(), false);"},{"lineNumber":321,"author":{"gitId":"-"},"content":" linksFragmentValue.append(Templates.populateTemplate("},{"lineNumber":322,"author":{"gitId":"-"},"content":" EmailTemplates.FRAGMENT_SINGLE_FEEDBACK_SESSION_LINKS,"},{"lineNumber":323,"author":{"gitId":"-"},"content":" \"${feedbackSessionName}\", fs.getName(),"},{"lineNumber":324,"author":{"gitId":"-"},"content":" \"${deadline}\", TimeHelper.formatInstant(endTime, fs.getCourse().getTimeZone(), DATETIME_DISPLAY_FORMAT)"},{"lineNumber":325,"author":{"gitId":"-"},"content":" + (fs.isClosed() ? \" (Passed)\" : \"\"),"},{"lineNumber":326,"author":{"gitId":"-"},"content":" \"${submitUrl}\", submitUrlHtml,"},{"lineNumber":327,"author":{"gitId":"-"},"content":" \"${reportUrl}\", reportUrlHtml));"},{"lineNumber":328,"author":{"gitId":"-"},"content":" }"},{"lineNumber":329,"author":{"gitId":"-"},"content":""},{"lineNumber":330,"author":{"gitId":"-"},"content":" if (linksFragmentValue.length() \u003d\u003d 0) {"},{"lineNumber":331,"author":{"gitId":"-"},"content":" linksFragmentValue.append(\"No links found.\");"},{"lineNumber":332,"author":{"gitId":"-"},"content":" }"},{"lineNumber":333,"author":{"gitId":"-"},"content":""},{"lineNumber":334,"author":{"gitId":"-"},"content":" String additionalContactInformation \u003d getAdditionalContactInformationFragment(course, isInstructor);"},{"lineNumber":335,"author":{"gitId":"-"},"content":" String resendLinksTemplate \u003d emailType \u003d\u003d EmailType.STUDENT_EMAIL_CHANGED"},{"lineNumber":336,"author":{"gitId":"-"},"content":" ? Templates.EmailTemplates.USER_FEEDBACK_SESSION_RESEND_ALL_LINKS"},{"lineNumber":337,"author":{"gitId":"-"},"content":" : Templates.EmailTemplates.USER_REGKEY_REGENERATION_RESEND_ALL_COURSE_LINKS;"},{"lineNumber":338,"author":{"gitId":"-"},"content":""},{"lineNumber":339,"author":{"gitId":"-"},"content":" String userName \u003d isInstructor ? instructor.getName() : student.getName();"},{"lineNumber":340,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate(resendLinksTemplate,"},{"lineNumber":341,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(userName),"},{"lineNumber":342,"author":{"gitId":"-"},"content":" \"${userEmail}\", userEmail,"},{"lineNumber":343,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":344,"author":{"gitId":"-"},"content":" \"${courseId}\", course.getId(),"},{"lineNumber":345,"author":{"gitId":"-"},"content":" \"${joinFragment}\", joinFragmentValue,"},{"lineNumber":346,"author":{"gitId":"-"},"content":" \"${linksFragment}\", linksFragmentValue.toString(),"},{"lineNumber":347,"author":{"gitId":"-"},"content":" \"${additionalContactInformation}\", additionalContactInformation);"},{"lineNumber":348,"author":{"gitId":"-"},"content":""},{"lineNumber":349,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(userEmail);"},{"lineNumber":350,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":351,"author":{"gitId":"-"},"content":" email.setType(emailType);"},{"lineNumber":352,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), course.getId());"},{"lineNumber":353,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":354,"author":{"gitId":"-"},"content":" }"},{"lineNumber":355,"author":{"gitId":"-"},"content":""},{"lineNumber":356,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":357,"author":{"gitId":"-"},"content":" * Generates for the student an recovery email listing the links to submit/view responses for all feedback sessions"},{"lineNumber":358,"author":{"gitId":"-"},"content":" * under {@code recoveryEmailAddress} in the past 180 days. If no student with {@code recoveryEmailAddress} is"},{"lineNumber":359,"author":{"gitId":"-"},"content":" * found, generate an email stating that there is no such student in the system. If no feedback sessions are found,"},{"lineNumber":360,"author":{"gitId":"-"},"content":" * generate an email stating no feedback sessions found."},{"lineNumber":361,"author":{"gitId":"-"},"content":" */"},{"lineNumber":362,"author":{"gitId":"-"},"content":" public EmailWrapper generateSessionLinksRecoveryEmailForStudent(String recoveryEmailAddress,"},{"lineNumber":363,"author":{"gitId":"-"},"content":" String studentNameFromDatastore, Map\u003cCourseAttributes, StringBuilder\u003e dataStoreLinkFragmentMap) {"},{"lineNumber":364,"author":{"gitId":"-"},"content":""},{"lineNumber":365,"author":{"gitId":"-"},"content":" // Datastore attributes should be removed once migration is completed"},{"lineNumber":366,"author":{"gitId":"-"},"content":" String emptyName \u003d \"\";"},{"lineNumber":367,"author":{"gitId":"-"},"content":" boolean noDataStoreStudent \u003d studentNameFromDatastore.equals(emptyName); // student name cannot be empty"},{"lineNumber":368,"author":{"gitId":"-"},"content":""},{"lineNumber":369,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e studentsForEmail \u003d usersLogic.getAllStudentsForEmail(recoveryEmailAddress);"},{"lineNumber":370,"author":{"gitId":"-"},"content":""},{"lineNumber":371,"author":{"gitId":"-"},"content":" if (studentsForEmail.isEmpty() \u0026\u0026 noDataStoreStudent) {"},{"lineNumber":372,"author":{"gitId":"-"},"content":" return generateSessionLinksRecoveryEmailForNonExistentStudent(recoveryEmailAddress);"},{"lineNumber":373,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":374,"author":{"gitId":"-"},"content":" return generateSessionLinksRecoveryEmailForExistingStudent(recoveryEmailAddress, studentsForEmail,"},{"lineNumber":375,"author":{"gitId":"-"},"content":" studentNameFromDatastore, dataStoreLinkFragmentMap);"},{"lineNumber":376,"author":{"gitId":"-"},"content":" }"},{"lineNumber":377,"author":{"gitId":"-"},"content":" }"},{"lineNumber":378,"author":{"gitId":"-"},"content":""},{"lineNumber":379,"author":{"gitId":"-"},"content":" private EmailWrapper generateSessionLinksRecoveryEmailForNonExistentStudent(String recoveryEmailAddress) {"},{"lineNumber":380,"author":{"gitId":"-"},"content":" String recoveryUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSIONS_LINK_RECOVERY_PAGE).toAbsoluteString();"},{"lineNumber":381,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate("},{"lineNumber":382,"author":{"gitId":"-"},"content":" EmailTemplates.SESSION_LINKS_RECOVERY_EMAIL_NOT_FOUND,"},{"lineNumber":383,"author":{"gitId":"-"},"content":" \"${userEmail}\", SanitizationHelper.sanitizeForHtml(recoveryEmailAddress),"},{"lineNumber":384,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL,"},{"lineNumber":385,"author":{"gitId":"-"},"content":" \"${teammateHomePageLink}\", Config.getFrontEndAppUrl(\"/\").toAbsoluteString(),"},{"lineNumber":386,"author":{"gitId":"-"},"content":" \"${sessionsRecoveryLink}\", recoveryUrl);"},{"lineNumber":387,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(recoveryEmailAddress);"},{"lineNumber":388,"author":{"gitId":"-"},"content":" email.setType(EmailType.SESSION_LINKS_RECOVERY);"},{"lineNumber":389,"author":{"gitId":"-"},"content":" email.setSubjectFromType();"},{"lineNumber":390,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":391,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":392,"author":{"gitId":"-"},"content":" }"},{"lineNumber":393,"author":{"gitId":"-"},"content":""},{"lineNumber":394,"author":{"gitId":"-"},"content":" private EmailWrapper generateSessionLinksRecoveryEmailForExistingStudent(String recoveryEmailAddress,"},{"lineNumber":395,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e studentsForEmail, String studentNameFromDatastore,"},{"lineNumber":396,"author":{"gitId":"-"},"content":" Map\u003cCourseAttributes, StringBuilder\u003e dataStoreLinkFragmentMap) {"},{"lineNumber":397,"author":{"gitId":"-"},"content":" assert !studentsForEmail.isEmpty() || studentNameFromDatastore !\u003d null;"},{"lineNumber":398,"author":{"gitId":"-"},"content":" int firstStudentIdx \u003d 0;"},{"lineNumber":399,"author":{"gitId":"-"},"content":""},{"lineNumber":400,"author":{"gitId":"-"},"content":" Map\u003cCourse, StringBuilder\u003e linkFragmentsMap \u003d generateLinkFragmentsMap(studentsForEmail);"},{"lineNumber":401,"author":{"gitId":"-"},"content":""},{"lineNumber":402,"author":{"gitId":"-"},"content":" String emailBody;"},{"lineNumber":403,"author":{"gitId":"-"},"content":""},{"lineNumber":404,"author":{"gitId":"-"},"content":" String studentName;"},{"lineNumber":405,"author":{"gitId":"-"},"content":""},{"lineNumber":406,"author":{"gitId":"-"},"content":" if (studentsForEmail.isEmpty()) {"},{"lineNumber":407,"author":{"gitId":"-"},"content":" studentName \u003d studentNameFromDatastore;"},{"lineNumber":408,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":409,"author":{"gitId":"-"},"content":" studentName \u003d studentsForEmail.get(firstStudentIdx).getName();"},{"lineNumber":410,"author":{"gitId":"-"},"content":" }"},{"lineNumber":411,"author":{"gitId":"-"},"content":""},{"lineNumber":412,"author":{"gitId":"-"},"content":" var recoveryUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSIONS_LINK_RECOVERY_PAGE).toAbsoluteString();"},{"lineNumber":413,"author":{"gitId":"-"},"content":""},{"lineNumber":414,"author":{"gitId":"-"},"content":" if (linkFragmentsMap.isEmpty() \u0026\u0026 dataStoreLinkFragmentMap.isEmpty()) {"},{"lineNumber":415,"author":{"gitId":"-"},"content":" emailBody \u003d Templates.populateTemplate("},{"lineNumber":416,"author":{"gitId":"-"},"content":" EmailTemplates.SESSION_LINKS_RECOVERY_ACCESS_LINKS_NONE,"},{"lineNumber":417,"author":{"gitId":"-"},"content":" \"${teammateHomePageLink}\", Config.getFrontEndAppUrl(\"/\").toAbsoluteString(),"},{"lineNumber":418,"author":{"gitId":"-"},"content":" \"${userEmail}\", SanitizationHelper.sanitizeForHtml(recoveryEmailAddress),"},{"lineNumber":419,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL,"},{"lineNumber":420,"author":{"gitId":"-"},"content":" \"${sessionsRecoveryLink}\", recoveryUrl);"},{"lineNumber":421,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":422,"author":{"gitId":"-"},"content":" var courseFragments \u003d new StringBuilder(10000);"},{"lineNumber":423,"author":{"gitId":"-"},"content":" linkFragmentsMap.forEach((course, linksFragments) -\u003e {"},{"lineNumber":424,"author":{"gitId":"-"},"content":" String courseBody \u003d Templates.populateTemplate("},{"lineNumber":425,"author":{"gitId":"-"},"content":" EmailTemplates.FRAGMENT_SESSION_LINKS_RECOVERY_ACCESS_LINKS_BY_COURSE,"},{"lineNumber":426,"author":{"gitId":"-"},"content":" \"${sessionFragment}\", linksFragments.toString(),"},{"lineNumber":427,"author":{"gitId":"-"},"content":" \"${courseName}\", course.getName());"},{"lineNumber":428,"author":{"gitId":"-"},"content":" courseFragments.append(courseBody);"},{"lineNumber":429,"author":{"gitId":"-"},"content":" });"},{"lineNumber":430,"author":{"gitId":"-"},"content":""},{"lineNumber":431,"author":{"gitId":"-"},"content":" // To remove after migrating to postgres"},{"lineNumber":432,"author":{"gitId":"-"},"content":" dataStoreLinkFragmentMap.forEach((course, linksFragments) -\u003e {"},{"lineNumber":433,"author":{"gitId":"-"},"content":" String courseBody \u003d Templates.populateTemplate("},{"lineNumber":434,"author":{"gitId":"-"},"content":" EmailTemplates.FRAGMENT_SESSION_LINKS_RECOVERY_ACCESS_LINKS_BY_COURSE,"},{"lineNumber":435,"author":{"gitId":"-"},"content":" \"${sessionFragment}\", linksFragments.toString(),"},{"lineNumber":436,"author":{"gitId":"-"},"content":" \"${courseName}\", course.getName());"},{"lineNumber":437,"author":{"gitId":"-"},"content":" courseFragments.append(courseBody);"},{"lineNumber":438,"author":{"gitId":"-"},"content":" });"},{"lineNumber":439,"author":{"gitId":"-"},"content":" emailBody \u003d Templates.populateTemplate("},{"lineNumber":440,"author":{"gitId":"-"},"content":" EmailTemplates.SESSION_LINKS_RECOVERY_ACCESS_LINKS,"},{"lineNumber":441,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(studentName),"},{"lineNumber":442,"author":{"gitId":"-"},"content":" \"${linksFragment}\", courseFragments.toString(),"},{"lineNumber":443,"author":{"gitId":"-"},"content":" \"${userEmail}\", SanitizationHelper.sanitizeForHtml(recoveryEmailAddress),"},{"lineNumber":444,"author":{"gitId":"-"},"content":" \"${teammateHomePageLink}\", Config.getFrontEndAppUrl(\"/\").toAbsoluteString(),"},{"lineNumber":445,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL,"},{"lineNumber":446,"author":{"gitId":"-"},"content":" \"${sessionsRecoveryLink}\", recoveryUrl);"},{"lineNumber":447,"author":{"gitId":"-"},"content":" }"},{"lineNumber":448,"author":{"gitId":"-"},"content":""},{"lineNumber":449,"author":{"gitId":"-"},"content":" var email \u003d getEmptyEmailAddressedToEmail(recoveryEmailAddress);"},{"lineNumber":450,"author":{"gitId":"-"},"content":" email.setType(EmailType.SESSION_LINKS_RECOVERY);"},{"lineNumber":451,"author":{"gitId":"-"},"content":" email.setSubjectFromType();"},{"lineNumber":452,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":453,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":454,"author":{"gitId":"-"},"content":" }"},{"lineNumber":455,"author":{"gitId":"-"},"content":""},{"lineNumber":456,"author":{"gitId":"-"},"content":" private Map\u003cCourse, StringBuilder\u003e generateLinkFragmentsMap(List\u003cStudent\u003e studentsForEmail) {"},{"lineNumber":457,"author":{"gitId":"-"},"content":" Instant searchStartTime \u003d TimeHelper.getInstantDaysOffsetBeforeNow(SESSION_LINK_RECOVERY_DURATION_IN_DAYS);"},{"lineNumber":458,"author":{"gitId":"-"},"content":" Map\u003cCourse, StringBuilder\u003e linkFragmentsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":459,"author":{"gitId":"-"},"content":""},{"lineNumber":460,"author":{"gitId":"-"},"content":" for (var student : studentsForEmail) {"},{"lineNumber":461,"author":{"gitId":"-"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":462,"author":{"gitId":"-"},"content":" // Query students\u0027 courses first"},{"lineNumber":463,"author":{"gitId":"-"},"content":" // as a student will likely be in only a small number of courses."},{"lineNumber":464,"author":{"gitId":"-"},"content":" Course course \u003d student.getCourse();"},{"lineNumber":465,"author":{"gitId":"-"},"content":" String courseId \u003d course.getId();"},{"lineNumber":466,"author":{"gitId":"-"},"content":""},{"lineNumber":467,"author":{"gitId":"-"},"content":" StringBuilder linksFragmentValue;"},{"lineNumber":468,"author":{"gitId":"-"},"content":" if (linkFragmentsMap.containsKey(course)) {"},{"lineNumber":469,"author":{"gitId":"-"},"content":" linksFragmentValue \u003d linkFragmentsMap.get(course);"},{"lineNumber":470,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":471,"author":{"gitId":"-"},"content":" linksFragmentValue \u003d new StringBuilder(5000);"},{"lineNumber":472,"author":{"gitId":"-"},"content":" }"},{"lineNumber":473,"author":{"gitId":"-"},"content":""},{"lineNumber":474,"author":{"gitId":"-"},"content":" for (var session : fsLogic.getFeedbackSessionsForCourseStartingAfter(courseId, searchStartTime)) {"},{"lineNumber":475,"author":{"gitId":"-"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":476,"author":{"gitId":"-"},"content":" var submitUrlHtml \u003d \"\";"},{"lineNumber":477,"author":{"gitId":"-"},"content":" var reportUrlHtml \u003d \"\";"},{"lineNumber":478,"author":{"gitId":"-"},"content":""},{"lineNumber":479,"author":{"gitId":"-"},"content":" if (session.isOpened() || session.isClosed()) {"},{"lineNumber":480,"author":{"gitId":"-"},"content":" var submitUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSION_SUBMISSION_PAGE)"},{"lineNumber":481,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":482,"author":{"gitId":"-"},"content":" .withSessionName(session.getName())"},{"lineNumber":483,"author":{"gitId":"-"},"content":" .withRegistrationKey(student.getRegKey())"},{"lineNumber":484,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":485,"author":{"gitId":"-"},"content":" submitUrlHtml \u003d \"[\u003ca href\u003d\\\"\" + submitUrl + \"\\\"\u003esubmission link\u003c/a\u003e]\";"},{"lineNumber":486,"author":{"gitId":"-"},"content":" }"},{"lineNumber":487,"author":{"gitId":"-"},"content":""},{"lineNumber":488,"author":{"gitId":"-"},"content":" if (session.isPublished()) {"},{"lineNumber":489,"author":{"gitId":"-"},"content":" var reportUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSION_RESULTS_PAGE)"},{"lineNumber":490,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":491,"author":{"gitId":"-"},"content":" .withSessionName(session.getName())"},{"lineNumber":492,"author":{"gitId":"-"},"content":" .withRegistrationKey(student.getRegKey())"},{"lineNumber":493,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":494,"author":{"gitId":"-"},"content":" reportUrlHtml \u003d \"[\u003ca href\u003d\\\"\" + reportUrl + \"\\\"\u003eresult link\u003c/a\u003e]\";"},{"lineNumber":495,"author":{"gitId":"-"},"content":" }"},{"lineNumber":496,"author":{"gitId":"-"},"content":""},{"lineNumber":497,"author":{"gitId":"-"},"content":" if (submitUrlHtml.isEmpty() \u0026\u0026 reportUrlHtml.isEmpty()) {"},{"lineNumber":498,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":499,"author":{"gitId":"-"},"content":" }"},{"lineNumber":500,"author":{"gitId":"-"},"content":""},{"lineNumber":501,"author":{"gitId":"-"},"content":" linksFragmentValue.append(Templates.populateTemplate("},{"lineNumber":502,"author":{"gitId":"-"},"content":" EmailTemplates.FRAGMENT_SESSION_LINKS_RECOVERY_ACCESS_LINKS_BY_SESSION,"},{"lineNumber":503,"author":{"gitId":"-"},"content":" \"${sessionName}\", session.getName(),"},{"lineNumber":504,"author":{"gitId":"-"},"content":" \"${submitUrl}\", submitUrlHtml,"},{"lineNumber":505,"author":{"gitId":"-"},"content":" \"${reportUrl}\", reportUrlHtml));"},{"lineNumber":506,"author":{"gitId":"-"},"content":""},{"lineNumber":507,"author":{"gitId":"-"},"content":" linkFragmentsMap.putIfAbsent(course, linksFragmentValue);"},{"lineNumber":508,"author":{"gitId":"-"},"content":" }"},{"lineNumber":509,"author":{"gitId":"-"},"content":" }"},{"lineNumber":510,"author":{"gitId":"-"},"content":" return linkFragmentsMap;"},{"lineNumber":511,"author":{"gitId":"-"},"content":""},{"lineNumber":512,"author":{"gitId":"-"},"content":" }"},{"lineNumber":513,"author":{"gitId":"-"},"content":""},{"lineNumber":514,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":515,"author":{"gitId":"-"},"content":" * Generates the feedback session closing emails for the given {@code session}."},{"lineNumber":516,"author":{"gitId":"-"},"content":" *"},{"lineNumber":517,"author":{"gitId":"-"},"content":" * \u003cp\u003eStudents and instructors with deadline extensions are not notified."},{"lineNumber":518,"author":{"gitId":"-"},"content":" */"},{"lineNumber":519,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateFeedbackSessionClosingEmails(FeedbackSession session) {"},{"lineNumber":520,"author":{"gitId":"-"},"content":" return generateFeedbackSessionOpeningOrClosingEmails(session, EmailType.FEEDBACK_CLOSING);"},{"lineNumber":521,"author":{"gitId":"-"},"content":" }"},{"lineNumber":522,"author":{"gitId":"-"},"content":""},{"lineNumber":523,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":524,"author":{"gitId":"-"},"content":" * Generates the feedback session closed emails for the given {@code session}."},{"lineNumber":525,"author":{"gitId":"-"},"content":" */"},{"lineNumber":526,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateFeedbackSessionClosedEmails(FeedbackSession session) {"},{"lineNumber":527,"author":{"gitId":"-"},"content":" return generateFeedbackSessionOpeningSoonOrClosedEmails(session, EmailType.FEEDBACK_CLOSED);"},{"lineNumber":528,"author":{"gitId":"-"},"content":" }"},{"lineNumber":529,"author":{"gitId":"-"},"content":""},{"lineNumber":530,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":531,"author":{"gitId":"-"},"content":" * Generates the feedback session closing emails for users with deadline extensions."},{"lineNumber":532,"author":{"gitId":"-"},"content":" */"},{"lineNumber":533,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateFeedbackSessionClosingWithExtensionEmails("},{"lineNumber":534,"author":{"gitId":"-"},"content":" FeedbackSession session, List\u003cDeadlineExtension\u003e deadlineExtensions) {"},{"lineNumber":535,"author":{"gitId":"-"},"content":" Course course \u003d session.getCourse();"},{"lineNumber":536,"author":{"gitId":"-"},"content":""},{"lineNumber":537,"author":{"gitId":"-"},"content":" boolean isEmailNeededForStudents \u003d"},{"lineNumber":538,"author":{"gitId":"-"},"content":" !deadlineExtensions.isEmpty() \u0026\u0026 fsLogic.isFeedbackSessionForUserTypeToAnswer(session, false);"},{"lineNumber":539,"author":{"gitId":"-"},"content":" boolean isEmailNeededForInstructors \u003d"},{"lineNumber":540,"author":{"gitId":"-"},"content":" !deadlineExtensions.isEmpty() \u0026\u0026 fsLogic.isFeedbackSessionForUserTypeToAnswer(session, true);"},{"lineNumber":541,"author":{"gitId":"-"},"content":""},{"lineNumber":542,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e students \u003d new ArrayList\u003c\u003e();"},{"lineNumber":543,"author":{"gitId":"-"},"content":" if (isEmailNeededForStudents) {"},{"lineNumber":544,"author":{"gitId":"-"},"content":" for (DeadlineExtension de : deadlineExtensions) {"},{"lineNumber":545,"author":{"gitId":"-"},"content":" Student student \u003d usersLogic.getStudentForEmail(course.getId(), de.getUser().getEmail());"},{"lineNumber":546,"author":{"gitId":"-"},"content":" if (student !\u003d null) {"},{"lineNumber":547,"author":{"gitId":"-"},"content":" students.add(student);"},{"lineNumber":548,"author":{"gitId":"-"},"content":" }"},{"lineNumber":549,"author":{"gitId":"-"},"content":" }"},{"lineNumber":550,"author":{"gitId":"-"},"content":" }"},{"lineNumber":551,"author":{"gitId":"-"},"content":""},{"lineNumber":552,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors \u003d new ArrayList\u003c\u003e();"},{"lineNumber":553,"author":{"gitId":"-"},"content":" if (isEmailNeededForInstructors) {"},{"lineNumber":554,"author":{"gitId":"-"},"content":" for (DeadlineExtension de : deadlineExtensions) {"},{"lineNumber":555,"author":{"gitId":"-"},"content":" Instructor instructor \u003d"},{"lineNumber":556,"author":{"gitId":"-"},"content":" usersLogic.getInstructorForEmail(course.getId(), de.getUser().getEmail());"},{"lineNumber":557,"author":{"gitId":"-"},"content":" if (instructor !\u003d null) {"},{"lineNumber":558,"author":{"gitId":"-"},"content":" instructors.add(instructor);"},{"lineNumber":559,"author":{"gitId":"-"},"content":" }"},{"lineNumber":560,"author":{"gitId":"-"},"content":" }"},{"lineNumber":561,"author":{"gitId":"-"},"content":" }"},{"lineNumber":562,"author":{"gitId":"-"},"content":""},{"lineNumber":563,"author":{"gitId":"-"},"content":" String template \u003d EmailTemplates.USER_FEEDBACK_SESSION.replace(\"${status}\", FEEDBACK_STATUS_SESSION_CLOSING);"},{"lineNumber":564,"author":{"gitId":"-"},"content":" EmailType type \u003d EmailType.FEEDBACK_CLOSING;"},{"lineNumber":565,"author":{"gitId":"-"},"content":" String feedbackAction \u003d FEEDBACK_ACTION_SUBMIT_EDIT_OR_VIEW;"},{"lineNumber":566,"author":{"gitId":"-"},"content":" List\u003cEmailWrapper\u003e emails \u003d new ArrayList\u003c\u003e();"},{"lineNumber":567,"author":{"gitId":"-"},"content":" for (Student student : students) {"},{"lineNumber":568,"author":{"gitId":"-"},"content":" emails.addAll(generateFeedbackSessionEmailBases(course, session, Collections.singletonList(student),"},{"lineNumber":569,"author":{"gitId":"-"},"content":" Collections.emptyList(), Collections.emptyList(), template, type, feedbackAction));"},{"lineNumber":570,"author":{"gitId":"-"},"content":" }"},{"lineNumber":571,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructors) {"},{"lineNumber":572,"author":{"gitId":"-"},"content":" emails.addAll(generateFeedbackSessionEmailBases(course, session, Collections.emptyList(),"},{"lineNumber":573,"author":{"gitId":"-"},"content":" Collections.singletonList(instructor), Collections.emptyList(), template, type, feedbackAction));"},{"lineNumber":574,"author":{"gitId":"-"},"content":" }"},{"lineNumber":575,"author":{"gitId":"-"},"content":" return emails;"},{"lineNumber":576,"author":{"gitId":"-"},"content":" }"},{"lineNumber":577,"author":{"gitId":"-"},"content":""},{"lineNumber":578,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":579,"author":{"gitId":"-"},"content":" * Generates the feedback session published emails for the given {@code session}."},{"lineNumber":580,"author":{"gitId":"-"},"content":" */"},{"lineNumber":581,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateFeedbackSessionPublishedEmails(FeedbackSession session) {"},{"lineNumber":582,"author":{"gitId":"-"},"content":" return generateFeedbackSessionPublishedOrUnpublishedEmails(session, EmailType.FEEDBACK_PUBLISHED);"},{"lineNumber":583,"author":{"gitId":"-"},"content":" }"},{"lineNumber":584,"author":{"gitId":"-"},"content":""},{"lineNumber":585,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":586,"author":{"gitId":"-"},"content":" * Generates the feedback session published emails for the given {@code students} and"},{"lineNumber":587,"author":{"gitId":"-"},"content":" * {@code instructors} in {@code session}."},{"lineNumber":588,"author":{"gitId":"-"},"content":" */"},{"lineNumber":589,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateFeedbackSessionPublishedEmails(FeedbackSession session,"},{"lineNumber":590,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e students, List\u003cInstructor\u003e instructors,"},{"lineNumber":591,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorsToNotify) {"},{"lineNumber":592,"author":{"gitId":"-"},"content":" return generateFeedbackSessionPublishedOrUnpublishedEmails("},{"lineNumber":593,"author":{"gitId":"-"},"content":" session, students, instructors, instructorsToNotify, EmailType.FEEDBACK_PUBLISHED);"},{"lineNumber":594,"author":{"gitId":"-"},"content":" }"},{"lineNumber":595,"author":{"gitId":"-"},"content":""},{"lineNumber":596,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":597,"author":{"gitId":"-"},"content":" * Generates the feedback session unpublished emails for the given {@code session}."},{"lineNumber":598,"author":{"gitId":"-"},"content":" */"},{"lineNumber":599,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateFeedbackSessionUnpublishedEmails(FeedbackSession session) {"},{"lineNumber":600,"author":{"gitId":"-"},"content":" return generateFeedbackSessionPublishedOrUnpublishedEmails(session, EmailType.FEEDBACK_UNPUBLISHED);"},{"lineNumber":601,"author":{"gitId":"-"},"content":" }"},{"lineNumber":602,"author":{"gitId":"-"},"content":""},{"lineNumber":603,"author":{"gitId":"-"},"content":" private List\u003cEmailWrapper\u003e generateFeedbackSessionPublishedOrUnpublishedEmails("},{"lineNumber":604,"author":{"gitId":"-"},"content":" FeedbackSession session, EmailType emailType) {"},{"lineNumber":605,"author":{"gitId":"-"},"content":" boolean isEmailNeededForStudents \u003d fsLogic.isFeedbackSessionViewableToUserType(session, false);"},{"lineNumber":606,"author":{"gitId":"-"},"content":" boolean isEmailNeededForInstructors \u003d fsLogic.isFeedbackSessionViewableToUserType(session, true);"},{"lineNumber":607,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorsToNotify \u003d isEmailNeededForStudents"},{"lineNumber":608,"author":{"gitId":"-"},"content":" ? usersLogic.getCoOwnersForCourse(session.getCourse().getId())"},{"lineNumber":609,"author":{"gitId":"-"},"content":" : new ArrayList\u003c\u003e();"},{"lineNumber":610,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e students \u003d isEmailNeededForStudents"},{"lineNumber":611,"author":{"gitId":"-"},"content":" ? usersLogic.getStudentsForCourse(session.getCourse().getId())"},{"lineNumber":612,"author":{"gitId":"-"},"content":" : new ArrayList\u003c\u003e();"},{"lineNumber":613,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors \u003d isEmailNeededForInstructors"},{"lineNumber":614,"author":{"gitId":"-"},"content":" ? usersLogic.getInstructorsForCourse(session.getCourse().getId())"},{"lineNumber":615,"author":{"gitId":"-"},"content":" : new ArrayList\u003c\u003e();"},{"lineNumber":616,"author":{"gitId":"-"},"content":""},{"lineNumber":617,"author":{"gitId":"-"},"content":" return generateFeedbackSessionPublishedOrUnpublishedEmails("},{"lineNumber":618,"author":{"gitId":"-"},"content":" session, students, instructors, instructorsToNotify, emailType);"},{"lineNumber":619,"author":{"gitId":"-"},"content":" }"},{"lineNumber":620,"author":{"gitId":"-"},"content":""},{"lineNumber":621,"author":{"gitId":"-"},"content":" private List\u003cEmailWrapper\u003e generateFeedbackSessionPublishedOrUnpublishedEmails("},{"lineNumber":622,"author":{"gitId":"-"},"content":" FeedbackSession session, List\u003cStudent\u003e students,"},{"lineNumber":623,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors, List\u003cInstructor\u003e instructorsToNotify, EmailType emailType) {"},{"lineNumber":624,"author":{"gitId":"-"},"content":" Course course \u003d session.getCourse();"},{"lineNumber":625,"author":{"gitId":"-"},"content":" String template;"},{"lineNumber":626,"author":{"gitId":"-"},"content":" String action;"},{"lineNumber":627,"author":{"gitId":"-"},"content":" if (emailType \u003d\u003d EmailType.FEEDBACK_PUBLISHED) {"},{"lineNumber":628,"author":{"gitId":"-"},"content":" template \u003d EmailTemplates.USER_FEEDBACK_SESSION_PUBLISHED;"},{"lineNumber":629,"author":{"gitId":"-"},"content":" action \u003d FEEDBACK_ACTION_VIEW;"},{"lineNumber":630,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":631,"author":{"gitId":"-"},"content":" template \u003d EmailTemplates.USER_FEEDBACK_SESSION_UNPUBLISHED;"},{"lineNumber":632,"author":{"gitId":"-"},"content":" action \u003d FEEDBACK_ACTION_SUBMIT_EDIT_OR_VIEW;"},{"lineNumber":633,"author":{"gitId":"-"},"content":" }"},{"lineNumber":634,"author":{"gitId":"-"},"content":""},{"lineNumber":635,"author":{"gitId":"-"},"content":" return generateFeedbackSessionEmailBases(course, session, students, instructors, instructorsToNotify, template,"},{"lineNumber":636,"author":{"gitId":"-"},"content":" emailType, action);"},{"lineNumber":637,"author":{"gitId":"-"},"content":" }"},{"lineNumber":638,"author":{"gitId":"-"},"content":""},{"lineNumber":639,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":640,"author":{"gitId":"-"},"content":" * Generates deadline extension granted emails."},{"lineNumber":641,"author":{"gitId":"-"},"content":" */"},{"lineNumber":642,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateDeadlineGrantedEmails(Course course,"},{"lineNumber":643,"author":{"gitId":"-"},"content":" FeedbackSession session, Map\u003cString, Instant\u003e createdDeadlines, boolean areInstructors) {"},{"lineNumber":644,"author":{"gitId":"-"},"content":" return createdDeadlines.entrySet()"},{"lineNumber":645,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":646,"author":{"gitId":"-"},"content":" .map(entry -\u003e"},{"lineNumber":647,"author":{"gitId":"-"},"content":" generateDeadlineExtensionEmail(course, session,"},{"lineNumber":648,"author":{"gitId":"-"},"content":" session.getEndTime(), entry.getValue(), EmailType.DEADLINE_EXTENSION_GRANTED,"},{"lineNumber":649,"author":{"gitId":"-"},"content":" entry.getKey(), areInstructors))"},{"lineNumber":650,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":651,"author":{"gitId":"-"},"content":" }"},{"lineNumber":652,"author":{"gitId":"-"},"content":""},{"lineNumber":653,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":654,"author":{"gitId":"-"},"content":" * Generates deadline extension updated emails."},{"lineNumber":655,"author":{"gitId":"-"},"content":" */"},{"lineNumber":656,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateDeadlineUpdatedEmails(Course course, FeedbackSession session,"},{"lineNumber":657,"author":{"gitId":"-"},"content":" Map\u003cString, Instant\u003e updatedDeadlines, Map\u003cString, Instant\u003e oldDeadlines, boolean areInstructors) {"},{"lineNumber":658,"author":{"gitId":"-"},"content":" return updatedDeadlines.entrySet()"},{"lineNumber":659,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":660,"author":{"gitId":"-"},"content":" .map(entry -\u003e"},{"lineNumber":661,"author":{"gitId":"-"},"content":" generateDeadlineExtensionEmail(course, session,"},{"lineNumber":662,"author":{"gitId":"-"},"content":" oldDeadlines.get(entry.getKey()), entry.getValue(), EmailType.DEADLINE_EXTENSION_UPDATED,"},{"lineNumber":663,"author":{"gitId":"-"},"content":" entry.getKey(), areInstructors))"},{"lineNumber":664,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":665,"author":{"gitId":"-"},"content":" }"},{"lineNumber":666,"author":{"gitId":"-"},"content":""},{"lineNumber":667,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":668,"author":{"gitId":"-"},"content":" * Generates deadline extension revoked emails."},{"lineNumber":669,"author":{"gitId":"-"},"content":" */"},{"lineNumber":670,"author":{"gitId":"-"},"content":" public List\u003cEmailWrapper\u003e generateDeadlineRevokedEmails(Course course,"},{"lineNumber":671,"author":{"gitId":"-"},"content":" FeedbackSession session, Map\u003cString, Instant\u003e revokedDeadlines, boolean areInstructors) {"},{"lineNumber":672,"author":{"gitId":"-"},"content":" return revokedDeadlines.entrySet()"},{"lineNumber":673,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":674,"author":{"gitId":"-"},"content":" .map(entry -\u003e"},{"lineNumber":675,"author":{"gitId":"-"},"content":" generateDeadlineExtensionEmail(course, session,"},{"lineNumber":676,"author":{"gitId":"-"},"content":" entry.getValue(), session.getEndTime(), EmailType.DEADLINE_EXTENSION_REVOKED,"},{"lineNumber":677,"author":{"gitId":"-"},"content":" entry.getKey(), areInstructors))"},{"lineNumber":678,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":679,"author":{"gitId":"-"},"content":" }"},{"lineNumber":680,"author":{"gitId":"-"},"content":""},{"lineNumber":681,"author":{"gitId":"-"},"content":" private EmailWrapper generateDeadlineExtensionEmail("},{"lineNumber":682,"author":{"gitId":"-"},"content":" Course course, FeedbackSession session, Instant oldEndTime, Instant endTime,"},{"lineNumber":683,"author":{"gitId":"-"},"content":" EmailType emailType, String userEmail, boolean isInstructor) {"},{"lineNumber":684,"author":{"gitId":"-"},"content":" String status;"},{"lineNumber":685,"author":{"gitId":"-"},"content":""},{"lineNumber":686,"author":{"gitId":"-"},"content":" switch (emailType) {"},{"lineNumber":687,"author":{"gitId":"-"},"content":" case DEADLINE_EXTENSION_GRANTED:"},{"lineNumber":688,"author":{"gitId":"-"},"content":" status \u003d \"You have been granted a deadline extension for the following feedback session.\";"},{"lineNumber":689,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":690,"author":{"gitId":"-"},"content":" case DEADLINE_EXTENSION_UPDATED:"},{"lineNumber":691,"author":{"gitId":"-"},"content":" status \u003d \"Your deadline for the following feedback session has been updated.\";"},{"lineNumber":692,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":693,"author":{"gitId":"-"},"content":" case DEADLINE_EXTENSION_REVOKED:"},{"lineNumber":694,"author":{"gitId":"-"},"content":" status \u003d \"Your deadline extension for the following feedback session has been revoked.\";"},{"lineNumber":695,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":696,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":697,"author":{"gitId":"-"},"content":" throw new AssertionError(\"Invalid email type: \" + emailType);"},{"lineNumber":698,"author":{"gitId":"-"},"content":" }"},{"lineNumber":699,"author":{"gitId":"-"},"content":""},{"lineNumber":700,"author":{"gitId":"-"},"content":" String additionalContactInformation \u003d getAdditionalContactInformationFragment(course, isInstructor);"},{"lineNumber":701,"author":{"gitId":"-"},"content":" Instant oldEndTimeFormatted \u003d"},{"lineNumber":702,"author":{"gitId":"-"},"content":" TimeHelper.getMidnightAdjustedInstantBasedOnZone(oldEndTime, session.getCourse().getTimeZone(), false);"},{"lineNumber":703,"author":{"gitId":"-"},"content":" Instant newEndTimeFormatted \u003d"},{"lineNumber":704,"author":{"gitId":"-"},"content":" TimeHelper.getMidnightAdjustedInstantBasedOnZone(endTime, session.getCourse().getTimeZone(), false);"},{"lineNumber":705,"author":{"gitId":"-"},"content":" String template \u003d EmailTemplates.USER_DEADLINE_EXTENSION"},{"lineNumber":706,"author":{"gitId":"-"},"content":" .replace(\"${status}\", status)"},{"lineNumber":707,"author":{"gitId":"-"},"content":" .replace(\"${oldEndTime}\", SanitizationHelper.sanitizeForHtml("},{"lineNumber":708,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(oldEndTimeFormatted,"},{"lineNumber":709,"author":{"gitId":"-"},"content":" session.getCourse().getTimeZone(), DATETIME_DISPLAY_FORMAT)))"},{"lineNumber":710,"author":{"gitId":"-"},"content":" .replace(\"${newEndTime}\", SanitizationHelper.sanitizeForHtml("},{"lineNumber":711,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(newEndTimeFormatted,"},{"lineNumber":712,"author":{"gitId":"-"},"content":" session.getCourse().getTimeZone(), DATETIME_DISPLAY_FORMAT)));"},{"lineNumber":713,"author":{"gitId":"-"},"content":" String feedbackAction \u003d FEEDBACK_ACTION_SUBMIT_EDIT_OR_VIEW;"},{"lineNumber":714,"author":{"gitId":"-"},"content":""},{"lineNumber":715,"author":{"gitId":"-"},"content":" if (isInstructor) {"},{"lineNumber":716,"author":{"gitId":"-"},"content":" Instructor instructor \u003d usersLogic.getInstructorForEmail(course.getId(), userEmail);"},{"lineNumber":717,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":718,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":719,"author":{"gitId":"-"},"content":" }"},{"lineNumber":720,"author":{"gitId":"-"},"content":" return generateFeedbackSessionEmailBaseForInstructors("},{"lineNumber":721,"author":{"gitId":"-"},"content":" course, session, instructor, template, emailType, feedbackAction, additionalContactInformation);"},{"lineNumber":722,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":723,"author":{"gitId":"-"},"content":" Student student \u003d usersLogic.getStudentForEmail(course.getId(), userEmail);"},{"lineNumber":724,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":725,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":726,"author":{"gitId":"-"},"content":" }"},{"lineNumber":727,"author":{"gitId":"-"},"content":" return generateFeedbackSessionEmailBaseForStudents("},{"lineNumber":728,"author":{"gitId":"-"},"content":" course, session, student, template, emailType, feedbackAction, additionalContactInformation);"},{"lineNumber":729,"author":{"gitId":"-"},"content":" }"},{"lineNumber":730,"author":{"gitId":"-"},"content":" }"},{"lineNumber":731,"author":{"gitId":"-"},"content":""},{"lineNumber":732,"author":{"gitId":"-"},"content":" private List\u003cEmailWrapper\u003e generateFeedbackSessionEmailBases("},{"lineNumber":733,"author":{"gitId":"-"},"content":" Course course, FeedbackSession session, List\u003cStudent\u003e students,"},{"lineNumber":734,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors, List\u003cInstructor\u003e instructorsToNotify, String template,"},{"lineNumber":735,"author":{"gitId":"-"},"content":" EmailType type, String feedbackAction) {"},{"lineNumber":736,"author":{"gitId":"-"},"content":" StringBuilder studentAdditionalContactBuilder \u003d new StringBuilder();"},{"lineNumber":737,"author":{"gitId":"-"},"content":" StringBuilder instructorAdditionalContactBuilder \u003d new StringBuilder();"},{"lineNumber":738,"author":{"gitId":"-"},"content":" studentAdditionalContactBuilder.append(getAdditionalContactInformationFragment(course, false));"},{"lineNumber":739,"author":{"gitId":"-"},"content":" instructorAdditionalContactBuilder.append(getAdditionalContactInformationFragment(course, true));"},{"lineNumber":740,"author":{"gitId":"-"},"content":""},{"lineNumber":741,"author":{"gitId":"-"},"content":" List\u003cEmailWrapper\u003e emails \u003d new ArrayList\u003c\u003e();"},{"lineNumber":742,"author":{"gitId":"-"},"content":" for (Student student : students) {"},{"lineNumber":743,"author":{"gitId":"-"},"content":" emails.add(generateFeedbackSessionEmailBaseForStudents(course, session, student,"},{"lineNumber":744,"author":{"gitId":"-"},"content":" template, type, feedbackAction, studentAdditionalContactBuilder.toString()));"},{"lineNumber":745,"author":{"gitId":"-"},"content":" }"},{"lineNumber":746,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructors) {"},{"lineNumber":747,"author":{"gitId":"-"},"content":" emails.add(generateFeedbackSessionEmailBaseForInstructors(course, session, instructor,"},{"lineNumber":748,"author":{"gitId":"-"},"content":" template, type, feedbackAction, instructorAdditionalContactBuilder.toString()));"},{"lineNumber":749,"author":{"gitId":"-"},"content":" }"},{"lineNumber":750,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructorsToNotify) {"},{"lineNumber":751,"author":{"gitId":"-"},"content":" emails.add(generateFeedbackSessionEmailBaseForNotifiedInstructors(course, session, instructor,"},{"lineNumber":752,"author":{"gitId":"-"},"content":" template, type, feedbackAction, studentAdditionalContactBuilder.toString()));"},{"lineNumber":753,"author":{"gitId":"-"},"content":" }"},{"lineNumber":754,"author":{"gitId":"-"},"content":" return emails;"},{"lineNumber":755,"author":{"gitId":"-"},"content":" }"},{"lineNumber":756,"author":{"gitId":"-"},"content":""},{"lineNumber":757,"author":{"gitId":"-"},"content":" private EmailWrapper generateFeedbackSessionEmailBaseForStudents("},{"lineNumber":758,"author":{"gitId":"-"},"content":" Course course, FeedbackSession session, Student student, String template,"},{"lineNumber":759,"author":{"gitId":"-"},"content":" EmailType type, String feedbackAction, String additionalContactInformation) {"},{"lineNumber":760,"author":{"gitId":"-"},"content":" String submitUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSION_SUBMISSION_PAGE)"},{"lineNumber":761,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":762,"author":{"gitId":"-"},"content":" .withSessionName(session.getName())"},{"lineNumber":763,"author":{"gitId":"-"},"content":" .withRegistrationKey(student.getRegKey())"},{"lineNumber":764,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":765,"author":{"gitId":"-"},"content":""},{"lineNumber":766,"author":{"gitId":"-"},"content":" String reportUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSION_RESULTS_PAGE)"},{"lineNumber":767,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":768,"author":{"gitId":"-"},"content":" .withSessionName(session.getName())"},{"lineNumber":769,"author":{"gitId":"-"},"content":" .withRegistrationKey(student.getRegKey())"},{"lineNumber":770,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":771,"author":{"gitId":"-"},"content":""},{"lineNumber":772,"author":{"gitId":"-"},"content":" Instant deadline \u003d deLogic.getDeadlineForUser(session, student);"},{"lineNumber":773,"author":{"gitId":"-"},"content":""},{"lineNumber":774,"author":{"gitId":"-"},"content":" Instant endTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":775,"author":{"gitId":"-"},"content":" deadline, session.getCourse().getTimeZone(), false);"},{"lineNumber":776,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate(template,"},{"lineNumber":777,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(student.getName()),"},{"lineNumber":778,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":779,"author":{"gitId":"-"},"content":" \"${courseId}\", SanitizationHelper.sanitizeForHtml(course.getId()),"},{"lineNumber":780,"author":{"gitId":"-"},"content":" \"${feedbackSessionName}\", SanitizationHelper.sanitizeForHtml(session.getName()),"},{"lineNumber":781,"author":{"gitId":"-"},"content":" \"${deadline}\", SanitizationHelper.sanitizeForHtml("},{"lineNumber":782,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(endTime, session.getCourse().getTimeZone(), DATETIME_DISPLAY_FORMAT))"},{"lineNumber":783,"author":{"gitId":"-"},"content":" + (session.getEndTime().equals(deadline) ? \"\" : \" (after extension)\"),"},{"lineNumber":784,"author":{"gitId":"-"},"content":" \"${instructorPreamble}\", \"\","},{"lineNumber":785,"author":{"gitId":"-"},"content":" \"${sessionInstructions}\", session.getInstructionsString(),"},{"lineNumber":786,"author":{"gitId":"-"},"content":" \"${submitUrl}\", submitUrl,"},{"lineNumber":787,"author":{"gitId":"-"},"content":" \"${reportUrl}\", reportUrl,"},{"lineNumber":788,"author":{"gitId":"-"},"content":" \"${feedbackAction}\", feedbackAction,"},{"lineNumber":789,"author":{"gitId":"-"},"content":" \"${additionalContactInformation}\", additionalContactInformation);"},{"lineNumber":790,"author":{"gitId":"-"},"content":""},{"lineNumber":791,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(student.getEmail());"},{"lineNumber":792,"author":{"gitId":"-"},"content":" email.setType(type);"},{"lineNumber":793,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), session.getName());"},{"lineNumber":794,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":795,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":796,"author":{"gitId":"-"},"content":" }"},{"lineNumber":797,"author":{"gitId":"-"},"content":""},{"lineNumber":798,"author":{"gitId":"-"},"content":" private EmailWrapper generateFeedbackSessionEmailBaseForInstructors("},{"lineNumber":799,"author":{"gitId":"-"},"content":" Course course, FeedbackSession session, Instructor instructor,"},{"lineNumber":800,"author":{"gitId":"-"},"content":" String template, EmailType type, String feedbackAction, String additionalContactInformation) {"},{"lineNumber":801,"author":{"gitId":"-"},"content":" String submitUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSION_SUBMISSION_PAGE)"},{"lineNumber":802,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":803,"author":{"gitId":"-"},"content":" .withSessionName(session.getName())"},{"lineNumber":804,"author":{"gitId":"-"},"content":" .withRegistrationKey(instructor.getRegKey())"},{"lineNumber":805,"author":{"gitId":"-"},"content":" .withEntityType(Const.EntityType.INSTRUCTOR)"},{"lineNumber":806,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":807,"author":{"gitId":"-"},"content":""},{"lineNumber":808,"author":{"gitId":"-"},"content":" String reportUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.SESSION_RESULTS_PAGE)"},{"lineNumber":809,"author":{"gitId":"-"},"content":" .withCourseId(course.getId())"},{"lineNumber":810,"author":{"gitId":"-"},"content":" .withSessionName(session.getName())"},{"lineNumber":811,"author":{"gitId":"-"},"content":" .withRegistrationKey(instructor.getRegKey())"},{"lineNumber":812,"author":{"gitId":"-"},"content":" .withEntityType(Const.EntityType.INSTRUCTOR)"},{"lineNumber":813,"author":{"gitId":"-"},"content":" .toAbsoluteString();"},{"lineNumber":814,"author":{"gitId":"-"},"content":""},{"lineNumber":815,"author":{"gitId":"-"},"content":" Instant deadline \u003d deLogic.getDeadlineForUser(session, instructor);"},{"lineNumber":816,"author":{"gitId":"-"},"content":""},{"lineNumber":817,"author":{"gitId":"-"},"content":" Instant endTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":818,"author":{"gitId":"-"},"content":" deadline, session.getCourse().getTimeZone(), false);"},{"lineNumber":819,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate(template,"},{"lineNumber":820,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(instructor.getName()),"},{"lineNumber":821,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":822,"author":{"gitId":"-"},"content":" \"${courseId}\", SanitizationHelper.sanitizeForHtml(course.getId()),"},{"lineNumber":823,"author":{"gitId":"-"},"content":" \"${feedbackSessionName}\", SanitizationHelper.sanitizeForHtml(session.getName()),"},{"lineNumber":824,"author":{"gitId":"-"},"content":" \"${deadline}\", SanitizationHelper.sanitizeForHtml("},{"lineNumber":825,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(endTime, session.getCourse().getTimeZone(), DATETIME_DISPLAY_FORMAT))"},{"lineNumber":826,"author":{"gitId":"-"},"content":" + (session.getEndTime().equals(deadline) ? \"\" : \" (after extension)\"),"},{"lineNumber":827,"author":{"gitId":"-"},"content":" \"${instructorPreamble}\", \"\","},{"lineNumber":828,"author":{"gitId":"-"},"content":" \"${sessionInstructions}\", session.getInstructionsString(),"},{"lineNumber":829,"author":{"gitId":"-"},"content":" \"${submitUrl}\", submitUrl,"},{"lineNumber":830,"author":{"gitId":"-"},"content":" \"${reportUrl}\", reportUrl,"},{"lineNumber":831,"author":{"gitId":"-"},"content":" \"${feedbackAction}\", feedbackAction,"},{"lineNumber":832,"author":{"gitId":"-"},"content":" \"${additionalContactInformation}\", additionalContactInformation);"},{"lineNumber":833,"author":{"gitId":"-"},"content":""},{"lineNumber":834,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(instructor.getEmail());"},{"lineNumber":835,"author":{"gitId":"-"},"content":" email.setType(type);"},{"lineNumber":836,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), session.getName());"},{"lineNumber":837,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":838,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":839,"author":{"gitId":"-"},"content":" }"},{"lineNumber":840,"author":{"gitId":"-"},"content":""},{"lineNumber":841,"author":{"gitId":"-"},"content":" private EmailWrapper generateFeedbackSessionEmailBaseForNotifiedInstructors("},{"lineNumber":842,"author":{"gitId":"-"},"content":" Course course, FeedbackSession session, Instructor instructor,"},{"lineNumber":843,"author":{"gitId":"-"},"content":" String template, EmailType type, String feedbackAction, String additionalContactInformation) {"},{"lineNumber":844,"author":{"gitId":"-"},"content":""},{"lineNumber":845,"author":{"gitId":"-"},"content":" Instant endTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":846,"author":{"gitId":"-"},"content":" session.getEndTime(), session.getCourse().getTimeZone(), false);"},{"lineNumber":847,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate(template,"},{"lineNumber":848,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(instructor.getName()),"},{"lineNumber":849,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":850,"author":{"gitId":"-"},"content":" \"${courseId}\", SanitizationHelper.sanitizeForHtml(course.getId()),"},{"lineNumber":851,"author":{"gitId":"-"},"content":" \"${feedbackSessionName}\", SanitizationHelper.sanitizeForHtml(session.getName()),"},{"lineNumber":852,"author":{"gitId":"-"},"content":" \"${deadline}\", SanitizationHelper.sanitizeForHtml("},{"lineNumber":853,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(endTime, session.getCourse().getTimeZone(), DATETIME_DISPLAY_FORMAT)),"},{"lineNumber":854,"author":{"gitId":"-"},"content":" \"${instructorPreamble}\", fillUpInstructorPreamble(course),"},{"lineNumber":855,"author":{"gitId":"-"},"content":" \"${sessionInstructions}\", session.getInstructionsString(),"},{"lineNumber":856,"author":{"gitId":"-"},"content":" \"${submitUrl}\", \"{in the actual email sent to the students, this will be the unique link}\","},{"lineNumber":857,"author":{"gitId":"-"},"content":" \"${reportUrl}\", \"{in the actual email sent to the students, this will be the unique link}\","},{"lineNumber":858,"author":{"gitId":"-"},"content":" \"${feedbackAction}\", feedbackAction,"},{"lineNumber":859,"author":{"gitId":"-"},"content":" \"${additionalContactInformation}\", additionalContactInformation);"},{"lineNumber":860,"author":{"gitId":"-"},"content":""},{"lineNumber":861,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(instructor.getEmail());"},{"lineNumber":862,"author":{"gitId":"-"},"content":" email.setType(type);"},{"lineNumber":863,"author":{"gitId":"-"},"content":" email.setIsCopy(true);"},{"lineNumber":864,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), session.getName());"},{"lineNumber":865,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":866,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":867,"author":{"gitId":"-"},"content":" }"},{"lineNumber":868,"author":{"gitId":"-"},"content":""},{"lineNumber":869,"author":{"gitId":"-"},"content":" private boolean isYetToJoinCourse(Student student) {"},{"lineNumber":870,"author":{"gitId":"-"},"content":" return student.getAccount() \u003d\u003d null || student.getAccount().getGoogleId().isEmpty();"},{"lineNumber":871,"author":{"gitId":"-"},"content":" }"},{"lineNumber":872,"author":{"gitId":"-"},"content":""},{"lineNumber":873,"author":{"gitId":"-"},"content":" private boolean isYetToJoinCourse(Instructor instructor) {"},{"lineNumber":874,"author":{"gitId":"-"},"content":" return instructor.getAccount() \u003d\u003d null || instructor.getAccount().getGoogleId().isEmpty();"},{"lineNumber":875,"author":{"gitId":"-"},"content":" }"},{"lineNumber":876,"author":{"gitId":"-"},"content":""},{"lineNumber":877,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":878,"author":{"gitId":"-"},"content":" * Generates the new instructor account join email for the given {@code instructor}."},{"lineNumber":879,"author":{"gitId":"-"},"content":" */"},{"lineNumber":880,"author":{"gitId":"-"},"content":" public EmailWrapper generateNewInstructorAccountJoinEmail("},{"lineNumber":881,"author":{"gitId":"-"},"content":" String instructorEmail, String instructorName, String joinUrl) {"},{"lineNumber":882,"author":{"gitId":"-"},"content":""},{"lineNumber":883,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate(EmailTemplates.NEW_INSTRUCTOR_ACCOUNT_WELCOME,"},{"lineNumber":884,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(instructorName),"},{"lineNumber":885,"author":{"gitId":"-"},"content":" \"${joinUrl}\", joinUrl);"},{"lineNumber":886,"author":{"gitId":"-"},"content":""},{"lineNumber":887,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(instructorEmail);"},{"lineNumber":888,"author":{"gitId":"-"},"content":" email.setBcc(Config.SUPPORT_EMAIL);"},{"lineNumber":889,"author":{"gitId":"-"},"content":" email.setType(EmailType.NEW_INSTRUCTOR_ACCOUNT);"},{"lineNumber":890,"author":{"gitId":"-"},"content":" email.setSubjectFromType(SanitizationHelper.sanitizeForHtml(instructorName));"},{"lineNumber":891,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":892,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":893,"author":{"gitId":"-"},"content":" }"},{"lineNumber":894,"author":{"gitId":"-"},"content":""},{"lineNumber":895,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":896,"author":{"gitId":"-"},"content":" * Generates the course join email for the given {@code student} in {@code course}."},{"lineNumber":897,"author":{"gitId":"-"},"content":" */"},{"lineNumber":898,"author":{"gitId":"-"},"content":" public EmailWrapper generateStudentCourseJoinEmail(Course course, Student student) {"},{"lineNumber":899,"author":{"gitId":"-"},"content":""},{"lineNumber":900,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate("},{"lineNumber":901,"author":{"gitId":"-"},"content":" fillUpStudentJoinFragment(student),"},{"lineNumber":902,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(student.getName()),"},{"lineNumber":903,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":904,"author":{"gitId":"-"},"content":" \"${coOwnersEmails}\", generateCoOwnersEmailsLine(course.getId()),"},{"lineNumber":905,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL);"},{"lineNumber":906,"author":{"gitId":"-"},"content":""},{"lineNumber":907,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(student.getEmail());"},{"lineNumber":908,"author":{"gitId":"-"},"content":" email.setType(EmailType.STUDENT_COURSE_JOIN);"},{"lineNumber":909,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), course.getId());"},{"lineNumber":910,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":911,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":912,"author":{"gitId":"-"},"content":" }"},{"lineNumber":913,"author":{"gitId":"-"},"content":""},{"lineNumber":914,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":915,"author":{"gitId":"-"},"content":" * Generates the course re-join email for the given {@code student} in {@code course}."},{"lineNumber":916,"author":{"gitId":"-"},"content":" */"},{"lineNumber":917,"author":{"gitId":"-"},"content":" public EmailWrapper generateStudentCourseRejoinEmailAfterGoogleIdReset("},{"lineNumber":918,"author":{"gitId":"-"},"content":" Course course, Student student) {"},{"lineNumber":919,"author":{"gitId":"-"},"content":""},{"lineNumber":920,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate("},{"lineNumber":921,"author":{"gitId":"-"},"content":" fillUpStudentRejoinAfterGoogleIdResetFragment(student),"},{"lineNumber":922,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(student.getName()),"},{"lineNumber":923,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":924,"author":{"gitId":"-"},"content":" \"${coOwnersEmails}\", generateCoOwnersEmailsLine(course.getId()),"},{"lineNumber":925,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL);"},{"lineNumber":926,"author":{"gitId":"-"},"content":""},{"lineNumber":927,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(student.getEmail());"},{"lineNumber":928,"author":{"gitId":"-"},"content":" email.setType(EmailType.STUDENT_COURSE_REJOIN_AFTER_GOOGLE_ID_RESET);"},{"lineNumber":929,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), course.getId());"},{"lineNumber":930,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":931,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":932,"author":{"gitId":"-"},"content":" }"},{"lineNumber":933,"author":{"gitId":"-"},"content":""},{"lineNumber":934,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":935,"author":{"gitId":"-"},"content":" * Generates the course join email for the given {@code instructor} in {@code course}."},{"lineNumber":936,"author":{"gitId":"-"},"content":" * Also specifies contact information of {@code inviter}."},{"lineNumber":937,"author":{"gitId":"-"},"content":" */"},{"lineNumber":938,"author":{"gitId":"-"},"content":" public EmailWrapper generateInstructorCourseJoinEmail(Account inviter,"},{"lineNumber":939,"author":{"gitId":"-"},"content":" Instructor instructor, Course course) {"},{"lineNumber":940,"author":{"gitId":"-"},"content":""},{"lineNumber":941,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate("},{"lineNumber":942,"author":{"gitId":"-"},"content":" fillUpInstructorJoinFragment(instructor),"},{"lineNumber":943,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(instructor.getName()),"},{"lineNumber":944,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":945,"author":{"gitId":"-"},"content":" \"${inviterName}\", SanitizationHelper.sanitizeForHtml(inviter.getName()),"},{"lineNumber":946,"author":{"gitId":"-"},"content":" \"${inviterEmail}\", SanitizationHelper.sanitizeForHtml(inviter.getEmail()),"},{"lineNumber":947,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL);"},{"lineNumber":948,"author":{"gitId":"-"},"content":""},{"lineNumber":949,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(instructor.getEmail());"},{"lineNumber":950,"author":{"gitId":"-"},"content":" email.setType(EmailType.INSTRUCTOR_COURSE_JOIN);"},{"lineNumber":951,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), course.getId());"},{"lineNumber":952,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":953,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":954,"author":{"gitId":"-"},"content":" }"},{"lineNumber":955,"author":{"gitId":"-"},"content":""},{"lineNumber":956,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":957,"author":{"gitId":"-"},"content":" * Generates the course re-join email for the given {@code instructor} in {@code course}."},{"lineNumber":958,"author":{"gitId":"-"},"content":" */"},{"lineNumber":959,"author":{"gitId":"-"},"content":" public EmailWrapper generateInstructorCourseRejoinEmailAfterGoogleIdReset("},{"lineNumber":960,"author":{"gitId":"-"},"content":" Instructor instructor, Course course) {"},{"lineNumber":961,"author":{"gitId":"-"},"content":""},{"lineNumber":962,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate("},{"lineNumber":963,"author":{"gitId":"-"},"content":" fillUpInstructorRejoinAfterGoogleIdResetFragment(instructor),"},{"lineNumber":964,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(instructor.getName()),"},{"lineNumber":965,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":966,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL);"},{"lineNumber":967,"author":{"gitId":"-"},"content":""},{"lineNumber":968,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(instructor.getEmail());"},{"lineNumber":969,"author":{"gitId":"-"},"content":" email.setType(EmailType.INSTRUCTOR_COURSE_REJOIN_AFTER_GOOGLE_ID_RESET);"},{"lineNumber":970,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), course.getId());"},{"lineNumber":971,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":972,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":973,"author":{"gitId":"-"},"content":" }"},{"lineNumber":974,"author":{"gitId":"-"},"content":""},{"lineNumber":975,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":976,"author":{"gitId":"-"},"content":" * Generates the email to alert the admin of the new {@code accountRequest}."},{"lineNumber":977,"author":{"gitId":"-"},"content":" */"},{"lineNumber":978,"author":{"gitId":"-"},"content":" public EmailWrapper generateNewAccountRequestAdminAlertEmail(AccountRequest accountRequest) {"},{"lineNumber":979,"author":{"gitId":"-"},"content":" String name \u003d accountRequest.getName();"},{"lineNumber":980,"author":{"gitId":"-"},"content":" String institute \u003d accountRequest.getInstitute();"},{"lineNumber":981,"author":{"gitId":"-"},"content":" String emailAddress \u003d accountRequest.getEmail();"},{"lineNumber":982,"author":{"gitId":"-"},"content":" String comments \u003d accountRequest.getComments();"},{"lineNumber":983,"author":{"gitId":"-"},"content":" if (comments \u003d\u003d null) {"},{"lineNumber":984,"author":{"gitId":"-"},"content":" comments \u003d \"\";"},{"lineNumber":985,"author":{"gitId":"-"},"content":" }"},{"lineNumber":986,"author":{"gitId":"-"},"content":" String adminAccountRequestsPageUrl \u003d Config.getFrontEndAppUrl(Const.WebPageURIs.ADMIN_HOME_PAGE).toAbsoluteString();"},{"lineNumber":987,"author":{"gitId":"-"},"content":" String[] templateKeyValuePairs \u003d new String[] {"},{"lineNumber":988,"author":{"gitId":"-"},"content":" \"${name}\", name,"},{"lineNumber":989,"author":{"gitId":"-"},"content":" \"${institute}\", institute,"},{"lineNumber":990,"author":{"gitId":"-"},"content":" \"${emailAddress}\", emailAddress,"},{"lineNumber":991,"author":{"gitId":"-"},"content":" \"${comments}\", comments,"},{"lineNumber":992,"author":{"gitId":"-"},"content":" \"${adminAccountRequestsPageUrl}\", adminAccountRequestsPageUrl,"},{"lineNumber":993,"author":{"gitId":"-"},"content":" };"},{"lineNumber":994,"author":{"gitId":"-"},"content":" String content \u003d Templates.populateTemplate(EmailTemplates.ADMIN_NEW_ACCOUNT_REQUEST_ALERT, templateKeyValuePairs);"},{"lineNumber":995,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(Config.SUPPORT_EMAIL);"},{"lineNumber":996,"author":{"gitId":"-"},"content":" email.setType(EmailType.NEW_ACCOUNT_REQUEST_ADMIN_ALERT);"},{"lineNumber":997,"author":{"gitId":"-"},"content":" email.setSubjectFromType();"},{"lineNumber":998,"author":{"gitId":"-"},"content":" email.setContent(content);"},{"lineNumber":999,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":1000,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1001,"author":{"gitId":"-"},"content":""},{"lineNumber":1002,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1003,"author":{"gitId":"xenosf"},"content":" * Generates the acknowledgement email to be sent to the person who submitted {@code accountRequest}."},{"lineNumber":1004,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1005,"author":{"gitId":"xenosf"},"content":" public EmailWrapper generateNewAccountRequestAcknowledgementEmail(AccountRequest accountRequest) {"},{"lineNumber":1006,"author":{"gitId":"xenosf"},"content":" String name \u003d SanitizationHelper.sanitizeForHtml(accountRequest.getName());"},{"lineNumber":1007,"author":{"gitId":"xenosf"},"content":" String institute \u003d SanitizationHelper.sanitizeForHtml(accountRequest.getInstitute());"},{"lineNumber":1008,"author":{"gitId":"xenosf"},"content":" String emailAddress \u003d SanitizationHelper.sanitizeForHtml(accountRequest.getEmail());"},{"lineNumber":1009,"author":{"gitId":"xenosf"},"content":" String comments \u003d SanitizationHelper.sanitizeForHtml(accountRequest.getComments());"},{"lineNumber":1010,"author":{"gitId":"xenosf"},"content":" if (comments \u003d\u003d null) {"},{"lineNumber":1011,"author":{"gitId":"xenosf"},"content":" comments \u003d \"\";"},{"lineNumber":1012,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1013,"author":{"gitId":"xenosf"},"content":" String[] templateKeyValuePairs \u003d new String[] {"},{"lineNumber":1014,"author":{"gitId":"xenosf"},"content":" \"${name}\", name,"},{"lineNumber":1015,"author":{"gitId":"xenosf"},"content":" \"${institute}\", institute,"},{"lineNumber":1016,"author":{"gitId":"xenosf"},"content":" \"${emailAddress}\", emailAddress,"},{"lineNumber":1017,"author":{"gitId":"xenosf"},"content":" \"${comments}\", comments,"},{"lineNumber":1018,"author":{"gitId":"xenosf"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL,"},{"lineNumber":1019,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":1020,"author":{"gitId":"xenosf"},"content":" String content \u003d Templates.populateTemplate("},{"lineNumber":1021,"author":{"gitId":"xenosf"},"content":" EmailTemplates.INSTRUCTOR_NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT, templateKeyValuePairs);"},{"lineNumber":1022,"author":{"gitId":"xenosf"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(emailAddress);"},{"lineNumber":1023,"author":{"gitId":"xenosf"},"content":" email.setType(EmailType.NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT);"},{"lineNumber":1024,"author":{"gitId":"xenosf"},"content":" email.setBcc(Config.SUPPORT_EMAIL);"},{"lineNumber":1025,"author":{"gitId":"xenosf"},"content":" email.setSubjectFromType();"},{"lineNumber":1026,"author":{"gitId":"xenosf"},"content":" email.setContent(content);"},{"lineNumber":1027,"author":{"gitId":"xenosf"},"content":" return email;"},{"lineNumber":1028,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1029,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1030,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1031,"author":{"gitId":"-"},"content":" * Generates the email to be sent to instructor when their account request has been rejected by admin."},{"lineNumber":1032,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1033,"author":{"gitId":"-"},"content":" public EmailWrapper generateAccountRequestRejectionEmail(AccountRequest accountRequest, String title, String content) {"},{"lineNumber":1034,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(accountRequest.getEmail());"},{"lineNumber":1035,"author":{"gitId":"-"},"content":" email.setType(EmailType.ACCOUNT_REQUEST_REJECTION);"},{"lineNumber":1036,"author":{"gitId":"-"},"content":" email.setBcc(Config.SUPPORT_EMAIL);"},{"lineNumber":1037,"author":{"gitId":"-"},"content":" email.setSubjectFromType(SanitizationHelper.sanitizeTitle(title));"},{"lineNumber":1038,"author":{"gitId":"-"},"content":" email.setContent(SanitizationHelper.sanitizeForRichText(content));"},{"lineNumber":1039,"author":{"gitId":"-"},"content":""},{"lineNumber":1040,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":1041,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1042,"author":{"gitId":"-"},"content":""},{"lineNumber":1043,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1044,"author":{"gitId":"-"},"content":" * Generates the course registered email for the user with the given details in {@code course}."},{"lineNumber":1045,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1046,"author":{"gitId":"-"},"content":" public EmailWrapper generateUserCourseRegisteredEmail("},{"lineNumber":1047,"author":{"gitId":"-"},"content":" String name, String emailAddress, String googleId, boolean isInstructor, Course course) {"},{"lineNumber":1048,"author":{"gitId":"-"},"content":" String emailBody \u003d Templates.populateTemplate(EmailTemplates.USER_COURSE_REGISTER,"},{"lineNumber":1049,"author":{"gitId":"-"},"content":" \"${userName}\", SanitizationHelper.sanitizeForHtml(name),"},{"lineNumber":1050,"author":{"gitId":"-"},"content":" \"${userType}\", isInstructor ? \"an instructor\" : \"a student\","},{"lineNumber":1051,"author":{"gitId":"-"},"content":" \"${courseId}\", SanitizationHelper.sanitizeForHtml(course.getId()),"},{"lineNumber":1052,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()),"},{"lineNumber":1053,"author":{"gitId":"-"},"content":" \"${googleId}\", SanitizationHelper.sanitizeForHtml(googleId),"},{"lineNumber":1054,"author":{"gitId":"-"},"content":" \"${appUrl}\", isInstructor"},{"lineNumber":1055,"author":{"gitId":"-"},"content":" ? Config.getFrontEndAppUrl(Const.WebPageURIs.INSTRUCTOR_HOME_PAGE).toAbsoluteString()"},{"lineNumber":1056,"author":{"gitId":"-"},"content":" : Config.getFrontEndAppUrl(Const.WebPageURIs.STUDENT_HOME_PAGE).toAbsoluteString(),"},{"lineNumber":1057,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL);"},{"lineNumber":1058,"author":{"gitId":"-"},"content":""},{"lineNumber":1059,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(emailAddress);"},{"lineNumber":1060,"author":{"gitId":"-"},"content":" email.setType(EmailType.USER_COURSE_REGISTER);"},{"lineNumber":1061,"author":{"gitId":"-"},"content":" email.setSubjectFromType(course.getName(), course.getId());"},{"lineNumber":1062,"author":{"gitId":"-"},"content":" email.setContent(emailBody);"},{"lineNumber":1063,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":1064,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1065,"author":{"gitId":"-"},"content":""},{"lineNumber":1066,"author":{"gitId":"-"},"content":" private String fillUpStudentJoinFragment(Student student) {"},{"lineNumber":1067,"author":{"gitId":"-"},"content":" String joinUrl \u003d Config.getFrontEndAppUrl(student.getRegistrationUrl()).toAbsoluteString();"},{"lineNumber":1068,"author":{"gitId":"-"},"content":""},{"lineNumber":1069,"author":{"gitId":"-"},"content":" return Templates.populateTemplate(EmailTemplates.USER_COURSE_JOIN,"},{"lineNumber":1070,"author":{"gitId":"-"},"content":" \"${joinFragment}\", EmailTemplates.FRAGMENT_STUDENT_COURSE_JOIN,"},{"lineNumber":1071,"author":{"gitId":"-"},"content":" \"${joinUrl}\", joinUrl);"},{"lineNumber":1072,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1073,"author":{"gitId":"-"},"content":""},{"lineNumber":1074,"author":{"gitId":"-"},"content":" private String fillUpStudentRejoinAfterGoogleIdResetFragment(Student student) {"},{"lineNumber":1075,"author":{"gitId":"-"},"content":" String joinUrl \u003d Config.getFrontEndAppUrl(student.getRegistrationUrl()).toAbsoluteString();"},{"lineNumber":1076,"author":{"gitId":"-"},"content":""},{"lineNumber":1077,"author":{"gitId":"-"},"content":" return Templates.populateTemplate(EmailTemplates.USER_COURSE_JOIN,"},{"lineNumber":1078,"author":{"gitId":"-"},"content":" \"${joinFragment}\", EmailTemplates.FRAGMENT_STUDENT_COURSE_REJOIN_AFTER_GOOGLE_ID_RESET,"},{"lineNumber":1079,"author":{"gitId":"-"},"content":" \"${joinUrl}\", joinUrl,"},{"lineNumber":1080,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL);"},{"lineNumber":1081,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1082,"author":{"gitId":"-"},"content":""},{"lineNumber":1083,"author":{"gitId":"-"},"content":" private String getInstructorCourseJoinUrl(Instructor instructor) {"},{"lineNumber":1084,"author":{"gitId":"-"},"content":" return Config.getFrontEndAppUrl(instructor.getRegistrationUrl()).toAbsoluteString();"},{"lineNumber":1085,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1086,"author":{"gitId":"-"},"content":""},{"lineNumber":1087,"author":{"gitId":"-"},"content":" private String fillUpInstructorJoinFragment(Instructor instructor) {"},{"lineNumber":1088,"author":{"gitId":"-"},"content":" return Templates.populateTemplate(EmailTemplates.USER_COURSE_JOIN,"},{"lineNumber":1089,"author":{"gitId":"-"},"content":" \"${joinFragment}\", EmailTemplates.FRAGMENT_INSTRUCTOR_COURSE_JOIN,"},{"lineNumber":1090,"author":{"gitId":"-"},"content":" \"${joinUrl}\", getInstructorCourseJoinUrl(instructor));"},{"lineNumber":1091,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1092,"author":{"gitId":"-"},"content":""},{"lineNumber":1093,"author":{"gitId":"-"},"content":" private String fillUpInstructorRejoinAfterGoogleIdResetFragment(Instructor instructor) {"},{"lineNumber":1094,"author":{"gitId":"-"},"content":" String joinUrl \u003d Config.getFrontEndAppUrl(instructor.getRegistrationUrl()).toAbsoluteString();"},{"lineNumber":1095,"author":{"gitId":"-"},"content":""},{"lineNumber":1096,"author":{"gitId":"-"},"content":" return Templates.populateTemplate(EmailTemplates.USER_COURSE_JOIN,"},{"lineNumber":1097,"author":{"gitId":"-"},"content":" \"${joinFragment}\", EmailTemplates.FRAGMENT_INSTRUCTOR_COURSE_REJOIN_AFTER_GOOGLE_ID_RESET,"},{"lineNumber":1098,"author":{"gitId":"-"},"content":" \"${joinUrl}\", joinUrl,"},{"lineNumber":1099,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL);"},{"lineNumber":1100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1101,"author":{"gitId":"-"},"content":""},{"lineNumber":1102,"author":{"gitId":"-"},"content":" private String fillUpInstructorPreamble(Course course) {"},{"lineNumber":1103,"author":{"gitId":"-"},"content":" return Templates.populateTemplate(EmailTemplates.FRAGMENT_INSTRUCTOR_COPY_PREAMBLE,"},{"lineNumber":1104,"author":{"gitId":"-"},"content":" \"${courseId}\", SanitizationHelper.sanitizeForHtml(course.getId()),"},{"lineNumber":1105,"author":{"gitId":"-"},"content":" \"${courseName}\", SanitizationHelper.sanitizeForHtml(course.getName()));"},{"lineNumber":1106,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1107,"author":{"gitId":"-"},"content":""},{"lineNumber":1108,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1109,"author":{"gitId":"-"},"content":" * Generates the logs compilation email for the given {@code logs}."},{"lineNumber":1110,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1111,"author":{"gitId":"-"},"content":" public EmailWrapper generateCompiledLogsEmail(List\u003cErrorLogEntry\u003e logs) {"},{"lineNumber":1112,"author":{"gitId":"-"},"content":" StringBuilder emailBody \u003d new StringBuilder();"},{"lineNumber":1113,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c logs.size(); i++) {"},{"lineNumber":1114,"author":{"gitId":"-"},"content":" emailBody.append(generateSevereErrorLogLine(i, logs.get(i).getMessage(),"},{"lineNumber":1115,"author":{"gitId":"-"},"content":" logs.get(i).getSeverity(), logs.get(i).getTraceId()));"},{"lineNumber":1116,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1117,"author":{"gitId":"-"},"content":""},{"lineNumber":1118,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d getEmptyEmailAddressedToEmail(Config.SUPPORT_EMAIL);"},{"lineNumber":1119,"author":{"gitId":"-"},"content":" email.setType(EmailType.SEVERE_LOGS_COMPILATION);"},{"lineNumber":1120,"author":{"gitId":"-"},"content":" email.setSubjectFromType(Config.APP_VERSION);"},{"lineNumber":1121,"author":{"gitId":"-"},"content":" email.setContent(emailBody.toString());"},{"lineNumber":1122,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":1123,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1124,"author":{"gitId":"-"},"content":""},{"lineNumber":1125,"author":{"gitId":"-"},"content":" private String generateSevereErrorLogLine(int index, String logMessage, String logLevel, String traceId) {"},{"lineNumber":1126,"author":{"gitId":"-"},"content":" return Templates.populateTemplate("},{"lineNumber":1127,"author":{"gitId":"-"},"content":" EmailTemplates.SEVERE_ERROR_LOG_LINE,"},{"lineNumber":1128,"author":{"gitId":"-"},"content":" \"${index}\", String.valueOf(index),"},{"lineNumber":1129,"author":{"gitId":"-"},"content":" \"${errorType}\", logLevel,"},{"lineNumber":1130,"author":{"gitId":"-"},"content":" \"${errorMessage}\", logMessage.replaceAll(\"\\n\", \"\\n\u003cbr\u003e\"),"},{"lineNumber":1131,"author":{"gitId":"-"},"content":" \"${traceId}\", traceId);"},{"lineNumber":1132,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1133,"author":{"gitId":"-"},"content":""},{"lineNumber":1134,"author":{"gitId":"-"},"content":" private EmailWrapper getEmptyEmailAddressedToEmail(String recipient) {"},{"lineNumber":1135,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d new EmailWrapper();"},{"lineNumber":1136,"author":{"gitId":"-"},"content":" email.setRecipient(recipient);"},{"lineNumber":1137,"author":{"gitId":"-"},"content":" email.setSenderEmail(Config.EMAIL_SENDEREMAIL);"},{"lineNumber":1138,"author":{"gitId":"-"},"content":" email.setSenderName(Config.EMAIL_SENDERNAME);"},{"lineNumber":1139,"author":{"gitId":"-"},"content":" email.setReplyTo(Config.EMAIL_REPLYTO);"},{"lineNumber":1140,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":1141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1142,"author":{"gitId":"-"},"content":""},{"lineNumber":1143,"author":{"gitId":"-"},"content":" private String generateCoOwnersEmailsLine(String courseId) {"},{"lineNumber":1144,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e coOwners \u003d usersLogic.getCoOwnersForCourse(courseId);"},{"lineNumber":1145,"author":{"gitId":"-"},"content":" if (coOwners.isEmpty()) {"},{"lineNumber":1146,"author":{"gitId":"-"},"content":" return \"(No contactable instructors found)\";"},{"lineNumber":1147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1148,"author":{"gitId":"-"},"content":" StringBuilder coOwnersEmailsLine \u003d new StringBuilder();"},{"lineNumber":1149,"author":{"gitId":"-"},"content":" for (Instructor coOwner : coOwners) {"},{"lineNumber":1150,"author":{"gitId":"-"},"content":" coOwnersEmailsLine"},{"lineNumber":1151,"author":{"gitId":"-"},"content":" .append(SanitizationHelper.sanitizeForHtml(coOwner.getName()))"},{"lineNumber":1152,"author":{"gitId":"-"},"content":" .append(\" (\")"},{"lineNumber":1153,"author":{"gitId":"-"},"content":" .append(coOwner.getEmail())"},{"lineNumber":1154,"author":{"gitId":"-"},"content":" .append(\"), \");"},{"lineNumber":1155,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1156,"author":{"gitId":"-"},"content":" return coOwnersEmailsLine.substring(0, coOwnersEmailsLine.length() - 2);"},{"lineNumber":1157,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1158,"author":{"gitId":"-"},"content":""},{"lineNumber":1159,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1160,"author":{"gitId":"-"},"content":" * Generates additional contact information for User Email Templates."},{"lineNumber":1161,"author":{"gitId":"-"},"content":" * @return The contact information after replacing the placeholders."},{"lineNumber":1162,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1163,"author":{"gitId":"-"},"content":" private String getAdditionalContactInformationFragment(Course course, boolean isInstructor) {"},{"lineNumber":1164,"author":{"gitId":"-"},"content":" String particulars \u003d isInstructor ? \"instructor data (e.g. wrong permission, misspelled name)\""},{"lineNumber":1165,"author":{"gitId":"-"},"content":" : \"team/student data (e.g. wrong team, misspelled name)\";"},{"lineNumber":1166,"author":{"gitId":"-"},"content":" return Templates.populateTemplate(EmailTemplates.FRAGMENT_SESSION_ADDITIONAL_CONTACT_INFORMATION,"},{"lineNumber":1167,"author":{"gitId":"-"},"content":" \"${particulars}\", particulars,"},{"lineNumber":1168,"author":{"gitId":"-"},"content":" \"${coOwnersEmails}\", generateCoOwnersEmailsLine(course.getId()),"},{"lineNumber":1169,"author":{"gitId":"-"},"content":" \"${supportEmail}\", Config.SUPPORT_EMAIL);"},{"lineNumber":1170,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1171,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":28,"-":1143}},{"path":"src/main/java/teammates/sqllogic/core/AccountRequestsLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.AccountRequestsDb;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.AccountRequestSearchManager;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * Handles operations related to account requests."},{"lineNumber":17,"author":{"gitId":"-"},"content":" *"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * @see AccountRequest"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * @see AccountRequestsDb"},{"lineNumber":20,"author":{"gitId":"-"},"content":" */"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public final class AccountRequestsLogic {"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" private static final AccountRequestsLogic instance \u003d new AccountRequestsLogic();"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" private AccountRequestsDb accountRequestDb;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" private AccountRequestsLogic() {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" // prevent notification"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" public static AccountRequestsLogic inst() {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":36,"author":{"gitId":"-"},"content":" * Initialise dependencies for {@code AccountRequestLogic} object."},{"lineNumber":37,"author":{"gitId":"-"},"content":" */"},{"lineNumber":38,"author":{"gitId":"-"},"content":" public void initLogicDependencies(AccountRequestsDb accountRequestDb) {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.accountRequestDb \u003d accountRequestDb;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" private AccountRequestSearchManager getSearchManager() {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" return accountRequestDb.getSearchManager();"},{"lineNumber":44,"author":{"gitId":"-"},"content":" }"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":47,"author":{"gitId":"-"},"content":" * Creates or updates search document for the given account request."},{"lineNumber":48,"author":{"gitId":"-"},"content":" */"},{"lineNumber":49,"author":{"gitId":"-"},"content":" public void putDocument(AccountRequest accountRequest) throws SearchServiceException {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" getSearchManager().putDocument(accountRequest);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" }"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":54,"author":{"gitId":"-"},"content":" * Creates an account request."},{"lineNumber":55,"author":{"gitId":"-"},"content":" */"},{"lineNumber":56,"author":{"gitId":"-"},"content":" public AccountRequest createAccountRequest(AccountRequest accountRequest) throws InvalidParametersException {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" return accountRequestDb.createAccountRequest(accountRequest);"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":61,"author":{"gitId":"-"},"content":" * Creates an account request."},{"lineNumber":62,"author":{"gitId":"-"},"content":" */"},{"lineNumber":63,"author":{"gitId":"-"},"content":" public AccountRequest createAccountRequest(String name, String email, String institute, AccountRequestStatus status,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" String comments) throws InvalidParametersException {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" AccountRequest toCreate \u003d new AccountRequest(email, name, institute, status, comments);"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" return accountRequestDb.createAccountRequest(toCreate);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" }"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":71,"author":{"gitId":"-"},"content":" * Gets the account request associated with the {@code id}."},{"lineNumber":72,"author":{"gitId":"-"},"content":" */"},{"lineNumber":73,"author":{"gitId":"-"},"content":" public AccountRequest getAccountRequest(UUID id) {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" return accountRequestDb.getAccountRequest(id);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" }"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" * Gets the account request associated with the {@code id}."},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" public AccountRequest getAccountRequestWithTransaction(UUID id) {"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" AccountRequest request \u003d accountRequestDb.getAccountRequest(id);"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" return request;"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":88,"author":{"gitId":"-"},"content":" * Updates an account request."},{"lineNumber":89,"author":{"gitId":"-"},"content":" */"},{"lineNumber":90,"author":{"gitId":"-"},"content":" public AccountRequest updateAccountRequest(AccountRequest accountRequest)"},{"lineNumber":91,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" return accountRequestDb.updateAccountRequest(accountRequest);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" }"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" * Updates an account request."},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":" @SuppressWarnings(\"PMD\")"},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" public AccountRequest updateAccountRequestWithTransaction(AccountRequest accountRequest)"},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":" AccountRequest updatedRequest;"},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" updatedRequest \u003d accountRequestDb.updateAccountRequest(accountRequest);"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" } catch (InvalidParametersException ipe) {"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.rollbackTransaction();"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" throw new InvalidParametersException(ipe.getMessage());"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" return updatedRequest;"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" * Gets account request associated with the {@code regkey}."},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" public AccountRequest getAccountRequestByRegistrationKey(String regkey) {"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" return accountRequestDb.getAccountRequestByRegistrationKey(regkey);"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":124,"author":{"gitId":"-"},"content":" * Gets all pending account requests."},{"lineNumber":125,"author":{"gitId":"-"},"content":" */"},{"lineNumber":126,"author":{"gitId":"-"},"content":" public List\u003cAccountRequest\u003e getPendingAccountRequests() {"},{"lineNumber":127,"author":{"gitId":"-"},"content":" return accountRequestDb.getPendingAccountRequests();"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":" * Gets all account requests."},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccountRequest\u003e getAllAccountRequests() {"},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" return accountRequestDb.getAllAccountRequests();"},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":137,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":" * Get a list of account requests associated with email provided."},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":140,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccountRequest\u003e getApprovedAccountRequestsForEmailWithTransaction(String email) {"},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":" List\u003cAccountRequest\u003e accountRequests \u003d accountRequestDb.getApprovedAccountRequestsForEmail(email);"},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":" return accountRequests;"},{"lineNumber":145,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":" * Creates/resets the account request with the given id such that it is not registered."},{"lineNumber":149,"author":{"gitId":"-"},"content":" */"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":" public AccountRequest resetAccountRequest(UUID id)"},{"lineNumber":151,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, InvalidParametersException {"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":" AccountRequest accountRequest \u003d accountRequestDb.getAccountRequest(id);"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"-"},"content":" if (accountRequest \u003d\u003d null) {"},{"lineNumber":155,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Failed to reset since AccountRequest with \""},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" + \"the given id cannot be found.\");"},{"lineNumber":157,"author":{"gitId":"-"},"content":" }"},{"lineNumber":158,"author":{"gitId":"-"},"content":" accountRequest.setRegisteredAt(null);"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" return accountRequestDb.updateAccountRequest(accountRequest);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":164,"author":{"gitId":"dishenggg"},"content":" * Deletes account request associated with the {@code id}."},{"lineNumber":165,"author":{"gitId":"-"},"content":" *"},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":" * \u003cp\u003eFails silently if no account requests with the given id to delete can be found.\u003c/p\u003e"},{"lineNumber":167,"author":{"gitId":"-"},"content":" *"},{"lineNumber":168,"author":{"gitId":"-"},"content":" */"},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":" public void deleteAccountRequest(UUID id) {"},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" AccountRequest toDelete \u003d accountRequestDb.getAccountRequest(id);"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" accountRequestDb.deleteAccountRequest(toDelete);"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":" * Searches for account requests in the whole system."},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":" * @return A list of {@link AccountRequest} or {@code null} if no match found."},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccountRequest\u003e searchAccountRequestsInWholeSystem(String queryString)"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":" throws SearchServiceException {"},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":" return accountRequestDb.searchAccountRequestsInWholeSystem(queryString);"},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":184,"author":{"gitId":"-"},"content":""},{"lineNumber":185,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":186,"author":{"gitId":"-"},"content":" * Creates an or gets an account request."},{"lineNumber":187,"author":{"gitId":"-"},"content":" */"},{"lineNumber":188,"author":{"gitId":"-"},"content":" public AccountRequest createOrGetAccountRequestWithTransaction(String name, String email, String institute,"},{"lineNumber":189,"author":{"gitId":"-"},"content":" AccountRequestStatus status, String comments)"},{"lineNumber":190,"author":{"gitId":"-"},"content":" throws InvalidParametersException {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" AccountRequest toCreate \u003d new AccountRequest(email, name, institute, status, comments);"},{"lineNumber":192,"author":{"gitId":"-"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":193,"author":{"gitId":"-"},"content":" AccountRequest accountRequest;"},{"lineNumber":194,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":195,"author":{"gitId":"-"},"content":" accountRequest \u003d accountRequestDb.createAccountRequest(toCreate);"},{"lineNumber":196,"author":{"gitId":"-"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":197,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException ipe) {"},{"lineNumber":198,"author":{"gitId":"-"},"content":" HibernateUtil.rollbackTransaction();"},{"lineNumber":199,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(ipe);"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }"},{"lineNumber":201,"author":{"gitId":"-"},"content":" return accountRequest;"},{"lineNumber":202,"author":{"gitId":"-"},"content":" }"},{"lineNumber":203,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":60,"dishenggg":15,"-":128}},{"path":"src/main/java/teammates/sqllogic/core/AccountsLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.AccountsDb;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":14,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":15,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.ReadNotification;"},{"lineNumber":18,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.User;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * Handles operations related to accounts."},{"lineNumber":23,"author":{"gitId":"-"},"content":" *"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * @see Account"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * @see AccountsDb"},{"lineNumber":26,"author":{"gitId":"-"},"content":" */"},{"lineNumber":27,"author":{"gitId":"-"},"content":"public final class AccountsLogic {"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" private static final AccountsLogic instance \u003d new AccountsLogic();"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" private AccountsDb accountsDb;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private NotificationsLogic notificationsLogic;"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" private UsersLogic usersLogic;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"yuanxi1"},"content":" private CoursesLogic coursesLogic;"},{"lineNumber":38,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" private AccountsLogic() {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"yuanxi1"},"content":" void initLogicDependencies(AccountsDb accountsDb, NotificationsLogic notificationsLogic,"},{"lineNumber":44,"author":{"gitId":"yuanxi1"},"content":" UsersLogic usersLogic, CoursesLogic coursesLogic) {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" this.accountsDb \u003d accountsDb;"},{"lineNumber":46,"author":{"gitId":"-"},"content":" this.notificationsLogic \u003d notificationsLogic;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" this.usersLogic \u003d usersLogic;"},{"lineNumber":48,"author":{"gitId":"yuanxi1"},"content":" this.coursesLogic \u003d coursesLogic;"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" public static AccountsLogic inst() {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":56,"author":{"gitId":"-"},"content":" * Gets an account."},{"lineNumber":57,"author":{"gitId":"-"},"content":" */"},{"lineNumber":58,"author":{"gitId":"-"},"content":" public Account getAccount(UUID id) {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" assert id !\u003d null;"},{"lineNumber":60,"author":{"gitId":"-"},"content":" return accountsDb.getAccount(id);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":64,"author":{"gitId":"-"},"content":" * Gets an account by googleId."},{"lineNumber":65,"author":{"gitId":"-"},"content":" */"},{"lineNumber":66,"author":{"gitId":"-"},"content":" public Account getAccountForGoogleId(String googleId) {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" return accountsDb.getAccountByGoogleId(googleId);"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":73,"author":{"gitId":"-"},"content":" * Gets accounts associated with email."},{"lineNumber":74,"author":{"gitId":"-"},"content":" */"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public List\u003cAccount\u003e getAccountsForEmail(String email) {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" return accountsDb.getAccountsByEmail(email);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" }"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" * Gets accounts associated with email."},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccount\u003e getAccountsForEmailWithTransaction(String email) {"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" assert email !\u003d null;"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" List\u003cAccount\u003e accounts \u003d accountsDb.getAccountsByEmail(email);"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" return accounts;"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":95,"author":{"gitId":"-"},"content":" * Creates an account."},{"lineNumber":96,"author":{"gitId":"-"},"content":" *"},{"lineNumber":97,"author":{"gitId":"-"},"content":" * @return the created account"},{"lineNumber":98,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the account is not valid"},{"lineNumber":99,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the account already exists in the"},{"lineNumber":100,"author":{"gitId":"-"},"content":" * database."},{"lineNumber":101,"author":{"gitId":"-"},"content":" */"},{"lineNumber":102,"author":{"gitId":"-"},"content":" public Account createAccount(Account account)"},{"lineNumber":103,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" assert account !\u003d null;"},{"lineNumber":105,"author":{"gitId":"-"},"content":" return accountsDb.createAccount(account);"},{"lineNumber":106,"author":{"gitId":"-"},"content":" }"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" * Creates an account."},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" * @return the created account"},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" * @throws InvalidParametersException if the account is not valid"},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" * @throws EntityAlreadyExistsException if the account already exists in the"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" * database."},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" public Account createAccountWithTransaction(Account account)"},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":" assert account !\u003d null;"},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":" Account createdAccount \u003d accountsDb.createAccount(account);"},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" HibernateUtil.commitTransaction();"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" return createdAccount;"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":128,"author":{"gitId":"-"},"content":" * Deletes account associated with the {@code googleId}."},{"lineNumber":129,"author":{"gitId":"-"},"content":" *"},{"lineNumber":130,"author":{"gitId":"-"},"content":" * \u003cp\u003eFails silently if the account doesn\u0027t exist.\u003c/p\u003e"},{"lineNumber":131,"author":{"gitId":"-"},"content":" */"},{"lineNumber":132,"author":{"gitId":"-"},"content":" public void deleteAccount(String googleId) {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" Account account \u003d getAccountForGoogleId(googleId);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" accountsDb.deleteAccount(account);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":140,"author":{"gitId":"-"},"content":" * Deletes account and all users associated with the {@code googleId}."},{"lineNumber":141,"author":{"gitId":"-"},"content":" *"},{"lineNumber":142,"author":{"gitId":"-"},"content":" * \u003cp\u003eFails silently if the account doesn\u0027t exist.\u003c/p\u003e"},{"lineNumber":143,"author":{"gitId":"-"},"content":" */"},{"lineNumber":144,"author":{"gitId":"-"},"content":" public void deleteAccountCascade(String googleId) {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" List\u003cUser\u003e usersToDelete \u003d usersLogic.getAllUsersByGoogleId(googleId);"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" for (User user : usersToDelete) {"},{"lineNumber":150,"author":{"gitId":"-"},"content":" usersLogic.deleteUser(user);"},{"lineNumber":151,"author":{"gitId":"-"},"content":" }"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":" deleteAccount(googleId);"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":157,"author":{"gitId":"-"},"content":" * Updates the readNotifications of an account."},{"lineNumber":158,"author":{"gitId":"-"},"content":" *"},{"lineNumber":159,"author":{"gitId":"-"},"content":" * @param googleId google ID of the user who read the notification."},{"lineNumber":160,"author":{"gitId":"-"},"content":" * @param notificationId ID of notification to be marked as read."},{"lineNumber":161,"author":{"gitId":"-"},"content":" * @param endTime the expiry time of the notification, i.e. notification"},{"lineNumber":162,"author":{"gitId":"-"},"content":" * will not be shown after this time."},{"lineNumber":163,"author":{"gitId":"-"},"content":" * @return the account with updated read notifications."},{"lineNumber":164,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the notification has expired."},{"lineNumber":165,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if account or notification does not"},{"lineNumber":166,"author":{"gitId":"-"},"content":" * exist."},{"lineNumber":167,"author":{"gitId":"-"},"content":" */"},{"lineNumber":168,"author":{"gitId":"-"},"content":" public List\u003cUUID\u003e updateReadNotifications(String googleId, UUID notificationId, Instant endTime)"},{"lineNumber":169,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":170,"author":{"gitId":"-"},"content":" Account account \u003d accountsDb.getAccountByGoogleId(googleId);"},{"lineNumber":171,"author":{"gitId":"-"},"content":" if (account \u003d\u003d null) {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Trying to update the read notifications of a non-existent account.\");"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" Notification notification \u003d notificationsLogic.getNotification(notificationId);"},{"lineNumber":176,"author":{"gitId":"-"},"content":" if (notification \u003d\u003d null) {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Trying to mark as read a notification that does not exist.\");"},{"lineNumber":178,"author":{"gitId":"-"},"content":" }"},{"lineNumber":179,"author":{"gitId":"-"},"content":" if (endTime.isBefore(Instant.now())) {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(\"Trying to mark an expired notification as read.\");"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" ReadNotification readNotification \u003d new ReadNotification(account, notification);"},{"lineNumber":184,"author":{"gitId":"-"},"content":" account.addReadNotification(readNotification);"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" return account.getReadNotifications().stream()"},{"lineNumber":187,"author":{"gitId":"-"},"content":" .map(n -\u003e n.getNotification().getId())"},{"lineNumber":188,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":192,"author":{"gitId":"-"},"content":" * Gets ids of read notifications in an account."},{"lineNumber":193,"author":{"gitId":"-"},"content":" */"},{"lineNumber":194,"author":{"gitId":"-"},"content":" public List\u003cUUID\u003e getReadNotificationsId(String googleId) {"},{"lineNumber":195,"author":{"gitId":"-"},"content":" return accountsDb.getAccountByGoogleId(googleId).getReadNotifications().stream()"},{"lineNumber":196,"author":{"gitId":"-"},"content":" .map(n -\u003e n.getNotification().getId())"},{"lineNumber":197,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":198,"author":{"gitId":"-"},"content":" }"},{"lineNumber":199,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":200,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":201,"author":{"gitId":"yuanxi1"},"content":" * Joins the user as a student."},{"lineNumber":202,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":203,"author":{"gitId":"yuanxi1"},"content":" public Student joinCourseForStudent(String registrationKey, String googleId)"},{"lineNumber":204,"author":{"gitId":"yuanxi1"},"content":" throws InvalidParametersException, EntityDoesNotExistException, EntityAlreadyExistsException {"},{"lineNumber":205,"author":{"gitId":"yuanxi1"},"content":" Student student \u003d validateStudentJoinRequest(registrationKey, googleId);"},{"lineNumber":206,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":207,"author":{"gitId":"yuanxi1"},"content":" Account account \u003d accountsDb.getAccountByGoogleId(googleId);"},{"lineNumber":208,"author":{"gitId":"yuanxi1"},"content":" // Create an account if it doesn\u0027t exist"},{"lineNumber":209,"author":{"gitId":"yuanxi1"},"content":" if (account \u003d\u003d null) {"},{"lineNumber":210,"author":{"gitId":"yuanxi1"},"content":" account \u003d new Account(googleId, student.getName(), student.getEmail());"},{"lineNumber":211,"author":{"gitId":"yuanxi1"},"content":" createAccount(account);"},{"lineNumber":212,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":213,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":214,"author":{"gitId":"yuanxi1"},"content":" if (student.getAccount() \u003d\u003d null) {"},{"lineNumber":215,"author":{"gitId":"yuanxi1"},"content":" student.setAccount(account);"},{"lineNumber":216,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":217,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":218,"author":{"gitId":"yuanxi1"},"content":" return student;"},{"lineNumber":219,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":220,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":221,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":222,"author":{"gitId":"yuanxi1"},"content":" * Joins the user as an instructor."},{"lineNumber":223,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":224,"author":{"gitId":"yuanxi1"},"content":" public Instructor joinCourseForInstructor(String key, String googleId)"},{"lineNumber":225,"author":{"gitId":"yuanxi1"},"content":" throws InvalidParametersException, EntityDoesNotExistException, EntityAlreadyExistsException {"},{"lineNumber":226,"author":{"gitId":"yuanxi1"},"content":" Instructor instructor \u003d validateInstructorJoinRequest(key, googleId);"},{"lineNumber":227,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":228,"author":{"gitId":"yuanxi1"},"content":" Account account \u003d accountsDb.getAccountByGoogleId(googleId);"},{"lineNumber":229,"author":{"gitId":"yuanxi1"},"content":" if (account \u003d\u003d null) {"},{"lineNumber":230,"author":{"gitId":"yuanxi1"},"content":" try {"},{"lineNumber":231,"author":{"gitId":"yuanxi1"},"content":" account \u003d new Account(googleId, instructor.getName(), instructor.getEmail());"},{"lineNumber":232,"author":{"gitId":"yuanxi1"},"content":" createAccount(account);"},{"lineNumber":233,"author":{"gitId":"yuanxi1"},"content":" } catch (EntityAlreadyExistsException e) {"},{"lineNumber":234,"author":{"gitId":"yuanxi1"},"content":" assert false : \"Account already exists.\";"},{"lineNumber":235,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":236,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":237,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":238,"author":{"gitId":"yuanxi1"},"content":" instructor.setAccount(account);"},{"lineNumber":239,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":240,"author":{"gitId":"yuanxi1"},"content":" // Update the googleId of the student entity for the instructor which was created from sample data."},{"lineNumber":241,"author":{"gitId":"yuanxi1"},"content":" Student student \u003d usersLogic.getStudentForEmail(instructor.getCourseId(), instructor.getEmail());"},{"lineNumber":242,"author":{"gitId":"yuanxi1"},"content":" if (student !\u003d null) {"},{"lineNumber":243,"author":{"gitId":"yuanxi1"},"content":" student.setAccount(account);"},{"lineNumber":244,"author":{"gitId":"yuanxi1"},"content":" usersLogic.updateStudentCascade(student);"},{"lineNumber":245,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":246,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":247,"author":{"gitId":"yuanxi1"},"content":" return instructor;"},{"lineNumber":248,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":249,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":250,"author":{"gitId":"yuanxi1"},"content":" private Instructor validateInstructorJoinRequest(String registrationKey, String googleId)"},{"lineNumber":251,"author":{"gitId":"yuanxi1"},"content":" throws EntityDoesNotExistException, EntityAlreadyExistsException {"},{"lineNumber":252,"author":{"gitId":"yuanxi1"},"content":" Instructor instructorForKey \u003d usersLogic.getInstructorByRegistrationKey(registrationKey);"},{"lineNumber":253,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":254,"author":{"gitId":"yuanxi1"},"content":" if (instructorForKey \u003d\u003d null) {"},{"lineNumber":255,"author":{"gitId":"yuanxi1"},"content":" throw new EntityDoesNotExistException(\"No instructor with given registration key: \" + registrationKey);"},{"lineNumber":256,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":257,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":258,"author":{"gitId":"yuanxi1"},"content":" Course course \u003d coursesLogic.getCourse(instructorForKey.getCourseId());"},{"lineNumber":259,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":260,"author":{"gitId":"yuanxi1"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":261,"author":{"gitId":"yuanxi1"},"content":" throw new EntityDoesNotExistException(\"Course with id \" + instructorForKey.getCourseId() + \" does not exist\");"},{"lineNumber":262,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":263,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":264,"author":{"gitId":"yuanxi1"},"content":" if (course.isCourseDeleted()) {"},{"lineNumber":265,"author":{"gitId":"yuanxi1"},"content":" throw new EntityDoesNotExistException(\"The course you are trying to join has been deleted by an instructor\");"},{"lineNumber":266,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":267,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":268,"author":{"gitId":"yuanxi1"},"content":" if (instructorForKey.isRegistered()) {"},{"lineNumber":269,"author":{"gitId":"yuanxi1"},"content":" if (instructorForKey.getGoogleId().equals(googleId)) {"},{"lineNumber":270,"author":{"gitId":"yuanxi1"},"content":" Account existingAccount \u003d accountsDb.getAccountByGoogleId(googleId);"},{"lineNumber":271,"author":{"gitId":"yuanxi1"},"content":" if (existingAccount !\u003d null) {"},{"lineNumber":272,"author":{"gitId":"yuanxi1"},"content":" throw new EntityAlreadyExistsException(\"Instructor has already joined course\");"},{"lineNumber":273,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":274,"author":{"gitId":"yuanxi1"},"content":" } else {"},{"lineNumber":275,"author":{"gitId":"yuanxi1"},"content":" throw new EntityAlreadyExistsException(\"Instructor has already joined course\");"},{"lineNumber":276,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":277,"author":{"gitId":"yuanxi1"},"content":" } else {"},{"lineNumber":278,"author":{"gitId":"yuanxi1"},"content":" // Check if this Google ID has already joined this course"},{"lineNumber":279,"author":{"gitId":"yuanxi1"},"content":" Instructor existingInstructor \u003d"},{"lineNumber":280,"author":{"gitId":"yuanxi1"},"content":" usersLogic.getInstructorByGoogleId(instructorForKey.getCourseId(), googleId);"},{"lineNumber":281,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":282,"author":{"gitId":"yuanxi1"},"content":" if (existingInstructor !\u003d null) {"},{"lineNumber":283,"author":{"gitId":"yuanxi1"},"content":" throw new EntityAlreadyExistsException(\"Instructor has already joined course\");"},{"lineNumber":284,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":285,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":286,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":287,"author":{"gitId":"yuanxi1"},"content":" return instructorForKey;"},{"lineNumber":288,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":289,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":290,"author":{"gitId":"yuanxi1"},"content":" private Student validateStudentJoinRequest(String registrationKey, String googleId)"},{"lineNumber":291,"author":{"gitId":"yuanxi1"},"content":" throws EntityDoesNotExistException, EntityAlreadyExistsException {"},{"lineNumber":292,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":293,"author":{"gitId":"yuanxi1"},"content":" Student studentRole \u003d usersLogic.getStudentByRegistrationKey(registrationKey);"},{"lineNumber":294,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":295,"author":{"gitId":"yuanxi1"},"content":" if (studentRole \u003d\u003d null) {"},{"lineNumber":296,"author":{"gitId":"yuanxi1"},"content":" throw new EntityDoesNotExistException(\"No student with given registration key: \" + registrationKey);"},{"lineNumber":297,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":298,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":299,"author":{"gitId":"yuanxi1"},"content":" Course course \u003d coursesLogic.getCourse(studentRole.getCourseId());"},{"lineNumber":300,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":301,"author":{"gitId":"yuanxi1"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":302,"author":{"gitId":"yuanxi1"},"content":" throw new EntityDoesNotExistException(\"Course with id \" + studentRole.getCourseId() + \" does not exist\");"},{"lineNumber":303,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":304,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":305,"author":{"gitId":"yuanxi1"},"content":" if (course.isCourseDeleted()) {"},{"lineNumber":306,"author":{"gitId":"yuanxi1"},"content":" throw new EntityDoesNotExistException(\"The course you are trying to join has been deleted by an instructor\");"},{"lineNumber":307,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":308,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":309,"author":{"gitId":"yuanxi1"},"content":" if (studentRole.isRegistered()) {"},{"lineNumber":310,"author":{"gitId":"yuanxi1"},"content":" throw new EntityAlreadyExistsException(\"Student has already joined course\");"},{"lineNumber":311,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":312,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":313,"author":{"gitId":"yuanxi1"},"content":" // Check if this Google ID has already joined this course"},{"lineNumber":314,"author":{"gitId":"yuanxi1"},"content":" Student existingStudent \u003d"},{"lineNumber":315,"author":{"gitId":"yuanxi1"},"content":" usersLogic.getStudentByGoogleId(studentRole.getCourseId(), googleId);"},{"lineNumber":316,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":317,"author":{"gitId":"yuanxi1"},"content":" if (existingStudent !\u003d null) {"},{"lineNumber":318,"author":{"gitId":"yuanxi1"},"content":" throw new EntityAlreadyExistsException(\"Student has already joined course\");"},{"lineNumber":319,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":320,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":321,"author":{"gitId":"yuanxi1"},"content":" return studentRole;"},{"lineNumber":322,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":323,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":33,"yuanxi1":132,"-":158}},{"path":"src/main/java/teammates/sqllogic/core/CoursesLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static teammates.common.util.Const.ERROR_UPDATE_NON_EXISTENT;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Comparator;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.CoursesDb;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * Handles operations related to courses."},{"lineNumber":23,"author":{"gitId":"-"},"content":" *"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * @see Course"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * @see CoursesDb"},{"lineNumber":26,"author":{"gitId":"-"},"content":" */"},{"lineNumber":27,"author":{"gitId":"-"},"content":"public final class CoursesLogic {"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" private static final CoursesLogic instance \u003d new CoursesLogic();"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" private CoursesDb coursesDb;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private FeedbackSessionsLogic fsLogic;"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" private UsersLogic usersLogic;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" private CoursesLogic() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" public static CoursesLogic inst() {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" }"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" void initLogicDependencies(CoursesDb coursesDb, FeedbackSessionsLogic fsLogic, UsersLogic usersLogic) {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" this.coursesDb \u003d coursesDb;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" this.fsLogic \u003d fsLogic;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" this.usersLogic \u003d usersLogic;"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":52,"author":{"gitId":"-"},"content":" * Creates a course."},{"lineNumber":53,"author":{"gitId":"-"},"content":" *"},{"lineNumber":54,"author":{"gitId":"-"},"content":" * @return the created course"},{"lineNumber":55,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the course is not valid"},{"lineNumber":56,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the course already exists in the"},{"lineNumber":57,"author":{"gitId":"-"},"content":" * database."},{"lineNumber":58,"author":{"gitId":"-"},"content":" */"},{"lineNumber":59,"author":{"gitId":"-"},"content":" public Course createCourse(Course course) throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" return coursesDb.createCourse(course);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":64,"author":{"gitId":"-"},"content":" * Gets a course by course id."},{"lineNumber":65,"author":{"gitId":"-"},"content":" *"},{"lineNumber":66,"author":{"gitId":"-"},"content":" * @param courseId of course."},{"lineNumber":67,"author":{"gitId":"-"},"content":" * @return the specified course."},{"lineNumber":68,"author":{"gitId":"-"},"content":" */"},{"lineNumber":69,"author":{"gitId":"-"},"content":" public Course getCourse(String courseId) {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" return coursesDb.getCourse(courseId);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":74,"author":{"gitId":"-"},"content":" * Returns a list of {@link Course} for all courses a given student is enrolled in."},{"lineNumber":75,"author":{"gitId":"-"},"content":" *"},{"lineNumber":76,"author":{"gitId":"-"},"content":" * @param googleId The Google ID of the student"},{"lineNumber":77,"author":{"gitId":"-"},"content":" */"},{"lineNumber":78,"author":{"gitId":"-"},"content":" public List\u003cCourse\u003e getCoursesForStudentAccount(String googleId) {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e students \u003d usersLogic.getAllStudentsByGoogleId(googleId);"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" return students"},{"lineNumber":82,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":83,"author":{"gitId":"-"},"content":" .map(Student::getCourse)"},{"lineNumber":84,"author":{"gitId":"-"},"content":" .filter(course -\u003e !course.isCourseDeleted())"},{"lineNumber":85,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":86,"author":{"gitId":"-"},"content":" }"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":89,"author":{"gitId":"-"},"content":" * Returns a list of {@link Course} for all courses for a given list of instructors"},{"lineNumber":90,"author":{"gitId":"-"},"content":" * except for courses in Recycle Bin."},{"lineNumber":91,"author":{"gitId":"-"},"content":" */"},{"lineNumber":92,"author":{"gitId":"-"},"content":" public List\u003cCourse\u003e getCoursesForInstructors(List\u003cInstructor\u003e instructors) {"},{"lineNumber":93,"author":{"gitId":"-"},"content":" assert instructors !\u003d null;"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" return instructors"},{"lineNumber":96,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":97,"author":{"gitId":"-"},"content":" .map(Instructor::getCourse)"},{"lineNumber":98,"author":{"gitId":"-"},"content":" .filter(course -\u003e !course.isCourseDeleted())"},{"lineNumber":99,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":103,"author":{"gitId":"-"},"content":" * Returns a list of soft-deleted {@link Course} for a given list of instructors."},{"lineNumber":104,"author":{"gitId":"-"},"content":" */"},{"lineNumber":105,"author":{"gitId":"-"},"content":" public List\u003cCourse\u003e getSoftDeletedCoursesForInstructors(List\u003cInstructor\u003e instructors) {"},{"lineNumber":106,"author":{"gitId":"-"},"content":" assert instructors !\u003d null;"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" return instructors"},{"lineNumber":109,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":110,"author":{"gitId":"-"},"content":" .map(Instructor::getCourse)"},{"lineNumber":111,"author":{"gitId":"-"},"content":" .filter(course -\u003e course.isCourseDeleted())"},{"lineNumber":112,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":113,"author":{"gitId":"-"},"content":" }"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":116,"author":{"gitId":"-"},"content":" * Deletes a course and cascade its students, instructors, sessions, responses, deadline extensions and comments."},{"lineNumber":117,"author":{"gitId":"-"},"content":" * Fails silently if no such course."},{"lineNumber":118,"author":{"gitId":"-"},"content":" */"},{"lineNumber":119,"author":{"gitId":"-"},"content":" public void deleteCourseCascade(String courseId) {"},{"lineNumber":120,"author":{"gitId":"-"},"content":" Course course \u003d coursesDb.getCourse(courseId);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":123,"author":{"gitId":"-"},"content":" }"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" usersLogic.deleteStudentsInCourseCascade(courseId);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e feedbackSessions \u003d fsLogic.getFeedbackSessionsForCourse(courseId);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" feedbackSessions.forEach(feedbackSession -\u003e {"},{"lineNumber":128,"author":{"gitId":"-"},"content":" fsLogic.deleteFeedbackSessionCascade(feedbackSession.getName(), courseId);"},{"lineNumber":129,"author":{"gitId":"-"},"content":" });"},{"lineNumber":130,"author":{"gitId":"-"},"content":" coursesDb.deleteSectionsByCourseId(courseId);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors \u003d usersLogic.getInstructorsForCourse(courseId);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" instructors.forEach(instructor -\u003e {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" usersLogic.deleteInstructorCascade(courseId, instructor.getEmail());"},{"lineNumber":134,"author":{"gitId":"-"},"content":" });"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" coursesDb.deleteCourse(course);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":140,"author":{"gitId":"-"},"content":" * Moves a course to Recycle Bin by its given corresponding ID."},{"lineNumber":141,"author":{"gitId":"-"},"content":" *"},{"lineNumber":142,"author":{"gitId":"-"},"content":" * @return the time when the course is moved to the recycle bin."},{"lineNumber":143,"author":{"gitId":"-"},"content":" */"},{"lineNumber":144,"author":{"gitId":"-"},"content":" public Course moveCourseToRecycleBin(String courseId) throws EntityDoesNotExistException {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" Course course \u003d coursesDb.getCourse(courseId);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":147,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Trying to move a non-existent course to recycling bin.\");"},{"lineNumber":148,"author":{"gitId":"-"},"content":" }"},{"lineNumber":149,"author":{"gitId":"-"},"content":""},{"lineNumber":150,"author":{"gitId":"-"},"content":" Instant now \u003d Instant.now();"},{"lineNumber":151,"author":{"gitId":"-"},"content":" course.setDeletedAt(now);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" return course;"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":156,"author":{"gitId":"-"},"content":" * Restores a course from Recycle Bin by its given corresponding ID."},{"lineNumber":157,"author":{"gitId":"-"},"content":" */"},{"lineNumber":158,"author":{"gitId":"-"},"content":" public void restoreCourseFromRecycleBin(String courseId) throws EntityDoesNotExistException {"},{"lineNumber":159,"author":{"gitId":"-"},"content":" Course course \u003d coursesDb.getCourse(courseId);"},{"lineNumber":160,"author":{"gitId":"-"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":161,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Trying to restore a non-existent course from recycling bin.\");"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" course.setDeletedAt(null);"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":168,"author":{"gitId":"-"},"content":" * Updates a course."},{"lineNumber":169,"author":{"gitId":"-"},"content":" *"},{"lineNumber":170,"author":{"gitId":"-"},"content":" * @return updated course"},{"lineNumber":171,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":172,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the course cannot be found"},{"lineNumber":173,"author":{"gitId":"-"},"content":" */"},{"lineNumber":174,"author":{"gitId":"-"},"content":" public Course updateCourse(String courseId, String name, String timezone)"},{"lineNumber":175,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" Course course \u003d getCourse(courseId);"},{"lineNumber":177,"author":{"gitId":"-"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT + Course.class);"},{"lineNumber":179,"author":{"gitId":"-"},"content":" }"},{"lineNumber":180,"author":{"gitId":"-"},"content":" course.setName(name);"},{"lineNumber":181,"author":{"gitId":"-"},"content":" course.setTimeZone(timezone);"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" if (!course.isValid()) {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(course.getInvalidityInfo());"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" return course;"},{"lineNumber":188,"author":{"gitId":"-"},"content":" }"},{"lineNumber":189,"author":{"gitId":"-"},"content":""},{"lineNumber":190,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":191,"author":{"gitId":"-"},"content":" * Creates a section."},{"lineNumber":192,"author":{"gitId":"-"},"content":" */"},{"lineNumber":193,"author":{"gitId":"-"},"content":" public Section createSection(Section section) throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":194,"author":{"gitId":"-"},"content":" return coursesDb.createSection(section);"},{"lineNumber":195,"author":{"gitId":"-"},"content":" }"},{"lineNumber":196,"author":{"gitId":"-"},"content":""},{"lineNumber":197,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":198,"author":{"gitId":"-"},"content":" * Get section by {@code courseId} and {@code teamName}."},{"lineNumber":199,"author":{"gitId":"-"},"content":" */"},{"lineNumber":200,"author":{"gitId":"-"},"content":" public Section getSectionByCourseIdAndTeam(String courseId, String teamName) {"},{"lineNumber":201,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":202,"author":{"gitId":"-"},"content":" assert teamName !\u003d null;"},{"lineNumber":203,"author":{"gitId":"-"},"content":""},{"lineNumber":204,"author":{"gitId":"-"},"content":" return coursesDb.getSectionByCourseIdAndTeam(courseId, teamName);"},{"lineNumber":205,"author":{"gitId":"-"},"content":" }"},{"lineNumber":206,"author":{"gitId":"-"},"content":""},{"lineNumber":207,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":208,"author":{"gitId":"-"},"content":" * Gets a list of section names for the given {@code courseId}."},{"lineNumber":209,"author":{"gitId":"-"},"content":" */"},{"lineNumber":210,"author":{"gitId":"-"},"content":" public List\u003cString\u003e getSectionNamesForCourse(String courseId) throws EntityDoesNotExistException {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":212,"author":{"gitId":"-"},"content":" Course course \u003d getCourse(courseId);"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Trying to get section names for a non-existent course.\");"},{"lineNumber":216,"author":{"gitId":"-"},"content":" }"},{"lineNumber":217,"author":{"gitId":"-"},"content":""},{"lineNumber":218,"author":{"gitId":"-"},"content":" return course.getSections()"},{"lineNumber":219,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":220,"author":{"gitId":"-"},"content":" .map(section -\u003e section.getName())"},{"lineNumber":221,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":222,"author":{"gitId":"-"},"content":" }"},{"lineNumber":223,"author":{"gitId":"-"},"content":""},{"lineNumber":224,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":225,"author":{"gitId":"yuanxi1"},"content":" * Gets the institute of the course."},{"lineNumber":226,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":227,"author":{"gitId":"yuanxi1"},"content":" public String getCourseInstitute(String courseId) {"},{"lineNumber":228,"author":{"gitId":"yuanxi1"},"content":" Course course \u003d getCourse(courseId);"},{"lineNumber":229,"author":{"gitId":"yuanxi1"},"content":" assert course !\u003d null : \"Trying to getCourseInstitute for inexistent course with id \" + courseId;"},{"lineNumber":230,"author":{"gitId":"yuanxi1"},"content":" return course.getInstitute();"},{"lineNumber":231,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":232,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":234,"author":{"gitId":"-"},"content":" * Creates a team."},{"lineNumber":235,"author":{"gitId":"-"},"content":" */"},{"lineNumber":236,"author":{"gitId":"-"},"content":" public Team createTeam(Team team) throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":237,"author":{"gitId":"-"},"content":" return coursesDb.createTeam(team);"},{"lineNumber":238,"author":{"gitId":"-"},"content":" }"},{"lineNumber":239,"author":{"gitId":"-"},"content":""},{"lineNumber":240,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":241,"author":{"gitId":"-"},"content":" * Returns teams for a particular section."},{"lineNumber":242,"author":{"gitId":"-"},"content":" */"},{"lineNumber":243,"author":{"gitId":"-"},"content":" public List\u003cTeam\u003e getTeamsForSection(Section section) {"},{"lineNumber":244,"author":{"gitId":"-"},"content":" return coursesDb.getTeamsForSection(section);"},{"lineNumber":245,"author":{"gitId":"-"},"content":" }"},{"lineNumber":246,"author":{"gitId":"-"},"content":""},{"lineNumber":247,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":248,"author":{"gitId":"-"},"content":" * Returns teams for a course."},{"lineNumber":249,"author":{"gitId":"-"},"content":" */"},{"lineNumber":250,"author":{"gitId":"-"},"content":" public List\u003cTeam\u003e getTeamsForCourse(String courseId) {"},{"lineNumber":251,"author":{"gitId":"-"},"content":" return coursesDb.getTeamsForCourse(courseId);"},{"lineNumber":252,"author":{"gitId":"-"},"content":" }"},{"lineNumber":253,"author":{"gitId":"-"},"content":""},{"lineNumber":254,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":255,"author":{"gitId":"-"},"content":" * Sorts the courses list alphabetically by id."},{"lineNumber":256,"author":{"gitId":"-"},"content":" */"},{"lineNumber":257,"author":{"gitId":"-"},"content":" public static void sortById(List\u003cCourse\u003e courses) {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" courses.sort(Comparator.comparing(Course::getId));"},{"lineNumber":259,"author":{"gitId":"-"},"content":" }"},{"lineNumber":260,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"yuanxi1":9,"-":251}},{"path":"src/main/java/teammates/sqllogic/core/DataBundleLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Collection;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.ReadNotification;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.User;"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":33,"author":{"gitId":"-"},"content":" * Handles operations related to data bundles."},{"lineNumber":34,"author":{"gitId":"-"},"content":" *"},{"lineNumber":35,"author":{"gitId":"-"},"content":" * @see DataBundle"},{"lineNumber":36,"author":{"gitId":"-"},"content":" */"},{"lineNumber":37,"author":{"gitId":"-"},"content":"public final class DataBundleLogic {"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" private static final DataBundleLogic instance \u003d new DataBundleLogic();"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" private AccountsLogic accountsLogic;"},{"lineNumber":42,"author":{"gitId":"-"},"content":" private AccountRequestsLogic accountRequestsLogic;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" private CoursesLogic coursesLogic;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" private DeadlineExtensionsLogic deadlineExtensionsLogic;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" private FeedbackSessionsLogic fsLogic;"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" private FeedbackSessionLogsLogic fslLogic;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" private FeedbackQuestionsLogic fqLogic;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" private FeedbackResponsesLogic frLogic;"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private FeedbackResponseCommentsLogic frcLogic;"},{"lineNumber":50,"author":{"gitId":"-"},"content":" private NotificationsLogic notificationsLogic;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" private UsersLogic usersLogic;"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" private DataBundleLogic() {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" public static DataBundleLogic inst() {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":59,"author":{"gitId":"-"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" void initLogicDependencies(AccountsLogic accountsLogic, AccountRequestsLogic accountRequestsLogic,"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" CoursesLogic coursesLogic, DeadlineExtensionsLogic deadlineExtensionsLogic, FeedbackSessionsLogic fsLogic,"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogsLogic fslLogic, FeedbackQuestionsLogic fqLogic, FeedbackResponsesLogic frLogic,"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" FeedbackResponseCommentsLogic frcLogic, NotificationsLogic notificationsLogic, UsersLogic usersLogic) {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" this.accountsLogic \u003d accountsLogic;"},{"lineNumber":66,"author":{"gitId":"-"},"content":" this.accountRequestsLogic \u003d accountRequestsLogic;"},{"lineNumber":67,"author":{"gitId":"-"},"content":" this.coursesLogic \u003d coursesLogic;"},{"lineNumber":68,"author":{"gitId":"-"},"content":" this.deadlineExtensionsLogic \u003d deadlineExtensionsLogic;"},{"lineNumber":69,"author":{"gitId":"-"},"content":" this.fsLogic \u003d fsLogic;"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" this.fslLogic \u003d fslLogic;"},{"lineNumber":71,"author":{"gitId":"-"},"content":" this.fqLogic \u003d fqLogic;"},{"lineNumber":72,"author":{"gitId":"-"},"content":" this.frLogic \u003d frLogic;"},{"lineNumber":73,"author":{"gitId":"-"},"content":" this.frcLogic \u003d frcLogic;"},{"lineNumber":74,"author":{"gitId":"-"},"content":" this.notificationsLogic \u003d notificationsLogic;"},{"lineNumber":75,"author":{"gitId":"-"},"content":" this.usersLogic \u003d usersLogic;"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":79,"author":{"gitId":"-"},"content":" * Deserialize JSON into a data bundle."},{"lineNumber":80,"author":{"gitId":"-"},"content":" *"},{"lineNumber":81,"author":{"gitId":"-"},"content":" * \u003cp\u003eNOTE: apart from for Course, ids used in the jsonString may be any valid UUID"},{"lineNumber":82,"author":{"gitId":"-"},"content":" * and are used only to link entities together. They will be replaced by a random"},{"lineNumber":83,"author":{"gitId":"-"},"content":" * UUID when deserialized and hence do not need to be checked if they exist in the"},{"lineNumber":84,"author":{"gitId":"-"},"content":" * database previously.\u003c/p\u003e"},{"lineNumber":85,"author":{"gitId":"-"},"content":" *"},{"lineNumber":86,"author":{"gitId":"-"},"content":" * @param jsonString containing entities to persist at once to the database."},{"lineNumber":87,"author":{"gitId":"-"},"content":" * CourseID must be a valid UUID not currently in use."},{"lineNumber":88,"author":{"gitId":"-"},"content":" * For other entities, replaces the given ids with randomly generated UUIDs."},{"lineNumber":89,"author":{"gitId":"-"},"content":" * @return newly created DataBundle"},{"lineNumber":90,"author":{"gitId":"-"},"content":" */"},{"lineNumber":91,"author":{"gitId":"-"},"content":" public static SqlDataBundle deserializeDataBundle(String jsonString) {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" SqlDataBundle dataBundle \u003d JsonUtils.fromJson(jsonString, SqlDataBundle.class);"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" Collection\u003cAccount\u003e accounts \u003d dataBundle.accounts.values();"},{"lineNumber":95,"author":{"gitId":"-"},"content":" Collection\u003cAccountRequest\u003e accountRequests \u003d dataBundle.accountRequests.values();"},{"lineNumber":96,"author":{"gitId":"-"},"content":" Collection\u003cCourse\u003e courses \u003d dataBundle.courses.values();"},{"lineNumber":97,"author":{"gitId":"-"},"content":" Collection\u003cSection\u003e sections \u003d dataBundle.sections.values();"},{"lineNumber":98,"author":{"gitId":"-"},"content":" Collection\u003cTeam\u003e teams \u003d dataBundle.teams.values();"},{"lineNumber":99,"author":{"gitId":"-"},"content":" Collection\u003cInstructor\u003e instructors \u003d dataBundle.instructors.values();"},{"lineNumber":100,"author":{"gitId":"-"},"content":" Collection\u003cStudent\u003e students \u003d dataBundle.students.values();"},{"lineNumber":101,"author":{"gitId":"-"},"content":" Collection\u003cFeedbackSession\u003e sessions \u003d dataBundle.feedbackSessions.values();"},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" Collection\u003cFeedbackSessionLog\u003e sessionLogs \u003d dataBundle.feedbackSessionLogs.values();"},{"lineNumber":103,"author":{"gitId":"-"},"content":" Collection\u003cFeedbackQuestion\u003e questions \u003d dataBundle.feedbackQuestions.values();"},{"lineNumber":104,"author":{"gitId":"-"},"content":" Collection\u003cFeedbackResponse\u003e responses \u003d dataBundle.feedbackResponses.values();"},{"lineNumber":105,"author":{"gitId":"-"},"content":" Collection\u003cFeedbackResponseComment\u003e responseComments \u003d dataBundle.feedbackResponseComments.values();"},{"lineNumber":106,"author":{"gitId":"-"},"content":" Collection\u003cDeadlineExtension\u003e deadlineExtensions \u003d dataBundle.deadlineExtensions.values();"},{"lineNumber":107,"author":{"gitId":"-"},"content":" Collection\u003cNotification\u003e notifications \u003d dataBundle.notifications.values();"},{"lineNumber":108,"author":{"gitId":"-"},"content":" Collection\u003cReadNotification\u003e readNotifications \u003d dataBundle.readNotifications.values();"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" // Mapping of IDs or placeholder IDs to actual entity"},{"lineNumber":111,"author":{"gitId":"-"},"content":" Map\u003cString, Course\u003e coursesMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":112,"author":{"gitId":"-"},"content":" Map\u003cUUID, Section\u003e sectionsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":113,"author":{"gitId":"-"},"content":" Map\u003cUUID, Team\u003e teamsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":114,"author":{"gitId":"-"},"content":" Map\u003cUUID, FeedbackSession\u003e sessionsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":115,"author":{"gitId":"-"},"content":" Map\u003cUUID, FeedbackQuestion\u003e questionMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":116,"author":{"gitId":"-"},"content":" Map\u003cUUID, FeedbackResponse\u003e responseMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":117,"author":{"gitId":"-"},"content":" Map\u003cUUID, Account\u003e accountsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":118,"author":{"gitId":"-"},"content":" Map\u003cUUID, User\u003e usersMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":119,"author":{"gitId":"-"},"content":" Map\u003cUUID, Notification\u003e notificationsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":120,"author":{"gitId":"-"},"content":""},{"lineNumber":121,"author":{"gitId":"-"},"content":" // Replace any placeholder IDs with newly generated UUIDs"},{"lineNumber":122,"author":{"gitId":"-"},"content":" // Store mapping of placeholder ID to actual entity to keep track of"},{"lineNumber":123,"author":{"gitId":"-"},"content":" // associations between entities"},{"lineNumber":124,"author":{"gitId":"-"},"content":" for (AccountRequest accountRequest : accountRequests) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" accountRequest.setId(UUID.randomUUID());"},{"lineNumber":126,"author":{"gitId":"-"},"content":" accountRequest.generateNewRegistrationKey();"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" for (Course course : courses) {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" coursesMap.put(course.getId(), course);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" }"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" for (Section section : sections) {"},{"lineNumber":134,"author":{"gitId":"-"},"content":" UUID placeholderId \u003d section.getId();"},{"lineNumber":135,"author":{"gitId":"-"},"content":" section.setId(UUID.randomUUID());"},{"lineNumber":136,"author":{"gitId":"-"},"content":" sectionsMap.put(placeholderId, section);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" Course course \u003d coursesMap.get(section.getCourse().getId());"},{"lineNumber":138,"author":{"gitId":"-"},"content":" section.setCourse(course);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" }"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" for (Team team : teams) {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" UUID placeholderId \u003d team.getId();"},{"lineNumber":143,"author":{"gitId":"-"},"content":" team.setId(UUID.randomUUID());"},{"lineNumber":144,"author":{"gitId":"-"},"content":" teamsMap.put(placeholderId, team);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" Section section \u003d sectionsMap.get(team.getSection().getId());"},{"lineNumber":146,"author":{"gitId":"-"},"content":" team.setSection(section);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" for (FeedbackSession session : sessions) {"},{"lineNumber":150,"author":{"gitId":"-"},"content":" UUID placeholderId \u003d session.getId();"},{"lineNumber":151,"author":{"gitId":"-"},"content":" session.setId(UUID.randomUUID());"},{"lineNumber":152,"author":{"gitId":"-"},"content":" sessionsMap.put(placeholderId, session);"},{"lineNumber":153,"author":{"gitId":"-"},"content":" Course course \u003d coursesMap.get(session.getCourse().getId());"},{"lineNumber":154,"author":{"gitId":"-"},"content":" session.setCourse(course);"},{"lineNumber":155,"author":{"gitId":"-"},"content":" }"},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"-"},"content":" for (FeedbackQuestion question : questions) {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" UUID placeholderId \u003d question.getId();"},{"lineNumber":159,"author":{"gitId":"-"},"content":" question.setId(UUID.randomUUID());"},{"lineNumber":160,"author":{"gitId":"-"},"content":" questionMap.put(placeholderId, question);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d sessionsMap.get(question.getFeedbackSession().getId());"},{"lineNumber":162,"author":{"gitId":"-"},"content":" question.setFeedbackSession(fs);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" for (FeedbackResponse response : responses) {"},{"lineNumber":166,"author":{"gitId":"-"},"content":" UUID placeholderId \u003d response.getId();"},{"lineNumber":167,"author":{"gitId":"-"},"content":" response.setId(UUID.randomUUID());"},{"lineNumber":168,"author":{"gitId":"-"},"content":" responseMap.put(placeholderId, response);"},{"lineNumber":169,"author":{"gitId":"-"},"content":" FeedbackQuestion fq \u003d questionMap.get(response.getFeedbackQuestion().getId());"},{"lineNumber":170,"author":{"gitId":"-"},"content":" Section giverSection \u003d sectionsMap.get(response.getGiverSection().getId());"},{"lineNumber":171,"author":{"gitId":"-"},"content":" Section recipientSection \u003d response.getRecipientSection() !\u003d null"},{"lineNumber":172,"author":{"gitId":"-"},"content":" ? sectionsMap.get(response.getRecipientSection().getId()) : null;"},{"lineNumber":173,"author":{"gitId":"-"},"content":" response.setFeedbackQuestion(fq);"},{"lineNumber":174,"author":{"gitId":"-"},"content":" response.setGiverSection(giverSection);"},{"lineNumber":175,"author":{"gitId":"-"},"content":" response.setRecipientSection(recipientSection);"},{"lineNumber":176,"author":{"gitId":"-"},"content":" }"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" for (FeedbackResponseComment responseComment : responseComments) {"},{"lineNumber":179,"author":{"gitId":"-"},"content":" FeedbackResponse fr \u003d responseMap.get(responseComment.getFeedbackResponse().getId());"},{"lineNumber":180,"author":{"gitId":"-"},"content":" Section giverSection \u003d sectionsMap.get(responseComment.getGiverSection().getId());"},{"lineNumber":181,"author":{"gitId":"-"},"content":" Section recipientSection \u003d sectionsMap.get(responseComment.getRecipientSection().getId());"},{"lineNumber":182,"author":{"gitId":"-"},"content":" responseComment.setFeedbackResponse(fr);"},{"lineNumber":183,"author":{"gitId":"-"},"content":" responseComment.setGiverSection(giverSection);"},{"lineNumber":184,"author":{"gitId":"-"},"content":" responseComment.setRecipientSection(recipientSection);"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" for (Account account : accounts) {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" UUID placeholderId \u003d account.getId();"},{"lineNumber":189,"author":{"gitId":"-"},"content":" account.setId(UUID.randomUUID());"},{"lineNumber":190,"author":{"gitId":"-"},"content":" accountsMap.put(placeholderId, account);"},{"lineNumber":191,"author":{"gitId":"-"},"content":" }"},{"lineNumber":192,"author":{"gitId":"-"},"content":""},{"lineNumber":193,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructors) {"},{"lineNumber":194,"author":{"gitId":"-"},"content":" UUID placeholderId \u003d instructor.getId();"},{"lineNumber":195,"author":{"gitId":"-"},"content":" instructor.setId(UUID.randomUUID());"},{"lineNumber":196,"author":{"gitId":"-"},"content":" usersMap.put(placeholderId, instructor);"},{"lineNumber":197,"author":{"gitId":"-"},"content":" Course course \u003d coursesMap.get(instructor.getCourse().getId());"},{"lineNumber":198,"author":{"gitId":"-"},"content":" instructor.setCourse(course);"},{"lineNumber":199,"author":{"gitId":"-"},"content":" if (instructor.getAccount() !\u003d null) {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" Account account \u003d accountsMap.get(instructor.getAccount().getId());"},{"lineNumber":201,"author":{"gitId":"-"},"content":" instructor.setAccount(account);"},{"lineNumber":202,"author":{"gitId":"-"},"content":" }"},{"lineNumber":203,"author":{"gitId":"-"},"content":" instructor.generateNewRegistrationKey();"},{"lineNumber":204,"author":{"gitId":"-"},"content":" }"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" for (Student student : students) {"},{"lineNumber":207,"author":{"gitId":"-"},"content":" UUID placeholderId \u003d student.getId();"},{"lineNumber":208,"author":{"gitId":"-"},"content":" student.setId(UUID.randomUUID());"},{"lineNumber":209,"author":{"gitId":"-"},"content":" usersMap.put(placeholderId, student);"},{"lineNumber":210,"author":{"gitId":"-"},"content":" Course course \u003d coursesMap.get(student.getCourse().getId());"},{"lineNumber":211,"author":{"gitId":"-"},"content":" student.setCourse(course);"},{"lineNumber":212,"author":{"gitId":"-"},"content":" Team team \u003d teamsMap.get(student.getTeam().getId());"},{"lineNumber":213,"author":{"gitId":"-"},"content":" student.setTeam(team);"},{"lineNumber":214,"author":{"gitId":"-"},"content":" if (student.getAccount() !\u003d null) {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" Account account \u003d accountsMap.get(student.getAccount().getId());"},{"lineNumber":216,"author":{"gitId":"-"},"content":" student.setAccount(account);"},{"lineNumber":217,"author":{"gitId":"-"},"content":" }"},{"lineNumber":218,"author":{"gitId":"-"},"content":" student.generateNewRegistrationKey();"},{"lineNumber":219,"author":{"gitId":"-"},"content":" }"},{"lineNumber":220,"author":{"gitId":"-"},"content":""},{"lineNumber":221,"author":{"gitId":"dishenggg"},"content":" for (FeedbackSessionLog log : sessionLogs) {"},{"lineNumber":222,"author":{"gitId":"dishenggg"},"content":" log.setId(UUID.randomUUID());"},{"lineNumber":223,"author":{"gitId":"dishenggg"},"content":" FeedbackSession fs \u003d sessionsMap.get(log.getFeedbackSession().getId());"},{"lineNumber":224,"author":{"gitId":"dishenggg"},"content":" log.setFeedbackSession(fs);"},{"lineNumber":225,"author":{"gitId":"dishenggg"},"content":" Student student \u003d (Student) usersMap.get(log.getStudent().getId());"},{"lineNumber":226,"author":{"gitId":"dishenggg"},"content":" log.setStudent(student);"},{"lineNumber":227,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":228,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" for (Notification notification : notifications) {"},{"lineNumber":230,"author":{"gitId":"-"},"content":" UUID placeholderId \u003d notification.getId();"},{"lineNumber":231,"author":{"gitId":"-"},"content":" notification.setId(UUID.randomUUID());"},{"lineNumber":232,"author":{"gitId":"-"},"content":" notificationsMap.put(placeholderId, notification);"},{"lineNumber":233,"author":{"gitId":"-"},"content":" }"},{"lineNumber":234,"author":{"gitId":"-"},"content":""},{"lineNumber":235,"author":{"gitId":"-"},"content":" for (ReadNotification readNotification : readNotifications) {"},{"lineNumber":236,"author":{"gitId":"-"},"content":" readNotification.setId(UUID.randomUUID());"},{"lineNumber":237,"author":{"gitId":"-"},"content":" Account account \u003d accountsMap.get(readNotification.getAccount().getId());"},{"lineNumber":238,"author":{"gitId":"-"},"content":" readNotification.setAccount(account);"},{"lineNumber":239,"author":{"gitId":"-"},"content":" account.addReadNotification(readNotification);"},{"lineNumber":240,"author":{"gitId":"-"},"content":" Notification notification \u003d notificationsMap.get(readNotification.getNotification().getId());"},{"lineNumber":241,"author":{"gitId":"-"},"content":" readNotification.setNotification(notification);"},{"lineNumber":242,"author":{"gitId":"-"},"content":" }"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" for (DeadlineExtension deadlineExtension : deadlineExtensions) {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" deadlineExtension.setId(UUID.randomUUID());"},{"lineNumber":246,"author":{"gitId":"-"},"content":" FeedbackSession session \u003d sessionsMap.get(deadlineExtension.getFeedbackSession().getId());"},{"lineNumber":247,"author":{"gitId":"-"},"content":" deadlineExtension.setFeedbackSession(session);"},{"lineNumber":248,"author":{"gitId":"-"},"content":" User user \u003d usersMap.get(deadlineExtension.getUser().getId());"},{"lineNumber":249,"author":{"gitId":"-"},"content":" deadlineExtension.setUser(user);"},{"lineNumber":250,"author":{"gitId":"-"},"content":" }"},{"lineNumber":251,"author":{"gitId":"-"},"content":""},{"lineNumber":252,"author":{"gitId":"-"},"content":" return dataBundle;"},{"lineNumber":253,"author":{"gitId":"-"},"content":" }"},{"lineNumber":254,"author":{"gitId":"-"},"content":""},{"lineNumber":255,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":256,"author":{"gitId":"-"},"content":" * Persists data in the given {@link DataBundle} to the database."},{"lineNumber":257,"author":{"gitId":"-"},"content":" *"},{"lineNumber":258,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if invalid data is encountered."},{"lineNumber":259,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if an entity was not found."},{"lineNumber":260,"author":{"gitId":"-"},"content":" * (ReadNotification requires Account and Notification to be created)"},{"lineNumber":261,"author":{"gitId":"-"},"content":" */"},{"lineNumber":262,"author":{"gitId":"-"},"content":" public SqlDataBundle persistDataBundle(SqlDataBundle dataBundle)"},{"lineNumber":263,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException, EntityDoesNotExistException {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" if (dataBundle \u003d\u003d null) {"},{"lineNumber":265,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(\"Null data bundle\");"},{"lineNumber":266,"author":{"gitId":"-"},"content":" }"},{"lineNumber":267,"author":{"gitId":"-"},"content":""},{"lineNumber":268,"author":{"gitId":"yuanxi1"},"content":" linkEntities(dataBundle);"},{"lineNumber":269,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":" Collection\u003cAccount\u003e accounts \u003d dataBundle.accounts.values();"},{"lineNumber":271,"author":{"gitId":"-"},"content":" Collection\u003cAccountRequest\u003e accountRequests \u003d dataBundle.accountRequests.values();"},{"lineNumber":272,"author":{"gitId":"-"},"content":" Collection\u003cCourse\u003e courses \u003d dataBundle.courses.values();"},{"lineNumber":273,"author":{"gitId":"-"},"content":" Collection\u003cSection\u003e sections \u003d dataBundle.sections.values();"},{"lineNumber":274,"author":{"gitId":"-"},"content":" Collection\u003cTeam\u003e teams \u003d dataBundle.teams.values();"},{"lineNumber":275,"author":{"gitId":"-"},"content":" Collection\u003cInstructor\u003e instructors \u003d dataBundle.instructors.values();"},{"lineNumber":276,"author":{"gitId":"-"},"content":" Collection\u003cStudent\u003e students \u003d dataBundle.students.values();"},{"lineNumber":277,"author":{"gitId":"-"},"content":" Collection\u003cFeedbackSession\u003e sessions \u003d dataBundle.feedbackSessions.values();"},{"lineNumber":278,"author":{"gitId":"dishenggg"},"content":" Collection\u003cFeedbackSessionLog\u003e sessionLogs \u003d dataBundle.feedbackSessionLogs.values();"},{"lineNumber":279,"author":{"gitId":"-"},"content":" Collection\u003cFeedbackQuestion\u003e questions \u003d dataBundle.feedbackQuestions.values();"},{"lineNumber":280,"author":{"gitId":"-"},"content":" Collection\u003cFeedbackResponse\u003e responses \u003d dataBundle.feedbackResponses.values();"},{"lineNumber":281,"author":{"gitId":"-"},"content":" Collection\u003cFeedbackResponseComment\u003e responseComments \u003d dataBundle.feedbackResponseComments.values();"},{"lineNumber":282,"author":{"gitId":"-"},"content":" Collection\u003cDeadlineExtension\u003e deadlineExtensions \u003d dataBundle.deadlineExtensions.values();"},{"lineNumber":283,"author":{"gitId":"-"},"content":" Collection\u003cNotification\u003e notifications \u003d dataBundle.notifications.values();"},{"lineNumber":284,"author":{"gitId":"-"},"content":" Collection\u003cReadNotification\u003e readNotifications \u003d dataBundle.readNotifications.values();"},{"lineNumber":285,"author":{"gitId":"-"},"content":""},{"lineNumber":286,"author":{"gitId":"-"},"content":" for (AccountRequest accountRequest : accountRequests) {"},{"lineNumber":287,"author":{"gitId":"-"},"content":" accountRequestsLogic.createAccountRequest(accountRequest);"},{"lineNumber":288,"author":{"gitId":"-"},"content":" }"},{"lineNumber":289,"author":{"gitId":"-"},"content":""},{"lineNumber":290,"author":{"gitId":"-"},"content":" for (Notification notification : notifications) {"},{"lineNumber":291,"author":{"gitId":"-"},"content":" notificationsLogic.createNotification(notification);"},{"lineNumber":292,"author":{"gitId":"-"},"content":" }"},{"lineNumber":293,"author":{"gitId":"-"},"content":""},{"lineNumber":294,"author":{"gitId":"-"},"content":" for (Course course : courses) {"},{"lineNumber":295,"author":{"gitId":"-"},"content":" coursesLogic.createCourse(course);"},{"lineNumber":296,"author":{"gitId":"-"},"content":" }"},{"lineNumber":297,"author":{"gitId":"-"},"content":""},{"lineNumber":298,"author":{"gitId":"-"},"content":" for (Section section : sections) {"},{"lineNumber":299,"author":{"gitId":"-"},"content":" coursesLogic.createSection(section);"},{"lineNumber":300,"author":{"gitId":"-"},"content":" }"},{"lineNumber":301,"author":{"gitId":"-"},"content":""},{"lineNumber":302,"author":{"gitId":"-"},"content":" for (Team team : teams) {"},{"lineNumber":303,"author":{"gitId":"-"},"content":" coursesLogic.createTeam(team);"},{"lineNumber":304,"author":{"gitId":"-"},"content":" }"},{"lineNumber":305,"author":{"gitId":"-"},"content":""},{"lineNumber":306,"author":{"gitId":"-"},"content":" for (FeedbackSession session : sessions) {"},{"lineNumber":307,"author":{"gitId":"-"},"content":" fsLogic.createFeedbackSession(session);"},{"lineNumber":308,"author":{"gitId":"-"},"content":" }"},{"lineNumber":309,"author":{"gitId":"-"},"content":""},{"lineNumber":310,"author":{"gitId":"-"},"content":" for (FeedbackQuestion question : questions) {"},{"lineNumber":311,"author":{"gitId":"-"},"content":" fqLogic.createFeedbackQuestion(question);"},{"lineNumber":312,"author":{"gitId":"-"},"content":" }"},{"lineNumber":313,"author":{"gitId":"-"},"content":""},{"lineNumber":314,"author":{"gitId":"-"},"content":" for (FeedbackResponse response : responses) {"},{"lineNumber":315,"author":{"gitId":"-"},"content":" frLogic.createFeedbackResponse(response);"},{"lineNumber":316,"author":{"gitId":"-"},"content":" }"},{"lineNumber":317,"author":{"gitId":"-"},"content":""},{"lineNumber":318,"author":{"gitId":"-"},"content":" for (FeedbackResponseComment responseComment : responseComments) {"},{"lineNumber":319,"author":{"gitId":"-"},"content":" responseComment.setId(null);"},{"lineNumber":320,"author":{"gitId":"-"},"content":" frcLogic.createFeedbackResponseComment(responseComment);"},{"lineNumber":321,"author":{"gitId":"-"},"content":" }"},{"lineNumber":322,"author":{"gitId":"-"},"content":""},{"lineNumber":323,"author":{"gitId":"-"},"content":" for (Account account : accounts) {"},{"lineNumber":324,"author":{"gitId":"-"},"content":" accountsLogic.createAccount(account);"},{"lineNumber":325,"author":{"gitId":"-"},"content":" }"},{"lineNumber":326,"author":{"gitId":"-"},"content":""},{"lineNumber":327,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructors) {"},{"lineNumber":328,"author":{"gitId":"-"},"content":" usersLogic.createInstructor(instructor);"},{"lineNumber":329,"author":{"gitId":"-"},"content":" }"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" for (Student student : students) {"},{"lineNumber":332,"author":{"gitId":"-"},"content":" usersLogic.createStudent(student);"},{"lineNumber":333,"author":{"gitId":"-"},"content":" }"},{"lineNumber":334,"author":{"gitId":"-"},"content":""},{"lineNumber":335,"author":{"gitId":"dishenggg"},"content":" fslLogic.createFeedbackSessionLogs(new ArrayList\u003c\u003e(sessionLogs));"},{"lineNumber":336,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":337,"author":{"gitId":"-"},"content":" for (ReadNotification readNotification : readNotifications) {"},{"lineNumber":338,"author":{"gitId":"-"},"content":" accountsLogic.updateReadNotifications(readNotification.getAccount().getGoogleId(),"},{"lineNumber":339,"author":{"gitId":"-"},"content":" readNotification.getNotification().getId(), readNotification.getNotification().getEndTime());"},{"lineNumber":340,"author":{"gitId":"-"},"content":" }"},{"lineNumber":341,"author":{"gitId":"-"},"content":""},{"lineNumber":342,"author":{"gitId":"-"},"content":" for (DeadlineExtension deadlineExtension : deadlineExtensions) {"},{"lineNumber":343,"author":{"gitId":"-"},"content":" deadlineExtensionsLogic.createDeadlineExtension(deadlineExtension);"},{"lineNumber":344,"author":{"gitId":"-"},"content":" }"},{"lineNumber":345,"author":{"gitId":"-"},"content":""},{"lineNumber":346,"author":{"gitId":"-"},"content":" return dataBundle;"},{"lineNumber":347,"author":{"gitId":"-"},"content":" }"},{"lineNumber":348,"author":{"gitId":"-"},"content":""},{"lineNumber":349,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":350,"author":{"gitId":"-"},"content":" * Removes the items in the data bundle from the database."},{"lineNumber":351,"author":{"gitId":"-"},"content":" */"},{"lineNumber":352,"author":{"gitId":"-"},"content":" public void removeDataBundle(SqlDataBundle dataBundle) throws InvalidParametersException {"},{"lineNumber":353,"author":{"gitId":"-"},"content":" if (dataBundle \u003d\u003d null) {"},{"lineNumber":354,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(\"Data bundle is null\");"},{"lineNumber":355,"author":{"gitId":"-"},"content":" }"},{"lineNumber":356,"author":{"gitId":"-"},"content":""},{"lineNumber":357,"author":{"gitId":"yuanxi1"},"content":" linkEntities(dataBundle);"},{"lineNumber":358,"author":{"gitId":"-"},"content":" dataBundle.courses.values().forEach(course -\u003e {"},{"lineNumber":359,"author":{"gitId":"-"},"content":" coursesLogic.deleteCourseCascade(course.getId());"},{"lineNumber":360,"author":{"gitId":"-"},"content":" });"},{"lineNumber":361,"author":{"gitId":"-"},"content":" dataBundle.notifications.values().forEach(notification -\u003e {"},{"lineNumber":362,"author":{"gitId":"-"},"content":" notificationsLogic.deleteNotification(notification.getId());"},{"lineNumber":363,"author":{"gitId":"-"},"content":" });"},{"lineNumber":364,"author":{"gitId":"-"},"content":" dataBundle.accounts.values().forEach(account -\u003e {"},{"lineNumber":365,"author":{"gitId":"-"},"content":" accountsLogic.deleteAccount(account.getGoogleId());"},{"lineNumber":366,"author":{"gitId":"-"},"content":" });"},{"lineNumber":367,"author":{"gitId":"-"},"content":" dataBundle.accountRequests.values().forEach(accountRequest -\u003e {"},{"lineNumber":368,"author":{"gitId":"dishenggg"},"content":" accountRequestsLogic.deleteAccountRequest(accountRequest.getId());"},{"lineNumber":369,"author":{"gitId":"-"},"content":" });"},{"lineNumber":370,"author":{"gitId":"-"},"content":" }"},{"lineNumber":371,"author":{"gitId":"-"},"content":""},{"lineNumber":372,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":373,"author":{"gitId":"-"},"content":" * Creates document for entities that have document, i.e. searchable."},{"lineNumber":374,"author":{"gitId":"-"},"content":" */"},{"lineNumber":375,"author":{"gitId":"-"},"content":" public void putDocuments(SqlDataBundle dataBundle) throws SearchServiceException {"},{"lineNumber":376,"author":{"gitId":"-"},"content":" Map\u003cString, Student\u003e students \u003d dataBundle.students;"},{"lineNumber":377,"author":{"gitId":"-"},"content":" for (Student student : students.values()) {"},{"lineNumber":378,"author":{"gitId":"-"},"content":" usersLogic.putStudentDocument(student);"},{"lineNumber":379,"author":{"gitId":"-"},"content":" }"},{"lineNumber":380,"author":{"gitId":"-"},"content":""},{"lineNumber":381,"author":{"gitId":"-"},"content":" Map\u003cString, Instructor\u003e instructors \u003d dataBundle.instructors;"},{"lineNumber":382,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructors.values()) {"},{"lineNumber":383,"author":{"gitId":"-"},"content":" usersLogic.putInstructorDocument(instructor);"},{"lineNumber":384,"author":{"gitId":"-"},"content":" }"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"-"},"content":" Map\u003cString, AccountRequest\u003e accountRequests \u003d dataBundle.accountRequests;"},{"lineNumber":387,"author":{"gitId":"-"},"content":" for (AccountRequest accountRequest : accountRequests.values()) {"},{"lineNumber":388,"author":{"gitId":"-"},"content":" accountRequestsLogic.putDocument(accountRequest);"},{"lineNumber":389,"author":{"gitId":"-"},"content":" }"},{"lineNumber":390,"author":{"gitId":"-"},"content":" }"},{"lineNumber":391,"author":{"gitId":"-"},"content":""},{"lineNumber":392,"author":{"gitId":"yuanxi1"},"content":" private static void linkEntities(SqlDataBundle dataBundle) {"},{"lineNumber":393,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cAccount\u003e accounts \u003d dataBundle.accounts.values();"},{"lineNumber":394,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cCourse\u003e courses \u003d dataBundle.courses.values();"},{"lineNumber":395,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cSection\u003e sections \u003d dataBundle.sections.values();"},{"lineNumber":396,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cTeam\u003e teams \u003d dataBundle.teams.values();"},{"lineNumber":397,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cInstructor\u003e instructors \u003d dataBundle.instructors.values();"},{"lineNumber":398,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cStudent\u003e students \u003d dataBundle.students.values();"},{"lineNumber":399,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cFeedbackSession\u003e sessions \u003d dataBundle.feedbackSessions.values();"},{"lineNumber":400,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cFeedbackQuestion\u003e questions \u003d dataBundle.feedbackQuestions.values();"},{"lineNumber":401,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cFeedbackResponse\u003e responses \u003d dataBundle.feedbackResponses.values();"},{"lineNumber":402,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cFeedbackResponseComment\u003e responseComments \u003d dataBundle.feedbackResponseComments.values();"},{"lineNumber":403,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cDeadlineExtension\u003e deadlineExtensions \u003d dataBundle.deadlineExtensions.values();"},{"lineNumber":404,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cNotification\u003e notifications \u003d dataBundle.notifications.values();"},{"lineNumber":405,"author":{"gitId":"yuanxi1"},"content":" Collection\u003cReadNotification\u003e readNotifications \u003d dataBundle.readNotifications.values();"},{"lineNumber":406,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":407,"author":{"gitId":"yuanxi1"},"content":" // Mapping of IDs or placeholder IDs to actual entity"},{"lineNumber":408,"author":{"gitId":"yuanxi1"},"content":" Map\u003cString, Course\u003e coursesMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":409,"author":{"gitId":"yuanxi1"},"content":" Map\u003cUUID, Section\u003e sectionsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":410,"author":{"gitId":"yuanxi1"},"content":" Map\u003cUUID, Team\u003e teamsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":411,"author":{"gitId":"yuanxi1"},"content":" Map\u003cUUID, FeedbackSession\u003e sessionsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":412,"author":{"gitId":"yuanxi1"},"content":" Map\u003cUUID, FeedbackQuestion\u003e questionMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":413,"author":{"gitId":"yuanxi1"},"content":" Map\u003cUUID, FeedbackResponse\u003e responseMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":414,"author":{"gitId":"yuanxi1"},"content":" Map\u003cUUID, Account\u003e accountsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":415,"author":{"gitId":"yuanxi1"},"content":" Map\u003cUUID, User\u003e usersMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":416,"author":{"gitId":"yuanxi1"},"content":" Map\u003cUUID, Notification\u003e notificationsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":417,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":418,"author":{"gitId":"yuanxi1"},"content":" for (Course course : courses) {"},{"lineNumber":419,"author":{"gitId":"yuanxi1"},"content":" coursesMap.put(course.getId(), course);"},{"lineNumber":420,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":421,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":422,"author":{"gitId":"yuanxi1"},"content":" for (Section section : sections) {"},{"lineNumber":423,"author":{"gitId":"yuanxi1"},"content":" sectionsMap.put(section.getId(), section);"},{"lineNumber":424,"author":{"gitId":"yuanxi1"},"content":" Course course \u003d coursesMap.get(section.getCourse().getId());"},{"lineNumber":425,"author":{"gitId":"yuanxi1"},"content":" section.setCourse(course);"},{"lineNumber":426,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":427,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":428,"author":{"gitId":"yuanxi1"},"content":" for (Team team : teams) {"},{"lineNumber":429,"author":{"gitId":"yuanxi1"},"content":" teamsMap.put(team.getId(), team);"},{"lineNumber":430,"author":{"gitId":"yuanxi1"},"content":" Section section \u003d sectionsMap.get(team.getSection().getId());"},{"lineNumber":431,"author":{"gitId":"yuanxi1"},"content":" team.setSection(section);"},{"lineNumber":432,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":433,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":434,"author":{"gitId":"yuanxi1"},"content":" for (FeedbackSession session : sessions) {"},{"lineNumber":435,"author":{"gitId":"yuanxi1"},"content":" sessionsMap.put(session.getId(), session);"},{"lineNumber":436,"author":{"gitId":"yuanxi1"},"content":" Course course \u003d coursesMap.get(session.getCourse().getId());"},{"lineNumber":437,"author":{"gitId":"yuanxi1"},"content":" session.setCourse(course);"},{"lineNumber":438,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":439,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":440,"author":{"gitId":"yuanxi1"},"content":" for (FeedbackQuestion question : questions) {"},{"lineNumber":441,"author":{"gitId":"yuanxi1"},"content":" questionMap.put(question.getId(), question);"},{"lineNumber":442,"author":{"gitId":"yuanxi1"},"content":" FeedbackSession fs \u003d sessionsMap.get(question.getFeedbackSession().getId());"},{"lineNumber":443,"author":{"gitId":"yuanxi1"},"content":" question.setFeedbackSession(fs);"},{"lineNumber":444,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":445,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":446,"author":{"gitId":"yuanxi1"},"content":" for (FeedbackResponse response : responses) {"},{"lineNumber":447,"author":{"gitId":"yuanxi1"},"content":" UUID placeholderId \u003d response.getId();"},{"lineNumber":448,"author":{"gitId":"yuanxi1"},"content":" responseMap.put(placeholderId, response);"},{"lineNumber":449,"author":{"gitId":"yuanxi1"},"content":" FeedbackQuestion fq \u003d questionMap.get(response.getFeedbackQuestion().getId());"},{"lineNumber":450,"author":{"gitId":"yuanxi1"},"content":" Section giverSection \u003d sectionsMap.get(response.getGiverSection().getId());"},{"lineNumber":451,"author":{"gitId":"yuanxi1"},"content":" Section recipientSection \u003d response.getRecipientSection() !\u003d null"},{"lineNumber":452,"author":{"gitId":"yuanxi1"},"content":" ? sectionsMap.get(response.getRecipientSection().getId()) : null;"},{"lineNumber":453,"author":{"gitId":"yuanxi1"},"content":" response.setFeedbackQuestion(fq);"},{"lineNumber":454,"author":{"gitId":"yuanxi1"},"content":" response.setGiverSection(giverSection);"},{"lineNumber":455,"author":{"gitId":"yuanxi1"},"content":" response.setRecipientSection(recipientSection);"},{"lineNumber":456,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":457,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":458,"author":{"gitId":"yuanxi1"},"content":" for (FeedbackResponseComment responseComment : responseComments) {"},{"lineNumber":459,"author":{"gitId":"yuanxi1"},"content":" FeedbackResponse fr \u003d responseMap.get(responseComment.getFeedbackResponse().getId());"},{"lineNumber":460,"author":{"gitId":"yuanxi1"},"content":" Section giverSection \u003d sectionsMap.get(responseComment.getGiverSection().getId());"},{"lineNumber":461,"author":{"gitId":"yuanxi1"},"content":" Section recipientSection \u003d sectionsMap.get(responseComment.getRecipientSection().getId());"},{"lineNumber":462,"author":{"gitId":"yuanxi1"},"content":" responseComment.setFeedbackResponse(fr);"},{"lineNumber":463,"author":{"gitId":"yuanxi1"},"content":" responseComment.setGiverSection(giverSection);"},{"lineNumber":464,"author":{"gitId":"yuanxi1"},"content":" responseComment.setRecipientSection(recipientSection);"},{"lineNumber":465,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":466,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":467,"author":{"gitId":"yuanxi1"},"content":" for (Account account : accounts) {"},{"lineNumber":468,"author":{"gitId":"yuanxi1"},"content":" accountsMap.put(account.getId(), account);"},{"lineNumber":469,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":470,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":471,"author":{"gitId":"yuanxi1"},"content":" for (Instructor instructor : instructors) {"},{"lineNumber":472,"author":{"gitId":"yuanxi1"},"content":" usersMap.put(instructor.getId(), instructor);"},{"lineNumber":473,"author":{"gitId":"yuanxi1"},"content":" Course course \u003d coursesMap.get(instructor.getCourse().getId());"},{"lineNumber":474,"author":{"gitId":"yuanxi1"},"content":" instructor.setCourse(course);"},{"lineNumber":475,"author":{"gitId":"yuanxi1"},"content":" if (instructor.getAccount() !\u003d null) {"},{"lineNumber":476,"author":{"gitId":"yuanxi1"},"content":" Account account \u003d accountsMap.get(instructor.getAccount().getId());"},{"lineNumber":477,"author":{"gitId":"yuanxi1"},"content":" instructor.setAccount(account);"},{"lineNumber":478,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":479,"author":{"gitId":"yuanxi1"},"content":" instructor.generateNewRegistrationKey();"},{"lineNumber":480,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":481,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":482,"author":{"gitId":"yuanxi1"},"content":" for (Student student : students) {"},{"lineNumber":483,"author":{"gitId":"yuanxi1"},"content":" usersMap.put(student.getId(), student);"},{"lineNumber":484,"author":{"gitId":"yuanxi1"},"content":" Course course \u003d coursesMap.get(student.getCourse().getId());"},{"lineNumber":485,"author":{"gitId":"yuanxi1"},"content":" student.setCourse(course);"},{"lineNumber":486,"author":{"gitId":"yuanxi1"},"content":" Team team \u003d teamsMap.get(student.getTeam().getId());"},{"lineNumber":487,"author":{"gitId":"yuanxi1"},"content":" student.setTeam(team);"},{"lineNumber":488,"author":{"gitId":"yuanxi1"},"content":" if (student.getAccount() !\u003d null) {"},{"lineNumber":489,"author":{"gitId":"yuanxi1"},"content":" Account account \u003d accountsMap.get(student.getAccount().getId());"},{"lineNumber":490,"author":{"gitId":"yuanxi1"},"content":" student.setAccount(account);"},{"lineNumber":491,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":492,"author":{"gitId":"yuanxi1"},"content":" student.generateNewRegistrationKey();"},{"lineNumber":493,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":494,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":495,"author":{"gitId":"yuanxi1"},"content":" for (Notification notification : notifications) {"},{"lineNumber":496,"author":{"gitId":"yuanxi1"},"content":" notificationsMap.put(notification.getId(), notification);"},{"lineNumber":497,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":498,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":499,"author":{"gitId":"yuanxi1"},"content":" for (ReadNotification readNotification : readNotifications) {"},{"lineNumber":500,"author":{"gitId":"yuanxi1"},"content":" Account account \u003d accountsMap.get(readNotification.getAccount().getId());"},{"lineNumber":501,"author":{"gitId":"yuanxi1"},"content":" readNotification.setAccount(account);"},{"lineNumber":502,"author":{"gitId":"yuanxi1"},"content":" Notification notification \u003d notificationsMap.get(readNotification.getNotification().getId());"},{"lineNumber":503,"author":{"gitId":"yuanxi1"},"content":" readNotification.setNotification(notification);"},{"lineNumber":504,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":505,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":506,"author":{"gitId":"yuanxi1"},"content":" for (DeadlineExtension deadlineExtension : deadlineExtensions) {"},{"lineNumber":507,"author":{"gitId":"yuanxi1"},"content":" FeedbackSession session \u003d sessionsMap.get(deadlineExtension.getFeedbackSession().getId());"},{"lineNumber":508,"author":{"gitId":"yuanxi1"},"content":" deadlineExtension.setFeedbackSession(session);"},{"lineNumber":509,"author":{"gitId":"yuanxi1"},"content":" User user \u003d usersMap.get(deadlineExtension.getUser().getId());"},{"lineNumber":510,"author":{"gitId":"yuanxi1"},"content":" deadlineExtension.setUser(user);"},{"lineNumber":511,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":512,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":513,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"yuanxi1":124,"dishenggg":20,"-":369}},{"path":"src/main/java/teammates/sqllogic/core/FeedbackQuestionsLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Collections;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.HashSet;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.Set;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackQuestionRecipient;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlCourseRoster;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackMcqQuestionDetails;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackMsqQuestionDetails;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionDetails;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionType;"},{"lineNumber":22,"author":{"gitId":"marquestye"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackQuestionsDb;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackMcqQuestion;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackMsqQuestion;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.ui.request.FeedbackQuestionUpdateRequest;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":37,"author":{"gitId":"-"},"content":" * Handles operations related to feedback questions."},{"lineNumber":38,"author":{"gitId":"-"},"content":" *"},{"lineNumber":39,"author":{"gitId":"-"},"content":" * @see FeedbackQuestion"},{"lineNumber":40,"author":{"gitId":"-"},"content":" * @see FeedbackQuestionsDb"},{"lineNumber":41,"author":{"gitId":"-"},"content":" */"},{"lineNumber":42,"author":{"gitId":"-"},"content":"public final class FeedbackQuestionsLogic {"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" static final String USER_NAME_FOR_SELF \u003d \"Myself\";"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" private static final FeedbackQuestionsLogic instance \u003d new FeedbackQuestionsLogic();"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private FeedbackQuestionsDb fqDb;"},{"lineNumber":50,"author":{"gitId":"-"},"content":" private CoursesLogic coursesLogic;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" private FeedbackResponsesLogic frLogic;"},{"lineNumber":52,"author":{"gitId":"-"},"content":" private UsersLogic usersLogic;"},{"lineNumber":53,"author":{"gitId":"-"},"content":" private FeedbackSessionsLogic feedbackSessionsLogic;"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" private FeedbackQuestionsLogic() {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" public static FeedbackQuestionsLogic inst() {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" void initLogicDependencies(FeedbackQuestionsDb fqDb, CoursesLogic coursesLogic, FeedbackResponsesLogic frLogic,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" UsersLogic usersLogic, FeedbackSessionsLogic feedbackSessionsLogic) {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" this.fqDb \u003d fqDb;"},{"lineNumber":66,"author":{"gitId":"-"},"content":" this.coursesLogic \u003d coursesLogic;"},{"lineNumber":67,"author":{"gitId":"-"},"content":" this.frLogic \u003d frLogic;"},{"lineNumber":68,"author":{"gitId":"-"},"content":" this.usersLogic \u003d usersLogic;"},{"lineNumber":69,"author":{"gitId":"-"},"content":" this.feedbackSessionsLogic \u003d feedbackSessionsLogic;"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":73,"author":{"gitId":"-"},"content":" * Creates a new feedback question."},{"lineNumber":74,"author":{"gitId":"-"},"content":" *"},{"lineNumber":75,"author":{"gitId":"-"},"content":" * @return the created question"},{"lineNumber":76,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the question is invalid"},{"lineNumber":77,"author":{"gitId":"marquestye"},"content":" * @throws EntityAlreadyExistsException if the question already exists"},{"lineNumber":78,"author":{"gitId":"-"},"content":" */"},{"lineNumber":79,"author":{"gitId":"marquestye"},"content":" public FeedbackQuestion createFeedbackQuestion(FeedbackQuestion feedbackQuestion)"},{"lineNumber":80,"author":{"gitId":"marquestye"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":81,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion createdQuestion \u003d fqDb.createFeedbackQuestion(feedbackQuestion);"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsBefore \u003d getFeedbackQuestionsForSession(feedbackQuestion.getFeedbackSession());"},{"lineNumber":84,"author":{"gitId":"marquestye"},"content":" questionsBefore.remove(createdQuestion);"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" adjustQuestionNumbers(questionsBefore.size() + 1, createdQuestion.getQuestionNumber(), questionsBefore);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" return createdQuestion;"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":91,"author":{"gitId":"-"},"content":" * Gets an feedback question by feedback question id."},{"lineNumber":92,"author":{"gitId":"-"},"content":" * @param id of feedback question."},{"lineNumber":93,"author":{"gitId":"-"},"content":" * @return the specified feedback question."},{"lineNumber":94,"author":{"gitId":"-"},"content":" */"},{"lineNumber":95,"author":{"gitId":"-"},"content":" public FeedbackQuestion getFeedbackQuestion(UUID id) {"},{"lineNumber":96,"author":{"gitId":"-"},"content":" return fqDb.getFeedbackQuestion(id);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" }"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":100,"author":{"gitId":"-"},"content":" * Gets a {@link List} of every FeedbackQuestion in the given session."},{"lineNumber":101,"author":{"gitId":"-"},"content":" */"},{"lineNumber":102,"author":{"gitId":"-"},"content":" public List\u003cFeedbackQuestion\u003e getFeedbackQuestionsForSession(FeedbackSession feedbackSession) {"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questions \u003d fqDb.getFeedbackQuestionsForSession(feedbackSession.getId());"},{"lineNumber":105,"author":{"gitId":"-"},"content":" questions.sort(null);"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" // check whether the question numbers are consistent"},{"lineNumber":108,"author":{"gitId":"-"},"content":" if (questions.size() \u003e 1 \u0026\u0026 !areQuestionNumbersConsistent(questions)) {"},{"lineNumber":109,"author":{"gitId":"-"},"content":" log.severe(feedbackSession.getCourse().getId() + \": \" + feedbackSession.getName()"},{"lineNumber":110,"author":{"gitId":"-"},"content":" + \" has invalid question numbers\");"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" return questions;"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":117,"author":{"gitId":"-"},"content":" * Checks if there are any questions for the given session that instructors can view/submit."},{"lineNumber":118,"author":{"gitId":"-"},"content":" */"},{"lineNumber":119,"author":{"gitId":"-"},"content":" public boolean hasFeedbackQuestionsForInstructors(List\u003cFeedbackQuestion\u003e fqs, boolean isCreator) {"},{"lineNumber":120,"author":{"gitId":"-"},"content":" boolean hasQuestions \u003d hasFeedbackQuestionsForGiverType(fqs, FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" if (hasQuestions) {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":123,"author":{"gitId":"-"},"content":" }"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" if (isCreator) {"},{"lineNumber":126,"author":{"gitId":"-"},"content":" hasQuestions \u003d hasFeedbackQuestionsForGiverType(fqs, FeedbackParticipantType.SELF);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" return hasQuestions;"},{"lineNumber":130,"author":{"gitId":"-"},"content":" }"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":133,"author":{"gitId":"-"},"content":" * Gets a {@code List} of all questions for the given session that instructors can view/submit."},{"lineNumber":134,"author":{"gitId":"-"},"content":" */"},{"lineNumber":135,"author":{"gitId":"-"},"content":" public List\u003cFeedbackQuestion\u003e getFeedbackQuestionsForInstructors("},{"lineNumber":136,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession, String userEmail) {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" questions.addAll("},{"lineNumber":140,"author":{"gitId":"-"},"content":" fqDb.getFeedbackQuestionsForGiverType("},{"lineNumber":141,"author":{"gitId":"-"},"content":" feedbackSession, FeedbackParticipantType.INSTRUCTORS));"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" if (feedbackSession.getCreatorEmail().equals(userEmail)) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" questions.addAll("},{"lineNumber":145,"author":{"gitId":"-"},"content":" fqDb.getFeedbackQuestionsForGiverType("},{"lineNumber":146,"author":{"gitId":"-"},"content":" feedbackSession, FeedbackParticipantType.SELF));"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" return questions;"},{"lineNumber":150,"author":{"gitId":"-"},"content":" }"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":153,"author":{"gitId":"-"},"content":" * Gets a {@code List} of all questions for the given session that students can view/submit."},{"lineNumber":154,"author":{"gitId":"-"},"content":" */"},{"lineNumber":155,"author":{"gitId":"-"},"content":" public List\u003cFeedbackQuestion\u003e getFeedbackQuestionsForStudents(FeedbackSession feedbackSession) {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"-"},"content":" questions.addAll(fqDb.getFeedbackQuestionsForGiverType(feedbackSession, FeedbackParticipantType.STUDENTS));"},{"lineNumber":159,"author":{"gitId":"-"},"content":" questions.addAll(fqDb.getFeedbackQuestionsForGiverType(feedbackSession, FeedbackParticipantType.SELF));"},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":" questions.sort(null);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" return questions;"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":165,"author":{"gitId":"-"},"content":" * Updates a feedback question."},{"lineNumber":166,"author":{"gitId":"-"},"content":" *"},{"lineNumber":167,"author":{"gitId":"-"},"content":" * \u003cp\u003eCascade adjust the question number of questions in the same session."},{"lineNumber":168,"author":{"gitId":"-"},"content":" *"},{"lineNumber":169,"author":{"gitId":"-"},"content":" * \u003cp\u003eCascade adjust the existing response of the question."},{"lineNumber":170,"author":{"gitId":"-"},"content":" *"},{"lineNumber":171,"author":{"gitId":"-"},"content":" * @return updated feedback question"},{"lineNumber":172,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":173,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the feedback question cannot be found"},{"lineNumber":174,"author":{"gitId":"-"},"content":" */"},{"lineNumber":175,"author":{"gitId":"-"},"content":" public FeedbackQuestion updateFeedbackQuestionCascade(UUID questionId, FeedbackQuestionUpdateRequest updateRequest)"},{"lineNumber":176,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" FeedbackQuestion question \u003d fqDb.getFeedbackQuestion(questionId);"},{"lineNumber":178,"author":{"gitId":"-"},"content":" if (question \u003d\u003d null) {"},{"lineNumber":179,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Trying to update a feedback question that does not exist.\");"},{"lineNumber":180,"author":{"gitId":"-"},"content":" }"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" int oldQuestionNumber \u003d question.getQuestionNumber();"},{"lineNumber":183,"author":{"gitId":"-"},"content":" int newQuestionNumber \u003d updateRequest.getQuestionNumber();"},{"lineNumber":184,"author":{"gitId":"-"},"content":""},{"lineNumber":185,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e previousQuestionsInSession \u003d new ArrayList\u003c\u003e();"},{"lineNumber":186,"author":{"gitId":"-"},"content":" if (oldQuestionNumber !\u003d newQuestionNumber) {"},{"lineNumber":187,"author":{"gitId":"-"},"content":" // get questions in session before update"},{"lineNumber":188,"author":{"gitId":"-"},"content":" previousQuestionsInSession \u003d getFeedbackQuestionsForSession(question.getFeedbackSession());"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" // update question"},{"lineNumber":192,"author":{"gitId":"-"},"content":" question.setQuestionNumber(updateRequest.getQuestionNumber());"},{"lineNumber":193,"author":{"gitId":"-"},"content":" question.setDescription(updateRequest.getQuestionDescription());"},{"lineNumber":194,"author":{"gitId":"-"},"content":" question.setQuestionDetails(updateRequest.getQuestionDetails());"},{"lineNumber":195,"author":{"gitId":"-"},"content":" question.setGiverType(updateRequest.getGiverType());"},{"lineNumber":196,"author":{"gitId":"-"},"content":" question.setRecipientType(updateRequest.getRecipientType());"},{"lineNumber":197,"author":{"gitId":"-"},"content":" question.setNumOfEntitiesToGiveFeedbackTo(updateRequest.getNumberOfEntitiesToGiveFeedbackTo());"},{"lineNumber":198,"author":{"gitId":"-"},"content":" question.setShowResponsesTo(updateRequest.getShowResponsesTo());"},{"lineNumber":199,"author":{"gitId":"-"},"content":" question.setShowGiverNameTo(updateRequest.getShowGiverNameTo());"},{"lineNumber":200,"author":{"gitId":"-"},"content":" question.setShowRecipientNameTo(updateRequest.getShowRecipientNameTo());"},{"lineNumber":201,"author":{"gitId":"-"},"content":""},{"lineNumber":202,"author":{"gitId":"-"},"content":" // validate questions (giver \u0026 recipient)"},{"lineNumber":203,"author":{"gitId":"-"},"content":" String err \u003d question.getQuestionDetailsCopy().validateGiverRecipientVisibility(question);"},{"lineNumber":204,"author":{"gitId":"-"},"content":" if (!err.isEmpty()) {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(err);"},{"lineNumber":206,"author":{"gitId":"-"},"content":" }"},{"lineNumber":207,"author":{"gitId":"-"},"content":" // validate questions (question details)"},{"lineNumber":208,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails questionDetails \u003d question.getQuestionDetailsCopy();"},{"lineNumber":209,"author":{"gitId":"-"},"content":" List\u003cString\u003e questionDetailsErrors \u003d questionDetails.validateQuestionDetails();"},{"lineNumber":210,"author":{"gitId":"-"},"content":""},{"lineNumber":211,"author":{"gitId":"-"},"content":" if (!questionDetailsErrors.isEmpty()) {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(questionDetailsErrors.toString());"},{"lineNumber":213,"author":{"gitId":"-"},"content":" }"},{"lineNumber":214,"author":{"gitId":"-"},"content":""},{"lineNumber":215,"author":{"gitId":"-"},"content":" if (oldQuestionNumber !\u003d newQuestionNumber) {"},{"lineNumber":216,"author":{"gitId":"-"},"content":" // shift other feedback questions (generate an empty \"slot\")"},{"lineNumber":217,"author":{"gitId":"-"},"content":" adjustQuestionNumbers(oldQuestionNumber, newQuestionNumber, previousQuestionsInSession);"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" // adjust responses"},{"lineNumber":221,"author":{"gitId":"-"},"content":" if (question.areResponseDeletionsRequiredForChanges(updateRequest.getGiverType(),"},{"lineNumber":222,"author":{"gitId":"-"},"content":" updateRequest.getRecipientType(), updateRequest.getQuestionDetails())) {"},{"lineNumber":223,"author":{"gitId":"-"},"content":" frLogic.deleteFeedbackResponsesForQuestionCascade(question.getId());"},{"lineNumber":224,"author":{"gitId":"-"},"content":" }"},{"lineNumber":225,"author":{"gitId":"-"},"content":""},{"lineNumber":226,"author":{"gitId":"-"},"content":" return question;"},{"lineNumber":227,"author":{"gitId":"-"},"content":" }"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":230,"author":{"gitId":"-"},"content":" * Checks if there are any questions for the given session that students can view/submit."},{"lineNumber":231,"author":{"gitId":"-"},"content":" */"},{"lineNumber":232,"author":{"gitId":"-"},"content":" public boolean hasFeedbackQuestionsForStudents(List\u003cFeedbackQuestion\u003e fqs) {"},{"lineNumber":233,"author":{"gitId":"-"},"content":" return hasFeedbackQuestionsForGiverType(fqs, FeedbackParticipantType.STUDENTS)"},{"lineNumber":234,"author":{"gitId":"-"},"content":" || hasFeedbackQuestionsForGiverType(fqs, FeedbackParticipantType.TEAMS);"},{"lineNumber":235,"author":{"gitId":"-"},"content":" }"},{"lineNumber":236,"author":{"gitId":"-"},"content":""},{"lineNumber":237,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":238,"author":{"gitId":"-"},"content":" * Checks if there is any feedback questions in a session in a course for the given giver type."},{"lineNumber":239,"author":{"gitId":"-"},"content":" */"},{"lineNumber":240,"author":{"gitId":"-"},"content":" public boolean hasFeedbackQuestionsForGiverType("},{"lineNumber":241,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e feedbackQuestions, FeedbackParticipantType giverType) {"},{"lineNumber":242,"author":{"gitId":"-"},"content":" assert feedbackQuestions !\u003d null;"},{"lineNumber":243,"author":{"gitId":"-"},"content":" assert giverType !\u003d null;"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":" for (FeedbackQuestion fq : feedbackQuestions) {"},{"lineNumber":246,"author":{"gitId":"-"},"content":" if (fq.getGiverType() \u003d\u003d giverType) {"},{"lineNumber":247,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":248,"author":{"gitId":"-"},"content":" }"},{"lineNumber":249,"author":{"gitId":"-"},"content":" }"},{"lineNumber":250,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":251,"author":{"gitId":"-"},"content":" }"},{"lineNumber":252,"author":{"gitId":"-"},"content":""},{"lineNumber":253,"author":{"gitId":"-"},"content":" // TODO can be removed once we are sure that question numbers will be consistent"},{"lineNumber":254,"author":{"gitId":"-"},"content":" private boolean areQuestionNumbersConsistent(List\u003cFeedbackQuestion\u003e questions) {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" Set\u003cInteger\u003e questionNumbersInSession \u003d new HashSet\u003c\u003e();"},{"lineNumber":256,"author":{"gitId":"-"},"content":" for (FeedbackQuestion question : questions) {"},{"lineNumber":257,"author":{"gitId":"-"},"content":" if (!questionNumbersInSession.add(question.getQuestionNumber())) {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":259,"author":{"gitId":"-"},"content":" }"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":""},{"lineNumber":262,"author":{"gitId":"-"},"content":" for (int i \u003d 1; i \u003c\u003d questions.size(); i++) {"},{"lineNumber":263,"author":{"gitId":"-"},"content":" if (!questionNumbersInSession.contains(i)) {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":265,"author":{"gitId":"-"},"content":" }"},{"lineNumber":266,"author":{"gitId":"-"},"content":" }"},{"lineNumber":267,"author":{"gitId":"-"},"content":""},{"lineNumber":268,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":269,"author":{"gitId":"-"},"content":" }"},{"lineNumber":270,"author":{"gitId":"-"},"content":""},{"lineNumber":271,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":272,"author":{"gitId":"-"},"content":" * Adjust questions between the old and new number,"},{"lineNumber":273,"author":{"gitId":"-"},"content":" * if the new number is smaller, then shift up (increase qn#) all questions in between."},{"lineNumber":274,"author":{"gitId":"-"},"content":" * if the new number is bigger, then shift down(decrease qn#) all questions in between."},{"lineNumber":275,"author":{"gitId":"-"},"content":" */"},{"lineNumber":276,"author":{"gitId":"-"},"content":" private void adjustQuestionNumbers(int oldQuestionNumber, int newQuestionNumber, List\u003cFeedbackQuestion\u003e questions) {"},{"lineNumber":277,"author":{"gitId":"-"},"content":" if (oldQuestionNumber \u003e newQuestionNumber \u0026\u0026 oldQuestionNumber \u003e\u003d 1) {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" for (int i \u003d oldQuestionNumber - 1; i \u003e\u003d newQuestionNumber; i--) {"},{"lineNumber":279,"author":{"gitId":"-"},"content":" FeedbackQuestion question \u003d questions.get(i - 1);"},{"lineNumber":280,"author":{"gitId":"-"},"content":" question.setQuestionNumber(question.getQuestionNumber() + 1);"},{"lineNumber":281,"author":{"gitId":"-"},"content":" }"},{"lineNumber":282,"author":{"gitId":"-"},"content":" } else if (oldQuestionNumber \u003c newQuestionNumber \u0026\u0026 oldQuestionNumber \u003c questions.size()) {"},{"lineNumber":283,"author":{"gitId":"-"},"content":" for (int i \u003d oldQuestionNumber + 1; i \u003c\u003d newQuestionNumber; i++) {"},{"lineNumber":284,"author":{"gitId":"-"},"content":" FeedbackQuestion question \u003d questions.get(i - 1);"},{"lineNumber":285,"author":{"gitId":"-"},"content":" question.setQuestionNumber(question.getQuestionNumber() - 1);"},{"lineNumber":286,"author":{"gitId":"-"},"content":" }"},{"lineNumber":287,"author":{"gitId":"-"},"content":" }"},{"lineNumber":288,"author":{"gitId":"-"},"content":" }"},{"lineNumber":289,"author":{"gitId":"-"},"content":""},{"lineNumber":290,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":291,"author":{"gitId":"-"},"content":" * Populates fields that need dynamic generation in a question."},{"lineNumber":292,"author":{"gitId":"-"},"content":" *"},{"lineNumber":293,"author":{"gitId":"-"},"content":" * \u003cp\u003eCurrently, only MCQ/MSQ needs to generate choices dynamically.\u003c/p\u003e"},{"lineNumber":294,"author":{"gitId":"-"},"content":" *"},{"lineNumber":295,"author":{"gitId":"-"},"content":" * @param feedbackQuestion the question to populate"},{"lineNumber":296,"author":{"gitId":"-"},"content":" * @param courseId the ID of the course"},{"lineNumber":297,"author":{"gitId":"-"},"content":" * @param emailOfEntityDoingQuestion the email of the entity doing the question"},{"lineNumber":298,"author":{"gitId":"-"},"content":" * @param teamOfEntityDoingQuestion the team of the entity doing the question. If the entity is an instructor,"},{"lineNumber":299,"author":{"gitId":"-"},"content":" * it can be {@code null}."},{"lineNumber":300,"author":{"gitId":"-"},"content":" */"},{"lineNumber":301,"author":{"gitId":"-"},"content":" public void populateFieldsToGenerateInQuestion(FeedbackQuestion feedbackQuestion,"},{"lineNumber":302,"author":{"gitId":"-"},"content":" String courseId, String emailOfEntityDoingQuestion, String teamOfEntityDoingQuestion) {"},{"lineNumber":303,"author":{"gitId":"-"},"content":" List\u003cString\u003e optionList;"},{"lineNumber":304,"author":{"gitId":"-"},"content":""},{"lineNumber":305,"author":{"gitId":"-"},"content":" FeedbackParticipantType generateOptionsFor;"},{"lineNumber":306,"author":{"gitId":"-"},"content":" FeedbackQuestionType questionType \u003d feedbackQuestion.getQuestionDetailsCopy().getQuestionType();"},{"lineNumber":307,"author":{"gitId":"-"},"content":""},{"lineNumber":308,"author":{"gitId":"-"},"content":" if (questionType \u003d\u003d FeedbackQuestionType.MCQ) {"},{"lineNumber":309,"author":{"gitId":"-"},"content":" FeedbackMcqQuestionDetails feedbackMcqQuestionDetails \u003d"},{"lineNumber":310,"author":{"gitId":"-"},"content":" (FeedbackMcqQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":311,"author":{"gitId":"-"},"content":" optionList \u003d feedbackMcqQuestionDetails.getMcqChoices();"},{"lineNumber":312,"author":{"gitId":"-"},"content":" generateOptionsFor \u003d feedbackMcqQuestionDetails.getGenerateOptionsFor();"},{"lineNumber":313,"author":{"gitId":"-"},"content":" } else if (questionType \u003d\u003d FeedbackQuestionType.MSQ) {"},{"lineNumber":314,"author":{"gitId":"-"},"content":" FeedbackMsqQuestionDetails feedbackMsqQuestionDetails \u003d"},{"lineNumber":315,"author":{"gitId":"-"},"content":" (FeedbackMsqQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":316,"author":{"gitId":"-"},"content":" optionList \u003d feedbackMsqQuestionDetails.getMsqChoices();"},{"lineNumber":317,"author":{"gitId":"-"},"content":" generateOptionsFor \u003d feedbackMsqQuestionDetails.getGenerateOptionsFor();"},{"lineNumber":318,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":319,"author":{"gitId":"-"},"content":" // other question types"},{"lineNumber":320,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":321,"author":{"gitId":"-"},"content":" }"},{"lineNumber":322,"author":{"gitId":"-"},"content":""},{"lineNumber":323,"author":{"gitId":"-"},"content":" switch (generateOptionsFor) {"},{"lineNumber":324,"author":{"gitId":"-"},"content":" case NONE:"},{"lineNumber":325,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":326,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":327,"author":{"gitId":"-"},"content":" case STUDENTS_IN_SAME_SECTION:"},{"lineNumber":328,"author":{"gitId":"-"},"content":" case STUDENTS_EXCLUDING_SELF:"},{"lineNumber":329,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e studentList;"},{"lineNumber":330,"author":{"gitId":"-"},"content":" if (generateOptionsFor \u003d\u003d FeedbackParticipantType.STUDENTS_IN_SAME_SECTION) {"},{"lineNumber":331,"author":{"gitId":"-"},"content":" Student student \u003d"},{"lineNumber":332,"author":{"gitId":"-"},"content":" usersLogic.getStudentForEmail(courseId, emailOfEntityDoingQuestion);"},{"lineNumber":333,"author":{"gitId":"-"},"content":" studentList \u003d usersLogic.getStudentsForSection(student.getSectionName(), courseId);"},{"lineNumber":334,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":335,"author":{"gitId":"-"},"content":" studentList \u003d usersLogic.getStudentsForCourse(courseId);"},{"lineNumber":336,"author":{"gitId":"-"},"content":" }"},{"lineNumber":337,"author":{"gitId":"-"},"content":""},{"lineNumber":338,"author":{"gitId":"-"},"content":" if (generateOptionsFor \u003d\u003d FeedbackParticipantType.STUDENTS_EXCLUDING_SELF) {"},{"lineNumber":339,"author":{"gitId":"-"},"content":" studentList.removeIf(studentInList -\u003e studentInList.getEmail().equals(emailOfEntityDoingQuestion));"},{"lineNumber":340,"author":{"gitId":"-"},"content":" }"},{"lineNumber":341,"author":{"gitId":"-"},"content":""},{"lineNumber":342,"author":{"gitId":"-"},"content":" for (Student student : studentList) {"},{"lineNumber":343,"author":{"gitId":"dishenggg"},"content":" optionList.add(student.getName() + \" (\" + student.getTeam().getName() + \")\");"},{"lineNumber":344,"author":{"gitId":"-"},"content":" }"},{"lineNumber":345,"author":{"gitId":"-"},"content":""},{"lineNumber":346,"author":{"gitId":"-"},"content":" optionList.sort(null);"},{"lineNumber":347,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":348,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":349,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":350,"author":{"gitId":"-"},"content":" case TEAMS_EXCLUDING_SELF:"},{"lineNumber":351,"author":{"gitId":"-"},"content":" List\u003cString\u003e teams;"},{"lineNumber":352,"author":{"gitId":"-"},"content":" if (generateOptionsFor \u003d\u003d FeedbackParticipantType.TEAMS_IN_SAME_SECTION) {"},{"lineNumber":353,"author":{"gitId":"-"},"content":" Student student \u003d"},{"lineNumber":354,"author":{"gitId":"-"},"content":" usersLogic.getStudentForEmail(courseId, emailOfEntityDoingQuestion);"},{"lineNumber":355,"author":{"gitId":"-"},"content":" teams \u003d coursesLogic.getTeamsForSection(student.getSection())"},{"lineNumber":356,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":357,"author":{"gitId":"-"},"content":" .map(team -\u003e { return team.getName(); })"},{"lineNumber":358,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":359,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":360,"author":{"gitId":"-"},"content":" teams \u003d coursesLogic.getTeamsForCourse(courseId)"},{"lineNumber":361,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":362,"author":{"gitId":"-"},"content":" .map(team -\u003e { return team.getName(); })"},{"lineNumber":363,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":364,"author":{"gitId":"-"},"content":" }"},{"lineNumber":365,"author":{"gitId":"-"},"content":""},{"lineNumber":366,"author":{"gitId":"-"},"content":" if (generateOptionsFor \u003d\u003d FeedbackParticipantType.TEAMS_EXCLUDING_SELF) {"},{"lineNumber":367,"author":{"gitId":"-"},"content":" teams.removeIf(team -\u003e team.equals(teamOfEntityDoingQuestion));"},{"lineNumber":368,"author":{"gitId":"-"},"content":" }"},{"lineNumber":369,"author":{"gitId":"-"},"content":""},{"lineNumber":370,"author":{"gitId":"-"},"content":" for (String team : teams) {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" optionList.add(team);"},{"lineNumber":372,"author":{"gitId":"-"},"content":" }"},{"lineNumber":373,"author":{"gitId":"-"},"content":""},{"lineNumber":374,"author":{"gitId":"-"},"content":" optionList.sort(null);"},{"lineNumber":375,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":376,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS_INCLUDING_SELF:"},{"lineNumber":377,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":378,"author":{"gitId":"-"},"content":" if (teamOfEntityDoingQuestion !\u003d null) {"},{"lineNumber":379,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e teamMembers \u003d usersLogic.getStudentsForTeam(teamOfEntityDoingQuestion,"},{"lineNumber":380,"author":{"gitId":"-"},"content":" courseId);"},{"lineNumber":381,"author":{"gitId":"-"},"content":""},{"lineNumber":382,"author":{"gitId":"-"},"content":" if (generateOptionsFor \u003d\u003d FeedbackParticipantType.OWN_TEAM_MEMBERS) {"},{"lineNumber":383,"author":{"gitId":"-"},"content":" teamMembers.removeIf(teamMember -\u003e teamMember.getEmail().equals(emailOfEntityDoingQuestion));"},{"lineNumber":384,"author":{"gitId":"-"},"content":" }"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"-"},"content":" teamMembers.forEach(teamMember -\u003e optionList.add(teamMember.getName()));"},{"lineNumber":387,"author":{"gitId":"-"},"content":""},{"lineNumber":388,"author":{"gitId":"-"},"content":" optionList.sort(null);"},{"lineNumber":389,"author":{"gitId":"-"},"content":" }"},{"lineNumber":390,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":391,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":392,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorList \u003d"},{"lineNumber":393,"author":{"gitId":"-"},"content":" usersLogic.getInstructorsForCourse(courseId);"},{"lineNumber":394,"author":{"gitId":"-"},"content":""},{"lineNumber":395,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructorList) {"},{"lineNumber":396,"author":{"gitId":"-"},"content":" optionList.add(instructor.getName());"},{"lineNumber":397,"author":{"gitId":"-"},"content":" }"},{"lineNumber":398,"author":{"gitId":"-"},"content":""},{"lineNumber":399,"author":{"gitId":"-"},"content":" optionList.sort(null);"},{"lineNumber":400,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":401,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":402,"author":{"gitId":"-"},"content":" assert false : \"Trying to generate options for neither students, teams nor instructors\";"},{"lineNumber":403,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":404,"author":{"gitId":"-"},"content":" }"},{"lineNumber":405,"author":{"gitId":"-"},"content":""},{"lineNumber":406,"author":{"gitId":"-"},"content":" if (questionType \u003d\u003d FeedbackQuestionType.MCQ) {"},{"lineNumber":407,"author":{"gitId":"-"},"content":" FeedbackMcqQuestionDetails feedbackMcqQuestionDetails \u003d"},{"lineNumber":408,"author":{"gitId":"-"},"content":" (FeedbackMcqQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":409,"author":{"gitId":"-"},"content":" feedbackMcqQuestionDetails.setMcqChoices(optionList);"},{"lineNumber":410,"author":{"gitId":"-"},"content":" ((FeedbackMcqQuestion) feedbackQuestion).setFeedBackQuestionDetails(feedbackMcqQuestionDetails);"},{"lineNumber":411,"author":{"gitId":"-"},"content":" } else if (questionType \u003d\u003d FeedbackQuestionType.MSQ) {"},{"lineNumber":412,"author":{"gitId":"-"},"content":" FeedbackMsqQuestionDetails feedbackMsqQuestionDetails \u003d"},{"lineNumber":413,"author":{"gitId":"-"},"content":" (FeedbackMsqQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":414,"author":{"gitId":"-"},"content":" feedbackMsqQuestionDetails.setMsqChoices(optionList);"},{"lineNumber":415,"author":{"gitId":"-"},"content":" ((FeedbackMsqQuestion) feedbackQuestion).setFeedBackQuestionDetails(feedbackMsqQuestionDetails);"},{"lineNumber":416,"author":{"gitId":"-"},"content":" }"},{"lineNumber":417,"author":{"gitId":"-"},"content":" }"},{"lineNumber":418,"author":{"gitId":"-"},"content":""},{"lineNumber":419,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":420,"author":{"gitId":"-"},"content":" * Gets the recipients of a feedback question including recipient section and team."},{"lineNumber":421,"author":{"gitId":"-"},"content":" *"},{"lineNumber":422,"author":{"gitId":"-"},"content":" * @param question the feedback question"},{"lineNumber":423,"author":{"gitId":"-"},"content":" * @param instructorGiver can be null for student giver"},{"lineNumber":424,"author":{"gitId":"-"},"content":" * @param studentGiver can be null for instructor giver"},{"lineNumber":425,"author":{"gitId":"-"},"content":" * @param courseRoster if provided, the function can be completed without touching database"},{"lineNumber":426,"author":{"gitId":"-"},"content":" * @return a Map of {@code FeedbackQuestionRecipient} as the value and identifier as the key."},{"lineNumber":427,"author":{"gitId":"-"},"content":" */"},{"lineNumber":428,"author":{"gitId":"-"},"content":" public Map\u003cString, FeedbackQuestionRecipient\u003e getRecipientsOfQuestion("},{"lineNumber":429,"author":{"gitId":"-"},"content":" FeedbackQuestion question,"},{"lineNumber":430,"author":{"gitId":"-"},"content":" @Nullable Instructor instructorGiver, @Nullable Student studentGiver,"},{"lineNumber":431,"author":{"gitId":"-"},"content":" @Nullable SqlCourseRoster courseRoster) {"},{"lineNumber":432,"author":{"gitId":"-"},"content":" assert instructorGiver !\u003d null || studentGiver !\u003d null;"},{"lineNumber":433,"author":{"gitId":"-"},"content":""},{"lineNumber":434,"author":{"gitId":"-"},"content":" String courseId \u003d question.getCourseId();"},{"lineNumber":435,"author":{"gitId":"-"},"content":""},{"lineNumber":436,"author":{"gitId":"-"},"content":" Map\u003cString, FeedbackQuestionRecipient\u003e recipients \u003d new HashMap\u003c\u003e();"},{"lineNumber":437,"author":{"gitId":"-"},"content":""},{"lineNumber":438,"author":{"gitId":"-"},"content":" boolean isStudentGiver \u003d studentGiver !\u003d null;"},{"lineNumber":439,"author":{"gitId":"-"},"content":" boolean isInstructorGiver \u003d instructorGiver !\u003d null;"},{"lineNumber":440,"author":{"gitId":"-"},"content":""},{"lineNumber":441,"author":{"gitId":"-"},"content":" String giverEmail \u003d \"\";"},{"lineNumber":442,"author":{"gitId":"-"},"content":" String giverTeam \u003d \"\";"},{"lineNumber":443,"author":{"gitId":"-"},"content":" String giverSection \u003d \"\";"},{"lineNumber":444,"author":{"gitId":"-"},"content":" if (isStudentGiver) {"},{"lineNumber":445,"author":{"gitId":"-"},"content":" giverEmail \u003d studentGiver.getEmail();"},{"lineNumber":446,"author":{"gitId":"-"},"content":" giverTeam \u003d studentGiver.getTeamName();"},{"lineNumber":447,"author":{"gitId":"-"},"content":" giverSection \u003d studentGiver.getSectionName();"},{"lineNumber":448,"author":{"gitId":"-"},"content":" } else if (isInstructorGiver) {"},{"lineNumber":449,"author":{"gitId":"-"},"content":" giverEmail \u003d instructorGiver.getEmail();"},{"lineNumber":450,"author":{"gitId":"-"},"content":" giverTeam \u003d Const.USER_TEAM_FOR_INSTRUCTOR;"},{"lineNumber":451,"author":{"gitId":"-"},"content":" giverSection \u003d Const.DEFAULT_SECTION;"},{"lineNumber":452,"author":{"gitId":"-"},"content":" }"},{"lineNumber":453,"author":{"gitId":"-"},"content":""},{"lineNumber":454,"author":{"gitId":"-"},"content":" FeedbackParticipantType recipientType \u003d question.getRecipientType();"},{"lineNumber":455,"author":{"gitId":"-"},"content":" FeedbackParticipantType generateOptionsFor \u003d recipientType;"},{"lineNumber":456,"author":{"gitId":"-"},"content":""},{"lineNumber":457,"author":{"gitId":"-"},"content":" switch (recipientType) {"},{"lineNumber":458,"author":{"gitId":"-"},"content":" case SELF:"},{"lineNumber":459,"author":{"gitId":"-"},"content":" if (question.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS) {"},{"lineNumber":460,"author":{"gitId":"-"},"content":" recipients.put(giverTeam,"},{"lineNumber":461,"author":{"gitId":"-"},"content":" new FeedbackQuestionRecipient(giverTeam, giverTeam));"},{"lineNumber":462,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":463,"author":{"gitId":"-"},"content":" recipients.put(giverEmail,"},{"lineNumber":464,"author":{"gitId":"-"},"content":" new FeedbackQuestionRecipient(USER_NAME_FOR_SELF, giverEmail));"},{"lineNumber":465,"author":{"gitId":"-"},"content":" }"},{"lineNumber":466,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":467,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":468,"author":{"gitId":"-"},"content":" case STUDENTS_EXCLUDING_SELF:"},{"lineNumber":469,"author":{"gitId":"-"},"content":" case STUDENTS_IN_SAME_SECTION:"},{"lineNumber":470,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e studentList;"},{"lineNumber":471,"author":{"gitId":"-"},"content":" if (courseRoster \u003d\u003d null) {"},{"lineNumber":472,"author":{"gitId":"-"},"content":" if (generateOptionsFor \u003d\u003d FeedbackParticipantType.STUDENTS_IN_SAME_SECTION) {"},{"lineNumber":473,"author":{"gitId":"-"},"content":" studentList \u003d usersLogic.getStudentsForSection(giverSection, courseId);"},{"lineNumber":474,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":475,"author":{"gitId":"-"},"content":" studentList \u003d usersLogic.getStudentsForCourse(courseId);"},{"lineNumber":476,"author":{"gitId":"-"},"content":" }"},{"lineNumber":477,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":478,"author":{"gitId":"-"},"content":" if (generateOptionsFor \u003d\u003d FeedbackParticipantType.STUDENTS_IN_SAME_SECTION) {"},{"lineNumber":479,"author":{"gitId":"-"},"content":" final String finalGiverSection \u003d giverSection;"},{"lineNumber":480,"author":{"gitId":"-"},"content":" studentList \u003d courseRoster.getStudents().stream()"},{"lineNumber":481,"author":{"gitId":"-"},"content":" .filter(studentAttributes -\u003e studentAttributes.getSectionName()"},{"lineNumber":482,"author":{"gitId":"-"},"content":" .equals(finalGiverSection)).collect(Collectors.toList());"},{"lineNumber":483,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":484,"author":{"gitId":"-"},"content":" studentList \u003d courseRoster.getStudents();"},{"lineNumber":485,"author":{"gitId":"-"},"content":" }"},{"lineNumber":486,"author":{"gitId":"-"},"content":" }"},{"lineNumber":487,"author":{"gitId":"-"},"content":" for (Student student : studentList) {"},{"lineNumber":488,"author":{"gitId":"-"},"content":" if (isInstructorGiver \u0026\u0026 !instructorGiver.isAllowedForPrivilege("},{"lineNumber":489,"author":{"gitId":"-"},"content":" student.getSectionName(), question.getFeedbackSession().getName(),"},{"lineNumber":490,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_SUBMIT_SESSION_IN_SECTIONS)) {"},{"lineNumber":491,"author":{"gitId":"-"},"content":" // instructor can only see students in allowed sections for him/her"},{"lineNumber":492,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":493,"author":{"gitId":"-"},"content":" }"},{"lineNumber":494,"author":{"gitId":"-"},"content":" // Ensure student does not evaluate him/herself if it\u0027s STUDENTS_EXCLUDING_SELF or"},{"lineNumber":495,"author":{"gitId":"-"},"content":" // STUDENTS_IN_SAME_SECTION"},{"lineNumber":496,"author":{"gitId":"-"},"content":" if (giverEmail.equals(student.getEmail()) \u0026\u0026 generateOptionsFor !\u003d FeedbackParticipantType.STUDENTS) {"},{"lineNumber":497,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":498,"author":{"gitId":"-"},"content":" }"},{"lineNumber":499,"author":{"gitId":"-"},"content":" recipients.put(student.getEmail(), new FeedbackQuestionRecipient(student.getName(), student.getEmail(),"},{"lineNumber":500,"author":{"gitId":"-"},"content":" student.getSectionName(), student.getTeamName()));"},{"lineNumber":501,"author":{"gitId":"-"},"content":" }"},{"lineNumber":502,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":503,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":504,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorsInCourse;"},{"lineNumber":505,"author":{"gitId":"-"},"content":" if (courseRoster \u003d\u003d null) {"},{"lineNumber":506,"author":{"gitId":"-"},"content":" instructorsInCourse \u003d usersLogic.getInstructorsForCourse(courseId);"},{"lineNumber":507,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":508,"author":{"gitId":"-"},"content":" instructorsInCourse \u003d courseRoster.getInstructors();"},{"lineNumber":509,"author":{"gitId":"-"},"content":" }"},{"lineNumber":510,"author":{"gitId":"-"},"content":" for (Instructor instr : instructorsInCourse) {"},{"lineNumber":511,"author":{"gitId":"-"},"content":" // remove hidden instructors for students"},{"lineNumber":512,"author":{"gitId":"-"},"content":" if (isStudentGiver \u0026\u0026 !instr.isDisplayedToStudents()) {"},{"lineNumber":513,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":514,"author":{"gitId":"-"},"content":" }"},{"lineNumber":515,"author":{"gitId":"-"},"content":" // Ensure instructor does not evaluate himself"},{"lineNumber":516,"author":{"gitId":"-"},"content":" if (!giverEmail.equals(instr.getEmail())) {"},{"lineNumber":517,"author":{"gitId":"-"},"content":" recipients.put(instr.getEmail(),"},{"lineNumber":518,"author":{"gitId":"-"},"content":" new FeedbackQuestionRecipient(instr.getName(), instr.getEmail()));"},{"lineNumber":519,"author":{"gitId":"-"},"content":" }"},{"lineNumber":520,"author":{"gitId":"-"},"content":" }"},{"lineNumber":521,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":522,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":523,"author":{"gitId":"-"},"content":" case TEAMS_EXCLUDING_SELF:"},{"lineNumber":524,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":525,"author":{"gitId":"-"},"content":" Map\u003cString, List\u003cStudent\u003e\u003e teamToTeamMembersTable;"},{"lineNumber":526,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e teamStudents;"},{"lineNumber":527,"author":{"gitId":"-"},"content":" if (courseRoster \u003d\u003d null) {"},{"lineNumber":528,"author":{"gitId":"-"},"content":" if (generateOptionsFor \u003d\u003d FeedbackParticipantType.TEAMS_IN_SAME_SECTION) {"},{"lineNumber":529,"author":{"gitId":"-"},"content":" teamStudents \u003d usersLogic.getStudentsForSection(giverSection, courseId);"},{"lineNumber":530,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":531,"author":{"gitId":"-"},"content":" teamStudents \u003d usersLogic.getStudentsForCourse(courseId);"},{"lineNumber":532,"author":{"gitId":"-"},"content":" }"},{"lineNumber":533,"author":{"gitId":"-"},"content":" teamToTeamMembersTable \u003d SqlCourseRoster.buildTeamToMembersTable(teamStudents);"},{"lineNumber":534,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":535,"author":{"gitId":"-"},"content":" if (generateOptionsFor \u003d\u003d FeedbackParticipantType.TEAMS_IN_SAME_SECTION) {"},{"lineNumber":536,"author":{"gitId":"-"},"content":" final String finalGiverSection \u003d giverSection;"},{"lineNumber":537,"author":{"gitId":"-"},"content":" teamStudents \u003d courseRoster.getStudents().stream()"},{"lineNumber":538,"author":{"gitId":"-"},"content":" .filter(student -\u003e student.getSectionName().equals(finalGiverSection))"},{"lineNumber":539,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":540,"author":{"gitId":"-"},"content":" teamToTeamMembersTable \u003d SqlCourseRoster.buildTeamToMembersTable(teamStudents);"},{"lineNumber":541,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":542,"author":{"gitId":"-"},"content":" teamToTeamMembersTable \u003d courseRoster.getTeamToMembersTable();"},{"lineNumber":543,"author":{"gitId":"-"},"content":" }"},{"lineNumber":544,"author":{"gitId":"-"},"content":" }"},{"lineNumber":545,"author":{"gitId":"-"},"content":" for (Map.Entry\u003cString, List\u003cStudent\u003e\u003e team : teamToTeamMembersTable.entrySet()) {"},{"lineNumber":546,"author":{"gitId":"-"},"content":" if (isInstructorGiver \u0026\u0026 !instructorGiver.isAllowedForPrivilege("},{"lineNumber":547,"author":{"gitId":"-"},"content":" team.getValue().iterator().next().getSectionName(),"},{"lineNumber":548,"author":{"gitId":"-"},"content":" question.getFeedbackSession().getName(),"},{"lineNumber":549,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_SUBMIT_SESSION_IN_SECTIONS)) {"},{"lineNumber":550,"author":{"gitId":"-"},"content":" // instructor can only see teams in allowed sections for him/her"},{"lineNumber":551,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":552,"author":{"gitId":"-"},"content":" }"},{"lineNumber":553,"author":{"gitId":"-"},"content":" // Ensure student(\u0027s team) does not evaluate own team if it\u0027s TEAMS_EXCLUDING_SELF or"},{"lineNumber":554,"author":{"gitId":"-"},"content":" // TEAMS_IN_SAME_SECTION"},{"lineNumber":555,"author":{"gitId":"-"},"content":" if (giverTeam.equals(team.getKey()) \u0026\u0026 generateOptionsFor !\u003d FeedbackParticipantType.TEAMS) {"},{"lineNumber":556,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":557,"author":{"gitId":"-"},"content":" }"},{"lineNumber":558,"author":{"gitId":"-"},"content":" // recipientEmail doubles as team name in this case."},{"lineNumber":559,"author":{"gitId":"-"},"content":" recipients.put(team.getKey(), new FeedbackQuestionRecipient(team.getKey(), team.getKey()));"},{"lineNumber":560,"author":{"gitId":"-"},"content":" }"},{"lineNumber":561,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":562,"author":{"gitId":"-"},"content":" case OWN_TEAM:"},{"lineNumber":563,"author":{"gitId":"-"},"content":" recipients.put(giverTeam, new FeedbackQuestionRecipient(giverTeam, giverTeam));"},{"lineNumber":564,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":565,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":566,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e students;"},{"lineNumber":567,"author":{"gitId":"-"},"content":" if (courseRoster \u003d\u003d null) {"},{"lineNumber":568,"author":{"gitId":"-"},"content":" students \u003d usersLogic.getStudentsForTeam(giverTeam, courseId);"},{"lineNumber":569,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":570,"author":{"gitId":"-"},"content":" students \u003d courseRoster.getTeamToMembersTable().getOrDefault(giverTeam, Collections.emptyList());"},{"lineNumber":571,"author":{"gitId":"-"},"content":" }"},{"lineNumber":572,"author":{"gitId":"-"},"content":" for (Student student : students) {"},{"lineNumber":573,"author":{"gitId":"-"},"content":" if (!student.getEmail().equals(giverEmail)) {"},{"lineNumber":574,"author":{"gitId":"-"},"content":" recipients.put(student.getEmail(), new FeedbackQuestionRecipient(student.getName(), student.getEmail(),"},{"lineNumber":575,"author":{"gitId":"-"},"content":" student.getSectionName(), student.getTeamName()));"},{"lineNumber":576,"author":{"gitId":"-"},"content":" }"},{"lineNumber":577,"author":{"gitId":"-"},"content":" }"},{"lineNumber":578,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":579,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS_INCLUDING_SELF:"},{"lineNumber":580,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e teamMembers;"},{"lineNumber":581,"author":{"gitId":"-"},"content":" if (courseRoster \u003d\u003d null) {"},{"lineNumber":582,"author":{"gitId":"-"},"content":" teamMembers \u003d usersLogic.getStudentsForTeam(giverTeam, courseId);"},{"lineNumber":583,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":584,"author":{"gitId":"-"},"content":" teamMembers \u003d courseRoster.getTeamToMembersTable().getOrDefault(giverTeam, Collections.emptyList());"},{"lineNumber":585,"author":{"gitId":"-"},"content":" }"},{"lineNumber":586,"author":{"gitId":"-"},"content":" for (Student student : teamMembers) {"},{"lineNumber":587,"author":{"gitId":"-"},"content":" // accepts self feedback too"},{"lineNumber":588,"author":{"gitId":"-"},"content":" recipients.put(student.getEmail(), new FeedbackQuestionRecipient(student.getName(), student.getEmail(),"},{"lineNumber":589,"author":{"gitId":"-"},"content":" student.getSectionName(), student.getTeamName()));"},{"lineNumber":590,"author":{"gitId":"-"},"content":" }"},{"lineNumber":591,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":592,"author":{"gitId":"-"},"content":" case NONE:"},{"lineNumber":593,"author":{"gitId":"-"},"content":" recipients.put(Const.GENERAL_QUESTION,"},{"lineNumber":594,"author":{"gitId":"-"},"content":" new FeedbackQuestionRecipient(Const.GENERAL_QUESTION, Const.GENERAL_QUESTION));"},{"lineNumber":595,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":596,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":597,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":598,"author":{"gitId":"-"},"content":" }"},{"lineNumber":599,"author":{"gitId":"-"},"content":" return recipients;"},{"lineNumber":600,"author":{"gitId":"-"},"content":" }"},{"lineNumber":601,"author":{"gitId":"-"},"content":""},{"lineNumber":602,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":603,"author":{"gitId":"-"},"content":" * Returns true if a session has question in a specific giverType."},{"lineNumber":604,"author":{"gitId":"-"},"content":" */"},{"lineNumber":605,"author":{"gitId":"-"},"content":" public boolean sessionHasQuestionsForGiverType("},{"lineNumber":606,"author":{"gitId":"-"},"content":" String feedbackSessionName, String courseId, FeedbackParticipantType giverType) {"},{"lineNumber":607,"author":{"gitId":"-"},"content":" return fqDb.hasFeedbackQuestionsForGiverType(feedbackSessionName, courseId, giverType);"},{"lineNumber":608,"author":{"gitId":"-"},"content":" }"},{"lineNumber":609,"author":{"gitId":"-"},"content":""},{"lineNumber":610,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":611,"author":{"gitId":"-"},"content":" * Returns true if a session has question in either STUDENTS type or TEAMS type."},{"lineNumber":612,"author":{"gitId":"-"},"content":" */"},{"lineNumber":613,"author":{"gitId":"-"},"content":" public boolean sessionHasQuestionsForStudent(String feedbackSessionName, String courseId) {"},{"lineNumber":614,"author":{"gitId":"-"},"content":" return fqDb.hasFeedbackQuestionsForGiverType(feedbackSessionName, courseId, FeedbackParticipantType.STUDENTS)"},{"lineNumber":615,"author":{"gitId":"-"},"content":" || fqDb.hasFeedbackQuestionsForGiverType(feedbackSessionName, courseId, FeedbackParticipantType.TEAMS);"},{"lineNumber":616,"author":{"gitId":"-"},"content":" }"},{"lineNumber":617,"author":{"gitId":"-"},"content":""},{"lineNumber":618,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":619,"author":{"gitId":"-"},"content":" * Deletes a feedback question cascade its responses and comments."},{"lineNumber":620,"author":{"gitId":"-"},"content":" *"},{"lineNumber":621,"author":{"gitId":"-"},"content":" * \u003cp\u003eSilently fail if question does not exist."},{"lineNumber":622,"author":{"gitId":"-"},"content":" */"},{"lineNumber":623,"author":{"gitId":"-"},"content":" public void deleteFeedbackQuestionCascade(UUID feedbackQuestionId) {"},{"lineNumber":624,"author":{"gitId":"-"},"content":" fqDb.deleteFeedbackQuestion(feedbackQuestionId);"},{"lineNumber":625,"author":{"gitId":"-"},"content":" }"},{"lineNumber":626,"author":{"gitId":"-"},"content":""},{"lineNumber":627,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":628,"author":{"gitId":"-"},"content":" * Filters the feedback questions in a course, with specified question type."},{"lineNumber":629,"author":{"gitId":"-"},"content":" * @param courseId the course to search from"},{"lineNumber":630,"author":{"gitId":"-"},"content":" * @param questionType the question type to search on"},{"lineNumber":631,"author":{"gitId":"-"},"content":" * @return a list of filtered questions"},{"lineNumber":632,"author":{"gitId":"-"},"content":" */"},{"lineNumber":633,"author":{"gitId":"-"},"content":" public List\u003cFeedbackQuestion\u003e getFeedbackQuestionForCourseWithType("},{"lineNumber":634,"author":{"gitId":"-"},"content":" String courseId, FeedbackQuestionType questionType) {"},{"lineNumber":635,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e feedbackSessions \u003d feedbackSessionsLogic.getFeedbackSessionsForCourse(courseId);"},{"lineNumber":636,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e feedbackQuestions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":637,"author":{"gitId":"-"},"content":""},{"lineNumber":638,"author":{"gitId":"-"},"content":" for (FeedbackSession session : feedbackSessions) {"},{"lineNumber":639,"author":{"gitId":"-"},"content":" feedbackQuestions.addAll(getFeedbackQuestionsForSession(session));"},{"lineNumber":640,"author":{"gitId":"-"},"content":" }"},{"lineNumber":641,"author":{"gitId":"-"},"content":""},{"lineNumber":642,"author":{"gitId":"-"},"content":" return feedbackQuestions"},{"lineNumber":643,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":644,"author":{"gitId":"-"},"content":" .filter(q -\u003e q.getQuestionDetailsCopy().getQuestionType().equals(questionType))"},{"lineNumber":645,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":646,"author":{"gitId":"-"},"content":" }"},{"lineNumber":647,"author":{"gitId":"-"},"content":""},{"lineNumber":648,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":649,"author":{"gitId":"xenosf"},"content":" * Builds a complete giver to recipient map for a {@code relatedQuestion}."},{"lineNumber":650,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":651,"author":{"gitId":"xenosf"},"content":" * @param relatedQuestion The question to be considered"},{"lineNumber":652,"author":{"gitId":"xenosf"},"content":" * @param courseRoster the roster in the course"},{"lineNumber":653,"author":{"gitId":"xenosf"},"content":" * @return a map from giver to recipient for the question."},{"lineNumber":654,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":655,"author":{"gitId":"xenosf"},"content":" public Map\u003cString, Set\u003cString\u003e\u003e buildCompleteGiverRecipientMap("},{"lineNumber":656,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion relatedQuestion, SqlCourseRoster courseRoster) {"},{"lineNumber":657,"author":{"gitId":"xenosf"},"content":" Map\u003cString, Set\u003cString\u003e\u003e completeGiverRecipientMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":658,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":659,"author":{"gitId":"xenosf"},"content":" List\u003cString\u003e possibleGiverEmails \u003d getPossibleGivers(relatedQuestion, courseRoster);"},{"lineNumber":660,"author":{"gitId":"xenosf"},"content":" for (String possibleGiverEmail : possibleGiverEmails) {"},{"lineNumber":661,"author":{"gitId":"xenosf"},"content":" switch (relatedQuestion.getGiverType()) {"},{"lineNumber":662,"author":{"gitId":"xenosf"},"content":" case STUDENTS:"},{"lineNumber":663,"author":{"gitId":"xenosf"},"content":" Student studentGiver \u003d courseRoster.getStudentForEmail(possibleGiverEmail);"},{"lineNumber":664,"author":{"gitId":"xenosf"},"content":" completeGiverRecipientMap"},{"lineNumber":665,"author":{"gitId":"xenosf"},"content":" .computeIfAbsent(possibleGiverEmail, key -\u003e new HashSet\u003c\u003e())"},{"lineNumber":666,"author":{"gitId":"xenosf"},"content":" .addAll(getRecipientsOfQuestion("},{"lineNumber":667,"author":{"gitId":"xenosf"},"content":" relatedQuestion, null, studentGiver, courseRoster).keySet());"},{"lineNumber":668,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":669,"author":{"gitId":"xenosf"},"content":" case TEAMS:"},{"lineNumber":670,"author":{"gitId":"xenosf"},"content":" Student oneTeamMember \u003d"},{"lineNumber":671,"author":{"gitId":"xenosf"},"content":" courseRoster.getTeamToMembersTable().get(possibleGiverEmail).iterator().next();"},{"lineNumber":672,"author":{"gitId":"xenosf"},"content":" completeGiverRecipientMap"},{"lineNumber":673,"author":{"gitId":"xenosf"},"content":" .computeIfAbsent(possibleGiverEmail, key -\u003e new HashSet\u003c\u003e())"},{"lineNumber":674,"author":{"gitId":"xenosf"},"content":" .addAll(getRecipientsOfQuestion("},{"lineNumber":675,"author":{"gitId":"xenosf"},"content":" relatedQuestion, null, oneTeamMember, courseRoster).keySet());"},{"lineNumber":676,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":677,"author":{"gitId":"xenosf"},"content":" case INSTRUCTORS:"},{"lineNumber":678,"author":{"gitId":"xenosf"},"content":" case SELF:"},{"lineNumber":679,"author":{"gitId":"xenosf"},"content":" Instructor instructorGiver \u003d courseRoster.getInstructorForEmail(possibleGiverEmail);"},{"lineNumber":680,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":681,"author":{"gitId":"xenosf"},"content":" // only happens when a session creator quits their course"},{"lineNumber":682,"author":{"gitId":"xenosf"},"content":" if (instructorGiver \u003d\u003d null) {"},{"lineNumber":683,"author":{"gitId":"xenosf"},"content":" instructorGiver \u003d new Instructor("},{"lineNumber":684,"author":{"gitId":"xenosf"},"content":" relatedQuestion.getCourse(),"},{"lineNumber":685,"author":{"gitId":"xenosf"},"content":" USER_NAME_FOR_SELF,"},{"lineNumber":686,"author":{"gitId":"xenosf"},"content":" possibleGiverEmail,"},{"lineNumber":687,"author":{"gitId":"xenosf"},"content":" false,"},{"lineNumber":688,"author":{"gitId":"xenosf"},"content":" USER_NAME_FOR_SELF,"},{"lineNumber":689,"author":{"gitId":"xenosf"},"content":" null,"},{"lineNumber":690,"author":{"gitId":"xenosf"},"content":" null"},{"lineNumber":691,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":692,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":693,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":694,"author":{"gitId":"xenosf"},"content":" completeGiverRecipientMap"},{"lineNumber":695,"author":{"gitId":"xenosf"},"content":" .computeIfAbsent(possibleGiverEmail, key -\u003e new HashSet\u003c\u003e())"},{"lineNumber":696,"author":{"gitId":"xenosf"},"content":" .addAll(getRecipientsOfQuestion("},{"lineNumber":697,"author":{"gitId":"xenosf"},"content":" relatedQuestion, instructorGiver, null, courseRoster).keySet());"},{"lineNumber":698,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":699,"author":{"gitId":"xenosf"},"content":" default:"},{"lineNumber":700,"author":{"gitId":"xenosf"},"content":" log.severe(\"Invalid giver type specified\");"},{"lineNumber":701,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":702,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":703,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":704,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":705,"author":{"gitId":"xenosf"},"content":" return completeGiverRecipientMap;"},{"lineNumber":706,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":707,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":708,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":709,"author":{"gitId":"xenosf"},"content":" * Gets possible giver identifiers for a feedback question."},{"lineNumber":710,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":711,"author":{"gitId":"xenosf"},"content":" * @param fq the feedback question"},{"lineNumber":712,"author":{"gitId":"xenosf"},"content":" * @param courseRoster roster of all students and instructors"},{"lineNumber":713,"author":{"gitId":"xenosf"},"content":" * @return a list of giver identifier"},{"lineNumber":714,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":715,"author":{"gitId":"xenosf"},"content":" private List\u003cString\u003e getPossibleGivers("},{"lineNumber":716,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion fq, SqlCourseRoster courseRoster) {"},{"lineNumber":717,"author":{"gitId":"xenosf"},"content":" FeedbackParticipantType giverType \u003d fq.getGiverType();"},{"lineNumber":718,"author":{"gitId":"xenosf"},"content":" List\u003cString\u003e possibleGivers \u003d new ArrayList\u003c\u003e();"},{"lineNumber":719,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":720,"author":{"gitId":"xenosf"},"content":" switch (giverType) {"},{"lineNumber":721,"author":{"gitId":"xenosf"},"content":" case STUDENTS:"},{"lineNumber":722,"author":{"gitId":"xenosf"},"content":" possibleGivers \u003d courseRoster.getStudents()"},{"lineNumber":723,"author":{"gitId":"xenosf"},"content":" .stream()"},{"lineNumber":724,"author":{"gitId":"xenosf"},"content":" .map(Student::getEmail)"},{"lineNumber":725,"author":{"gitId":"xenosf"},"content":" .collect(Collectors.toList());"},{"lineNumber":726,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":727,"author":{"gitId":"xenosf"},"content":" case INSTRUCTORS:"},{"lineNumber":728,"author":{"gitId":"xenosf"},"content":" possibleGivers \u003d courseRoster.getInstructors()"},{"lineNumber":729,"author":{"gitId":"xenosf"},"content":" .stream()"},{"lineNumber":730,"author":{"gitId":"xenosf"},"content":" .map(Instructor::getEmail)"},{"lineNumber":731,"author":{"gitId":"xenosf"},"content":" .collect(Collectors.toList());"},{"lineNumber":732,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":733,"author":{"gitId":"xenosf"},"content":" case TEAMS:"},{"lineNumber":734,"author":{"gitId":"xenosf"},"content":" possibleGivers \u003d new ArrayList\u003c\u003e(courseRoster.getTeamToMembersTable().keySet());"},{"lineNumber":735,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":736,"author":{"gitId":"xenosf"},"content":" case SELF:"},{"lineNumber":737,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession \u003d"},{"lineNumber":738,"author":{"gitId":"xenosf"},"content":" feedbackSessionsLogic.getFeedbackSession(fq.getFeedbackSessionName(), fq.getCourseId());"},{"lineNumber":739,"author":{"gitId":"xenosf"},"content":" possibleGivers \u003d Collections.singletonList(feedbackSession.getCreatorEmail());"},{"lineNumber":740,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":741,"author":{"gitId":"xenosf"},"content":" default:"},{"lineNumber":742,"author":{"gitId":"xenosf"},"content":" log.severe(\"Invalid giver type specified\");"},{"lineNumber":743,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":744,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":745,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":746,"author":{"gitId":"xenosf"},"content":" return possibleGivers;"},{"lineNumber":747,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":748,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":749,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":6,"xenosf":101,"dishenggg":2,"-":640}},{"path":"src/main/java/teammates/sqllogic/core/FeedbackResponseCommentsLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import java.util.Set;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.SqlCourseRoster;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackResponseCommentsDb;"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.ui.request.FeedbackResponseCommentUpdateRequest;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * Handles operations related to feedback response comments."},{"lineNumber":23,"author":{"gitId":"-"},"content":" *"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * @see FeedbackResponseComment"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * @see FeedbackResponseCommentsDb"},{"lineNumber":26,"author":{"gitId":"-"},"content":" */"},{"lineNumber":27,"author":{"gitId":"-"},"content":"public final class FeedbackResponseCommentsLogic {"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" private static final FeedbackResponseCommentsLogic instance \u003d new FeedbackResponseCommentsLogic();"},{"lineNumber":30,"author":{"gitId":"-"},"content":" private FeedbackResponseCommentsDb frcDb;"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" private FeedbackResponseCommentsLogic() {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" public static FeedbackResponseCommentsLogic inst() {"},{"lineNumber":37,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" }"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":41,"author":{"gitId":"-"},"content":" * Initialize dependencies for {@code FeedbackResponseCommentsLogic}."},{"lineNumber":42,"author":{"gitId":"-"},"content":" */"},{"lineNumber":43,"author":{"gitId":"-"},"content":" void initLogicDependencies(FeedbackResponseCommentsDb frcDb) {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" this.frcDb \u003d frcDb;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":48,"author":{"gitId":"-"},"content":" * Gets an feedback response comment by feedback response comment id."},{"lineNumber":49,"author":{"gitId":"-"},"content":" * @param id of feedback response comment."},{"lineNumber":50,"author":{"gitId":"-"},"content":" * @return the specified feedback response comment."},{"lineNumber":51,"author":{"gitId":"-"},"content":" */"},{"lineNumber":52,"author":{"gitId":"-"},"content":" public FeedbackResponseComment getFeedbackResponseComment(Long id) {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" return frcDb.getFeedbackResponseComment(id);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" }"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" * Gets all feedback response comments for a response."},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentForResponse(UUID feedbackResponseId) {"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" return frcDb.getFeedbackResponseCommentsForResponse(feedbackResponseId);"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" * Gets all response comments for a response."},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentsForResponse(UUID feedbackResponseId) {"},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" assert feedbackResponseId !\u003d null;"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" return frcDb.getFeedbackResponseCommentsForResponse(feedbackResponseId);"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":73,"author":{"gitId":"-"},"content":" * Gets the comment associated with the response."},{"lineNumber":74,"author":{"gitId":"-"},"content":" */"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public FeedbackResponseComment getFeedbackResponseCommentForResponseFromParticipant("},{"lineNumber":76,"author":{"gitId":"-"},"content":" UUID feedbackResponseId) {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" return frcDb.getFeedbackResponseCommentForResponseFromParticipant(feedbackResponseId);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":81,"author":{"gitId":"-"},"content":" * Creates a feedback response comment."},{"lineNumber":82,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the comment alreadty exists"},{"lineNumber":83,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the comment is invalid"},{"lineNumber":84,"author":{"gitId":"-"},"content":" */"},{"lineNumber":85,"author":{"gitId":"-"},"content":" public FeedbackResponseComment createFeedbackResponseComment(FeedbackResponseComment frc)"},{"lineNumber":86,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" return frcDb.createFeedbackResponseComment(frc);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":91,"author":{"gitId":"-"},"content":" * Deletes a feedbackResponseComment."},{"lineNumber":92,"author":{"gitId":"-"},"content":" */"},{"lineNumber":93,"author":{"gitId":"-"},"content":" public void deleteFeedbackResponseComment(Long frcId) {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" frcDb.deleteFeedbackResponseComment(frcId);"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":98,"author":{"gitId":"-"},"content":" * Updates a feedback response comment by {@link FeedbackResponseComment}."},{"lineNumber":99,"author":{"gitId":"-"},"content":" *"},{"lineNumber":100,"author":{"gitId":"-"},"content":" * @return updated comment"},{"lineNumber":101,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":102,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the comment cannot be found"},{"lineNumber":103,"author":{"gitId":"-"},"content":" */"},{"lineNumber":104,"author":{"gitId":"-"},"content":" public FeedbackResponseComment updateFeedbackResponseComment(FeedbackResponseComment feedbackResponseComment)"},{"lineNumber":105,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" return frcDb.updateFeedbackResponseComment(feedbackResponseComment);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":111,"author":{"gitId":"-"},"content":" * Updates a feedback response comment."},{"lineNumber":112,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the comment does not exist"},{"lineNumber":113,"author":{"gitId":"-"},"content":" */"},{"lineNumber":114,"author":{"gitId":"-"},"content":" public FeedbackResponseComment updateFeedbackResponseComment(Long frcId,"},{"lineNumber":115,"author":{"gitId":"-"},"content":" FeedbackResponseCommentUpdateRequest updateRequest, String updaterEmail)"},{"lineNumber":116,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" FeedbackResponseComment comment \u003d frcDb.getFeedbackResponseComment(frcId);"},{"lineNumber":118,"author":{"gitId":"-"},"content":" if (comment \u003d\u003d null) {"},{"lineNumber":119,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Trying to update a feedback response comment that does not exist.\");"},{"lineNumber":120,"author":{"gitId":"-"},"content":" }"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" comment.setCommentText(updateRequest.getCommentText());"},{"lineNumber":123,"author":{"gitId":"-"},"content":" comment.setShowCommentTo(updateRequest.getShowCommentTo());"},{"lineNumber":124,"author":{"gitId":"-"},"content":" comment.setShowGiverNameTo(updateRequest.getShowGiverNameTo());"},{"lineNumber":125,"author":{"gitId":"-"},"content":" comment.setLastEditorEmail(updaterEmail);"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" return comment;"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":" * Updates all feedback response comments with new emails."},{"lineNumber":132,"author":{"gitId":"-"},"content":" */"},{"lineNumber":133,"author":{"gitId":"-"},"content":" public void updateFeedbackResponseCommentsEmails(String courseId, String oldEmail, String updatedEmail) {"},{"lineNumber":134,"author":{"gitId":"-"},"content":" frcDb.updateGiverEmailOfFeedbackResponseComments(courseId, oldEmail, updatedEmail);"},{"lineNumber":135,"author":{"gitId":"-"},"content":" frcDb.updateLastEditorEmailOfFeedbackResponseComments(courseId, oldEmail, updatedEmail);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" }"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":" * Updates all feedback response comments with new sections."},{"lineNumber":140,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":" public void updateFeedbackResponseCommentsForResponse(FeedbackResponse response)"},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackResponseComment\u003e comments \u003d getFeedbackResponseCommentForResponse(response.getId());"},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":" for (FeedbackResponseComment comment : comments) {"},{"lineNumber":145,"author":{"gitId":"domoberzin"},"content":" comment.setGiverSection(response.getGiverSection());"},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":" comment.setRecipientSection(response.getRecipientSection());"},{"lineNumber":147,"author":{"gitId":"domoberzin"},"content":" frcDb.updateFeedbackResponseComment(comment);"},{"lineNumber":148,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":149,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":150,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":151,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":152,"author":{"gitId":"xenosf"},"content":" * Gets all feedback response comments for session in a section."},{"lineNumber":153,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":154,"author":{"gitId":"xenosf"},"content":" * @param courseId the course ID of the feedback session"},{"lineNumber":155,"author":{"gitId":"xenosf"},"content":" * @param feedbackSessionName the feedback session name"},{"lineNumber":156,"author":{"gitId":"xenosf"},"content":" * @param sectionName if null, will retrieve all comments in the session"},{"lineNumber":157,"author":{"gitId":"xenosf"},"content":" * @return a list of feedback response comments"},{"lineNumber":158,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":159,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentForSessionInSection("},{"lineNumber":160,"author":{"gitId":"xenosf"},"content":" String courseId, String feedbackSessionName, @Nullable String sectionName) {"},{"lineNumber":161,"author":{"gitId":"xenosf"},"content":" if (sectionName \u003d\u003d null) {"},{"lineNumber":162,"author":{"gitId":"xenosf"},"content":" return frcDb.getFeedbackResponseCommentsForSession(courseId, feedbackSessionName);"},{"lineNumber":163,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":164,"author":{"gitId":"xenosf"},"content":" return frcDb.getFeedbackResponseCommentsForSessionInSection(courseId, feedbackSessionName, sectionName);"},{"lineNumber":165,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":166,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":167,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":168,"author":{"gitId":"xenosf"},"content":" * Gets all feedback response comments for a question in a section."},{"lineNumber":169,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":170,"author":{"gitId":"xenosf"},"content":" * @param questionId the ID of the question"},{"lineNumber":171,"author":{"gitId":"xenosf"},"content":" * @param sectionName if null, will retrieve all comments for the question"},{"lineNumber":172,"author":{"gitId":"xenosf"},"content":" * @return a list of feedback response comments"},{"lineNumber":173,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":174,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentForQuestionInSection("},{"lineNumber":175,"author":{"gitId":"xenosf"},"content":" UUID questionId, @Nullable String sectionName) {"},{"lineNumber":176,"author":{"gitId":"xenosf"},"content":" if (sectionName \u003d\u003d null) {"},{"lineNumber":177,"author":{"gitId":"xenosf"},"content":" return frcDb.getFeedbackResponseCommentsForQuestion(questionId);"},{"lineNumber":178,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":179,"author":{"gitId":"xenosf"},"content":" return frcDb.getFeedbackResponseCommentsForQuestionInSection(questionId, sectionName);"},{"lineNumber":180,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":181,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":182,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":183,"author":{"gitId":"xenosf"},"content":" * Verifies whether the comment is visible to certain user."},{"lineNumber":184,"author":{"gitId":"xenosf"},"content":" * @return true/false"},{"lineNumber":185,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":186,"author":{"gitId":"xenosf"},"content":" public boolean checkIsResponseCommentVisibleForUser(String userEmail, boolean isInstructor,"},{"lineNumber":187,"author":{"gitId":"xenosf"},"content":" Student student, Set\u003cString\u003e studentsEmailInTeam, FeedbackResponse response,"},{"lineNumber":188,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion relatedQuestion, FeedbackResponseComment relatedComment) {"},{"lineNumber":189,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":190,"author":{"gitId":"xenosf"},"content":" if (response \u003d\u003d null || relatedQuestion \u003d\u003d null) {"},{"lineNumber":191,"author":{"gitId":"xenosf"},"content":" return false;"},{"lineNumber":192,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":193,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":194,"author":{"gitId":"xenosf"},"content":" boolean isVisibilityFollowingFeedbackQuestion \u003d relatedComment.getIsVisibilityFollowingFeedbackQuestion();"},{"lineNumber":195,"author":{"gitId":"xenosf"},"content":" boolean isVisibleToGiver \u003d isVisibilityFollowingFeedbackQuestion"},{"lineNumber":196,"author":{"gitId":"xenosf"},"content":" || relatedComment.checkIsVisibleTo(FeedbackParticipantType.GIVER);"},{"lineNumber":197,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":198,"author":{"gitId":"xenosf"},"content":" boolean isVisibleToUser \u003d checkIsVisibleToUser(userEmail, response, relatedQuestion, relatedComment,"},{"lineNumber":199,"author":{"gitId":"xenosf"},"content":" isVisibleToGiver, isInstructor, !isInstructor);"},{"lineNumber":200,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":201,"author":{"gitId":"xenosf"},"content":" boolean isVisibleToUserTeam \u003d checkIsVisibleToUserTeam(student, studentsEmailInTeam, response,"},{"lineNumber":202,"author":{"gitId":"xenosf"},"content":" relatedQuestion, relatedComment, !isInstructor);"},{"lineNumber":203,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":204,"author":{"gitId":"xenosf"},"content":" return isVisibleToUser || isVisibleToUserTeam;"},{"lineNumber":205,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":206,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":207,"author":{"gitId":"xenosf"},"content":" private boolean checkIsVisibleToUserTeam(Student student, Set\u003cString\u003e studentsEmailInTeam,"},{"lineNumber":208,"author":{"gitId":"xenosf"},"content":" FeedbackResponse response, FeedbackQuestion relatedQuestion,"},{"lineNumber":209,"author":{"gitId":"xenosf"},"content":" FeedbackResponseComment relatedComment, boolean isUserStudent) {"},{"lineNumber":210,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":211,"author":{"gitId":"xenosf"},"content":" boolean isUserInResponseRecipientTeamAndRelatedResponseCommentVisibleToRecipients \u003d"},{"lineNumber":212,"author":{"gitId":"xenosf"},"content":" isUserStudent"},{"lineNumber":213,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 relatedQuestion.getRecipientType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 checkIsResponseCommentVisibleTo(relatedQuestion, relatedComment,"},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" FeedbackParticipantType.RECEIVER)"},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 response.getRecipient().equals(student.getTeamName());"},{"lineNumber":217,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":218,"author":{"gitId":"xenosf"},"content":" boolean isUserInResponseGiverTeamAndRelatedResponseCommentVisibleToGiversTeamMembers \u003d"},{"lineNumber":219,"author":{"gitId":"xenosf"},"content":" (relatedQuestion.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":220,"author":{"gitId":"xenosf"},"content":" || checkIsResponseCommentVisibleTo(relatedQuestion, relatedComment,"},{"lineNumber":221,"author":{"gitId":"xenosf"},"content":" FeedbackParticipantType.OWN_TEAM_MEMBERS))"},{"lineNumber":222,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 (studentsEmailInTeam.contains(response.getGiver())"},{"lineNumber":223,"author":{"gitId":"xenosf"},"content":" || isUserStudent \u0026\u0026 student.getTeamName().equals(response.getGiver()));"},{"lineNumber":224,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":225,"author":{"gitId":"xenosf"},"content":" boolean isUserInResponseRecipientTeamAndRelatedResponseCommentVisibleToRecipientsTeamMembers \u003d"},{"lineNumber":226,"author":{"gitId":"xenosf"},"content":" checkIsResponseCommentVisibleTo(relatedQuestion, relatedComment,"},{"lineNumber":227,"author":{"gitId":"xenosf"},"content":" FeedbackParticipantType.RECEIVER_TEAM_MEMBERS)"},{"lineNumber":228,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 studentsEmailInTeam.contains(response.getRecipient());"},{"lineNumber":229,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":230,"author":{"gitId":"xenosf"},"content":" return isUserInResponseRecipientTeamAndRelatedResponseCommentVisibleToRecipients"},{"lineNumber":231,"author":{"gitId":"xenosf"},"content":" || isUserInResponseGiverTeamAndRelatedResponseCommentVisibleToGiversTeamMembers"},{"lineNumber":232,"author":{"gitId":"xenosf"},"content":" || isUserInResponseRecipientTeamAndRelatedResponseCommentVisibleToRecipientsTeamMembers;"},{"lineNumber":233,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":234,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":235,"author":{"gitId":"xenosf"},"content":" private boolean checkIsVisibleToUser(String userEmail, FeedbackResponse response,"},{"lineNumber":236,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion relatedQuestion, FeedbackResponseComment relatedComment,"},{"lineNumber":237,"author":{"gitId":"xenosf"},"content":" boolean isVisibleToGiver, boolean isUserInstructor, boolean isUserStudent) {"},{"lineNumber":238,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":239,"author":{"gitId":"xenosf"},"content":" boolean isUserInstructorAndRelatedResponseCommentVisibleToInstructors \u003d"},{"lineNumber":240,"author":{"gitId":"xenosf"},"content":" isUserInstructor \u0026\u0026 checkIsResponseCommentVisibleTo(relatedQuestion, relatedComment,"},{"lineNumber":241,"author":{"gitId":"xenosf"},"content":" FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":242,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":243,"author":{"gitId":"xenosf"},"content":" boolean isUserResponseRecipientAndRelatedResponseCommentVisibleToRecipients \u003d"},{"lineNumber":244,"author":{"gitId":"xenosf"},"content":" response.getRecipient().equals(userEmail) \u0026\u0026 checkIsResponseCommentVisibleTo(relatedQuestion,"},{"lineNumber":245,"author":{"gitId":"xenosf"},"content":" relatedComment, FeedbackParticipantType.RECEIVER);"},{"lineNumber":246,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":247,"author":{"gitId":"xenosf"},"content":" boolean isUserResponseGiverAndRelatedResponseCommentVisibleToGivers \u003d"},{"lineNumber":248,"author":{"gitId":"xenosf"},"content":" response.getGiver().equals(userEmail) \u0026\u0026 isVisibleToGiver;"},{"lineNumber":249,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":250,"author":{"gitId":"xenosf"},"content":" boolean isUserRelatedResponseCommentGiver \u003d relatedComment.getGiver().equals(userEmail);"},{"lineNumber":251,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":252,"author":{"gitId":"xenosf"},"content":" boolean isUserStudentAndRelatedResponseCommentVisibleToStudents \u003d"},{"lineNumber":253,"author":{"gitId":"xenosf"},"content":" isUserStudent \u0026\u0026 checkIsResponseCommentVisibleTo(relatedQuestion,"},{"lineNumber":254,"author":{"gitId":"xenosf"},"content":" relatedComment, FeedbackParticipantType.STUDENTS);"},{"lineNumber":255,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":256,"author":{"gitId":"xenosf"},"content":" return isUserInstructorAndRelatedResponseCommentVisibleToInstructors"},{"lineNumber":257,"author":{"gitId":"xenosf"},"content":" || isUserResponseRecipientAndRelatedResponseCommentVisibleToRecipients"},{"lineNumber":258,"author":{"gitId":"xenosf"},"content":" || isUserResponseGiverAndRelatedResponseCommentVisibleToGivers"},{"lineNumber":259,"author":{"gitId":"xenosf"},"content":" || isUserRelatedResponseCommentGiver"},{"lineNumber":260,"author":{"gitId":"xenosf"},"content":" || isUserStudentAndRelatedResponseCommentVisibleToStudents;"},{"lineNumber":261,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":262,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":263,"author":{"gitId":"xenosf"},"content":" private boolean checkIsResponseCommentVisibleTo(FeedbackQuestion relatedQuestion,"},{"lineNumber":264,"author":{"gitId":"xenosf"},"content":" FeedbackResponseComment relatedComment,"},{"lineNumber":265,"author":{"gitId":"xenosf"},"content":" FeedbackParticipantType viewerType) {"},{"lineNumber":266,"author":{"gitId":"xenosf"},"content":" boolean isVisibilityFollowingFeedbackQuestion \u003d relatedComment.getIsVisibilityFollowingFeedbackQuestion();"},{"lineNumber":267,"author":{"gitId":"xenosf"},"content":" return isVisibilityFollowingFeedbackQuestion"},{"lineNumber":268,"author":{"gitId":"xenosf"},"content":" ? relatedQuestion.isResponseVisibleTo(viewerType)"},{"lineNumber":269,"author":{"gitId":"xenosf"},"content":" : relatedComment.checkIsVisibleTo(viewerType);"},{"lineNumber":270,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":271,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":272,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":273,"author":{"gitId":"xenosf"},"content":" * Returns true if the comment\u0027s giver name is visible to certain user."},{"lineNumber":274,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":275,"author":{"gitId":"xenosf"},"content":" public boolean checkIsNameVisibleToUser(FeedbackResponseComment comment, FeedbackResponse response,"},{"lineNumber":276,"author":{"gitId":"xenosf"},"content":" String userEmail, SqlCourseRoster roster) {"},{"lineNumber":277,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackParticipantType\u003e showNameTo \u003d comment.getShowGiverNameTo();"},{"lineNumber":278,"author":{"gitId":"xenosf"},"content":" //in the old ver, name is always visible"},{"lineNumber":279,"author":{"gitId":"xenosf"},"content":" if (showNameTo \u003d\u003d null || comment.getIsVisibilityFollowingFeedbackQuestion()) {"},{"lineNumber":280,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":281,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":282,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":283,"author":{"gitId":"xenosf"},"content":" //comment giver can always see"},{"lineNumber":284,"author":{"gitId":"xenosf"},"content":" if (userEmail.equals(comment.getGiver())) {"},{"lineNumber":285,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":286,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":287,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":288,"author":{"gitId":"xenosf"},"content":" return checkIsFeedbackParticipantNameVisibleToUser(response, userEmail, roster, showNameTo);"},{"lineNumber":289,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":290,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":291,"author":{"gitId":"xenosf"},"content":" private boolean checkIsFeedbackParticipantNameVisibleToUser(FeedbackResponse response,"},{"lineNumber":292,"author":{"gitId":"xenosf"},"content":" String userEmail, SqlCourseRoster roster, List\u003cFeedbackParticipantType\u003e showNameTo) {"},{"lineNumber":293,"author":{"gitId":"xenosf"},"content":" String responseGiverTeam \u003d \"giverTeam\";"},{"lineNumber":294,"author":{"gitId":"xenosf"},"content":" if (roster.getStudentForEmail(response.getGiver()) !\u003d null) {"},{"lineNumber":295,"author":{"gitId":"xenosf"},"content":" responseGiverTeam \u003d roster.getStudentForEmail(response.getGiver()).getTeamName();"},{"lineNumber":296,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":297,"author":{"gitId":"xenosf"},"content":" String responseRecipientTeam \u003d \"recipientTeam\";"},{"lineNumber":298,"author":{"gitId":"xenosf"},"content":" if (roster.getStudentForEmail(response.getRecipient()) !\u003d null) {"},{"lineNumber":299,"author":{"gitId":"xenosf"},"content":" responseRecipientTeam \u003d roster.getStudentForEmail(response.getRecipient()).getTeamName();"},{"lineNumber":300,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":301,"author":{"gitId":"xenosf"},"content":" String currentUserTeam \u003d \"currentUserTeam\";"},{"lineNumber":302,"author":{"gitId":"xenosf"},"content":" if (roster.getStudentForEmail(userEmail) !\u003d null) {"},{"lineNumber":303,"author":{"gitId":"xenosf"},"content":" currentUserTeam \u003d roster.getStudentForEmail(userEmail).getTeamName();"},{"lineNumber":304,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":305,"author":{"gitId":"xenosf"},"content":" for (FeedbackParticipantType type : showNameTo) {"},{"lineNumber":306,"author":{"gitId":"xenosf"},"content":" switch (type) {"},{"lineNumber":307,"author":{"gitId":"xenosf"},"content":" case INSTRUCTORS:"},{"lineNumber":308,"author":{"gitId":"xenosf"},"content":" if (roster.getInstructorForEmail(userEmail) !\u003d null) {"},{"lineNumber":309,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":310,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":311,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":312,"author":{"gitId":"xenosf"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":313,"author":{"gitId":"xenosf"},"content":" if (responseGiverTeam.equals(currentUserTeam)) {"},{"lineNumber":314,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":315,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":316,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":317,"author":{"gitId":"xenosf"},"content":" case RECEIVER:"},{"lineNumber":318,"author":{"gitId":"xenosf"},"content":" if (userEmail.equals(response.getRecipient())) {"},{"lineNumber":319,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":320,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":321,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":322,"author":{"gitId":"xenosf"},"content":" case RECEIVER_TEAM_MEMBERS:"},{"lineNumber":323,"author":{"gitId":"xenosf"},"content":" if (responseRecipientTeam.equals(currentUserTeam)) {"},{"lineNumber":324,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":325,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":326,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":327,"author":{"gitId":"xenosf"},"content":" case STUDENTS:"},{"lineNumber":328,"author":{"gitId":"xenosf"},"content":" if (roster.getStudentForEmail(userEmail) !\u003d null) {"},{"lineNumber":329,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":330,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":331,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":332,"author":{"gitId":"xenosf"},"content":" case GIVER:"},{"lineNumber":333,"author":{"gitId":"xenosf"},"content":" if (userEmail.equals(response.getGiver())) {"},{"lineNumber":334,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":335,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":336,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":337,"author":{"gitId":"xenosf"},"content":" default:"},{"lineNumber":338,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":339,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":340,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":341,"author":{"gitId":"xenosf"},"content":" return false;"},{"lineNumber":342,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":343,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":32,"xenosf":198,"-":113}},{"path":"src/main/java/teammates/sqllogic/core/FeedbackResponsesLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import java.util.Collections;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import java.util.HashMap;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import java.util.HashSet;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":"import java.util.Set;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.FeedbackResultFetchType;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlCourseRoster;"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.SqlSessionResultsBundle;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionType;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRankRecipientsResponseDetails;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const;"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.RequestTracer;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackResponsesDb;"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.responses.FeedbackMissingResponse;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackRankRecipientsResponse;"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" * Handles operations related to feedback responses."},{"lineNumber":40,"author":{"gitId":"-"},"content":" *"},{"lineNumber":41,"author":{"gitId":"-"},"content":" * @see FeedbackResponse"},{"lineNumber":42,"author":{"gitId":"-"},"content":" * @see FeedbackResponsesDb"},{"lineNumber":43,"author":{"gitId":"-"},"content":" */"},{"lineNumber":44,"author":{"gitId":"-"},"content":"public final class FeedbackResponsesLogic {"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" private static final FeedbackResponsesLogic instance \u003d new FeedbackResponsesLogic();"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" private FeedbackResponsesDb frDb;"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private UsersLogic usersLogic;"},{"lineNumber":50,"author":{"gitId":"-"},"content":" private FeedbackQuestionsLogic fqLogic;"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" private FeedbackResponseCommentsLogic frcLogic;"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" private FeedbackResponsesLogic() {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" public static FeedbackResponsesLogic inst() {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":59,"author":{"gitId":"-"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":62,"author":{"gitId":"-"},"content":" * Initialize dependencies for {@code FeedbackResponsesLogic}."},{"lineNumber":63,"author":{"gitId":"-"},"content":" */"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" void initLogicDependencies(FeedbackResponsesDb frDb,"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" UsersLogic usersLogic, FeedbackQuestionsLogic fqLogic, FeedbackResponseCommentsLogic frcLogic) {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" this.frDb \u003d frDb;"},{"lineNumber":67,"author":{"gitId":"-"},"content":" this.usersLogic \u003d usersLogic;"},{"lineNumber":68,"author":{"gitId":"-"},"content":" this.fqLogic \u003d fqLogic;"},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" this.frcLogic \u003d frcLogic;"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":73,"author":{"gitId":"-"},"content":" * Gets a feedbackResponse or null if it does not exist."},{"lineNumber":74,"author":{"gitId":"-"},"content":" */"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public FeedbackResponse getFeedbackResponse(UUID frId) {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" return frDb.getFeedbackResponse(frId);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":80,"author":{"gitId":"-"},"content":" * Returns true if the responses of the question are visible to students."},{"lineNumber":81,"author":{"gitId":"-"},"content":" */"},{"lineNumber":82,"author":{"gitId":"-"},"content":" public boolean isResponseOfFeedbackQuestionVisibleToStudent(FeedbackQuestion question) {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" if (question.isResponseVisibleTo(FeedbackParticipantType.STUDENTS)) {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" }"},{"lineNumber":86,"author":{"gitId":"-"},"content":" boolean isStudentRecipientType \u003d"},{"lineNumber":87,"author":{"gitId":"-"},"content":" question.getRecipientType().equals(FeedbackParticipantType.STUDENTS)"},{"lineNumber":88,"author":{"gitId":"-"},"content":" || question.getRecipientType().equals(FeedbackParticipantType.STUDENTS_EXCLUDING_SELF)"},{"lineNumber":89,"author":{"gitId":"-"},"content":" || question.getRecipientType().equals(FeedbackParticipantType.STUDENTS_IN_SAME_SECTION)"},{"lineNumber":90,"author":{"gitId":"-"},"content":" || question.getRecipientType().equals(FeedbackParticipantType.OWN_TEAM_MEMBERS)"},{"lineNumber":91,"author":{"gitId":"-"},"content":" || question.getRecipientType().equals(FeedbackParticipantType.OWN_TEAM_MEMBERS_INCLUDING_SELF)"},{"lineNumber":92,"author":{"gitId":"-"},"content":" || question.getRecipientType().equals(FeedbackParticipantType.GIVER)"},{"lineNumber":93,"author":{"gitId":"-"},"content":" \u0026\u0026 question.getGiverType().equals(FeedbackParticipantType.STUDENTS);"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" if ((isStudentRecipientType || question.getRecipientType().isTeam())"},{"lineNumber":96,"author":{"gitId":"-"},"content":" \u0026\u0026 question.isResponseVisibleTo(FeedbackParticipantType.RECEIVER)) {"},{"lineNumber":97,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":98,"author":{"gitId":"-"},"content":" }"},{"lineNumber":99,"author":{"gitId":"-"},"content":" if (question.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":100,"author":{"gitId":"-"},"content":" || question.isResponseVisibleTo(FeedbackParticipantType.OWN_TEAM_MEMBERS)) {"},{"lineNumber":101,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"-"},"content":" return question.isResponseVisibleTo(FeedbackParticipantType.RECEIVER_TEAM_MEMBERS);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":107,"author":{"gitId":"-"},"content":" * Returns true if the responses of the question are visible to instructors."},{"lineNumber":108,"author":{"gitId":"-"},"content":" */"},{"lineNumber":109,"author":{"gitId":"-"},"content":" public boolean isResponseOfFeedbackQuestionVisibleToInstructor(FeedbackQuestion question) {"},{"lineNumber":110,"author":{"gitId":"-"},"content":" return question.isResponseVisibleTo(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":114,"author":{"gitId":"-"},"content":" * Checks whether a giver has responded a session."},{"lineNumber":115,"author":{"gitId":"-"},"content":" */"},{"lineNumber":116,"author":{"gitId":"-"},"content":" public boolean hasGiverRespondedForSession(String giverIdentifier, List\u003cFeedbackQuestion\u003e questions) {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" assert questions !\u003d null;"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" for (FeedbackQuestion question : questions) {"},{"lineNumber":120,"author":{"gitId":"-"},"content":" boolean hasResponse \u003d question"},{"lineNumber":121,"author":{"gitId":"-"},"content":" .getFeedbackResponses()"},{"lineNumber":122,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":123,"author":{"gitId":"-"},"content":" .anyMatch(response -\u003e response.getGiver().equals(giverIdentifier));"},{"lineNumber":124,"author":{"gitId":"-"},"content":" if (hasResponse) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":126,"author":{"gitId":"-"},"content":" }"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":130,"author":{"gitId":"-"},"content":" }"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":133,"author":{"gitId":"-"},"content":" * Checks whether a giver has responded a session."},{"lineNumber":134,"author":{"gitId":"-"},"content":" */"},{"lineNumber":135,"author":{"gitId":"-"},"content":" public boolean hasGiverRespondedForSession(String giver, String feedbackSessionName, String courseId) {"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" return frDb.hasResponsesFromGiverInSession(giver, feedbackSessionName, courseId);"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":141,"author":{"gitId":"-"},"content":" * Creates a feedback response."},{"lineNumber":142,"author":{"gitId":"-"},"content":" * @return the created response"},{"lineNumber":143,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the response is not valid"},{"lineNumber":144,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the response already exist"},{"lineNumber":145,"author":{"gitId":"-"},"content":" */"},{"lineNumber":146,"author":{"gitId":"-"},"content":" public FeedbackResponse createFeedbackResponse(FeedbackResponse feedbackResponse)"},{"lineNumber":147,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" return frDb.createFeedbackResponse(feedbackResponse);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" }"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":152,"author":{"gitId":"-"},"content":" * Get existing feedback responses from instructor for the given question."},{"lineNumber":153,"author":{"gitId":"-"},"content":" */"},{"lineNumber":154,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesFromInstructorForQuestion("},{"lineNumber":155,"author":{"gitId":"-"},"content":" FeedbackQuestion question, Instructor instructor) {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" return frDb.getFeedbackResponsesFromGiverForQuestion("},{"lineNumber":157,"author":{"gitId":"-"},"content":" question.getId(), instructor.getEmail());"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":161,"author":{"gitId":"-"},"content":" * Get existing feedback responses from student or his team for the given"},{"lineNumber":162,"author":{"gitId":"-"},"content":" * question."},{"lineNumber":163,"author":{"gitId":"-"},"content":" */"},{"lineNumber":164,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesFromStudentOrTeamForQuestion("},{"lineNumber":165,"author":{"gitId":"-"},"content":" FeedbackQuestion question, Student student) {"},{"lineNumber":166,"author":{"gitId":"-"},"content":" if (question.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS) {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" return getFeedbackResponsesFromTeamForQuestion("},{"lineNumber":168,"author":{"gitId":"-"},"content":" question.getId(), question.getCourseId(), student.getTeamName(), null);"},{"lineNumber":169,"author":{"gitId":"-"},"content":" }"},{"lineNumber":170,"author":{"gitId":"-"},"content":" return frDb.getFeedbackResponsesFromGiverForQuestion(question.getId(), student.getEmail());"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" private List\u003cFeedbackResponse\u003e getFeedbackResponsesFromTeamForQuestion("},{"lineNumber":174,"author":{"gitId":"-"},"content":" UUID feedbackQuestionId, String courseId, String teamName, @Nullable SqlCourseRoster courseRoster) {"},{"lineNumber":175,"author":{"gitId":"-"},"content":""},{"lineNumber":176,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponse\u003e responses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":177,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e studentsInTeam \u003d courseRoster \u003d\u003d null"},{"lineNumber":178,"author":{"gitId":"-"},"content":" ? usersLogic.getStudentsForTeam(teamName, courseId) : courseRoster.getTeamToMembersTable().get(teamName);"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" for (Student student : studentsInTeam) {"},{"lineNumber":181,"author":{"gitId":"-"},"content":" responses.addAll(frDb.getFeedbackResponsesFromGiverForQuestion("},{"lineNumber":182,"author":{"gitId":"-"},"content":" feedbackQuestionId, student.getEmail()));"},{"lineNumber":183,"author":{"gitId":"-"},"content":" }"},{"lineNumber":184,"author":{"gitId":"-"},"content":""},{"lineNumber":185,"author":{"gitId":"-"},"content":" responses.addAll(frDb.getFeedbackResponsesFromGiverForQuestion("},{"lineNumber":186,"author":{"gitId":"-"},"content":" feedbackQuestionId, teamName));"},{"lineNumber":187,"author":{"gitId":"-"},"content":" return responses;"},{"lineNumber":188,"author":{"gitId":"-"},"content":" }"},{"lineNumber":189,"author":{"gitId":"-"},"content":""},{"lineNumber":190,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":191,"author":{"gitId":"-"},"content":" * Updates a non-null feedback response by {@link FeedbackResponse}."},{"lineNumber":192,"author":{"gitId":"-"},"content":" *"},{"lineNumber":193,"author":{"gitId":"-"},"content":" * \u003cp\u003eCascade updates its associated feedback response comment"},{"lineNumber":194,"author":{"gitId":"-"},"content":" * (e.g. associated response ID, giverSection and recipientSection)."},{"lineNumber":195,"author":{"gitId":"-"},"content":" *"},{"lineNumber":196,"author":{"gitId":"-"},"content":" * \u003cp\u003eIf the giver/recipient field is changed, the response is updated by recreating the response"},{"lineNumber":197,"author":{"gitId":"-"},"content":" * as question-giver-recipient is the primary key."},{"lineNumber":198,"author":{"gitId":"-"},"content":" *"},{"lineNumber":199,"author":{"gitId":"-"},"content":" * @return updated feedback response"},{"lineNumber":200,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":201,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the comment cannot be found"},{"lineNumber":202,"author":{"gitId":"-"},"content":" */"},{"lineNumber":203,"author":{"gitId":"-"},"content":" public FeedbackResponse updateFeedbackResponseCascade(FeedbackResponse feedbackResponse)"},{"lineNumber":204,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" FeedbackResponse oldResponse \u003d frDb.getFeedbackResponse(feedbackResponse.getId());"},{"lineNumber":207,"author":{"gitId":"-"},"content":" FeedbackResponse newResponse \u003d frDb.updateFeedbackResponse(feedbackResponse);"},{"lineNumber":208,"author":{"gitId":"-"},"content":""},{"lineNumber":209,"author":{"gitId":"-"},"content":" boolean isGiverSectionChanged \u003d !oldResponse.getGiverSection().equals(newResponse.getGiverSection());"},{"lineNumber":210,"author":{"gitId":"-"},"content":" boolean isRecipientSectionChanged \u003d !oldResponse.getRecipientSection().equals(newResponse.getRecipientSection());"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" if (isGiverSectionChanged || isRecipientSectionChanged) {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponseComment\u003e oldResponseComments \u003d"},{"lineNumber":214,"author":{"gitId":"-"},"content":" frcLogic.getFeedbackResponseCommentForResponse(oldResponse.getId());"},{"lineNumber":215,"author":{"gitId":"-"},"content":" for (FeedbackResponseComment oldResponseComment : oldResponseComments) {"},{"lineNumber":216,"author":{"gitId":"-"},"content":" if (isGiverSectionChanged) {"},{"lineNumber":217,"author":{"gitId":"-"},"content":" oldResponseComment.setGiverSection(newResponse.getGiverSection());"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" if (isRecipientSectionChanged) {"},{"lineNumber":221,"author":{"gitId":"-"},"content":" oldResponseComment.setRecipientSection(newResponse.getRecipientSection());"},{"lineNumber":222,"author":{"gitId":"-"},"content":" }"},{"lineNumber":223,"author":{"gitId":"-"},"content":""},{"lineNumber":224,"author":{"gitId":"-"},"content":" frcLogic.updateFeedbackResponseComment(oldResponseComment);"},{"lineNumber":225,"author":{"gitId":"-"},"content":" }"},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"-"},"content":" }"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" return newResponse;"},{"lineNumber":230,"author":{"gitId":"-"},"content":" }"},{"lineNumber":231,"author":{"gitId":"-"},"content":""},{"lineNumber":232,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":233,"author":{"gitId":"-"},"content":" * Deletes a feedback response cascade its associated feedback response comments."},{"lineNumber":234,"author":{"gitId":"-"},"content":" * Implicitly makes use of CascadeType.REMOVE."},{"lineNumber":235,"author":{"gitId":"-"},"content":" */"},{"lineNumber":236,"author":{"gitId":"-"},"content":" public void deleteFeedbackResponsesAndCommentsCascade(FeedbackResponse feedbackResponse) {"},{"lineNumber":237,"author":{"gitId":"-"},"content":" frDb.deleteFeedbackResponse(feedbackResponse);"},{"lineNumber":238,"author":{"gitId":"-"},"content":" }"},{"lineNumber":239,"author":{"gitId":"-"},"content":""},{"lineNumber":240,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":241,"author":{"gitId":"-"},"content":" * Deletes all feedback responses of a question cascade its associated comments."},{"lineNumber":242,"author":{"gitId":"-"},"content":" */"},{"lineNumber":243,"author":{"gitId":"-"},"content":" public void deleteFeedbackResponsesForQuestionCascade(UUID feedbackQuestionId) {"},{"lineNumber":244,"author":{"gitId":"-"},"content":" // delete all responses, comments of the question"},{"lineNumber":245,"author":{"gitId":"-"},"content":" frDb.deleteFeedbackResponsesForQuestionCascade(feedbackQuestionId);"},{"lineNumber":246,"author":{"gitId":"-"},"content":" }"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":249,"author":{"gitId":"-"},"content":" * Checks whether there are responses for a question."},{"lineNumber":250,"author":{"gitId":"-"},"content":" */"},{"lineNumber":251,"author":{"gitId":"-"},"content":" public boolean areThereResponsesForQuestion(UUID questionId) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" return frDb.areThereResponsesForQuestion(questionId);"},{"lineNumber":253,"author":{"gitId":"-"},"content":" }"},{"lineNumber":254,"author":{"gitId":"-"},"content":""},{"lineNumber":255,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":256,"author":{"gitId":"-"},"content":" * Checks whether there are responses for a course."},{"lineNumber":257,"author":{"gitId":"-"},"content":" */"},{"lineNumber":258,"author":{"gitId":"-"},"content":" public boolean hasResponsesForCourse(String courseId) {"},{"lineNumber":259,"author":{"gitId":"-"},"content":" return frDb.hasResponsesForCourse(courseId);"},{"lineNumber":260,"author":{"gitId":"-"},"content":""},{"lineNumber":261,"author":{"gitId":"-"},"content":" }"},{"lineNumber":262,"author":{"gitId":"-"},"content":""},{"lineNumber":263,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":264,"author":{"gitId":"-"},"content":" * Deletes all feedback responses involved an entity, cascade its associated comments."},{"lineNumber":265,"author":{"gitId":"-"},"content":" * Deletion will automatically be cascaded to each feedback response\u0027s comments,"},{"lineNumber":266,"author":{"gitId":"-"},"content":" * handled by Hibernate using the OnDelete annotation."},{"lineNumber":267,"author":{"gitId":"-"},"content":" */"},{"lineNumber":268,"author":{"gitId":"-"},"content":" public void deleteFeedbackResponsesForCourseCascade(String courseId, String entityEmail) {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" // delete responses from the entity"},{"lineNumber":270,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponse\u003e responsesFromStudent \u003d"},{"lineNumber":271,"author":{"gitId":"-"},"content":" getFeedbackResponsesFromGiverForCourse(courseId, entityEmail);"},{"lineNumber":272,"author":{"gitId":"-"},"content":" for (FeedbackResponse response : responsesFromStudent) {"},{"lineNumber":273,"author":{"gitId":"-"},"content":" frDb.deleteFeedbackResponse(response);"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" // delete responses to the entity"},{"lineNumber":277,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponse\u003e responsesToStudent \u003d"},{"lineNumber":278,"author":{"gitId":"-"},"content":" getFeedbackResponsesForRecipientForCourse(courseId, entityEmail);"},{"lineNumber":279,"author":{"gitId":"-"},"content":" for (FeedbackResponse response : responsesToStudent) {"},{"lineNumber":280,"author":{"gitId":"-"},"content":" frDb.deleteFeedbackResponse(response);"},{"lineNumber":281,"author":{"gitId":"-"},"content":" }"},{"lineNumber":282,"author":{"gitId":"-"},"content":" }"},{"lineNumber":283,"author":{"gitId":"-"},"content":""},{"lineNumber":284,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":285,"author":{"gitId":"-"},"content":" * Gets all responses given by a user for a course."},{"lineNumber":286,"author":{"gitId":"-"},"content":" */"},{"lineNumber":287,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesFromGiverForCourse("},{"lineNumber":288,"author":{"gitId":"-"},"content":" String courseId, String giver) {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":290,"author":{"gitId":"-"},"content":" assert giver !\u003d null;"},{"lineNumber":291,"author":{"gitId":"-"},"content":""},{"lineNumber":292,"author":{"gitId":"-"},"content":" return frDb.getFeedbackResponsesFromGiverForCourse(courseId, giver);"},{"lineNumber":293,"author":{"gitId":"-"},"content":" }"},{"lineNumber":294,"author":{"gitId":"-"},"content":""},{"lineNumber":295,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":296,"author":{"gitId":"-"},"content":" * Gets all responses received by a user for a course."},{"lineNumber":297,"author":{"gitId":"-"},"content":" */"},{"lineNumber":298,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForRecipientForCourse("},{"lineNumber":299,"author":{"gitId":"-"},"content":" String courseId, String recipient) {"},{"lineNumber":300,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":301,"author":{"gitId":"-"},"content":" assert recipient !\u003d null;"},{"lineNumber":302,"author":{"gitId":"-"},"content":""},{"lineNumber":303,"author":{"gitId":"-"},"content":" return frDb.getFeedbackResponsesForRecipientForCourse(courseId, recipient);"},{"lineNumber":304,"author":{"gitId":"-"},"content":" }"},{"lineNumber":305,"author":{"gitId":"-"},"content":""},{"lineNumber":306,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":307,"author":{"gitId":"-"},"content":" * Gets all responses given by a user for a question."},{"lineNumber":308,"author":{"gitId":"-"},"content":" */"},{"lineNumber":309,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesFromGiverForQuestion("},{"lineNumber":310,"author":{"gitId":"-"},"content":" UUID feedbackQuestionId, String giver) {"},{"lineNumber":311,"author":{"gitId":"-"},"content":" return frDb.getFeedbackResponsesFromGiverForQuestion(feedbackQuestionId, giver);"},{"lineNumber":312,"author":{"gitId":"-"},"content":" }"},{"lineNumber":313,"author":{"gitId":"-"},"content":""},{"lineNumber":314,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":315,"author":{"gitId":"xenosf"},"content":" * Gets all responses for a question."},{"lineNumber":316,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":317,"author":{"gitId":"domoberzin"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForQuestion(UUID feedbackQuestionId) {"},{"lineNumber":318,"author":{"gitId":"domoberzin"},"content":" return frDb.getResponsesForQuestion(feedbackQuestionId);"},{"lineNumber":319,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":320,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":321,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":322,"author":{"gitId":"-"},"content":" * Updates the relevant responses before the deletion of a student."},{"lineNumber":323,"author":{"gitId":"-"},"content":" * This method takes care of the following:"},{"lineNumber":324,"author":{"gitId":"-"},"content":" * Making existing responses of \u0027rank recipient question\u0027 consistent."},{"lineNumber":325,"author":{"gitId":"-"},"content":" */"},{"lineNumber":326,"author":{"gitId":"-"},"content":" public void updateRankRecipientQuestionResponsesAfterDeletingStudent(String courseId) {"},{"lineNumber":327,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e filteredQuestions \u003d"},{"lineNumber":328,"author":{"gitId":"-"},"content":" fqLogic.getFeedbackQuestionForCourseWithType(courseId, FeedbackQuestionType.RANK_RECIPIENTS);"},{"lineNumber":329,"author":{"gitId":"-"},"content":" SqlCourseRoster roster \u003d new SqlCourseRoster("},{"lineNumber":330,"author":{"gitId":"-"},"content":" usersLogic.getStudentsForCourse(courseId),"},{"lineNumber":331,"author":{"gitId":"-"},"content":" usersLogic.getInstructorsForCourse(courseId));"},{"lineNumber":332,"author":{"gitId":"-"},"content":""},{"lineNumber":333,"author":{"gitId":"-"},"content":" for (FeedbackQuestion question : filteredQuestions) {"},{"lineNumber":334,"author":{"gitId":"-"},"content":" makeRankRecipientQuestionResponsesConsistent(question, roster);"},{"lineNumber":335,"author":{"gitId":"-"},"content":" }"},{"lineNumber":336,"author":{"gitId":"-"},"content":" }"},{"lineNumber":337,"author":{"gitId":"-"},"content":""},{"lineNumber":338,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":339,"author":{"gitId":"-"},"content":" * Makes the rankings by one giver in the response to a \u0027rank recipient question\u0027 consistent, after deleting a"},{"lineNumber":340,"author":{"gitId":"-"},"content":" * student."},{"lineNumber":341,"author":{"gitId":"-"},"content":" * \u003cp\u003e"},{"lineNumber":342,"author":{"gitId":"-"},"content":" * Fails silently if the question type is not \u0027rank recipient question\u0027."},{"lineNumber":343,"author":{"gitId":"-"},"content":" * \u003c/p\u003e"},{"lineNumber":344,"author":{"gitId":"-"},"content":" */"},{"lineNumber":345,"author":{"gitId":"-"},"content":" private void makeRankRecipientQuestionResponsesConsistent("},{"lineNumber":346,"author":{"gitId":"-"},"content":" FeedbackQuestion question, SqlCourseRoster roster) {"},{"lineNumber":347,"author":{"gitId":"mingyuanc"},"content":" assert question.getQuestionDetailsCopy().getQuestionType()"},{"lineNumber":348,"author":{"gitId":"-"},"content":" .equals(FeedbackQuestionType.RANK_RECIPIENTS);"},{"lineNumber":349,"author":{"gitId":"-"},"content":""},{"lineNumber":350,"author":{"gitId":"-"},"content":" FeedbackParticipantType giverType \u003d question.getGiverType();"},{"lineNumber":351,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponse\u003e responses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":352,"author":{"gitId":"-"},"content":" int numberOfRecipients \u003d 0;"},{"lineNumber":353,"author":{"gitId":"-"},"content":""},{"lineNumber":354,"author":{"gitId":"-"},"content":" switch (giverType) {"},{"lineNumber":355,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":356,"author":{"gitId":"-"},"content":" case SELF:"},{"lineNumber":357,"author":{"gitId":"-"},"content":" for (Instructor instructor : roster.getInstructors()) {"},{"lineNumber":358,"author":{"gitId":"-"},"content":" numberOfRecipients \u003d"},{"lineNumber":359,"author":{"gitId":"-"},"content":" fqLogic.getRecipientsOfQuestion(question, instructor, null, roster).size();"},{"lineNumber":360,"author":{"gitId":"-"},"content":" responses \u003d getFeedbackResponsesFromGiverForQuestion(question.getId(), instructor.getEmail());"},{"lineNumber":361,"author":{"gitId":"-"},"content":" }"},{"lineNumber":362,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":363,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":364,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":365,"author":{"gitId":"-"},"content":" Student firstMemberOfTeam;"},{"lineNumber":366,"author":{"gitId":"-"},"content":" String team;"},{"lineNumber":367,"author":{"gitId":"-"},"content":" Map\u003cString, List\u003cStudent\u003e\u003e teams \u003d roster.getTeamToMembersTable();"},{"lineNumber":368,"author":{"gitId":"-"},"content":" for (Map.Entry\u003cString, List\u003cStudent\u003e\u003e entry : teams.entrySet()) {"},{"lineNumber":369,"author":{"gitId":"-"},"content":" team \u003d entry.getKey();"},{"lineNumber":370,"author":{"gitId":"-"},"content":" firstMemberOfTeam \u003d entry.getValue().get(0);"},{"lineNumber":371,"author":{"gitId":"-"},"content":" numberOfRecipients \u003d"},{"lineNumber":372,"author":{"gitId":"-"},"content":" fqLogic.getRecipientsOfQuestion(question, null, firstMemberOfTeam, roster).size();"},{"lineNumber":373,"author":{"gitId":"-"},"content":" responses \u003d"},{"lineNumber":374,"author":{"gitId":"-"},"content":" getFeedbackResponsesFromTeamForQuestion("},{"lineNumber":375,"author":{"gitId":"-"},"content":" question.getId(), question.getCourseId(), team, roster);"},{"lineNumber":376,"author":{"gitId":"-"},"content":" }"},{"lineNumber":377,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":378,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":379,"author":{"gitId":"-"},"content":" for (Student student : roster.getStudents()) {"},{"lineNumber":380,"author":{"gitId":"-"},"content":" numberOfRecipients \u003d"},{"lineNumber":381,"author":{"gitId":"-"},"content":" fqLogic.getRecipientsOfQuestion(question, null, student, roster).size();"},{"lineNumber":382,"author":{"gitId":"-"},"content":" responses \u003d getFeedbackResponsesFromGiverForQuestion(question.getId(), student.getEmail());"},{"lineNumber":383,"author":{"gitId":"-"},"content":" }"},{"lineNumber":384,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":385,"author":{"gitId":"-"},"content":" }"},{"lineNumber":386,"author":{"gitId":"-"},"content":""},{"lineNumber":387,"author":{"gitId":"-"},"content":" updateFeedbackResponsesForRankRecipientQuestions(responses, numberOfRecipients);"},{"lineNumber":388,"author":{"gitId":"-"},"content":" }"},{"lineNumber":389,"author":{"gitId":"-"},"content":""},{"lineNumber":390,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":391,"author":{"gitId":"-"},"content":" * Updates responses for \u0027rank recipient question\u0027, such that the ranks in the responses are consistent."},{"lineNumber":392,"author":{"gitId":"-"},"content":" * @param responses responses to one feedback question, from one giver"},{"lineNumber":393,"author":{"gitId":"-"},"content":" * @param maxRank the maximum rank in each response"},{"lineNumber":394,"author":{"gitId":"-"},"content":" */"},{"lineNumber":395,"author":{"gitId":"-"},"content":" private void updateFeedbackResponsesForRankRecipientQuestions("},{"lineNumber":396,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponse\u003e responses, int maxRank) {"},{"lineNumber":397,"author":{"gitId":"-"},"content":" if (maxRank \u003c\u003d 0) {"},{"lineNumber":398,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":399,"author":{"gitId":"-"},"content":" }"},{"lineNumber":400,"author":{"gitId":"-"},"content":""},{"lineNumber":401,"author":{"gitId":"-"},"content":" FeedbackRankRecipientsResponseDetails responseDetails;"},{"lineNumber":402,"author":{"gitId":"-"},"content":" boolean[] isRankUsed;"},{"lineNumber":403,"author":{"gitId":"-"},"content":" boolean isUpdateNeeded \u003d false;"},{"lineNumber":404,"author":{"gitId":"-"},"content":" int answer;"},{"lineNumber":405,"author":{"gitId":"-"},"content":" int maxUnusedRank \u003d 0;"},{"lineNumber":406,"author":{"gitId":"-"},"content":""},{"lineNumber":407,"author":{"gitId":"-"},"content":" // Checks whether update is needed."},{"lineNumber":408,"author":{"gitId":"-"},"content":" for (FeedbackResponse response : responses) {"},{"lineNumber":409,"author":{"gitId":"-"},"content":" if (!(response instanceof FeedbackRankRecipientsResponse)) {"},{"lineNumber":410,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":411,"author":{"gitId":"-"},"content":" }"},{"lineNumber":412,"author":{"gitId":"-"},"content":" responseDetails \u003d ((FeedbackRankRecipientsResponse) response).getAnswer();"},{"lineNumber":413,"author":{"gitId":"-"},"content":" answer \u003d responseDetails.getAnswer();"},{"lineNumber":414,"author":{"gitId":"-"},"content":" if (answer \u003e maxRank) {"},{"lineNumber":415,"author":{"gitId":"-"},"content":" isUpdateNeeded \u003d true;"},{"lineNumber":416,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":417,"author":{"gitId":"-"},"content":" }"},{"lineNumber":418,"author":{"gitId":"-"},"content":" }"},{"lineNumber":419,"author":{"gitId":"-"},"content":""},{"lineNumber":420,"author":{"gitId":"-"},"content":" // Updates repeatedly, until all responses are consistent."},{"lineNumber":421,"author":{"gitId":"-"},"content":" while (isUpdateNeeded) {"},{"lineNumber":422,"author":{"gitId":"-"},"content":" isUpdateNeeded \u003d false; // will be set to true again once invalid rank appears after update"},{"lineNumber":423,"author":{"gitId":"-"},"content":" isRankUsed \u003d new boolean[maxRank];"},{"lineNumber":424,"author":{"gitId":"-"},"content":""},{"lineNumber":425,"author":{"gitId":"-"},"content":" // Obtains the largest unused rank."},{"lineNumber":426,"author":{"gitId":"-"},"content":" for (FeedbackResponse response : responses) {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" if (!(response instanceof FeedbackRankRecipientsResponse)) {"},{"lineNumber":428,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":429,"author":{"gitId":"-"},"content":" }"},{"lineNumber":430,"author":{"gitId":"-"},"content":" responseDetails \u003d ((FeedbackRankRecipientsResponse) response).getAnswer();"},{"lineNumber":431,"author":{"gitId":"-"},"content":" answer \u003d responseDetails.getAnswer();"},{"lineNumber":432,"author":{"gitId":"-"},"content":" if (answer \u003c\u003d maxRank) {"},{"lineNumber":433,"author":{"gitId":"-"},"content":" isRankUsed[answer - 1] \u003d true;"},{"lineNumber":434,"author":{"gitId":"-"},"content":" }"},{"lineNumber":435,"author":{"gitId":"-"},"content":" }"},{"lineNumber":436,"author":{"gitId":"-"},"content":" for (int i \u003d maxRank - 1; i \u003e\u003d 0; i--) {"},{"lineNumber":437,"author":{"gitId":"-"},"content":" if (!isRankUsed[i]) {"},{"lineNumber":438,"author":{"gitId":"-"},"content":" maxUnusedRank \u003d i + 1;"},{"lineNumber":439,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":440,"author":{"gitId":"-"},"content":" }"},{"lineNumber":441,"author":{"gitId":"-"},"content":" }"},{"lineNumber":442,"author":{"gitId":"-"},"content":" assert maxUnusedRank \u003e 0; // if update is needed, there must be at least one unused rank"},{"lineNumber":443,"author":{"gitId":"-"},"content":""},{"lineNumber":444,"author":{"gitId":"-"},"content":" for (FeedbackResponse response : responses) {"},{"lineNumber":445,"author":{"gitId":"-"},"content":" if (response instanceof FeedbackRankRecipientsResponse) {"},{"lineNumber":446,"author":{"gitId":"-"},"content":" responseDetails \u003d ((FeedbackRankRecipientsResponse) response).getAnswer();"},{"lineNumber":447,"author":{"gitId":"-"},"content":" answer \u003d responseDetails.getAnswer();"},{"lineNumber":448,"author":{"gitId":"-"},"content":" if (answer \u003e maxUnusedRank) {"},{"lineNumber":449,"author":{"gitId":"-"},"content":" answer--;"},{"lineNumber":450,"author":{"gitId":"-"},"content":" responseDetails.setAnswer(answer);"},{"lineNumber":451,"author":{"gitId":"-"},"content":" }"},{"lineNumber":452,"author":{"gitId":"-"},"content":" if (answer \u003e maxRank) {"},{"lineNumber":453,"author":{"gitId":"-"},"content":" isUpdateNeeded \u003d true; // sets the flag to true if the updated rank is still invalid"},{"lineNumber":454,"author":{"gitId":"-"},"content":" }"},{"lineNumber":455,"author":{"gitId":"-"},"content":" }"},{"lineNumber":456,"author":{"gitId":"-"},"content":" }"},{"lineNumber":457,"author":{"gitId":"-"},"content":" }"},{"lineNumber":458,"author":{"gitId":"-"},"content":" }"},{"lineNumber":459,"author":{"gitId":"-"},"content":""},{"lineNumber":460,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":461,"author":{"gitId":"domoberzin"},"content":" * Updates responses for a student when his team changes."},{"lineNumber":462,"author":{"gitId":"domoberzin"},"content":" * \u003cp\u003e"},{"lineNumber":463,"author":{"gitId":"domoberzin"},"content":" * This is done by deleting responses that are no longer relevant to him in his new team."},{"lineNumber":464,"author":{"gitId":"domoberzin"},"content":" * \u003c/p\u003e"},{"lineNumber":465,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":466,"author":{"gitId":"domoberzin"},"content":" public void updateFeedbackResponsesForChangingTeam(Course course, String newEmail, Team newTeam, Team oldTeam)"},{"lineNumber":467,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":468,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":469,"author":{"gitId":"domoberzin"},"content":" FeedbackQuestion qn;"},{"lineNumber":470,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":471,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackResponse\u003e responsesFromUser \u003d"},{"lineNumber":472,"author":{"gitId":"domoberzin"},"content":" getFeedbackResponsesFromGiverForCourse(course.getId(), newEmail);"},{"lineNumber":473,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":474,"author":{"gitId":"domoberzin"},"content":" for (FeedbackResponse response : responsesFromUser) {"},{"lineNumber":475,"author":{"gitId":"domoberzin"},"content":" qn \u003d fqLogic.getFeedbackQuestion(response.getId());"},{"lineNumber":476,"author":{"gitId":"domoberzin"},"content":" if (qn !\u003d null \u0026\u0026 qn.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS) {"},{"lineNumber":477,"author":{"gitId":"domoberzin"},"content":" deleteFeedbackResponsesForQuestionCascade(qn.getId());"},{"lineNumber":478,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":479,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":480,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":481,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackResponse\u003e responsesToUser \u003d"},{"lineNumber":482,"author":{"gitId":"domoberzin"},"content":" getFeedbackResponsesForRecipientForCourse(course.getId(), newEmail);"},{"lineNumber":483,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":484,"author":{"gitId":"domoberzin"},"content":" for (FeedbackResponse response : responsesToUser) {"},{"lineNumber":485,"author":{"gitId":"domoberzin"},"content":" qn \u003d fqLogic.getFeedbackQuestion(response.getId());"},{"lineNumber":486,"author":{"gitId":"domoberzin"},"content":" if (qn !\u003d null \u0026\u0026 qn.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS) {"},{"lineNumber":487,"author":{"gitId":"domoberzin"},"content":" deleteFeedbackResponsesForQuestionCascade(qn.getId());"},{"lineNumber":488,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":489,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":490,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":491,"author":{"gitId":"domoberzin"},"content":" boolean isOldTeamEmpty \u003d usersLogic.getStudentsForTeam(oldTeam.getName(), course.getId()).isEmpty();"},{"lineNumber":492,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":493,"author":{"gitId":"domoberzin"},"content":" if (isOldTeamEmpty) {"},{"lineNumber":494,"author":{"gitId":"domoberzin"},"content":" deleteFeedbackResponsesForCourseCascade(course.getId(), oldTeam.getName());"},{"lineNumber":495,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":496,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":497,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":498,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":499,"author":{"gitId":"domoberzin"},"content":" * Updates responses for a student when his section changes."},{"lineNumber":500,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":501,"author":{"gitId":"domoberzin"},"content":" public void updateFeedbackResponsesForChangingSection(Course course, String newEmail, Section newSection)"},{"lineNumber":502,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":503,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":504,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackResponse\u003e responsesFromUser \u003d"},{"lineNumber":505,"author":{"gitId":"domoberzin"},"content":" getFeedbackResponsesFromGiverForCourse(course.getId(), newEmail);"},{"lineNumber":506,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":507,"author":{"gitId":"domoberzin"},"content":" for (FeedbackResponse response : responsesFromUser) {"},{"lineNumber":508,"author":{"gitId":"domoberzin"},"content":" response.setGiverSection(newSection);"},{"lineNumber":509,"author":{"gitId":"domoberzin"},"content":" frDb.updateFeedbackResponse(response);"},{"lineNumber":510,"author":{"gitId":"domoberzin"},"content":" frcLogic.updateFeedbackResponseCommentsForResponse(response);"},{"lineNumber":511,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":512,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":513,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackResponse\u003e responsesToUser \u003d"},{"lineNumber":514,"author":{"gitId":"domoberzin"},"content":" getFeedbackResponsesForRecipientForCourse(course.getId(), newEmail);"},{"lineNumber":515,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":516,"author":{"gitId":"domoberzin"},"content":" for (FeedbackResponse response : responsesToUser) {"},{"lineNumber":517,"author":{"gitId":"domoberzin"},"content":" response.setRecipientSection(newSection);"},{"lineNumber":518,"author":{"gitId":"domoberzin"},"content":" frDb.updateFeedbackResponse(response);"},{"lineNumber":519,"author":{"gitId":"domoberzin"},"content":" frcLogic.updateFeedbackResponseCommentsForResponse(response);"},{"lineNumber":520,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":521,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":522,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":523,"author":{"gitId":"marquestye"},"content":" /**"},{"lineNumber":524,"author":{"gitId":"marquestye"},"content":" * Updates a student\u0027s email in their given/received responses."},{"lineNumber":525,"author":{"gitId":"marquestye"},"content":" */"},{"lineNumber":526,"author":{"gitId":"marquestye"},"content":" public void updateFeedbackResponsesForChangingEmail(String courseId, String oldEmail, String newEmail)"},{"lineNumber":527,"author":{"gitId":"marquestye"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":528,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":529,"author":{"gitId":"marquestye"},"content":" List\u003cFeedbackResponse\u003e responsesFromUser \u003d"},{"lineNumber":530,"author":{"gitId":"marquestye"},"content":" getFeedbackResponsesFromGiverForCourse(courseId, oldEmail);"},{"lineNumber":531,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":532,"author":{"gitId":"marquestye"},"content":" for (FeedbackResponse response : responsesFromUser) {"},{"lineNumber":533,"author":{"gitId":"marquestye"},"content":" response.setGiver(newEmail);"},{"lineNumber":534,"author":{"gitId":"marquestye"},"content":" frDb.updateFeedbackResponse(response);"},{"lineNumber":535,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":536,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":537,"author":{"gitId":"marquestye"},"content":" List\u003cFeedbackResponse\u003e responsesToUser \u003d"},{"lineNumber":538,"author":{"gitId":"marquestye"},"content":" getFeedbackResponsesForRecipientForCourse(courseId, oldEmail);"},{"lineNumber":539,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":540,"author":{"gitId":"marquestye"},"content":" for (FeedbackResponse response : responsesToUser) {"},{"lineNumber":541,"author":{"gitId":"marquestye"},"content":" response.setRecipient(newEmail);"},{"lineNumber":542,"author":{"gitId":"marquestye"},"content":" frDb.updateFeedbackResponse(response);"},{"lineNumber":543,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":544,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":545,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":546,"author":{"gitId":"xenosf"},"content":" private List\u003cFeedbackQuestion\u003e getQuestionsForSession("},{"lineNumber":547,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession, @Nullable UUID questionId) {"},{"lineNumber":548,"author":{"gitId":"xenosf"},"content":" if (questionId \u003d\u003d null) {"},{"lineNumber":549,"author":{"gitId":"xenosf"},"content":" return fqLogic.getFeedbackQuestionsForSession(feedbackSession);"},{"lineNumber":550,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":551,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion fq \u003d fqLogic.getFeedbackQuestion(questionId);"},{"lineNumber":552,"author":{"gitId":"xenosf"},"content":" return fq \u003d\u003d null ? Collections.emptyList() : Collections.singletonList(fq);"},{"lineNumber":553,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":554,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":555,"author":{"gitId":"xenosf"},"content":" private SqlSessionResultsBundle buildResultsBundle("},{"lineNumber":556,"author":{"gitId":"xenosf"},"content":" boolean isCourseWide, FeedbackSession feedbackSession, String courseId, String sectionName, UUID questionId,"},{"lineNumber":557,"author":{"gitId":"xenosf"},"content":" boolean isInstructor, String userEmail, Instructor instructor, Student student,"},{"lineNumber":558,"author":{"gitId":"xenosf"},"content":" SqlCourseRoster roster, List\u003cFeedbackQuestion\u003e allQuestions,"},{"lineNumber":559,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e allResponses, boolean isPreviewResults) {"},{"lineNumber":560,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":561,"author":{"gitId":"xenosf"},"content":" Set\u003cFeedbackQuestion\u003e questionsNotVisibleToInstructors \u003d new HashSet\u003c\u003e();"},{"lineNumber":562,"author":{"gitId":"xenosf"},"content":" for (FeedbackQuestion qn : allQuestions) {"},{"lineNumber":563,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":564,"author":{"gitId":"xenosf"},"content":" // set questions that should not be visible to instructors if results are being previewed"},{"lineNumber":565,"author":{"gitId":"xenosf"},"content":" if (isPreviewResults \u0026\u0026 !checkCanInstructorsSeeQuestion(qn)) {"},{"lineNumber":566,"author":{"gitId":"xenosf"},"content":" questionsNotVisibleToInstructors.add(qn);"},{"lineNumber":567,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":568,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":569,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":570,"author":{"gitId":"xenosf"},"content":" // load comment(s)"},{"lineNumber":571,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e allComments;"},{"lineNumber":572,"author":{"gitId":"xenosf"},"content":" if (questionId \u003d\u003d null) {"},{"lineNumber":573,"author":{"gitId":"xenosf"},"content":" allComments \u003d frcLogic.getFeedbackResponseCommentForSessionInSection("},{"lineNumber":574,"author":{"gitId":"xenosf"},"content":" courseId, feedbackSession.getName(), sectionName);"},{"lineNumber":575,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":576,"author":{"gitId":"xenosf"},"content":" allComments \u003d frcLogic.getFeedbackResponseCommentForQuestionInSection(questionId, sectionName);"},{"lineNumber":577,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":578,"author":{"gitId":"xenosf"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":579,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":580,"author":{"gitId":"xenosf"},"content":" // related questions, responses, and comment"},{"lineNumber":581,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackQuestion\u003e relatedQuestions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":582,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e relatedResponses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":583,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackResponse, List\u003cFeedbackResponseComment\u003e\u003e relatedCommentsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":584,"author":{"gitId":"xenosf"},"content":" Set\u003cFeedbackQuestion\u003e relatedQuestionsNotVisibleForPreviewSet \u003d new HashSet\u003c\u003e();"},{"lineNumber":585,"author":{"gitId":"xenosf"},"content":" Set\u003cFeedbackQuestion\u003e relatedQuestionsWithCommentNotVisibleForPreview \u003d new HashSet\u003c\u003e();"},{"lineNumber":586,"author":{"gitId":"xenosf"},"content":" if (isCourseWide) {"},{"lineNumber":587,"author":{"gitId":"xenosf"},"content":" // all questions are related questions when viewing course-wide result"},{"lineNumber":588,"author":{"gitId":"xenosf"},"content":" for (FeedbackQuestion qn : allQuestions) {"},{"lineNumber":589,"author":{"gitId":"xenosf"},"content":" relatedQuestions.add(qn);"},{"lineNumber":590,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":591,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":592,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":593,"author":{"gitId":"xenosf"},"content":" Set\u003cString\u003e studentsEmailInTeam \u003d new HashSet\u003c\u003e();"},{"lineNumber":594,"author":{"gitId":"xenosf"},"content":" if (student !\u003d null) {"},{"lineNumber":595,"author":{"gitId":"xenosf"},"content":" for (Student studentInTeam"},{"lineNumber":596,"author":{"gitId":"mingyuanc"},"content":" : roster.getTeamToMembersTable().getOrDefault(student.getTeam().getName(), Collections.emptyList())) {"},{"lineNumber":597,"author":{"gitId":"xenosf"},"content":" studentsEmailInTeam.add(studentInTeam.getEmail());"},{"lineNumber":598,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":599,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":600,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":601,"author":{"gitId":"xenosf"},"content":" // visibility table for each response and comment"},{"lineNumber":602,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackResponse, Boolean\u003e responseGiverVisibilityTable \u003d new HashMap\u003c\u003e();"},{"lineNumber":603,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackResponse, Boolean\u003e responseRecipientVisibilityTable \u003d new HashMap\u003c\u003e();"},{"lineNumber":604,"author":{"gitId":"xenosf"},"content":" Map\u003cLong, Boolean\u003e commentVisibilityTable \u003d new HashMap\u003c\u003e();"},{"lineNumber":605,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":606,"author":{"gitId":"xenosf"},"content":" // build response"},{"lineNumber":607,"author":{"gitId":"xenosf"},"content":" for (FeedbackResponse response : allResponses) {"},{"lineNumber":608,"author":{"gitId":"xenosf"},"content":" if (isPreviewResults"},{"lineNumber":609,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 relatedQuestionsNotVisibleForPreviewSet.contains(response.getFeedbackQuestion())) {"},{"lineNumber":610,"author":{"gitId":"xenosf"},"content":" // corresponding question\u0027s responses will not be shown to previewer, ignore the response"},{"lineNumber":611,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":612,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":613,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion correspondingQuestion \u003d response.getFeedbackQuestion();"},{"lineNumber":614,"author":{"gitId":"xenosf"},"content":" if (correspondingQuestion \u003d\u003d null) {"},{"lineNumber":615,"author":{"gitId":"xenosf"},"content":" // orphan response without corresponding question, ignore it"},{"lineNumber":616,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":617,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":618,"author":{"gitId":"xenosf"},"content":" // check visibility of response"},{"lineNumber":619,"author":{"gitId":"xenosf"},"content":" boolean isVisibleResponse \u003d isResponseVisibleForUser("},{"lineNumber":620,"author":{"gitId":"xenosf"},"content":" userEmail, isInstructor, student, studentsEmailInTeam, response, correspondingQuestion, instructor);"},{"lineNumber":621,"author":{"gitId":"xenosf"},"content":" if (!isVisibleResponse) {"},{"lineNumber":622,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":623,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":624,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":625,"author":{"gitId":"xenosf"},"content":" // if previewing results and corresponding question should not be visible to instructors,"},{"lineNumber":626,"author":{"gitId":"xenosf"},"content":" // note down the question and do not add the response"},{"lineNumber":627,"author":{"gitId":"xenosf"},"content":" if (isPreviewResults \u0026\u0026 questionsNotVisibleToInstructors.contains(response.getFeedbackQuestion())) {"},{"lineNumber":628,"author":{"gitId":"xenosf"},"content":" relatedQuestionsNotVisibleForPreviewSet.add(response.getFeedbackQuestion());"},{"lineNumber":629,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":630,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":631,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":632,"author":{"gitId":"xenosf"},"content":" // if there are viewable responses, the corresponding question becomes related"},{"lineNumber":633,"author":{"gitId":"xenosf"},"content":" relatedQuestions.add(response.getFeedbackQuestion());"},{"lineNumber":634,"author":{"gitId":"xenosf"},"content":" relatedResponses.add(response);"},{"lineNumber":635,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":636,"author":{"gitId":"xenosf"},"content":" // generate giver/recipient name visibility table"},{"lineNumber":637,"author":{"gitId":"xenosf"},"content":" responseGiverVisibilityTable.put(response,"},{"lineNumber":638,"author":{"gitId":"xenosf"},"content":" isNameVisibleToUser(correspondingQuestion, response, userEmail, isInstructor, true, roster));"},{"lineNumber":639,"author":{"gitId":"xenosf"},"content":" responseRecipientVisibilityTable.put(response,"},{"lineNumber":640,"author":{"gitId":"xenosf"},"content":" isNameVisibleToUser(correspondingQuestion, response, userEmail, isInstructor, false, roster));"},{"lineNumber":641,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":642,"author":{"gitId":"xenosf"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":643,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":644,"author":{"gitId":"xenosf"},"content":" // build comment"},{"lineNumber":645,"author":{"gitId":"xenosf"},"content":" for (FeedbackResponseComment frc : allComments) {"},{"lineNumber":646,"author":{"gitId":"xenosf"},"content":" FeedbackResponse relatedResponse \u003d frc.getFeedbackResponse();"},{"lineNumber":647,"author":{"gitId":"xenosf"},"content":" // the comment needs to be relevant to the question and response"},{"lineNumber":648,"author":{"gitId":"xenosf"},"content":" if (relatedResponse \u003d\u003d null) {"},{"lineNumber":649,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":650,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":651,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion relatedQuestion \u003d relatedResponse.getFeedbackQuestion();"},{"lineNumber":652,"author":{"gitId":"xenosf"},"content":" if (relatedQuestion \u003d\u003d null) {"},{"lineNumber":653,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":654,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":655,"author":{"gitId":"xenosf"},"content":" // check visibility of comment"},{"lineNumber":656,"author":{"gitId":"xenosf"},"content":" boolean isVisibleResponseComment \u003d frcLogic.checkIsResponseCommentVisibleForUser("},{"lineNumber":657,"author":{"gitId":"xenosf"},"content":" userEmail, isInstructor, student, studentsEmailInTeam, relatedResponse, relatedQuestion, frc);"},{"lineNumber":658,"author":{"gitId":"xenosf"},"content":" if (!isVisibleResponseComment) {"},{"lineNumber":659,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":660,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":661,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":662,"author":{"gitId":"xenosf"},"content":" // if previewing results and the comment should not be visible to instructors,"},{"lineNumber":663,"author":{"gitId":"xenosf"},"content":" // note down the corresponding question and do not add the comment"},{"lineNumber":664,"author":{"gitId":"xenosf"},"content":" if (isPreviewResults \u0026\u0026 !checkCanInstructorsSeeComment(frc)) {"},{"lineNumber":665,"author":{"gitId":"xenosf"},"content":" relatedQuestionsWithCommentNotVisibleForPreview.add(frc.getFeedbackResponse().getFeedbackQuestion());"},{"lineNumber":666,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":667,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":668,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":669,"author":{"gitId":"xenosf"},"content":" relatedCommentsMap.computeIfAbsent(relatedResponse, key -\u003e new ArrayList\u003c\u003e()).add(frc);"},{"lineNumber":670,"author":{"gitId":"xenosf"},"content":" // generate comment giver name visibility table"},{"lineNumber":671,"author":{"gitId":"xenosf"},"content":" commentVisibilityTable.put(frc.getId(),"},{"lineNumber":672,"author":{"gitId":"xenosf"},"content":" frcLogic.checkIsNameVisibleToUser(frc, relatedResponse, userEmail, roster));"},{"lineNumber":673,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":674,"author":{"gitId":"xenosf"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":675,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":676,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e existingResponses \u003d new ArrayList\u003c\u003e(relatedResponses);"},{"lineNumber":677,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e missingResponses \u003d Collections.emptyList();"},{"lineNumber":678,"author":{"gitId":"xenosf"},"content":" if (isCourseWide) {"},{"lineNumber":679,"author":{"gitId":"xenosf"},"content":" missingResponses \u003d buildMissingResponses("},{"lineNumber":680,"author":{"gitId":"xenosf"},"content":" instructor, responseGiverVisibilityTable, responseRecipientVisibilityTable, relatedQuestions,"},{"lineNumber":681,"author":{"gitId":"xenosf"},"content":" existingResponses, roster, sectionName);"},{"lineNumber":682,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":683,"author":{"gitId":"xenosf"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":684,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":685,"author":{"gitId":"xenosf"},"content":" return new SqlSessionResultsBundle(relatedQuestions, relatedQuestionsNotVisibleForPreviewSet,"},{"lineNumber":686,"author":{"gitId":"xenosf"},"content":" relatedQuestionsWithCommentNotVisibleForPreview, existingResponses, missingResponses,"},{"lineNumber":687,"author":{"gitId":"xenosf"},"content":" responseGiverVisibilityTable, responseRecipientVisibilityTable, relatedCommentsMap,"},{"lineNumber":688,"author":{"gitId":"xenosf"},"content":" commentVisibilityTable, roster);"},{"lineNumber":689,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":690,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":691,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":692,"author":{"gitId":"xenosf"},"content":" * Gets the session result for a feedback session."},{"lineNumber":693,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":694,"author":{"gitId":"xenosf"},"content":" * @param feedbackSession the feedback session"},{"lineNumber":695,"author":{"gitId":"xenosf"},"content":" * @param courseId the ID of the course"},{"lineNumber":696,"author":{"gitId":"xenosf"},"content":" * @param instructorEmail the instructor viewing the feedback session"},{"lineNumber":697,"author":{"gitId":"xenosf"},"content":" * @param questionId if not null, will only return partial bundle for the question"},{"lineNumber":698,"author":{"gitId":"xenosf"},"content":" * @param sectionName if not null, will only return partial bundle for the section"},{"lineNumber":699,"author":{"gitId":"xenosf"},"content":" * @param fetchType if not null, will fetch responses by giver, receiver sections, or both"},{"lineNumber":700,"author":{"gitId":"xenosf"},"content":" * @return the session result bundle"},{"lineNumber":701,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":702,"author":{"gitId":"xenosf"},"content":" public SqlSessionResultsBundle getSessionResultsForCourse("},{"lineNumber":703,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession, String courseId, String instructorEmail,"},{"lineNumber":704,"author":{"gitId":"xenosf"},"content":" @Nullable UUID questionId, @Nullable String sectionName, @Nullable FeedbackResultFetchType fetchType) {"},{"lineNumber":705,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":706,"author":{"gitId":"xenosf"},"content":" SqlCourseRoster roster \u003d new SqlCourseRoster("},{"lineNumber":707,"author":{"gitId":"xenosf"},"content":" usersLogic.getStudentsForCourse(courseId),"},{"lineNumber":708,"author":{"gitId":"xenosf"},"content":" usersLogic.getInstructorsForCourse(courseId));"},{"lineNumber":709,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":710,"author":{"gitId":"xenosf"},"content":" // load question(s)"},{"lineNumber":711,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackQuestion\u003e allQuestions \u003d getQuestionsForSession(feedbackSession, questionId);"},{"lineNumber":712,"author":{"gitId":"xenosf"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":713,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":714,"author":{"gitId":"xenosf"},"content":" // load response(s)"},{"lineNumber":715,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e allResponses;"},{"lineNumber":716,"author":{"gitId":"xenosf"},"content":" // load all response for instructors and passively filter them later"},{"lineNumber":717,"author":{"gitId":"xenosf"},"content":" if (questionId \u003d\u003d null) {"},{"lineNumber":718,"author":{"gitId":"xenosf"},"content":" allResponses \u003d getFeedbackResponsesForSessionInSection(feedbackSession, courseId, sectionName, fetchType);"},{"lineNumber":719,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":720,"author":{"gitId":"xenosf"},"content":" allResponses \u003d getFeedbackResponsesForQuestionInSection(questionId, sectionName, fetchType);"},{"lineNumber":721,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":722,"author":{"gitId":"xenosf"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":723,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":724,"author":{"gitId":"xenosf"},"content":" // consider the current viewing user"},{"lineNumber":725,"author":{"gitId":"xenosf"},"content":" Instructor instructor \u003d usersLogic.getInstructorForEmail(courseId, instructorEmail);"},{"lineNumber":726,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":727,"author":{"gitId":"xenosf"},"content":" return buildResultsBundle(true, feedbackSession, courseId, sectionName, questionId, true, instructorEmail,"},{"lineNumber":728,"author":{"gitId":"xenosf"},"content":" instructor, null, roster, allQuestions, allResponses, false);"},{"lineNumber":729,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":730,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":731,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":732,"author":{"gitId":"xenosf"},"content":" * Gets the session result for a feedback session for the given user."},{"lineNumber":733,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":734,"author":{"gitId":"xenosf"},"content":" * @param feedbackSession the feedback session"},{"lineNumber":735,"author":{"gitId":"xenosf"},"content":" * @param courseId the ID of the course"},{"lineNumber":736,"author":{"gitId":"xenosf"},"content":" * @param userEmail the user viewing the feedback session"},{"lineNumber":737,"author":{"gitId":"xenosf"},"content":" * @param isInstructor true if the user is an instructor"},{"lineNumber":738,"author":{"gitId":"xenosf"},"content":" * @param questionId if not null, will only return partial bundle for the question"},{"lineNumber":739,"author":{"gitId":"xenosf"},"content":" * @param isPreviewResults true if getting session results for preview purpose"},{"lineNumber":740,"author":{"gitId":"xenosf"},"content":" * @return the session result bundle"},{"lineNumber":741,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":742,"author":{"gitId":"xenosf"},"content":" public SqlSessionResultsBundle getSessionResultsForUser("},{"lineNumber":743,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession, String courseId, String userEmail, boolean isInstructor,"},{"lineNumber":744,"author":{"gitId":"xenosf"},"content":" @Nullable UUID questionId, boolean isPreviewResults) {"},{"lineNumber":745,"author":{"gitId":"xenosf"},"content":" SqlCourseRoster roster \u003d new SqlCourseRoster("},{"lineNumber":746,"author":{"gitId":"xenosf"},"content":" usersLogic.getStudentsForCourse(courseId),"},{"lineNumber":747,"author":{"gitId":"xenosf"},"content":" usersLogic.getInstructorsForCourse(courseId));"},{"lineNumber":748,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":749,"author":{"gitId":"xenosf"},"content":" // load question(s)"},{"lineNumber":750,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackQuestion\u003e allQuestions \u003d getQuestionsForSession(feedbackSession, questionId);"},{"lineNumber":751,"author":{"gitId":"xenosf"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":752,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":753,"author":{"gitId":"xenosf"},"content":" // load response(s)"},{"lineNumber":754,"author":{"gitId":"xenosf"},"content":" Student student \u003d isInstructor ? null : usersLogic.getStudentForEmail(courseId, userEmail);"},{"lineNumber":755,"author":{"gitId":"xenosf"},"content":" Instructor instructor \u003d isInstructor ? usersLogic.getInstructorForEmail(courseId, userEmail) : null;"},{"lineNumber":756,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e allResponses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":757,"author":{"gitId":"xenosf"},"content":" for (FeedbackQuestion question : allQuestions) {"},{"lineNumber":758,"author":{"gitId":"xenosf"},"content":" // load viewable responses for students/instructors proactively"},{"lineNumber":759,"author":{"gitId":"xenosf"},"content":" // this is cost-effective as in most of time responses for the whole session will not be viewable to individuals"},{"lineNumber":760,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e viewableResponses \u003d isInstructor"},{"lineNumber":761,"author":{"gitId":"xenosf"},"content":" ? getFeedbackResponsesToOrFromInstructorForQuestion(question, instructor)"},{"lineNumber":762,"author":{"gitId":"xenosf"},"content":" : getViewableFeedbackResponsesForStudentForQuestion(question, student, roster);"},{"lineNumber":763,"author":{"gitId":"xenosf"},"content":" allResponses.addAll(viewableResponses);"},{"lineNumber":764,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":765,"author":{"gitId":"xenosf"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":766,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":767,"author":{"gitId":"xenosf"},"content":" return buildResultsBundle(false, feedbackSession, courseId, null, questionId, isInstructor, userEmail,"},{"lineNumber":768,"author":{"gitId":"xenosf"},"content":" instructor, student, roster, allQuestions, allResponses, isPreviewResults);"},{"lineNumber":769,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":770,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":771,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":772,"author":{"gitId":"xenosf"},"content":" * Builds viewable missing responses for the session for instructor."},{"lineNumber":773,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":774,"author":{"gitId":"xenosf"},"content":" * @param instructor the instructor"},{"lineNumber":775,"author":{"gitId":"xenosf"},"content":" * @param responseGiverVisibilityTable"},{"lineNumber":776,"author":{"gitId":"xenosf"},"content":" * the giver visibility table which will be updated with the visibility of missing responses"},{"lineNumber":777,"author":{"gitId":"xenosf"},"content":" * @param responseRecipientVisibilityTable"},{"lineNumber":778,"author":{"gitId":"xenosf"},"content":" * the recipient visibility table which will be updated with the visibility of missing responses"},{"lineNumber":779,"author":{"gitId":"xenosf"},"content":" * @param relatedQuestions the relevant questions"},{"lineNumber":780,"author":{"gitId":"xenosf"},"content":" * @param existingResponses existing responses"},{"lineNumber":781,"author":{"gitId":"xenosf"},"content":" * @param courseRoster the course roster"},{"lineNumber":782,"author":{"gitId":"xenosf"},"content":" * @param sectionName if not null, will only build missing responses for the section"},{"lineNumber":783,"author":{"gitId":"xenosf"},"content":" * @return a list of missing responses for the session."},{"lineNumber":784,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":785,"author":{"gitId":"xenosf"},"content":" private List\u003cFeedbackResponse\u003e buildMissingResponses("},{"lineNumber":786,"author":{"gitId":"xenosf"},"content":" Instructor instructor, Map\u003cFeedbackResponse, Boolean\u003e responseGiverVisibilityTable,"},{"lineNumber":787,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackResponse, Boolean\u003e responseRecipientVisibilityTable, List\u003cFeedbackQuestion\u003e relatedQuestions,"},{"lineNumber":788,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e existingResponses, SqlCourseRoster courseRoster, @Nullable String sectionName) {"},{"lineNumber":789,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":790,"author":{"gitId":"xenosf"},"content":" // first get all possible giver recipient pairs"},{"lineNumber":791,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackQuestion, Map\u003cString, Set\u003cString\u003e\u003e\u003e questionCompleteGiverRecipientMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":792,"author":{"gitId":"xenosf"},"content":" for (FeedbackQuestion feedbackQuestion : relatedQuestions) {"},{"lineNumber":793,"author":{"gitId":"xenosf"},"content":" if (feedbackQuestion.getQuestionDetailsCopy().shouldGenerateMissingResponses(feedbackQuestion)) {"},{"lineNumber":794,"author":{"gitId":"xenosf"},"content":" questionCompleteGiverRecipientMap.put(feedbackQuestion,"},{"lineNumber":795,"author":{"gitId":"xenosf"},"content":" fqLogic.buildCompleteGiverRecipientMap(feedbackQuestion, courseRoster));"},{"lineNumber":796,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":797,"author":{"gitId":"xenosf"},"content":" questionCompleteGiverRecipientMap.put(feedbackQuestion, new HashMap\u003c\u003e());"},{"lineNumber":798,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":799,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":800,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":801,"author":{"gitId":"xenosf"},"content":" // remove the existing responses in those pairs"},{"lineNumber":802,"author":{"gitId":"xenosf"},"content":" for (FeedbackResponse existingResponse : existingResponses) {"},{"lineNumber":803,"author":{"gitId":"xenosf"},"content":" Map\u003cString, Set\u003cString\u003e\u003e currGiverRecipientMap \u003d"},{"lineNumber":804,"author":{"gitId":"xenosf"},"content":" questionCompleteGiverRecipientMap.get(existingResponse.getFeedbackQuestion());"},{"lineNumber":805,"author":{"gitId":"xenosf"},"content":" if (!currGiverRecipientMap.containsKey(existingResponse.getGiver())) {"},{"lineNumber":806,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":807,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":808,"author":{"gitId":"xenosf"},"content":" currGiverRecipientMap.get(existingResponse.getGiver()).remove(existingResponse.getRecipient());"},{"lineNumber":809,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":810,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":811,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e missingResponses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":812,"author":{"gitId":"xenosf"},"content":" // build dummy responses"},{"lineNumber":813,"author":{"gitId":"xenosf"},"content":" for (Map.Entry\u003cFeedbackQuestion, Map\u003cString, Set\u003cString\u003e\u003e\u003e currGiverRecipientMapEntry"},{"lineNumber":814,"author":{"gitId":"xenosf"},"content":" : questionCompleteGiverRecipientMap.entrySet()) {"},{"lineNumber":815,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion correspondingQuestion \u003d currGiverRecipientMapEntry.getKey();"},{"lineNumber":816,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":817,"author":{"gitId":"xenosf"},"content":" for (Map.Entry\u003cString, Set\u003cString\u003e\u003e giverRecipientEntry"},{"lineNumber":818,"author":{"gitId":"xenosf"},"content":" : currGiverRecipientMapEntry.getValue().entrySet()) {"},{"lineNumber":819,"author":{"gitId":"xenosf"},"content":" // giver"},{"lineNumber":820,"author":{"gitId":"xenosf"},"content":" String giverIdentifier \u003d giverRecipientEntry.getKey();"},{"lineNumber":821,"author":{"gitId":"xenosf"},"content":" SqlCourseRoster.ParticipantInfo giverInfo \u003d courseRoster.getInfoForIdentifier(giverIdentifier);"},{"lineNumber":822,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":823,"author":{"gitId":"xenosf"},"content":" for (String recipientIdentifier : giverRecipientEntry.getValue()) {"},{"lineNumber":824,"author":{"gitId":"xenosf"},"content":" // recipient"},{"lineNumber":825,"author":{"gitId":"xenosf"},"content":" SqlCourseRoster.ParticipantInfo recipientInfo \u003d courseRoster.getInfoForIdentifier(recipientIdentifier);"},{"lineNumber":826,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":827,"author":{"gitId":"xenosf"},"content":" // skip responses not in current section"},{"lineNumber":828,"author":{"gitId":"xenosf"},"content":" if (sectionName !\u003d null"},{"lineNumber":829,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 !giverInfo.getSectionName().equals(sectionName)"},{"lineNumber":830,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 !recipientInfo.getSectionName().equals(sectionName)) {"},{"lineNumber":831,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":832,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":833,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":834,"author":{"gitId":"xenosf"},"content":" FeedbackResponse missingResponse \u003d new FeedbackMissingResponse("},{"lineNumber":835,"author":{"gitId":"xenosf"},"content":" correspondingQuestion,"},{"lineNumber":836,"author":{"gitId":"xenosf"},"content":" giverIdentifier, giverInfo.getSectionName(),"},{"lineNumber":837,"author":{"gitId":"xenosf"},"content":" recipientIdentifier, recipientInfo.getSectionName());"},{"lineNumber":838,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":839,"author":{"gitId":"xenosf"},"content":" // check visibility of the missing response"},{"lineNumber":840,"author":{"gitId":"xenosf"},"content":" boolean isVisibleResponse \u003d isResponseVisibleForUser("},{"lineNumber":841,"author":{"gitId":"xenosf"},"content":" instructor.getEmail(), true, null, Collections.emptySet(),"},{"lineNumber":842,"author":{"gitId":"xenosf"},"content":" missingResponse, correspondingQuestion, instructor);"},{"lineNumber":843,"author":{"gitId":"xenosf"},"content":" if (!isVisibleResponse) {"},{"lineNumber":844,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":845,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":846,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":847,"author":{"gitId":"xenosf"},"content":" // generate giver/recipient name visibility table"},{"lineNumber":848,"author":{"gitId":"xenosf"},"content":" responseGiverVisibilityTable.put(missingResponse,"},{"lineNumber":849,"author":{"gitId":"xenosf"},"content":" isNameVisibleToUser(correspondingQuestion, missingResponse,"},{"lineNumber":850,"author":{"gitId":"xenosf"},"content":" instructor.getEmail(), true, true, courseRoster));"},{"lineNumber":851,"author":{"gitId":"xenosf"},"content":" responseRecipientVisibilityTable.put(missingResponse,"},{"lineNumber":852,"author":{"gitId":"xenosf"},"content":" isNameVisibleToUser(correspondingQuestion, missingResponse,"},{"lineNumber":853,"author":{"gitId":"xenosf"},"content":" instructor.getEmail(), true, false, courseRoster));"},{"lineNumber":854,"author":{"gitId":"xenosf"},"content":" missingResponses.add(missingResponse);"},{"lineNumber":855,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":856,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":857,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":858,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":859,"author":{"gitId":"xenosf"},"content":" return missingResponses;"},{"lineNumber":860,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":861,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":862,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":863,"author":{"gitId":"xenosf"},"content":" * Checks whether the giver name of a response is visible to an user."},{"lineNumber":864,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":865,"author":{"gitId":"xenosf"},"content":" public boolean isNameVisibleToUser("},{"lineNumber":866,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question,"},{"lineNumber":867,"author":{"gitId":"xenosf"},"content":" FeedbackResponse response,"},{"lineNumber":868,"author":{"gitId":"xenosf"},"content":" String userEmail,"},{"lineNumber":869,"author":{"gitId":"xenosf"},"content":" boolean isInstructor, boolean isGiverName, SqlCourseRoster roster) {"},{"lineNumber":870,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":871,"author":{"gitId":"xenosf"},"content":" if (question \u003d\u003d null) {"},{"lineNumber":872,"author":{"gitId":"xenosf"},"content":" return false;"},{"lineNumber":873,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":874,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":875,"author":{"gitId":"xenosf"},"content":" // Early return if user is giver"},{"lineNumber":876,"author":{"gitId":"xenosf"},"content":" if (question.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS) {"},{"lineNumber":877,"author":{"gitId":"xenosf"},"content":" // if response is given by team, then anyone in the team can see the response"},{"lineNumber":878,"author":{"gitId":"xenosf"},"content":" if (roster.isStudentInTeam(userEmail, response.getGiver())) {"},{"lineNumber":879,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":880,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":881,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":882,"author":{"gitId":"xenosf"},"content":" if (response.getGiver().equals(userEmail)) {"},{"lineNumber":883,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":884,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":885,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":886,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":887,"author":{"gitId":"xenosf"},"content":" return isFeedbackParticipantNameVisibleToUser(question, response,"},{"lineNumber":888,"author":{"gitId":"xenosf"},"content":" userEmail, isInstructor, isGiverName, roster);"},{"lineNumber":889,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":890,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":891,"author":{"gitId":"xenosf"},"content":" private boolean isFeedbackParticipantNameVisibleToUser("},{"lineNumber":892,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question, FeedbackResponse response,"},{"lineNumber":893,"author":{"gitId":"xenosf"},"content":" String userEmail, boolean isInstructor, boolean isGiverName, SqlCourseRoster roster) {"},{"lineNumber":894,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackParticipantType\u003e showNameTo \u003d isGiverName"},{"lineNumber":895,"author":{"gitId":"xenosf"},"content":" ? question.getShowGiverNameTo()"},{"lineNumber":896,"author":{"gitId":"xenosf"},"content":" : question.getShowRecipientNameTo();"},{"lineNumber":897,"author":{"gitId":"xenosf"},"content":" for (FeedbackParticipantType type : showNameTo) {"},{"lineNumber":898,"author":{"gitId":"xenosf"},"content":" switch (type) {"},{"lineNumber":899,"author":{"gitId":"xenosf"},"content":" case INSTRUCTORS:"},{"lineNumber":900,"author":{"gitId":"xenosf"},"content":" if (roster.getInstructorForEmail(userEmail) !\u003d null \u0026\u0026 isInstructor) {"},{"lineNumber":901,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":902,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":903,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":904,"author":{"gitId":"xenosf"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":905,"author":{"gitId":"xenosf"},"content":" case OWN_TEAM_MEMBERS_INCLUDING_SELF:"},{"lineNumber":906,"author":{"gitId":"xenosf"},"content":" // Refers to Giver\u0027s Team Members"},{"lineNumber":907,"author":{"gitId":"xenosf"},"content":" if (roster.isStudentsInSameTeam(response.getGiver(), userEmail)) {"},{"lineNumber":908,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":909,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":910,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":911,"author":{"gitId":"xenosf"},"content":" case RECEIVER:"},{"lineNumber":912,"author":{"gitId":"xenosf"},"content":" // Response to team"},{"lineNumber":913,"author":{"gitId":"xenosf"},"content":" if (question.getRecipientType().isTeam()) {"},{"lineNumber":914,"author":{"gitId":"xenosf"},"content":" if (roster.isStudentInTeam(userEmail, response.getRecipient())) {"},{"lineNumber":915,"author":{"gitId":"xenosf"},"content":" // this is a team name"},{"lineNumber":916,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":917,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":918,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":919,"author":{"gitId":"xenosf"},"content":" // Response to individual"},{"lineNumber":920,"author":{"gitId":"xenosf"},"content":" } else if (response.getRecipient().equals(userEmail)) {"},{"lineNumber":921,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":922,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":923,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":924,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":925,"author":{"gitId":"xenosf"},"content":" case RECEIVER_TEAM_MEMBERS:"},{"lineNumber":926,"author":{"gitId":"xenosf"},"content":" // Response to team; recipient \u003d teamName"},{"lineNumber":927,"author":{"gitId":"xenosf"},"content":" if (question.getRecipientType().isTeam()) {"},{"lineNumber":928,"author":{"gitId":"xenosf"},"content":" if (roster.isStudentInTeam(userEmail, response.getRecipient())) {"},{"lineNumber":929,"author":{"gitId":"xenosf"},"content":" // this is a team name"},{"lineNumber":930,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":931,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":932,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":933,"author":{"gitId":"xenosf"},"content":" } else if (roster.isStudentsInSameTeam(response.getRecipient(), userEmail)) {"},{"lineNumber":934,"author":{"gitId":"xenosf"},"content":" // Response to individual"},{"lineNumber":935,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":936,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":937,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":938,"author":{"gitId":"xenosf"},"content":" case STUDENTS:"},{"lineNumber":939,"author":{"gitId":"xenosf"},"content":" if (roster.isStudentInCourse(userEmail)) {"},{"lineNumber":940,"author":{"gitId":"xenosf"},"content":" return true;"},{"lineNumber":941,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":942,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":943,"author":{"gitId":"xenosf"},"content":" default:"},{"lineNumber":944,"author":{"gitId":"xenosf"},"content":" assert false : \"Invalid FeedbackParticipantType for showNameTo in \""},{"lineNumber":945,"author":{"gitId":"xenosf"},"content":" + \"FeedbackResponseLogic.isFeedbackParticipantNameVisibleToUser()\";"},{"lineNumber":946,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":947,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":948,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":949,"author":{"gitId":"xenosf"},"content":" return false;"},{"lineNumber":950,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":951,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":952,"author":{"gitId":"xenosf"},"content":" private boolean isResponseVisibleForUser("},{"lineNumber":953,"author":{"gitId":"xenosf"},"content":" String userEmail, boolean isInstructor, Student student,"},{"lineNumber":954,"author":{"gitId":"xenosf"},"content":" Set\u003cString\u003e studentsEmailInTeam, FeedbackResponse response,"},{"lineNumber":955,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion relatedQuestion, Instructor instructor) {"},{"lineNumber":956,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":957,"author":{"gitId":"xenosf"},"content":" boolean isVisibleResponse \u003d false;"},{"lineNumber":958,"author":{"gitId":"xenosf"},"content":" if (isInstructor \u0026\u0026 relatedQuestion.isResponseVisibleTo(FeedbackParticipantType.INSTRUCTORS)"},{"lineNumber":959,"author":{"gitId":"xenosf"},"content":" || response.getRecipient().equals(userEmail)"},{"lineNumber":960,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 relatedQuestion.isResponseVisibleTo(FeedbackParticipantType.RECEIVER)"},{"lineNumber":961,"author":{"gitId":"xenosf"},"content":" || response.getGiver().equals(userEmail)"},{"lineNumber":962,"author":{"gitId":"xenosf"},"content":" || !isInstructor \u0026\u0026 relatedQuestion.isResponseVisibleTo(FeedbackParticipantType.STUDENTS)) {"},{"lineNumber":963,"author":{"gitId":"xenosf"},"content":" isVisibleResponse \u003d true;"},{"lineNumber":964,"author":{"gitId":"xenosf"},"content":" } else if (studentsEmailInTeam !\u003d null \u0026\u0026 !isInstructor) {"},{"lineNumber":965,"author":{"gitId":"xenosf"},"content":" if ((relatedQuestion.getRecipientType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":966,"author":{"gitId":"xenosf"},"content":" || relatedQuestion.getRecipientType() \u003d\u003d FeedbackParticipantType.TEAMS_IN_SAME_SECTION"},{"lineNumber":967,"author":{"gitId":"xenosf"},"content":" || relatedQuestion.getRecipientType() \u003d\u003d FeedbackParticipantType.TEAMS_EXCLUDING_SELF)"},{"lineNumber":968,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 relatedQuestion.isResponseVisibleTo(FeedbackParticipantType.RECEIVER)"},{"lineNumber":969,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 response.getRecipient().equals(student.getTeamName())) {"},{"lineNumber":970,"author":{"gitId":"xenosf"},"content":" isVisibleResponse \u003d true;"},{"lineNumber":971,"author":{"gitId":"xenosf"},"content":" } else if (relatedQuestion.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":972,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 response.getGiver().equals(student.getTeamName())) {"},{"lineNumber":973,"author":{"gitId":"xenosf"},"content":" isVisibleResponse \u003d true;"},{"lineNumber":974,"author":{"gitId":"xenosf"},"content":" } else if (relatedQuestion.isResponseVisibleTo(FeedbackParticipantType.OWN_TEAM_MEMBERS)"},{"lineNumber":975,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 studentsEmailInTeam.contains(response.getGiver())) {"},{"lineNumber":976,"author":{"gitId":"xenosf"},"content":" isVisibleResponse \u003d true;"},{"lineNumber":977,"author":{"gitId":"xenosf"},"content":" } else if (relatedQuestion.isResponseVisibleTo(FeedbackParticipantType.RECEIVER_TEAM_MEMBERS)"},{"lineNumber":978,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 studentsEmailInTeam.contains(response.getRecipient())) {"},{"lineNumber":979,"author":{"gitId":"xenosf"},"content":" isVisibleResponse \u003d true;"},{"lineNumber":980,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":981,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":982,"author":{"gitId":"xenosf"},"content":" if (isVisibleResponse \u0026\u0026 instructor !\u003d null) {"},{"lineNumber":983,"author":{"gitId":"xenosf"},"content":" boolean isGiverSectionRestricted \u003d"},{"lineNumber":984,"author":{"gitId":"xenosf"},"content":" !instructor.isAllowedForPrivilege(response.getGiverSectionName(),"},{"lineNumber":985,"author":{"gitId":"xenosf"},"content":" response.getFeedbackQuestion().getFeedbackSession().getName(),"},{"lineNumber":986,"author":{"gitId":"xenosf"},"content":" Const.InstructorPermissions.CAN_VIEW_SESSION_IN_SECTIONS);"},{"lineNumber":987,"author":{"gitId":"xenosf"},"content":" // If instructors are not restricted to view the giver\u0027s section,"},{"lineNumber":988,"author":{"gitId":"xenosf"},"content":" // they are allowed to view responses to GENERAL, subject to visibility options"},{"lineNumber":989,"author":{"gitId":"xenosf"},"content":" boolean isRecipientSectionRestricted \u003d"},{"lineNumber":990,"author":{"gitId":"xenosf"},"content":" relatedQuestion.getRecipientType() !\u003d FeedbackParticipantType.NONE"},{"lineNumber":991,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 !instructor.isAllowedForPrivilege(response.getRecipientSectionName(),"},{"lineNumber":992,"author":{"gitId":"xenosf"},"content":" response.getFeedbackQuestion().getFeedbackSession().getName(),"},{"lineNumber":993,"author":{"gitId":"xenosf"},"content":" Const.InstructorPermissions.CAN_VIEW_SESSION_IN_SECTIONS);"},{"lineNumber":994,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":995,"author":{"gitId":"xenosf"},"content":" boolean isNotAllowedForInstructor \u003d isGiverSectionRestricted || isRecipientSectionRestricted;"},{"lineNumber":996,"author":{"gitId":"xenosf"},"content":" if (isNotAllowedForInstructor) {"},{"lineNumber":997,"author":{"gitId":"xenosf"},"content":" isVisibleResponse \u003d false;"},{"lineNumber":998,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":999,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1000,"author":{"gitId":"xenosf"},"content":" return isVisibleResponse;"},{"lineNumber":1001,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1002,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1003,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1004,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1005,"author":{"gitId":"xenosf"},"content":" * Gets all responses for a session."},{"lineNumber":1006,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1007,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e getFeedbackResponsesForSession("},{"lineNumber":1008,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession, String courseId) {"},{"lineNumber":1009,"author":{"gitId":"xenosf"},"content":" return frDb.getFeedbackResponsesForSession(feedbackSession, courseId);"},{"lineNumber":1010,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1011,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1012,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1013,"author":{"gitId":"xenosf"},"content":" * Gets all responses given to/from a section in a feedback session in a course."},{"lineNumber":1014,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":1015,"author":{"gitId":"xenosf"},"content":" * @param feedbackSession the session"},{"lineNumber":1016,"author":{"gitId":"xenosf"},"content":" * @param courseId the course ID of the session"},{"lineNumber":1017,"author":{"gitId":"xenosf"},"content":" * @param sectionName if null, will retrieve all responses in the session"},{"lineNumber":1018,"author":{"gitId":"xenosf"},"content":" * @param fetchType if not null, will retrieve responses by giver, receiver sections, or both"},{"lineNumber":1019,"author":{"gitId":"xenosf"},"content":" * @return a list of responses"},{"lineNumber":1020,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1021,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForSessionInSection("},{"lineNumber":1022,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession, String courseId, @Nullable String sectionName,"},{"lineNumber":1023,"author":{"gitId":"xenosf"},"content":" @Nullable FeedbackResultFetchType fetchType) {"},{"lineNumber":1024,"author":{"gitId":"xenosf"},"content":" if (sectionName \u003d\u003d null) {"},{"lineNumber":1025,"author":{"gitId":"xenosf"},"content":" return getFeedbackResponsesForSession(feedbackSession, courseId);"},{"lineNumber":1026,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1027,"author":{"gitId":"xenosf"},"content":" return frDb.getFeedbackResponsesForSessionInSection(feedbackSession, courseId, sectionName, fetchType);"},{"lineNumber":1028,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1029,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1030,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1031,"author":{"gitId":"xenosf"},"content":" * Gets all responses given to/from a section for a question."},{"lineNumber":1032,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":1033,"author":{"gitId":"xenosf"},"content":" * @param feedbackQuestionId the question UUID"},{"lineNumber":1034,"author":{"gitId":"xenosf"},"content":" * @param sectionName if null, will retrieve all responses for the question"},{"lineNumber":1035,"author":{"gitId":"xenosf"},"content":" * @return a list of responses"},{"lineNumber":1036,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1037,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForQuestionInSection("},{"lineNumber":1038,"author":{"gitId":"xenosf"},"content":" UUID feedbackQuestionId, @Nullable String sectionName, FeedbackResultFetchType fetchType) {"},{"lineNumber":1039,"author":{"gitId":"xenosf"},"content":" if (sectionName \u003d\u003d null) {"},{"lineNumber":1040,"author":{"gitId":"xenosf"},"content":" return getFeedbackResponsesForQuestion(feedbackQuestionId);"},{"lineNumber":1041,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1042,"author":{"gitId":"xenosf"},"content":" return frDb.getFeedbackResponsesForQuestionInSection(feedbackQuestionId, sectionName, fetchType);"},{"lineNumber":1043,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1044,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1045,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1046,"author":{"gitId":"xenosf"},"content":" * Returns feedback responses given/received by an instructor."},{"lineNumber":1047,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1048,"author":{"gitId":"xenosf"},"content":" private List\u003cFeedbackResponse\u003e getFeedbackResponsesToOrFromInstructorForQuestion("},{"lineNumber":1049,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question, Instructor instructor) {"},{"lineNumber":1050,"author":{"gitId":"xenosf"},"content":" Set\u003cFeedbackResponse\u003e viewableResponses \u003d new HashSet\u003c\u003e();"},{"lineNumber":1051,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1052,"author":{"gitId":"xenosf"},"content":" // Add responses that the instructor submitted him/herself"},{"lineNumber":1053,"author":{"gitId":"xenosf"},"content":" if (question.getGiverType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS) {"},{"lineNumber":1054,"author":{"gitId":"xenosf"},"content":" viewableResponses.addAll("},{"lineNumber":1055,"author":{"gitId":"xenosf"},"content":" getFeedbackResponsesFromGiverForQuestion(question.getId(), instructor.getEmail())"},{"lineNumber":1056,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":1057,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1058,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1059,"author":{"gitId":"xenosf"},"content":" // Add responses that user is a receiver of when response is visible to receiver or instructors"},{"lineNumber":1060,"author":{"gitId":"xenosf"},"content":" if (question.getRecipientType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":1061,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 (question.isResponseVisibleTo(FeedbackParticipantType.RECEIVER)"},{"lineNumber":1062,"author":{"gitId":"xenosf"},"content":" || question.isResponseVisibleTo(FeedbackParticipantType.INSTRUCTORS))) {"},{"lineNumber":1063,"author":{"gitId":"xenosf"},"content":" viewableResponses.addAll("},{"lineNumber":1064,"author":{"gitId":"xenosf"},"content":" getFeedbackResponsesForRecipientForQuestion(question.getId(), instructor.getEmail())"},{"lineNumber":1065,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":1066,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1067,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1068,"author":{"gitId":"xenosf"},"content":" return new ArrayList\u003c\u003e(viewableResponses);"},{"lineNumber":1069,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1070,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1071,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1072,"author":{"gitId":"xenosf"},"content":" * Returns viewable feedback responses for a student."},{"lineNumber":1073,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1074,"author":{"gitId":"xenosf"},"content":" private List\u003cFeedbackResponse\u003e getViewableFeedbackResponsesForStudentForQuestion("},{"lineNumber":1075,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question, Student student, SqlCourseRoster courseRoster) {"},{"lineNumber":1076,"author":{"gitId":"xenosf"},"content":" Set\u003cFeedbackResponse\u003e viewableResponses \u003d new HashSet\u003c\u003e();"},{"lineNumber":1077,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1078,"author":{"gitId":"xenosf"},"content":" // Add responses that the student submitted him/herself"},{"lineNumber":1079,"author":{"gitId":"xenosf"},"content":" if (question.getGiverType() !\u003d FeedbackParticipantType.INSTRUCTORS) {"},{"lineNumber":1080,"author":{"gitId":"xenosf"},"content":" viewableResponses.addAll("},{"lineNumber":1081,"author":{"gitId":"xenosf"},"content":" getFeedbackResponsesFromGiverForQuestion(question.getId(), student.getEmail())"},{"lineNumber":1082,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":1083,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1084,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1085,"author":{"gitId":"xenosf"},"content":" // Add responses that user is a receiver of when response is visible to receiver"},{"lineNumber":1086,"author":{"gitId":"xenosf"},"content":" if (question.getRecipientType() !\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":1087,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 question.isResponseVisibleTo(FeedbackParticipantType.RECEIVER)) {"},{"lineNumber":1088,"author":{"gitId":"xenosf"},"content":" viewableResponses.addAll("},{"lineNumber":1089,"author":{"gitId":"xenosf"},"content":" getFeedbackResponsesForRecipientForQuestion(question.getId(), student.getEmail())"},{"lineNumber":1090,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":1091,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1092,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1093,"author":{"gitId":"xenosf"},"content":" if (question.isResponseVisibleTo(FeedbackParticipantType.STUDENTS)) {"},{"lineNumber":1094,"author":{"gitId":"xenosf"},"content":" viewableResponses.addAll(getFeedbackResponsesForQuestion(question.getId()));"},{"lineNumber":1095,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1096,"author":{"gitId":"xenosf"},"content":" // Early return as STUDENTS covers all cases below."},{"lineNumber":1097,"author":{"gitId":"xenosf"},"content":" return new ArrayList\u003c\u003e(viewableResponses);"},{"lineNumber":1098,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1099,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1100,"author":{"gitId":"xenosf"},"content":" if (question.getRecipientType().isTeam()"},{"lineNumber":1101,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 question.isResponseVisibleTo(FeedbackParticipantType.RECEIVER)) {"},{"lineNumber":1102,"author":{"gitId":"xenosf"},"content":" viewableResponses.addAll("},{"lineNumber":1103,"author":{"gitId":"xenosf"},"content":" getFeedbackResponsesForRecipientForQuestion(question.getId(), student.getTeamName())"},{"lineNumber":1104,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":1105,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1106,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1107,"author":{"gitId":"xenosf"},"content":" if (question.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":1108,"author":{"gitId":"xenosf"},"content":" || question.isResponseVisibleTo(FeedbackParticipantType.OWN_TEAM_MEMBERS)) {"},{"lineNumber":1109,"author":{"gitId":"xenosf"},"content":" viewableResponses.addAll("},{"lineNumber":1110,"author":{"gitId":"xenosf"},"content":" getFeedbackResponsesFromTeamForQuestion("},{"lineNumber":1111,"author":{"gitId":"xenosf"},"content":" question.getId(), question.getCourseId(), student.getTeamName(), courseRoster));"},{"lineNumber":1112,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1113,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1114,"author":{"gitId":"xenosf"},"content":" if (question.isResponseVisibleTo(FeedbackParticipantType.RECEIVER_TEAM_MEMBERS)) {"},{"lineNumber":1115,"author":{"gitId":"xenosf"},"content":" for (Student studentInTeam : courseRoster.getTeamToMembersTable().get(student.getTeamName())) {"},{"lineNumber":1116,"author":{"gitId":"xenosf"},"content":" if (studentInTeam.getEmail().equals(student.getEmail())) {"},{"lineNumber":1117,"author":{"gitId":"xenosf"},"content":" continue;"},{"lineNumber":1118,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1119,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e responses \u003d"},{"lineNumber":1120,"author":{"gitId":"xenosf"},"content":" getFeedbackResponsesForRecipientForQuestion(question.getId(), studentInTeam.getEmail());"},{"lineNumber":1121,"author":{"gitId":"xenosf"},"content":" viewableResponses.addAll(responses);"},{"lineNumber":1122,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1123,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1124,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1125,"author":{"gitId":"xenosf"},"content":" return new ArrayList\u003c\u003e(viewableResponses);"},{"lineNumber":1126,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1127,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1128,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1129,"author":{"gitId":"xenosf"},"content":" * Gets all responses received by a user for a question."},{"lineNumber":1130,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1131,"author":{"gitId":"xenosf"},"content":" private List\u003cFeedbackResponse\u003e getFeedbackResponsesForRecipientForQuestion("},{"lineNumber":1132,"author":{"gitId":"xenosf"},"content":" UUID feedbackQuestionId, String userEmail) {"},{"lineNumber":1133,"author":{"gitId":"xenosf"},"content":" return frDb.getFeedbackResponsesForRecipientForQuestion(feedbackQuestionId, userEmail);"},{"lineNumber":1134,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1135,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1136,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1137,"author":{"gitId":"xenosf"},"content":" * Checks whether instructors can see the question."},{"lineNumber":1138,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1139,"author":{"gitId":"xenosf"},"content":" boolean checkCanInstructorsSeeQuestion(FeedbackQuestion feedbackQuestion) {"},{"lineNumber":1140,"author":{"gitId":"xenosf"},"content":" boolean isResponseVisibleToInstructor \u003d"},{"lineNumber":1141,"author":{"gitId":"xenosf"},"content":" feedbackQuestion.getShowResponsesTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":1142,"author":{"gitId":"xenosf"},"content":" boolean isGiverVisibleToInstructor \u003d"},{"lineNumber":1143,"author":{"gitId":"xenosf"},"content":" feedbackQuestion.getShowGiverNameTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":1144,"author":{"gitId":"xenosf"},"content":" boolean isRecipientVisibleToInstructor \u003d"},{"lineNumber":1145,"author":{"gitId":"xenosf"},"content":" feedbackQuestion.getShowRecipientNameTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":1146,"author":{"gitId":"xenosf"},"content":" return isResponseVisibleToInstructor \u0026\u0026 isGiverVisibleToInstructor \u0026\u0026 isRecipientVisibleToInstructor;"},{"lineNumber":1147,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1148,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1149,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1150,"author":{"gitId":"xenosf"},"content":" * Checks whether instructors can see the comment."},{"lineNumber":1151,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1152,"author":{"gitId":"xenosf"},"content":" boolean checkCanInstructorsSeeComment(FeedbackResponseComment feedbackResponseComment) {"},{"lineNumber":1153,"author":{"gitId":"xenosf"},"content":" boolean isCommentVisibleToInstructor \u003d"},{"lineNumber":1154,"author":{"gitId":"xenosf"},"content":" feedbackResponseComment.getShowCommentTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":1155,"author":{"gitId":"xenosf"},"content":" boolean isGiverVisibleToInstructor \u003d"},{"lineNumber":1156,"author":{"gitId":"xenosf"},"content":" feedbackResponseComment.getShowGiverNameTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":1157,"author":{"gitId":"xenosf"},"content":" return isCommentVisibleToInstructor \u0026\u0026 isGiverVisibleToInstructor;"},{"lineNumber":1158,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1159,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1160,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":77,"marquestye":23,"xenosf":625,"mingyuanc":2,"-":433}},{"path":"src/main/java/teammates/sqllogic/core/FeedbackSessionLogsLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import org.hibernate.ObjectNotFoundException;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Logger;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlapi.FeedbackSessionLogsDb;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":" * Handles operations related to feedback sessions."},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":" * @see FeedbackSessionLog"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":" * @see FeedbackSessionLogsDb"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"public final class FeedbackSessionLogsLogic {"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" private static final FeedbackSessionLogsLogic instance \u003d new FeedbackSessionLogsLogic();"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":" private static final String ERROR_FAILED_TO_CREATE_LOG \u003d \"Failed to create session activity log\";"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" private FeedbackSessionLogsDb fslDb;"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" private FeedbackSessionLogsLogic() {"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" // prevent initialization"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" public static FeedbackSessionLogsLogic inst() {"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" return instance;"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" void initLogicDependencies(FeedbackSessionLogsDb fslDb) {"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" this.fslDb \u003d fslDb;"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" * Creates feedback session logs."},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" public void createFeedbackSessionLogs(List\u003cFeedbackSessionLog\u003e fsLogs) {"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" for (FeedbackSessionLog fsLog : fsLogs) {"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" try {"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" fslDb.createFeedbackSessionLog(fsLog);"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" } catch (ObjectNotFoundException e) {"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" log.severe(String.format(ERROR_FAILED_TO_CREATE_LOG), e);"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" * Gets the feedback session logs as filtered by the given parameters ordered by"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" * ascending timestamp. Logs with the same timestamp will be ordered by the"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" * student\u0027s email."},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" * @param studentId Can be null"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" * @param feedbackSessionId Can be null"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" public List\u003cFeedbackSessionLog\u003e getOrderedFeedbackSessionLogs(String courseId, UUID studentId,"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" UUID feedbackSessionId, Instant startTime, Instant endTime) {"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" return fslDb.getOrderedFeedbackSessionLogs(courseId, studentId, feedbackSessionId, startTime,"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" endTime);"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":67}},{"path":"src/main/java/teammates/sqllogic/core/FeedbackSessionsLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.HashSet;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.Set;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackSessionsDb;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * Handles operations related to feedback sessions."},{"lineNumber":25,"author":{"gitId":"-"},"content":" *"},{"lineNumber":26,"author":{"gitId":"-"},"content":" * @see FeedbackSession"},{"lineNumber":27,"author":{"gitId":"-"},"content":" * @see FeedbackSessionsDb"},{"lineNumber":28,"author":{"gitId":"-"},"content":" */"},{"lineNumber":29,"author":{"gitId":"-"},"content":"public final class FeedbackSessionsLogic {"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private static final String ERROR_NON_EXISTENT_FS_STRING_FORMAT \u003d \"Trying to %s a non-existent feedback session: \";"},{"lineNumber":34,"author":{"gitId":"-"},"content":" private static final String ERROR_NON_EXISTENT_FS_UPDATE \u003d String.format(ERROR_NON_EXISTENT_FS_STRING_FORMAT, \"update\");"},{"lineNumber":35,"author":{"gitId":"-"},"content":" private static final String ERROR_FS_ALREADY_PUBLISH \u003d \"Error publishing feedback session: \""},{"lineNumber":36,"author":{"gitId":"-"},"content":" + \"Session has already been published.\";"},{"lineNumber":37,"author":{"gitId":"-"},"content":" private static final String ERROR_FS_ALREADY_UNPUBLISH \u003d \"Error unpublishing feedback session: \""},{"lineNumber":38,"author":{"gitId":"-"},"content":" + \"Session has already been unpublished.\";"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" private static final int NUMBER_OF_HOURS_BEFORE_CLOSING_ALERT \u003d 24;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" private static final int NUMBER_OF_HOURS_BEFORE_OPENING_SOON_ALERT \u003d 24;"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" private static final FeedbackSessionsLogic instance \u003d new FeedbackSessionsLogic();"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" private FeedbackSessionsDb fsDb;"},{"lineNumber":46,"author":{"gitId":"-"},"content":" private FeedbackQuestionsLogic fqLogic;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" private FeedbackResponsesLogic frLogic;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" private CoursesLogic coursesLogic;"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" private UsersLogic usersLogic;"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" private FeedbackSessionsLogic() {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" public static FeedbackSessionsLogic inst() {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" void initLogicDependencies(FeedbackSessionsDb fsDb, CoursesLogic coursesLogic,"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" FeedbackResponsesLogic frLogic, FeedbackQuestionsLogic fqLogic, UsersLogic usersLogic) {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" this.fsDb \u003d fsDb;"},{"lineNumber":62,"author":{"gitId":"-"},"content":" this.frLogic \u003d frLogic;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" this.fqLogic \u003d fqLogic;"},{"lineNumber":64,"author":{"gitId":"-"},"content":" this.coursesLogic \u003d coursesLogic;"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" this.usersLogic \u003d usersLogic;"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":69,"author":{"gitId":"-"},"content":" * Gets a feedback session."},{"lineNumber":70,"author":{"gitId":"-"},"content":" *"},{"lineNumber":71,"author":{"gitId":"-"},"content":" * @return null if not found."},{"lineNumber":72,"author":{"gitId":"-"},"content":" */"},{"lineNumber":73,"author":{"gitId":"-"},"content":" public FeedbackSession getFeedbackSession(UUID id) {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" assert id !\u003d null;"},{"lineNumber":75,"author":{"gitId":"-"},"content":" return fsDb.getFeedbackSession(id);"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":79,"author":{"gitId":"-"},"content":" * Gets a feedback session for {@code feedbackSessionName} and {@code courseId}."},{"lineNumber":80,"author":{"gitId":"-"},"content":" *"},{"lineNumber":81,"author":{"gitId":"-"},"content":" * @return null if not found."},{"lineNumber":82,"author":{"gitId":"-"},"content":" */"},{"lineNumber":83,"author":{"gitId":"-"},"content":" public FeedbackSession getFeedbackSession(String feedbackSessionName, String courseId) {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" return fsDb.getFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":" * Gets a feedback session reference."},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":" * @return Returns a proxy for the feedback session."},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" public FeedbackSession getFeedbackSessionReference(UUID id) {"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" assert id !\u003d null;"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" return fsDb.getFeedbackSessionReference(id);"},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":101,"author":{"gitId":"-"},"content":" * Gets all feedback sessions of a course, except those that are soft-deleted."},{"lineNumber":102,"author":{"gitId":"-"},"content":" */"},{"lineNumber":103,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsForCourse(String courseId) {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" return fsDb.getFeedbackSessionEntitiesForCourse(courseId).stream()"},{"lineNumber":105,"author":{"gitId":"-"},"content":" .filter(fs -\u003e fs.getDeletedAt() \u003d\u003d null)"},{"lineNumber":106,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":110,"author":{"gitId":"-"},"content":" * Gets all feedback sessions of a course started after time, except those that are soft-deleted."},{"lineNumber":111,"author":{"gitId":"-"},"content":" */"},{"lineNumber":112,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsForCourseStartingAfter(String courseId, Instant after) {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" return fsDb.getFeedbackSessionEntitiesForCourseStartingAfter(courseId, after).stream()"},{"lineNumber":114,"author":{"gitId":"-"},"content":" .filter(session -\u003e session.getDeletedAt() \u003d\u003d null)"},{"lineNumber":115,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":116,"author":{"gitId":"-"},"content":" }"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":119,"author":{"gitId":"-"},"content":" * Gets a feedback session from the recycle bin."},{"lineNumber":120,"author":{"gitId":"-"},"content":" *"},{"lineNumber":121,"author":{"gitId":"-"},"content":" * @return null if not found."},{"lineNumber":122,"author":{"gitId":"-"},"content":" */"},{"lineNumber":123,"author":{"gitId":"-"},"content":" public FeedbackSession getFeedbackSessionFromRecycleBin(String feedbackSessionName, String courseId) {"},{"lineNumber":124,"author":{"gitId":"-"},"content":" return fsDb.getSoftDeletedFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" }"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":128,"author":{"gitId":"-"},"content":" * Gets a list of feedback sessions for instructors."},{"lineNumber":129,"author":{"gitId":"-"},"content":" */"},{"lineNumber":130,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsForInstructors("},{"lineNumber":131,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorList) {"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e courseNotDeletedInstructorList \u003d instructorList.stream()"},{"lineNumber":134,"author":{"gitId":"-"},"content":" .filter(instructor -\u003e coursesLogic.getCourse(instructor.getCourseId()).getDeletedAt() \u003d\u003d null)"},{"lineNumber":135,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e fsList \u003d new ArrayList\u003c\u003e();"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" for (Instructor instructor : courseNotDeletedInstructorList) {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" fsList.addAll(getFeedbackSessionsForCourse(instructor.getCourseId()));"},{"lineNumber":141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" return fsList;"},{"lineNumber":144,"author":{"gitId":"-"},"content":" }"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":147,"author":{"gitId":"-"},"content":" * Returns a {@code List} of feedback sessions in the Recycle Bin for the instructors."},{"lineNumber":148,"author":{"gitId":"-"},"content":" * \u003cbr\u003e"},{"lineNumber":149,"author":{"gitId":"-"},"content":" * Omits sessions if the corresponding courses are archived or in Recycle Bin"},{"lineNumber":150,"author":{"gitId":"-"},"content":" */"},{"lineNumber":151,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getSoftDeletedFeedbackSessionsForInstructors("},{"lineNumber":152,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorList) {"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e courseNotDeletedInstructorList \u003d instructorList.stream()"},{"lineNumber":155,"author":{"gitId":"-"},"content":" .filter(instructor -\u003e coursesLogic.getCourse(instructor.getCourseId()).getDeletedAt() \u003d\u003d null)"},{"lineNumber":156,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e fsList \u003d new ArrayList\u003c\u003e();"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" for (Instructor instructor : courseNotDeletedInstructorList) {"},{"lineNumber":161,"author":{"gitId":"-"},"content":" fsList.addAll(fsDb.getSoftDeletedFeedbackSessionsForCourse(instructor.getCourseId()));"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" return fsList;"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":168,"author":{"gitId":"-"},"content":" * Gets all and only the feedback sessions ongoing within a range of time."},{"lineNumber":169,"author":{"gitId":"-"},"content":" */"},{"lineNumber":170,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getOngoingSessions(Instant rangeStart, Instant rangeEnd) {"},{"lineNumber":171,"author":{"gitId":"-"},"content":" return fsDb.getOngoingSessions(rangeStart, rangeEnd);"},{"lineNumber":172,"author":{"gitId":"-"},"content":" }"},{"lineNumber":173,"author":{"gitId":"-"},"content":""},{"lineNumber":174,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":175,"author":{"gitId":"-"},"content":" * Gets a set of giver identifiers that has at least one response under a feedback session."},{"lineNumber":176,"author":{"gitId":"-"},"content":" */"},{"lineNumber":177,"author":{"gitId":"-"},"content":" public Set\u003cString\u003e getGiverSetThatAnsweredFeedbackSession(String feedbackSessionName, String courseId) {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":179,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":180,"author":{"gitId":"-"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession \u003d fsDb.getFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" Set\u003cString\u003e giverSet \u003d new HashSet\u003c\u003e();"},{"lineNumber":184,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":185,"author":{"gitId":"domoberzin"},"content":" fqLogic.getFeedbackQuestionsForSession(feedbackSession).forEach(question -\u003e {"},{"lineNumber":186,"author":{"gitId":"domoberzin"},"content":" frLogic.getFeedbackResponsesForQuestion(question.getId()).forEach(response -\u003e {"},{"lineNumber":187,"author":{"gitId":"-"},"content":" giverSet.add(response.getGiver());"},{"lineNumber":188,"author":{"gitId":"-"},"content":" });"},{"lineNumber":189,"author":{"gitId":"-"},"content":" });"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" return giverSet;"},{"lineNumber":192,"author":{"gitId":"-"},"content":" }"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" * Gets a set of giver identifiers that has at least one response under a feedback session."},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":" public Set\u003cString\u003e getGiverSetThatAnsweredFeedbackSession(FeedbackSession fs) {"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" assert fs !\u003d null;"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":200,"author":{"gitId":"domoberzin"},"content":" Set\u003cString\u003e giverSet \u003d new HashSet\u003c\u003e();"},{"lineNumber":201,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":202,"author":{"gitId":"domoberzin"},"content":" fqLogic.getFeedbackQuestionsForSession(fs).forEach(question -\u003e {"},{"lineNumber":203,"author":{"gitId":"domoberzin"},"content":" frLogic.getFeedbackResponsesForQuestion(question.getId()).forEach(response -\u003e {"},{"lineNumber":204,"author":{"gitId":"domoberzin"},"content":" giverSet.add(response.getGiver());"},{"lineNumber":205,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":206,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":207,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":208,"author":{"gitId":"domoberzin"},"content":" return giverSet;"},{"lineNumber":209,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":210,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":211,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":212,"author":{"gitId":"-"},"content":" * Creates a feedback session."},{"lineNumber":213,"author":{"gitId":"-"},"content":" *"},{"lineNumber":214,"author":{"gitId":"-"},"content":" * @return created feedback session"},{"lineNumber":215,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the session is not valid"},{"lineNumber":216,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the session already exist"},{"lineNumber":217,"author":{"gitId":"-"},"content":" */"},{"lineNumber":218,"author":{"gitId":"-"},"content":" public FeedbackSession createFeedbackSession(FeedbackSession session)"},{"lineNumber":219,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" assert session !\u003d null;"},{"lineNumber":221,"author":{"gitId":"-"},"content":" return fsDb.createFeedbackSession(session);"},{"lineNumber":222,"author":{"gitId":"-"},"content":" }"},{"lineNumber":223,"author":{"gitId":"-"},"content":""},{"lineNumber":224,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":225,"author":{"gitId":"-"},"content":" * Updates a feedback session."},{"lineNumber":226,"author":{"gitId":"-"},"content":" *"},{"lineNumber":227,"author":{"gitId":"-"},"content":" * @return updated feedback session"},{"lineNumber":228,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the feedback session does not exist"},{"lineNumber":229,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the new fields for feedback session are invalid"},{"lineNumber":230,"author":{"gitId":"-"},"content":" */"},{"lineNumber":231,"author":{"gitId":"-"},"content":" public FeedbackSession updateFeedbackSession(FeedbackSession session)"},{"lineNumber":232,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":233,"author":{"gitId":"-"},"content":" return fsDb.updateFeedbackSession(session);"},{"lineNumber":234,"author":{"gitId":"-"},"content":" }"},{"lineNumber":235,"author":{"gitId":"-"},"content":""},{"lineNumber":236,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":237,"author":{"gitId":"-"},"content":" * Unpublishes a feedback session."},{"lineNumber":238,"author":{"gitId":"-"},"content":" *"},{"lineNumber":239,"author":{"gitId":"-"},"content":" * @return the unpublished feedback session"},{"lineNumber":240,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if session is already unpublished"},{"lineNumber":241,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the feedback session cannot be found"},{"lineNumber":242,"author":{"gitId":"-"},"content":" */"},{"lineNumber":243,"author":{"gitId":"-"},"content":" public FeedbackSession unpublishFeedbackSession(String feedbackSessionName, String courseId)"},{"lineNumber":244,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, InvalidParametersException {"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" FeedbackSession sessionToUnpublish \u003d getFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" if (sessionToUnpublish \u003d\u003d null) {"},{"lineNumber":249,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(ERROR_NON_EXISTENT_FS_UPDATE + courseId + \"/\" + feedbackSessionName);"},{"lineNumber":250,"author":{"gitId":"-"},"content":" }"},{"lineNumber":251,"author":{"gitId":"-"},"content":" if (!sessionToUnpublish.isPublished()) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(ERROR_FS_ALREADY_UNPUBLISH);"},{"lineNumber":253,"author":{"gitId":"-"},"content":" }"},{"lineNumber":254,"author":{"gitId":"-"},"content":""},{"lineNumber":255,"author":{"gitId":"-"},"content":" sessionToUnpublish.setResultsVisibleFromTime(Const.TIME_REPRESENTS_LATER);"},{"lineNumber":256,"author":{"gitId":"-"},"content":""},{"lineNumber":257,"author":{"gitId":"-"},"content":" return sessionToUnpublish;"},{"lineNumber":258,"author":{"gitId":"-"},"content":" }"},{"lineNumber":259,"author":{"gitId":"-"},"content":""},{"lineNumber":260,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":261,"author":{"gitId":"-"},"content":" * Publishes a feedback session."},{"lineNumber":262,"author":{"gitId":"-"},"content":" *"},{"lineNumber":263,"author":{"gitId":"-"},"content":" * @return the published feedback session"},{"lineNumber":264,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if session is already published"},{"lineNumber":265,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the feedback session cannot be found"},{"lineNumber":266,"author":{"gitId":"-"},"content":" */"},{"lineNumber":267,"author":{"gitId":"-"},"content":" public FeedbackSession publishFeedbackSession(String feedbackSessionName, String courseId)"},{"lineNumber":268,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, InvalidParametersException {"},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":" FeedbackSession sessionToPublish \u003d getFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" if (sessionToPublish \u003d\u003d null) {"},{"lineNumber":273,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(ERROR_NON_EXISTENT_FS_UPDATE + courseId + \"/\" + feedbackSessionName);"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":" if (sessionToPublish.isPublished()) {"},{"lineNumber":276,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(ERROR_FS_ALREADY_PUBLISH);"},{"lineNumber":277,"author":{"gitId":"-"},"content":" }"},{"lineNumber":278,"author":{"gitId":"-"},"content":""},{"lineNumber":279,"author":{"gitId":"-"},"content":" sessionToPublish.setResultsVisibleFromTime(Instant.now());"},{"lineNumber":280,"author":{"gitId":"-"},"content":""},{"lineNumber":281,"author":{"gitId":"-"},"content":" return sessionToPublish;"},{"lineNumber":282,"author":{"gitId":"-"},"content":" }"},{"lineNumber":283,"author":{"gitId":"-"},"content":""},{"lineNumber":284,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":285,"author":{"gitId":"-"},"content":" * Deletes a feedback session cascade to its associated questions, responses, deadline extensions and comments."},{"lineNumber":286,"author":{"gitId":"-"},"content":" */"},{"lineNumber":287,"author":{"gitId":"-"},"content":" public void deleteFeedbackSessionCascade(String feedbackSessionName, String courseId) {"},{"lineNumber":288,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession \u003d fsDb.getFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":289,"author":{"gitId":"-"},"content":" fsDb.deleteFeedbackSession(feedbackSession);"},{"lineNumber":290,"author":{"gitId":"-"},"content":" }"},{"lineNumber":291,"author":{"gitId":"-"},"content":""},{"lineNumber":292,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":293,"author":{"gitId":"-"},"content":" * Soft-deletes a specific feedback session to Recycle Bin."},{"lineNumber":294,"author":{"gitId":"-"},"content":" * @return the feedback session"},{"lineNumber":295,"author":{"gitId":"-"},"content":" */"},{"lineNumber":296,"author":{"gitId":"-"},"content":" public FeedbackSession moveFeedbackSessionToRecycleBin(String feedbackSessionName, String courseId)"},{"lineNumber":297,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":298,"author":{"gitId":"-"},"content":""},{"lineNumber":299,"author":{"gitId":"-"},"content":" return fsDb.softDeleteFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":300,"author":{"gitId":"-"},"content":" }"},{"lineNumber":301,"author":{"gitId":"-"},"content":""},{"lineNumber":302,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":303,"author":{"gitId":"-"},"content":" * Restores a specific feedback session from Recycle Bin."},{"lineNumber":304,"author":{"gitId":"-"},"content":" */"},{"lineNumber":305,"author":{"gitId":"-"},"content":" public void restoreFeedbackSessionFromRecycleBin(String feedbackSessionName, String courseId)"},{"lineNumber":306,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":307,"author":{"gitId":"-"},"content":" fsDb.restoreDeletedFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":308,"author":{"gitId":"-"},"content":" }"},{"lineNumber":309,"author":{"gitId":"-"},"content":""},{"lineNumber":310,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":311,"author":{"gitId":"-"},"content":" * Returns true if there are any questions for the specified user type (students/instructors) to answer."},{"lineNumber":312,"author":{"gitId":"-"},"content":" */"},{"lineNumber":313,"author":{"gitId":"-"},"content":" public boolean isFeedbackSessionForUserTypeToAnswer(FeedbackSession session, boolean isInstructor) {"},{"lineNumber":314,"author":{"gitId":"-"},"content":" if (!session.isVisible()) {"},{"lineNumber":315,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":316,"author":{"gitId":"-"},"content":" }"},{"lineNumber":317,"author":{"gitId":"-"},"content":""},{"lineNumber":318,"author":{"gitId":"-"},"content":" return isInstructor"},{"lineNumber":319,"author":{"gitId":"-"},"content":" ? fqLogic.hasFeedbackQuestionsForInstructors(session.getFeedbackQuestions(), false)"},{"lineNumber":320,"author":{"gitId":"-"},"content":" : fqLogic.hasFeedbackQuestionsForStudents(session.getFeedbackQuestions());"},{"lineNumber":321,"author":{"gitId":"-"},"content":" }"},{"lineNumber":322,"author":{"gitId":"-"},"content":""},{"lineNumber":323,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":324,"author":{"gitId":"-"},"content":" * Returns true if the feedback session is viewable by the given user type (students/instructors)."},{"lineNumber":325,"author":{"gitId":"-"},"content":" */"},{"lineNumber":326,"author":{"gitId":"-"},"content":" public boolean isFeedbackSessionViewableToUserType(FeedbackSession session, boolean isInstructor) {"},{"lineNumber":327,"author":{"gitId":"-"},"content":" // Allow user to view the feedback session if there are questions for them"},{"lineNumber":328,"author":{"gitId":"-"},"content":" if (isFeedbackSessionForUserTypeToAnswer(session, isInstructor)) {"},{"lineNumber":329,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":330,"author":{"gitId":"-"},"content":" }"},{"lineNumber":331,"author":{"gitId":"-"},"content":""},{"lineNumber":332,"author":{"gitId":"-"},"content":" // Allow user to view the feedback session if there are any question whose responses are visible to the user"},{"lineNumber":333,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsWithVisibleResponses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":334,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsForUser \u003d session.getFeedbackQuestions();"},{"lineNumber":335,"author":{"gitId":"-"},"content":" for (FeedbackQuestion question : questionsForUser) {"},{"lineNumber":336,"author":{"gitId":"-"},"content":" if (!isInstructor \u0026\u0026 frLogic.isResponseOfFeedbackQuestionVisibleToStudent(question)"},{"lineNumber":337,"author":{"gitId":"-"},"content":" || isInstructor \u0026\u0026 frLogic.isResponseOfFeedbackQuestionVisibleToInstructor(question)) {"},{"lineNumber":338,"author":{"gitId":"-"},"content":" // We only need one question with visible responses for the entire session to be visible"},{"lineNumber":339,"author":{"gitId":"-"},"content":" questionsWithVisibleResponses.add(question);"},{"lineNumber":340,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":341,"author":{"gitId":"-"},"content":" }"},{"lineNumber":342,"author":{"gitId":"-"},"content":" }"},{"lineNumber":343,"author":{"gitId":"-"},"content":""},{"lineNumber":344,"author":{"gitId":"-"},"content":" return session.isVisible() \u0026\u0026 !questionsWithVisibleResponses.isEmpty();"},{"lineNumber":345,"author":{"gitId":"-"},"content":" }"},{"lineNumber":346,"author":{"gitId":"-"},"content":""},{"lineNumber":347,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":348,"author":{"gitId":"-"},"content":" * Checks whether a student has attempted a feedback session."},{"lineNumber":349,"author":{"gitId":"-"},"content":" *"},{"lineNumber":350,"author":{"gitId":"-"},"content":" * \u003cp\u003eIf feedback session consists of all team questions, session is attempted by student only"},{"lineNumber":351,"author":{"gitId":"-"},"content":" * if someone from the team has responded. If feedback session has some individual questions,"},{"lineNumber":352,"author":{"gitId":"-"},"content":" * session is attempted only if the student has responded to any of the individual questions"},{"lineNumber":353,"author":{"gitId":"-"},"content":" * (regardless of the completion status of the team questions).\u003c/p\u003e"},{"lineNumber":354,"author":{"gitId":"-"},"content":" */"},{"lineNumber":355,"author":{"gitId":"-"},"content":" public boolean isFeedbackSessionAttemptedByStudent(FeedbackSession session, String userEmail, String userTeam) {"},{"lineNumber":356,"author":{"gitId":"-"},"content":" assert session !\u003d null;"},{"lineNumber":357,"author":{"gitId":"-"},"content":" assert userEmail !\u003d null;"},{"lineNumber":358,"author":{"gitId":"-"},"content":" assert userTeam !\u003d null;"},{"lineNumber":359,"author":{"gitId":"-"},"content":""},{"lineNumber":360,"author":{"gitId":"-"},"content":" if (!fqLogic.hasFeedbackQuestionsForStudents(session.getFeedbackQuestions())) {"},{"lineNumber":361,"author":{"gitId":"-"},"content":" // if there are no questions for student, session is attempted"},{"lineNumber":362,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":363,"author":{"gitId":"-"},"content":" } else if (fqLogic.hasFeedbackQuestionsForGiverType("},{"lineNumber":364,"author":{"gitId":"-"},"content":" session.getFeedbackQuestions(), FeedbackParticipantType.STUDENTS)) {"},{"lineNumber":365,"author":{"gitId":"-"},"content":" // case where there are some individual questions"},{"lineNumber":366,"author":{"gitId":"-"},"content":" return frLogic.hasGiverRespondedForSession(userEmail, session.getFeedbackQuestions());"},{"lineNumber":367,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":368,"author":{"gitId":"-"},"content":" // case where all are team questions"},{"lineNumber":369,"author":{"gitId":"-"},"content":" return frLogic.hasGiverRespondedForSession(userTeam, session.getFeedbackQuestions());"},{"lineNumber":370,"author":{"gitId":"-"},"content":" }"},{"lineNumber":371,"author":{"gitId":"-"},"content":" }"},{"lineNumber":372,"author":{"gitId":"-"},"content":""},{"lineNumber":373,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":374,"author":{"gitId":"-"},"content":" * Checks whether an instructor has attempted a feedback session."},{"lineNumber":375,"author":{"gitId":"-"},"content":" *"},{"lineNumber":376,"author":{"gitId":"-"},"content":" * \u003cp\u003eIf there is no question for instructors, the feedback session is considered as attempted.\u003c/p\u003e"},{"lineNumber":377,"author":{"gitId":"-"},"content":" */"},{"lineNumber":378,"author":{"gitId":"-"},"content":" public boolean isFeedbackSessionAttemptedByInstructor(FeedbackSession session, String userEmail) {"},{"lineNumber":379,"author":{"gitId":"-"},"content":" assert session !\u003d null;"},{"lineNumber":380,"author":{"gitId":"-"},"content":" assert userEmail !\u003d null;"},{"lineNumber":381,"author":{"gitId":"-"},"content":""},{"lineNumber":382,"author":{"gitId":"-"},"content":" if (frLogic.hasGiverRespondedForSession(userEmail, session.getFeedbackQuestions())) {"},{"lineNumber":383,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":384,"author":{"gitId":"-"},"content":" }"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"-"},"content":" // if there is no question for instructor, session is attempted"},{"lineNumber":387,"author":{"gitId":"-"},"content":" return !fqLogic.hasFeedbackQuestionsForInstructors(session.getFeedbackQuestions(), session.isCreator(userEmail));"},{"lineNumber":388,"author":{"gitId":"-"},"content":" }"},{"lineNumber":389,"author":{"gitId":"-"},"content":""},{"lineNumber":390,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":391,"author":{"gitId":"-"},"content":" * After an update to feedback session\u0027s fields, may need to adjust the email status of the session."},{"lineNumber":392,"author":{"gitId":"-"},"content":" * @param session recently updated session."},{"lineNumber":393,"author":{"gitId":"-"},"content":" */"},{"lineNumber":394,"author":{"gitId":"-"},"content":" public void adjustFeedbackSessionEmailStatusAfterUpdate(FeedbackSession session) {"},{"lineNumber":395,"author":{"gitId":"-"},"content":" // reset isOpenEmailSent if the session has opened but is being un-opened"},{"lineNumber":396,"author":{"gitId":"-"},"content":" // now, or else leave it as sent if so."},{"lineNumber":397,"author":{"gitId":"-"},"content":" if (session.isOpenEmailSent()) {"},{"lineNumber":398,"author":{"gitId":"-"},"content":" session.setOpenEmailSent(session.isOpened());"},{"lineNumber":399,"author":{"gitId":"-"},"content":""},{"lineNumber":400,"author":{"gitId":"-"},"content":" // also reset isOpeningSoonEmailSent"},{"lineNumber":401,"author":{"gitId":"-"},"content":" session.setOpeningSoonEmailSent("},{"lineNumber":402,"author":{"gitId":"domoberzin"},"content":" session.isOpened() || session.isOpeningInHours(NUMBER_OF_HOURS_BEFORE_OPENING_SOON_ALERT));"},{"lineNumber":403,"author":{"gitId":"-"},"content":" }"},{"lineNumber":404,"author":{"gitId":"-"},"content":""},{"lineNumber":405,"author":{"gitId":"-"},"content":" // reset isClosedEmailSent if the session has closed but is being un-closed"},{"lineNumber":406,"author":{"gitId":"-"},"content":" // now, or else leave it as sent if so."},{"lineNumber":407,"author":{"gitId":"-"},"content":" if (session.isClosedEmailSent()) {"},{"lineNumber":408,"author":{"gitId":"-"},"content":" session.setClosedEmailSent(session.isClosed());"},{"lineNumber":409,"author":{"gitId":"-"},"content":""},{"lineNumber":410,"author":{"gitId":"-"},"content":" // also reset isClosingSoonEmailSent"},{"lineNumber":411,"author":{"gitId":"-"},"content":" session.setClosingSoonEmailSent("},{"lineNumber":412,"author":{"gitId":"domoberzin"},"content":" session.isClosed() || session.isClosedAfter(NUMBER_OF_HOURS_BEFORE_CLOSING_ALERT));"},{"lineNumber":413,"author":{"gitId":"-"},"content":" }"},{"lineNumber":414,"author":{"gitId":"-"},"content":""},{"lineNumber":415,"author":{"gitId":"-"},"content":" // reset isPublishedEmailSent if the session has been published but is"},{"lineNumber":416,"author":{"gitId":"-"},"content":" // going to be unpublished now, or else leave it as sent if so."},{"lineNumber":417,"author":{"gitId":"-"},"content":" if (session.isPublishedEmailSent()) {"},{"lineNumber":418,"author":{"gitId":"-"},"content":" session.setPublishedEmailSent(session.isPublished());"},{"lineNumber":419,"author":{"gitId":"-"},"content":" }"},{"lineNumber":420,"author":{"gitId":"-"},"content":" }"},{"lineNumber":421,"author":{"gitId":"-"},"content":""},{"lineNumber":422,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":423,"author":{"gitId":"-"},"content":" * Criteria: must be published, publishEmail must be enabled and"},{"lineNumber":424,"author":{"gitId":"-"},"content":" * resultsVisibleTime must be custom."},{"lineNumber":425,"author":{"gitId":"-"},"content":" *"},{"lineNumber":426,"author":{"gitId":"-"},"content":" * @return returns a list of sessions that require automated emails to be"},{"lineNumber":427,"author":{"gitId":"-"},"content":" * sent as they are published"},{"lineNumber":428,"author":{"gitId":"-"},"content":" */"},{"lineNumber":429,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsWhichNeedAutomatedPublishedEmailsToBeSent() {"},{"lineNumber":430,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e sessionsToSendEmailsFor \u003d new ArrayList\u003c\u003e();"},{"lineNumber":431,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e sessions \u003d fsDb.getFeedbackSessionsPossiblyNeedingPublishedEmail();"},{"lineNumber":432,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration: %d\", sessions.size()));"},{"lineNumber":433,"author":{"gitId":"-"},"content":""},{"lineNumber":434,"author":{"gitId":"-"},"content":" for (FeedbackSession session : sessions) {"},{"lineNumber":435,"author":{"gitId":"-"},"content":" // automated emails are required only for custom publish times"},{"lineNumber":436,"author":{"gitId":"-"},"content":" if (session.isPublished()"},{"lineNumber":437,"author":{"gitId":"-"},"content":" \u0026\u0026 !TimeHelper.isSpecialTime(session.getResultsVisibleFromTime())"},{"lineNumber":438,"author":{"gitId":"-"},"content":" \u0026\u0026 session.getCourse().getDeletedAt() \u003d\u003d null) {"},{"lineNumber":439,"author":{"gitId":"-"},"content":" sessionsToSendEmailsFor.add(session);"},{"lineNumber":440,"author":{"gitId":"-"},"content":" }"},{"lineNumber":441,"author":{"gitId":"-"},"content":" }"},{"lineNumber":442,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration after filtering: %d\","},{"lineNumber":443,"author":{"gitId":"-"},"content":" sessionsToSendEmailsFor.size()));"},{"lineNumber":444,"author":{"gitId":"-"},"content":" return sessionsToSendEmailsFor;"},{"lineNumber":445,"author":{"gitId":"-"},"content":" }"},{"lineNumber":446,"author":{"gitId":"-"},"content":""},{"lineNumber":447,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":448,"author":{"gitId":"-"},"content":" * Returns a list of sessions that are going to close within the next 24 hours."},{"lineNumber":449,"author":{"gitId":"-"},"content":" */"},{"lineNumber":450,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsClosingWithinTimeLimit() {"},{"lineNumber":451,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e requiredSessions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":452,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e sessions \u003d fsDb.getFeedbackSessionsPossiblyNeedingClosingSoonEmail();"},{"lineNumber":453,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration: %d\", sessions.size()));"},{"lineNumber":454,"author":{"gitId":"-"},"content":""},{"lineNumber":455,"author":{"gitId":"-"},"content":" for (FeedbackSession session : sessions) {"},{"lineNumber":456,"author":{"gitId":"-"},"content":" if (session.isClosingWithinTimeLimit(NUMBER_OF_HOURS_BEFORE_CLOSING_ALERT)"},{"lineNumber":457,"author":{"gitId":"-"},"content":" \u0026\u0026 session.getCourse().getDeletedAt() \u003d\u003d null) {"},{"lineNumber":458,"author":{"gitId":"-"},"content":" requiredSessions.add(session);"},{"lineNumber":459,"author":{"gitId":"-"},"content":" }"},{"lineNumber":460,"author":{"gitId":"-"},"content":" }"},{"lineNumber":461,"author":{"gitId":"-"},"content":""},{"lineNumber":462,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration after filtering: %d\","},{"lineNumber":463,"author":{"gitId":"-"},"content":" requiredSessions.size()));"},{"lineNumber":464,"author":{"gitId":"-"},"content":" return requiredSessions;"},{"lineNumber":465,"author":{"gitId":"-"},"content":" }"},{"lineNumber":466,"author":{"gitId":"-"},"content":""},{"lineNumber":467,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":468,"author":{"gitId":"-"},"content":" * Returns a list of sessions that are going to open in 24 hours."},{"lineNumber":469,"author":{"gitId":"-"},"content":" */"},{"lineNumber":470,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsOpeningWithinTimeLimit() {"},{"lineNumber":471,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e requiredSessions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":472,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e sessions \u003d fsDb.getFeedbackSessionsPossiblyNeedingOpeningSoonEmail();"},{"lineNumber":473,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration: %d\", sessions.size()));"},{"lineNumber":474,"author":{"gitId":"-"},"content":""},{"lineNumber":475,"author":{"gitId":"-"},"content":" for (FeedbackSession session : sessions) {"},{"lineNumber":476,"author":{"gitId":"-"},"content":" if (session.isOpeningWithinTimeLimit(NUMBER_OF_HOURS_BEFORE_OPENING_SOON_ALERT)"},{"lineNumber":477,"author":{"gitId":"-"},"content":" \u0026\u0026 session.getCourse().getDeletedAt() \u003d\u003d null) {"},{"lineNumber":478,"author":{"gitId":"-"},"content":" requiredSessions.add(session);"},{"lineNumber":479,"author":{"gitId":"-"},"content":" }"},{"lineNumber":480,"author":{"gitId":"-"},"content":" }"},{"lineNumber":481,"author":{"gitId":"-"},"content":""},{"lineNumber":482,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration after filtering: %d\","},{"lineNumber":483,"author":{"gitId":"-"},"content":" requiredSessions.size()));"},{"lineNumber":484,"author":{"gitId":"-"},"content":" return requiredSessions;"},{"lineNumber":485,"author":{"gitId":"-"},"content":" }"},{"lineNumber":486,"author":{"gitId":"-"},"content":""},{"lineNumber":487,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":488,"author":{"gitId":"-"},"content":" * Returns a list of sessions that were closed within past hour."},{"lineNumber":489,"author":{"gitId":"-"},"content":" */"},{"lineNumber":490,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsClosedWithinThePastHour() {"},{"lineNumber":491,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e requiredSessions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":492,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e sessions \u003d fsDb.getFeedbackSessionsPossiblyNeedingClosedEmail();"},{"lineNumber":493,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration: %d\", sessions.size()));"},{"lineNumber":494,"author":{"gitId":"-"},"content":""},{"lineNumber":495,"author":{"gitId":"-"},"content":" for (FeedbackSession session : sessions) {"},{"lineNumber":496,"author":{"gitId":"-"},"content":" // is session closed in the past 1 hour"},{"lineNumber":497,"author":{"gitId":"-"},"content":" if (session.isClosedWithinPastHour()"},{"lineNumber":498,"author":{"gitId":"-"},"content":" \u0026\u0026 session.getCourse().getDeletedAt() \u003d\u003d null) {"},{"lineNumber":499,"author":{"gitId":"-"},"content":" requiredSessions.add(session);"},{"lineNumber":500,"author":{"gitId":"-"},"content":" }"},{"lineNumber":501,"author":{"gitId":"-"},"content":" }"},{"lineNumber":502,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration after filtering: %d\","},{"lineNumber":503,"author":{"gitId":"-"},"content":" requiredSessions.size()));"},{"lineNumber":504,"author":{"gitId":"-"},"content":" return requiredSessions;"},{"lineNumber":505,"author":{"gitId":"-"},"content":" }"},{"lineNumber":506,"author":{"gitId":"-"},"content":""},{"lineNumber":507,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":508,"author":{"gitId":"-"},"content":" * Gets a list of undeleted feedback sessions which start within the last 2 hours"},{"lineNumber":509,"author":{"gitId":"-"},"content":" * and need an open email to be sent."},{"lineNumber":510,"author":{"gitId":"-"},"content":" */"},{"lineNumber":511,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsWhichNeedOpenEmailsToBeSent() {"},{"lineNumber":512,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e sessionsToSendEmailsFor \u003d new ArrayList\u003c\u003e();"},{"lineNumber":513,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e sessions \u003d fsDb.getFeedbackSessionsPossiblyNeedingOpenEmail();"},{"lineNumber":514,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration: %d\", sessions.size()));"},{"lineNumber":515,"author":{"gitId":"-"},"content":""},{"lineNumber":516,"author":{"gitId":"-"},"content":" for (FeedbackSession session : sessions) {"},{"lineNumber":517,"author":{"gitId":"-"},"content":" if (session.isOpened() \u0026\u0026 session.getCourse().getDeletedAt() \u003d\u003d null) {"},{"lineNumber":518,"author":{"gitId":"-"},"content":" sessionsToSendEmailsFor.add(session);"},{"lineNumber":519,"author":{"gitId":"-"},"content":" }"},{"lineNumber":520,"author":{"gitId":"-"},"content":" }"},{"lineNumber":521,"author":{"gitId":"-"},"content":""},{"lineNumber":522,"author":{"gitId":"-"},"content":" log.info(String.format(\"Number of sessions under consideration after filtering: %d\","},{"lineNumber":523,"author":{"gitId":"-"},"content":" sessionsToSendEmailsFor.size()));"},{"lineNumber":524,"author":{"gitId":"-"},"content":" return sessionsToSendEmailsFor;"},{"lineNumber":525,"author":{"gitId":"-"},"content":" }"},{"lineNumber":526,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":527,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":528,"author":{"gitId":"domoberzin"},"content":" * Gets the expected number of submissions for a feedback session."},{"lineNumber":529,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":530,"author":{"gitId":"domoberzin"},"content":" public int getExpectedTotalSubmission(FeedbackSession fs) {"},{"lineNumber":531,"author":{"gitId":"domoberzin"},"content":" int expectedTotal \u003d 0;"},{"lineNumber":532,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackQuestion\u003e questions \u003d fqLogic.getFeedbackQuestionsForSession(fs);"},{"lineNumber":533,"author":{"gitId":"domoberzin"},"content":" if (fqLogic.hasFeedbackQuestionsForStudents(questions)) {"},{"lineNumber":534,"author":{"gitId":"domoberzin"},"content":" expectedTotal +\u003d usersLogic.getStudentsForCourse(fs.getCourse().getId()).size();"},{"lineNumber":535,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":536,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":537,"author":{"gitId":"domoberzin"},"content":" // Pre-flight check to ensure there are questions for instructors."},{"lineNumber":538,"author":{"gitId":"domoberzin"},"content":" if (!fqLogic.hasFeedbackQuestionsForInstructors(questions, true)) {"},{"lineNumber":539,"author":{"gitId":"domoberzin"},"content":" return expectedTotal;"},{"lineNumber":540,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":541,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":542,"author":{"gitId":"domoberzin"},"content":" List\u003cInstructor\u003e instructors \u003d usersLogic.getInstructorsForCourse(fs.getCourse().getId());"},{"lineNumber":543,"author":{"gitId":"domoberzin"},"content":" if (instructors.isEmpty()) {"},{"lineNumber":544,"author":{"gitId":"domoberzin"},"content":" return expectedTotal;"},{"lineNumber":545,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":546,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":547,"author":{"gitId":"domoberzin"},"content":" // Check presence of questions for instructors."},{"lineNumber":548,"author":{"gitId":"domoberzin"},"content":" if (fqLogic.hasFeedbackQuestionsForInstructors(fqLogic.getFeedbackQuestionsForSession(fs), false)) {"},{"lineNumber":549,"author":{"gitId":"domoberzin"},"content":" expectedTotal +\u003d instructors.size();"},{"lineNumber":550,"author":{"gitId":"domoberzin"},"content":" } else {"},{"lineNumber":551,"author":{"gitId":"domoberzin"},"content":" // No questions for instructors. There must be questions for creator."},{"lineNumber":552,"author":{"gitId":"domoberzin"},"content":" List\u003cInstructor\u003e creators \u003d instructors.stream()"},{"lineNumber":553,"author":{"gitId":"domoberzin"},"content":" .filter(instructor -\u003e fs.getCreatorEmail().equals(instructor.getEmail()))"},{"lineNumber":554,"author":{"gitId":"domoberzin"},"content":" .collect(Collectors.toList());"},{"lineNumber":555,"author":{"gitId":"domoberzin"},"content":" expectedTotal +\u003d creators.size();"},{"lineNumber":556,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":557,"author":{"gitId":"domoberzin"},"content":" return expectedTotal;"},{"lineNumber":558,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":559,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":560,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":561,"author":{"gitId":"domoberzin"},"content":" * Gets the actual number of submissions for a feedback session."},{"lineNumber":562,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":563,"author":{"gitId":"domoberzin"},"content":" public int getActualTotalSubmission(FeedbackSession fs) {"},{"lineNumber":564,"author":{"gitId":"domoberzin"},"content":" return getGiverSetThatAnsweredFeedbackSession(fs).size();"},{"lineNumber":565,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":566,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":65,"dishenggg":10,"-":491}},{"path":"src/main/java/teammates/sqllogic/core/LogicStarter.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import jakarta.servlet.ServletContextEvent;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import jakarta.servlet.ServletContextListener;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.AccountRequestsDb;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.AccountsDb;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.CoursesDb;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.DeadlineExtensionsDb;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackQuestionsDb;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackResponseCommentsDb;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackResponsesDb;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlapi.FeedbackSessionLogsDb;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackSessionsDb;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.NotificationsDb;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.UsageStatisticsDb;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.UsersDb;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":21,"author":{"gitId":"-"},"content":" * Setup in web.xml to register logic classes at application startup."},{"lineNumber":22,"author":{"gitId":"-"},"content":" */"},{"lineNumber":23,"author":{"gitId":"-"},"content":"public class LogicStarter implements ServletContextListener {"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":28,"author":{"gitId":"-"},"content":" * Registers dependencies between different logic classes."},{"lineNumber":29,"author":{"gitId":"-"},"content":" */"},{"lineNumber":30,"author":{"gitId":"-"},"content":" public static void initializeDependencies() {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" AccountsLogic accountsLogic \u003d AccountsLogic.inst();"},{"lineNumber":32,"author":{"gitId":"-"},"content":" AccountRequestsLogic accountRequestsLogic \u003d AccountRequestsLogic.inst();"},{"lineNumber":33,"author":{"gitId":"-"},"content":" CoursesLogic coursesLogic \u003d CoursesLogic.inst();"},{"lineNumber":34,"author":{"gitId":"-"},"content":" DataBundleLogic dataBundleLogic \u003d DataBundleLogic.inst();"},{"lineNumber":35,"author":{"gitId":"-"},"content":" DeadlineExtensionsLogic deadlineExtensionsLogic \u003d DeadlineExtensionsLogic.inst();"},{"lineNumber":36,"author":{"gitId":"-"},"content":" FeedbackSessionsLogic fsLogic \u003d FeedbackSessionsLogic.inst();"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogsLogic fslLogic \u003d FeedbackSessionLogsLogic.inst();"},{"lineNumber":38,"author":{"gitId":"-"},"content":" FeedbackResponsesLogic frLogic \u003d FeedbackResponsesLogic.inst();"},{"lineNumber":39,"author":{"gitId":"-"},"content":" FeedbackResponseCommentsLogic frcLogic \u003d FeedbackResponseCommentsLogic.inst();"},{"lineNumber":40,"author":{"gitId":"-"},"content":" FeedbackQuestionsLogic fqLogic \u003d FeedbackQuestionsLogic.inst();"},{"lineNumber":41,"author":{"gitId":"-"},"content":" NotificationsLogic notificationsLogic \u003d NotificationsLogic.inst();"},{"lineNumber":42,"author":{"gitId":"-"},"content":" UsageStatisticsLogic usageStatisticsLogic \u003d UsageStatisticsLogic.inst();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" UsersLogic usersLogic \u003d UsersLogic.inst();"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" accountRequestsLogic.initLogicDependencies(AccountRequestsDb.inst());"},{"lineNumber":46,"author":{"gitId":"yuanxi1"},"content":" accountsLogic.initLogicDependencies(AccountsDb.inst(), notificationsLogic, usersLogic, coursesLogic);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" coursesLogic.initLogicDependencies(CoursesDb.inst(), fsLogic, usersLogic);"},{"lineNumber":48,"author":{"gitId":"-"},"content":" dataBundleLogic.initLogicDependencies(accountsLogic, accountRequestsLogic, coursesLogic,"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" deadlineExtensionsLogic, fsLogic, fslLogic, fqLogic, frLogic, frcLogic,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" notificationsLogic, usersLogic);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" deadlineExtensionsLogic.initLogicDependencies(DeadlineExtensionsDb.inst(), fsLogic);"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" fsLogic.initLogicDependencies(FeedbackSessionsDb.inst(), coursesLogic, frLogic, fqLogic, usersLogic);"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" fslLogic.initLogicDependencies(FeedbackSessionLogsDb.inst());"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" frLogic.initLogicDependencies(FeedbackResponsesDb.inst(), usersLogic, fqLogic, frcLogic);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" frcLogic.initLogicDependencies(FeedbackResponseCommentsDb.inst());"},{"lineNumber":56,"author":{"gitId":"-"},"content":" fqLogic.initLogicDependencies(FeedbackQuestionsDb.inst(), coursesLogic, frLogic, usersLogic, fsLogic);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" notificationsLogic.initLogicDependencies(NotificationsDb.inst());"},{"lineNumber":58,"author":{"gitId":"-"},"content":" usageStatisticsLogic.initLogicDependencies(UsageStatisticsDb.inst());"},{"lineNumber":59,"author":{"gitId":"-"},"content":" usersLogic.initLogicDependencies(UsersDb.inst(), accountsLogic, frLogic, frcLogic, deadlineExtensionsLogic);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" log.info(\"Initialized dependencies between logic classes\");"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":64,"author":{"gitId":"-"},"content":" public void contextInitialized(ServletContextEvent event) {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" // Invoked by Jetty at application startup."},{"lineNumber":66,"author":{"gitId":"-"},"content":" initializeDependencies();"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":70,"author":{"gitId":"-"},"content":" public void contextDestroyed(ServletContextEvent event) {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" // Nothing to do"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":2,"yuanxi1":1,"dishenggg":4,"-":67}},{"path":"src/main/java/teammates/sqllogic/core/UsersLogic.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"marquestye"},"content":"import static teammates.common.util.Const.ERROR_CREATE_ENTITY_ALREADY_EXISTS;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import static teammates.common.util.Const.ERROR_UPDATE_NON_EXISTENT;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.Comparator;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import java.util.StringJoiner;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPermissionRole;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPrivileges;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EnrollException;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.exception.InstructorUpdateException;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.exception.StudentUpdateException;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.util.RequestTracer;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.UsersDb;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.User;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.InstructorSearchManager;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.StudentSearchManager;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import teammates.ui.request.InstructorCreateRequest;"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":41,"author":{"gitId":"-"},"content":" * Handles operations related to user (instructor \u0026 student)."},{"lineNumber":42,"author":{"gitId":"-"},"content":" *"},{"lineNumber":43,"author":{"gitId":"-"},"content":" * @see User"},{"lineNumber":44,"author":{"gitId":"-"},"content":" * @see UsersDb"},{"lineNumber":45,"author":{"gitId":"-"},"content":" */"},{"lineNumber":46,"author":{"gitId":"-"},"content":"public final class UsersLogic {"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" static final String ERROR_INVALID_TEAM_NAME \u003d"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" \"Team \\\"%s\\\" is detected in both Section \\\"%s\\\" and Section \\\"%s\\\".\";"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" static final String ERROR_INVALID_TEAM_NAME_INSTRUCTION \u003d"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" \"Please use different team names in different sections.\";"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" static final String ERROR_ENROLL_EXCEED_SECTION_LIMIT \u003d"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" \"You are trying enroll more than %s students in section \\\"%s\\\".\";"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" static final String ERROR_ENROLL_EXCEED_SECTION_LIMIT_INSTRUCTION \u003d"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" \"To avoid performance problems, please do not enroll more than %s students in a single section.\";"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" private static final UsersLogic instance \u003d new UsersLogic();"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" private static final int MAX_KEY_REGENERATION_TRIES \u003d 10;"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" private UsersDb usersDb;"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" private AccountsLogic accountsLogic;"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" private FeedbackResponsesLogic feedbackResponsesLogic;"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" private FeedbackResponseCommentsLogic feedbackResponseCommentsLogic;"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" private DeadlineExtensionsLogic deadlineExtensionsLogic;"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" private UsersLogic() {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":73,"author":{"gitId":"-"},"content":" }"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" public static UsersLogic inst() {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" void initLogicDependencies(UsersDb usersDb, AccountsLogic accountsLogic, FeedbackResponsesLogic feedbackResponsesLogic,"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" FeedbackResponseCommentsLogic feedbackResponseCommentsLogic,"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" DeadlineExtensionsLogic deadlineExtensionsLogic) {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" this.usersDb \u003d usersDb;"},{"lineNumber":83,"author":{"gitId":"-"},"content":" this.accountsLogic \u003d accountsLogic;"},{"lineNumber":84,"author":{"gitId":"-"},"content":" this.feedbackResponsesLogic \u003d feedbackResponsesLogic;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" this.feedbackResponseCommentsLogic \u003d feedbackResponseCommentsLogic;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" this.deadlineExtensionsLogic \u003d deadlineExtensionsLogic;"},{"lineNumber":87,"author":{"gitId":"-"},"content":" }"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" private InstructorSearchManager getInstructorSearchManager() {"},{"lineNumber":90,"author":{"gitId":"-"},"content":" return usersDb.getInstructorSearchManager();"},{"lineNumber":91,"author":{"gitId":"-"},"content":" }"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" private StudentSearchManager getStudentSearchManager() {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" return usersDb.getStudentSearchManager();"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":98,"author":{"gitId":"-"},"content":" * Creates or updates search document for the given instructor."},{"lineNumber":99,"author":{"gitId":"-"},"content":" */"},{"lineNumber":100,"author":{"gitId":"-"},"content":" public void putInstructorDocument(Instructor instructor) throws SearchServiceException {"},{"lineNumber":101,"author":{"gitId":"-"},"content":" getInstructorSearchManager().putDocument(instructor);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":105,"author":{"gitId":"-"},"content":" * Creates or updates search document for the given student."},{"lineNumber":106,"author":{"gitId":"-"},"content":" */"},{"lineNumber":107,"author":{"gitId":"-"},"content":" public void putStudentDocument(Student student) throws SearchServiceException {"},{"lineNumber":108,"author":{"gitId":"-"},"content":" getStudentSearchManager().putDocument(student);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" }"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":112,"author":{"gitId":"-"},"content":" * Create an instructor."},{"lineNumber":113,"author":{"gitId":"-"},"content":" *"},{"lineNumber":114,"author":{"gitId":"-"},"content":" * @return the created instructor"},{"lineNumber":115,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the instructor is not valid"},{"lineNumber":116,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the instructor already exists in the"},{"lineNumber":117,"author":{"gitId":"-"},"content":" * database."},{"lineNumber":118,"author":{"gitId":"-"},"content":" */"},{"lineNumber":119,"author":{"gitId":"-"},"content":" public Instructor createInstructor(Instructor instructor)"},{"lineNumber":120,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":121,"author":{"gitId":"mingyuanc"},"content":" if (getInstructorForEmail(instructor.getCourseId(), instructor.getEmail()) !\u003d null) {"},{"lineNumber":122,"author":{"gitId":"mingyuanc"},"content":" throw new EntityAlreadyExistsException(\"Instructor already exists.\");"},{"lineNumber":123,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":124,"author":{"gitId":"-"},"content":" return usersDb.createInstructor(instructor);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" }"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":128,"author":{"gitId":"-"},"content":" * Updates an instructor and cascades to responses and comments if needed."},{"lineNumber":129,"author":{"gitId":"-"},"content":" *"},{"lineNumber":130,"author":{"gitId":"-"},"content":" * @return updated instructor"},{"lineNumber":131,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the instructor update request is invalid"},{"lineNumber":132,"author":{"gitId":"-"},"content":" * @throws InstructorUpdateException if the update violates instructor validity"},{"lineNumber":133,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the instructor does not exist in the database"},{"lineNumber":134,"author":{"gitId":"-"},"content":" */"},{"lineNumber":135,"author":{"gitId":"-"},"content":" public Instructor updateInstructorCascade(String courseId, InstructorCreateRequest instructorRequest) throws"},{"lineNumber":136,"author":{"gitId":"-"},"content":" InvalidParametersException, InstructorUpdateException, EntityDoesNotExistException {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" Instructor instructor;"},{"lineNumber":138,"author":{"gitId":"-"},"content":" String instructorId \u003d instructorRequest.getId();"},{"lineNumber":139,"author":{"gitId":"-"},"content":" if (instructorId \u003d\u003d null) {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" instructor \u003d getInstructorForEmail(courseId, instructorRequest.getEmail());"},{"lineNumber":141,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" instructor \u003d getInstructorByGoogleId(courseId, instructorId);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" }"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":146,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(\"Trying to update an instructor that does not exist.\");"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" verifyAtLeastOneInstructorIsDisplayed("},{"lineNumber":150,"author":{"gitId":"-"},"content":" courseId, instructor.isDisplayedToStudents(), instructorRequest.getIsDisplayedToStudent());"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" String originalEmail \u003d instructor.getEmail();"},{"lineNumber":153,"author":{"gitId":"-"},"content":" boolean needsCascade \u003d false;"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" String newDisplayName \u003d instructorRequest.getDisplayName();"},{"lineNumber":156,"author":{"gitId":"-"},"content":" if (newDisplayName \u003d\u003d null || newDisplayName.isEmpty()) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" newDisplayName \u003d Const.DEFAULT_DISPLAY_NAME_FOR_INSTRUCTOR;"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" instructor.setName(SanitizationHelper.sanitizeName(instructorRequest.getName()));"},{"lineNumber":161,"author":{"gitId":"-"},"content":" instructor.setEmail(SanitizationHelper.sanitizeEmail(instructorRequest.getEmail()));"},{"lineNumber":162,"author":{"gitId":"-"},"content":" instructor.setRole(InstructorPermissionRole.getEnum(instructorRequest.getRoleName()));"},{"lineNumber":163,"author":{"gitId":"-"},"content":" instructor.setPrivileges(new InstructorPrivileges(instructorRequest.getRoleName()));"},{"lineNumber":164,"author":{"gitId":"-"},"content":" instructor.setDisplayName(SanitizationHelper.sanitizeName(newDisplayName));"},{"lineNumber":165,"author":{"gitId":"-"},"content":" instructor.setDisplayedToStudents(instructorRequest.getIsDisplayedToStudent());"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" String newEmail \u003d instructor.getEmail();"},{"lineNumber":168,"author":{"gitId":"-"},"content":""},{"lineNumber":169,"author":{"gitId":"-"},"content":" if (!originalEmail.equals(newEmail)) {"},{"lineNumber":170,"author":{"gitId":"-"},"content":" needsCascade \u003d true;"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" if (!instructor.isValid()) {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(instructor.getInvalidityInfo());"},{"lineNumber":175,"author":{"gitId":"-"},"content":" }"},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":" if (needsCascade) {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" // cascade responses"},{"lineNumber":179,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponse\u003e responsesFromUser \u003d"},{"lineNumber":180,"author":{"gitId":"-"},"content":" feedbackResponsesLogic.getFeedbackResponsesFromGiverForCourse(courseId, originalEmail);"},{"lineNumber":181,"author":{"gitId":"-"},"content":" for (FeedbackResponse responseFromUser : responsesFromUser) {"},{"lineNumber":182,"author":{"gitId":"-"},"content":" FeedbackQuestion question \u003d responseFromUser.getFeedbackQuestion();"},{"lineNumber":183,"author":{"gitId":"-"},"content":" if (question.getGiverType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":184,"author":{"gitId":"-"},"content":" || question.getGiverType() \u003d\u003d FeedbackParticipantType.SELF) {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" responseFromUser.setGiver(newEmail);"},{"lineNumber":186,"author":{"gitId":"-"},"content":" }"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponse\u003e responsesToUser \u003d"},{"lineNumber":189,"author":{"gitId":"-"},"content":" feedbackResponsesLogic.getFeedbackResponsesForRecipientForCourse(courseId, originalEmail);"},{"lineNumber":190,"author":{"gitId":"-"},"content":" for (FeedbackResponse responseToUser : responsesToUser) {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" FeedbackQuestion question \u003d responseToUser.getFeedbackQuestion();"},{"lineNumber":192,"author":{"gitId":"-"},"content":" if (question.getRecipientType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":193,"author":{"gitId":"-"},"content":" || question.getGiverType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":194,"author":{"gitId":"-"},"content":" \u0026\u0026 question.getRecipientType() \u003d\u003d FeedbackParticipantType.SELF) {"},{"lineNumber":195,"author":{"gitId":"-"},"content":" responseToUser.setRecipient(newEmail);"},{"lineNumber":196,"author":{"gitId":"-"},"content":" }"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }"},{"lineNumber":198,"author":{"gitId":"-"},"content":" // cascade comments"},{"lineNumber":199,"author":{"gitId":"-"},"content":" feedbackResponseCommentsLogic.updateFeedbackResponseCommentsEmails(courseId, originalEmail, newEmail);"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }"},{"lineNumber":201,"author":{"gitId":"-"},"content":""},{"lineNumber":202,"author":{"gitId":"-"},"content":" return instructor;"},{"lineNumber":203,"author":{"gitId":"-"},"content":" }"},{"lineNumber":204,"author":{"gitId":"-"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":206,"author":{"gitId":"-"},"content":" * Verifies that at least one instructor is displayed to studens."},{"lineNumber":207,"author":{"gitId":"-"},"content":" *"},{"lineNumber":208,"author":{"gitId":"-"},"content":" * @throws InstructorUpdateException if there is no instructor displayed to students."},{"lineNumber":209,"author":{"gitId":"-"},"content":" */"},{"lineNumber":210,"author":{"gitId":"-"},"content":" void verifyAtLeastOneInstructorIsDisplayed(String courseId, boolean isOriginalInstructorDisplayed,"},{"lineNumber":211,"author":{"gitId":"-"},"content":" boolean isEditedInstructorDisplayed)"},{"lineNumber":212,"author":{"gitId":"-"},"content":" throws InstructorUpdateException {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorsDisplayed \u003d usersDb.getInstructorsDisplayedToStudents(courseId);"},{"lineNumber":214,"author":{"gitId":"-"},"content":" boolean isEditedInstructorChangedToNonVisible \u003d isOriginalInstructorDisplayed \u0026\u0026 !isEditedInstructorDisplayed;"},{"lineNumber":215,"author":{"gitId":"-"},"content":" boolean isNoInstructorMadeVisible \u003d instructorsDisplayed.isEmpty() \u0026\u0026 !isEditedInstructorDisplayed;"},{"lineNumber":216,"author":{"gitId":"-"},"content":""},{"lineNumber":217,"author":{"gitId":"-"},"content":" if (isNoInstructorMadeVisible || instructorsDisplayed.size() \u003d\u003d 1 \u0026\u0026 isEditedInstructorChangedToNonVisible) {"},{"lineNumber":218,"author":{"gitId":"-"},"content":" throw new InstructorUpdateException(\"At least one instructor must be displayed to students\");"},{"lineNumber":219,"author":{"gitId":"-"},"content":" }"},{"lineNumber":220,"author":{"gitId":"-"},"content":" }"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":223,"author":{"gitId":"-"},"content":" * Creates a student."},{"lineNumber":224,"author":{"gitId":"-"},"content":" *"},{"lineNumber":225,"author":{"gitId":"-"},"content":" * @return the created student"},{"lineNumber":226,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the student is not valid"},{"lineNumber":227,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the student already exists in the"},{"lineNumber":228,"author":{"gitId":"-"},"content":" * database."},{"lineNumber":229,"author":{"gitId":"-"},"content":" */"},{"lineNumber":230,"author":{"gitId":"-"},"content":" public Student createStudent(Student student) throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":231,"author":{"gitId":"-"},"content":" return usersDb.createStudent(student);"},{"lineNumber":232,"author":{"gitId":"-"},"content":" }"},{"lineNumber":233,"author":{"gitId":"-"},"content":""},{"lineNumber":234,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":235,"author":{"gitId":"-"},"content":" * Gets instructor associated with {@code id}."},{"lineNumber":236,"author":{"gitId":"-"},"content":" *"},{"lineNumber":237,"author":{"gitId":"-"},"content":" * @param id Id of Instructor."},{"lineNumber":238,"author":{"gitId":"-"},"content":" * @return Returns Instructor if found else null."},{"lineNumber":239,"author":{"gitId":"-"},"content":" */"},{"lineNumber":240,"author":{"gitId":"-"},"content":" public Instructor getInstructor(UUID id) {"},{"lineNumber":241,"author":{"gitId":"-"},"content":" assert id !\u003d null;"},{"lineNumber":242,"author":{"gitId":"-"},"content":""},{"lineNumber":243,"author":{"gitId":"-"},"content":" return usersDb.getInstructor(id);"},{"lineNumber":244,"author":{"gitId":"-"},"content":" }"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":247,"author":{"gitId":"-"},"content":" * Gets the instructor with the specified email."},{"lineNumber":248,"author":{"gitId":"-"},"content":" */"},{"lineNumber":249,"author":{"gitId":"-"},"content":" public Instructor getInstructorForEmail(String courseId, String userEmail) {"},{"lineNumber":250,"author":{"gitId":"-"},"content":" return usersDb.getInstructorForEmail(courseId, userEmail);"},{"lineNumber":251,"author":{"gitId":"-"},"content":" }"},{"lineNumber":252,"author":{"gitId":"-"},"content":""},{"lineNumber":253,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":254,"author":{"gitId":"-"},"content":" * Gets instructors matching any of the specified emails."},{"lineNumber":255,"author":{"gitId":"-"},"content":" */"},{"lineNumber":256,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getInstructorsForEmails(String courseId, List\u003cString\u003e userEmails) {"},{"lineNumber":257,"author":{"gitId":"-"},"content":" return usersDb.getInstructorsForEmails(courseId, userEmails);"},{"lineNumber":258,"author":{"gitId":"-"},"content":" }"},{"lineNumber":259,"author":{"gitId":"-"},"content":""},{"lineNumber":260,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":261,"author":{"gitId":"-"},"content":" * Gets an instructor by associated {@code regkey}."},{"lineNumber":262,"author":{"gitId":"-"},"content":" */"},{"lineNumber":263,"author":{"gitId":"-"},"content":" public Instructor getInstructorByRegistrationKey(String regKey) {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" assert regKey !\u003d null;"},{"lineNumber":265,"author":{"gitId":"-"},"content":""},{"lineNumber":266,"author":{"gitId":"-"},"content":" return usersDb.getInstructorByRegKey(regKey);"},{"lineNumber":267,"author":{"gitId":"-"},"content":" }"},{"lineNumber":268,"author":{"gitId":"-"},"content":""},{"lineNumber":269,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":270,"author":{"gitId":"-"},"content":" * Gets an instructor by associated {@code googleId}."},{"lineNumber":271,"author":{"gitId":"-"},"content":" */"},{"lineNumber":272,"author":{"gitId":"-"},"content":" public Instructor getInstructorByGoogleId(String courseId, String googleId) {"},{"lineNumber":273,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":274,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" return usersDb.getInstructorByGoogleId(courseId, googleId);"},{"lineNumber":277,"author":{"gitId":"-"},"content":" }"},{"lineNumber":278,"author":{"gitId":"-"},"content":""},{"lineNumber":279,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":280,"author":{"gitId":"-"},"content":" * Searches instructors in the whole system. Used by admin only."},{"lineNumber":281,"author":{"gitId":"-"},"content":" *"},{"lineNumber":282,"author":{"gitId":"-"},"content":" * @return List of found instructors in the whole system. Null if no result found."},{"lineNumber":283,"author":{"gitId":"-"},"content":" */"},{"lineNumber":284,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e searchInstructorsInWholeSystem(String queryString)"},{"lineNumber":285,"author":{"gitId":"-"},"content":" throws SearchServiceException {"},{"lineNumber":286,"author":{"gitId":"-"},"content":" return usersDb.searchInstructorsInWholeSystem(queryString);"},{"lineNumber":287,"author":{"gitId":"-"},"content":" }"},{"lineNumber":288,"author":{"gitId":"-"},"content":""},{"lineNumber":289,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":290,"author":{"gitId":"-"},"content":" * Deletes an instructor or student."},{"lineNumber":291,"author":{"gitId":"-"},"content":" */"},{"lineNumber":292,"author":{"gitId":"-"},"content":" public \u003cT extends User\u003e void deleteUser(T user) {"},{"lineNumber":293,"author":{"gitId":"-"},"content":" usersDb.deleteUser(user);"},{"lineNumber":294,"author":{"gitId":"-"},"content":" }"},{"lineNumber":295,"author":{"gitId":"-"},"content":""},{"lineNumber":296,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":297,"author":{"gitId":"-"},"content":" * Deletes an instructor and cascades deletion to"},{"lineNumber":298,"author":{"gitId":"-"},"content":" * associated feedback responses, deadline extensions and comments."},{"lineNumber":299,"author":{"gitId":"-"},"content":" *"},{"lineNumber":300,"author":{"gitId":"-"},"content":" * \u003cp\u003eFails silently if the instructor does not exist."},{"lineNumber":301,"author":{"gitId":"-"},"content":" */"},{"lineNumber":302,"author":{"gitId":"-"},"content":" public void deleteInstructorCascade(String courseId, String email) {"},{"lineNumber":303,"author":{"gitId":"-"},"content":" Instructor instructor \u003d getInstructorForEmail(courseId, email);"},{"lineNumber":304,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":305,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":306,"author":{"gitId":"-"},"content":" }"},{"lineNumber":307,"author":{"gitId":"-"},"content":""},{"lineNumber":308,"author":{"gitId":"-"},"content":" feedbackResponsesLogic.deleteFeedbackResponsesForCourseCascade(courseId, email);"},{"lineNumber":309,"author":{"gitId":"-"},"content":" deadlineExtensionsLogic.deleteDeadlineExtensionsForUser(instructor);"},{"lineNumber":310,"author":{"gitId":"-"},"content":" deleteUser(instructor);"},{"lineNumber":311,"author":{"gitId":"-"},"content":" }"},{"lineNumber":312,"author":{"gitId":"-"},"content":""},{"lineNumber":313,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":314,"author":{"gitId":"-"},"content":" * Gets the list of instructors with co-owner privileges in a course."},{"lineNumber":315,"author":{"gitId":"-"},"content":" */"},{"lineNumber":316,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getCoOwnersForCourse(String courseId) {"},{"lineNumber":317,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors \u003d getInstructorsForCourse(courseId);"},{"lineNumber":318,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorsWithCoOwnerPrivileges \u003d new ArrayList\u003c\u003e();"},{"lineNumber":319,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructors) {"},{"lineNumber":320,"author":{"gitId":"-"},"content":" if (!instructor.hasCoownerPrivileges()) {"},{"lineNumber":321,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":322,"author":{"gitId":"-"},"content":" }"},{"lineNumber":323,"author":{"gitId":"-"},"content":" instructorsWithCoOwnerPrivileges.add(instructor);"},{"lineNumber":324,"author":{"gitId":"-"},"content":" }"},{"lineNumber":325,"author":{"gitId":"-"},"content":" return instructorsWithCoOwnerPrivileges;"},{"lineNumber":326,"author":{"gitId":"-"},"content":" }"},{"lineNumber":327,"author":{"gitId":"-"},"content":""},{"lineNumber":328,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":329,"author":{"gitId":"-"},"content":" * Gets a list of instructors for the specified course."},{"lineNumber":330,"author":{"gitId":"-"},"content":" */"},{"lineNumber":331,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getInstructorsForCourse(String courseId) {"},{"lineNumber":332,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructorReturnList \u003d usersDb.getInstructorsForCourse(courseId);"},{"lineNumber":333,"author":{"gitId":"-"},"content":" sortByName(instructorReturnList);"},{"lineNumber":334,"author":{"gitId":"-"},"content":""},{"lineNumber":335,"author":{"gitId":"-"},"content":" return instructorReturnList;"},{"lineNumber":336,"author":{"gitId":"-"},"content":" }"},{"lineNumber":337,"author":{"gitId":"-"},"content":""},{"lineNumber":338,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":339,"author":{"gitId":"-"},"content":" * Check if the instructors with the provided emails exist in the course."},{"lineNumber":340,"author":{"gitId":"-"},"content":" */"},{"lineNumber":341,"author":{"gitId":"-"},"content":" public boolean verifyInstructorsExistInCourse(String courseId, List\u003cString\u003e emails) {"},{"lineNumber":342,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors \u003d usersDb.getInstructorsForEmails(courseId, emails);"},{"lineNumber":343,"author":{"gitId":"-"},"content":" Map\u003cString, User\u003e emailInstructorMap \u003d convertUserListToEmailUserMap(instructors);"},{"lineNumber":344,"author":{"gitId":"-"},"content":""},{"lineNumber":345,"author":{"gitId":"-"},"content":" for (String email : emails) {"},{"lineNumber":346,"author":{"gitId":"-"},"content":" if (!emailInstructorMap.containsKey(email)) {"},{"lineNumber":347,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":348,"author":{"gitId":"-"},"content":" }"},{"lineNumber":349,"author":{"gitId":"-"},"content":" }"},{"lineNumber":350,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":351,"author":{"gitId":"-"},"content":" }"},{"lineNumber":352,"author":{"gitId":"-"},"content":""},{"lineNumber":353,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":354,"author":{"gitId":"-"},"content":" * Gets all instructors associated with a googleId."},{"lineNumber":355,"author":{"gitId":"-"},"content":" */"},{"lineNumber":356,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getInstructorsForGoogleId(String googleId) {"},{"lineNumber":357,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":358,"author":{"gitId":"-"},"content":" return usersDb.getInstructorsForGoogleId(googleId);"},{"lineNumber":359,"author":{"gitId":"-"},"content":" }"},{"lineNumber":360,"author":{"gitId":"-"},"content":""},{"lineNumber":361,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":362,"author":{"gitId":"-"},"content":" * Make the instructor join the course, i.e. associate an account to the instructor with the given googleId."},{"lineNumber":363,"author":{"gitId":"-"},"content":" * Creates an account for the instructor if no existing account is found."},{"lineNumber":364,"author":{"gitId":"-"},"content":" * Preconditions:"},{"lineNumber":365,"author":{"gitId":"-"},"content":" * Parameters regkey and googleId are non-null."},{"lineNumber":366,"author":{"gitId":"-"},"content":" * @throws EntityAlreadyExistsException if the instructor already exists in the database."},{"lineNumber":367,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if the instructor parameters are not valid"},{"lineNumber":368,"author":{"gitId":"-"},"content":" */"},{"lineNumber":369,"author":{"gitId":"-"},"content":" public Instructor joinCourseForInstructor(String googleId, Instructor instructor)"},{"lineNumber":370,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" if (googleId \u003d\u003d null) {"},{"lineNumber":372,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(\"Instructor\u0027s googleId cannot be null\");"},{"lineNumber":373,"author":{"gitId":"-"},"content":" }"},{"lineNumber":374,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":375,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(\"Instructor cannot be null\");"},{"lineNumber":376,"author":{"gitId":"-"},"content":" }"},{"lineNumber":377,"author":{"gitId":"-"},"content":""},{"lineNumber":378,"author":{"gitId":"-"},"content":" // setting account for instructor sets it as registered"},{"lineNumber":379,"author":{"gitId":"-"},"content":" if (instructor.getAccount() \u003d\u003d null) {"},{"lineNumber":380,"author":{"gitId":"-"},"content":" Account dbAccount \u003d accountsLogic.getAccountForGoogleId(googleId);"},{"lineNumber":381,"author":{"gitId":"-"},"content":" if (dbAccount !\u003d null) {"},{"lineNumber":382,"author":{"gitId":"-"},"content":" instructor.setAccount(dbAccount);"},{"lineNumber":383,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":384,"author":{"gitId":"-"},"content":" Account account \u003d new Account(googleId, instructor.getName(), instructor.getEmail());"},{"lineNumber":385,"author":{"gitId":"-"},"content":" instructor.setAccount(account);"},{"lineNumber":386,"author":{"gitId":"-"},"content":" accountsLogic.createAccount(account);"},{"lineNumber":387,"author":{"gitId":"-"},"content":" }"},{"lineNumber":388,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":389,"author":{"gitId":"-"},"content":" instructor.setGoogleId(googleId);"},{"lineNumber":390,"author":{"gitId":"-"},"content":" }"},{"lineNumber":391,"author":{"gitId":"-"},"content":" usersDb.updateUser(instructor);"},{"lineNumber":392,"author":{"gitId":"-"},"content":""},{"lineNumber":393,"author":{"gitId":"-"},"content":" // Update the googleId of the student entity for the instructor which was created from sample data."},{"lineNumber":394,"author":{"gitId":"-"},"content":" Student student \u003d getStudentForEmail(instructor.getCourseId(), instructor.getEmail());"},{"lineNumber":395,"author":{"gitId":"-"},"content":" if (student !\u003d null) {"},{"lineNumber":396,"author":{"gitId":"-"},"content":" if (student.getAccount() \u003d\u003d null) {"},{"lineNumber":397,"author":{"gitId":"-"},"content":" Account account \u003d new Account(googleId, student.getName(), student.getEmail());"},{"lineNumber":398,"author":{"gitId":"-"},"content":" student.setAccount(account);"},{"lineNumber":399,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":400,"author":{"gitId":"-"},"content":" student.getAccount().setGoogleId(googleId);"},{"lineNumber":401,"author":{"gitId":"-"},"content":" }"},{"lineNumber":402,"author":{"gitId":"-"},"content":" usersDb.updateUser(student);"},{"lineNumber":403,"author":{"gitId":"-"},"content":" }"},{"lineNumber":404,"author":{"gitId":"-"},"content":""},{"lineNumber":405,"author":{"gitId":"-"},"content":" return instructor;"},{"lineNumber":406,"author":{"gitId":"-"},"content":" }"},{"lineNumber":407,"author":{"gitId":"-"},"content":""},{"lineNumber":408,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":409,"author":{"gitId":"-"},"content":" * Regenerates the registration key for the instructor with email address {@code email} in course {@code courseId}."},{"lineNumber":410,"author":{"gitId":"-"},"content":" *"},{"lineNumber":411,"author":{"gitId":"-"},"content":" * @return the instructor with the new registration key."},{"lineNumber":412,"author":{"gitId":"-"},"content":" * @throws InstructorUpdateException if system was unable to generate a new registration key."},{"lineNumber":413,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the instructor does not exist."},{"lineNumber":414,"author":{"gitId":"-"},"content":" */"},{"lineNumber":415,"author":{"gitId":"-"},"content":" public Instructor regenerateInstructorRegistrationKey(String courseId, String email)"},{"lineNumber":416,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, InstructorUpdateException {"},{"lineNumber":417,"author":{"gitId":"-"},"content":" Instructor instructor \u003d getInstructorForEmail(courseId, email);"},{"lineNumber":418,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":419,"author":{"gitId":"-"},"content":" String errorMessage \u003d String.format("},{"lineNumber":420,"author":{"gitId":"-"},"content":" \"The instructor with the email %s could not be found for the course with ID [%s].\", email, courseId);"},{"lineNumber":421,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(errorMessage);"},{"lineNumber":422,"author":{"gitId":"-"},"content":" }"},{"lineNumber":423,"author":{"gitId":"-"},"content":""},{"lineNumber":424,"author":{"gitId":"-"},"content":" String oldKey \u003d instructor.getRegKey();"},{"lineNumber":425,"author":{"gitId":"-"},"content":" int numTries \u003d 0;"},{"lineNumber":426,"author":{"gitId":"-"},"content":" while (numTries \u003c MAX_KEY_REGENERATION_TRIES) {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" instructor.generateNewRegistrationKey();"},{"lineNumber":428,"author":{"gitId":"-"},"content":" if (!instructor.getRegKey().equals(oldKey)) {"},{"lineNumber":429,"author":{"gitId":"-"},"content":" return instructor;"},{"lineNumber":430,"author":{"gitId":"-"},"content":" }"},{"lineNumber":431,"author":{"gitId":"-"},"content":" numTries++;"},{"lineNumber":432,"author":{"gitId":"-"},"content":" }"},{"lineNumber":433,"author":{"gitId":"-"},"content":""},{"lineNumber":434,"author":{"gitId":"-"},"content":" throw new InstructorUpdateException(\"Could not regenerate a new course registration key for the instructor.\");"},{"lineNumber":435,"author":{"gitId":"-"},"content":" }"},{"lineNumber":436,"author":{"gitId":"-"},"content":""},{"lineNumber":437,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":438,"author":{"gitId":"-"},"content":" * Regenerates the registration key for the student with email address {@code email} in course {@code courseId}."},{"lineNumber":439,"author":{"gitId":"-"},"content":" *"},{"lineNumber":440,"author":{"gitId":"-"},"content":" * @return the student with the new registration key."},{"lineNumber":441,"author":{"gitId":"-"},"content":" * @throws StudentUpdateException if system was unable to generate a new registration key."},{"lineNumber":442,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the student does not exist."},{"lineNumber":443,"author":{"gitId":"-"},"content":" */"},{"lineNumber":444,"author":{"gitId":"-"},"content":" public Student regenerateStudentRegistrationKey(String courseId, String email)"},{"lineNumber":445,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException, StudentUpdateException {"},{"lineNumber":446,"author":{"gitId":"-"},"content":" Student student \u003d getStudentForEmail(courseId, email);"},{"lineNumber":447,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":448,"author":{"gitId":"-"},"content":" String errorMessage \u003d String.format("},{"lineNumber":449,"author":{"gitId":"-"},"content":" \"The student with the email %s could not be found for the course with ID [%s].\", email, courseId);"},{"lineNumber":450,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(errorMessage);"},{"lineNumber":451,"author":{"gitId":"-"},"content":" }"},{"lineNumber":452,"author":{"gitId":"-"},"content":""},{"lineNumber":453,"author":{"gitId":"-"},"content":" String oldKey \u003d student.getRegKey();"},{"lineNumber":454,"author":{"gitId":"-"},"content":" int numTries \u003d 0;"},{"lineNumber":455,"author":{"gitId":"-"},"content":" while (numTries \u003c MAX_KEY_REGENERATION_TRIES) {"},{"lineNumber":456,"author":{"gitId":"-"},"content":" student.generateNewRegistrationKey();"},{"lineNumber":457,"author":{"gitId":"-"},"content":" if (!student.getRegKey().equals(oldKey)) {"},{"lineNumber":458,"author":{"gitId":"-"},"content":" return student;"},{"lineNumber":459,"author":{"gitId":"-"},"content":" }"},{"lineNumber":460,"author":{"gitId":"-"},"content":" numTries++;"},{"lineNumber":461,"author":{"gitId":"-"},"content":" }"},{"lineNumber":462,"author":{"gitId":"-"},"content":""},{"lineNumber":463,"author":{"gitId":"-"},"content":" throw new StudentUpdateException(\"Could not regenerate a new course registration key for the student.\");"},{"lineNumber":464,"author":{"gitId":"-"},"content":" }"},{"lineNumber":465,"author":{"gitId":"-"},"content":""},{"lineNumber":466,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":467,"author":{"gitId":"-"},"content":" * Returns true if the user associated with the googleId is an instructor in any course in the system."},{"lineNumber":468,"author":{"gitId":"-"},"content":" */"},{"lineNumber":469,"author":{"gitId":"-"},"content":" public boolean isInstructorInAnyCourse(String googleId) {"},{"lineNumber":470,"author":{"gitId":"-"},"content":" return !usersDb.getAllInstructorsByGoogleId(googleId).isEmpty();"},{"lineNumber":471,"author":{"gitId":"-"},"content":" }"},{"lineNumber":472,"author":{"gitId":"-"},"content":""},{"lineNumber":473,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":474,"author":{"gitId":"-"},"content":" * Gets student associated with {@code id}."},{"lineNumber":475,"author":{"gitId":"-"},"content":" *"},{"lineNumber":476,"author":{"gitId":"-"},"content":" * @param id Id of Student."},{"lineNumber":477,"author":{"gitId":"-"},"content":" * @return Returns Student if found else null."},{"lineNumber":478,"author":{"gitId":"-"},"content":" */"},{"lineNumber":479,"author":{"gitId":"-"},"content":" public Student getStudent(UUID id) {"},{"lineNumber":480,"author":{"gitId":"-"},"content":" assert id !\u003d null;"},{"lineNumber":481,"author":{"gitId":"-"},"content":""},{"lineNumber":482,"author":{"gitId":"-"},"content":" return usersDb.getStudent(id);"},{"lineNumber":483,"author":{"gitId":"-"},"content":" }"},{"lineNumber":484,"author":{"gitId":"-"},"content":""},{"lineNumber":485,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":486,"author":{"gitId":"dishenggg"},"content":" * Gets student reference associated with {@code id}."},{"lineNumber":487,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":488,"author":{"gitId":"dishenggg"},"content":" * @param id Id of Student."},{"lineNumber":489,"author":{"gitId":"dishenggg"},"content":" * @return Returns a proxy for the Student."},{"lineNumber":490,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":491,"author":{"gitId":"dishenggg"},"content":" public Student getStudentReference(UUID id) {"},{"lineNumber":492,"author":{"gitId":"dishenggg"},"content":" assert id !\u003d null;"},{"lineNumber":493,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":494,"author":{"gitId":"dishenggg"},"content":" return usersDb.getStudentReference(id);"},{"lineNumber":495,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":496,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":497,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":498,"author":{"gitId":"-"},"content":" * Gets the student with the specified email."},{"lineNumber":499,"author":{"gitId":"-"},"content":" */"},{"lineNumber":500,"author":{"gitId":"-"},"content":" public Student getStudentForEmail(String courseId, String userEmail) {"},{"lineNumber":501,"author":{"gitId":"-"},"content":" return usersDb.getStudentForEmail(courseId, userEmail);"},{"lineNumber":502,"author":{"gitId":"-"},"content":" }"},{"lineNumber":503,"author":{"gitId":"-"},"content":""},{"lineNumber":504,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":505,"author":{"gitId":"-"},"content":" * Check if the students with the provided emails exist in the course."},{"lineNumber":506,"author":{"gitId":"-"},"content":" */"},{"lineNumber":507,"author":{"gitId":"-"},"content":" public boolean verifyStudentsExistInCourse(String courseId, List\u003cString\u003e emails) {"},{"lineNumber":508,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e students \u003d usersDb.getStudentsForEmails(courseId, emails);"},{"lineNumber":509,"author":{"gitId":"-"},"content":" Map\u003cString, User\u003e emailStudentMap \u003d convertUserListToEmailUserMap(students);"},{"lineNumber":510,"author":{"gitId":"-"},"content":""},{"lineNumber":511,"author":{"gitId":"-"},"content":" for (String email : emails) {"},{"lineNumber":512,"author":{"gitId":"-"},"content":" if (!emailStudentMap.containsKey(email)) {"},{"lineNumber":513,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":514,"author":{"gitId":"-"},"content":" }"},{"lineNumber":515,"author":{"gitId":"-"},"content":" }"},{"lineNumber":516,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":517,"author":{"gitId":"-"},"content":" }"},{"lineNumber":518,"author":{"gitId":"-"},"content":""},{"lineNumber":519,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":520,"author":{"gitId":"-"},"content":" * Gets a list of students with the specified email."},{"lineNumber":521,"author":{"gitId":"-"},"content":" */"},{"lineNumber":522,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getAllStudentsForEmail(String email) {"},{"lineNumber":523,"author":{"gitId":"-"},"content":" return usersDb.getAllStudentsForEmail(email);"},{"lineNumber":524,"author":{"gitId":"-"},"content":" }"},{"lineNumber":525,"author":{"gitId":"-"},"content":""},{"lineNumber":526,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":527,"author":{"gitId":"-"},"content":" * Gets all students associated with a googleId."},{"lineNumber":528,"author":{"gitId":"-"},"content":" */"},{"lineNumber":529,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getAllStudentsByGoogleId(String googleId) {"},{"lineNumber":530,"author":{"gitId":"-"},"content":" return usersDb.getAllStudentsByGoogleId(googleId);"},{"lineNumber":531,"author":{"gitId":"-"},"content":" }"},{"lineNumber":532,"author":{"gitId":"-"},"content":""},{"lineNumber":533,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":534,"author":{"gitId":"-"},"content":" * Gets a list of students for the specified course."},{"lineNumber":535,"author":{"gitId":"-"},"content":" */"},{"lineNumber":536,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsForCourse(String courseId) {"},{"lineNumber":537,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e studentReturnList \u003d usersDb.getStudentsForCourse(courseId);"},{"lineNumber":538,"author":{"gitId":"-"},"content":" sortByName(studentReturnList);"},{"lineNumber":539,"author":{"gitId":"-"},"content":""},{"lineNumber":540,"author":{"gitId":"-"},"content":" return studentReturnList;"},{"lineNumber":541,"author":{"gitId":"-"},"content":" }"},{"lineNumber":542,"author":{"gitId":"-"},"content":""},{"lineNumber":543,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":544,"author":{"gitId":"-"},"content":" * Gets a list of unregistered students for the specified course."},{"lineNumber":545,"author":{"gitId":"-"},"content":" */"},{"lineNumber":546,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getUnregisteredStudentsForCourse(String courseId) {"},{"lineNumber":547,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e students \u003d getStudentsForCourse(courseId);"},{"lineNumber":548,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e unregisteredStudents \u003d new ArrayList\u003c\u003e();"},{"lineNumber":549,"author":{"gitId":"-"},"content":""},{"lineNumber":550,"author":{"gitId":"-"},"content":" for (Student s : students) {"},{"lineNumber":551,"author":{"gitId":"-"},"content":" if (s.getAccount() \u003d\u003d null) {"},{"lineNumber":552,"author":{"gitId":"-"},"content":" unregisteredStudents.add(s);"},{"lineNumber":553,"author":{"gitId":"-"},"content":" }"},{"lineNumber":554,"author":{"gitId":"-"},"content":" }"},{"lineNumber":555,"author":{"gitId":"-"},"content":""},{"lineNumber":556,"author":{"gitId":"-"},"content":" return unregisteredStudents;"},{"lineNumber":557,"author":{"gitId":"-"},"content":" }"},{"lineNumber":558,"author":{"gitId":"-"},"content":""},{"lineNumber":559,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":560,"author":{"gitId":"yuanxi1"},"content":" * Searches for students."},{"lineNumber":561,"author":{"gitId":"yuanxi1"},"content":" *"},{"lineNumber":562,"author":{"gitId":"yuanxi1"},"content":" * @param instructors the constraint that restricts the search result"},{"lineNumber":563,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":564,"author":{"gitId":"yuanxi1"},"content":" public List\u003cStudent\u003e searchStudents(String queryString, List\u003cInstructor\u003e instructors)"},{"lineNumber":565,"author":{"gitId":"yuanxi1"},"content":" throws SearchServiceException {"},{"lineNumber":566,"author":{"gitId":"yuanxi1"},"content":" return usersDb.searchStudents(queryString, instructors);"},{"lineNumber":567,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":568,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":569,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":570,"author":{"gitId":"yuanxi1"},"content":" * This method should be used by admin only since the searching does not restrict the"},{"lineNumber":571,"author":{"gitId":"yuanxi1"},"content":" * visibility according to the logged-in user\u0027s google ID. This is used by admin to"},{"lineNumber":572,"author":{"gitId":"yuanxi1"},"content":" * search students in the whole system."},{"lineNumber":573,"author":{"gitId":"yuanxi1"},"content":" * @return null if no result found"},{"lineNumber":574,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":575,"author":{"gitId":"yuanxi1"},"content":" public List\u003cStudent\u003e searchStudentsInWholeSystem(String queryString)"},{"lineNumber":576,"author":{"gitId":"yuanxi1"},"content":" throws SearchServiceException {"},{"lineNumber":577,"author":{"gitId":"yuanxi1"},"content":" return usersDb.searchStudentsInWholeSystem(queryString);"},{"lineNumber":578,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":579,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":580,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":581,"author":{"gitId":"-"},"content":" * Gets all students of a section."},{"lineNumber":582,"author":{"gitId":"-"},"content":" */"},{"lineNumber":583,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsForSection(String sectionName, String courseId) {"},{"lineNumber":584,"author":{"gitId":"-"},"content":" return usersDb.getStudentsForSection(sectionName, courseId);"},{"lineNumber":585,"author":{"gitId":"-"},"content":" }"},{"lineNumber":586,"author":{"gitId":"-"},"content":""},{"lineNumber":587,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":588,"author":{"gitId":"-"},"content":" * Gets all students of a team."},{"lineNumber":589,"author":{"gitId":"-"},"content":" */"},{"lineNumber":590,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsForTeam(String teamName, String courseId) {"},{"lineNumber":591,"author":{"gitId":"-"},"content":" return usersDb.getStudentsForTeam(teamName, courseId);"},{"lineNumber":592,"author":{"gitId":"-"},"content":" }"},{"lineNumber":593,"author":{"gitId":"-"},"content":""},{"lineNumber":594,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":595,"author":{"gitId":"-"},"content":" * Gets a student by associated {@code regkey}."},{"lineNumber":596,"author":{"gitId":"-"},"content":" */"},{"lineNumber":597,"author":{"gitId":"-"},"content":" public Student getStudentByRegistrationKey(String regKey) {"},{"lineNumber":598,"author":{"gitId":"-"},"content":" assert regKey !\u003d null;"},{"lineNumber":599,"author":{"gitId":"-"},"content":""},{"lineNumber":600,"author":{"gitId":"-"},"content":" return usersDb.getStudentByRegKey(regKey);"},{"lineNumber":601,"author":{"gitId":"-"},"content":" }"},{"lineNumber":602,"author":{"gitId":"-"},"content":""},{"lineNumber":603,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":604,"author":{"gitId":"-"},"content":" * Gets a student by associated {@code googleId}."},{"lineNumber":605,"author":{"gitId":"-"},"content":" */"},{"lineNumber":606,"author":{"gitId":"-"},"content":" public Student getStudentByGoogleId(String courseId, String googleId) {"},{"lineNumber":607,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":608,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":609,"author":{"gitId":"-"},"content":""},{"lineNumber":610,"author":{"gitId":"-"},"content":" return usersDb.getStudentByGoogleId(courseId, googleId);"},{"lineNumber":611,"author":{"gitId":"-"},"content":" }"},{"lineNumber":612,"author":{"gitId":"-"},"content":""},{"lineNumber":613,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":614,"author":{"gitId":"-"},"content":" * Gets all students associated with a googleId."},{"lineNumber":615,"author":{"gitId":"-"},"content":" */"},{"lineNumber":616,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsByGoogleId(String googleId) {"},{"lineNumber":617,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":618,"author":{"gitId":"-"},"content":""},{"lineNumber":619,"author":{"gitId":"-"},"content":" return usersDb.getStudentsByGoogleId(googleId);"},{"lineNumber":620,"author":{"gitId":"-"},"content":" }"},{"lineNumber":621,"author":{"gitId":"-"},"content":""},{"lineNumber":622,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":623,"author":{"gitId":"-"},"content":" * Returns true if the user associated with the googleId is a student in any"},{"lineNumber":624,"author":{"gitId":"-"},"content":" * course in the system."},{"lineNumber":625,"author":{"gitId":"-"},"content":" */"},{"lineNumber":626,"author":{"gitId":"-"},"content":" public boolean isStudentInAnyCourse(String googleId) {"},{"lineNumber":627,"author":{"gitId":"-"},"content":" return !usersDb.getAllStudentsByGoogleId(googleId).isEmpty();"},{"lineNumber":628,"author":{"gitId":"-"},"content":" }"},{"lineNumber":629,"author":{"gitId":"-"},"content":""},{"lineNumber":630,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":631,"author":{"gitId":"-"},"content":" * Gets all instructors and students by {@code googleId}."},{"lineNumber":632,"author":{"gitId":"-"},"content":" */"},{"lineNumber":633,"author":{"gitId":"-"},"content":" public List\u003cUser\u003e getAllUsersByGoogleId(String googleId) {"},{"lineNumber":634,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":635,"author":{"gitId":"-"},"content":""},{"lineNumber":636,"author":{"gitId":"-"},"content":" return usersDb.getAllUsersByGoogleId(googleId);"},{"lineNumber":637,"author":{"gitId":"-"},"content":" }"},{"lineNumber":638,"author":{"gitId":"-"},"content":""},{"lineNumber":639,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":640,"author":{"gitId":"domoberzin"},"content":" * Gets the section with the name in a particular course."},{"lineNumber":641,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":642,"author":{"gitId":"domoberzin"},"content":" public Section getSection(String courseId, String sectionName) {"},{"lineNumber":643,"author":{"gitId":"domoberzin"},"content":" return usersDb.getSection(courseId, sectionName);"},{"lineNumber":644,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":645,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":646,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":647,"author":{"gitId":"domoberzin"},"content":" * Gets the section with the name in a particular course, otherwise creates a new section."},{"lineNumber":648,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":649,"author":{"gitId":"domoberzin"},"content":" public Section getSectionOrCreate(String courseId, String sectionName) {"},{"lineNumber":650,"author":{"gitId":"domoberzin"},"content":" return usersDb.getSectionOrCreate(courseId, sectionName);"},{"lineNumber":651,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":652,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":653,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":654,"author":{"gitId":"domoberzin"},"content":" * Gets the team with the name in a particular session, otherwise creates a new team."},{"lineNumber":655,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":656,"author":{"gitId":"domoberzin"},"content":" public Team getTeamOrCreate(Section section, String teamName) {"},{"lineNumber":657,"author":{"gitId":"domoberzin"},"content":" return usersDb.getTeamOrCreate(section, teamName);"},{"lineNumber":658,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":659,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":660,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":661,"author":{"gitId":"-"},"content":" * Checks if there are any other registered instructors that can modify instructors."},{"lineNumber":662,"author":{"gitId":"-"},"content":" * If there are none, the instructor currently being edited will be granted the privilege"},{"lineNumber":663,"author":{"gitId":"-"},"content":" * of modifying instructors automatically."},{"lineNumber":664,"author":{"gitId":"-"},"content":" *"},{"lineNumber":665,"author":{"gitId":"-"},"content":" * @param courseId Id of the course."},{"lineNumber":666,"author":{"gitId":"-"},"content":" * @param instructorToEdit Instructor that will be edited."},{"lineNumber":667,"author":{"gitId":"-"},"content":" * This may be modified within the method."},{"lineNumber":668,"author":{"gitId":"-"},"content":" */"},{"lineNumber":669,"author":{"gitId":"-"},"content":" public void updateToEnsureValidityOfInstructorsForTheCourse(String courseId, Instructor instructorToEdit) {"},{"lineNumber":670,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors \u003d getInstructorsForCourse(courseId);"},{"lineNumber":671,"author":{"gitId":"-"},"content":" int numOfInstrCanModifyInstructor \u003d 0;"},{"lineNumber":672,"author":{"gitId":"-"},"content":" Instructor instrWithModifyInstructorPrivilege \u003d null;"},{"lineNumber":673,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructors) {"},{"lineNumber":674,"author":{"gitId":"-"},"content":" if (instructor.isAllowedForPrivilege(Const.InstructorPermissions.CAN_MODIFY_INSTRUCTOR)) {"},{"lineNumber":675,"author":{"gitId":"-"},"content":" numOfInstrCanModifyInstructor++;"},{"lineNumber":676,"author":{"gitId":"-"},"content":" instrWithModifyInstructorPrivilege \u003d instructor;"},{"lineNumber":677,"author":{"gitId":"-"},"content":" }"},{"lineNumber":678,"author":{"gitId":"-"},"content":" }"},{"lineNumber":679,"author":{"gitId":"-"},"content":" boolean isLastRegInstructorWithPrivilege \u003d numOfInstrCanModifyInstructor \u003c\u003d 1"},{"lineNumber":680,"author":{"gitId":"-"},"content":" \u0026\u0026 instrWithModifyInstructorPrivilege !\u003d null"},{"lineNumber":681,"author":{"gitId":"-"},"content":" \u0026\u0026 (!instrWithModifyInstructorPrivilege.isRegistered()"},{"lineNumber":682,"author":{"gitId":"-"},"content":" || instrWithModifyInstructorPrivilege.getGoogleId()"},{"lineNumber":683,"author":{"gitId":"-"},"content":" .equals(instructorToEdit.getGoogleId()));"},{"lineNumber":684,"author":{"gitId":"-"},"content":" if (isLastRegInstructorWithPrivilege) {"},{"lineNumber":685,"author":{"gitId":"-"},"content":" instructorToEdit.getPrivileges().updatePrivilege(Const.InstructorPermissions.CAN_MODIFY_INSTRUCTOR, true);"},{"lineNumber":686,"author":{"gitId":"-"},"content":" }"},{"lineNumber":687,"author":{"gitId":"-"},"content":" }"},{"lineNumber":688,"author":{"gitId":"-"},"content":""},{"lineNumber":689,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":690,"author":{"gitId":"-"},"content":" * Deletes a student along with its associated feedback responses, deadline extensions and comments."},{"lineNumber":691,"author":{"gitId":"-"},"content":" *"},{"lineNumber":692,"author":{"gitId":"-"},"content":" * \u003cp\u003eFails silently if the student does not exist."},{"lineNumber":693,"author":{"gitId":"-"},"content":" */"},{"lineNumber":694,"author":{"gitId":"-"},"content":" public void deleteStudentCascade(String courseId, String studentEmail) {"},{"lineNumber":695,"author":{"gitId":"-"},"content":" Student student \u003d getStudentForEmail(courseId, studentEmail);"},{"lineNumber":696,"author":{"gitId":"-"},"content":""},{"lineNumber":697,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":698,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":699,"author":{"gitId":"-"},"content":" }"},{"lineNumber":700,"author":{"gitId":"-"},"content":""},{"lineNumber":701,"author":{"gitId":"-"},"content":" feedbackResponsesLogic"},{"lineNumber":702,"author":{"gitId":"-"},"content":" .deleteFeedbackResponsesForCourseCascade(courseId, studentEmail);"},{"lineNumber":703,"author":{"gitId":"-"},"content":""},{"lineNumber":704,"author":{"gitId":"-"},"content":" if (usersDb.getStudentCountForTeam(student.getTeamName(), student.getCourseId()) \u003d\u003d 1) {"},{"lineNumber":705,"author":{"gitId":"-"},"content":" // the student is the only student in the team, delete responses related to the team"},{"lineNumber":706,"author":{"gitId":"-"},"content":" feedbackResponsesLogic"},{"lineNumber":707,"author":{"gitId":"-"},"content":" .deleteFeedbackResponsesForCourseCascade("},{"lineNumber":708,"author":{"gitId":"-"},"content":" student.getCourse().getId(), student.getTeamName());"},{"lineNumber":709,"author":{"gitId":"-"},"content":" }"},{"lineNumber":710,"author":{"gitId":"-"},"content":""},{"lineNumber":711,"author":{"gitId":"-"},"content":" deadlineExtensionsLogic.deleteDeadlineExtensionsForUser(student);"},{"lineNumber":712,"author":{"gitId":"-"},"content":" deleteUser(student);"},{"lineNumber":713,"author":{"gitId":"-"},"content":" feedbackResponsesLogic.updateRankRecipientQuestionResponsesAfterDeletingStudent(courseId);"},{"lineNumber":714,"author":{"gitId":"-"},"content":" }"},{"lineNumber":715,"author":{"gitId":"-"},"content":""},{"lineNumber":716,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":717,"author":{"gitId":"-"},"content":" * Deletes students in the course cascade their associated responses, deadline extensions, and comments."},{"lineNumber":718,"author":{"gitId":"-"},"content":" */"},{"lineNumber":719,"author":{"gitId":"-"},"content":" public void deleteStudentsInCourseCascade(String courseId) {"},{"lineNumber":720,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e studentsInCourse \u003d getStudentsForCourse(courseId);"},{"lineNumber":721,"author":{"gitId":"-"},"content":""},{"lineNumber":722,"author":{"gitId":"-"},"content":" for (Student student : studentsInCourse) {"},{"lineNumber":723,"author":{"gitId":"-"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":724,"author":{"gitId":"-"},"content":" deleteStudentCascade(courseId, student.getEmail());"},{"lineNumber":725,"author":{"gitId":"-"},"content":" }"},{"lineNumber":726,"author":{"gitId":"-"},"content":" }"},{"lineNumber":727,"author":{"gitId":"-"},"content":""},{"lineNumber":728,"author":{"gitId":"marquestye"},"content":" private boolean isEmailChanged(String originalEmail, String newEmail) {"},{"lineNumber":729,"author":{"gitId":"marquestye"},"content":" return newEmail !\u003d null \u0026\u0026 !originalEmail.equals(newEmail);"},{"lineNumber":730,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":731,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":732,"author":{"gitId":"domoberzin"},"content":" private boolean isTeamChanged(Team originalTeam, Team newTeam) {"},{"lineNumber":733,"author":{"gitId":"domoberzin"},"content":" return newTeam !\u003d null \u0026\u0026 originalTeam !\u003d null"},{"lineNumber":734,"author":{"gitId":"domoberzin"},"content":" \u0026\u0026 !originalTeam.equals(newTeam);"},{"lineNumber":735,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":736,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":737,"author":{"gitId":"domoberzin"},"content":" private boolean isSectionChanged(Section originalSection, Section newSection) {"},{"lineNumber":738,"author":{"gitId":"domoberzin"},"content":" return newSection !\u003d null \u0026\u0026 originalSection !\u003d null"},{"lineNumber":739,"author":{"gitId":"domoberzin"},"content":" \u0026\u0026 !originalSection.equals(newSection);"},{"lineNumber":740,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":741,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":742,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":743,"author":{"gitId":"domoberzin"},"content":" * Updates a student by {@link Student}."},{"lineNumber":744,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":745,"author":{"gitId":"marquestye"},"content":" * \u003cp\u003eIf email changed, update by recreating the student and cascade update all responses"},{"lineNumber":746,"author":{"gitId":"marquestye"},"content":" * and comments the student gives/receives."},{"lineNumber":747,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":748,"author":{"gitId":"domoberzin"},"content":" * \u003cp\u003eIf team changed, cascade delete all responses the student gives/receives within that team."},{"lineNumber":749,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":750,"author":{"gitId":"domoberzin"},"content":" * \u003cp\u003eIf section changed, cascade update all responses the student gives/receives."},{"lineNumber":751,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":752,"author":{"gitId":"domoberzin"},"content":" * @return updated student"},{"lineNumber":753,"author":{"gitId":"domoberzin"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":754,"author":{"gitId":"domoberzin"},"content":" * @throws EntityDoesNotExistException if the student cannot be found"},{"lineNumber":755,"author":{"gitId":"domoberzin"},"content":" * @throws EntityAlreadyExistsException if the student cannot be updated"},{"lineNumber":756,"author":{"gitId":"domoberzin"},"content":" * by recreation because of an existent student"},{"lineNumber":757,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":758,"author":{"gitId":"domoberzin"},"content":" public Student updateStudentCascade(Student student)"},{"lineNumber":759,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException, EntityAlreadyExistsException {"},{"lineNumber":760,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":761,"author":{"gitId":"marquestye"},"content":" String courseId \u003d student.getCourseId();"},{"lineNumber":762,"author":{"gitId":"marquestye"},"content":" Student originalStudent \u003d getStudent(student.getId());"},{"lineNumber":763,"author":{"gitId":"marquestye"},"content":" String originalEmail \u003d originalStudent.getEmail();"},{"lineNumber":764,"author":{"gitId":"marquestye"},"content":" boolean changedEmail \u003d isEmailChanged(originalEmail, student.getEmail());"},{"lineNumber":765,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":766,"author":{"gitId":"marquestye"},"content":" // check for email conflict"},{"lineNumber":767,"author":{"gitId":"marquestye"},"content":" Student s \u003d usersDb.getStudentForEmail(courseId, student.getEmail());"},{"lineNumber":768,"author":{"gitId":"marquestye"},"content":" if (changedEmail \u0026\u0026 s !\u003d null) {"},{"lineNumber":769,"author":{"gitId":"marquestye"},"content":" String errorMessage \u003d String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, s.toString());"},{"lineNumber":770,"author":{"gitId":"marquestye"},"content":" throw new EntityAlreadyExistsException(errorMessage);"},{"lineNumber":771,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":772,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":773,"author":{"gitId":"domoberzin"},"content":" Team originalTeam \u003d originalStudent.getTeam();"},{"lineNumber":774,"author":{"gitId":"domoberzin"},"content":" Section originalSection \u003d originalStudent.getSection();"},{"lineNumber":775,"author":{"gitId":"domoberzin"},"content":" boolean changedTeam \u003d isTeamChanged(originalTeam, student.getTeam());"},{"lineNumber":776,"author":{"gitId":"domoberzin"},"content":" boolean changedSection \u003d isSectionChanged(originalSection, student.getSection());"},{"lineNumber":777,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":778,"author":{"gitId":"marquestye"},"content":" // update student"},{"lineNumber":779,"author":{"gitId":"marquestye"},"content":" usersDb.checkBeforeUpdateStudent(student);"},{"lineNumber":780,"author":{"gitId":"domoberzin"},"content":" originalStudent.setName(student.getName());"},{"lineNumber":781,"author":{"gitId":"domoberzin"},"content":" originalStudent.setTeam(student.getTeam());"},{"lineNumber":782,"author":{"gitId":"domoberzin"},"content":" originalStudent.setEmail(student.getEmail());"},{"lineNumber":783,"author":{"gitId":"domoberzin"},"content":" originalStudent.setComments(student.getComments());"},{"lineNumber":784,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":785,"author":{"gitId":"marquestye"},"content":" // cascade email changes to responses and comments"},{"lineNumber":786,"author":{"gitId":"marquestye"},"content":" if (changedEmail) {"},{"lineNumber":787,"author":{"gitId":"marquestye"},"content":" feedbackResponsesLogic.updateFeedbackResponsesForChangingEmail(courseId, originalEmail, student.getEmail());"},{"lineNumber":788,"author":{"gitId":"marquestye"},"content":" feedbackResponseCommentsLogic.updateFeedbackResponseCommentsEmails(courseId, originalEmail, student.getEmail());"},{"lineNumber":789,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":790,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":791,"author":{"gitId":"domoberzin"},"content":" // adjust submissions if moving to a different team"},{"lineNumber":792,"author":{"gitId":"domoberzin"},"content":" if (changedTeam) {"},{"lineNumber":793,"author":{"gitId":"marquestye"},"content":" feedbackResponsesLogic.updateFeedbackResponsesForChangingTeam(student.getCourse(), student.getEmail(),"},{"lineNumber":794,"author":{"gitId":"marquestye"},"content":" student.getTeam(), originalTeam);"},{"lineNumber":795,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":796,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":797,"author":{"gitId":"domoberzin"},"content":" // update the new section name in responses"},{"lineNumber":798,"author":{"gitId":"domoberzin"},"content":" if (changedSection) {"},{"lineNumber":799,"author":{"gitId":"domoberzin"},"content":" feedbackResponsesLogic.updateFeedbackResponsesForChangingSection("},{"lineNumber":800,"author":{"gitId":"marquestye"},"content":" student.getCourse(), student.getEmail(), student.getSection());"},{"lineNumber":801,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":802,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":803,"author":{"gitId":"marquestye"},"content":" return originalStudent;"},{"lineNumber":804,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":805,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":806,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":807,"author":{"gitId":"-"},"content":" * Resets the googleId associated with the instructor."},{"lineNumber":808,"author":{"gitId":"-"},"content":" */"},{"lineNumber":809,"author":{"gitId":"-"},"content":" public void resetInstructorGoogleId(String email, String courseId, String googleId)"},{"lineNumber":810,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":811,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":812,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":813,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":814,"author":{"gitId":"-"},"content":""},{"lineNumber":815,"author":{"gitId":"-"},"content":" Instructor instructor \u003d getInstructorForEmail(courseId, email);"},{"lineNumber":816,"author":{"gitId":"-"},"content":""},{"lineNumber":817,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":818,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT"},{"lineNumber":819,"author":{"gitId":"-"},"content":" + \"Instructor [courseId\u003d\" + courseId + \", email\u003d\" + email + \"]\");"},{"lineNumber":820,"author":{"gitId":"-"},"content":" }"},{"lineNumber":821,"author":{"gitId":"-"},"content":""},{"lineNumber":822,"author":{"gitId":"-"},"content":" instructor.setAccount(null);"},{"lineNumber":823,"author":{"gitId":"-"},"content":""},{"lineNumber":824,"author":{"gitId":"-"},"content":" if (usersDb.getAllUsersByGoogleId(googleId).isEmpty()) {"},{"lineNumber":825,"author":{"gitId":"-"},"content":" accountsLogic.deleteAccountCascade(googleId);"},{"lineNumber":826,"author":{"gitId":"-"},"content":" }"},{"lineNumber":827,"author":{"gitId":"-"},"content":" }"},{"lineNumber":828,"author":{"gitId":"-"},"content":""},{"lineNumber":829,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":830,"author":{"gitId":"domoberzin"},"content":" * Validates sections for any limit violations and teams for any team name violations."},{"lineNumber":831,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":832,"author":{"gitId":"domoberzin"},"content":" public void validateSectionsAndTeams("},{"lineNumber":833,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e studentList, String courseId) throws EnrollException {"},{"lineNumber":834,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":835,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e mergedList \u003d getMergedList(studentList, courseId);"},{"lineNumber":836,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":837,"author":{"gitId":"domoberzin"},"content":" if (mergedList.size() \u003c 2) { // no conflicts"},{"lineNumber":838,"author":{"gitId":"domoberzin"},"content":" return;"},{"lineNumber":839,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":840,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":841,"author":{"gitId":"domoberzin"},"content":" String errorMessage \u003d getSectionInvalidityInfo(mergedList) + getTeamInvalidityInfo(mergedList);"},{"lineNumber":842,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":843,"author":{"gitId":"domoberzin"},"content":" if (!errorMessage.isEmpty()) {"},{"lineNumber":844,"author":{"gitId":"domoberzin"},"content":" throw new EnrollException(errorMessage);"},{"lineNumber":845,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":846,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":847,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":848,"author":{"gitId":"domoberzin"},"content":" private List\u003cStudent\u003e getMergedList(List\u003cStudent\u003e studentList, String courseId) {"},{"lineNumber":849,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":850,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e mergedList \u003d new ArrayList\u003c\u003e();"},{"lineNumber":851,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e studentsInCourse \u003d getStudentsForCourse(courseId);"},{"lineNumber":852,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":853,"author":{"gitId":"domoberzin"},"content":" for (Student student : studentList) {"},{"lineNumber":854,"author":{"gitId":"domoberzin"},"content":" mergedList.add(student);"},{"lineNumber":855,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":856,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":857,"author":{"gitId":"domoberzin"},"content":" for (Student student : studentsInCourse) {"},{"lineNumber":858,"author":{"gitId":"domoberzin"},"content":" if (!isInEnrollList(student, mergedList)) {"},{"lineNumber":859,"author":{"gitId":"domoberzin"},"content":" mergedList.add(student);"},{"lineNumber":860,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":861,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":862,"author":{"gitId":"domoberzin"},"content":" return mergedList;"},{"lineNumber":863,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":864,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":865,"author":{"gitId":"domoberzin"},"content":" private String getSectionInvalidityInfo(List\u003cStudent\u003e mergedList) {"},{"lineNumber":866,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":867,"author":{"gitId":"domoberzin"},"content":" mergedList.sort(Comparator.comparing((Student student) -\u003e student.getSectionName())"},{"lineNumber":868,"author":{"gitId":"domoberzin"},"content":" .thenComparing(student -\u003e student.getTeamName())"},{"lineNumber":869,"author":{"gitId":"domoberzin"},"content":" .thenComparing(student -\u003e student.getName()));"},{"lineNumber":870,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":871,"author":{"gitId":"domoberzin"},"content":" List\u003cString\u003e invalidSectionList \u003d new ArrayList\u003c\u003e();"},{"lineNumber":872,"author":{"gitId":"domoberzin"},"content":" int studentsCount \u003d 1;"},{"lineNumber":873,"author":{"gitId":"domoberzin"},"content":" for (int i \u003d 1; i \u003c mergedList.size(); i++) {"},{"lineNumber":874,"author":{"gitId":"domoberzin"},"content":" Student currentStudent \u003d mergedList.get(i);"},{"lineNumber":875,"author":{"gitId":"domoberzin"},"content":" Student previousStudent \u003d mergedList.get(i - 1);"},{"lineNumber":876,"author":{"gitId":"domoberzin"},"content":" if (currentStudent.getSectionName().equals(previousStudent.getSectionName())) {"},{"lineNumber":877,"author":{"gitId":"domoberzin"},"content":" studentsCount++;"},{"lineNumber":878,"author":{"gitId":"domoberzin"},"content":" } else {"},{"lineNumber":879,"author":{"gitId":"domoberzin"},"content":" if (studentsCount \u003e Const.SECTION_SIZE_LIMIT) {"},{"lineNumber":880,"author":{"gitId":"domoberzin"},"content":" invalidSectionList.add(previousStudent.getSectionName());"},{"lineNumber":881,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":882,"author":{"gitId":"domoberzin"},"content":" studentsCount \u003d 1;"},{"lineNumber":883,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":884,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":885,"author":{"gitId":"domoberzin"},"content":" if (i \u003d\u003d mergedList.size() - 1 \u0026\u0026 studentsCount \u003e Const.SECTION_SIZE_LIMIT) {"},{"lineNumber":886,"author":{"gitId":"domoberzin"},"content":" invalidSectionList.add(currentStudent.getSectionName());"},{"lineNumber":887,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":888,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":889,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":890,"author":{"gitId":"domoberzin"},"content":" StringJoiner errorMessage \u003d new StringJoiner(\" \");"},{"lineNumber":891,"author":{"gitId":"domoberzin"},"content":" for (String section : invalidSectionList) {"},{"lineNumber":892,"author":{"gitId":"domoberzin"},"content":" errorMessage.add(String.format("},{"lineNumber":893,"author":{"gitId":"domoberzin"},"content":" ERROR_ENROLL_EXCEED_SECTION_LIMIT,"},{"lineNumber":894,"author":{"gitId":"domoberzin"},"content":" Const.SECTION_SIZE_LIMIT, section));"},{"lineNumber":895,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":896,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":897,"author":{"gitId":"domoberzin"},"content":" if (!invalidSectionList.isEmpty()) {"},{"lineNumber":898,"author":{"gitId":"domoberzin"},"content":" errorMessage.add(String.format("},{"lineNumber":899,"author":{"gitId":"domoberzin"},"content":" ERROR_ENROLL_EXCEED_SECTION_LIMIT_INSTRUCTION,"},{"lineNumber":900,"author":{"gitId":"domoberzin"},"content":" Const.SECTION_SIZE_LIMIT));"},{"lineNumber":901,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":902,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":903,"author":{"gitId":"domoberzin"},"content":" return errorMessage.toString();"},{"lineNumber":904,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":905,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":906,"author":{"gitId":"domoberzin"},"content":" private String getTeamInvalidityInfo(List\u003cStudent\u003e mergedList) {"},{"lineNumber":907,"author":{"gitId":"domoberzin"},"content":" StringJoiner errorMessage \u003d new StringJoiner(\" \");"},{"lineNumber":908,"author":{"gitId":"domoberzin"},"content":" mergedList.sort(Comparator.comparing((Student student) -\u003e student.getTeamName())"},{"lineNumber":909,"author":{"gitId":"domoberzin"},"content":" .thenComparing(student -\u003e student.getName()));"},{"lineNumber":910,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":911,"author":{"gitId":"domoberzin"},"content":" List\u003cString\u003e invalidTeamList \u003d new ArrayList\u003c\u003e();"},{"lineNumber":912,"author":{"gitId":"domoberzin"},"content":" for (int i \u003d 1; i \u003c mergedList.size(); i++) {"},{"lineNumber":913,"author":{"gitId":"domoberzin"},"content":" Student currentStudent \u003d mergedList.get(i);"},{"lineNumber":914,"author":{"gitId":"domoberzin"},"content":" Student previousStudent \u003d mergedList.get(i - 1);"},{"lineNumber":915,"author":{"gitId":"domoberzin"},"content":" if (currentStudent.getTeamName().equals(previousStudent.getTeamName())"},{"lineNumber":916,"author":{"gitId":"domoberzin"},"content":" \u0026\u0026 !currentStudent.getSectionName().equals(previousStudent.getSectionName())"},{"lineNumber":917,"author":{"gitId":"domoberzin"},"content":" \u0026\u0026 !invalidTeamList.contains(currentStudent.getTeamName())) {"},{"lineNumber":918,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":919,"author":{"gitId":"domoberzin"},"content":" errorMessage.add(String.format(ERROR_INVALID_TEAM_NAME,"},{"lineNumber":920,"author":{"gitId":"domoberzin"},"content":" currentStudent.getTeamName(),"},{"lineNumber":921,"author":{"gitId":"domoberzin"},"content":" previousStudent.getSectionName(),"},{"lineNumber":922,"author":{"gitId":"domoberzin"},"content":" currentStudent.getSectionName()));"},{"lineNumber":923,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":924,"author":{"gitId":"domoberzin"},"content":" invalidTeamList.add(currentStudent.getTeamName());"},{"lineNumber":925,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":926,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":927,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":928,"author":{"gitId":"domoberzin"},"content":" if (!invalidTeamList.isEmpty()) {"},{"lineNumber":929,"author":{"gitId":"domoberzin"},"content":" errorMessage.add(ERROR_INVALID_TEAM_NAME_INSTRUCTION);"},{"lineNumber":930,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":931,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":932,"author":{"gitId":"domoberzin"},"content":" return errorMessage.toString();"},{"lineNumber":933,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":934,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":935,"author":{"gitId":"domoberzin"},"content":" private boolean isInEnrollList(Student student,"},{"lineNumber":936,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e studentInfoList) {"},{"lineNumber":937,"author":{"gitId":"domoberzin"},"content":" for (Student studentInfo : studentInfoList) {"},{"lineNumber":938,"author":{"gitId":"domoberzin"},"content":" if (studentInfo.getEmail().equalsIgnoreCase(student.getEmail())) {"},{"lineNumber":939,"author":{"gitId":"domoberzin"},"content":" return true;"},{"lineNumber":940,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":941,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":942,"author":{"gitId":"domoberzin"},"content":" return false;"},{"lineNumber":943,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":944,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":945,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":946,"author":{"gitId":"-"},"content":" * Resets the googleId associated with the student."},{"lineNumber":947,"author":{"gitId":"-"},"content":" */"},{"lineNumber":948,"author":{"gitId":"-"},"content":" public void resetStudentGoogleId(String email, String courseId, String googleId)"},{"lineNumber":949,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":950,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":951,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":952,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":953,"author":{"gitId":"-"},"content":""},{"lineNumber":954,"author":{"gitId":"-"},"content":" Student student \u003d getStudentForEmail(courseId, email);"},{"lineNumber":955,"author":{"gitId":"-"},"content":""},{"lineNumber":956,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":957,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT"},{"lineNumber":958,"author":{"gitId":"-"},"content":" + \"Student [courseId\u003d\" + courseId + \", email\u003d\" + email + \"]\");"},{"lineNumber":959,"author":{"gitId":"-"},"content":" }"},{"lineNumber":960,"author":{"gitId":"-"},"content":""},{"lineNumber":961,"author":{"gitId":"-"},"content":" student.setAccount(null);"},{"lineNumber":962,"author":{"gitId":"-"},"content":""},{"lineNumber":963,"author":{"gitId":"-"},"content":" if (usersDb.getAllUsersByGoogleId(googleId).isEmpty()) {"},{"lineNumber":964,"author":{"gitId":"-"},"content":" accountsLogic.deleteAccountCascade(googleId);"},{"lineNumber":965,"author":{"gitId":"-"},"content":" }"},{"lineNumber":966,"author":{"gitId":"-"},"content":" }"},{"lineNumber":967,"author":{"gitId":"-"},"content":""},{"lineNumber":968,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":969,"author":{"gitId":"-"},"content":" * Sorts the instructors list alphabetically by name."},{"lineNumber":970,"author":{"gitId":"-"},"content":" */"},{"lineNumber":971,"author":{"gitId":"-"},"content":" public static \u003cT extends User\u003e void sortByName(List\u003cT\u003e users) {"},{"lineNumber":972,"author":{"gitId":"-"},"content":" users.sort(Comparator.comparing(user -\u003e user.getName().toLowerCase()));"},{"lineNumber":973,"author":{"gitId":"-"},"content":" }"},{"lineNumber":974,"author":{"gitId":"-"},"content":""},{"lineNumber":975,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":976,"author":{"gitId":"-"},"content":" * Checks if an instructor with {@code googleId} can create a course with"},{"lineNumber":977,"author":{"gitId":"-"},"content":" * {@code institute}"},{"lineNumber":978,"author":{"gitId":"-"},"content":" * (ie. has an existing course(s) with the same {@code institute})."},{"lineNumber":979,"author":{"gitId":"-"},"content":" */"},{"lineNumber":980,"author":{"gitId":"-"},"content":" public boolean canInstructorCreateCourse(String googleId, String institute) {"},{"lineNumber":981,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":982,"author":{"gitId":"-"},"content":" assert institute !\u003d null;"},{"lineNumber":983,"author":{"gitId":"-"},"content":""},{"lineNumber":984,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e existingInstructors \u003d getInstructorsForGoogleId(googleId);"},{"lineNumber":985,"author":{"gitId":"-"},"content":" return existingInstructors"},{"lineNumber":986,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":987,"author":{"gitId":"-"},"content":" .filter(Instructor::hasCoownerPrivileges)"},{"lineNumber":988,"author":{"gitId":"-"},"content":" .map(instructor -\u003e instructor.getCourse())"},{"lineNumber":989,"author":{"gitId":"-"},"content":" .anyMatch(course -\u003e institute.equals(course.getInstitute()));"},{"lineNumber":990,"author":{"gitId":"-"},"content":" }"},{"lineNumber":991,"author":{"gitId":"-"},"content":""},{"lineNumber":992,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":993,"author":{"gitId":"-"},"content":" * Utility function to convert user list to email-user map for faster email lookup."},{"lineNumber":994,"author":{"gitId":"-"},"content":" *"},{"lineNumber":995,"author":{"gitId":"-"},"content":" * @param users users list which contains users with unique email addresses"},{"lineNumber":996,"author":{"gitId":"-"},"content":" * @return email-user map for faster email lookup"},{"lineNumber":997,"author":{"gitId":"-"},"content":" */"},{"lineNumber":998,"author":{"gitId":"-"},"content":" private Map\u003cString, User\u003e convertUserListToEmailUserMap(List\u003c? extends User\u003e users) {"},{"lineNumber":999,"author":{"gitId":"-"},"content":" Map\u003cString, User\u003e emailUserMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":1000,"author":{"gitId":"-"},"content":" users.forEach(u -\u003e emailUserMap.put(u.getEmail(), u));"},{"lineNumber":1001,"author":{"gitId":"-"},"content":""},{"lineNumber":1002,"author":{"gitId":"-"},"content":" return emailUserMap;"},{"lineNumber":1003,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1004,"author":{"gitId":"-"},"content":""},{"lineNumber":1005,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":201,"yuanxi1":21,"marquestye":30,"mingyuanc":3,"dishenggg":12,"-":738}},{"path":"src/main/java/teammates/storage/sqlapi/AccountRequestsDb.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static teammates.common.util.Const.ERROR_UPDATE_NON_EXISTENT;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import java.util.ArrayList;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import java.util.Collections;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import java.util.UUID;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import jakarta.persistence.TypedQuery;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaBuilder;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaQuery;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Root;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.AccountRequestSearchManager;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.SearchManagerFactory;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"-"},"content":" * Generates CRUD operations for AccountRequest."},{"lineNumber":27,"author":{"gitId":"-"},"content":" *"},{"lineNumber":28,"author":{"gitId":"-"},"content":" * @see AccountRequest"},{"lineNumber":29,"author":{"gitId":"-"},"content":" */"},{"lineNumber":30,"author":{"gitId":"-"},"content":"public final class AccountRequestsDb extends EntitiesDb {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" private static final AccountRequestsDb instance \u003d new AccountRequestsDb();"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private AccountRequestsDb() {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" // prevent instantiation"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" public static AccountRequestsDb inst() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" public AccountRequestSearchManager getSearchManager() {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" return SearchManagerFactory.getAccountRequestSearchManager();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" }"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":46,"author":{"gitId":"-"},"content":" * Creates an AccountRequest in the database."},{"lineNumber":47,"author":{"gitId":"-"},"content":" */"},{"lineNumber":48,"author":{"gitId":"-"},"content":" public AccountRequest createAccountRequest(AccountRequest accountRequest) throws InvalidParametersException {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" assert accountRequest !\u003d null;"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" if (!accountRequest.isValid()) {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(accountRequest.getInvalidityInfo());"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":" persist(accountRequest);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" return accountRequest;"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":59,"author":{"gitId":"-"},"content":" * Get AccountRequest by {@code id} from the database."},{"lineNumber":60,"author":{"gitId":"-"},"content":" */"},{"lineNumber":61,"author":{"gitId":"-"},"content":" public AccountRequest getAccountRequest(UUID id) {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" assert id !\u003d null;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" return HibernateUtil.get(AccountRequest.class, id);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" }"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":67,"author":{"gitId":"-"},"content":" * Get all Account Requests with {@code status} of \u0027pending\u0027."},{"lineNumber":68,"author":{"gitId":"-"},"content":" */"},{"lineNumber":69,"author":{"gitId":"-"},"content":" public List\u003cAccountRequest\u003e getPendingAccountRequests() {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":71,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cAccountRequest\u003e cr \u003d cb.createQuery(AccountRequest.class);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" Root\u003cAccountRequest\u003e root \u003d cr.from(AccountRequest.class);"},{"lineNumber":73,"author":{"gitId":"-"},"content":" cr.select(root)"},{"lineNumber":74,"author":{"gitId":"-"},"content":" .where(cb.equal(root.get(\"status\"), AccountRequestStatus.PENDING))"},{"lineNumber":75,"author":{"gitId":"-"},"content":" .orderBy(cb.desc(root.get(\"createdAt\")));"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" TypedQuery\u003cAccountRequest\u003e query \u003d HibernateUtil.createQuery(cr);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" return query.getResultList();"},{"lineNumber":79,"author":{"gitId":"-"},"content":" }"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" * Get all Account Requests."},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccountRequest\u003e getAllAccountRequests() {"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":" CriteriaQuery\u003cAccountRequest\u003e cr \u003d cb.createQuery(AccountRequest.class);"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" Root\u003cAccountRequest\u003e root \u003d cr.from(AccountRequest.class);"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" cr.select(root);"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" TypedQuery\u003cAccountRequest\u003e query \u003d HibernateUtil.createQuery(cr);"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" return query.getResultList();"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" * Get all Account Requests for a given {@code email}."},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccountRequest\u003e getApprovedAccountRequestsForEmail(String email) {"},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" CriteriaQuery\u003cAccountRequest\u003e cr \u003d cb.createQuery(AccountRequest.class);"},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":" Root\u003cAccountRequest\u003e root \u003d cr.from(AccountRequest.class);"},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" cr.select(root).where(cb.and(cb.equal(root.get(\"email\"), email),"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" cb.equal(root.get(\"status\"), AccountRequestStatus.APPROVED)));"},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" TypedQuery\u003cAccountRequest\u003e query \u003d HibernateUtil.createQuery(cr);"},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" return query.getResultList();"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":109,"author":{"gitId":"-"},"content":" * Get AccountRequest by {@code registrationKey} from database."},{"lineNumber":110,"author":{"gitId":"-"},"content":" */"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":" public AccountRequest getAccountRequestByRegistrationKey(String registrationKey) {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":113,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cAccountRequest\u003e cr \u003d cb.createQuery(AccountRequest.class);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" Root\u003cAccountRequest\u003e root \u003d cr.from(AccountRequest.class);"},{"lineNumber":115,"author":{"gitId":"-"},"content":" cr.select(root).where(cb.equal(root.get(\"registrationKey\"), registrationKey));"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" TypedQuery\u003cAccountRequest\u003e query \u003d HibernateUtil.createQuery(cr);"},{"lineNumber":118,"author":{"gitId":"-"},"content":" return query.getResultStream().findFirst().orElse(null);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" }"},{"lineNumber":120,"author":{"gitId":"-"},"content":""},{"lineNumber":121,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":122,"author":{"gitId":"-"},"content":" * Get AccountRequest with {@code createdTime} within the times {@code startTime} and {@code endTime}."},{"lineNumber":123,"author":{"gitId":"-"},"content":" */"},{"lineNumber":124,"author":{"gitId":"-"},"content":" public List\u003cAccountRequest\u003e getAccountRequests(Instant startTime, Instant endTime) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":126,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cAccountRequest\u003e cr \u003d cb.createQuery(AccountRequest.class);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" Root\u003cAccountRequest\u003e root \u003d cr.from(AccountRequest.class);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" cr.select(root).where(cb.and(cb.greaterThanOrEqualTo(root.get(\"createdAt\"), startTime),"},{"lineNumber":129,"author":{"gitId":"-"},"content":" cb.lessThanOrEqualTo(root.get(\"createdAt\"), endTime)));"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" TypedQuery\u003cAccountRequest\u003e query \u003d HibernateUtil.createQuery(cr);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" return query.getResultList();"},{"lineNumber":133,"author":{"gitId":"-"},"content":" }"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":136,"author":{"gitId":"-"},"content":" * Updates or creates (if does not exist) the AccountRequest in the database."},{"lineNumber":137,"author":{"gitId":"-"},"content":" */"},{"lineNumber":138,"author":{"gitId":"-"},"content":" public AccountRequest updateAccountRequest(AccountRequest accountRequest)"},{"lineNumber":139,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" assert accountRequest !\u003d null;"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" if (!accountRequest.isValid()) {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(accountRequest.getInvalidityInfo());"},{"lineNumber":144,"author":{"gitId":"-"},"content":" }"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" if (getAccountRequest(accountRequest.getId()) \u003d\u003d null) {"},{"lineNumber":147,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException("},{"lineNumber":148,"author":{"gitId":"-"},"content":" String.format(ERROR_UPDATE_NON_EXISTENT, accountRequest.toString()));"},{"lineNumber":149,"author":{"gitId":"-"},"content":" }"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" merge(accountRequest);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" return accountRequest;"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":156,"author":{"gitId":"-"},"content":" * Deletes an AccountRequest."},{"lineNumber":157,"author":{"gitId":"-"},"content":" */"},{"lineNumber":158,"author":{"gitId":"-"},"content":" public void deleteAccountRequest(AccountRequest accountRequest) {"},{"lineNumber":159,"author":{"gitId":"-"},"content":" if (accountRequest !\u003d null) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" delete(accountRequest);"},{"lineNumber":161,"author":{"gitId":"domoberzin"},"content":" deleteDocumentByAccountRequestId(accountRequest.getId());"},{"lineNumber":162,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":163,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":164,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":165,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":" * Removes search document for the given account request."},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":" public void deleteDocumentByAccountRequestId(UUID accountRequestId) {"},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" if (getSearchManager() !\u003d null) {"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" getSearchManager().deleteDocuments("},{"lineNumber":171,"author":{"gitId":"-"},"content":" Collections.singletonList(accountRequestId.toString()));"},{"lineNumber":172,"author":{"gitId":"-"},"content":" }"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":" * Searches all account requests in the system."},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":" * \u003cp\u003eThis is used by admin to search account requests in the whole system."},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" public List\u003cAccountRequest\u003e searchAccountRequestsInWholeSystem(String queryString)"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":" throws SearchServiceException {"},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":" if (queryString.trim().isEmpty()) {"},{"lineNumber":184,"author":{"gitId":"domoberzin"},"content":" return new ArrayList\u003c\u003e();"},{"lineNumber":185,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":186,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":187,"author":{"gitId":"domoberzin"},"content":" return getSearchManager().searchAccountRequests(queryString);"},{"lineNumber":188,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":189,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":56,"dishenggg":1,"-":132}},{"path":"src/main/java/teammates/storage/sqlapi/FeedbackQuestionsDb.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"marquestye"},"content":"import static teammates.common.util.Const.ERROR_CREATE_ENTITY_ALREADY_EXISTS;"},{"lineNumber":4,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaBuilder;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaQuery;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Join;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Root;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":14,"author":{"gitId":"marquestye"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":15,"author":{"gitId":"marquestye"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * Handles CRUD operations for feedback questions."},{"lineNumber":23,"author":{"gitId":"-"},"content":" *"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * @see FeedbackQuestion"},{"lineNumber":25,"author":{"gitId":"-"},"content":" */"},{"lineNumber":26,"author":{"gitId":"-"},"content":"public final class FeedbackQuestionsDb extends EntitiesDb {"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" private static final FeedbackQuestionsDb instance \u003d new FeedbackQuestionsDb();"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" private FeedbackQuestionsDb() {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":32,"author":{"gitId":"-"},"content":" }"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" public static FeedbackQuestionsDb inst() {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" }"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":39,"author":{"gitId":"-"},"content":" * Creates a new feedback question."},{"lineNumber":40,"author":{"gitId":"-"},"content":" *"},{"lineNumber":41,"author":{"gitId":"-"},"content":" * @return the created question"},{"lineNumber":42,"author":{"gitId":"marquestye"},"content":" * @throws InvalidParametersException if the question is invalid"},{"lineNumber":43,"author":{"gitId":"marquestye"},"content":" * @throws EntityAlreadyExistsException if the question already exists"},{"lineNumber":44,"author":{"gitId":"-"},"content":" */"},{"lineNumber":45,"author":{"gitId":"marquestye"},"content":" public FeedbackQuestion createFeedbackQuestion(FeedbackQuestion feedbackQuestion)"},{"lineNumber":46,"author":{"gitId":"marquestye"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":47,"author":{"gitId":"marquestye"},"content":" assert feedbackQuestion !\u003d null;"},{"lineNumber":48,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":49,"author":{"gitId":"marquestye"},"content":" if (!feedbackQuestion.isValid()) {"},{"lineNumber":50,"author":{"gitId":"marquestye"},"content":" throw new InvalidParametersException(feedbackQuestion.getInvalidityInfo());"},{"lineNumber":51,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":52,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":53,"author":{"gitId":"marquestye"},"content":" if (getFeedbackQuestion(feedbackQuestion.getId()) !\u003d null) {"},{"lineNumber":54,"author":{"gitId":"marquestye"},"content":" String errorMessage \u003d String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, feedbackQuestion.toString());"},{"lineNumber":55,"author":{"gitId":"marquestye"},"content":" throw new EntityAlreadyExistsException(errorMessage);"},{"lineNumber":56,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":57,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" persist(feedbackQuestion);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" return feedbackQuestion;"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":63,"author":{"gitId":"-"},"content":" * Gets a feedback question."},{"lineNumber":64,"author":{"gitId":"-"},"content":" *"},{"lineNumber":65,"author":{"gitId":"-"},"content":" * @return null if not found"},{"lineNumber":66,"author":{"gitId":"-"},"content":" */"},{"lineNumber":67,"author":{"gitId":"-"},"content":" public FeedbackQuestion getFeedbackQuestion(UUID fqId) {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" assert fqId !\u003d null;"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" return HibernateUtil.get(FeedbackQuestion.class, fqId);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":74,"author":{"gitId":"-"},"content":" * Gets all feedback questions of a session."},{"lineNumber":75,"author":{"gitId":"-"},"content":" */"},{"lineNumber":76,"author":{"gitId":"-"},"content":" public List\u003cFeedbackQuestion\u003e getFeedbackQuestionsForSession(UUID fdId) {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":78,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackQuestion\u003e cq \u003d cb.createQuery(FeedbackQuestion.class);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" Root\u003cFeedbackQuestion\u003e fqRoot \u003d cq.from(FeedbackQuestion.class);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fqJoin \u003d fqRoot.join(\"feedbackSession\");"},{"lineNumber":81,"author":{"gitId":"-"},"content":" cq.select(fqRoot).where(cb.equal(fqJoin.get(\"id\"), fdId));"},{"lineNumber":82,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":83,"author":{"gitId":"-"},"content":" }"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":86,"author":{"gitId":"-"},"content":" * Gets a list of feedback questions by {@code feedbackSession} and {@code giverType}."},{"lineNumber":87,"author":{"gitId":"-"},"content":" *"},{"lineNumber":88,"author":{"gitId":"-"},"content":" * @return null if not found"},{"lineNumber":89,"author":{"gitId":"-"},"content":" */"},{"lineNumber":90,"author":{"gitId":"-"},"content":" public List\u003cFeedbackQuestion\u003e getFeedbackQuestionsForGiverType("},{"lineNumber":91,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession, FeedbackParticipantType giverType) {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":93,"author":{"gitId":"-"},"content":" assert giverType !\u003d null;"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":96,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackQuestion\u003e cq \u003d cb.createQuery(FeedbackQuestion.class);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" Root\u003cFeedbackQuestion\u003e root \u003d cq.from(FeedbackQuestion.class);"},{"lineNumber":98,"author":{"gitId":"-"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fqJoin \u003d root.join(\"feedbackSession\");"},{"lineNumber":99,"author":{"gitId":"-"},"content":" cq.select(root)"},{"lineNumber":100,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":101,"author":{"gitId":"-"},"content":" cb.equal(fqJoin.get(\"id\"), feedbackSession.getId()),"},{"lineNumber":102,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"giverType\"), giverType)));"},{"lineNumber":103,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":107,"author":{"gitId":"-"},"content":" * Deletes a feedback question."},{"lineNumber":108,"author":{"gitId":"-"},"content":" */"},{"lineNumber":109,"author":{"gitId":"-"},"content":" public void deleteFeedbackQuestion(UUID fqId) {"},{"lineNumber":110,"author":{"gitId":"-"},"content":" assert fqId !\u003d null;"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" FeedbackQuestion fq \u003d getFeedbackQuestion(fqId);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" if (fq !\u003d null) {"},{"lineNumber":114,"author":{"gitId":"-"},"content":" delete(fq);"},{"lineNumber":115,"author":{"gitId":"-"},"content":" }"},{"lineNumber":116,"author":{"gitId":"-"},"content":" }"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":119,"author":{"gitId":"-"},"content":" * Checks if there is any feedback questions in a session in a course for the given giver type."},{"lineNumber":120,"author":{"gitId":"-"},"content":" */"},{"lineNumber":121,"author":{"gitId":"-"},"content":" public boolean hasFeedbackQuestionsForGiverType("},{"lineNumber":122,"author":{"gitId":"-"},"content":" String feedbackSessionName, String courseId, FeedbackParticipantType giverType) {"},{"lineNumber":123,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":124,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackQuestion\u003e cq \u003d cb.createQuery(FeedbackQuestion.class);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" Root\u003cFeedbackQuestion\u003e root \u003d cq.from(FeedbackQuestion.class);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d root.join(\"feedbackSession\");"},{"lineNumber":127,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e courseJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" cq.select(root)"},{"lineNumber":130,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":131,"author":{"gitId":"-"},"content":" cb.equal(courseJoin.get(\"id\"), courseId),"},{"lineNumber":132,"author":{"gitId":"-"},"content":" cb.equal(fsJoin.get(\"name\"), feedbackSessionName),"},{"lineNumber":133,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"giverType\"), giverType)));"},{"lineNumber":134,"author":{"gitId":"-"},"content":" return !HibernateUtil.createQuery(cq).getResultList().isEmpty();"},{"lineNumber":135,"author":{"gitId":"-"},"content":" }"},{"lineNumber":136,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":19,"-":117}},{"path":"src/main/java/teammates/storage/sqlapi/FeedbackResponseCommentsDb.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static teammates.common.util.Const.ERROR_CREATE_ENTITY_ALREADY_EXISTS;"},{"lineNumber":4,"author":{"gitId":"mingyuanc"},"content":"import static teammates.common.util.Const.ERROR_UPDATE_NON_EXISTENT;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaBuilder;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaQuery;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Join;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Root;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":15,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"-"},"content":" * Handles CRUD operations for feedbackResponseComments."},{"lineNumber":27,"author":{"gitId":"-"},"content":" *"},{"lineNumber":28,"author":{"gitId":"-"},"content":" * @see FeedbackResponseComment"},{"lineNumber":29,"author":{"gitId":"-"},"content":" */"},{"lineNumber":30,"author":{"gitId":"-"},"content":"public final class FeedbackResponseCommentsDb extends EntitiesDb {"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" private static final FeedbackResponseCommentsDb instance \u003d new FeedbackResponseCommentsDb();"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" private FeedbackResponseCommentsDb() {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":36,"author":{"gitId":"-"},"content":" }"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" public static FeedbackResponseCommentsDb inst() {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":43,"author":{"gitId":"-"},"content":" * Gets a feedbackResponseComment or null if it does not exist."},{"lineNumber":44,"author":{"gitId":"-"},"content":" */"},{"lineNumber":45,"author":{"gitId":"-"},"content":" public FeedbackResponseComment getFeedbackResponseComment(Long frId) {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" assert frId !\u003d null;"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" return HibernateUtil.get(FeedbackResponseComment.class, frId);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":52,"author":{"gitId":"-"},"content":" * Creates a feedbackResponseComment."},{"lineNumber":53,"author":{"gitId":"-"},"content":" */"},{"lineNumber":54,"author":{"gitId":"-"},"content":" public FeedbackResponseComment createFeedbackResponseComment(FeedbackResponseComment feedbackResponseComment)"},{"lineNumber":55,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" assert feedbackResponseComment !\u003d null;"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" if (!feedbackResponseComment.isValid()) {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(feedbackResponseComment.getInvalidityInfo());"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" if (feedbackResponseComment.getId() !\u003d null"},{"lineNumber":63,"author":{"gitId":"-"},"content":" \u0026\u0026 getFeedbackResponseComment(feedbackResponseComment.getId()) !\u003d null) {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" throw new EntityAlreadyExistsException("},{"lineNumber":65,"author":{"gitId":"-"},"content":" String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, feedbackResponseComment.toString()));"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" persist(feedbackResponseComment);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" return feedbackResponseComment;"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":73,"author":{"gitId":"-"},"content":" * Deletes a feedbackResponseComment."},{"lineNumber":74,"author":{"gitId":"-"},"content":" */"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public void deleteFeedbackResponseComment(Long frcId) {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" assert frcId !\u003d null;"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" FeedbackResponseComment frc \u003d getFeedbackResponseComment(frcId);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" if (frc !\u003d null) {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" delete(frc);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":" }"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" * Gets all feedback response comments for a response."},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentsForResponse(UUID feedbackResponseId) {"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" assert feedbackResponseId !\u003d null;"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" CriteriaQuery\u003cFeedbackResponseComment\u003e cq \u003d cb.createQuery(FeedbackResponseComment.class);"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" Root\u003cFeedbackResponseComment\u003e root \u003d cq.from(FeedbackResponseComment.class);"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":" Join\u003cFeedbackResponseComment, FeedbackResponse\u003e frJoin \u003d root.join(\"feedbackResponse\");"},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":" cq.select(root)"},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" .where(cb.and("},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" cb.equal(frJoin.get(\"id\"), feedbackResponseId)));"},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":102,"author":{"gitId":"-"},"content":" * Gets the comment associated with the feedback response."},{"lineNumber":103,"author":{"gitId":"-"},"content":" */"},{"lineNumber":104,"author":{"gitId":"-"},"content":" public FeedbackResponseComment getFeedbackResponseCommentForResponseFromParticipant("},{"lineNumber":105,"author":{"gitId":"-"},"content":" UUID feedbackResponseId) {"},{"lineNumber":106,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":107,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackResponseComment\u003e cq \u003d cb.createQuery(FeedbackResponseComment.class);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponseComment\u003e root \u003d cq.from(FeedbackResponseComment.class);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponseComment, FeedbackResponse\u003e frJoin \u003d root.join(\"feedbackResponse\");"},{"lineNumber":110,"author":{"gitId":"-"},"content":" cq.select(root)"},{"lineNumber":111,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":112,"author":{"gitId":"-"},"content":" cb.equal(frJoin.get(\"id\"), feedbackResponseId)));"},{"lineNumber":113,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cq).getResultStream().findFirst().orElse(null);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":117,"author":{"gitId":"-"},"content":" * Updates the giver email for all of the giver\u0027s comments in a course."},{"lineNumber":118,"author":{"gitId":"-"},"content":" */"},{"lineNumber":119,"author":{"gitId":"-"},"content":" public void updateGiverEmailOfFeedbackResponseComments(String courseId, String oldEmail, String updatedEmail) {"},{"lineNumber":120,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":121,"author":{"gitId":"-"},"content":" assert oldEmail !\u003d null;"},{"lineNumber":122,"author":{"gitId":"-"},"content":" assert updatedEmail !\u003d null;"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" if (oldEmail.equals(updatedEmail)) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":126,"author":{"gitId":"-"},"content":" }"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponseComment\u003e responseComments \u003d"},{"lineNumber":129,"author":{"gitId":"-"},"content":" getFeedbackResponseCommentEntitiesForGiverInCourse(courseId, oldEmail);"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" for (FeedbackResponseComment responseComment : responseComments) {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" responseComment.setGiver(updatedEmail);"},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" merge(responseComment);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" }"},{"lineNumber":135,"author":{"gitId":"-"},"content":" }"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":" * Updates the last editor to a new one for all comments in a course."},{"lineNumber":139,"author":{"gitId":"-"},"content":" */"},{"lineNumber":140,"author":{"gitId":"-"},"content":" public void updateLastEditorEmailOfFeedbackResponseComments(String courseId, String oldEmail, String updatedEmail) {"},{"lineNumber":141,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":142,"author":{"gitId":"-"},"content":" assert oldEmail !\u003d null;"},{"lineNumber":143,"author":{"gitId":"-"},"content":" assert updatedEmail !\u003d null;"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" if (oldEmail.equals(updatedEmail)) {"},{"lineNumber":146,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponseComment\u003e responseComments \u003d"},{"lineNumber":150,"author":{"gitId":"-"},"content":" getFeedbackResponseCommentEntitiesForLastEditorInCourse(courseId, oldEmail);"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" for (FeedbackResponseComment responseComment : responseComments) {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" responseComment.setLastEditorEmail(updatedEmail);"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":" }"},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"-"},"content":" private List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentEntitiesForGiverInCourse("},{"lineNumber":158,"author":{"gitId":"-"},"content":" String courseId, String giver) {"},{"lineNumber":159,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":160,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackResponseComment\u003e cq \u003d cb.createQuery(FeedbackResponseComment.class);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponseComment\u003e root \u003d cq.from(FeedbackResponseComment.class);"},{"lineNumber":162,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponseComment, FeedbackResponse\u003e frJoin \u003d root.join(\"feedbackResponse\");"},{"lineNumber":163,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d frJoin.join(\"feedbackQuestion\");"},{"lineNumber":164,"author":{"gitId":"-"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":165,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e cJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" cq.select(root)"},{"lineNumber":168,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":169,"author":{"gitId":"-"},"content":" cb.equal(cJoin.get(\"id\"), courseId),"},{"lineNumber":170,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"giver\"), giver)));"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" private List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentEntitiesForLastEditorInCourse("},{"lineNumber":176,"author":{"gitId":"-"},"content":" String courseId, String lastEditorEmail) {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":178,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackResponseComment\u003e cq \u003d cb.createQuery(FeedbackResponseComment.class);"},{"lineNumber":179,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponseComment\u003e root \u003d cq.from(FeedbackResponseComment.class);"},{"lineNumber":180,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponseComment, FeedbackResponse\u003e frJoin \u003d root.join(\"feedbackResponse\");"},{"lineNumber":181,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d frJoin.join(\"feedbackQuestion\");"},{"lineNumber":182,"author":{"gitId":"-"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":183,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e cJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":184,"author":{"gitId":"-"},"content":""},{"lineNumber":185,"author":{"gitId":"-"},"content":" cq.select(root)"},{"lineNumber":186,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":187,"author":{"gitId":"-"},"content":" cb.equal(cJoin.get(\"id\"), courseId),"},{"lineNumber":188,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"lastEditorEmail\"), lastEditorEmail)));"},{"lineNumber":189,"author":{"gitId":"-"},"content":""},{"lineNumber":190,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":191,"author":{"gitId":"-"},"content":" }"},{"lineNumber":192,"author":{"gitId":"-"},"content":""},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" * Updates the feedback response comment."},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":196,"author":{"gitId":"mingyuanc"},"content":" public FeedbackResponseComment updateFeedbackResponseComment(FeedbackResponseComment feedbackResponseComment)"},{"lineNumber":197,"author":{"gitId":"mingyuanc"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" assert feedbackResponseComment !\u003d null;"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":200,"author":{"gitId":"mingyuanc"},"content":" if (!feedbackResponseComment.isValid()) {"},{"lineNumber":201,"author":{"gitId":"mingyuanc"},"content":" throw new InvalidParametersException(feedbackResponseComment.getInvalidityInfo());"},{"lineNumber":202,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":203,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":204,"author":{"gitId":"mingyuanc"},"content":" if (getFeedbackResponseComment(feedbackResponseComment.getId()) \u003d\u003d null) {"},{"lineNumber":205,"author":{"gitId":"mingyuanc"},"content":" throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT);"},{"lineNumber":206,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":207,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" return merge(feedbackResponseComment);"},{"lineNumber":209,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":210,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":211,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":212,"author":{"gitId":"xenosf"},"content":" * Gets all comments in a feedback session of a course."},{"lineNumber":213,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentsForSession("},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" String courseId, String feedbackSessionName) {"},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" assert courseId !\u003d null;"},{"lineNumber":217,"author":{"gitId":"xenosf"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":218,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":219,"author":{"gitId":"xenosf"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":220,"author":{"gitId":"xenosf"},"content":" CriteriaQuery\u003cFeedbackResponseComment\u003e cq \u003d cb.createQuery(FeedbackResponseComment.class);"},{"lineNumber":221,"author":{"gitId":"xenosf"},"content":" Root\u003cFeedbackResponseComment\u003e root \u003d cq.from(FeedbackResponseComment.class);"},{"lineNumber":222,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponseComment, FeedbackResponse\u003e frJoin \u003d root.join(\"feedbackResponse\");"},{"lineNumber":223,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d frJoin.join(\"feedbackQuestion\");"},{"lineNumber":224,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":225,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackSession, Course\u003e cJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":226,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":227,"author":{"gitId":"xenosf"},"content":" cq.select(root)"},{"lineNumber":228,"author":{"gitId":"xenosf"},"content":" .where(cb.and("},{"lineNumber":229,"author":{"gitId":"xenosf"},"content":" cb.equal(cJoin.get(\"id\"), courseId),"},{"lineNumber":230,"author":{"gitId":"xenosf"},"content":" cb.equal(fsJoin.get(\"name\"), feedbackSessionName)"},{"lineNumber":231,"author":{"gitId":"xenosf"},"content":" ));"},{"lineNumber":232,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":233,"author":{"gitId":"xenosf"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":234,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":235,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":236,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":237,"author":{"gitId":"xenosf"},"content":" * Gets all comments of a feedback question of a course."},{"lineNumber":238,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":239,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentsForQuestion(UUID questionId) {"},{"lineNumber":240,"author":{"gitId":"xenosf"},"content":" assert questionId !\u003d null;"},{"lineNumber":241,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":242,"author":{"gitId":"xenosf"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":243,"author":{"gitId":"xenosf"},"content":" CriteriaQuery\u003cFeedbackResponseComment\u003e cq \u003d cb.createQuery(FeedbackResponseComment.class);"},{"lineNumber":244,"author":{"gitId":"xenosf"},"content":" Root\u003cFeedbackResponseComment\u003e root \u003d cq.from(FeedbackResponseComment.class);"},{"lineNumber":245,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponseComment, FeedbackResponse\u003e frJoin \u003d root.join(\"feedbackResponse\");"},{"lineNumber":246,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d frJoin.join(\"feedbackQuestion\");"},{"lineNumber":247,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":248,"author":{"gitId":"xenosf"},"content":" cq.select(root)"},{"lineNumber":249,"author":{"gitId":"xenosf"},"content":" .where(cb.and("},{"lineNumber":250,"author":{"gitId":"xenosf"},"content":" cb.equal(fqJoin.get(\"id\"), questionId)));"},{"lineNumber":251,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":252,"author":{"gitId":"xenosf"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":253,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":254,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":255,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":256,"author":{"gitId":"xenosf"},"content":" * Gets all comments in the given session where the giver or recipient is in the given section."},{"lineNumber":257,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":258,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentsForSessionInSection("},{"lineNumber":259,"author":{"gitId":"xenosf"},"content":" String courseId, String feedbackSessionName, String sectionName) {"},{"lineNumber":260,"author":{"gitId":"xenosf"},"content":" assert courseId !\u003d null;"},{"lineNumber":261,"author":{"gitId":"xenosf"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":262,"author":{"gitId":"xenosf"},"content":" assert sectionName !\u003d null;"},{"lineNumber":263,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":264,"author":{"gitId":"xenosf"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":265,"author":{"gitId":"xenosf"},"content":" CriteriaQuery\u003cFeedbackResponseComment\u003e cq \u003d cb.createQuery(FeedbackResponseComment.class);"},{"lineNumber":266,"author":{"gitId":"xenosf"},"content":" Root\u003cFeedbackResponseComment\u003e root \u003d cq.from(FeedbackResponseComment.class);"},{"lineNumber":267,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponseComment, FeedbackResponse\u003e frJoin \u003d root.join(\"feedbackResponse\");"},{"lineNumber":268,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d frJoin.join(\"feedbackQuestion\");"},{"lineNumber":269,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":270,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackSession, Course\u003e cJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":271,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":272,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponseComment, Section\u003e giverJoin \u003d root.join(\"giverSection\");"},{"lineNumber":273,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponseComment, Section\u003e recipientJoin \u003d root.join(\"recipientSection\");"},{"lineNumber":274,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":275,"author":{"gitId":"xenosf"},"content":" cq.select(root)"},{"lineNumber":276,"author":{"gitId":"xenosf"},"content":" .where(cb.and("},{"lineNumber":277,"author":{"gitId":"xenosf"},"content":" cb.equal(cJoin.get(\"id\"), courseId),"},{"lineNumber":278,"author":{"gitId":"xenosf"},"content":" cb.equal(fsJoin.get(\"name\"), feedbackSessionName),"},{"lineNumber":279,"author":{"gitId":"xenosf"},"content":" cb.or("},{"lineNumber":280,"author":{"gitId":"xenosf"},"content":" cb.equal(giverJoin.get(\"name\"), sectionName),"},{"lineNumber":281,"author":{"gitId":"xenosf"},"content":" cb.equal(recipientJoin.get(\"name\"), sectionName))"},{"lineNumber":282,"author":{"gitId":"xenosf"},"content":" ));"},{"lineNumber":283,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":284,"author":{"gitId":"xenosf"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":285,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":286,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":287,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":288,"author":{"gitId":"xenosf"},"content":" * Gets all comments for a question where the giver or recipient is in the given section."},{"lineNumber":289,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":290,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseCommentsForQuestionInSection("},{"lineNumber":291,"author":{"gitId":"xenosf"},"content":" UUID questionId, String sectionName) {"},{"lineNumber":292,"author":{"gitId":"xenosf"},"content":" assert questionId !\u003d null;"},{"lineNumber":293,"author":{"gitId":"xenosf"},"content":" assert sectionName !\u003d null;"},{"lineNumber":294,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":295,"author":{"gitId":"xenosf"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":296,"author":{"gitId":"xenosf"},"content":" CriteriaQuery\u003cFeedbackResponseComment\u003e cq \u003d cb.createQuery(FeedbackResponseComment.class);"},{"lineNumber":297,"author":{"gitId":"xenosf"},"content":" Root\u003cFeedbackResponseComment\u003e root \u003d cq.from(FeedbackResponseComment.class);"},{"lineNumber":298,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponseComment, FeedbackResponse\u003e frJoin \u003d root.join(\"feedbackResponse\");"},{"lineNumber":299,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d frJoin.join(\"feedbackQuestion\");"},{"lineNumber":300,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":301,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponseComment, Section\u003e giverJoin \u003d root.join(\"giverSection\");"},{"lineNumber":302,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponseComment, Section\u003e recipientJoin \u003d root.join(\"recipientSection\");"},{"lineNumber":303,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":304,"author":{"gitId":"xenosf"},"content":" cq.select(root)"},{"lineNumber":305,"author":{"gitId":"xenosf"},"content":" .where(cb.and("},{"lineNumber":306,"author":{"gitId":"xenosf"},"content":" cb.equal(fqJoin.get(\"id\"), questionId),"},{"lineNumber":307,"author":{"gitId":"xenosf"},"content":" cb.or("},{"lineNumber":308,"author":{"gitId":"xenosf"},"content":" cb.equal(giverJoin.get(\"name\"), sectionName),"},{"lineNumber":309,"author":{"gitId":"xenosf"},"content":" cb.equal(recipientJoin.get(\"name\"), sectionName))"},{"lineNumber":310,"author":{"gitId":"xenosf"},"content":" ));"},{"lineNumber":311,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":312,"author":{"gitId":"xenosf"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":313,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":314,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":315,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":26,"xenosf":105,"mingyuanc":12,"-":172}},{"path":"src/main/java/teammates/storage/sqlapi/FeedbackResponsesDb.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static teammates.common.util.Const.ERROR_CREATE_ENTITY_ALREADY_EXISTS;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import static teammates.common.util.Const.ERROR_UPDATE_NON_EXISTENT;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaBuilder;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaDelete;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaQuery;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Join;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Predicate;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Root;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Subquery;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.FeedbackResultFetchType;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":29,"author":{"gitId":"-"},"content":" * Handles CRUD operations for feedbackResponses."},{"lineNumber":30,"author":{"gitId":"-"},"content":" *"},{"lineNumber":31,"author":{"gitId":"-"},"content":" * @see FeedbackResponse"},{"lineNumber":32,"author":{"gitId":"-"},"content":" */"},{"lineNumber":33,"author":{"gitId":"-"},"content":"public final class FeedbackResponsesDb extends EntitiesDb {"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" private static final FeedbackResponsesDb instance \u003d new FeedbackResponsesDb();"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" private FeedbackResponsesDb() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" public static FeedbackResponsesDb inst() {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" }"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":46,"author":{"gitId":"-"},"content":" * Gets a feedbackResponse or null if it does not exist."},{"lineNumber":47,"author":{"gitId":"-"},"content":" */"},{"lineNumber":48,"author":{"gitId":"-"},"content":" public FeedbackResponse getFeedbackResponse(UUID frId) {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" assert frId !\u003d null;"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" return HibernateUtil.get(FeedbackResponse.class, frId);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" }"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":55,"author":{"gitId":"-"},"content":" * Gets all responses given by a user in a course."},{"lineNumber":56,"author":{"gitId":"-"},"content":" */"},{"lineNumber":57,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesFromGiverForCourse("},{"lineNumber":58,"author":{"gitId":"-"},"content":" String courseId, String giver) {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":60,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cr \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponse\u003e frRoot \u003d cr.from(FeedbackResponse.class);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d frRoot.join(\"feedbackQuestion\");"},{"lineNumber":63,"author":{"gitId":"-"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":64,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e cJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" cr.select(frRoot)"},{"lineNumber":67,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":68,"author":{"gitId":"-"},"content":" cb.equal(cJoin.get(\"id\"), courseId),"},{"lineNumber":69,"author":{"gitId":"-"},"content":" cb.equal(frRoot.get(\"giver\"), giver)));"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":75,"author":{"gitId":"-"},"content":" * Gets all responses given to a user in a course."},{"lineNumber":76,"author":{"gitId":"-"},"content":" */"},{"lineNumber":77,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForRecipientForCourse(String courseId, String recipient) {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":79,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cr \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponse\u003e frRoot \u003d cr.from(FeedbackResponse.class);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d frRoot.join(\"feedbackQuestion\");"},{"lineNumber":82,"author":{"gitId":"-"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":83,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e cJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" cr.select(frRoot)"},{"lineNumber":86,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":87,"author":{"gitId":"-"},"content":" cb.equal(cJoin.get(\"id\"), courseId),"},{"lineNumber":88,"author":{"gitId":"-"},"content":" cb.equal(frRoot.get(\"recipient\"), recipient)));"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":91,"author":{"gitId":"-"},"content":" }"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":94,"author":{"gitId":"-"},"content":" * Creates a feedbackResponse."},{"lineNumber":95,"author":{"gitId":"-"},"content":" */"},{"lineNumber":96,"author":{"gitId":"-"},"content":" public FeedbackResponse createFeedbackResponse(FeedbackResponse feedbackResponse)"},{"lineNumber":97,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" assert feedbackResponse !\u003d null;"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" if (!feedbackResponse.isValid()) {"},{"lineNumber":101,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(feedbackResponse.getInvalidityInfo());"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" if (getFeedbackResponse(feedbackResponse.getId()) !\u003d null) {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" throw new EntityAlreadyExistsException("},{"lineNumber":106,"author":{"gitId":"-"},"content":" String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, feedbackResponse.toString()));"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" persist(feedbackResponse);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" return feedbackResponse;"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":114,"author":{"gitId":"-"},"content":" * Deletes a feedbackResponse."},{"lineNumber":115,"author":{"gitId":"-"},"content":" */"},{"lineNumber":116,"author":{"gitId":"-"},"content":" public void deleteFeedbackResponse(FeedbackResponse feedbackResponse) {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" if (feedbackResponse !\u003d null) {"},{"lineNumber":118,"author":{"gitId":"-"},"content":" delete(feedbackResponse);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" }"},{"lineNumber":120,"author":{"gitId":"-"},"content":" }"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":123,"author":{"gitId":"-"},"content":" * Gets the feedback responses for a feedback question."},{"lineNumber":124,"author":{"gitId":"-"},"content":" * @param feedbackQuestionId the Id of the feedback question."},{"lineNumber":125,"author":{"gitId":"-"},"content":" * @param giverEmail the email of the response giver."},{"lineNumber":126,"author":{"gitId":"-"},"content":" */"},{"lineNumber":127,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesFromGiverForQuestion("},{"lineNumber":128,"author":{"gitId":"-"},"content":" UUID feedbackQuestionId, String giverEmail) {"},{"lineNumber":129,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":130,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cq \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponse\u003e root \u003d cq.from(FeedbackResponse.class);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e frJoin \u003d root.join(\"feedbackQuestion\");"},{"lineNumber":133,"author":{"gitId":"-"},"content":" cq.select(root)"},{"lineNumber":134,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":135,"author":{"gitId":"-"},"content":" cb.equal(frJoin.get(\"id\"), feedbackQuestionId),"},{"lineNumber":136,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"giver\"), giverEmail)));"},{"lineNumber":137,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":141,"author":{"gitId":"-"},"content":" * Deletes all feedback responses of a question cascade its associated comments."},{"lineNumber":142,"author":{"gitId":"-"},"content":" */"},{"lineNumber":143,"author":{"gitId":"-"},"content":" public void deleteFeedbackResponsesForQuestionCascade(UUID feedbackQuestionId) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":145,"author":{"gitId":"-"},"content":" CriteriaDelete\u003cFeedbackResponse\u003e cd \u003d cb.createCriteriaDelete(FeedbackResponse.class);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponse\u003e frRoot \u003d cd.from(FeedbackResponse.class);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" Subquery\u003cUUID\u003e subquery \u003d cd.subquery(UUID.class);"},{"lineNumber":148,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponse\u003e subqueryRoot \u003d subquery.from(FeedbackResponse.class);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e sqJoin \u003d subqueryRoot.join(\"feedbackQuestion\");"},{"lineNumber":150,"author":{"gitId":"-"},"content":" subquery.select(subqueryRoot.get(\"id\"));"},{"lineNumber":151,"author":{"gitId":"-"},"content":" subquery.where(cb.equal(sqJoin.get(\"id\"), feedbackQuestionId));"},{"lineNumber":152,"author":{"gitId":"-"},"content":" cd.where(cb.in(frRoot.get(\"id\")).value(subquery));"},{"lineNumber":153,"author":{"gitId":"-"},"content":" HibernateUtil.createMutationQuery(cd).executeUpdate();"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":157,"author":{"gitId":"-"},"content":" * Checks whether there are responses for a question."},{"lineNumber":158,"author":{"gitId":"-"},"content":" */"},{"lineNumber":159,"author":{"gitId":"-"},"content":" public boolean areThereResponsesForQuestion(UUID questionId) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":161,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cq \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":162,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponse\u003e root \u003d cq.from(FeedbackResponse.class);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d root.join(\"feedbackQuestion\");"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" cq.select(root)"},{"lineNumber":166,"author":{"gitId":"-"},"content":" .where(cb.equal(fqJoin.get(\"id\"), questionId));"},{"lineNumber":167,"author":{"gitId":"-"},"content":" return !HibernateUtil.createQuery(cq).getResultList().isEmpty();"},{"lineNumber":168,"author":{"gitId":"-"},"content":" }"},{"lineNumber":169,"author":{"gitId":"-"},"content":""},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":171,"author":{"gitId":"xenosf"},"content":" * Get responses for a question."},{"lineNumber":172,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":" public List\u003cFeedbackResponse\u003e getResponsesForQuestion(UUID questionId) {"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cq \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":" Root\u003cFeedbackResponse\u003e root \u003d cq.from(FeedbackResponse.class);"},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d root.join(\"feedbackQuestion\");"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" cq.select(root)"},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" .where(cb.equal(fqJoin.get(\"id\"), questionId));"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":184,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":185,"author":{"gitId":"-"},"content":" * Checks whether a user has responses in a session."},{"lineNumber":186,"author":{"gitId":"-"},"content":" */"},{"lineNumber":187,"author":{"gitId":"-"},"content":" public boolean hasResponsesFromGiverInSession("},{"lineNumber":188,"author":{"gitId":"-"},"content":" String giver, String feedbackSessionName, String courseId) {"},{"lineNumber":189,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":190,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cq \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":191,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponse\u003e root \u003d cq.from(FeedbackResponse.class);"},{"lineNumber":192,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d root.join(\"feedbackQuestion\");"},{"lineNumber":193,"author":{"gitId":"-"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":194,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e courseJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":195,"author":{"gitId":"-"},"content":""},{"lineNumber":196,"author":{"gitId":"-"},"content":" cq.select(root)"},{"lineNumber":197,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":198,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"giver\"), giver),"},{"lineNumber":199,"author":{"gitId":"-"},"content":" cb.equal(fsJoin.get(\"name\"), feedbackSessionName),"},{"lineNumber":200,"author":{"gitId":"-"},"content":" cb.equal(courseJoin.get(\"id\"), courseId)));"},{"lineNumber":201,"author":{"gitId":"-"},"content":""},{"lineNumber":202,"author":{"gitId":"-"},"content":" return !HibernateUtil.createQuery(cq).getResultList().isEmpty();"},{"lineNumber":203,"author":{"gitId":"-"},"content":" }"},{"lineNumber":204,"author":{"gitId":"-"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":206,"author":{"gitId":"-"},"content":" * Checks whether there are responses for a course."},{"lineNumber":207,"author":{"gitId":"-"},"content":" */"},{"lineNumber":208,"author":{"gitId":"-"},"content":" public boolean hasResponsesForCourse(String courseId) {"},{"lineNumber":209,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":210,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cq \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":211,"author":{"gitId":"-"},"content":" Root\u003cFeedbackResponse\u003e root \u003d cq.from(FeedbackResponse.class);"},{"lineNumber":212,"author":{"gitId":"-"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d root.join(\"feedbackQuestion\");"},{"lineNumber":213,"author":{"gitId":"-"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":214,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e courseJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":215,"author":{"gitId":"-"},"content":""},{"lineNumber":216,"author":{"gitId":"-"},"content":" cq.select(root)"},{"lineNumber":217,"author":{"gitId":"-"},"content":" .where(cb.equal(courseJoin.get(\"id\"), courseId));"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":" return !HibernateUtil.createQuery(cq).getResultList().isEmpty();"},{"lineNumber":220,"author":{"gitId":"-"},"content":" }"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":223,"author":{"gitId":"domoberzin"},"content":" * Updates a feedbackResponse."},{"lineNumber":224,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":225,"author":{"gitId":"domoberzin"},"content":" * @throws EntityDoesNotExistException if the feedbackResponse does not exist"},{"lineNumber":226,"author":{"gitId":"domoberzin"},"content":" * @throws InvalidParametersException if the feedbackResponse is not valid"},{"lineNumber":227,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":228,"author":{"gitId":"domoberzin"},"content":" public FeedbackResponse updateFeedbackResponse(FeedbackResponse feedbackResponse)"},{"lineNumber":229,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":230,"author":{"gitId":"domoberzin"},"content":" assert feedbackResponse !\u003d null;"},{"lineNumber":231,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":232,"author":{"gitId":"domoberzin"},"content":" if (!feedbackResponse.isValid()) {"},{"lineNumber":233,"author":{"gitId":"domoberzin"},"content":" throw new InvalidParametersException(feedbackResponse.getInvalidityInfo());"},{"lineNumber":234,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":235,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":236,"author":{"gitId":"domoberzin"},"content":" if (getFeedbackResponse(feedbackResponse.getId()) \u003d\u003d null) {"},{"lineNumber":237,"author":{"gitId":"domoberzin"},"content":" throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT);"},{"lineNumber":238,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":239,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":240,"author":{"gitId":"domoberzin"},"content":" return merge(feedbackResponse);"},{"lineNumber":241,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":242,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":243,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":244,"author":{"gitId":"xenosf"},"content":" * Gets all responses received by a user for a question."},{"lineNumber":245,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":246,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForRecipientForQuestion("},{"lineNumber":247,"author":{"gitId":"xenosf"},"content":" UUID questionId, String recipient) {"},{"lineNumber":248,"author":{"gitId":"xenosf"},"content":" assert questionId !\u003d null;"},{"lineNumber":249,"author":{"gitId":"xenosf"},"content":" assert recipient !\u003d null;"},{"lineNumber":250,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":251,"author":{"gitId":"xenosf"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":252,"author":{"gitId":"xenosf"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cq \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":253,"author":{"gitId":"xenosf"},"content":" Root\u003cFeedbackResponse\u003e root \u003d cq.from(FeedbackResponse.class);"},{"lineNumber":254,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d root.join(\"feedbackQuestion\");"},{"lineNumber":255,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":256,"author":{"gitId":"xenosf"},"content":" cq.select(root)"},{"lineNumber":257,"author":{"gitId":"xenosf"},"content":" .where(cb.and("},{"lineNumber":258,"author":{"gitId":"xenosf"},"content":" cb.equal(fqJoin.get(\"id\"), questionId),"},{"lineNumber":259,"author":{"gitId":"xenosf"},"content":" cb.equal(root.get(\"recipient\"), recipient)"},{"lineNumber":260,"author":{"gitId":"xenosf"},"content":" ));"},{"lineNumber":261,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":262,"author":{"gitId":"xenosf"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":263,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":264,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":265,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":266,"author":{"gitId":"xenosf"},"content":" * Gets all responses given to/from a section in a feedback session in a course."},{"lineNumber":267,"author":{"gitId":"xenosf"},"content":" * Optionally, retrieves by either giver, receiver sections, or both."},{"lineNumber":268,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":269,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForSessionInSection("},{"lineNumber":270,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession, String courseId, String sectionName, FeedbackResultFetchType fetchType) {"},{"lineNumber":271,"author":{"gitId":"xenosf"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":272,"author":{"gitId":"xenosf"},"content":" assert courseId !\u003d null;"},{"lineNumber":273,"author":{"gitId":"xenosf"},"content":" assert sectionName !\u003d null;"},{"lineNumber":274,"author":{"gitId":"xenosf"},"content":" assert fetchType !\u003d null;"},{"lineNumber":275,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":276,"author":{"gitId":"xenosf"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":277,"author":{"gitId":"xenosf"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cq \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":278,"author":{"gitId":"xenosf"},"content":" Root\u003cFeedbackResponse\u003e root \u003d cq.from(FeedbackResponse.class);"},{"lineNumber":279,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d root.join(\"feedbackQuestion\");"},{"lineNumber":280,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":281,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackSession, Course\u003e cJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":282,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":283,"author":{"gitId":"xenosf"},"content":" // unless specified by fetchType, do not filter by giver/recipient section"},{"lineNumber":284,"author":{"gitId":"xenosf"},"content":" Predicate giverSectionFilter \u003d cb.isTrue(cb.literal(true));"},{"lineNumber":285,"author":{"gitId":"xenosf"},"content":" Predicate recipientSectionFilter \u003d cb.isTrue(cb.literal(true));"},{"lineNumber":286,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, Section\u003e giverJoin \u003d root.join(\"giverSection\");"},{"lineNumber":287,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, Section\u003e recipientJoin \u003d root.join(\"recipientSection\");"},{"lineNumber":288,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":289,"author":{"gitId":"xenosf"},"content":" if (fetchType.shouldFetchByGiver()) {"},{"lineNumber":290,"author":{"gitId":"xenosf"},"content":" giverSectionFilter \u003d cb.equal(giverJoin.get(\"name\"), sectionName);"},{"lineNumber":291,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":292,"author":{"gitId":"xenosf"},"content":" if (fetchType.shouldFetchByReceiver()) {"},{"lineNumber":293,"author":{"gitId":"xenosf"},"content":" recipientSectionFilter \u003d cb.equal(recipientJoin.get(\"name\"), sectionName);"},{"lineNumber":294,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":295,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":296,"author":{"gitId":"xenosf"},"content":" cq.select(root)"},{"lineNumber":297,"author":{"gitId":"xenosf"},"content":" .where(cb.and("},{"lineNumber":298,"author":{"gitId":"xenosf"},"content":" cb.equal(fsJoin.get(\"id\"), feedbackSession.getId()),"},{"lineNumber":299,"author":{"gitId":"xenosf"},"content":" cb.equal(cJoin.get(\"id\"), courseId),"},{"lineNumber":300,"author":{"gitId":"xenosf"},"content":" giverSectionFilter,"},{"lineNumber":301,"author":{"gitId":"xenosf"},"content":" recipientSectionFilter"},{"lineNumber":302,"author":{"gitId":"xenosf"},"content":" ));"},{"lineNumber":303,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":304,"author":{"gitId":"xenosf"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":305,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":306,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":307,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":308,"author":{"gitId":"xenosf"},"content":" * Gets all feedback responses of a question in a specific section."},{"lineNumber":309,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":310,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForQuestionInSection("},{"lineNumber":311,"author":{"gitId":"xenosf"},"content":" UUID questionId, String sectionName, FeedbackResultFetchType fetchType) {"},{"lineNumber":312,"author":{"gitId":"xenosf"},"content":" assert questionId !\u003d null;"},{"lineNumber":313,"author":{"gitId":"xenosf"},"content":" assert sectionName !\u003d null;"},{"lineNumber":314,"author":{"gitId":"xenosf"},"content":" assert fetchType !\u003d null;"},{"lineNumber":315,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":316,"author":{"gitId":"xenosf"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":317,"author":{"gitId":"xenosf"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cq \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":318,"author":{"gitId":"xenosf"},"content":" Root\u003cFeedbackResponse\u003e root \u003d cq.from(FeedbackResponse.class);"},{"lineNumber":319,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d root.join(\"feedbackQuestion\");"},{"lineNumber":320,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":321,"author":{"gitId":"xenosf"},"content":" // unless specified by fetchType, do not filter by giver/recipient section"},{"lineNumber":322,"author":{"gitId":"xenosf"},"content":" Predicate giverSectionFilter \u003d cb.isTrue(cb.literal(true));"},{"lineNumber":323,"author":{"gitId":"xenosf"},"content":" Predicate recipientSectionFilter \u003d cb.isTrue(cb.literal(true));"},{"lineNumber":324,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, Section\u003e giverJoin \u003d root.join(\"giverSection\");"},{"lineNumber":325,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, Section\u003e recipientJoin \u003d root.join(\"recipientSection\");"},{"lineNumber":326,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":327,"author":{"gitId":"xenosf"},"content":" if (fetchType.shouldFetchByGiver()) {"},{"lineNumber":328,"author":{"gitId":"xenosf"},"content":" giverSectionFilter \u003d cb.equal(giverJoin.get(\"name\"), sectionName);"},{"lineNumber":329,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":330,"author":{"gitId":"xenosf"},"content":" if (fetchType.shouldFetchByReceiver()) {"},{"lineNumber":331,"author":{"gitId":"xenosf"},"content":" recipientSectionFilter \u003d cb.equal(recipientJoin.get(\"name\"), sectionName);"},{"lineNumber":332,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":333,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":334,"author":{"gitId":"xenosf"},"content":" cq.select(root)"},{"lineNumber":335,"author":{"gitId":"xenosf"},"content":" .where(cb.and("},{"lineNumber":336,"author":{"gitId":"xenosf"},"content":" cb.equal(fqJoin.get(\"id\"), questionId),"},{"lineNumber":337,"author":{"gitId":"xenosf"},"content":" giverSectionFilter,"},{"lineNumber":338,"author":{"gitId":"xenosf"},"content":" recipientSectionFilter"},{"lineNumber":339,"author":{"gitId":"xenosf"},"content":" ));"},{"lineNumber":340,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":341,"author":{"gitId":"xenosf"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":342,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":343,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":344,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":345,"author":{"gitId":"xenosf"},"content":" * Gets all responses of a feedback session in a course."},{"lineNumber":346,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":347,"author":{"gitId":"xenosf"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponsesForSession("},{"lineNumber":348,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession, String courseId) {"},{"lineNumber":349,"author":{"gitId":"xenosf"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":350,"author":{"gitId":"xenosf"},"content":" assert courseId !\u003d null;"},{"lineNumber":351,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":352,"author":{"gitId":"xenosf"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":353,"author":{"gitId":"xenosf"},"content":" CriteriaQuery\u003cFeedbackResponse\u003e cq \u003d cb.createQuery(FeedbackResponse.class);"},{"lineNumber":354,"author":{"gitId":"xenosf"},"content":" Root\u003cFeedbackResponse\u003e root \u003d cq.from(FeedbackResponse.class);"},{"lineNumber":355,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackResponse, FeedbackQuestion\u003e fqJoin \u003d root.join(\"feedbackQuestion\");"},{"lineNumber":356,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackQuestion, FeedbackSession\u003e fsJoin \u003d fqJoin.join(\"feedbackSession\");"},{"lineNumber":357,"author":{"gitId":"xenosf"},"content":" Join\u003cFeedbackSession, Course\u003e cJoin \u003d fsJoin.join(\"course\");"},{"lineNumber":358,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":359,"author":{"gitId":"xenosf"},"content":" cq.select(root)"},{"lineNumber":360,"author":{"gitId":"xenosf"},"content":" .where(cb.and("},{"lineNumber":361,"author":{"gitId":"xenosf"},"content":" cb.equal(fsJoin.get(\"id\"), feedbackSession.getId()),"},{"lineNumber":362,"author":{"gitId":"xenosf"},"content":" cb.equal(cJoin.get(\"id\"), courseId)"},{"lineNumber":363,"author":{"gitId":"xenosf"},"content":" ));"},{"lineNumber":364,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":365,"author":{"gitId":"xenosf"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":366,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":367,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":368,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":37,"xenosf":127,"-":204}},{"path":"src/main/java/teammates/storage/sqlapi/FeedbackSessionLogsDb.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.criteria.CriteriaBuilder;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.criteria.CriteriaQuery;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.criteria.Join;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.criteria.Predicate;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.criteria.Root;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":" * Handles CRUD operations for feedback session logs."},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" * @see FeedbackSessionLog"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":"public final class FeedbackSessionLogsDb extends EntitiesDb {"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" private static final FeedbackSessionLogsDb instance \u003d new FeedbackSessionLogsDb();"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" private FeedbackSessionLogsDb() {"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" // prevent initialization"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" public static FeedbackSessionLogsDb inst() {"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" return instance;"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" * Gets the feedback session logs as filtered by the given parameters ordered by"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" * ascending timestamp. Logs with the same timestamp will be ordered by the"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" * student\u0027s email."},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" * @param studentId Can be null"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" * @param feedbackSessionId Can be null"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" public List\u003cFeedbackSessionLog\u003e getOrderedFeedbackSessionLogs(String courseId, UUID studentId,"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" UUID feedbackSessionId, Instant startTime, Instant endTime) {"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" assert courseId !\u003d null;"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" assert startTime !\u003d null;"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" assert endTime !\u003d null;"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" CriteriaQuery\u003cFeedbackSessionLog\u003e cr \u003d cb.createQuery(FeedbackSessionLog.class);"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" Root\u003cFeedbackSessionLog\u003e root \u003d cr.from(FeedbackSessionLog.class);"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" Join\u003cFeedbackSessionLog, FeedbackSession\u003e feedbackSessionJoin \u003d root.join(\"feedbackSession\");"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" Join\u003cFeedbackSessionLog, Student\u003e studentJoin \u003d root.join(\"student\");"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" List\u003cPredicate\u003e predicates \u003d new ArrayList\u003c\u003e();"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" if (studentId !\u003d null) {"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" predicates.add(cb.equal(studentJoin.get(\"id\"), studentId));"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" if (feedbackSessionId !\u003d null) {"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" predicates.add(cb.equal(feedbackSessionJoin.get(\"id\"), feedbackSessionId));"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" predicates.add(cb.equal(feedbackSessionJoin.get(\"course\").get(\"id\"), courseId));"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" predicates.add(cb.greaterThanOrEqualTo(root.get(\"timestamp\"), startTime));"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" predicates.add(cb.lessThan(root.get(\"timestamp\"), endTime));"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" cr.select(root).where(predicates.toArray(new Predicate[0])).orderBy(cb.asc(root.get(\"timestamp\")),"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" cb.asc(studentJoin.get(\"email\")));"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" * Creates feedback session logs."},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" public FeedbackSessionLog createFeedbackSessionLog(FeedbackSessionLog log) {"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" assert log !\u003d null;"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" persist(log);"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" return log;"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":81,"-":5}},{"path":"src/main/java/teammates/storage/sqlapi/FeedbackSessionsDb.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static teammates.common.util.Const.ERROR_CREATE_ENTITY_ALREADY_EXISTS;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import static teammates.common.util.Const.ERROR_UPDATE_NON_EXISTENT;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaBuilder;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaQuery;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Join;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Root;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * Handles CRUD operations for feedback sessions."},{"lineNumber":26,"author":{"gitId":"-"},"content":" *"},{"lineNumber":27,"author":{"gitId":"-"},"content":" * @see FeedbackSession"},{"lineNumber":28,"author":{"gitId":"-"},"content":" */"},{"lineNumber":29,"author":{"gitId":"-"},"content":"public final class FeedbackSessionsDb extends EntitiesDb {"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" private static final FeedbackSessionsDb instance \u003d new FeedbackSessionsDb();"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private FeedbackSessionsDb() {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" public static FeedbackSessionsDb inst() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":42,"author":{"gitId":"-"},"content":" * Gets a feedback session."},{"lineNumber":43,"author":{"gitId":"-"},"content":" *"},{"lineNumber":44,"author":{"gitId":"-"},"content":" * @return null if not found"},{"lineNumber":45,"author":{"gitId":"-"},"content":" */"},{"lineNumber":46,"author":{"gitId":"-"},"content":" public FeedbackSession getFeedbackSession(UUID fsId) {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" assert fsId !\u003d null;"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" return HibernateUtil.get(FeedbackSession.class, fsId);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" }"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":53,"author":{"gitId":"-"},"content":" * Gets a feedback session for {@code feedbackSessionName} and {@code courseId}."},{"lineNumber":54,"author":{"gitId":"-"},"content":" *"},{"lineNumber":55,"author":{"gitId":"-"},"content":" * @return null if not found"},{"lineNumber":56,"author":{"gitId":"-"},"content":" */"},{"lineNumber":57,"author":{"gitId":"-"},"content":" public FeedbackSession getFeedbackSession(String feedbackSessionName, String courseId) {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":59,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cq \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e fsRoot \u003d cq.from(FeedbackSession.class);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e fsJoin \u003d fsRoot.join(\"course\");"},{"lineNumber":62,"author":{"gitId":"-"},"content":" cq.select(fsRoot).where(cb.and("},{"lineNumber":63,"author":{"gitId":"-"},"content":" cb.equal(fsRoot.get(\"name\"), feedbackSessionName),"},{"lineNumber":64,"author":{"gitId":"-"},"content":" cb.equal(fsJoin.get(\"id\"), courseId)));"},{"lineNumber":65,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cq).getResultStream().findFirst().orElse(null);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" * Gets a feedback session reference."},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" *"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" * @return Returns a proxy for the feedback session."},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" public FeedbackSession getFeedbackSessionReference(UUID id) {"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" assert id !\u003d null;"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" return HibernateUtil.getReference(FeedbackSession.class, id);"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":80,"author":{"gitId":"-"},"content":" * Gets a soft-deleted feedback session."},{"lineNumber":81,"author":{"gitId":"-"},"content":" *"},{"lineNumber":82,"author":{"gitId":"-"},"content":" * @return null if not found or not soft-deleted."},{"lineNumber":83,"author":{"gitId":"-"},"content":" */"},{"lineNumber":84,"author":{"gitId":"-"},"content":" public FeedbackSession getSoftDeletedFeedbackSession(String feedbackSessionName, String courseId) {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession \u003d getFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" if (feedbackSession !\u003d null \u0026\u0026 feedbackSession.getDeletedAt() \u003d\u003d null) {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" log.info(feedbackSessionName + \"/\" + courseId + \" is not soft-deleted!\");"},{"lineNumber":92,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":93,"author":{"gitId":"-"},"content":" }"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" return feedbackSession;"},{"lineNumber":96,"author":{"gitId":"-"},"content":" }"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":99,"author":{"gitId":"-"},"content":" * Gets soft-deleted feedback sessions for course."},{"lineNumber":100,"author":{"gitId":"-"},"content":" */"},{"lineNumber":101,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getSoftDeletedFeedbackSessionsForCourse(String courseId) {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":103,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cq \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e fsRoot \u003d cq.from(FeedbackSession.class);"},{"lineNumber":105,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e fsJoin \u003d fsRoot.join(\"course\");"},{"lineNumber":106,"author":{"gitId":"-"},"content":" cq.select(fsRoot).where(cb.and("},{"lineNumber":107,"author":{"gitId":"-"},"content":" cb.isNotNull(fsRoot.get(\"deletedAt\")),"},{"lineNumber":108,"author":{"gitId":"-"},"content":" cb.equal(fsJoin.get(\"id\"), courseId)));"},{"lineNumber":109,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":113,"author":{"gitId":"-"},"content":" * Gets all and only the feedback sessions ongoing within a range of time."},{"lineNumber":114,"author":{"gitId":"-"},"content":" */"},{"lineNumber":115,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getOngoingSessions(Instant rangeStart, Instant rangeEnd) {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" assert rangeStart !\u003d null;"},{"lineNumber":117,"author":{"gitId":"-"},"content":" assert rangeEnd !\u003d null;"},{"lineNumber":118,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":119,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cr \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e root \u003d cr.from(FeedbackSession.class);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" cr.select(root)"},{"lineNumber":122,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":123,"author":{"gitId":"-"},"content":" cb.greaterThan(root.get(\"endTime\"), rangeStart),"},{"lineNumber":124,"author":{"gitId":"-"},"content":" cb.lessThan(root.get(\"startTime\"), rangeEnd)));"},{"lineNumber":125,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":126,"author":{"gitId":"-"},"content":" }"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":129,"author":{"gitId":"-"},"content":" * Restores a specific soft deleted feedback session."},{"lineNumber":130,"author":{"gitId":"-"},"content":" */"},{"lineNumber":131,"author":{"gitId":"-"},"content":" public void restoreDeletedFeedbackSession(String feedbackSessionName, String courseId)"},{"lineNumber":132,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":134,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" FeedbackSession sessionEntity \u003d getFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" if (sessionEntity \u003d\u003d null) {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" sessionEntity.setDeletedAt(null);"},{"lineNumber":143,"author":{"gitId":"dishenggg"},"content":" merge(sessionEntity);"},{"lineNumber":144,"author":{"gitId":"-"},"content":" }"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":147,"author":{"gitId":"-"},"content":" * Creates a feedback session."},{"lineNumber":148,"author":{"gitId":"-"},"content":" */"},{"lineNumber":149,"author":{"gitId":"-"},"content":" public FeedbackSession createFeedbackSession(FeedbackSession session)"},{"lineNumber":150,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" assert session !\u003d null;"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":" if (!session.isValid()) {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(session.getInvalidityInfo());"},{"lineNumber":155,"author":{"gitId":"-"},"content":" }"},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"-"},"content":" if (getFeedbackSession(session.getId()) !\u003d null) {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" throw new EntityAlreadyExistsException(String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, session.toString()));"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" persist(session);"},{"lineNumber":162,"author":{"gitId":"-"},"content":" return session;"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":166,"author":{"gitId":"-"},"content":" * Saves an updated {@code FeedbackSession} to the db."},{"lineNumber":167,"author":{"gitId":"-"},"content":" *"},{"lineNumber":168,"author":{"gitId":"-"},"content":" * @return updated feedback session"},{"lineNumber":169,"author":{"gitId":"-"},"content":" * @throws InvalidParametersException if attributes to update are not valid"},{"lineNumber":170,"author":{"gitId":"-"},"content":" * @throws EntityDoesNotExistException if the feedback session cannot be found"},{"lineNumber":171,"author":{"gitId":"-"},"content":" */"},{"lineNumber":172,"author":{"gitId":"-"},"content":" public FeedbackSession updateFeedbackSession(FeedbackSession feedbackSession)"},{"lineNumber":173,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":175,"author":{"gitId":"-"},"content":""},{"lineNumber":176,"author":{"gitId":"-"},"content":" if (!feedbackSession.isValid()) {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(feedbackSession.getInvalidityInfo());"},{"lineNumber":178,"author":{"gitId":"-"},"content":" }"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" if (getFeedbackSession(feedbackSession.getId()) \u003d\u003d null) {"},{"lineNumber":181,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT);"},{"lineNumber":182,"author":{"gitId":"-"},"content":" }"},{"lineNumber":183,"author":{"gitId":"-"},"content":""},{"lineNumber":184,"author":{"gitId":"-"},"content":" return merge(feedbackSession);"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":188,"author":{"gitId":"-"},"content":" * Deletes a feedback session."},{"lineNumber":189,"author":{"gitId":"-"},"content":" */"},{"lineNumber":190,"author":{"gitId":"-"},"content":" public void deleteFeedbackSession(FeedbackSession feedbackSession) {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" if (feedbackSession !\u003d null) {"},{"lineNumber":192,"author":{"gitId":"-"},"content":" delete(feedbackSession);"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":" }"},{"lineNumber":195,"author":{"gitId":"-"},"content":""},{"lineNumber":196,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":197,"author":{"gitId":"-"},"content":" * Soft-deletes a specific feedback session by its name and course id."},{"lineNumber":198,"author":{"gitId":"-"},"content":" *"},{"lineNumber":199,"author":{"gitId":"-"},"content":" * @return the feedback session."},{"lineNumber":200,"author":{"gitId":"-"},"content":" */"},{"lineNumber":201,"author":{"gitId":"-"},"content":" public FeedbackSession softDeleteFeedbackSession(String feedbackSessionName, String courseId)"},{"lineNumber":202,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":203,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":204,"author":{"gitId":"-"},"content":" assert feedbackSessionName !\u003d null;"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSessionEntity \u003d getFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":207,"author":{"gitId":"-"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" if (feedbackSessionEntity \u003d\u003d null) {"},{"lineNumber":209,"author":{"gitId":"-"},"content":" throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT);"},{"lineNumber":210,"author":{"gitId":"-"},"content":" }"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" feedbackSessionEntity.setDeletedAt(Instant.now());"},{"lineNumber":213,"author":{"gitId":"-"},"content":" merge(feedbackSessionEntity);"},{"lineNumber":214,"author":{"gitId":"-"},"content":""},{"lineNumber":215,"author":{"gitId":"-"},"content":" return feedbackSessionEntity;"},{"lineNumber":216,"author":{"gitId":"-"},"content":" }"},{"lineNumber":217,"author":{"gitId":"-"},"content":""},{"lineNumber":218,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":219,"author":{"gitId":"-"},"content":" * Gets feedback sessions for a given {@code courseId}."},{"lineNumber":220,"author":{"gitId":"-"},"content":" */"},{"lineNumber":221,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionEntitiesForCourse(String courseId) {"},{"lineNumber":222,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":223,"author":{"gitId":"-"},"content":""},{"lineNumber":224,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":225,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cq \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":226,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e root \u003d cq.from(FeedbackSession.class);"},{"lineNumber":227,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e courseJoin \u003d root.join(\"course\");"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" cq.select(root).where(cb.equal(courseJoin.get(\"id\"), courseId));"},{"lineNumber":230,"author":{"gitId":"-"},"content":""},{"lineNumber":231,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cq).getResultList();"},{"lineNumber":232,"author":{"gitId":"-"},"content":" }"},{"lineNumber":233,"author":{"gitId":"-"},"content":""},{"lineNumber":234,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":235,"author":{"gitId":"-"},"content":" * Gets feedback sessions for a given {@code courseId} that start after {@code after}."},{"lineNumber":236,"author":{"gitId":"-"},"content":" */"},{"lineNumber":237,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionEntitiesForCourseStartingAfter(String courseId, Instant after) {"},{"lineNumber":238,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":239,"author":{"gitId":"-"},"content":" assert after !\u003d null;"},{"lineNumber":240,"author":{"gitId":"-"},"content":""},{"lineNumber":241,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":242,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cr \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":243,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e root \u003d cr.from(FeedbackSession.class);"},{"lineNumber":244,"author":{"gitId":"-"},"content":" Join\u003cFeedbackSession, Course\u003e courseJoin \u003d root.join(\"course\");"},{"lineNumber":245,"author":{"gitId":"-"},"content":" cr.select(root)"},{"lineNumber":246,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":247,"author":{"gitId":"-"},"content":" cb.greaterThanOrEqualTo(root.get(\"startTime\"), after),"},{"lineNumber":248,"author":{"gitId":"-"},"content":" cb.equal(courseJoin.get(\"id\"), courseId)));"},{"lineNumber":249,"author":{"gitId":"-"},"content":""},{"lineNumber":250,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":251,"author":{"gitId":"-"},"content":" }"},{"lineNumber":252,"author":{"gitId":"-"},"content":""},{"lineNumber":253,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":254,"author":{"gitId":"-"},"content":" * Gets a list of undeleted feedback sessions which open in the future"},{"lineNumber":255,"author":{"gitId":"-"},"content":" * and possibly need a opening soon email to be sent."},{"lineNumber":256,"author":{"gitId":"-"},"content":" */"},{"lineNumber":257,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsPossiblyNeedingOpeningSoonEmail() {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" return getFeedbackSessionEntitiesPossiblyNeedingOpeningSoonEmail().stream()"},{"lineNumber":259,"author":{"gitId":"-"},"content":" .filter(session -\u003e session.getDeletedAt() \u003d\u003d null)"},{"lineNumber":260,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":261,"author":{"gitId":"-"},"content":" }"},{"lineNumber":262,"author":{"gitId":"-"},"content":""},{"lineNumber":263,"author":{"gitId":"-"},"content":" private List\u003cFeedbackSession\u003e getFeedbackSessionEntitiesPossiblyNeedingOpeningSoonEmail() {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":265,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cr \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":266,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e root \u003d cr.from(FeedbackSession.class);"},{"lineNumber":267,"author":{"gitId":"-"},"content":""},{"lineNumber":268,"author":{"gitId":"-"},"content":" cr.select(root)"},{"lineNumber":269,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":270,"author":{"gitId":"-"},"content":" cb.greaterThan(root.get(\"startTime\"), TimeHelper.getInstantDaysOffsetFromNow(-2)),"},{"lineNumber":271,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"isOpeningSoonEmailSent\"), false)));"},{"lineNumber":272,"author":{"gitId":"-"},"content":""},{"lineNumber":273,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":277,"author":{"gitId":"-"},"content":" * Gets a list of undeleted feedback sessions which end in the future (2 hour ago onward)"},{"lineNumber":278,"author":{"gitId":"-"},"content":" * and possibly need a closing soon email to be sent."},{"lineNumber":279,"author":{"gitId":"-"},"content":" */"},{"lineNumber":280,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsPossiblyNeedingClosingSoonEmail() {"},{"lineNumber":281,"author":{"gitId":"-"},"content":" return getFeedbackSessionEntitiesPossiblyNeedingClosingSoonEmail().stream()"},{"lineNumber":282,"author":{"gitId":"-"},"content":" .filter(session -\u003e session.getDeletedAt() \u003d\u003d null)"},{"lineNumber":283,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":284,"author":{"gitId":"-"},"content":" }"},{"lineNumber":285,"author":{"gitId":"-"},"content":""},{"lineNumber":286,"author":{"gitId":"-"},"content":" private List\u003cFeedbackSession\u003e getFeedbackSessionEntitiesPossiblyNeedingClosingSoonEmail() {"},{"lineNumber":287,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":288,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cr \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":289,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e root \u003d cr.from(FeedbackSession.class);"},{"lineNumber":290,"author":{"gitId":"-"},"content":""},{"lineNumber":291,"author":{"gitId":"-"},"content":" cr.select(root)"},{"lineNumber":292,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":293,"author":{"gitId":"-"},"content":" cb.greaterThan(root.get(\"endTime\"), TimeHelper.getInstantDaysOffsetFromNow(-2)),"},{"lineNumber":294,"author":{"gitId":"-"},"content":" cb.and("},{"lineNumber":295,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"isClosingSoonEmailSent\"), false),"},{"lineNumber":296,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"isClosingEmailEnabled\"), true))"},{"lineNumber":297,"author":{"gitId":"-"},"content":" ));"},{"lineNumber":298,"author":{"gitId":"-"},"content":""},{"lineNumber":299,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":300,"author":{"gitId":"-"},"content":" }"},{"lineNumber":301,"author":{"gitId":"-"},"content":""},{"lineNumber":302,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":303,"author":{"gitId":"-"},"content":" * Gets a list of undeleted feedback sessions which end in the future (2 hour ago onward)"},{"lineNumber":304,"author":{"gitId":"-"},"content":" * and possibly need a closed email to be sent."},{"lineNumber":305,"author":{"gitId":"-"},"content":" */"},{"lineNumber":306,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsPossiblyNeedingClosedEmail() {"},{"lineNumber":307,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":308,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cr \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":309,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e root \u003d cr.from(FeedbackSession.class);"},{"lineNumber":310,"author":{"gitId":"-"},"content":""},{"lineNumber":311,"author":{"gitId":"-"},"content":" cr.select(root)"},{"lineNumber":312,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":313,"author":{"gitId":"-"},"content":" cb.greaterThan(root.get(\"endTime\"), TimeHelper.getInstantDaysOffsetFromNow(-2)),"},{"lineNumber":314,"author":{"gitId":"-"},"content":" cb.isFalse(root.get(\"isClosedEmailSent\")),"},{"lineNumber":315,"author":{"gitId":"-"},"content":" cb.isTrue(root.get(\"isClosingEmailEnabled\")),"},{"lineNumber":316,"author":{"gitId":"-"},"content":" cb.isNull(root.get(\"deletedAt\"))"},{"lineNumber":317,"author":{"gitId":"-"},"content":" ));"},{"lineNumber":318,"author":{"gitId":"-"},"content":""},{"lineNumber":319,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":320,"author":{"gitId":"-"},"content":" }"},{"lineNumber":321,"author":{"gitId":"-"},"content":""},{"lineNumber":322,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":323,"author":{"gitId":"-"},"content":" * Gets a list of undeleted published feedback sessions which possibly need a published email"},{"lineNumber":324,"author":{"gitId":"-"},"content":" * to be sent."},{"lineNumber":325,"author":{"gitId":"-"},"content":" */"},{"lineNumber":326,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsPossiblyNeedingPublishedEmail() {"},{"lineNumber":327,"author":{"gitId":"-"},"content":" return getFeedbackSessionEntitiesPossiblyNeedingPublishedEmail().stream()"},{"lineNumber":328,"author":{"gitId":"-"},"content":" .filter(session -\u003e session.getDeletedAt() \u003d\u003d null)"},{"lineNumber":329,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":330,"author":{"gitId":"-"},"content":" }"},{"lineNumber":331,"author":{"gitId":"-"},"content":""},{"lineNumber":332,"author":{"gitId":"-"},"content":" private List\u003cFeedbackSession\u003e getFeedbackSessionEntitiesPossiblyNeedingPublishedEmail() {"},{"lineNumber":333,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":334,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cr \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":335,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e root \u003d cr.from(FeedbackSession.class);"},{"lineNumber":336,"author":{"gitId":"-"},"content":""},{"lineNumber":337,"author":{"gitId":"-"},"content":" cr.select(root)"},{"lineNumber":338,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":339,"author":{"gitId":"-"},"content":" cb.greaterThan(root.get(\"resultsVisibleFromTime\"), TimeHelper.getInstantDaysOffsetFromNow(-2)),"},{"lineNumber":340,"author":{"gitId":"-"},"content":" cb.and("},{"lineNumber":341,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"isPublishedEmailSent\"), false),"},{"lineNumber":342,"author":{"gitId":"-"},"content":" cb.equal(root.get(\"isPublishedEmailEnabled\"), true))"},{"lineNumber":343,"author":{"gitId":"-"},"content":" ));"},{"lineNumber":344,"author":{"gitId":"-"},"content":""},{"lineNumber":345,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":346,"author":{"gitId":"-"},"content":" }"},{"lineNumber":347,"author":{"gitId":"-"},"content":""},{"lineNumber":348,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":349,"author":{"gitId":"-"},"content":" * Gets a list of undeleted feedback sessions which start within the last 2 days"},{"lineNumber":350,"author":{"gitId":"-"},"content":" * and possibly need an open email to be sent."},{"lineNumber":351,"author":{"gitId":"-"},"content":" */"},{"lineNumber":352,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSession\u003e getFeedbackSessionsPossiblyNeedingOpenEmail() {"},{"lineNumber":353,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":354,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cFeedbackSession\u003e cr \u003d cb.createQuery(FeedbackSession.class);"},{"lineNumber":355,"author":{"gitId":"-"},"content":" Root\u003cFeedbackSession\u003e root \u003d cr.from(FeedbackSession.class);"},{"lineNumber":356,"author":{"gitId":"-"},"content":""},{"lineNumber":357,"author":{"gitId":"-"},"content":" cr.select(root)"},{"lineNumber":358,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":359,"author":{"gitId":"-"},"content":" cb.greaterThan(root.get(\"startTime\"), TimeHelper.getInstantDaysOffsetFromNow(-2)),"},{"lineNumber":360,"author":{"gitId":"-"},"content":" cb.isFalse(root.get(\"isOpenEmailSent\")),"},{"lineNumber":361,"author":{"gitId":"-"},"content":" cb.isNull(root.get(\"deletedAt\"))"},{"lineNumber":362,"author":{"gitId":"-"},"content":" ));"},{"lineNumber":363,"author":{"gitId":"-"},"content":""},{"lineNumber":364,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":365,"author":{"gitId":"-"},"content":" }"},{"lineNumber":366,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":12,"-":354}},{"path":"src/main/java/teammates/storage/sqlapi/UsersDb.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import static teammates.common.util.Const.ERROR_UPDATE_NON_EXISTENT;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaBuilder;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.CriteriaQuery;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Join;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Predicate;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import jakarta.persistence.criteria.Root;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.User;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.InstructorSearchManager;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.SearchManagerFactory;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlsearch.StudentSearchManager;"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":33,"author":{"gitId":"-"},"content":" * Handles CRUD operations for users."},{"lineNumber":34,"author":{"gitId":"-"},"content":" *"},{"lineNumber":35,"author":{"gitId":"-"},"content":" * @see User"},{"lineNumber":36,"author":{"gitId":"-"},"content":" */"},{"lineNumber":37,"author":{"gitId":"-"},"content":"public final class UsersDb extends EntitiesDb {"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" private static final UsersDb instance \u003d new UsersDb();"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" private UsersDb() {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":43,"author":{"gitId":"-"},"content":" }"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" public static UsersDb inst() {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" return instance;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" }"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" public InstructorSearchManager getInstructorSearchManager() {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" return SearchManagerFactory.getInstructorSearchManager();"},{"lineNumber":51,"author":{"gitId":"-"},"content":" }"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" public StudentSearchManager getStudentSearchManager() {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" return SearchManagerFactory.getStudentSearchManager();"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":58,"author":{"gitId":"-"},"content":" * Creates an instructor."},{"lineNumber":59,"author":{"gitId":"-"},"content":" */"},{"lineNumber":60,"author":{"gitId":"-"},"content":" public Instructor createInstructor(Instructor instructor)"},{"lineNumber":61,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" assert instructor !\u003d null;"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" if (!instructor.isValid()) {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(instructor.getInvalidityInfo());"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" persist(instructor);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" return instructor;"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":73,"author":{"gitId":"-"},"content":" * Creates a student."},{"lineNumber":74,"author":{"gitId":"-"},"content":" */"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public Student createStudent(Student student)"},{"lineNumber":76,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" assert student !\u003d null;"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" if (!student.isValid()) {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" throw new InvalidParametersException(student.getInvalidityInfo());"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" persist(student);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" return student;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" }"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":88,"author":{"gitId":"-"},"content":" * Gets an instructor by its {@code id}."},{"lineNumber":89,"author":{"gitId":"-"},"content":" */"},{"lineNumber":90,"author":{"gitId":"-"},"content":" public Instructor getInstructor(UUID id) {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" assert id !\u003d null;"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" return HibernateUtil.get(Instructor.class, id);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" }"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":97,"author":{"gitId":"-"},"content":" * Gets an instructor by {@code regKey}."},{"lineNumber":98,"author":{"gitId":"-"},"content":" */"},{"lineNumber":99,"author":{"gitId":"-"},"content":" public Instructor getInstructorByRegKey(String regKey) {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":101,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cInstructor\u003e cr \u003d cb.createQuery(Instructor.class);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" Root\u003cInstructor\u003e instructorRoot \u003d cr.from(Instructor.class);"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" cr.select(instructorRoot).where(cb.equal(instructorRoot.get(\"regKey\"), regKey));"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultStream().findFirst().orElse(null);"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":110,"author":{"gitId":"-"},"content":" * Gets an instructor by {@code googleId}."},{"lineNumber":111,"author":{"gitId":"-"},"content":" */"},{"lineNumber":112,"author":{"gitId":"-"},"content":" public Instructor getInstructorByGoogleId(String courseId, String googleId) {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":114,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cInstructor\u003e cr \u003d cb.createQuery(Instructor.class);"},{"lineNumber":115,"author":{"gitId":"-"},"content":" Root\u003cInstructor\u003e instructorRoot \u003d cr.from(Instructor.class);"},{"lineNumber":116,"author":{"gitId":"-"},"content":" Join\u003cInstructor, Account\u003e accountsJoin \u003d instructorRoot.join(\"account\");"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" cr.select(instructorRoot).where(cb.and("},{"lineNumber":119,"author":{"gitId":"-"},"content":" cb.equal(instructorRoot.get(\"courseId\"), courseId),"},{"lineNumber":120,"author":{"gitId":"-"},"content":" cb.equal(accountsJoin.get(\"googleId\"), googleId)));"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultStream().findFirst().orElse(null);"},{"lineNumber":123,"author":{"gitId":"-"},"content":" }"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":126,"author":{"gitId":"-"},"content":" * Gets all instructors that will be displayed to students of a course."},{"lineNumber":127,"author":{"gitId":"-"},"content":" */"},{"lineNumber":128,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getInstructorsDisplayedToStudents(String courseId) {"},{"lineNumber":129,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":130,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cInstructor\u003e cr \u003d cb.createQuery(Instructor.class);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" Root\u003cInstructor\u003e instructorRoot \u003d cr.from(Instructor.class);"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" cr.select(instructorRoot).where(cb.and("},{"lineNumber":134,"author":{"gitId":"-"},"content":" cb.equal(instructorRoot.get(\"courseId\"), courseId),"},{"lineNumber":135,"author":{"gitId":"-"},"content":" cb.equal(instructorRoot.get(\"isDisplayedToStudents\"), true)));"},{"lineNumber":136,"author":{"gitId":"-"},"content":""},{"lineNumber":137,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":141,"author":{"gitId":"-"},"content":" * Gets a student by its {@code id}."},{"lineNumber":142,"author":{"gitId":"-"},"content":" */"},{"lineNumber":143,"author":{"gitId":"-"},"content":" public Student getStudent(UUID id) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" assert id !\u003d null;"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" return HibernateUtil.get(Student.class, id);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":" * Gets a student reference by its {@code id}."},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":" public Student getStudentReference(UUID id) {"},{"lineNumber":153,"author":{"gitId":"dishenggg"},"content":" assert id !\u003d null;"},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":" return HibernateUtil.getReference(Student.class, id);"},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":158,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":159,"author":{"gitId":"-"},"content":" * Gets a student by {@code regKey}."},{"lineNumber":160,"author":{"gitId":"-"},"content":" */"},{"lineNumber":161,"author":{"gitId":"-"},"content":" public Student getStudentByRegKey(String regKey) {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":163,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":164,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" cr.select(studentRoot).where(cb.equal(studentRoot.get(\"regKey\"), regKey));"},{"lineNumber":167,"author":{"gitId":"-"},"content":""},{"lineNumber":168,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultStream().findFirst().orElse(null);"},{"lineNumber":169,"author":{"gitId":"-"},"content":" }"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":172,"author":{"gitId":"-"},"content":" * Gets a student by {@code googleId}."},{"lineNumber":173,"author":{"gitId":"-"},"content":" */"},{"lineNumber":174,"author":{"gitId":"-"},"content":" public Student getStudentByGoogleId(String courseId, String googleId) {"},{"lineNumber":175,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":176,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":177,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":178,"author":{"gitId":"-"},"content":" Join\u003cStudent, Account\u003e accountsJoin \u003d studentRoot.join(\"account\");"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" cr.select(studentRoot).where(cb.and("},{"lineNumber":181,"author":{"gitId":"-"},"content":" cb.equal(studentRoot.get(\"courseId\"), courseId),"},{"lineNumber":182,"author":{"gitId":"-"},"content":" cb.equal(accountsJoin.get(\"googleId\"), googleId)));"},{"lineNumber":183,"author":{"gitId":"-"},"content":""},{"lineNumber":184,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultStream().findFirst().orElse(null);"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":188,"author":{"gitId":"-"},"content":" * Gets all students by {@code googleId}."},{"lineNumber":189,"author":{"gitId":"-"},"content":" */"},{"lineNumber":190,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsByGoogleId(String googleId) {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":192,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":193,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":194,"author":{"gitId":"-"},"content":" Join\u003cStudent, Account\u003e accountsJoin \u003d studentRoot.join(\"account\");"},{"lineNumber":195,"author":{"gitId":"-"},"content":""},{"lineNumber":196,"author":{"gitId":"-"},"content":" cr.select(studentRoot).where(cb.equal(accountsJoin.get(\"googleId\"), googleId));"},{"lineNumber":197,"author":{"gitId":"-"},"content":""},{"lineNumber":198,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":199,"author":{"gitId":"-"},"content":" }"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":202,"author":{"gitId":"-"},"content":" * Gets a list of students by {@code teamName} and {@code courseId}."},{"lineNumber":203,"author":{"gitId":"-"},"content":" */"},{"lineNumber":204,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsByTeamName(String teamName, String courseId) {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":206,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":207,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":208,"author":{"gitId":"-"},"content":""},{"lineNumber":209,"author":{"gitId":"-"},"content":" studentRoot.alias(\"student\");"},{"lineNumber":210,"author":{"gitId":"-"},"content":""},{"lineNumber":211,"author":{"gitId":"-"},"content":" Join\u003cStudent, Team\u003e teamsJoin \u003d studentRoot.join(\"team\");"},{"lineNumber":212,"author":{"gitId":"-"},"content":""},{"lineNumber":213,"author":{"gitId":"-"},"content":" cr.select(studentRoot).where(cb.and("},{"lineNumber":214,"author":{"gitId":"-"},"content":" cb.equal(studentRoot.get(\"courseId\"), courseId),"},{"lineNumber":215,"author":{"gitId":"-"},"content":" cb.equal(teamsJoin.get(\"name\"), teamName)));"},{"lineNumber":216,"author":{"gitId":"-"},"content":""},{"lineNumber":217,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":221,"author":{"gitId":"-"},"content":" * Gets all instructors and students by {@code googleId}."},{"lineNumber":222,"author":{"gitId":"-"},"content":" */"},{"lineNumber":223,"author":{"gitId":"-"},"content":" public List\u003cUser\u003e getAllUsersByGoogleId(String googleId) {"},{"lineNumber":224,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":225,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cUser\u003e usersCr \u003d cb.createQuery(User.class);"},{"lineNumber":226,"author":{"gitId":"-"},"content":" Root\u003cUser\u003e usersRoot \u003d usersCr.from(User.class);"},{"lineNumber":227,"author":{"gitId":"-"},"content":" Join\u003cUser, Account\u003e accountsJoin \u003d usersRoot.join(\"account\");"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" usersCr.select(usersRoot).where(cb.equal(accountsJoin.get(\"googleId\"), googleId));"},{"lineNumber":230,"author":{"gitId":"-"},"content":""},{"lineNumber":231,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(usersCr).getResultList();"},{"lineNumber":232,"author":{"gitId":"-"},"content":" }"},{"lineNumber":233,"author":{"gitId":"-"},"content":""},{"lineNumber":234,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":235,"author":{"gitId":"-"},"content":" * Gets all instructors by {@code googleId}."},{"lineNumber":236,"author":{"gitId":"-"},"content":" */"},{"lineNumber":237,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getAllInstructorsByGoogleId(String googleId) {"},{"lineNumber":238,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":239,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cInstructor\u003e instructorsCr \u003d cb.createQuery(Instructor.class);"},{"lineNumber":240,"author":{"gitId":"-"},"content":" Root\u003cInstructor\u003e instructorsRoot \u003d instructorsCr.from(Instructor.class);"},{"lineNumber":241,"author":{"gitId":"-"},"content":" Join\u003cInstructor, Account\u003e accountsJoin \u003d instructorsRoot.join(\"account\");"},{"lineNumber":242,"author":{"gitId":"-"},"content":""},{"lineNumber":243,"author":{"gitId":"-"},"content":" instructorsCr.select(instructorsRoot).where(cb.equal(accountsJoin.get(\"googleId\"), googleId));"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(instructorsCr).getResultList();"},{"lineNumber":246,"author":{"gitId":"-"},"content":" }"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":249,"author":{"gitId":"-"},"content":" * Gets all students by {@code googleId}."},{"lineNumber":250,"author":{"gitId":"-"},"content":" */"},{"lineNumber":251,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getAllStudentsByGoogleId(String googleId) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":253,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e studentsCr \u003d cb.createQuery(Student.class);"},{"lineNumber":254,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentsRoot \u003d studentsCr.from(Student.class);"},{"lineNumber":255,"author":{"gitId":"-"},"content":" Join\u003cStudent, Account\u003e accountsJoin \u003d studentsRoot.join(\"account\");"},{"lineNumber":256,"author":{"gitId":"-"},"content":""},{"lineNumber":257,"author":{"gitId":"-"},"content":" studentsCr.select(studentsRoot).where(cb.equal(accountsJoin.get(\"googleId\"), googleId));"},{"lineNumber":258,"author":{"gitId":"-"},"content":""},{"lineNumber":259,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(studentsCr).getResultList();"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":""},{"lineNumber":262,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":263,"author":{"gitId":"-"},"content":" * Gets all instructors."},{"lineNumber":264,"author":{"gitId":"-"},"content":" */"},{"lineNumber":265,"author":{"gitId":"-"},"content":" public \u003cT extends User\u003e T updateUser(T user) {"},{"lineNumber":266,"author":{"gitId":"-"},"content":" assert user !\u003d null;"},{"lineNumber":267,"author":{"gitId":"-"},"content":""},{"lineNumber":268,"author":{"gitId":"-"},"content":" return merge(user);"},{"lineNumber":269,"author":{"gitId":"-"},"content":" }"},{"lineNumber":270,"author":{"gitId":"-"},"content":""},{"lineNumber":271,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":272,"author":{"gitId":"-"},"content":" * Searches all instructors in the system."},{"lineNumber":273,"author":{"gitId":"-"},"content":" *"},{"lineNumber":274,"author":{"gitId":"-"},"content":" * \u003cp\u003eThis method should be used by admin only since the searching does not"},{"lineNumber":275,"author":{"gitId":"-"},"content":" * restrict the visibility according to the logged-in user\u0027s google ID. This"},{"lineNumber":276,"author":{"gitId":"-"},"content":" * is used by admin to search instructors in the whole system."},{"lineNumber":277,"author":{"gitId":"-"},"content":" */"},{"lineNumber":278,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e searchInstructorsInWholeSystem(String queryString)"},{"lineNumber":279,"author":{"gitId":"-"},"content":" throws SearchServiceException {"},{"lineNumber":280,"author":{"gitId":"-"},"content":" if (queryString.trim().isEmpty()) {"},{"lineNumber":281,"author":{"gitId":"-"},"content":" return new ArrayList\u003c\u003e();"},{"lineNumber":282,"author":{"gitId":"-"},"content":" }"},{"lineNumber":283,"author":{"gitId":"-"},"content":""},{"lineNumber":284,"author":{"gitId":"-"},"content":" return getInstructorSearchManager().searchInstructors(queryString);"},{"lineNumber":285,"author":{"gitId":"-"},"content":" }"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":288,"author":{"gitId":"yuanxi1"},"content":" * Searches for students."},{"lineNumber":289,"author":{"gitId":"yuanxi1"},"content":" *"},{"lineNumber":290,"author":{"gitId":"yuanxi1"},"content":" * @param instructors the constraint that restricts the search result"},{"lineNumber":291,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":292,"author":{"gitId":"yuanxi1"},"content":" public List\u003cStudent\u003e searchStudents(String queryString, List\u003cInstructor\u003e instructors)"},{"lineNumber":293,"author":{"gitId":"yuanxi1"},"content":" throws SearchServiceException {"},{"lineNumber":294,"author":{"gitId":"yuanxi1"},"content":" if (queryString.trim().isEmpty()) {"},{"lineNumber":295,"author":{"gitId":"yuanxi1"},"content":" return new ArrayList\u003c\u003e();"},{"lineNumber":296,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":297,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":298,"author":{"gitId":"yuanxi1"},"content":" return getStudentSearchManager().searchStudents(queryString, instructors);"},{"lineNumber":299,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":300,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":301,"author":{"gitId":"yuanxi1"},"content":" /**"},{"lineNumber":302,"author":{"gitId":"yuanxi1"},"content":" * Searches all students in the system."},{"lineNumber":303,"author":{"gitId":"yuanxi1"},"content":" *"},{"lineNumber":304,"author":{"gitId":"yuanxi1"},"content":" * \u003cp\u003eThis method should be used by admin only since the searching does not restrict the"},{"lineNumber":305,"author":{"gitId":"yuanxi1"},"content":" * visibility according to the logged-in user\u0027s google ID. This is used by admin to"},{"lineNumber":306,"author":{"gitId":"yuanxi1"},"content":" * search instructors in the whole system."},{"lineNumber":307,"author":{"gitId":"yuanxi1"},"content":" */"},{"lineNumber":308,"author":{"gitId":"yuanxi1"},"content":" public List\u003cStudent\u003e searchStudentsInWholeSystem(String queryString)"},{"lineNumber":309,"author":{"gitId":"yuanxi1"},"content":" throws SearchServiceException {"},{"lineNumber":310,"author":{"gitId":"yuanxi1"},"content":" if (queryString.trim().isEmpty()) {"},{"lineNumber":311,"author":{"gitId":"yuanxi1"},"content":" return new ArrayList\u003c\u003e();"},{"lineNumber":312,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":313,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":314,"author":{"gitId":"yuanxi1"},"content":" return getStudentSearchManager().searchStudents(queryString, null);"},{"lineNumber":315,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":316,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":317,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":318,"author":{"gitId":"-"},"content":" * Deletes a user."},{"lineNumber":319,"author":{"gitId":"-"},"content":" */"},{"lineNumber":320,"author":{"gitId":"-"},"content":" public \u003cT extends User\u003e void deleteUser(T user) {"},{"lineNumber":321,"author":{"gitId":"-"},"content":" if (user !\u003d null) {"},{"lineNumber":322,"author":{"gitId":"-"},"content":" delete(user);"},{"lineNumber":323,"author":{"gitId":"-"},"content":" }"},{"lineNumber":324,"author":{"gitId":"-"},"content":" }"},{"lineNumber":325,"author":{"gitId":"-"},"content":""},{"lineNumber":326,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":327,"author":{"gitId":"-"},"content":" * Gets the number of instructors created within a specified time range."},{"lineNumber":328,"author":{"gitId":"-"},"content":" */"},{"lineNumber":329,"author":{"gitId":"-"},"content":" public long getNumInstructorsByTimeRange(Instant startTime, Instant endTime) {"},{"lineNumber":330,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":331,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cLong\u003e cr \u003d cb.createQuery(Long.class);"},{"lineNumber":332,"author":{"gitId":"-"},"content":" Root\u003cInstructor\u003e root \u003d cr.from(Instructor.class);"},{"lineNumber":333,"author":{"gitId":"-"},"content":""},{"lineNumber":334,"author":{"gitId":"-"},"content":" cr.select(cb.count(root.get(\"id\"))).where(cb.and("},{"lineNumber":335,"author":{"gitId":"-"},"content":" cb.greaterThanOrEqualTo(root.get(\"createdAt\"), startTime),"},{"lineNumber":336,"author":{"gitId":"-"},"content":" cb.lessThan(root.get(\"createdAt\"), endTime)));"},{"lineNumber":337,"author":{"gitId":"-"},"content":""},{"lineNumber":338,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getSingleResult();"},{"lineNumber":339,"author":{"gitId":"-"},"content":" }"},{"lineNumber":340,"author":{"gitId":"-"},"content":""},{"lineNumber":341,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":342,"author":{"gitId":"-"},"content":" * Gets the number of students created within a specified time range."},{"lineNumber":343,"author":{"gitId":"-"},"content":" */"},{"lineNumber":344,"author":{"gitId":"-"},"content":" public long getNumStudentsByTimeRange(Instant startTime, Instant endTime) {"},{"lineNumber":345,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":346,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cLong\u003e cr \u003d cb.createQuery(Long.class);"},{"lineNumber":347,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e root \u003d cr.from(Student.class);"},{"lineNumber":348,"author":{"gitId":"-"},"content":""},{"lineNumber":349,"author":{"gitId":"-"},"content":" cr.select(cb.count(root.get(\"id\"))).where(cb.and("},{"lineNumber":350,"author":{"gitId":"-"},"content":" cb.greaterThanOrEqualTo(root.get(\"createdAt\"), startTime),"},{"lineNumber":351,"author":{"gitId":"-"},"content":" cb.lessThan(root.get(\"createdAt\"), endTime)));"},{"lineNumber":352,"author":{"gitId":"-"},"content":""},{"lineNumber":353,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getSingleResult();"},{"lineNumber":354,"author":{"gitId":"-"},"content":" }"},{"lineNumber":355,"author":{"gitId":"-"},"content":""},{"lineNumber":356,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":357,"author":{"gitId":"-"},"content":" * Gets the list of instructors for the specified {@code courseId}."},{"lineNumber":358,"author":{"gitId":"-"},"content":" */"},{"lineNumber":359,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getInstructorsForCourse(String courseId) {"},{"lineNumber":360,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":361,"author":{"gitId":"-"},"content":""},{"lineNumber":362,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":363,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cInstructor\u003e cr \u003d cb.createQuery(Instructor.class);"},{"lineNumber":364,"author":{"gitId":"-"},"content":" Root\u003cInstructor\u003e root \u003d cr.from(Instructor.class);"},{"lineNumber":365,"author":{"gitId":"-"},"content":""},{"lineNumber":366,"author":{"gitId":"-"},"content":" cr.select(root).where(cb.equal(root.get(\"courseId\"), courseId));"},{"lineNumber":367,"author":{"gitId":"-"},"content":""},{"lineNumber":368,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":369,"author":{"gitId":"-"},"content":" }"},{"lineNumber":370,"author":{"gitId":"-"},"content":""},{"lineNumber":371,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":372,"author":{"gitId":"-"},"content":" * Gets the list of students for the specified {@code courseId}."},{"lineNumber":373,"author":{"gitId":"-"},"content":" */"},{"lineNumber":374,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsForCourse(String courseId) {"},{"lineNumber":375,"author":{"gitId":"-"},"content":" assert courseId !\u003d null \u0026\u0026 !courseId.isEmpty();"},{"lineNumber":376,"author":{"gitId":"-"},"content":""},{"lineNumber":377,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":378,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":379,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e root \u003d cr.from(Student.class);"},{"lineNumber":380,"author":{"gitId":"-"},"content":""},{"lineNumber":381,"author":{"gitId":"-"},"content":" cr.select(root).where(cb.equal(root.get(\"courseId\"), courseId));"},{"lineNumber":382,"author":{"gitId":"-"},"content":""},{"lineNumber":383,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":384,"author":{"gitId":"-"},"content":" }"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":387,"author":{"gitId":"-"},"content":" * Gets the list of students for the specified {@code courseId} in batches with {@code batchSize}."},{"lineNumber":388,"author":{"gitId":"-"},"content":" */"},{"lineNumber":389,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsForCourse(String courseId, int batchSize) {"},{"lineNumber":390,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":391,"author":{"gitId":"-"},"content":""},{"lineNumber":392,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":393,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":394,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e root \u003d cr.from(Student.class);"},{"lineNumber":395,"author":{"gitId":"-"},"content":""},{"lineNumber":396,"author":{"gitId":"-"},"content":" cr.select(root).where(cb.equal(root.get(\"courseId\"), courseId));"},{"lineNumber":397,"author":{"gitId":"-"},"content":""},{"lineNumber":398,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).setMaxResults(batchSize).getResultList();"},{"lineNumber":399,"author":{"gitId":"-"},"content":" }"},{"lineNumber":400,"author":{"gitId":"-"},"content":""},{"lineNumber":401,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":402,"author":{"gitId":"-"},"content":" * Gets the instructor with the specified {@code userEmail}."},{"lineNumber":403,"author":{"gitId":"-"},"content":" */"},{"lineNumber":404,"author":{"gitId":"-"},"content":" public Instructor getInstructorForEmail(String courseId, String userEmail) {"},{"lineNumber":405,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":406,"author":{"gitId":"-"},"content":" assert userEmail !\u003d null;"},{"lineNumber":407,"author":{"gitId":"-"},"content":""},{"lineNumber":408,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":409,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cInstructor\u003e cr \u003d cb.createQuery(Instructor.class);"},{"lineNumber":410,"author":{"gitId":"-"},"content":" Root\u003cInstructor\u003e instructorRoot \u003d cr.from(Instructor.class);"},{"lineNumber":411,"author":{"gitId":"-"},"content":""},{"lineNumber":412,"author":{"gitId":"-"},"content":" cr.select(instructorRoot)"},{"lineNumber":413,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":414,"author":{"gitId":"-"},"content":" cb.equal(instructorRoot.get(\"courseId\"), courseId),"},{"lineNumber":415,"author":{"gitId":"-"},"content":" cb.equal(instructorRoot.get(\"email\"), userEmail)));"},{"lineNumber":416,"author":{"gitId":"-"},"content":""},{"lineNumber":417,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultStream().findFirst().orElse(null);"},{"lineNumber":418,"author":{"gitId":"-"},"content":" }"},{"lineNumber":419,"author":{"gitId":"-"},"content":""},{"lineNumber":420,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":421,"author":{"gitId":"-"},"content":" * Gets instructors with the specified {@code userEmail}."},{"lineNumber":422,"author":{"gitId":"-"},"content":" */"},{"lineNumber":423,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getInstructorsForEmails(String courseId, List\u003cString\u003e userEmails) {"},{"lineNumber":424,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":425,"author":{"gitId":"-"},"content":" assert userEmails !\u003d null;"},{"lineNumber":426,"author":{"gitId":"-"},"content":""},{"lineNumber":427,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":428,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cInstructor\u003e cr \u003d cb.createQuery(Instructor.class);"},{"lineNumber":429,"author":{"gitId":"-"},"content":" Root\u003cInstructor\u003e instructorRoot \u003d cr.from(Instructor.class);"},{"lineNumber":430,"author":{"gitId":"-"},"content":""},{"lineNumber":431,"author":{"gitId":"-"},"content":" List\u003cPredicate\u003e predicates \u003d new ArrayList\u003c\u003e();"},{"lineNumber":432,"author":{"gitId":"-"},"content":" for (String userEmail : userEmails) {"},{"lineNumber":433,"author":{"gitId":"-"},"content":" predicates.add(cb.equal(instructorRoot.get(\"email\"), userEmail));"},{"lineNumber":434,"author":{"gitId":"-"},"content":" }"},{"lineNumber":435,"author":{"gitId":"-"},"content":""},{"lineNumber":436,"author":{"gitId":"-"},"content":" cr.select(instructorRoot)"},{"lineNumber":437,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":438,"author":{"gitId":"-"},"content":" cb.equal(instructorRoot.get(\"courseId\"), courseId),"},{"lineNumber":439,"author":{"gitId":"-"},"content":" cb.or(predicates.toArray(new Predicate[0]))));"},{"lineNumber":440,"author":{"gitId":"-"},"content":""},{"lineNumber":441,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":442,"author":{"gitId":"-"},"content":" }"},{"lineNumber":443,"author":{"gitId":"-"},"content":""},{"lineNumber":444,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":445,"author":{"gitId":"-"},"content":" * Gets the student with the specified {@code userEmail}."},{"lineNumber":446,"author":{"gitId":"-"},"content":" */"},{"lineNumber":447,"author":{"gitId":"-"},"content":" public Student getStudentForEmail(String courseId, String userEmail) {"},{"lineNumber":448,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":449,"author":{"gitId":"-"},"content":" assert userEmail !\u003d null;"},{"lineNumber":450,"author":{"gitId":"-"},"content":""},{"lineNumber":451,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":452,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":453,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":454,"author":{"gitId":"-"},"content":""},{"lineNumber":455,"author":{"gitId":"-"},"content":" cr.select(studentRoot)"},{"lineNumber":456,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":457,"author":{"gitId":"-"},"content":" cb.equal(studentRoot.get(\"courseId\"), courseId),"},{"lineNumber":458,"author":{"gitId":"-"},"content":" cb.equal(studentRoot.get(\"email\"), userEmail)));"},{"lineNumber":459,"author":{"gitId":"-"},"content":""},{"lineNumber":460,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultStream().findFirst().orElse(null);"},{"lineNumber":461,"author":{"gitId":"-"},"content":" }"},{"lineNumber":462,"author":{"gitId":"-"},"content":""},{"lineNumber":463,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":464,"author":{"gitId":"-"},"content":" * Gets students with the specified {@code userEmail}."},{"lineNumber":465,"author":{"gitId":"-"},"content":" */"},{"lineNumber":466,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsForEmails(String courseId, List\u003cString\u003e userEmails) {"},{"lineNumber":467,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":468,"author":{"gitId":"-"},"content":" assert userEmails !\u003d null;"},{"lineNumber":469,"author":{"gitId":"-"},"content":""},{"lineNumber":470,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":471,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":472,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":473,"author":{"gitId":"-"},"content":""},{"lineNumber":474,"author":{"gitId":"-"},"content":" List\u003cPredicate\u003e predicates \u003d new ArrayList\u003c\u003e();"},{"lineNumber":475,"author":{"gitId":"-"},"content":" for (String userEmail : userEmails) {"},{"lineNumber":476,"author":{"gitId":"-"},"content":" predicates.add(cb.equal(studentRoot.get(\"email\"), userEmail));"},{"lineNumber":477,"author":{"gitId":"-"},"content":" }"},{"lineNumber":478,"author":{"gitId":"-"},"content":""},{"lineNumber":479,"author":{"gitId":"-"},"content":" cr.select(studentRoot)"},{"lineNumber":480,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":481,"author":{"gitId":"-"},"content":" cb.equal(studentRoot.get(\"courseId\"), courseId),"},{"lineNumber":482,"author":{"gitId":"-"},"content":" cb.or(predicates.toArray(new Predicate[0]))));"},{"lineNumber":483,"author":{"gitId":"-"},"content":""},{"lineNumber":484,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":485,"author":{"gitId":"-"},"content":" }"},{"lineNumber":486,"author":{"gitId":"-"},"content":""},{"lineNumber":487,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":488,"author":{"gitId":"-"},"content":" * Gets list of students by email."},{"lineNumber":489,"author":{"gitId":"-"},"content":" */"},{"lineNumber":490,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getAllStudentsForEmail(String email) {"},{"lineNumber":491,"author":{"gitId":"-"},"content":" assert email !\u003d null;"},{"lineNumber":492,"author":{"gitId":"-"},"content":""},{"lineNumber":493,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":494,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":495,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":496,"author":{"gitId":"-"},"content":""},{"lineNumber":497,"author":{"gitId":"-"},"content":" cr.select(studentRoot)"},{"lineNumber":498,"author":{"gitId":"-"},"content":" .where(cb.equal(studentRoot.get(\"email\"), email));"},{"lineNumber":499,"author":{"gitId":"-"},"content":""},{"lineNumber":500,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":501,"author":{"gitId":"-"},"content":" }"},{"lineNumber":502,"author":{"gitId":"-"},"content":""},{"lineNumber":503,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":504,"author":{"gitId":"-"},"content":" * Gets all instructors associated with a googleId."},{"lineNumber":505,"author":{"gitId":"-"},"content":" */"},{"lineNumber":506,"author":{"gitId":"-"},"content":" public List\u003cInstructor\u003e getInstructorsForGoogleId(String googleId) {"},{"lineNumber":507,"author":{"gitId":"-"},"content":" assert googleId !\u003d null;"},{"lineNumber":508,"author":{"gitId":"-"},"content":""},{"lineNumber":509,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":510,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cInstructor\u003e cr \u003d cb.createQuery(Instructor.class);"},{"lineNumber":511,"author":{"gitId":"-"},"content":" Root\u003cInstructor\u003e instructorRoot \u003d cr.from(Instructor.class);"},{"lineNumber":512,"author":{"gitId":"-"},"content":" Join\u003cInstructor, Account\u003e accountsJoin \u003d instructorRoot.join(\"account\");"},{"lineNumber":513,"author":{"gitId":"-"},"content":""},{"lineNumber":514,"author":{"gitId":"-"},"content":" cr.select(instructorRoot).where(cb.equal(accountsJoin.get(\"googleId\"), googleId));"},{"lineNumber":515,"author":{"gitId":"-"},"content":""},{"lineNumber":516,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":517,"author":{"gitId":"-"},"content":" }"},{"lineNumber":518,"author":{"gitId":"-"},"content":""},{"lineNumber":519,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":520,"author":{"gitId":"-"},"content":" * Gets all students of a section of a course."},{"lineNumber":521,"author":{"gitId":"-"},"content":" */"},{"lineNumber":522,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsForSection(String sectionName, String courseId) {"},{"lineNumber":523,"author":{"gitId":"-"},"content":" assert sectionName !\u003d null;"},{"lineNumber":524,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":525,"author":{"gitId":"-"},"content":""},{"lineNumber":526,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":527,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":528,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":529,"author":{"gitId":"-"},"content":" Join\u003cStudent, Course\u003e courseJoin \u003d studentRoot.join(\"course\");"},{"lineNumber":530,"author":{"gitId":"-"},"content":" Join\u003cStudent, Team\u003e teamsJoin \u003d studentRoot.join(\"team\");"},{"lineNumber":531,"author":{"gitId":"-"},"content":" Join\u003cTeam, Section\u003e sectionJoin \u003d teamsJoin.join(\"section\");"},{"lineNumber":532,"author":{"gitId":"-"},"content":""},{"lineNumber":533,"author":{"gitId":"-"},"content":" cr.select(studentRoot)"},{"lineNumber":534,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":535,"author":{"gitId":"-"},"content":" cb.equal(courseJoin.get(\"id\"), courseId),"},{"lineNumber":536,"author":{"gitId":"-"},"content":" cb.equal(sectionJoin.get(\"name\"), sectionName)));"},{"lineNumber":537,"author":{"gitId":"-"},"content":""},{"lineNumber":538,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":539,"author":{"gitId":"-"},"content":" }"},{"lineNumber":540,"author":{"gitId":"-"},"content":""},{"lineNumber":541,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":542,"author":{"gitId":"-"},"content":" * Gets all students of a team of a course."},{"lineNumber":543,"author":{"gitId":"-"},"content":" */"},{"lineNumber":544,"author":{"gitId":"-"},"content":" public List\u003cStudent\u003e getStudentsForTeam(String teamName, String courseId) {"},{"lineNumber":545,"author":{"gitId":"-"},"content":" assert teamName !\u003d null;"},{"lineNumber":546,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":547,"author":{"gitId":"-"},"content":""},{"lineNumber":548,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":549,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cStudent\u003e cr \u003d cb.createQuery(Student.class);"},{"lineNumber":550,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":551,"author":{"gitId":"-"},"content":" Join\u003cStudent, Course\u003e courseJoin \u003d studentRoot.join(\"course\");"},{"lineNumber":552,"author":{"gitId":"-"},"content":" Join\u003cStudent, Team\u003e teamsJoin \u003d studentRoot.join(\"team\");"},{"lineNumber":553,"author":{"gitId":"-"},"content":""},{"lineNumber":554,"author":{"gitId":"-"},"content":" cr.select(studentRoot)"},{"lineNumber":555,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":556,"author":{"gitId":"-"},"content":" cb.equal(courseJoin.get(\"id\"), courseId),"},{"lineNumber":557,"author":{"gitId":"-"},"content":" cb.equal(teamsJoin.get(\"name\"), teamName)));"},{"lineNumber":558,"author":{"gitId":"-"},"content":""},{"lineNumber":559,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getResultList();"},{"lineNumber":560,"author":{"gitId":"-"},"content":" }"},{"lineNumber":561,"author":{"gitId":"-"},"content":""},{"lineNumber":562,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":563,"author":{"gitId":"-"},"content":" * Gets count of students of a team of a course."},{"lineNumber":564,"author":{"gitId":"-"},"content":" */"},{"lineNumber":565,"author":{"gitId":"-"},"content":" public long getStudentCountForTeam(String teamName, String courseId) {"},{"lineNumber":566,"author":{"gitId":"-"},"content":" assert teamName !\u003d null;"},{"lineNumber":567,"author":{"gitId":"-"},"content":" assert courseId !\u003d null;"},{"lineNumber":568,"author":{"gitId":"-"},"content":""},{"lineNumber":569,"author":{"gitId":"-"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":570,"author":{"gitId":"-"},"content":" CriteriaQuery\u003cLong\u003e cr \u003d cb.createQuery(Long.class);"},{"lineNumber":571,"author":{"gitId":"-"},"content":" Root\u003cStudent\u003e studentRoot \u003d cr.from(Student.class);"},{"lineNumber":572,"author":{"gitId":"-"},"content":" Join\u003cStudent, Course\u003e courseJoin \u003d studentRoot.join(\"course\");"},{"lineNumber":573,"author":{"gitId":"-"},"content":" Join\u003cStudent, Team\u003e teamsJoin \u003d studentRoot.join(\"team\");"},{"lineNumber":574,"author":{"gitId":"-"},"content":""},{"lineNumber":575,"author":{"gitId":"-"},"content":" cr.select(cb.count(studentRoot.get(\"id\")))"},{"lineNumber":576,"author":{"gitId":"-"},"content":" .where(cb.and("},{"lineNumber":577,"author":{"gitId":"-"},"content":" cb.equal(courseJoin.get(\"id\"), courseId),"},{"lineNumber":578,"author":{"gitId":"-"},"content":" cb.equal(teamsJoin.get(\"name\"), teamName)));"},{"lineNumber":579,"author":{"gitId":"-"},"content":""},{"lineNumber":580,"author":{"gitId":"-"},"content":" return HibernateUtil.createQuery(cr).getSingleResult();"},{"lineNumber":581,"author":{"gitId":"-"},"content":" }"},{"lineNumber":582,"author":{"gitId":"-"},"content":""},{"lineNumber":583,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":584,"author":{"gitId":"domoberzin"},"content":" * Gets the section with the specified {@code sectionName} and {@code courseId}."},{"lineNumber":585,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":586,"author":{"gitId":"domoberzin"},"content":" public Section getSection(String courseId, String sectionName) {"},{"lineNumber":587,"author":{"gitId":"domoberzin"},"content":" assert sectionName !\u003d null;"},{"lineNumber":588,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":589,"author":{"gitId":"domoberzin"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":590,"author":{"gitId":"domoberzin"},"content":" CriteriaQuery\u003cSection\u003e cr \u003d cb.createQuery(Section.class);"},{"lineNumber":591,"author":{"gitId":"domoberzin"},"content":" Root\u003cSection\u003e sectionRoot \u003d cr.from(Section.class);"},{"lineNumber":592,"author":{"gitId":"domoberzin"},"content":" Join\u003cSection, Course\u003e courseJoin \u003d sectionRoot.join(\"course\");"},{"lineNumber":593,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":594,"author":{"gitId":"domoberzin"},"content":" cr.select(sectionRoot)"},{"lineNumber":595,"author":{"gitId":"domoberzin"},"content":" .where(cb.and("},{"lineNumber":596,"author":{"gitId":"domoberzin"},"content":" cb.equal(courseJoin.get(\"id\"), courseId),"},{"lineNumber":597,"author":{"gitId":"domoberzin"},"content":" cb.equal(sectionRoot.get(\"name\"), sectionName)));"},{"lineNumber":598,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":599,"author":{"gitId":"domoberzin"},"content":" return HibernateUtil.createQuery(cr).getResultStream().findFirst().orElse(null);"},{"lineNumber":600,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":601,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":602,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":603,"author":{"gitId":"domoberzin"},"content":" * Gets a section by its {@code courseId} and {@code sectionName}."},{"lineNumber":604,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":605,"author":{"gitId":"domoberzin"},"content":" public Section getSectionOrCreate(String courseId, String sectionName) {"},{"lineNumber":606,"author":{"gitId":"domoberzin"},"content":" assert courseId !\u003d null;"},{"lineNumber":607,"author":{"gitId":"domoberzin"},"content":" assert sectionName !\u003d null;"},{"lineNumber":608,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":609,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getSection(courseId, sectionName);"},{"lineNumber":610,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":611,"author":{"gitId":"domoberzin"},"content":" if (section \u003d\u003d null) {"},{"lineNumber":612,"author":{"gitId":"domoberzin"},"content":" Course course \u003d CoursesDb.inst().getCourse(courseId);"},{"lineNumber":613,"author":{"gitId":"domoberzin"},"content":" section \u003d new Section(course, sectionName);"},{"lineNumber":614,"author":{"gitId":"domoberzin"},"content":" persist(section);"},{"lineNumber":615,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":616,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":617,"author":{"gitId":"domoberzin"},"content":" return section;"},{"lineNumber":618,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":619,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":620,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":621,"author":{"gitId":"domoberzin"},"content":" * Gets a team by its {@code section} and {@code teamName}."},{"lineNumber":622,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":623,"author":{"gitId":"domoberzin"},"content":" public Team getTeam(Section section, String teamName) {"},{"lineNumber":624,"author":{"gitId":"domoberzin"},"content":" assert teamName !\u003d null;"},{"lineNumber":625,"author":{"gitId":"domoberzin"},"content":" assert section !\u003d null;"},{"lineNumber":626,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":627,"author":{"gitId":"domoberzin"},"content":" CriteriaBuilder cb \u003d HibernateUtil.getCriteriaBuilder();"},{"lineNumber":628,"author":{"gitId":"domoberzin"},"content":" CriteriaQuery\u003cTeam\u003e cr \u003d cb.createQuery(Team.class);"},{"lineNumber":629,"author":{"gitId":"domoberzin"},"content":" Root\u003cTeam\u003e teamRoot \u003d cr.from(Team.class);"},{"lineNumber":630,"author":{"gitId":"domoberzin"},"content":" Join\u003cTeam, Section\u003e sectionJoin \u003d teamRoot.join(\"section\");"},{"lineNumber":631,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":632,"author":{"gitId":"domoberzin"},"content":" cr.select(teamRoot)"},{"lineNumber":633,"author":{"gitId":"domoberzin"},"content":" .where(cb.and("},{"lineNumber":634,"author":{"gitId":"domoberzin"},"content":" cb.equal(sectionJoin.get(\"id\"), section.getId()),"},{"lineNumber":635,"author":{"gitId":"domoberzin"},"content":" cb.equal(teamRoot.get(\"name\"), teamName)));"},{"lineNumber":636,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":637,"author":{"gitId":"domoberzin"},"content":" return HibernateUtil.createQuery(cr).getResultStream().findFirst().orElse(null);"},{"lineNumber":638,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":639,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":640,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":641,"author":{"gitId":"domoberzin"},"content":" * Gets a team by its {@code section} and {@code teamName}."},{"lineNumber":642,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":643,"author":{"gitId":"domoberzin"},"content":" public Team getTeamOrCreate(Section section, String teamName) {"},{"lineNumber":644,"author":{"gitId":"domoberzin"},"content":" assert teamName !\u003d null;"},{"lineNumber":645,"author":{"gitId":"domoberzin"},"content":" assert section !\u003d null;"},{"lineNumber":646,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":647,"author":{"gitId":"domoberzin"},"content":" Team team \u003d getTeam(section, teamName);"},{"lineNumber":648,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":649,"author":{"gitId":"domoberzin"},"content":" if (team \u003d\u003d null) {"},{"lineNumber":650,"author":{"gitId":"domoberzin"},"content":" team \u003d new Team(section, teamName);"},{"lineNumber":651,"author":{"gitId":"domoberzin"},"content":" persist(team);"},{"lineNumber":652,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":653,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":654,"author":{"gitId":"domoberzin"},"content":" return team;"},{"lineNumber":655,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":656,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":657,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":658,"author":{"gitId":"domoberzin"},"content":" * Updates a student."},{"lineNumber":659,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":660,"author":{"gitId":"domoberzin"},"content":" public Student updateStudent(Student student)"},{"lineNumber":661,"author":{"gitId":"domoberzin"},"content":" throws EntityDoesNotExistException, InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":662,"author":{"gitId":"marquestye"},"content":" checkBeforeUpdateStudent(student);"},{"lineNumber":663,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":664,"author":{"gitId":"marquestye"},"content":" return merge(student);"},{"lineNumber":665,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":666,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":667,"author":{"gitId":"marquestye"},"content":" /**"},{"lineNumber":668,"author":{"gitId":"marquestye"},"content":" * Performs checks on student without updating."},{"lineNumber":669,"author":{"gitId":"marquestye"},"content":" */"},{"lineNumber":670,"author":{"gitId":"marquestye"},"content":" public void checkBeforeUpdateStudent(Student student)"},{"lineNumber":671,"author":{"gitId":"marquestye"},"content":" throws EntityDoesNotExistException, InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":672,"author":{"gitId":"domoberzin"},"content":" assert student !\u003d null;"},{"lineNumber":673,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":674,"author":{"gitId":"domoberzin"},"content":" if (!student.isValid()) {"},{"lineNumber":675,"author":{"gitId":"domoberzin"},"content":" throw new InvalidParametersException(student.getInvalidityInfo());"},{"lineNumber":676,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":677,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":678,"author":{"gitId":"domoberzin"},"content":" if (getStudent(student.getId()) \u003d\u003d null) {"},{"lineNumber":679,"author":{"gitId":"domoberzin"},"content":" throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT);"},{"lineNumber":680,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":681,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":682,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":683,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":93,"yuanxi1":30,"marquestye":10,"dishenggg":9,"-":541}},{"path":"src/main/java/teammates/storage/sqlentity/FeedbackQuestion.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlentity;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Objects;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.persistence.CascadeType;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import jakarta.persistence.Column;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import jakarta.persistence.Convert;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.persistence.Entity;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import jakarta.persistence.EnumType;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import jakarta.persistence.Enumerated;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import jakarta.persistence.Id;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import jakarta.persistence.Inheritance;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import jakarta.persistence.InheritanceType;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import jakarta.persistence.JoinColumn;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import jakarta.persistence.ManyToOne;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import jakarta.persistence.OneToMany;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import jakarta.persistence.Table;"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":"import org.hibernate.annotations.UpdateTimestamp;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionDetails;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackConstantSumQuestion;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackContributionQuestion;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackMcqQuestion;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackMsqQuestion;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackNumericalScaleQuestion;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackRankOptionsQuestion;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackRankRecipientsQuestion;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackRubricQuestion;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.questions.FeedbackTextQuestion;"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":39,"author":{"gitId":"-"},"content":" * Represents a feedback question."},{"lineNumber":40,"author":{"gitId":"-"},"content":" */"},{"lineNumber":41,"author":{"gitId":"-"},"content":"@Entity"},{"lineNumber":42,"author":{"gitId":"-"},"content":"@Table(name \u003d \"FeedbackQuestions\")"},{"lineNumber":43,"author":{"gitId":"-"},"content":"@Inheritance(strategy \u003d InheritanceType.SINGLE_TABLE)"},{"lineNumber":44,"author":{"gitId":"-"},"content":"public abstract class FeedbackQuestion extends BaseEntity implements Comparable\u003cFeedbackQuestion\u003e {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" @Id"},{"lineNumber":46,"author":{"gitId":"-"},"content":" private UUID id;"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" @ManyToOne"},{"lineNumber":49,"author":{"gitId":"-"},"content":" @JoinColumn(name \u003d \"sessionId\")"},{"lineNumber":50,"author":{"gitId":"-"},"content":" private FeedbackSession feedbackSession;"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" @OneToMany(mappedBy \u003d \"feedbackQuestion\", cascade \u003d CascadeType.REMOVE)"},{"lineNumber":53,"author":{"gitId":"-"},"content":" private List\u003cFeedbackResponse\u003e feedbackResponses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":56,"author":{"gitId":"-"},"content":" private Integer questionNumber;"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" @Column(nullable \u003d true)"},{"lineNumber":59,"author":{"gitId":"-"},"content":" private String description;"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":62,"author":{"gitId":"-"},"content":" @Enumerated(EnumType.STRING)"},{"lineNumber":63,"author":{"gitId":"-"},"content":" private FeedbackParticipantType giverType;"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":66,"author":{"gitId":"-"},"content":" @Enumerated(EnumType.STRING)"},{"lineNumber":67,"author":{"gitId":"-"},"content":" private FeedbackParticipantType recipientType;"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":70,"author":{"gitId":"-"},"content":" private Integer numOfEntitiesToGiveFeedbackTo;"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":73,"author":{"gitId":"-"},"content":" @Convert(converter \u003d FeedbackParticipantTypeListConverter.class)"},{"lineNumber":74,"author":{"gitId":"-"},"content":" private List\u003cFeedbackParticipantType\u003e showResponsesTo;"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":77,"author":{"gitId":"-"},"content":" @Convert(converter \u003d FeedbackParticipantTypeListConverter.class)"},{"lineNumber":78,"author":{"gitId":"-"},"content":" private List\u003cFeedbackParticipantType\u003e showGiverNameTo;"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":81,"author":{"gitId":"-"},"content":" @Convert(converter \u003d FeedbackParticipantTypeListConverter.class)"},{"lineNumber":82,"author":{"gitId":"-"},"content":" private List\u003cFeedbackParticipantType\u003e showRecipientNameTo;"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" @UpdateTimestamp"},{"lineNumber":85,"author":{"gitId":"-"},"content":" @Column"},{"lineNumber":86,"author":{"gitId":"-"},"content":" private Instant updatedAt;"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" protected FeedbackQuestion() {"},{"lineNumber":89,"author":{"gitId":"-"},"content":" // required by Hibernate"},{"lineNumber":90,"author":{"gitId":"-"},"content":" }"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" public FeedbackQuestion("},{"lineNumber":93,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession, Integer questionNumber,"},{"lineNumber":94,"author":{"gitId":"-"},"content":" String description, FeedbackParticipantType giverType, FeedbackParticipantType recipientType,"},{"lineNumber":95,"author":{"gitId":"-"},"content":" Integer numOfEntitiesToGiveFeedbackTo, List\u003cFeedbackParticipantType\u003e showResponsesTo,"},{"lineNumber":96,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showGiverNameTo, List\u003cFeedbackParticipantType\u003e showRecipientNameTo"},{"lineNumber":97,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" this.setId(UUID.randomUUID());"},{"lineNumber":99,"author":{"gitId":"-"},"content":" this.setFeedbackSession(feedbackSession);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" this.setQuestionNumber(questionNumber);"},{"lineNumber":101,"author":{"gitId":"-"},"content":" this.setDescription(description);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" this.setGiverType(giverType);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" this.setRecipientType(recipientType);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" this.setNumOfEntitiesToGiveFeedbackTo(numOfEntitiesToGiveFeedbackTo);"},{"lineNumber":105,"author":{"gitId":"-"},"content":" this.setShowResponsesTo(showResponsesTo);"},{"lineNumber":106,"author":{"gitId":"-"},"content":" this.setShowGiverNameTo(showGiverNameTo);"},{"lineNumber":107,"author":{"gitId":"-"},"content":" this.setShowRecipientNameTo(showRecipientNameTo);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":111,"author":{"gitId":"-"},"content":" * Gets a copy of the question details of the feedback question."},{"lineNumber":112,"author":{"gitId":"-"},"content":" */"},{"lineNumber":113,"author":{"gitId":"-"},"content":" public abstract FeedbackQuestionDetails getQuestionDetailsCopy();"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":116,"author":{"gitId":"-"},"content":" * Make a copy of the FeedbackQuestion."},{"lineNumber":117,"author":{"gitId":"-"},"content":" */"},{"lineNumber":118,"author":{"gitId":"-"},"content":" public abstract FeedbackQuestion makeDeepCopy(FeedbackSession newFeedbackSession);"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":121,"author":{"gitId":"-"},"content":" * Creates a feedback question according to its {@code FeedbackQuestionType}."},{"lineNumber":122,"author":{"gitId":"-"},"content":" */"},{"lineNumber":123,"author":{"gitId":"-"},"content":" public static FeedbackQuestion makeQuestion("},{"lineNumber":124,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession, Integer questionNumber,"},{"lineNumber":125,"author":{"gitId":"-"},"content":" String description, FeedbackParticipantType giverType, FeedbackParticipantType recipientType,"},{"lineNumber":126,"author":{"gitId":"-"},"content":" Integer numOfEntitiesToGiveFeedbackTo, List\u003cFeedbackParticipantType\u003e showResponsesTo,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showGiverNameTo, List\u003cFeedbackParticipantType\u003e showRecipientNameTo,"},{"lineNumber":128,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails feedbackQuestionDetails"},{"lineNumber":129,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" FeedbackQuestion feedbackQuestion \u003d null;"},{"lineNumber":131,"author":{"gitId":"-"},"content":" switch (feedbackQuestionDetails.getQuestionType()) {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" case TEXT:"},{"lineNumber":133,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d new FeedbackTextQuestion("},{"lineNumber":134,"author":{"gitId":"-"},"content":" feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":135,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo,"},{"lineNumber":136,"author":{"gitId":"-"},"content":" feedbackQuestionDetails"},{"lineNumber":137,"author":{"gitId":"-"},"content":" );"},{"lineNumber":138,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":139,"author":{"gitId":"-"},"content":" case MCQ:"},{"lineNumber":140,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d new FeedbackMcqQuestion("},{"lineNumber":141,"author":{"gitId":"-"},"content":" feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":142,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo,"},{"lineNumber":143,"author":{"gitId":"-"},"content":" feedbackQuestionDetails"},{"lineNumber":144,"author":{"gitId":"-"},"content":" );"},{"lineNumber":145,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":146,"author":{"gitId":"-"},"content":" case MSQ:"},{"lineNumber":147,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d new FeedbackMsqQuestion("},{"lineNumber":148,"author":{"gitId":"-"},"content":" feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":149,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo,"},{"lineNumber":150,"author":{"gitId":"-"},"content":" feedbackQuestionDetails"},{"lineNumber":151,"author":{"gitId":"-"},"content":" );"},{"lineNumber":152,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":153,"author":{"gitId":"-"},"content":" case NUMSCALE:"},{"lineNumber":154,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d new FeedbackNumericalScaleQuestion("},{"lineNumber":155,"author":{"gitId":"-"},"content":" feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":156,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo,"},{"lineNumber":157,"author":{"gitId":"-"},"content":" feedbackQuestionDetails"},{"lineNumber":158,"author":{"gitId":"-"},"content":" );"},{"lineNumber":159,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":160,"author":{"gitId":"-"},"content":" case CONSTSUM:"},{"lineNumber":161,"author":{"gitId":"-"},"content":" case CONSTSUM_OPTIONS:"},{"lineNumber":162,"author":{"gitId":"-"},"content":" case CONSTSUM_RECIPIENTS:"},{"lineNumber":163,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d new FeedbackConstantSumQuestion("},{"lineNumber":164,"author":{"gitId":"-"},"content":" feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":165,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo,"},{"lineNumber":166,"author":{"gitId":"-"},"content":" feedbackQuestionDetails"},{"lineNumber":167,"author":{"gitId":"-"},"content":" );"},{"lineNumber":168,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":169,"author":{"gitId":"-"},"content":" case CONTRIB:"},{"lineNumber":170,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d new FeedbackContributionQuestion("},{"lineNumber":171,"author":{"gitId":"-"},"content":" feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":172,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo,"},{"lineNumber":173,"author":{"gitId":"-"},"content":" feedbackQuestionDetails"},{"lineNumber":174,"author":{"gitId":"-"},"content":" );"},{"lineNumber":175,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":176,"author":{"gitId":"-"},"content":" case RUBRIC:"},{"lineNumber":177,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d new FeedbackRubricQuestion("},{"lineNumber":178,"author":{"gitId":"-"},"content":" feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":179,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo,"},{"lineNumber":180,"author":{"gitId":"-"},"content":" feedbackQuestionDetails"},{"lineNumber":181,"author":{"gitId":"-"},"content":" );"},{"lineNumber":182,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":183,"author":{"gitId":"-"},"content":" case RANK_OPTIONS:"},{"lineNumber":184,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d new FeedbackRankOptionsQuestion("},{"lineNumber":185,"author":{"gitId":"-"},"content":" feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":186,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo,"},{"lineNumber":187,"author":{"gitId":"-"},"content":" feedbackQuestionDetails"},{"lineNumber":188,"author":{"gitId":"-"},"content":" );"},{"lineNumber":189,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":190,"author":{"gitId":"-"},"content":" case RANK_RECIPIENTS:"},{"lineNumber":191,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d new FeedbackRankRecipientsQuestion("},{"lineNumber":192,"author":{"gitId":"-"},"content":" feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":193,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo,"},{"lineNumber":194,"author":{"gitId":"-"},"content":" feedbackQuestionDetails"},{"lineNumber":195,"author":{"gitId":"-"},"content":" );"},{"lineNumber":196,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }"},{"lineNumber":198,"author":{"gitId":"-"},"content":" return feedbackQuestion;"},{"lineNumber":199,"author":{"gitId":"-"},"content":" }"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":202,"author":{"gitId":"-"},"content":" public List\u003cString\u003e getInvalidityInfo() {"},{"lineNumber":203,"author":{"gitId":"-"},"content":" List\u003cString\u003e errors \u003d new ArrayList\u003c\u003e();"},{"lineNumber":204,"author":{"gitId":"-"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" errors.addAll(FieldValidator.getValidityInfoForFeedbackParticipantType(giverType, recipientType));"},{"lineNumber":206,"author":{"gitId":"-"},"content":""},{"lineNumber":207,"author":{"gitId":"-"},"content":" errors.addAll(FieldValidator.getValidityInfoForFeedbackResponseVisibility(showResponsesTo,"},{"lineNumber":208,"author":{"gitId":"-"},"content":" showGiverNameTo,"},{"lineNumber":209,"author":{"gitId":"-"},"content":" showRecipientNameTo));"},{"lineNumber":210,"author":{"gitId":"-"},"content":""},{"lineNumber":211,"author":{"gitId":"-"},"content":" return errors;"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":215,"author":{"gitId":"-"},"content":" * Checks if updating this question to the question will"},{"lineNumber":216,"author":{"gitId":"-"},"content":" * require the responses to be deleted for consistency."},{"lineNumber":217,"author":{"gitId":"-"},"content":" * Does not check if any responses exist."},{"lineNumber":218,"author":{"gitId":"-"},"content":" */"},{"lineNumber":219,"author":{"gitId":"-"},"content":" public boolean areResponseDeletionsRequiredForChanges(FeedbackParticipantType giverType,"},{"lineNumber":220,"author":{"gitId":"-"},"content":" FeedbackParticipantType recipientType,"},{"lineNumber":221,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails questionDetails) {"},{"lineNumber":222,"author":{"gitId":"-"},"content":" if (!giverType.equals(this.giverType)"},{"lineNumber":223,"author":{"gitId":"-"},"content":" || !recipientType.equals(this.recipientType)) {"},{"lineNumber":224,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":225,"author":{"gitId":"-"},"content":" }"},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"-"},"content":" return this.getQuestionDetailsCopy().shouldChangesRequireResponseDeletion(questionDetails);"},{"lineNumber":228,"author":{"gitId":"-"},"content":" }"},{"lineNumber":229,"author":{"gitId":"-"},"content":""},{"lineNumber":230,"author":{"gitId":"-"},"content":" public UUID getId() {"},{"lineNumber":231,"author":{"gitId":"-"},"content":" return id;"},{"lineNumber":232,"author":{"gitId":"-"},"content":" }"},{"lineNumber":233,"author":{"gitId":"-"},"content":""},{"lineNumber":234,"author":{"gitId":"-"},"content":" public void setId(UUID id) {"},{"lineNumber":235,"author":{"gitId":"-"},"content":" this.id \u003d id;"},{"lineNumber":236,"author":{"gitId":"-"},"content":" }"},{"lineNumber":237,"author":{"gitId":"-"},"content":""},{"lineNumber":238,"author":{"gitId":"-"},"content":" public FeedbackSession getFeedbackSession() {"},{"lineNumber":239,"author":{"gitId":"-"},"content":" return feedbackSession;"},{"lineNumber":240,"author":{"gitId":"-"},"content":" }"},{"lineNumber":241,"author":{"gitId":"-"},"content":""},{"lineNumber":242,"author":{"gitId":"xenosf"},"content":" public String getFeedbackSessionName() {"},{"lineNumber":243,"author":{"gitId":"xenosf"},"content":" return feedbackSession.getName();"},{"lineNumber":244,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":245,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" public void setFeedbackSession(FeedbackSession feedbackSession) {"},{"lineNumber":247,"author":{"gitId":"-"},"content":" this.feedbackSession \u003d feedbackSession;"},{"lineNumber":248,"author":{"gitId":"-"},"content":" }"},{"lineNumber":249,"author":{"gitId":"-"},"content":""},{"lineNumber":250,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponse\u003e getFeedbackResponses() {"},{"lineNumber":251,"author":{"gitId":"-"},"content":" return feedbackResponses;"},{"lineNumber":252,"author":{"gitId":"-"},"content":" }"},{"lineNumber":253,"author":{"gitId":"-"},"content":""},{"lineNumber":254,"author":{"gitId":"-"},"content":" public void setFeedbackResponses(List\u003cFeedbackResponse\u003e feedbackResponses) {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" this.feedbackResponses \u003d feedbackResponses;"},{"lineNumber":256,"author":{"gitId":"-"},"content":" }"},{"lineNumber":257,"author":{"gitId":"-"},"content":""},{"lineNumber":258,"author":{"gitId":"-"},"content":" public Integer getQuestionNumber() {"},{"lineNumber":259,"author":{"gitId":"-"},"content":" return questionNumber;"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":""},{"lineNumber":262,"author":{"gitId":"-"},"content":" public void setQuestionNumber(Integer questionNumber) {"},{"lineNumber":263,"author":{"gitId":"-"},"content":" this.questionNumber \u003d questionNumber;"},{"lineNumber":264,"author":{"gitId":"-"},"content":" }"},{"lineNumber":265,"author":{"gitId":"-"},"content":""},{"lineNumber":266,"author":{"gitId":"-"},"content":" public String getDescription() {"},{"lineNumber":267,"author":{"gitId":"-"},"content":" return description;"},{"lineNumber":268,"author":{"gitId":"-"},"content":" }"},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":" public void setDescription(String description) {"},{"lineNumber":271,"author":{"gitId":"-"},"content":" this.description \u003d description;"},{"lineNumber":272,"author":{"gitId":"-"},"content":" }"},{"lineNumber":273,"author":{"gitId":"-"},"content":""},{"lineNumber":274,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":275,"author":{"gitId":"-"},"content":" * Set the question details of the question."},{"lineNumber":276,"author":{"gitId":"-"},"content":" */"},{"lineNumber":277,"author":{"gitId":"-"},"content":" public abstract void setQuestionDetails(FeedbackQuestionDetails questionDetails);"},{"lineNumber":278,"author":{"gitId":"-"},"content":""},{"lineNumber":279,"author":{"gitId":"-"},"content":" public FeedbackParticipantType getGiverType() {"},{"lineNumber":280,"author":{"gitId":"-"},"content":" return giverType;"},{"lineNumber":281,"author":{"gitId":"-"},"content":" }"},{"lineNumber":282,"author":{"gitId":"-"},"content":""},{"lineNumber":283,"author":{"gitId":"-"},"content":" public void setGiverType(FeedbackParticipantType giverType) {"},{"lineNumber":284,"author":{"gitId":"-"},"content":" this.giverType \u003d giverType;"},{"lineNumber":285,"author":{"gitId":"-"},"content":" }"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"-"},"content":" public FeedbackParticipantType getRecipientType() {"},{"lineNumber":288,"author":{"gitId":"-"},"content":" return recipientType;"},{"lineNumber":289,"author":{"gitId":"-"},"content":" }"},{"lineNumber":290,"author":{"gitId":"-"},"content":""},{"lineNumber":291,"author":{"gitId":"-"},"content":" public void setRecipientType(FeedbackParticipantType recipientType) {"},{"lineNumber":292,"author":{"gitId":"-"},"content":" this.recipientType \u003d recipientType;"},{"lineNumber":293,"author":{"gitId":"-"},"content":" }"},{"lineNumber":294,"author":{"gitId":"-"},"content":""},{"lineNumber":295,"author":{"gitId":"-"},"content":" public Integer getNumOfEntitiesToGiveFeedbackTo() {"},{"lineNumber":296,"author":{"gitId":"-"},"content":" return numOfEntitiesToGiveFeedbackTo;"},{"lineNumber":297,"author":{"gitId":"-"},"content":" }"},{"lineNumber":298,"author":{"gitId":"-"},"content":""},{"lineNumber":299,"author":{"gitId":"-"},"content":" public void setNumOfEntitiesToGiveFeedbackTo(Integer numOfEntitiesToGiveFeedbackTo) {"},{"lineNumber":300,"author":{"gitId":"-"},"content":" this.numOfEntitiesToGiveFeedbackTo \u003d numOfEntitiesToGiveFeedbackTo;"},{"lineNumber":301,"author":{"gitId":"-"},"content":" }"},{"lineNumber":302,"author":{"gitId":"-"},"content":""},{"lineNumber":303,"author":{"gitId":"-"},"content":" public List\u003cFeedbackParticipantType\u003e getShowResponsesTo() {"},{"lineNumber":304,"author":{"gitId":"-"},"content":" return showResponsesTo;"},{"lineNumber":305,"author":{"gitId":"-"},"content":" }"},{"lineNumber":306,"author":{"gitId":"-"},"content":""},{"lineNumber":307,"author":{"gitId":"-"},"content":" public void setShowResponsesTo(List\u003cFeedbackParticipantType\u003e showResponsesTo) {"},{"lineNumber":308,"author":{"gitId":"-"},"content":" this.showResponsesTo \u003d showResponsesTo;"},{"lineNumber":309,"author":{"gitId":"-"},"content":" }"},{"lineNumber":310,"author":{"gitId":"-"},"content":""},{"lineNumber":311,"author":{"gitId":"-"},"content":" public List\u003cFeedbackParticipantType\u003e getShowGiverNameTo() {"},{"lineNumber":312,"author":{"gitId":"-"},"content":" return showGiverNameTo;"},{"lineNumber":313,"author":{"gitId":"-"},"content":" }"},{"lineNumber":314,"author":{"gitId":"-"},"content":""},{"lineNumber":315,"author":{"gitId":"-"},"content":" public void setShowGiverNameTo(List\u003cFeedbackParticipantType\u003e showGiverNameTo) {"},{"lineNumber":316,"author":{"gitId":"-"},"content":" this.showGiverNameTo \u003d showGiverNameTo;"},{"lineNumber":317,"author":{"gitId":"-"},"content":" }"},{"lineNumber":318,"author":{"gitId":"-"},"content":""},{"lineNumber":319,"author":{"gitId":"-"},"content":" public List\u003cFeedbackParticipantType\u003e getShowRecipientNameTo() {"},{"lineNumber":320,"author":{"gitId":"-"},"content":" return showRecipientNameTo;"},{"lineNumber":321,"author":{"gitId":"-"},"content":" }"},{"lineNumber":322,"author":{"gitId":"-"},"content":""},{"lineNumber":323,"author":{"gitId":"-"},"content":" public void setShowRecipientNameTo(List\u003cFeedbackParticipantType\u003e showRecipientNameTo) {"},{"lineNumber":324,"author":{"gitId":"-"},"content":" this.showRecipientNameTo \u003d showRecipientNameTo;"},{"lineNumber":325,"author":{"gitId":"-"},"content":" }"},{"lineNumber":326,"author":{"gitId":"-"},"content":""},{"lineNumber":327,"author":{"gitId":"-"},"content":" public Instant getUpdatedAt() {"},{"lineNumber":328,"author":{"gitId":"-"},"content":" return updatedAt;"},{"lineNumber":329,"author":{"gitId":"-"},"content":" }"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" public void setUpdatedAt(Instant updatedAt) {"},{"lineNumber":332,"author":{"gitId":"-"},"content":" this.updatedAt \u003d updatedAt;"},{"lineNumber":333,"author":{"gitId":"-"},"content":" }"},{"lineNumber":334,"author":{"gitId":"-"},"content":""},{"lineNumber":335,"author":{"gitId":"xenosf"},"content":" public Course getCourse() {"},{"lineNumber":336,"author":{"gitId":"xenosf"},"content":" return this.feedbackSession.getCourse();"},{"lineNumber":337,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":338,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":339,"author":{"gitId":"-"},"content":" public String getCourseId() {"},{"lineNumber":340,"author":{"gitId":"-"},"content":" return this.feedbackSession.getCourse().getId();"},{"lineNumber":341,"author":{"gitId":"-"},"content":" }"},{"lineNumber":342,"author":{"gitId":"-"},"content":""},{"lineNumber":343,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":344,"author":{"gitId":"-"},"content":" public String toString() {"},{"lineNumber":345,"author":{"gitId":"-"},"content":" return \"Question [id\u003d\" + id + \", questionNumber\u003d\" + questionNumber + \", description\u003d\" + description"},{"lineNumber":346,"author":{"gitId":"-"},"content":" + \", giverType\u003d\" + giverType + \", recipientType\u003d\" + recipientType"},{"lineNumber":347,"author":{"gitId":"-"},"content":" + \", numOfEntitiesToGiveFeedbackTo\u003d\" + numOfEntitiesToGiveFeedbackTo + \", showResponsesTo\u003d\""},{"lineNumber":348,"author":{"gitId":"-"},"content":" + showResponsesTo + \", showGiverNameTo\u003d\" + showGiverNameTo + \", showRecipientNameTo\u003d\""},{"lineNumber":349,"author":{"gitId":"-"},"content":" + showRecipientNameTo + \", isClosingEmailEnabled\u003d\" + \", createdAt\u003d\" + getCreatedAt() + \", updatedAt\u003d\""},{"lineNumber":350,"author":{"gitId":"-"},"content":" + updatedAt + \"]\";"},{"lineNumber":351,"author":{"gitId":"-"},"content":" }"},{"lineNumber":352,"author":{"gitId":"-"},"content":""},{"lineNumber":353,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":354,"author":{"gitId":"-"},"content":" public int compareTo(FeedbackQuestion o) {"},{"lineNumber":355,"author":{"gitId":"-"},"content":" if (o \u003d\u003d null) {"},{"lineNumber":356,"author":{"gitId":"-"},"content":" return 1;"},{"lineNumber":357,"author":{"gitId":"-"},"content":" }"},{"lineNumber":358,"author":{"gitId":"-"},"content":""},{"lineNumber":359,"author":{"gitId":"-"},"content":" if (!this.questionNumber.equals(o.questionNumber)) {"},{"lineNumber":360,"author":{"gitId":"-"},"content":" return Integer.compare(this.questionNumber, o.questionNumber);"},{"lineNumber":361,"author":{"gitId":"-"},"content":" }"},{"lineNumber":362,"author":{"gitId":"-"},"content":" // Although question numbers ought to be unique in a feedback session,"},{"lineNumber":363,"author":{"gitId":"-"},"content":" // eventual consistency can result in duplicate questions numbers."},{"lineNumber":364,"author":{"gitId":"-"},"content":" // Therefore, to ensure that the question order is always consistent to the user,"},{"lineNumber":365,"author":{"gitId":"-"},"content":" // compare feedbackQuestionId, which is guaranteed to be unique,"},{"lineNumber":366,"author":{"gitId":"-"},"content":" // when the questionNumbers are the same."},{"lineNumber":367,"author":{"gitId":"-"},"content":" return this.id.compareTo(o.id);"},{"lineNumber":368,"author":{"gitId":"-"},"content":" }"},{"lineNumber":369,"author":{"gitId":"-"},"content":""},{"lineNumber":370,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":371,"author":{"gitId":"-"},"content":" public int hashCode() {"},{"lineNumber":372,"author":{"gitId":"-"},"content":" // FeedbackQuestion ID uniquely identifies a FeedbackQuestion."},{"lineNumber":373,"author":{"gitId":"-"},"content":" return this.getId().hashCode();"},{"lineNumber":374,"author":{"gitId":"-"},"content":" }"},{"lineNumber":375,"author":{"gitId":"-"},"content":""},{"lineNumber":376,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":377,"author":{"gitId":"-"},"content":" public boolean equals(Object other) {"},{"lineNumber":378,"author":{"gitId":"-"},"content":" if (other \u003d\u003d null) {"},{"lineNumber":379,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":380,"author":{"gitId":"-"},"content":" } else if (this \u003d\u003d other) {"},{"lineNumber":381,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":382,"author":{"gitId":"-"},"content":" } else if (this.getClass() \u003d\u003d other.getClass()) {"},{"lineNumber":383,"author":{"gitId":"-"},"content":" FeedbackQuestion otherQuestion \u003d (FeedbackQuestion) other;"},{"lineNumber":384,"author":{"gitId":"-"},"content":" return Objects.equals(this.getId(), otherQuestion.getId());"},{"lineNumber":385,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":386,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":387,"author":{"gitId":"-"},"content":" }"},{"lineNumber":388,"author":{"gitId":"-"},"content":" }"},{"lineNumber":389,"author":{"gitId":"-"},"content":""},{"lineNumber":390,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":391,"author":{"gitId":"-"},"content":" * Returns true if the response is visible to the given participant type."},{"lineNumber":392,"author":{"gitId":"-"},"content":" */"},{"lineNumber":393,"author":{"gitId":"-"},"content":" public boolean isResponseVisibleTo(FeedbackParticipantType userType) {"},{"lineNumber":394,"author":{"gitId":"-"},"content":" return showResponsesTo.contains(userType);"},{"lineNumber":395,"author":{"gitId":"-"},"content":" }"},{"lineNumber":396,"author":{"gitId":"-"},"content":"}"},{"lineNumber":397,"author":{"gitId":"-"},"content":""}],"authorContributionMap":{"xenosf":8,"-":389}},{"path":"src/main/java/teammates/storage/sqlentity/FeedbackResponse.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlentity;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Objects;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.persistence.CascadeType;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import jakarta.persistence.Column;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import jakarta.persistence.Entity;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.persistence.Id;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import jakarta.persistence.Inheritance;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import jakarta.persistence.InheritanceType;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import jakarta.persistence.JoinColumn;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import jakarta.persistence.ManyToOne;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import jakarta.persistence.OneToMany;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import jakarta.persistence.Table;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"import org.hibernate.annotations.UpdateTimestamp;"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackResponseDetails;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackConstantSumResponse;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackContributionResponse;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackMcqResponse;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackMsqResponse;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackNumericalScaleResponse;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackRankOptionsResponse;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackRankRecipientsResponse;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackRubricResponse;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.responses.FeedbackTextResponse;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":34,"author":{"gitId":"-"},"content":" * Represents a Feedback Response."},{"lineNumber":35,"author":{"gitId":"-"},"content":" */"},{"lineNumber":36,"author":{"gitId":"-"},"content":"@Entity"},{"lineNumber":37,"author":{"gitId":"-"},"content":"@Table(name \u003d \"FeedbackResponses\")"},{"lineNumber":38,"author":{"gitId":"-"},"content":"@Inheritance(strategy \u003d InheritanceType.SINGLE_TABLE)"},{"lineNumber":39,"author":{"gitId":"-"},"content":"public abstract class FeedbackResponse extends BaseEntity {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" @Id"},{"lineNumber":41,"author":{"gitId":"-"},"content":" private UUID id;"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" @ManyToOne"},{"lineNumber":44,"author":{"gitId":"-"},"content":" @JoinColumn(name \u003d \"questionId\")"},{"lineNumber":45,"author":{"gitId":"-"},"content":" private FeedbackQuestion feedbackQuestion;"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" @OneToMany(mappedBy \u003d \"feedbackResponse\", cascade \u003d CascadeType.REMOVE)"},{"lineNumber":48,"author":{"gitId":"-"},"content":" private List\u003cFeedbackResponseComment\u003e feedbackResponseComments \u003d new ArrayList\u003c\u003e();"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":51,"author":{"gitId":"-"},"content":" private String giver;"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" @ManyToOne"},{"lineNumber":54,"author":{"gitId":"-"},"content":" @JoinColumn(name \u003d \"giverSectionId\")"},{"lineNumber":55,"author":{"gitId":"-"},"content":" private Section giverSection;"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":58,"author":{"gitId":"-"},"content":" private String recipient;"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" @ManyToOne"},{"lineNumber":61,"author":{"gitId":"-"},"content":" @JoinColumn(name \u003d \"recipientSectionId\")"},{"lineNumber":62,"author":{"gitId":"-"},"content":" private Section recipientSection;"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" @UpdateTimestamp"},{"lineNumber":65,"author":{"gitId":"-"},"content":" private Instant updatedAt;"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" protected FeedbackResponse() {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" // required by Hibernate"},{"lineNumber":69,"author":{"gitId":"-"},"content":" }"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" public FeedbackResponse("},{"lineNumber":72,"author":{"gitId":"-"},"content":" FeedbackQuestion feedbackQuestion, String giver,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" Section giverSection, String recipient, Section recipientSection"},{"lineNumber":74,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" this.setId(UUID.randomUUID());"},{"lineNumber":76,"author":{"gitId":"-"},"content":" this.setFeedbackQuestion(feedbackQuestion);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" this.setGiver(giver);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" this.setGiverSection(giverSection);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" this.setRecipient(recipient);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" this.setRecipientSection(recipientSection);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":84,"author":{"gitId":"-"},"content":" * Creates a feedback response according to its {@code FeedbackQuestionType}."},{"lineNumber":85,"author":{"gitId":"-"},"content":" */"},{"lineNumber":86,"author":{"gitId":"-"},"content":" public static FeedbackResponse makeResponse("},{"lineNumber":87,"author":{"gitId":"-"},"content":" FeedbackQuestion feedbackQuestion, String giver,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" Section giverSection, String receiver, Section receiverSection,"},{"lineNumber":89,"author":{"gitId":"-"},"content":" FeedbackResponseDetails responseDetails"},{"lineNumber":90,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" FeedbackResponse feedbackResponse \u003d null;"},{"lineNumber":92,"author":{"gitId":"-"},"content":" switch (responseDetails.getQuestionType()) {"},{"lineNumber":93,"author":{"gitId":"-"},"content":" case TEXT:"},{"lineNumber":94,"author":{"gitId":"-"},"content":" feedbackResponse \u003d new FeedbackTextResponse("},{"lineNumber":95,"author":{"gitId":"-"},"content":" feedbackQuestion, giver, giverSection, receiver, receiverSection, responseDetails"},{"lineNumber":96,"author":{"gitId":"-"},"content":" );"},{"lineNumber":97,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":98,"author":{"gitId":"-"},"content":" case MCQ:"},{"lineNumber":99,"author":{"gitId":"-"},"content":" feedbackResponse \u003d new FeedbackMcqResponse("},{"lineNumber":100,"author":{"gitId":"-"},"content":" feedbackQuestion, giver, giverSection, receiver, receiverSection, responseDetails"},{"lineNumber":101,"author":{"gitId":"-"},"content":" );"},{"lineNumber":102,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":103,"author":{"gitId":"-"},"content":" case MSQ:"},{"lineNumber":104,"author":{"gitId":"-"},"content":" feedbackResponse \u003d new FeedbackMsqResponse("},{"lineNumber":105,"author":{"gitId":"-"},"content":" feedbackQuestion, giver, giverSection, receiver, receiverSection, responseDetails"},{"lineNumber":106,"author":{"gitId":"-"},"content":" );"},{"lineNumber":107,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":108,"author":{"gitId":"-"},"content":" case NUMSCALE:"},{"lineNumber":109,"author":{"gitId":"-"},"content":" feedbackResponse \u003d new FeedbackNumericalScaleResponse("},{"lineNumber":110,"author":{"gitId":"-"},"content":" feedbackQuestion, giver, giverSection, receiver, receiverSection, responseDetails"},{"lineNumber":111,"author":{"gitId":"-"},"content":" );"},{"lineNumber":112,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":113,"author":{"gitId":"-"},"content":" case CONSTSUM:"},{"lineNumber":114,"author":{"gitId":"-"},"content":" case CONSTSUM_OPTIONS:"},{"lineNumber":115,"author":{"gitId":"-"},"content":" case CONSTSUM_RECIPIENTS:"},{"lineNumber":116,"author":{"gitId":"-"},"content":" feedbackResponse \u003d new FeedbackConstantSumResponse("},{"lineNumber":117,"author":{"gitId":"-"},"content":" feedbackQuestion, giver, giverSection, receiver, receiverSection, responseDetails"},{"lineNumber":118,"author":{"gitId":"-"},"content":" );"},{"lineNumber":119,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":120,"author":{"gitId":"-"},"content":" case CONTRIB:"},{"lineNumber":121,"author":{"gitId":"-"},"content":" feedbackResponse \u003d new FeedbackContributionResponse("},{"lineNumber":122,"author":{"gitId":"-"},"content":" feedbackQuestion, giver, giverSection, receiver, receiverSection, responseDetails"},{"lineNumber":123,"author":{"gitId":"-"},"content":" );"},{"lineNumber":124,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":125,"author":{"gitId":"-"},"content":" case RUBRIC:"},{"lineNumber":126,"author":{"gitId":"-"},"content":" feedbackResponse \u003d new FeedbackRubricResponse("},{"lineNumber":127,"author":{"gitId":"-"},"content":" feedbackQuestion, giver, giverSection, receiver, receiverSection, responseDetails"},{"lineNumber":128,"author":{"gitId":"-"},"content":" );"},{"lineNumber":129,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":130,"author":{"gitId":"-"},"content":" case RANK_OPTIONS:"},{"lineNumber":131,"author":{"gitId":"-"},"content":" feedbackResponse \u003d new FeedbackRankOptionsResponse("},{"lineNumber":132,"author":{"gitId":"-"},"content":" feedbackQuestion, giver, giverSection, receiver, receiverSection, responseDetails"},{"lineNumber":133,"author":{"gitId":"-"},"content":" );"},{"lineNumber":134,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":135,"author":{"gitId":"-"},"content":" case RANK_RECIPIENTS:"},{"lineNumber":136,"author":{"gitId":"-"},"content":" feedbackResponse \u003d new FeedbackRankRecipientsResponse("},{"lineNumber":137,"author":{"gitId":"-"},"content":" feedbackQuestion, giver, giverSection, receiver, receiverSection, responseDetails"},{"lineNumber":138,"author":{"gitId":"-"},"content":" );"},{"lineNumber":139,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":" return feedbackResponse;"},{"lineNumber":142,"author":{"gitId":"-"},"content":" }"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":145,"author":{"gitId":"-"},"content":" * Update a feedback response according to its {@code FeedbackQuestionType}."},{"lineNumber":146,"author":{"gitId":"-"},"content":" */"},{"lineNumber":147,"author":{"gitId":"-"},"content":" public static FeedbackResponse updateResponse("},{"lineNumber":148,"author":{"gitId":"-"},"content":" FeedbackResponse originalFeedbackResponse,"},{"lineNumber":149,"author":{"gitId":"-"},"content":" FeedbackQuestion feedbackQuestion, String giver,"},{"lineNumber":150,"author":{"gitId":"-"},"content":" Section giverSection, String receiver, Section receiverSection,"},{"lineNumber":151,"author":{"gitId":"-"},"content":" FeedbackResponseDetails responseDetails"},{"lineNumber":152,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" FeedbackResponse updatedFeedbackResponse \u003d makeResponse("},{"lineNumber":154,"author":{"gitId":"-"},"content":" feedbackQuestion,"},{"lineNumber":155,"author":{"gitId":"-"},"content":" giver,"},{"lineNumber":156,"author":{"gitId":"-"},"content":" giverSection,"},{"lineNumber":157,"author":{"gitId":"-"},"content":" receiver,"},{"lineNumber":158,"author":{"gitId":"-"},"content":" receiverSection,"},{"lineNumber":159,"author":{"gitId":"-"},"content":" responseDetails"},{"lineNumber":160,"author":{"gitId":"-"},"content":" );"},{"lineNumber":161,"author":{"gitId":"-"},"content":" updatedFeedbackResponse.setCreatedAt(originalFeedbackResponse.getCreatedAt());"},{"lineNumber":162,"author":{"gitId":"-"},"content":" updatedFeedbackResponse.setId(originalFeedbackResponse.getId());"},{"lineNumber":163,"author":{"gitId":"-"},"content":" return updatedFeedbackResponse;"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":167,"author":{"gitId":"-"},"content":" * Gets a copy of the question details of the feedback question."},{"lineNumber":168,"author":{"gitId":"-"},"content":" */"},{"lineNumber":169,"author":{"gitId":"-"},"content":" public abstract FeedbackResponseDetails getFeedbackResponseDetailsCopy();"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" public UUID getId() {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" return id;"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" public void setId(UUID id) {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" this.id \u003d id;"},{"lineNumber":177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" public FeedbackQuestion getFeedbackQuestion() {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" return feedbackQuestion;"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" public void setFeedbackQuestion(FeedbackQuestion feedbackQuestion) {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" this.feedbackQuestion \u003d feedbackQuestion;"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" public List\u003cFeedbackResponseComment\u003e getFeedbackResponseComments() {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" return feedbackResponseComments;"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" public void setFeedbackResponseComments(List\u003cFeedbackResponseComment\u003e feedbackResponseComments) {"},{"lineNumber":192,"author":{"gitId":"-"},"content":" this.feedbackResponseComments \u003d feedbackResponseComments;"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"-"},"content":" public String getGiver() {"},{"lineNumber":196,"author":{"gitId":"-"},"content":" return giver;"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" public void setGiver(String giver) {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" this.giver \u003d giver;"},{"lineNumber":201,"author":{"gitId":"-"},"content":" }"},{"lineNumber":202,"author":{"gitId":"-"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":" public Section getGiverSection() {"},{"lineNumber":204,"author":{"gitId":"-"},"content":" return giverSection;"},{"lineNumber":205,"author":{"gitId":"-"},"content":" }"},{"lineNumber":206,"author":{"gitId":"-"},"content":""},{"lineNumber":207,"author":{"gitId":"xenosf"},"content":" public String getGiverSectionName() {"},{"lineNumber":208,"author":{"gitId":"xenosf"},"content":" return giverSection.getName();"},{"lineNumber":209,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":210,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":211,"author":{"gitId":"-"},"content":" public void setGiverSection(Section giverSection) {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" this.giverSection \u003d giverSection;"},{"lineNumber":213,"author":{"gitId":"-"},"content":" }"},{"lineNumber":214,"author":{"gitId":"-"},"content":""},{"lineNumber":215,"author":{"gitId":"-"},"content":" public String getRecipient() {"},{"lineNumber":216,"author":{"gitId":"-"},"content":" return recipient;"},{"lineNumber":217,"author":{"gitId":"-"},"content":" }"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":" public void setRecipient(String recipient) {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" this.recipient \u003d recipient;"},{"lineNumber":221,"author":{"gitId":"-"},"content":" }"},{"lineNumber":222,"author":{"gitId":"-"},"content":""},{"lineNumber":223,"author":{"gitId":"-"},"content":" public Section getRecipientSection() {"},{"lineNumber":224,"author":{"gitId":"-"},"content":" return recipientSection;"},{"lineNumber":225,"author":{"gitId":"-"},"content":" }"},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"xenosf"},"content":" public String getRecipientSectionName() {"},{"lineNumber":228,"author":{"gitId":"xenosf"},"content":" return recipientSection.getName();"},{"lineNumber":229,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":230,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":231,"author":{"gitId":"-"},"content":" public void setRecipientSection(Section recipientSection) {"},{"lineNumber":232,"author":{"gitId":"-"},"content":" this.recipientSection \u003d recipientSection;"},{"lineNumber":233,"author":{"gitId":"-"},"content":" }"},{"lineNumber":234,"author":{"gitId":"-"},"content":""},{"lineNumber":235,"author":{"gitId":"-"},"content":" public Instant getUpdatedAt() {"},{"lineNumber":236,"author":{"gitId":"-"},"content":" return updatedAt;"},{"lineNumber":237,"author":{"gitId":"-"},"content":" }"},{"lineNumber":238,"author":{"gitId":"-"},"content":""},{"lineNumber":239,"author":{"gitId":"-"},"content":" public void setUpdatedAt(Instant updatedAt) {"},{"lineNumber":240,"author":{"gitId":"-"},"content":" this.updatedAt \u003d updatedAt;"},{"lineNumber":241,"author":{"gitId":"-"},"content":" }"},{"lineNumber":242,"author":{"gitId":"-"},"content":""},{"lineNumber":243,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":244,"author":{"gitId":"-"},"content":" public List\u003cString\u003e getInvalidityInfo() {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" return new ArrayList\u003c\u003e();"},{"lineNumber":246,"author":{"gitId":"-"},"content":" }"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":249,"author":{"gitId":"-"},"content":" public String toString() {"},{"lineNumber":250,"author":{"gitId":"-"},"content":" return \"FeedbackResponse [id\u003d\" + id + \", giver\u003d\" + giver + \", recipient\u003d\" + recipient"},{"lineNumber":251,"author":{"gitId":"-"},"content":" + \", createdAt\u003d\" + getCreatedAt() + \", updatedAt\u003d\" + updatedAt + \"]\";"},{"lineNumber":252,"author":{"gitId":"-"},"content":" }"},{"lineNumber":253,"author":{"gitId":"-"},"content":""},{"lineNumber":254,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":255,"author":{"gitId":"-"},"content":" public int hashCode() {"},{"lineNumber":256,"author":{"gitId":"-"},"content":" return this.getId().hashCode();"},{"lineNumber":257,"author":{"gitId":"-"},"content":" }"},{"lineNumber":258,"author":{"gitId":"-"},"content":""},{"lineNumber":259,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":260,"author":{"gitId":"-"},"content":" public boolean equals(Object other) {"},{"lineNumber":261,"author":{"gitId":"-"},"content":" if (other \u003d\u003d null) {"},{"lineNumber":262,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":263,"author":{"gitId":"-"},"content":" } else if (this \u003d\u003d other) {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":265,"author":{"gitId":"-"},"content":" } else if (this.getClass() \u003d\u003d other.getClass()) {"},{"lineNumber":266,"author":{"gitId":"-"},"content":" FeedbackResponse otherResponse \u003d (FeedbackResponse) other;"},{"lineNumber":267,"author":{"gitId":"-"},"content":" return Objects.equals(this.getId(), otherResponse.getId());"},{"lineNumber":268,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":" }"},{"lineNumber":272,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":8,"-":264}},{"path":"src/main/java/teammates/storage/sqlentity/FeedbackResponseComment.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlentity;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Objects;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import jakarta.persistence.Column;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.persistence.Convert;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import jakarta.persistence.Entity;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import jakarta.persistence.GeneratedValue;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.persistence.Id;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import jakarta.persistence.JoinColumn;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import jakarta.persistence.ManyToOne;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import jakarta.persistence.Table;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"import org.hibernate.annotations.OnDelete;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import org.hibernate.annotations.OnDeleteAction;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import org.hibernate.annotations.UpdateTimestamp;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"-"},"content":" * Represents a feedback response comment."},{"lineNumber":27,"author":{"gitId":"-"},"content":" */"},{"lineNumber":28,"author":{"gitId":"-"},"content":"@Entity"},{"lineNumber":29,"author":{"gitId":"-"},"content":"@Table(name \u003d \"FeedbackResponseComments\")"},{"lineNumber":30,"author":{"gitId":"-"},"content":"public class FeedbackResponseComment extends BaseEntity {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" @Id"},{"lineNumber":32,"author":{"gitId":"-"},"content":" @GeneratedValue"},{"lineNumber":33,"author":{"gitId":"-"},"content":" private Long id;"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" @ManyToOne"},{"lineNumber":36,"author":{"gitId":"-"},"content":" @OnDelete(action \u003d OnDeleteAction.CASCADE)"},{"lineNumber":37,"author":{"gitId":"-"},"content":" @JoinColumn(name \u003d \"responseId\")"},{"lineNumber":38,"author":{"gitId":"-"},"content":" private FeedbackResponse feedbackResponse;"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":41,"author":{"gitId":"-"},"content":" private String giver;"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":44,"author":{"gitId":"-"},"content":" @Convert(converter \u003d FeedbackParticipantTypeConverter.class)"},{"lineNumber":45,"author":{"gitId":"-"},"content":" private FeedbackParticipantType giverType;"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" @ManyToOne"},{"lineNumber":48,"author":{"gitId":"-"},"content":" @JoinColumn(name \u003d \"giverSectionId\")"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private Section giverSection;"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" @ManyToOne"},{"lineNumber":52,"author":{"gitId":"-"},"content":" @JoinColumn(name \u003d \"recipientSectionId\")"},{"lineNumber":53,"author":{"gitId":"-"},"content":" private Section recipientSection;"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":56,"author":{"gitId":"-"},"content":" private String commentText;"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":59,"author":{"gitId":"-"},"content":" private boolean isVisibilityFollowingFeedbackQuestion;"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":62,"author":{"gitId":"-"},"content":" private boolean isCommentFromFeedbackParticipant;"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":65,"author":{"gitId":"-"},"content":" @Convert(converter \u003d FeedbackParticipantTypeListConverter.class)"},{"lineNumber":66,"author":{"gitId":"-"},"content":" private List\u003cFeedbackParticipantType\u003e showCommentTo;"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":69,"author":{"gitId":"-"},"content":" @Convert(converter \u003d FeedbackParticipantTypeListConverter.class)"},{"lineNumber":70,"author":{"gitId":"-"},"content":" private List\u003cFeedbackParticipantType\u003e showGiverNameTo;"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" @UpdateTimestamp"},{"lineNumber":73,"author":{"gitId":"-"},"content":" private Instant updatedAt;"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":76,"author":{"gitId":"-"},"content":" private String lastEditorEmail;"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" protected FeedbackResponseComment() {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" // required by Hibernate"},{"lineNumber":80,"author":{"gitId":"-"},"content":" }"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" public FeedbackResponseComment("},{"lineNumber":83,"author":{"gitId":"-"},"content":" FeedbackResponse feedbackResponse, String giver, FeedbackParticipantType giverType,"},{"lineNumber":84,"author":{"gitId":"-"},"content":" Section giverSection, Section recipientSection, String commentText,"},{"lineNumber":85,"author":{"gitId":"-"},"content":" boolean isVisibilityFollowingFeedbackQuestion, boolean isCommentFromFeedbackParticipant,"},{"lineNumber":86,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showCommentTo, List\u003cFeedbackParticipantType\u003e showGiverNameTo,"},{"lineNumber":87,"author":{"gitId":"-"},"content":" String lastEditorEmail"},{"lineNumber":88,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":89,"author":{"gitId":"-"},"content":" this.setFeedbackResponse(feedbackResponse);"},{"lineNumber":90,"author":{"gitId":"-"},"content":" this.setGiver(giver);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" this.setGiverType(giverType);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" this.setGiverSection(giverSection);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" this.setRecipientSection(recipientSection);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" this.setCommentText(commentText);"},{"lineNumber":95,"author":{"gitId":"-"},"content":" this.setIsVisibilityFollowingFeedbackQuestion(isVisibilityFollowingFeedbackQuestion);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" this.setIsCommentFromFeedbackParticipant(isCommentFromFeedbackParticipant);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" this.setShowCommentTo(showCommentTo);"},{"lineNumber":98,"author":{"gitId":"-"},"content":" this.setShowGiverNameTo(showGiverNameTo);"},{"lineNumber":99,"author":{"gitId":"-"},"content":" this.setLastEditorEmail(lastEditorEmail);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" public Long getId() {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" return id;"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" public void setId(Long id) {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" this.id \u003d id;"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" public FeedbackResponse getFeedbackResponse() {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" return feedbackResponse;"},{"lineNumber":112,"author":{"gitId":"-"},"content":" }"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" public void setFeedbackResponse(FeedbackResponse feedbackResponse) {"},{"lineNumber":115,"author":{"gitId":"-"},"content":" this.feedbackResponse \u003d feedbackResponse;"},{"lineNumber":116,"author":{"gitId":"-"},"content":" }"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" public String getGiver() {"},{"lineNumber":119,"author":{"gitId":"-"},"content":" return giver;"},{"lineNumber":120,"author":{"gitId":"-"},"content":" }"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" public void setGiver(String giver) {"},{"lineNumber":123,"author":{"gitId":"-"},"content":" this.giver \u003d giver;"},{"lineNumber":124,"author":{"gitId":"-"},"content":" }"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" public FeedbackParticipantType getGiverType() {"},{"lineNumber":127,"author":{"gitId":"-"},"content":" return giverType;"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" public void setGiverType(FeedbackParticipantType giverType) {"},{"lineNumber":131,"author":{"gitId":"-"},"content":" this.giverType \u003d giverType;"},{"lineNumber":132,"author":{"gitId":"-"},"content":" }"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" public Section getGiverSection() {"},{"lineNumber":135,"author":{"gitId":"-"},"content":" return giverSection;"},{"lineNumber":136,"author":{"gitId":"-"},"content":" }"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" public void setGiverSection(Section giverSection) {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" this.giverSection \u003d giverSection;"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" public Section getRecipientSection() {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" return recipientSection;"},{"lineNumber":144,"author":{"gitId":"-"},"content":" }"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" public void setRecipientSection(Section recipientSection) {"},{"lineNumber":147,"author":{"gitId":"-"},"content":" this.recipientSection \u003d recipientSection;"},{"lineNumber":148,"author":{"gitId":"-"},"content":" }"},{"lineNumber":149,"author":{"gitId":"-"},"content":""},{"lineNumber":150,"author":{"gitId":"-"},"content":" public String getCommentText() {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" return commentText;"},{"lineNumber":152,"author":{"gitId":"-"},"content":" }"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"-"},"content":" public void setCommentText(String commentText) {"},{"lineNumber":155,"author":{"gitId":"-"},"content":" this.commentText \u003d commentText;"},{"lineNumber":156,"author":{"gitId":"-"},"content":" }"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"-"},"content":" public boolean getIsVisibilityFollowingFeedbackQuestion() {"},{"lineNumber":159,"author":{"gitId":"-"},"content":" return this.isVisibilityFollowingFeedbackQuestion;"},{"lineNumber":160,"author":{"gitId":"-"},"content":" }"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"-"},"content":" public void setIsVisibilityFollowingFeedbackQuestion(boolean isVisibilityFollowingFeedbackQuestion) {"},{"lineNumber":163,"author":{"gitId":"-"},"content":" this.isVisibilityFollowingFeedbackQuestion \u003d isVisibilityFollowingFeedbackQuestion;"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" public boolean getIsCommentFromFeedbackParticipant() {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" return this.isCommentFromFeedbackParticipant;"},{"lineNumber":168,"author":{"gitId":"-"},"content":" }"},{"lineNumber":169,"author":{"gitId":"-"},"content":""},{"lineNumber":170,"author":{"gitId":"-"},"content":" public void setIsCommentFromFeedbackParticipant(boolean isCommentFromFeedbackParticipant) {"},{"lineNumber":171,"author":{"gitId":"-"},"content":" this.isCommentFromFeedbackParticipant \u003d isCommentFromFeedbackParticipant;"},{"lineNumber":172,"author":{"gitId":"-"},"content":" }"},{"lineNumber":173,"author":{"gitId":"-"},"content":""},{"lineNumber":174,"author":{"gitId":"-"},"content":" public List\u003cFeedbackParticipantType\u003e getShowCommentTo() {"},{"lineNumber":175,"author":{"gitId":"-"},"content":" return showCommentTo;"},{"lineNumber":176,"author":{"gitId":"-"},"content":" }"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" public void setShowCommentTo(List\u003cFeedbackParticipantType\u003e showCommentTo) {"},{"lineNumber":179,"author":{"gitId":"-"},"content":" this.showCommentTo \u003d showCommentTo;"},{"lineNumber":180,"author":{"gitId":"-"},"content":" }"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" public List\u003cFeedbackParticipantType\u003e getShowGiverNameTo() {"},{"lineNumber":183,"author":{"gitId":"-"},"content":" return showGiverNameTo;"},{"lineNumber":184,"author":{"gitId":"-"},"content":" }"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" public void setShowGiverNameTo(List\u003cFeedbackParticipantType\u003e showGiverNameTo) {"},{"lineNumber":187,"author":{"gitId":"-"},"content":" this.showGiverNameTo \u003d showGiverNameTo;"},{"lineNumber":188,"author":{"gitId":"-"},"content":" }"},{"lineNumber":189,"author":{"gitId":"-"},"content":""},{"lineNumber":190,"author":{"gitId":"-"},"content":" public Instant getUpdatedAt() {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" return updatedAt;"},{"lineNumber":192,"author":{"gitId":"-"},"content":" }"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"-"},"content":" public void setUpdatedAt(Instant updatedAt) {"},{"lineNumber":195,"author":{"gitId":"-"},"content":" this.updatedAt \u003d updatedAt;"},{"lineNumber":196,"author":{"gitId":"-"},"content":" }"},{"lineNumber":197,"author":{"gitId":"-"},"content":""},{"lineNumber":198,"author":{"gitId":"-"},"content":" public String getLastEditorEmail() {"},{"lineNumber":199,"author":{"gitId":"-"},"content":" return lastEditorEmail;"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }"},{"lineNumber":201,"author":{"gitId":"-"},"content":""},{"lineNumber":202,"author":{"gitId":"-"},"content":" public void setLastEditorEmail(String lastEditorEmail) {"},{"lineNumber":203,"author":{"gitId":"-"},"content":" this.lastEditorEmail \u003d lastEditorEmail;"},{"lineNumber":204,"author":{"gitId":"-"},"content":" }"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":207,"author":{"gitId":"-"},"content":" * Formats the entity before persisting in database."},{"lineNumber":208,"author":{"gitId":"-"},"content":" * TODO: Override when BaseEntity adds abstract sanitizeForSaving"},{"lineNumber":209,"author":{"gitId":"-"},"content":" */"},{"lineNumber":210,"author":{"gitId":"-"},"content":" public void sanitizeForSaving() {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" this.commentText \u003d SanitizationHelper.sanitizeForRichText(this.commentText);"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" * Returns true if the response comment is visible to the given participant type."},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":217,"author":{"gitId":"xenosf"},"content":" public boolean checkIsVisibleTo(FeedbackParticipantType viewerType) {"},{"lineNumber":218,"author":{"gitId":"xenosf"},"content":" return showCommentTo.contains(viewerType);"},{"lineNumber":219,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":220,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":221,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":222,"author":{"gitId":"-"},"content":" public List\u003cString\u003e getInvalidityInfo() {"},{"lineNumber":223,"author":{"gitId":"-"},"content":" List\u003cString\u003e errors \u003d new ArrayList\u003c\u003e();"},{"lineNumber":224,"author":{"gitId":"-"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForCommentGiverType(giverType), errors);"},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForVisibilityOfFeedbackParticipantComments("},{"lineNumber":228,"author":{"gitId":"-"},"content":" isCommentFromFeedbackParticipant, isVisibilityFollowingFeedbackQuestion), errors);"},{"lineNumber":229,"author":{"gitId":"-"},"content":""},{"lineNumber":230,"author":{"gitId":"-"},"content":" return errors;"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":234,"author":{"gitId":"-"},"content":" public String toString() {"},{"lineNumber":235,"author":{"gitId":"-"},"content":" return \"FeedbackResponse [id\u003d\" + id + \", giver\u003d\" + giver + \", commentText\u003d\" + commentText"},{"lineNumber":236,"author":{"gitId":"-"},"content":" + \", isVisibilityFollowingFeedbackQuestion\u003d\" + isVisibilityFollowingFeedbackQuestion"},{"lineNumber":237,"author":{"gitId":"-"},"content":" + \", isCommentFromFeedbackParticipant\u003d\" + isCommentFromFeedbackParticipant"},{"lineNumber":238,"author":{"gitId":"-"},"content":" + \", lastEditorEmail\u003d\" + lastEditorEmail + \", createdAt\u003d\" + getCreatedAt()"},{"lineNumber":239,"author":{"gitId":"-"},"content":" + \", updatedAt\u003d\" + updatedAt + \"]\";"},{"lineNumber":240,"author":{"gitId":"-"},"content":" }"},{"lineNumber":241,"author":{"gitId":"-"},"content":""},{"lineNumber":242,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":243,"author":{"gitId":"-"},"content":" public int hashCode() {"},{"lineNumber":244,"author":{"gitId":"-"},"content":" return this.getId().hashCode();"},{"lineNumber":245,"author":{"gitId":"-"},"content":" }"},{"lineNumber":246,"author":{"gitId":"-"},"content":""},{"lineNumber":247,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":248,"author":{"gitId":"-"},"content":" public boolean equals(Object other) {"},{"lineNumber":249,"author":{"gitId":"-"},"content":" if (other \u003d\u003d null) {"},{"lineNumber":250,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":251,"author":{"gitId":"-"},"content":" } else if (this \u003d\u003d other) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":253,"author":{"gitId":"-"},"content":" } else if (this.getClass() \u003d\u003d other.getClass()) {"},{"lineNumber":254,"author":{"gitId":"-"},"content":" FeedbackResponseComment otherResponse \u003d (FeedbackResponseComment) other;"},{"lineNumber":255,"author":{"gitId":"-"},"content":" return Objects.equals(this.getId(), otherResponse.getId());"},{"lineNumber":256,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":257,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":258,"author":{"gitId":"-"},"content":" }"},{"lineNumber":259,"author":{"gitId":"-"},"content":" }"},{"lineNumber":260,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":7,"-":253}},{"path":"src/main/java/teammates/storage/sqlentity/FeedbackSessionLog.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.storage.sqlentity;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import java.util.Objects;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.Column;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.Entity;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.EnumType;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.Enumerated;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.Id;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.JoinColumn;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.ManyToOne;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"import jakarta.persistence.Table;"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"import org.hibernate.annotations.NotFound;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import org.hibernate.annotations.NotFoundAction;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import org.hibernate.annotations.OnDelete;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import org.hibernate.annotations.OnDeleteAction;"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" * Represents a feedback session log."},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":"@Entity"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":"@Table(name \u003d \"FeedbackSessionLogs\")"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":"public class FeedbackSessionLog extends BaseEntity {"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" @Id"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" private UUID id;"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" @ManyToOne"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" @JoinColumn(name \u003d \"studentId\")"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" @NotFound(action \u003d NotFoundAction.IGNORE)"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" @OnDelete(action \u003d OnDeleteAction.CASCADE)"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" private Student student;"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" @ManyToOne"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" @JoinColumn(name \u003d \"sessionId\")"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" @NotFound(action \u003d NotFoundAction.IGNORE)"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" @OnDelete(action \u003d OnDeleteAction.CASCADE)"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" private FeedbackSession feedbackSession;"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" @Column(nullable \u003d false)"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" @Enumerated(EnumType.STRING)"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" private FeedbackSessionLogType feedbackSessionLogType;"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" @Column(nullable \u003d false)"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" private Instant timestamp;"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" protected FeedbackSessionLog() {"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" // required by Hibernate"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" public FeedbackSessionLog(Student student, FeedbackSession feedbackSession,"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType feedbackSessionLogType, Instant timestamp) {"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" this.setId(UUID.randomUUID());"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" this.student \u003d student;"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" this.feedbackSession \u003d feedbackSession;"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionLogType \u003d feedbackSessionLogType;"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" this.timestamp \u003d timestamp;"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" public UUID getId() {"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" return id;"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" public void setId(UUID id) {"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" this.id \u003d id;"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" public Student getStudent() {"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" return student;"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" public void setStudent(Student student) {"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" this.student \u003d student;"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" public FeedbackSession getFeedbackSession() {"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" return feedbackSession;"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":" public void setFeedbackSession(FeedbackSession feedbackSession) {"},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" this.feedbackSession \u003d feedbackSession;"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" public FeedbackSessionLogType getFeedbackSessionLogType() {"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":" return feedbackSessionLogType;"},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" public void setFeedbackSessionLogType(FeedbackSessionLogType feedbackSessionLogType) {"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionLogType \u003d feedbackSessionLogType;"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" public Instant getTimestamp() {"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" return timestamp;"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" public void setTimestamp(Instant timestamp) {"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":" this.timestamp \u003d timestamp;"},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":" public String toString() {"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" return \"FeedbackSessionLog [id\u003d\" + id + \", student\u003d\" + student + \", feedbackSession\u003d\" + feedbackSession"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":" + \", feedbackSessionLogType\u003d\" + feedbackSessionLogType.getLabel() + \", timestamp\u003d\" + timestamp + \"]\";"},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" public int hashCode() {"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":" return this.getId().hashCode();"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" public boolean equals(Object other) {"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" if (other \u003d\u003d null) {"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" return false;"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" } else if (this \u003d\u003d other) {"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" return true;"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" } else if (this.getClass() \u003d\u003d other.getClass()) {"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog otherFeedbackSessionLog \u003d (FeedbackSessionLog) other;"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" return Objects.equals(this.getId(), otherFeedbackSessionLog.getId());"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" return false;"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" public List\u003cString\u003e getInvalidityInfo() {"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" return new ArrayList\u003c\u003e();"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":128,"-":7}},{"path":"src/main/java/teammates/storage/sqlentity/Student.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlentity;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import jakarta.persistence.Column;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import jakarta.persistence.Entity;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import jakarta.persistence.Table;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * Represents a Student."},{"lineNumber":17,"author":{"gitId":"-"},"content":" */"},{"lineNumber":18,"author":{"gitId":"-"},"content":"@Entity"},{"lineNumber":19,"author":{"gitId":"-"},"content":"@Table(name \u003d \"Students\")"},{"lineNumber":20,"author":{"gitId":"-"},"content":"public class Student extends User {"},{"lineNumber":21,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false)"},{"lineNumber":22,"author":{"gitId":"-"},"content":" private String comments;"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" protected Student() {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" // required by Hibernate"},{"lineNumber":26,"author":{"gitId":"-"},"content":" }"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" public Student(Course course, String name, String email, String comments) {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" super(course, name, email);"},{"lineNumber":30,"author":{"gitId":"-"},"content":" this.setComments(comments);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" }"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" public Student(Course course, String name, String email, String comments, Team team) {"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" super(course, name, email);"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" this.setComments(comments);"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" this.setTeam(team);"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" * Gets the comments of the student."},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":42,"author":{"gitId":"-"},"content":" public String getComments() {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" return comments;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" }"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" * Sets the comments of the student."},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":49,"author":{"gitId":"-"},"content":" public void setComments(String comments) {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" this.comments \u003d SanitizationHelper.sanitizeTextField(comments);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" }"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":54,"author":{"gitId":"-"},"content":" public String getTeamName() {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" return getTeam().getName();"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":59,"author":{"gitId":"-"},"content":" public String getSectionName() {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" return this.getTeam().getSection().getName();"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":64,"author":{"gitId":"-"},"content":" public Section getSection() {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" return this.getTeam().getSection();"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":69,"author":{"gitId":"-"},"content":" public String toString() {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" return \"Student [id\u003d\" + super.getId() + \", comments\u003d\" + comments"},{"lineNumber":71,"author":{"gitId":"-"},"content":" + \", createdAt\u003d\" + super.getCreatedAt() + \", updatedAt\u003d\" + super.getUpdatedAt() + \"]\";"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public List\u003cString\u003e getInvalidityInfo() {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" assert comments !\u003d null;"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" List\u003cString\u003e errors \u003d new ArrayList\u003c\u003e();"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForEmail(super.getEmail()), errors);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForStudentRoleComments(comments), errors);"},{"lineNumber":82,"author":{"gitId":"-"},"content":" addNonEmptyError(FieldValidator.getInvalidityInfoForPersonName(super.getName()), errors);"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" return errors;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" }"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" public String getRegistrationUrl() {"},{"lineNumber":88,"author":{"gitId":"-"},"content":" return Config.getFrontEndAppUrl(Const.WebPageURIs.JOIN_PAGE)"},{"lineNumber":89,"author":{"gitId":"-"},"content":" .withRegistrationKey(getRegKey())"},{"lineNumber":90,"author":{"gitId":"-"},"content":" .withEntityType(Const.EntityType.STUDENT)"},{"lineNumber":91,"author":{"gitId":"-"},"content":" .toString();"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":12,"-":81}},{"path":"src/main/java/teammates/storage/sqlentity/questions/FeedbackMsqQuestion.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlentity.questions;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import jakarta.persistence.Column;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import jakarta.persistence.Convert;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import jakarta.persistence.Converter;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.persistence.Entity;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackMsqQuestionDetails;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionDetails;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * Represents an msq question."},{"lineNumber":19,"author":{"gitId":"-"},"content":" */"},{"lineNumber":20,"author":{"gitId":"-"},"content":"@Entity"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public class FeedbackMsqQuestion extends FeedbackQuestion {"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false, columnDefinition \u003d \"TEXT\")"},{"lineNumber":24,"author":{"gitId":"-"},"content":" @Convert(converter \u003d FeedbackMsqQuestionDetailsConverter.class)"},{"lineNumber":25,"author":{"gitId":"-"},"content":" private FeedbackMsqQuestionDetails questionDetails;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" protected FeedbackMsqQuestion() {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" // required by Hibernate"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" public FeedbackMsqQuestion("},{"lineNumber":32,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession, Integer questionNumber,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" String description, FeedbackParticipantType giverType, FeedbackParticipantType recipientType,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" Integer numOfEntitiesToGiveFeedbackTo, List\u003cFeedbackParticipantType\u003e showResponsesTo,"},{"lineNumber":35,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showGiverNameTo, List\u003cFeedbackParticipantType\u003e showRecipientNameTo,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails feedbackQuestionDetails"},{"lineNumber":37,"author":{"gitId":"-"},"content":" ) {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" super(feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":39,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo);"},{"lineNumber":40,"author":{"gitId":"-"},"content":" setFeedBackQuestionDetails((FeedbackMsqQuestionDetails) feedbackQuestionDetails);"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":44,"author":{"gitId":"-"},"content":" public FeedbackQuestionDetails getQuestionDetailsCopy() {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" return questionDetails.getDeepCopy();"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":49,"author":{"gitId":"-"},"content":" public FeedbackMsqQuestion makeDeepCopy(FeedbackSession newFeedbackSession) {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" return new FeedbackMsqQuestion("},{"lineNumber":51,"author":{"gitId":"-"},"content":" newFeedbackSession, this.getQuestionNumber(), this.getDescription(), this.getGiverType(),"},{"lineNumber":52,"author":{"gitId":"-"},"content":" this.getRecipientType(), this.getNumOfEntitiesToGiveFeedbackTo(), new ArrayList\u003c\u003e(this.getShowResponsesTo()),"},{"lineNumber":53,"author":{"gitId":"-"},"content":" new ArrayList\u003c\u003e(this.getShowGiverNameTo()), new ArrayList\u003c\u003e(this.getShowRecipientNameTo()),"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" this.questionDetails.getDeepCopy()"},{"lineNumber":55,"author":{"gitId":"-"},"content":" );"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":59,"author":{"gitId":"-"},"content":" public void setQuestionDetails(FeedbackQuestionDetails questionDetails) {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" this.questionDetails \u003d (FeedbackMsqQuestionDetails) questionDetails;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":64,"author":{"gitId":"-"},"content":" public String toString() {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" return \"FeedbackMsqQuestion [id\u003d\" + super.getId()"},{"lineNumber":66,"author":{"gitId":"-"},"content":" + \", createdAt\u003d\" + super.getCreatedAt() + \", updatedAt\u003d\" + super.getUpdatedAt() + \"]\";"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" public void setFeedBackQuestionDetails(FeedbackMsqQuestionDetails questionDetails) {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" this.questionDetails \u003d questionDetails;"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" public FeedbackMsqQuestionDetails getFeedbackQuestionDetails() {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" return questionDetails;"},{"lineNumber":75,"author":{"gitId":"-"},"content":" }"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":78,"author":{"gitId":"-"},"content":" * Converter for FeedbackMsqQuestion specific attributes."},{"lineNumber":79,"author":{"gitId":"-"},"content":" */"},{"lineNumber":80,"author":{"gitId":"-"},"content":" @Converter"},{"lineNumber":81,"author":{"gitId":"-"},"content":" public static class FeedbackMsqQuestionDetailsConverter"},{"lineNumber":82,"author":{"gitId":"-"},"content":" extends FeedbackQuestionDetailsConverter {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" }"},{"lineNumber":84,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":1,"-":83}},{"path":"src/main/java/teammates/storage/sqlentity/questions/FeedbackRankOptionsQuestion.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlentity.questions;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import jakarta.persistence.Column;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import jakarta.persistence.Convert;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import jakarta.persistence.Converter;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.persistence.Entity;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionDetails;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackRankOptionsQuestionDetails;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * Represents a rank options question."},{"lineNumber":19,"author":{"gitId":"-"},"content":" */"},{"lineNumber":20,"author":{"gitId":"-"},"content":"@Entity"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public class FeedbackRankOptionsQuestion extends FeedbackQuestion {"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" @Column(nullable \u003d false, columnDefinition \u003d \"TEXT\")"},{"lineNumber":24,"author":{"gitId":"-"},"content":" @Convert(converter \u003d FeedbackRankOptionsQuestionDetailsConverter.class)"},{"lineNumber":25,"author":{"gitId":"-"},"content":" private FeedbackRankOptionsQuestionDetails questionDetails;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" protected FeedbackRankOptionsQuestion() {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" // required by Hibernate"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" public FeedbackRankOptionsQuestion("},{"lineNumber":32,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession, Integer questionNumber,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" String description, FeedbackParticipantType giverType, FeedbackParticipantType recipientType,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" Integer numOfEntitiesToGiveFeedbackTo, List\u003cFeedbackParticipantType\u003e showResponsesTo,"},{"lineNumber":35,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e showGiverNameTo, List\u003cFeedbackParticipantType\u003e showRecipientNameTo,"},{"lineNumber":36,"author":{"gitId":"mingyuanc"},"content":" FeedbackQuestionDetails feedbackQuestionDetails) {"},{"lineNumber":37,"author":{"gitId":"-"},"content":" super(feedbackSession, questionNumber, description, giverType, recipientType,"},{"lineNumber":38,"author":{"gitId":"-"},"content":" numOfEntitiesToGiveFeedbackTo, showResponsesTo, showGiverNameTo, showRecipientNameTo);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" setFeedBackQuestionDetails((FeedbackRankOptionsQuestionDetails) feedbackQuestionDetails);"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":43,"author":{"gitId":"-"},"content":" public FeedbackQuestionDetails getQuestionDetailsCopy() {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return questionDetails.getDeepCopy();"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":48,"author":{"gitId":"-"},"content":" public FeedbackRankOptionsQuestion makeDeepCopy(FeedbackSession newFeedbackSession) {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" return new FeedbackRankOptionsQuestion("},{"lineNumber":50,"author":{"gitId":"-"},"content":" newFeedbackSession, this.getQuestionNumber(), this.getDescription(), this.getGiverType(),"},{"lineNumber":51,"author":{"gitId":"-"},"content":" this.getRecipientType(), this.getNumOfEntitiesToGiveFeedbackTo(),"},{"lineNumber":52,"author":{"gitId":"-"},"content":" new ArrayList\u003c\u003e(this.getShowResponsesTo()), new ArrayList\u003c\u003e(this.getShowGiverNameTo()),"},{"lineNumber":53,"author":{"gitId":"-"},"content":" new ArrayList\u003c\u003e(this.getShowRecipientNameTo()),"},{"lineNumber":54,"author":{"gitId":"mingyuanc"},"content":" this.questionDetails.getDeepCopy());"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":58,"author":{"gitId":"-"},"content":" public void setQuestionDetails(FeedbackQuestionDetails questionDetails) {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" this.questionDetails \u003d (FeedbackRankOptionsQuestionDetails) questionDetails;"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":63,"author":{"gitId":"-"},"content":" public String toString() {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" return \"FeedbackRankOptionsQuestion [id\u003d\" + super.getId()"},{"lineNumber":65,"author":{"gitId":"-"},"content":" + \", createdAt\u003d\" + super.getCreatedAt() + \", updatedAt\u003d\" + super.getUpdatedAt() + \"]\";"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" public void setFeedBackQuestionDetails(FeedbackRankOptionsQuestionDetails questionDetails) {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" this.questionDetails \u003d questionDetails;"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" public FeedbackRankOptionsQuestionDetails getFeedbackQuestionDetails() {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" return questionDetails;"},{"lineNumber":74,"author":{"gitId":"-"},"content":" }"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":77,"author":{"gitId":"-"},"content":" * Converter for FeedbackRankOptionsQuestion specific attributes."},{"lineNumber":78,"author":{"gitId":"-"},"content":" */"},{"lineNumber":79,"author":{"gitId":"-"},"content":" @Converter"},{"lineNumber":80,"author":{"gitId":"-"},"content":" public static class FeedbackRankOptionsQuestionDetailsConverter"},{"lineNumber":81,"author":{"gitId":"-"},"content":" extends FeedbackQuestionDetailsConverter {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" }"},{"lineNumber":83,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"mingyuanc":2,"-":81}},{"path":"src/main/java/teammates/storage/sqlentity/responses/FeedbackMissingResponse.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.storage.sqlentity.responses;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.questions.FeedbackTextResponseDetails;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":" * Represents a missing response."},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"public class FeedbackMissingResponse extends FeedbackTextResponse {"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" private String giverSectionName;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" private String recipientSectionName;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":" protected FeedbackMissingResponse() {"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" // required by Hibernate"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":" public FeedbackMissingResponse("},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion feedbackQuestion, String giver,"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" String giverSectionName, String recipient, String recipientSectionName"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" ) {"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" super(feedbackQuestion, giver, null, recipient, null, new FeedbackTextResponseDetails(Const.MISSING_RESPONSE_TEXT));"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" this.giverSectionName \u003d giverSectionName;"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" this.recipientSectionName \u003d recipientSectionName;"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" public String getGiverSectionName() {"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" return giverSectionName;"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" public String getRecipientSectionName() {"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" return recipientSectionName;"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":37}},{"path":"src/main/java/teammates/storage/sqlsearch/SearchManager.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.storage.sqlsearch;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.io.IOException;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.net.SocketTimeoutException;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.Collections;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.apache.commons.lang.StringUtils;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.apache.solr.client.solrj.SolrQuery;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import org.apache.solr.client.solrj.SolrServerException;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import org.apache.solr.client.solrj.impl.HttpSolrClient;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import org.apache.solr.client.solrj.response.QueryResponse;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import org.apache.solr.common.SolrDocument;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import org.apache.solr.common.SolrInputDocument;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.util.StringHelper;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.BaseEntity;"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":27,"author":{"gitId":"-"},"content":" * Acts as a proxy to search service."},{"lineNumber":28,"author":{"gitId":"-"},"content":" *"},{"lineNumber":29,"author":{"gitId":"-"},"content":" * @param \u003cT\u003e Type of entity to be returned"},{"lineNumber":30,"author":{"gitId":"-"},"content":" */"},{"lineNumber":31,"author":{"gitId":"-"},"content":"abstract class SearchManager\u003cT extends BaseEntity\u003e {"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" private static final String ERROR_DELETE_DOCUMENT \u003d \"Failed to delete document(s) %s in Solr. Root cause: %s \";"},{"lineNumber":36,"author":{"gitId":"-"},"content":" private static final String ERROR_SEARCH_DOCUMENT \u003d \"Failed to search for document(s) %s from Solr. Root cause: %s \";"},{"lineNumber":37,"author":{"gitId":"-"},"content":" private static final String ERROR_SEARCH_NOT_IMPLEMENTED \u003d \"Search service is not implemented\";"},{"lineNumber":38,"author":{"gitId":"-"},"content":" private static final String ERROR_PUT_DOCUMENT \u003d \"Failed to put document %s into Solr. Root cause: %s \";"},{"lineNumber":39,"author":{"gitId":"-"},"content":" private static final String ERROR_RESET_COLLECTION \u003d \"Failed to reset collections. Root cause: %s \";"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" private static final int START_INDEX \u003d 0;"},{"lineNumber":42,"author":{"gitId":"-"},"content":" private static final int NUM_OF_RESULTS \u003d Const.SEARCH_QUERY_SIZE_LIMIT;"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" private final HttpSolrClient client;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" private final boolean isResetAllowed;"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" SearchManager(String searchServiceHost, boolean isResetAllowed) {"},{"lineNumber":48,"author":{"gitId":"-"},"content":" this.isResetAllowed \u003d Config.IS_DEV_SERVER \u0026\u0026 isResetAllowed;"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" if (StringHelper.isEmpty(searchServiceHost)) {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" this.client \u003d null;"},{"lineNumber":52,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" this.client \u003d new HttpSolrClient.Builder(searchServiceHost)"},{"lineNumber":54,"author":{"gitId":"-"},"content":" .withConnectionTimeout(2000) // timeout for connecting to Solr server"},{"lineNumber":55,"author":{"gitId":"-"},"content":" .withSocketTimeout(5000) // timeout for reading data"},{"lineNumber":56,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" SolrQuery getBasicQuery(String queryString) {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" SolrQuery query \u003d new SolrQuery();"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" String cleanQueryString \u003d cleanSpecialChars(queryString);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" query.setQuery(cleanQueryString);"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" query.setStart(START_INDEX);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" query.setRows(NUM_OF_RESULTS);"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" return query;"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" QueryResponse performQuery(SolrQuery query) throws SearchServiceException {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" if (client \u003d\u003d null) {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" throw new SearchServiceException(\"Full-text search is not available.\", HttpStatus.SC_NOT_IMPLEMENTED);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" }"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" return client.query(getCollectionName(), query);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" } catch (SolrServerException e) {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" Throwable rootCause \u003d e.getRootCause();"},{"lineNumber":81,"author":{"gitId":"-"},"content":" log.severe(String.format(ERROR_SEARCH_DOCUMENT, query.getQuery(), rootCause), e);"},{"lineNumber":82,"author":{"gitId":"-"},"content":" if (rootCause instanceof SocketTimeoutException) {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" throw new SearchServiceException(\"A timeout was reached while processing your request. \""},{"lineNumber":84,"author":{"gitId":"-"},"content":" + \"Please try again later.\", e, HttpStatus.SC_GATEWAY_TIMEOUT);"},{"lineNumber":85,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":86,"author":{"gitId":"-"},"content":" throw new SearchServiceException(\"An error has occurred while performing search. \""},{"lineNumber":87,"author":{"gitId":"-"},"content":" + \"Please try again later.\", e, HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":90,"author":{"gitId":"-"},"content":" log.severe(String.format(ERROR_SEARCH_DOCUMENT, query.getQuery(), e.getCause()), e);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" throw new SearchServiceException(\"An error has occurred while performing search. \""},{"lineNumber":92,"author":{"gitId":"-"},"content":" + \"Please try again later.\", e, HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" }"},{"lineNumber":94,"author":{"gitId":"-"},"content":" }"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" abstract String getCollectionName();"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" abstract SearchDocument\u003cT\u003e createDocument(T entity);"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":101,"author":{"gitId":"-"},"content":" * Creates or updates search document for the given entity."},{"lineNumber":102,"author":{"gitId":"-"},"content":" */"},{"lineNumber":103,"author":{"gitId":"-"},"content":" public void putDocument(T entity) throws SearchServiceException {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" if (client \u003d\u003d null) {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" log.warning(ERROR_SEARCH_NOT_IMPLEMENTED);"},{"lineNumber":106,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":107,"author":{"gitId":"-"},"content":" }"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" if (entity \u003d\u003d null) {"},{"lineNumber":110,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" Map\u003cString, Object\u003e searchableFields \u003d createDocument(entity).getSearchableFields();"},{"lineNumber":114,"author":{"gitId":"-"},"content":" SolrInputDocument document \u003d new SolrInputDocument();"},{"lineNumber":115,"author":{"gitId":"-"},"content":" searchableFields.forEach((key, value) -\u003e document.addField(key, value));"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":118,"author":{"gitId":"-"},"content":" client.add(getCollectionName(), Collections.singleton(document));"},{"lineNumber":119,"author":{"gitId":"-"},"content":" client.commit(getCollectionName());"},{"lineNumber":120,"author":{"gitId":"-"},"content":" } catch (SolrServerException e) {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" log.severe(String.format(ERROR_PUT_DOCUMENT, document, e.getRootCause()), e);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" throw new SearchServiceException(e, HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":123,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":124,"author":{"gitId":"-"},"content":" log.severe(String.format(ERROR_PUT_DOCUMENT, document, e.getCause()), e);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" throw new SearchServiceException(e, HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" }"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":130,"author":{"gitId":"-"},"content":" * Removes search documents based on the given keys."},{"lineNumber":131,"author":{"gitId":"-"},"content":" */"},{"lineNumber":132,"author":{"gitId":"-"},"content":" public void deleteDocuments(List\u003cString\u003e keys) {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" if (client \u003d\u003d null) {"},{"lineNumber":134,"author":{"gitId":"-"},"content":" log.warning(ERROR_SEARCH_NOT_IMPLEMENTED);"},{"lineNumber":135,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":136,"author":{"gitId":"-"},"content":" }"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" if (keys.isEmpty()) {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" client.deleteById(getCollectionName(), keys);"},{"lineNumber":144,"author":{"gitId":"-"},"content":" client.commit(getCollectionName());"},{"lineNumber":145,"author":{"gitId":"-"},"content":" } catch (SolrServerException e) {"},{"lineNumber":146,"author":{"gitId":"-"},"content":" log.severe(String.format(ERROR_DELETE_DOCUMENT, keys, e.getRootCause()), e);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" log.severe(String.format(ERROR_DELETE_DOCUMENT, keys, e.getCause()), e);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" }"},{"lineNumber":150,"author":{"gitId":"-"},"content":" }"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":153,"author":{"gitId":"-"},"content":" * Resets the data for all collections if, and only if called during component"},{"lineNumber":154,"author":{"gitId":"-"},"content":" * tests."},{"lineNumber":155,"author":{"gitId":"-"},"content":" */"},{"lineNumber":156,"author":{"gitId":"-"},"content":" public void resetCollections() {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" if (client \u003d\u003d null || !isResetAllowed) {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" client.deleteByQuery(getCollectionName(), \"*:*\");"},{"lineNumber":163,"author":{"gitId":"-"},"content":" client.commit(getCollectionName());"},{"lineNumber":164,"author":{"gitId":"-"},"content":" } catch (SolrServerException e) {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" log.severe(String.format(ERROR_RESET_COLLECTION, e.getRootCause()), e);"},{"lineNumber":166,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" log.severe(String.format(ERROR_RESET_COLLECTION, e.getCause()), e);"},{"lineNumber":168,"author":{"gitId":"-"},"content":" }"},{"lineNumber":169,"author":{"gitId":"-"},"content":" }"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" private String cleanSpecialChars(String queryString) {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" String htmlTagStripPattern \u003d \"\u003c[^\u003e]*\u003e\";"},{"lineNumber":173,"author":{"gitId":"-"},"content":""},{"lineNumber":174,"author":{"gitId":"-"},"content":" // Solr special characters: + - \u0026\u0026 || ! ( ) { } [ ] ^ \" ~ * ? : \\ /"},{"lineNumber":175,"author":{"gitId":"-"},"content":" String res \u003d queryString.replaceAll(htmlTagStripPattern, \"\")"},{"lineNumber":176,"author":{"gitId":"-"},"content":" .replace(\"\\\\\", \"\\\\\\\\\")"},{"lineNumber":177,"author":{"gitId":"-"},"content":" .replace(\"+\", \"\\\\+\")"},{"lineNumber":178,"author":{"gitId":"-"},"content":" .replace(\"-\", \"\\\\-\")"},{"lineNumber":179,"author":{"gitId":"-"},"content":" .replace(\"\u0026\u0026\", \"\\\\\u0026\u0026\")"},{"lineNumber":180,"author":{"gitId":"-"},"content":" .replace(\"||\", \"\\\\||\")"},{"lineNumber":181,"author":{"gitId":"-"},"content":" .replace(\"!\", \"\\\\!\")"},{"lineNumber":182,"author":{"gitId":"-"},"content":" .replace(\"(\", \"\\\\(\")"},{"lineNumber":183,"author":{"gitId":"-"},"content":" .replace(\")\", \"\\\\)\")"},{"lineNumber":184,"author":{"gitId":"-"},"content":" .replace(\"{\", \"\\\\{\")"},{"lineNumber":185,"author":{"gitId":"-"},"content":" .replace(\"}\", \"\\\\}\")"},{"lineNumber":186,"author":{"gitId":"-"},"content":" .replace(\"[\", \"\\\\[\")"},{"lineNumber":187,"author":{"gitId":"-"},"content":" .replace(\"]\", \"\\\\]\")"},{"lineNumber":188,"author":{"gitId":"-"},"content":" .replace(\"^\", \"\\\\^\")"},{"lineNumber":189,"author":{"gitId":"-"},"content":" .replace(\"~\", \"\\\\~\")"},{"lineNumber":190,"author":{"gitId":"-"},"content":" .replace(\"?\", \"\\\\?\")"},{"lineNumber":191,"author":{"gitId":"-"},"content":" .replace(\":\", \"\\\\:\")"},{"lineNumber":192,"author":{"gitId":"-"},"content":" .replace(\"/\", \"\\\\/\");"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"-"},"content":" // imbalanced double quotes are invalid"},{"lineNumber":195,"author":{"gitId":"-"},"content":" int count \u003d StringUtils.countMatches(res, \"\\\"\");"},{"lineNumber":196,"author":{"gitId":"-"},"content":" if (count % 2 \u003d\u003d 1) {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" res \u003d res.replace(\"\\\"\", \"\");"},{"lineNumber":198,"author":{"gitId":"-"},"content":" }"},{"lineNumber":199,"author":{"gitId":"-"},"content":""},{"lineNumber":200,"author":{"gitId":"-"},"content":" // use exact match only when there\u0027s email-like input"},{"lineNumber":201,"author":{"gitId":"-"},"content":" if (res.contains(\"@\") \u0026\u0026 count \u003d\u003d 0) {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" return \"\\\"\" + res + \"\\\"\";"},{"lineNumber":203,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":204,"author":{"gitId":"-"},"content":" return res;"},{"lineNumber":205,"author":{"gitId":"-"},"content":" }"},{"lineNumber":206,"author":{"gitId":"-"},"content":" }"},{"lineNumber":207,"author":{"gitId":"-"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" abstract T getEntityFromDocument(SolrDocument document);"},{"lineNumber":209,"author":{"gitId":"-"},"content":""},{"lineNumber":210,"author":{"gitId":"-"},"content":" abstract void sortResult(List\u003cT\u003e result);"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" List\u003cT\u003e convertDocumentToEntities(List\u003cSolrDocument\u003e documents) {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" if (documents \u003d\u003d null) {"},{"lineNumber":214,"author":{"gitId":"-"},"content":" return new ArrayList\u003c\u003e();"},{"lineNumber":215,"author":{"gitId":"-"},"content":" }"},{"lineNumber":216,"author":{"gitId":"-"},"content":""},{"lineNumber":217,"author":{"gitId":"-"},"content":" List\u003cT\u003e result \u003d new ArrayList\u003c\u003e();"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":" for (SolrDocument document : documents) {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" T entity \u003d getEntityFromDocument(document);"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"-"},"content":" // Entity will be null if document corresponds to entity in datastore"},{"lineNumber":223,"author":{"gitId":"-"},"content":" if (entity \u003d\u003d null) {"},{"lineNumber":224,"author":{"gitId":"-"},"content":" // search engine out of sync as SearchManager may fail to delete documents"},{"lineNumber":225,"author":{"gitId":"-"},"content":" // the chance is low and it is generally not a big problem"},{"lineNumber":226,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":227,"author":{"gitId":"domoberzin"},"content":" // these lines below are commented out as they interfere with the dual db search,"},{"lineNumber":228,"author":{"gitId":"domoberzin"},"content":" // and cause unwanted deletions, please refer to the following PR for more details"},{"lineNumber":229,"author":{"gitId":"domoberzin"},"content":" // [PR](https://github.com/TEAMMATES/teammates/pull/12838)"},{"lineNumber":230,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":231,"author":{"gitId":"domoberzin"},"content":" // String id \u003d (String) document.getFirstValue(\"id\");"},{"lineNumber":232,"author":{"gitId":"domoberzin"},"content":" // deleteDocuments(Collections.singletonList(id));"},{"lineNumber":233,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":234,"author":{"gitId":"-"},"content":" }"},{"lineNumber":235,"author":{"gitId":"-"},"content":" result.add(entity);"},{"lineNumber":236,"author":{"gitId":"-"},"content":" }"},{"lineNumber":237,"author":{"gitId":"-"},"content":" sortResult(result);"},{"lineNumber":238,"author":{"gitId":"-"},"content":""},{"lineNumber":239,"author":{"gitId":"-"},"content":" return result;"},{"lineNumber":240,"author":{"gitId":"-"},"content":" }"},{"lineNumber":241,"author":{"gitId":"-"},"content":""},{"lineNumber":242,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":7,"-":235}},{"path":"src/main/java/teammates/ui/constants/ApiConst.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.constants;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import com.fasterxml.jackson.annotation.JsonValue;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":9,"author":{"gitId":"-"},"content":" * Special constants used by the back-end."},{"lineNumber":10,"author":{"gitId":"-"},"content":" */"},{"lineNumber":11,"author":{"gitId":"-"},"content":"public enum ApiConst {"},{"lineNumber":12,"author":{"gitId":"-"},"content":" // CHECKSTYLE.OFF:JavadocVariable"},{"lineNumber":13,"author":{"gitId":"-"},"content":" COURSE_ID_MAX_LENGTH(FieldValidator.COURSE_ID_MAX_LENGTH),"},{"lineNumber":14,"author":{"gitId":"-"},"content":" COURSE_NAME_MAX_LENGTH(FieldValidator.COURSE_NAME_MAX_LENGTH),"},{"lineNumber":15,"author":{"gitId":"-"},"content":" STUDENT_NAME_MAX_LENGTH(FieldValidator.PERSON_NAME_MAX_LENGTH),"},{"lineNumber":16,"author":{"gitId":"-"},"content":" SECTION_NAME_MAX_LENGTH(FieldValidator.SECTION_NAME_MAX_LENGTH),"},{"lineNumber":17,"author":{"gitId":"-"},"content":" TEAM_NAME_MAX_LENGTH(FieldValidator.TEAM_NAME_MAX_LENGTH),"},{"lineNumber":18,"author":{"gitId":"-"},"content":" EMAIL_MAX_LENGTH(FieldValidator.EMAIL_MAX_LENGTH),"},{"lineNumber":19,"author":{"gitId":"-"},"content":" FEEDBACK_SESSION_NAME_MAX_LENGTH(FieldValidator.FEEDBACK_SESSION_NAME_MAX_LENGTH),"},{"lineNumber":20,"author":{"gitId":"-"},"content":" NOTIFICATION_TITLE_MAX_LENGTH(FieldValidator.NOTIFICATION_TITLE_MAX_LENGTH),"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" CONTRIBUTION_POINT_NOT_SUBMITTED(Const.POINTS_NOT_SUBMITTED),"},{"lineNumber":23,"author":{"gitId":"-"},"content":" CONTRIBUTION_POINT_NOT_INITIALIZED(Const.INT_UNINITIALIZED),"},{"lineNumber":24,"author":{"gitId":"-"},"content":" CONTRIBUTION_POINT_NOT_SURE(Const.POINTS_NOT_SURE),"},{"lineNumber":25,"author":{"gitId":"-"},"content":" CONTRIBUTION_POINT_EQUAL_SHARE(Const.POINTS_EQUAL_SHARE),"},{"lineNumber":26,"author":{"gitId":"-"},"content":" NUMERICAL_SCALE_ANSWER_NOT_SUBMITTED(Const.POINTS_NOT_SUBMITTED),"},{"lineNumber":27,"author":{"gitId":"-"},"content":" RANK_OPTIONS_ANSWER_NOT_SUBMITTED(Const.POINTS_NOT_SUBMITTED),"},{"lineNumber":28,"author":{"gitId":"-"},"content":" RANK_RECIPIENTS_ANSWER_NOT_SUBMITTED(Const.POINTS_NOT_SUBMITTED),"},{"lineNumber":29,"author":{"gitId":"-"},"content":" NO_VALUE(Const.POINTS_NO_VALUE),"},{"lineNumber":30,"author":{"gitId":"-"},"content":" LOGS_RETENTION_PERIOD(Const.LOGS_RETENTION_PERIOD.toDays()),"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" SEARCH_QUERY_SIZE_LIMIT(Const.SEARCH_QUERY_SIZE_LIMIT),"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" STUDENT_ACTIVITY_LOGS_UPDATE_INTERVAL(Const.STUDENT_ACTIVITY_LOGS_UPDATE_INTERVAL.toMinutes());"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" // CHECKSTYLE.ON:JavadocVariable"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" private final Object value;"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" ApiConst(Object value) {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.value \u003d value;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" @JsonValue"},{"lineNumber":43,"author":{"gitId":"-"},"content":" public Object getValue() {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return value;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":3,"-":44}},{"path":"src/main/java/teammates/ui/constants/ApiStringConst.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.ui.constants;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import com.fasterxml.jackson.annotation.JsonValue;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":" * Special constants used by the back-end."},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"public enum ApiStringConst {"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":" // CHECKSTYLE.OFF:JavadocVariable"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" EMAIL_REGEX(escapeRegex(FieldValidator.REGEX_EMAIL));"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" // CHECKSTYLE.ON:JavadocVariable"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":" private final Object value;"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" ApiStringConst(Object value) {"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":" this.value \u003d value;"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" @JsonValue"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" public Object getValue() {"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" return value;"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" * Escape regex pattern strings to ensure the pattern remains valid when converted to JS."},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" private static String escapeRegex(String regexStr) {"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" String escapedRegexStr \u003d regexStr;"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" // Double escape backslashes"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" escapedRegexStr \u003d escapedRegexStr.replace(\"\\\\\", \"\\\\\\\\\");"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" // Replace possessive zero or more times quantifier *+ that the email pattern uses"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" // with greedy zero or more times quantifier *"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" // as possessive quantifiers are not supported in JavaScript"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" escapedRegexStr \u003d escapedRegexStr.replace(\"*+\", \"*\");"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" return escapedRegexStr;"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":40}},{"path":"src/main/java/teammates/ui/constants/ResourceEndpoints.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.constants;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import com.fasterxml.jackson.annotation.JsonValue;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.ResourceURIs;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":8,"author":{"gitId":"-"},"content":" * API endpoints for resources."},{"lineNumber":9,"author":{"gitId":"-"},"content":" */"},{"lineNumber":10,"author":{"gitId":"-"},"content":"public enum ResourceEndpoints {"},{"lineNumber":11,"author":{"gitId":"-"},"content":" //CHECKSTYLE.OFF:JavadocVariable"},{"lineNumber":12,"author":{"gitId":"-"},"content":" ERROR_REPORT(ResourceURIs.ERROR_REPORT),"},{"lineNumber":13,"author":{"gitId":"-"},"content":" AUTH(ResourceURIs.AUTH),"},{"lineNumber":14,"author":{"gitId":"-"},"content":" AUTH_REGKEY(ResourceURIs.AUTH_REGKEY),"},{"lineNumber":15,"author":{"gitId":"-"},"content":" ACCOUNT(ResourceURIs.ACCOUNT),"},{"lineNumber":16,"author":{"gitId":"-"},"content":" ACCOUNT_RESET(ResourceURIs.ACCOUNT_RESET),"},{"lineNumber":17,"author":{"gitId":"-"},"content":" ACCOUNT_REQUEST(ResourceURIs.ACCOUNT_REQUEST),"},{"lineNumber":18,"author":{"gitId":"-"},"content":" ACCOUNT_REQUESTS(ResourceURIs.ACCOUNT_REQUESTS),"},{"lineNumber":19,"author":{"gitId":"-"},"content":" ACCOUNT_REQUEST_RESET(ResourceURIs.ACCOUNT_REQUEST_RESET),"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" ACCOUNT_REQUEST_REJECT(ResourceURIs.ACCOUNT_REQUEST_REJECTION),"},{"lineNumber":21,"author":{"gitId":"-"},"content":" ACCOUNTS(ResourceURIs.ACCOUNTS),"},{"lineNumber":22,"author":{"gitId":"-"},"content":" RESPONSE_COMMENT(ResourceURIs.RESPONSE_COMMENT),"},{"lineNumber":23,"author":{"gitId":"-"},"content":" COURSE(ResourceURIs.COURSE),"},{"lineNumber":24,"author":{"gitId":"-"},"content":" COURSE_ARCHIVE(ResourceURIs.COURSE_ARCHIVE),"},{"lineNumber":25,"author":{"gitId":"-"},"content":" BIN_COURSE(ResourceURIs.BIN_COURSE),"},{"lineNumber":26,"author":{"gitId":"-"},"content":" COURSE_SECTIONS(ResourceURIs.COURSE_SECTIONS),"},{"lineNumber":27,"author":{"gitId":"-"},"content":" COURSES(ResourceURIs.COURSES),"},{"lineNumber":28,"author":{"gitId":"-"},"content":" INSTRUCTORS(ResourceURIs.INSTRUCTORS),"},{"lineNumber":29,"author":{"gitId":"-"},"content":" INSTRUCTOR(ResourceURIs.INSTRUCTOR),"},{"lineNumber":30,"author":{"gitId":"-"},"content":" INSTRUCTOR_PRIVILEGE(ResourceURIs.INSTRUCTOR_PRIVILEGE),"},{"lineNumber":31,"author":{"gitId":"-"},"content":" INSTRUCTOR_KEY(ResourceURIs.INSTRUCTOR_KEY),"},{"lineNumber":32,"author":{"gitId":"-"},"content":" RESULT(ResourceURIs.RESULT),"},{"lineNumber":33,"author":{"gitId":"-"},"content":" STUDENTS(ResourceURIs.STUDENTS),"},{"lineNumber":34,"author":{"gitId":"-"},"content":" STUDENT(ResourceURIs.STUDENT),"},{"lineNumber":35,"author":{"gitId":"-"},"content":" STUDENT_KEY(ResourceURIs.STUDENT_KEY),"},{"lineNumber":36,"author":{"gitId":"-"},"content":" SESSIONS_ONGOING(ResourceURIs.SESSIONS_ONGOING),"},{"lineNumber":37,"author":{"gitId":"-"},"content":" SESSION(ResourceURIs.SESSION),"},{"lineNumber":38,"author":{"gitId":"-"},"content":" SESSION_LOGS(ResourceURIs.SESSION_LOGS),"},{"lineNumber":39,"author":{"gitId":"-"},"content":" SESSION_PUBLISH(ResourceURIs.SESSION_PUBLISH),"},{"lineNumber":40,"author":{"gitId":"-"},"content":" SESSION_REMIND_SUBMISSION(ResourceURIs.SESSION_REMIND_SUBMISSION),"},{"lineNumber":41,"author":{"gitId":"-"},"content":" SESSION_REMIND_RESULT(ResourceURIs.SESSION_REMIND_RESULT),"},{"lineNumber":42,"author":{"gitId":"-"},"content":" SESSION_STATS(ResourceURIs.SESSION_STATS),"},{"lineNumber":43,"author":{"gitId":"-"},"content":" SESSION_SUBMITTED_GIVER_SET(ResourceURIs.SESSION_SUBMITTED_GIVER_SET),"},{"lineNumber":44,"author":{"gitId":"-"},"content":" SESSIONS(ResourceURIs.SESSIONS),"},{"lineNumber":45,"author":{"gitId":"-"},"content":" BIN_SESSION(ResourceURIs.BIN_SESSION),"},{"lineNumber":46,"author":{"gitId":"-"},"content":" QUESTIONS(ResourceURIs.QUESTIONS),"},{"lineNumber":47,"author":{"gitId":"-"},"content":" QUESTION(ResourceURIs.QUESTION),"},{"lineNumber":48,"author":{"gitId":"-"},"content":" QUESTION_RECIPIENTS(ResourceURIs.QUESTION_RECIPIENTS),"},{"lineNumber":49,"author":{"gitId":"-"},"content":" RESPONSES(ResourceURIs.RESPONSES),"},{"lineNumber":50,"author":{"gitId":"-"},"content":" HAS_RESPONSES(ResourceURIs.HAS_RESPONSES),"},{"lineNumber":51,"author":{"gitId":"-"},"content":" NOTIFICATION(ResourceURIs.NOTIFICATION),"},{"lineNumber":52,"author":{"gitId":"-"},"content":" NOTIFICATIONS(ResourceURIs.NOTIFICATIONS),"},{"lineNumber":53,"author":{"gitId":"-"},"content":" NOTIFICATION_READ(ResourceURIs.NOTIFICATION_READ),"},{"lineNumber":54,"author":{"gitId":"-"},"content":" JOIN(ResourceURIs.JOIN),"},{"lineNumber":55,"author":{"gitId":"-"},"content":" JOIN_REMIND(ResourceURIs.JOIN_REMIND),"},{"lineNumber":56,"author":{"gitId":"-"},"content":" TIMEZONE(ResourceURIs.TIMEZONE),"},{"lineNumber":57,"author":{"gitId":"-"},"content":" SESSION_LINKS_RECOVERY(ResourceURIs.SESSION_LINKS_RECOVERY),"},{"lineNumber":58,"author":{"gitId":"-"},"content":" EMAIL(ResourceURIs.EMAIL),"},{"lineNumber":59,"author":{"gitId":"-"},"content":" SEARCH_ACCOUNT_REQUESTS(ResourceURIs.SEARCH_ACCOUNT_REQUESTS),"},{"lineNumber":60,"author":{"gitId":"-"},"content":" SEARCH_INSTRUCTORS(ResourceURIs.SEARCH_INSTRUCTORS),"},{"lineNumber":61,"author":{"gitId":"-"},"content":" SEARCH_STUDENTS(ResourceURIs.SEARCH_STUDENTS),"},{"lineNumber":62,"author":{"gitId":"-"},"content":" LOGS(ResourceURIs.LOGS),"},{"lineNumber":63,"author":{"gitId":"-"},"content":" USAGE_STATISTICS(ResourceURIs.USAGE_STATISTICS),"},{"lineNumber":64,"author":{"gitId":"-"},"content":" ACTION_CLASS(ResourceURIs.ACTION_CLASS),"},{"lineNumber":65,"author":{"gitId":"-"},"content":" LOGIN_EMAIL(ResourceURIs.LOGIN_EMAIL);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" //CHECKSTYLE.ON:JavadocVariable"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" private final String url;"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" ResourceEndpoints(String s) {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" this.url \u003d s;"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" @JsonValue"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public String getUrl() {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" return url;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":1,"-":77}},{"path":"src/main/java/teammates/ui/output/CourseData.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.output;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPermissionSet;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":10,"author":{"gitId":"-"},"content":" * The API output format of a course."},{"lineNumber":11,"author":{"gitId":"-"},"content":" */"},{"lineNumber":12,"author":{"gitId":"-"},"content":"public class CourseData extends ApiOutput {"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":" private final String courseId;"},{"lineNumber":15,"author":{"gitId":"-"},"content":" private final String courseName;"},{"lineNumber":16,"author":{"gitId":"-"},"content":" private final String timeZone;"},{"lineNumber":17,"author":{"gitId":"-"},"content":" private final String institute;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" @Nullable"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":" private final Boolean isMigrated;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" private long creationTimestamp;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" private long deletionTimestamp;"},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":23,"author":{"gitId":"-"},"content":" private InstructorPermissionSet privileges;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" public CourseData(CourseAttributes courseAttributes) {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" this.courseId \u003d courseAttributes.getId();"},{"lineNumber":27,"author":{"gitId":"-"},"content":" this.courseName \u003d courseAttributes.getName();"},{"lineNumber":28,"author":{"gitId":"-"},"content":" this.timeZone \u003d courseAttributes.getTimeZone();"},{"lineNumber":29,"author":{"gitId":"-"},"content":" this.institute \u003d courseAttributes.getInstitute();"},{"lineNumber":30,"author":{"gitId":"-"},"content":" this.creationTimestamp \u003d courseAttributes.getCreatedAt().toEpochMilli();"},{"lineNumber":31,"author":{"gitId":"-"},"content":" if (courseAttributes.getDeletedAt() !\u003d null) {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" this.deletionTimestamp \u003d courseAttributes.getDeletedAt().toEpochMilli();"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" this.isMigrated \u003d false;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" public CourseData(Course course) {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" this.courseId \u003d course.getId();"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.courseName \u003d course.getName();"},{"lineNumber":40,"author":{"gitId":"-"},"content":" this.timeZone \u003d course.getTimeZone();"},{"lineNumber":41,"author":{"gitId":"-"},"content":" this.institute \u003d course.getInstitute();"},{"lineNumber":42,"author":{"gitId":"-"},"content":" this.creationTimestamp \u003d course.getCreatedAt().toEpochMilli();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" if (course.getDeletedAt() !\u003d null) {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" this.deletionTimestamp \u003d course.getDeletedAt().toEpochMilli();"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" this.isMigrated \u003d true;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" }"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" public String getCourseId() {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" return courseId;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" }"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" public String getCourseName() {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" return courseName;"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" public String getInstitute() {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" return institute;"},{"lineNumber":59,"author":{"gitId":"-"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" public String getTimeZone() {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" return timeZone;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" public long getCreationTimestamp() {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" return creationTimestamp;"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" public long getDeletionTimestamp() {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" return deletionTimestamp;"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" public Boolean getIsMigrated() {"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" return isMigrated;"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" public InstructorPermissionSet getPrivileges() {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" return privileges;"},{"lineNumber":79,"author":{"gitId":"-"},"content":" }"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" public void setCreationTimestamp(long creationTimestamp) {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" this.creationTimestamp \u003d creationTimestamp;"},{"lineNumber":83,"author":{"gitId":"-"},"content":" }"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" public void setDeletionTimestamp(long deletionTimestamp) {"},{"lineNumber":86,"author":{"gitId":"-"},"content":" this.deletionTimestamp \u003d deletionTimestamp;"},{"lineNumber":87,"author":{"gitId":"-"},"content":" }"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" public void setPrivileges(InstructorPermissionSet privileges) {"},{"lineNumber":90,"author":{"gitId":"-"},"content":" this.privileges \u003d privileges;"},{"lineNumber":91,"author":{"gitId":"-"},"content":" }"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":94,"author":{"gitId":"-"},"content":" * Hides some attributes to student."},{"lineNumber":95,"author":{"gitId":"-"},"content":" */"},{"lineNumber":96,"author":{"gitId":"-"},"content":" public void hideInformationForStudent() {"},{"lineNumber":97,"author":{"gitId":"-"},"content":" setDeletionTimestamp(0);"},{"lineNumber":98,"author":{"gitId":"-"},"content":" }"},{"lineNumber":99,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":8,"-":91}},{"path":"src/main/java/teammates/ui/output/FeedbackSessionData.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.output;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPermissionSet;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":21,"author":{"gitId":"-"},"content":" * The API output format of {@link FeedbackSessionAttributes}."},{"lineNumber":22,"author":{"gitId":"-"},"content":" */"},{"lineNumber":23,"author":{"gitId":"-"},"content":"public class FeedbackSessionData extends ApiOutput {"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":" @Nullable"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" private final UUID feedbackSessionId;"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" private final String courseId;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" private final String timeZone;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" private final String feedbackSessionName;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" private final String instructions;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private final Long submissionStartTimestamp;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" private final Long submissionEndTimestamp;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":36,"author":{"gitId":"-"},"content":" private Long submissionEndWithExtensionTimestamp;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":38,"author":{"gitId":"-"},"content":" private Long sessionVisibleFromTimestamp;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":40,"author":{"gitId":"-"},"content":" private Long resultVisibleFromTimestamp;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" private Long gracePeriod;"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" private SessionVisibleSetting sessionVisibleSetting;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":45,"author":{"gitId":"-"},"content":" private Long customSessionVisibleTimestamp;"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" private ResponseVisibleSetting responseVisibleSetting;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private Long customResponseVisibleTimestamp;"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" private FeedbackSessionSubmissionStatus submissionStatus;"},{"lineNumber":52,"author":{"gitId":"-"},"content":" private FeedbackSessionPublishStatus publishStatus;"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" private Boolean isClosingEmailEnabled;"},{"lineNumber":55,"author":{"gitId":"-"},"content":" private Boolean isPublishedEmailEnabled;"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" private long createdAtTimestamp;"},{"lineNumber":58,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":59,"author":{"gitId":"-"},"content":" private final Long deletedAtTimestamp;"},{"lineNumber":60,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":61,"author":{"gitId":"-"},"content":" private InstructorPermissionSet privileges;"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" private Map\u003cString, Long\u003e studentDeadlines;"},{"lineNumber":64,"author":{"gitId":"-"},"content":" private Map\u003cString, Long\u003e instructorDeadlines;"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" public FeedbackSessionData(FeedbackSessionAttributes feedbackSessionAttributes) {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" String timeZone \u003d feedbackSessionAttributes.getTimeZone();"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionId \u003d null;"},{"lineNumber":69,"author":{"gitId":"-"},"content":" this.courseId \u003d feedbackSessionAttributes.getCourseId();"},{"lineNumber":70,"author":{"gitId":"-"},"content":" this.timeZone \u003d timeZone;"},{"lineNumber":71,"author":{"gitId":"-"},"content":" this.feedbackSessionName \u003d feedbackSessionAttributes.getFeedbackSessionName();"},{"lineNumber":72,"author":{"gitId":"-"},"content":" this.instructions \u003d feedbackSessionAttributes.getInstructions();"},{"lineNumber":73,"author":{"gitId":"-"},"content":" this.submissionStartTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":74,"author":{"gitId":"-"},"content":" feedbackSessionAttributes.getStartTime(), timeZone, true).toEpochMilli();"},{"lineNumber":75,"author":{"gitId":"-"},"content":" this.submissionEndTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":76,"author":{"gitId":"-"},"content":" feedbackSessionAttributes.getEndTime(), timeZone, true).toEpochMilli();"},{"lineNumber":77,"author":{"gitId":"-"},"content":" this.submissionEndWithExtensionTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":78,"author":{"gitId":"-"},"content":" feedbackSessionAttributes.getDeadline(), timeZone, true).toEpochMilli();"},{"lineNumber":79,"author":{"gitId":"-"},"content":" this.gracePeriod \u003d feedbackSessionAttributes.getGracePeriodMinutes();"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" Instant sessionVisibleTime \u003d feedbackSessionAttributes.getSessionVisibleFromTime();"},{"lineNumber":82,"author":{"gitId":"-"},"content":" this.sessionVisibleFromTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":83,"author":{"gitId":"-"},"content":" sessionVisibleTime, timeZone, true).toEpochMilli();"},{"lineNumber":84,"author":{"gitId":"-"},"content":" if (sessionVisibleTime.equals(Const.TIME_REPRESENTS_FOLLOW_OPENING)) {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" this.sessionVisibleSetting \u003d SessionVisibleSetting.AT_OPEN;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" this.sessionVisibleSetting \u003d SessionVisibleSetting.CUSTOM;"},{"lineNumber":88,"author":{"gitId":"-"},"content":" this.customSessionVisibleTimestamp \u003d this.sessionVisibleFromTimestamp;"},{"lineNumber":89,"author":{"gitId":"-"},"content":" }"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" Instant responseVisibleTime \u003d feedbackSessionAttributes.getResultsVisibleFromTime();"},{"lineNumber":92,"author":{"gitId":"-"},"content":" this.resultVisibleFromTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":93,"author":{"gitId":"-"},"content":" responseVisibleTime, timeZone, true).toEpochMilli();"},{"lineNumber":94,"author":{"gitId":"-"},"content":" if (responseVisibleTime.equals(Const.TIME_REPRESENTS_FOLLOW_VISIBLE)) {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" this.responseVisibleSetting \u003d ResponseVisibleSetting.AT_VISIBLE;"},{"lineNumber":96,"author":{"gitId":"-"},"content":" } else if (responseVisibleTime.equals(Const.TIME_REPRESENTS_LATER)) {"},{"lineNumber":97,"author":{"gitId":"-"},"content":" this.responseVisibleSetting \u003d ResponseVisibleSetting.LATER;"},{"lineNumber":98,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" this.responseVisibleSetting \u003d ResponseVisibleSetting.CUSTOM;"},{"lineNumber":100,"author":{"gitId":"-"},"content":" this.customResponseVisibleTimestamp \u003d this.resultVisibleFromTimestamp;"},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" if (!feedbackSessionAttributes.isVisible()) {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.NOT_VISIBLE;"},{"lineNumber":105,"author":{"gitId":"-"},"content":" }"},{"lineNumber":106,"author":{"gitId":"-"},"content":" if (feedbackSessionAttributes.isVisible() \u0026\u0026 !feedbackSessionAttributes.isOpened()) {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.VISIBLE_NOT_OPEN;"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":" if (feedbackSessionAttributes.isOpened()) {"},{"lineNumber":110,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.OPEN;"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":" if (feedbackSessionAttributes.isInGracePeriod()) {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.GRACE_PERIOD;"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":" if (feedbackSessionAttributes.isClosed()) {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.CLOSED;"},{"lineNumber":117,"author":{"gitId":"-"},"content":" }"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" if (feedbackSessionAttributes.isPublished()) {"},{"lineNumber":120,"author":{"gitId":"-"},"content":" this.publishStatus \u003d FeedbackSessionPublishStatus.PUBLISHED;"},{"lineNumber":121,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" this.publishStatus \u003d FeedbackSessionPublishStatus.NOT_PUBLISHED;"},{"lineNumber":123,"author":{"gitId":"-"},"content":" }"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" this.isClosingEmailEnabled \u003d feedbackSessionAttributes.isClosingEmailEnabled();"},{"lineNumber":126,"author":{"gitId":"-"},"content":" this.isPublishedEmailEnabled \u003d feedbackSessionAttributes.isPublishedEmailEnabled();"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" this.createdAtTimestamp \u003d feedbackSessionAttributes.getCreatedTime().toEpochMilli();"},{"lineNumber":129,"author":{"gitId":"-"},"content":" if (feedbackSessionAttributes.getDeletedTime() \u003d\u003d null) {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" this.deletedAtTimestamp \u003d null;"},{"lineNumber":131,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" this.deletedAtTimestamp \u003d feedbackSessionAttributes.getDeletedTime().toEpochMilli();"},{"lineNumber":133,"author":{"gitId":"-"},"content":" }"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" String userEmail \u003d feedbackSessionAttributes.getUserEmail();"},{"lineNumber":136,"author":{"gitId":"-"},"content":" this.studentDeadlines \u003d feedbackSessionAttributes.getStudentDeadlines()"},{"lineNumber":137,"author":{"gitId":"-"},"content":" .entrySet()"},{"lineNumber":138,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":139,"author":{"gitId":"-"},"content":" .filter(entry -\u003e userEmail \u003d\u003d null || userEmail.equals(entry.getKey()))"},{"lineNumber":140,"author":{"gitId":"-"},"content":" .collect(Collectors.toMap(Map.Entry::getKey, entry -\u003e"},{"lineNumber":141,"author":{"gitId":"-"},"content":" TimeHelper.getMidnightAdjustedInstantBasedOnZone(entry.getValue(), timeZone, true)"},{"lineNumber":142,"author":{"gitId":"-"},"content":" .toEpochMilli()));"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" this.instructorDeadlines \u003d feedbackSessionAttributes.getInstructorDeadlines()"},{"lineNumber":145,"author":{"gitId":"-"},"content":" .entrySet()"},{"lineNumber":146,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":147,"author":{"gitId":"-"},"content":" .filter(entry -\u003e userEmail \u003d\u003d null || userEmail.equals(entry.getKey()))"},{"lineNumber":148,"author":{"gitId":"-"},"content":" .collect(Collectors.toMap(Map.Entry::getKey, entry -\u003e"},{"lineNumber":149,"author":{"gitId":"-"},"content":" TimeHelper.getMidnightAdjustedInstantBasedOnZone(entry.getValue(), timeZone, true)"},{"lineNumber":150,"author":{"gitId":"-"},"content":" .toEpochMilli()));"},{"lineNumber":151,"author":{"gitId":"-"},"content":" }"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":" public FeedbackSessionData(FeedbackSession feedbackSession) {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" assert feedbackSession !\u003d null;"},{"lineNumber":155,"author":{"gitId":"-"},"content":" assert feedbackSession.getCourse() !\u003d null;"},{"lineNumber":156,"author":{"gitId":"-"},"content":" String timeZone \u003d feedbackSession.getCourse().getTimeZone();"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionId \u003d feedbackSession.getId();"},{"lineNumber":158,"author":{"gitId":"-"},"content":" this.courseId \u003d feedbackSession.getCourse().getId();"},{"lineNumber":159,"author":{"gitId":"-"},"content":" this.timeZone \u003d timeZone;"},{"lineNumber":160,"author":{"gitId":"-"},"content":" this.feedbackSessionName \u003d feedbackSession.getName();"},{"lineNumber":161,"author":{"gitId":"-"},"content":" this.instructions \u003d feedbackSession.getInstructions();"},{"lineNumber":162,"author":{"gitId":"-"},"content":" this.submissionStartTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":163,"author":{"gitId":"-"},"content":" feedbackSession.getStartTime(), timeZone, true).toEpochMilli();"},{"lineNumber":164,"author":{"gitId":"-"},"content":" this.submissionEndTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":165,"author":{"gitId":"-"},"content":" feedbackSession.getEndTime(), timeZone, true).toEpochMilli();"},{"lineNumber":166,"author":{"gitId":"-"},"content":" // If no deadline extension time is provided, then the end time with extension is assumed to be"},{"lineNumber":167,"author":{"gitId":"-"},"content":" // just the end time."},{"lineNumber":168,"author":{"gitId":"-"},"content":" this.submissionEndWithExtensionTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":169,"author":{"gitId":"-"},"content":" feedbackSession.getEndTime(), timeZone, true).toEpochMilli();"},{"lineNumber":170,"author":{"gitId":"-"},"content":" this.gracePeriod \u003d feedbackSession.getGracePeriod().toMinutes();"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" Instant sessionVisibleTime \u003d feedbackSession.getSessionVisibleFromTime();"},{"lineNumber":173,"author":{"gitId":"-"},"content":" this.sessionVisibleFromTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":174,"author":{"gitId":"-"},"content":" sessionVisibleTime, timeZone, true).toEpochMilli();"},{"lineNumber":175,"author":{"gitId":"-"},"content":" if (sessionVisibleTime.equals(Const.TIME_REPRESENTS_FOLLOW_OPENING)) {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" this.sessionVisibleSetting \u003d SessionVisibleSetting.AT_OPEN;"},{"lineNumber":177,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" this.sessionVisibleSetting \u003d SessionVisibleSetting.CUSTOM;"},{"lineNumber":179,"author":{"gitId":"-"},"content":" this.customSessionVisibleTimestamp \u003d this.sessionVisibleFromTimestamp;"},{"lineNumber":180,"author":{"gitId":"-"},"content":" }"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" Instant responseVisibleTime \u003d feedbackSession.getResultsVisibleFromTime();"},{"lineNumber":183,"author":{"gitId":"-"},"content":" this.resultVisibleFromTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":184,"author":{"gitId":"-"},"content":" responseVisibleTime, timeZone, true).toEpochMilli();"},{"lineNumber":185,"author":{"gitId":"-"},"content":" if (responseVisibleTime.equals(Const.TIME_REPRESENTS_FOLLOW_VISIBLE)) {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" this.responseVisibleSetting \u003d ResponseVisibleSetting.AT_VISIBLE;"},{"lineNumber":187,"author":{"gitId":"-"},"content":" } else if (responseVisibleTime.equals(Const.TIME_REPRESENTS_LATER)) {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" this.responseVisibleSetting \u003d ResponseVisibleSetting.LATER;"},{"lineNumber":189,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" this.responseVisibleSetting \u003d ResponseVisibleSetting.CUSTOM;"},{"lineNumber":191,"author":{"gitId":"-"},"content":" this.customResponseVisibleTimestamp \u003d this.resultVisibleFromTimestamp;"},{"lineNumber":192,"author":{"gitId":"-"},"content":" }"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"-"},"content":" if (!feedbackSession.isVisible()) {"},{"lineNumber":195,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.NOT_VISIBLE;"},{"lineNumber":196,"author":{"gitId":"-"},"content":" } else if (feedbackSession.isVisible() \u0026\u0026 !feedbackSession.isOpened()"},{"lineNumber":197,"author":{"gitId":"-"},"content":" \u0026\u0026 !feedbackSession.isClosed()) {"},{"lineNumber":198,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.VISIBLE_NOT_OPEN;"},{"lineNumber":199,"author":{"gitId":"-"},"content":" } else if (feedbackSession.isInGracePeriod()) {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.GRACE_PERIOD;"},{"lineNumber":201,"author":{"gitId":"-"},"content":" } else if (feedbackSession.isOpened()) {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.OPEN;"},{"lineNumber":203,"author":{"gitId":"-"},"content":" } else if (feedbackSession.isClosed()) {"},{"lineNumber":204,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.CLOSED;"},{"lineNumber":205,"author":{"gitId":"-"},"content":" }"},{"lineNumber":206,"author":{"gitId":"-"},"content":""},{"lineNumber":207,"author":{"gitId":"-"},"content":" if (feedbackSession.isPublished()) {"},{"lineNumber":208,"author":{"gitId":"-"},"content":" this.publishStatus \u003d FeedbackSessionPublishStatus.PUBLISHED;"},{"lineNumber":209,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" this.publishStatus \u003d FeedbackSessionPublishStatus.NOT_PUBLISHED;"},{"lineNumber":211,"author":{"gitId":"-"},"content":" }"},{"lineNumber":212,"author":{"gitId":"-"},"content":""},{"lineNumber":213,"author":{"gitId":"-"},"content":" this.isClosingEmailEnabled \u003d feedbackSession.isClosingEmailEnabled();"},{"lineNumber":214,"author":{"gitId":"-"},"content":" this.isPublishedEmailEnabled \u003d feedbackSession.isPublishedEmailEnabled();"},{"lineNumber":215,"author":{"gitId":"-"},"content":""},{"lineNumber":216,"author":{"gitId":"-"},"content":" this.createdAtTimestamp \u003d feedbackSession.getCreatedAt().toEpochMilli();"},{"lineNumber":217,"author":{"gitId":"-"},"content":" if (feedbackSession.getDeletedAt() \u003d\u003d null) {"},{"lineNumber":218,"author":{"gitId":"-"},"content":" this.deletedAtTimestamp \u003d null;"},{"lineNumber":219,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" this.deletedAtTimestamp \u003d feedbackSession.getDeletedAt().toEpochMilli();"},{"lineNumber":221,"author":{"gitId":"-"},"content":" }"},{"lineNumber":222,"author":{"gitId":"-"},"content":""},{"lineNumber":223,"author":{"gitId":"-"},"content":" this.studentDeadlines \u003d new HashMap\u003c\u003e();"},{"lineNumber":224,"author":{"gitId":"-"},"content":" this.instructorDeadlines \u003d new HashMap\u003c\u003e();"},{"lineNumber":225,"author":{"gitId":"-"},"content":""},{"lineNumber":226,"author":{"gitId":"-"},"content":" // place deadline extensions into appropriate student and instructor deadline maps"},{"lineNumber":227,"author":{"gitId":"-"},"content":" for (DeadlineExtension de : feedbackSession.getDeadlineExtensions()) {"},{"lineNumber":228,"author":{"gitId":"-"},"content":" if (de.getUser() instanceof Student) {"},{"lineNumber":229,"author":{"gitId":"-"},"content":" this.studentDeadlines.put(de.getUser().getEmail(),"},{"lineNumber":230,"author":{"gitId":"-"},"content":" TimeHelper.getMidnightAdjustedInstantBasedOnZone(de.getEndTime(), timeZone, true).toEpochMilli());"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":" if (de.getUser() instanceof Instructor) {"},{"lineNumber":233,"author":{"gitId":"-"},"content":" this.instructorDeadlines.put(de.getUser().getEmail(),"},{"lineNumber":234,"author":{"gitId":"-"},"content":" TimeHelper.getMidnightAdjustedInstantBasedOnZone(de.getEndTime(), timeZone, true).toEpochMilli());"},{"lineNumber":235,"author":{"gitId":"-"},"content":" }"},{"lineNumber":236,"author":{"gitId":"-"},"content":" }"},{"lineNumber":237,"author":{"gitId":"-"},"content":" }"},{"lineNumber":238,"author":{"gitId":"-"},"content":""},{"lineNumber":239,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":240,"author":{"gitId":"-"},"content":" * Constructs FeedbackSessionData for a given user deadline."},{"lineNumber":241,"author":{"gitId":"-"},"content":" */"},{"lineNumber":242,"author":{"gitId":"-"},"content":" public FeedbackSessionData(FeedbackSession feedbackSession, Instant extendedDeadline) {"},{"lineNumber":243,"author":{"gitId":"-"},"content":" this(feedbackSession);"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":" this.submissionEndWithExtensionTimestamp \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":246,"author":{"gitId":"-"},"content":" extendedDeadline, timeZone, true).toEpochMilli();"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" if (!feedbackSession.isVisible()) {"},{"lineNumber":249,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.NOT_VISIBLE;"},{"lineNumber":250,"author":{"gitId":"-"},"content":" } else if (feedbackSession.isVisible() \u0026\u0026 !feedbackSession.isOpenedGivenExtendedDeadline(extendedDeadline)"},{"lineNumber":251,"author":{"gitId":"-"},"content":" \u0026\u0026 !feedbackSession.isClosedGivenExtendedDeadline(extendedDeadline)) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.VISIBLE_NOT_OPEN;"},{"lineNumber":253,"author":{"gitId":"-"},"content":" } else if (feedbackSession.isInGracePeriodGivenExtendedDeadline(extendedDeadline)) {"},{"lineNumber":254,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.GRACE_PERIOD;"},{"lineNumber":255,"author":{"gitId":"-"},"content":" } else if (feedbackSession.isOpenedGivenExtendedDeadline(extendedDeadline)) {"},{"lineNumber":256,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.OPEN;"},{"lineNumber":257,"author":{"gitId":"-"},"content":" } else if (feedbackSession.isClosedGivenExtendedDeadline(extendedDeadline)) {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" this.submissionStatus \u003d FeedbackSessionSubmissionStatus.CLOSED;"},{"lineNumber":259,"author":{"gitId":"-"},"content":" }"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":""},{"lineNumber":262,"author":{"gitId":"dishenggg"},"content":" public UUID getFeedbackSessionId() {"},{"lineNumber":263,"author":{"gitId":"dishenggg"},"content":" return feedbackSessionId;"},{"lineNumber":264,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":265,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":266,"author":{"gitId":"-"},"content":" public String getCourseId() {"},{"lineNumber":267,"author":{"gitId":"-"},"content":" return courseId;"},{"lineNumber":268,"author":{"gitId":"-"},"content":" }"},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":" public String getTimeZone() {"},{"lineNumber":271,"author":{"gitId":"-"},"content":" return timeZone;"},{"lineNumber":272,"author":{"gitId":"-"},"content":" }"},{"lineNumber":273,"author":{"gitId":"-"},"content":""},{"lineNumber":274,"author":{"gitId":"-"},"content":" public String getFeedbackSessionName() {"},{"lineNumber":275,"author":{"gitId":"-"},"content":" return feedbackSessionName;"},{"lineNumber":276,"author":{"gitId":"-"},"content":" }"},{"lineNumber":277,"author":{"gitId":"-"},"content":""},{"lineNumber":278,"author":{"gitId":"-"},"content":" public String getInstructions() {"},{"lineNumber":279,"author":{"gitId":"-"},"content":" return instructions;"},{"lineNumber":280,"author":{"gitId":"-"},"content":" }"},{"lineNumber":281,"author":{"gitId":"-"},"content":""},{"lineNumber":282,"author":{"gitId":"-"},"content":" public long getSubmissionStartTimestamp() {"},{"lineNumber":283,"author":{"gitId":"-"},"content":" return submissionStartTimestamp;"},{"lineNumber":284,"author":{"gitId":"-"},"content":" }"},{"lineNumber":285,"author":{"gitId":"-"},"content":""},{"lineNumber":286,"author":{"gitId":"-"},"content":" public long getSubmissionEndTimestamp() {"},{"lineNumber":287,"author":{"gitId":"-"},"content":" return submissionEndTimestamp;"},{"lineNumber":288,"author":{"gitId":"-"},"content":" }"},{"lineNumber":289,"author":{"gitId":"-"},"content":""},{"lineNumber":290,"author":{"gitId":"-"},"content":" public long getSubmissionEndWithExtensionTimestamp() {"},{"lineNumber":291,"author":{"gitId":"-"},"content":" return submissionEndWithExtensionTimestamp;"},{"lineNumber":292,"author":{"gitId":"-"},"content":" }"},{"lineNumber":293,"author":{"gitId":"-"},"content":""},{"lineNumber":294,"author":{"gitId":"-"},"content":" public Long getSessionVisibleFromTimestamp() {"},{"lineNumber":295,"author":{"gitId":"-"},"content":" return sessionVisibleFromTimestamp;"},{"lineNumber":296,"author":{"gitId":"-"},"content":" }"},{"lineNumber":297,"author":{"gitId":"-"},"content":""},{"lineNumber":298,"author":{"gitId":"-"},"content":" public Long getResultVisibleFromTimestamp() {"},{"lineNumber":299,"author":{"gitId":"-"},"content":" return resultVisibleFromTimestamp;"},{"lineNumber":300,"author":{"gitId":"-"},"content":" }"},{"lineNumber":301,"author":{"gitId":"-"},"content":""},{"lineNumber":302,"author":{"gitId":"-"},"content":" public Long getGracePeriod() {"},{"lineNumber":303,"author":{"gitId":"-"},"content":" return gracePeriod;"},{"lineNumber":304,"author":{"gitId":"-"},"content":" }"},{"lineNumber":305,"author":{"gitId":"-"},"content":""},{"lineNumber":306,"author":{"gitId":"-"},"content":" public SessionVisibleSetting getSessionVisibleSetting() {"},{"lineNumber":307,"author":{"gitId":"-"},"content":" return sessionVisibleSetting;"},{"lineNumber":308,"author":{"gitId":"-"},"content":" }"},{"lineNumber":309,"author":{"gitId":"-"},"content":""},{"lineNumber":310,"author":{"gitId":"-"},"content":" public Long getCustomSessionVisibleTimestamp() {"},{"lineNumber":311,"author":{"gitId":"-"},"content":" return customSessionVisibleTimestamp;"},{"lineNumber":312,"author":{"gitId":"-"},"content":" }"},{"lineNumber":313,"author":{"gitId":"-"},"content":""},{"lineNumber":314,"author":{"gitId":"-"},"content":" public ResponseVisibleSetting getResponseVisibleSetting() {"},{"lineNumber":315,"author":{"gitId":"-"},"content":" return responseVisibleSetting;"},{"lineNumber":316,"author":{"gitId":"-"},"content":" }"},{"lineNumber":317,"author":{"gitId":"-"},"content":""},{"lineNumber":318,"author":{"gitId":"-"},"content":" public Long getCustomResponseVisibleTimestamp() {"},{"lineNumber":319,"author":{"gitId":"-"},"content":" return customResponseVisibleTimestamp;"},{"lineNumber":320,"author":{"gitId":"-"},"content":" }"},{"lineNumber":321,"author":{"gitId":"-"},"content":""},{"lineNumber":322,"author":{"gitId":"-"},"content":" public FeedbackSessionSubmissionStatus getSubmissionStatus() {"},{"lineNumber":323,"author":{"gitId":"-"},"content":" return submissionStatus;"},{"lineNumber":324,"author":{"gitId":"-"},"content":" }"},{"lineNumber":325,"author":{"gitId":"-"},"content":""},{"lineNumber":326,"author":{"gitId":"-"},"content":" public FeedbackSessionPublishStatus getPublishStatus() {"},{"lineNumber":327,"author":{"gitId":"-"},"content":" return publishStatus;"},{"lineNumber":328,"author":{"gitId":"-"},"content":" }"},{"lineNumber":329,"author":{"gitId":"-"},"content":""},{"lineNumber":330,"author":{"gitId":"-"},"content":" public Boolean getIsClosingEmailEnabled() {"},{"lineNumber":331,"author":{"gitId":"-"},"content":" return isClosingEmailEnabled;"},{"lineNumber":332,"author":{"gitId":"-"},"content":" }"},{"lineNumber":333,"author":{"gitId":"-"},"content":""},{"lineNumber":334,"author":{"gitId":"-"},"content":" public Boolean getIsPublishedEmailEnabled() {"},{"lineNumber":335,"author":{"gitId":"-"},"content":" return isPublishedEmailEnabled;"},{"lineNumber":336,"author":{"gitId":"-"},"content":" }"},{"lineNumber":337,"author":{"gitId":"-"},"content":""},{"lineNumber":338,"author":{"gitId":"-"},"content":" public Map\u003cString, Long\u003e getStudentDeadlines() {"},{"lineNumber":339,"author":{"gitId":"-"},"content":" return studentDeadlines;"},{"lineNumber":340,"author":{"gitId":"-"},"content":" }"},{"lineNumber":341,"author":{"gitId":"-"},"content":""},{"lineNumber":342,"author":{"gitId":"-"},"content":" public Map\u003cString, Long\u003e getInstructorDeadlines() {"},{"lineNumber":343,"author":{"gitId":"-"},"content":" return instructorDeadlines;"},{"lineNumber":344,"author":{"gitId":"-"},"content":" }"},{"lineNumber":345,"author":{"gitId":"-"},"content":""},{"lineNumber":346,"author":{"gitId":"-"},"content":" public void setSessionVisibleFromTimestamp(Long sessionVisibleFromTimestamp) {"},{"lineNumber":347,"author":{"gitId":"-"},"content":" this.sessionVisibleFromTimestamp \u003d sessionVisibleFromTimestamp;"},{"lineNumber":348,"author":{"gitId":"-"},"content":" }"},{"lineNumber":349,"author":{"gitId":"-"},"content":""},{"lineNumber":350,"author":{"gitId":"-"},"content":" public void setResultVisibleFromTimestamp(Long resultVisibleFromTimestamp) {"},{"lineNumber":351,"author":{"gitId":"-"},"content":" this.resultVisibleFromTimestamp \u003d resultVisibleFromTimestamp;"},{"lineNumber":352,"author":{"gitId":"-"},"content":" }"},{"lineNumber":353,"author":{"gitId":"-"},"content":""},{"lineNumber":354,"author":{"gitId":"-"},"content":" public void setGracePeriod(Long gracePeriod) {"},{"lineNumber":355,"author":{"gitId":"-"},"content":" this.gracePeriod \u003d gracePeriod;"},{"lineNumber":356,"author":{"gitId":"-"},"content":" }"},{"lineNumber":357,"author":{"gitId":"-"},"content":""},{"lineNumber":358,"author":{"gitId":"-"},"content":" public void setSessionVisibleSetting(SessionVisibleSetting sessionVisibleSetting) {"},{"lineNumber":359,"author":{"gitId":"-"},"content":" this.sessionVisibleSetting \u003d sessionVisibleSetting;"},{"lineNumber":360,"author":{"gitId":"-"},"content":" }"},{"lineNumber":361,"author":{"gitId":"-"},"content":""},{"lineNumber":362,"author":{"gitId":"-"},"content":" public void setCustomSessionVisibleTimestamp(Long customSessionVisibleTimestamp) {"},{"lineNumber":363,"author":{"gitId":"-"},"content":" this.customSessionVisibleTimestamp \u003d customSessionVisibleTimestamp;"},{"lineNumber":364,"author":{"gitId":"-"},"content":" }"},{"lineNumber":365,"author":{"gitId":"-"},"content":""},{"lineNumber":366,"author":{"gitId":"-"},"content":" public void setResponseVisibleSetting(ResponseVisibleSetting responseVisibleSetting) {"},{"lineNumber":367,"author":{"gitId":"-"},"content":" this.responseVisibleSetting \u003d responseVisibleSetting;"},{"lineNumber":368,"author":{"gitId":"-"},"content":" }"},{"lineNumber":369,"author":{"gitId":"-"},"content":""},{"lineNumber":370,"author":{"gitId":"-"},"content":" public void setCustomResponseVisibleTimestamp(Long customResponseVisibleTimestamp) {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" this.customResponseVisibleTimestamp \u003d customResponseVisibleTimestamp;"},{"lineNumber":372,"author":{"gitId":"-"},"content":" }"},{"lineNumber":373,"author":{"gitId":"-"},"content":""},{"lineNumber":374,"author":{"gitId":"-"},"content":" public void setPublishStatus(FeedbackSessionPublishStatus publishStatus) {"},{"lineNumber":375,"author":{"gitId":"-"},"content":" this.publishStatus \u003d publishStatus;"},{"lineNumber":376,"author":{"gitId":"-"},"content":" }"},{"lineNumber":377,"author":{"gitId":"-"},"content":""},{"lineNumber":378,"author":{"gitId":"-"},"content":" public void setClosingEmailEnabled(Boolean closingEmailEnabled) {"},{"lineNumber":379,"author":{"gitId":"-"},"content":" isClosingEmailEnabled \u003d closingEmailEnabled;"},{"lineNumber":380,"author":{"gitId":"-"},"content":" }"},{"lineNumber":381,"author":{"gitId":"-"},"content":""},{"lineNumber":382,"author":{"gitId":"-"},"content":" public void setPublishedEmailEnabled(Boolean publishedEmailEnabled) {"},{"lineNumber":383,"author":{"gitId":"-"},"content":" isPublishedEmailEnabled \u003d publishedEmailEnabled;"},{"lineNumber":384,"author":{"gitId":"-"},"content":" }"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"-"},"content":" public long getCreatedAtTimestamp() {"},{"lineNumber":387,"author":{"gitId":"-"},"content":" return createdAtTimestamp;"},{"lineNumber":388,"author":{"gitId":"-"},"content":" }"},{"lineNumber":389,"author":{"gitId":"-"},"content":""},{"lineNumber":390,"author":{"gitId":"-"},"content":" public void setCreatedAtTimestamp(long timestamp) {"},{"lineNumber":391,"author":{"gitId":"-"},"content":" createdAtTimestamp \u003d timestamp;"},{"lineNumber":392,"author":{"gitId":"-"},"content":" }"},{"lineNumber":393,"author":{"gitId":"-"},"content":""},{"lineNumber":394,"author":{"gitId":"-"},"content":" public Long getDeletedAtTimestamp() {"},{"lineNumber":395,"author":{"gitId":"-"},"content":" return deletedAtTimestamp;"},{"lineNumber":396,"author":{"gitId":"-"},"content":" }"},{"lineNumber":397,"author":{"gitId":"-"},"content":""},{"lineNumber":398,"author":{"gitId":"-"},"content":" public InstructorPermissionSet getPrivileges() {"},{"lineNumber":399,"author":{"gitId":"-"},"content":" return privileges;"},{"lineNumber":400,"author":{"gitId":"-"},"content":" }"},{"lineNumber":401,"author":{"gitId":"-"},"content":""},{"lineNumber":402,"author":{"gitId":"-"},"content":" public void setPrivileges(InstructorPermissionSet privileges) {"},{"lineNumber":403,"author":{"gitId":"-"},"content":" this.privileges \u003d privileges;"},{"lineNumber":404,"author":{"gitId":"-"},"content":" }"},{"lineNumber":405,"author":{"gitId":"-"},"content":""},{"lineNumber":406,"author":{"gitId":"-"},"content":" public void setStudentDeadlines(Map\u003cString, Long\u003e studentDeadlines) {"},{"lineNumber":407,"author":{"gitId":"-"},"content":" this.studentDeadlines \u003d studentDeadlines;"},{"lineNumber":408,"author":{"gitId":"-"},"content":" }"},{"lineNumber":409,"author":{"gitId":"-"},"content":""},{"lineNumber":410,"author":{"gitId":"-"},"content":" public void setInstructorDeadlines(Map\u003cString, Long\u003e instructorDeadlines) {"},{"lineNumber":411,"author":{"gitId":"-"},"content":" this.instructorDeadlines \u003d instructorDeadlines;"},{"lineNumber":412,"author":{"gitId":"-"},"content":" }"},{"lineNumber":413,"author":{"gitId":"-"},"content":""},{"lineNumber":414,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":415,"author":{"gitId":"-"},"content":" * Hides some attributes to student."},{"lineNumber":416,"author":{"gitId":"-"},"content":" */"},{"lineNumber":417,"author":{"gitId":"-"},"content":" public void hideInformationForStudent() {"},{"lineNumber":418,"author":{"gitId":"-"},"content":" hideInformationForStudentAndInstructor();"},{"lineNumber":419,"author":{"gitId":"-"},"content":" hideSessionVisibilityTimestamps();"},{"lineNumber":420,"author":{"gitId":"-"},"content":" instructorDeadlines.clear();"},{"lineNumber":421,"author":{"gitId":"-"},"content":" }"},{"lineNumber":422,"author":{"gitId":"-"},"content":""},{"lineNumber":423,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":424,"author":{"gitId":"-"},"content":" * Hides some attributes to student."},{"lineNumber":425,"author":{"gitId":"-"},"content":" */"},{"lineNumber":426,"author":{"gitId":"-"},"content":" public void hideInformationForStudent(String studentEmail) {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" hideInformationForStudentAndInstructor();"},{"lineNumber":428,"author":{"gitId":"-"},"content":" hideSessionVisibilityTimestamps();"},{"lineNumber":429,"author":{"gitId":"-"},"content":" studentDeadlines.keySet().removeIf(email -\u003e !(email.equals(studentEmail)));"},{"lineNumber":430,"author":{"gitId":"-"},"content":" instructorDeadlines.clear();"},{"lineNumber":431,"author":{"gitId":"-"},"content":" }"},{"lineNumber":432,"author":{"gitId":"-"},"content":""},{"lineNumber":433,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":434,"author":{"gitId":"-"},"content":" * Hides some attributes to instructor without appropriate privilege."},{"lineNumber":435,"author":{"gitId":"-"},"content":" */"},{"lineNumber":436,"author":{"gitId":"-"},"content":" public void hideInformationForInstructor() {"},{"lineNumber":437,"author":{"gitId":"-"},"content":" hideInformationForStudentAndInstructor();"},{"lineNumber":438,"author":{"gitId":"-"},"content":" studentDeadlines.clear();"},{"lineNumber":439,"author":{"gitId":"-"},"content":" }"},{"lineNumber":440,"author":{"gitId":"-"},"content":""},{"lineNumber":441,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":442,"author":{"gitId":"-"},"content":" * Hides some attributes to instructor without appropriate privilege."},{"lineNumber":443,"author":{"gitId":"-"},"content":" */"},{"lineNumber":444,"author":{"gitId":"-"},"content":" public void hideInformationForInstructor(String instructorEmail) {"},{"lineNumber":445,"author":{"gitId":"-"},"content":" hideInformationForStudentAndInstructor();"},{"lineNumber":446,"author":{"gitId":"-"},"content":" instructorDeadlines.keySet().removeIf(email -\u003e !(email.equals(instructorEmail)));"},{"lineNumber":447,"author":{"gitId":"-"},"content":" studentDeadlines.clear();"},{"lineNumber":448,"author":{"gitId":"-"},"content":" }"},{"lineNumber":449,"author":{"gitId":"-"},"content":""},{"lineNumber":450,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":451,"author":{"gitId":"-"},"content":" * Hides some attributes for instructor who is submitting feedback session."},{"lineNumber":452,"author":{"gitId":"-"},"content":" */"},{"lineNumber":453,"author":{"gitId":"-"},"content":" public void hideInformationForInstructorSubmission() {"},{"lineNumber":454,"author":{"gitId":"-"},"content":" hideInformationForInstructor();"},{"lineNumber":455,"author":{"gitId":"-"},"content":" hideSessionVisibilityTimestamps();"},{"lineNumber":456,"author":{"gitId":"-"},"content":" }"},{"lineNumber":457,"author":{"gitId":"-"},"content":""},{"lineNumber":458,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":459,"author":{"gitId":"-"},"content":" * Hides some attributes for instructor who is submitting feedback session."},{"lineNumber":460,"author":{"gitId":"-"},"content":" */"},{"lineNumber":461,"author":{"gitId":"-"},"content":" public void hideInformationForInstructorSubmission(String userEmail) {"},{"lineNumber":462,"author":{"gitId":"-"},"content":" hideInformationForInstructor(userEmail);"},{"lineNumber":463,"author":{"gitId":"-"},"content":" hideSessionVisibilityTimestamps();"},{"lineNumber":464,"author":{"gitId":"-"},"content":" }"},{"lineNumber":465,"author":{"gitId":"-"},"content":""},{"lineNumber":466,"author":{"gitId":"-"},"content":" private void hideSessionVisibilityTimestamps() {"},{"lineNumber":467,"author":{"gitId":"-"},"content":" setSessionVisibleFromTimestamp(null);"},{"lineNumber":468,"author":{"gitId":"-"},"content":" setResultVisibleFromTimestamp(null);"},{"lineNumber":469,"author":{"gitId":"-"},"content":" setSessionVisibleSetting(null);"},{"lineNumber":470,"author":{"gitId":"-"},"content":" setCustomSessionVisibleTimestamp(null);"},{"lineNumber":471,"author":{"gitId":"-"},"content":" setResponseVisibleSetting(null);"},{"lineNumber":472,"author":{"gitId":"-"},"content":" setCustomResponseVisibleTimestamp(null);"},{"lineNumber":473,"author":{"gitId":"-"},"content":" }"},{"lineNumber":474,"author":{"gitId":"-"},"content":""},{"lineNumber":475,"author":{"gitId":"-"},"content":" private void hideInformationForStudentAndInstructor() {"},{"lineNumber":476,"author":{"gitId":"-"},"content":" setClosingEmailEnabled(null);"},{"lineNumber":477,"author":{"gitId":"-"},"content":" setPublishedEmailEnabled(null);"},{"lineNumber":478,"author":{"gitId":"-"},"content":" setGracePeriod(null);"},{"lineNumber":479,"author":{"gitId":"-"},"content":" setCreatedAtTimestamp(0);"},{"lineNumber":480,"author":{"gitId":"-"},"content":" }"},{"lineNumber":481,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":11,"-":470}},{"path":"src/main/java/teammates/ui/output/FeedbackSessionLogData.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.output;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":15,"author":{"gitId":"-"},"content":" * The response log of a single feedback session."},{"lineNumber":16,"author":{"gitId":"-"},"content":" */"},{"lineNumber":17,"author":{"gitId":"-"},"content":"public class FeedbackSessionLogData {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" private final FeedbackSessionData feedbackSessionData;"},{"lineNumber":19,"author":{"gitId":"-"},"content":" private final List\u003cFeedbackSessionLogEntryData\u003e feedbackSessionLogEntries;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":" // Remove generic types after migration is done (i.e. can just use FeedbackSession, Student, FeedbackSessionLog)"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" public \u003cS, T, U\u003e FeedbackSessionLogData(S feedbackSession, List\u003cU\u003e logEntries,"},{"lineNumber":23,"author":{"gitId":"-"},"content":" Map\u003cString, T\u003e studentsMap) {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" if (feedbackSession instanceof FeedbackSessionAttributes) {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes fs \u003d (FeedbackSessionAttributes) feedbackSession;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" FeedbackSessionData fsData \u003d new FeedbackSessionData(fs);"},{"lineNumber":27,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogEntryData\u003e fsLogEntryDatas \u003d logEntries.stream()"},{"lineNumber":28,"author":{"gitId":"-"},"content":" .map(log -\u003e {"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" if (log instanceof FeedbackSessionLogEntry) {"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogEntry convertedLog \u003d (FeedbackSessionLogEntry) log;"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" T student \u003d studentsMap.get(convertedLog.getStudentEmail());"},{"lineNumber":32,"author":{"gitId":"-"},"content":" if (student instanceof StudentAttributes) {"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" return new FeedbackSessionLogEntryData(convertedLog, (StudentAttributes) student);"},{"lineNumber":34,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" throw new IllegalArgumentException(\"Invalid student type\");"},{"lineNumber":36,"author":{"gitId":"-"},"content":" }"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" throw new IllegalArgumentException(\"Invalid log type\");"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":" })"},{"lineNumber":41,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":42,"author":{"gitId":"-"},"content":" this.feedbackSessionData \u003d fsData;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" this.feedbackSessionLogEntries \u003d fsLogEntryDatas;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" } else if (feedbackSession instanceof FeedbackSession) {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d (FeedbackSession) feedbackSession;"},{"lineNumber":46,"author":{"gitId":"-"},"content":" FeedbackSessionData fsData \u003d new FeedbackSessionData(fs);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogEntryData\u003e fsLogEntryDatas \u003d logEntries.stream()"},{"lineNumber":48,"author":{"gitId":"-"},"content":" .map(log -\u003e {"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" if (log instanceof FeedbackSessionLog) {"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog convertedLog \u003d (FeedbackSessionLog) log;"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" T student \u003d studentsMap.get(convertedLog.getStudent().getEmail());"},{"lineNumber":52,"author":{"gitId":"-"},"content":" if (student instanceof Student) {"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" return new FeedbackSessionLogEntryData(convertedLog, (Student) student);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" throw new IllegalArgumentException(\"Invalid student type\");"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" throw new IllegalArgumentException(\"Invalid log type\");"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":" })"},{"lineNumber":61,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":62,"author":{"gitId":"-"},"content":" this.feedbackSessionData \u003d fsData;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" this.feedbackSessionLogEntries \u003d fsLogEntryDatas;"},{"lineNumber":64,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" throw new IllegalArgumentException(\"Invalid feedback session type\");"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" public FeedbackSessionData getFeedbackSessionData() {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" return feedbackSessionData;"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":74,"author":{"gitId":"-"},"content":" * Returns all feedback session log entries."},{"lineNumber":75,"author":{"gitId":"-"},"content":" */"},{"lineNumber":76,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSessionLogEntryData\u003e getFeedbackSessionLogEntries() {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" return feedbackSessionLogEntries;"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }"},{"lineNumber":79,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":17,"-":62}},{"path":"src/main/java/teammates/ui/output/FeedbackSessionLogEntryData.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.output;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":10,"author":{"gitId":"-"},"content":" * The session log of a student for a single feedback session."},{"lineNumber":11,"author":{"gitId":"-"},"content":" */"},{"lineNumber":12,"author":{"gitId":"-"},"content":"public class FeedbackSessionLogEntryData {"},{"lineNumber":13,"author":{"gitId":"-"},"content":" private final StudentData studentData;"},{"lineNumber":14,"author":{"gitId":"-"},"content":" private final FeedbackSessionLogType feedbackSessionLogType;"},{"lineNumber":15,"author":{"gitId":"-"},"content":" private final long timestamp;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":" public FeedbackSessionLogEntryData(FeedbackSessionLogEntry logEntry, StudentAttributes student) {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" StudentData studentData \u003d new StudentData(student);"},{"lineNumber":19,"author":{"gitId":"-"},"content":" FeedbackSessionLogType logType \u003d FeedbackSessionLogType.valueOfLabel(logEntry.getFeedbackSessionLogType());"},{"lineNumber":20,"author":{"gitId":"-"},"content":" long timestamp \u003d logEntry.getTimestamp();"},{"lineNumber":21,"author":{"gitId":"-"},"content":" this.studentData \u003d studentData;"},{"lineNumber":22,"author":{"gitId":"-"},"content":" this.feedbackSessionLogType \u003d logType;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" this.timestamp \u003d timestamp;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" }"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" public FeedbackSessionLogEntryData(FeedbackSessionLog logEntry, Student student) {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" StudentData studentData \u003d new StudentData(student);"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType logType \u003d logEntry.getFeedbackSessionLogType();"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" long timestamp \u003d logEntry.getTimestamp().toEpochMilli();"},{"lineNumber":30,"author":{"gitId":"-"},"content":" this.studentData \u003d studentData;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" this.feedbackSessionLogType \u003d logType;"},{"lineNumber":32,"author":{"gitId":"-"},"content":" this.timestamp \u003d timestamp;"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" public StudentData getStudentData() {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" return studentData;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" }"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" public FeedbackSessionLogType getFeedbackSessionLogType() {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" return feedbackSessionLogType;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" public long getTimestamp() {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return timestamp;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":4,"-":42}},{"path":"src/main/java/teammates/ui/output/FeedbackSessionLogsData.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.output;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":8,"author":{"gitId":"-"},"content":" * The API output format for logs on all feedback sessions in a course."},{"lineNumber":9,"author":{"gitId":"-"},"content":" */"},{"lineNumber":10,"author":{"gitId":"-"},"content":"public class FeedbackSessionLogsData extends ApiOutput {"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":" private final List\u003cFeedbackSessionLogData\u003e feedbackSessionLogs;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":" // Remove generic types after migration is done (i.e. can just use FeedbackSession and Student, FeedbackSessionLog)"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":" public \u003cS, T, U\u003e FeedbackSessionLogsData(Map\u003cString, List\u003cU\u003e\u003e groupedEntries,"},{"lineNumber":16,"author":{"gitId":"-"},"content":" Map\u003cString, S\u003e studentsMap, Map\u003cString, T\u003e sessionsMap) {"},{"lineNumber":17,"author":{"gitId":"-"},"content":" this.feedbackSessionLogs \u003d groupedEntries.entrySet().stream()"},{"lineNumber":18,"author":{"gitId":"-"},"content":" .map(entry -\u003e {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" T feedbackSession \u003d sessionsMap.get(entry.getKey());"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":" List\u003cU\u003e logEntries \u003d entry.getValue();"},{"lineNumber":21,"author":{"gitId":"-"},"content":" return new FeedbackSessionLogData(feedbackSession, logEntries, studentsMap);"},{"lineNumber":22,"author":{"gitId":"-"},"content":" })"},{"lineNumber":23,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":24,"author":{"gitId":"-"},"content":" }"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" public List\u003cFeedbackSessionLogData\u003e getFeedbackSessionLogs() {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" return feedbackSessionLogs;"},{"lineNumber":28,"author":{"gitId":"-"},"content":" }"},{"lineNumber":29,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":3,"-":26}},{"path":"src/main/java/teammates/ui/output/NotificationData.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.output;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import org.threeten.bp.Instant;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationStyle;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationTargetUser;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.NotificationAttributes;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * The API output format of a notification."},{"lineNumber":12,"author":{"gitId":"-"},"content":" */"},{"lineNumber":13,"author":{"gitId":"-"},"content":"public class NotificationData extends ApiOutput {"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":" private String notificationId;"},{"lineNumber":16,"author":{"gitId":"-"},"content":" private long startTimestamp;"},{"lineNumber":17,"author":{"gitId":"-"},"content":" private long endTimestamp;"},{"lineNumber":18,"author":{"gitId":"-"},"content":" private long createdAt;"},{"lineNumber":19,"author":{"gitId":"-"},"content":" private NotificationStyle style;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" private NotificationTargetUser targetUser;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" private String title;"},{"lineNumber":22,"author":{"gitId":"-"},"content":" private String message;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" private boolean shown;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" public NotificationData(NotificationAttributes notificationAttributes) {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" this.notificationId \u003d notificationAttributes.getNotificationId();"},{"lineNumber":27,"author":{"gitId":"-"},"content":" this.startTimestamp \u003d notificationAttributes.getStartTime().toEpochMilli();"},{"lineNumber":28,"author":{"gitId":"-"},"content":" this.endTimestamp \u003d notificationAttributes.getEndTime().toEpochMilli();"},{"lineNumber":29,"author":{"gitId":"-"},"content":" this.createdAt \u003d notificationAttributes.getCreatedAt().toEpochMilli();"},{"lineNumber":30,"author":{"gitId":"-"},"content":" this.style \u003d notificationAttributes.getStyle();"},{"lineNumber":31,"author":{"gitId":"-"},"content":" this.targetUser \u003d notificationAttributes.getTargetUser();"},{"lineNumber":32,"author":{"gitId":"-"},"content":" this.title \u003d notificationAttributes.getTitle();"},{"lineNumber":33,"author":{"gitId":"-"},"content":" this.message \u003d notificationAttributes.getMessage();"},{"lineNumber":34,"author":{"gitId":"-"},"content":" this.shown \u003d notificationAttributes.isShown();"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" public NotificationData(Notification notification) {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" this.notificationId \u003d notification.getId().toString();"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.startTimestamp \u003d notification.getStartTime().toEpochMilli();"},{"lineNumber":40,"author":{"gitId":"-"},"content":" this.endTimestamp \u003d notification.getEndTime().toEpochMilli();"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" this.createdAt \u003d notification.getCreatedAt() \u003d\u003d null"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" ? Instant.now().toEpochMilli() : notification.getCreatedAt().toEpochMilli();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" this.style \u003d notification.getStyle();"},{"lineNumber":44,"author":{"gitId":"-"},"content":" this.targetUser \u003d notification.getTargetUser();"},{"lineNumber":45,"author":{"gitId":"-"},"content":" this.title \u003d notification.getTitle();"},{"lineNumber":46,"author":{"gitId":"-"},"content":" this.message \u003d notification.getMessage();"},{"lineNumber":47,"author":{"gitId":"-"},"content":" this.shown \u003d notification.isShown();"},{"lineNumber":48,"author":{"gitId":"-"},"content":" }"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" public String getNotificationId() {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" return this.notificationId;"},{"lineNumber":52,"author":{"gitId":"-"},"content":" }"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" public long getStartTimestamp() {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" return this.startTimestamp;"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" public long getEndTimestamp() {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" return this.endTimestamp;"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" public long getCreatedAt() {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" return this.createdAt;"},{"lineNumber":64,"author":{"gitId":"-"},"content":" }"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" public NotificationStyle getStyle() {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" return this.style;"},{"lineNumber":68,"author":{"gitId":"-"},"content":" }"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" public NotificationTargetUser getTargetUser() {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" return this.targetUser;"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" public String getTitle() {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" return this.title;"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" public String getMessage() {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" return this.message;"},{"lineNumber":80,"author":{"gitId":"-"},"content":" }"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" public boolean isShown() {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" return this.shown;"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":4,"-":81}},{"path":"src/main/java/teammates/ui/output/SessionResultsData.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.output;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Collections;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.LinkedList;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.Queue;"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"import java.util.Set;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.CourseRoster;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SessionResultsBundle;"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.SqlCourseRoster;"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.SqlSessionResultsBundle;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseAttributes;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseCommentAttributes;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionDetails;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackResponseDetails;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.common.util.StringHelper;"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":36,"author":{"gitId":"-"},"content":" * API output format for session results, including statistics."},{"lineNumber":37,"author":{"gitId":"-"},"content":" */"},{"lineNumber":38,"author":{"gitId":"-"},"content":"public class SessionResultsData extends ApiOutput {"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" private static final String REGEX_ANONYMOUS_PARTICIPANT_HASH \u003d \"[0-9]{1,10}\";"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" final List\u003cQuestionOutput\u003e questions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" SessionResultsData() {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" // use factory method instead"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":49,"author":{"gitId":"-"},"content":" * Factory method to construct API output for instructor."},{"lineNumber":50,"author":{"gitId":"-"},"content":" */"},{"lineNumber":51,"author":{"gitId":"-"},"content":" public static SessionResultsData initForInstructor(SessionResultsBundle bundle) {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" SessionResultsData sessionResultsData \u003d new SessionResultsData();"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" Map\u003cString, List\u003cFeedbackResponseAttributes\u003e\u003e questionsWithResponses \u003d"},{"lineNumber":55,"author":{"gitId":"-"},"content":" bundle.getQuestionResponseMap();"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" questionsWithResponses.forEach((questionId, responses) -\u003e {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes question \u003d bundle.getQuestionsMap().get(questionId);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails questionDetails \u003d question.getQuestionDetailsCopy();"},{"lineNumber":60,"author":{"gitId":"-"},"content":" QuestionOutput qnOutput \u003d new QuestionOutput(question,"},{"lineNumber":61,"author":{"gitId":"-"},"content":" questionDetails.getQuestionResultStatisticsJson(question, null, bundle), false, false);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" // put normal responses"},{"lineNumber":63,"author":{"gitId":"-"},"content":" List\u003cResponseOutput\u003e allResponses \u003d buildResponsesForInstructor(responses, bundle, false);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" qnOutput.allResponses.addAll(allResponses);"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" // put missing responses"},{"lineNumber":67,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponseAttributes\u003e missingResponses \u003d bundle.getQuestionMissingResponseMap().get(questionId);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" qnOutput.allResponses.addAll(buildResponsesForInstructor(missingResponses, bundle, true));"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" sessionResultsData.questions.add(qnOutput);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" });"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" return sessionResultsData;"},{"lineNumber":74,"author":{"gitId":"-"},"content":" }"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":" * Factory method to construct API output for instructor."},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":" public static SessionResultsData initForInstructor(SqlSessionResultsBundle bundle) {"},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" SessionResultsData sessionResultsData \u003d new SessionResultsData();"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackQuestion, List\u003cFeedbackResponse\u003e\u003e questionsWithResponses \u003d"},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" bundle.getQuestionResponseMap();"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":" questionsWithResponses.forEach((question, responses) -\u003e {"},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":" FeedbackQuestionDetails questionDetails \u003d question.getQuestionDetailsCopy();"},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":" QuestionOutput qnOutput \u003d new QuestionOutput(question,"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" questionDetails.getQuestionResultStatisticsJson(question, null, bundle), false, false);"},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":" // put normal responses"},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" List\u003cResponseOutput\u003e allResponses \u003d buildResponsesForInstructor(responses, bundle, false);"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":" qnOutput.allResponses.addAll(allResponses);"},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":93,"author":{"gitId":"xenosf"},"content":" // put missing responses"},{"lineNumber":94,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e missingResponses \u003d bundle.getQuestionMissingResponseMap().get(question);"},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":" qnOutput.allResponses.addAll(buildResponsesForInstructor(missingResponses, bundle, true));"},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" sessionResultsData.questions.add(qnOutput);"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":100,"author":{"gitId":"xenosf"},"content":" return sessionResultsData;"},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":102,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":104,"author":{"gitId":"-"},"content":" * Factory method to construct API output for student."},{"lineNumber":105,"author":{"gitId":"-"},"content":" */"},{"lineNumber":106,"author":{"gitId":"-"},"content":" public static SessionResultsData initForStudent(SessionResultsBundle bundle, StudentAttributes student) {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" SessionResultsData sessionResultsData \u003d new SessionResultsData();"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" Map\u003cString, List\u003cFeedbackResponseAttributes\u003e\u003e questionsWithResponses \u003d"},{"lineNumber":110,"author":{"gitId":"-"},"content":" bundle.getQuestionResponseMap();"},{"lineNumber":111,"author":{"gitId":"-"},"content":" questionsWithResponses.forEach((questionId, responses) -\u003e {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes question \u003d bundle.getQuestionsMap().get(questionId);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails questionDetails \u003d question.getQuestionDetailsCopy();"},{"lineNumber":114,"author":{"gitId":"-"},"content":" // check if question has comments (on any responses) not visible for preview"},{"lineNumber":115,"author":{"gitId":"-"},"content":" boolean hasCommentNotVisibleForPreview \u003d bundle.getQuestionsWithCommentNotVisibleForPreview()"},{"lineNumber":116,"author":{"gitId":"-"},"content":" .contains(questionId);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" QuestionOutput qnOutput \u003d new QuestionOutput(question,"},{"lineNumber":118,"author":{"gitId":"-"},"content":" questionDetails.getQuestionResultStatisticsJson(question, student.getEmail(), bundle),"},{"lineNumber":119,"author":{"gitId":"-"},"content":" false, hasCommentNotVisibleForPreview);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" Map\u003cString, List\u003cResponseOutput\u003e\u003e otherResponsesMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" qnOutput.getFeedbackQuestion().hideInformationForStudent();"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" if (questionDetails.isIndividualResponsesShownToStudents()) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" for (FeedbackResponseAttributes response : responses) {"},{"lineNumber":126,"author":{"gitId":"-"},"content":" boolean isUserInstructor \u003d Const.USER_TEAM_FOR_INSTRUCTOR.equals(student.getTeam());"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" boolean isUserGiver \u003d student.getEmail().equals(response.getGiver())"},{"lineNumber":129,"author":{"gitId":"-"},"content":" \u0026\u0026 (isUserInstructor \u0026\u0026 question.getGiverType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":130,"author":{"gitId":"-"},"content":" || !isUserInstructor \u0026\u0026 question.getGiverType() !\u003d FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" boolean isUserRecipient \u003d student.getEmail().equals(response.getRecipient())"},{"lineNumber":132,"author":{"gitId":"-"},"content":" \u0026\u0026 (isUserInstructor \u0026\u0026 question.getRecipientType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":133,"author":{"gitId":"-"},"content":" || !isUserInstructor \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" ResponseOutput responseOutput \u003d buildSingleResponseForStudent(response, bundle, student);"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" if (isUserRecipient) {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" qnOutput.responsesToSelf.add(responseOutput);"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" if (isUserGiver) {"},{"lineNumber":141,"author":{"gitId":"-"},"content":" qnOutput.responsesFromSelf.add(responseOutput);"},{"lineNumber":142,"author":{"gitId":"-"},"content":" }"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" if (!isUserRecipient \u0026\u0026 !isUserGiver) {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" // we don\u0027t need care about the keys of the map here"},{"lineNumber":146,"author":{"gitId":"-"},"content":" // as only the values of the map will be used"},{"lineNumber":147,"author":{"gitId":"-"},"content":" otherResponsesMap.computeIfAbsent(response.getRecipient(), k -\u003e new ArrayList\u003c\u003e())"},{"lineNumber":148,"author":{"gitId":"-"},"content":" .add(responseOutput);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" }"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" qnOutput.allResponses.add(responseOutput);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" }"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":" qnOutput.otherResponses.addAll(otherResponsesMap.values());"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" sessionResultsData.questions.add(qnOutput);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" });"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" Map\u003cString, FeedbackQuestionAttributes\u003e questionsWithResponsesNotVisibleForPreview \u003d"},{"lineNumber":160,"author":{"gitId":"-"},"content":" bundle.getQuestionsNotVisibleForPreviewMap();"},{"lineNumber":161,"author":{"gitId":"-"},"content":" questionsWithResponsesNotVisibleForPreview.forEach((questionId, question) -\u003e {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" QuestionOutput qnOutput \u003d new QuestionOutput(question, \"\", true, false);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" sessionResultsData.questions.add(qnOutput);"},{"lineNumber":164,"author":{"gitId":"-"},"content":" });"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" return sessionResultsData;"},{"lineNumber":167,"author":{"gitId":"-"},"content":" }"},{"lineNumber":168,"author":{"gitId":"-"},"content":""},{"lineNumber":169,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":170,"author":{"gitId":"xenosf"},"content":" * Factory method to construct API output for student."},{"lineNumber":171,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":172,"author":{"gitId":"xenosf"},"content":" public static SessionResultsData initForStudent(SqlSessionResultsBundle bundle, Student student) {"},{"lineNumber":173,"author":{"gitId":"xenosf"},"content":" SessionResultsData sessionResultsData \u003d new SessionResultsData();"},{"lineNumber":174,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":175,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackQuestion, List\u003cFeedbackResponse\u003e\u003e questionsWithResponses \u003d"},{"lineNumber":176,"author":{"gitId":"xenosf"},"content":" bundle.getQuestionResponseMap();"},{"lineNumber":177,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":178,"author":{"gitId":"xenosf"},"content":" questionsWithResponses.forEach((question, responses) -\u003e {"},{"lineNumber":179,"author":{"gitId":"xenosf"},"content":" FeedbackQuestionDetails questionDetails \u003d question.getQuestionDetailsCopy();"},{"lineNumber":180,"author":{"gitId":"xenosf"},"content":" // check if question has comments (on any responses) not visible for preview"},{"lineNumber":181,"author":{"gitId":"xenosf"},"content":" boolean hasCommentNotVisibleForPreview \u003d bundle.getQuestionsWithCommentNotVisibleForPreviewSet()"},{"lineNumber":182,"author":{"gitId":"xenosf"},"content":" .contains(question);"},{"lineNumber":183,"author":{"gitId":"xenosf"},"content":" QuestionOutput qnOutput \u003d new QuestionOutput(question,"},{"lineNumber":184,"author":{"gitId":"xenosf"},"content":" questionDetails.getQuestionResultStatisticsJson(question, student.getEmail(), bundle),"},{"lineNumber":185,"author":{"gitId":"xenosf"},"content":" false, hasCommentNotVisibleForPreview);"},{"lineNumber":186,"author":{"gitId":"xenosf"},"content":" Map\u003cString, List\u003cResponseOutput\u003e\u003e otherResponsesMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":187,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":188,"author":{"gitId":"xenosf"},"content":" qnOutput.getFeedbackQuestion().hideInformationForStudent();"},{"lineNumber":189,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":190,"author":{"gitId":"xenosf"},"content":" if (questionDetails.isIndividualResponsesShownToStudents()) {"},{"lineNumber":191,"author":{"gitId":"xenosf"},"content":" for (FeedbackResponse response : responses) {"},{"lineNumber":192,"author":{"gitId":"xenosf"},"content":" boolean isUserInstructor \u003d Const.USER_TEAM_FOR_INSTRUCTOR.equals(student.getTeamName());"},{"lineNumber":193,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":194,"author":{"gitId":"xenosf"},"content":" boolean isUserGiver \u003d student.getEmail().equals(response.getGiver())"},{"lineNumber":195,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 (isUserInstructor \u0026\u0026 question.getGiverType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":196,"author":{"gitId":"xenosf"},"content":" || !isUserInstructor \u0026\u0026 question.getGiverType() !\u003d FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":197,"author":{"gitId":"xenosf"},"content":" boolean isUserRecipient \u003d student.getEmail().equals(response.getRecipient())"},{"lineNumber":198,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 (isUserInstructor \u0026\u0026 question.getRecipientType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":199,"author":{"gitId":"xenosf"},"content":" || !isUserInstructor \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":200,"author":{"gitId":"xenosf"},"content":" ResponseOutput responseOutput \u003d buildSingleResponseForStudent(response, bundle, student);"},{"lineNumber":201,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":202,"author":{"gitId":"xenosf"},"content":" if (isUserRecipient) {"},{"lineNumber":203,"author":{"gitId":"xenosf"},"content":" qnOutput.responsesToSelf.add(responseOutput);"},{"lineNumber":204,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":205,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":206,"author":{"gitId":"xenosf"},"content":" if (isUserGiver) {"},{"lineNumber":207,"author":{"gitId":"xenosf"},"content":" qnOutput.responsesFromSelf.add(responseOutput);"},{"lineNumber":208,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":209,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":210,"author":{"gitId":"xenosf"},"content":" if (!isUserRecipient \u0026\u0026 !isUserGiver) {"},{"lineNumber":211,"author":{"gitId":"xenosf"},"content":" // we don\u0027t need care about the keys of the map here"},{"lineNumber":212,"author":{"gitId":"xenosf"},"content":" // as only the values of the map will be used"},{"lineNumber":213,"author":{"gitId":"xenosf"},"content":" otherResponsesMap.computeIfAbsent(response.getRecipient(), k -\u003e new ArrayList\u003c\u003e())"},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" .add(responseOutput);"},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":217,"author":{"gitId":"xenosf"},"content":" qnOutput.allResponses.add(responseOutput);"},{"lineNumber":218,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":219,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":220,"author":{"gitId":"xenosf"},"content":" qnOutput.otherResponses.addAll(otherResponsesMap.values());"},{"lineNumber":221,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":222,"author":{"gitId":"xenosf"},"content":" sessionResultsData.questions.add(qnOutput);"},{"lineNumber":223,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":224,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":225,"author":{"gitId":"xenosf"},"content":" Set\u003cFeedbackQuestion\u003e questionsWithResponsesNotVisibleForPreview \u003d"},{"lineNumber":226,"author":{"gitId":"xenosf"},"content":" bundle.getQuestionsNotVisibleForPreviewSet();"},{"lineNumber":227,"author":{"gitId":"xenosf"},"content":" questionsWithResponsesNotVisibleForPreview.forEach(question -\u003e {"},{"lineNumber":228,"author":{"gitId":"xenosf"},"content":" QuestionOutput qnOutput \u003d new QuestionOutput(question, \"\", true, false);"},{"lineNumber":229,"author":{"gitId":"xenosf"},"content":" sessionResultsData.questions.add(qnOutput);"},{"lineNumber":230,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":231,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":232,"author":{"gitId":"xenosf"},"content":" return sessionResultsData;"},{"lineNumber":233,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":234,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":235,"author":{"gitId":"-"},"content":" private static ResponseOutput buildSingleResponseForStudent("},{"lineNumber":236,"author":{"gitId":"-"},"content":" FeedbackResponseAttributes response, SessionResultsBundle bundle, StudentAttributes student) {"},{"lineNumber":237,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes question \u003d bundle.getQuestionsMap().get(response.getFeedbackQuestionId());"},{"lineNumber":238,"author":{"gitId":"-"},"content":" boolean isUserInstructor \u003d Const.USER_TEAM_FOR_INSTRUCTOR.equals(student.getTeam());"},{"lineNumber":239,"author":{"gitId":"-"},"content":""},{"lineNumber":240,"author":{"gitId":"-"},"content":" // process giver"},{"lineNumber":241,"author":{"gitId":"-"},"content":" boolean isUserGiver \u003d student.getEmail().equals(response.getGiver())"},{"lineNumber":242,"author":{"gitId":"-"},"content":" \u0026\u0026 (isUserInstructor \u0026\u0026 question.getGiverType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":243,"author":{"gitId":"-"},"content":" || !isUserInstructor \u0026\u0026 question.getGiverType() !\u003d FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":244,"author":{"gitId":"-"},"content":" boolean isUserTeamGiver \u003d question.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":245,"author":{"gitId":"-"},"content":" \u0026\u0026 student.getTeam().equals(response.getGiver());"},{"lineNumber":246,"author":{"gitId":"-"},"content":" String giverName;"},{"lineNumber":247,"author":{"gitId":"-"},"content":" String giverTeam \u003d \"\";"},{"lineNumber":248,"author":{"gitId":"-"},"content":" if (isUserTeamGiver) {"},{"lineNumber":249,"author":{"gitId":"-"},"content":" giverName \u003d String.format(\"Your Team (%s)\", response.getGiver());"},{"lineNumber":250,"author":{"gitId":"-"},"content":" giverTeam \u003d response.getGiver();"},{"lineNumber":251,"author":{"gitId":"-"},"content":" } else if (isUserGiver) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" giverName \u003d \"You\";"},{"lineNumber":253,"author":{"gitId":"-"},"content":" giverTeam \u003d student.getTeam();"},{"lineNumber":254,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" // we don\u0027t want student to figure out who is who by using the hash"},{"lineNumber":256,"author":{"gitId":"-"},"content":" giverName \u003d removeAnonymousHash(getGiverNameOfResponse(response, bundle));"},{"lineNumber":257,"author":{"gitId":"-"},"content":" }"},{"lineNumber":258,"author":{"gitId":"-"},"content":""},{"lineNumber":259,"author":{"gitId":"-"},"content":" // process recipient"},{"lineNumber":260,"author":{"gitId":"-"},"content":" boolean isUserRecipient \u003d student.getEmail().equals(response.getRecipient())"},{"lineNumber":261,"author":{"gitId":"-"},"content":" \u0026\u0026 (isUserInstructor \u0026\u0026 question.getRecipientType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":262,"author":{"gitId":"-"},"content":" || !isUserInstructor \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":263,"author":{"gitId":"-"},"content":" boolean isUserTeamRecipient \u003d (question.getRecipientType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":264,"author":{"gitId":"-"},"content":" || question.getRecipientType() \u003d\u003d FeedbackParticipantType.TEAMS_IN_SAME_SECTION)"},{"lineNumber":265,"author":{"gitId":"-"},"content":" \u0026\u0026 student.getTeam().equals(response.getRecipient());"},{"lineNumber":266,"author":{"gitId":"-"},"content":" String recipientName;"},{"lineNumber":267,"author":{"gitId":"-"},"content":" String recipientTeam \u003d \"\";"},{"lineNumber":268,"author":{"gitId":"-"},"content":" if (isUserRecipient) {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" recipientName \u003d \"You\";"},{"lineNumber":270,"author":{"gitId":"-"},"content":" recipientTeam \u003d student.getTeam();"},{"lineNumber":271,"author":{"gitId":"-"},"content":" } else if (isUserTeamRecipient) {"},{"lineNumber":272,"author":{"gitId":"-"},"content":" recipientName \u003d String.format(\"Your Team (%s)\", response.getRecipient());"},{"lineNumber":273,"author":{"gitId":"-"},"content":" recipientTeam \u003d response.getRecipient();"},{"lineNumber":274,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":275,"author":{"gitId":"-"},"content":" // we don\u0027t want student to figure out who is who by using the hash"},{"lineNumber":276,"author":{"gitId":"-"},"content":" recipientName \u003d removeAnonymousHash(getRecipientNameOfResponse(response, bundle));"},{"lineNumber":277,"author":{"gitId":"-"},"content":" if (!recipientName.contains(Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT)) {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" recipientTeam \u003d bundle.getRoster().getInfoForIdentifier(response.getRecipient()).getTeamName();"},{"lineNumber":279,"author":{"gitId":"-"},"content":" }"},{"lineNumber":280,"author":{"gitId":"-"},"content":" }"},{"lineNumber":281,"author":{"gitId":"-"},"content":""},{"lineNumber":282,"author":{"gitId":"-"},"content":" // process comments"},{"lineNumber":283,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponseCommentAttributes\u003e feedbackResponseComments \u003d"},{"lineNumber":284,"author":{"gitId":"-"},"content":" bundle.getResponseCommentsMap().getOrDefault(response.getId(), Collections.emptyList());"},{"lineNumber":285,"author":{"gitId":"-"},"content":" Queue\u003cCommentOutput\u003e comments \u003d buildComments(feedbackResponseComments, bundle);"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"-"},"content":" return ResponseOutput.builder()"},{"lineNumber":288,"author":{"gitId":"-"},"content":" .withResponseId(response.getId())"},{"lineNumber":289,"author":{"gitId":"-"},"content":" .withGiver(giverName)"},{"lineNumber":290,"author":{"gitId":"-"},"content":" .withGiverTeam(giverTeam)"},{"lineNumber":291,"author":{"gitId":"-"},"content":" .withGiverEmail(null)"},{"lineNumber":292,"author":{"gitId":"-"},"content":" .withRelatedGiverEmail(null)"},{"lineNumber":293,"author":{"gitId":"xenosf"},"content":" .withGiverSectionName(response.getGiverSection())"},{"lineNumber":294,"author":{"gitId":"xenosf"},"content":" .withRecipient(recipientName)"},{"lineNumber":295,"author":{"gitId":"xenosf"},"content":" .withRecipientTeam(recipientTeam)"},{"lineNumber":296,"author":{"gitId":"xenosf"},"content":" .withRecipientEmail(null)"},{"lineNumber":297,"author":{"gitId":"xenosf"},"content":" .withRecipientSectionName(response.getRecipientSection())"},{"lineNumber":298,"author":{"gitId":"xenosf"},"content":" .withResponseDetails(response.getResponseDetailsCopy())"},{"lineNumber":299,"author":{"gitId":"xenosf"},"content":" .withParticipantComment(comments.poll())"},{"lineNumber":300,"author":{"gitId":"xenosf"},"content":" .withInstructorComments(new ArrayList\u003c\u003e(comments))"},{"lineNumber":301,"author":{"gitId":"xenosf"},"content":" .build();"},{"lineNumber":302,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":303,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":304,"author":{"gitId":"xenosf"},"content":" private static ResponseOutput buildSingleResponseForStudent("},{"lineNumber":305,"author":{"gitId":"xenosf"},"content":" FeedbackResponse response, SqlSessionResultsBundle bundle, Student student) {"},{"lineNumber":306,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question \u003d response.getFeedbackQuestion();"},{"lineNumber":307,"author":{"gitId":"xenosf"},"content":" boolean isUserInstructor \u003d Const.USER_TEAM_FOR_INSTRUCTOR.equals(student.getTeamName());"},{"lineNumber":308,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":309,"author":{"gitId":"xenosf"},"content":" // process giver"},{"lineNumber":310,"author":{"gitId":"xenosf"},"content":" boolean isUserGiver \u003d student.getEmail().equals(response.getGiver())"},{"lineNumber":311,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 (isUserInstructor \u0026\u0026 question.getGiverType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":312,"author":{"gitId":"xenosf"},"content":" || !isUserInstructor \u0026\u0026 question.getGiverType() !\u003d FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":313,"author":{"gitId":"xenosf"},"content":" boolean isUserTeamGiver \u003d question.getGiverType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":314,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 student.getTeamName().equals(response.getGiver());"},{"lineNumber":315,"author":{"gitId":"xenosf"},"content":" String giverName;"},{"lineNumber":316,"author":{"gitId":"xenosf"},"content":" String giverTeam \u003d \"\";"},{"lineNumber":317,"author":{"gitId":"xenosf"},"content":" if (isUserTeamGiver) {"},{"lineNumber":318,"author":{"gitId":"xenosf"},"content":" giverName \u003d String.format(\"Your Team (%s)\", response.getGiver());"},{"lineNumber":319,"author":{"gitId":"xenosf"},"content":" giverTeam \u003d response.getGiver();"},{"lineNumber":320,"author":{"gitId":"xenosf"},"content":" } else if (isUserGiver) {"},{"lineNumber":321,"author":{"gitId":"xenosf"},"content":" giverName \u003d \"You\";"},{"lineNumber":322,"author":{"gitId":"xenosf"},"content":" giverTeam \u003d student.getTeamName();"},{"lineNumber":323,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":324,"author":{"gitId":"xenosf"},"content":" // we don\u0027t want student to figure out who is who by using the hash"},{"lineNumber":325,"author":{"gitId":"xenosf"},"content":" giverName \u003d removeAnonymousHash(getGiverNameOfResponse(response, bundle));"},{"lineNumber":326,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":327,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":328,"author":{"gitId":"xenosf"},"content":" // process recipient"},{"lineNumber":329,"author":{"gitId":"xenosf"},"content":" boolean isUserRecipient \u003d student.getEmail().equals(response.getRecipient())"},{"lineNumber":330,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 (isUserInstructor \u0026\u0026 question.getRecipientType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS"},{"lineNumber":331,"author":{"gitId":"xenosf"},"content":" || !isUserInstructor \u0026\u0026 question.getRecipientType() !\u003d FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":332,"author":{"gitId":"xenosf"},"content":" boolean isUserTeamRecipient \u003d (question.getRecipientType() \u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":333,"author":{"gitId":"xenosf"},"content":" || question.getRecipientType() \u003d\u003d FeedbackParticipantType.TEAMS_IN_SAME_SECTION)"},{"lineNumber":334,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 student.getTeamName().equals(response.getRecipient());"},{"lineNumber":335,"author":{"gitId":"xenosf"},"content":" String recipientName;"},{"lineNumber":336,"author":{"gitId":"xenosf"},"content":" String recipientTeam \u003d \"\";"},{"lineNumber":337,"author":{"gitId":"xenosf"},"content":" if (isUserRecipient) {"},{"lineNumber":338,"author":{"gitId":"xenosf"},"content":" recipientName \u003d \"You\";"},{"lineNumber":339,"author":{"gitId":"xenosf"},"content":" recipientTeam \u003d student.getTeamName();"},{"lineNumber":340,"author":{"gitId":"xenosf"},"content":" } else if (isUserTeamRecipient) {"},{"lineNumber":341,"author":{"gitId":"xenosf"},"content":" recipientName \u003d String.format(\"Your Team (%s)\", response.getRecipient());"},{"lineNumber":342,"author":{"gitId":"xenosf"},"content":" recipientTeam \u003d response.getRecipient();"},{"lineNumber":343,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":344,"author":{"gitId":"xenosf"},"content":" // we don\u0027t want student to figure out who is who by using the hash"},{"lineNumber":345,"author":{"gitId":"xenosf"},"content":" recipientName \u003d removeAnonymousHash(getRecipientNameOfResponse(response, bundle));"},{"lineNumber":346,"author":{"gitId":"xenosf"},"content":" if (!recipientName.contains(Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT)) {"},{"lineNumber":347,"author":{"gitId":"xenosf"},"content":" recipientTeam \u003d bundle.getRoster().getInfoForIdentifier(response.getRecipient()).getTeamName();"},{"lineNumber":348,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":349,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":350,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":351,"author":{"gitId":"xenosf"},"content":" // process comments"},{"lineNumber":352,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e feedbackResponseComments \u003d"},{"lineNumber":353,"author":{"gitId":"xenosf"},"content":" bundle.getResponseCommentsMap().getOrDefault(response, Collections.emptyList());"},{"lineNumber":354,"author":{"gitId":"xenosf"},"content":" Queue\u003cCommentOutput\u003e comments \u003d buildComments(feedbackResponseComments, bundle);"},{"lineNumber":355,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":356,"author":{"gitId":"xenosf"},"content":" return ResponseOutput.builder()"},{"lineNumber":357,"author":{"gitId":"xenosf"},"content":" .withResponse(response)"},{"lineNumber":358,"author":{"gitId":"xenosf"},"content":" .withGiver(giverName)"},{"lineNumber":359,"author":{"gitId":"xenosf"},"content":" .withGiverTeam(giverTeam)"},{"lineNumber":360,"author":{"gitId":"xenosf"},"content":" .withGiverEmail(null)"},{"lineNumber":361,"author":{"gitId":"xenosf"},"content":" .withRelatedGiverEmail(null)"},{"lineNumber":362,"author":{"gitId":"-"},"content":" .withGiverSection(response.getGiverSection())"},{"lineNumber":363,"author":{"gitId":"-"},"content":" .withRecipient(recipientName)"},{"lineNumber":364,"author":{"gitId":"-"},"content":" .withRecipientTeam(recipientTeam)"},{"lineNumber":365,"author":{"gitId":"-"},"content":" .withRecipientEmail(null)"},{"lineNumber":366,"author":{"gitId":"-"},"content":" .withRecipientSection(response.getRecipientSection())"},{"lineNumber":367,"author":{"gitId":"xenosf"},"content":" .withResponseDetails(response.getFeedbackResponseDetailsCopy())"},{"lineNumber":368,"author":{"gitId":"-"},"content":" .withParticipantComment(comments.poll())"},{"lineNumber":369,"author":{"gitId":"-"},"content":" .withInstructorComments(new ArrayList\u003c\u003e(comments))"},{"lineNumber":370,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":371,"author":{"gitId":"-"},"content":" }"},{"lineNumber":372,"author":{"gitId":"-"},"content":""},{"lineNumber":373,"author":{"gitId":"-"},"content":" private static String removeAnonymousHash(String identifier) {"},{"lineNumber":374,"author":{"gitId":"-"},"content":" return identifier.replaceAll(Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT + \" (student|instructor|team) \""},{"lineNumber":375,"author":{"gitId":"-"},"content":" + REGEX_ANONYMOUS_PARTICIPANT_HASH, Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT + \" $1\");"},{"lineNumber":376,"author":{"gitId":"-"},"content":" }"},{"lineNumber":377,"author":{"gitId":"-"},"content":""},{"lineNumber":378,"author":{"gitId":"-"},"content":" private static List\u003cResponseOutput\u003e buildResponsesForInstructor("},{"lineNumber":379,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponseAttributes\u003e responses, SessionResultsBundle bundle, boolean areMissingResponses) {"},{"lineNumber":380,"author":{"gitId":"-"},"content":" List\u003cResponseOutput\u003e output \u003d new ArrayList\u003c\u003e();"},{"lineNumber":381,"author":{"gitId":"-"},"content":""},{"lineNumber":382,"author":{"gitId":"-"},"content":" for (FeedbackResponseAttributes response : responses) {"},{"lineNumber":383,"author":{"gitId":"-"},"content":" output.add(buildSingleResponseForInstructor(response, bundle, areMissingResponses));"},{"lineNumber":384,"author":{"gitId":"-"},"content":" }"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"-"},"content":" return output;"},{"lineNumber":387,"author":{"gitId":"-"},"content":" }"},{"lineNumber":388,"author":{"gitId":"-"},"content":""},{"lineNumber":389,"author":{"gitId":"xenosf"},"content":" private static List\u003cResponseOutput\u003e buildResponsesForInstructor("},{"lineNumber":390,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e responses, SqlSessionResultsBundle bundle, boolean areMissingResponses) {"},{"lineNumber":391,"author":{"gitId":"xenosf"},"content":" List\u003cResponseOutput\u003e output \u003d new ArrayList\u003c\u003e();"},{"lineNumber":392,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":393,"author":{"gitId":"xenosf"},"content":" for (FeedbackResponse response : responses) {"},{"lineNumber":394,"author":{"gitId":"xenosf"},"content":" output.add(buildSingleResponseForInstructor(response, bundle, areMissingResponses));"},{"lineNumber":395,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":396,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":397,"author":{"gitId":"xenosf"},"content":" return output;"},{"lineNumber":398,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":399,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":400,"author":{"gitId":"-"},"content":" private static ResponseOutput buildSingleResponseForInstructor("},{"lineNumber":401,"author":{"gitId":"-"},"content":" FeedbackResponseAttributes response, SessionResultsBundle bundle, boolean isMissingResponse) {"},{"lineNumber":402,"author":{"gitId":"-"},"content":" // process giver"},{"lineNumber":403,"author":{"gitId":"-"},"content":" String giverEmail \u003d null;"},{"lineNumber":404,"author":{"gitId":"-"},"content":" String relatedGiverEmail \u003d null;"},{"lineNumber":405,"author":{"gitId":"-"},"content":" if (bundle.isResponseGiverVisible(response)) {"},{"lineNumber":406,"author":{"gitId":"-"},"content":" giverEmail \u003d response.getGiver();"},{"lineNumber":407,"author":{"gitId":"-"},"content":" relatedGiverEmail \u003d response.getGiver();"},{"lineNumber":408,"author":{"gitId":"-"},"content":""},{"lineNumber":409,"author":{"gitId":"-"},"content":" if (bundle.getRoster().isTeamInCourse(giverEmail)) {"},{"lineNumber":410,"author":{"gitId":"-"},"content":" // remove recipient email as it is a team name"},{"lineNumber":411,"author":{"gitId":"-"},"content":" relatedGiverEmail \u003d"},{"lineNumber":412,"author":{"gitId":"-"},"content":" bundle.getRoster().getTeamToMembersTable().get(giverEmail).iterator().next().getEmail();"},{"lineNumber":413,"author":{"gitId":"-"},"content":" giverEmail \u003d null;"},{"lineNumber":414,"author":{"gitId":"-"},"content":" }"},{"lineNumber":415,"author":{"gitId":"-"},"content":" }"},{"lineNumber":416,"author":{"gitId":"-"},"content":" String giverName \u003d getGiverNameOfResponse(response, bundle);"},{"lineNumber":417,"author":{"gitId":"-"},"content":" String giverTeam \u003d bundle.getRoster().getInfoForIdentifier(response.getGiver()).getTeamName();"},{"lineNumber":418,"author":{"gitId":"-"},"content":" String giverSection \u003d response.getGiverSection();"},{"lineNumber":419,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes question \u003d bundle.getQuestionsMap().get(response.getFeedbackQuestionId());"},{"lineNumber":420,"author":{"gitId":"-"},"content":" if (question.getGiverType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS) {"},{"lineNumber":421,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d bundle.getRoster().getInstructorForEmail(response.getGiver());"},{"lineNumber":422,"author":{"gitId":"-"},"content":" giverName \u003d instructor.getName();"},{"lineNumber":423,"author":{"gitId":"-"},"content":" giverTeam \u003d Const.USER_TEAM_FOR_INSTRUCTOR;"},{"lineNumber":424,"author":{"gitId":"-"},"content":" giverSection \u003d Const.DEFAULT_SECTION;"},{"lineNumber":425,"author":{"gitId":"-"},"content":" }"},{"lineNumber":426,"author":{"gitId":"-"},"content":""},{"lineNumber":427,"author":{"gitId":"-"},"content":" // process recipient"},{"lineNumber":428,"author":{"gitId":"-"},"content":" String recipientEmail \u003d null;"},{"lineNumber":429,"author":{"gitId":"-"},"content":" String recipientName \u003d getRecipientNameOfResponse(response, bundle);"},{"lineNumber":430,"author":{"gitId":"-"},"content":" String recipientTeam \u003d"},{"lineNumber":431,"author":{"gitId":"-"},"content":" bundle.getRoster().getInfoForIdentifier(response.getRecipient()).getTeamName();"},{"lineNumber":432,"author":{"gitId":"-"},"content":" String recipientSection \u003d response.getRecipientSection();"},{"lineNumber":433,"author":{"gitId":"-"},"content":" if (question.getRecipientType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS) {"},{"lineNumber":434,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d bundle.getRoster().getInstructorForEmail(response.getRecipient());"},{"lineNumber":435,"author":{"gitId":"-"},"content":" recipientName \u003d instructor.getName();"},{"lineNumber":436,"author":{"gitId":"-"},"content":" recipientTeam \u003d Const.USER_TEAM_FOR_INSTRUCTOR;"},{"lineNumber":437,"author":{"gitId":"-"},"content":" recipientSection \u003d Const.DEFAULT_SECTION;"},{"lineNumber":438,"author":{"gitId":"-"},"content":" }"},{"lineNumber":439,"author":{"gitId":"-"},"content":" if (bundle.isResponseRecipientVisible(response)) {"},{"lineNumber":440,"author":{"gitId":"-"},"content":" recipientEmail \u003d response.getRecipient();"},{"lineNumber":441,"author":{"gitId":"-"},"content":""},{"lineNumber":442,"author":{"gitId":"-"},"content":" if (bundle.getRoster().isTeamInCourse(recipientEmail)) {"},{"lineNumber":443,"author":{"gitId":"-"},"content":" // remove recipient email as it is a team name"},{"lineNumber":444,"author":{"gitId":"-"},"content":" recipientEmail \u003d null;"},{"lineNumber":445,"author":{"gitId":"-"},"content":" } else if (Const.GENERAL_QUESTION.equals(recipientEmail)) {"},{"lineNumber":446,"author":{"gitId":"-"},"content":" // general recipient does not have email"},{"lineNumber":447,"author":{"gitId":"-"},"content":" recipientEmail \u003d null;"},{"lineNumber":448,"author":{"gitId":"-"},"content":" }"},{"lineNumber":449,"author":{"gitId":"-"},"content":" }"},{"lineNumber":450,"author":{"gitId":"-"},"content":""},{"lineNumber":451,"author":{"gitId":"-"},"content":" // process comments"},{"lineNumber":452,"author":{"gitId":"-"},"content":" List\u003cFeedbackResponseCommentAttributes\u003e feedbackResponseComments \u003d"},{"lineNumber":453,"author":{"gitId":"-"},"content":" bundle.getResponseCommentsMap().getOrDefault(response.getId(), Collections.emptyList());"},{"lineNumber":454,"author":{"gitId":"-"},"content":" Queue\u003cCommentOutput\u003e comments \u003d buildComments(feedbackResponseComments, bundle);"},{"lineNumber":455,"author":{"gitId":"-"},"content":""},{"lineNumber":456,"author":{"gitId":"-"},"content":" return ResponseOutput.builder()"},{"lineNumber":457,"author":{"gitId":"-"},"content":" .withIsMissingResponse(isMissingResponse)"},{"lineNumber":458,"author":{"gitId":"-"},"content":" .withResponseId(response.getId())"},{"lineNumber":459,"author":{"gitId":"-"},"content":" .withGiver(giverName)"},{"lineNumber":460,"author":{"gitId":"-"},"content":" .withGiverTeam(giverTeam)"},{"lineNumber":461,"author":{"gitId":"-"},"content":" .withGiverEmail(giverEmail)"},{"lineNumber":462,"author":{"gitId":"-"},"content":" .withRelatedGiverEmail(relatedGiverEmail)"},{"lineNumber":463,"author":{"gitId":"xenosf"},"content":" .withGiverSectionName(giverSection)"},{"lineNumber":464,"author":{"gitId":"-"},"content":" .withRecipient(recipientName)"},{"lineNumber":465,"author":{"gitId":"-"},"content":" .withRecipientTeam(recipientTeam)"},{"lineNumber":466,"author":{"gitId":"-"},"content":" .withRecipientEmail(recipientEmail)"},{"lineNumber":467,"author":{"gitId":"xenosf"},"content":" .withRecipientSectionName(recipientSection)"},{"lineNumber":468,"author":{"gitId":"-"},"content":" .withResponseDetails(response.getResponseDetailsCopy())"},{"lineNumber":469,"author":{"gitId":"-"},"content":" .withParticipantComment(comments.poll())"},{"lineNumber":470,"author":{"gitId":"-"},"content":" .withInstructorComments(new ArrayList\u003c\u003e(comments))"},{"lineNumber":471,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":472,"author":{"gitId":"-"},"content":" }"},{"lineNumber":473,"author":{"gitId":"-"},"content":""},{"lineNumber":474,"author":{"gitId":"xenosf"},"content":" private static ResponseOutput buildSingleResponseForInstructor("},{"lineNumber":475,"author":{"gitId":"xenosf"},"content":" FeedbackResponse response, SqlSessionResultsBundle bundle, boolean isMissingResponse) {"},{"lineNumber":476,"author":{"gitId":"xenosf"},"content":" // process giver"},{"lineNumber":477,"author":{"gitId":"xenosf"},"content":" String giverEmail \u003d null;"},{"lineNumber":478,"author":{"gitId":"xenosf"},"content":" String relatedGiverEmail \u003d null;"},{"lineNumber":479,"author":{"gitId":"xenosf"},"content":" if (bundle.isResponseGiverVisible(response)) {"},{"lineNumber":480,"author":{"gitId":"xenosf"},"content":" giverEmail \u003d response.getGiver();"},{"lineNumber":481,"author":{"gitId":"xenosf"},"content":" relatedGiverEmail \u003d response.getGiver();"},{"lineNumber":482,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":483,"author":{"gitId":"xenosf"},"content":" if (bundle.getRoster().isTeamInCourse(giverEmail)) {"},{"lineNumber":484,"author":{"gitId":"xenosf"},"content":" // remove recipient email as it is a team name"},{"lineNumber":485,"author":{"gitId":"xenosf"},"content":" relatedGiverEmail \u003d"},{"lineNumber":486,"author":{"gitId":"xenosf"},"content":" bundle.getRoster().getTeamToMembersTable().get(giverEmail).iterator().next().getEmail();"},{"lineNumber":487,"author":{"gitId":"xenosf"},"content":" giverEmail \u003d null;"},{"lineNumber":488,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":489,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":490,"author":{"gitId":"xenosf"},"content":" String giverName \u003d getGiverNameOfResponse(response, bundle);"},{"lineNumber":491,"author":{"gitId":"xenosf"},"content":" String giverTeam \u003d bundle.getRoster().getInfoForIdentifier(response.getGiver()).getTeamName();"},{"lineNumber":492,"author":{"gitId":"xenosf"},"content":" String giverSectionName \u003d response.getGiverSectionName();"},{"lineNumber":493,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question \u003d response.getFeedbackQuestion();"},{"lineNumber":494,"author":{"gitId":"xenosf"},"content":" if (question.getGiverType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS) {"},{"lineNumber":495,"author":{"gitId":"xenosf"},"content":" Instructor instructor \u003d bundle.getRoster().getInstructorForEmail(response.getGiver());"},{"lineNumber":496,"author":{"gitId":"xenosf"},"content":" giverName \u003d instructor.getName();"},{"lineNumber":497,"author":{"gitId":"xenosf"},"content":" giverTeam \u003d Const.USER_TEAM_FOR_INSTRUCTOR;"},{"lineNumber":498,"author":{"gitId":"xenosf"},"content":" giverSectionName \u003d Const.DEFAULT_SECTION;"},{"lineNumber":499,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":500,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":501,"author":{"gitId":"xenosf"},"content":" // process recipient"},{"lineNumber":502,"author":{"gitId":"xenosf"},"content":" String recipientEmail \u003d null;"},{"lineNumber":503,"author":{"gitId":"xenosf"},"content":" String recipientName \u003d getRecipientNameOfResponse(response, bundle);"},{"lineNumber":504,"author":{"gitId":"xenosf"},"content":" String recipientTeam \u003d"},{"lineNumber":505,"author":{"gitId":"xenosf"},"content":" bundle.getRoster().getInfoForIdentifier(response.getRecipient()).getTeamName();"},{"lineNumber":506,"author":{"gitId":"xenosf"},"content":" String recipientSectionName \u003d response.getRecipientSectionName();"},{"lineNumber":507,"author":{"gitId":"xenosf"},"content":" if (question.getRecipientType() \u003d\u003d FeedbackParticipantType.INSTRUCTORS) {"},{"lineNumber":508,"author":{"gitId":"xenosf"},"content":" Instructor instructor \u003d bundle.getRoster().getInstructorForEmail(response.getRecipient());"},{"lineNumber":509,"author":{"gitId":"xenosf"},"content":" recipientName \u003d instructor.getName();"},{"lineNumber":510,"author":{"gitId":"xenosf"},"content":" recipientTeam \u003d Const.USER_TEAM_FOR_INSTRUCTOR;"},{"lineNumber":511,"author":{"gitId":"xenosf"},"content":" recipientSectionName \u003d Const.DEFAULT_SECTION;"},{"lineNumber":512,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":513,"author":{"gitId":"xenosf"},"content":" if (bundle.isResponseRecipientVisible(response)) {"},{"lineNumber":514,"author":{"gitId":"xenosf"},"content":" recipientEmail \u003d response.getRecipient();"},{"lineNumber":515,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":516,"author":{"gitId":"xenosf"},"content":" if (bundle.getRoster().isTeamInCourse(recipientEmail)) {"},{"lineNumber":517,"author":{"gitId":"xenosf"},"content":" // remove recipient email as it is a team name"},{"lineNumber":518,"author":{"gitId":"xenosf"},"content":" recipientEmail \u003d null;"},{"lineNumber":519,"author":{"gitId":"xenosf"},"content":" } else if (Const.GENERAL_QUESTION.equals(recipientEmail)) {"},{"lineNumber":520,"author":{"gitId":"xenosf"},"content":" // general recipient does not have email"},{"lineNumber":521,"author":{"gitId":"xenosf"},"content":" recipientEmail \u003d null;"},{"lineNumber":522,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":523,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":524,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":525,"author":{"gitId":"xenosf"},"content":" // process comments"},{"lineNumber":526,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponseComment\u003e feedbackResponseComments \u003d"},{"lineNumber":527,"author":{"gitId":"xenosf"},"content":" bundle.getResponseCommentsMap().getOrDefault(response, Collections.emptyList());"},{"lineNumber":528,"author":{"gitId":"xenosf"},"content":" Queue\u003cCommentOutput\u003e comments \u003d buildComments(feedbackResponseComments, bundle);"},{"lineNumber":529,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":530,"author":{"gitId":"xenosf"},"content":" return ResponseOutput.builder()"},{"lineNumber":531,"author":{"gitId":"xenosf"},"content":" .withIsMissingResponse(isMissingResponse)"},{"lineNumber":532,"author":{"gitId":"xenosf"},"content":" .withResponse(response)"},{"lineNumber":533,"author":{"gitId":"xenosf"},"content":" .withGiver(giverName)"},{"lineNumber":534,"author":{"gitId":"xenosf"},"content":" .withGiverTeam(giverTeam)"},{"lineNumber":535,"author":{"gitId":"xenosf"},"content":" .withGiverEmail(giverEmail)"},{"lineNumber":536,"author":{"gitId":"xenosf"},"content":" .withRelatedGiverEmail(relatedGiverEmail)"},{"lineNumber":537,"author":{"gitId":"xenosf"},"content":" .withGiverSectionName(giverSectionName)"},{"lineNumber":538,"author":{"gitId":"xenosf"},"content":" .withRecipient(recipientName)"},{"lineNumber":539,"author":{"gitId":"xenosf"},"content":" .withRecipientTeam(recipientTeam)"},{"lineNumber":540,"author":{"gitId":"xenosf"},"content":" .withRecipientEmail(recipientEmail)"},{"lineNumber":541,"author":{"gitId":"xenosf"},"content":" .withRecipientSectionName(recipientSectionName)"},{"lineNumber":542,"author":{"gitId":"xenosf"},"content":" .withResponseDetails(response.getFeedbackResponseDetailsCopy())"},{"lineNumber":543,"author":{"gitId":"xenosf"},"content":" .withParticipantComment(comments.poll())"},{"lineNumber":544,"author":{"gitId":"xenosf"},"content":" .withInstructorComments(new ArrayList\u003c\u003e(comments))"},{"lineNumber":545,"author":{"gitId":"xenosf"},"content":" .build();"},{"lineNumber":546,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":547,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":548,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":549,"author":{"gitId":"-"},"content":" * Gets giver name of a response from the bundle."},{"lineNumber":550,"author":{"gitId":"-"},"content":" *"},{"lineNumber":551,"author":{"gitId":"-"},"content":" * \u003cp\u003eAnonymized the name if necessary."},{"lineNumber":552,"author":{"gitId":"-"},"content":" */"},{"lineNumber":553,"author":{"gitId":"-"},"content":" private static String getGiverNameOfResponse(FeedbackResponseAttributes response, SessionResultsBundle bundle) {"},{"lineNumber":554,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes question \u003d bundle.getQuestionsMap().get(response.getFeedbackQuestionId());"},{"lineNumber":555,"author":{"gitId":"-"},"content":" FeedbackParticipantType participantType \u003d question.getGiverType();"},{"lineNumber":556,"author":{"gitId":"-"},"content":""},{"lineNumber":557,"author":{"gitId":"-"},"content":" CourseRoster.ParticipantInfo userInfo \u003d bundle.getRoster().getInfoForIdentifier(response.getGiver());"},{"lineNumber":558,"author":{"gitId":"-"},"content":" String name \u003d userInfo.getName();"},{"lineNumber":559,"author":{"gitId":"-"},"content":""},{"lineNumber":560,"author":{"gitId":"-"},"content":" if (!bundle.isResponseGiverVisible(response)) {"},{"lineNumber":561,"author":{"gitId":"-"},"content":" name \u003d SessionResultsBundle.getAnonName(participantType, name);"},{"lineNumber":562,"author":{"gitId":"-"},"content":" }"},{"lineNumber":563,"author":{"gitId":"-"},"content":""},{"lineNumber":564,"author":{"gitId":"-"},"content":" return name;"},{"lineNumber":565,"author":{"gitId":"-"},"content":" }"},{"lineNumber":566,"author":{"gitId":"-"},"content":""},{"lineNumber":567,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":568,"author":{"gitId":"xenosf"},"content":" * Gets giver name of a response from the bundle."},{"lineNumber":569,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":570,"author":{"gitId":"xenosf"},"content":" * \u003cp\u003eAnonymized the name if necessary."},{"lineNumber":571,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":572,"author":{"gitId":"xenosf"},"content":" private static String getGiverNameOfResponse(FeedbackResponse response, SqlSessionResultsBundle bundle) {"},{"lineNumber":573,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question \u003d response.getFeedbackQuestion();"},{"lineNumber":574,"author":{"gitId":"xenosf"},"content":" FeedbackParticipantType participantType \u003d question.getGiverType();"},{"lineNumber":575,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":576,"author":{"gitId":"xenosf"},"content":" SqlCourseRoster.ParticipantInfo userInfo \u003d bundle.getRoster().getInfoForIdentifier(response.getGiver());"},{"lineNumber":577,"author":{"gitId":"xenosf"},"content":" String name \u003d userInfo.getName();"},{"lineNumber":578,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":579,"author":{"gitId":"xenosf"},"content":" if (!bundle.isResponseGiverVisible(response)) {"},{"lineNumber":580,"author":{"gitId":"xenosf"},"content":" name \u003d SessionResultsBundle.getAnonName(participantType, name);"},{"lineNumber":581,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":582,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":583,"author":{"gitId":"xenosf"},"content":" return name;"},{"lineNumber":584,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":585,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":586,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":587,"author":{"gitId":"-"},"content":" * Gets recipient name of a response from the bundle."},{"lineNumber":588,"author":{"gitId":"-"},"content":" *"},{"lineNumber":589,"author":{"gitId":"-"},"content":" * \u003cp\u003eAnonymized the name if necessary."},{"lineNumber":590,"author":{"gitId":"-"},"content":" */"},{"lineNumber":591,"author":{"gitId":"-"},"content":" private static String getRecipientNameOfResponse(FeedbackResponseAttributes response, SessionResultsBundle bundle) {"},{"lineNumber":592,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes question \u003d bundle.getQuestionsMap().get(response.getFeedbackQuestionId());"},{"lineNumber":593,"author":{"gitId":"-"},"content":" FeedbackParticipantType participantType \u003d question.getRecipientType();"},{"lineNumber":594,"author":{"gitId":"-"},"content":" if (participantType \u003d\u003d FeedbackParticipantType.SELF) {"},{"lineNumber":595,"author":{"gitId":"-"},"content":" // recipient type for self-feedback is the same as the giver type"},{"lineNumber":596,"author":{"gitId":"-"},"content":" participantType \u003d question.getGiverType();"},{"lineNumber":597,"author":{"gitId":"-"},"content":" }"},{"lineNumber":598,"author":{"gitId":"-"},"content":""},{"lineNumber":599,"author":{"gitId":"-"},"content":" CourseRoster.ParticipantInfo userInfo \u003d bundle.getRoster().getInfoForIdentifier(response.getRecipient());"},{"lineNumber":600,"author":{"gitId":"-"},"content":" String name \u003d userInfo.getName();"},{"lineNumber":601,"author":{"gitId":"-"},"content":" if (Const.GENERAL_QUESTION.equals(response.getRecipient())) {"},{"lineNumber":602,"author":{"gitId":"-"},"content":" // for general question"},{"lineNumber":603,"author":{"gitId":"-"},"content":" name \u003d Const.USER_NOBODY_TEXT;"},{"lineNumber":604,"author":{"gitId":"-"},"content":" }"},{"lineNumber":605,"author":{"gitId":"-"},"content":" if (!bundle.isResponseRecipientVisible(response)) {"},{"lineNumber":606,"author":{"gitId":"-"},"content":" name \u003d SessionResultsBundle.getAnonName(participantType, name);"},{"lineNumber":607,"author":{"gitId":"-"},"content":" }"},{"lineNumber":608,"author":{"gitId":"-"},"content":""},{"lineNumber":609,"author":{"gitId":"-"},"content":" return name;"},{"lineNumber":610,"author":{"gitId":"-"},"content":" }"},{"lineNumber":611,"author":{"gitId":"-"},"content":""},{"lineNumber":612,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":613,"author":{"gitId":"xenosf"},"content":" * Gets recipient name of a response from the bundle."},{"lineNumber":614,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":615,"author":{"gitId":"xenosf"},"content":" * \u003cp\u003eAnonymized the name if necessary."},{"lineNumber":616,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":617,"author":{"gitId":"xenosf"},"content":" private static String getRecipientNameOfResponse(FeedbackResponse response, SqlSessionResultsBundle bundle) {"},{"lineNumber":618,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question \u003d response.getFeedbackQuestion();"},{"lineNumber":619,"author":{"gitId":"xenosf"},"content":" FeedbackParticipantType participantType \u003d question.getRecipientType();"},{"lineNumber":620,"author":{"gitId":"xenosf"},"content":" if (participantType \u003d\u003d FeedbackParticipantType.SELF) {"},{"lineNumber":621,"author":{"gitId":"xenosf"},"content":" // recipient type for self-feedback is the same as the giver type"},{"lineNumber":622,"author":{"gitId":"xenosf"},"content":" participantType \u003d question.getGiverType();"},{"lineNumber":623,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":624,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":625,"author":{"gitId":"xenosf"},"content":" SqlCourseRoster.ParticipantInfo userInfo \u003d bundle.getRoster().getInfoForIdentifier(response.getRecipient());"},{"lineNumber":626,"author":{"gitId":"xenosf"},"content":" String name \u003d userInfo.getName();"},{"lineNumber":627,"author":{"gitId":"xenosf"},"content":" if (Const.GENERAL_QUESTION.equals(response.getRecipient())) {"},{"lineNumber":628,"author":{"gitId":"xenosf"},"content":" // for general question"},{"lineNumber":629,"author":{"gitId":"xenosf"},"content":" name \u003d Const.USER_NOBODY_TEXT;"},{"lineNumber":630,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":631,"author":{"gitId":"xenosf"},"content":" if (!bundle.isResponseRecipientVisible(response)) {"},{"lineNumber":632,"author":{"gitId":"xenosf"},"content":" name \u003d SessionResultsBundle.getAnonName(participantType, name);"},{"lineNumber":633,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":634,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":635,"author":{"gitId":"xenosf"},"content":" return name;"},{"lineNumber":636,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":637,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":638,"author":{"gitId":"-"},"content":" private static Queue\u003cCommentOutput\u003e buildComments(List\u003cFeedbackResponseCommentAttributes\u003e feedbackResponseComments,"},{"lineNumber":639,"author":{"gitId":"-"},"content":" SessionResultsBundle bundle) {"},{"lineNumber":640,"author":{"gitId":"-"},"content":" LinkedList\u003cCommentOutput\u003e outputs \u003d new LinkedList\u003c\u003e();"},{"lineNumber":641,"author":{"gitId":"-"},"content":""},{"lineNumber":642,"author":{"gitId":"-"},"content":" CommentOutput participantComment \u003d null;"},{"lineNumber":643,"author":{"gitId":"-"},"content":" for (FeedbackResponseCommentAttributes comment : feedbackResponseComments) {"},{"lineNumber":644,"author":{"gitId":"-"},"content":" if (comment.isCommentFromFeedbackParticipant()) {"},{"lineNumber":645,"author":{"gitId":"-"},"content":" // participant comment will not need these fields"},{"lineNumber":646,"author":{"gitId":"-"},"content":" participantComment \u003d CommentOutput.builder(comment)"},{"lineNumber":647,"author":{"gitId":"-"},"content":" .withCommentGiver(null)"},{"lineNumber":648,"author":{"gitId":"-"},"content":" .withCommentGiverName(null)"},{"lineNumber":649,"author":{"gitId":"-"},"content":" .withLastEditorEmail(null)"},{"lineNumber":650,"author":{"gitId":"-"},"content":" .withLastEditorName(null)"},{"lineNumber":651,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":652,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":653,"author":{"gitId":"-"},"content":" String giverEmail \u003d Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT;"},{"lineNumber":654,"author":{"gitId":"-"},"content":" String giverName \u003d Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT;"},{"lineNumber":655,"author":{"gitId":"-"},"content":" String lastEditorEmail \u003d Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT;"},{"lineNumber":656,"author":{"gitId":"-"},"content":" String lastEditorName \u003d Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT;"},{"lineNumber":657,"author":{"gitId":"-"},"content":" if (bundle.isCommentGiverVisible(comment)) {"},{"lineNumber":658,"author":{"gitId":"-"},"content":" giverEmail \u003d comment.getCommentGiver();"},{"lineNumber":659,"author":{"gitId":"-"},"content":" giverName \u003d bundle.getRoster().getInfoForIdentifier(comment.getCommentGiver()).getName();"},{"lineNumber":660,"author":{"gitId":"-"},"content":" lastEditorEmail \u003d comment.getLastEditorEmail();"},{"lineNumber":661,"author":{"gitId":"-"},"content":" lastEditorName \u003d bundle.getRoster().getInfoForIdentifier(comment.getLastEditorEmail()).getName();"},{"lineNumber":662,"author":{"gitId":"-"},"content":" }"},{"lineNumber":663,"author":{"gitId":"-"},"content":" outputs.add(CommentOutput.builder(comment)"},{"lineNumber":664,"author":{"gitId":"-"},"content":" .withCommentGiver(giverEmail)"},{"lineNumber":665,"author":{"gitId":"-"},"content":" .withCommentGiverName(giverName)"},{"lineNumber":666,"author":{"gitId":"-"},"content":" .withLastEditorEmail(lastEditorEmail)"},{"lineNumber":667,"author":{"gitId":"-"},"content":" .withLastEditorName(lastEditorName)"},{"lineNumber":668,"author":{"gitId":"-"},"content":" .build());"},{"lineNumber":669,"author":{"gitId":"-"},"content":" }"},{"lineNumber":670,"author":{"gitId":"-"},"content":" }"},{"lineNumber":671,"author":{"gitId":"-"},"content":" outputs.addFirst(participantComment);"},{"lineNumber":672,"author":{"gitId":"-"},"content":""},{"lineNumber":673,"author":{"gitId":"-"},"content":" return outputs;"},{"lineNumber":674,"author":{"gitId":"-"},"content":" }"},{"lineNumber":675,"author":{"gitId":"-"},"content":""},{"lineNumber":676,"author":{"gitId":"xenosf"},"content":" private static Queue\u003cCommentOutput\u003e buildComments(List\u003cFeedbackResponseComment\u003e feedbackResponseComments,"},{"lineNumber":677,"author":{"gitId":"xenosf"},"content":" SqlSessionResultsBundle bundle) {"},{"lineNumber":678,"author":{"gitId":"xenosf"},"content":" LinkedList\u003cCommentOutput\u003e outputs \u003d new LinkedList\u003c\u003e();"},{"lineNumber":679,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":680,"author":{"gitId":"xenosf"},"content":" CommentOutput participantComment \u003d null;"},{"lineNumber":681,"author":{"gitId":"xenosf"},"content":" for (FeedbackResponseComment comment : feedbackResponseComments) {"},{"lineNumber":682,"author":{"gitId":"xenosf"},"content":" if (comment.getIsCommentFromFeedbackParticipant()) {"},{"lineNumber":683,"author":{"gitId":"xenosf"},"content":" // participant comment will not need these fields"},{"lineNumber":684,"author":{"gitId":"xenosf"},"content":" participantComment \u003d CommentOutput.builder(comment)"},{"lineNumber":685,"author":{"gitId":"xenosf"},"content":" .withCommentGiver(null)"},{"lineNumber":686,"author":{"gitId":"xenosf"},"content":" .withCommentGiverName(null)"},{"lineNumber":687,"author":{"gitId":"xenosf"},"content":" .withLastEditorEmail(null)"},{"lineNumber":688,"author":{"gitId":"xenosf"},"content":" .withLastEditorName(null)"},{"lineNumber":689,"author":{"gitId":"xenosf"},"content":" .build();"},{"lineNumber":690,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":691,"author":{"gitId":"xenosf"},"content":" String giverEmail \u003d Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT;"},{"lineNumber":692,"author":{"gitId":"xenosf"},"content":" String giverName \u003d Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT;"},{"lineNumber":693,"author":{"gitId":"xenosf"},"content":" String lastEditorEmail \u003d Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT;"},{"lineNumber":694,"author":{"gitId":"xenosf"},"content":" String lastEditorName \u003d Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT;"},{"lineNumber":695,"author":{"gitId":"xenosf"},"content":" if (bundle.isCommentGiverVisible(comment)) {"},{"lineNumber":696,"author":{"gitId":"xenosf"},"content":" giverEmail \u003d comment.getGiver();"},{"lineNumber":697,"author":{"gitId":"xenosf"},"content":" giverName \u003d bundle.getRoster().getInfoForIdentifier(comment.getGiver()).getName();"},{"lineNumber":698,"author":{"gitId":"xenosf"},"content":" lastEditorEmail \u003d comment.getLastEditorEmail();"},{"lineNumber":699,"author":{"gitId":"xenosf"},"content":" lastEditorName \u003d bundle.getRoster().getInfoForIdentifier(comment.getLastEditorEmail()).getName();"},{"lineNumber":700,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":701,"author":{"gitId":"xenosf"},"content":" outputs.add(CommentOutput.builder(comment)"},{"lineNumber":702,"author":{"gitId":"xenosf"},"content":" .withCommentGiver(giverEmail)"},{"lineNumber":703,"author":{"gitId":"xenosf"},"content":" .withCommentGiverName(giverName)"},{"lineNumber":704,"author":{"gitId":"xenosf"},"content":" .withLastEditorEmail(lastEditorEmail)"},{"lineNumber":705,"author":{"gitId":"xenosf"},"content":" .withLastEditorName(lastEditorName)"},{"lineNumber":706,"author":{"gitId":"xenosf"},"content":" .build());"},{"lineNumber":707,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":708,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":709,"author":{"gitId":"xenosf"},"content":" outputs.addFirst(participantComment);"},{"lineNumber":710,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":711,"author":{"gitId":"xenosf"},"content":" return outputs;"},{"lineNumber":712,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":713,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":714,"author":{"gitId":"-"},"content":" public List\u003cQuestionOutput\u003e getQuestions() {"},{"lineNumber":715,"author":{"gitId":"-"},"content":" return questions;"},{"lineNumber":716,"author":{"gitId":"-"},"content":" }"},{"lineNumber":717,"author":{"gitId":"-"},"content":""},{"lineNumber":718,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":719,"author":{"gitId":"-"},"content":" * API output format for questions in session results."},{"lineNumber":720,"author":{"gitId":"-"},"content":" */"},{"lineNumber":721,"author":{"gitId":"-"},"content":" public static final class QuestionOutput {"},{"lineNumber":722,"author":{"gitId":"-"},"content":""},{"lineNumber":723,"author":{"gitId":"-"},"content":" private final FeedbackQuestionData feedbackQuestion;"},{"lineNumber":724,"author":{"gitId":"-"},"content":" private final String questionStatistics;"},{"lineNumber":725,"author":{"gitId":"-"},"content":""},{"lineNumber":726,"author":{"gitId":"-"},"content":" private final List\u003cResponseOutput\u003e allResponses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":727,"author":{"gitId":"-"},"content":" private final boolean hasResponseButNotVisibleForPreview;"},{"lineNumber":728,"author":{"gitId":"-"},"content":" private final boolean hasCommentNotVisibleForPreview;"},{"lineNumber":729,"author":{"gitId":"-"},"content":""},{"lineNumber":730,"author":{"gitId":"-"},"content":" // For student view only"},{"lineNumber":731,"author":{"gitId":"-"},"content":" private final List\u003cResponseOutput\u003e responsesToSelf \u003d new ArrayList\u003c\u003e();"},{"lineNumber":732,"author":{"gitId":"-"},"content":" private final List\u003cResponseOutput\u003e responsesFromSelf \u003d new ArrayList\u003c\u003e();"},{"lineNumber":733,"author":{"gitId":"-"},"content":" private final List\u003cList\u003cResponseOutput\u003e\u003e otherResponses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":734,"author":{"gitId":"-"},"content":""},{"lineNumber":735,"author":{"gitId":"-"},"content":" private QuestionOutput(FeedbackQuestionAttributes feedbackQuestionAttributes, String questionStatistics,"},{"lineNumber":736,"author":{"gitId":"-"},"content":" boolean hasResponseButNotVisibleForPreview, boolean hasCommentNotVisibleForPreview) {"},{"lineNumber":737,"author":{"gitId":"-"},"content":" this.feedbackQuestion \u003d new FeedbackQuestionData(feedbackQuestionAttributes);"},{"lineNumber":738,"author":{"gitId":"-"},"content":" this.questionStatistics \u003d questionStatistics;"},{"lineNumber":739,"author":{"gitId":"-"},"content":" this.hasResponseButNotVisibleForPreview \u003d hasResponseButNotVisibleForPreview;"},{"lineNumber":740,"author":{"gitId":"-"},"content":" this.hasCommentNotVisibleForPreview \u003d hasCommentNotVisibleForPreview;"},{"lineNumber":741,"author":{"gitId":"-"},"content":" }"},{"lineNumber":742,"author":{"gitId":"-"},"content":""},{"lineNumber":743,"author":{"gitId":"xenosf"},"content":" private QuestionOutput(FeedbackQuestion feedbackQuestion, String questionStatistics,"},{"lineNumber":744,"author":{"gitId":"xenosf"},"content":" boolean hasResponseButNotVisibleForPreview, boolean hasCommentNotVisibleForPreview) {"},{"lineNumber":745,"author":{"gitId":"xenosf"},"content":" this.feedbackQuestion \u003d new FeedbackQuestionData(feedbackQuestion);"},{"lineNumber":746,"author":{"gitId":"xenosf"},"content":" this.questionStatistics \u003d questionStatistics;"},{"lineNumber":747,"author":{"gitId":"xenosf"},"content":" this.hasResponseButNotVisibleForPreview \u003d hasResponseButNotVisibleForPreview;"},{"lineNumber":748,"author":{"gitId":"xenosf"},"content":" this.hasCommentNotVisibleForPreview \u003d hasCommentNotVisibleForPreview;"},{"lineNumber":749,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":750,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":751,"author":{"gitId":"-"},"content":" public FeedbackQuestionData getFeedbackQuestion() {"},{"lineNumber":752,"author":{"gitId":"-"},"content":" return feedbackQuestion;"},{"lineNumber":753,"author":{"gitId":"-"},"content":" }"},{"lineNumber":754,"author":{"gitId":"-"},"content":""},{"lineNumber":755,"author":{"gitId":"-"},"content":" public String getQuestionStatistics() {"},{"lineNumber":756,"author":{"gitId":"-"},"content":" return questionStatistics;"},{"lineNumber":757,"author":{"gitId":"-"},"content":" }"},{"lineNumber":758,"author":{"gitId":"-"},"content":""},{"lineNumber":759,"author":{"gitId":"-"},"content":" public List\u003cResponseOutput\u003e getAllResponses() {"},{"lineNumber":760,"author":{"gitId":"-"},"content":" return allResponses;"},{"lineNumber":761,"author":{"gitId":"-"},"content":" }"},{"lineNumber":762,"author":{"gitId":"-"},"content":""},{"lineNumber":763,"author":{"gitId":"-"},"content":" public boolean getHasResponseButNotVisibleForPreview() {"},{"lineNumber":764,"author":{"gitId":"-"},"content":" return hasResponseButNotVisibleForPreview;"},{"lineNumber":765,"author":{"gitId":"-"},"content":" }"},{"lineNumber":766,"author":{"gitId":"-"},"content":""},{"lineNumber":767,"author":{"gitId":"-"},"content":" public boolean getHasCommentNotVisibleForPreview() {"},{"lineNumber":768,"author":{"gitId":"-"},"content":" return hasCommentNotVisibleForPreview;"},{"lineNumber":769,"author":{"gitId":"-"},"content":" }"},{"lineNumber":770,"author":{"gitId":"-"},"content":""},{"lineNumber":771,"author":{"gitId":"-"},"content":" public List\u003cResponseOutput\u003e getResponsesFromSelf() {"},{"lineNumber":772,"author":{"gitId":"-"},"content":" return responsesFromSelf;"},{"lineNumber":773,"author":{"gitId":"-"},"content":" }"},{"lineNumber":774,"author":{"gitId":"-"},"content":""},{"lineNumber":775,"author":{"gitId":"-"},"content":" public List\u003cResponseOutput\u003e getResponsesToSelf() {"},{"lineNumber":776,"author":{"gitId":"-"},"content":" return responsesToSelf;"},{"lineNumber":777,"author":{"gitId":"-"},"content":" }"},{"lineNumber":778,"author":{"gitId":"-"},"content":""},{"lineNumber":779,"author":{"gitId":"-"},"content":" public List\u003cList\u003cResponseOutput\u003e\u003e getOtherResponses() {"},{"lineNumber":780,"author":{"gitId":"-"},"content":" return otherResponses;"},{"lineNumber":781,"author":{"gitId":"-"},"content":" }"},{"lineNumber":782,"author":{"gitId":"-"},"content":""},{"lineNumber":783,"author":{"gitId":"-"},"content":" }"},{"lineNumber":784,"author":{"gitId":"-"},"content":""},{"lineNumber":785,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":786,"author":{"gitId":"-"},"content":" * API output format for question responses."},{"lineNumber":787,"author":{"gitId":"-"},"content":" */"},{"lineNumber":788,"author":{"gitId":"-"},"content":" public static final class ResponseOutput {"},{"lineNumber":789,"author":{"gitId":"-"},"content":""},{"lineNumber":790,"author":{"gitId":"-"},"content":" private boolean isMissingResponse;"},{"lineNumber":791,"author":{"gitId":"-"},"content":""},{"lineNumber":792,"author":{"gitId":"-"},"content":" private String responseId;"},{"lineNumber":793,"author":{"gitId":"-"},"content":""},{"lineNumber":794,"author":{"gitId":"-"},"content":" private String giver;"},{"lineNumber":795,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":796,"author":{"gitId":"-"},"content":" * Depending on the question giver type, {@code giverIdentifier} may contain the giver\u0027s email, any team member\u0027s"},{"lineNumber":797,"author":{"gitId":"-"},"content":" * email or null."},{"lineNumber":798,"author":{"gitId":"-"},"content":" */"},{"lineNumber":799,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":800,"author":{"gitId":"-"},"content":" private String relatedGiverEmail;"},{"lineNumber":801,"author":{"gitId":"-"},"content":" private String giverTeam;"},{"lineNumber":802,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":803,"author":{"gitId":"-"},"content":" private String giverEmail;"},{"lineNumber":804,"author":{"gitId":"-"},"content":" private String giverSection;"},{"lineNumber":805,"author":{"gitId":"-"},"content":" private String recipient;"},{"lineNumber":806,"author":{"gitId":"-"},"content":" private String recipientTeam;"},{"lineNumber":807,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":808,"author":{"gitId":"-"},"content":" private String recipientEmail;"},{"lineNumber":809,"author":{"gitId":"-"},"content":" private String recipientSection;"},{"lineNumber":810,"author":{"gitId":"-"},"content":" private FeedbackResponseDetails responseDetails;"},{"lineNumber":811,"author":{"gitId":"-"},"content":""},{"lineNumber":812,"author":{"gitId":"-"},"content":" // comments"},{"lineNumber":813,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":814,"author":{"gitId":"-"},"content":" private CommentOutput participantComment;"},{"lineNumber":815,"author":{"gitId":"-"},"content":" private List\u003cCommentOutput\u003e instructorComments;"},{"lineNumber":816,"author":{"gitId":"-"},"content":""},{"lineNumber":817,"author":{"gitId":"-"},"content":" private ResponseOutput() {"},{"lineNumber":818,"author":{"gitId":"-"},"content":" // use builder instead"},{"lineNumber":819,"author":{"gitId":"-"},"content":" }"},{"lineNumber":820,"author":{"gitId":"-"},"content":""},{"lineNumber":821,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":822,"author":{"gitId":"-"},"content":" * Returns a builder for {@link ResponseOutput}."},{"lineNumber":823,"author":{"gitId":"-"},"content":" */"},{"lineNumber":824,"author":{"gitId":"-"},"content":" static Builder builder() {"},{"lineNumber":825,"author":{"gitId":"-"},"content":" return new Builder();"},{"lineNumber":826,"author":{"gitId":"-"},"content":" }"},{"lineNumber":827,"author":{"gitId":"-"},"content":""},{"lineNumber":828,"author":{"gitId":"-"},"content":" public boolean isMissingResponse() {"},{"lineNumber":829,"author":{"gitId":"-"},"content":" return isMissingResponse;"},{"lineNumber":830,"author":{"gitId":"-"},"content":" }"},{"lineNumber":831,"author":{"gitId":"-"},"content":""},{"lineNumber":832,"author":{"gitId":"-"},"content":" public String getResponseId() {"},{"lineNumber":833,"author":{"gitId":"-"},"content":" return responseId;"},{"lineNumber":834,"author":{"gitId":"-"},"content":" }"},{"lineNumber":835,"author":{"gitId":"-"},"content":""},{"lineNumber":836,"author":{"gitId":"-"},"content":" public String getGiver() {"},{"lineNumber":837,"author":{"gitId":"-"},"content":" return giver;"},{"lineNumber":838,"author":{"gitId":"-"},"content":" }"},{"lineNumber":839,"author":{"gitId":"-"},"content":""},{"lineNumber":840,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":841,"author":{"gitId":"-"},"content":" public String getGiverEmail() {"},{"lineNumber":842,"author":{"gitId":"-"},"content":" return giverEmail;"},{"lineNumber":843,"author":{"gitId":"-"},"content":" }"},{"lineNumber":844,"author":{"gitId":"-"},"content":""},{"lineNumber":845,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":846,"author":{"gitId":"-"},"content":" public String getRelatedGiverEmail() {"},{"lineNumber":847,"author":{"gitId":"-"},"content":" return relatedGiverEmail;"},{"lineNumber":848,"author":{"gitId":"-"},"content":" }"},{"lineNumber":849,"author":{"gitId":"-"},"content":""},{"lineNumber":850,"author":{"gitId":"-"},"content":" public String getGiverTeam() {"},{"lineNumber":851,"author":{"gitId":"-"},"content":" return giverTeam;"},{"lineNumber":852,"author":{"gitId":"-"},"content":" }"},{"lineNumber":853,"author":{"gitId":"-"},"content":""},{"lineNumber":854,"author":{"gitId":"-"},"content":" public String getGiverSection() {"},{"lineNumber":855,"author":{"gitId":"-"},"content":" return giverSection;"},{"lineNumber":856,"author":{"gitId":"-"},"content":" }"},{"lineNumber":857,"author":{"gitId":"-"},"content":""},{"lineNumber":858,"author":{"gitId":"-"},"content":" public String getRecipient() {"},{"lineNumber":859,"author":{"gitId":"-"},"content":" return recipient;"},{"lineNumber":860,"author":{"gitId":"-"},"content":" }"},{"lineNumber":861,"author":{"gitId":"-"},"content":""},{"lineNumber":862,"author":{"gitId":"-"},"content":" public String getRecipientTeam() {"},{"lineNumber":863,"author":{"gitId":"-"},"content":" return recipientTeam;"},{"lineNumber":864,"author":{"gitId":"-"},"content":" }"},{"lineNumber":865,"author":{"gitId":"-"},"content":""},{"lineNumber":866,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":867,"author":{"gitId":"-"},"content":" public String getRecipientEmail() {"},{"lineNumber":868,"author":{"gitId":"-"},"content":" return recipientEmail;"},{"lineNumber":869,"author":{"gitId":"-"},"content":" }"},{"lineNumber":870,"author":{"gitId":"-"},"content":""},{"lineNumber":871,"author":{"gitId":"-"},"content":" public String getRecipientSection() {"},{"lineNumber":872,"author":{"gitId":"-"},"content":" return recipientSection;"},{"lineNumber":873,"author":{"gitId":"-"},"content":" }"},{"lineNumber":874,"author":{"gitId":"-"},"content":""},{"lineNumber":875,"author":{"gitId":"-"},"content":" public FeedbackResponseDetails getResponseDetails() {"},{"lineNumber":876,"author":{"gitId":"-"},"content":" return responseDetails;"},{"lineNumber":877,"author":{"gitId":"-"},"content":" }"},{"lineNumber":878,"author":{"gitId":"-"},"content":""},{"lineNumber":879,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":880,"author":{"gitId":"-"},"content":" public CommentOutput getParticipantComment() {"},{"lineNumber":881,"author":{"gitId":"-"},"content":" return participantComment;"},{"lineNumber":882,"author":{"gitId":"-"},"content":" }"},{"lineNumber":883,"author":{"gitId":"-"},"content":""},{"lineNumber":884,"author":{"gitId":"-"},"content":" public List\u003cCommentOutput\u003e getInstructorComments() {"},{"lineNumber":885,"author":{"gitId":"-"},"content":" return instructorComments;"},{"lineNumber":886,"author":{"gitId":"-"},"content":" }"},{"lineNumber":887,"author":{"gitId":"-"},"content":""},{"lineNumber":888,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":889,"author":{"gitId":"-"},"content":" * Builder class for {@link ResponseOutput}."},{"lineNumber":890,"author":{"gitId":"-"},"content":" */"},{"lineNumber":891,"author":{"gitId":"-"},"content":" public static final class Builder {"},{"lineNumber":892,"author":{"gitId":"-"},"content":" private final ResponseOutput responseOutput;"},{"lineNumber":893,"author":{"gitId":"-"},"content":""},{"lineNumber":894,"author":{"gitId":"-"},"content":" private Builder() {"},{"lineNumber":895,"author":{"gitId":"-"},"content":" responseOutput \u003d new ResponseOutput();"},{"lineNumber":896,"author":{"gitId":"-"},"content":" }"},{"lineNumber":897,"author":{"gitId":"-"},"content":""},{"lineNumber":898,"author":{"gitId":"-"},"content":" Builder withIsMissingResponse(boolean isMissingResponse) {"},{"lineNumber":899,"author":{"gitId":"-"},"content":" responseOutput.isMissingResponse \u003d isMissingResponse;"},{"lineNumber":900,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":901,"author":{"gitId":"-"},"content":" }"},{"lineNumber":902,"author":{"gitId":"-"},"content":""},{"lineNumber":903,"author":{"gitId":"-"},"content":" Builder withResponseId(String responseId) {"},{"lineNumber":904,"author":{"gitId":"-"},"content":" responseOutput.responseId \u003d StringHelper.encrypt(responseId);"},{"lineNumber":905,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":906,"author":{"gitId":"-"},"content":" }"},{"lineNumber":907,"author":{"gitId":"-"},"content":""},{"lineNumber":908,"author":{"gitId":"xenosf"},"content":" Builder withResponse(FeedbackResponse response) {"},{"lineNumber":909,"author":{"gitId":"xenosf"},"content":" responseOutput.responseId \u003d StringHelper.encrypt(response.getId().toString());"},{"lineNumber":910,"author":{"gitId":"xenosf"},"content":" return this;"},{"lineNumber":911,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":912,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":913,"author":{"gitId":"-"},"content":" Builder withGiver(String giverName) {"},{"lineNumber":914,"author":{"gitId":"-"},"content":" responseOutput.giver \u003d giverName;"},{"lineNumber":915,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":916,"author":{"gitId":"-"},"content":" }"},{"lineNumber":917,"author":{"gitId":"-"},"content":""},{"lineNumber":918,"author":{"gitId":"-"},"content":" Builder withRelatedGiverEmail(@Nullable String relatedGiverEmail) {"},{"lineNumber":919,"author":{"gitId":"-"},"content":" responseOutput.relatedGiverEmail \u003d relatedGiverEmail;"},{"lineNumber":920,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":921,"author":{"gitId":"-"},"content":" }"},{"lineNumber":922,"author":{"gitId":"-"},"content":""},{"lineNumber":923,"author":{"gitId":"-"},"content":" Builder withGiverTeam(String giverTeam) {"},{"lineNumber":924,"author":{"gitId":"-"},"content":" responseOutput.giverTeam \u003d giverTeam;"},{"lineNumber":925,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":926,"author":{"gitId":"-"},"content":" }"},{"lineNumber":927,"author":{"gitId":"-"},"content":""},{"lineNumber":928,"author":{"gitId":"-"},"content":" Builder withGiverEmail(@Nullable String giverEmail) {"},{"lineNumber":929,"author":{"gitId":"-"},"content":" responseOutput.giverEmail \u003d giverEmail;"},{"lineNumber":930,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":931,"author":{"gitId":"-"},"content":" }"},{"lineNumber":932,"author":{"gitId":"-"},"content":""},{"lineNumber":933,"author":{"gitId":"xenosf"},"content":" Builder withGiverSectionName(String giverSection) {"},{"lineNumber":934,"author":{"gitId":"-"},"content":" responseOutput.giverSection \u003d giverSection;"},{"lineNumber":935,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":936,"author":{"gitId":"-"},"content":" }"},{"lineNumber":937,"author":{"gitId":"-"},"content":""},{"lineNumber":938,"author":{"gitId":"xenosf"},"content":" Builder withGiverSection(Section giverSection) {"},{"lineNumber":939,"author":{"gitId":"xenosf"},"content":" responseOutput.giverSection \u003d giverSection.getName();"},{"lineNumber":940,"author":{"gitId":"xenosf"},"content":" return this;"},{"lineNumber":941,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":942,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":943,"author":{"gitId":"-"},"content":" Builder withRecipient(String recipientName) {"},{"lineNumber":944,"author":{"gitId":"-"},"content":" responseOutput.recipient \u003d recipientName;"},{"lineNumber":945,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":946,"author":{"gitId":"-"},"content":" }"},{"lineNumber":947,"author":{"gitId":"-"},"content":""},{"lineNumber":948,"author":{"gitId":"-"},"content":" Builder withRecipientTeam(String recipientTeam) {"},{"lineNumber":949,"author":{"gitId":"-"},"content":" responseOutput.recipientTeam \u003d recipientTeam;"},{"lineNumber":950,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":951,"author":{"gitId":"-"},"content":" }"},{"lineNumber":952,"author":{"gitId":"-"},"content":""},{"lineNumber":953,"author":{"gitId":"-"},"content":" Builder withRecipientEmail(@Nullable String recipientEmail) {"},{"lineNumber":954,"author":{"gitId":"-"},"content":" responseOutput.recipientEmail \u003d recipientEmail;"},{"lineNumber":955,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":956,"author":{"gitId":"-"},"content":" }"},{"lineNumber":957,"author":{"gitId":"-"},"content":""},{"lineNumber":958,"author":{"gitId":"xenosf"},"content":" Builder withRecipientSectionName(String recipientSection) {"},{"lineNumber":959,"author":{"gitId":"-"},"content":" responseOutput.recipientSection \u003d recipientSection;"},{"lineNumber":960,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":961,"author":{"gitId":"-"},"content":" }"},{"lineNumber":962,"author":{"gitId":"-"},"content":""},{"lineNumber":963,"author":{"gitId":"xenosf"},"content":" Builder withRecipientSection(Section recipientSection) {"},{"lineNumber":964,"author":{"gitId":"xenosf"},"content":" responseOutput.recipientSection \u003d recipientSection.getName();"},{"lineNumber":965,"author":{"gitId":"xenosf"},"content":" return this;"},{"lineNumber":966,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":967,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":968,"author":{"gitId":"-"},"content":" Builder withResponseDetails(FeedbackResponseDetails responseDetails) {"},{"lineNumber":969,"author":{"gitId":"-"},"content":" responseOutput.responseDetails \u003d responseDetails;"},{"lineNumber":970,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":971,"author":{"gitId":"-"},"content":" }"},{"lineNumber":972,"author":{"gitId":"-"},"content":""},{"lineNumber":973,"author":{"gitId":"-"},"content":" Builder withParticipantComment(@Nullable CommentOutput participantComment) {"},{"lineNumber":974,"author":{"gitId":"-"},"content":" responseOutput.participantComment \u003d participantComment;"},{"lineNumber":975,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":976,"author":{"gitId":"-"},"content":" }"},{"lineNumber":977,"author":{"gitId":"-"},"content":""},{"lineNumber":978,"author":{"gitId":"-"},"content":" Builder withInstructorComments(List\u003cCommentOutput\u003e instructorComments) {"},{"lineNumber":979,"author":{"gitId":"-"},"content":" responseOutput.instructorComments \u003d instructorComments;"},{"lineNumber":980,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":981,"author":{"gitId":"-"},"content":" }"},{"lineNumber":982,"author":{"gitId":"-"},"content":""},{"lineNumber":983,"author":{"gitId":"-"},"content":" ResponseOutput build() {"},{"lineNumber":984,"author":{"gitId":"-"},"content":" return responseOutput;"},{"lineNumber":985,"author":{"gitId":"-"},"content":" }"},{"lineNumber":986,"author":{"gitId":"-"},"content":" }"},{"lineNumber":987,"author":{"gitId":"-"},"content":" }"},{"lineNumber":988,"author":{"gitId":"-"},"content":""},{"lineNumber":989,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":990,"author":{"gitId":"-"},"content":" * API output format for response comments."},{"lineNumber":991,"author":{"gitId":"-"},"content":" */"},{"lineNumber":992,"author":{"gitId":"-"},"content":" public static final class CommentOutput extends FeedbackResponseCommentData {"},{"lineNumber":993,"author":{"gitId":"-"},"content":""},{"lineNumber":994,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":995,"author":{"gitId":"-"},"content":" private String commentGiverName;"},{"lineNumber":996,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":997,"author":{"gitId":"-"},"content":" private String lastEditorName;"},{"lineNumber":998,"author":{"gitId":"-"},"content":""},{"lineNumber":999,"author":{"gitId":"xenosf"},"content":" private CommentOutput(FeedbackResponseCommentAttributes frca) {"},{"lineNumber":1000,"author":{"gitId":"xenosf"},"content":" // use builder instead"},{"lineNumber":1001,"author":{"gitId":"xenosf"},"content":" super(frca);"},{"lineNumber":1002,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1003,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1004,"author":{"gitId":"xenosf"},"content":" private CommentOutput(FeedbackResponseComment frc) {"},{"lineNumber":1005,"author":{"gitId":"-"},"content":" // use builder instead"},{"lineNumber":1006,"author":{"gitId":"-"},"content":" super(frc);"},{"lineNumber":1007,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1008,"author":{"gitId":"-"},"content":""},{"lineNumber":1009,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1010,"author":{"gitId":"-"},"content":" * Returns a builder for {@link CommentOutput}."},{"lineNumber":1011,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1012,"author":{"gitId":"xenosf"},"content":" static Builder builder(FeedbackResponseCommentAttributes frca) {"},{"lineNumber":1013,"author":{"gitId":"xenosf"},"content":" return new Builder(frca);"},{"lineNumber":1014,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1015,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1016,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":1017,"author":{"gitId":"xenosf"},"content":" * Returns a builder for {@link CommentOutput}."},{"lineNumber":1018,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":1019,"author":{"gitId":"xenosf"},"content":" static Builder builder(FeedbackResponseComment frc) {"},{"lineNumber":1020,"author":{"gitId":"-"},"content":" return new Builder(frc);"},{"lineNumber":1021,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1022,"author":{"gitId":"-"},"content":""},{"lineNumber":1023,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":1024,"author":{"gitId":"-"},"content":" public String getCommentGiverName() {"},{"lineNumber":1025,"author":{"gitId":"-"},"content":" return commentGiverName;"},{"lineNumber":1026,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1027,"author":{"gitId":"-"},"content":""},{"lineNumber":1028,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":1029,"author":{"gitId":"-"},"content":" public String getLastEditorName() {"},{"lineNumber":1030,"author":{"gitId":"-"},"content":" return lastEditorName;"},{"lineNumber":1031,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1032,"author":{"gitId":"-"},"content":""},{"lineNumber":1033,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1034,"author":{"gitId":"-"},"content":" * Builder class for {@link CommentOutput}."},{"lineNumber":1035,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1036,"author":{"gitId":"-"},"content":" public static final class Builder {"},{"lineNumber":1037,"author":{"gitId":"-"},"content":" private final CommentOutput commentOutput;"},{"lineNumber":1038,"author":{"gitId":"-"},"content":""},{"lineNumber":1039,"author":{"gitId":"xenosf"},"content":" private Builder(FeedbackResponseCommentAttributes frca) {"},{"lineNumber":1040,"author":{"gitId":"xenosf"},"content":" commentOutput \u003d new CommentOutput(frca);"},{"lineNumber":1041,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":1042,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":1043,"author":{"gitId":"xenosf"},"content":" private Builder(FeedbackResponseComment frc) {"},{"lineNumber":1044,"author":{"gitId":"-"},"content":" commentOutput \u003d new CommentOutput(frc);"},{"lineNumber":1045,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1046,"author":{"gitId":"-"},"content":""},{"lineNumber":1047,"author":{"gitId":"-"},"content":" Builder withCommentGiver(@Nullable String commentGiver) {"},{"lineNumber":1048,"author":{"gitId":"-"},"content":" commentOutput.commentGiver \u003d commentGiver;"},{"lineNumber":1049,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":1050,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1051,"author":{"gitId":"-"},"content":""},{"lineNumber":1052,"author":{"gitId":"-"},"content":" Builder withCommentGiverName(@Nullable String commentGiverName) {"},{"lineNumber":1053,"author":{"gitId":"-"},"content":" commentOutput.commentGiverName \u003d commentGiverName;"},{"lineNumber":1054,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":1055,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1056,"author":{"gitId":"-"},"content":""},{"lineNumber":1057,"author":{"gitId":"-"},"content":" Builder withLastEditorEmail(@Nullable String lastEditorEmail) {"},{"lineNumber":1058,"author":{"gitId":"-"},"content":" commentOutput.lastEditorEmail \u003d lastEditorEmail;"},{"lineNumber":1059,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":1060,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1061,"author":{"gitId":"-"},"content":""},{"lineNumber":1062,"author":{"gitId":"-"},"content":" Builder withLastEditorName(@Nullable String lastEditorName) {"},{"lineNumber":1063,"author":{"gitId":"-"},"content":" commentOutput.lastEditorName \u003d lastEditorName;"},{"lineNumber":1064,"author":{"gitId":"-"},"content":" return this;"},{"lineNumber":1065,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1066,"author":{"gitId":"-"},"content":""},{"lineNumber":1067,"author":{"gitId":"-"},"content":" CommentOutput build() {"},{"lineNumber":1068,"author":{"gitId":"-"},"content":" return commentOutput;"},{"lineNumber":1069,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1070,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1071,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1072,"author":{"gitId":"-"},"content":""},{"lineNumber":1073,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":386,"-":687}},{"path":"src/main/java/teammates/ui/output/StudentData.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.output;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * The API output format of {@link StudentAttributes}."},{"lineNumber":12,"author":{"gitId":"-"},"content":" */"},{"lineNumber":13,"author":{"gitId":"-"},"content":"public class StudentData extends ApiOutput {"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":" @Nullable"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":" private final UUID studentId;"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":" private final String email;"},{"lineNumber":19,"author":{"gitId":"-"},"content":" private final String courseId;"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" private final String name;"},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":23,"author":{"gitId":"-"},"content":" private String googleId;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":25,"author":{"gitId":"-"},"content":" private String comments;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":27,"author":{"gitId":"-"},"content":" private String key;"},{"lineNumber":28,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":29,"author":{"gitId":"-"},"content":" private String institute;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" @Nullable"},{"lineNumber":31,"author":{"gitId":"-"},"content":" private JoinState joinState;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private final String teamName;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" private final String sectionName;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" public StudentData(StudentAttributes studentAttributes) {"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" this.studentId \u003d null;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" this.email \u003d studentAttributes.getEmail();"},{"lineNumber":39,"author":{"gitId":"-"},"content":" this.courseId \u003d studentAttributes.getCourse();"},{"lineNumber":40,"author":{"gitId":"-"},"content":" this.name \u003d studentAttributes.getName();"},{"lineNumber":41,"author":{"gitId":"-"},"content":" this.joinState \u003d studentAttributes.isRegistered() ? JoinState.JOINED : JoinState.NOT_JOINED;"},{"lineNumber":42,"author":{"gitId":"-"},"content":" this.comments \u003d studentAttributes.getComments();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" this.teamName \u003d studentAttributes.getTeam();"},{"lineNumber":44,"author":{"gitId":"-"},"content":" this.sectionName \u003d studentAttributes.getSection();"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" public StudentData(Student student) {"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" this.studentId \u003d student.getId();"},{"lineNumber":49,"author":{"gitId":"-"},"content":" this.email \u003d student.getEmail();"},{"lineNumber":50,"author":{"gitId":"-"},"content":" this.courseId \u003d student.getCourseId();"},{"lineNumber":51,"author":{"gitId":"-"},"content":" this.name \u003d student.getName();"},{"lineNumber":52,"author":{"gitId":"-"},"content":" this.joinState \u003d student.isRegistered() ? JoinState.JOINED : JoinState.NOT_JOINED;"},{"lineNumber":53,"author":{"gitId":"-"},"content":" this.comments \u003d student.getComments();"},{"lineNumber":54,"author":{"gitId":"-"},"content":" this.teamName \u003d student.getTeamName();"},{"lineNumber":55,"author":{"gitId":"-"},"content":" this.sectionName \u003d student.getSectionName();"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" public UUID getStudentId() {"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" return studentId;"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" public String getEmail() {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" return email;"},{"lineNumber":64,"author":{"gitId":"-"},"content":" }"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" public String getCourseId() {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" return courseId;"},{"lineNumber":68,"author":{"gitId":"-"},"content":" }"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" public String getName() {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" return name;"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" public String getGoogleId() {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" return googleId;"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" public String getComments() {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" return comments;"},{"lineNumber":80,"author":{"gitId":"-"},"content":" }"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" public JoinState getJoinState() {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" return joinState;"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" public String getTeamName() {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" return teamName;"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" public String getSectionName() {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" return sectionName;"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" public String getKey() {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" return key;"},{"lineNumber":96,"author":{"gitId":"-"},"content":" }"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" public String getInstitute() {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" return institute;"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" public void setGoogleId(String googleId) {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" this.googleId \u003d googleId;"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" public void setComments(String comments) {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" this.comments \u003d comments;"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" public void setJoinState(JoinState joinState) {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" this.joinState \u003d joinState;"},{"lineNumber":112,"author":{"gitId":"-"},"content":" }"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" public void setKey(String key) {"},{"lineNumber":115,"author":{"gitId":"-"},"content":" this.key \u003d key;"},{"lineNumber":116,"author":{"gitId":"-"},"content":" }"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" public void setInstitute(String institute) {"},{"lineNumber":119,"author":{"gitId":"-"},"content":" this.institute \u003d institute;"},{"lineNumber":120,"author":{"gitId":"-"},"content":" }"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":123,"author":{"gitId":"-"},"content":" * Hides some attributes to student."},{"lineNumber":124,"author":{"gitId":"-"},"content":" */"},{"lineNumber":125,"author":{"gitId":"-"},"content":" public void hideInformationForStudent() {"},{"lineNumber":126,"author":{"gitId":"-"},"content":" setComments(null);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" setJoinState(null);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":131,"author":{"gitId":"-"},"content":" * Adds additional information only for search result for admin."},{"lineNumber":132,"author":{"gitId":"-"},"content":" * @param key The registration key"},{"lineNumber":133,"author":{"gitId":"-"},"content":" * @param institute The institute of the student"},{"lineNumber":134,"author":{"gitId":"-"},"content":" * @param googleId The googleId of the student"},{"lineNumber":135,"author":{"gitId":"-"},"content":" */"},{"lineNumber":136,"author":{"gitId":"-"},"content":" public void addAdditionalInformationForAdminSearch(String key, String institute, String googleId) {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" this.setKey(key);"},{"lineNumber":138,"author":{"gitId":"-"},"content":" this.setInstitute(institute);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" this.setGoogleId(googleId);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":11,"-":130}},{"path":"src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.ui.request;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import java.util.Objects;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":" * The request reasonBody for rejecting an account request."},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":"public class AccountRequestRejectionRequest extends BasicRequest {"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" @Nullable"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":" private String reasonTitle;"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" @Nullable"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" private String reasonBody;"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":" public AccountRequestRejectionRequest(String reasonTitle, String reasonBody) {"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" this.reasonTitle \u003d SanitizationHelper.sanitizeTitle(reasonTitle);"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" this.reasonBody \u003d SanitizationHelper.sanitizeForRichText(reasonBody);"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" public void validate() throws InvalidHttpRequestBodyException {"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" if (reasonBody \u003d\u003d null || reasonTitle \u003d\u003d null) {"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" assertTrue(Objects.equals(reasonBody, reasonTitle),"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" \"Both reason body and title need to be null to reject silently\");"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" public String getReasonTitle() {"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" return this.reasonTitle;"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" public String getReasonBody() {"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" return this.reasonBody;"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" * Returns true if both reason body and title are non-null."},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" public boolean checkHasReason() {"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" return this.reasonBody !\u003d null \u0026\u0026 this.reasonTitle !\u003d null;"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":45,"-":1}},{"path":"src/main/java/teammates/ui/request/AccountRequestUpdateRequest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.ui.request;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import jakarta.annotation.Nullable;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":" * The create request for an account request update request."},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"public class AccountRequestUpdateRequest extends BasicRequest {"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":" private String name;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":" private String email;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":" private String institute;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" private AccountRequestStatus status;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" @Nullable"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" private String comments;"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" public AccountRequestUpdateRequest(String name, String email, String institute, AccountRequestStatus status,"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" String comments) {"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" this.name \u003d SanitizationHelper.sanitizeName(name);"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" this.email \u003d SanitizationHelper.sanitizeEmail(email);"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" this.institute \u003d SanitizationHelper.sanitizeName(institute);"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" this.status \u003d status;"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" if (comments !\u003d null) {"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" this.comments \u003d SanitizationHelper.sanitizeTextField(comments);"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" public void validate() throws InvalidHttpRequestBodyException {"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" assertTrue(name !\u003d null, \"name cannot be null\");"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" assertTrue(email !\u003d null, \"email cannot be null\");"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" assertTrue(institute !\u003d null, \"institute cannot be null\");"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" assertTrue(status !\u003d null, \"status cannot be null\");"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" assertTrue(status \u003d\u003d AccountRequestStatus.APPROVED"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" || status \u003d\u003d AccountRequestStatus.REJECTED"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" || status \u003d\u003d AccountRequestStatus.PENDING"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" || status \u003d\u003d AccountRequestStatus.REGISTERED,"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" \"status must be one of the following: APPROVED, REJECTED, PENDING, REGISTERED\");"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" public String getName() {"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" return this.name;"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" public String getEmail() {"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" return this.email;"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" public String getInstitute() {"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" return this.institute;"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" public AccountRequestStatus getStatus() {"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" return this.status;"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" public String getComments() {"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" return this.comments;"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":62,"-":1}},{"path":"src/main/java/teammates/ui/webapi/AccountRequestSearchIndexingWorkerAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.ParamsNames;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":12,"author":{"gitId":"-"},"content":" * Task queue worker action: performs account request search indexing."},{"lineNumber":13,"author":{"gitId":"-"},"content":" */"},{"lineNumber":14,"author":{"gitId":"-"},"content":"public class AccountRequestSearchIndexingWorkerAction extends AdminOnlyAction {"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":17,"author":{"gitId":"-"},"content":" public ActionResult execute() {"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" String id \u003d getNonNullRequestParamValue(ParamsNames.ACCOUNT_REQUEST_ID);"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" UUID accountRequestId;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" accountRequestId \u003d UUID.fromString(id);"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" } catch (IllegalArgumentException e) {"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" throw new InvalidHttpParameterException(e.getMessage(), e);"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" AccountRequest accRequest \u003d sqlLogic.getAccountRequest(accountRequestId);"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" sqlLogic.putAccountRequestDocument(accRequest);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" // Set an arbitrary retry code outside of the range 200-299 to trigger automatic retry"},{"lineNumber":33,"author":{"gitId":"-"},"content":" return new JsonResult(\"Failure\", HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" return new JsonResult(\"Successful\");"},{"lineNumber":37,"author":{"gitId":"-"},"content":" }"},{"lineNumber":38,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":13,"-":25}},{"path":"src/main/java/teammates/ui/webapi/ActionFactory.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import jakarta.servlet.http.HttpServletRequest;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpDelete;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpGet;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpPost;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpPut;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.CronJobURIs;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.ResourceURIs;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.TaskQueue;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * Generates the matching {@link Action} for a given URI and request method."},{"lineNumber":20,"author":{"gitId":"-"},"content":" */"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public final class ActionFactory {"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" static final Map\u003cString, Map\u003cString, Class\u003c? extends Action\u003e\u003e\u003e ACTION_MAPPINGS \u003d new HashMap\u003c\u003e();"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" private static final String GET \u003d HttpGet.METHOD_NAME;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" private static final String POST \u003d HttpPost.METHOD_NAME;"},{"lineNumber":27,"author":{"gitId":"-"},"content":" private static final String PUT \u003d HttpPut.METHOD_NAME;"},{"lineNumber":28,"author":{"gitId":"-"},"content":" private static final String DELETE \u003d HttpDelete.METHOD_NAME;"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" static {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" map(ResourceURIs.DATABUNDLE, POST, PutDataBundleAction.class);"},{"lineNumber":32,"author":{"gitId":"-"},"content":" // Even though this is a DELETE action, PUT is used as DELETE does not allow usage of response body"},{"lineNumber":33,"author":{"gitId":"-"},"content":" map(ResourceURIs.DATABUNDLE, PUT, DeleteDataBundleAction.class);"},{"lineNumber":34,"author":{"gitId":"-"},"content":" map(ResourceURIs.SQL_DATABUNDLE, POST, PutSqlDataBundleAction.class);"},{"lineNumber":35,"author":{"gitId":"-"},"content":" // Even though this is a DELETE action, PUT is used as DELETE does not allow usage of response body"},{"lineNumber":36,"author":{"gitId":"-"},"content":" map(ResourceURIs.SQL_DATABUNDLE, PUT, DeleteSqlDataBundleAction.class);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" map(ResourceURIs.DATABUNDLE_DOCUMENTS, PUT, PutDataBundleDocumentsAction.class);"},{"lineNumber":38,"author":{"gitId":"-"},"content":" map(ResourceURIs.EXCEPTION, GET, AdminExceptionTestAction.class);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" // Even though this is a GET action, POST is used in order to get extra protection from CSRF"},{"lineNumber":40,"author":{"gitId":"-"},"content":" map(ResourceURIs.USER_COOKIE, POST, GetUserCookieAction.class);"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" map(ResourceURIs.ERROR_REPORT, POST, SendErrorReportAction.class);"},{"lineNumber":43,"author":{"gitId":"-"},"content":" map(ResourceURIs.TIMEZONE, GET, GetTimeZonesAction.class);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" map(ResourceURIs.AUTH, GET, GetAuthInfoAction.class);"},{"lineNumber":45,"author":{"gitId":"-"},"content":" map(ResourceURIs.AUTH_REGKEY, GET, GetRegkeyValidityAction.class);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNT, GET, GetAccountAction.class);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNT, POST, CreateAccountAction.class);"},{"lineNumber":48,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNT, DELETE, DeleteAccountAction.class);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNT_RESET, PUT, ResetAccountAction.class);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNT_REQUEST, GET, GetAccountRequestAction.class);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNT_REQUEST, POST, CreateAccountRequestAction.class);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNT_REQUEST, DELETE, DeleteAccountRequestAction.class);"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" map(ResourceURIs.ACCOUNT_REQUEST, PUT, UpdateAccountRequestAction.class);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNT_REQUESTS, GET, GetAccountRequestsAction.class);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNT_REQUEST_RESET, PUT, ResetAccountRequestAction.class);"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" map(ResourceURIs.ACCOUNT_REQUEST_REJECTION, POST, RejectAccountRequestAction.class);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACCOUNTS, GET, GetAccountsAction.class);"},{"lineNumber":58,"author":{"gitId":"-"},"content":" map(ResourceURIs.COURSE, GET, GetCourseAction.class);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" map(ResourceURIs.COURSE, DELETE, DeleteCourseAction.class);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" map(ResourceURIs.COURSE, POST, CreateCourseAction.class);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" map(ResourceURIs.COURSE, PUT, UpdateCourseAction.class);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" map(ResourceURIs.COURSE_ARCHIVE, PUT, ArchiveCourseAction.class);"},{"lineNumber":63,"author":{"gitId":"-"},"content":" map(ResourceURIs.DEADLINE_EXTENSION, GET, GetDeadlineExtensionAction.class);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" map(ResourceURIs.BIN_COURSE, PUT, BinCourseAction.class);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" map(ResourceURIs.BIN_COURSE, DELETE, RestoreCourseAction.class);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" map(ResourceURIs.COURSES, GET, GetCoursesAction.class);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" map(ResourceURIs.COURSE_SECTIONS, GET, GetCourseSectionNamesAction.class);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" map(ResourceURIs.INSTRUCTORS, GET, GetInstructorsAction.class);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" map(ResourceURIs.INSTRUCTOR, GET, GetInstructorAction.class);"},{"lineNumber":70,"author":{"gitId":"-"},"content":" map(ResourceURIs.INSTRUCTOR, DELETE, DeleteInstructorAction.class);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" map(ResourceURIs.INSTRUCTOR_PRIVILEGE, GET, GetInstructorPrivilegeAction.class);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" map(ResourceURIs.INSTRUCTOR_PRIVILEGE, PUT, UpdateInstructorPrivilegeAction.class);"},{"lineNumber":73,"author":{"gitId":"-"},"content":" map(ResourceURIs.RESPONSE_COMMENT, POST, CreateFeedbackResponseCommentAction.class);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" map(ResourceURIs.RESPONSE_COMMENT, GET, GetFeedbackResponseCommentAction.class);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" map(ResourceURIs.RESPONSE_COMMENT, PUT, UpdateFeedbackResponseCommentAction.class);"},{"lineNumber":76,"author":{"gitId":"-"},"content":" map(ResourceURIs.RESPONSE_COMMENT, DELETE, DeleteFeedbackResponseCommentAction.class);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" map(ResourceURIs.RESULT, GET, GetSessionResultsAction.class);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" map(ResourceURIs.LOGIN_EMAIL, POST, SendLoginEmailAction.class);"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" //STUDENTS APIs"},{"lineNumber":81,"author":{"gitId":"-"},"content":" map(ResourceURIs.STUDENTS, GET, GetStudentsAction.class);"},{"lineNumber":82,"author":{"gitId":"-"},"content":" map(ResourceURIs.STUDENTS, PUT, EnrollStudentsAction.class);"},{"lineNumber":83,"author":{"gitId":"-"},"content":" map(ResourceURIs.STUDENTS, DELETE, DeleteStudentsAction.class);"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" //STUDENT APIs"},{"lineNumber":86,"author":{"gitId":"-"},"content":" map(ResourceURIs.STUDENT, DELETE, DeleteStudentAction.class);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" map(ResourceURIs.STUDENT, GET, GetStudentAction.class);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" map(ResourceURIs.STUDENT, PUT, UpdateStudentAction.class);"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" // NOTIFICATION APIs"},{"lineNumber":91,"author":{"gitId":"-"},"content":" map(ResourceURIs.NOTIFICATION, GET, GetNotificationAction.class);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" map(ResourceURIs.NOTIFICATION, POST, CreateNotificationAction.class);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" map(ResourceURIs.NOTIFICATION, PUT, UpdateNotificationAction.class);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" map(ResourceURIs.NOTIFICATION, DELETE, DeleteNotificationAction.class);"},{"lineNumber":95,"author":{"gitId":"-"},"content":" map(ResourceURIs.NOTIFICATION_READ, POST, MarkNotificationAsReadAction.class);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" map(ResourceURIs.NOTIFICATION_READ, GET, GetReadNotificationsAction.class);"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" // NOTIFICATIONS APIs"},{"lineNumber":99,"author":{"gitId":"-"},"content":" map(ResourceURIs.NOTIFICATIONS, GET, GetNotificationsAction.class);"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" //SEARCH APIs"},{"lineNumber":102,"author":{"gitId":"-"},"content":" map(ResourceURIs.SEARCH_INSTRUCTORS, GET, SearchInstructorsAction.class);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" map(ResourceURIs.SEARCH_STUDENTS, GET, SearchStudentsAction.class);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" map(ResourceURIs.SEARCH_ACCOUNT_REQUESTS, GET, SearchAccountRequestsAction.class);"},{"lineNumber":105,"author":{"gitId":"-"},"content":" map(ResourceURIs.EMAIL, GET, GenerateEmailAction.class);"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSIONS_ONGOING, GET, GetOngoingSessionsAction.class);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION_STATS, GET, GetSessionResponseStatsAction.class);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION, GET, GetFeedbackSessionAction.class);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION, PUT, UpdateFeedbackSessionAction.class);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION, POST, CreateFeedbackSessionAction.class);"},{"lineNumber":112,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION, DELETE, DeleteFeedbackSessionAction.class);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION_PUBLISH, POST, PublishFeedbackSessionAction.class);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION_PUBLISH, DELETE, UnpublishFeedbackSessionAction.class);"},{"lineNumber":115,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION_SUBMITTED_GIVER_SET, GET, GetFeedbackSessionSubmittedGiverSetAction.class);"},{"lineNumber":116,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION_REMIND_SUBMISSION, POST, RemindFeedbackSessionSubmissionAction.class);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION_REMIND_RESULT, POST, RemindFeedbackSessionResultAction.class);"},{"lineNumber":118,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSIONS, GET, GetFeedbackSessionsAction.class);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" map(ResourceURIs.BIN_SESSION, PUT, BinFeedbackSessionAction.class);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" map(ResourceURIs.BIN_SESSION, DELETE, RestoreFeedbackSessionAction.class);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" map(ResourceURIs.INSTRUCTOR_KEY, POST, RegenerateInstructorKeyAction.class);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" map(ResourceURIs.STUDENT_KEY, POST, RegenerateStudentKeyAction.class);"},{"lineNumber":123,"author":{"gitId":"-"},"content":" map(ResourceURIs.QUESTIONS, GET, GetFeedbackQuestionsAction.class);"},{"lineNumber":124,"author":{"gitId":"-"},"content":" map(ResourceURIs.QUESTION, POST, CreateFeedbackQuestionAction.class);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" map(ResourceURIs.QUESTION, PUT, UpdateFeedbackQuestionAction.class);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" map(ResourceURIs.QUESTION, DELETE, DeleteFeedbackQuestionAction.class);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" map(ResourceURIs.QUESTION_RECIPIENTS, GET, GetFeedbackQuestionRecipientsAction.class);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" map(ResourceURIs.RESPONSES, GET, GetFeedbackResponsesAction.class);"},{"lineNumber":129,"author":{"gitId":"-"},"content":" map(ResourceURIs.RESPONSES, PUT, SubmitFeedbackResponsesAction.class);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" map(ResourceURIs.HAS_RESPONSES, GET, GetHasResponsesAction.class);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION_LINKS_RECOVERY, POST, SessionLinksRecoveryAction.class);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" map(ResourceURIs.JOIN, GET, GetCourseJoinStatusAction.class);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" map(ResourceURIs.JOIN, PUT, JoinCourseAction.class);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" map(ResourceURIs.JOIN_REMIND, POST, SendJoinReminderEmailAction.class);"},{"lineNumber":135,"author":{"gitId":"-"},"content":" map(ResourceURIs.INSTRUCTOR, PUT, UpdateInstructorAction.class);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" map(ResourceURIs.INSTRUCTOR, POST, CreateInstructorAction.class);"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" // Logging and tracking"},{"lineNumber":139,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION_LOGS, POST, CreateFeedbackSessionLogAction.class);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" map(ResourceURIs.SESSION_LOGS, GET, GetFeedbackSessionLogsAction.class);"},{"lineNumber":141,"author":{"gitId":"-"},"content":" map(ResourceURIs.LOGS, GET, QueryLogsAction.class);"},{"lineNumber":142,"author":{"gitId":"-"},"content":" map(ResourceURIs.USAGE_STATISTICS, GET, GetUsageStatisticsAction.class);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" map(ResourceURIs.ACTION_CLASS, GET, GetActionClassesAction.class);"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" // Cron jobs; use GET request"},{"lineNumber":146,"author":{"gitId":"-"},"content":" // Reference: https://cloud.google.com/appengine/docs/standard/scheduling-jobs-with-cron-yaml"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" map(CronJobURIs.AUTOMATED_LOG_COMPILATION, GET, CompileLogsAction.class);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" map(CronJobURIs.AUTOMATED_DATASTORE_BACKUP, GET, DatastoreBackupAction.class);"},{"lineNumber":150,"author":{"gitId":"-"},"content":" map(CronJobURIs.AUTOMATED_FEEDBACK_OPENING_REMINDERS, GET, FeedbackSessionOpeningRemindersAction.class);"},{"lineNumber":151,"author":{"gitId":"-"},"content":" map(CronJobURIs.AUTOMATED_FEEDBACK_CLOSED_REMINDERS, GET, FeedbackSessionClosedRemindersAction.class);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" map(CronJobURIs.AUTOMATED_FEEDBACK_CLOSING_REMINDERS, GET, FeedbackSessionClosingRemindersAction.class);"},{"lineNumber":153,"author":{"gitId":"-"},"content":" map(CronJobURIs.AUTOMATED_FEEDBACK_PUBLISHED_REMINDERS, GET, FeedbackSessionPublishedRemindersAction.class);"},{"lineNumber":154,"author":{"gitId":"-"},"content":" map(CronJobURIs.AUTOMATED_FEEDBACK_OPENING_SOON_REMINDERS, GET,"},{"lineNumber":155,"author":{"gitId":"-"},"content":" FeedbackSessionOpeningSoonRemindersAction.class);"},{"lineNumber":156,"author":{"gitId":"-"},"content":" map(CronJobURIs.AUTOMATED_USAGE_STATISTICS_COLLECTION, GET, CalculateUsageStatisticsAction.class);"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":" map(CronJobURIs.AUTOMATED_FEEDBACK_SESSION_LOGS_PROCESSING, GET, UpdateFeedbackSessionLogsAction.class);"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" // Task queue workers; use POST request"},{"lineNumber":160,"author":{"gitId":"-"},"content":" // Reference: https://cloud.google.com/tasks/docs/creating-appengine-tasks"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"-"},"content":" map(TaskQueue.FEEDBACK_SESSION_PUBLISHED_EMAIL_WORKER_URL, POST, FeedbackSessionPublishedEmailWorkerAction.class);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" map(TaskQueue.FEEDBACK_SESSION_RESEND_PUBLISHED_EMAIL_WORKER_URL, POST,"},{"lineNumber":164,"author":{"gitId":"-"},"content":" FeedbackSessionResendPublishedEmailWorkerAction.class);"},{"lineNumber":165,"author":{"gitId":"-"},"content":" map(TaskQueue.FEEDBACK_SESSION_REMIND_EMAIL_WORKER_URL, POST, FeedbackSessionRemindEmailWorkerAction.class);"},{"lineNumber":166,"author":{"gitId":"-"},"content":" map(TaskQueue.FEEDBACK_SESSION_REMIND_PARTICULAR_USERS_EMAIL_WORKER_URL, POST,"},{"lineNumber":167,"author":{"gitId":"-"},"content":" FeedbackSessionRemindParticularUsersEmailWorkerAction.class);"},{"lineNumber":168,"author":{"gitId":"-"},"content":" map(TaskQueue.FEEDBACK_SESSION_UNPUBLISHED_EMAIL_WORKER_URL, POST,"},{"lineNumber":169,"author":{"gitId":"-"},"content":" FeedbackSessionUnpublishedEmailWorkerAction.class);"},{"lineNumber":170,"author":{"gitId":"-"},"content":" map(TaskQueue.INSTRUCTOR_COURSE_JOIN_EMAIL_WORKER_URL, POST, InstructorCourseJoinEmailWorkerAction.class);"},{"lineNumber":171,"author":{"gitId":"-"},"content":" map(TaskQueue.SEND_EMAIL_WORKER_URL, POST, SendEmailWorkerAction.class);"},{"lineNumber":172,"author":{"gitId":"-"},"content":" map(TaskQueue.STUDENT_COURSE_JOIN_EMAIL_WORKER_URL, POST, StudentCourseJoinEmailWorkerAction.class);"},{"lineNumber":173,"author":{"gitId":"-"},"content":" map(TaskQueue.ACCOUNT_REQUEST_SEARCH_INDEXING_WORKER_URL, POST, AccountRequestSearchIndexingWorkerAction.class);"},{"lineNumber":174,"author":{"gitId":"-"},"content":" map(TaskQueue.INSTRUCTOR_SEARCH_INDEXING_WORKER_URL, POST, InstructorSearchIndexingWorkerAction.class);"},{"lineNumber":175,"author":{"gitId":"-"},"content":" map(TaskQueue.STUDENT_SEARCH_INDEXING_WORKER_URL, POST, StudentSearchIndexingWorkerAction.class);"},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" private ActionFactory() {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" // prevent initialization"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" private static void map(String uri, String method, Class\u003c? extends Action\u003e actionClass) {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" ACTION_MAPPINGS.computeIfAbsent(uri, k -\u003e new HashMap\u003c\u003e()).put(method, actionClass);"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":188,"author":{"gitId":"-"},"content":" * Returns the matching {@link Action} object for the URI and method in {@code req}."},{"lineNumber":189,"author":{"gitId":"-"},"content":" */"},{"lineNumber":190,"author":{"gitId":"-"},"content":" public static Action getAction(HttpServletRequest req, String method) throws ActionMappingException {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" String uri \u003d req.getRequestURI();"},{"lineNumber":192,"author":{"gitId":"-"},"content":" if (uri.contains(\";\")) {"},{"lineNumber":193,"author":{"gitId":"-"},"content":" uri \u003d uri.split(\";\")[0];"},{"lineNumber":194,"author":{"gitId":"-"},"content":" }"},{"lineNumber":195,"author":{"gitId":"-"},"content":" return getAction(uri, method);"},{"lineNumber":196,"author":{"gitId":"-"},"content":" }"},{"lineNumber":197,"author":{"gitId":"-"},"content":""},{"lineNumber":198,"author":{"gitId":"-"},"content":" private static Action getAction(String uri, String method) throws ActionMappingException {"},{"lineNumber":199,"author":{"gitId":"-"},"content":" if (!ACTION_MAPPINGS.containsKey(uri)) {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" throw new ActionMappingException(\"Resource with URI \" + uri + \" is not found.\", HttpStatus.SC_NOT_FOUND);"},{"lineNumber":201,"author":{"gitId":"-"},"content":" }"},{"lineNumber":202,"author":{"gitId":"-"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":" Class\u003c? extends Action\u003e controllerClass \u003d"},{"lineNumber":204,"author":{"gitId":"-"},"content":" ACTION_MAPPINGS.getOrDefault(uri, new HashMap\u003c\u003e()).get(method);"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" if (controllerClass \u003d\u003d null) {"},{"lineNumber":207,"author":{"gitId":"-"},"content":" throw new ActionMappingException(\"Method [\" + method + \"] is not allowed for URI \" + uri + \".\","},{"lineNumber":208,"author":{"gitId":"-"},"content":" HttpStatus.SC_METHOD_NOT_ALLOWED);"},{"lineNumber":209,"author":{"gitId":"-"},"content":" }"},{"lineNumber":210,"author":{"gitId":"-"},"content":""},{"lineNumber":211,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" return controllerClass.getDeclaredConstructor().newInstance();"},{"lineNumber":213,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":214,"author":{"gitId":"-"},"content":" assert false : \"Could not create the action for \" + uri;"},{"lineNumber":215,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":216,"author":{"gitId":"-"},"content":" }"},{"lineNumber":217,"author":{"gitId":"-"},"content":" }"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":1,"xenosf":1,"dishenggg":1,"-":216}},{"path":"src/main/java/teammates/ui/webapi/BasicFeedbackSubmissionAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.StringHelper;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * The basic action for feedback submission."},{"lineNumber":18,"author":{"gitId":"-"},"content":" */"},{"lineNumber":19,"author":{"gitId":"-"},"content":"abstract class BasicFeedbackSubmissionAction extends Action {"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":22,"author":{"gitId":"-"},"content":" * Checks whether instructors can see the question."},{"lineNumber":23,"author":{"gitId":"-"},"content":" */"},{"lineNumber":24,"author":{"gitId":"-"},"content":" boolean canInstructorSeeQuestion(FeedbackQuestionAttributes feedbackQuestion) {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" boolean isGiverVisibleToInstructor \u003d"},{"lineNumber":26,"author":{"gitId":"-"},"content":" feedbackQuestion.getShowGiverNameTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":27,"author":{"gitId":"-"},"content":" boolean isRecipientVisibleToInstructor \u003d"},{"lineNumber":28,"author":{"gitId":"-"},"content":" feedbackQuestion.getShowRecipientNameTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":29,"author":{"gitId":"-"},"content":" boolean isResponseVisibleToInstructor \u003d"},{"lineNumber":30,"author":{"gitId":"-"},"content":" feedbackQuestion.getShowResponsesTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" return isResponseVisibleToInstructor \u0026\u0026 isGiverVisibleToInstructor \u0026\u0026 isRecipientVisibleToInstructor;"},{"lineNumber":32,"author":{"gitId":"-"},"content":" }"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":35,"author":{"gitId":"-"},"content":" * Checks whether instructors can see the question."},{"lineNumber":36,"author":{"gitId":"-"},"content":" */"},{"lineNumber":37,"author":{"gitId":"-"},"content":" boolean canInstructorSeeQuestion(FeedbackQuestion feedbackQuestion) {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" boolean isGiverVisibleToInstructor \u003d"},{"lineNumber":39,"author":{"gitId":"-"},"content":" feedbackQuestion.getShowGiverNameTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":40,"author":{"gitId":"-"},"content":" boolean isRecipientVisibleToInstructor \u003d"},{"lineNumber":41,"author":{"gitId":"-"},"content":" feedbackQuestion.getShowRecipientNameTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":42,"author":{"gitId":"-"},"content":" boolean isResponseVisibleToInstructor \u003d"},{"lineNumber":43,"author":{"gitId":"-"},"content":" feedbackQuestion.getShowResponsesTo().contains(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return isResponseVisibleToInstructor \u0026\u0026 isGiverVisibleToInstructor \u0026\u0026 isRecipientVisibleToInstructor;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" }"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":48,"author":{"gitId":"-"},"content":" * Verifies that instructor can see the moderated question in moderation request."},{"lineNumber":49,"author":{"gitId":"-"},"content":" */"},{"lineNumber":50,"author":{"gitId":"-"},"content":" void verifyInstructorCanSeeQuestionIfInModeration(FeedbackQuestionAttributes feedbackQuestion)"},{"lineNumber":51,"author":{"gitId":"-"},"content":" throws UnauthorizedAccessException {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson) \u0026\u0026 !canInstructorSeeQuestion(feedbackQuestion)) {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" // should not moderate question which instructors cannot see"},{"lineNumber":56,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"The question is not applicable for moderation\", true);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":61,"author":{"gitId":"-"},"content":" * Verifies that instructor can see the moderated question in moderation request."},{"lineNumber":62,"author":{"gitId":"-"},"content":" */"},{"lineNumber":63,"author":{"gitId":"-"},"content":" void verifyInstructorCanSeeQuestionIfInModeration(FeedbackQuestion feedbackQuestion)"},{"lineNumber":64,"author":{"gitId":"-"},"content":" throws UnauthorizedAccessException {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson) \u0026\u0026 !canInstructorSeeQuestion(feedbackQuestion)) {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" // should not moderate question which instructors cannot see"},{"lineNumber":69,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"The question is not applicable for moderation\", true);"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":74,"author":{"gitId":"-"},"content":" * Gets the student involved in the submission process."},{"lineNumber":75,"author":{"gitId":"-"},"content":" */"},{"lineNumber":76,"author":{"gitId":"-"},"content":" StudentAttributes getStudentOfCourseFromRequest(String courseId) {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson)) {"},{"lineNumber":81,"author":{"gitId":"-"},"content":" return logic.getStudentForEmail(courseId, moderatedPerson);"},{"lineNumber":82,"author":{"gitId":"-"},"content":" } else if (!StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" return logic.getStudentForEmail(courseId, previewAsPerson);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" return getPossiblyUnregisteredStudent(courseId);"},{"lineNumber":86,"author":{"gitId":"-"},"content":" }"},{"lineNumber":87,"author":{"gitId":"-"},"content":" }"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":90,"author":{"gitId":"-"},"content":" * Gets the student involved in the submission process."},{"lineNumber":91,"author":{"gitId":"-"},"content":" */"},{"lineNumber":92,"author":{"gitId":"-"},"content":" Student getSqlStudentOfCourseFromRequest(String courseId) {"},{"lineNumber":93,"author":{"gitId":"-"},"content":" // TODO: Rename method to remove Sql after migration."},{"lineNumber":94,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":95,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson)) {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" return sqlLogic.getStudentForEmail(courseId, moderatedPerson);"},{"lineNumber":99,"author":{"gitId":"-"},"content":" } else if (!StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" return sqlLogic.getStudentForEmail(courseId, previewAsPerson);"},{"lineNumber":101,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" return getPossiblyUnregisteredSqlStudent(courseId);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" }"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":107,"author":{"gitId":"-"},"content":" * Checks the access control for student feedback submission."},{"lineNumber":108,"author":{"gitId":"-"},"content":" */"},{"lineNumber":109,"author":{"gitId":"-"},"content":" void checkAccessControlForStudentFeedbackSubmission("},{"lineNumber":110,"author":{"gitId":"-"},"content":" StudentAttributes student, FeedbackSessionAttributes feedbackSession) throws UnauthorizedAccessException {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Trying to access system using a non-existent student entity\");"},{"lineNumber":113,"author":{"gitId":"-"},"content":" }"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":116,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson)) {"},{"lineNumber":119,"author":{"gitId":"-"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":121,"author":{"gitId":"-"},"content":" logic.getInstructorForGoogleId(feedbackSession.getCourseId(), userInfo.getId()), feedbackSession,"},{"lineNumber":122,"author":{"gitId":"-"},"content":" student.getSection(),"},{"lineNumber":123,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_MODIFY_SESSION_COMMENT_IN_SECTIONS);"},{"lineNumber":124,"author":{"gitId":"-"},"content":" } else if (!StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" checkAccessControlForPreview(feedbackSession, false);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":127,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(student, feedbackSession);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" verifyMatchingGoogleId(student.getGoogleId());"},{"lineNumber":129,"author":{"gitId":"-"},"content":" }"},{"lineNumber":130,"author":{"gitId":"-"},"content":" }"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":133,"author":{"gitId":"-"},"content":" * Checks the access control for student feedback submission."},{"lineNumber":134,"author":{"gitId":"-"},"content":" */"},{"lineNumber":135,"author":{"gitId":"-"},"content":" void checkAccessControlForStudentFeedbackSubmission(Student student, FeedbackSession feedbackSession)"},{"lineNumber":136,"author":{"gitId":"-"},"content":" throws UnauthorizedAccessException {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":138,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Trying to access system using a non-existent student entity\");"},{"lineNumber":139,"author":{"gitId":"-"},"content":" }"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":142,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson)) {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":147,"author":{"gitId":"-"},"content":" sqlLogic.getInstructorByGoogleId(feedbackSession.getCourse().getId(), userInfo.getId()), feedbackSession,"},{"lineNumber":148,"author":{"gitId":"-"},"content":" student.getSectionName(),"},{"lineNumber":149,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_MODIFY_SESSION_COMMENT_IN_SECTIONS);"},{"lineNumber":150,"author":{"gitId":"-"},"content":" } else if (!StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":153,"author":{"gitId":"-"},"content":" sqlLogic.getInstructorByGoogleId(feedbackSession.getCourse().getId(), userInfo.getId()), feedbackSession,"},{"lineNumber":154,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":155,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(student, feedbackSession);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" if (student.getAccount() !\u003d null) {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" if (userInfo \u003d\u003d null) {"},{"lineNumber":159,"author":{"gitId":"-"},"content":" // Student is associated with an account; even if registration key is passed, do not allow access"},{"lineNumber":160,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Login is required to access this feedback session\");"},{"lineNumber":161,"author":{"gitId":"-"},"content":" } else if (!userInfo.id.equals(student.getAccount().getGoogleId())) {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" // Logged in student is not the same as the student registered for the given key, do not allow access"},{"lineNumber":163,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"You are not authorized to access this feedback session\");"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":" }"},{"lineNumber":167,"author":{"gitId":"-"},"content":" }"},{"lineNumber":168,"author":{"gitId":"-"},"content":""},{"lineNumber":169,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":170,"author":{"gitId":"-"},"content":" * Checks the access control for student feedback result."},{"lineNumber":171,"author":{"gitId":"-"},"content":" */"},{"lineNumber":172,"author":{"gitId":"-"},"content":" void checkAccessControlForStudentFeedbackResult("},{"lineNumber":173,"author":{"gitId":"-"},"content":" StudentAttributes student, FeedbackSessionAttributes feedbackSession) throws UnauthorizedAccessException {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":175,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Trying to access system using a non-existent student entity\");"},{"lineNumber":176,"author":{"gitId":"-"},"content":" }"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" if (StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":181,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(student, feedbackSession);"},{"lineNumber":182,"author":{"gitId":"-"},"content":" verifyMatchingGoogleId(student.getGoogleId());"},{"lineNumber":183,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" checkAccessControlForPreview(feedbackSession, false);"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":" }"},{"lineNumber":187,"author":{"gitId":"-"},"content":""},{"lineNumber":188,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":189,"author":{"gitId":"xenosf"},"content":" * Checks the access control for student feedback result."},{"lineNumber":190,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":191,"author":{"gitId":"xenosf"},"content":" void checkAccessControlForStudentFeedbackResult("},{"lineNumber":192,"author":{"gitId":"xenosf"},"content":" Student student, FeedbackSession feedbackSession) throws UnauthorizedAccessException {"},{"lineNumber":193,"author":{"gitId":"xenosf"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":194,"author":{"gitId":"xenosf"},"content":" throw new UnauthorizedAccessException(\"Trying to access system using a non-existent student entity\");"},{"lineNumber":195,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":196,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":197,"author":{"gitId":"xenosf"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":198,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":199,"author":{"gitId":"xenosf"},"content":" if (StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":200,"author":{"gitId":"xenosf"},"content":" gateKeeper.verifyAccessible(student, feedbackSession);"},{"lineNumber":201,"author":{"gitId":"xenosf"},"content":" verifyMatchingGoogleId(student.getGoogleId());"},{"lineNumber":202,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":203,"author":{"gitId":"xenosf"},"content":" checkAccessControlForPreview(feedbackSession, false);"},{"lineNumber":204,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":205,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":206,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":207,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":208,"author":{"gitId":"-"},"content":" * Gets the instructor involved in the submission process."},{"lineNumber":209,"author":{"gitId":"-"},"content":" */"},{"lineNumber":210,"author":{"gitId":"-"},"content":" InstructorAttributes getInstructorOfCourseFromRequest(String courseId) {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":212,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson)) {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" return logic.getInstructorForEmail(courseId, moderatedPerson);"},{"lineNumber":216,"author":{"gitId":"-"},"content":" } else if (!StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":217,"author":{"gitId":"-"},"content":" return logic.getInstructorForEmail(courseId, previewAsPerson);"},{"lineNumber":218,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":219,"author":{"gitId":"-"},"content":" return getPossiblyUnregisteredInstructor(courseId);"},{"lineNumber":220,"author":{"gitId":"-"},"content":" }"},{"lineNumber":221,"author":{"gitId":"-"},"content":" }"},{"lineNumber":222,"author":{"gitId":"-"},"content":""},{"lineNumber":223,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":224,"author":{"gitId":"-"},"content":" * Gets the instructor involved in the submission process."},{"lineNumber":225,"author":{"gitId":"-"},"content":" */"},{"lineNumber":226,"author":{"gitId":"-"},"content":" Instructor getSqlInstructorOfCourseFromRequest(String courseId) {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":228,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":229,"author":{"gitId":"-"},"content":""},{"lineNumber":230,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson)) {"},{"lineNumber":231,"author":{"gitId":"-"},"content":" return sqlLogic.getInstructorForEmail(courseId, moderatedPerson);"},{"lineNumber":232,"author":{"gitId":"-"},"content":" } else if (!StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":233,"author":{"gitId":"-"},"content":" return sqlLogic.getInstructorForEmail(courseId, previewAsPerson);"},{"lineNumber":234,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":235,"author":{"gitId":"-"},"content":" return getPossiblyUnregisteredSqlInstructor(courseId);"},{"lineNumber":236,"author":{"gitId":"-"},"content":" }"},{"lineNumber":237,"author":{"gitId":"-"},"content":" }"},{"lineNumber":238,"author":{"gitId":"-"},"content":""},{"lineNumber":239,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":240,"author":{"gitId":"-"},"content":" * Checks the access control for instructor feedback submission."},{"lineNumber":241,"author":{"gitId":"-"},"content":" */"},{"lineNumber":242,"author":{"gitId":"-"},"content":" void checkAccessControlForInstructorFeedbackSubmission("},{"lineNumber":243,"author":{"gitId":"-"},"content":" InstructorAttributes instructor, FeedbackSessionAttributes feedbackSession) throws UnauthorizedAccessException {"},{"lineNumber":244,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Trying to access system using a non-existent instructor entity\");"},{"lineNumber":246,"author":{"gitId":"-"},"content":" }"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":249,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":250,"author":{"gitId":"-"},"content":""},{"lineNumber":251,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson)) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":253,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(logic.getInstructorForGoogleId(feedbackSession.getCourseId(), userInfo.getId()),"},{"lineNumber":254,"author":{"gitId":"-"},"content":" feedbackSession, Const.InstructorPermissions.CAN_MODIFY_SESSION_COMMENT_IN_SECTIONS);"},{"lineNumber":255,"author":{"gitId":"-"},"content":" } else if (!StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":256,"author":{"gitId":"-"},"content":" checkAccessControlForPreview(feedbackSession, true);"},{"lineNumber":257,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" gateKeeper.verifySessionSubmissionPrivilegeForInstructor(feedbackSession, instructor);"},{"lineNumber":259,"author":{"gitId":"-"},"content":" verifyMatchingGoogleId(instructor.getGoogleId());"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":" }"},{"lineNumber":262,"author":{"gitId":"-"},"content":""},{"lineNumber":263,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":264,"author":{"gitId":"-"},"content":" * Checks the access control for instructor feedback submission."},{"lineNumber":265,"author":{"gitId":"-"},"content":" */"},{"lineNumber":266,"author":{"gitId":"-"},"content":" void checkAccessControlForInstructorFeedbackSubmission("},{"lineNumber":267,"author":{"gitId":"-"},"content":" Instructor instructor, FeedbackSession feedbackSession) throws UnauthorizedAccessException {"},{"lineNumber":268,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Trying to access system using a non-existent instructor entity\");"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":273,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":274,"author":{"gitId":"-"},"content":""},{"lineNumber":275,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(moderatedPerson)) {"},{"lineNumber":276,"author":{"gitId":"-"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":277,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":278,"author":{"gitId":"-"},"content":" sqlLogic.getInstructorByGoogleId(feedbackSession.getCourse().getId(), userInfo.getId()),"},{"lineNumber":279,"author":{"gitId":"-"},"content":" feedbackSession, Const.InstructorPermissions.CAN_MODIFY_SESSION_COMMENT_IN_SECTIONS);"},{"lineNumber":280,"author":{"gitId":"-"},"content":" } else if (!StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":281,"author":{"gitId":"-"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":282,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":283,"author":{"gitId":"-"},"content":" sqlLogic.getInstructorByGoogleId(feedbackSession.getCourse().getId(), userInfo.getId()),"},{"lineNumber":284,"author":{"gitId":"-"},"content":" feedbackSession, Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":285,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":286,"author":{"gitId":"-"},"content":" gateKeeper.verifySessionSubmissionPrivilegeForInstructor(feedbackSession, instructor);"},{"lineNumber":287,"author":{"gitId":"-"},"content":" if (instructor.getAccount() !\u003d null) {"},{"lineNumber":288,"author":{"gitId":"-"},"content":" if (userInfo \u003d\u003d null) {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" // Instructor is associated to an account; even if registration key is passed, do not allow access"},{"lineNumber":290,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Login is required to access this feedback session\");"},{"lineNumber":291,"author":{"gitId":"-"},"content":" } else if (!userInfo.id.equals(instructor.getAccount().getGoogleId())) {"},{"lineNumber":292,"author":{"gitId":"-"},"content":" // Logged in instructor is not the same as the instructor registered for the given key,"},{"lineNumber":293,"author":{"gitId":"-"},"content":" // do not allow access"},{"lineNumber":294,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"You are not authorized to access this feedback session\");"},{"lineNumber":295,"author":{"gitId":"-"},"content":" }"},{"lineNumber":296,"author":{"gitId":"-"},"content":" }"},{"lineNumber":297,"author":{"gitId":"-"},"content":" }"},{"lineNumber":298,"author":{"gitId":"-"},"content":" }"},{"lineNumber":299,"author":{"gitId":"-"},"content":""},{"lineNumber":300,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":301,"author":{"gitId":"-"},"content":" * Checks the access control for instructor feedback result."},{"lineNumber":302,"author":{"gitId":"-"},"content":" */"},{"lineNumber":303,"author":{"gitId":"-"},"content":" void checkAccessControlForInstructorFeedbackResult("},{"lineNumber":304,"author":{"gitId":"-"},"content":" InstructorAttributes instructor, FeedbackSessionAttributes feedbackSession) throws UnauthorizedAccessException {"},{"lineNumber":305,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":306,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Trying to access system using a non-existent instructor entity\");"},{"lineNumber":307,"author":{"gitId":"-"},"content":" }"},{"lineNumber":308,"author":{"gitId":"-"},"content":""},{"lineNumber":309,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":310,"author":{"gitId":"-"},"content":""},{"lineNumber":311,"author":{"gitId":"-"},"content":" if (StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":312,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, feedbackSession,"},{"lineNumber":313,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_VIEW_SESSION_IN_SECTIONS);"},{"lineNumber":314,"author":{"gitId":"-"},"content":" verifyMatchingGoogleId(instructor.getGoogleId());"},{"lineNumber":315,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":316,"author":{"gitId":"-"},"content":" checkAccessControlForPreview(feedbackSession, true);"},{"lineNumber":317,"author":{"gitId":"-"},"content":" }"},{"lineNumber":318,"author":{"gitId":"-"},"content":" }"},{"lineNumber":319,"author":{"gitId":"-"},"content":""},{"lineNumber":320,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":321,"author":{"gitId":"-"},"content":" * Checks the access control for instructor feedback result."},{"lineNumber":322,"author":{"gitId":"-"},"content":" */"},{"lineNumber":323,"author":{"gitId":"-"},"content":" void checkAccessControlForInstructorFeedbackResult("},{"lineNumber":324,"author":{"gitId":"-"},"content":" Instructor instructor, FeedbackSession feedbackSession) throws UnauthorizedAccessException {"},{"lineNumber":325,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":326,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Trying to access system using a non-existent instructor entity\");"},{"lineNumber":327,"author":{"gitId":"-"},"content":" }"},{"lineNumber":328,"author":{"gitId":"-"},"content":""},{"lineNumber":329,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" if (StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":332,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, feedbackSession,"},{"lineNumber":333,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_VIEW_SESSION_IN_SECTIONS);"},{"lineNumber":334,"author":{"gitId":"-"},"content":" verifyMatchingGoogleId(instructor.getGoogleId());"},{"lineNumber":335,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":336,"author":{"gitId":"-"},"content":" checkAccessControlForPreview(feedbackSession, true);"},{"lineNumber":337,"author":{"gitId":"-"},"content":" }"},{"lineNumber":338,"author":{"gitId":"-"},"content":" }"},{"lineNumber":339,"author":{"gitId":"-"},"content":""},{"lineNumber":340,"author":{"gitId":"-"},"content":" private void verifyMatchingGoogleId(String googleId) throws UnauthorizedAccessException {"},{"lineNumber":341,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(googleId)) {"},{"lineNumber":342,"author":{"gitId":"-"},"content":" if (userInfo \u003d\u003d null) {"},{"lineNumber":343,"author":{"gitId":"-"},"content":" // Student/Instructor is associated to a google ID; even if registration key is passed, do not allow access"},{"lineNumber":344,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Login is required to access this feedback session\");"},{"lineNumber":345,"author":{"gitId":"-"},"content":" } else if (!userInfo.id.equals(googleId)) {"},{"lineNumber":346,"author":{"gitId":"-"},"content":" // Logged in student/instructor is not the same as the student/instructor registered for the given key,"},{"lineNumber":347,"author":{"gitId":"-"},"content":" // do not allow access"},{"lineNumber":348,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"You are not authorized to access this feedback session\");"},{"lineNumber":349,"author":{"gitId":"-"},"content":" }"},{"lineNumber":350,"author":{"gitId":"-"},"content":" }"},{"lineNumber":351,"author":{"gitId":"-"},"content":" }"},{"lineNumber":352,"author":{"gitId":"-"},"content":""},{"lineNumber":353,"author":{"gitId":"-"},"content":" private void checkAccessControlForPreview(FeedbackSessionAttributes feedbackSession, boolean isInstructor)"},{"lineNumber":354,"author":{"gitId":"-"},"content":" throws UnauthorizedAccessException {"},{"lineNumber":355,"author":{"gitId":"-"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":356,"author":{"gitId":"-"},"content":" if (isInstructor) {"},{"lineNumber":357,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":358,"author":{"gitId":"-"},"content":" logic.getInstructorForGoogleId(feedbackSession.getCourseId(), userInfo.getId()), feedbackSession,"},{"lineNumber":359,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":360,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":361,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":362,"author":{"gitId":"-"},"content":" logic.getInstructorForGoogleId(feedbackSession.getCourseId(), userInfo.getId()), feedbackSession,"},{"lineNumber":363,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":364,"author":{"gitId":"-"},"content":" }"},{"lineNumber":365,"author":{"gitId":"-"},"content":" }"},{"lineNumber":366,"author":{"gitId":"-"},"content":""},{"lineNumber":367,"author":{"gitId":"xenosf"},"content":" private void checkAccessControlForPreview(FeedbackSession feedbackSession, boolean isInstructor)"},{"lineNumber":368,"author":{"gitId":"xenosf"},"content":" throws UnauthorizedAccessException {"},{"lineNumber":369,"author":{"gitId":"xenosf"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":370,"author":{"gitId":"xenosf"},"content":" if (isInstructor) {"},{"lineNumber":371,"author":{"gitId":"xenosf"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":372,"author":{"gitId":"xenosf"},"content":" sqlLogic.getInstructorByGoogleId(feedbackSession.getCourse().getId(), userInfo.getId()), feedbackSession,"},{"lineNumber":373,"author":{"gitId":"xenosf"},"content":" Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":374,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":375,"author":{"gitId":"xenosf"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":376,"author":{"gitId":"xenosf"},"content":" sqlLogic.getInstructorByGoogleId(feedbackSession.getCourse().getId(), userInfo.getId()), feedbackSession,"},{"lineNumber":377,"author":{"gitId":"xenosf"},"content":" Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":378,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":379,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":380,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":381,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":382,"author":{"gitId":"-"},"content":" * Verifies that it is not a preview request."},{"lineNumber":383,"author":{"gitId":"-"},"content":" */"},{"lineNumber":384,"author":{"gitId":"-"},"content":" void verifyNotPreview() throws UnauthorizedAccessException {"},{"lineNumber":385,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":386,"author":{"gitId":"-"},"content":" if (!StringHelper.isEmpty(previewAsPerson)) {"},{"lineNumber":387,"author":{"gitId":"-"},"content":" // should not view response under preview mode"},{"lineNumber":388,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"You are not allowed to see responses when previewing\", true);"},{"lineNumber":389,"author":{"gitId":"-"},"content":" }"},{"lineNumber":390,"author":{"gitId":"-"},"content":" }"},{"lineNumber":391,"author":{"gitId":"-"},"content":""},{"lineNumber":392,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":393,"author":{"gitId":"-"},"content":" * Verifies that the session is open for submission."},{"lineNumber":394,"author":{"gitId":"-"},"content":" *"},{"lineNumber":395,"author":{"gitId":"-"},"content":" * \u003cp\u003eIf it is moderation request, omit the check."},{"lineNumber":396,"author":{"gitId":"-"},"content":" */"},{"lineNumber":397,"author":{"gitId":"-"},"content":" void verifySessionOpenExceptForModeration(FeedbackSessionAttributes feedbackSession) throws UnauthorizedAccessException {"},{"lineNumber":398,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":399,"author":{"gitId":"-"},"content":""},{"lineNumber":400,"author":{"gitId":"-"},"content":" if (StringHelper.isEmpty(moderatedPerson) \u0026\u0026 !(feedbackSession.isOpened() || feedbackSession.isInGracePeriod())) {"},{"lineNumber":401,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"The feedback session is not available for submission\", true);"},{"lineNumber":402,"author":{"gitId":"-"},"content":" }"},{"lineNumber":403,"author":{"gitId":"-"},"content":" }"},{"lineNumber":404,"author":{"gitId":"-"},"content":""},{"lineNumber":405,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":406,"author":{"gitId":"-"},"content":" * Verifies that the session is open for submission."},{"lineNumber":407,"author":{"gitId":"-"},"content":" *"},{"lineNumber":408,"author":{"gitId":"-"},"content":" * \u003cp\u003eIf it is moderation request, omit the check."},{"lineNumber":409,"author":{"gitId":"-"},"content":" */"},{"lineNumber":410,"author":{"gitId":"-"},"content":" void verifySessionOpenExceptForModeration(FeedbackSession feedbackSession) throws UnauthorizedAccessException {"},{"lineNumber":411,"author":{"gitId":"-"},"content":" String moderatedPerson \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON);"},{"lineNumber":412,"author":{"gitId":"-"},"content":""},{"lineNumber":413,"author":{"gitId":"-"},"content":" if (StringHelper.isEmpty(moderatedPerson) \u0026\u0026 !(feedbackSession.isOpened() || feedbackSession.isInGracePeriod())) {"},{"lineNumber":414,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"The feedback session is not available for submission\", true);"},{"lineNumber":415,"author":{"gitId":"-"},"content":" }"},{"lineNumber":416,"author":{"gitId":"-"},"content":" }"},{"lineNumber":417,"author":{"gitId":"-"},"content":""},{"lineNumber":418,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":419,"author":{"gitId":"-"},"content":" * Gets the section of a recipient."},{"lineNumber":420,"author":{"gitId":"-"},"content":" */"},{"lineNumber":421,"author":{"gitId":"-"},"content":" @SuppressWarnings(\"PMD.ImplicitSwitchFallThrough\") // false positive"},{"lineNumber":422,"author":{"gitId":"-"},"content":" Section getRecipientSection("},{"lineNumber":423,"author":{"gitId":"-"},"content":" String courseId, FeedbackParticipantType giverType, FeedbackParticipantType recipientType,"},{"lineNumber":424,"author":{"gitId":"-"},"content":" String recipientIdentifier) {"},{"lineNumber":425,"author":{"gitId":"-"},"content":""},{"lineNumber":426,"author":{"gitId":"-"},"content":" switch (recipientType) {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" case SELF:"},{"lineNumber":428,"author":{"gitId":"-"},"content":" switch (giverType) {"},{"lineNumber":429,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":430,"author":{"gitId":"-"},"content":" case SELF:"},{"lineNumber":431,"author":{"gitId":"-"},"content":" return Const.DEFAULT_SQL_SECTION;"},{"lineNumber":432,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":433,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":434,"author":{"gitId":"-"},"content":" Section section \u003d sqlLogic.getSectionByCourseIdAndTeam(courseId, recipientIdentifier);"},{"lineNumber":435,"author":{"gitId":"-"},"content":" return section \u003d\u003d null ? Const.DEFAULT_SQL_SECTION : section;"},{"lineNumber":436,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":437,"author":{"gitId":"-"},"content":" case STUDENTS_IN_SAME_SECTION:"},{"lineNumber":438,"author":{"gitId":"-"},"content":" Student student \u003d sqlLogic.getStudentForEmail(courseId, recipientIdentifier);"},{"lineNumber":439,"author":{"gitId":"-"},"content":" return student \u003d\u003d null ? Const.DEFAULT_SQL_SECTION : student.getSection();"},{"lineNumber":440,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":441,"author":{"gitId":"-"},"content":" assert false : \"Invalid giver type \" + giverType + \" for recipient type \" + recipientType;"},{"lineNumber":442,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":443,"author":{"gitId":"-"},"content":" }"},{"lineNumber":444,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":445,"author":{"gitId":"-"},"content":" case NONE:"},{"lineNumber":446,"author":{"gitId":"-"},"content":" return Const.DEFAULT_SQL_SECTION;"},{"lineNumber":447,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":448,"author":{"gitId":"-"},"content":" case TEAMS_EXCLUDING_SELF:"},{"lineNumber":449,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":450,"author":{"gitId":"-"},"content":" case OWN_TEAM:"},{"lineNumber":451,"author":{"gitId":"-"},"content":" Section section \u003d sqlLogic.getSectionByCourseIdAndTeam(courseId, recipientIdentifier);"},{"lineNumber":452,"author":{"gitId":"-"},"content":" return section \u003d\u003d null ? Const.DEFAULT_SQL_SECTION : section;"},{"lineNumber":453,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":454,"author":{"gitId":"-"},"content":" case STUDENTS_EXCLUDING_SELF:"},{"lineNumber":455,"author":{"gitId":"-"},"content":" case STUDENTS_IN_SAME_SECTION:"},{"lineNumber":456,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":457,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS_INCLUDING_SELF:"},{"lineNumber":458,"author":{"gitId":"-"},"content":" Student student \u003d sqlLogic.getStudentForEmail(courseId, recipientIdentifier);"},{"lineNumber":459,"author":{"gitId":"-"},"content":" return student \u003d\u003d null ? Const.DEFAULT_SQL_SECTION : student.getSection();"},{"lineNumber":460,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":461,"author":{"gitId":"-"},"content":" assert false : \"Unknown recipient type \" + recipientType;"},{"lineNumber":462,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":463,"author":{"gitId":"-"},"content":" }"},{"lineNumber":464,"author":{"gitId":"-"},"content":" }"},{"lineNumber":465,"author":{"gitId":"-"},"content":""},{"lineNumber":466,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":467,"author":{"gitId":"-"},"content":" * Gets the section of a recipient."},{"lineNumber":468,"author":{"gitId":"-"},"content":" */"},{"lineNumber":469,"author":{"gitId":"-"},"content":" @SuppressWarnings(\"PMD.ImplicitSwitchFallThrough\") // false positive"},{"lineNumber":470,"author":{"gitId":"-"},"content":" String getDatastoreRecipientSection("},{"lineNumber":471,"author":{"gitId":"-"},"content":" String courseId, FeedbackParticipantType giverType, FeedbackParticipantType recipientType,"},{"lineNumber":472,"author":{"gitId":"-"},"content":" String recipientIdentifier) {"},{"lineNumber":473,"author":{"gitId":"-"},"content":" switch (recipientType) {"},{"lineNumber":474,"author":{"gitId":"-"},"content":" case SELF:"},{"lineNumber":475,"author":{"gitId":"-"},"content":" switch (giverType) {"},{"lineNumber":476,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":477,"author":{"gitId":"-"},"content":" case SELF:"},{"lineNumber":478,"author":{"gitId":"-"},"content":" return Const.DEFAULT_SECTION;"},{"lineNumber":479,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":480,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":481,"author":{"gitId":"-"},"content":" return logic.getSectionForTeam(courseId, recipientIdentifier);"},{"lineNumber":482,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":483,"author":{"gitId":"-"},"content":" case STUDENTS_IN_SAME_SECTION:"},{"lineNumber":484,"author":{"gitId":"-"},"content":" StudentAttributes student \u003d logic.getStudentForEmail(courseId, recipientIdentifier);"},{"lineNumber":485,"author":{"gitId":"-"},"content":" return student \u003d\u003d null ? Const.DEFAULT_SECTION : student.getSection();"},{"lineNumber":486,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":487,"author":{"gitId":"-"},"content":" assert false : \"Invalid giver type \" + giverType + \" for recipient type \" + recipientType;"},{"lineNumber":488,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":489,"author":{"gitId":"-"},"content":" }"},{"lineNumber":490,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":491,"author":{"gitId":"-"},"content":" case NONE:"},{"lineNumber":492,"author":{"gitId":"-"},"content":" return Const.DEFAULT_SECTION;"},{"lineNumber":493,"author":{"gitId":"-"},"content":" case TEAMS:"},{"lineNumber":494,"author":{"gitId":"-"},"content":" case TEAMS_EXCLUDING_SELF:"},{"lineNumber":495,"author":{"gitId":"-"},"content":" case TEAMS_IN_SAME_SECTION:"},{"lineNumber":496,"author":{"gitId":"-"},"content":" case OWN_TEAM:"},{"lineNumber":497,"author":{"gitId":"-"},"content":" return logic.getSectionForTeam(courseId, recipientIdentifier);"},{"lineNumber":498,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":499,"author":{"gitId":"-"},"content":" case STUDENTS_EXCLUDING_SELF:"},{"lineNumber":500,"author":{"gitId":"-"},"content":" case STUDENTS_IN_SAME_SECTION:"},{"lineNumber":501,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS:"},{"lineNumber":502,"author":{"gitId":"-"},"content":" case OWN_TEAM_MEMBERS_INCLUDING_SELF:"},{"lineNumber":503,"author":{"gitId":"-"},"content":" StudentAttributes student \u003d logic.getStudentForEmail(courseId, recipientIdentifier);"},{"lineNumber":504,"author":{"gitId":"-"},"content":" return student \u003d\u003d null ? Const.DEFAULT_SECTION : student.getSection();"},{"lineNumber":505,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":506,"author":{"gitId":"-"},"content":" assert false : \"Unknown recipient type \" + recipientType;"},{"lineNumber":507,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":508,"author":{"gitId":"-"},"content":" }"},{"lineNumber":509,"author":{"gitId":"-"},"content":" }"},{"lineNumber":510,"author":{"gitId":"-"},"content":""},{"lineNumber":511,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":33,"-":478}},{"path":"src/main/java/teammates/ui/webapi/CreateAccountAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.time.ZoneId;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.ZonedDateTime;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.time.temporal.ChronoUnit;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.regex.Pattern;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.DataBundle;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.util.StringHelper;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.util.Templates;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":30,"author":{"gitId":"-"},"content":" * Creates a new instructor account with sample courses."},{"lineNumber":31,"author":{"gitId":"-"},"content":" */"},{"lineNumber":32,"author":{"gitId":"-"},"content":"public class CreateAccountAction extends Action {"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":37,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":42,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" // Any user can create instructor account as long as the registration key is valid."},{"lineNumber":44,"author":{"gitId":"-"},"content":" }"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":47,"author":{"gitId":"-"},"content":" public JsonResult execute() throws InvalidHttpRequestBodyException, InvalidOperationException {"},{"lineNumber":48,"author":{"gitId":"-"},"content":" String registrationKey \u003d getNonNullRequestParamValue(Const.ParamsNames.REGKEY);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" String timezone \u003d getRequestParamValue(Const.ParamsNames.TIMEZONE);"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" if (timezone \u003d\u003d null || !FieldValidator.getInvalidityInfoForTimeZone(timezone).isEmpty()) {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" // Use default timezone instead"},{"lineNumber":53,"author":{"gitId":"-"},"content":" timezone \u003d Const.DEFAULT_TIME_ZONE;"},{"lineNumber":54,"author":{"gitId":"-"},"content":" }"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d sqlLogic.getAccountRequestByRegistrationKey(registrationKey);"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" if (accountRequest \u003d\u003d null) {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(\"Account request with registration key \""},{"lineNumber":60,"author":{"gitId":"-"},"content":" + registrationKey + \" could not be found\");"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" if (accountRequest.getRegisteredAt() !\u003d null) {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(\"The registration key \" + registrationKey + \" has already been used.\");"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" String instructorEmail \u003d accountRequest.getEmail();"},{"lineNumber":68,"author":{"gitId":"-"},"content":" String instructorName \u003d accountRequest.getName();"},{"lineNumber":69,"author":{"gitId":"-"},"content":" String instructorInstitution \u003d accountRequest.getInstitute();"},{"lineNumber":70,"author":{"gitId":"-"},"content":" String courseId;"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" courseId \u003d importDemoData(instructorEmail, instructorName, instructorInstitution, timezone);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException ipe) {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" // There should not be any invalid parameter here"},{"lineNumber":76,"author":{"gitId":"-"},"content":" log.severe(\"Unexpected error\", ipe);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" return new JsonResult(ipe.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" List\u003cInstructorAttributes\u003e instructorList \u003d logic.getInstructorsForCourse(courseId);"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" assert !instructorList.isEmpty();"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" logic.joinCourseForInstructor(instructorList.get(0).getKey(), userInfo.id);"},{"lineNumber":86,"author":{"gitId":"-"},"content":" } catch (EntityDoesNotExistException | EntityAlreadyExistsException | InvalidParametersException e) {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" // EntityDoesNotExistException should not be thrown as all entities should exist in demo course."},{"lineNumber":88,"author":{"gitId":"-"},"content":" // EntityAlreadyExistsException should not be thrown as updated entities should not have"},{"lineNumber":89,"author":{"gitId":"-"},"content":" // conflict with generated entities in new demo course."},{"lineNumber":90,"author":{"gitId":"-"},"content":" // InvalidParametersException should not be thrown as as there should not be any invalid parameters."},{"lineNumber":91,"author":{"gitId":"-"},"content":" log.severe(\"Unexpected error\", e);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" return new JsonResult(e.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" }"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":96,"author":{"gitId":"-"},"content":" setAccountRequestAsRegistered(accountRequest);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" } catch (EntityDoesNotExistException | InvalidParametersException e) {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" // EntityDoesNotExistException should not be thrown as existence of account request has been validated before."},{"lineNumber":99,"author":{"gitId":"-"},"content":" // InvalidParametersException should not be thrown as there should not be any invalid parameters."},{"lineNumber":100,"author":{"gitId":"-"},"content":" log.severe(\"Unexpected error\", e);"},{"lineNumber":101,"author":{"gitId":"-"},"content":" return new JsonResult(e.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" return new JsonResult(\"Account successfully created\", HttpStatus.SC_OK);"},{"lineNumber":105,"author":{"gitId":"-"},"content":" }"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":108,"author":{"gitId":"-"},"content":" * Abstracts the logic of updating an account request to be registered."},{"lineNumber":109,"author":{"gitId":"-"},"content":" *"},{"lineNumber":110,"author":{"gitId":"-"},"content":" * @return the updated account request"},{"lineNumber":111,"author":{"gitId":"-"},"content":" */"},{"lineNumber":112,"author":{"gitId":"-"},"content":" private AccountRequest setAccountRequestAsRegistered(AccountRequest accountRequest)"},{"lineNumber":113,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" accountRequest.setStatus(AccountRequestStatus.REGISTERED);"},{"lineNumber":115,"author":{"gitId":"-"},"content":" accountRequest.setRegisteredAt(Instant.now());"},{"lineNumber":116,"author":{"gitId":"-"},"content":" sqlLogic.updateAccountRequest(accountRequest);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" return accountRequest;"},{"lineNumber":118,"author":{"gitId":"-"},"content":" }"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" private static String getDateString(Instant instant) {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" return TimeHelper.formatInstant(instant, Const.DEFAULT_TIME_ZONE, \"yyyy-MM-dd\");"},{"lineNumber":122,"author":{"gitId":"-"},"content":" }"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":125,"author":{"gitId":"-"},"content":" * Imports demo course for the new instructor."},{"lineNumber":126,"author":{"gitId":"-"},"content":" *"},{"lineNumber":127,"author":{"gitId":"-"},"content":" * @return the ID of demo course"},{"lineNumber":128,"author":{"gitId":"-"},"content":" */"},{"lineNumber":129,"author":{"gitId":"-"},"content":" private String importDemoData(String instructorEmail, String instructorName, String instructorInstitute, String timezone)"},{"lineNumber":130,"author":{"gitId":"-"},"content":" throws InvalidParametersException {"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":" String courseId \u003d generateDemoCourseId(instructorEmail);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" Instant now \u003d Instant.now();"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" // Used for start time + visible time for all sessions"},{"lineNumber":136,"author":{"gitId":"-"},"content":" String dateString1 \u003d getDateString(now.minus(7, ChronoUnit.DAYS));"},{"lineNumber":137,"author":{"gitId":"-"},"content":" // Used for end time for sessions already past"},{"lineNumber":138,"author":{"gitId":"-"},"content":" String dateString2 \u003d getDateString(now.minus(3, ChronoUnit.DAYS));"},{"lineNumber":139,"author":{"gitId":"-"},"content":" // Used for result visible time for sessions already past"},{"lineNumber":140,"author":{"gitId":"-"},"content":" String dateString3 \u003d getDateString(now.minus(2, ChronoUnit.DAYS));"},{"lineNumber":141,"author":{"gitId":"-"},"content":" // Used for end time for session still ongoing"},{"lineNumber":142,"author":{"gitId":"-"},"content":" String dateString4 \u003d getDateString(now.plus(3, ChronoUnit.DAYS));"},{"lineNumber":143,"author":{"gitId":"-"},"content":" // Used for timestamp of comments"},{"lineNumber":144,"author":{"gitId":"-"},"content":" String dateString5 \u003d getDateString(now);"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" String dataBundleString \u003d Templates.populateTemplate(Templates.INSTRUCTOR_SAMPLE_DATA,"},{"lineNumber":147,"author":{"gitId":"-"},"content":" // replace email"},{"lineNumber":148,"author":{"gitId":"-"},"content":" \"teammates.demo.instructor@demo.course\", instructorEmail,"},{"lineNumber":149,"author":{"gitId":"-"},"content":" // replace name"},{"lineNumber":150,"author":{"gitId":"-"},"content":" \"Demo_Instructor\", instructorName,"},{"lineNumber":151,"author":{"gitId":"-"},"content":" // replace course"},{"lineNumber":152,"author":{"gitId":"-"},"content":" \"demo.course\", courseId,"},{"lineNumber":153,"author":{"gitId":"-"},"content":" // replace institute"},{"lineNumber":154,"author":{"gitId":"-"},"content":" \"demo.institute\", instructorInstitute,"},{"lineNumber":155,"author":{"gitId":"-"},"content":" // replace timezone"},{"lineNumber":156,"author":{"gitId":"-"},"content":" \"demo.timezone\", timezone,"},{"lineNumber":157,"author":{"gitId":"-"},"content":" // replace dates"},{"lineNumber":158,"author":{"gitId":"-"},"content":" \"demo.date1\", dateString1,"},{"lineNumber":159,"author":{"gitId":"-"},"content":" \"demo.date2\", dateString2,"},{"lineNumber":160,"author":{"gitId":"-"},"content":" \"demo.date3\", dateString3,"},{"lineNumber":161,"author":{"gitId":"-"},"content":" \"demo.date4\", dateString4,"},{"lineNumber":162,"author":{"gitId":"-"},"content":" \"demo.date5\", dateString5);"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" if (!Const.DEFAULT_TIME_ZONE.equals(timezone)) {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" dataBundleString \u003d replaceAdjustedTimeAndTimezone(dataBundleString, timezone);"},{"lineNumber":166,"author":{"gitId":"-"},"content":" }"},{"lineNumber":167,"author":{"gitId":"-"},"content":""},{"lineNumber":168,"author":{"gitId":"-"},"content":" DataBundle data \u003d JsonUtils.fromJson(dataBundleString, DataBundle.class);"},{"lineNumber":169,"author":{"gitId":"-"},"content":""},{"lineNumber":170,"author":{"gitId":"-"},"content":" logic.persistDataBundle(data);"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" List\u003cStudentAttributes\u003e students \u003d logic.getStudentsForCourse(courseId);"},{"lineNumber":173,"author":{"gitId":"-"},"content":" List\u003cInstructorAttributes\u003e instructors \u003d logic.getInstructorsForCourse(courseId);"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" for (StudentAttributes student : students) {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" taskQueuer.scheduleStudentForSearchIndexing(student.getCourse(), student.getEmail());"},{"lineNumber":177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" for (InstructorAttributes instructor : instructors) {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" taskQueuer.scheduleInstructorForSearchIndexing(instructor.getCourseId(), instructor.getEmail());"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" return courseId;"},{"lineNumber":184,"author":{"gitId":"-"},"content":" }"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" // Strategy to Generate New Demo Course Id:"},{"lineNumber":187,"author":{"gitId":"-"},"content":" // a. keep the part of email before \"@\""},{"lineNumber":188,"author":{"gitId":"-"},"content":" // replace \"@\" with \".\""},{"lineNumber":189,"author":{"gitId":"-"},"content":" // replace email host with their first 3 chars. eg, gmail.com -\u003e gma"},{"lineNumber":190,"author":{"gitId":"-"},"content":" // append \"-demo\""},{"lineNumber":191,"author":{"gitId":"-"},"content":" // to sum up: lebron@gmail.com -\u003e lebron.gma-demo"},{"lineNumber":192,"author":{"gitId":"-"},"content":" //"},{"lineNumber":193,"author":{"gitId":"-"},"content":" // b. if the generated courseId already exists, create another one by appending a integer to the previous courseId."},{"lineNumber":194,"author":{"gitId":"-"},"content":" // if the newly generate id still exists, increment the id, until we find a feasible one"},{"lineNumber":195,"author":{"gitId":"-"},"content":" // eg."},{"lineNumber":196,"author":{"gitId":"-"},"content":" // lebron@gmail.com -\u003e lebron.gma-demo // already exists!"},{"lineNumber":197,"author":{"gitId":"-"},"content":" // lebron@gmail.com -\u003e lebron.gma-demo0 // already exists!"},{"lineNumber":198,"author":{"gitId":"-"},"content":" // lebron@gmail.com -\u003e lebron.gma-demo1 // already exists!"},{"lineNumber":199,"author":{"gitId":"-"},"content":" // ..."},{"lineNumber":200,"author":{"gitId":"-"},"content":" // lebron@gmail.com -\u003e lebron.gma-demo99 // already exists!"},{"lineNumber":201,"author":{"gitId":"-"},"content":" // lebron@gmail.com -\u003e lebron.gma-demo100 // found! a feasible id"},{"lineNumber":202,"author":{"gitId":"-"},"content":" //"},{"lineNumber":203,"author":{"gitId":"-"},"content":" // c. in any cases(a or b), if generated Id is longer than FieldValidator.COURSE_ID_MAX_LENGTH, shorten the part"},{"lineNumber":204,"author":{"gitId":"-"},"content":" // before \"@\" of the initial input email, by continuously removing its last character"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":207,"author":{"gitId":"-"},"content":" * Generate a course ID for demo course, and if the generated id already exists, try another one."},{"lineNumber":208,"author":{"gitId":"-"},"content":" *"},{"lineNumber":209,"author":{"gitId":"-"},"content":" * @param instructorEmail is the instructor email."},{"lineNumber":210,"author":{"gitId":"-"},"content":" * @return generated course id"},{"lineNumber":211,"author":{"gitId":"-"},"content":" */"},{"lineNumber":212,"author":{"gitId":"-"},"content":" private String generateDemoCourseId(String instructorEmail) {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" String proposedCourseId \u003d generateNextDemoCourseId(instructorEmail, FieldValidator.COURSE_ID_MAX_LENGTH);"},{"lineNumber":214,"author":{"gitId":"-"},"content":" while (logic.getCourse(proposedCourseId) !\u003d null) {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" proposedCourseId \u003d generateNextDemoCourseId(proposedCourseId, FieldValidator.COURSE_ID_MAX_LENGTH);"},{"lineNumber":216,"author":{"gitId":"-"},"content":" }"},{"lineNumber":217,"author":{"gitId":"-"},"content":" return proposedCourseId;"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":221,"author":{"gitId":"-"},"content":" * Generate a course ID for demo course from a given email."},{"lineNumber":222,"author":{"gitId":"-"},"content":" *"},{"lineNumber":223,"author":{"gitId":"-"},"content":" * @param instructorEmail is the instructor email."},{"lineNumber":224,"author":{"gitId":"-"},"content":" * @return the first proposed course id. eg.lebron@gmail.com -\u003e lebron.gma-demo"},{"lineNumber":225,"author":{"gitId":"-"},"content":" */"},{"lineNumber":226,"author":{"gitId":"-"},"content":" private String getDemoCourseIdRoot(String instructorEmail) {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" String[] emailSplit \u003d instructorEmail.split(\"@\");"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" String username \u003d emailSplit[0];"},{"lineNumber":230,"author":{"gitId":"-"},"content":" String host \u003d emailSplit[1];"},{"lineNumber":231,"author":{"gitId":"-"},"content":""},{"lineNumber":232,"author":{"gitId":"-"},"content":" String head \u003d StringHelper.replaceIllegalChars(username, FieldValidator.REGEX_COURSE_ID, \u0027_\u0027);"},{"lineNumber":233,"author":{"gitId":"-"},"content":" String hostAbbreviation \u003d host.substring(0, Math.min(host.length(), 3));"},{"lineNumber":234,"author":{"gitId":"-"},"content":""},{"lineNumber":235,"author":{"gitId":"-"},"content":" return head + \".\" + hostAbbreviation + \"-demo\";"},{"lineNumber":236,"author":{"gitId":"-"},"content":" }"},{"lineNumber":237,"author":{"gitId":"-"},"content":""},{"lineNumber":238,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":239,"author":{"gitId":"-"},"content":" * Generate a course ID for demo course from a given email or a generated course Id."},{"lineNumber":240,"author":{"gitId":"-"},"content":" *"},{"lineNumber":241,"author":{"gitId":"-"},"content":" * \u003cp\u003eHere we check the input string is an email or course Id and handle them accordingly;"},{"lineNumber":242,"author":{"gitId":"-"},"content":" * check the resulting course id, and if bigger than maximumIdLength, cut it so that it equals maximumIdLength."},{"lineNumber":243,"author":{"gitId":"-"},"content":" *"},{"lineNumber":244,"author":{"gitId":"-"},"content":" * @param instructorEmailOrProposedCourseId is the instructor email or a proposed course id that already exists."},{"lineNumber":245,"author":{"gitId":"-"},"content":" * @param maximumIdLength is the maximum resulting id length allowed, above which we will cut the part before \"@\""},{"lineNumber":246,"author":{"gitId":"-"},"content":" * @return the proposed course id, e.g.:"},{"lineNumber":247,"author":{"gitId":"-"},"content":" * \u003cul\u003e"},{"lineNumber":248,"author":{"gitId":"-"},"content":" * \u003cli\u003elebron@gmail.com -\u003e lebron.gma-demo\u003c/li\u003e"},{"lineNumber":249,"author":{"gitId":"-"},"content":" * \u003cli\u003elebron.gma-demo -\u003e lebron.gma-demo0\u003c/li\u003e"},{"lineNumber":250,"author":{"gitId":"-"},"content":" * \u003cli\u003elebron.gma-demo0 -\u003e lebron.gma-demo1\u003c/li\u003e"},{"lineNumber":251,"author":{"gitId":"-"},"content":" * \u003cli\u003e012345678901234567890123456789.gma-demo9 -\u003e 01234567890123456789012345678.gma-demo10 (being cut)\u003c/li\u003e"},{"lineNumber":252,"author":{"gitId":"-"},"content":" * \u003c/ul\u003e"},{"lineNumber":253,"author":{"gitId":"-"},"content":" */"},{"lineNumber":254,"author":{"gitId":"-"},"content":" public String generateNextDemoCourseId(String instructorEmailOrProposedCourseId, int maximumIdLength) {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" boolean isFirstCourseId \u003d instructorEmailOrProposedCourseId.contains(\"@\");"},{"lineNumber":256,"author":{"gitId":"-"},"content":" if (isFirstCourseId) {"},{"lineNumber":257,"author":{"gitId":"-"},"content":" return StringHelper.truncateHead(getDemoCourseIdRoot(instructorEmailOrProposedCourseId), maximumIdLength);"},{"lineNumber":258,"author":{"gitId":"-"},"content":" }"},{"lineNumber":259,"author":{"gitId":"-"},"content":""},{"lineNumber":260,"author":{"gitId":"-"},"content":" boolean isFirstTimeDuplicate \u003d instructorEmailOrProposedCourseId.endsWith(\"-demo\");"},{"lineNumber":261,"author":{"gitId":"-"},"content":" if (isFirstTimeDuplicate) {"},{"lineNumber":262,"author":{"gitId":"-"},"content":" return StringHelper.truncateHead(instructorEmailOrProposedCourseId + \"0\", maximumIdLength);"},{"lineNumber":263,"author":{"gitId":"-"},"content":" }"},{"lineNumber":264,"author":{"gitId":"-"},"content":""},{"lineNumber":265,"author":{"gitId":"-"},"content":" int lastIndexOfDemo \u003d instructorEmailOrProposedCourseId.lastIndexOf(\"-demo\");"},{"lineNumber":266,"author":{"gitId":"-"},"content":" String root \u003d instructorEmailOrProposedCourseId.substring(0, lastIndexOfDemo);"},{"lineNumber":267,"author":{"gitId":"-"},"content":" int previousDedupSuffix \u003d Integer.parseInt(instructorEmailOrProposedCourseId.substring(lastIndexOfDemo + 5));"},{"lineNumber":268,"author":{"gitId":"-"},"content":""},{"lineNumber":269,"author":{"gitId":"-"},"content":" return StringHelper.truncateHead(root + \"-demo\" + (previousDedupSuffix + 1), maximumIdLength);"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":273,"author":{"gitId":"-"},"content":" * Replace time and timezone based on users timezone."},{"lineNumber":274,"author":{"gitId":"-"},"content":" * Strings representing instant are adjusted so that they represent the same date and time but in the users timezone."},{"lineNumber":275,"author":{"gitId":"-"},"content":" * Timezone is changed to users timezone."},{"lineNumber":276,"author":{"gitId":"-"},"content":" */"},{"lineNumber":277,"author":{"gitId":"-"},"content":" private String replaceAdjustedTimeAndTimezone(String template, String timezoneString) {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" // timezoneString should have been validated in #execute() method already"},{"lineNumber":279,"author":{"gitId":"-"},"content":" assert ZoneId.getAvailableZoneIds().contains(timezoneString);"},{"lineNumber":280,"author":{"gitId":"-"},"content":""},{"lineNumber":281,"author":{"gitId":"-"},"content":" String pattern \u003d \"\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}Z\"; // regex for instant"},{"lineNumber":282,"author":{"gitId":"-"},"content":" ZoneId timezone \u003d ZoneId.of(timezoneString);"},{"lineNumber":283,"author":{"gitId":"-"},"content":""},{"lineNumber":284,"author":{"gitId":"-"},"content":" // replace instant with instant adjusted for user\u0027s timezone"},{"lineNumber":285,"author":{"gitId":"-"},"content":" return Pattern.compile(pattern).matcher(template).replaceAll(timestampMatch -\u003e {"},{"lineNumber":286,"author":{"gitId":"-"},"content":" String timestamp \u003d timestampMatch.group();"},{"lineNumber":287,"author":{"gitId":"-"},"content":" Instant instant \u003d Instant.parse(timestamp);"},{"lineNumber":288,"author":{"gitId":"-"},"content":""},{"lineNumber":289,"author":{"gitId":"-"},"content":" if (TimeHelper.isSpecialTime(instant)) {"},{"lineNumber":290,"author":{"gitId":"-"},"content":" return timestamp;"},{"lineNumber":291,"author":{"gitId":"-"},"content":" }"},{"lineNumber":292,"author":{"gitId":"-"},"content":""},{"lineNumber":293,"author":{"gitId":"-"},"content":" return ZonedDateTime.ofInstant(instant, ZoneId.of(Const.DEFAULT_TIME_ZONE))"},{"lineNumber":294,"author":{"gitId":"-"},"content":" .withZoneSameLocal(timezone).toInstant().toString();"},{"lineNumber":295,"author":{"gitId":"-"},"content":" });"},{"lineNumber":296,"author":{"gitId":"-"},"content":" }"},{"lineNumber":297,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":2,"-":295}},{"path":"src/main/java/teammates/ui/webapi/CreateAccountRequestAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.ui.output.AccountRequestData;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.ui.request.AccountCreateRequest;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":12,"author":{"gitId":"-"},"content":" * Creates a new account request."},{"lineNumber":13,"author":{"gitId":"-"},"content":" */"},{"lineNumber":14,"author":{"gitId":"-"},"content":"public class CreateAccountRequestAction extends Action {"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":17,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" return AuthType.PUBLIC;"},{"lineNumber":19,"author":{"gitId":"-"},"content":" }"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":22,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":23,"author":{"gitId":"-"},"content":" // Nothing needs to be done here because anybody should be able to create an account request."},{"lineNumber":24,"author":{"gitId":"-"},"content":" }"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":27,"author":{"gitId":"-"},"content":" public boolean isTransactionNeeded() {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" }"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":32,"author":{"gitId":"-"},"content":" public JsonResult execute()"},{"lineNumber":33,"author":{"gitId":"-"},"content":" throws InvalidHttpRequestBodyException, InvalidOperationException {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" AccountCreateRequest createRequest \u003d getAndValidateRequestBody(AccountCreateRequest.class);"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" String instructorName \u003d createRequest.getInstructorName().trim();"},{"lineNumber":37,"author":{"gitId":"-"},"content":" String instructorEmail \u003d createRequest.getInstructorEmail().trim();"},{"lineNumber":38,"author":{"gitId":"-"},"content":" String instructorInstitution \u003d createRequest.getInstructorInstitution().trim();"},{"lineNumber":39,"author":{"gitId":"-"},"content":" String comments \u003d createRequest.getInstructorComments();"},{"lineNumber":40,"author":{"gitId":"-"},"content":" if (comments !\u003d null) {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" comments \u003d comments.trim();"},{"lineNumber":42,"author":{"gitId":"-"},"content":" }"},{"lineNumber":43,"author":{"gitId":"-"},"content":" AccountRequest accountRequest;"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" accountRequest \u003d sqlLogic.createAccountRequestWithTransaction(instructorName, instructorEmail,"},{"lineNumber":47,"author":{"gitId":"-"},"content":" instructorInstitution, AccountRequestStatus.PENDING, comments);"},{"lineNumber":48,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException ipe) {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(ipe);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" }"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" taskQueuer.scheduleAccountRequestForSearchIndexing(accountRequest.getId().toString());"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" assert accountRequest !\u003d null;"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" if (userInfo \u003d\u003d null || !userInfo.isAdmin) {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" EmailWrapper adminAlertEmail \u003d sqlEmailGenerator.generateNewAccountRequestAdminAlertEmail(accountRequest);"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" EmailWrapper userAcknowledgementEmail \u003d sqlEmailGenerator"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" .generateNewAccountRequestAcknowledgementEmail(accountRequest);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" emailSender.sendEmail(adminAlertEmail);"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" emailSender.sendEmail(userAcknowledgementEmail);"},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" AccountRequestData output \u003d new AccountRequestData(accountRequest);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" return new JsonResult(output);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":1,"xenosf":5,"-":62}},{"path":"src/main/java/teammates/ui/webapi/CreateFeedbackQuestionAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionDetails;"},{"lineNumber":8,"author":{"gitId":"marquestye"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackQuestionData;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.ui.request.FeedbackQuestionCreateRequest;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * Creates a feedback question."},{"lineNumber":19,"author":{"gitId":"-"},"content":" */"},{"lineNumber":20,"author":{"gitId":"-"},"content":"public class CreateFeedbackQuestionAction extends Action {"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":23,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":30,"author":{"gitId":"-"},"content":" String feedbackSessionName \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" InstructorAttributes instructorDetailForCourse \u003d logic.getInstructorForGoogleId(courseId, userInfo.getId());"},{"lineNumber":32,"author":{"gitId":"-"},"content":" if (!isCourseMigrated(courseId)) {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructorDetailForCourse,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" getNonNullFeedbackSession(feedbackSessionName, courseId),"},{"lineNumber":35,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":36,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" }"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" // TODO: Remove sql from variable name after migration"},{"lineNumber":40,"author":{"gitId":"-"},"content":" Instructor sqlInstructorDetailForCourse \u003d sqlLogic.getInstructorByGoogleId(courseId, userInfo.getId());"},{"lineNumber":41,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(sqlInstructorDetailForCourse,"},{"lineNumber":42,"author":{"gitId":"-"},"content":" getNonNullSqlFeedbackSession(feedbackSessionName, courseId),"},{"lineNumber":43,"author":{"gitId":"-"},"content":" Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" }"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":47,"author":{"gitId":"marquestye"},"content":" public JsonResult execute() throws InvalidHttpRequestBodyException, InvalidOperationException {"},{"lineNumber":48,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" String feedbackSessionName \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" FeedbackQuestionCreateRequest request \u003d getAndValidateRequestBody(FeedbackQuestionCreateRequest.class);"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" if (!isCourseMigrated(courseId)) {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" return executeWithDataStore(courseId, feedbackSessionName, request);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" }"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" FeedbackQuestion feedbackQuestion \u003d FeedbackQuestion.makeQuestion("},{"lineNumber":57,"author":{"gitId":"-"},"content":" getNonNullSqlFeedbackSession(feedbackSessionName, courseId),"},{"lineNumber":58,"author":{"gitId":"-"},"content":" request.getQuestionNumber(),"},{"lineNumber":59,"author":{"gitId":"-"},"content":" request.getQuestionDescription(),"},{"lineNumber":60,"author":{"gitId":"-"},"content":" request.getGiverType(),"},{"lineNumber":61,"author":{"gitId":"-"},"content":" request.getRecipientType(),"},{"lineNumber":62,"author":{"gitId":"-"},"content":" request.getNumberOfEntitiesToGiveFeedbackTo(),"},{"lineNumber":63,"author":{"gitId":"-"},"content":" request.getShowResponsesTo(),"},{"lineNumber":64,"author":{"gitId":"-"},"content":" request.getShowGiverNameTo(),"},{"lineNumber":65,"author":{"gitId":"-"},"content":" request.getShowRecipientNameTo(),"},{"lineNumber":66,"author":{"gitId":"-"},"content":" request.getQuestionDetails()"},{"lineNumber":67,"author":{"gitId":"-"},"content":" );"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" // validate questions (giver \u0026 recipient)"},{"lineNumber":71,"author":{"gitId":"-"},"content":" String err \u003d feedbackQuestion.getQuestionDetailsCopy().validateGiverRecipientVisibility(feedbackQuestion);"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" if (!err.isEmpty()) {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(err);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" }"},{"lineNumber":76,"author":{"gitId":"-"},"content":" // validate questions (question details)"},{"lineNumber":77,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails questionDetails \u003d feedbackQuestion.getQuestionDetailsCopy();"},{"lineNumber":78,"author":{"gitId":"-"},"content":" List\u003cString\u003e questionDetailsErrors \u003d questionDetails.validateQuestionDetails();"},{"lineNumber":79,"author":{"gitId":"-"},"content":" if (!questionDetailsErrors.isEmpty()) {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(questionDetailsErrors.toString());"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":" feedbackQuestion \u003d sqlLogic.createFeedbackQuestion(feedbackQuestion);"},{"lineNumber":83,"author":{"gitId":"-"},"content":" return new JsonResult(new FeedbackQuestionData(feedbackQuestion));"},{"lineNumber":84,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException ex) {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(ex);"},{"lineNumber":86,"author":{"gitId":"marquestye"},"content":" } catch (EntityAlreadyExistsException e) {"},{"lineNumber":87,"author":{"gitId":"marquestye"},"content":" throw new InvalidOperationException(e);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":" }"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" private JsonResult executeWithDataStore(String courseId, String feedbackSessionName,"},{"lineNumber":92,"author":{"gitId":"-"},"content":" FeedbackQuestionCreateRequest request) throws InvalidHttpRequestBodyException {"},{"lineNumber":93,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes attributes \u003d FeedbackQuestionAttributes.builder()"},{"lineNumber":94,"author":{"gitId":"-"},"content":" .withCourseId(courseId)"},{"lineNumber":95,"author":{"gitId":"-"},"content":" .withFeedbackSessionName(feedbackSessionName)"},{"lineNumber":96,"author":{"gitId":"-"},"content":" .withGiverType(request.getGiverType())"},{"lineNumber":97,"author":{"gitId":"-"},"content":" .withRecipientType(request.getRecipientType())"},{"lineNumber":98,"author":{"gitId":"-"},"content":" .withQuestionNumber(request.getQuestionNumber())"},{"lineNumber":99,"author":{"gitId":"-"},"content":" .withNumberOfEntitiesToGiveFeedbackTo(request.getNumberOfEntitiesToGiveFeedbackTo())"},{"lineNumber":100,"author":{"gitId":"-"},"content":" .withShowResponsesTo(request.getShowResponsesTo())"},{"lineNumber":101,"author":{"gitId":"-"},"content":" .withShowGiverNameTo(request.getShowGiverNameTo())"},{"lineNumber":102,"author":{"gitId":"-"},"content":" .withShowRecipientNameTo(request.getShowRecipientNameTo())"},{"lineNumber":103,"author":{"gitId":"-"},"content":" .withQuestionDetails(request.getQuestionDetails())"},{"lineNumber":104,"author":{"gitId":"-"},"content":" .withQuestionDescription(request.getQuestionDescription())"},{"lineNumber":105,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" // validate questions (giver \u0026 recipient)"},{"lineNumber":108,"author":{"gitId":"-"},"content":" String err \u003d attributes.getQuestionDetailsCopy().validateGiverRecipientVisibility(attributes);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" if (!err.isEmpty()) {"},{"lineNumber":110,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(err);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":" // validate questions (question details)"},{"lineNumber":113,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails questionDetails \u003d attributes.getQuestionDetailsCopy();"},{"lineNumber":114,"author":{"gitId":"-"},"content":" List\u003cString\u003e questionDetailsErrors \u003d questionDetails.validateQuestionDetails();"},{"lineNumber":115,"author":{"gitId":"-"},"content":" if (!questionDetailsErrors.isEmpty()) {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(String.join(\"\\n\", questionDetailsErrors));"},{"lineNumber":117,"author":{"gitId":"-"},"content":" }"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":120,"author":{"gitId":"-"},"content":" attributes \u003d logic.createFeedbackQuestion(attributes);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(e);"},{"lineNumber":123,"author":{"gitId":"-"},"content":" }"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" return new JsonResult(new FeedbackQuestionData(attributes));"},{"lineNumber":126,"author":{"gitId":"-"},"content":" }"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":4,"-":124}},{"path":"src/main/java/teammates/ui/webapi/CreateFeedbackSessionAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPermissionSet;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionData;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.ui.request.FeedbackSessionCreateRequest;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"-"},"content":" * Create a feedback session."},{"lineNumber":27,"author":{"gitId":"-"},"content":" */"},{"lineNumber":28,"author":{"gitId":"-"},"content":"public class CreateFeedbackSessionAction extends Action {"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":33,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" Instructor instructor \u003d sqlLogic.getInstructorByGoogleId(courseId, userInfo.getId());"},{"lineNumber":43,"author":{"gitId":"-"},"content":" Course course \u003d sqlLogic.getCourse(courseId);"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, course, Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d logic.getInstructorForGoogleId(courseId, userInfo.getId());"},{"lineNumber":48,"author":{"gitId":"-"},"content":" CourseAttributes course \u003d logic.getCourse(courseId);"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, course, Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" }"},{"lineNumber":52,"author":{"gitId":"-"},"content":" }"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":55,"author":{"gitId":"-"},"content":" public JsonResult execute() throws InvalidHttpRequestBodyException, InvalidOperationException {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" FeedbackSessionCreateRequest createRequest \u003d"},{"lineNumber":58,"author":{"gitId":"-"},"content":" getAndValidateRequestBody(FeedbackSessionCreateRequest.class);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" String feedbackSessionName \u003d SanitizationHelper.sanitizeTitle(createRequest.getFeedbackSessionName());"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" Course course \u003d sqlLogic.getCourse(courseId);"},{"lineNumber":63,"author":{"gitId":"-"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Failed to find course with the given course id.\");"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":" Instructor instructor \u003d sqlLogic.getInstructorByGoogleId(courseId, userInfo.getId());"},{"lineNumber":67,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Failed to find instructor with the given courseId and googleId.\");"},{"lineNumber":69,"author":{"gitId":"-"},"content":" }"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" String timeZone \u003d course.getTimeZone();"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" Instant startTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":74,"author":{"gitId":"-"},"content":" createRequest.getSubmissionStartTime(), timeZone, true);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" String startTimeError \u003d FieldValidator.getInvalidityInfoForNewStartTime(startTime, timeZone);"},{"lineNumber":76,"author":{"gitId":"-"},"content":" if (!startTimeError.isEmpty()) {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(\"Invalid submission opening time: \" + startTimeError);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }"},{"lineNumber":79,"author":{"gitId":"-"},"content":" Instant endTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":80,"author":{"gitId":"-"},"content":" createRequest.getSubmissionEndTime(), timeZone, true);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" String endTimeError \u003d FieldValidator.getInvalidityInfoForNewEndTime(endTime, timeZone);"},{"lineNumber":82,"author":{"gitId":"-"},"content":" if (!endTimeError.isEmpty()) {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(\"Invalid submission closing time: \" + endTimeError);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":" Instant sessionVisibleTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":86,"author":{"gitId":"-"},"content":" createRequest.getSessionVisibleFromTime(), timeZone, true);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" String visibilityStartAndSessionStartTimeError \u003d"},{"lineNumber":88,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForNewVisibilityStart(sessionVisibleTime, startTime);"},{"lineNumber":89,"author":{"gitId":"-"},"content":" if (!visibilityStartAndSessionStartTimeError.isEmpty()) {"},{"lineNumber":90,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(\"Invalid session visible time: \""},{"lineNumber":91,"author":{"gitId":"-"},"content":" + visibilityStartAndSessionStartTimeError);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":" Instant resultsVisibleTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":94,"author":{"gitId":"-"},"content":" createRequest.getResultsVisibleFromTime(), timeZone, true);"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" FeedbackSession feedbackSession \u003d new FeedbackSession("},{"lineNumber":97,"author":{"gitId":"-"},"content":" feedbackSessionName,"},{"lineNumber":98,"author":{"gitId":"-"},"content":" course,"},{"lineNumber":99,"author":{"gitId":"-"},"content":" instructor.getEmail(),"},{"lineNumber":100,"author":{"gitId":"-"},"content":" createRequest.getInstructions(),"},{"lineNumber":101,"author":{"gitId":"-"},"content":" startTime,"},{"lineNumber":102,"author":{"gitId":"-"},"content":" endTime,"},{"lineNumber":103,"author":{"gitId":"-"},"content":" sessionVisibleTime,"},{"lineNumber":104,"author":{"gitId":"-"},"content":" resultsVisibleTime,"},{"lineNumber":105,"author":{"gitId":"-"},"content":" createRequest.getGracePeriod(),"},{"lineNumber":106,"author":{"gitId":"-"},"content":" true,"},{"lineNumber":107,"author":{"gitId":"-"},"content":" createRequest.isClosingEmailEnabled(),"},{"lineNumber":108,"author":{"gitId":"-"},"content":" createRequest.isPublishedEmailEnabled()"},{"lineNumber":109,"author":{"gitId":"-"},"content":" );"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" feedbackSession \u003d sqlLogic.createFeedbackSession(feedbackSession);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" } catch (EntityAlreadyExistsException e) {"},{"lineNumber":114,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(\"A session named \" + feedbackSessionName"},{"lineNumber":115,"author":{"gitId":"-"},"content":" + \" exists already in the course \" + course.getName()"},{"lineNumber":116,"author":{"gitId":"-"},"content":" + \" (Course ID: \" + courseId + \")\", e);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":118,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(e);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" }"},{"lineNumber":120,"author":{"gitId":"-"},"content":""},{"lineNumber":121,"author":{"gitId":"-"},"content":" if (createRequest.getToCopyCourseId() !\u003d null) {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" createCopiedFeedbackQuestions(createRequest.getToCopyCourseId(), courseId,"},{"lineNumber":123,"author":{"gitId":"-"},"content":" feedbackSessionName, createRequest.getToCopySessionName());"},{"lineNumber":124,"author":{"gitId":"-"},"content":" }"},{"lineNumber":125,"author":{"gitId":"-"},"content":" FeedbackSessionData output \u003d new FeedbackSessionData(feedbackSession);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" InstructorPermissionSet privilege \u003d constructInstructorPrivileges(instructor, feedbackSessionName);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" output.setPrivileges(privilege);"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" return new JsonResult(output);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":131,"author":{"gitId":"-"},"content":" CourseAttributes course \u003d logic.getCourse(courseId);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" String timeZone \u003d course.getTimeZone();"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" Instant startTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":135,"author":{"gitId":"-"},"content":" createRequest.getSubmissionStartTime(), timeZone, true);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" String startTimeError \u003d FieldValidator.getInvalidityInfoForNewStartTime(startTime, timeZone);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" if (!startTimeError.isEmpty()) {"},{"lineNumber":138,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(\"Invalid submission opening time: \" + startTimeError);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" }"},{"lineNumber":140,"author":{"gitId":"-"},"content":" Instant endTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":141,"author":{"gitId":"-"},"content":" createRequest.getSubmissionEndTime(), timeZone, true);"},{"lineNumber":142,"author":{"gitId":"-"},"content":" String endTimeError \u003d FieldValidator.getInvalidityInfoForNewEndTime(endTime, timeZone);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" if (!endTimeError.isEmpty()) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(\"Invalid submission closing time: \" + endTimeError);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":" Instant sessionVisibleTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":147,"author":{"gitId":"-"},"content":" createRequest.getSessionVisibleFromTime(), timeZone, true);"},{"lineNumber":148,"author":{"gitId":"-"},"content":" String visibilityStartAndSessionStartTimeError \u003d"},{"lineNumber":149,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForNewVisibilityStart(sessionVisibleTime, startTime);"},{"lineNumber":150,"author":{"gitId":"-"},"content":" if (!visibilityStartAndSessionStartTimeError.isEmpty()) {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(\"Invalid session visible time: \""},{"lineNumber":152,"author":{"gitId":"-"},"content":" + visibilityStartAndSessionStartTimeError);"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":" Instant resultsVisibleTime \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone("},{"lineNumber":155,"author":{"gitId":"-"},"content":" createRequest.getResultsVisibleFromTime(), timeZone, true);"},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d logic.getInstructorForGoogleId(courseId, userInfo.getId());"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes fs \u003d"},{"lineNumber":160,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes"},{"lineNumber":161,"author":{"gitId":"-"},"content":" .builder(feedbackSessionName, course.getId())"},{"lineNumber":162,"author":{"gitId":"-"},"content":" .withCreatorEmail(instructor.getEmail())"},{"lineNumber":163,"author":{"gitId":"-"},"content":" .withTimeZone(course.getTimeZone())"},{"lineNumber":164,"author":{"gitId":"-"},"content":" .withInstructions(createRequest.getInstructions())"},{"lineNumber":165,"author":{"gitId":"-"},"content":" .withStartTime(startTime)"},{"lineNumber":166,"author":{"gitId":"-"},"content":" .withEndTime(endTime)"},{"lineNumber":167,"author":{"gitId":"-"},"content":" .withGracePeriod(createRequest.getGracePeriod())"},{"lineNumber":168,"author":{"gitId":"-"},"content":" .withSessionVisibleFromTime(sessionVisibleTime)"},{"lineNumber":169,"author":{"gitId":"-"},"content":" .withResultsVisibleFromTime(resultsVisibleTime)"},{"lineNumber":170,"author":{"gitId":"-"},"content":" .withIsClosingEmailEnabled(createRequest.isClosingEmailEnabled())"},{"lineNumber":171,"author":{"gitId":"-"},"content":" .withIsPublishedEmailEnabled(createRequest.isPublishedEmailEnabled())"},{"lineNumber":172,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":173,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" logic.createFeedbackSession(fs);"},{"lineNumber":175,"author":{"gitId":"-"},"content":" } catch (EntityAlreadyExistsException e) {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(\"A session named \" + feedbackSessionName"},{"lineNumber":177,"author":{"gitId":"-"},"content":" + \" exists already in the course \" + course.getName()"},{"lineNumber":178,"author":{"gitId":"-"},"content":" + \" (Course ID: \" + courseId + \")\", e);"},{"lineNumber":179,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(e);"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" if (createRequest.getToCopyCourseId() !\u003d null) {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" createFeedbackQuestions(createRequest.getToCopyCourseId(), courseId, feedbackSessionName,"},{"lineNumber":185,"author":{"gitId":"-"},"content":" createRequest.getToCopySessionName());"},{"lineNumber":186,"author":{"gitId":"-"},"content":" }"},{"lineNumber":187,"author":{"gitId":"-"},"content":" fs \u003d getNonNullFeedbackSession(fs.getFeedbackSessionName(), fs.getCourseId());"},{"lineNumber":188,"author":{"gitId":"-"},"content":" FeedbackSessionData output \u003d new FeedbackSessionData(fs);"},{"lineNumber":189,"author":{"gitId":"-"},"content":" InstructorPermissionSet privilege \u003d constructInstructorPrivileges(instructor, feedbackSessionName);"},{"lineNumber":190,"author":{"gitId":"-"},"content":" output.setPrivileges(privilege);"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"-"},"content":" return new JsonResult(output);"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":" }"},{"lineNumber":195,"author":{"gitId":"-"},"content":""},{"lineNumber":196,"author":{"gitId":"-"},"content":" private void createCopiedFeedbackQuestions(String oldCourseId, String newCourseId,"},{"lineNumber":197,"author":{"gitId":"-"},"content":" String newFeedbackSessionName, String oldFeedbackSessionName) {"},{"lineNumber":198,"author":{"gitId":"-"},"content":" FeedbackSession oldFeedbackSession \u003d sqlLogic.getFeedbackSession(oldFeedbackSessionName, oldCourseId);"},{"lineNumber":199,"author":{"gitId":"-"},"content":" FeedbackSession newFeedbackSession \u003d sqlLogic.getFeedbackSession(newFeedbackSessionName, newCourseId);"},{"lineNumber":200,"author":{"gitId":"-"},"content":" sqlLogic.getFeedbackQuestionsForSession(oldFeedbackSession).forEach(question -\u003e {"},{"lineNumber":201,"author":{"gitId":"-"},"content":" FeedbackQuestion feedbackQuestion \u003d question.makeDeepCopy(newFeedbackSession);"},{"lineNumber":202,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":203,"author":{"gitId":"-"},"content":" sqlLogic.createFeedbackQuestion(feedbackQuestion);"},{"lineNumber":204,"author":{"gitId":"marquestye"},"content":" } catch (InvalidParametersException | EntityAlreadyExistsException e) {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" log.severe(\"Error when copying feedback question: \" + e.getMessage());"},{"lineNumber":206,"author":{"gitId":"-"},"content":" }"},{"lineNumber":207,"author":{"gitId":"-"},"content":" });"},{"lineNumber":208,"author":{"gitId":"-"},"content":" }"},{"lineNumber":209,"author":{"gitId":"-"},"content":""},{"lineNumber":210,"author":{"gitId":"-"},"content":" private void createFeedbackQuestions(String copyCourseId, String newCourseId, String feedbackSessionName,"},{"lineNumber":211,"author":{"gitId":"-"},"content":" String oldSessionName) {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" logic.getFeedbackQuestionsForSession(oldSessionName, copyCourseId).forEach(question -\u003e {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes attributes \u003d FeedbackQuestionAttributes.builder()"},{"lineNumber":214,"author":{"gitId":"-"},"content":" .withCourseId(newCourseId)"},{"lineNumber":215,"author":{"gitId":"-"},"content":" .withFeedbackSessionName(feedbackSessionName)"},{"lineNumber":216,"author":{"gitId":"-"},"content":" .withGiverType(question.getGiverType())"},{"lineNumber":217,"author":{"gitId":"-"},"content":" .withRecipientType(question.getRecipientType())"},{"lineNumber":218,"author":{"gitId":"-"},"content":" .withQuestionNumber(question.getQuestionNumber())"},{"lineNumber":219,"author":{"gitId":"-"},"content":" .withNumberOfEntitiesToGiveFeedbackTo(question.getNumberOfEntitiesToGiveFeedbackTo())"},{"lineNumber":220,"author":{"gitId":"-"},"content":" .withShowResponsesTo(question.getShowResponsesTo())"},{"lineNumber":221,"author":{"gitId":"-"},"content":" .withShowGiverNameTo(question.getShowGiverNameTo())"},{"lineNumber":222,"author":{"gitId":"-"},"content":" .withShowRecipientNameTo(question.getShowRecipientNameTo())"},{"lineNumber":223,"author":{"gitId":"-"},"content":" .withQuestionDetails(question.getQuestionDetails())"},{"lineNumber":224,"author":{"gitId":"-"},"content":" .withQuestionDescription(question.getQuestionDescription())"},{"lineNumber":225,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":226,"author":{"gitId":"-"},"content":""},{"lineNumber":227,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":228,"author":{"gitId":"-"},"content":" logic.createFeedbackQuestion(attributes);"},{"lineNumber":229,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":230,"author":{"gitId":"-"},"content":" log.severe(\"Error when copying feedback question: \" + e.getMessage());"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":" });"},{"lineNumber":233,"author":{"gitId":"-"},"content":" }"},{"lineNumber":234,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":1,"-":233}},{"path":"src/main/java/teammates/ui/webapi/CreateFeedbackSessionLogAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionAuditLogDetails;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * Action: creates a feedback session log for the purposes of tracking and auditing."},{"lineNumber":12,"author":{"gitId":"-"},"content":" */"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"public class CreateFeedbackSessionLogAction extends Action {"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":18,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" return AuthType.PUBLIC;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" }"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":23,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" // No specific access control restrictions on creating feedback session logs"},{"lineNumber":25,"author":{"gitId":"-"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"-"},"content":" public JsonResult execute() {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" String fslType \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE);"},{"lineNumber":30,"author":{"gitId":"-"},"content":" FeedbackSessionLogType convertedFslType \u003d FeedbackSessionLogType.valueOfLabel(fslType);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" if (convertedFslType \u003d\u003d null) {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Invalid log type\");"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":36,"author":{"gitId":"-"},"content":" String fsName \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" String studentEmail \u003d getNonNullRequestParamValue(Const.ParamsNames.STUDENT_EMAIL);"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" // Skip rigorous validations to avoid incurring extra db reads and to keep the endpoint"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" // light"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" FeedbackSessionAuditLogDetails details \u003d new FeedbackSessionAuditLogDetails();"},{"lineNumber":42,"author":{"gitId":"-"},"content":" details.setCourseId(courseId);"},{"lineNumber":43,"author":{"gitId":"-"},"content":" details.setFeedbackSessionName(fsName);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" details.setStudentEmail(studentEmail);"},{"lineNumber":45,"author":{"gitId":"-"},"content":" details.setAccessType(fslType);"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" UUID studentId \u003d getUuidRequestParamValue(Const.ParamsNames.STUDENT_SQL_ID);"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" UUID fsId \u003d getUuidRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_ID);"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" details.setStudentId(studentId.toString());"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" details.setFeedbackSessionId(fsId.toString());"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" // Necessary to assist local testing. For production usage, this will be a no-op."},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" logsProcessor.createFeedbackSessionLog(courseId, studentId, fsId, fslType);"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" // Necessary to assist local testing. For production usage, this will be a no-op."},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" logsProcessor.createFeedbackSessionLog(courseId, studentEmail, fsName, fslType);"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" log.event(\"Feedback session audit event: \" + fslType, details);"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" return new JsonResult(\"Successful\");"},{"lineNumber":64,"author":{"gitId":"-"},"content":" }"},{"lineNumber":65,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":19,"-":46}},{"path":"src/main/java/teammates/ui/webapi/CreateInstructorAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.datatransfer.InstructorPermissionRole;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPrivileges;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.SanitizationHelper;"},{"lineNumber":10,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":11,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.ui.output.InstructorData;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.ui.request.InstructorCreateRequest;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * Action: adds another instructor to a course that already exists."},{"lineNumber":18,"author":{"gitId":"-"},"content":" */"},{"lineNumber":19,"author":{"gitId":"mingyuanc"},"content":"public class CreateInstructorAction extends Action {"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":22,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":23,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" }"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":27,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" if (userInfo.isAdmin) {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" if (!userInfo.isInstructor) {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Instructor privilege is required to access this resource.\");"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"mingyuanc"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":39,"author":{"gitId":"mingyuanc"},"content":" Instructor instructor \u003d sqlLogic.getInstructorByGoogleId(courseId, userInfo.id);"},{"lineNumber":40,"author":{"gitId":"mingyuanc"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":41,"author":{"gitId":"mingyuanc"},"content":" instructor, sqlLogic.getCourse(courseId), Const.InstructorPermissions.CAN_MODIFY_INSTRUCTOR);"},{"lineNumber":42,"author":{"gitId":"mingyuanc"},"content":" } else {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d logic.getInstructorForGoogleId(courseId, userInfo.id);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":45,"author":{"gitId":"-"},"content":" instructor, logic.getCourse(courseId), Const.InstructorPermissions.CAN_MODIFY_INSTRUCTOR);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":" }"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":50,"author":{"gitId":"-"},"content":" public JsonResult execute() throws InvalidHttpRequestBodyException, InvalidOperationException {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" InstructorCreateRequest instructorRequest \u003d getAndValidateRequestBody(InstructorCreateRequest.class);"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":55,"author":{"gitId":"mingyuanc"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":56,"author":{"gitId":"mingyuanc"},"content":" return executeWithSql(courseId, instructorRequest);"},{"lineNumber":57,"author":{"gitId":"mingyuanc"},"content":" } else {"},{"lineNumber":58,"author":{"gitId":"mingyuanc"},"content":" return executeWithDataStore(courseId, instructorRequest);"},{"lineNumber":59,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":" } catch (EntityAlreadyExistsException e) {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" throw new InvalidOperationException("},{"lineNumber":62,"author":{"gitId":"-"},"content":" \"An instructor with the same email address already exists in the course.\", e);"},{"lineNumber":63,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(e);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":67,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":68,"author":{"gitId":"mingyuanc"},"content":" /**"},{"lineNumber":69,"author":{"gitId":"mingyuanc"},"content":" * Executes the action using SQL storage."},{"lineNumber":70,"author":{"gitId":"mingyuanc"},"content":" *"},{"lineNumber":71,"author":{"gitId":"mingyuanc"},"content":" * @param courseId Id of the course the instructor is being added"},{"lineNumber":72,"author":{"gitId":"mingyuanc"},"content":" * to."},{"lineNumber":73,"author":{"gitId":"mingyuanc"},"content":" * @param instructorRequest Request body containing the instructor\u0027s info."},{"lineNumber":74,"author":{"gitId":"mingyuanc"},"content":" * @return The Json result of the created Instructor"},{"lineNumber":75,"author":{"gitId":"mingyuanc"},"content":" * @throws InvalidParametersException If a parameter is invalid"},{"lineNumber":76,"author":{"gitId":"mingyuanc"},"content":" * @throws EntityAlreadyExistsException If there is a conflict at the email"},{"lineNumber":77,"author":{"gitId":"mingyuanc"},"content":" * field"},{"lineNumber":78,"author":{"gitId":"mingyuanc"},"content":" */"},{"lineNumber":79,"author":{"gitId":"mingyuanc"},"content":" private JsonResult executeWithSql(String courseId, InstructorCreateRequest instructorRequest)"},{"lineNumber":80,"author":{"gitId":"mingyuanc"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":81,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":82,"author":{"gitId":"mingyuanc"},"content":" Instructor instructorToAdd \u003d createInstructorWithBasicAttributesSql(courseId,"},{"lineNumber":83,"author":{"gitId":"mingyuanc"},"content":" SanitizationHelper.sanitizeName(instructorRequest.getName()),"},{"lineNumber":84,"author":{"gitId":"mingyuanc"},"content":" SanitizationHelper.sanitizeEmail(instructorRequest.getEmail()), instructorRequest.getRoleName(),"},{"lineNumber":85,"author":{"gitId":"mingyuanc"},"content":" instructorRequest.getIsDisplayedToStudent(),"},{"lineNumber":86,"author":{"gitId":"mingyuanc"},"content":" SanitizationHelper.sanitizeName(instructorRequest.getDisplayName()));"},{"lineNumber":87,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":88,"author":{"gitId":"mingyuanc"},"content":" Instructor createdInstructor \u003d sqlLogic.createInstructor(instructorToAdd);"},{"lineNumber":89,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":90,"author":{"gitId":"mingyuanc"},"content":" taskQueuer.scheduleCourseRegistrationInviteToInstructor("},{"lineNumber":91,"author":{"gitId":"mingyuanc"},"content":" this.userInfo.id, instructorToAdd.getEmail(), courseId, false);"},{"lineNumber":92,"author":{"gitId":"mingyuanc"},"content":" taskQueuer.scheduleInstructorForSearchIndexing(createdInstructor.getCourseId(), createdInstructor.getEmail());"},{"lineNumber":93,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":94,"author":{"gitId":"mingyuanc"},"content":" return new JsonResult(new InstructorData(createdInstructor));"},{"lineNumber":95,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":96,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":97,"author":{"gitId":"mingyuanc"},"content":" /**"},{"lineNumber":98,"author":{"gitId":"mingyuanc"},"content":" * Executes the action using Datastore storage."},{"lineNumber":99,"author":{"gitId":"mingyuanc"},"content":" *"},{"lineNumber":100,"author":{"gitId":"mingyuanc"},"content":" * @param courseId Id of the course the instructor is being added"},{"lineNumber":101,"author":{"gitId":"mingyuanc"},"content":" * to."},{"lineNumber":102,"author":{"gitId":"mingyuanc"},"content":" * @param instructorRequest Request body containing the instructor\u0027s info."},{"lineNumber":103,"author":{"gitId":"mingyuanc"},"content":" * @return The Json result of the created Instructor"},{"lineNumber":104,"author":{"gitId":"mingyuanc"},"content":" * @throws InvalidParametersException If a parameter is invalid"},{"lineNumber":105,"author":{"gitId":"mingyuanc"},"content":" * @throws EntityAlreadyExistsException If there is a conflict at the email"},{"lineNumber":106,"author":{"gitId":"mingyuanc"},"content":" * field"},{"lineNumber":107,"author":{"gitId":"mingyuanc"},"content":" */"},{"lineNumber":108,"author":{"gitId":"mingyuanc"},"content":" private JsonResult executeWithDataStore(String courseId, InstructorCreateRequest instructorRequest)"},{"lineNumber":109,"author":{"gitId":"mingyuanc"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":110,"author":{"gitId":"-"},"content":" InstructorAttributes instructorToAdd \u003d createInstructorWithBasicAttributes(courseId,"},{"lineNumber":111,"author":{"gitId":"-"},"content":" instructorRequest.getName(), instructorRequest.getEmail(), instructorRequest.getRoleName(),"},{"lineNumber":112,"author":{"gitId":"-"},"content":" instructorRequest.getIsDisplayedToStudent(), instructorRequest.getDisplayName());"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" InstructorAttributes createdInstructor \u003d logic.createInstructor(instructorToAdd);"},{"lineNumber":115,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" taskQueuer.scheduleCourseRegistrationInviteToInstructor("},{"lineNumber":117,"author":{"gitId":"-"},"content":" userInfo.id, instructorToAdd.getEmail(), instructorToAdd.getCourseId(), false);"},{"lineNumber":118,"author":{"gitId":"-"},"content":" taskQueuer.scheduleInstructorForSearchIndexing(createdInstructor.getCourseId(), createdInstructor.getEmail());"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" return new JsonResult(new InstructorData(createdInstructor));"},{"lineNumber":121,"author":{"gitId":"-"},"content":" }"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"mingyuanc"},"content":" /**"},{"lineNumber":124,"author":{"gitId":"mingyuanc"},"content":" * Creates a new instructor with basic information."},{"lineNumber":125,"author":{"gitId":"mingyuanc"},"content":" * This consists of everything apart from custom privileges."},{"lineNumber":126,"author":{"gitId":"mingyuanc"},"content":" *"},{"lineNumber":127,"author":{"gitId":"mingyuanc"},"content":" * @param courseId Id of the course the instructor is being added"},{"lineNumber":128,"author":{"gitId":"mingyuanc"},"content":" * to."},{"lineNumber":129,"author":{"gitId":"mingyuanc"},"content":" * @param instructorName Name of the instructor."},{"lineNumber":130,"author":{"gitId":"mingyuanc"},"content":" * @param instructorEmail Email of the instructor."},{"lineNumber":131,"author":{"gitId":"mingyuanc"},"content":" * @param instructorRole Role of the instructor."},{"lineNumber":132,"author":{"gitId":"mingyuanc"},"content":" * @param isDisplayedToStudents Whether the instructor should be visible to"},{"lineNumber":133,"author":{"gitId":"mingyuanc"},"content":" * students."},{"lineNumber":134,"author":{"gitId":"mingyuanc"},"content":" * @param displayedName Name to be visible to students."},{"lineNumber":135,"author":{"gitId":"mingyuanc"},"content":" * Should not be {@code null} even if"},{"lineNumber":136,"author":{"gitId":"mingyuanc"},"content":" * {@code isDisplayedToStudents} is false."},{"lineNumber":137,"author":{"gitId":"mingyuanc"},"content":" * @return An instructor with basic info, excluding custom privileges"},{"lineNumber":138,"author":{"gitId":"mingyuanc"},"content":" */"},{"lineNumber":139,"author":{"gitId":"mingyuanc"},"content":" private Instructor createInstructorWithBasicAttributesSql(String courseId, String instructorName,"},{"lineNumber":140,"author":{"gitId":"mingyuanc"},"content":" String instructorEmail, String instructorRole,"},{"lineNumber":141,"author":{"gitId":"mingyuanc"},"content":" boolean isDisplayedToStudents, String displayedName) {"},{"lineNumber":142,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":143,"author":{"gitId":"mingyuanc"},"content":" String instrName \u003d SanitizationHelper.sanitizeName(instructorName);"},{"lineNumber":144,"author":{"gitId":"mingyuanc"},"content":" String instrEmail \u003d SanitizationHelper.sanitizeEmail(instructorEmail);"},{"lineNumber":145,"author":{"gitId":"mingyuanc"},"content":" String instrRole \u003d SanitizationHelper.sanitizeName(instructorRole);"},{"lineNumber":146,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":147,"author":{"gitId":"mingyuanc"},"content":" String instrDisplayedName \u003d displayedName;"},{"lineNumber":148,"author":{"gitId":"mingyuanc"},"content":" if (displayedName \u003d\u003d null || displayedName.isEmpty()) {"},{"lineNumber":149,"author":{"gitId":"mingyuanc"},"content":" instrDisplayedName \u003d Const.DEFAULT_DISPLAY_NAME_FOR_INSTRUCTOR;"},{"lineNumber":150,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":151,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":152,"author":{"gitId":"mingyuanc"},"content":" InstructorPrivileges privileges \u003d new InstructorPrivileges(instrRole);"},{"lineNumber":153,"author":{"gitId":"mingyuanc"},"content":" InstructorPermissionRole role \u003d InstructorPermissionRole.getEnum(instrRole);"},{"lineNumber":154,"author":{"gitId":"mingyuanc"},"content":" Course course \u003d sqlLogic.getCourse(courseId);"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"mingyuanc"},"content":" return new Instructor(course, instrName, instrEmail, isDisplayedToStudents, instrDisplayedName, role,"},{"lineNumber":157,"author":{"gitId":"mingyuanc"},"content":" privileges);"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":161,"author":{"gitId":"-"},"content":" * Creates a new instructor with basic information."},{"lineNumber":162,"author":{"gitId":"-"},"content":" * This consists of everything apart from custom privileges."},{"lineNumber":163,"author":{"gitId":"-"},"content":" *"},{"lineNumber":164,"author":{"gitId":"mingyuanc"},"content":" * @param courseId Id of the course the instructor is being added"},{"lineNumber":165,"author":{"gitId":"mingyuanc"},"content":" * to."},{"lineNumber":166,"author":{"gitId":"-"},"content":" * @param instructorName Name of the instructor."},{"lineNumber":167,"author":{"gitId":"-"},"content":" * @param instructorEmail Email of the instructor."},{"lineNumber":168,"author":{"gitId":"-"},"content":" * @param instructorRole Role of the instructor."},{"lineNumber":169,"author":{"gitId":"mingyuanc"},"content":" * @param isDisplayedToStudents Whether the instructor should be visible to"},{"lineNumber":170,"author":{"gitId":"mingyuanc"},"content":" * students."},{"lineNumber":171,"author":{"gitId":"-"},"content":" * @param displayedName Name to be visible to students."},{"lineNumber":172,"author":{"gitId":"mingyuanc"},"content":" * Should not be {@code null} even if"},{"lineNumber":173,"author":{"gitId":"mingyuanc"},"content":" * {@code isDisplayedToStudents} is false."},{"lineNumber":174,"author":{"gitId":"-"},"content":" * @return An instructor with basic info, excluding custom privileges"},{"lineNumber":175,"author":{"gitId":"-"},"content":" */"},{"lineNumber":176,"author":{"gitId":"-"},"content":" private InstructorAttributes createInstructorWithBasicAttributes(String courseId, String instructorName,"},{"lineNumber":177,"author":{"gitId":"-"},"content":" String instructorEmail, String instructorRole,"},{"lineNumber":178,"author":{"gitId":"-"},"content":" boolean isDisplayedToStudents, String displayedName) {"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" String instrName \u003d SanitizationHelper.sanitizeName(instructorName);"},{"lineNumber":181,"author":{"gitId":"-"},"content":" String instrEmail \u003d SanitizationHelper.sanitizeEmail(instructorEmail);"},{"lineNumber":182,"author":{"gitId":"-"},"content":" String instrRole \u003d SanitizationHelper.sanitizeName(instructorRole);"},{"lineNumber":183,"author":{"gitId":"-"},"content":""},{"lineNumber":184,"author":{"gitId":"-"},"content":" String instrDisplayedName \u003d displayedName;"},{"lineNumber":185,"author":{"gitId":"-"},"content":" if (displayedName \u003d\u003d null || displayedName.isEmpty()) {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" instrDisplayedName \u003d Const.DEFAULT_DISPLAY_NAME_FOR_INSTRUCTOR;"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":" instrDisplayedName \u003d SanitizationHelper.sanitizeName(instrDisplayedName);"},{"lineNumber":190,"author":{"gitId":"-"},"content":" InstructorPrivileges privileges \u003d new InstructorPrivileges(instructorRole);"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"-"},"content":" return InstructorAttributes.builder(courseId, instrEmail)"},{"lineNumber":193,"author":{"gitId":"-"},"content":" .withName(instrName)"},{"lineNumber":194,"author":{"gitId":"-"},"content":" .withRole(instrRole)"},{"lineNumber":195,"author":{"gitId":"-"},"content":" .withIsDisplayedToStudents(isDisplayedToStudents)"},{"lineNumber":196,"author":{"gitId":"-"},"content":" .withDisplayedName(instrDisplayedName)"},{"lineNumber":197,"author":{"gitId":"-"},"content":" .withPrivileges(privileges)"},{"lineNumber":198,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":199,"author":{"gitId":"-"},"content":" }"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"mingyuanc":99,"-":102}},{"path":"src/main/java/teammates/ui/webapi/DeleteAccountRequestAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":9,"author":{"gitId":"-"},"content":" * Deletes an existing account request."},{"lineNumber":10,"author":{"gitId":"-"},"content":" */"},{"lineNumber":11,"author":{"gitId":"-"},"content":"class DeleteAccountRequestAction extends AdminOnlyAction {"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":14,"author":{"gitId":"-"},"content":" public JsonResult execute() throws InvalidOperationException {"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":" UUID id \u003d getUuidRequestParamValue(Const.ParamsNames.ACCOUNT_REQUEST_ID);"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":" AccountRequest toDelete \u003d sqlLogic.getAccountRequest(id);"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":" if (toDelete !\u003d null \u0026\u0026 toDelete.getRegisteredAt() !\u003d null) {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" // instructor is already registered and cannot be deleted"},{"lineNumber":21,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(\"Account request of a registered instructor cannot be deleted.\");"},{"lineNumber":22,"author":{"gitId":"-"},"content":" }"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":" sqlLogic.deleteAccountRequest(id);"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" return new JsonResult(\"Account request successfully deleted.\");"},{"lineNumber":27,"author":{"gitId":"-"},"content":" }"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":5,"-":24}},{"path":"src/main/java/teammates/ui/webapi/EnrollStudentsAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.Set;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.EnrollException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.util.RequestTracer;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.ui.output.EnrollStudentsData;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.ui.output.StudentData;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.ui.output.StudentsData;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.ui.request.StudentsEnrollRequest;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":28,"author":{"gitId":"-"},"content":" * Enroll a list of students."},{"lineNumber":29,"author":{"gitId":"-"},"content":" *"},{"lineNumber":30,"author":{"gitId":"-"},"content":" * \u003cp\u003eCreate the students who are not in the course."},{"lineNumber":31,"author":{"gitId":"-"},"content":" *"},{"lineNumber":32,"author":{"gitId":"-"},"content":" * \u003cp\u003eUpdate the students who are already existed."},{"lineNumber":33,"author":{"gitId":"-"},"content":" *"},{"lineNumber":34,"author":{"gitId":"-"},"content":" * \u003cp\u003eReturn all students who are successfully enrolled."},{"lineNumber":35,"author":{"gitId":"-"},"content":" */"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":"public class EnrollStudentsAction extends Action {"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":39,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":44,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" if (!userInfo.isInstructor) {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Instructor privilege is required to access this resource.\");"},{"lineNumber":47,"author":{"gitId":"-"},"content":" }"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" if (!isCourseMigrated(courseId)) {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d logic.getInstructorForGoogleId(courseId, userInfo.id);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":53,"author":{"gitId":"-"},"content":" instructor, logic.getCourse(courseId), Const.InstructorPermissions.CAN_MODIFY_STUDENT);"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" return;"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" Instructor instructor \u003d sqlLogic.getInstructorByGoogleId(courseId, userInfo.id);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" instructor, sqlLogic.getCourse(courseId), Const.InstructorPermissions.CAN_MODIFY_STUDENT);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":64,"author":{"gitId":"-"},"content":" public JsonResult execute() throws InvalidHttpRequestBodyException, InvalidOperationException {"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" StudentsEnrollRequest enrollRequests \u003d getAndValidateRequestBody(StudentsEnrollRequest.class);"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":" List\u003cStudentsEnrollRequest.StudentEnrollRequest\u003e studentEnrollRequests \u003d enrollRequests.getStudentEnrollRequests();"},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" Course course \u003d sqlLogic.getCourse(courseId);"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" boolean isCourseMigrated \u003d isCourseMigrated(courseId);"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" if (isCourseMigrated) {"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e studentsToEnroll \u003d new ArrayList\u003c\u003e();"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" studentEnrollRequests.forEach(studentEnrollRequest -\u003e {"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" Section section \u003d new Section(course, studentEnrollRequest.getSection());"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" Team team \u003d new Team(section, studentEnrollRequest.getTeam());"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" studentsToEnroll.add(new Student("},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" course, studentEnrollRequest.getName(),"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" studentEnrollRequest.getEmail(), studentEnrollRequest.getComments(), team));"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" sqlLogic.validateSectionsAndTeams(studentsToEnroll, courseId);"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" } catch (EnrollException e) {"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" throw new InvalidOperationException(e);"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e enrolledStudents \u003d new ArrayList\u003c\u003e();"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" List\u003cEnrollStudentsData.EnrollErrorResults\u003e failToEnrollStudents \u003d new ArrayList\u003c\u003e();"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" Set\u003cString\u003e existingStudentsEmail;"},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" List\u003cStudent\u003e existingStudents \u003d sqlLogic.getStudentsForCourse(courseId);"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" existingStudentsEmail \u003d"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":" existingStudents.stream().map(Student::getEmail).collect(Collectors.toSet());"},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" for (StudentsEnrollRequest.StudentEnrollRequest enrollRequest : studentEnrollRequests) {"},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":" if (existingStudentsEmail.contains(enrollRequest.getEmail())) {"},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":" // The student has been enrolled in the course."},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":" Section section \u003d sqlLogic.getSectionOrCreate(courseId, enrollRequest.getSection());"},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" Team team \u003d sqlLogic.getTeamOrCreate(section, enrollRequest.getTeam());"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" Student newStudent \u003d new Student("},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":" course, enrollRequest.getName(),"},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" enrollRequest.getEmail(), enrollRequest.getComments(), team);"},{"lineNumber":105,"author":{"gitId":"marquestye"},"content":" newStudent.setId(sqlLogic.getStudentForEmail(courseId, enrollRequest.getEmail()).getId());"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" Student updatedStudent \u003d sqlLogic.updateStudentCascade(newStudent);"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" taskQueuer.scheduleStudentForSearchIndexing("},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" updatedStudent.getCourseId(), updatedStudent.getEmail());"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" enrolledStudents.add(updatedStudent);"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" } catch (InvalidParametersException | EntityDoesNotExistException"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" | EntityAlreadyExistsException exception) {"},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" // Unsuccessfully enrolled students will not be returned."},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" failToEnrollStudents.add(new EnrollStudentsData.EnrollErrorResults(enrollRequest.getEmail(),"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" exception.getMessage()));"},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" } else {"},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":" // The student is new."},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" Section section \u003d sqlLogic.getSectionOrCreate(courseId, enrollRequest.getSection());"},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" Team team \u003d sqlLogic.getTeamOrCreate(section, enrollRequest.getTeam());"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":" Student newStudent \u003d new Student("},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" course, enrollRequest.getName(),"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":" enrollRequest.getEmail(), enrollRequest.getComments(), team);"},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" newStudent \u003d sqlLogic.createStudent(newStudent);"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" taskQueuer.scheduleStudentForSearchIndexing("},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" newStudent.getCourseId(), newStudent.getEmail());"},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" enrolledStudents.add(newStudent);"},{"lineNumber":128,"author":{"gitId":"domoberzin"},"content":" } catch (InvalidParametersException | EntityAlreadyExistsException exception) {"},{"lineNumber":129,"author":{"gitId":"domoberzin"},"content":" // Unsuccessfully enrolled students will not be returned."},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":" failToEnrollStudents.add(new EnrollStudentsData.EnrollErrorResults(enrollRequest.getEmail(),"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":" exception.getMessage()));"},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" List\u003cStudentData\u003e studentDataList \u003d enrolledStudents"},{"lineNumber":137,"author":{"gitId":"domoberzin"},"content":" .stream()"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":" .map(StudentData::new)"},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":" .collect(Collectors.toList());"},{"lineNumber":140,"author":{"gitId":"domoberzin"},"content":" StudentsData data \u003d new StudentsData();"},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":" data.setStudents(studentDataList);"},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":" return new JsonResult(new EnrollStudentsData(data, failToEnrollStudents));"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":" } else {"},{"lineNumber":147,"author":{"gitId":"-"},"content":" List\u003cStudentAttributes\u003e studentsToEnroll \u003d new ArrayList\u003c\u003e();"},{"lineNumber":148,"author":{"gitId":"-"},"content":" enrollRequests.getStudentEnrollRequests().forEach(studentEnrollRequest -\u003e {"},{"lineNumber":149,"author":{"gitId":"-"},"content":" studentsToEnroll.add(StudentAttributes.builder(courseId, studentEnrollRequest.getEmail())"},{"lineNumber":150,"author":{"gitId":"-"},"content":" .withName(studentEnrollRequest.getName())"},{"lineNumber":151,"author":{"gitId":"-"},"content":" .withSectionName(studentEnrollRequest.getSection())"},{"lineNumber":152,"author":{"gitId":"-"},"content":" .withTeamName(studentEnrollRequest.getTeam())"},{"lineNumber":153,"author":{"gitId":"-"},"content":" .withComment(studentEnrollRequest.getComments())"},{"lineNumber":154,"author":{"gitId":"-"},"content":" .build());"},{"lineNumber":155,"author":{"gitId":"-"},"content":" });"},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" logic.validateSectionsAndTeams(studentsToEnroll, courseId);"},{"lineNumber":159,"author":{"gitId":"-"},"content":" } catch (EnrollException e) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(e);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" List\u003cStudentAttributes\u003e enrolledStudents \u003d new ArrayList\u003c\u003e();"},{"lineNumber":164,"author":{"gitId":"-"},"content":" List\u003cEnrollStudentsData.EnrollErrorResults\u003e failToEnrollStudents \u003d new ArrayList\u003c\u003e();"},{"lineNumber":165,"author":{"gitId":"domoberzin"},"content":" Set\u003cString\u003e existingStudentsEmail;"},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" List\u003cStudentAttributes\u003e existingStudents \u003d logic.getStudentsForCourse(courseId);"},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":" existingStudentsEmail \u003d"},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" existingStudents.stream().map(StudentAttributes::getEmail).collect(Collectors.toSet());"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" for (StudentAttributes student : studentsToEnroll) {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" RequestTracer.checkRemainingTime();"},{"lineNumber":173,"author":{"gitId":"-"},"content":" if (existingStudentsEmail.contains(student.getEmail())) {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" // The student has been enrolled in the course."},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" StudentAttributes.UpdateOptions updateOptions \u003d"},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" StudentAttributes.updateOptionsBuilder(courseId, student.getEmail())"},{"lineNumber":178,"author":{"gitId":"-"},"content":" .withName(student.getName())"},{"lineNumber":179,"author":{"gitId":"-"},"content":" .withSectionName(student.getSection())"},{"lineNumber":180,"author":{"gitId":"-"},"content":" .withTeamName(student.getTeam())"},{"lineNumber":181,"author":{"gitId":"-"},"content":" .withComment(student.getComments())"},{"lineNumber":182,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":183,"author":{"gitId":"-"},"content":" StudentAttributes updatedStudent \u003d logic.updateStudentCascade(updateOptions);"},{"lineNumber":184,"author":{"gitId":"domoberzin"},"content":" taskQueuer.scheduleStudentForSearchIndexing("},{"lineNumber":185,"author":{"gitId":"domoberzin"},"content":" updatedStudent.getCourse(), updatedStudent.getEmail());"},{"lineNumber":186,"author":{"gitId":"-"},"content":" enrolledStudents.add(updatedStudent);"},{"lineNumber":187,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException | EntityDoesNotExistException"},{"lineNumber":188,"author":{"gitId":"-"},"content":" | EntityAlreadyExistsException exception) {"},{"lineNumber":189,"author":{"gitId":"-"},"content":" // Unsuccessfully enrolled students will not be returned."},{"lineNumber":190,"author":{"gitId":"-"},"content":" failToEnrollStudents.add(new EnrollStudentsData.EnrollErrorResults(student.getEmail(),"},{"lineNumber":191,"author":{"gitId":"-"},"content":" exception.getMessage()));"},{"lineNumber":192,"author":{"gitId":"-"},"content":" }"},{"lineNumber":193,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":194,"author":{"gitId":"-"},"content":" // The student is new."},{"lineNumber":195,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":" StudentAttributes studentAttributes \u003d StudentAttributes.builder(courseId, student.getEmail())"},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":" .withName(student.getName())"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" .withSectionName(student.getSection())"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":" .withTeamName(student.getTeam())"},{"lineNumber":200,"author":{"gitId":"domoberzin"},"content":" .withComment(student.getComments())"},{"lineNumber":201,"author":{"gitId":"domoberzin"},"content":" .build();"},{"lineNumber":202,"author":{"gitId":"domoberzin"},"content":" StudentAttributes newStudent \u003d logic.createStudent(studentAttributes);"},{"lineNumber":203,"author":{"gitId":"-"},"content":" taskQueuer.scheduleStudentForSearchIndexing(newStudent.getCourse(), newStudent.getEmail());"},{"lineNumber":204,"author":{"gitId":"-"},"content":" enrolledStudents.add(newStudent);"},{"lineNumber":205,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException | EntityAlreadyExistsException exception) {"},{"lineNumber":206,"author":{"gitId":"-"},"content":" // Unsuccessfully enrolled students will not be returned."},{"lineNumber":207,"author":{"gitId":"-"},"content":" failToEnrollStudents.add(new EnrollStudentsData.EnrollErrorResults(student.getEmail(),"},{"lineNumber":208,"author":{"gitId":"-"},"content":" exception.getMessage()));"},{"lineNumber":209,"author":{"gitId":"-"},"content":" }"},{"lineNumber":210,"author":{"gitId":"-"},"content":" }"},{"lineNumber":211,"author":{"gitId":"-"},"content":" }"},{"lineNumber":212,"author":{"gitId":"-"},"content":""},{"lineNumber":213,"author":{"gitId":"-"},"content":" List\u003cStudentData\u003e studentDataList \u003d enrolledStudents"},{"lineNumber":214,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":215,"author":{"gitId":"-"},"content":" .map(StudentData::new)"},{"lineNumber":216,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":217,"author":{"gitId":"-"},"content":" StudentsData data \u003d new StudentsData();"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":" data.setStudents(studentDataList);"},{"lineNumber":220,"author":{"gitId":"-"},"content":""},{"lineNumber":221,"author":{"gitId":"-"},"content":" return new JsonResult(new EnrollStudentsData(data, failToEnrollStudents));"},{"lineNumber":222,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":223,"author":{"gitId":"-"},"content":" }"},{"lineNumber":224,"author":{"gitId":"-"},"content":" }"},{"lineNumber":225,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":108,"marquestye":1,"-":116}},{"path":"src/main/java/teammates/ui/webapi/GetCourseJoinStatusAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountRequestAttributes;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.ui.output.JoinStatus;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * Get the join status of a course."},{"lineNumber":14,"author":{"gitId":"-"},"content":" */"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"public class GetCourseJoinStatusAction extends Action {"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":18,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" }"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":23,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" // Any user can use a join link as long as its parameters are valid"},{"lineNumber":25,"author":{"gitId":"-"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"-"},"content":" public JsonResult execute() {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" String regkey \u003d getNonNullRequestParamValue(Const.ParamsNames.REGKEY);"},{"lineNumber":30,"author":{"gitId":"-"},"content":" String entityType \u003d getNonNullRequestParamValue(Const.ParamsNames.ENTITY_TYPE);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" String isCreatingAccount \u003d getRequestParamValue(Const.ParamsNames.IS_CREATING_ACCOUNT);"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" switch (entityType) {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" case Const.EntityType.STUDENT:"},{"lineNumber":35,"author":{"gitId":"-"},"content":" return getStudentJoinStatus(regkey);"},{"lineNumber":36,"author":{"gitId":"-"},"content":" case Const.EntityType.INSTRUCTOR:"},{"lineNumber":37,"author":{"gitId":"-"},"content":" return getInstructorJoinStatus(regkey, \"true\".equals(isCreatingAccount));"},{"lineNumber":38,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":39,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Error: invalid entity type\");"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":" }"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" private JsonResult getStudentJoinStatus(String regkey) {"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" StudentAttributes studentAttributes \u003d logic.getStudentForRegistrationKey(regkey);"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" if (studentAttributes !\u003d null \u0026\u0026 !isCourseMigrated(studentAttributes.getCourse())) {"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" return getJoinStatusResult(studentAttributes.isRegistered());"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" Student student \u003d sqlLogic.getStudentByRegistrationKey(regkey);"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(\"No student with given registration key: \" + regkey);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":" return getJoinStatusResult(student.isRegistered());"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" private JsonResult getInstructorJoinStatus(String regkey, boolean isCreatingAccount) {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" if (isCreatingAccount) {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" AccountRequestAttributes accountRequest \u003d logic.getAccountRequestForRegistrationKey(regkey);"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" AccountRequest sqlAccountRequest \u003d sqlLogic.getAccountRequestByRegistrationKey(regkey);"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" if (accountRequest \u003d\u003d null \u0026\u0026 sqlAccountRequest \u003d\u003d null) {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(\"No account request with given registration key: \" + regkey);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" if (sqlAccountRequest !\u003d null) {"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" return getJoinStatusResult(sqlAccountRequest.getRegisteredAt() !\u003d null);"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" if (accountRequest !\u003d null) {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" return getJoinStatusResult(accountRequest.getRegisteredAt() !\u003d null);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":" }"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" InstructorAttributes instructorAttributes \u003d logic.getInstructorForRegistrationKey(regkey);"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" if (instructorAttributes !\u003d null \u0026\u0026 !isCourseMigrated(instructorAttributes.getCourseId())) {"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" return getJoinStatusResult(instructorAttributes.isRegistered());"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" Instructor instructor \u003d sqlLogic.getInstructorByRegistrationKey(regkey);"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" if (instructor \u003d\u003d null) {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(\"No instructor with given registration key: \" + regkey);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":" return getJoinStatusResult(instructor.isRegistered());"},{"lineNumber":86,"author":{"gitId":"-"},"content":" }"},{"lineNumber":87,"author":{"gitId":"-"},"content":" }"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" private JsonResult getJoinStatusResult(boolean hasJoined) {"},{"lineNumber":90,"author":{"gitId":"-"},"content":" JoinStatus result \u003d new JoinStatus(hasJoined);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" return new JsonResult(result);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":24,"-":69}},{"path":"src/main/java/teammates/ui/webapi/GetFeedbackSessionLogsAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.LinkedHashMap;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionLogsData;"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":28,"author":{"gitId":"-"},"content":" * Action: gets the feedback session logs of feedback sessions of a course."},{"lineNumber":29,"author":{"gitId":"-"},"content":" */"},{"lineNumber":30,"author":{"gitId":"-"},"content":"public class GetFeedbackSessionLogsAction extends Action {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":32,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":37,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" if (!userInfo.isInstructor) {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Instructor privilege is required to access this resource.\");"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" Course course \u003d sqlLogic.getCourse(courseId);"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" if (course \u003d\u003d null) {"},{"lineNumber":48,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(\"Course is not found\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" Instructor instructor \u003d sqlLogic.getInstructorByGoogleId(courseId, userInfo.getId());"},{"lineNumber":52,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, course, Const.InstructorPermissions.CAN_MODIFY_STUDENT);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, course, Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, course, Const.InstructorPermissions.CAN_MODIFY_INSTRUCTOR);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" CourseAttributes courseAttributes \u003d logic.getCourse(courseId);"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" if (courseAttributes \u003d\u003d null) {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(\"Course is not found\");"},{"lineNumber":60,"author":{"gitId":"-"},"content":" }"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d logic.getInstructorForGoogleId(courseId, userInfo.getId());"},{"lineNumber":63,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, courseAttributes, Const.InstructorPermissions.CAN_MODIFY_STUDENT);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, courseAttributes, Const.InstructorPermissions.CAN_MODIFY_SESSION);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, courseAttributes, Const.InstructorPermissions.CAN_MODIFY_INSTRUCTOR);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":70,"author":{"gitId":"-"},"content":" public JsonResult execute() {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" String fslTypes \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogType\u003e convertedFslTypes \u003d new ArrayList\u003c\u003e();"},{"lineNumber":73,"author":{"gitId":"-"},"content":" if (fslTypes !\u003d null) {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" // Multiple log types are separated by a comma e.g access,submission"},{"lineNumber":75,"author":{"gitId":"-"},"content":" for (String fslType : fslTypes.split(\",\")) {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" FeedbackSessionLogType convertedFslType \u003d FeedbackSessionLogType.valueOfLabel(fslType);"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" if (convertedFslType \u003d\u003d null) {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Invalid log type\");"},{"lineNumber":80,"author":{"gitId":"-"},"content":" }"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" convertedFslTypes.add(convertedFslType);"},{"lineNumber":83,"author":{"gitId":"-"},"content":" }"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" String startTimeStr \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" String endTimeStr \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" long startTime;"},{"lineNumber":89,"author":{"gitId":"-"},"content":" long endTime;"},{"lineNumber":90,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" startTime \u003d Long.parseLong(startTimeStr);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" endTime \u003d Long.parseLong(endTimeStr);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" } catch (NumberFormatException e) {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Invalid start or end time\", e);"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":" // TODO: we might want to impose limits on the time range from startTime to endTime"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" if (endTime \u003c startTime) {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"The end time should be after the start time.\");"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" if (!isCourseMigrated(courseId)) {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" long earliestSearchTime \u003d TimeHelper.getInstantDaysOffsetBeforeNow(Const.LOGS_RETENTION_PERIOD.toDays())"},{"lineNumber":106,"author":{"gitId":"-"},"content":" .toEpochMilli();"},{"lineNumber":107,"author":{"gitId":"-"},"content":" if (startTime \u003c earliestSearchTime) {"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" throw new InvalidHttpParameterException(\"The earliest date you can search for is \""},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":" + Const.LOGS_RETENTION_PERIOD.toDays() + \" days before today.\");"},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":" UUID studentId \u003d null;"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" UUID feedbackSessionId \u003d null;"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" String studentIdString \u003d getRequestParamValue(Const.ParamsNames.STUDENT_SQL_ID);"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" String feedbackSessionIdString \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_ID);"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" if (studentIdString !\u003d null) {"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" studentId \u003d getUuidFromString(Const.ParamsNames.STUDENT_SQL_ID, studentIdString);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" }"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" if (feedbackSessionIdString !\u003d null) {"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" feedbackSessionId \u003d getUuidFromString(Const.ParamsNames.FEEDBACK_SESSION_ID, feedbackSessionIdString);"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" if (sqlLogic.getCourse(courseId) \u003d\u003d null) {"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":" throw new EntityNotFoundException(\"Course not found\");"},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" if (studentId !\u003d null \u0026\u0026 sqlLogic.getStudent(studentId) \u003d\u003d null) {"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" throw new EntityNotFoundException(\"Student not found\");"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":" if (feedbackSessionId !\u003d null \u0026\u0026 sqlLogic.getFeedbackSession(feedbackSessionId) \u003d\u003d null) {"},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" throw new EntityNotFoundException(\"Feedback session not found\");"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e fsLogEntries \u003d sqlLogic.getOrderedFeedbackSessionLogs(courseId, studentId,"},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":" feedbackSessionId, Instant.ofEpochMilli(startTime), Instant.ofEpochMilli(endTime));"},{"lineNumber":141,"author":{"gitId":"-"},"content":" Map\u003cString, Student\u003e studentsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":142,"author":{"gitId":"-"},"content":" Map\u003cString, FeedbackSession\u003e sessionsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":143,"author":{"gitId":"-"},"content":" List\u003cFeedbackSession\u003e feedbackSessions \u003d sqlLogic.getFeedbackSessionsForCourse(courseId);"},{"lineNumber":144,"author":{"gitId":"-"},"content":" feedbackSessions.forEach(fs -\u003e sessionsMap.put(fs.getName(), fs));"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" fsLogEntries \u003d fsLogEntries.stream().filter(logEntry -\u003e {"},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType logType \u003d logEntry.getFeedbackSessionLogType();"},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":" if (logType \u003d\u003d null || fslTypes !\u003d null \u0026\u0026 !convertedFslTypes.contains(logType)) {"},{"lineNumber":149,"author":{"gitId":"-"},"content":" // If the feedback session log type retrieved from the log is invalid"},{"lineNumber":150,"author":{"gitId":"-"},"content":" // or not the type being queried, ignore the log"},{"lineNumber":151,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":152,"author":{"gitId":"-"},"content":" }"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":" if (!studentsMap.containsKey(logEntry.getStudent().getEmail())) {"},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":" Student student \u003d sqlLogic.getStudent(logEntry.getStudent().getId());"},{"lineNumber":156,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" // If the student email retrieved from the log is invalid, ignore the log"},{"lineNumber":158,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":" studentsMap.put(student.getEmail(), student);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":" // If the feedback session retrieved from the log is invalid, ignore the log"},{"lineNumber":163,"author":{"gitId":"dishenggg"},"content":" return sessionsMap.containsKey(logEntry.getFeedbackSession().getName());"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }).collect(Collectors.toList());"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":" Map\u003cString, List\u003cFeedbackSessionLog\u003e\u003e groupedEntries \u003d groupFeedbackSessionLogs(fsLogEntries);"},{"lineNumber":167,"author":{"gitId":"-"},"content":" feedbackSessions.forEach(fs -\u003e groupedEntries.putIfAbsent(fs.getName(), new ArrayList\u003c\u003e()));"},{"lineNumber":168,"author":{"gitId":"-"},"content":""},{"lineNumber":169,"author":{"gitId":"-"},"content":" FeedbackSessionLogsData fslData \u003d new FeedbackSessionLogsData(groupedEntries, studentsMap, sessionsMap);"},{"lineNumber":170,"author":{"gitId":"-"},"content":" return new JsonResult(fslData);"},{"lineNumber":171,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":" if (logic.getCourse(courseId) \u003d\u003d null) {"},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":" throw new EntityNotFoundException(\"Course not found\");"},{"lineNumber":174,"author":{"gitId":"-"},"content":" }"},{"lineNumber":175,"author":{"gitId":"-"},"content":""},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":" String email \u003d getRequestParamValue(Const.ParamsNames.STUDENT_EMAIL);"},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":" if (email !\u003d null \u0026\u0026 logic.getStudentForEmail(courseId, email) \u003d\u003d null) {"},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":" throw new EntityNotFoundException(\"Student not found\");"},{"lineNumber":179,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":180,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":181,"author":{"gitId":"dishenggg"},"content":" String feedbackSessionName \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME);"},{"lineNumber":182,"author":{"gitId":"dishenggg"},"content":" if (feedbackSessionName !\u003d null \u0026\u0026 logic.getFeedbackSession(feedbackSessionName, courseId) \u003d\u003d null) {"},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":" throw new EntityNotFoundException(\"Feedback session not found\");"},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":185,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":186,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntry\u003e fsLogEntries \u003d"},{"lineNumber":187,"author":{"gitId":"dishenggg"},"content":" logsProcessor.getOrderedFeedbackSessionLogs(courseId, email, startTime, endTime, feedbackSessionName);"},{"lineNumber":188,"author":{"gitId":"-"},"content":" Map\u003cString, StudentAttributes\u003e studentsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":189,"author":{"gitId":"-"},"content":" Map\u003cString, FeedbackSessionAttributes\u003e sessionsMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":190,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionAttributes\u003e feedbackSessions \u003d logic.getFeedbackSessionsForCourse(courseId);"},{"lineNumber":191,"author":{"gitId":"-"},"content":" feedbackSessions.forEach(fs -\u003e sessionsMap.put(fs.getFeedbackSessionName(), fs));"},{"lineNumber":192,"author":{"gitId":"-"},"content":""},{"lineNumber":193,"author":{"gitId":"-"},"content":" fsLogEntries \u003d fsLogEntries.stream().filter(logEntry -\u003e {"},{"lineNumber":194,"author":{"gitId":"-"},"content":" String logType \u003d logEntry.getFeedbackSessionLogType();"},{"lineNumber":195,"author":{"gitId":"-"},"content":" FeedbackSessionLogType convertedLogType \u003d FeedbackSessionLogType.valueOfLabel(logType);"},{"lineNumber":196,"author":{"gitId":"-"},"content":" if (convertedLogType \u003d\u003d null || fslTypes !\u003d null \u0026\u0026 !convertedFslTypes.contains(convertedLogType)) {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" // If the feedback session log type retrieved from the log is invalid"},{"lineNumber":198,"author":{"gitId":"-"},"content":" // or not the type being queried, ignore the log"},{"lineNumber":199,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }"},{"lineNumber":201,"author":{"gitId":"-"},"content":""},{"lineNumber":202,"author":{"gitId":"-"},"content":" if (!studentsMap.containsKey(logEntry.getStudentEmail())) {"},{"lineNumber":203,"author":{"gitId":"-"},"content":" StudentAttributes student \u003d logic.getStudentForEmail(courseId, logEntry.getStudentEmail());"},{"lineNumber":204,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" // If the student email retrieved from the log is invalid, ignore the log"},{"lineNumber":206,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":207,"author":{"gitId":"-"},"content":" }"},{"lineNumber":208,"author":{"gitId":"-"},"content":" studentsMap.put(logEntry.getStudentEmail(), student);"},{"lineNumber":209,"author":{"gitId":"-"},"content":" }"},{"lineNumber":210,"author":{"gitId":"-"},"content":" // If the feedback session retrieved from the log is invalid, ignore the log"},{"lineNumber":211,"author":{"gitId":"-"},"content":" return sessionsMap.containsKey(logEntry.getFeedbackSessionName());"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }).collect(Collectors.toList());"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" Map\u003cString, List\u003cFeedbackSessionLogEntry\u003e\u003e groupedEntries \u003d"},{"lineNumber":215,"author":{"gitId":"-"},"content":" groupFeedbackSessionLogEntries(fsLogEntries);"},{"lineNumber":216,"author":{"gitId":"-"},"content":" feedbackSessions.forEach(fs -\u003e groupedEntries.putIfAbsent(fs.getFeedbackSessionName(), new ArrayList\u003c\u003e()));"},{"lineNumber":217,"author":{"gitId":"-"},"content":""},{"lineNumber":218,"author":{"gitId":"-"},"content":" FeedbackSessionLogsData fslData \u003d new FeedbackSessionLogsData(groupedEntries, studentsMap, sessionsMap);"},{"lineNumber":219,"author":{"gitId":"-"},"content":" return new JsonResult(fslData);"},{"lineNumber":220,"author":{"gitId":"-"},"content":" }"},{"lineNumber":221,"author":{"gitId":"-"},"content":" }"},{"lineNumber":222,"author":{"gitId":"-"},"content":""},{"lineNumber":223,"author":{"gitId":"-"},"content":" private Map\u003cString, List\u003cFeedbackSessionLogEntry\u003e\u003e groupFeedbackSessionLogEntries("},{"lineNumber":224,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogEntry\u003e fsLogEntries) {"},{"lineNumber":225,"author":{"gitId":"-"},"content":" Map\u003cString, List\u003cFeedbackSessionLogEntry\u003e\u003e groupedEntries \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":226,"author":{"gitId":"-"},"content":" for (FeedbackSessionLogEntry fsLogEntry : fsLogEntries) {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" String fsName \u003d fsLogEntry.getFeedbackSessionName();"},{"lineNumber":228,"author":{"gitId":"-"},"content":" groupedEntries.computeIfAbsent(fsName, k -\u003e new ArrayList\u003c\u003e()).add(fsLogEntry);"},{"lineNumber":229,"author":{"gitId":"-"},"content":" }"},{"lineNumber":230,"author":{"gitId":"-"},"content":" return groupedEntries;"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":233,"author":{"gitId":"dishenggg"},"content":" private Map\u003cString, List\u003cFeedbackSessionLog\u003e\u003e groupFeedbackSessionLogs("},{"lineNumber":234,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e fsLogEntries) {"},{"lineNumber":235,"author":{"gitId":"dishenggg"},"content":" Map\u003cString, List\u003cFeedbackSessionLog\u003e\u003e groupedEntries \u003d new LinkedHashMap\u003c\u003e();"},{"lineNumber":236,"author":{"gitId":"dishenggg"},"content":" for (FeedbackSessionLog fsLogEntry : fsLogEntries) {"},{"lineNumber":237,"author":{"gitId":"dishenggg"},"content":" String fsName \u003d fsLogEntry.getFeedbackSession().getName();"},{"lineNumber":238,"author":{"gitId":"dishenggg"},"content":" groupedEntries.computeIfAbsent(fsName, k -\u003e new ArrayList\u003c\u003e()).add(fsLogEntry);"},{"lineNumber":239,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":240,"author":{"gitId":"dishenggg"},"content":" return groupedEntries;"},{"lineNumber":241,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":242,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":65,"-":177}},{"path":"src/main/java/teammates/ui/webapi/GetSessionResponseStatsAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionStatsData;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * Action: gets the response stats (submitted / total) of a feedback session."},{"lineNumber":12,"author":{"gitId":"-"},"content":" */"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"public class GetSessionResponseStatsAction extends Action {"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":16,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":17,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":18,"author":{"gitId":"-"},"content":" }"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":21,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" if (userInfo.isAdmin) {"},{"lineNumber":23,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" }"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":27,"author":{"gitId":"-"},"content":" String feedbackSessionName \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME);"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" FeedbackSession fs \u003d getNonNullSqlFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" Instructor instructor \u003d sqlLogic.getInstructorByGoogleId(courseId, userInfo.getId());"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" gateKeeper.verifyAccessible(instructor, fs);"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" } else {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes fsa \u003d getNonNullFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":34,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d logic.getInstructorForGoogleId(courseId, userInfo.getId());"},{"lineNumber":35,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible(instructor, fsa);"},{"lineNumber":36,"author":{"gitId":"-"},"content":" }"},{"lineNumber":37,"author":{"gitId":"-"},"content":" }"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":40,"author":{"gitId":"-"},"content":" public JsonResult execute() {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":42,"author":{"gitId":"-"},"content":" String feedbackSessionName \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME);"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" FeedbackSession fsa \u003d getNonNullSqlFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" int expectedTotal \u003d sqlLogic.getExpectedTotalSubmission(fsa);"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" int actualTotal \u003d sqlLogic.getActualTotalSubmission(fsa);"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" FeedbackSessionStatsData output \u003d new FeedbackSessionStatsData(actualTotal, expectedTotal);"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" return new JsonResult(output);"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" } else {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes fsa \u003d getNonNullFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" int expectedTotal \u003d logic.getExpectedTotalSubmission(fsa);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" int actualTotal \u003d logic.getActualTotalSubmission(fsa);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" FeedbackSessionStatsData output \u003d new FeedbackSessionStatsData(actualTotal, expectedTotal);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" return new JsonResult(output);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":15,"-":44}},{"path":"src/main/java/teammates/ui/webapi/GetSessionResultsAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackResultFetchType;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SessionResultsBundle;"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.SqlSessionResultsBundle;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.StringHelper;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":16,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.ui.output.SessionResultsData;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.ui.request.Intent;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":21,"author":{"gitId":"-"},"content":" * Gets feedback session results including statistics where necessary."},{"lineNumber":22,"author":{"gitId":"-"},"content":" */"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":"public class GetSessionResultsAction extends BasicFeedbackSubmissionAction {"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":26,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" return AuthType.PUBLIC;"},{"lineNumber":28,"author":{"gitId":"-"},"content":" }"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":31,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":33,"author":{"gitId":"-"},"content":" String feedbackSessionName \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME);"},{"lineNumber":34,"author":{"gitId":"-"},"content":" Intent intent \u003d Intent.valueOf(getNonNullRequestParamValue(Const.ParamsNames.INTENT));"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" boolean isPreviewResults \u003d !StringHelper.isEmpty(previewAsPerson);"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" checkSpecificAccessControlSql(courseId, feedbackSessionName, intent, isPreviewResults);"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" checkSpecificAccessControlDatastore(courseId, feedbackSessionName, intent, isPreviewResults);"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" private void checkSpecificAccessControlDatastore("},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" String courseId, String feedbackSessionName, Intent intent, boolean isPreviewResults)"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" throws UnauthorizedAccessException {"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" FeedbackSessionAttributes feedbackSession \u003d getNonNullFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" switch (intent) {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" case FULL_DETAIL:"},{"lineNumber":52,"author":{"gitId":"-"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d logic.getInstructorForGoogleId(courseId, userInfo.getId());"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" gateKeeper.verifyAccessible(instructor, feedbackSession);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":56,"author":{"gitId":"-"},"content":" case INSTRUCTOR_RESULT:"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" if (!isPreviewResults \u0026\u0026 !feedbackSession.isPublished()) {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"This feedback session is not yet published.\", true);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" }"},{"lineNumber":60,"author":{"gitId":"-"},"content":" instructor \u003d getInstructorOfCourseFromRequest(courseId);"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" checkAccessControlForInstructorFeedbackResult(instructor, feedbackSession);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" case STUDENT_RESULT:"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" if (!isPreviewResults \u0026\u0026 !feedbackSession.isPublished()) {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"This feedback session is not yet published.\", true);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":" StudentAttributes student \u003d getStudentOfCourseFromRequest(courseId);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" checkAccessControlForStudentFeedbackResult(student, feedbackSession);"},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":" case INSTRUCTOR_SUBMISSION:"},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" case STUDENT_SUBMISSION:"},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" throw new InvalidHttpParameterException(\"Invalid intent for this action\");"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":" default:"},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" throw new InvalidHttpParameterException(\"Unknown intent \" + intent);"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" private void checkSpecificAccessControlSql("},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":" String courseId, String feedbackSessionName, Intent intent, boolean isPreviewResults)"},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" throws UnauthorizedAccessException {"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession \u003d getNonNullSqlFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" switch (intent) {"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":" case FULL_DETAIL:"},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":" gateKeeper.verifyLoggedInUserPrivileges(userInfo);"},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":" Instructor instructor \u003d sqlLogic.getInstructorByGoogleId(courseId, userInfo.getId());"},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":" gateKeeper.verifyAccessible(instructor, feedbackSession);"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":" case INSTRUCTOR_RESULT:"},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" if (!isPreviewResults \u0026\u0026 !feedbackSession.isPublished()) {"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":" throw new UnauthorizedAccessException(\"This feedback session is not yet published.\", true);"},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":" instructor \u003d getSqlInstructorOfCourseFromRequest(courseId);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" checkAccessControlForInstructorFeedbackResult(instructor, feedbackSession);"},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":" break;"},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":" case STUDENT_RESULT:"},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" if (!isPreviewResults \u0026\u0026 !feedbackSession.isPublished()) {"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" throw new UnauthorizedAccessException(\"This feedback session is not yet published.\", true);"},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":" Student student \u003d getSqlStudentOfCourseFromRequest(courseId);"},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":" checkAccessControlForStudentFeedbackResult(student, feedbackSession);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":103,"author":{"gitId":"-"},"content":" case INSTRUCTOR_SUBMISSION:"},{"lineNumber":104,"author":{"gitId":"-"},"content":" case STUDENT_SUBMISSION:"},{"lineNumber":105,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Invalid intent for this action\");"},{"lineNumber":106,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":107,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Unknown intent \" + intent);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":" }"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":112,"author":{"gitId":"-"},"content":" public JsonResult execute() {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" String feedbackSessionName \u003d getNonNullRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME);"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" // Allow additional filter by question ID and section name"},{"lineNumber":117,"author":{"gitId":"-"},"content":" String questionId \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_QUESTION_ID);"},{"lineNumber":118,"author":{"gitId":"-"},"content":" String selectedSection \u003d getRequestParamValue(Const.ParamsNames.FEEDBACK_RESULTS_GROUPBYSECTION);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" FeedbackResultFetchType fetchType \u003d FeedbackResultFetchType.parseFetchType("},{"lineNumber":120,"author":{"gitId":"-"},"content":" getRequestParamValue(Const.ParamsNames.FEEDBACK_RESULTS_SECTION_BY_GIVER_RECEIVER));"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" String previewAsPerson \u003d getRequestParamValue(Const.ParamsNames.PREVIEWAS);"},{"lineNumber":123,"author":{"gitId":"-"},"content":" boolean isPreviewResults \u003d !StringHelper.isEmpty(previewAsPerson);"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"xenosf"},"content":" Intent intent \u003d Intent.valueOf(getNonNullRequestParamValue(Const.ParamsNames.INTENT));"},{"lineNumber":126,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":127,"author":{"gitId":"xenosf"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":128,"author":{"gitId":"xenosf"},"content":" if (questionId !\u003d null) {"},{"lineNumber":129,"author":{"gitId":"xenosf"},"content":" UUID questionUuid \u003d getUuidRequestParamValue(Const.ParamsNames.FEEDBACK_QUESTION_ID);"},{"lineNumber":130,"author":{"gitId":"mingyuanc"},"content":" return executeWithSql(courseId, feedbackSessionName, questionUuid,"},{"lineNumber":131,"author":{"gitId":"xenosf"},"content":" selectedSection, fetchType, intent, isPreviewResults);"},{"lineNumber":132,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":133,"author":{"gitId":"xenosf"},"content":" return executeWithSql(courseId, feedbackSessionName, null, selectedSection,"},{"lineNumber":134,"author":{"gitId":"xenosf"},"content":" fetchType, intent, isPreviewResults);"},{"lineNumber":135,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":136,"author":{"gitId":"xenosf"},"content":" return executeWithDatastore(courseId, feedbackSessionName, questionId, selectedSection,"},{"lineNumber":137,"author":{"gitId":"xenosf"},"content":" fetchType, intent, isPreviewResults);"},{"lineNumber":138,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":139,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":140,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":141,"author":{"gitId":"xenosf"},"content":" private JsonResult executeWithDatastore("},{"lineNumber":142,"author":{"gitId":"xenosf"},"content":" String courseId, String feedbackSessionName, String questionId, String selectedSection,"},{"lineNumber":143,"author":{"gitId":"xenosf"},"content":" FeedbackResultFetchType fetchType, Intent intent, boolean isPreviewResults) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" InstructorAttributes instructor;"},{"lineNumber":145,"author":{"gitId":"-"},"content":" StudentAttributes student;"},{"lineNumber":146,"author":{"gitId":"xenosf"},"content":" SessionResultsBundle bundle;"},{"lineNumber":147,"author":{"gitId":"-"},"content":" switch (intent) {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" case FULL_DETAIL:"},{"lineNumber":149,"author":{"gitId":"-"},"content":" instructor \u003d logic.getInstructorForGoogleId(courseId, userInfo.id);"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" bundle \u003d logic.getSessionResultsForCourse(feedbackSessionName, courseId, instructor.getEmail(),"},{"lineNumber":152,"author":{"gitId":"-"},"content":" questionId, selectedSection, fetchType);"},{"lineNumber":153,"author":{"gitId":"-"},"content":" return new JsonResult(SessionResultsData.initForInstructor(bundle));"},{"lineNumber":154,"author":{"gitId":"-"},"content":" case INSTRUCTOR_RESULT:"},{"lineNumber":155,"author":{"gitId":"-"},"content":" // Section name filter is not applicable here"},{"lineNumber":156,"author":{"gitId":"-"},"content":" instructor \u003d getInstructorOfCourseFromRequest(courseId);"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"-"},"content":" bundle \u003d logic.getSessionResultsForUser(feedbackSessionName, courseId, instructor.getEmail(),"},{"lineNumber":159,"author":{"gitId":"-"},"content":" true, questionId, isPreviewResults);"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" // Build a fake student object, as the results will be displayed as if they are displayed to a student"},{"lineNumber":162,"author":{"gitId":"-"},"content":" student \u003d StudentAttributes.builder(instructor.getCourseId(), instructor.getEmail())"},{"lineNumber":163,"author":{"gitId":"-"},"content":" .withTeamName(Const.USER_TEAM_FOR_INSTRUCTOR)"},{"lineNumber":164,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" return new JsonResult(SessionResultsData.initForStudent(bundle, student));"},{"lineNumber":167,"author":{"gitId":"-"},"content":" case STUDENT_RESULT:"},{"lineNumber":168,"author":{"gitId":"-"},"content":" // Section name filter is not applicable here"},{"lineNumber":169,"author":{"gitId":"-"},"content":" student \u003d getStudentOfCourseFromRequest(courseId);"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" bundle \u003d logic.getSessionResultsForUser(feedbackSessionName, courseId, student.getEmail(),"},{"lineNumber":172,"author":{"gitId":"-"},"content":" false, questionId, isPreviewResults);"},{"lineNumber":173,"author":{"gitId":"-"},"content":""},{"lineNumber":174,"author":{"gitId":"-"},"content":" return new JsonResult(SessionResultsData.initForStudent(bundle, student));"},{"lineNumber":175,"author":{"gitId":"-"},"content":" case INSTRUCTOR_SUBMISSION:"},{"lineNumber":176,"author":{"gitId":"-"},"content":" case STUDENT_SUBMISSION:"},{"lineNumber":177,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Invalid intent for this action\");"},{"lineNumber":178,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":179,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Unknown intent \" + intent);"},{"lineNumber":180,"author":{"gitId":"-"},"content":" }"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"xenosf"},"content":" private JsonResult executeWithSql("},{"lineNumber":184,"author":{"gitId":"xenosf"},"content":" String courseId, String feedbackSessionName, UUID questionUuid, String selectedSection,"},{"lineNumber":185,"author":{"gitId":"xenosf"},"content":" FeedbackResultFetchType fetchType, Intent intent, boolean isPreviewResults) {"},{"lineNumber":186,"author":{"gitId":"xenosf"},"content":" Instructor instructor;"},{"lineNumber":187,"author":{"gitId":"xenosf"},"content":" Student student;"},{"lineNumber":188,"author":{"gitId":"xenosf"},"content":" FeedbackSession feedbackSession \u003d getNonNullSqlFeedbackSession(feedbackSessionName, courseId);"},{"lineNumber":189,"author":{"gitId":"xenosf"},"content":" SqlSessionResultsBundle bundle;"},{"lineNumber":190,"author":{"gitId":"xenosf"},"content":" switch (intent) {"},{"lineNumber":191,"author":{"gitId":"xenosf"},"content":" case FULL_DETAIL:"},{"lineNumber":192,"author":{"gitId":"xenosf"},"content":" instructor \u003d getSqlInstructorOfCourseFromRequest(courseId);"},{"lineNumber":193,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":194,"author":{"gitId":"xenosf"},"content":" bundle \u003d sqlLogic.getSessionResultsForCourse(feedbackSession, courseId, instructor.getEmail(),"},{"lineNumber":195,"author":{"gitId":"xenosf"},"content":" questionUuid, selectedSection, fetchType);"},{"lineNumber":196,"author":{"gitId":"xenosf"},"content":" return new JsonResult(SessionResultsData.initForInstructor(bundle));"},{"lineNumber":197,"author":{"gitId":"xenosf"},"content":" case INSTRUCTOR_RESULT:"},{"lineNumber":198,"author":{"gitId":"xenosf"},"content":" // Section name filter is not applicable here"},{"lineNumber":199,"author":{"gitId":"mingyuanc"},"content":" instructor \u003d getSqlInstructorOfCourseFromRequest(courseId);"},{"lineNumber":200,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":201,"author":{"gitId":"xenosf"},"content":" bundle \u003d sqlLogic.getSessionResultsForUser(feedbackSession, courseId, instructor.getEmail(),"},{"lineNumber":202,"author":{"gitId":"xenosf"},"content":" true, questionUuid, isPreviewResults);"},{"lineNumber":203,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":204,"author":{"gitId":"xenosf"},"content":" // Build a fake student object, as the results will be displayed as if they are displayed to a student"},{"lineNumber":205,"author":{"gitId":"xenosf"},"content":" student \u003d new Student(instructor.getCourse(), instructor.getName(), instructor.getEmail(), \"\");"},{"lineNumber":206,"author":{"gitId":"mingyuanc"},"content":" student.setTeam(new Team(null, Const.USER_TEAM_FOR_INSTRUCTOR));"},{"lineNumber":207,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":208,"author":{"gitId":"xenosf"},"content":" return new JsonResult(SessionResultsData.initForStudent(bundle, student));"},{"lineNumber":209,"author":{"gitId":"xenosf"},"content":" case STUDENT_RESULT:"},{"lineNumber":210,"author":{"gitId":"xenosf"},"content":" // Section name filter is not applicable here"},{"lineNumber":211,"author":{"gitId":"xenosf"},"content":" student \u003d getSqlStudentOfCourseFromRequest(courseId);"},{"lineNumber":212,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":213,"author":{"gitId":"xenosf"},"content":" bundle \u003d sqlLogic.getSessionResultsForUser(feedbackSession, courseId, student.getEmail(),"},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" false, questionUuid, isPreviewResults);"},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" return new JsonResult(SessionResultsData.initForStudent(bundle, student));"},{"lineNumber":217,"author":{"gitId":"xenosf"},"content":" case INSTRUCTOR_SUBMISSION:"},{"lineNumber":218,"author":{"gitId":"xenosf"},"content":" case STUDENT_SUBMISSION:"},{"lineNumber":219,"author":{"gitId":"xenosf"},"content":" throw new InvalidHttpParameterException(\"Invalid intent for this action\");"},{"lineNumber":220,"author":{"gitId":"xenosf"},"content":" default:"},{"lineNumber":221,"author":{"gitId":"xenosf"},"content":" throw new InvalidHttpParameterException(\"Unknown intent \" + intent);"},{"lineNumber":222,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":223,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":224,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":114,"mingyuanc":4,"-":107}},{"path":"src/main/java/teammates/ui/webapi/InstructorSearchIndexingWorkerAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.ParamsNames;"},{"lineNumber":8,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * Task queue worker action: performs instructor search indexing."},{"lineNumber":12,"author":{"gitId":"-"},"content":" */"},{"lineNumber":13,"author":{"gitId":"-"},"content":"public class InstructorSearchIndexingWorkerAction extends AdminOnlyAction {"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":16,"author":{"gitId":"-"},"content":" public ActionResult execute() {"},{"lineNumber":17,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(ParamsNames.COURSE_ID);"},{"lineNumber":18,"author":{"gitId":"-"},"content":" String email \u003d getNonNullRequestParamValue(ParamsNames.INSTRUCTOR_EMAIL);"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"mingyuanc"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":21,"author":{"gitId":"mingyuanc"},"content":" return executeWithSql(courseId, email);"},{"lineNumber":22,"author":{"gitId":"mingyuanc"},"content":" } else {"},{"lineNumber":23,"author":{"gitId":"mingyuanc"},"content":" return executeWithDataStore(courseId, email);"},{"lineNumber":24,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":25,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":26,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":27,"author":{"gitId":"mingyuanc"},"content":" private JsonResult executeWithSql(String courseId, String email) {"},{"lineNumber":28,"author":{"gitId":"mingyuanc"},"content":" Instructor instructor \u003d sqlLogic.getInstructorForEmail(courseId, email);"},{"lineNumber":29,"author":{"gitId":"mingyuanc"},"content":" try {"},{"lineNumber":30,"author":{"gitId":"mingyuanc"},"content":" sqlLogic.putInstructorDocument(instructor);"},{"lineNumber":31,"author":{"gitId":"mingyuanc"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":32,"author":{"gitId":"mingyuanc"},"content":" // Set an arbitrary retry code outside the range 200-299 to trigger automatic retry"},{"lineNumber":33,"author":{"gitId":"mingyuanc"},"content":" return new JsonResult(\"Failure\", HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":34,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":35,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":36,"author":{"gitId":"mingyuanc"},"content":" return new JsonResult(\"Successful\");"},{"lineNumber":37,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":38,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":39,"author":{"gitId":"mingyuanc"},"content":" private JsonResult executeWithDataStore(String courseId, String email) {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d logic.getInstructorForEmail(courseId, email);"},{"lineNumber":41,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" logic.putInstructorDocument(instructor);"},{"lineNumber":43,"author":{"gitId":"-"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" // Set an arbitrary retry code outside of the range 200-299 to trigger automatic retry"},{"lineNumber":45,"author":{"gitId":"-"},"content":" return new JsonResult(\"Failure\", HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" return new JsonResult(\"Successful\");"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"mingyuanc":21,"-":29}},{"path":"src/main/java/teammates/ui/webapi/JoinCourseAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"yuanxi1"},"content":"import java.util.Optional;"},{"lineNumber":4,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":16,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":17,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":18,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":21,"author":{"gitId":"-"},"content":" * Action: joins a course for a student/instructor."},{"lineNumber":22,"author":{"gitId":"-"},"content":" */"},{"lineNumber":23,"author":{"gitId":"yuanxi1"},"content":"public class JoinCourseAction extends Action {"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":33,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" // Any user can use a join link as long as its parameters are valid"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":38,"author":{"gitId":"-"},"content":" public JsonResult execute() throws InvalidOperationException {"},{"lineNumber":39,"author":{"gitId":"-"},"content":" String regKey \u003d getNonNullRequestParamValue(Const.ParamsNames.REGKEY);"},{"lineNumber":40,"author":{"gitId":"-"},"content":" String entityType \u003d getNonNullRequestParamValue(Const.ParamsNames.ENTITY_TYPE);"},{"lineNumber":41,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":42,"author":{"gitId":"yuanxi1"},"content":" String courseId \u003d getCourseId(regKey, entityType);"},{"lineNumber":43,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":44,"author":{"gitId":"yuanxi1"},"content":" // courseId is null when the registration key does not exist, this case is handled in the AccountsLogic."},{"lineNumber":45,"author":{"gitId":"yuanxi1"},"content":" // Hence default to not migrated. Getting the courseId in the action layer is not needed once migration is done."},{"lineNumber":46,"author":{"gitId":"yuanxi1"},"content":" if (courseId \u003d\u003d null || !isCourseMigrated(courseId)) {"},{"lineNumber":47,"author":{"gitId":"yuanxi1"},"content":" switch (entityType) {"},{"lineNumber":48,"author":{"gitId":"yuanxi1"},"content":" case Const.EntityType.STUDENT:"},{"lineNumber":49,"author":{"gitId":"yuanxi1"},"content":" return joinCourseForStudentDatastore(regKey);"},{"lineNumber":50,"author":{"gitId":"yuanxi1"},"content":" case Const.EntityType.INSTRUCTOR:"},{"lineNumber":51,"author":{"gitId":"yuanxi1"},"content":" return joinCourseForInstructorDatastore(regKey);"},{"lineNumber":52,"author":{"gitId":"yuanxi1"},"content":" default:"},{"lineNumber":53,"author":{"gitId":"yuanxi1"},"content":" throw new InvalidHttpParameterException(\"Error: invalid entity type\");"},{"lineNumber":54,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":55,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":56,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" switch (entityType) {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" case Const.EntityType.STUDENT:"},{"lineNumber":59,"author":{"gitId":"-"},"content":" return joinCourseForStudent(regKey);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" case Const.EntityType.INSTRUCTOR:"},{"lineNumber":61,"author":{"gitId":"-"},"content":" return joinCourseForInstructor(regKey);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":63,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Error: invalid entity type\");"},{"lineNumber":64,"author":{"gitId":"-"},"content":" }"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" private JsonResult joinCourseForStudent(String regkey) throws InvalidOperationException {"},{"lineNumber":68,"author":{"gitId":"yuanxi1"},"content":" Student student;"},{"lineNumber":69,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":70,"author":{"gitId":"yuanxi1"},"content":" try {"},{"lineNumber":71,"author":{"gitId":"yuanxi1"},"content":" student \u003d sqlLogic.joinCourseForStudent(regkey, userInfo.id);"},{"lineNumber":72,"author":{"gitId":"yuanxi1"},"content":" } catch (EntityDoesNotExistException ednee) {"},{"lineNumber":73,"author":{"gitId":"yuanxi1"},"content":" throw new EntityNotFoundException(ednee);"},{"lineNumber":74,"author":{"gitId":"yuanxi1"},"content":" } catch (EntityAlreadyExistsException eaee) {"},{"lineNumber":75,"author":{"gitId":"yuanxi1"},"content":" throw new InvalidOperationException(eaee);"},{"lineNumber":76,"author":{"gitId":"yuanxi1"},"content":" } catch (InvalidParametersException ipe) {"},{"lineNumber":77,"author":{"gitId":"yuanxi1"},"content":" // There should not be any invalid parameter here"},{"lineNumber":78,"author":{"gitId":"yuanxi1"},"content":" log.severe(\"Unexpected error\", ipe);"},{"lineNumber":79,"author":{"gitId":"yuanxi1"},"content":" return new JsonResult(ipe.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR);"},{"lineNumber":80,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":81,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":82,"author":{"gitId":"yuanxi1"},"content":" sendJoinEmail(student.getCourseId(), student.getName(), student.getEmail(), false);"},{"lineNumber":83,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":84,"author":{"gitId":"yuanxi1"},"content":" return new JsonResult(\"Student successfully joined course\");"},{"lineNumber":85,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":86,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":87,"author":{"gitId":"yuanxi1"},"content":" private JsonResult joinCourseForInstructor(String regkey) throws InvalidOperationException {"},{"lineNumber":88,"author":{"gitId":"yuanxi1"},"content":" Instructor instructor;"},{"lineNumber":89,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":90,"author":{"gitId":"yuanxi1"},"content":" try {"},{"lineNumber":91,"author":{"gitId":"yuanxi1"},"content":" instructor \u003d sqlLogic.joinCourseForInstructor(regkey, userInfo.id);"},{"lineNumber":92,"author":{"gitId":"yuanxi1"},"content":" } catch (EntityDoesNotExistException ednee) {"},{"lineNumber":93,"author":{"gitId":"yuanxi1"},"content":" throw new EntityNotFoundException(ednee);"},{"lineNumber":94,"author":{"gitId":"yuanxi1"},"content":" } catch (EntityAlreadyExistsException eaee) {"},{"lineNumber":95,"author":{"gitId":"yuanxi1"},"content":" throw new InvalidOperationException(eaee);"},{"lineNumber":96,"author":{"gitId":"yuanxi1"},"content":" } catch (InvalidParametersException ipe) {"},{"lineNumber":97,"author":{"gitId":"yuanxi1"},"content":" // There should not be any invalid parameter here"},{"lineNumber":98,"author":{"gitId":"yuanxi1"},"content":" log.severe(\"Unexpected error\", ipe);"},{"lineNumber":99,"author":{"gitId":"yuanxi1"},"content":" return new JsonResult(ipe.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR);"},{"lineNumber":100,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":101,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":102,"author":{"gitId":"yuanxi1"},"content":" sendJoinEmail(instructor.getCourseId(), instructor.getName(), instructor.getEmail(), true);"},{"lineNumber":103,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":104,"author":{"gitId":"yuanxi1"},"content":" return new JsonResult(\"Instructor successfully joined course\");"},{"lineNumber":105,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":106,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":107,"author":{"gitId":"yuanxi1"},"content":" private JsonResult joinCourseForStudentDatastore(String regkey) throws InvalidOperationException {"},{"lineNumber":108,"author":{"gitId":"-"},"content":" StudentAttributes student;"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" student \u003d logic.joinCourseForStudent(regkey, userInfo.id);"},{"lineNumber":112,"author":{"gitId":"-"},"content":" } catch (EntityDoesNotExistException ednee) {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(ednee);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" } catch (EntityAlreadyExistsException eaee) {"},{"lineNumber":115,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(eaee);"},{"lineNumber":116,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException ipe) {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" // There should not be any invalid parameter here"},{"lineNumber":118,"author":{"gitId":"-"},"content":" log.severe(\"Unexpected error\", ipe);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" return new JsonResult(ipe.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" }"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"yuanxi1"},"content":" sendJoinEmailDatastore(student.getCourse(), student.getName(), student.getEmail(), false);"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" return new JsonResult(\"Student successfully joined course\");"},{"lineNumber":125,"author":{"gitId":"-"},"content":" }"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"yuanxi1"},"content":" private JsonResult joinCourseForInstructorDatastore(String regkey) throws InvalidOperationException {"},{"lineNumber":128,"author":{"gitId":"-"},"content":" InstructorAttributes instructor;"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":131,"author":{"gitId":"-"},"content":" instructor \u003d logic.joinCourseForInstructor(regkey, userInfo.id);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" } catch (EntityDoesNotExistException ednee) {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(ednee);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" } catch (EntityAlreadyExistsException eaee) {"},{"lineNumber":135,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(eaee);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException ipe) {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" // There should not be any invalid parameter here"},{"lineNumber":138,"author":{"gitId":"-"},"content":" log.severe(\"Unexpected error\", ipe);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" return new JsonResult(ipe.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"yuanxi1"},"content":" sendJoinEmailDatastore(instructor.getCourseId(), instructor.getName(), instructor.getEmail(), true);"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":" return new JsonResult(\"Instructor successfully joined course\");"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"yuanxi1"},"content":" private void sendJoinEmailDatastore(String courseId, String userName, String userEmail, boolean isInstructor) {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" CourseAttributes course \u003d logic.getCourse(courseId);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d emailGenerator.generateUserCourseRegisteredEmail("},{"lineNumber":150,"author":{"gitId":"-"},"content":" userName, userEmail, userInfo.id, isInstructor, course);"},{"lineNumber":151,"author":{"gitId":"-"},"content":" emailSender.sendEmail(email);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" }"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"yuanxi1"},"content":" private void sendJoinEmail(String courseId, String userName, String userEmail, boolean isInstructor) {"},{"lineNumber":155,"author":{"gitId":"yuanxi1"},"content":" Course course \u003d sqlLogic.getCourse(courseId);"},{"lineNumber":156,"author":{"gitId":"yuanxi1"},"content":" EmailWrapper email \u003d sqlEmailGenerator.generateUserCourseRegisteredEmail("},{"lineNumber":157,"author":{"gitId":"yuanxi1"},"content":" userName, userEmail, userInfo.id, isInstructor, course);"},{"lineNumber":158,"author":{"gitId":"yuanxi1"},"content":" emailSender.sendEmail(email);"},{"lineNumber":159,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":160,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":161,"author":{"gitId":"yuanxi1"},"content":" private String getCourseId(String regKey, String entityType) {"},{"lineNumber":162,"author":{"gitId":"yuanxi1"},"content":" String courseIdSql;"},{"lineNumber":163,"author":{"gitId":"yuanxi1"},"content":" String courseIdDatastore;"},{"lineNumber":164,"author":{"gitId":"yuanxi1"},"content":" switch (entityType) {"},{"lineNumber":165,"author":{"gitId":"yuanxi1"},"content":" case Const.EntityType.STUDENT:"},{"lineNumber":166,"author":{"gitId":"yuanxi1"},"content":" courseIdSql \u003d Optional.ofNullable(sqlLogic.getStudentByRegistrationKey(regKey))"},{"lineNumber":167,"author":{"gitId":"yuanxi1"},"content":" .map(Student::getCourseId)"},{"lineNumber":168,"author":{"gitId":"yuanxi1"},"content":" .orElse(null);"},{"lineNumber":169,"author":{"gitId":"yuanxi1"},"content":" courseIdDatastore \u003d Optional.ofNullable(logic.getStudentForRegistrationKey(regKey))"},{"lineNumber":170,"author":{"gitId":"yuanxi1"},"content":" .map(StudentAttributes::getCourse)"},{"lineNumber":171,"author":{"gitId":"yuanxi1"},"content":" .orElse(null);"},{"lineNumber":172,"author":{"gitId":"yuanxi1"},"content":" break;"},{"lineNumber":173,"author":{"gitId":"yuanxi1"},"content":" case Const.EntityType.INSTRUCTOR:"},{"lineNumber":174,"author":{"gitId":"yuanxi1"},"content":" courseIdSql \u003d Optional.ofNullable(sqlLogic.getInstructorByRegistrationKey(regKey))"},{"lineNumber":175,"author":{"gitId":"yuanxi1"},"content":" .map(Instructor::getCourseId)"},{"lineNumber":176,"author":{"gitId":"yuanxi1"},"content":" .orElse(null);"},{"lineNumber":177,"author":{"gitId":"yuanxi1"},"content":" courseIdDatastore \u003d Optional.ofNullable(logic.getInstructorForRegistrationKey(regKey))"},{"lineNumber":178,"author":{"gitId":"yuanxi1"},"content":" .map(InstructorAttributes::getCourseId)"},{"lineNumber":179,"author":{"gitId":"yuanxi1"},"content":" .orElse(null);"},{"lineNumber":180,"author":{"gitId":"yuanxi1"},"content":" break;"},{"lineNumber":181,"author":{"gitId":"yuanxi1"},"content":" default:"},{"lineNumber":182,"author":{"gitId":"yuanxi1"},"content":" throw new InvalidHttpParameterException(\"Error: invalid entity type\");"},{"lineNumber":183,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":184,"author":{"gitId":"yuanxi1"},"content":" return courseIdDatastore !\u003d null ? courseIdDatastore : courseIdSql;"},{"lineNumber":185,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"yuanxi1":98,"-":88}},{"path":"src/main/java/teammates/ui/webapi/PutDataBundleDocumentsAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.DataBundle;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * Puts searchable documents from the data bundle into the DB."},{"lineNumber":14,"author":{"gitId":"-"},"content":" */"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"public class PutDataBundleDocumentsAction extends Action {"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":18,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" return AuthType.ALL_ACCESS;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" }"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":23,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" if (!Config.IS_DEV_SERVER) {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Admin privilege is required to access this resource.\");"},{"lineNumber":26,"author":{"gitId":"-"},"content":" }"},{"lineNumber":27,"author":{"gitId":"-"},"content":" }"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" public JsonResult execute() throws InvalidHttpRequestBodyException {"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" String type \u003d getNonNullRequestParamValue(\"databundletype\");"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" switch (type) {"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" case \"sql\":"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" return putSqlDataBundleDocuments();"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" case \"datastore\":"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" return putDataBundleDocuments();"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" default:"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" throw new InvalidHttpParameterException(\"Error: invalid data bundle type\");"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" private JsonResult putSqlDataBundleDocuments() throws InvalidHttpRequestBodyException {"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" SqlDataBundle sqlDataBundle \u003d JsonUtils.fromJson(getRequestBody(), SqlDataBundle.class);"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" try {"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" sqlLogic.putDocuments(sqlDataBundle);"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" return new JsonResult(\"Failed to add data bundle documents.\", HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" return new JsonResult(\"Data bundle documents successfully added.\");"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" private JsonResult putDataBundleDocuments() throws InvalidHttpRequestBodyException {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" DataBundle dataBundle \u003d JsonUtils.fromJson(getRequestBody(), DataBundle.class);"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" logic.putDocuments(dataBundle);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" return new JsonResult(\"Failed to add data bundle documents.\", HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":" return new JsonResult(\"Data bundle documents successfully added.\");"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":29,"-":35}},{"path":"src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":"import teammates.ui.output.AccountRequestData;"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":"import teammates.ui.request.AccountRequestRejectionRequest;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" * Rejects an account request."},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":"public class RejectAccountRequestAction extends AdminOnlyAction {"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" public boolean isTransactionNeeded() {"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" return false;"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" @Override"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" public JsonResult execute() throws InvalidOperationException, InvalidHttpRequestBodyException {"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" String id \u003d getNonNullRequestParamValue(Const.ParamsNames.ACCOUNT_REQUEST_ID);"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" UUID accountRequestId \u003d getUuidFromString(Const.ParamsNames.ACCOUNT_REQUEST_ID, id);"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d sqlLogic.getAccountRequestWithTransaction(accountRequestId);"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" if (accountRequest \u003d\u003d null) {"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" String errorMessage \u003d String.format(Const.ACCOUNT_REQUEST_NOT_FOUND, accountRequestId.toString());"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" throw new EntityNotFoundException(errorMessage);"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest accountRequestRejectionRequest \u003d"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" getAndValidateRequestBody(AccountRequestRejectionRequest.class);"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" AccountRequestStatus initialStatus \u003d accountRequest.getStatus();"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" try {"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" accountRequest.setStatus(AccountRequestStatus.REJECTED);"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d sqlLogic.updateAccountRequestWithTransaction(accountRequest);"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" if (accountRequestRejectionRequest.checkHasReason()"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" \u0026\u0026 initialStatus !\u003d AccountRequestStatus.REJECTED) {"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" EmailWrapper email \u003d sqlEmailGenerator.generateAccountRequestRejectionEmail(accountRequest,"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" accountRequestRejectionRequest.getReasonTitle(), accountRequestRejectionRequest.getReasonBody());"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" emailSender.sendEmail(email);"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" taskQueuer.scheduleAccountRequestForSearchIndexing(accountRequest.getId().toString());"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" throw new InvalidHttpRequestBodyException(e);"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" } catch (EntityDoesNotExistException e) {"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" throw new EntityNotFoundException(e);"},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" return new JsonResult(new AccountRequestData(accountRequest));"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"domoberzin":9,"xenosf":50}},{"path":"src/main/java/teammates/ui/webapi/ResetAccountRequestAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.Logger;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.ui.output.JoinLinkData;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * Action: resets an account request."},{"lineNumber":17,"author":{"gitId":"-"},"content":" */"},{"lineNumber":18,"author":{"gitId":"-"},"content":"class ResetAccountRequestAction extends AdminOnlyAction {"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" private static final Logger log \u003d Logger.getLogger();"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":23,"author":{"gitId":"-"},"content":" public JsonResult execute() throws InvalidOperationException {"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":" UUID id \u003d getUuidRequestParamValue(Const.ParamsNames.ACCOUNT_REQUEST_ID);"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" AccountRequest accountRequest \u003d sqlLogic.getAccountRequest(id);"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" if (accountRequest \u003d\u003d null) {"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" throw new EntityNotFoundException(\"Account request with id: \" + id.toString() + \" does not exist.\");"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":" if (accountRequest.getRegisteredAt() \u003d\u003d null) {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(\"Unable to reset account request as instructor is still unregistered.\");"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" accountRequest \u003d sqlLogic.resetAccountRequest(id);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException | EntityDoesNotExistException ue) {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" // InvalidParametersException and EntityDoesNotExistException should not be thrown as"},{"lineNumber":39,"author":{"gitId":"-"},"content":" // validity of params has been verified when fetching entity."},{"lineNumber":40,"author":{"gitId":"-"},"content":" log.severe(\"Unexpected error\", ue);"},{"lineNumber":41,"author":{"gitId":"-"},"content":" return new JsonResult(ue.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR);"},{"lineNumber":42,"author":{"gitId":"-"},"content":" }"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" String joinLink \u003d accountRequest.getRegistrationUrl();"},{"lineNumber":45,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d emailGenerator.generateNewInstructorAccountJoinEmail("},{"lineNumber":46,"author":{"gitId":"-"},"content":" accountRequest.getEmail(), accountRequest.getName(), joinLink);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" emailSender.sendEmail(email);"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" JoinLinkData output \u003d new JoinLinkData(joinLink);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" return new JsonResult(output);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" }"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":6,"-":47}},{"path":"src/main/java/teammates/ui/webapi/SearchAccountRequestsAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountRequestAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.ui.output.AccountRequestData;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.ui.output.AccountRequestsData;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"-"},"content":" * Searches for account requests."},{"lineNumber":15,"author":{"gitId":"-"},"content":" */"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"public class SearchAccountRequestsAction extends AdminOnlyAction {"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":19,"author":{"gitId":"-"},"content":" public JsonResult execute() {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" String searchKey \u003d getNonNullRequestParamValue(Const.ParamsNames.SEARCH_KEY);"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" List\u003cAccountRequest\u003e accountRequests;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" accountRequests \u003d sqlLogic.searchAccountRequestsInWholeSystem(searchKey);"},{"lineNumber":25,"author":{"gitId":"-"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" return new JsonResult(e.getMessage(), e.getStatusCode());"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" List\u003cAccountRequestAttributes\u003e requestsDatastore;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" requestsDatastore \u003d logic.searchAccountRequestsInWholeSystem(searchKey);"},{"lineNumber":32,"author":{"gitId":"-"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" return new JsonResult(e.getMessage(), e.getStatusCode());"},{"lineNumber":34,"author":{"gitId":"-"},"content":" }"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" List\u003cAccountRequestData\u003e accountRequestDataList \u003d new ArrayList\u003c\u003e();"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" for (AccountRequest accountRequest : accountRequests) {"},{"lineNumber":38,"author":{"gitId":"-"},"content":" AccountRequestData accountRequestData \u003d new AccountRequestData(accountRequest);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" accountRequestDataList.add(accountRequestData);"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" for (AccountRequestAttributes request : requestsDatastore) {"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" if (accountRequestDataList.stream().noneMatch(data -\u003e data.getEmail().equals(request.getEmail()))) {"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" AccountRequestData accountRequestData \u003d new AccountRequestData(request);"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" accountRequestDataList.add(accountRequestData);"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" AccountRequestsData accountRequestsData \u003d new AccountRequestsData();"},{"lineNumber":50,"author":{"gitId":"-"},"content":" accountRequestsData.setAccountRequests(accountRequestDataList);"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" return new JsonResult(accountRequestsData);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" }"},{"lineNumber":54,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":17,"-":37}},{"path":"src/main/java/teammates/ui/webapi/SearchInstructorsAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.ui.output.InstructorData;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.ui.output.InstructorsData;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"-"},"content":" * Searches for instructors."},{"lineNumber":15,"author":{"gitId":"-"},"content":" */"},{"lineNumber":16,"author":{"gitId":"-"},"content":"public class SearchInstructorsAction extends AdminOnlyAction {"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":19,"author":{"gitId":"-"},"content":" public JsonResult execute() {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" // Search for sql db"},{"lineNumber":21,"author":{"gitId":"-"},"content":" String searchKey \u003d getNonNullRequestParamValue(Const.ParamsNames.SEARCH_KEY);"},{"lineNumber":22,"author":{"gitId":"-"},"content":" List\u003cInstructor\u003e instructors;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" instructors \u003d sqlLogic.searchInstructorsInWholeSystem(searchKey);"},{"lineNumber":25,"author":{"gitId":"-"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":26,"author":{"gitId":"-"},"content":" return new JsonResult(e.getMessage(), e.getStatusCode());"},{"lineNumber":27,"author":{"gitId":"-"},"content":" }"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" // Search for datastore"},{"lineNumber":30,"author":{"gitId":"-"},"content":" List\u003cInstructorAttributes\u003e instructorsDatastore;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" instructorsDatastore \u003d logic.searchInstructorsInWholeSystem(searchKey);"},{"lineNumber":33,"author":{"gitId":"-"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" return new JsonResult(e.getMessage(), e.getStatusCode());"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" List\u003cInstructorData\u003e instructorDataList \u003d new ArrayList\u003c\u003e();"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" // Add instructors from sql db"},{"lineNumber":40,"author":{"gitId":"-"},"content":" for (Instructor instructor : instructors) {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" InstructorData instructorData \u003d new InstructorData(instructor);"},{"lineNumber":42,"author":{"gitId":"-"},"content":" instructorData.addAdditionalInformationForAdminSearch("},{"lineNumber":43,"author":{"gitId":"-"},"content":" instructor.getRegKey(),"},{"lineNumber":44,"author":{"gitId":"-"},"content":" sqlLogic.getCourse(instructor.getCourseId()).getInstitute(),"},{"lineNumber":45,"author":{"gitId":"-"},"content":" instructor.getGoogleId());"},{"lineNumber":46,"author":{"gitId":"-"},"content":""},{"lineNumber":47,"author":{"gitId":"-"},"content":" instructorDataList.add(instructorData);"},{"lineNumber":48,"author":{"gitId":"-"},"content":" }"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" // Add instructors from datastore"},{"lineNumber":51,"author":{"gitId":"-"},"content":" for (InstructorAttributes instructor : instructorsDatastore) {"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" InstructorData instructorData \u003d new InstructorData(instructor);"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" if (isCourseMigrated(instructorData.getCourseId())) {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" instructorData.addAdditionalInformationForAdminSearch("},{"lineNumber":60,"author":{"gitId":"-"},"content":" instructor.getKey(),"},{"lineNumber":61,"author":{"gitId":"-"},"content":" logic.getCourseInstitute(instructor.getCourseId()),"},{"lineNumber":62,"author":{"gitId":"-"},"content":" instructor.getGoogleId());"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" instructorDataList.add(instructorData);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" }"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" InstructorsData instructorsData \u003d new InstructorsData();"},{"lineNumber":68,"author":{"gitId":"-"},"content":" instructorsData.setInstructors(instructorDataList);"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" return new JsonResult(instructorsData);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }"},{"lineNumber":72,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":1,"-":71}},{"path":"src/main/java/teammates/ui/webapi/SearchStudentsAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":10,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":11,"author":{"gitId":"yuanxi1"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.ui.output.StudentData;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.ui.output.StudentsData;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * Action for searching for students."},{"lineNumber":17,"author":{"gitId":"-"},"content":" */"},{"lineNumber":18,"author":{"gitId":"yuanxi1"},"content":"public class SearchStudentsAction extends Action {"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":21,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":23,"author":{"gitId":"-"},"content":" }"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":26,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" // Only instructors and admins can search for student"},{"lineNumber":28,"author":{"gitId":"-"},"content":" if (!userInfo.isInstructor \u0026\u0026 !userInfo.isAdmin) {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Instructor or Admin privilege is required to access this resource.\");"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":" }"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":34,"author":{"gitId":"-"},"content":" public JsonResult execute() {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" String searchKey \u003d getNonNullRequestParamValue(Const.ParamsNames.SEARCH_KEY);"},{"lineNumber":36,"author":{"gitId":"-"},"content":" String entity \u003d getNonNullRequestParamValue(Const.ParamsNames.ENTITY_TYPE);"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"yuanxi1"},"content":" List\u003cStudent\u003e students;"},{"lineNumber":39,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":40,"author":{"gitId":"yuanxi1"},"content":" try {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" if (userInfo.isInstructor \u0026\u0026 Const.EntityType.INSTRUCTOR.equals(entity)) {"},{"lineNumber":42,"author":{"gitId":"yuanxi1"},"content":" List\u003cInstructor\u003e instructors \u003d sqlLogic.getInstructorsForGoogleId(userInfo.id);"},{"lineNumber":43,"author":{"gitId":"yuanxi1"},"content":" students \u003d sqlLogic.searchStudents(searchKey, instructors);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" } else if (userInfo.isAdmin \u0026\u0026 Const.EntityType.ADMIN.equals(entity)) {"},{"lineNumber":45,"author":{"gitId":"yuanxi1"},"content":" students \u003d sqlLogic.searchStudentsInWholeSystem(searchKey);"},{"lineNumber":46,"author":{"gitId":"yuanxi1"},"content":" } else {"},{"lineNumber":47,"author":{"gitId":"yuanxi1"},"content":" throw new InvalidHttpParameterException(\"Invalid entity type for search\");"},{"lineNumber":48,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":49,"author":{"gitId":"yuanxi1"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":50,"author":{"gitId":"yuanxi1"},"content":" return new JsonResult(e.getMessage(), e.getStatusCode());"},{"lineNumber":51,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":52,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":53,"author":{"gitId":"yuanxi1"},"content":" // Search in datastore. For more information on dual db support, see this [PR](https://github.com/TEAMMATES/teammates/pull/12728/files)"},{"lineNumber":54,"author":{"gitId":"yuanxi1"},"content":" List\u003cStudentAttributes\u003e studentsDatastore;"},{"lineNumber":55,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" if (userInfo.isInstructor \u0026\u0026 Const.EntityType.INSTRUCTOR.equals(entity)) {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" List\u003cInstructorAttributes\u003e instructors \u003d logic.getInstructorsForGoogleId(userInfo.id);"},{"lineNumber":58,"author":{"gitId":"yuanxi1"},"content":" studentsDatastore \u003d logic.searchStudents(searchKey, instructors);"},{"lineNumber":59,"author":{"gitId":"-"},"content":" } else if (userInfo.isAdmin \u0026\u0026 Const.EntityType.ADMIN.equals(entity)) {"},{"lineNumber":60,"author":{"gitId":"yuanxi1"},"content":" studentsDatastore \u003d logic.searchStudentsInWholeSystem(searchKey);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" throw new InvalidHttpParameterException(\"Invalid entity type for search\");"},{"lineNumber":63,"author":{"gitId":"-"},"content":" }"},{"lineNumber":64,"author":{"gitId":"-"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" return new JsonResult(e.getMessage(), e.getStatusCode());"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" List\u003cStudentData\u003e studentDataList \u003d new ArrayList\u003c\u003e();"},{"lineNumber":69,"author":{"gitId":"yuanxi1"},"content":" // Add students from sql database"},{"lineNumber":70,"author":{"gitId":"yuanxi1"},"content":" for (Student s : students) {"},{"lineNumber":71,"author":{"gitId":"yuanxi1"},"content":" StudentData studentData \u003d new StudentData(s);"},{"lineNumber":72,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" if (userInfo.isAdmin \u0026\u0026 Const.EntityType.ADMIN.equals(entity)) {"},{"lineNumber":74,"author":{"gitId":"yuanxi1"},"content":" studentData.addAdditionalInformationForAdminSearch("},{"lineNumber":75,"author":{"gitId":"yuanxi1"},"content":" s.getRegKey(),"},{"lineNumber":76,"author":{"gitId":"yuanxi1"},"content":" sqlLogic.getCourseInstitute(s.getCourseId()),"},{"lineNumber":77,"author":{"gitId":"yuanxi1"},"content":" s.getGoogleId()"},{"lineNumber":78,"author":{"gitId":"yuanxi1"},"content":" );"},{"lineNumber":79,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":80,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":81,"author":{"gitId":"yuanxi1"},"content":" studentDataList.add(studentData);"},{"lineNumber":82,"author":{"gitId":"yuanxi1"},"content":" }"},{"lineNumber":83,"author":{"gitId":"yuanxi1"},"content":" // Add students from datastore"},{"lineNumber":84,"author":{"gitId":"yuanxi1"},"content":" for (StudentAttributes s : studentsDatastore) {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" StudentData studentData \u003d new StudentData(s);"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" if (isCourseMigrated(studentData.getCourseId())) {"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" continue;"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" if (userInfo.isAdmin \u0026\u0026 Const.EntityType.ADMIN.equals(entity)) {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" studentData.addAdditionalInformationForAdminSearch("},{"lineNumber":93,"author":{"gitId":"-"},"content":" s.getKey(),"},{"lineNumber":94,"author":{"gitId":"-"},"content":" logic.getCourseInstitute(s.getCourse()),"},{"lineNumber":95,"author":{"gitId":"-"},"content":" s.getGoogleId()"},{"lineNumber":96,"author":{"gitId":"-"},"content":" );"},{"lineNumber":97,"author":{"gitId":"-"},"content":" }"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" studentDataList.add(studentData);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":" StudentsData studentsData \u003d new StudentsData();"},{"lineNumber":102,"author":{"gitId":"-"},"content":" studentsData.setStudents(studentDataList);"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" return new JsonResult(studentsData);"},{"lineNumber":105,"author":{"gitId":"-"},"content":" }"},{"lineNumber":106,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":4,"yuanxi1":35,"-":67}},{"path":"src/main/java/teammates/ui/webapi/StudentSearchIndexingWorkerAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.exception.SearchServiceException;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.util.Const.ParamsNames;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":11,"author":{"gitId":"-"},"content":" * Task queue worker action: performs student search indexing."},{"lineNumber":12,"author":{"gitId":"-"},"content":" */"},{"lineNumber":13,"author":{"gitId":"-"},"content":"public class StudentSearchIndexingWorkerAction extends AdminOnlyAction {"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":16,"author":{"gitId":"-"},"content":" public ActionResult execute() {"},{"lineNumber":17,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(ParamsNames.COURSE_ID);"},{"lineNumber":18,"author":{"gitId":"-"},"content":" String email \u003d getNonNullRequestParamValue(ParamsNames.STUDENT_EMAIL);"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" return executeWithSql(courseId, email);"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" } else {"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" return executeWithDataStore(courseId, email);"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" private ActionResult executeWithDataStore(String courseId, String email) {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" StudentAttributes student \u003d logic.getStudentForEmail(courseId, email);"},{"lineNumber":30,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" logic.putStudentDocument(student);"},{"lineNumber":32,"author":{"gitId":"-"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" // Set an arbitrary retry code outside of the range 200-299 to trigger automatic retry"},{"lineNumber":34,"author":{"gitId":"-"},"content":" return new JsonResult(\"Failure\", HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":35,"author":{"gitId":"-"},"content":" }"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" return new JsonResult(\"Successful\");"},{"lineNumber":38,"author":{"gitId":"-"},"content":" }"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" private ActionResult executeWithSql(String courseId, String email) {"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" Student student \u003d sqlLogic.getStudentForEmail(courseId, email);"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" try {"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" sqlLogic.putStudentDocument(student);"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" } catch (SearchServiceException e) {"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" // Set an arbitrary retry code outside of the range 200-299 to trigger automatic retry"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" return new JsonResult(\"Failure\", HttpStatus.SC_BAD_GATEWAY);"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" return new JsonResult(\"Successful\");"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":51,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":22,"-":29}},{"path":"src/main/java/teammates/ui/webapi/UpdateAccountRequestAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import java.util.UUID;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.Const;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.output.AccountRequestData;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.request.AccountRequestUpdateRequest;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" * Updates an account request."},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"public class UpdateAccountRequestAction extends AdminOnlyAction {"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" public boolean isTransactionNeeded() {"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" return false;"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" public JsonResult execute() throws InvalidOperationException, InvalidHttpRequestBodyException {"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" String id \u003d getNonNullRequestParamValue(Const.ParamsNames.ACCOUNT_REQUEST_ID);"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" UUID accountRequestId \u003d getUuidFromString(Const.ParamsNames.ACCOUNT_REQUEST_ID, id);"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" AccountRequest accountRequest \u003d sqlLogic.getAccountRequestWithTransaction(accountRequestId);"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" if (accountRequest \u003d\u003d null) {"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" String errorMessage \u003d String.format(Const.ACCOUNT_REQUEST_NOT_FOUND, accountRequestId.toString());"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" throw new EntityNotFoundException(errorMessage);"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" AccountRequestUpdateRequest accountRequestUpdateRequest \u003d"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" getAndValidateRequestBody(AccountRequestUpdateRequest.class);"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" if (accountRequestUpdateRequest.getStatus() \u003d\u003d AccountRequestStatus.APPROVED"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" \u0026\u0026 (accountRequest.getStatus() \u003d\u003d AccountRequestStatus.PENDING"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" || accountRequest.getStatus() \u003d\u003d AccountRequestStatus.REJECTED)) {"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" if (!sqlLogic.getAccountsForEmailWithTransaction(accountRequest.getEmail()).isEmpty()) {"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" throw new InvalidOperationException(String.format(\"An account with email %s already exists. \""},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" + \"Please reject or delete the account request instead.\","},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" accountRequest.getEmail()));"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" if (!sqlLogic.getApprovedAccountRequestsForEmailWithTransaction(accountRequest.getEmail()).isEmpty()) {"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" throw new InvalidOperationException(String.format("},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" \"An account request with email %s has already been approved. \""},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" + \"Please reject or delete the account request instead.\","},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" accountRequest.getEmail()));"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" // should not need to update other fields for an approval"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" accountRequest.setStatus(accountRequestUpdateRequest.getStatus());"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d sqlLogic.updateAccountRequestWithTransaction(accountRequest);"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" EmailWrapper email \u003d sqlEmailGenerator.generateNewInstructorAccountJoinEmail("},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" accountRequest.getEmail(), accountRequest.getName(), accountRequest.getRegistrationUrl());"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" taskQueuer.scheduleAccountRequestForSearchIndexing(accountRequest.getId().toString());"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" emailSender.sendEmail(email);"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":" throw new InvalidHttpRequestBodyException(e);"},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" } catch (EntityDoesNotExistException e) {"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":" throw new EntityNotFoundException(e);"},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" } else {"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" accountRequest.setName(accountRequestUpdateRequest.getName());"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" accountRequest.setEmail(accountRequestUpdateRequest.getEmail());"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" accountRequest.setInstitute(accountRequestUpdateRequest.getInstitute());"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" accountRequest.setStatus(accountRequest.getStatus());"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" accountRequest.setComments(accountRequestUpdateRequest.getComments());"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" accountRequest \u003d sqlLogic.updateAccountRequestWithTransaction(accountRequest);"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" taskQueuer.scheduleAccountRequestForSearchIndexing(accountRequest.getId().toString());"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" throw new InvalidHttpRequestBodyException(e);"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" } catch (EntityDoesNotExistException e) {"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" throw new EntityNotFoundException(e);"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":" return new JsonResult(new AccountRequestData(accountRequest));"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":85,"xenosf":1,"-":2}},{"path":"src/main/java/teammates/ui/webapi/UpdateFeedbackSessionLogsAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import java.time.temporal.ChronoUnit;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import java.util.HashMap;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import java.util.Map;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Const;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":" * Process feedback session logs from GCP in the past defined time period and"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" * store in the database."},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":"public class UpdateFeedbackSessionLogsAction extends AdminOnlyAction {"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" static final long COLLECTION_TIME_PERIOD \u003d Const.STUDENT_ACTIVITY_LOGS_UPDATE_INTERVAL.toMinutes();"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" static final long SPAM_FILTER \u003d Const.STUDENT_ACTIVITY_LOGS_FILTER_WINDOW.toMillis();"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" public JsonResult execute() {"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e filteredLogs \u003d new ArrayList\u003c\u003e();"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" Instant endTime \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.now());"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" Instant startTime \u003d endTime.minus(COLLECTION_TIME_PERIOD, ChronoUnit.MINUTES);"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntry\u003e logEntries \u003d logsProcessor.getOrderedFeedbackSessionLogs(null, null,"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" startTime.toEpochMilli(), endTime.toEpochMilli(), null);"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" Map\u003cUUID, Map\u003cString, Map\u003cUUID, Map\u003cString, Long\u003e\u003e\u003e\u003e lastSavedTimestamps \u003d new HashMap\u003c\u003e();"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" Map\u003cString, Boolean\u003e isCourseMigratedMap \u003d new HashMap\u003c\u003e();"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" for (FeedbackSessionLogEntry logEntry : logEntries) {"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" isCourseMigratedMap.computeIfAbsent(logEntry.getCourseId(), k -\u003e {"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" CourseAttributes course \u003d logic.getCourse(logEntry.getCourseId());"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" return course \u003d\u003d null || course.isMigrated();"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" });"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" if (!isCourseMigratedMap.get(logEntry.getCourseId())) {"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" continue;"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" String courseId \u003d logEntry.getCourseId();"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" UUID studentId \u003d logEntry.getStudentId();"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" UUID fbSessionId \u003d logEntry.getFeedbackSessionId();"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" String type \u003d logEntry.getFeedbackSessionLogType();"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" Long timestamp \u003d logEntry.getTimestamp();"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" lastSavedTimestamps.computeIfAbsent(studentId, k -\u003e new HashMap\u003c\u003e());"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" lastSavedTimestamps.get(studentId).computeIfAbsent(courseId, k -\u003e new HashMap\u003c\u003e());"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":" lastSavedTimestamps.get(studentId).get(courseId).computeIfAbsent(fbSessionId, k -\u003e new HashMap\u003c\u003e());"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" Long lastSaved \u003d lastSavedTimestamps.get(studentId).get(courseId).get(fbSessionId).getOrDefault(type, 0L);"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" if (Math.abs(timestamp - lastSaved) \u003e SPAM_FILTER) {"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" lastSavedTimestamps.get(studentId).get(courseId).get(fbSessionId).put(type, timestamp);"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" Student student \u003d sqlLogic.getStudentReference(studentId);"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d sqlLogic.getFeedbackSessionReference(fbSessionId);"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog fslEntity \u003d new FeedbackSessionLog(student, feedbackSession,"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.valueOfLabel(type), Instant.ofEpochMilli(timestamp));"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" filteredLogs.add(fslEntity);"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" sqlLogic.createFeedbackSessionLogs(filteredLogs);"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" return new JsonResult(\"Successful\");"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":77}},{"path":"src/main/java/teammates/ui/webapi/UpdateStudentAction.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.Arrays;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.exception.EnrollException;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailSendingStatus;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailType;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":15,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":16,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":17,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":18,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":19,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.ui.request.InvalidHttpRequestBodyException;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.ui.request.StudentUpdateRequest;"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * Action: Edits details of a student in a course."},{"lineNumber":25,"author":{"gitId":"-"},"content":" */"},{"lineNumber":26,"author":{"gitId":"marquestye"},"content":"public class UpdateStudentAction extends Action {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" static final String STUDENT_NOT_FOUND_FOR_EDIT \u003d \"The student you tried to edit does not exist. \""},{"lineNumber":28,"author":{"gitId":"-"},"content":" + \"If the student was created during the last few minutes, \""},{"lineNumber":29,"author":{"gitId":"-"},"content":" + \"try again in a few more minutes as the student may still be being saved.\";"},{"lineNumber":30,"author":{"gitId":"-"},"content":" private static final String SUCCESSFUL_UPDATE \u003d \"Student has been updated\";"},{"lineNumber":31,"author":{"gitId":"-"},"content":" private static final String SUCCESSFUL_UPDATE_WITH_EMAIL \u003d SUCCESSFUL_UPDATE + \" and email sent\";"},{"lineNumber":32,"author":{"gitId":"-"},"content":" private static final String SUCCESSFUL_UPDATE_BUT_EMAIL_FAILED \u003d SUCCESSFUL_UPDATE + \" but email failed to send\";"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":35,"author":{"gitId":"-"},"content":" AuthType getMinAuthLevel() {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" return AuthType.LOGGED_IN;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" }"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":40,"author":{"gitId":"-"},"content":" void checkSpecificAccessControl() throws UnauthorizedAccessException {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" if (!userInfo.isInstructor) {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" throw new UnauthorizedAccessException(\"Instructor privilege is required to access this resource.\");"},{"lineNumber":43,"author":{"gitId":"-"},"content":" }"},{"lineNumber":44,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"marquestye"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":47,"author":{"gitId":"marquestye"},"content":" Instructor instructor \u003d sqlLogic.getInstructorByGoogleId(courseId, userInfo.getId());"},{"lineNumber":48,"author":{"gitId":"marquestye"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":49,"author":{"gitId":"marquestye"},"content":" instructor, sqlLogic.getCourse(courseId), Const.InstructorPermissions.CAN_MODIFY_STUDENT);"},{"lineNumber":50,"author":{"gitId":"marquestye"},"content":" } else {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d logic.getInstructorForGoogleId(courseId, userInfo.id);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" gateKeeper.verifyAccessible("},{"lineNumber":53,"author":{"gitId":"-"},"content":" instructor, logic.getCourse(courseId), Const.InstructorPermissions.CAN_MODIFY_STUDENT);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" }"},{"lineNumber":55,"author":{"gitId":"-"},"content":" }"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":58,"author":{"gitId":"-"},"content":" public JsonResult execute() throws InvalidHttpRequestBodyException, InvalidOperationException {"},{"lineNumber":59,"author":{"gitId":"-"},"content":" String courseId \u003d getNonNullRequestParamValue(Const.ParamsNames.COURSE_ID);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" String studentEmail \u003d getNonNullRequestParamValue(Const.ParamsNames.STUDENT_EMAIL);"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"marquestye"},"content":" if (!isCourseMigrated(courseId)) {"},{"lineNumber":63,"author":{"gitId":"marquestye"},"content":" return executeWithDatastore(courseId, studentEmail);"},{"lineNumber":64,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":65,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":66,"author":{"gitId":"marquestye"},"content":" Student existingStudent \u003d sqlLogic.getStudentForEmail(courseId, studentEmail);"},{"lineNumber":67,"author":{"gitId":"marquestye"},"content":" if (existingStudent \u003d\u003d null) {"},{"lineNumber":68,"author":{"gitId":"marquestye"},"content":" throw new EntityNotFoundException(STUDENT_NOT_FOUND_FOR_EDIT);"},{"lineNumber":69,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":70,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":71,"author":{"gitId":"marquestye"},"content":" StudentUpdateRequest updateRequest \u003d getAndValidateRequestBody(StudentUpdateRequest.class);"},{"lineNumber":72,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":73,"author":{"gitId":"marquestye"},"content":" Course course \u003d sqlLogic.getCourse(courseId);"},{"lineNumber":74,"author":{"gitId":"marquestye"},"content":" Section section \u003d sqlLogic.getSectionOrCreate(courseId, updateRequest.getSection());"},{"lineNumber":75,"author":{"gitId":"marquestye"},"content":" Team team \u003d sqlLogic.getTeamOrCreate(section, updateRequest.getTeam());"},{"lineNumber":76,"author":{"gitId":"marquestye"},"content":" Student studentToUpdate \u003d new Student(course, updateRequest.getName(), updateRequest.getEmail(),"},{"lineNumber":77,"author":{"gitId":"marquestye"},"content":" updateRequest.getComments(), team);"},{"lineNumber":78,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":79,"author":{"gitId":"marquestye"},"content":" try {"},{"lineNumber":80,"author":{"gitId":"marquestye"},"content":" //we swap out email before we validate"},{"lineNumber":81,"author":{"gitId":"marquestye"},"content":" //TODO: this is duct tape at the moment, need to refactor how we do the validation"},{"lineNumber":82,"author":{"gitId":"marquestye"},"content":" String newEmail \u003d studentToUpdate.getEmail();"},{"lineNumber":83,"author":{"gitId":"marquestye"},"content":" studentToUpdate.setEmail(existingStudent.getEmail());"},{"lineNumber":84,"author":{"gitId":"marquestye"},"content":" sqlLogic.validateSectionsAndTeams(Arrays.asList(studentToUpdate), courseId);"},{"lineNumber":85,"author":{"gitId":"marquestye"},"content":" studentToUpdate.setEmail(newEmail);"},{"lineNumber":86,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":87,"author":{"gitId":"marquestye"},"content":" studentToUpdate.setId(existingStudent.getId());"},{"lineNumber":88,"author":{"gitId":"marquestye"},"content":" Student updatedStudent \u003d sqlLogic.updateStudentCascade(studentToUpdate);"},{"lineNumber":89,"author":{"gitId":"marquestye"},"content":" taskQueuer.scheduleStudentForSearchIndexing(courseId, updatedStudent.getEmail());"},{"lineNumber":90,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":91,"author":{"gitId":"marquestye"},"content":" if (!studentEmail.equals(updateRequest.getEmail()) \u0026\u0026 updateRequest.getIsSessionSummarySendEmail()) {"},{"lineNumber":92,"author":{"gitId":"marquestye"},"content":" boolean emailSent \u003d sendEmail(courseId, updateRequest.getEmail());"},{"lineNumber":93,"author":{"gitId":"marquestye"},"content":" String statusMessage \u003d emailSent ? SUCCESSFUL_UPDATE_WITH_EMAIL"},{"lineNumber":94,"author":{"gitId":"marquestye"},"content":" : SUCCESSFUL_UPDATE_BUT_EMAIL_FAILED;"},{"lineNumber":95,"author":{"gitId":"marquestye"},"content":" return new JsonResult(statusMessage);"},{"lineNumber":96,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":97,"author":{"gitId":"marquestye"},"content":" } catch (EnrollException e) {"},{"lineNumber":98,"author":{"gitId":"marquestye"},"content":" throw new InvalidOperationException(e);"},{"lineNumber":99,"author":{"gitId":"marquestye"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":100,"author":{"gitId":"marquestye"},"content":" throw new InvalidHttpRequestBodyException(e);"},{"lineNumber":101,"author":{"gitId":"marquestye"},"content":" } catch (EntityDoesNotExistException ednee) {"},{"lineNumber":102,"author":{"gitId":"marquestye"},"content":" throw new EntityNotFoundException(ednee);"},{"lineNumber":103,"author":{"gitId":"marquestye"},"content":" } catch (EntityAlreadyExistsException e) {"},{"lineNumber":104,"author":{"gitId":"marquestye"},"content":" throw new InvalidOperationException(\"Trying to update to an email that is already in use\", e);"},{"lineNumber":105,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":106,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":107,"author":{"gitId":"marquestye"},"content":" return new JsonResult(SUCCESSFUL_UPDATE);"},{"lineNumber":108,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":109,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":110,"author":{"gitId":"marquestye"},"content":" private JsonResult executeWithDatastore(String courseId, String studentEmail)"},{"lineNumber":111,"author":{"gitId":"marquestye"},"content":" throws InvalidHttpRequestBodyException, InvalidOperationException {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" StudentAttributes student \u003d logic.getStudentForEmail(courseId, studentEmail);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" if (student \u003d\u003d null) {"},{"lineNumber":114,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(STUDENT_NOT_FOUND_FOR_EDIT);"},{"lineNumber":115,"author":{"gitId":"-"},"content":" }"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" StudentUpdateRequest updateRequest \u003d getAndValidateRequestBody(StudentUpdateRequest.class);"},{"lineNumber":118,"author":{"gitId":"-"},"content":" StudentAttributes studentToUpdate \u003d StudentAttributes.builder(courseId, updateRequest.getEmail())"},{"lineNumber":119,"author":{"gitId":"-"},"content":" .withName(updateRequest.getName())"},{"lineNumber":120,"author":{"gitId":"-"},"content":" .withSectionName(updateRequest.getSection())"},{"lineNumber":121,"author":{"gitId":"-"},"content":" .withTeamName(updateRequest.getTeam())"},{"lineNumber":122,"author":{"gitId":"-"},"content":" .withComment(updateRequest.getComments())"},{"lineNumber":123,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":126,"author":{"gitId":"-"},"content":" //we swap out email before we validate"},{"lineNumber":127,"author":{"gitId":"-"},"content":" //TODO: this is duct tape at the moment, need to refactor how we do the validation"},{"lineNumber":128,"author":{"gitId":"-"},"content":" String newEmail \u003d studentToUpdate.getEmail();"},{"lineNumber":129,"author":{"gitId":"-"},"content":" studentToUpdate.setEmail(student.getEmail());"},{"lineNumber":130,"author":{"gitId":"-"},"content":" logic.validateSectionsAndTeams(Arrays.asList(studentToUpdate), student.getCourse());"},{"lineNumber":131,"author":{"gitId":"-"},"content":" studentToUpdate.setEmail(newEmail);"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" StudentAttributes updatedStudent \u003d logic.updateStudentCascade("},{"lineNumber":134,"author":{"gitId":"-"},"content":" StudentAttributes.updateOptionsBuilder(courseId, studentEmail)"},{"lineNumber":135,"author":{"gitId":"-"},"content":" .withName(updateRequest.getName())"},{"lineNumber":136,"author":{"gitId":"-"},"content":" .withNewEmail(updateRequest.getEmail())"},{"lineNumber":137,"author":{"gitId":"-"},"content":" .withTeamName(updateRequest.getTeam())"},{"lineNumber":138,"author":{"gitId":"-"},"content":" .withSectionName(updateRequest.getSection())"},{"lineNumber":139,"author":{"gitId":"-"},"content":" .withComment(updateRequest.getComments())"},{"lineNumber":140,"author":{"gitId":"-"},"content":" .build());"},{"lineNumber":141,"author":{"gitId":"-"},"content":" taskQueuer.scheduleStudentForSearchIndexing(updatedStudent.getCourse(), updatedStudent.getEmail());"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" if (!student.getEmail().equals(updateRequest.getEmail())) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" logic.resetStudentGoogleId(updateRequest.getEmail(), courseId);"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" if (updateRequest.getIsSessionSummarySendEmail()) {"},{"lineNumber":147,"author":{"gitId":"-"},"content":" boolean emailSent \u003d sendEmail(courseId, updateRequest.getEmail());"},{"lineNumber":148,"author":{"gitId":"-"},"content":" String statusMessage \u003d emailSent ? SUCCESSFUL_UPDATE_WITH_EMAIL"},{"lineNumber":149,"author":{"gitId":"-"},"content":" : SUCCESSFUL_UPDATE_BUT_EMAIL_FAILED;"},{"lineNumber":150,"author":{"gitId":"-"},"content":" return new JsonResult(statusMessage);"},{"lineNumber":151,"author":{"gitId":"-"},"content":" }"},{"lineNumber":152,"author":{"gitId":"-"},"content":" }"},{"lineNumber":153,"author":{"gitId":"-"},"content":" } catch (EnrollException e) {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(e);"},{"lineNumber":155,"author":{"gitId":"-"},"content":" } catch (InvalidParametersException e) {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" throw new InvalidHttpRequestBodyException(e);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" } catch (EntityDoesNotExistException ednee) {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" throw new EntityNotFoundException(ednee);"},{"lineNumber":159,"author":{"gitId":"-"},"content":" } catch (EntityAlreadyExistsException e) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" throw new InvalidOperationException(\"Trying to update to an email that is already in use\", e);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" return new JsonResult(SUCCESSFUL_UPDATE);"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":167,"author":{"gitId":"-"},"content":" * Sends the feedback session summary as an email."},{"lineNumber":168,"author":{"gitId":"-"},"content":" *"},{"lineNumber":169,"author":{"gitId":"-"},"content":" * @return The true if email was sent successfully or false otherwise."},{"lineNumber":170,"author":{"gitId":"-"},"content":" */"},{"lineNumber":171,"author":{"gitId":"-"},"content":" private boolean sendEmail(String courseId, String studentEmail) {"},{"lineNumber":172,"author":{"gitId":"marquestye"},"content":" if (isCourseMigrated(courseId)) {"},{"lineNumber":173,"author":{"gitId":"marquestye"},"content":" EmailWrapper email \u003d sqlEmailGenerator.generateFeedbackSessionSummaryOfCourse("},{"lineNumber":174,"author":{"gitId":"marquestye"},"content":" courseId, studentEmail, EmailType.STUDENT_EMAIL_CHANGED);"},{"lineNumber":175,"author":{"gitId":"marquestye"},"content":" EmailSendingStatus status \u003d emailSender.sendEmail(email);"},{"lineNumber":176,"author":{"gitId":"marquestye"},"content":" return status.isSuccess();"},{"lineNumber":177,"author":{"gitId":"marquestye"},"content":" } else {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d emailGenerator.generateFeedbackSessionSummaryOfCourse("},{"lineNumber":179,"author":{"gitId":"-"},"content":" courseId, studentEmail, EmailType.STUDENT_EMAIL_CHANGED);"},{"lineNumber":180,"author":{"gitId":"-"},"content":" EmailSendingStatus status \u003d emailSender.sendEmail(email);"},{"lineNumber":181,"author":{"gitId":"-"},"content":" return status.isSuccess();"},{"lineNumber":182,"author":{"gitId":"-"},"content":" }"},{"lineNumber":183,"author":{"gitId":"-"},"content":" }"},{"lineNumber":184,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":185,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":68,"-":117}},{"path":"src/main/resources/instructorEmailTemplate-newAccountRequestAcknowledgement.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"\u003cp\u003eHello, ${name}\u003c/p\u003e"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":" Thank you for submitting an account request. This is what you have submitted:"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"\u003cdiv\u003e"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":" \u003ctable style\u003d\"max-width:600px;border:1px solid black;\"\u003e"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" Full Name"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" ${name}"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" Country \u0026 Institute"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" ${institute}"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" Email Address"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" ${emailAddress}"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" Comments"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" ${comments}"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" \u003c/table\u003e"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":"\u003c/div\u003e"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" Your request will be reviewed within 24 hours. We will send another email once your request has been accepted."},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" If you have any additional queries, please feel free to contact us at ${supportEmail}."},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" Regards,\u003cbr\u003e"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" TEAMMATES Team."},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"}],"authorContributionMap":{"xenosf":65}},{"path":"src/test/java/teammates/common/datatransfer/SqlSessionResultsBundleTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.common.datatransfer;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import java.util.HashMap;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import java.util.HashSet;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import java.util.List;"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import java.util.Map;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":"import org.testng.annotations.Test;"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const;"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":" * SUT: {@link SqlSessionResultsBundle}."},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":"public class SqlSessionResultsBundleTest extends BaseTestCase {"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" public void testGetQuestionResponseMap() {"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" SqlDataBundle responseBundle \u003d loadSqlDataBundle(\"/SqlFeedbackSessionResultsBundleTest.json\");"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" List\u003cString\u003e allExpectedResponses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" allExpectedResponses.add(responseBundle.feedbackResponses.get(\"response1ForQ1\").toString());"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" allExpectedResponses.add(responseBundle.feedbackResponses.get(\"response2ForQ1\").toString());"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" SqlSessionResultsBundle bundle \u003d"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" new SqlSessionResultsBundle("},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.feedbackQuestions.values()),"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(),"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(),"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.feedbackResponses.values()),"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(),"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" new SqlCourseRoster(new ArrayList\u003c\u003e(responseBundle.students.values()),"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.instructors.values()))"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" ______TS(\"Test question having responses\");"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion fq \u003d responseBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e allResponses \u003d bundle.getQuestionResponseMap().get(fq);"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" assertEquals(2, allResponses.size());"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" List\u003cString\u003e allResponsesString \u003d new ArrayList\u003c\u003e();"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" allResponsesString.add(allResponses.get(0).toString());"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" allResponsesString.add(allResponses.get(1).toString());"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" assertEquals(allExpectedResponses, allResponsesString);"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":" ______TS(\"Test question having no responses\");"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" fq \u003d responseBundle.feedbackQuestions.get(\"qn4InSession1InCourse1\");"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" allResponses \u003d bundle.getQuestionResponseMap().get(fq);"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" assertEquals(0, allResponses.size());"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" public void testGetQuestionMissingResponseMap() {"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" SqlDataBundle responseBundle \u003d loadSqlDataBundle(\"/SqlFeedbackSessionResultsBundleTest.json\");"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":" List\u003cString\u003e expectedMissingResponses \u003d new ArrayList\u003c\u003e();"},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":" expectedMissingResponses.add(responseBundle.feedbackResponses.get(\"response1ForQ1\").toString());"},{"lineNumber":67,"author":{"gitId":"xenosf"},"content":" expectedMissingResponses.add(responseBundle.feedbackResponses.get(\"response2ForQ1\").toString());"},{"lineNumber":68,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":" SqlSessionResultsBundle bundle \u003d"},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":" new SqlSessionResultsBundle("},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.feedbackQuestions.values()),"},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(),"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(),"},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(),"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.feedbackResponses.values()),"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" new SqlCourseRoster(new ArrayList\u003c\u003e(responseBundle.students.values()),"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.instructors.values()))"},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":" ______TS(\"Test question having missing responses\");"},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion fq \u003d responseBundle.feedbackQuestions.get(\"qn1InSession1InCourse1\");"},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":" List\u003cFeedbackResponse\u003e missingResponses \u003d bundle.getQuestionMissingResponseMap().get(fq);"},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":" assertEquals(2, missingResponses.size());"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" List\u003cString\u003e missingResponsesString \u003d new ArrayList\u003c\u003e();"},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":" missingResponsesString.add(missingResponses.get(0).toString());"},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" missingResponsesString.add(missingResponses.get(1).toString());"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":" assertEquals(expectedMissingResponses, missingResponsesString);"},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":93,"author":{"gitId":"xenosf"},"content":" ______TS(\"Test question having no missing responses\");"},{"lineNumber":94,"author":{"gitId":"xenosf"},"content":" fq \u003d responseBundle.feedbackQuestions.get(\"qn4InSession1InCourse1\");"},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":" missingResponses \u003d bundle.getQuestionMissingResponseMap().get(fq);"},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":" assertEquals(0, missingResponses.size());"},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":100,"author":{"gitId":"xenosf"},"content":" public void testIsResponseGiverRecipientVisible_typicalCase_shouldReturnCorrectValues() {"},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":102,"author":{"gitId":"xenosf"},"content":" SqlDataBundle responseBundle \u003d loadSqlDataBundle(\"/SqlFeedbackSessionResultsBundleTest.json\");"},{"lineNumber":103,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":104,"author":{"gitId":"xenosf"},"content":" FeedbackSession session1Course1 \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":105,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":106,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question1ForS1C1 \u003d getTypicalFeedbackQuestionForSession(session1Course1);"},{"lineNumber":107,"author":{"gitId":"xenosf"},"content":" FeedbackQuestion question2ForS1C1 \u003d getTypicalFeedbackQuestionForSession(session1Course1);"},{"lineNumber":108,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":109,"author":{"gitId":"xenosf"},"content":" FeedbackResponse response1ForQ1S1C1 \u003d getTypicalFeedbackResponseForQuestion(question1ForS1C1);"},{"lineNumber":110,"author":{"gitId":"xenosf"},"content":" FeedbackResponse response2ForQ1S1C1 \u003d getTypicalFeedbackResponseForQuestion(question1ForS1C1);"},{"lineNumber":111,"author":{"gitId":"xenosf"},"content":" FeedbackResponse response1ForQ2S1C1 \u003d getTypicalFeedbackResponseForQuestion(question2ForS1C1);"},{"lineNumber":112,"author":{"gitId":"xenosf"},"content":" FeedbackResponse response2ForQ2S1C1 \u003d getTypicalFeedbackResponseForQuestion(question2ForS1C1);"},{"lineNumber":113,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":114,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackResponse, Boolean\u003e responseGiverVisibilityTable \u003d new HashMap\u003c\u003e();"},{"lineNumber":115,"author":{"gitId":"xenosf"},"content":" responseGiverVisibilityTable.put(response1ForQ1S1C1, true);"},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" responseGiverVisibilityTable.put(response2ForQ1S1C1, false);"},{"lineNumber":117,"author":{"gitId":"xenosf"},"content":" responseGiverVisibilityTable.put(response1ForQ2S1C1, true);"},{"lineNumber":118,"author":{"gitId":"xenosf"},"content":" responseGiverVisibilityTable.put(response2ForQ2S1C1, false);"},{"lineNumber":119,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":120,"author":{"gitId":"xenosf"},"content":" Map\u003cFeedbackResponse, Boolean\u003e responseRecipientVisibilityTable \u003d new HashMap\u003c\u003e();"},{"lineNumber":121,"author":{"gitId":"xenosf"},"content":" responseRecipientVisibilityTable.put(response1ForQ1S1C1, false);"},{"lineNumber":122,"author":{"gitId":"xenosf"},"content":" responseRecipientVisibilityTable.put(response2ForQ1S1C1, true);"},{"lineNumber":123,"author":{"gitId":"xenosf"},"content":" responseRecipientVisibilityTable.put(response1ForQ2S1C1, true);"},{"lineNumber":124,"author":{"gitId":"xenosf"},"content":" responseRecipientVisibilityTable.put(response2ForQ2S1C1, false);"},{"lineNumber":125,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":126,"author":{"gitId":"xenosf"},"content":" SqlSessionResultsBundle bundle \u003d"},{"lineNumber":127,"author":{"gitId":"xenosf"},"content":" new SqlSessionResultsBundle("},{"lineNumber":128,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.feedbackQuestions.values()),"},{"lineNumber":129,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(),"},{"lineNumber":130,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(),"},{"lineNumber":131,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.feedbackResponses.values()),"},{"lineNumber":132,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(),"},{"lineNumber":133,"author":{"gitId":"xenosf"},"content":" responseGiverVisibilityTable,"},{"lineNumber":134,"author":{"gitId":"xenosf"},"content":" responseRecipientVisibilityTable,"},{"lineNumber":135,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":136,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":137,"author":{"gitId":"xenosf"},"content":" new SqlCourseRoster(new ArrayList\u003c\u003e(responseBundle.students.values()),"},{"lineNumber":138,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.instructors.values()))"},{"lineNumber":139,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":140,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":141,"author":{"gitId":"xenosf"},"content":" for (Map.Entry\u003cFeedbackResponse, Boolean\u003e visibilityEntry : responseGiverVisibilityTable.entrySet()) {"},{"lineNumber":142,"author":{"gitId":"xenosf"},"content":" assertEquals(visibilityEntry.getValue(),"},{"lineNumber":143,"author":{"gitId":"xenosf"},"content":" bundle.isResponseGiverVisible(visibilityEntry.getKey()));"},{"lineNumber":144,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":145,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":146,"author":{"gitId":"xenosf"},"content":" for (Map.Entry\u003cFeedbackResponse, Boolean\u003e visibilityEntry : responseRecipientVisibilityTable.entrySet()) {"},{"lineNumber":147,"author":{"gitId":"xenosf"},"content":" assertEquals(visibilityEntry.getValue(),"},{"lineNumber":148,"author":{"gitId":"xenosf"},"content":" bundle.isResponseRecipientVisible(visibilityEntry.getKey()));"},{"lineNumber":149,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":150,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":151,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":152,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":153,"author":{"gitId":"xenosf"},"content":" public void testIsCommentGiverVisible_typicalCase_shouldReturnCorrectValues() {"},{"lineNumber":154,"author":{"gitId":"xenosf"},"content":" SqlDataBundle responseBundle \u003d loadSqlDataBundle(\"/SqlFeedbackSessionResultsBundleTest.json\");"},{"lineNumber":155,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":156,"author":{"gitId":"xenosf"},"content":" Map\u003cLong, Boolean\u003e commentGiverVisibilityTable \u003d new HashMap\u003c\u003e();"},{"lineNumber":157,"author":{"gitId":"xenosf"},"content":" commentGiverVisibilityTable.put(1L, true);"},{"lineNumber":158,"author":{"gitId":"xenosf"},"content":" commentGiverVisibilityTable.put(2L, false);"},{"lineNumber":159,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":160,"author":{"gitId":"xenosf"},"content":" SqlSessionResultsBundle bundle \u003d"},{"lineNumber":161,"author":{"gitId":"xenosf"},"content":" new SqlSessionResultsBundle("},{"lineNumber":162,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.feedbackQuestions.values()),"},{"lineNumber":163,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(),"},{"lineNumber":164,"author":{"gitId":"xenosf"},"content":" new HashSet\u003c\u003e(),"},{"lineNumber":165,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.feedbackResponses.values()),"},{"lineNumber":166,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(),"},{"lineNumber":167,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":168,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":169,"author":{"gitId":"xenosf"},"content":" new HashMap\u003c\u003e(),"},{"lineNumber":170,"author":{"gitId":"xenosf"},"content":" commentGiverVisibilityTable,"},{"lineNumber":171,"author":{"gitId":"xenosf"},"content":" new SqlCourseRoster(new ArrayList\u003c\u003e(responseBundle.students.values()),"},{"lineNumber":172,"author":{"gitId":"xenosf"},"content":" new ArrayList\u003c\u003e(responseBundle.instructors.values()))"},{"lineNumber":173,"author":{"gitId":"xenosf"},"content":" );"},{"lineNumber":174,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":175,"author":{"gitId":"xenosf"},"content":" // Manually add comment IDs as loadSqlDataBundle does not add comment IDs"},{"lineNumber":176,"author":{"gitId":"xenosf"},"content":" FeedbackResponseComment comment1 \u003d responseBundle.feedbackResponseComments.get(\"comment1ToResponse1ForQ1\");"},{"lineNumber":177,"author":{"gitId":"xenosf"},"content":" FeedbackResponseComment comment2 \u003d responseBundle.feedbackResponseComments.get(\"comment2ToResponse1ForQ1\");"},{"lineNumber":178,"author":{"gitId":"xenosf"},"content":" comment1.setId(1L);"},{"lineNumber":179,"author":{"gitId":"xenosf"},"content":" comment2.setId(2L);"},{"lineNumber":180,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":181,"author":{"gitId":"xenosf"},"content":" assertTrue(bundle.isCommentGiverVisible(comment1));"},{"lineNumber":182,"author":{"gitId":"xenosf"},"content":" assertFalse(bundle.isCommentGiverVisible(comment2));"},{"lineNumber":183,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":184,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":185,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":186,"author":{"gitId":"xenosf"},"content":" public void testGetAnonName_typicalCase_shouldGenerateCorrectly() {"},{"lineNumber":187,"author":{"gitId":"xenosf"},"content":" String anonName \u003d SqlSessionResultsBundle.getAnonName(FeedbackParticipantType.STUDENTS, \"\");"},{"lineNumber":188,"author":{"gitId":"xenosf"},"content":" assertTrue(anonName.startsWith(Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT));"},{"lineNumber":189,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":190,"author":{"gitId":"xenosf"},"content":" anonName \u003d SqlSessionResultsBundle.getAnonName(FeedbackParticipantType.STUDENTS, \"test@gmail.com\");"},{"lineNumber":191,"author":{"gitId":"xenosf"},"content":" assertTrue(anonName.startsWith(Const.DISPLAYED_NAME_FOR_ANONYMOUS_PARTICIPANT));"},{"lineNumber":192,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":193,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":193}},{"path":"src/test/java/teammates/common/util/FieldValidatorTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.util;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Duration;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.temporal.ChronoUnit;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"-"},"content":" * SUT: {@link FieldValidator}."},{"lineNumber":15,"author":{"gitId":"-"},"content":" */"},{"lineNumber":16,"author":{"gitId":"-"},"content":"public class FieldValidatorTest extends BaseTestCase {"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":19,"author":{"gitId":"-"},"content":" public void testGetValidityInfoForNonHtmlField_cleanInput_returnEmptyString() {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" String clean \u003d \"Valid clean input with no special HTML characters\";"},{"lineNumber":21,"author":{"gitId":"-"},"content":" String testFieldName \u003d \"Inconsequential test field name\";"},{"lineNumber":22,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getValidityInfoForNonHtmlField(testFieldName, clean);"},{"lineNumber":23,"author":{"gitId":"-"},"content":" assertEquals(\"Valid clean input with no special HTML characters should return empty string\", \"\","},{"lineNumber":24,"author":{"gitId":"-"},"content":" actual);"},{"lineNumber":25,"author":{"gitId":"-"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":28,"author":{"gitId":"-"},"content":" public void testGetValidityInfoForNonHtmlField_sanitizedInput_returnEmptyString() {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" String sanitizedInput \u003d \"Valid sanitized input \u0026lt; \u0026gt; \u0026quot; \u0026#x2f; \u0026#39; \u0026amp;\";"},{"lineNumber":30,"author":{"gitId":"-"},"content":" String testFieldName \u003d \"Inconsequential test field name\";"},{"lineNumber":31,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getValidityInfoForNonHtmlField(testFieldName, sanitizedInput);"},{"lineNumber":32,"author":{"gitId":"-"},"content":" assertEquals(\"Valid sanitized input should return empty string\", \"\", actual);"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":36,"author":{"gitId":"-"},"content":" public void testGetValidityInfoForNonHtmlField_unsanitizedInput_returnErrorString() {"},{"lineNumber":37,"author":{"gitId":"-"},"content":" String unsanitizedInput \u003d \"Invalid unsanitized input \u003c\u003e\\\"/\u0027\u0026\";"},{"lineNumber":38,"author":{"gitId":"-"},"content":" String testFieldName \u003d \"Inconsequential test field name\";"},{"lineNumber":39,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getValidityInfoForNonHtmlField(testFieldName, unsanitizedInput);"},{"lineNumber":40,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid unsanitized input should return error string\","},{"lineNumber":41,"author":{"gitId":"-"},"content":" \"The provided Inconsequential test field name is not acceptable to TEAMMATES as it \""},{"lineNumber":42,"author":{"gitId":"-"},"content":" + \"cannot contain the following special html characters in brackets: (\u003c \u003e \\\" / \u0027 \u0026)\","},{"lineNumber":43,"author":{"gitId":"-"},"content":" actual);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" }"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":47,"author":{"gitId":"-"},"content":" public void testGetValidityInfoForSizeCappedPossiblyEmptyString() {"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" String typicalFieldName \u003d \"my field\";"},{"lineNumber":50,"author":{"gitId":"-"},"content":" int maxLength \u003d 50;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" assertEquals(\"valid: typical value\","},{"lineNumber":52,"author":{"gitId":"-"},"content":" \"\","},{"lineNumber":53,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForSizeCappedPossiblyEmptyString("},{"lineNumber":54,"author":{"gitId":"-"},"content":" typicalFieldName,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" maxLength,"},{"lineNumber":56,"author":{"gitId":"-"},"content":" \"Dr. Amy-B s/o O\u0027br, \u0026 2nd \\t \\n (alias \u0027JB\u0027)\"));"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" assertEquals(\"valid: max length\","},{"lineNumber":59,"author":{"gitId":"-"},"content":" \"\","},{"lineNumber":60,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForSizeCappedPossiblyEmptyString("},{"lineNumber":61,"author":{"gitId":"-"},"content":" typicalFieldName,"},{"lineNumber":62,"author":{"gitId":"-"},"content":" maxLength,"},{"lineNumber":63,"author":{"gitId":"-"},"content":" StringHelperExtension.generateStringOfLength(maxLength)));"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" String emptyValue \u003d \"\";"},{"lineNumber":66,"author":{"gitId":"-"},"content":" assertEquals(\"valid: empty\","},{"lineNumber":67,"author":{"gitId":"-"},"content":" \"\","},{"lineNumber":68,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForSizeCappedPossiblyEmptyString("},{"lineNumber":69,"author":{"gitId":"-"},"content":" typicalFieldName,"},{"lineNumber":70,"author":{"gitId":"-"},"content":" maxLength,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" emptyValue));"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" String untrimmedValue \u003d \" abc \";"},{"lineNumber":74,"author":{"gitId":"-"},"content":" assertEquals(\"invalid: untrimmed\","},{"lineNumber":75,"author":{"gitId":"-"},"content":" \"The provided my field is not acceptable to TEAMMATES as it contains only whitespace or \""},{"lineNumber":76,"author":{"gitId":"-"},"content":" + \"contains extra spaces at the beginning or at the end of the text.\","},{"lineNumber":77,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForSizeCappedPossiblyEmptyString(typicalFieldName, maxLength,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" untrimmedValue));"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" String tooLongName \u003d StringHelperExtension.generateStringOfLength(maxLength + 1);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" assertEquals(\"invalid: too long\","},{"lineNumber":82,"author":{"gitId":"-"},"content":" \"\\\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\" is not acceptable to TEAMMATES \""},{"lineNumber":83,"author":{"gitId":"-"},"content":" + \"as a/an my field because it is too long. The value of a/an my field should be no \""},{"lineNumber":84,"author":{"gitId":"-"},"content":" + \"longer than 50 characters.\","},{"lineNumber":85,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForSizeCappedPossiblyEmptyString(typicalFieldName, maxLength,"},{"lineNumber":86,"author":{"gitId":"-"},"content":" tooLongName));"},{"lineNumber":87,"author":{"gitId":"-"},"content":" }"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":90,"author":{"gitId":"-"},"content":" public void testGetValidityInfoForAllowedName() {"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" ______TS(\"null value\");"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" String typicalFieldName \u003d \"name field\";"},{"lineNumber":95,"author":{"gitId":"-"},"content":" int typicalLength \u003d 25;"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" assertThrows(AssertionError.class, () -\u003e"},{"lineNumber":98,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName(typicalFieldName, typicalLength, null));"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" ______TS(\"typical success case\");"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" int maxLength \u003d 50;"},{"lineNumber":103,"author":{"gitId":"-"},"content":" assertEquals(\"valid: typical length with valid characters\","},{"lineNumber":104,"author":{"gitId":"-"},"content":" \"\","},{"lineNumber":105,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName("},{"lineNumber":106,"author":{"gitId":"-"},"content":" typicalFieldName,"},{"lineNumber":107,"author":{"gitId":"-"},"content":" maxLength,"},{"lineNumber":108,"author":{"gitId":"-"},"content":" \"Ýàn-B. s/o O\u0027br, \u00262\\t\\n(~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\"));"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" ______TS(\"failure: invalid characters\");"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" String nameContainInvalidChars \u003d \"Dr. Amy-Bén s/o O\u0027\u0026|% 2\\t\\n (~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\";"},{"lineNumber":113,"author":{"gitId":"-"},"content":" assertEquals(\"invalid: typical length with invalid characters\","},{"lineNumber":114,"author":{"gitId":"-"},"content":" \"\\\"Dr. Amy-Bén s/o O\u0027\u0026|% 2\\t\\n (~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\\\" is \""},{"lineNumber":115,"author":{"gitId":"-"},"content":" + \"not acceptable to TEAMMATES as a/an name field because it contains invalid \""},{"lineNumber":116,"author":{"gitId":"-"},"content":" + \"characters. A/An name field must start with an alphanumeric character, and cannot \""},{"lineNumber":117,"author":{"gitId":"-"},"content":" + \"contain any vertical bar (|) or percent sign (%).\","},{"lineNumber":118,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName(typicalFieldName, maxLength,"},{"lineNumber":119,"author":{"gitId":"-"},"content":" nameContainInvalidChars));"},{"lineNumber":120,"author":{"gitId":"-"},"content":""},{"lineNumber":121,"author":{"gitId":"-"},"content":" ______TS(\"failure: starts with non-alphanumeric character\");"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" String nameStartedWithNonAlphaNumChar \u003d \"!Amy-Bén s/o O\u0027\u0026|% 2\\t\\n (~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\";"},{"lineNumber":124,"author":{"gitId":"-"},"content":" assertEquals(\"invalid: typical length with invalid characters\","},{"lineNumber":125,"author":{"gitId":"-"},"content":" \"\\\"!Amy-Bén s/o O\u0027\u0026|% 2\\t\\n (~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\\\" is not \""},{"lineNumber":126,"author":{"gitId":"-"},"content":" + \"acceptable to TEAMMATES as a/an name field because it starts with a \""},{"lineNumber":127,"author":{"gitId":"-"},"content":" + \"non-alphanumeric character. A/An name field must start with an alphanumeric \""},{"lineNumber":128,"author":{"gitId":"-"},"content":" + \"character, and cannot contain any vertical bar (|) or percent sign (%).\","},{"lineNumber":129,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName(typicalFieldName, maxLength,"},{"lineNumber":130,"author":{"gitId":"-"},"content":" nameStartedWithNonAlphaNumChar));"},{"lineNumber":131,"author":{"gitId":"-"},"content":""},{"lineNumber":132,"author":{"gitId":"-"},"content":" ______TS(\"failure: starts with curly braces but contains invalid char\");"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" String nameStartedWithBracesButHasInvalidChar \u003d \"{Amy} -Bén s/o O\u0027\u0026|% 2\\t\\n (~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\";"},{"lineNumber":135,"author":{"gitId":"-"},"content":" assertEquals(\"invalid: typical length with invalid characters\","},{"lineNumber":136,"author":{"gitId":"-"},"content":" \"\\\"{Amy} -Bén s/o O\u0027\u0026|% 2\\t\\n (~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\\\" is not \""},{"lineNumber":137,"author":{"gitId":"-"},"content":" + \"acceptable to TEAMMATES as a/an name field because it contains invalid \""},{"lineNumber":138,"author":{"gitId":"-"},"content":" + \"characters. A/An name field must start with an alphanumeric character, and cannot \""},{"lineNumber":139,"author":{"gitId":"-"},"content":" + \"contain any vertical bar (|) or percent sign (%).\","},{"lineNumber":140,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName(typicalFieldName, maxLength,"},{"lineNumber":141,"author":{"gitId":"-"},"content":" nameStartedWithBracesButHasInvalidChar));"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" ______TS(\"failure: starts with opening curly bracket but dose not have closing bracket\");"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" String nameStartedWithCurlyBracketButHasNoEnd \u003d \"{Amy -Bén s/o O\u0027\u0026|% 2\\t\\n (~!@#$^*+_\u003d{[]\\\\:;\\\"\u003c\u003e?)\";"},{"lineNumber":146,"author":{"gitId":"-"},"content":" assertEquals(\"invalid: typical length started with non-alphanumeric character\","},{"lineNumber":147,"author":{"gitId":"-"},"content":" \"\\\"{Amy -Bén s/o O\u0027\u0026|% 2\\t\\n (~!@#$^*+_\u003d{[]\\\\:;\\\"\u003c\u003e?)\\\" is not \""},{"lineNumber":148,"author":{"gitId":"-"},"content":" + \"acceptable to TEAMMATES as a/an name field because it starts with a \""},{"lineNumber":149,"author":{"gitId":"-"},"content":" + \"non-alphanumeric character. A/An name field must start with an alphanumeric \""},{"lineNumber":150,"author":{"gitId":"-"},"content":" + \"character, and cannot contain any vertical bar (|) or percent sign (%).\","},{"lineNumber":151,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName(typicalFieldName, maxLength,"},{"lineNumber":152,"author":{"gitId":"-"},"content":" nameStartedWithCurlyBracketButHasNoEnd));"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"-"},"content":" ______TS(\"success: with opening and closing curly braces\");"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" assertEquals(\"valid: max length\","},{"lineNumber":157,"author":{"gitId":"-"},"content":" \"\","},{"lineNumber":158,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName("},{"lineNumber":159,"author":{"gitId":"-"},"content":" typicalFieldName,"},{"lineNumber":160,"author":{"gitId":"-"},"content":" maxLength,"},{"lineNumber":161,"author":{"gitId":"-"},"content":" \"{last name} first name\"));"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" ______TS(\"success: max length\");"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" assertEquals(\"valid: max length\","},{"lineNumber":166,"author":{"gitId":"-"},"content":" \"\","},{"lineNumber":167,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName("},{"lineNumber":168,"author":{"gitId":"-"},"content":" typicalFieldName,"},{"lineNumber":169,"author":{"gitId":"-"},"content":" maxLength,"},{"lineNumber":170,"author":{"gitId":"-"},"content":" StringHelperExtension.generateStringOfLength(maxLength)));"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" ______TS(\"failure: too long\");"},{"lineNumber":173,"author":{"gitId":"-"},"content":""},{"lineNumber":174,"author":{"gitId":"-"},"content":" String tooLongName \u003d StringHelperExtension.generateStringOfLength(maxLength + 1);"},{"lineNumber":175,"author":{"gitId":"-"},"content":" assertEquals(\"invalid: too long\","},{"lineNumber":176,"author":{"gitId":"-"},"content":" \"\\\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\" is not acceptable to TEAMMATES \""},{"lineNumber":177,"author":{"gitId":"-"},"content":" + \"as a/an name field because it is too long. The value of a/an name field should \""},{"lineNumber":178,"author":{"gitId":"-"},"content":" + \"be no longer than 50 characters. It should not be empty.\","},{"lineNumber":179,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName(typicalFieldName, maxLength, tooLongName));"},{"lineNumber":180,"author":{"gitId":"-"},"content":""},{"lineNumber":181,"author":{"gitId":"-"},"content":" ______TS(\"failure: empty string\");"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" String emptyValue \u003d \"\";"},{"lineNumber":184,"author":{"gitId":"-"},"content":" assertEquals(\"invalid: empty\","},{"lineNumber":185,"author":{"gitId":"-"},"content":" \"The field \u0027name field\u0027 is empty. The value of a/an name field should be no longer \""},{"lineNumber":186,"author":{"gitId":"-"},"content":" + \"than 50 characters. It should not be empty.\","},{"lineNumber":187,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName(typicalFieldName, maxLength, emptyValue));"},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":" ______TS(\"failure: untrimmed value\");"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" String untrimmedValue \u003d \" abc \";"},{"lineNumber":192,"author":{"gitId":"-"},"content":" assertEquals(\"invalid: untrimmed\","},{"lineNumber":193,"author":{"gitId":"-"},"content":" \"The provided name field is not acceptable to TEAMMATES as it contains only whitespace \""},{"lineNumber":194,"author":{"gitId":"-"},"content":" + \"or contains extra spaces at the beginning or at the end of the text.\","},{"lineNumber":195,"author":{"gitId":"-"},"content":" FieldValidator.getValidityInfoForAllowedName(typicalFieldName, maxLength, untrimmedValue));"},{"lineNumber":196,"author":{"gitId":"-"},"content":" }"},{"lineNumber":197,"author":{"gitId":"-"},"content":""},{"lineNumber":198,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":199,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForPersonName_invalid_returnSpecificErrorString() {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" String invalidPersonName \u003d \"\";"},{"lineNumber":201,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getInvalidityInfoForPersonName(invalidPersonName);"},{"lineNumber":202,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid person name (empty) should return error message that is specific to person name\","},{"lineNumber":203,"author":{"gitId":"-"},"content":" \"The field \u0027person name\u0027 is empty. The value of a/an person name should be no longer \""},{"lineNumber":204,"author":{"gitId":"-"},"content":" + \"than 100 characters. It should not be empty.\","},{"lineNumber":205,"author":{"gitId":"-"},"content":" actual);"},{"lineNumber":206,"author":{"gitId":"-"},"content":" }"},{"lineNumber":207,"author":{"gitId":"-"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":209,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForInstituteName_invalid_returnSpecificErrorString() {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" String invalidInstituteName \u003d StringHelperExtension.generateStringOfLength("},{"lineNumber":211,"author":{"gitId":"-"},"content":" FieldValidator.INSTITUTE_NAME_MAX_LENGTH + 1);"},{"lineNumber":212,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getInvalidityInfoForInstituteName(invalidInstituteName);"},{"lineNumber":213,"author":{"gitId":"xenosf"},"content":" String expectedTemplate \u003d \"\\\"%s\\\" is not \""},{"lineNumber":214,"author":{"gitId":"-"},"content":" + \"acceptable to TEAMMATES as a/an institute name because it is too long. The value \""},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" + \"of a/an institute name should be no longer than 128 characters. It should not be empty.\";"},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" String expected \u003d String.format(expectedTemplate, invalidInstituteName);"},{"lineNumber":217,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid institute name (too long) should return error message that is specific to institute name\","},{"lineNumber":218,"author":{"gitId":"xenosf"},"content":" expected, actual);"},{"lineNumber":219,"author":{"gitId":"-"},"content":" }"},{"lineNumber":220,"author":{"gitId":"-"},"content":""},{"lineNumber":221,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":222,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTeamName_invalid_returnSpecificErrorString() {"},{"lineNumber":223,"author":{"gitId":"-"},"content":" String invalidTeamName \u003d \"\";"},{"lineNumber":224,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getInvalidityInfoForTeamName(invalidTeamName);"},{"lineNumber":225,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid team name (empty) should return error message that is specific to team name\","},{"lineNumber":226,"author":{"gitId":"-"},"content":" \"The field \u0027team name\u0027 is empty. The value of a/an team name should be no longer \""},{"lineNumber":227,"author":{"gitId":"-"},"content":" + \"than 60 characters. It should not be empty.\","},{"lineNumber":228,"author":{"gitId":"-"},"content":" actual);"},{"lineNumber":229,"author":{"gitId":"-"},"content":" }"},{"lineNumber":230,"author":{"gitId":"-"},"content":""},{"lineNumber":231,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":232,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForSectionName_invalid_returnSpecificErrorString() {"},{"lineNumber":233,"author":{"gitId":"-"},"content":" String invalidSectionName \u003d \"Percent Symbol % Section\";"},{"lineNumber":234,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getInvalidityInfoForSectionName(invalidSectionName);"},{"lineNumber":235,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid section name (invalid char) should return error string that is specific to section name\","},{"lineNumber":236,"author":{"gitId":"-"},"content":" \"\\\"Percent Symbol % Section\\\" is not acceptable to TEAMMATES as a/an section name \""},{"lineNumber":237,"author":{"gitId":"-"},"content":" + \"because it contains invalid characters. A/An section name must start with an \""},{"lineNumber":238,"author":{"gitId":"-"},"content":" + \"alphanumeric character, and cannot contain any vertical bar (|) or percent sign (%).\","},{"lineNumber":239,"author":{"gitId":"-"},"content":" actual);"},{"lineNumber":240,"author":{"gitId":"-"},"content":" }"},{"lineNumber":241,"author":{"gitId":"-"},"content":""},{"lineNumber":242,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":243,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForCourseName_invalid_returnSpecificErrorString() {"},{"lineNumber":244,"author":{"gitId":"-"},"content":" String invalidCourseName \u003d \"Vertical Bar | Course\";"},{"lineNumber":245,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getInvalidityInfoForCourseName(invalidCourseName);"},{"lineNumber":246,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid course name (invalid char) should return error string that is specific to course name\","},{"lineNumber":247,"author":{"gitId":"-"},"content":" \"\\\"Vertical Bar | Course\\\" is not acceptable to TEAMMATES as a/an course name because \""},{"lineNumber":248,"author":{"gitId":"-"},"content":" + \"it contains invalid characters. A/An course name must start with an alphanumeric \""},{"lineNumber":249,"author":{"gitId":"-"},"content":" + \"character, and cannot contain any vertical bar (|) or percent sign (%).\","},{"lineNumber":250,"author":{"gitId":"-"},"content":" actual);"},{"lineNumber":251,"author":{"gitId":"-"},"content":" }"},{"lineNumber":252,"author":{"gitId":"-"},"content":""},{"lineNumber":253,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":254,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForFeedbackSessionName_invalid_returnSpecificErrorString() {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" String invalidSessionName \u003d StringHelperExtension.generateStringOfLength("},{"lineNumber":256,"author":{"gitId":"-"},"content":" FieldValidator.FEEDBACK_SESSION_NAME_MAX_LENGTH + 1);"},{"lineNumber":257,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getInvalidityInfoForFeedbackSessionName(invalidSessionName);"},{"lineNumber":258,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid feedback session name (too long) should return error message specific to feedback \""},{"lineNumber":259,"author":{"gitId":"-"},"content":" + \"session name\","},{"lineNumber":260,"author":{"gitId":"-"},"content":" \"\\\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\" \""},{"lineNumber":261,"author":{"gitId":"-"},"content":" + \"is not acceptable to TEAMMATES as a/an feedback session name because it is too long. \""},{"lineNumber":262,"author":{"gitId":"-"},"content":" + \"The value of a/an feedback session name should be no longer than 64 characters. \""},{"lineNumber":263,"author":{"gitId":"-"},"content":" + \"It should not be empty.\","},{"lineNumber":264,"author":{"gitId":"-"},"content":" actual);"},{"lineNumber":265,"author":{"gitId":"-"},"content":" }"},{"lineNumber":266,"author":{"gitId":"-"},"content":""},{"lineNumber":267,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":268,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForRole_null_throwException() {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" assertThrows(AssertionError.class, () -\u003e FieldValidator.getInvalidityInfoForRole(null));"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":273,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForRole_valid_returnEmptyString() {"},{"lineNumber":274,"author":{"gitId":"-"},"content":" String validRole \u003d Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_COOWNER;"},{"lineNumber":275,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getInvalidityInfoForRole(validRole);"},{"lineNumber":276,"author":{"gitId":"-"},"content":" assertEquals(\"Valid role should return empty string\", \"\", actual);"},{"lineNumber":277,"author":{"gitId":"-"},"content":" }"},{"lineNumber":278,"author":{"gitId":"-"},"content":""},{"lineNumber":279,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":280,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForRole_invalid_returnErrorString() {"},{"lineNumber":281,"author":{"gitId":"-"},"content":" String invalidRole \u003d \"student leader\";"},{"lineNumber":282,"author":{"gitId":"-"},"content":" String actual \u003d FieldValidator.getInvalidityInfoForRole(invalidRole);"},{"lineNumber":283,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid role should return appropriate error string\","},{"lineNumber":284,"author":{"gitId":"-"},"content":" String.format(FieldValidator.ROLE_ERROR_MESSAGE, invalidRole),"},{"lineNumber":285,"author":{"gitId":"-"},"content":" actual);"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"-"},"content":" invalidRole \u003d \"\u003cscript\u003e alert(\u0027hi!\u0027); \u003c/script\u003e\";"},{"lineNumber":288,"author":{"gitId":"-"},"content":" actual \u003d FieldValidator.getInvalidityInfoForRole(invalidRole);"},{"lineNumber":289,"author":{"gitId":"-"},"content":" assertEquals(\"Unsanitized, invalid role should return appropriate error string\","},{"lineNumber":290,"author":{"gitId":"-"},"content":" String.format(FieldValidator.ROLE_ERROR_MESSAGE, invalidRole), actual);"},{"lineNumber":291,"author":{"gitId":"-"},"content":" }"},{"lineNumber":292,"author":{"gitId":"-"},"content":""},{"lineNumber":293,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":294,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForGoogleId_null_throwException() {"},{"lineNumber":295,"author":{"gitId":"-"},"content":" assertThrows(AssertionError.class, () -\u003e FieldValidator.getInvalidityInfoForGoogleId(null));"},{"lineNumber":296,"author":{"gitId":"-"},"content":" }"},{"lineNumber":297,"author":{"gitId":"-"},"content":""},{"lineNumber":298,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":299,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForGoogleId_valid_returnEmptyString() {"},{"lineNumber":300,"author":{"gitId":"-"},"content":" String typicalId \u003d \"valid9.Goo-gle.id_\";"},{"lineNumber":301,"author":{"gitId":"-"},"content":" assertEquals(\"Valid Google ID (typical) should return empty string\", \"\","},{"lineNumber":302,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(typicalId));"},{"lineNumber":303,"author":{"gitId":"-"},"content":""},{"lineNumber":304,"author":{"gitId":"-"},"content":" String shortId \u003d \"e\";"},{"lineNumber":305,"author":{"gitId":"-"},"content":" assertEquals(\"Valid Google ID (short) should return empty string\", \"\","},{"lineNumber":306,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(shortId));"},{"lineNumber":307,"author":{"gitId":"-"},"content":""},{"lineNumber":308,"author":{"gitId":"-"},"content":" String emailAsId \u003d \"someone@yahoo.com\";"},{"lineNumber":309,"author":{"gitId":"-"},"content":" assertEquals(\"Valid Google ID (typical email) should return empty string\", \"\","},{"lineNumber":310,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(emailAsId));"},{"lineNumber":311,"author":{"gitId":"-"},"content":""},{"lineNumber":312,"author":{"gitId":"-"},"content":" String shortEmailAsId \u003d \"e@y.c\";"},{"lineNumber":313,"author":{"gitId":"-"},"content":" assertEquals(\"Valid Google ID (short email) should return empty string\", \"\","},{"lineNumber":314,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(shortEmailAsId));"},{"lineNumber":315,"author":{"gitId":"-"},"content":""},{"lineNumber":316,"author":{"gitId":"-"},"content":" String maxLengthId \u003d StringHelperExtension.generateStringOfLength(FieldValidator.GOOGLE_ID_MAX_LENGTH);"},{"lineNumber":317,"author":{"gitId":"-"},"content":" assertEquals(\"Valid Google ID (max length) should return empty string\", \"\","},{"lineNumber":318,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(maxLengthId));"},{"lineNumber":319,"author":{"gitId":"-"},"content":" }"},{"lineNumber":320,"author":{"gitId":"-"},"content":""},{"lineNumber":321,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":322,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForGoogleId_invalid_returnErrorString() {"},{"lineNumber":323,"author":{"gitId":"-"},"content":" String emptyId \u003d \"\";"},{"lineNumber":324,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Google ID (empty) should return appropriate error message\","},{"lineNumber":325,"author":{"gitId":"-"},"content":" \"The field \u0027Google ID\u0027 is empty. A Google ID must be a valid id \""},{"lineNumber":326,"author":{"gitId":"-"},"content":" + \"already registered with Google. It cannot be longer than \""},{"lineNumber":327,"author":{"gitId":"-"},"content":" + \"254 characters, cannot be empty and cannot contain spaces.\","},{"lineNumber":328,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(emptyId));"},{"lineNumber":329,"author":{"gitId":"-"},"content":""},{"lineNumber":330,"author":{"gitId":"-"},"content":" String whitespaceId \u003d \" \";"},{"lineNumber":331,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Google ID (contains whitespaces only) should return appropriate error message\","},{"lineNumber":332,"author":{"gitId":"-"},"content":" FieldValidator.WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace("},{"lineNumber":333,"author":{"gitId":"-"},"content":" \"${fieldName}\", FieldValidator.GOOGLE_ID_FIELD_NAME),"},{"lineNumber":334,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(whitespaceId));"},{"lineNumber":335,"author":{"gitId":"-"},"content":""},{"lineNumber":336,"author":{"gitId":"-"},"content":" String untrimmedId \u003d \" googleIdWithSpacesAround \";"},{"lineNumber":337,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Google ID (leading/trailing whitespaces) should return appropriate error message\","},{"lineNumber":338,"author":{"gitId":"-"},"content":" FieldValidator.WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace("},{"lineNumber":339,"author":{"gitId":"-"},"content":" \"${fieldName}\", FieldValidator.GOOGLE_ID_FIELD_NAME),"},{"lineNumber":340,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(untrimmedId));"},{"lineNumber":341,"author":{"gitId":"-"},"content":""},{"lineNumber":342,"author":{"gitId":"-"},"content":" String tooLongId \u003d StringHelperExtension.generateStringOfLength(FieldValidator.GOOGLE_ID_MAX_LENGTH + 1);"},{"lineNumber":343,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Google ID (too long) should return appropriate error message\","},{"lineNumber":344,"author":{"gitId":"-"},"content":" \"\\\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\""},{"lineNumber":345,"author":{"gitId":"-"},"content":" + \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\""},{"lineNumber":346,"author":{"gitId":"-"},"content":" + \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\""},{"lineNumber":347,"author":{"gitId":"-"},"content":" + \"aaaaaaaa\\\" is not acceptable to TEAMMATES as a/an Google ID because it is too \""},{"lineNumber":348,"author":{"gitId":"-"},"content":" + \"long. A Google ID must be a valid id already registered with Google. It cannot \""},{"lineNumber":349,"author":{"gitId":"-"},"content":" + \"be longer than 254 characters, cannot be empty and cannot contain spaces.\","},{"lineNumber":350,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(tooLongId));"},{"lineNumber":351,"author":{"gitId":"-"},"content":""},{"lineNumber":352,"author":{"gitId":"-"},"content":" String idWithSpaces \u003d \"invalid google id with spaces\";"},{"lineNumber":353,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Google ID (with spaces) should return appropriate error message\","},{"lineNumber":354,"author":{"gitId":"-"},"content":" \"\\\"invalid google id with spaces\\\" is not acceptable to TEAMMATES as a/an Google ID \""},{"lineNumber":355,"author":{"gitId":"-"},"content":" + \"because it is not in the correct format. A Google ID must be a valid id already \""},{"lineNumber":356,"author":{"gitId":"-"},"content":" + \"registered with Google. It cannot be longer than 254 characters, cannot be empty \""},{"lineNumber":357,"author":{"gitId":"-"},"content":" + \"and cannot contain spaces.\","},{"lineNumber":358,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(idWithSpaces));"},{"lineNumber":359,"author":{"gitId":"-"},"content":""},{"lineNumber":360,"author":{"gitId":"-"},"content":" String idWithInvalidHtmlChar \u003d \"invalid google id with HTML/\u003c special characters\";"},{"lineNumber":361,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Google ID (contains HTML characters) should return appropriate error message\","},{"lineNumber":362,"author":{"gitId":"-"},"content":" \"\\\"invalid google id with HTML/\u003c special characters\\\" is not acceptable to \""},{"lineNumber":363,"author":{"gitId":"-"},"content":" + \"TEAMMATES as a/an Google ID because it is not in the correct format. A Google ID \""},{"lineNumber":364,"author":{"gitId":"-"},"content":" + \"must be a valid id already registered with Google. It cannot be longer than 254 \""},{"lineNumber":365,"author":{"gitId":"-"},"content":" + \"characters, cannot be empty and cannot contain spaces.\","},{"lineNumber":366,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForGoogleId(idWithInvalidHtmlChar));"},{"lineNumber":367,"author":{"gitId":"-"},"content":" }"},{"lineNumber":368,"author":{"gitId":"-"},"content":""},{"lineNumber":369,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":370,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForEmail_null_throwException() {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" assertThrows(AssertionError.class, () -\u003e FieldValidator.getInvalidityInfoForEmail(null));"},{"lineNumber":372,"author":{"gitId":"-"},"content":" }"},{"lineNumber":373,"author":{"gitId":"-"},"content":""},{"lineNumber":374,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":375,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForEmail_valid_returnEmptyString() {"},{"lineNumber":376,"author":{"gitId":"-"},"content":" String typicalEmail \u003d \"someone@yahoo.com\";"},{"lineNumber":377,"author":{"gitId":"-"},"content":" assertEquals(\"Valid email (typical) should return empty string\", \"\","},{"lineNumber":378,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(typicalEmail));"},{"lineNumber":379,"author":{"gitId":"-"},"content":""},{"lineNumber":380,"author":{"gitId":"-"},"content":" String shortEmail \u003d \"e@y.c\";"},{"lineNumber":381,"author":{"gitId":"-"},"content":" assertEquals(\"Valid email (short) should return empty string\", \"\","},{"lineNumber":382,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(shortEmail));"},{"lineNumber":383,"author":{"gitId":"-"},"content":""},{"lineNumber":384,"author":{"gitId":"-"},"content":" String maxLengthEmail \u003d StringHelperExtension.generateStringOfLength(FieldValidator.EMAIL_MAX_LENGTH - 6) + \"@c.gov\";"},{"lineNumber":385,"author":{"gitId":"-"},"content":" assertEquals(\"Valid email (max-length) should return empty string\", \"\","},{"lineNumber":386,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(maxLengthEmail));"},{"lineNumber":387,"author":{"gitId":"-"},"content":" }"},{"lineNumber":388,"author":{"gitId":"-"},"content":""},{"lineNumber":389,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":390,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForEmail_invalid_returnErrorString() {"},{"lineNumber":391,"author":{"gitId":"-"},"content":" String emptyEmail \u003d \"\";"},{"lineNumber":392,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid email (empty) should return appropriate error string\","},{"lineNumber":393,"author":{"gitId":"-"},"content":" \"The field \u0027email\u0027 is empty. An email address contains some text followed by one \""},{"lineNumber":394,"author":{"gitId":"-"},"content":" + \"\u0027@\u0027 sign followed by some more text, and should end with a top level domain address like \""},{"lineNumber":395,"author":{"gitId":"-"},"content":" + \".com. It cannot be longer than 254 characters, cannot be empty and cannot contain spaces.\","},{"lineNumber":396,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(emptyEmail));"},{"lineNumber":397,"author":{"gitId":"-"},"content":""},{"lineNumber":398,"author":{"gitId":"-"},"content":" String untrimmedEmail \u003d \" untrimmed@email.com \";"},{"lineNumber":399,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid email (leading/trailing spaces) should return appropriate error string\","},{"lineNumber":400,"author":{"gitId":"-"},"content":" FieldValidator.WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace("},{"lineNumber":401,"author":{"gitId":"-"},"content":" \"${fieldName}\", FieldValidator.EMAIL_FIELD_NAME),"},{"lineNumber":402,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(untrimmedEmail));"},{"lineNumber":403,"author":{"gitId":"-"},"content":""},{"lineNumber":404,"author":{"gitId":"-"},"content":" String whitespaceEmail \u003d \" \";"},{"lineNumber":405,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid email (only whitespaces) should return appropriate error string\","},{"lineNumber":406,"author":{"gitId":"-"},"content":" FieldValidator.WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace("},{"lineNumber":407,"author":{"gitId":"-"},"content":" \"${fieldName}\", FieldValidator.EMAIL_FIELD_NAME),"},{"lineNumber":408,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(whitespaceEmail));"},{"lineNumber":409,"author":{"gitId":"-"},"content":""},{"lineNumber":410,"author":{"gitId":"-"},"content":" String tooLongEmail \u003d StringHelperExtension.generateStringOfLength(FieldValidator.EMAIL_MAX_LENGTH + 1) + \"@c.gov\";"},{"lineNumber":411,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid email (too long) should return appropriate error string\","},{"lineNumber":412,"author":{"gitId":"-"},"content":" \"\\\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\""},{"lineNumber":413,"author":{"gitId":"-"},"content":" + \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\""},{"lineNumber":414,"author":{"gitId":"-"},"content":" + \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\""},{"lineNumber":415,"author":{"gitId":"-"},"content":" + \"aaaaaaaa@c.gov\\\" is not acceptable to TEAMMATES as a/an email because it is too \""},{"lineNumber":416,"author":{"gitId":"-"},"content":" + \"long. An email address contains some text followed by one \u0027@\u0027 sign followed by \""},{"lineNumber":417,"author":{"gitId":"-"},"content":" + \"some more text, and should end with a top level domain address like .com. \""},{"lineNumber":418,"author":{"gitId":"-"},"content":" + \"It cannot be longer than 254 characters, cannot be empty and \""},{"lineNumber":419,"author":{"gitId":"-"},"content":" + \"cannot contain spaces.\","},{"lineNumber":420,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(tooLongEmail));"},{"lineNumber":421,"author":{"gitId":"-"},"content":""},{"lineNumber":422,"author":{"gitId":"-"},"content":" String emailWithSpaceAfterAtSymbol \u003d \"woMAN@com. sg\";"},{"lineNumber":423,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid email (space character after \u0027@\u0027) should return appropriate error string\","},{"lineNumber":424,"author":{"gitId":"-"},"content":" \"\\\"woMAN@com. sg\\\" is not acceptable to TEAMMATES as a/an email because it is not in \""},{"lineNumber":425,"author":{"gitId":"-"},"content":" + \"the correct format. An email address contains some text followed by one \u0027@\u0027 sign \""},{"lineNumber":426,"author":{"gitId":"-"},"content":" + \"followed by some more text, and should end with a top level domain address like .com. \""},{"lineNumber":427,"author":{"gitId":"-"},"content":" + \"It cannot be longer than 254 characters, cannot be \""},{"lineNumber":428,"author":{"gitId":"-"},"content":" + \"empty and cannot contain spaces.\","},{"lineNumber":429,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(emailWithSpaceAfterAtSymbol));"},{"lineNumber":430,"author":{"gitId":"-"},"content":""},{"lineNumber":431,"author":{"gitId":"-"},"content":" String emailWithSpaceBeforeAtSymbol \u003d \"man woman@com.sg\";"},{"lineNumber":432,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid email (space character before \u0027@\u0027) should return appropriate error string\","},{"lineNumber":433,"author":{"gitId":"-"},"content":" \"\\\"man woman@com.sg\\\" is not acceptable to TEAMMATES as a/an email because it \""},{"lineNumber":434,"author":{"gitId":"-"},"content":" + \"is not in the correct format. An email address contains some text followed by \""},{"lineNumber":435,"author":{"gitId":"-"},"content":" + \"one \u0027@\u0027 sign followed by some more text, and should end with a top level domain address \""},{"lineNumber":436,"author":{"gitId":"-"},"content":" + \"like .com. It cannot be longer than 254 \""},{"lineNumber":437,"author":{"gitId":"-"},"content":" + \"characters, cannot be empty and cannot contain spaces.\","},{"lineNumber":438,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(emailWithSpaceBeforeAtSymbol));"},{"lineNumber":439,"author":{"gitId":"-"},"content":""},{"lineNumber":440,"author":{"gitId":"-"},"content":" String emailWithMultipleAtSymbol \u003d \"man@woman@com.lk\";"},{"lineNumber":441,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid email (multiple \u0027@\u0027 characters) should return appropriate error string\","},{"lineNumber":442,"author":{"gitId":"-"},"content":" \"\\\"man@woman@com.lk\\\" is not acceptable to TEAMMATES as a/an email because it is not \""},{"lineNumber":443,"author":{"gitId":"-"},"content":" + \"in the correct format. An email address contains some text followed by one \u0027@\u0027 \""},{"lineNumber":444,"author":{"gitId":"-"},"content":" + \"sign followed by some more text, and should end with a top level domain address like .com. \""},{"lineNumber":445,"author":{"gitId":"-"},"content":" + \"It cannot be longer than 254 characters, \""},{"lineNumber":446,"author":{"gitId":"-"},"content":" + \"cannot be empty and cannot contain spaces.\","},{"lineNumber":447,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForEmail(emailWithMultipleAtSymbol));"},{"lineNumber":448,"author":{"gitId":"-"},"content":" }"},{"lineNumber":449,"author":{"gitId":"-"},"content":""},{"lineNumber":450,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":451,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForCourseId_null_throwException() {"},{"lineNumber":452,"author":{"gitId":"-"},"content":" assertThrows(AssertionError.class, () -\u003e FieldValidator.getInvalidityInfoForCourseId(null));"},{"lineNumber":453,"author":{"gitId":"-"},"content":" }"},{"lineNumber":454,"author":{"gitId":"-"},"content":""},{"lineNumber":455,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":456,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForCourseId_valid_returnEmptyString() {"},{"lineNumber":457,"author":{"gitId":"-"},"content":" String typicalCourseId \u003d \"cs1101-sem1.2_\";"},{"lineNumber":458,"author":{"gitId":"-"},"content":" assertEquals(\"Valid Course ID (typical) should return empty string\", \"\","},{"lineNumber":459,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForCourseId(typicalCourseId));"},{"lineNumber":460,"author":{"gitId":"-"},"content":""},{"lineNumber":461,"author":{"gitId":"-"},"content":" String shortCourseId \u003d \"c\";"},{"lineNumber":462,"author":{"gitId":"-"},"content":" assertEquals(\"Valid Course ID (short) should return empty string\", \"\","},{"lineNumber":463,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForCourseId(shortCourseId));"},{"lineNumber":464,"author":{"gitId":"-"},"content":""},{"lineNumber":465,"author":{"gitId":"-"},"content":" String maxLengthCourseId \u003d StringHelperExtension.generateStringOfLength("},{"lineNumber":466,"author":{"gitId":"-"},"content":" FieldValidator.COURSE_ID_MAX_LENGTH);"},{"lineNumber":467,"author":{"gitId":"-"},"content":" assertEquals(\"Valid Course ID (max length) should return empty string\", \"\","},{"lineNumber":468,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForCourseId(maxLengthCourseId));"},{"lineNumber":469,"author":{"gitId":"-"},"content":" }"},{"lineNumber":470,"author":{"gitId":"-"},"content":""},{"lineNumber":471,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":472,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForCourseId_invalid_returnErrorString() {"},{"lineNumber":473,"author":{"gitId":"-"},"content":" String emptyCourseId \u003d \"\";"},{"lineNumber":474,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Course ID (empty) should return appropriate error string\","},{"lineNumber":475,"author":{"gitId":"-"},"content":" \"The field \u0027course ID\u0027 is empty. A course ID can contain letters, numbers, \""},{"lineNumber":476,"author":{"gitId":"-"},"content":" + \"fullstops, hyphens, underscores, and dollar signs. It cannot be \""},{"lineNumber":477,"author":{"gitId":"-"},"content":" + \"longer than 64 characters, cannot be empty and cannot contain spaces.\","},{"lineNumber":478,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForCourseId(emptyCourseId));"},{"lineNumber":479,"author":{"gitId":"-"},"content":""},{"lineNumber":480,"author":{"gitId":"-"},"content":" String untrimmedCourseId \u003d \" $cs1101-sem1.2_ \";"},{"lineNumber":481,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Course ID (untrimmed) should return appropriate error string\","},{"lineNumber":482,"author":{"gitId":"-"},"content":" FieldValidator.WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace("},{"lineNumber":483,"author":{"gitId":"-"},"content":" \"${fieldName}\", FieldValidator.COURSE_ID_FIELD_NAME),"},{"lineNumber":484,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForCourseId(untrimmedCourseId));"},{"lineNumber":485,"author":{"gitId":"-"},"content":""},{"lineNumber":486,"author":{"gitId":"-"},"content":" String whitespaceOnlyCourseId \u003d \" \";"},{"lineNumber":487,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Course ID (whitespace only) should return appropriate error string\","},{"lineNumber":488,"author":{"gitId":"-"},"content":" FieldValidator.WHITESPACE_ONLY_OR_EXTRA_WHITESPACE_ERROR_MESSAGE.replace("},{"lineNumber":489,"author":{"gitId":"-"},"content":" \"${fieldName}\", FieldValidator.COURSE_ID_FIELD_NAME),"},{"lineNumber":490,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForCourseId(whitespaceOnlyCourseId));"},{"lineNumber":491,"author":{"gitId":"-"},"content":""},{"lineNumber":492,"author":{"gitId":"-"},"content":" String tooLongCourseId \u003d StringHelperExtension.generateStringOfLength("},{"lineNumber":493,"author":{"gitId":"-"},"content":" FieldValidator.COURSE_ID_MAX_LENGTH + 1);"},{"lineNumber":494,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Course ID (too long) should return appropriate error string\","},{"lineNumber":495,"author":{"gitId":"-"},"content":" \"\\\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\" \""},{"lineNumber":496,"author":{"gitId":"-"},"content":" + \"is not acceptable to TEAMMATES as a/an course ID because it is too long. \""},{"lineNumber":497,"author":{"gitId":"-"},"content":" + \"A course ID can contain letters, numbers, fullstops, hyphens, underscores, \""},{"lineNumber":498,"author":{"gitId":"-"},"content":" + \"and dollar signs. It cannot be longer than 64 characters, \""},{"lineNumber":499,"author":{"gitId":"-"},"content":" + \"cannot be empty and cannot contain spaces.\","},{"lineNumber":500,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForCourseId(tooLongCourseId));"},{"lineNumber":501,"author":{"gitId":"-"},"content":""},{"lineNumber":502,"author":{"gitId":"-"},"content":" String courseIdWithSpaces \u003d \"my course id with spaces\";"},{"lineNumber":503,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Course ID (contains spaces) should return appropriate error string\","},{"lineNumber":504,"author":{"gitId":"-"},"content":" \"\\\"my course id with spaces\\\" is not acceptable to TEAMMATES as a/an course ID because \""},{"lineNumber":505,"author":{"gitId":"-"},"content":" + \"it is not in the correct format. A course ID can contain letters, numbers, \""},{"lineNumber":506,"author":{"gitId":"-"},"content":" + \"fullstops, hyphens, underscores, and dollar signs. It cannot be longer than 64 \""},{"lineNumber":507,"author":{"gitId":"-"},"content":" + \"characters, cannot be empty and cannot contain spaces.\","},{"lineNumber":508,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForCourseId(courseIdWithSpaces));"},{"lineNumber":509,"author":{"gitId":"-"},"content":""},{"lineNumber":510,"author":{"gitId":"-"},"content":" String courseIdWithInvalidChar \u003d \"cour@s*hy#\";"},{"lineNumber":511,"author":{"gitId":"-"},"content":" assertEquals(\"Invalid Course ID (invalid char) should return appropriate error string\","},{"lineNumber":512,"author":{"gitId":"-"},"content":" \"\\\"cour@s*hy#\\\" is not acceptable to TEAMMATES as a/an course ID because it is not in \""},{"lineNumber":513,"author":{"gitId":"-"},"content":" + \"the correct format. A course ID can contain letters, numbers, fullstops, \""},{"lineNumber":514,"author":{"gitId":"-"},"content":" + \"hyphens, underscores, and dollar signs. It cannot be longer than 64 characters, \""},{"lineNumber":515,"author":{"gitId":"-"},"content":" + \"cannot be empty and cannot contain spaces.\","},{"lineNumber":516,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForCourseId(courseIdWithInvalidChar));"},{"lineNumber":517,"author":{"gitId":"-"},"content":" }"},{"lineNumber":518,"author":{"gitId":"-"},"content":""},{"lineNumber":519,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":520,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNewStartTime_valid_returnEmptyString() {"},{"lineNumber":521,"author":{"gitId":"-"},"content":" Instant earliestSessionStart \u003d TimeHelperExtension"},{"lineNumber":522,"author":{"gitId":"-"},"content":" .getInstantHoursOffsetFromNow(-1)"},{"lineNumber":523,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS);"},{"lineNumber":524,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForNewStartTime(earliestSessionStart, Const.DEFAULT_TIME_ZONE));"},{"lineNumber":525,"author":{"gitId":"-"},"content":""},{"lineNumber":526,"author":{"gitId":"-"},"content":" Instant latestSessionStart \u003d TimeHelperExtension"},{"lineNumber":527,"author":{"gitId":"-"},"content":" .getInstantDaysOffsetFromNow(90)"},{"lineNumber":528,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS);"},{"lineNumber":529,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForNewStartTime(latestSessionStart, Const.DEFAULT_TIME_ZONE));"},{"lineNumber":530,"author":{"gitId":"-"},"content":" }"},{"lineNumber":531,"author":{"gitId":"-"},"content":""},{"lineNumber":532,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":533,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNewStartTime_invalid_returnErrorString() {"},{"lineNumber":534,"author":{"gitId":"-"},"content":" Instant threeHoursBeforeNowRounded \u003d TimeHelperExtension"},{"lineNumber":535,"author":{"gitId":"-"},"content":" .getInstantHoursOffsetFromNow(-3)"},{"lineNumber":536,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS);"},{"lineNumber":537,"author":{"gitId":"-"},"content":" assertEquals(\"The start time for this feedback session cannot be earlier than 2 hours before now.\","},{"lineNumber":538,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNewStartTime(threeHoursBeforeNowRounded, Const.DEFAULT_TIME_ZONE));"},{"lineNumber":539,"author":{"gitId":"-"},"content":""},{"lineNumber":540,"author":{"gitId":"-"},"content":" Instant thirteenMonthsFromNow \u003d TimeHelperExtension"},{"lineNumber":541,"author":{"gitId":"-"},"content":" .getInstantMonthsOffsetFromNow(13, Const.DEFAULT_TIME_ZONE)"},{"lineNumber":542,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS);"},{"lineNumber":543,"author":{"gitId":"-"},"content":" assertEquals(\"The start time for this feedback session cannot be later than 12 months from now.\","},{"lineNumber":544,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNewStartTime(thirteenMonthsFromNow, Const.DEFAULT_TIME_ZONE));"},{"lineNumber":545,"author":{"gitId":"-"},"content":""},{"lineNumber":546,"author":{"gitId":"-"},"content":" Instant notAtHourMark \u003d TimeHelperExtension"},{"lineNumber":547,"author":{"gitId":"-"},"content":" .getInstantHoursOffsetFromNow(1)"},{"lineNumber":548,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS)"},{"lineNumber":549,"author":{"gitId":"-"},"content":" .plus(Duration.ofMinutes(30));"},{"lineNumber":550,"author":{"gitId":"-"},"content":" assertEquals(\"The start time for this feedback session must be at exact hour mark.\","},{"lineNumber":551,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNewStartTime(notAtHourMark, Const.DEFAULT_TIME_ZONE));"},{"lineNumber":552,"author":{"gitId":"-"},"content":" }"},{"lineNumber":553,"author":{"gitId":"-"},"content":""},{"lineNumber":554,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":555,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNewEndTime_valid_returnEmptyString() {"},{"lineNumber":556,"author":{"gitId":"-"},"content":" Instant earliestSessionEnd \u003d TimeHelperExtension"},{"lineNumber":557,"author":{"gitId":"-"},"content":" .getInstantHoursOffsetFromNow(0)"},{"lineNumber":558,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS);"},{"lineNumber":559,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForNewEndTime(earliestSessionEnd, Const.DEFAULT_TIME_ZONE));"},{"lineNumber":560,"author":{"gitId":"-"},"content":""},{"lineNumber":561,"author":{"gitId":"-"},"content":" Instant latestSessionEnd \u003d TimeHelperExtension"},{"lineNumber":562,"author":{"gitId":"-"},"content":" .getInstantDaysOffsetFromNow(180)"},{"lineNumber":563,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS);"},{"lineNumber":564,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForNewEndTime(latestSessionEnd, Const.DEFAULT_TIME_ZONE));"},{"lineNumber":565,"author":{"gitId":"-"},"content":" }"},{"lineNumber":566,"author":{"gitId":"-"},"content":""},{"lineNumber":567,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":568,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNewEndTime_invalid_returnErrorString() {"},{"lineNumber":569,"author":{"gitId":"-"},"content":" Instant twoHoursBeforeNowRounded \u003d TimeHelperExtension"},{"lineNumber":570,"author":{"gitId":"-"},"content":" .getInstantHoursOffsetFromNow(-2)"},{"lineNumber":571,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS);"},{"lineNumber":572,"author":{"gitId":"-"},"content":" assertEquals(\"The end time for this feedback session cannot be earlier than 1 hour before now.\","},{"lineNumber":573,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNewEndTime(twoHoursBeforeNowRounded, Const.DEFAULT_TIME_ZONE));"},{"lineNumber":574,"author":{"gitId":"-"},"content":""},{"lineNumber":575,"author":{"gitId":"-"},"content":" Instant thirteenMonthsFromNow \u003d TimeHelperExtension"},{"lineNumber":576,"author":{"gitId":"-"},"content":" .getInstantMonthsOffsetFromNow(13, Const.DEFAULT_TIME_ZONE)"},{"lineNumber":577,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS);"},{"lineNumber":578,"author":{"gitId":"-"},"content":" assertEquals(\"The end time for this feedback session cannot be later than 12 months from now.\","},{"lineNumber":579,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNewEndTime(thirteenMonthsFromNow,"},{"lineNumber":580,"author":{"gitId":"-"},"content":" Const.DEFAULT_TIME_ZONE));"},{"lineNumber":581,"author":{"gitId":"-"},"content":""},{"lineNumber":582,"author":{"gitId":"-"},"content":" Instant notAtHourMark \u003d TimeHelperExtension"},{"lineNumber":583,"author":{"gitId":"-"},"content":" .getInstantHoursOffsetFromNow(1)"},{"lineNumber":584,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.HOURS)"},{"lineNumber":585,"author":{"gitId":"-"},"content":" .plus(Duration.ofMinutes(30));"},{"lineNumber":586,"author":{"gitId":"-"},"content":" assertEquals(\"The end time for this feedback session must be at exact hour mark.\","},{"lineNumber":587,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNewEndTime(notAtHourMark, Const.DEFAULT_TIME_ZONE));"},{"lineNumber":588,"author":{"gitId":"-"},"content":" }"},{"lineNumber":589,"author":{"gitId":"-"},"content":""},{"lineNumber":590,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":591,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForSessionStartAndEnd_valid_returnEmptyString() {"},{"lineNumber":592,"author":{"gitId":"-"},"content":" Instant sessionStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":593,"author":{"gitId":"-"},"content":" Instant sessionEnd \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(1);"},{"lineNumber":594,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForTimeForSessionStartAndEnd(sessionStart, sessionEnd));"},{"lineNumber":595,"author":{"gitId":"-"},"content":" }"},{"lineNumber":596,"author":{"gitId":"-"},"content":""},{"lineNumber":597,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":598,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForSessionStartAndEnd_invalid_returnErrorString() {"},{"lineNumber":599,"author":{"gitId":"-"},"content":" Instant sessionStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(1);"},{"lineNumber":600,"author":{"gitId":"-"},"content":" Instant sessionEnd \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":601,"author":{"gitId":"-"},"content":" assertEquals(\"The end time for this feedback session cannot be earlier than the start time.\","},{"lineNumber":602,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForSessionStartAndEnd(sessionStart, sessionEnd));"},{"lineNumber":603,"author":{"gitId":"-"},"content":" }"},{"lineNumber":604,"author":{"gitId":"-"},"content":""},{"lineNumber":605,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":606,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForVisibilityStartAndSessionStart_valid_returnEmptyString() {"},{"lineNumber":607,"author":{"gitId":"-"},"content":" Instant visibilityStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":608,"author":{"gitId":"-"},"content":" Instant sessionStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(1);"},{"lineNumber":609,"author":{"gitId":"-"},"content":" assertEquals(\"\","},{"lineNumber":610,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForVisibilityStartAndSessionStart("},{"lineNumber":611,"author":{"gitId":"-"},"content":" visibilityStart, sessionStart));"},{"lineNumber":612,"author":{"gitId":"-"},"content":" }"},{"lineNumber":613,"author":{"gitId":"-"},"content":""},{"lineNumber":614,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":615,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForVisibilityStartAndSessionStart_invalid_returnErrorString() {"},{"lineNumber":616,"author":{"gitId":"-"},"content":" Instant visibilityStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(1);"},{"lineNumber":617,"author":{"gitId":"-"},"content":" Instant sessionStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":618,"author":{"gitId":"-"},"content":" assertEquals(\"The start time for this feedback session cannot be earlier than the time when the \""},{"lineNumber":619,"author":{"gitId":"-"},"content":" + \"session will be visible.\","},{"lineNumber":620,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForVisibilityStartAndSessionStart("},{"lineNumber":621,"author":{"gitId":"-"},"content":" visibilityStart, sessionStart));"},{"lineNumber":622,"author":{"gitId":"-"},"content":" }"},{"lineNumber":623,"author":{"gitId":"-"},"content":""},{"lineNumber":624,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":625,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForNewVisibilityStart_valid_returnEmptyString() {"},{"lineNumber":626,"author":{"gitId":"-"},"content":" Instant sessionStart \u003d TimeHelperExtension.getInstantDaysOffsetFromNow(1);"},{"lineNumber":627,"author":{"gitId":"-"},"content":" Instant visibilityStart \u003d sessionStart.plus(Duration.ofDays(29));"},{"lineNumber":628,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForTimeForNewVisibilityStart("},{"lineNumber":629,"author":{"gitId":"-"},"content":" visibilityStart, sessionStart));"},{"lineNumber":630,"author":{"gitId":"-"},"content":" }"},{"lineNumber":631,"author":{"gitId":"-"},"content":""},{"lineNumber":632,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":633,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForNewVisibilityStart_invalid_returnErrorString() {"},{"lineNumber":634,"author":{"gitId":"-"},"content":" Instant sessionStart \u003d TimeHelperExtension.getInstantDaysOffsetFromNow(1);"},{"lineNumber":635,"author":{"gitId":"-"},"content":" Instant thirtyOneDaysBeforeSessionStart \u003d TimeHelperExtension.getInstantDaysOffsetFromNow(-31);"},{"lineNumber":636,"author":{"gitId":"-"},"content":" assertEquals(\"The time when the session will be visible for this feedback session cannot be \""},{"lineNumber":637,"author":{"gitId":"-"},"content":" + \"earlier than 30 days before start time.\","},{"lineNumber":638,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForNewVisibilityStart("},{"lineNumber":639,"author":{"gitId":"-"},"content":" thirtyOneDaysBeforeSessionStart, sessionStart));"},{"lineNumber":640,"author":{"gitId":"-"},"content":" }"},{"lineNumber":641,"author":{"gitId":"-"},"content":""},{"lineNumber":642,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":643,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForVisibilityStartAndResultsPublish_valid_returnEmptyString() {"},{"lineNumber":644,"author":{"gitId":"-"},"content":" Instant visibilityStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":645,"author":{"gitId":"-"},"content":" Instant resultsPublish \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(1);"},{"lineNumber":646,"author":{"gitId":"-"},"content":" assertEquals(\"\","},{"lineNumber":647,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForVisibilityStartAndResultsPublish("},{"lineNumber":648,"author":{"gitId":"-"},"content":" visibilityStart, resultsPublish));"},{"lineNumber":649,"author":{"gitId":"-"},"content":" }"},{"lineNumber":650,"author":{"gitId":"-"},"content":""},{"lineNumber":651,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":652,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForVisibilityStartAndResultsPublish_invalid_returnErrorString() {"},{"lineNumber":653,"author":{"gitId":"-"},"content":" Instant visibilityStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(1);"},{"lineNumber":654,"author":{"gitId":"-"},"content":" Instant resultsPublish \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":655,"author":{"gitId":"-"},"content":" assertEquals(\"The time when the results will be visible for this feedback session cannot be \""},{"lineNumber":656,"author":{"gitId":"-"},"content":" + \"earlier than the time when the session will be visible.\","},{"lineNumber":657,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForVisibilityStartAndResultsPublish("},{"lineNumber":658,"author":{"gitId":"-"},"content":" visibilityStart, resultsPublish));"},{"lineNumber":659,"author":{"gitId":"-"},"content":" }"},{"lineNumber":660,"author":{"gitId":"-"},"content":""},{"lineNumber":661,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":662,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForSessionEndAndExtendedDeadlines_valid_returnEmptyString() {"},{"lineNumber":663,"author":{"gitId":"-"},"content":" Instant sessionEnd \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":664,"author":{"gitId":"-"},"content":" Map\u003cString, Instant\u003e extendedDeadlines \u003d new HashMap\u003c\u003e();"},{"lineNumber":665,"author":{"gitId":"-"},"content":" extendedDeadlines.put(\"participant@email.com\", TimeHelperExtension.getInstantHoursOffsetFromNow(1));"},{"lineNumber":666,"author":{"gitId":"-"},"content":" assertEquals(\"\","},{"lineNumber":667,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForSessionEndAndExtendedDeadlines("},{"lineNumber":668,"author":{"gitId":"-"},"content":" sessionEnd, extendedDeadlines));"},{"lineNumber":669,"author":{"gitId":"-"},"content":" }"},{"lineNumber":670,"author":{"gitId":"-"},"content":""},{"lineNumber":671,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":672,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForSessionEndAndExtendedDeadlines_invalid_returnErrorString() {"},{"lineNumber":673,"author":{"gitId":"-"},"content":" ______TS(\"extended deadline earlier than the end time\");"},{"lineNumber":674,"author":{"gitId":"-"},"content":" Instant sessionEnd \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(1);"},{"lineNumber":675,"author":{"gitId":"-"},"content":" Map\u003cString, Instant\u003e extendedDeadlines \u003d new HashMap\u003c\u003e();"},{"lineNumber":676,"author":{"gitId":"-"},"content":" extendedDeadlines.put(\"participant@email.com\", TimeHelperExtension.getInstantHoursOffsetFromNow(-1));"},{"lineNumber":677,"author":{"gitId":"-"},"content":" assertEquals(\"The extended deadlines for this feedback session cannot be earlier than or at the same time as \""},{"lineNumber":678,"author":{"gitId":"-"},"content":" + \"the end time.\","},{"lineNumber":679,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForSessionEndAndExtendedDeadlines("},{"lineNumber":680,"author":{"gitId":"-"},"content":" sessionEnd, extendedDeadlines));"},{"lineNumber":681,"author":{"gitId":"-"},"content":""},{"lineNumber":682,"author":{"gitId":"-"},"content":" ______TS(\"extended deadline at the same time as the end time\");"},{"lineNumber":683,"author":{"gitId":"-"},"content":" extendedDeadlines.put(\"participant@email.com\", sessionEnd);"},{"lineNumber":684,"author":{"gitId":"-"},"content":" assertEquals(\"The extended deadlines for this feedback session cannot be earlier than or at the same time as \""},{"lineNumber":685,"author":{"gitId":"-"},"content":" + \"the end time.\","},{"lineNumber":686,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForSessionEndAndExtendedDeadlines("},{"lineNumber":687,"author":{"gitId":"-"},"content":" sessionEnd, extendedDeadlines));"},{"lineNumber":688,"author":{"gitId":"-"},"content":" }"},{"lineNumber":689,"author":{"gitId":"-"},"content":""},{"lineNumber":690,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":691,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForNotificationStartAndEnd_valid_returnEmptyString() {"},{"lineNumber":692,"author":{"gitId":"-"},"content":" Instant notificationStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":693,"author":{"gitId":"-"},"content":" Instant notificationEnd \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(1);"},{"lineNumber":694,"author":{"gitId":"-"},"content":""},{"lineNumber":695,"author":{"gitId":"-"},"content":" assertEquals(\"\","},{"lineNumber":696,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForNotificationStartAndEnd("},{"lineNumber":697,"author":{"gitId":"-"},"content":" notificationStart, notificationEnd));"},{"lineNumber":698,"author":{"gitId":"-"},"content":" }"},{"lineNumber":699,"author":{"gitId":"-"},"content":""},{"lineNumber":700,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":701,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForTimeForNotificationStartAndEnd_inValid_returnErrorString() {"},{"lineNumber":702,"author":{"gitId":"-"},"content":" Instant notificationStart \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(1);"},{"lineNumber":703,"author":{"gitId":"-"},"content":" Instant notificationEnd \u003d TimeHelperExtension.getInstantHoursOffsetFromNow(-1);"},{"lineNumber":704,"author":{"gitId":"-"},"content":""},{"lineNumber":705,"author":{"gitId":"-"},"content":" assertEquals(\"The time when the notification will expire for this notification cannot be earlier \""},{"lineNumber":706,"author":{"gitId":"-"},"content":" + \"than the time when the notification will be visible.\","},{"lineNumber":707,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForTimeForNotificationStartAndEnd("},{"lineNumber":708,"author":{"gitId":"-"},"content":" notificationStart, notificationEnd));"},{"lineNumber":709,"author":{"gitId":"-"},"content":" }"},{"lineNumber":710,"author":{"gitId":"-"},"content":""},{"lineNumber":711,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":712,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNotificationTitle_valid_returnEmptyString() {"},{"lineNumber":713,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForNotificationTitle(\"valid title\"));"},{"lineNumber":714,"author":{"gitId":"-"},"content":" }"},{"lineNumber":715,"author":{"gitId":"-"},"content":""},{"lineNumber":716,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":717,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNotificationTitle_inValid_returnErrorString() {"},{"lineNumber":718,"author":{"gitId":"-"},"content":" ______TS(\"Empty notification title\");"},{"lineNumber":719,"author":{"gitId":"-"},"content":" assertEquals(\"The field \u0027notification title\u0027 is empty.\","},{"lineNumber":720,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNotificationTitle(\"\"));"},{"lineNumber":721,"author":{"gitId":"-"},"content":""},{"lineNumber":722,"author":{"gitId":"-"},"content":" ______TS(\"Notification title exceeds maximum length\");"},{"lineNumber":723,"author":{"gitId":"-"},"content":" String invalidNotificationTitle \u003d StringHelperExtension.generateStringOfLength("},{"lineNumber":724,"author":{"gitId":"-"},"content":" FieldValidator.NOTIFICATION_TITLE_MAX_LENGTH + 1);"},{"lineNumber":725,"author":{"gitId":"-"},"content":" assertEquals(\"\\\"\" + invalidNotificationTitle + \"\\\" is not acceptable to TEAMMATES as a/an \""},{"lineNumber":726,"author":{"gitId":"-"},"content":" + \"notification title because it is too long. \""},{"lineNumber":727,"author":{"gitId":"-"},"content":" + \"The value of a/an notification title should be no longer than \""},{"lineNumber":728,"author":{"gitId":"-"},"content":" + FieldValidator.NOTIFICATION_TITLE_MAX_LENGTH"},{"lineNumber":729,"author":{"gitId":"-"},"content":" + \" characters. It should not be empty.\","},{"lineNumber":730,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNotificationTitle(invalidNotificationTitle));"},{"lineNumber":731,"author":{"gitId":"-"},"content":" }"},{"lineNumber":732,"author":{"gitId":"-"},"content":""},{"lineNumber":733,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":734,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNotificationBody_valid_returnEmptyString() {"},{"lineNumber":735,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForNotificationBody(\"valid body\"));"},{"lineNumber":736,"author":{"gitId":"-"},"content":" }"},{"lineNumber":737,"author":{"gitId":"-"},"content":""},{"lineNumber":738,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":739,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNotificationBody_inValid_returnErrorString() {"},{"lineNumber":740,"author":{"gitId":"-"},"content":" assertEquals(\"The field \u0027notification message\u0027 is empty.\","},{"lineNumber":741,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNotificationBody(\"\"));"},{"lineNumber":742,"author":{"gitId":"-"},"content":" }"},{"lineNumber":743,"author":{"gitId":"-"},"content":""},{"lineNumber":744,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":745,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNotificationStyle_valid_returnEmptyString() {"},{"lineNumber":746,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForNotificationStyle(\"SUCCESS\"));"},{"lineNumber":747,"author":{"gitId":"-"},"content":" }"},{"lineNumber":748,"author":{"gitId":"-"},"content":""},{"lineNumber":749,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":750,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNotificationStyle_inValid_returnErrorString() {"},{"lineNumber":751,"author":{"gitId":"-"},"content":" String invalidStyle \u003d \"invalid style\";"},{"lineNumber":752,"author":{"gitId":"-"},"content":" assertEquals(\"\\\"\" + invalidStyle + \"\\\" is not an accepted notification style to TEAMMATES. \","},{"lineNumber":753,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNotificationStyle(invalidStyle));"},{"lineNumber":754,"author":{"gitId":"-"},"content":" }"},{"lineNumber":755,"author":{"gitId":"-"},"content":""},{"lineNumber":756,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":757,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNotificationTargetUser_valid_returnEmptyString() {"},{"lineNumber":758,"author":{"gitId":"-"},"content":" assertEquals(\"\", FieldValidator.getInvalidityInfoForNotificationTargetUser(\"GENERAL\"));"},{"lineNumber":759,"author":{"gitId":"-"},"content":" }"},{"lineNumber":760,"author":{"gitId":"-"},"content":""},{"lineNumber":761,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":762,"author":{"gitId":"-"},"content":" public void testGetInvalidityInfoForNotificationTargetUser_inValid_returnErrorString() {"},{"lineNumber":763,"author":{"gitId":"-"},"content":" String invalidUser \u003d \"invalid user\";"},{"lineNumber":764,"author":{"gitId":"-"},"content":" assertEquals(\"\\\"\" + invalidUser + \"\\\" is not an accepted notification target user to TEAMMATES. \","},{"lineNumber":765,"author":{"gitId":"-"},"content":" FieldValidator.getInvalidityInfoForNotificationTargetUser(invalidUser));"},{"lineNumber":766,"author":{"gitId":"-"},"content":" }"},{"lineNumber":767,"author":{"gitId":"-"},"content":""},{"lineNumber":768,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":769,"author":{"gitId":"-"},"content":" public void testRegexName() {"},{"lineNumber":770,"author":{"gitId":"-"},"content":" ______TS(\"success: typical name\");"},{"lineNumber":771,"author":{"gitId":"-"},"content":" String name \u003d \"Benny Charlés\";"},{"lineNumber":772,"author":{"gitId":"-"},"content":" assertTrue(StringHelper.isMatching(name, FieldValidator.REGEX_NAME));"},{"lineNumber":773,"author":{"gitId":"-"},"content":""},{"lineNumber":774,"author":{"gitId":"-"},"content":" ______TS(\"success: name begins with accented characters\");"},{"lineNumber":775,"author":{"gitId":"-"},"content":" name \u003d \"Ýàn-B. s/o O\u0027br, \u00262(~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\";"},{"lineNumber":776,"author":{"gitId":"-"},"content":" assertTrue(StringHelper.isMatching(name, FieldValidator.REGEX_NAME));"},{"lineNumber":777,"author":{"gitId":"-"},"content":""},{"lineNumber":778,"author":{"gitId":"-"},"content":" ______TS(\"failure: name begins with non-alphanumeric character\");"},{"lineNumber":779,"author":{"gitId":"-"},"content":" name \u003d \"~Amy-Ben. s/o O\u0027br, \u00262(~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\";"},{"lineNumber":780,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(name, FieldValidator.REGEX_NAME));"},{"lineNumber":781,"author":{"gitId":"-"},"content":""},{"lineNumber":782,"author":{"gitId":"-"},"content":" ______TS(\"failure: name contains invalid character\");"},{"lineNumber":783,"author":{"gitId":"-"},"content":" name \u003d \"Amy-B. s/o O\u0027br, %|\u00262(~!@#$^*+_\u003d{}[]\\\\:;\\\"\u003c\u003e?)\";"},{"lineNumber":784,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(name, FieldValidator.REGEX_NAME));"},{"lineNumber":785,"author":{"gitId":"-"},"content":" }"},{"lineNumber":786,"author":{"gitId":"-"},"content":""},{"lineNumber":787,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":788,"author":{"gitId":"-"},"content":" public void testRegexEmail() {"},{"lineNumber":789,"author":{"gitId":"-"},"content":" ______TS(\"success: typical email\");"},{"lineNumber":790,"author":{"gitId":"-"},"content":" String email \u003d \"john@email.com\";"},{"lineNumber":791,"author":{"gitId":"-"},"content":" assertTrue(StringHelper.isMatching(email, FieldValidator.REGEX_EMAIL));"},{"lineNumber":792,"author":{"gitId":"-"},"content":""},{"lineNumber":793,"author":{"gitId":"-"},"content":" ______TS(\"failure: no top level domain\");"},{"lineNumber":794,"author":{"gitId":"-"},"content":" email \u003d \"a@e\";"},{"lineNumber":795,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(email, FieldValidator.REGEX_EMAIL));"},{"lineNumber":796,"author":{"gitId":"-"},"content":""},{"lineNumber":797,"author":{"gitId":"-"},"content":" ______TS(\"success: minimum allowed email format\");"},{"lineNumber":798,"author":{"gitId":"-"},"content":" email \u003d \"a@e.c\";"},{"lineNumber":799,"author":{"gitId":"-"},"content":" assertTrue(StringHelper.isMatching(email, FieldValidator.REGEX_EMAIL));"},{"lineNumber":800,"author":{"gitId":"-"},"content":""},{"lineNumber":801,"author":{"gitId":"-"},"content":" ______TS(\"success: all allowed special characters\");"},{"lineNumber":802,"author":{"gitId":"-"},"content":" email \u003d \"a!#$%\u0026\u0027*/\u003d?^_`{}~@e.c\";"},{"lineNumber":803,"author":{"gitId":"-"},"content":" assertTrue(StringHelper.isMatching(email, FieldValidator.REGEX_EMAIL));"},{"lineNumber":804,"author":{"gitId":"-"},"content":""},{"lineNumber":805,"author":{"gitId":"-"},"content":" ______TS(\"failure: invalid starting character\");"},{"lineNumber":806,"author":{"gitId":"-"},"content":" email \u003d \"$john@email.com\";"},{"lineNumber":807,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(email, FieldValidator.REGEX_EMAIL));"},{"lineNumber":808,"author":{"gitId":"-"},"content":""},{"lineNumber":809,"author":{"gitId":"-"},"content":" ______TS(\"failure: two consecutive dots in local part\");"},{"lineNumber":810,"author":{"gitId":"-"},"content":" email \u003d \"john..dot@email.com\";"},{"lineNumber":811,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(email, FieldValidator.REGEX_EMAIL));"},{"lineNumber":812,"author":{"gitId":"-"},"content":""},{"lineNumber":813,"author":{"gitId":"-"},"content":" ______TS(\"failure: invalid characters in domain part\");"},{"lineNumber":814,"author":{"gitId":"-"},"content":" email \u003d \"john@e\u0026email.com\";"},{"lineNumber":815,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(email, FieldValidator.REGEX_EMAIL));"},{"lineNumber":816,"author":{"gitId":"-"},"content":""},{"lineNumber":817,"author":{"gitId":"-"},"content":" ______TS(\"failure: invalid ending character in domain part\");"},{"lineNumber":818,"author":{"gitId":"-"},"content":" email \u003d \"john@email.com3\";"},{"lineNumber":819,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(email, FieldValidator.REGEX_EMAIL));"},{"lineNumber":820,"author":{"gitId":"-"},"content":" }"},{"lineNumber":821,"author":{"gitId":"-"},"content":""},{"lineNumber":822,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":823,"author":{"gitId":"-"},"content":" public void testRegexCourseId() {"},{"lineNumber":824,"author":{"gitId":"-"},"content":" ______TS(\"success: typical course ID\");"},{"lineNumber":825,"author":{"gitId":"-"},"content":" String courseId \u003d \"CS101\";"},{"lineNumber":826,"author":{"gitId":"-"},"content":" assertTrue(StringHelper.isMatching(courseId, FieldValidator.REGEX_COURSE_ID));"},{"lineNumber":827,"author":{"gitId":"-"},"content":""},{"lineNumber":828,"author":{"gitId":"-"},"content":" ______TS(\"success: course ID with all accepted symbols\");"},{"lineNumber":829,"author":{"gitId":"-"},"content":" courseId \u003d \"CS101-B.$\";"},{"lineNumber":830,"author":{"gitId":"-"},"content":" assertTrue(StringHelper.isMatching(courseId, FieldValidator.REGEX_COURSE_ID));"},{"lineNumber":831,"author":{"gitId":"-"},"content":""},{"lineNumber":832,"author":{"gitId":"-"},"content":" ______TS(\"failure: contains invalid character\");"},{"lineNumber":833,"author":{"gitId":"-"},"content":" courseId \u003d \"CS101+B\";"},{"lineNumber":834,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(courseId, FieldValidator.REGEX_COURSE_ID));"},{"lineNumber":835,"author":{"gitId":"-"},"content":" }"},{"lineNumber":836,"author":{"gitId":"-"},"content":""},{"lineNumber":837,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":838,"author":{"gitId":"-"},"content":" public void testRegexGoogleIdNonEmail() {"},{"lineNumber":839,"author":{"gitId":"-"},"content":" ______TS(\"success: typical google id\");"},{"lineNumber":840,"author":{"gitId":"-"},"content":" String googleId \u003d \"teammates.instr\";"},{"lineNumber":841,"author":{"gitId":"-"},"content":" assertTrue(StringHelper.isMatching(googleId, FieldValidator.REGEX_GOOGLE_ID_NON_EMAIL));"},{"lineNumber":842,"author":{"gitId":"-"},"content":""},{"lineNumber":843,"author":{"gitId":"-"},"content":" ______TS(\"success: google id with all accepted characters\");"},{"lineNumber":844,"author":{"gitId":"-"},"content":" googleId \u003d \"teammates.new_instr-3\";"},{"lineNumber":845,"author":{"gitId":"-"},"content":" assertTrue(StringHelper.isMatching(googleId, FieldValidator.REGEX_GOOGLE_ID_NON_EMAIL));"},{"lineNumber":846,"author":{"gitId":"-"},"content":""},{"lineNumber":847,"author":{"gitId":"-"},"content":" ______TS(\"failure: is email\");"},{"lineNumber":848,"author":{"gitId":"-"},"content":" googleId \u003d \"teammates.instr@email.com\";"},{"lineNumber":849,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(googleId, FieldValidator.REGEX_GOOGLE_ID_NON_EMAIL));"},{"lineNumber":850,"author":{"gitId":"-"},"content":""},{"lineNumber":851,"author":{"gitId":"-"},"content":" ______TS(\"failure: contains invalid character\");"},{"lineNumber":852,"author":{"gitId":"-"},"content":" googleId \u003d \"teammates.$instr\";"},{"lineNumber":853,"author":{"gitId":"-"},"content":" assertFalse(StringHelper.isMatching(googleId, FieldValidator.REGEX_GOOGLE_ID_NON_EMAIL));"},{"lineNumber":854,"author":{"gitId":"-"},"content":" }"},{"lineNumber":855,"author":{"gitId":"-"},"content":""},{"lineNumber":856,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":4,"-":852}},{"path":"src/test/java/teammates/common/util/TimeHelperTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.common.util;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Duration;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.time.LocalDateTime;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.time.Month;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.time.OffsetDateTime;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.time.ZoneId;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.time.ZonedDateTime;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.time.temporal.ChronoUnit;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * SUT: {@link TimeHelper}."},{"lineNumber":18,"author":{"gitId":"-"},"content":" */"},{"lineNumber":19,"author":{"gitId":"-"},"content":"public class TimeHelperTest extends BaseTestCase {"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" private static final String DATETIME_DISPLAY_FORMAT \u003d \"EEE, dd MMM yyyy, hh:mm a z\";"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":24,"author":{"gitId":"-"},"content":" public void testEndOfYearDates() {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" LocalDateTime date \u003d LocalDateTime.of(2015, Month.DECEMBER, 30, 12, 0);"},{"lineNumber":26,"author":{"gitId":"-"},"content":" assertEquals(\"Wed, 30 Dec 2015, 12:00 NOON UTC\", TimeHelper.formatInstant("},{"lineNumber":27,"author":{"gitId":"-"},"content":" date.atZone(ZoneId.of(\"UTC\")).toInstant(), \"UTC\", DATETIME_DISPLAY_FORMAT));"},{"lineNumber":28,"author":{"gitId":"-"},"content":" }"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":31,"author":{"gitId":"-"},"content":" public void testFormatDateTimeForDisplay() {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" String zoneId \u003d \"UTC\";"},{"lineNumber":33,"author":{"gitId":"-"},"content":" Instant instant \u003d LocalDateTime.of(2015, Month.NOVEMBER, 30, 12, 0).atZone(ZoneId.of(zoneId)).toInstant();"},{"lineNumber":34,"author":{"gitId":"-"},"content":" assertEquals(\"Mon, 30 Nov 2015, 12:00 NOON UTC\", TimeHelper.formatInstant(instant, zoneId, DATETIME_DISPLAY_FORMAT));"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" zoneId \u003d \"Asia/Singapore\";"},{"lineNumber":37,"author":{"gitId":"-"},"content":" instant \u003d LocalDateTime.of(2015, Month.NOVEMBER, 30, 16, 0).atZone(ZoneId.of(zoneId)).toInstant();"},{"lineNumber":38,"author":{"gitId":"-"},"content":" assertEquals(\"Mon, 30 Nov 2015, 04:00 PM SGT\", TimeHelper.formatInstant(instant, zoneId, DATETIME_DISPLAY_FORMAT));"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" instant \u003d LocalDateTime.of(2015, Month.NOVEMBER, 30, 4, 0).atZone(ZoneId.of(zoneId)).toInstant();"},{"lineNumber":41,"author":{"gitId":"-"},"content":" assertEquals(\"Mon, 30 Nov 2015, 04:00 AM SGT\", TimeHelper.formatInstant(instant, zoneId, DATETIME_DISPLAY_FORMAT));"},{"lineNumber":42,"author":{"gitId":"-"},"content":" }"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":45,"author":{"gitId":"-"},"content":" public void testGetMidnightAdjustedInstantBasedOnZone() {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" String zoneId \u003d \"UTC\";"},{"lineNumber":47,"author":{"gitId":"-"},"content":" Instant instantAt0000 \u003d LocalDateTime.of(2015, Month.NOVEMBER, 30, 0, 0).atZone(ZoneId.of(zoneId)).toInstant();"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" Instant backwardAdjusted \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone(instantAt0000, zoneId, false);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" assertEquals(\"Sun, 29 Nov 2015, 11:59 PM UTC\","},{"lineNumber":51,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(backwardAdjusted, zoneId, DATETIME_DISPLAY_FORMAT));"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" Instant forwardAdjusted \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone(instantAt0000, zoneId, true);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" assertEquals(\"Mon, 30 Nov 2015, 12:00 AM UTC\","},{"lineNumber":55,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(forwardAdjusted, zoneId, DATETIME_DISPLAY_FORMAT));"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" Instant instantAt2359 \u003d LocalDateTime.of(2015, Month.NOVEMBER, 29, 23, 59).atZone(ZoneId.of(zoneId)).toInstant();"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" backwardAdjusted \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone(instantAt2359, zoneId, false);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" assertEquals(\"Sun, 29 Nov 2015, 11:59 PM UTC\","},{"lineNumber":61,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(backwardAdjusted, zoneId, DATETIME_DISPLAY_FORMAT));"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" forwardAdjusted \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone(instantAt2359, zoneId, true);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" assertEquals(\"Mon, 30 Nov 2015, 12:00 AM UTC\","},{"lineNumber":65,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(forwardAdjusted, zoneId, DATETIME_DISPLAY_FORMAT));"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" String wrongTimeZone \u003d \"Asia/Singapore\";"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" backwardAdjusted \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone(instantAt0000, wrongTimeZone, false);"},{"lineNumber":70,"author":{"gitId":"-"},"content":" assertEquals(\"Mon, 30 Nov 2015, 12:00 AM UTC\","},{"lineNumber":71,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(backwardAdjusted, zoneId, DATETIME_DISPLAY_FORMAT));"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" forwardAdjusted \u003d TimeHelper.getMidnightAdjustedInstantBasedOnZone(instantAt2359, wrongTimeZone, true);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" assertEquals(\"Sun, 29 Nov 2015, 11:59 PM UTC\","},{"lineNumber":75,"author":{"gitId":"-"},"content":" TimeHelper.formatInstant(forwardAdjusted, zoneId, DATETIME_DISPLAY_FORMAT));"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":79,"author":{"gitId":"-"},"content":" public void testGetInstantNearestHourBefore() {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" Instant expected \u003d Instant.parse(\"2020-12-31T16:00:00Z\");"},{"lineNumber":81,"author":{"gitId":"-"},"content":" Instant actual \u003d TimeHelper.getInstantNearestHourBefore(Instant.parse(\"2020-12-31T16:00:00Z\"));"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" actual \u003d TimeHelper.getInstantNearestHourBefore(Instant.parse(\"2020-12-31T16:10:00Z\"));"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" actual \u003d TimeHelper.getInstantNearestHourBefore(OffsetDateTime.parse(\"2021-01-01T00:30:00+08:00\").toInstant());"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" actual \u003d TimeHelper.getInstantNearestHourBefore(OffsetDateTime.parse(\"2020-12-31T12:59:00-04:00\").toInstant());"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" }"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":99,"author":{"gitId":"-"},"content":" public void testGetInstantDaysOffsetFromNow() {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" // Comparison using second precision is sufficient"},{"lineNumber":101,"author":{"gitId":"-"},"content":" Instant expected \u003d Instant.now().truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" Instant actual \u003d TimeHelper.getInstantDaysOffsetFromNow(0).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" expected \u003d Instant.now().plus(Duration.ofDays(365)).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":106,"author":{"gitId":"-"},"content":" actual \u003d TimeHelper.getInstantDaysOffsetFromNow(365).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":107,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":111,"author":{"gitId":"-"},"content":" public void testGetInstantDaysOffsetBeforeNow() {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" // Comparison using second precision is sufficient"},{"lineNumber":113,"author":{"gitId":"-"},"content":" Instant expected \u003d Instant.now().truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" Instant actual \u003d TimeHelper.getInstantDaysOffsetBeforeNow(0).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":115,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" expected \u003d Instant.now().minus(Duration.ofDays(365)).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":118,"author":{"gitId":"-"},"content":" actual \u003d TimeHelper.getInstantDaysOffsetBeforeNow(365).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" }"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":123,"author":{"gitId":"-"},"content":" public void testGetInstantHoursOffsetFromNow() {"},{"lineNumber":124,"author":{"gitId":"-"},"content":" // Comparison using second precision is sufficient"},{"lineNumber":125,"author":{"gitId":"-"},"content":" Instant expected \u003d Instant.now().truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":126,"author":{"gitId":"-"},"content":" Instant actual \u003d TimeHelper.getInstantHoursOffsetFromNow(0).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" expected \u003d Instant.now().plus(Duration.ofHours(60)).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" actual \u003d TimeHelper.getInstantHoursOffsetFromNow(60).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" }"},{"lineNumber":133,"author":{"gitId":"-"},"content":""},{"lineNumber":134,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":135,"author":{"gitId":"-"},"content":" public void testGetInstantMonthsOffsetFromNow() {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" Instant expected \u003d Instant.now().truncatedTo(ChronoUnit.DAYS);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" Instant actual \u003d TimeHelper.getInstantMonthsOffsetFromNow(0, Const.DEFAULT_TIME_ZONE)"},{"lineNumber":138,"author":{"gitId":"-"},"content":" .truncatedTo(ChronoUnit.DAYS);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" Instant now \u003d Instant.now();"},{"lineNumber":142,"author":{"gitId":"-"},"content":" ZonedDateTime zdt \u003d now.atZone(ZoneId.of(Const.DEFAULT_TIME_ZONE));"},{"lineNumber":143,"author":{"gitId":"-"},"content":" ZonedDateTime offsetZdt \u003d zdt.plusMonths(12);"},{"lineNumber":144,"author":{"gitId":"-"},"content":" expected \u003d offsetZdt.toInstant().truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" actual \u003d TimeHelper.getInstantMonthsOffsetFromNow(12, Const.DEFAULT_TIME_ZONE).truncatedTo(ChronoUnit.SECONDS);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" assertEquals(expected, actual);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":" public void getInstantNearestQuarterHourBefore() {"},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":" Instant expectedQ1 \u003d Instant.parse(\"2020-12-31T16:00:00Z\");"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":" Instant actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:00:00Z\"));"},{"lineNumber":153,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ1, actual);"},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:09:30Z\"));"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":158,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ1, actual);"},{"lineNumber":159,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:14:59Z\"));"},{"lineNumber":161,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":162,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ1, actual);"},{"lineNumber":163,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":164,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper"},{"lineNumber":165,"author":{"gitId":"dishenggg"},"content":" .getInstantNearestQuarterHourBefore(OffsetDateTime.parse(\"2021-01-01T00:10:00+08:00\").toInstant());"},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":167,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ1, actual);"},{"lineNumber":168,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper"},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" .getInstantNearestQuarterHourBefore(OffsetDateTime.parse(\"2020-12-31T12:09:00-04:00\").toInstant());"},{"lineNumber":171,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ1, actual);"},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":" Instant expectedQ2 \u003d Instant.parse(\"2020-12-31T16:15:00Z\");"},{"lineNumber":175,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:15:00Z\"));"},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ2, actual);"},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":179,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:19:30Z\"));"},{"lineNumber":180,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":181,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ2, actual);"},{"lineNumber":182,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:29:59Z\"));"},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":185,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ2, actual);"},{"lineNumber":186,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":187,"author":{"gitId":"dishenggg"},"content":" Instant expectedQ3 \u003d Instant.parse(\"2020-12-31T16:30:00Z\");"},{"lineNumber":188,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:30:00Z\"));"},{"lineNumber":189,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":190,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ3, actual);"},{"lineNumber":191,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":192,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:39:30Z\"));"},{"lineNumber":193,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":194,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ3, actual);"},{"lineNumber":195,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":196,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:44:59Z\"));"},{"lineNumber":197,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":198,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ3, actual);"},{"lineNumber":199,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":200,"author":{"gitId":"dishenggg"},"content":" Instant expectedQ4 \u003d Instant.parse(\"2020-12-31T16:45:00Z\");"},{"lineNumber":201,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:45:00Z\"));"},{"lineNumber":202,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":203,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ4, actual);"},{"lineNumber":204,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":205,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:49:30Z\"));"},{"lineNumber":206,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":207,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ4, actual);"},{"lineNumber":208,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":209,"author":{"gitId":"dishenggg"},"content":" actual \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.parse(\"2020-12-31T16:59:59Z\"));"},{"lineNumber":210,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":211,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedQ4, actual);"},{"lineNumber":212,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":64,"-":149}},{"path":"src/test/java/teammates/logic/api/MockLogsProcessor.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.logic.api;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.QueryLogsResults;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.GeneralLogEntry;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.LogDetails;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.LogSeverity;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.QueryLogsParams;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.SourceLocation;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":17,"author":{"gitId":"-"},"content":" * Allows mocking of {@link LogsProcessor}."},{"lineNumber":18,"author":{"gitId":"-"},"content":" */"},{"lineNumber":19,"author":{"gitId":"-"},"content":"public class MockLogsProcessor extends LogsProcessor {"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" private List\u003cFeedbackSessionLogEntry\u003e feedbackSessionLogs \u003d new ArrayList\u003c\u003e();"},{"lineNumber":22,"author":{"gitId":"-"},"content":" private List\u003cGeneralLogEntry\u003e generalLogs \u003d new ArrayList\u003c\u003e();"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * Simulates insertion of feedback session logs."},{"lineNumber":26,"author":{"gitId":"-"},"content":" */"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" public void insertFeedbackSessionLog(String courseId, String studentEmail, String feedbackSessionName,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" String fslType, long timestamp) {"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" feedbackSessionLogs"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" .add(new FeedbackSessionLogEntry(courseId, studentEmail, feedbackSessionName, fslType, timestamp));"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" * Simulates insertion of feedback session logs."},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" public void insertFeedbackSessionLog(String courseId, UUID studentId, UUID feedbackSessionId,"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" String fslType, long timestamp) {"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" feedbackSessionLogs"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" .add(new FeedbackSessionLogEntry(courseId, studentId, feedbackSessionId, fslType, timestamp));"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":43,"author":{"gitId":"-"},"content":" * Simulates insertion of general INFO logs."},{"lineNumber":44,"author":{"gitId":"-"},"content":" */"},{"lineNumber":45,"author":{"gitId":"-"},"content":" public void insertInfoLog(String trace, String insertId, SourceLocation sourceLocation,"},{"lineNumber":46,"author":{"gitId":"-"},"content":" long timestamp, String textPayloadMessage, LogDetails logDetails) {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" insertGeneralLog(LogSeverity.INFO, trace, insertId,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" sourceLocation, timestamp, textPayloadMessage, logDetails);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" }"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":52,"author":{"gitId":"-"},"content":" * Simulates insertion of general WARNING logs."},{"lineNumber":53,"author":{"gitId":"-"},"content":" */"},{"lineNumber":54,"author":{"gitId":"-"},"content":" public void insertWarningLog(String trace, String insertId, SourceLocation sourceLocation,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" long timestamp, String textPayloadMessage, LogDetails logDetails) {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" insertGeneralLog(LogSeverity.WARNING, trace, insertId,"},{"lineNumber":57,"author":{"gitId":"-"},"content":" sourceLocation, timestamp, textPayloadMessage, logDetails);"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":61,"author":{"gitId":"-"},"content":" * Simulates insertion of general ERROR logs."},{"lineNumber":62,"author":{"gitId":"-"},"content":" */"},{"lineNumber":63,"author":{"gitId":"-"},"content":" public void insertErrorLog(String trace, String insertId, SourceLocation sourceLocation,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" long timestamp, String textPayloadMessage, LogDetails logDetails) {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" insertGeneralLog(LogSeverity.ERROR, trace, insertId,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" sourceLocation, timestamp, textPayloadMessage, logDetails);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" }"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" private void insertGeneralLog(LogSeverity severity, String trace, String insertId,"},{"lineNumber":70,"author":{"gitId":"-"},"content":" SourceLocation sourceLocation, long timestamp, String textPayloadMessage,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" LogDetails logDetails) {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" GeneralLogEntry logEntry \u003d new GeneralLogEntry(severity, trace, insertId, new HashMap\u003c\u003e(), sourceLocation,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" timestamp);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" logEntry.setMessage(textPayloadMessage);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" logEntry.setDetails(logDetails);"},{"lineNumber":76,"author":{"gitId":"-"},"content":" generalLogs.add(logEntry);"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":80,"author":{"gitId":"-"},"content":" public QueryLogsResults queryLogs(QueryLogsParams queryLogsParams) {"},{"lineNumber":81,"author":{"gitId":"-"},"content":" List\u003cGeneralLogEntry\u003e queryResults \u003d new ArrayList\u003c\u003e();"},{"lineNumber":82,"author":{"gitId":"-"},"content":" if (queryLogsParams.getSeverity() !\u003d null) {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" generalLogs.forEach(entry -\u003e {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" if (queryLogsParams.getSeverity().equals(entry.getSeverity())"},{"lineNumber":85,"author":{"gitId":"-"},"content":" \u0026\u0026 entry.getTimestamp() \u003e\u003d queryLogsParams.getStartTime()"},{"lineNumber":86,"author":{"gitId":"-"},"content":" \u0026\u0026 entry.getTimestamp() \u003c\u003d queryLogsParams.getEndTime()) {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" queryResults.add(entry);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":" });"},{"lineNumber":90,"author":{"gitId":"-"},"content":" } else if (queryLogsParams.getMinSeverity() !\u003d null) {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" generalLogs.forEach(entry -\u003e {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" if (queryLogsParams.getMinSeverity().getSeverityLevel()"},{"lineNumber":93,"author":{"gitId":"-"},"content":" \u003c\u003d entry.getSeverity().getSeverityLevel()"},{"lineNumber":94,"author":{"gitId":"-"},"content":" \u0026\u0026 entry.getTimestamp() \u003e\u003d queryLogsParams.getStartTime()"},{"lineNumber":95,"author":{"gitId":"-"},"content":" \u0026\u0026 entry.getTimestamp() \u003c\u003d queryLogsParams.getEndTime()) {"},{"lineNumber":96,"author":{"gitId":"-"},"content":" queryResults.add(entry);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" }"},{"lineNumber":98,"author":{"gitId":"-"},"content":" });"},{"lineNumber":99,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":100,"author":{"gitId":"-"},"content":" generalLogs.forEach(entry -\u003e {"},{"lineNumber":101,"author":{"gitId":"-"},"content":" if (entry.getTimestamp() \u003e\u003d queryLogsParams.getStartTime()"},{"lineNumber":102,"author":{"gitId":"-"},"content":" \u0026\u0026 entry.getTimestamp() \u003c\u003d queryLogsParams.getEndTime()) {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" queryResults.add(entry);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":" });"},{"lineNumber":106,"author":{"gitId":"-"},"content":" }"},{"lineNumber":107,"author":{"gitId":"-"},"content":" return new QueryLogsResults(queryResults, false);"},{"lineNumber":108,"author":{"gitId":"-"},"content":" }"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":" public void createFeedbackSessionLog(String courseId, UUID studentId, UUID fsId, String fslType) {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" // No-op"},{"lineNumber":113,"author":{"gitId":"-"},"content":" }"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" public List\u003cFeedbackSessionLogEntry\u003e getOrderedFeedbackSessionLogs(String courseId, String email,"},{"lineNumber":117,"author":{"gitId":"-"},"content":" long startTime, long endTime, String fsName) {"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" feedbackSessionLogs.sort((x, y) -\u003e x.compareTo(y));"},{"lineNumber":119,"author":{"gitId":"-"},"content":" return feedbackSessionLogs;"},{"lineNumber":120,"author":{"gitId":"-"},"content":" }"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":16,"-":106}},{"path":"src/test/java/teammates/logic/api/MockUserProvision.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.logic.api;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.UserInfo;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.UserInfoCookie;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":7,"author":{"gitId":"-"},"content":" * Allows mocking of the {@link UserProvision} API used in production."},{"lineNumber":8,"author":{"gitId":"-"},"content":" *"},{"lineNumber":9,"author":{"gitId":"-"},"content":" * \u003cp\u003eInstead of getting user information from the authentication service,"},{"lineNumber":10,"author":{"gitId":"-"},"content":" * the API will return pre-determined information instead."},{"lineNumber":11,"author":{"gitId":"-"},"content":" */"},{"lineNumber":12,"author":{"gitId":"-"},"content":"public class MockUserProvision extends UserProvision {"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":" private UserInfo mockUser \u003d new UserInfo(\"user.id\");"},{"lineNumber":15,"author":{"gitId":"-"},"content":" private boolean isLoggedIn;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":" private UserInfo loginUser(String userId, boolean isAdmin) {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" isLoggedIn \u003d true;"},{"lineNumber":19,"author":{"gitId":"-"},"content":" mockUser.id \u003d userId;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" mockUser.isAdmin \u003d isAdmin;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" return getCurrentUser(null);"},{"lineNumber":22,"author":{"gitId":"-"},"content":" }"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * Adds a logged-in user without admin rights."},{"lineNumber":26,"author":{"gitId":"-"},"content":" *"},{"lineNumber":27,"author":{"gitId":"-"},"content":" * @return The user info after login process"},{"lineNumber":28,"author":{"gitId":"-"},"content":" */"},{"lineNumber":29,"author":{"gitId":"-"},"content":" public UserInfo loginUser(String userId) {"},{"lineNumber":30,"author":{"gitId":"-"},"content":" return loginUser(userId, false);"},{"lineNumber":31,"author":{"gitId":"-"},"content":" }"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" private UserInfo loginUserWithTransaction(String userId, boolean isAdmin) {"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" isLoggedIn \u003d true;"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" mockUser.id \u003d userId;"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" mockUser.isAdmin \u003d isAdmin;"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" return getCurrentUserWithTransaction(null);"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" * Adds a logged-in user without admin rights."},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" * @return The user info after login process"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" public UserInfo loginUserWithTransaction(String userId) {"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" return loginUserWithTransaction(userId, false);"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":50,"author":{"gitId":"-"},"content":" * Adds a logged-in user as an admin."},{"lineNumber":51,"author":{"gitId":"-"},"content":" *"},{"lineNumber":52,"author":{"gitId":"-"},"content":" * @return The user info after login process"},{"lineNumber":53,"author":{"gitId":"-"},"content":" */"},{"lineNumber":54,"author":{"gitId":"-"},"content":" public UserInfo loginAsAdmin(String userId) {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" return loginUser(userId, true);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" * Adds a logged-in user as an admin."},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" *"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" * @return The user info after login process"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" public UserInfo loginAsAdminWithTransaction(String userId) {"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" return loginUserWithTransaction(userId, true);"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":68,"author":{"gitId":"-"},"content":" * Removes the logged-in user information."},{"lineNumber":69,"author":{"gitId":"-"},"content":" */"},{"lineNumber":70,"author":{"gitId":"-"},"content":" public void logoutUser() {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" isLoggedIn \u003d false;"},{"lineNumber":72,"author":{"gitId":"-"},"content":" }"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":75,"author":{"gitId":"-"},"content":" public UserInfo getCurrentLoggedInUser(UserInfoCookie uic) {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" return isLoggedIn ? mockUser : null;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":25,"-":54}},{"path":"src/test/java/teammates/sqllogic/api/SqlEmailGeneratorTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.api;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.io.IOException;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.util.Config;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailType;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.EmailWrapper;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.test.EmailChecker;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":16,"author":{"gitId":"-"},"content":" * SUT: {@link SqlEmailGenerator}."},{"lineNumber":17,"author":{"gitId":"-"},"content":" */"},{"lineNumber":18,"author":{"gitId":"-"},"content":"public class SqlEmailGeneratorTest extends BaseTestCase {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" private final SqlEmailGenerator sqlEmailGenerator \u003d SqlEmailGenerator.inst();"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":22,"author":{"gitId":"-"},"content":" void testGenerateNewAccountRequestAdminAlertEmail_withComments_generatesSuccessfully() throws IOException {"},{"lineNumber":23,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d new AccountRequest(\"chosen-one@jedi.org\", \"Anakin Skywalker\", \"Jedi Order\","},{"lineNumber":24,"author":{"gitId":"-"},"content":" AccountRequestStatus.PENDING,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \"I don\u0027t like sand. It\u0027s coarse and rough and irritating... and it gets everywhere.\");"},{"lineNumber":26,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d sqlEmailGenerator.generateNewAccountRequestAdminAlertEmail(accountRequest);"},{"lineNumber":27,"author":{"gitId":"-"},"content":" verifyEmail(email, Config.SUPPORT_EMAIL, EmailType.NEW_ACCOUNT_REQUEST_ADMIN_ALERT,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" \"TEAMMATES (Action Needed): New Account Request Received\","},{"lineNumber":29,"author":{"gitId":"-"},"content":" \"/adminNewAccountRequestAlertEmailWithComments.html\");"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":33,"author":{"gitId":"-"},"content":" void testGenerateNewAccountRequestAdminAlertEmail_withNoComments_generatesSuccessfully() throws IOException {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d new AccountRequest(\"maul@sith.org\", \"Maul\", \"Sith Order\","},{"lineNumber":35,"author":{"gitId":"-"},"content":" AccountRequestStatus.PENDING, null);"},{"lineNumber":36,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d sqlEmailGenerator.generateNewAccountRequestAdminAlertEmail(accountRequest);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" verifyEmail(email, Config.SUPPORT_EMAIL, EmailType.NEW_ACCOUNT_REQUEST_ADMIN_ALERT,"},{"lineNumber":38,"author":{"gitId":"-"},"content":" \"TEAMMATES (Action Needed): New Account Request Received\","},{"lineNumber":39,"author":{"gitId":"-"},"content":" \"/adminNewAccountRequestAlertEmailWithNoComments.html\");"},{"lineNumber":40,"author":{"gitId":"-"},"content":" }"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" void testGenerateNewAccountRequestAcknowledgementEmail_withComments_generatesSuccessfully() throws IOException {"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" AccountRequest accountRequest \u003d new AccountRequest(\"darth-vader@sith.org\", \"Darth Vader\", \"Sith Order\","},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" AccountRequestStatus.PENDING,"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" \"I Am Your Father\");"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" EmailWrapper email \u003d sqlEmailGenerator.generateNewAccountRequestAcknowledgementEmail(accountRequest);"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" verifyEmail(email, \"darth-vader@sith.org\", EmailType.NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT,"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" \"TEAMMATES: Acknowledgement of Instructor Account Request\","},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" Config.SUPPORT_EMAIL,"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" \"/instructorNewAccountRequestAcknowledgementEmailWithComments.html\");"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":" void testGenerateNewAccountRequestAcknowledgementEmail_withNoComments_generatesSuccessfully() throws IOException {"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" AccountRequest accountRequest \u003d new AccountRequest(\"maul@sith.org\", \"Maul\", \"Sith Order\","},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" AccountRequestStatus.PENDING, null);"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" EmailWrapper email \u003d sqlEmailGenerator.generateNewAccountRequestAcknowledgementEmail(accountRequest);"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" verifyEmail(email, \"maul@sith.org\", EmailType.NEW_ACCOUNT_REQUEST_ACKNOWLEDGEMENT,"},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" \"TEAMMATES: Acknowledgement of Instructor Account Request\","},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" Config.SUPPORT_EMAIL,"},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" \"/instructorNewAccountRequestAcknowledgementEmailWithNoComments.html\");"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":66,"author":{"gitId":"-"},"content":" void testGenerateAccountRequestRejectionEmail_withDefaultReason_generatesSuccessfully() throws IOException {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" AccountRequest accountRequest \u003d new AccountRequest(\"maul@sith.org\", \"Maul\", \"Sith Order\","},{"lineNumber":68,"author":{"gitId":"-"},"content":" AccountRequestStatus.PENDING, null);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" String title \u003d \"We are Unable to Create an Account for you\";"},{"lineNumber":70,"author":{"gitId":"-"},"content":" String content \u003d new StringBuilder()"},{"lineNumber":71,"author":{"gitId":"-"},"content":" .append(\"\u003cp\u003eHi, Maul\u003c/p\u003e\\n\")"},{"lineNumber":72,"author":{"gitId":"-"},"content":" .append(\"\u003cp\u003eThanks for your interest in using TEAMMATES. \")"},{"lineNumber":73,"author":{"gitId":"-"},"content":" .append(\"We are unable to create a TEAMMATES instructor account for you.\u003c/p\u003e\\n\\n\")"},{"lineNumber":74,"author":{"gitId":"-"},"content":" .append(\"\u003cp\u003e\\n\")"},{"lineNumber":75,"author":{"gitId":"-"},"content":" .append(\" \u003cstrong\u003eReason:\u003c/strong\u003e The email address you provided \")"},{"lineNumber":76,"author":{"gitId":"-"},"content":" .append(\"is not an \u0027official\u0027 email address provided by your institution.\u003cbr /\u003e\\n\")"},{"lineNumber":77,"author":{"gitId":"-"},"content":" .append(\" \u003cstrong\u003eRemedy:\u003c/strong\u003e \")"},{"lineNumber":78,"author":{"gitId":"-"},"content":" .append(\"Please re-submit an account request with your \u0027official\u0027 institution email address.\\n\")"},{"lineNumber":79,"author":{"gitId":"-"},"content":" .append(\"\u003c/p\u003e\\n\\n\")"},{"lineNumber":80,"author":{"gitId":"-"},"content":" .append(\"\u003cp\u003eIf you need further clarification or would like to appeal this decision, \")"},{"lineNumber":81,"author":{"gitId":"-"},"content":" .append(\"please feel free to contact us at teammates@comp.nus.edu.sg.\u003c/p\u003e\\n\")"},{"lineNumber":82,"author":{"gitId":"-"},"content":" .append(\"\u003cp\u003eRegards,\u003cbr /\u003eTEAMMATES Team.\u003c/p\u003e\\n\")"},{"lineNumber":83,"author":{"gitId":"-"},"content":" .toString();"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" EmailWrapper email \u003d sqlEmailGenerator.generateAccountRequestRejectionEmail(accountRequest, title, content);"},{"lineNumber":86,"author":{"gitId":"-"},"content":" verifyEmail(email, \"maul@sith.org\", EmailType.ACCOUNT_REQUEST_REJECTION,"},{"lineNumber":87,"author":{"gitId":"-"},"content":" \"TEAMMATES: \" + title,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" Config.SUPPORT_EMAIL,"},{"lineNumber":89,"author":{"gitId":"-"},"content":" \"/instructorAccountRequestRejectionEmail.html\");"},{"lineNumber":90,"author":{"gitId":"-"},"content":" }"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" private void verifyEmail(EmailWrapper email, String expectedRecipientEmailAddress, EmailType expectedEmailType,"},{"lineNumber":93,"author":{"gitId":"-"},"content":" String expectedSubject, String expectedEmailContentFilePathname) throws IOException {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" assertEquals(expectedRecipientEmailAddress, email.getRecipient());"},{"lineNumber":95,"author":{"gitId":"-"},"content":" assertEquals(Config.EMAIL_SENDEREMAIL, email.getSenderEmail());"},{"lineNumber":96,"author":{"gitId":"-"},"content":" assertEquals(Config.EMAIL_SENDERNAME, email.getSenderName());"},{"lineNumber":97,"author":{"gitId":"-"},"content":" assertEquals(Config.EMAIL_REPLYTO, email.getReplyTo());"},{"lineNumber":98,"author":{"gitId":"-"},"content":" assertEquals(expectedEmailType, email.getType());"},{"lineNumber":99,"author":{"gitId":"-"},"content":" assertEquals(expectedSubject, email.getSubject());"},{"lineNumber":100,"author":{"gitId":"-"},"content":" String emailContent \u003d email.getContent();"},{"lineNumber":101,"author":{"gitId":"-"},"content":" EmailChecker.verifyEmailContent(emailContent, expectedEmailContentFilePathname);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" verifyEmailContentHasNoPlaceholders(emailContent);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" }"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"xenosf"},"content":" private void verifyEmail(EmailWrapper email, String expectedRecipientEmailAddress, EmailType expectedEmailType,"},{"lineNumber":106,"author":{"gitId":"xenosf"},"content":" String expectedSubject, String expectedBcc, String expectedEmailContentFilePathname) throws IOException {"},{"lineNumber":107,"author":{"gitId":"xenosf"},"content":" assertEquals(expectedRecipientEmailAddress, email.getRecipient());"},{"lineNumber":108,"author":{"gitId":"xenosf"},"content":" assertEquals(Config.EMAIL_SENDEREMAIL, email.getSenderEmail());"},{"lineNumber":109,"author":{"gitId":"xenosf"},"content":" assertEquals(Config.EMAIL_SENDERNAME, email.getSenderName());"},{"lineNumber":110,"author":{"gitId":"xenosf"},"content":" assertEquals(Config.EMAIL_REPLYTO, email.getReplyTo());"},{"lineNumber":111,"author":{"gitId":"xenosf"},"content":" assertEquals(expectedEmailType, email.getType());"},{"lineNumber":112,"author":{"gitId":"xenosf"},"content":" assertEquals(expectedSubject, email.getSubject());"},{"lineNumber":113,"author":{"gitId":"xenosf"},"content":" assertEquals(expectedBcc, email.getBcc());"},{"lineNumber":114,"author":{"gitId":"xenosf"},"content":" String emailContent \u003d email.getContent();"},{"lineNumber":115,"author":{"gitId":"xenosf"},"content":" EmailChecker.verifyEmailContent(emailContent, expectedEmailContentFilePathname);"},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" verifyEmailContentHasNoPlaceholders(emailContent);"},{"lineNumber":117,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":118,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" private void verifyEmailContentHasNoPlaceholders(String emailContent) {"},{"lineNumber":120,"author":{"gitId":"-"},"content":" assertFalse(emailContent.contains(\"${\"));"},{"lineNumber":121,"author":{"gitId":"-"},"content":" }"},{"lineNumber":122,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":37,"-":85}},{"path":"src/test/java/teammates/sqllogic/core/AccountRequestsLogicTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import static org.mockito.ArgumentMatchers.any;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import static org.mockito.ArgumentMatchers.nullable;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.mock;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import static org.mockito.Mockito.times;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.verify;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.when;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":"import teammates.common.util.Const;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.AccountRequestsDb;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * SUT: {@link AccountRequestsLogic}."},{"lineNumber":25,"author":{"gitId":"-"},"content":" */"},{"lineNumber":26,"author":{"gitId":"-"},"content":"public class AccountRequestsLogicTest extends BaseTestCase {"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" private AccountRequestsLogic accountRequestsLogic \u003d AccountRequestsLogic.inst();"},{"lineNumber":29,"author":{"gitId":"-"},"content":" private AccountRequestsDb accountRequestsDb;"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":32,"author":{"gitId":"-"},"content":" public void setUpMethod() {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" accountRequestsDb \u003d mock(AccountRequestsDb.class);"},{"lineNumber":34,"author":{"gitId":"-"},"content":" accountRequestsLogic.initLogicDependencies(accountRequestsDb);"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" public void testCreateAccountRequest_typicalRequest_success() throws Exception {"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" AccountRequest accountRequest \u003d getTypicalAccountRequest();"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.createAccountRequest(accountRequest)).thenReturn(accountRequest);"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" AccountRequest createdAccountRequest \u003d accountRequestsLogic.createAccountRequest(accountRequest);"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" assertEquals(accountRequest, createdAccountRequest);"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).createAccountRequest(accountRequest);"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" public void testCreateAccountRequest_requestAlreadyExists_success() throws Exception {"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" AccountRequest accountRequest1 \u003d getTypicalAccountRequest();"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" AccountRequest accountRequest2 \u003d getTypicalAccountRequest();"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.createAccountRequest(accountRequest1))"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" .thenReturn(accountRequest1);"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.createAccountRequest(accountRequest2))"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" .thenReturn(accountRequest2);"},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" accountRequestsLogic.createAccountRequest(accountRequest1);"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" accountRequestsLogic.createAccountRequest(accountRequest2);"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).createAccountRequest(accountRequest1);"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).createAccountRequest(accountRequest2);"},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" public void testCreateAccountRequest_invalidParams_failure() throws Exception {"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" AccountRequest invalidEmailAccountRequest \u003d getTypicalAccountRequest();"},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":" invalidEmailAccountRequest.setEmail(\"invalid email\");"},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.createAccountRequest(invalidEmailAccountRequest))"},{"lineNumber":67,"author":{"gitId":"xenosf"},"content":" .thenThrow(new InvalidParametersException(\"test exception\"));"},{"lineNumber":68,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":" assertThrows(InvalidParametersException.class, () -\u003e {"},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":" accountRequestsLogic.createAccountRequest(invalidEmailAccountRequest);"},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).createAccountRequest(invalidEmailAccountRequest);"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" public void testUpdateAccountRequest_typicalRequest_success()"},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" AccountRequest ar \u003d getTypicalAccountRequest();"},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.updateAccountRequest(ar)).thenReturn(ar);"},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" AccountRequest updatedAr \u003d accountRequestsLogic.updateAccountRequest(ar);"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":" assertEquals(ar, updatedAr);"},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).updateAccountRequest(ar);"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":" public void testUpdateAccountRequest_requestNotFound_failure()"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":" AccountRequest arNotFound \u003d getTypicalAccountRequest();"},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.updateAccountRequest(arNotFound)).thenThrow(new EntityDoesNotExistException(\"test message\"));"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":" assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":93,"author":{"gitId":"xenosf"},"content":" () -\u003e accountRequestsLogic.updateAccountRequest(arNotFound));"},{"lineNumber":94,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).updateAccountRequest(any(AccountRequest.class));"},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" public void testDeleteAccountRequest_typicalRequest_success() {"},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" AccountRequest ar \u003d getTypicalAccountRequest();"},{"lineNumber":100,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.getAccountRequest(ar.getId())).thenReturn(ar);"},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":" accountRequestsLogic.deleteAccountRequest(ar.getId());"},{"lineNumber":102,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":103,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).deleteAccountRequest(any(AccountRequest.class));"},{"lineNumber":104,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":105,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":106,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":107,"author":{"gitId":"xenosf"},"content":" public void testDeleteAccountRequest_nonexistentRequest_shouldSilentlyDelete() {"},{"lineNumber":108,"author":{"gitId":"xenosf"},"content":" UUID nonexistentUuid \u003d UUID.fromString(\"00000000-0000-4000-8000-000000000100\");"},{"lineNumber":109,"author":{"gitId":"xenosf"},"content":" accountRequestsLogic.deleteAccountRequest(nonexistentUuid);"},{"lineNumber":110,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":111,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).deleteAccountRequest(nullable(AccountRequest.class));"},{"lineNumber":112,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":113,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":114,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":115,"author":{"gitId":"xenosf"},"content":" public void testGetAccountRequestByRegistrationKey_typicalRequest_success() {"},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" AccountRequest ar \u003d getTypicalAccountRequest();"},{"lineNumber":117,"author":{"gitId":"xenosf"},"content":" String regkey \u003d \"regkey\";"},{"lineNumber":118,"author":{"gitId":"xenosf"},"content":" ar.setRegistrationKey(regkey);"},{"lineNumber":119,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.getAccountRequestByRegistrationKey(regkey)).thenReturn(ar);"},{"lineNumber":120,"author":{"gitId":"xenosf"},"content":" AccountRequest actualAr \u003d"},{"lineNumber":121,"author":{"gitId":"xenosf"},"content":" accountRequestsLogic.getAccountRequestByRegistrationKey(ar.getRegistrationKey());"},{"lineNumber":122,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":123,"author":{"gitId":"xenosf"},"content":" assertEquals(ar, actualAr);"},{"lineNumber":124,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).getAccountRequestByRegistrationKey(regkey);"},{"lineNumber":125,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":126,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":127,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":128,"author":{"gitId":"xenosf"},"content":" public void testGetAccountRequestByRegistrationKey_nonexistentRequest_shouldReturnNull() throws Exception {"},{"lineNumber":129,"author":{"gitId":"xenosf"},"content":" String nonexistentRegkey \u003d \"not_exist\";"},{"lineNumber":130,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.getAccountRequestByRegistrationKey(nonexistentRegkey)).thenReturn(null);"},{"lineNumber":131,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":132,"author":{"gitId":"xenosf"},"content":" assertNull(accountRequestsLogic.getAccountRequestByRegistrationKey(nonexistentRegkey));"},{"lineNumber":133,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).getAccountRequestByRegistrationKey(nonexistentRegkey);"},{"lineNumber":134,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":135,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":136,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":137,"author":{"gitId":"xenosf"},"content":" public void testResetAccountRequest_typicalRequest_success()"},{"lineNumber":138,"author":{"gitId":"xenosf"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":139,"author":{"gitId":"xenosf"},"content":" AccountRequest accountRequest \u003d getTypicalAccountRequest();"},{"lineNumber":140,"author":{"gitId":"xenosf"},"content":" accountRequest.setRegisteredAt(Const.TIME_REPRESENTS_NOW);"},{"lineNumber":141,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.getAccountRequest(accountRequest.getId()))"},{"lineNumber":142,"author":{"gitId":"xenosf"},"content":" .thenReturn(accountRequest);"},{"lineNumber":143,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.updateAccountRequest(accountRequest)).thenReturn(accountRequest);"},{"lineNumber":144,"author":{"gitId":"xenosf"},"content":" accountRequest \u003d accountRequestsLogic.resetAccountRequest(accountRequest.getId());"},{"lineNumber":145,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":146,"author":{"gitId":"xenosf"},"content":" assertNull(accountRequest.getRegisteredAt());"},{"lineNumber":147,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).getAccountRequest(accountRequest.getId());"},{"lineNumber":148,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":149,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":150,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":151,"author":{"gitId":"xenosf"},"content":" public void testResetAccountRequest_nonexistentRequest_failure()"},{"lineNumber":152,"author":{"gitId":"xenosf"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":153,"author":{"gitId":"xenosf"},"content":" AccountRequest accountRequest \u003d getTypicalAccountRequest();"},{"lineNumber":154,"author":{"gitId":"xenosf"},"content":" accountRequest.setRegisteredAt(Const.TIME_REPRESENTS_NOW);"},{"lineNumber":155,"author":{"gitId":"xenosf"},"content":" when(accountRequestsDb.getAccountRequest(accountRequest.getId()))"},{"lineNumber":156,"author":{"gitId":"xenosf"},"content":" .thenReturn(null);"},{"lineNumber":157,"author":{"gitId":"xenosf"},"content":" assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":158,"author":{"gitId":"xenosf"},"content":" () -\u003e accountRequestsLogic.resetAccountRequest(accountRequest.getId()));"},{"lineNumber":159,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(1)).getAccountRequest(accountRequest.getId());"},{"lineNumber":160,"author":{"gitId":"xenosf"},"content":" verify(accountRequestsDb, times(0)).updateAccountRequest(nullable(AccountRequest.class));"},{"lineNumber":161,"author":{"gitId":"-"},"content":" }"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":164,"author":{"gitId":"-"},"content":" public void testGetAccountRequest_nonExistentAccountRequest_returnsNull() {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" UUID id \u003d UUID.randomUUID();"},{"lineNumber":166,"author":{"gitId":"-"},"content":" when(accountRequestsDb.getAccountRequest(id)).thenReturn(null);"},{"lineNumber":167,"author":{"gitId":"-"},"content":" AccountRequest actualAccountRequest \u003d accountRequestsLogic.getAccountRequest(id);"},{"lineNumber":168,"author":{"gitId":"-"},"content":" verify(accountRequestsDb).getAccountRequest(id);"},{"lineNumber":169,"author":{"gitId":"-"},"content":" assertNull(actualAccountRequest);"},{"lineNumber":170,"author":{"gitId":"-"},"content":" }"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":173,"author":{"gitId":"-"},"content":" public void testGetAccountRequest_existingAccountRequest_getsSuccessfully() {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" AccountRequest expectedAccountRequest \u003d"},{"lineNumber":175,"author":{"gitId":"-"},"content":" new AccountRequest(\"test@gmail.com\", \"name\", \"institute\", AccountRequestStatus.PENDING, \"comments\");"},{"lineNumber":176,"author":{"gitId":"-"},"content":" UUID id \u003d expectedAccountRequest.getId();"},{"lineNumber":177,"author":{"gitId":"-"},"content":" when(accountRequestsDb.getAccountRequest(id)).thenReturn(expectedAccountRequest);"},{"lineNumber":178,"author":{"gitId":"-"},"content":" AccountRequest actualAccountRequest \u003d accountRequestsLogic.getAccountRequest(id);"},{"lineNumber":179,"author":{"gitId":"-"},"content":" verify(accountRequestsDb).getAccountRequest(id);"},{"lineNumber":180,"author":{"gitId":"-"},"content":" assertEquals(expectedAccountRequest, actualAccountRequest);"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":132,"-":50}},{"path":"src/test/java/teammates/sqllogic/core/AccountsLogicTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.mock;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.times;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.verify;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.when;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.AccountsDb;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.ReadNotification;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.User;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"-"},"content":" * SUT: {@link AccountsLogic}."},{"lineNumber":27,"author":{"gitId":"-"},"content":" */"},{"lineNumber":28,"author":{"gitId":"-"},"content":"public class AccountsLogicTest extends BaseTestCase {"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" private AccountsLogic accountsLogic \u003d AccountsLogic.inst();"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" private AccountsDb accountsDb;"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" private NotificationsLogic notificationsLogic;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" private UsersLogic usersLogic;"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"yuanxi1"},"content":" private CoursesLogic coursesLogic;"},{"lineNumber":39,"author":{"gitId":"yuanxi1"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":41,"author":{"gitId":"-"},"content":" public void setUpMethod() {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" accountsDb \u003d mock(AccountsDb.class);"},{"lineNumber":43,"author":{"gitId":"-"},"content":" notificationsLogic \u003d mock(NotificationsLogic.class);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" usersLogic \u003d mock(UsersLogic.class);"},{"lineNumber":45,"author":{"gitId":"yuanxi1"},"content":" accountsLogic.initLogicDependencies(accountsDb, notificationsLogic, usersLogic, coursesLogic);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":49,"author":{"gitId":"-"},"content":" public void testDeleteAccount_accountExists_success() {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" Account account \u003d getTypicalAccount();"},{"lineNumber":51,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":52,"author":{"gitId":"-"},"content":""},{"lineNumber":53,"author":{"gitId":"-"},"content":" when(accountsLogic.getAccountForGoogleId(googleId)).thenReturn(account);"},{"lineNumber":54,"author":{"gitId":"-"},"content":""},{"lineNumber":55,"author":{"gitId":"-"},"content":" accountsLogic.deleteAccount(googleId);"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" verify(accountsDb, times(1)).deleteAccount(account);"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":61,"author":{"gitId":"-"},"content":" public void testDeleteAccountCascade_googleIdExists_success() {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" Account account \u003d getTypicalAccount();"},{"lineNumber":63,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":64,"author":{"gitId":"-"},"content":" List\u003cUser\u003e users \u003d new ArrayList\u003c\u003e();"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c 2; ++i) {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" users.add(getTypicalInstructor());"},{"lineNumber":68,"author":{"gitId":"-"},"content":" users.add(getTypicalStudent());"},{"lineNumber":69,"author":{"gitId":"-"},"content":" }"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" when(usersLogic.getAllUsersByGoogleId(googleId)).thenReturn(users);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" when(accountsLogic.getAccountForGoogleId(googleId)).thenReturn(account);"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" accountsLogic.deleteAccountCascade(googleId);"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" for (User user : users) {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" verify(usersLogic, times(1)).deleteUser(user);"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }"},{"lineNumber":79,"author":{"gitId":"-"},"content":" verify(accountsDb, times(1)).deleteAccount(account);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" }"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":83,"author":{"gitId":"-"},"content":" public void testUpdateReadNotifications_shouldReturnCorrectReadNotificationId_success()"},{"lineNumber":84,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":85,"author":{"gitId":"-"},"content":" Account account \u003d getTypicalAccount();"},{"lineNumber":86,"author":{"gitId":"-"},"content":" Notification notification \u003d getTypicalNotificationWithId();"},{"lineNumber":87,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":88,"author":{"gitId":"-"},"content":" UUID notificationId \u003d notification.getId();"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" when(accountsDb.getAccountByGoogleId(googleId)).thenReturn(account);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" when(notificationsLogic.getNotification(notificationId)).thenReturn(notification);"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" List\u003cUUID\u003e readNotificationIds \u003d accountsLogic.updateReadNotifications(googleId, notificationId,"},{"lineNumber":94,"author":{"gitId":"-"},"content":" notification.getEndTime());"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" verify(accountsDb, times(1)).getAccountByGoogleId(googleId);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" verify(notificationsLogic, times(1)).getNotification(notificationId);"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" assertEquals(1, readNotificationIds.size());"},{"lineNumber":100,"author":{"gitId":"-"},"content":" assertEquals(notificationId, readNotificationIds.get(0));"},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":104,"author":{"gitId":"-"},"content":" public void testUpdateReadNotifications_shouldAddReadNotificationToAccount_success()"},{"lineNumber":105,"author":{"gitId":"-"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":106,"author":{"gitId":"-"},"content":" Account account \u003d getTypicalAccount();"},{"lineNumber":107,"author":{"gitId":"-"},"content":" Notification notification \u003d getTypicalNotificationWithId();"},{"lineNumber":108,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":109,"author":{"gitId":"-"},"content":" UUID notificationId \u003d notification.getId();"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" when(accountsDb.getAccountByGoogleId(googleId)).thenReturn(account);"},{"lineNumber":112,"author":{"gitId":"-"},"content":" when(notificationsLogic.getNotification(notificationId)).thenReturn(notification);"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" accountsLogic.updateReadNotifications(googleId, notificationId, notification.getEndTime());"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" verify(accountsDb, times(1)).getAccountByGoogleId(googleId);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" verify(notificationsLogic, times(1)).getNotification(notificationId);"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" List\u003cReadNotification\u003e accountReadNotifications \u003d account.getReadNotifications();"},{"lineNumber":120,"author":{"gitId":"-"},"content":" assertEquals(1, accountReadNotifications.size());"},{"lineNumber":121,"author":{"gitId":"-"},"content":" ReadNotification readNotification \u003d accountReadNotifications.get(0);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" assertSame(account, readNotification.getAccount());"},{"lineNumber":123,"author":{"gitId":"-"},"content":" assertSame(notification, readNotification.getNotification());"},{"lineNumber":124,"author":{"gitId":"-"},"content":" }"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":127,"author":{"gitId":"-"},"content":" public void testUpdateReadNotifications_accountDoesNotExist_throwEntityDoesNotExistException() {"},{"lineNumber":128,"author":{"gitId":"-"},"content":" Account account \u003d getTypicalAccount();"},{"lineNumber":129,"author":{"gitId":"-"},"content":" Notification notification \u003d getTypicalNotificationWithId();"},{"lineNumber":130,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":131,"author":{"gitId":"-"},"content":" UUID notificationId \u003d notification.getId();"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" when(accountsDb.getAccountByGoogleId(googleId)).thenReturn(null);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" when(notificationsLogic.getNotification(notificationId)).thenReturn(notification);"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" EntityDoesNotExistException ex \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":137,"author":{"gitId":"-"},"content":" () -\u003e accountsLogic.updateReadNotifications(googleId, notificationId, notification.getEndTime()));"},{"lineNumber":138,"author":{"gitId":"-"},"content":" assertEquals(\"Trying to update the read notifications of a non-existent account.\", ex.getMessage());"},{"lineNumber":139,"author":{"gitId":"-"},"content":" }"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":142,"author":{"gitId":"-"},"content":" public void testUpdateReadNotifications_notificationDoesNotExist_throwEntityDoesNotExistException() {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" Account account \u003d getTypicalAccount();"},{"lineNumber":144,"author":{"gitId":"-"},"content":" Notification notification \u003d getTypicalNotificationWithId();"},{"lineNumber":145,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":146,"author":{"gitId":"-"},"content":" UUID notificationId \u003d notification.getId();"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" when(accountsDb.getAccountByGoogleId(googleId)).thenReturn(account);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" when(notificationsLogic.getNotification(notificationId)).thenReturn(null);"},{"lineNumber":150,"author":{"gitId":"-"},"content":""},{"lineNumber":151,"author":{"gitId":"-"},"content":" EntityDoesNotExistException ex \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":152,"author":{"gitId":"-"},"content":" () -\u003e accountsLogic.updateReadNotifications(googleId, notificationId, notification.getEndTime()));"},{"lineNumber":153,"author":{"gitId":"-"},"content":" assertEquals(\"Trying to mark as read a notification that does not exist.\", ex.getMessage());"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":157,"author":{"gitId":"-"},"content":" public void testUpdateReadNotifications_markExpiredNotificationAsRead_throwInvalidParametersException() {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" Account account \u003d getTypicalAccount();"},{"lineNumber":159,"author":{"gitId":"-"},"content":" Notification notification \u003d getTypicalNotificationWithId();"},{"lineNumber":160,"author":{"gitId":"-"},"content":" notification.setEndTime(Instant.parse(\"2012-01-01T00:00:00Z\"));"},{"lineNumber":161,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":162,"author":{"gitId":"-"},"content":" UUID notificationId \u003d notification.getId();"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" when(accountsDb.getAccountByGoogleId(googleId)).thenReturn(account);"},{"lineNumber":165,"author":{"gitId":"-"},"content":" when(notificationsLogic.getNotification(notificationId)).thenReturn(notification);"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" InvalidParametersException ex \u003d assertThrows(InvalidParametersException.class,"},{"lineNumber":168,"author":{"gitId":"-"},"content":" () -\u003e accountsLogic.updateReadNotifications(googleId, notificationId, notification.getEndTime()));"},{"lineNumber":169,"author":{"gitId":"-"},"content":" assertEquals(\"Trying to mark an expired notification as read.\", ex.getMessage());"},{"lineNumber":170,"author":{"gitId":"-"},"content":" }"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":173,"author":{"gitId":"-"},"content":" public void testGetReadNotificationsId_doesNotHaveReadNotifications_success() {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" Account account \u003d getTypicalAccount();"},{"lineNumber":175,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":176,"author":{"gitId":"-"},"content":" when(accountsDb.getAccountByGoogleId(googleId)).thenReturn(account);"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" List\u003cUUID\u003e readNotifications \u003d accountsLogic.getReadNotificationsId(googleId);"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" assertEquals(0, readNotifications.size());"},{"lineNumber":181,"author":{"gitId":"-"},"content":" }"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":184,"author":{"gitId":"-"},"content":" public void testGetReadNotificationsId_hasReadNotifications_success() {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" Account account \u003d getTypicalAccount();"},{"lineNumber":186,"author":{"gitId":"-"},"content":" List\u003cReadNotification\u003e readNotifications \u003d new ArrayList\u003c\u003e();"},{"lineNumber":187,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c 10; i++) {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" Notification notification \u003d getTypicalNotificationWithId();"},{"lineNumber":189,"author":{"gitId":"-"},"content":" ReadNotification readNotification \u003d new ReadNotification(account, notification);"},{"lineNumber":190,"author":{"gitId":"-"},"content":" readNotifications.add(readNotification);"},{"lineNumber":191,"author":{"gitId":"-"},"content":" }"},{"lineNumber":192,"author":{"gitId":"-"},"content":" account.setReadNotifications(readNotifications);"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"-"},"content":" String googleId \u003d account.getGoogleId();"},{"lineNumber":195,"author":{"gitId":"-"},"content":" when(accountsDb.getAccountByGoogleId(googleId)).thenReturn(account);"},{"lineNumber":196,"author":{"gitId":"-"},"content":""},{"lineNumber":197,"author":{"gitId":"-"},"content":" List\u003cUUID\u003e actualReadNotifications \u003d accountsLogic.getReadNotificationsId(googleId);"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" assertEquals(10, actualReadNotifications.size());"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":" for (int i \u003d 0; i \u003c 10; i++) {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" assertEquals(readNotifications.get(i).getNotification().getId(),"},{"lineNumber":203,"author":{"gitId":"-"},"content":" actualReadNotifications.get(i));"},{"lineNumber":204,"author":{"gitId":"-"},"content":" }"},{"lineNumber":205,"author":{"gitId":"-"},"content":" }"},{"lineNumber":206,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"yuanxi1":3,"-":203}},{"path":"src/test/java/teammates/sqllogic/core/CoursesLogicTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.mock;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.times;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.verify;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.when;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import static teammates.common.util.Const.ERROR_CREATE_ENTITY_ALREADY_EXISTS;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import static teammates.common.util.Const.ERROR_UPDATE_NON_EXISTENT;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import java.time.Duration;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.CoursesDb;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":30,"author":{"gitId":"-"},"content":" * SUT: {@code CoursesLogic}."},{"lineNumber":31,"author":{"gitId":"-"},"content":" */"},{"lineNumber":32,"author":{"gitId":"-"},"content":"public class CoursesLogicTest extends BaseTestCase {"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" private CoursesLogic coursesLogic \u003d CoursesLogic.inst();"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" private UsersLogic usersLogic;"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" private FeedbackSessionsLogic fsLogic;"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":" private CoursesDb coursesDb;"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":43,"author":{"gitId":"-"},"content":" public void setUp() {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" coursesDb \u003d mock(CoursesDb.class);"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" fsLogic \u003d mock(FeedbackSessionsLogic.class);"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" usersLogic \u003d mock(UsersLogic.class);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" coursesLogic.initLogicDependencies(coursesDb, fsLogic, usersLogic);"},{"lineNumber":48,"author":{"gitId":"-"},"content":" }"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":51,"author":{"gitId":"-"},"content":" public void testMoveCourseToRecycleBin_shouldReturnBinnedCourse_success()"},{"lineNumber":52,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":54,"author":{"gitId":"-"},"content":" String courseId \u003d course.getId();"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(course);"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" Course binnedCourse \u003d coursesLogic.moveCourseToRecycleBin(courseId);"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" verify(coursesDb, times(1)).getCourse(courseId);"},{"lineNumber":61,"author":{"gitId":"-"},"content":" assertNotNull(binnedCourse);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" }"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":65,"author":{"gitId":"-"},"content":" public void testMoveCourseToRecycleBin_courseDoesNotExist_throwEntityDoesNotExistException() {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" String courseId \u003d getTypicalCourse().getId();"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(null);"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" EntityDoesNotExistException ex \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" () -\u003e coursesLogic.moveCourseToRecycleBin(courseId));"},{"lineNumber":72,"author":{"gitId":"-"},"content":""},{"lineNumber":73,"author":{"gitId":"-"},"content":" assertEquals(\"Trying to move a non-existent course to recycling bin.\", ex.getMessage());"},{"lineNumber":74,"author":{"gitId":"-"},"content":" }"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":77,"author":{"gitId":"-"},"content":" public void testRestoreCourseFromRecycleBin_shouldSetDeletedAtToNull_success()"},{"lineNumber":78,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":80,"author":{"gitId":"-"},"content":" String courseId \u003d course.getId();"},{"lineNumber":81,"author":{"gitId":"-"},"content":" course.setDeletedAt(Instant.parse(\"2021-01-01T00:00:00Z\"));"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(course);"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" coursesLogic.restoreCourseFromRecycleBin(courseId);"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" verify(coursesDb, times(1)).getCourse(courseId);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" assertNull(course.getDeletedAt());"},{"lineNumber":89,"author":{"gitId":"-"},"content":" }"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":92,"author":{"gitId":"-"},"content":" public void testRestoreCourseFromRecycleBin_courseDoesNotExist_throwEntityDoesNotExistException() {"},{"lineNumber":93,"author":{"gitId":"-"},"content":" String courseId \u003d getTypicalCourse().getId();"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(null);"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" EntityDoesNotExistException ex \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":98,"author":{"gitId":"-"},"content":" () -\u003e coursesLogic.restoreCourseFromRecycleBin(courseId));"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" assertEquals(\"Trying to restore a non-existent course from recycling bin.\", ex.getMessage());"},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":104,"author":{"gitId":"-"},"content":" public void testGetSectionNamesForCourse_shouldReturnListOfSectionNames_success() throws EntityDoesNotExistException {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":106,"author":{"gitId":"-"},"content":" String courseId \u003d course.getId();"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" Section s1 \u003d getTypicalSection();"},{"lineNumber":109,"author":{"gitId":"-"},"content":" s1.setName(\"test-sectionName1\");"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" Section s2 \u003d getTypicalSection();"},{"lineNumber":112,"author":{"gitId":"-"},"content":" s2.setName(\"test-sectionName2\");"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" List\u003cSection\u003e sections \u003d new ArrayList\u003c\u003e();"},{"lineNumber":115,"author":{"gitId":"-"},"content":" sections.add(s1);"},{"lineNumber":116,"author":{"gitId":"-"},"content":" sections.add(s2);"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" course.setSections(sections);"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(course);"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" List\u003cString\u003e sectionNames \u003d coursesLogic.getSectionNamesForCourse(courseId);"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" verify(coursesDb, times(1)).getCourse(courseId);"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" List\u003cString\u003e expectedSectionNames \u003d List.of(\"test-sectionName1\", \"test-sectionName2\");"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" assertEquals(expectedSectionNames, sectionNames);"},{"lineNumber":129,"author":{"gitId":"-"},"content":" }"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":132,"author":{"gitId":"-"},"content":" public void testGetSectionNamesForCourse_courseDoesNotExist_throwEntityDoesNotExistException()"},{"lineNumber":133,"author":{"gitId":"-"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":134,"author":{"gitId":"-"},"content":" String courseId \u003d getTypicalCourse().getId();"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(null);"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" EntityDoesNotExistException ex \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":139,"author":{"gitId":"-"},"content":" () -\u003e coursesLogic.getSectionNamesForCourse(courseId));"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" assertEquals(\"Trying to get section names for a non-existent course.\", ex.getMessage());"},{"lineNumber":142,"author":{"gitId":"-"},"content":" }"},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":145,"author":{"gitId":"domoberzin"},"content":" public void testCreateCourse_shouldReturnCreatedCourse_success()"},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":147,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":148,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":149,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.createCourse(course)).thenReturn(course);"},{"lineNumber":150,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":151,"author":{"gitId":"domoberzin"},"content":" Course createdCourse \u003d coursesLogic.createCourse(course);"},{"lineNumber":152,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":153,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).createCourse(course);"},{"lineNumber":154,"author":{"gitId":"domoberzin"},"content":" assertNotNull(createdCourse);"},{"lineNumber":155,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":156,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":157,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":158,"author":{"gitId":"domoberzin"},"content":" public void testCreateDuplicateCourse_throwEntityAlreadyExistsException()"},{"lineNumber":159,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":160,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":161,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":162,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.createCourse(course))"},{"lineNumber":163,"author":{"gitId":"domoberzin"},"content":" .thenThrow(new EntityAlreadyExistsException("},{"lineNumber":164,"author":{"gitId":"domoberzin"},"content":" String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, course.toString())));"},{"lineNumber":165,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":" EntityAlreadyExistsException ex \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" () -\u003e coursesLogic.createCourse(course));"},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" assertEquals(String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, course.toString()), ex.getMessage());"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":171,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":172,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":" public void testGetCourse_shouldReturnCourse_success() {"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d course.getId();"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(course);"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" Course returnedCourse \u003d coursesLogic.getCourse(courseId);"},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).getCourse(courseId);"},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":" assertNotNull(returnedCourse);"},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":184,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":185,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":186,"author":{"gitId":"domoberzin"},"content":" public void testDeleteCourseCascade_shouldDeleteCourse_success() {"},{"lineNumber":187,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":188,"author":{"gitId":"domoberzin"},"content":" List\u003cInstructor\u003e instructors \u003d new ArrayList\u003c\u003e();"},{"lineNumber":189,"author":{"gitId":"domoberzin"},"content":" List\u003cFeedbackSession\u003e feedbackSessions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":190,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":191,"author":{"gitId":"domoberzin"},"content":" FeedbackSession fs \u003d new FeedbackSession(\"test-fs\", course, \"test@email.com\","},{"lineNumber":192,"author":{"gitId":"domoberzin"},"content":" \"test\", Instant.now(), Instant.now(), Instant.now(), Instant.now(), Duration.ofSeconds(60),"},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":" false, false, false);"},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" feedbackSessions.add(fs);"},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" instructors.add(getTypicalInstructor());"},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":" when(fsLogic.getFeedbackSessionsForCourse(course.getId())).thenReturn(feedbackSessions);"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" when(usersLogic.getInstructorsForCourse(course.getId())).thenReturn(instructors);"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getCourse(course.getId())).thenReturn(course);"},{"lineNumber":200,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":201,"author":{"gitId":"domoberzin"},"content":" coursesLogic.deleteCourseCascade(course.getId());"},{"lineNumber":202,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":203,"author":{"gitId":"domoberzin"},"content":" verify(usersLogic, times(1)).deleteStudentsInCourseCascade(course.getId());"},{"lineNumber":204,"author":{"gitId":"domoberzin"},"content":" verify(usersLogic, times(1)).getInstructorsForCourse(course.getId());"},{"lineNumber":205,"author":{"gitId":"domoberzin"},"content":" verify(usersLogic, times(1)).deleteInstructorCascade(course.getId(), instructors.get(0).getEmail());"},{"lineNumber":206,"author":{"gitId":"domoberzin"},"content":" verify(fsLogic, times(1)).deleteFeedbackSessionCascade(fs.getName(), course.getId());"},{"lineNumber":207,"author":{"gitId":"domoberzin"},"content":" verify(fsLogic, times(1)).getFeedbackSessionsForCourse(course.getId());"},{"lineNumber":208,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).deleteCourse(course);"},{"lineNumber":209,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).deleteSectionsByCourseId(course.getId());"},{"lineNumber":210,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":211,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":212,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":213,"author":{"gitId":"domoberzin"},"content":" public void testUpdateCourse_shouldReturnUpdatedCourse_success()"},{"lineNumber":214,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":215,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":216,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d course.getId();"},{"lineNumber":217,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":218,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(course);"},{"lineNumber":219,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":220,"author":{"gitId":"domoberzin"},"content":" Course updatedCourse \u003d coursesLogic.updateCourse(courseId, \"Test Course 1\", \"Asia/India\");"},{"lineNumber":221,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":222,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).getCourse(courseId);"},{"lineNumber":223,"author":{"gitId":"domoberzin"},"content":" assertNotNull(updatedCourse);"},{"lineNumber":224,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"Test Course 1\", updatedCourse.getName());"},{"lineNumber":225,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"Asia/India\", updatedCourse.getTimeZone());"},{"lineNumber":226,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":227,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":228,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":229,"author":{"gitId":"domoberzin"},"content":" public void testUpdateCourse_throwEntityDoesNotExistException()"},{"lineNumber":230,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":231,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":232,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d course.getId();"},{"lineNumber":233,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":234,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(null);"},{"lineNumber":235,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":236,"author":{"gitId":"domoberzin"},"content":" EntityDoesNotExistException ex \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":237,"author":{"gitId":"domoberzin"},"content":" () -\u003e coursesLogic.updateCourse(courseId, course.getName(), \"Asia/Singapore\"));"},{"lineNumber":238,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":239,"author":{"gitId":"domoberzin"},"content":" assertEquals(ERROR_UPDATE_NON_EXISTENT + Course.class, ex.getMessage());"},{"lineNumber":240,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":241,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":242,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":243,"author":{"gitId":"domoberzin"},"content":" public void testUpdateCourse_throwInvalidParametersException()"},{"lineNumber":244,"author":{"gitId":"domoberzin"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":245,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":246,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d course.getId();"},{"lineNumber":247,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":248,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(course);"},{"lineNumber":249,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":250,"author":{"gitId":"domoberzin"},"content":" InvalidParametersException ex \u003d assertThrows(InvalidParametersException.class,"},{"lineNumber":251,"author":{"gitId":"domoberzin"},"content":" () -\u003e coursesLogic.updateCourse(courseId, \"\", \"Asia/Singapore\"));"},{"lineNumber":252,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":253,"author":{"gitId":"domoberzin"},"content":" String expectedMessage \u003d \"The field \u0027course name\u0027 is empty.\""},{"lineNumber":254,"author":{"gitId":"domoberzin"},"content":" + \" The value of a/an course name should be no longer than 80 characters.\""},{"lineNumber":255,"author":{"gitId":"domoberzin"},"content":" + \" It should not be empty.\";"},{"lineNumber":256,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":257,"author":{"gitId":"domoberzin"},"content":" assertEquals(expectedMessage, ex.getMessage());"},{"lineNumber":258,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":259,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":260,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":261,"author":{"gitId":"domoberzin"},"content":" public void testCreateSection_shouldReturnCreatedSection_success()"},{"lineNumber":262,"author":{"gitId":"domoberzin"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":263,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":264,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":265,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.createSection(section)).thenReturn(section);"},{"lineNumber":266,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":267,"author":{"gitId":"domoberzin"},"content":" Section createdSection \u003d coursesLogic.createSection(section);"},{"lineNumber":268,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":269,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).createSection(section);"},{"lineNumber":270,"author":{"gitId":"domoberzin"},"content":" assertNotNull(createdSection);"},{"lineNumber":271,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":272,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":273,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":274,"author":{"gitId":"domoberzin"},"content":" public void testCreateDuplicateSection_throwEntityAlreadyExistsException()"},{"lineNumber":275,"author":{"gitId":"domoberzin"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":276,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":277,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":278,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.createSection(section))"},{"lineNumber":279,"author":{"gitId":"domoberzin"},"content":" .thenThrow(new EntityAlreadyExistsException("},{"lineNumber":280,"author":{"gitId":"domoberzin"},"content":" String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, section.toString())));"},{"lineNumber":281,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":282,"author":{"gitId":"domoberzin"},"content":" EntityAlreadyExistsException ex \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":283,"author":{"gitId":"domoberzin"},"content":" () -\u003e coursesLogic.createSection(section));"},{"lineNumber":284,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":285,"author":{"gitId":"domoberzin"},"content":" assertEquals(String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, section.toString()), ex.getMessage());"},{"lineNumber":286,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":287,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":288,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":289,"author":{"gitId":"domoberzin"},"content":" public void testCreateSectionInvalidName_throwInvalidParametersException()"},{"lineNumber":290,"author":{"gitId":"domoberzin"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":291,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":292,"author":{"gitId":"domoberzin"},"content":" section.setName(null);"},{"lineNumber":293,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":294,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.createSection(section)).thenThrow(new InvalidParametersException(section.getInvalidityInfo()));"},{"lineNumber":295,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":296,"author":{"gitId":"domoberzin"},"content":" InvalidParametersException ex \u003d assertThrows(InvalidParametersException.class,"},{"lineNumber":297,"author":{"gitId":"domoberzin"},"content":" () -\u003e coursesLogic.createSection(section));"},{"lineNumber":298,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":299,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"The provided section name is not acceptable to TEAMMATES as it cannot be empty.\", ex.getMessage());"},{"lineNumber":300,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":301,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":302,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":303,"author":{"gitId":"domoberzin"},"content":" public void testGetSectionByCourseIdAndTeam_shouldReturnSection_success() {"},{"lineNumber":304,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":305,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d section.getCourse().getId();"},{"lineNumber":306,"author":{"gitId":"domoberzin"},"content":" String teamName \u003d section.getName();"},{"lineNumber":307,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":308,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getSectionByCourseIdAndTeam(courseId, teamName)).thenReturn(section);"},{"lineNumber":309,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":310,"author":{"gitId":"domoberzin"},"content":" Section returnedSection \u003d coursesLogic.getSectionByCourseIdAndTeam(courseId, teamName);"},{"lineNumber":311,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":312,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).getSectionByCourseIdAndTeam(courseId, teamName);"},{"lineNumber":313,"author":{"gitId":"domoberzin"},"content":" assertNotNull(returnedSection);"},{"lineNumber":314,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":315,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":316,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":317,"author":{"gitId":"domoberzin"},"content":" public void testGetSectionByCourseIdAndTeam_sectionDoesNotExist_returnNull() {"},{"lineNumber":318,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d getTypicalCourse().getId();"},{"lineNumber":319,"author":{"gitId":"domoberzin"},"content":" String teamName \u003d getTypicalSection().getName();"},{"lineNumber":320,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":321,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getSectionByCourseIdAndTeam(courseId, teamName)).thenReturn(null);"},{"lineNumber":322,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":323,"author":{"gitId":"domoberzin"},"content":" Section returnedSection \u003d coursesLogic.getSectionByCourseIdAndTeam(courseId, teamName);"},{"lineNumber":324,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":325,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).getSectionByCourseIdAndTeam(courseId, teamName);"},{"lineNumber":326,"author":{"gitId":"domoberzin"},"content":" assertNull(returnedSection);"},{"lineNumber":327,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":328,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":329,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":330,"author":{"gitId":"domoberzin"},"content":" public void testGetCourseInstitute_shouldReturnInstitute_success() {"},{"lineNumber":331,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":332,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d course.getId();"},{"lineNumber":333,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":334,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(course);"},{"lineNumber":335,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":336,"author":{"gitId":"domoberzin"},"content":" String institute \u003d coursesLogic.getCourseInstitute(courseId);"},{"lineNumber":337,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":338,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).getCourse(courseId);"},{"lineNumber":339,"author":{"gitId":"domoberzin"},"content":" assertNotNull(institute);"},{"lineNumber":340,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":341,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":342,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":343,"author":{"gitId":"domoberzin"},"content":" public void testGetCourseInstituteNonExistentCourse_throwAssertionError() {"},{"lineNumber":344,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":345,"author":{"gitId":"domoberzin"},"content":" String courseId \u003d course.getId();"},{"lineNumber":346,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":347,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getCourse(courseId)).thenReturn(null);"},{"lineNumber":348,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":349,"author":{"gitId":"domoberzin"},"content":" AssertionError ex \u003d assertThrows(AssertionError.class,"},{"lineNumber":350,"author":{"gitId":"domoberzin"},"content":" () -\u003e coursesLogic.getCourseInstitute(courseId));"},{"lineNumber":351,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":352,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"Trying to getCourseInstitute for inexistent course with id \" + courseId, ex.getMessage());"},{"lineNumber":353,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":354,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":355,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":356,"author":{"gitId":"domoberzin"},"content":" public void testCreateTeam_shouldReturnCreatedTeam_success()"},{"lineNumber":357,"author":{"gitId":"domoberzin"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":358,"author":{"gitId":"domoberzin"},"content":" Team team \u003d getTypicalTeam();"},{"lineNumber":359,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":360,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.createTeam(team)).thenReturn(team);"},{"lineNumber":361,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":362,"author":{"gitId":"domoberzin"},"content":" Team createdTeam \u003d coursesLogic.createTeam(team);"},{"lineNumber":363,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":364,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).createTeam(team);"},{"lineNumber":365,"author":{"gitId":"domoberzin"},"content":" assertNotNull(createdTeam);"},{"lineNumber":366,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":367,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":368,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":369,"author":{"gitId":"domoberzin"},"content":" public void testCreateDuplicateTeam_throwEntityAlreadyExistsException()"},{"lineNumber":370,"author":{"gitId":"domoberzin"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":371,"author":{"gitId":"domoberzin"},"content":" Team team \u003d getTypicalTeam();"},{"lineNumber":372,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":373,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.createTeam(team)).thenThrow("},{"lineNumber":374,"author":{"gitId":"domoberzin"},"content":" new EntityAlreadyExistsException("},{"lineNumber":375,"author":{"gitId":"domoberzin"},"content":" String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, team.toString())));"},{"lineNumber":376,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":377,"author":{"gitId":"domoberzin"},"content":" EntityAlreadyExistsException ex \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":378,"author":{"gitId":"domoberzin"},"content":" () -\u003e coursesLogic.createTeam(team));"},{"lineNumber":379,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":380,"author":{"gitId":"domoberzin"},"content":" assertEquals(String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, team.toString()), ex.getMessage());"},{"lineNumber":381,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":382,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":383,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":384,"author":{"gitId":"domoberzin"},"content":" public void testCreateTeamInvalidName_throwInvalidParametersException()"},{"lineNumber":385,"author":{"gitId":"domoberzin"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":386,"author":{"gitId":"domoberzin"},"content":" Team team \u003d getTypicalTeam();"},{"lineNumber":387,"author":{"gitId":"domoberzin"},"content":" team.setName(null);"},{"lineNumber":388,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":389,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.createTeam(team)).thenThrow(new InvalidParametersException(team.getInvalidityInfo()));"},{"lineNumber":390,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":391,"author":{"gitId":"domoberzin"},"content":" InvalidParametersException ex \u003d assertThrows(InvalidParametersException.class,"},{"lineNumber":392,"author":{"gitId":"domoberzin"},"content":" () -\u003e coursesLogic.createTeam(team));"},{"lineNumber":393,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":394,"author":{"gitId":"domoberzin"},"content":" assertEquals(\"The provided team name is not acceptable to TEAMMATES as it cannot be empty.\", ex.getMessage());"},{"lineNumber":395,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":396,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":397,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":398,"author":{"gitId":"domoberzin"},"content":" public void testGetTeamsForSection_shouldReturnListOfTeams_success() {"},{"lineNumber":399,"author":{"gitId":"domoberzin"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":400,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":401,"author":{"gitId":"domoberzin"},"content":" Team t1 \u003d getTypicalTeam();"},{"lineNumber":402,"author":{"gitId":"domoberzin"},"content":" t1.setName(\"test-teamName1\");"},{"lineNumber":403,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":404,"author":{"gitId":"domoberzin"},"content":" Team t2 \u003d getTypicalTeam();"},{"lineNumber":405,"author":{"gitId":"domoberzin"},"content":" t2.setName(\"test-teamName2\");"},{"lineNumber":406,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":407,"author":{"gitId":"domoberzin"},"content":" List\u003cTeam\u003e teams \u003d new ArrayList\u003c\u003e();"},{"lineNumber":408,"author":{"gitId":"domoberzin"},"content":" teams.add(t1);"},{"lineNumber":409,"author":{"gitId":"domoberzin"},"content":" teams.add(t2);"},{"lineNumber":410,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":411,"author":{"gitId":"domoberzin"},"content":" section.setTeams(teams);"},{"lineNumber":412,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":413,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getTeamsForSection(section)).thenReturn(teams);"},{"lineNumber":414,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":415,"author":{"gitId":"domoberzin"},"content":" List\u003cTeam\u003e returnedTeams \u003d coursesLogic.getTeamsForSection(section);"},{"lineNumber":416,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":417,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).getTeamsForSection(section);"},{"lineNumber":418,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":419,"author":{"gitId":"domoberzin"},"content":" List\u003cTeam\u003e expectedTeams \u003d List.of(t1, t2);"},{"lineNumber":420,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":421,"author":{"gitId":"domoberzin"},"content":" assertEquals(expectedTeams, returnedTeams);"},{"lineNumber":422,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":423,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":424,"author":{"gitId":"domoberzin"},"content":" @Test"},{"lineNumber":425,"author":{"gitId":"domoberzin"},"content":" public void testGetTeamsForCourse_shouldReturnListOfTeams_success() {"},{"lineNumber":426,"author":{"gitId":"domoberzin"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":427,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":428,"author":{"gitId":"domoberzin"},"content":" Team t1 \u003d getTypicalTeam();"},{"lineNumber":429,"author":{"gitId":"domoberzin"},"content":" t1.setName(\"test-teamName1\");"},{"lineNumber":430,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":431,"author":{"gitId":"domoberzin"},"content":" Team t2 \u003d getTypicalTeam();"},{"lineNumber":432,"author":{"gitId":"domoberzin"},"content":" t2.setName(\"test-teamName2\");"},{"lineNumber":433,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":434,"author":{"gitId":"domoberzin"},"content":" List\u003cTeam\u003e teams \u003d new ArrayList\u003c\u003e();"},{"lineNumber":435,"author":{"gitId":"domoberzin"},"content":" teams.add(t1);"},{"lineNumber":436,"author":{"gitId":"domoberzin"},"content":" teams.add(t2);"},{"lineNumber":437,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":438,"author":{"gitId":"domoberzin"},"content":" when(coursesDb.getTeamsForCourse(course.getId())).thenReturn(teams);"},{"lineNumber":439,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":440,"author":{"gitId":"domoberzin"},"content":" List\u003cTeam\u003e returnedTeams \u003d coursesLogic.getTeamsForCourse(course.getId());"},{"lineNumber":441,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":442,"author":{"gitId":"domoberzin"},"content":" verify(coursesDb, times(1)).getTeamsForCourse(course.getId());"},{"lineNumber":443,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":444,"author":{"gitId":"domoberzin"},"content":" List\u003cTeam\u003e expectedTeams \u003d List.of(t1, t2);"},{"lineNumber":445,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":446,"author":{"gitId":"domoberzin"},"content":" assertEquals(expectedTeams, returnedTeams);"},{"lineNumber":447,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":448,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":319,"-":129}},{"path":"src/test/java/teammates/sqllogic/core/FeedbackQuestionsLogicTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.mock;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import static org.mockito.Mockito.when;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlCourseRoster;"},{"lineNumber":15,"author":{"gitId":"marquestye"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlapi.FeedbackQuestionsDb;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":25,"author":{"gitId":"-"},"content":" * SUT: {@link FeedbackQuestionsLogic}."},{"lineNumber":26,"author":{"gitId":"-"},"content":" */"},{"lineNumber":27,"author":{"gitId":"-"},"content":"public class FeedbackQuestionsLogicTest extends BaseTestCase {"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" private FeedbackQuestionsLogic fqLogic \u003d FeedbackQuestionsLogic.inst();"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" private FeedbackQuestionsDb fqDb;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" private UsersLogic usersLogic;"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":36,"author":{"gitId":"-"},"content":" public void setUpMethod() {"},{"lineNumber":37,"author":{"gitId":"-"},"content":" fqDb \u003d mock(FeedbackQuestionsDb.class);"},{"lineNumber":38,"author":{"gitId":"-"},"content":" CoursesLogic coursesLogic \u003d mock(CoursesLogic.class);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" usersLogic \u003d mock(UsersLogic.class);"},{"lineNumber":40,"author":{"gitId":"-"},"content":" FeedbackResponsesLogic frLogic \u003d mock(FeedbackResponsesLogic.class);"},{"lineNumber":41,"author":{"gitId":"-"},"content":" FeedbackSessionsLogic feedbackSessionsLogic \u003d mock(FeedbackSessionsLogic.class);"},{"lineNumber":42,"author":{"gitId":"-"},"content":" fqLogic.initLogicDependencies(fqDb, coursesLogic, frLogic, usersLogic, feedbackSessionsLogic);"},{"lineNumber":43,"author":{"gitId":"-"},"content":" }"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":46,"author":{"gitId":"-"},"content":" public void testGetFeedbackQuestionsForSession_questionNumbersInOrder_success() {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":48,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questions \u003d createQuestionList(fs, 5);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" fs.setId(UUID.randomUUID());"},{"lineNumber":52,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForSession(fs.getId())).thenReturn(questions);"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e actualQuestions \u003d fqLogic.getFeedbackQuestionsForSession(fs);"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" assertEquals(questions.size(), actualQuestions.size());"},{"lineNumber":57,"author":{"gitId":"-"},"content":" assertTrue(questions.containsAll(actualQuestions));"},{"lineNumber":58,"author":{"gitId":"-"},"content":" }"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":61,"author":{"gitId":"-"},"content":" public void testGetFeedbackQuestionsForSession_questionNumbersOutOfOrder_success() {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":63,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" FeedbackQuestion fq3 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" FeedbackQuestion fq4 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" FeedbackQuestion fq5 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":69,"author":{"gitId":"-"},"content":""},{"lineNumber":70,"author":{"gitId":"-"},"content":" fq1.setQuestionNumber(1);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" fq2.setQuestionNumber(2);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" fq3.setQuestionNumber(3);"},{"lineNumber":73,"author":{"gitId":"-"},"content":" fq4.setQuestionNumber(4);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" fq5.setQuestionNumber(5);"},{"lineNumber":75,"author":{"gitId":"-"},"content":""},{"lineNumber":76,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questions \u003d new ArrayList\u003c\u003e(List.of(fq2, fq4, fq3, fq1, fq5));"},{"lineNumber":77,"author":{"gitId":"-"},"content":" fs.setId(UUID.randomUUID());"},{"lineNumber":78,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForSession(fs.getId())).thenReturn(questions);"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e actualQuestions \u003d fqLogic.getFeedbackQuestionsForSession(fs);"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" assertEquals(questions.size(), actualQuestions.size());"},{"lineNumber":83,"author":{"gitId":"-"},"content":" assertTrue(questions.containsAll(actualQuestions));"},{"lineNumber":84,"author":{"gitId":"-"},"content":" }"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":87,"author":{"gitId":"-"},"content":" public void testCreateFeedbackQuestion_questionNumbersAreConsistent_canCreateFeedbackQuestion()"},{"lineNumber":88,"author":{"gitId":"marquestye"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":89,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":90,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" FeedbackQuestion newQuestion \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" newQuestion.setQuestionNumber(5);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsBefore \u003d createQuestionList(fs, 4);"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" fs.setId(UUID.randomUUID());"},{"lineNumber":97,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForSession(fs.getId())).thenReturn(questionsBefore);"},{"lineNumber":98,"author":{"gitId":"-"},"content":" when(fqDb.createFeedbackQuestion(newQuestion)).thenReturn(newQuestion);"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" FeedbackQuestion createdQuestion \u003d fqLogic.createFeedbackQuestion(newQuestion);"},{"lineNumber":101,"author":{"gitId":"-"},"content":" assertEquals(newQuestion, createdQuestion);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":105,"author":{"gitId":"-"},"content":" public void testCreateFeedbackQuestion_questionNumbersAreInconsistent_canCreateFeedbackQuestion()"},{"lineNumber":106,"author":{"gitId":"marquestye"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":108,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" FeedbackQuestion fq3 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":112,"author":{"gitId":"-"},"content":" FeedbackQuestion fq4 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" FeedbackQuestion fq5 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" fq1.setQuestionNumber(2);"},{"lineNumber":115,"author":{"gitId":"-"},"content":" fq2.setQuestionNumber(3);"},{"lineNumber":116,"author":{"gitId":"-"},"content":" fq3.setQuestionNumber(4);"},{"lineNumber":117,"author":{"gitId":"-"},"content":" fq4.setQuestionNumber(5);"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsBefore \u003d new ArrayList\u003c\u003e(List.of(fq1, fq2, fq3, fq4));"},{"lineNumber":120,"author":{"gitId":"-"},"content":" fs.setId(UUID.randomUUID());"},{"lineNumber":121,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForSession(fs.getId())).thenReturn(questionsBefore);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" when(fqDb.createFeedbackQuestion(fq5)).thenReturn(fq5);"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" FeedbackQuestion createdQuestion \u003d fqLogic.createFeedbackQuestion(fq5);"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" assertEquals(fq5, createdQuestion);"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" @Test(enabled \u003d false)"},{"lineNumber":130,"author":{"gitId":"-"},"content":" public void testCreateFeedbackQuestion_oldQuestionNumberLargerThanNewQuestionNumber_adjustQuestionNumberCorrectly()"},{"lineNumber":131,"author":{"gitId":"marquestye"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":133,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":135,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" FeedbackQuestion fq3 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" FeedbackQuestion fq4 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":138,"author":{"gitId":"-"},"content":" FeedbackQuestion fq5 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" fq1.setQuestionNumber(2);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" fq2.setQuestionNumber(3);"},{"lineNumber":141,"author":{"gitId":"-"},"content":" fq3.setQuestionNumber(4);"},{"lineNumber":142,"author":{"gitId":"-"},"content":" fq4.setQuestionNumber(5);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" fq5.setQuestionNumber(1);"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsBefore \u003d new ArrayList\u003c\u003e(List.of(fq1, fq2, fq3, fq4));"},{"lineNumber":146,"author":{"gitId":"-"},"content":" fs.setId(UUID.randomUUID());"},{"lineNumber":147,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForSession(fs.getId())).thenReturn(questionsBefore);"},{"lineNumber":148,"author":{"gitId":"-"},"content":" when(fqDb.createFeedbackQuestion(fq5)).thenReturn(fq5);"},{"lineNumber":149,"author":{"gitId":"-"},"content":""},{"lineNumber":150,"author":{"gitId":"-"},"content":" fqLogic.createFeedbackQuestion(fq5);"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" assertEquals(1, fq1.getQuestionNumber().intValue());"},{"lineNumber":153,"author":{"gitId":"-"},"content":" assertEquals(2, fq2.getQuestionNumber().intValue());"},{"lineNumber":154,"author":{"gitId":"-"},"content":" assertEquals(3, fq3.getQuestionNumber().intValue());"},{"lineNumber":155,"author":{"gitId":"-"},"content":" assertEquals(4, fq4.getQuestionNumber().intValue());"},{"lineNumber":156,"author":{"gitId":"-"},"content":" }"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"-"},"content":" @Test(enabled \u003d false)"},{"lineNumber":159,"author":{"gitId":"-"},"content":" public void testCreateFeedbackQuestion_oldQuestionNumberSmallerThanNewQuestionNumber_adjustQuestionNumberCorrectly()"},{"lineNumber":160,"author":{"gitId":"marquestye"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":161,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":162,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":164,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":165,"author":{"gitId":"-"},"content":" FeedbackQuestion fq3 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":166,"author":{"gitId":"-"},"content":" FeedbackQuestion fq4 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":167,"author":{"gitId":"-"},"content":" FeedbackQuestion fq5 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":168,"author":{"gitId":"-"},"content":" fq1.setQuestionNumber(0);"},{"lineNumber":169,"author":{"gitId":"-"},"content":" fq2.setQuestionNumber(1);"},{"lineNumber":170,"author":{"gitId":"-"},"content":" fq3.setQuestionNumber(2);"},{"lineNumber":171,"author":{"gitId":"-"},"content":" fq4.setQuestionNumber(3);"},{"lineNumber":172,"author":{"gitId":"-"},"content":""},{"lineNumber":173,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsBefore \u003d new ArrayList\u003c\u003e(List.of(fq1, fq2, fq3, fq4));"},{"lineNumber":174,"author":{"gitId":"-"},"content":" fs.setId(UUID.randomUUID());"},{"lineNumber":175,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForSession(fs.getId())).thenReturn(questionsBefore);"},{"lineNumber":176,"author":{"gitId":"-"},"content":" when(fqDb.createFeedbackQuestion(fq5)).thenReturn(fq5);"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" fqLogic.createFeedbackQuestion(fq5);"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" assertEquals(1, fq1.getQuestionNumber().intValue());"},{"lineNumber":181,"author":{"gitId":"-"},"content":" assertEquals(2, fq2.getQuestionNumber().intValue());"},{"lineNumber":182,"author":{"gitId":"-"},"content":" assertEquals(3, fq3.getQuestionNumber().intValue());"},{"lineNumber":183,"author":{"gitId":"-"},"content":" assertEquals(4, fq4.getQuestionNumber().intValue());"},{"lineNumber":184,"author":{"gitId":"-"},"content":" }"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":187,"author":{"gitId":"-"},"content":" public void testGetFeedbackQuestionsForStudents_success() {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":189,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":190,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":191,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":192,"author":{"gitId":"-"},"content":" FeedbackQuestion fq3 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":193,"author":{"gitId":"-"},"content":" FeedbackQuestion fq4 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsSelf \u003d List.of(fq1, fq2);"},{"lineNumber":196,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsStudent \u003d List.of(fq3, fq4);"},{"lineNumber":197,"author":{"gitId":"-"},"content":""},{"lineNumber":198,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e expectedQuestions \u003d List.of(fq1, fq2, fq3, fq4);"},{"lineNumber":199,"author":{"gitId":"-"},"content":""},{"lineNumber":200,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForGiverType(fs, FeedbackParticipantType.SELF)).thenReturn(questionsSelf);"},{"lineNumber":201,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForGiverType(fs, FeedbackParticipantType.STUDENTS)).thenReturn(questionsStudent);"},{"lineNumber":202,"author":{"gitId":"-"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e actualQuestions \u003d fqLogic.getFeedbackQuestionsForStudents(fs);"},{"lineNumber":204,"author":{"gitId":"-"},"content":""},{"lineNumber":205,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestions.size(), actualQuestions.size());"},{"lineNumber":206,"author":{"gitId":"-"},"content":" assertTrue(actualQuestions.containsAll(actualQuestions));"},{"lineNumber":207,"author":{"gitId":"-"},"content":" }"},{"lineNumber":208,"author":{"gitId":"-"},"content":""},{"lineNumber":209,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":210,"author":{"gitId":"-"},"content":" public void testGetFeedbackQuestionsForInstructors_instructorIsCreator_success() {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":212,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":213,"author":{"gitId":"-"},"content":" fs.setCreatorEmail(\"instr1@teammates.tmt\");"},{"lineNumber":214,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":215,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":216,"author":{"gitId":"-"},"content":" FeedbackQuestion fq3 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":217,"author":{"gitId":"-"},"content":" FeedbackQuestion fq4 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":218,"author":{"gitId":"-"},"content":""},{"lineNumber":219,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsInstructors \u003d List.of(fq1, fq2);"},{"lineNumber":220,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsSelf \u003d List.of(fq3, fq4);"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForGiverType(fs, FeedbackParticipantType.INSTRUCTORS))"},{"lineNumber":223,"author":{"gitId":"-"},"content":" .thenReturn(questionsInstructors);"},{"lineNumber":224,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForGiverType(fs, FeedbackParticipantType.SELF)).thenReturn(questionsSelf);"},{"lineNumber":225,"author":{"gitId":"-"},"content":""},{"lineNumber":226,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e expectedQuestions \u003d List.of(fq1, fq2, fq3, fq4);"},{"lineNumber":227,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e actualQuestions \u003d fqLogic.getFeedbackQuestionsForInstructors(fs, \"instr1@teammates.tmt\");"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestions.size(), actualQuestions.size());"},{"lineNumber":230,"author":{"gitId":"-"},"content":" assertTrue(actualQuestions.containsAll(actualQuestions));"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":234,"author":{"gitId":"-"},"content":" public void testGetFeedbackQuestionsForInstructors_instructorIsNotCreator_success() {"},{"lineNumber":235,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":236,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":237,"author":{"gitId":"-"},"content":" fs.setCreatorEmail(\"instr1@teammates.tmt\");"},{"lineNumber":238,"author":{"gitId":"-"},"content":" FeedbackQuestion fq1 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":239,"author":{"gitId":"-"},"content":" FeedbackQuestion fq2 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":240,"author":{"gitId":"-"},"content":" FeedbackQuestion fq3 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":241,"author":{"gitId":"-"},"content":" FeedbackQuestion fq4 \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":242,"author":{"gitId":"-"},"content":""},{"lineNumber":243,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsInstructors \u003d List.of(fq1, fq2);"},{"lineNumber":244,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questionsSelf \u003d List.of(fq3, fq4);"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForGiverType(fs, FeedbackParticipantType.INSTRUCTORS))"},{"lineNumber":247,"author":{"gitId":"-"},"content":" .thenReturn(questionsInstructors);"},{"lineNumber":248,"author":{"gitId":"-"},"content":" when(fqDb.getFeedbackQuestionsForGiverType(fs, FeedbackParticipantType.SELF)).thenReturn(questionsSelf);"},{"lineNumber":249,"author":{"gitId":"-"},"content":""},{"lineNumber":250,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e expectedQuestions \u003d List.of(fq1, fq2);"},{"lineNumber":251,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e actualQuestions \u003d fqLogic.getFeedbackQuestionsForInstructors(fs, \"instr2@teammates.tmt\");"},{"lineNumber":252,"author":{"gitId":"-"},"content":""},{"lineNumber":253,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestions.size(), actualQuestions.size());"},{"lineNumber":254,"author":{"gitId":"-"},"content":" assertTrue(actualQuestions.containsAll(actualQuestions));"},{"lineNumber":255,"author":{"gitId":"-"},"content":" }"},{"lineNumber":256,"author":{"gitId":"-"},"content":""},{"lineNumber":257,"author":{"gitId":"-"},"content":" @Test(enabled \u003d false)"},{"lineNumber":258,"author":{"gitId":"-"},"content":" public void testGetRecipientsOfQuestion_giverTypeStudents() {"},{"lineNumber":259,"author":{"gitId":"-"},"content":" Course c \u003d getTypicalCourse();"},{"lineNumber":260,"author":{"gitId":"-"},"content":" FeedbackSession fs \u003d getTypicalFeedbackSessionForCourse(c);"},{"lineNumber":261,"author":{"gitId":"-"},"content":" FeedbackQuestion fq \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":262,"author":{"gitId":"-"},"content":""},{"lineNumber":263,"author":{"gitId":"-"},"content":" Student s1 \u003d getTypicalStudent();"},{"lineNumber":264,"author":{"gitId":"-"},"content":" Student s2 \u003d getTypicalStudent();"},{"lineNumber":265,"author":{"gitId":"-"},"content":" List\u003cStudent\u003e studentsInCourse \u003d List.of(s1, s2);"},{"lineNumber":266,"author":{"gitId":"-"},"content":""},{"lineNumber":267,"author":{"gitId":"-"},"content":" SqlCourseRoster courseRoster \u003d new SqlCourseRoster(studentsInCourse, null);"},{"lineNumber":268,"author":{"gitId":"-"},"content":""},{"lineNumber":269,"author":{"gitId":"-"},"content":" when(usersLogic.getStudentsForCourse(\"course-1\")).thenReturn(studentsInCourse);"},{"lineNumber":270,"author":{"gitId":"-"},"content":""},{"lineNumber":271,"author":{"gitId":"-"},"content":" ______TS(\"response to students except self\");"},{"lineNumber":272,"author":{"gitId":"-"},"content":" assertEquals(fqLogic.getRecipientsOfQuestion(fq, null, s2, null).size(), studentsInCourse.size() - 1);"},{"lineNumber":273,"author":{"gitId":"-"},"content":" assertEquals(fqLogic.getRecipientsOfQuestion(fq, null, s2, courseRoster).size(), studentsInCourse.size() - 1);"},{"lineNumber":274,"author":{"gitId":"-"},"content":""},{"lineNumber":275,"author":{"gitId":"-"},"content":" }"},{"lineNumber":276,"author":{"gitId":"-"},"content":""},{"lineNumber":277,"author":{"gitId":"-"},"content":" private List\u003cFeedbackQuestion\u003e createQuestionList(FeedbackSession fs, int numOfQuestions) {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" List\u003cFeedbackQuestion\u003e questions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":279,"author":{"gitId":"-"},"content":" for (int i \u003d 1; i \u003c\u003d numOfQuestions; i++) {"},{"lineNumber":280,"author":{"gitId":"-"},"content":" FeedbackQuestion fq \u003d getTypicalFeedbackQuestionForSession(fs);"},{"lineNumber":281,"author":{"gitId":"-"},"content":" fq.setQuestionNumber(i);"},{"lineNumber":282,"author":{"gitId":"-"},"content":" questions.add(fq);"},{"lineNumber":283,"author":{"gitId":"-"},"content":" }"},{"lineNumber":284,"author":{"gitId":"-"},"content":" return questions;"},{"lineNumber":285,"author":{"gitId":"-"},"content":" }"},{"lineNumber":286,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"marquestye":5,"-":281}},{"path":"src/test/java/teammates/sqllogic/core/FeedbackResponseCommentsLogicTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"mingyuanc"},"content":"package teammates.sqllogic.core;"},{"lineNumber":2,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":3,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.Mockito.mock;"},{"lineNumber":4,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.Mockito.times;"},{"lineNumber":5,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.Mockito.verify;"},{"lineNumber":6,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.Mockito.when;"},{"lineNumber":7,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":8,"author":{"gitId":"mingyuanc"},"content":"import java.util.ArrayList;"},{"lineNumber":9,"author":{"gitId":"mingyuanc"},"content":"import java.util.List;"},{"lineNumber":10,"author":{"gitId":"mingyuanc"},"content":"import java.util.UUID;"},{"lineNumber":11,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":12,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":13,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.Test;"},{"lineNumber":14,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":15,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":16,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":17,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":18,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":19,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlapi.FeedbackResponseCommentsDb;"},{"lineNumber":20,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":21,"author":{"gitId":"mingyuanc"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":22,"author":{"gitId":"mingyuanc"},"content":"import teammates.ui.output.CommentVisibilityType;"},{"lineNumber":23,"author":{"gitId":"mingyuanc"},"content":"import teammates.ui.request.FeedbackResponseCommentUpdateRequest;"},{"lineNumber":24,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":25,"author":{"gitId":"mingyuanc"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"mingyuanc"},"content":" * SUT: {@link FeedbackResponseCommentsLogic}."},{"lineNumber":27,"author":{"gitId":"mingyuanc"},"content":" */"},{"lineNumber":28,"author":{"gitId":"mingyuanc"},"content":"public class FeedbackResponseCommentsLogicTest extends BaseTestCase {"},{"lineNumber":29,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":30,"author":{"gitId":"mingyuanc"},"content":" private static final Long TYPICAL_ID \u003d 100L;"},{"lineNumber":31,"author":{"gitId":"mingyuanc"},"content":" private static final Long NOT_TYPICAL_ID \u003d 101L;"},{"lineNumber":32,"author":{"gitId":"mingyuanc"},"content":" private static final UUID TYPICAL_UUID \u003d UUID.randomUUID();"},{"lineNumber":33,"author":{"gitId":"mingyuanc"},"content":" private FeedbackResponseCommentsLogic frcLogic \u003d FeedbackResponseCommentsLogic.inst();"},{"lineNumber":34,"author":{"gitId":"mingyuanc"},"content":" private FeedbackResponseCommentsDb frcDb;"},{"lineNumber":35,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":36,"author":{"gitId":"mingyuanc"},"content":" @BeforeMethod"},{"lineNumber":37,"author":{"gitId":"mingyuanc"},"content":" public void setUpMethod() {"},{"lineNumber":38,"author":{"gitId":"mingyuanc"},"content":" frcDb \u003d mock(FeedbackResponseCommentsDb.class);"},{"lineNumber":39,"author":{"gitId":"mingyuanc"},"content":" frcLogic.initLogicDependencies(frcDb);"},{"lineNumber":40,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":41,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":42,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":43,"author":{"gitId":"mingyuanc"},"content":" public void testGetComment_commentAlreadyExists_success() {"},{"lineNumber":44,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":45,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":46,"author":{"gitId":"mingyuanc"},"content":" when(frcDb.getFeedbackResponseComment(comment.getId())).thenReturn(comment);"},{"lineNumber":47,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":48,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment commentFetched \u003d frcLogic.getFeedbackResponseComment(TYPICAL_ID);"},{"lineNumber":49,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":50,"author":{"gitId":"mingyuanc"},"content":" assertEquals(comment, commentFetched);"},{"lineNumber":51,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":52,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":53,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":54,"author":{"gitId":"mingyuanc"},"content":" public void testGetCommentForResponse_commentAlreadyExists_success() {"},{"lineNumber":55,"author":{"gitId":"mingyuanc"},"content":" List\u003cFeedbackResponseComment\u003e expectedReturn \u003d new ArrayList\u003c\u003e();"},{"lineNumber":56,"author":{"gitId":"mingyuanc"},"content":" expectedReturn.add(getTypicalResponseComment(TYPICAL_ID));"},{"lineNumber":57,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":58,"author":{"gitId":"mingyuanc"},"content":" when(frcDb.getFeedbackResponseCommentsForResponse(TYPICAL_UUID)).thenReturn(expectedReturn);"},{"lineNumber":59,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":60,"author":{"gitId":"mingyuanc"},"content":" List\u003cFeedbackResponseComment\u003e fetchedReturn \u003d frcLogic.getFeedbackResponseCommentsForResponse(TYPICAL_UUID);"},{"lineNumber":61,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":62,"author":{"gitId":"mingyuanc"},"content":" assertEquals(expectedReturn, fetchedReturn);"},{"lineNumber":63,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":64,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":65,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":66,"author":{"gitId":"mingyuanc"},"content":" public void testGetCommentForResponseFromParticipant_commentAlreadyExists_success() {"},{"lineNumber":67,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":68,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":69,"author":{"gitId":"mingyuanc"},"content":" when(frcDb.getFeedbackResponseCommentForResponseFromParticipant(TYPICAL_UUID)).thenReturn(comment);"},{"lineNumber":70,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":71,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment commentFetched \u003d frcLogic"},{"lineNumber":72,"author":{"gitId":"mingyuanc"},"content":" .getFeedbackResponseCommentForResponseFromParticipant(TYPICAL_UUID);"},{"lineNumber":73,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":74,"author":{"gitId":"mingyuanc"},"content":" assertEquals(comment, commentFetched);"},{"lineNumber":75,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":76,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":77,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":78,"author":{"gitId":"mingyuanc"},"content":" public void testGetComment_commentDoesNotExist_returnsNull() {"},{"lineNumber":79,"author":{"gitId":"mingyuanc"},"content":" when(frcDb.getFeedbackResponseComment(NOT_TYPICAL_ID)).thenReturn(null);"},{"lineNumber":80,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":81,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment commentFetched \u003d frcLogic.getFeedbackResponseComment(NOT_TYPICAL_ID);"},{"lineNumber":82,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":83,"author":{"gitId":"mingyuanc"},"content":" verify(frcDb, times(1)).getFeedbackResponseComment(NOT_TYPICAL_ID);"},{"lineNumber":84,"author":{"gitId":"mingyuanc"},"content":" assertNull(commentFetched);"},{"lineNumber":85,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":86,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":87,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":88,"author":{"gitId":"mingyuanc"},"content":" public void testCreateComment_commentDoesNotExist_success()"},{"lineNumber":89,"author":{"gitId":"mingyuanc"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":90,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":91,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":92,"author":{"gitId":"mingyuanc"},"content":" frcLogic.createFeedbackResponseComment(comment);"},{"lineNumber":93,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":94,"author":{"gitId":"mingyuanc"},"content":" verify(frcDb, times(1)).createFeedbackResponseComment(comment);"},{"lineNumber":95,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":96,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":97,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":98,"author":{"gitId":"mingyuanc"},"content":" public void testCreateComment_commentAlreadyExists_throwsEntityAlreadyExistsException()"},{"lineNumber":99,"author":{"gitId":"mingyuanc"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":100,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":101,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":102,"author":{"gitId":"mingyuanc"},"content":" when(frcDb.createFeedbackResponseComment(comment)).thenThrow(EntityAlreadyExistsException.class);"},{"lineNumber":103,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":104,"author":{"gitId":"mingyuanc"},"content":" assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":105,"author":{"gitId":"mingyuanc"},"content":" () -\u003e frcLogic.createFeedbackResponseComment(comment));"},{"lineNumber":106,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":107,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":108,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":109,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":110,"author":{"gitId":"mingyuanc"},"content":" public void testDeleteComment_commentExists_success() {"},{"lineNumber":111,"author":{"gitId":"mingyuanc"},"content":" frcLogic.deleteFeedbackResponseComment(TYPICAL_ID);"},{"lineNumber":112,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":113,"author":{"gitId":"mingyuanc"},"content":" verify(frcDb, times(1)).deleteFeedbackResponseComment(TYPICAL_ID);"},{"lineNumber":114,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":115,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":116,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":117,"author":{"gitId":"mingyuanc"},"content":" public void testUpdateCommentEmails_success() {"},{"lineNumber":118,"author":{"gitId":"mingyuanc"},"content":" String courseId \u003d \"Course_id\";"},{"lineNumber":119,"author":{"gitId":"mingyuanc"},"content":" String oldEmail \u003d \"oldEmail@gmail.com\";"},{"lineNumber":120,"author":{"gitId":"mingyuanc"},"content":" String newEmail \u003d \"newEmail@gmail.com\";"},{"lineNumber":121,"author":{"gitId":"mingyuanc"},"content":" frcLogic.updateFeedbackResponseCommentsEmails(courseId, oldEmail, newEmail);"},{"lineNumber":122,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":123,"author":{"gitId":"mingyuanc"},"content":" verify(frcDb, times(1)).updateGiverEmailOfFeedbackResponseComments(courseId, oldEmail, newEmail);"},{"lineNumber":124,"author":{"gitId":"mingyuanc"},"content":" verify(frcDb, times(1)).updateLastEditorEmailOfFeedbackResponseComments(courseId, oldEmail, newEmail);"},{"lineNumber":125,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":126,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":127,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":128,"author":{"gitId":"mingyuanc"},"content":" public void testUpdateComment_entityAlreadyExists_success()"},{"lineNumber":129,"author":{"gitId":"mingyuanc"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":130,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":131,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":132,"author":{"gitId":"mingyuanc"},"content":" when(frcDb.getFeedbackResponseComment(comment.getId())).thenReturn(comment);"},{"lineNumber":133,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":134,"author":{"gitId":"mingyuanc"},"content":" String updatedCommentText \u003d \"Update\";"},{"lineNumber":135,"author":{"gitId":"mingyuanc"},"content":" String lastEditorEmail \u003d \"me@gmail.com\";"},{"lineNumber":136,"author":{"gitId":"mingyuanc"},"content":" List\u003cCommentVisibilityType\u003e showCommentTo \u003d new ArrayList\u003c\u003e();"},{"lineNumber":137,"author":{"gitId":"mingyuanc"},"content":" showCommentTo.add(CommentVisibilityType.STUDENTS);"},{"lineNumber":138,"author":{"gitId":"mingyuanc"},"content":" showCommentTo.add(CommentVisibilityType.INSTRUCTORS);"},{"lineNumber":139,"author":{"gitId":"mingyuanc"},"content":" List\u003cCommentVisibilityType\u003e showGiverNameTo \u003d new ArrayList\u003c\u003e();"},{"lineNumber":140,"author":{"gitId":"mingyuanc"},"content":" showGiverNameTo.add(CommentVisibilityType.INSTRUCTORS);"},{"lineNumber":141,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":142,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseCommentUpdateRequest updateRequest \u003d new FeedbackResponseCommentUpdateRequest("},{"lineNumber":143,"author":{"gitId":"mingyuanc"},"content":" updatedCommentText, showCommentTo, showGiverNameTo);"},{"lineNumber":144,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment updatedComment \u003d frcLogic.updateFeedbackResponseComment(TYPICAL_ID, updateRequest,"},{"lineNumber":145,"author":{"gitId":"mingyuanc"},"content":" lastEditorEmail);"},{"lineNumber":146,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":147,"author":{"gitId":"mingyuanc"},"content":" verify(frcDb, times(1)).getFeedbackResponseComment(TYPICAL_ID);"},{"lineNumber":148,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":149,"author":{"gitId":"mingyuanc"},"content":" List\u003cFeedbackParticipantType\u003e expectedShowCommentTo \u003d new ArrayList\u003c\u003e();"},{"lineNumber":150,"author":{"gitId":"mingyuanc"},"content":" expectedShowCommentTo.add(FeedbackParticipantType.STUDENTS);"},{"lineNumber":151,"author":{"gitId":"mingyuanc"},"content":" expectedShowCommentTo.add(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":152,"author":{"gitId":"mingyuanc"},"content":" List\u003cFeedbackParticipantType\u003e expectedShowGiverNameTo \u003d new ArrayList\u003c\u003e();"},{"lineNumber":153,"author":{"gitId":"mingyuanc"},"content":" expectedShowGiverNameTo.add(FeedbackParticipantType.INSTRUCTORS);"},{"lineNumber":154,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":155,"author":{"gitId":"mingyuanc"},"content":" assertEquals(TYPICAL_ID, updatedComment.getId());"},{"lineNumber":156,"author":{"gitId":"mingyuanc"},"content":" assertEquals(updatedCommentText, updatedComment.getCommentText());"},{"lineNumber":157,"author":{"gitId":"mingyuanc"},"content":" assertEquals(expectedShowCommentTo, updatedComment.getShowCommentTo());"},{"lineNumber":158,"author":{"gitId":"mingyuanc"},"content":" assertEquals(expectedShowGiverNameTo, updatedComment.getShowGiverNameTo());"},{"lineNumber":159,"author":{"gitId":"mingyuanc"},"content":" assertEquals(lastEditorEmail, updatedComment.getLastEditorEmail());"},{"lineNumber":160,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":161,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":162,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":163,"author":{"gitId":"mingyuanc"},"content":" public void testUpdateComment_entityDoesNotExist() {"},{"lineNumber":164,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":165,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":166,"author":{"gitId":"mingyuanc"},"content":" when(frcDb.getFeedbackResponseComment(comment.getId())).thenReturn(comment);"},{"lineNumber":167,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":168,"author":{"gitId":"mingyuanc"},"content":" long nonExistentId \u003d 101L;"},{"lineNumber":169,"author":{"gitId":"mingyuanc"},"content":" String updatedCommentText \u003d \"Update\";"},{"lineNumber":170,"author":{"gitId":"mingyuanc"},"content":" String lastEditorEmail \u003d \"me@gmail.com\";"},{"lineNumber":171,"author":{"gitId":"mingyuanc"},"content":" List\u003cCommentVisibilityType\u003e showCommentTo \u003d new ArrayList\u003c\u003e();"},{"lineNumber":172,"author":{"gitId":"mingyuanc"},"content":" showCommentTo.add(CommentVisibilityType.STUDENTS);"},{"lineNumber":173,"author":{"gitId":"mingyuanc"},"content":" showCommentTo.add(CommentVisibilityType.INSTRUCTORS);"},{"lineNumber":174,"author":{"gitId":"mingyuanc"},"content":" List\u003cCommentVisibilityType\u003e showGiverNameTo \u003d new ArrayList\u003c\u003e();"},{"lineNumber":175,"author":{"gitId":"mingyuanc"},"content":" showGiverNameTo.add(CommentVisibilityType.INSTRUCTORS);"},{"lineNumber":176,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":177,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseCommentUpdateRequest updateRequest \u003d new FeedbackResponseCommentUpdateRequest("},{"lineNumber":178,"author":{"gitId":"mingyuanc"},"content":" updatedCommentText, showCommentTo, showGiverNameTo);"},{"lineNumber":179,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":180,"author":{"gitId":"mingyuanc"},"content":" EntityDoesNotExistException ex \u003d assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":181,"author":{"gitId":"mingyuanc"},"content":" () -\u003e frcLogic.updateFeedbackResponseComment(nonExistentId, updateRequest, lastEditorEmail));"},{"lineNumber":182,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":183,"author":{"gitId":"mingyuanc"},"content":" assertEquals(\"Trying to update a feedback response comment that does not exist.\", ex.getMessage());"},{"lineNumber":184,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":185,"author":{"gitId":"mingyuanc"},"content":"}"}],"authorContributionMap":{"mingyuanc":185}},{"path":"src/test/java/teammates/sqlui/webapi/GetFeedbackSessionLogsActionTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.sqlui.webapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.when;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.InstructorPrivileges;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Const;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.output.FeedbackSessionLogData;"},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.output.FeedbackSessionLogEntryData;"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.output.FeedbackSessionLogsData;"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.webapi.GetFeedbackSessionLogsAction;"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.webapi.JsonResult;"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link GetFeedbackSessionLogsAction}."},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":"public class GetFeedbackSessionLogsActionTest extends BaseActionTest\u003cGetFeedbackSessionLogsAction\u003e {"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" private Course course;"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" private Student student1;"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" private Student student2;"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" private FeedbackSession fs1;"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" private long startTime;"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" private long endTime;"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" private String googleId \u003d \"google-id\";"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" String getActionUri() {"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" return Const.ResourceURIs.SESSION_LOGS;"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" String getRequestMethod() {"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":" return GET;"},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" @BeforeMethod"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" void setUp() {"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" FeedbackSession fs2;"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" endTime \u003d Instant.now().toEpochMilli();"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" startTime \u003d endTime - (Const.LOGS_RETENTION_PERIOD.toDays() - 1) * 24 * 60 * 60 * 1000;"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" course \u003d getTypicalCourse();"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" student1 \u003d getTypicalStudent();"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" student1.setEmail(\"student1@teammates.tmt\");"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" student1.setTeam(getTypicalTeam());"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" student2 \u003d getTypicalStudent();"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" student2.setEmail(\"student2@teammates.tmt\");"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" student2.setTeam(getTypicalTeam());"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" fs1 \u003d getTypicalFeedbackSessionForCourse(course);"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" fs1.setName(\"fs1\");"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" fs1.setCreatedAt(Instant.now());"},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" fs2 \u003d getTypicalFeedbackSessionForCourse(course);"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" fs2.setName(\"fs2\");"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" fs2.setCreatedAt(Instant.now());"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getCourse(course.getId())).thenReturn(course);"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getFeedbackSession(fs1.getId())).thenReturn(fs1);"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getStudent(student1.getId())).thenReturn(student1);"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getStudent(student2.getId())).thenReturn(student2);"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSession\u003e feedbackSessions \u003d new ArrayList\u003c\u003e();"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" feedbackSessions.add(fs1);"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" feedbackSessions.add(fs2);"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getFeedbackSessionsForCourse(course.getId())).thenReturn(feedbackSessions);"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student1Session1Log1 \u003d new FeedbackSessionLog(student1, fs1, FeedbackSessionLogType.ACCESS,"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" Instant.ofEpochMilli(startTime));"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student1Session2Log1 \u003d new FeedbackSessionLog(student1, fs2, FeedbackSessionLogType.ACCESS,"},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" Instant.ofEpochMilli(startTime + 1000));"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student1Session2Log2 \u003d new FeedbackSessionLog(student1, fs2,"},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.SUBMISSION, Instant.ofEpochMilli(startTime + 2000));"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student2Session1Log1 \u003d new FeedbackSessionLog(student2, fs1, FeedbackSessionLogType.ACCESS,"},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" Instant.ofEpochMilli(startTime + 3000));"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog student2Session1Log2 \u003d new FeedbackSessionLog(student2, fs1,"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.SUBMISSION, Instant.ofEpochMilli(startTime + 4000));"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e allLogsInCourse \u003d new ArrayList\u003c\u003e();"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" allLogsInCourse.add(student1Session1Log1);"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":" allLogsInCourse.add(student1Session2Log1);"},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":" allLogsInCourse.add(student1Session2Log2);"},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" allLogsInCourse.add(student2Session1Log1);"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":" allLogsInCourse.add(student2Session1Log2);"},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getOrderedFeedbackSessionLogs(course.getId(), null, null, Instant.ofEpochMilli(startTime),"},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":" Instant.ofEpochMilli(endTime))).thenReturn(allLogsInCourse);"},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e student1Logs \u003d new ArrayList\u003c\u003e();"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" student1Logs.add(student1Session1Log1);"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":" student1Logs.add(student1Session2Log1);"},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" student1Logs.add(student1Session2Log2);"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getOrderedFeedbackSessionLogs(course.getId(), student1.getId(), null,"},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":" Instant.ofEpochMilli(startTime), Instant.ofEpochMilli(endTime))).thenReturn(student1Logs);"},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e fs1Logs \u003d new ArrayList\u003c\u003e();"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" fs1Logs.add(student1Session1Log1);"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" fs1Logs.add(student2Session1Log1);"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" fs1Logs.add(student2Session1Log2);"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getOrderedFeedbackSessionLogs(course.getId(), null, fs1.getId(),"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" Instant.ofEpochMilli(startTime), Instant.ofEpochMilli(endTime))).thenReturn(fs1Logs);"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLog\u003e student1Fs1Logs \u003d new ArrayList\u003c\u003e();"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" student1Fs1Logs.add(student1Session1Log1);"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getOrderedFeedbackSessionLogs(course.getId(), student1.getId(), fs1.getId(),"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" Instant.ofEpochMilli(startTime), Instant.ofEpochMilli(endTime))).thenReturn(student1Fs1Logs);"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":" protected void testExecute() {"},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":" JsonResult actionOutput;"},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: not enough parameters\");"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure("},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId());"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure("},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime));"},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure("},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime));"},{"lineNumber":141,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":142,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: invalid course id\");"},{"lineNumber":143,"author":{"gitId":"dishenggg"},"content":" String[] paramsInvalid1 \u003d {"},{"lineNumber":144,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, \"fake-course-id\","},{"lineNumber":145,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student1.getId().toString(),"},{"lineNumber":146,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":" verifyEntityNotFound(paramsInvalid1);"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: invalid student id\");"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":" String[] paramsInvalid2 \u003d {"},{"lineNumber":153,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, \"00000000-0000-0000-0000-000000000000\","},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":158,"author":{"gitId":"dishenggg"},"content":" verifyEntityNotFound(paramsInvalid2);"},{"lineNumber":159,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Failure case: invalid start or end times\");"},{"lineNumber":161,"author":{"gitId":"dishenggg"},"content":" String[] paramsInvalid3 \u003d {"},{"lineNumber":162,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":163,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, \"abc\","},{"lineNumber":164,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":165,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure(paramsInvalid3);"},{"lineNumber":167,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":168,"author":{"gitId":"dishenggg"},"content":" String[] paramsInvalid4 \u003d {"},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":171,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, \" \","},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":" verifyHttpParameterFailure(paramsInvalid4);"},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":175,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: should group by feedback session\");"},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":" String[] paramsSuccessful1 \u003d {"},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":179,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":180,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":181,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":182,"author":{"gitId":"dishenggg"},"content":" actionOutput \u003d getJsonResult(getAction(paramsSuccessful1));"},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogsData fslData \u003d (FeedbackSessionLogsData) actionOutput.getOutput();"},{"lineNumber":185,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogData\u003e fsLogs \u003d fslData.getFeedbackSessionLogs();"},{"lineNumber":186,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":187,"author":{"gitId":"dishenggg"},"content":" // Course has 2 feedback sessions"},{"lineNumber":188,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.size(), 2);"},{"lineNumber":189,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":190,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntryData\u003e fsLogEntries1 \u003d fsLogs.get(0).getFeedbackSessionLogEntries();"},{"lineNumber":191,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntryData\u003e fsLogEntries2 \u003d fsLogs.get(1).getFeedbackSessionLogEntries();"},{"lineNumber":192,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":193,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.size(), 3);"},{"lineNumber":194,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getStudentData().getEmail(), student1.getEmail());"},{"lineNumber":195,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":196,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(1).getStudentData().getEmail(), student2.getEmail());"},{"lineNumber":197,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":198,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(2).getStudentData().getEmail(), student2.getEmail());"},{"lineNumber":199,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(2).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":200,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":201,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.size(), 2);"},{"lineNumber":202,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(0).getStudentData().getEmail(), student1.getEmail());"},{"lineNumber":203,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":204,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(1).getStudentData().getEmail(), student1.getEmail());"},{"lineNumber":205,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":206,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":207,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: should accept optional student id\");"},{"lineNumber":208,"author":{"gitId":"dishenggg"},"content":" String[] paramsSuccessful2 \u003d {"},{"lineNumber":209,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":210,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student1.getId().toString(),"},{"lineNumber":211,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":212,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":213,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":214,"author":{"gitId":"dishenggg"},"content":" actionOutput \u003d getJsonResult(getAction(paramsSuccessful2));"},{"lineNumber":215,"author":{"gitId":"dishenggg"},"content":" fslData \u003d (FeedbackSessionLogsData) actionOutput.getOutput();"},{"lineNumber":216,"author":{"gitId":"dishenggg"},"content":" fsLogs \u003d fslData.getFeedbackSessionLogs();"},{"lineNumber":217,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":218,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.size(), 2);"},{"lineNumber":219,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":220,"author":{"gitId":"dishenggg"},"content":" fsLogEntries1 \u003d fsLogs.get(0).getFeedbackSessionLogEntries();"},{"lineNumber":221,"author":{"gitId":"dishenggg"},"content":" fsLogEntries2 \u003d fsLogs.get(1).getFeedbackSessionLogEntries();"},{"lineNumber":222,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":223,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.size(), 1);"},{"lineNumber":224,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getStudentData().getEmail(), student1.getEmail());"},{"lineNumber":225,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":226,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":227,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.size(), 2);"},{"lineNumber":228,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(0).getStudentData().getEmail(), student1.getEmail());"},{"lineNumber":229,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":230,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(1).getStudentData().getEmail(), student1.getEmail());"},{"lineNumber":231,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries2.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":232,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":233,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: should accept optional feedback session\");"},{"lineNumber":234,"author":{"gitId":"dishenggg"},"content":" String[] paramsSuccessful3 \u003d {"},{"lineNumber":235,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":236,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fs1.getId().toString(),"},{"lineNumber":237,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":238,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":239,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":240,"author":{"gitId":"dishenggg"},"content":" actionOutput \u003d getJsonResult(getAction(paramsSuccessful3));"},{"lineNumber":241,"author":{"gitId":"dishenggg"},"content":" fslData \u003d (FeedbackSessionLogsData) actionOutput.getOutput();"},{"lineNumber":242,"author":{"gitId":"dishenggg"},"content":" fsLogs \u003d fslData.getFeedbackSessionLogs();"},{"lineNumber":243,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":244,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.size(), 2);"},{"lineNumber":245,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(1).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":246,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":247,"author":{"gitId":"dishenggg"},"content":" fsLogEntries1 \u003d fsLogs.get(0).getFeedbackSessionLogEntries();"},{"lineNumber":248,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":249,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.size(), 3);"},{"lineNumber":250,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getStudentData().getEmail(), student1.getEmail());"},{"lineNumber":251,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":252,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(1).getStudentData().getEmail(), student2.getEmail());"},{"lineNumber":253,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":254,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(2).getStudentData().getEmail(), student2.getEmail());"},{"lineNumber":255,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(2).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":256,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":257,"author":{"gitId":"dishenggg"},"content":" ______TS(\"Success case: should accept all optional params\");"},{"lineNumber":258,"author":{"gitId":"dishenggg"},"content":" String[] paramsSuccessful4 \u003d {"},{"lineNumber":259,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":260,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.STUDENT_SQL_ID, student1.getId().toString(),"},{"lineNumber":261,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_ID, fs1.getId().toString(),"},{"lineNumber":262,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":263,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":264,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":265,"author":{"gitId":"dishenggg"},"content":" actionOutput \u003d getJsonResult(getAction(paramsSuccessful4));"},{"lineNumber":266,"author":{"gitId":"dishenggg"},"content":" fslData \u003d (FeedbackSessionLogsData) actionOutput.getOutput();"},{"lineNumber":267,"author":{"gitId":"dishenggg"},"content":" fsLogs \u003d fslData.getFeedbackSessionLogs();"},{"lineNumber":268,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":269,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.size(), 2);"},{"lineNumber":270,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogs.get(1).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":271,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":272,"author":{"gitId":"dishenggg"},"content":" fsLogEntries1 \u003d fsLogs.get(0).getFeedbackSessionLogEntries();"},{"lineNumber":273,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":274,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.size(), 1);"},{"lineNumber":275,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getStudentData().getEmail(), student1.getEmail());"},{"lineNumber":276,"author":{"gitId":"dishenggg"},"content":" assertEquals(fsLogEntries1.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":277,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":278,"author":{"gitId":"dishenggg"},"content":" // TODO: if we restrict the range from start to end time, it should be tested"},{"lineNumber":279,"author":{"gitId":"dishenggg"},"content":" // here as well"},{"lineNumber":280,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":281,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":282,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":283,"author":{"gitId":"dishenggg"},"content":" void testSpecificAccessControl_instructorWithInvalidPermission_cannotAccess() {"},{"lineNumber":284,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":285,"author":{"gitId":"dishenggg"},"content":" Instructor instructor \u003d new Instructor(course, \"name\", \"instructoremail@tm.tmt\","},{"lineNumber":286,"author":{"gitId":"dishenggg"},"content":" false, \"\", null, new InstructorPrivileges());"},{"lineNumber":287,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":288,"author":{"gitId":"dishenggg"},"content":" loginAsInstructor(googleId);"},{"lineNumber":289,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getCourse(course.getId())).thenReturn(course);"},{"lineNumber":290,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getInstructorByGoogleId(course.getId(), googleId)).thenReturn(instructor);"},{"lineNumber":291,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":292,"author":{"gitId":"dishenggg"},"content":" String[] params \u003d {"},{"lineNumber":293,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":294,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":295,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":296,"author":{"gitId":"dishenggg"},"content":" verifyCannotAccess(params);"},{"lineNumber":297,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":298,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":299,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":300,"author":{"gitId":"dishenggg"},"content":" void testSpecificAccessControl_instructorWithPermission_canAccess() {"},{"lineNumber":301,"author":{"gitId":"dishenggg"},"content":" InstructorPrivileges instructorPrivileges \u003d new InstructorPrivileges();"},{"lineNumber":302,"author":{"gitId":"dishenggg"},"content":" instructorPrivileges.updatePrivilege(Const.InstructorPermissions.CAN_MODIFY_SESSION, true);"},{"lineNumber":303,"author":{"gitId":"dishenggg"},"content":" instructorPrivileges.updatePrivilege(Const.InstructorPermissions.CAN_MODIFY_STUDENT, true);"},{"lineNumber":304,"author":{"gitId":"dishenggg"},"content":" instructorPrivileges.updatePrivilege(Const.InstructorPermissions.CAN_MODIFY_INSTRUCTOR, true);"},{"lineNumber":305,"author":{"gitId":"dishenggg"},"content":" Instructor instructor \u003d new Instructor(course, \"name\", \"instructoremail@tm.tmt\","},{"lineNumber":306,"author":{"gitId":"dishenggg"},"content":" false, \"\", null, instructorPrivileges);"},{"lineNumber":307,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":308,"author":{"gitId":"dishenggg"},"content":" loginAsInstructor(googleId);"},{"lineNumber":309,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getCourse(course.getId())).thenReturn(course);"},{"lineNumber":310,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getInstructorByGoogleId(course.getId(), googleId)).thenReturn(instructor);"},{"lineNumber":311,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":312,"author":{"gitId":"dishenggg"},"content":" String[] params \u003d {"},{"lineNumber":313,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":314,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":315,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":316,"author":{"gitId":"dishenggg"},"content":" verifyCanAccess(params);"},{"lineNumber":317,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":318,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":319,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":320,"author":{"gitId":"dishenggg"},"content":" void testSpecificAccessControl_notInstructor_cannotAccess() {"},{"lineNumber":321,"author":{"gitId":"dishenggg"},"content":" String[] params \u003d {"},{"lineNumber":322,"author":{"gitId":"dishenggg"},"content":" Const.ParamsNames.COURSE_ID, course.getId(),"},{"lineNumber":323,"author":{"gitId":"dishenggg"},"content":" };"},{"lineNumber":324,"author":{"gitId":"dishenggg"},"content":" loginAsStudent(googleId);"},{"lineNumber":325,"author":{"gitId":"dishenggg"},"content":" verifyCannotAccess(params);"},{"lineNumber":326,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":327,"author":{"gitId":"dishenggg"},"content":" logoutUser();"},{"lineNumber":328,"author":{"gitId":"dishenggg"},"content":" verifyCannotAccess(params);"},{"lineNumber":329,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":330,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":330}},{"path":"src/test/java/teammates/sqlui/webapi/UpdateFeedbackSessionLogsActionTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.sqlui.webapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.ArgumentMatchers.argThat;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.reset;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.verify;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.when;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import java.time.temporal.ChronoUnit;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import java.util.ArrayList;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":"import java.util.List;"},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.FeedbackSessionLogEntry;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Const;"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.webapi.UpdateFeedbackSessionLogsAction;"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" * SUT: {@link UpdateFeedbackSessionLogsAction}."},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":"public class UpdateFeedbackSessionLogsActionTest"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" extends BaseActionTest\u003cUpdateFeedbackSessionLogsAction\u003e {"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" static final long COLLECTION_TIME_PERIOD \u003d Const.STUDENT_ACTIVITY_LOGS_UPDATE_INTERVAL.toMinutes();"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" static final long SPAM_FILTER \u003d Const.STUDENT_ACTIVITY_LOGS_FILTER_WINDOW.toMillis();"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":" Student student1;"},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" Student student2;"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" Course course1;"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" Course course2;"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" FeedbackSession session1InCourse1;"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" FeedbackSession session2InCourse1;"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" FeedbackSession session1InCourse2;"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" Instant endTime;"},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" Instant startTime;"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" protected String getActionUri() {"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" return Const.CronJobURIs.AUTOMATED_FEEDBACK_SESSION_LOGS_PROCESSING;"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" @Override"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" String getRequestMethod() {"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" return GET;"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" @BeforeMethod"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" void setUp() {"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" endTime \u003d TimeHelper.getInstantNearestQuarterHourBefore(Instant.now());"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" startTime \u003d endTime.minus(COLLECTION_TIME_PERIOD, ChronoUnit.MINUTES);"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" course1 \u003d getTypicalCourse();"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" course1.setId(\"course1\");"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" course2 \u003d getTypicalCourse();"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" course2.setId(\"course2\");"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" student1 \u003d getTypicalStudent();"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" student1.setEmail(\"student1@teammates.tmt\");"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" student1.setId(UUID.randomUUID());"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" student2 \u003d getTypicalStudent();"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" student2.setEmail(\"student2@teammates.tmt\");"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" student2.setId(UUID.randomUUID());"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" session1InCourse1 \u003d getTypicalFeedbackSessionForCourse(course1);"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.setName(\"session1\");"},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" session1InCourse1.setId(UUID.randomUUID());"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" session2InCourse1 \u003d getTypicalFeedbackSessionForCourse(course1);"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" session2InCourse1.setName(\"session2\");"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":" session2InCourse1.setId(UUID.randomUUID());"},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" session1InCourse2 \u003d getTypicalFeedbackSessionForCourse(course2);"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":" session1InCourse2.setName(\"session1\");"},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" session1InCourse2.setId(UUID.randomUUID());"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" reset(mockLogic);"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getStudentReference(student1.getId())).thenReturn(student1);"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getStudentReference(student2.getId())).thenReturn(student2);"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getFeedbackSessionReference(session1InCourse1.getId())).thenReturn(session1InCourse1);"},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getFeedbackSessionReference(session2InCourse1.getId())).thenReturn(session2InCourse1);"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" when(mockLogic.getFeedbackSessionReference(session1InCourse2.getId())).thenReturn(session1InCourse2);"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.getOrderedFeedbackSessionLogs(\"\", \"\", 0, 0, \"\").clear();"},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":" public void testExecute_noRecentLogs_noLogsCreated()"},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":" UpdateFeedbackSessionLogsAction action \u003d getAction();"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" action.execute();"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" verify(mockLogic).createFeedbackSessionLogs(argThat(filteredLogs -\u003e filteredLogs.isEmpty()));"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":" public void testExecute_recentLogsNoSpam_allLogsCreated()"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" // Different Types"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(100).toEpochMilli());"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.SUBMISSION.getLabel(), startTime.plusSeconds(100).toEpochMilli());"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.VIEW_RESULT.getLabel(), startTime.plusSeconds(100).toEpochMilli());"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" // Different feedback sessions"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(200).toEpochMilli());"},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session2InCourse1.getId(),"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(200).toEpochMilli());"},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":" // Different Student"},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(300).toEpochMilli());"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student2.getId(), session1InCourse1.getId(),"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(300).toEpochMilli());"},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" // Different course"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(400).toEpochMilli());"},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course2.getId(), student1.getId(), session1InCourse2.getId(),"},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusSeconds(400).toEpochMilli());"},{"lineNumber":141,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":142,"author":{"gitId":"dishenggg"},"content":" // Gap is larger than spam filter"},{"lineNumber":143,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":144,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.toEpochMilli());"},{"lineNumber":145,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":146,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusMillis(SPAM_FILTER + 1).toEpochMilli());"},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":" UpdateFeedbackSessionLogsAction action \u003d getAction();"},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":" action.execute();"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":" // method returns all logs regardless of params"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntry\u003e expected \u003d mockLogsProcessor.getOrderedFeedbackSessionLogs(\"\", \"\", 0, 0, \"\");"},{"lineNumber":153,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":" verify(mockLogic).createFeedbackSessionLogs(argThat(filteredLogs -\u003e isEqual(expected, filteredLogs)));"},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":158,"author":{"gitId":"dishenggg"},"content":" public void testExecute_recentLogsWithSpam_someLogsCreated()"},{"lineNumber":159,"author":{"gitId":"dishenggg"},"content":" throws EntityAlreadyExistsException, InvalidParametersException {"},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":" // Gap is smaller than spam filter"},{"lineNumber":161,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":162,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.toEpochMilli());"},{"lineNumber":163,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":164,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusMillis(SPAM_FILTER - 2).toEpochMilli());"},{"lineNumber":165,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":" // Filters multiple logs within one spam window"},{"lineNumber":167,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":168,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusMillis(SPAM_FILTER - 1).toEpochMilli());"},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" // Correctly adds new log after filtering"},{"lineNumber":171,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusMillis(SPAM_FILTER + 1).toEpochMilli());"},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":" // Filters out spam in the new window"},{"lineNumber":175,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusMillis(SPAM_FILTER + 2).toEpochMilli());"},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":" UpdateFeedbackSessionLogsAction action \u003d getAction();"},{"lineNumber":179,"author":{"gitId":"dishenggg"},"content":" action.execute();"},{"lineNumber":180,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":181,"author":{"gitId":"dishenggg"},"content":" List\u003cFeedbackSessionLogEntry\u003e expected \u003d new ArrayList\u003c\u003e();"},{"lineNumber":182,"author":{"gitId":"dishenggg"},"content":" expected.add(new FeedbackSessionLogEntry(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.toEpochMilli()));"},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":" expected.add(new FeedbackSessionLogEntry(course1.getId(), student1.getId(), session1InCourse1.getId(),"},{"lineNumber":185,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime.plusMillis(SPAM_FILTER + 1).toEpochMilli()));"},{"lineNumber":186,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":187,"author":{"gitId":"dishenggg"},"content":" verify(mockLogic).createFeedbackSessionLogs(argThat(filteredLogs -\u003e isEqual(expected, filteredLogs)));"},{"lineNumber":188,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":189,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":190,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":191,"author":{"gitId":"dishenggg"},"content":" public void testSpecificAccessControl_isAdmin_canAccess() {"},{"lineNumber":192,"author":{"gitId":"dishenggg"},"content":" loginAsAdmin();"},{"lineNumber":193,"author":{"gitId":"dishenggg"},"content":" verifyCanAccess();"},{"lineNumber":194,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":195,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":196,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":197,"author":{"gitId":"dishenggg"},"content":" public void testSpecificAccessControl_isInstructor_cannotAccess() {"},{"lineNumber":198,"author":{"gitId":"dishenggg"},"content":" loginAsInstructor(\"user-id\");"},{"lineNumber":199,"author":{"gitId":"dishenggg"},"content":" verifyCannotAccess();"},{"lineNumber":200,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":201,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":202,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":203,"author":{"gitId":"dishenggg"},"content":" public void testSpecificAccessControl_isStudent_cannotAccess() {"},{"lineNumber":204,"author":{"gitId":"dishenggg"},"content":" loginAsStudent(\"user-id\");"},{"lineNumber":205,"author":{"gitId":"dishenggg"},"content":" verifyCannotAccess();"},{"lineNumber":206,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":207,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":208,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":209,"author":{"gitId":"dishenggg"},"content":" public void testSpecificAccessControl_loggedOut_cannotAccess() {"},{"lineNumber":210,"author":{"gitId":"dishenggg"},"content":" logoutUser();"},{"lineNumber":211,"author":{"gitId":"dishenggg"},"content":" verifyCannotAccess();"},{"lineNumber":212,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":213,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":214,"author":{"gitId":"dishenggg"},"content":" private Boolean isEqual(List\u003cFeedbackSessionLogEntry\u003e expected, List\u003cFeedbackSessionLog\u003e actual) {"},{"lineNumber":215,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":216,"author":{"gitId":"dishenggg"},"content":" assertEquals(expected.size(), actual.size());"},{"lineNumber":217,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":218,"author":{"gitId":"dishenggg"},"content":" for (int i \u003d 0; i \u003c expected.size(); i++) {"},{"lineNumber":219,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLogEntry expectedEntry \u003d expected.get(i);"},{"lineNumber":220,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog actualLog \u003d actual.get(i);"},{"lineNumber":221,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":222,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedEntry.getStudentId(), actualLog.getStudent().getId());"},{"lineNumber":223,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":224,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedEntry.getFeedbackSessionId(), actualLog.getFeedbackSession().getId());"},{"lineNumber":225,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":226,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedEntry.getFeedbackSessionLogType(), actualLog.getFeedbackSessionLogType().getLabel());"},{"lineNumber":227,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":228,"author":{"gitId":"dishenggg"},"content":" assertEquals(expectedEntry.getTimestamp(), actualLog.getTimestamp().toEpochMilli());"},{"lineNumber":229,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":230,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":231,"author":{"gitId":"dishenggg"},"content":" return true;"},{"lineNumber":232,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":233,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":232,"-":1}},{"path":"src/test/java/teammates/storage/sqlapi/FeedbackQuestionsDbTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"marquestye"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":3,"author":{"gitId":"marquestye"},"content":"import static org.mockito.ArgumentMatchers.any;"},{"lineNumber":4,"author":{"gitId":"marquestye"},"content":"import static org.mockito.Mockito.mockStatic;"},{"lineNumber":5,"author":{"gitId":"marquestye"},"content":"import static org.mockito.Mockito.never;"},{"lineNumber":6,"author":{"gitId":"marquestye"},"content":"import static org.mockito.Mockito.spy;"},{"lineNumber":7,"author":{"gitId":"marquestye"},"content":"import static org.mockito.Mockito.times;"},{"lineNumber":8,"author":{"gitId":"marquestye"},"content":"import static teammates.common.util.Const.ERROR_CREATE_ENTITY_ALREADY_EXISTS;"},{"lineNumber":9,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":10,"author":{"gitId":"marquestye"},"content":"import java.util.List;"},{"lineNumber":11,"author":{"gitId":"marquestye"},"content":"import java.util.UUID;"},{"lineNumber":12,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":13,"author":{"gitId":"marquestye"},"content":"import org.mockito.MockedStatic;"},{"lineNumber":14,"author":{"gitId":"marquestye"},"content":"import org.testng.annotations.AfterMethod;"},{"lineNumber":15,"author":{"gitId":"marquestye"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":16,"author":{"gitId":"marquestye"},"content":"import org.testng.annotations.Test;"},{"lineNumber":17,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":18,"author":{"gitId":"marquestye"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":19,"author":{"gitId":"marquestye"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":20,"author":{"gitId":"marquestye"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":21,"author":{"gitId":"marquestye"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":22,"author":{"gitId":"marquestye"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":23,"author":{"gitId":"marquestye"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":24,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":25,"author":{"gitId":"marquestye"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"marquestye"},"content":" * SUT: {@link FeedbackQuestionsDb}."},{"lineNumber":27,"author":{"gitId":"marquestye"},"content":" */"},{"lineNumber":28,"author":{"gitId":"marquestye"},"content":"public class FeedbackQuestionsDbTest extends BaseTestCase {"},{"lineNumber":29,"author":{"gitId":"marquestye"},"content":" private FeedbackQuestionsDb feedbackQuestionsDb;"},{"lineNumber":30,"author":{"gitId":"marquestye"},"content":" private MockedStatic\u003cHibernateUtil\u003e mockHibernateUtil;"},{"lineNumber":31,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":32,"author":{"gitId":"marquestye"},"content":" @BeforeMethod"},{"lineNumber":33,"author":{"gitId":"marquestye"},"content":" public void setUpMethod() {"},{"lineNumber":34,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil \u003d mockStatic(HibernateUtil.class);"},{"lineNumber":35,"author":{"gitId":"marquestye"},"content":" feedbackQuestionsDb \u003d spy(FeedbackQuestionsDb.class);"},{"lineNumber":36,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":37,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":38,"author":{"gitId":"marquestye"},"content":" @AfterMethod"},{"lineNumber":39,"author":{"gitId":"marquestye"},"content":" public void teardownMethod() {"},{"lineNumber":40,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.close();"},{"lineNumber":41,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":42,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":43,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":44,"author":{"gitId":"marquestye"},"content":" public void testCreateFeedbackQuestion_success() throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":45,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion feedbackQuestion \u003d getFeedbackQuestion();"},{"lineNumber":46,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":47,"author":{"gitId":"marquestye"},"content":" feedbackQuestionsDb.createFeedbackQuestion(feedbackQuestion);"},{"lineNumber":48,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":49,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.persist(feedbackQuestion), times(1));"},{"lineNumber":50,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":51,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":52,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":53,"author":{"gitId":"marquestye"},"content":" public void testCreateFeedbackQuestion_questionAlreadyExists_throwsEntityAlreadyExistsException() {"},{"lineNumber":54,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion feedbackQuestion \u003d getFeedbackQuestion();"},{"lineNumber":55,"author":{"gitId":"marquestye"},"content":" UUID fqid \u003d feedbackQuestion.getId();"},{"lineNumber":56,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":57,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackQuestion.class, fqid)).thenReturn(feedbackQuestion);"},{"lineNumber":58,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":59,"author":{"gitId":"marquestye"},"content":" EntityAlreadyExistsException eaee \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":60,"author":{"gitId":"marquestye"},"content":" () -\u003e feedbackQuestionsDb.createFeedbackQuestion(feedbackQuestion));"},{"lineNumber":61,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":62,"author":{"gitId":"marquestye"},"content":" assertEquals(String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, feedbackQuestion.toString()), eaee.getMessage());"},{"lineNumber":63,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.persist(feedbackQuestion), never());"},{"lineNumber":64,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":65,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":66,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":67,"author":{"gitId":"marquestye"},"content":" public void testCreateFeedbackQuestion_invalidQuestion_throwsInvalidParametersException() {"},{"lineNumber":68,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion feedbackQuestion \u003d getFeedbackQuestion();"},{"lineNumber":69,"author":{"gitId":"marquestye"},"content":" feedbackQuestion.setGiverType(FeedbackParticipantType.NONE);"},{"lineNumber":70,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":71,"author":{"gitId":"marquestye"},"content":" InvalidParametersException ipe \u003d assertThrows(InvalidParametersException.class,"},{"lineNumber":72,"author":{"gitId":"marquestye"},"content":" () -\u003e feedbackQuestionsDb.createFeedbackQuestion(feedbackQuestion));"},{"lineNumber":73,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":74,"author":{"gitId":"marquestye"},"content":" assertEquals(feedbackQuestion.getInvalidityInfo(), List.of(ipe.getMessage()));"},{"lineNumber":75,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.persist(feedbackQuestion), never());"},{"lineNumber":76,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":77,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":78,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":79,"author":{"gitId":"marquestye"},"content":" public void testGetFeedbackQuestion_success() {"},{"lineNumber":80,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion feedbackQuestion \u003d getFeedbackQuestion();"},{"lineNumber":81,"author":{"gitId":"marquestye"},"content":" UUID fqid \u003d feedbackQuestion.getId();"},{"lineNumber":82,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":83,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackQuestion.class, fqid)).thenReturn(feedbackQuestion);"},{"lineNumber":84,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":85,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion retrievedSession \u003d feedbackQuestionsDb.getFeedbackQuestion(fqid);"},{"lineNumber":86,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":87,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.get(FeedbackQuestion.class, fqid), times(1));"},{"lineNumber":88,"author":{"gitId":"marquestye"},"content":" assertEquals(feedbackQuestion, retrievedSession);"},{"lineNumber":89,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":90,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":91,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":92,"author":{"gitId":"marquestye"},"content":" public void testGetFeedbackQuestion_questionDoesNotExist_returnNull() {"},{"lineNumber":93,"author":{"gitId":"marquestye"},"content":" UUID fqid \u003d UUID.randomUUID();"},{"lineNumber":94,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":95,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackQuestion.class, fqid)).thenReturn(null);"},{"lineNumber":96,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":97,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion retrievedSession \u003d feedbackQuestionsDb.getFeedbackQuestion(fqid);"},{"lineNumber":98,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":99,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.get(FeedbackQuestion.class, fqid), times(1));"},{"lineNumber":100,"author":{"gitId":"marquestye"},"content":" assertNull(retrievedSession);"},{"lineNumber":101,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":102,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":103,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":104,"author":{"gitId":"marquestye"},"content":" public void testDeleteFeedbackQuestion_success() {"},{"lineNumber":105,"author":{"gitId":"marquestye"},"content":" FeedbackQuestion feedbackQuestion \u003d getFeedbackQuestion();"},{"lineNumber":106,"author":{"gitId":"marquestye"},"content":" UUID fqid \u003d feedbackQuestion.getId();"},{"lineNumber":107,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":108,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackQuestion.class, fqid)).thenReturn(feedbackQuestion);"},{"lineNumber":109,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":110,"author":{"gitId":"marquestye"},"content":" feedbackQuestionsDb.deleteFeedbackQuestion(fqid);"},{"lineNumber":111,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":112,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.remove(feedbackQuestion), times(1));"},{"lineNumber":113,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":114,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":115,"author":{"gitId":"marquestye"},"content":" @Test"},{"lineNumber":116,"author":{"gitId":"marquestye"},"content":" public void testDeleteFeedbackQuestion_questionDoesNotExist_nothingHappens() {"},{"lineNumber":117,"author":{"gitId":"marquestye"},"content":" UUID fqid \u003d UUID.randomUUID();"},{"lineNumber":118,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":119,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackQuestion.class, fqid)).thenReturn(null);"},{"lineNumber":120,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":121,"author":{"gitId":"marquestye"},"content":" feedbackQuestionsDb.deleteFeedbackQuestion(fqid);"},{"lineNumber":122,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":123,"author":{"gitId":"marquestye"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.remove(any()), never());"},{"lineNumber":124,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":125,"author":{"gitId":"marquestye"},"content":""},{"lineNumber":126,"author":{"gitId":"marquestye"},"content":" private FeedbackQuestion getFeedbackQuestion() {"},{"lineNumber":127,"author":{"gitId":"marquestye"},"content":" return getTypicalFeedbackQuestionForSession(getTypicalFeedbackSessionForCourse(getTypicalCourse()));"},{"lineNumber":128,"author":{"gitId":"marquestye"},"content":" }"},{"lineNumber":129,"author":{"gitId":"marquestye"},"content":"}"}],"authorContributionMap":{"marquestye":129}},{"path":"src/test/java/teammates/storage/sqlapi/FeedbackResponseCommentsDbTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"mingyuanc"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":3,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.ArgumentMatchers.anyLong;"},{"lineNumber":4,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.Mockito.doReturn;"},{"lineNumber":5,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.Mockito.mockStatic;"},{"lineNumber":6,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.Mockito.never;"},{"lineNumber":7,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.Mockito.spy;"},{"lineNumber":8,"author":{"gitId":"mingyuanc"},"content":"import static org.mockito.Mockito.times;"},{"lineNumber":9,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":10,"author":{"gitId":"mingyuanc"},"content":"import org.mockito.MockedStatic;"},{"lineNumber":11,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.AfterMethod;"},{"lineNumber":12,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":13,"author":{"gitId":"mingyuanc"},"content":"import org.testng.annotations.Test;"},{"lineNumber":14,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":15,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":16,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":17,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":18,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":19,"author":{"gitId":"mingyuanc"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":20,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":21,"author":{"gitId":"mingyuanc"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":22,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":23,"author":{"gitId":"mingyuanc"},"content":"/**"},{"lineNumber":24,"author":{"gitId":"mingyuanc"},"content":" * SUT: {@code FeedbackResponseCommentsDb}."},{"lineNumber":25,"author":{"gitId":"mingyuanc"},"content":" */"},{"lineNumber":26,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":27,"author":{"gitId":"mingyuanc"},"content":"public class FeedbackResponseCommentsDbTest extends BaseTestCase {"},{"lineNumber":28,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":29,"author":{"gitId":"mingyuanc"},"content":" private static final Long TYPICAL_ID \u003d 100L;"},{"lineNumber":30,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":31,"author":{"gitId":"mingyuanc"},"content":" private static final Long NOT_TYPICAL_ID \u003d 101L;"},{"lineNumber":32,"author":{"gitId":"mingyuanc"},"content":" private FeedbackResponseCommentsDb feedbackResponseCommentsDb;"},{"lineNumber":33,"author":{"gitId":"mingyuanc"},"content":" private MockedStatic\u003cHibernateUtil\u003e mockHibernateUtil;"},{"lineNumber":34,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":35,"author":{"gitId":"mingyuanc"},"content":" @BeforeMethod"},{"lineNumber":36,"author":{"gitId":"mingyuanc"},"content":" public void setUpMethod() {"},{"lineNumber":37,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil \u003d mockStatic(HibernateUtil.class);"},{"lineNumber":38,"author":{"gitId":"mingyuanc"},"content":" feedbackResponseCommentsDb \u003d spy(FeedbackResponseCommentsDb.class);"},{"lineNumber":39,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":40,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":41,"author":{"gitId":"mingyuanc"},"content":" @AfterMethod"},{"lineNumber":42,"author":{"gitId":"mingyuanc"},"content":" public void teardownMethod() {"},{"lineNumber":43,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.close();"},{"lineNumber":44,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":45,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":46,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":47,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":48,"author":{"gitId":"mingyuanc"},"content":" public void testCreateComment_commentDoesNotExist_success()"},{"lineNumber":49,"author":{"gitId":"mingyuanc"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":50,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":51,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":52,"author":{"gitId":"mingyuanc"},"content":" feedbackResponseCommentsDb.createFeedbackResponseComment(comment);"},{"lineNumber":53,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":54,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.persist(comment));"},{"lineNumber":55,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":56,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":57,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":58,"author":{"gitId":"mingyuanc"},"content":" public void testCreateComment_commentAlreadyExists_throwsEntityAlreadyExistsException() {"},{"lineNumber":59,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":60,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":61,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackResponseComment.class, TYPICAL_ID)).thenReturn(comment);"},{"lineNumber":62,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":63,"author":{"gitId":"mingyuanc"},"content":" EntityAlreadyExistsException ex \u003d assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":64,"author":{"gitId":"mingyuanc"},"content":" () -\u003e feedbackResponseCommentsDb.createFeedbackResponseComment(comment));"},{"lineNumber":65,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":66,"author":{"gitId":"mingyuanc"},"content":" assertEquals(\"Trying to create an entity that exists: \" + comment.toString(), ex.getMessage());"},{"lineNumber":67,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.persist(comment), never());"},{"lineNumber":68,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":69,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":70,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":71,"author":{"gitId":"mingyuanc"},"content":" public void testGetComment_commentAlreadyExists_success() {"},{"lineNumber":72,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":73,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":74,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackResponseComment.class, TYPICAL_ID)).thenReturn(comment);"},{"lineNumber":75,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":76,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment commentFetched \u003d feedbackResponseCommentsDb.getFeedbackResponseComment(TYPICAL_ID);"},{"lineNumber":77,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":78,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackResponseComment.class, TYPICAL_ID)).thenReturn(comment);"},{"lineNumber":79,"author":{"gitId":"mingyuanc"},"content":" assertEquals(comment, commentFetched);"},{"lineNumber":80,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":81,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":82,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":83,"author":{"gitId":"mingyuanc"},"content":" public void testGetComment_commentDoesNotExist_returnsNull() {"},{"lineNumber":84,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackResponseComment.class, NOT_TYPICAL_ID)).thenReturn(null);"},{"lineNumber":85,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":86,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment commentFetched \u003d feedbackResponseCommentsDb.getFeedbackResponseComment(NOT_TYPICAL_ID);"},{"lineNumber":87,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":88,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.get(FeedbackResponseComment.class, NOT_TYPICAL_ID), times(1));"},{"lineNumber":89,"author":{"gitId":"mingyuanc"},"content":" assertNull(commentFetched);"},{"lineNumber":90,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":91,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":92,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":93,"author":{"gitId":"mingyuanc"},"content":" public void testDeleteComment_commentExists_success() {"},{"lineNumber":94,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":95,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":96,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackResponseComment.class, TYPICAL_ID)).thenReturn(comment);"},{"lineNumber":97,"author":{"gitId":"mingyuanc"},"content":" feedbackResponseCommentsDb.deleteFeedbackResponseComment(TYPICAL_ID);"},{"lineNumber":98,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":99,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.remove(comment));"},{"lineNumber":100,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":101,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":102,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":103,"author":{"gitId":"mingyuanc"},"content":" public void testUpdateComment_commentInvalid_throwsInvalidParametersException() {"},{"lineNumber":104,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":105,"author":{"gitId":"mingyuanc"},"content":" comment.setGiverType(FeedbackParticipantType.SELF);"},{"lineNumber":106,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":107,"author":{"gitId":"mingyuanc"},"content":" assertThrows(InvalidParametersException.class,"},{"lineNumber":108,"author":{"gitId":"mingyuanc"},"content":" () -\u003e feedbackResponseCommentsDb.updateFeedbackResponseComment(comment));"},{"lineNumber":109,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":110,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(comment), never());"},{"lineNumber":111,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":112,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":113,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":114,"author":{"gitId":"mingyuanc"},"content":" public void testUpdateComment_commentDoesNotExist_throwsEntityDoesNotExistException() {"},{"lineNumber":115,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(NOT_TYPICAL_ID);"},{"lineNumber":116,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":117,"author":{"gitId":"mingyuanc"},"content":" assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":118,"author":{"gitId":"mingyuanc"},"content":" () -\u003e feedbackResponseCommentsDb.updateFeedbackResponseComment(comment));"},{"lineNumber":119,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":120,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(comment), never());"},{"lineNumber":121,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":122,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":123,"author":{"gitId":"mingyuanc"},"content":" @Test"},{"lineNumber":124,"author":{"gitId":"mingyuanc"},"content":" public void testUpdateCourse_success() throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":125,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d getTypicalResponseComment(TYPICAL_ID);"},{"lineNumber":126,"author":{"gitId":"mingyuanc"},"content":" comment.setCommentText(\"Placeholder Text\");"},{"lineNumber":127,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":128,"author":{"gitId":"mingyuanc"},"content":" doReturn(comment).when(feedbackResponseCommentsDb).getFeedbackResponseComment(anyLong());"},{"lineNumber":129,"author":{"gitId":"mingyuanc"},"content":" feedbackResponseCommentsDb.updateFeedbackResponseComment(comment);"},{"lineNumber":130,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":131,"author":{"gitId":"mingyuanc"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(comment));"},{"lineNumber":132,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":133,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":134,"author":{"gitId":"mingyuanc"},"content":"}"}],"authorContributionMap":{"mingyuanc":134}},{"path":"src/test/java/teammates/storage/sqlapi/FeedbackSessionLogsDbTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.mockStatic;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.time.Instant;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import org.mockito.MockedStatic;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.AfterMethod;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSessionLog;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":" * SUT: {@code FeedbackSessionLogsDb}."},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":"public class FeedbackSessionLogsDbTest extends BaseTestCase {"},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":" private FeedbackSessionLogsDb feedbackSessionLogsDb \u003d FeedbackSessionLogsDb.inst();"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":" private MockedStatic\u003cHibernateUtil\u003e mockHibernateUtil;"},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" @BeforeMethod"},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" public void setUpMethod() {"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil \u003d mockStatic(HibernateUtil.class);"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" @AfterMethod"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" public void teardownMethod() {"},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.close();"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" public void testCreateFeedbackSessionLog_success() {"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" FeedbackSessionLog logToAdd \u003d new FeedbackSessionLog(getTypicalStudent(),"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" getTypicalFeedbackSessionForCourse(getTypicalCourse()), FeedbackSessionLogType.ACCESS,"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" Instant.parse(\"2011-01-01T00:00:00Z\"));"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" feedbackSessionLogsDb.createFeedbackSessionLog(logToAdd);"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.persist(logToAdd));"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":46}},{"path":"src/test/java/teammates/storage/sqlapi/FeedbackSessionsDbTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"package teammates.storage.sqlapi;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.ArgumentMatchers.any;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.doReturn;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.mockStatic;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.never;"},{"lineNumber":7,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.spy;"},{"lineNumber":8,"author":{"gitId":"dishenggg"},"content":"import static org.mockito.Mockito.times;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import java.util.UUID;"},{"lineNumber":11,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":12,"author":{"gitId":"dishenggg"},"content":"import org.mockito.MockedStatic;"},{"lineNumber":13,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.AfterMethod;"},{"lineNumber":14,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":"import org.testng.annotations.Test;"},{"lineNumber":16,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":17,"author":{"gitId":"dishenggg"},"content":"import teammates.common.exception.EntityAlreadyExistsException;"},{"lineNumber":18,"author":{"gitId":"dishenggg"},"content":"import teammates.common.exception.EntityDoesNotExistException;"},{"lineNumber":19,"author":{"gitId":"dishenggg"},"content":"import teammates.common.exception.InvalidParametersException;"},{"lineNumber":20,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":21,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.TimeHelperExtension;"},{"lineNumber":22,"author":{"gitId":"dishenggg"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":23,"author":{"gitId":"dishenggg"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":24,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":25,"author":{"gitId":"dishenggg"},"content":"/**"},{"lineNumber":26,"author":{"gitId":"dishenggg"},"content":" * SUT: {@code FeedbackSessionsDb}."},{"lineNumber":27,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":28,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":"public class FeedbackSessionsDbTest extends BaseTestCase {"},{"lineNumber":30,"author":{"gitId":"dishenggg"},"content":" private FeedbackSessionsDb feedbackSessionsDb;"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" private MockedStatic\u003cHibernateUtil\u003e mockHibernateUtil;"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":33,"author":{"gitId":"dishenggg"},"content":" @BeforeMethod"},{"lineNumber":34,"author":{"gitId":"dishenggg"},"content":" public void setUpMethod() {"},{"lineNumber":35,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil \u003d mockStatic(HibernateUtil.class);"},{"lineNumber":36,"author":{"gitId":"dishenggg"},"content":" feedbackSessionsDb \u003d spy(FeedbackSessionsDb.class);"},{"lineNumber":37,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":39,"author":{"gitId":"dishenggg"},"content":" @AfterMethod"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" public void teardownMethod() {"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.close();"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" public void testCreateSession_sessionDoesNotExist_success()"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":49,"author":{"gitId":"dishenggg"},"content":" feedbackSessionsDb.createFeedbackSession(feedbackSession);"},{"lineNumber":50,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.persist(feedbackSession), times(1));"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" public void testCreateSession_duplicateSession_throwsEntityAlreadyExistsException()"},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" UUID uuid \u003d feedbackSession.getId();"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" doReturn(feedbackSession).when(feedbackSessionsDb).getFeedbackSession(uuid);"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" assertThrows(EntityAlreadyExistsException.class,"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" () -\u003e feedbackSessionsDb.createFeedbackSession(feedbackSession));"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.persist(feedbackSession), never());"},{"lineNumber":64,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" public void testCreateSession_invalidParams_throwsInvalidParametersException()"},{"lineNumber":68,"author":{"gitId":"dishenggg"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":69,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":70,"author":{"gitId":"dishenggg"},"content":" feedbackSession.setName(\"\");"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":72,"author":{"gitId":"dishenggg"},"content":" assertThrows(InvalidParametersException.class, () -\u003e feedbackSessionsDb.createFeedbackSession(feedbackSession));"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.persist(feedbackSession), never());"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" public void testCreateSession_nullParams_throwsAssertionError()"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" throws InvalidParametersException, EntityAlreadyExistsException {"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" assertThrows(AssertionError.class, () -\u003e feedbackSessionsDb.createFeedbackSession(null));"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":81,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" public void testGetFeedbackSession_sessionExists_success() {"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" UUID uuid \u003d feedbackSession.getId();"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackSession.class, uuid)).thenReturn(feedbackSession);"},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" FeedbackSession sessionFetched \u003d feedbackSessionsDb.getFeedbackSession(uuid);"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.get(FeedbackSession.class, uuid), times(1));"},{"lineNumber":91,"author":{"gitId":"dishenggg"},"content":" assertEquals(feedbackSession, sessionFetched);"},{"lineNumber":92,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":93,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" public void testGetFeedbackSession_sessionDoesNotExists_returnNull() {"},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" UUID randomUuid \u003d UUID.randomUUID();"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.when(() -\u003e HibernateUtil.get(FeedbackSession.class, randomUuid)).thenReturn(null);"},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" FeedbackSession sessionFetched \u003d feedbackSessionsDb.getFeedbackSession(randomUuid);"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.get(FeedbackSession.class, randomUuid), times(1));"},{"lineNumber":102,"author":{"gitId":"dishenggg"},"content":" assertNull(sessionFetched);"},{"lineNumber":103,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":105,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" public void testUpdateFeedbackSession_success() throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" doReturn(feedbackSession).when(feedbackSessionsDb).getFeedbackSession(any(UUID.class));"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" feedbackSessionsDb.updateFeedbackSession(feedbackSession);"},{"lineNumber":111,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":112,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(feedbackSession), times(1));"},{"lineNumber":113,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":114,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":116,"author":{"gitId":"dishenggg"},"content":" public void testUpdateFeedbackSession_sessionDoesNotExist_throwsEntityDoesNotExistException()"},{"lineNumber":117,"author":{"gitId":"dishenggg"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":119,"author":{"gitId":"dishenggg"},"content":" UUID uuid \u003d feedbackSession.getId();"},{"lineNumber":120,"author":{"gitId":"dishenggg"},"content":" doReturn(null).when(feedbackSessionsDb).getFeedbackSession(uuid);"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":122,"author":{"gitId":"dishenggg"},"content":" assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":123,"author":{"gitId":"dishenggg"},"content":" () -\u003e feedbackSessionsDb.updateFeedbackSession(feedbackSession));"},{"lineNumber":124,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(feedbackSession), never());"},{"lineNumber":125,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":126,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":127,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":128,"author":{"gitId":"dishenggg"},"content":" public void testUpdateFeedbackSession_sessionInvalid_throwsInvalidParametersException()"},{"lineNumber":129,"author":{"gitId":"dishenggg"},"content":" throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" UUID uuid \u003d feedbackSession.getId();"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":" feedbackSession.setName(\"\");"},{"lineNumber":133,"author":{"gitId":"dishenggg"},"content":" doReturn(feedbackSession).when(feedbackSessionsDb).getFeedbackSession(uuid);"},{"lineNumber":134,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":135,"author":{"gitId":"dishenggg"},"content":" assertThrows(InvalidParametersException.class, () -\u003e feedbackSessionsDb.updateFeedbackSession(feedbackSession));"},{"lineNumber":136,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(feedbackSession), never());"},{"lineNumber":137,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":138,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":139,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":" public void testDeleteFeedbackSession_success() throws InvalidParametersException, EntityDoesNotExistException {"},{"lineNumber":141,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":142,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":143,"author":{"gitId":"dishenggg"},"content":" feedbackSessionsDb.deleteFeedbackSession(feedbackSession);"},{"lineNumber":144,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":145,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.remove(feedbackSession), times(1));"},{"lineNumber":146,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":149,"author":{"gitId":"dishenggg"},"content":" public void testGetSoftDeletedFeedbackSession_isSoftDeleted_success() {"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":151,"author":{"gitId":"dishenggg"},"content":" String sessionName \u003d feedbackSession.getName();"},{"lineNumber":152,"author":{"gitId":"dishenggg"},"content":" String courseId \u003d feedbackSession.getCourse().getId();"},{"lineNumber":153,"author":{"gitId":"dishenggg"},"content":" feedbackSession.setDeletedAt(TimeHelperExtension.getInstantDaysOffsetFromNow(2));"},{"lineNumber":154,"author":{"gitId":"dishenggg"},"content":" doReturn(feedbackSession).when(feedbackSessionsDb).getFeedbackSession(sessionName, courseId);"},{"lineNumber":155,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":156,"author":{"gitId":"dishenggg"},"content":" FeedbackSession sessionFetched \u003d feedbackSessionsDb.getSoftDeletedFeedbackSession(sessionName, courseId);"},{"lineNumber":157,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":158,"author":{"gitId":"dishenggg"},"content":" assertEquals(feedbackSession, sessionFetched);"},{"lineNumber":159,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":160,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":161,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":162,"author":{"gitId":"dishenggg"},"content":" public void testGetSoftDeletedFeedbackSession_notSoftDeleted_returnNull() {"},{"lineNumber":163,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":164,"author":{"gitId":"dishenggg"},"content":" String sessionName \u003d feedbackSession.getName();"},{"lineNumber":165,"author":{"gitId":"dishenggg"},"content":" String courseId \u003d feedbackSession.getCourse().getId();"},{"lineNumber":166,"author":{"gitId":"dishenggg"},"content":" doReturn(feedbackSession).when(feedbackSessionsDb).getFeedbackSession(sessionName, courseId);"},{"lineNumber":167,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":168,"author":{"gitId":"dishenggg"},"content":" FeedbackSession sessionFetched \u003d feedbackSessionsDb.getSoftDeletedFeedbackSession(sessionName, courseId);"},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" assertNull(sessionFetched);"},{"lineNumber":171,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":" public void testGetSoftDeletedFeedbackSession_sessionDoesNotExist_returnNull() {"},{"lineNumber":175,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":" String sessionName \u003d feedbackSession.getName();"},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":" String courseId \u003d feedbackSession.getCourse().getId();"},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":" doReturn(null).when(feedbackSessionsDb).getFeedbackSession(sessionName, courseId);"},{"lineNumber":179,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":180,"author":{"gitId":"dishenggg"},"content":" FeedbackSession sessionFetched \u003d feedbackSessionsDb.getSoftDeletedFeedbackSession(sessionName, courseId);"},{"lineNumber":181,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":182,"author":{"gitId":"dishenggg"},"content":" assertNull(sessionFetched);"},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":185,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":186,"author":{"gitId":"dishenggg"},"content":" public void testRestoreDeletedFeedbackSession_success() throws EntityDoesNotExistException {"},{"lineNumber":187,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":188,"author":{"gitId":"dishenggg"},"content":" String sessionName \u003d feedbackSession.getName();"},{"lineNumber":189,"author":{"gitId":"dishenggg"},"content":" String courseId \u003d feedbackSession.getCourse().getId();"},{"lineNumber":190,"author":{"gitId":"dishenggg"},"content":" feedbackSession.setDeletedAt(TimeHelperExtension.getInstantDaysOffsetFromNow(2));"},{"lineNumber":191,"author":{"gitId":"dishenggg"},"content":" doReturn(feedbackSession).when(feedbackSessionsDb).getFeedbackSession(sessionName, courseId);"},{"lineNumber":192,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":193,"author":{"gitId":"dishenggg"},"content":" feedbackSessionsDb.restoreDeletedFeedbackSession(sessionName, courseId);"},{"lineNumber":194,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":195,"author":{"gitId":"dishenggg"},"content":" assertNull(feedbackSession.getDeletedAt());"},{"lineNumber":196,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(feedbackSession), times(1));"},{"lineNumber":197,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":198,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":199,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":200,"author":{"gitId":"dishenggg"},"content":" public void testRestoreDeletedFeedbackSession_sessionDoesNotExist_throwsEntityDoesNotExistException()"},{"lineNumber":201,"author":{"gitId":"dishenggg"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":202,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":203,"author":{"gitId":"dishenggg"},"content":" String sessionName \u003d feedbackSession.getName();"},{"lineNumber":204,"author":{"gitId":"dishenggg"},"content":" String courseId \u003d feedbackSession.getCourse().getId();"},{"lineNumber":205,"author":{"gitId":"dishenggg"},"content":" doReturn(null).when(feedbackSessionsDb).getFeedbackSession(sessionName, courseId);"},{"lineNumber":206,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":207,"author":{"gitId":"dishenggg"},"content":" assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":208,"author":{"gitId":"dishenggg"},"content":" () -\u003e feedbackSessionsDb.restoreDeletedFeedbackSession(sessionName, courseId));"},{"lineNumber":209,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(feedbackSession), never());"},{"lineNumber":210,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":211,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":212,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":213,"author":{"gitId":"dishenggg"},"content":" public void testSoftDeleteFeedbackSession_success() throws EntityDoesNotExistException {"},{"lineNumber":214,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":215,"author":{"gitId":"dishenggg"},"content":" String sessionName \u003d feedbackSession.getName();"},{"lineNumber":216,"author":{"gitId":"dishenggg"},"content":" String courseId \u003d feedbackSession.getCourse().getId();"},{"lineNumber":217,"author":{"gitId":"dishenggg"},"content":" doReturn(feedbackSession).when(feedbackSessionsDb).getFeedbackSession(sessionName, courseId);"},{"lineNumber":218,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":219,"author":{"gitId":"dishenggg"},"content":" feedbackSessionsDb.softDeleteFeedbackSession(sessionName, courseId);"},{"lineNumber":220,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":221,"author":{"gitId":"dishenggg"},"content":" assertNotNull(feedbackSession.getDeletedAt());"},{"lineNumber":222,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(feedbackSession), times(1));"},{"lineNumber":223,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":224,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":225,"author":{"gitId":"dishenggg"},"content":" @Test"},{"lineNumber":226,"author":{"gitId":"dishenggg"},"content":" public void testSoftDeleteFeedbackSession_sessionDoesNotExist_throwsEntityDoesNotExistException()"},{"lineNumber":227,"author":{"gitId":"dishenggg"},"content":" throws EntityDoesNotExistException {"},{"lineNumber":228,"author":{"gitId":"dishenggg"},"content":" FeedbackSession feedbackSession \u003d getTypicalFeedbackSessionForCourse(getTypicalCourse());"},{"lineNumber":229,"author":{"gitId":"dishenggg"},"content":" String sessionName \u003d feedbackSession.getName();"},{"lineNumber":230,"author":{"gitId":"dishenggg"},"content":" String courseId \u003d feedbackSession.getCourse().getId();"},{"lineNumber":231,"author":{"gitId":"dishenggg"},"content":" doReturn(null).when(feedbackSessionsDb).getFeedbackSession(sessionName, courseId);"},{"lineNumber":232,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":233,"author":{"gitId":"dishenggg"},"content":" assertThrows(EntityDoesNotExistException.class,"},{"lineNumber":234,"author":{"gitId":"dishenggg"},"content":" () -\u003e feedbackSessionsDb.restoreDeletedFeedbackSession(sessionName, courseId));"},{"lineNumber":235,"author":{"gitId":"dishenggg"},"content":" mockHibernateUtil.verify(() -\u003e HibernateUtil.merge(feedbackSession), never());"},{"lineNumber":236,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":237,"author":{"gitId":"dishenggg"},"content":"}"}],"authorContributionMap":{"dishenggg":237}},{"path":"src/test/java/teammates/test/AbstractBackDoor.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.test;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.io.BufferedReader;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.io.IOException;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.io.InputStreamReader;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.net.URI;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.net.URISyntaxException;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.time.Duration;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import java.util.Collections;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"import org.apache.http.HttpEntity;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import org.apache.http.HttpStatus;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import org.apache.http.NameValuePair;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.CloseableHttpResponse;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpDelete;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpGet;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpPost;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpPut;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import org.apache.http.client.methods.HttpRequestBase;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import org.apache.http.client.utils.URIBuilder;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import org.apache.http.entity.StringEntity;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import org.apache.http.impl.client.CloseableHttpClient;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import org.apache.http.impl.client.HttpClients;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import org.apache.http.message.BasicNameValuePair;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":"import com.google.gson.JsonObject;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import com.google.gson.JsonParser;"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.DataBundle;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":38,"author":{"gitId":"dishenggg"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountAttributes;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountRequestAttributes;"},{"lineNumber":41,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":42,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.DeadlineExtensionAttributes;"},{"lineNumber":43,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseAttributes;"},{"lineNumber":45,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseCommentAttributes;"},{"lineNumber":46,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":47,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.NotificationAttributes;"},{"lineNumber":49,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":50,"author":{"gitId":"-"},"content":"import teammates.common.exception.HttpRequestFailedException;"},{"lineNumber":51,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":52,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":53,"author":{"gitId":"-"},"content":"import teammates.common.util.TimeHelper;"},{"lineNumber":54,"author":{"gitId":"-"},"content":"import teammates.ui.output.AccountData;"},{"lineNumber":55,"author":{"gitId":"-"},"content":"import teammates.ui.output.AccountRequestData;"},{"lineNumber":56,"author":{"gitId":"-"},"content":"import teammates.ui.output.CourseData;"},{"lineNumber":57,"author":{"gitId":"-"},"content":"import teammates.ui.output.CoursesData;"},{"lineNumber":58,"author":{"gitId":"-"},"content":"import teammates.ui.output.DeadlineExtensionData;"},{"lineNumber":59,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackQuestionData;"},{"lineNumber":60,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackQuestionsData;"},{"lineNumber":61,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackResponseCommentData;"},{"lineNumber":62,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackResponseData;"},{"lineNumber":63,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackResponsesData;"},{"lineNumber":64,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionData;"},{"lineNumber":65,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionsData;"},{"lineNumber":66,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackVisibilityType;"},{"lineNumber":67,"author":{"gitId":"-"},"content":"import teammates.ui.output.InstructorData;"},{"lineNumber":68,"author":{"gitId":"-"},"content":"import teammates.ui.output.InstructorsData;"},{"lineNumber":69,"author":{"gitId":"-"},"content":"import teammates.ui.output.MessageOutput;"},{"lineNumber":70,"author":{"gitId":"-"},"content":"import teammates.ui.output.NotificationData;"},{"lineNumber":71,"author":{"gitId":"-"},"content":"import teammates.ui.output.NumberOfEntitiesToGiveFeedbackToSetting;"},{"lineNumber":72,"author":{"gitId":"-"},"content":"import teammates.ui.output.ResponseVisibleSetting;"},{"lineNumber":73,"author":{"gitId":"-"},"content":"import teammates.ui.output.SessionVisibleSetting;"},{"lineNumber":74,"author":{"gitId":"-"},"content":"import teammates.ui.output.StudentData;"},{"lineNumber":75,"author":{"gitId":"-"},"content":"import teammates.ui.request.Intent;"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":78,"author":{"gitId":"-"},"content":" * Used to create API calls to the back-end without going through the UI."},{"lineNumber":79,"author":{"gitId":"-"},"content":" */"},{"lineNumber":80,"author":{"gitId":"-"},"content":"public abstract class AbstractBackDoor {"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":83,"author":{"gitId":"-"},"content":" * Gets the URL of the back-end."},{"lineNumber":84,"author":{"gitId":"-"},"content":" */"},{"lineNumber":85,"author":{"gitId":"-"},"content":" protected abstract String getAppUrl();"},{"lineNumber":86,"author":{"gitId":"-"},"content":""},{"lineNumber":87,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":88,"author":{"gitId":"-"},"content":" * Gets the backdoor key used to authenticate with the back-end."},{"lineNumber":89,"author":{"gitId":"-"},"content":" */"},{"lineNumber":90,"author":{"gitId":"-"},"content":" protected abstract String getBackdoorKey();"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":93,"author":{"gitId":"-"},"content":" * Gets the CSRF key used to authenticate with the back-end."},{"lineNumber":94,"author":{"gitId":"-"},"content":" */"},{"lineNumber":95,"author":{"gitId":"-"},"content":" protected abstract String getCsrfKey();"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":98,"author":{"gitId":"-"},"content":" * Executes GET request with the given {@code relativeUrl}."},{"lineNumber":99,"author":{"gitId":"-"},"content":" *"},{"lineNumber":100,"author":{"gitId":"-"},"content":" * @return The body content and status of the HTTP response"},{"lineNumber":101,"author":{"gitId":"-"},"content":" */"},{"lineNumber":102,"author":{"gitId":"-"},"content":" public ResponseBodyAndCode executeGetRequest(String relativeUrl, Map\u003cString, String\u003e params) {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" return executeRequest(HttpGet.METHOD_NAME, relativeUrl, params, null);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":107,"author":{"gitId":"-"},"content":" * Executes POST request with the given {@code relativeUrl}."},{"lineNumber":108,"author":{"gitId":"-"},"content":" *"},{"lineNumber":109,"author":{"gitId":"-"},"content":" * @return The body content and status of the HTTP response"},{"lineNumber":110,"author":{"gitId":"-"},"content":" */"},{"lineNumber":111,"author":{"gitId":"-"},"content":" public ResponseBodyAndCode executePostRequest(String relativeUrl, Map\u003cString, String\u003e params, String body) {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" return executeRequest(HttpPost.METHOD_NAME, relativeUrl, params, body);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" }"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":116,"author":{"gitId":"-"},"content":" * Executes PUT request with the given {@code relativeUrl}."},{"lineNumber":117,"author":{"gitId":"-"},"content":" *"},{"lineNumber":118,"author":{"gitId":"-"},"content":" * @return The body content and status of the HTTP response"},{"lineNumber":119,"author":{"gitId":"-"},"content":" */"},{"lineNumber":120,"author":{"gitId":"-"},"content":" public ResponseBodyAndCode executePutRequest(String relativeUrl, Map\u003cString, String\u003e params, String body) {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" return executeRequest(HttpPut.METHOD_NAME, relativeUrl, params, body);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" }"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":125,"author":{"gitId":"-"},"content":" * Executes DELETE request with the given {@code relativeUrl}."},{"lineNumber":126,"author":{"gitId":"-"},"content":" *"},{"lineNumber":127,"author":{"gitId":"-"},"content":" * @return The body content and status of the HTTP response"},{"lineNumber":128,"author":{"gitId":"-"},"content":" */"},{"lineNumber":129,"author":{"gitId":"-"},"content":" public ResponseBodyAndCode executeDeleteRequest(String relativeUrl, Map\u003cString, String\u003e params) {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" return executeRequest(HttpDelete.METHOD_NAME, relativeUrl, params, null);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" }"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":134,"author":{"gitId":"-"},"content":" * Executes HTTP request with the given {@code method} and {@code relativeUrl}."},{"lineNumber":135,"author":{"gitId":"-"},"content":" *"},{"lineNumber":136,"author":{"gitId":"-"},"content":" * @return The content of the HTTP response"},{"lineNumber":137,"author":{"gitId":"-"},"content":" */"},{"lineNumber":138,"author":{"gitId":"-"},"content":" private ResponseBodyAndCode executeRequest("},{"lineNumber":139,"author":{"gitId":"-"},"content":" String method, String relativeUrl, Map\u003cString, String\u003e params, String body) {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" String url \u003d getAppUrl() + relativeUrl;"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" HttpRequestBase request;"},{"lineNumber":143,"author":{"gitId":"-"},"content":" switch (method) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" case HttpGet.METHOD_NAME:"},{"lineNumber":145,"author":{"gitId":"-"},"content":" request \u003d createGetRequest(url, params);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":147,"author":{"gitId":"-"},"content":" case HttpPost.METHOD_NAME:"},{"lineNumber":148,"author":{"gitId":"-"},"content":" request \u003d createPostRequest(url, params, body);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":150,"author":{"gitId":"-"},"content":" case HttpPut.METHOD_NAME:"},{"lineNumber":151,"author":{"gitId":"-"},"content":" request \u003d createPutRequest(url, params, body);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":153,"author":{"gitId":"-"},"content":" case HttpDelete.METHOD_NAME:"},{"lineNumber":154,"author":{"gitId":"-"},"content":" request \u003d createDeleteRequest(url, params);"},{"lineNumber":155,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":156,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":157,"author":{"gitId":"-"},"content":" throw new RuntimeException(\"Unaccepted HTTP method: \" + method);"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" addAuthKeys(request);"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"-"},"content":" try (CloseableHttpClient httpClient \u003d HttpClients.createDefault();"},{"lineNumber":163,"author":{"gitId":"-"},"content":" CloseableHttpResponse response \u003d httpClient.execute(request)) {"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" String responseBody \u003d null;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" HttpEntity entity \u003d response.getEntity();"},{"lineNumber":167,"author":{"gitId":"-"},"content":" if (entity !\u003d null) {"},{"lineNumber":168,"author":{"gitId":"-"},"content":" try (BufferedReader br \u003d new BufferedReader("},{"lineNumber":169,"author":{"gitId":"-"},"content":" new InputStreamReader(entity.getContent(), Const.ENCODING))) {"},{"lineNumber":170,"author":{"gitId":"-"},"content":" responseBody \u003d br.lines().collect(Collectors.joining(System.lineSeparator()));"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":" }"},{"lineNumber":173,"author":{"gitId":"-"},"content":" return new ResponseBodyAndCode(responseBody, response.getStatusLine().getStatusCode());"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":178,"author":{"gitId":"-"},"content":" }"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":181,"author":{"gitId":"-"},"content":" * Executes GET request with the given {@code relativeUrl}."},{"lineNumber":182,"author":{"gitId":"-"},"content":" *"},{"lineNumber":183,"author":{"gitId":"-"},"content":" * @return The content of the HTTP response"},{"lineNumber":184,"author":{"gitId":"-"},"content":" */"},{"lineNumber":185,"author":{"gitId":"-"},"content":" private static HttpGet createGetRequest(String url, Map\u003cString, String\u003e params) {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" return new HttpGet(createBasicUri(url, params));"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":" private static HttpPost createPostRequest(String url, Map\u003cString, String\u003e params, String body) {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" HttpPost post \u003d new HttpPost(createBasicUri(url, params));"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"-"},"content":" if (body !\u003d null) {"},{"lineNumber":193,"author":{"gitId":"-"},"content":" StringEntity entity \u003d new StringEntity(body, Const.ENCODING);"},{"lineNumber":194,"author":{"gitId":"-"},"content":" post.setEntity(entity);"},{"lineNumber":195,"author":{"gitId":"-"},"content":" }"},{"lineNumber":196,"author":{"gitId":"-"},"content":""},{"lineNumber":197,"author":{"gitId":"-"},"content":" return post;"},{"lineNumber":198,"author":{"gitId":"-"},"content":" }"},{"lineNumber":199,"author":{"gitId":"-"},"content":""},{"lineNumber":200,"author":{"gitId":"-"},"content":" private static HttpPut createPutRequest(String url, Map\u003cString, String\u003e params, String body) {"},{"lineNumber":201,"author":{"gitId":"-"},"content":" HttpPut put \u003d new HttpPut(createBasicUri(url, params));"},{"lineNumber":202,"author":{"gitId":"-"},"content":""},{"lineNumber":203,"author":{"gitId":"-"},"content":" if (body !\u003d null) {"},{"lineNumber":204,"author":{"gitId":"-"},"content":" StringEntity entity \u003d new StringEntity(body, Const.ENCODING);"},{"lineNumber":205,"author":{"gitId":"-"},"content":" put.setEntity(entity);"},{"lineNumber":206,"author":{"gitId":"-"},"content":" }"},{"lineNumber":207,"author":{"gitId":"-"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" return put;"},{"lineNumber":209,"author":{"gitId":"-"},"content":" }"},{"lineNumber":210,"author":{"gitId":"-"},"content":""},{"lineNumber":211,"author":{"gitId":"-"},"content":" private static HttpDelete createDeleteRequest(String url, Map\u003cString, String\u003e params) {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" return new HttpDelete(createBasicUri(url, params));"},{"lineNumber":213,"author":{"gitId":"-"},"content":" }"},{"lineNumber":214,"author":{"gitId":"-"},"content":""},{"lineNumber":215,"author":{"gitId":"-"},"content":" private static URI createBasicUri(String url, Map\u003cString, String\u003e params) {"},{"lineNumber":216,"author":{"gitId":"-"},"content":" List\u003cNameValuePair\u003e postParameters \u003d new ArrayList\u003c\u003e();"},{"lineNumber":217,"author":{"gitId":"-"},"content":" if (params !\u003d null) {"},{"lineNumber":218,"author":{"gitId":"-"},"content":" params.forEach((key, value) -\u003e postParameters.add(new BasicNameValuePair(key, value)));"},{"lineNumber":219,"author":{"gitId":"-"},"content":" }"},{"lineNumber":220,"author":{"gitId":"-"},"content":""},{"lineNumber":221,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":222,"author":{"gitId":"-"},"content":" URIBuilder uriBuilder \u003d new URIBuilder(url);"},{"lineNumber":223,"author":{"gitId":"-"},"content":" uriBuilder.addParameters(postParameters);"},{"lineNumber":224,"author":{"gitId":"-"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":" return uriBuilder.build();"},{"lineNumber":226,"author":{"gitId":"-"},"content":" } catch (URISyntaxException e) {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":228,"author":{"gitId":"-"},"content":" }"},{"lineNumber":229,"author":{"gitId":"-"},"content":" }"},{"lineNumber":230,"author":{"gitId":"-"},"content":""},{"lineNumber":231,"author":{"gitId":"-"},"content":" private void addAuthKeys(HttpRequestBase request) {"},{"lineNumber":232,"author":{"gitId":"-"},"content":" request.addHeader(Const.HeaderNames.BACKDOOR_KEY, getBackdoorKey());"},{"lineNumber":233,"author":{"gitId":"-"},"content":" request.addHeader(Const.HeaderNames.CSRF_KEY, getCsrfKey());"},{"lineNumber":234,"author":{"gitId":"-"},"content":" }"},{"lineNumber":235,"author":{"gitId":"-"},"content":""},{"lineNumber":236,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":237,"author":{"gitId":"-"},"content":" * Removes and restores given data in the database. This method is to be called on test startup."},{"lineNumber":238,"author":{"gitId":"-"},"content":" *"},{"lineNumber":239,"author":{"gitId":"-"},"content":" * \u003cp\u003eNote: The data associated with the test accounts have to be \u003cstrong\u003emanually\u003c/strong\u003e removed by removing the data"},{"lineNumber":240,"author":{"gitId":"-"},"content":" * bundle when a test ends because the test accounts are shared across tests."},{"lineNumber":241,"author":{"gitId":"-"},"content":" *"},{"lineNumber":242,"author":{"gitId":"-"},"content":" * \u003cp\u003eTest data should never be cleared after test in order to prevent incurring additional database costs because the"},{"lineNumber":243,"author":{"gitId":"-"},"content":" * test\u0027s data may not be accessed in another test. Also although unlikely in normal conditions, when a test fail to"},{"lineNumber":244,"author":{"gitId":"-"},"content":" * remove data bundle on teardown, another test should have no reason to fail."},{"lineNumber":245,"author":{"gitId":"-"},"content":" *"},{"lineNumber":246,"author":{"gitId":"-"},"content":" * \u003cp\u003eAnother reason not to remove associated data after a test is that in case of test failures, it helps to have the"},{"lineNumber":247,"author":{"gitId":"-"},"content":" * associated data in the database to debug the failure."},{"lineNumber":248,"author":{"gitId":"-"},"content":" *"},{"lineNumber":249,"author":{"gitId":"-"},"content":" * \u003cp\u003eThis means that removing the data bundle on startup is not always sufficient because a test only knows how"},{"lineNumber":250,"author":{"gitId":"-"},"content":" * to remove its associated data."},{"lineNumber":251,"author":{"gitId":"-"},"content":" * This is why some tests would fail when they use the same account and use different data."},{"lineNumber":252,"author":{"gitId":"-"},"content":" * Extending this method to remove data outside its associated data would introduce"},{"lineNumber":253,"author":{"gitId":"-"},"content":" * unnecessary complications such as extra costs and knowing exactly how much data to remove. Removing too much data"},{"lineNumber":254,"author":{"gitId":"-"},"content":" * would not just incur higher database costs but we can make tests unexpectedly pass(fail) when the data is expected to"},{"lineNumber":255,"author":{"gitId":"-"},"content":" * be not present(present) in another test."},{"lineNumber":256,"author":{"gitId":"-"},"content":" *"},{"lineNumber":257,"author":{"gitId":"-"},"content":" * \u003cp\u003eTODO: Hence, we need to explicitly remove the data bundle in tests on teardown to avoid instability of tests."},{"lineNumber":258,"author":{"gitId":"-"},"content":" * However, removing the data bundle on teardown manually is not a perfect solution because two tests can concurrently"},{"lineNumber":259,"author":{"gitId":"-"},"content":" * access the same account and their data may get mixed up in the process. This is a major problem we need to address."},{"lineNumber":260,"author":{"gitId":"-"},"content":" */"},{"lineNumber":261,"author":{"gitId":"-"},"content":" public String removeAndRestoreDataBundle(DataBundle dataBundle) throws HttpRequestFailedException {"},{"lineNumber":262,"author":{"gitId":"-"},"content":" removeDataBundle(dataBundle);"},{"lineNumber":263,"author":{"gitId":"-"},"content":" ResponseBodyAndCode putRequestOutput \u003d"},{"lineNumber":264,"author":{"gitId":"-"},"content":" executePostRequest(Const.ResourceURIs.DATABUNDLE, null, JsonUtils.toJson(dataBundle));"},{"lineNumber":265,"author":{"gitId":"-"},"content":" if (putRequestOutput.responseCode !\u003d HttpStatus.SC_OK) {"},{"lineNumber":266,"author":{"gitId":"-"},"content":" throw new HttpRequestFailedException(\"Request failed: [\" + putRequestOutput.responseCode + \"] \""},{"lineNumber":267,"author":{"gitId":"-"},"content":" + putRequestOutput.responseBody);"},{"lineNumber":268,"author":{"gitId":"-"},"content":" }"},{"lineNumber":269,"author":{"gitId":"-"},"content":" return putRequestOutput.responseBody;"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":273,"author":{"gitId":"-"},"content":" * Removes and restores given data in the database. This method is to be called on test startup."},{"lineNumber":274,"author":{"gitId":"-"},"content":" */"},{"lineNumber":275,"author":{"gitId":"-"},"content":" public SqlDataBundle removeAndRestoreSqlDataBundle(SqlDataBundle dataBundle) throws HttpRequestFailedException {"},{"lineNumber":276,"author":{"gitId":"-"},"content":" removeSqlDataBundle(dataBundle);"},{"lineNumber":277,"author":{"gitId":"-"},"content":" ResponseBodyAndCode putRequestOutput \u003d"},{"lineNumber":278,"author":{"gitId":"-"},"content":" executePostRequest(Const.ResourceURIs.SQL_DATABUNDLE, null, JsonUtils.toJson(dataBundle));"},{"lineNumber":279,"author":{"gitId":"-"},"content":" if (putRequestOutput.responseCode !\u003d HttpStatus.SC_OK) {"},{"lineNumber":280,"author":{"gitId":"-"},"content":" throw new HttpRequestFailedException(\"Request failed: [\" + putRequestOutput.responseCode + \"] \""},{"lineNumber":281,"author":{"gitId":"-"},"content":" + putRequestOutput.responseBody);"},{"lineNumber":282,"author":{"gitId":"-"},"content":" }"},{"lineNumber":283,"author":{"gitId":"-"},"content":""},{"lineNumber":284,"author":{"gitId":"-"},"content":" JsonObject jsonObject \u003d JsonParser.parseString(putRequestOutput.responseBody).getAsJsonObject();"},{"lineNumber":285,"author":{"gitId":"-"},"content":" // data bundle is nested under message key"},{"lineNumber":286,"author":{"gitId":"-"},"content":" String message \u003d jsonObject.get(\"message\").getAsString();"},{"lineNumber":287,"author":{"gitId":"-"},"content":" return JsonUtils.fromJson(message, SqlDataBundle.class);"},{"lineNumber":288,"author":{"gitId":"-"},"content":" }"},{"lineNumber":289,"author":{"gitId":"-"},"content":""},{"lineNumber":290,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":291,"author":{"gitId":"-"},"content":" * Removes given data from the database."},{"lineNumber":292,"author":{"gitId":"-"},"content":" *"},{"lineNumber":293,"author":{"gitId":"-"},"content":" * \u003cp\u003eIf given entities have already been deleted, it fails silently."},{"lineNumber":294,"author":{"gitId":"-"},"content":" */"},{"lineNumber":295,"author":{"gitId":"-"},"content":" public void removeDataBundle(DataBundle dataBundle) {"},{"lineNumber":296,"author":{"gitId":"-"},"content":" executePutRequest(Const.ResourceURIs.DATABUNDLE, null, JsonUtils.toJson(dataBundle));"},{"lineNumber":297,"author":{"gitId":"-"},"content":" }"},{"lineNumber":298,"author":{"gitId":"-"},"content":""},{"lineNumber":299,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":300,"author":{"gitId":"-"},"content":" * Removes given data from the database."},{"lineNumber":301,"author":{"gitId":"-"},"content":" *"},{"lineNumber":302,"author":{"gitId":"-"},"content":" * \u003cp\u003eIf given entities have already been deleted, it fails silently."},{"lineNumber":303,"author":{"gitId":"-"},"content":" */"},{"lineNumber":304,"author":{"gitId":"-"},"content":" public void removeSqlDataBundle(SqlDataBundle dataBundle) {"},{"lineNumber":305,"author":{"gitId":"-"},"content":" executePutRequest(Const.ResourceURIs.SQL_DATABUNDLE, null, JsonUtils.toJson(dataBundle));"},{"lineNumber":306,"author":{"gitId":"-"},"content":" }"},{"lineNumber":307,"author":{"gitId":"-"},"content":""},{"lineNumber":308,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":309,"author":{"gitId":"-"},"content":" * Gets the cookie format for the given user ID."},{"lineNumber":310,"author":{"gitId":"-"},"content":" */"},{"lineNumber":311,"author":{"gitId":"-"},"content":" public String getUserCookie(String userId) {"},{"lineNumber":312,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":313,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.USER_ID, userId);"},{"lineNumber":314,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executePostRequest(Const.ResourceURIs.USER_COOKIE, params, null);"},{"lineNumber":315,"author":{"gitId":"-"},"content":""},{"lineNumber":316,"author":{"gitId":"-"},"content":" MessageOutput output \u003d JsonUtils.fromJson(response.responseBody, MessageOutput.class);"},{"lineNumber":317,"author":{"gitId":"-"},"content":" return output.getMessage();"},{"lineNumber":318,"author":{"gitId":"-"},"content":" }"},{"lineNumber":319,"author":{"gitId":"-"},"content":""},{"lineNumber":320,"author":{"gitId":"dishenggg"},"content":" // TODO: remove params after migration"},{"lineNumber":321,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":322,"author":{"gitId":"-"},"content":" * Puts searchable documents in data bundle into the database."},{"lineNumber":323,"author":{"gitId":"-"},"content":" */"},{"lineNumber":324,"author":{"gitId":"-"},"content":" public String putDocuments(DataBundle dataBundle) throws HttpRequestFailedException {"},{"lineNumber":325,"author":{"gitId":"dishenggg"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":326,"author":{"gitId":"dishenggg"},"content":" params.put(\"databundletype\", \"datastore\");"},{"lineNumber":327,"author":{"gitId":"-"},"content":" ResponseBodyAndCode putRequestOutput \u003d"},{"lineNumber":328,"author":{"gitId":"dishenggg"},"content":" executePutRequest(Const.ResourceURIs.DATABUNDLE_DOCUMENTS, params, JsonUtils.toJson(dataBundle));"},{"lineNumber":329,"author":{"gitId":"-"},"content":" if (putRequestOutput.responseCode !\u003d HttpStatus.SC_OK) {"},{"lineNumber":330,"author":{"gitId":"-"},"content":" throw new HttpRequestFailedException(\"Request failed: [\" + putRequestOutput.responseCode + \"] \""},{"lineNumber":331,"author":{"gitId":"-"},"content":" + putRequestOutput.responseBody);"},{"lineNumber":332,"author":{"gitId":"-"},"content":" }"},{"lineNumber":333,"author":{"gitId":"-"},"content":" return putRequestOutput.responseBody;"},{"lineNumber":334,"author":{"gitId":"-"},"content":" }"},{"lineNumber":335,"author":{"gitId":"-"},"content":""},{"lineNumber":336,"author":{"gitId":"dishenggg"},"content":" // TODO: remove method after migration"},{"lineNumber":337,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":338,"author":{"gitId":"dishenggg"},"content":" * Puts searchable documents in data bundle into the SQL database."},{"lineNumber":339,"author":{"gitId":"-"},"content":" */"},{"lineNumber":340,"author":{"gitId":"dishenggg"},"content":" public String putSqlDocuments(SqlDataBundle dataBundle) throws HttpRequestFailedException {"},{"lineNumber":341,"author":{"gitId":"dishenggg"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":342,"author":{"gitId":"dishenggg"},"content":" params.put(\"databundletype\", \"sql\");"},{"lineNumber":343,"author":{"gitId":"-"},"content":" ResponseBodyAndCode putRequestOutput \u003d"},{"lineNumber":344,"author":{"gitId":"dishenggg"},"content":" executePutRequest(Const.ResourceURIs.DATABUNDLE_DOCUMENTS, params, JsonUtils.toJson(dataBundle));"},{"lineNumber":345,"author":{"gitId":"-"},"content":" if (putRequestOutput.responseCode !\u003d HttpStatus.SC_OK) {"},{"lineNumber":346,"author":{"gitId":"-"},"content":" throw new HttpRequestFailedException(\"Request failed: [\" + putRequestOutput.responseCode + \"] \""},{"lineNumber":347,"author":{"gitId":"-"},"content":" + putRequestOutput.responseBody);"},{"lineNumber":348,"author":{"gitId":"-"},"content":" }"},{"lineNumber":349,"author":{"gitId":"-"},"content":" return putRequestOutput.responseBody;"},{"lineNumber":350,"author":{"gitId":"-"},"content":" }"},{"lineNumber":351,"author":{"gitId":"-"},"content":""},{"lineNumber":352,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":353,"author":{"gitId":"-"},"content":" * Gets account data from the database."},{"lineNumber":354,"author":{"gitId":"-"},"content":" */"},{"lineNumber":355,"author":{"gitId":"-"},"content":" public AccountData getAccountData(String googleId) {"},{"lineNumber":356,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":357,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.INSTRUCTOR_ID, googleId);"},{"lineNumber":358,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.ACCOUNT, params);"},{"lineNumber":359,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":360,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":361,"author":{"gitId":"-"},"content":" }"},{"lineNumber":362,"author":{"gitId":"-"},"content":""},{"lineNumber":363,"author":{"gitId":"-"},"content":" return JsonUtils.fromJson(response.responseBody, AccountData.class);"},{"lineNumber":364,"author":{"gitId":"-"},"content":" }"},{"lineNumber":365,"author":{"gitId":"-"},"content":""},{"lineNumber":366,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":367,"author":{"gitId":"-"},"content":" * Gets an account from the database."},{"lineNumber":368,"author":{"gitId":"-"},"content":" */"},{"lineNumber":369,"author":{"gitId":"-"},"content":" public AccountAttributes getAccount(String googleId) {"},{"lineNumber":370,"author":{"gitId":"-"},"content":" AccountData accountData \u003d getAccountData(googleId);"},{"lineNumber":371,"author":{"gitId":"-"},"content":" return AccountAttributes.builder(accountData.getGoogleId())"},{"lineNumber":372,"author":{"gitId":"-"},"content":" .withName(accountData.getName())"},{"lineNumber":373,"author":{"gitId":"-"},"content":" .withEmail(accountData.getEmail())"},{"lineNumber":374,"author":{"gitId":"-"},"content":" .withReadNotifications("},{"lineNumber":375,"author":{"gitId":"-"},"content":" accountData.getReadNotifications()"},{"lineNumber":376,"author":{"gitId":"-"},"content":" .entrySet()"},{"lineNumber":377,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":378,"author":{"gitId":"-"},"content":" .collect(Collectors.toMap("},{"lineNumber":379,"author":{"gitId":"-"},"content":" e -\u003e e.getKey(),"},{"lineNumber":380,"author":{"gitId":"-"},"content":" e -\u003e Instant.ofEpochMilli(e.getValue())"},{"lineNumber":381,"author":{"gitId":"-"},"content":" ))"},{"lineNumber":382,"author":{"gitId":"-"},"content":" )"},{"lineNumber":383,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":384,"author":{"gitId":"-"},"content":" }"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":387,"author":{"gitId":"-"},"content":" * Gets course data from the database."},{"lineNumber":388,"author":{"gitId":"-"},"content":" */"},{"lineNumber":389,"author":{"gitId":"-"},"content":" public CourseData getCourseData(String courseId) {"},{"lineNumber":390,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":391,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.COURSE_ID, courseId);"},{"lineNumber":392,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.COURSE, params);"},{"lineNumber":393,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":394,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":395,"author":{"gitId":"-"},"content":" }"},{"lineNumber":396,"author":{"gitId":"-"},"content":""},{"lineNumber":397,"author":{"gitId":"-"},"content":" return JsonUtils.fromJson(response.responseBody, CourseData.class);"},{"lineNumber":398,"author":{"gitId":"-"},"content":" }"},{"lineNumber":399,"author":{"gitId":"-"},"content":""},{"lineNumber":400,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":401,"author":{"gitId":"-"},"content":" * Gets a course from the database."},{"lineNumber":402,"author":{"gitId":"-"},"content":" */"},{"lineNumber":403,"author":{"gitId":"-"},"content":" public CourseAttributes getCourse(String courseId) {"},{"lineNumber":404,"author":{"gitId":"-"},"content":" CourseData courseData \u003d getCourseData(courseId);"},{"lineNumber":405,"author":{"gitId":"-"},"content":" if (courseData \u003d\u003d null) {"},{"lineNumber":406,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":407,"author":{"gitId":"-"},"content":" }"},{"lineNumber":408,"author":{"gitId":"-"},"content":" return CourseAttributes.builder(courseData.getCourseId())"},{"lineNumber":409,"author":{"gitId":"-"},"content":" .withName(courseData.getCourseName())"},{"lineNumber":410,"author":{"gitId":"-"},"content":" .withTimezone(courseData.getTimeZone())"},{"lineNumber":411,"author":{"gitId":"-"},"content":" .withInstitute(courseData.getInstitute())"},{"lineNumber":412,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":413,"author":{"gitId":"-"},"content":" }"},{"lineNumber":414,"author":{"gitId":"-"},"content":""},{"lineNumber":415,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":416,"author":{"gitId":"-"},"content":" * Gets archived course data from the database."},{"lineNumber":417,"author":{"gitId":"-"},"content":" */"},{"lineNumber":418,"author":{"gitId":"-"},"content":" public CourseData getArchivedCourseData(String instructorId, String courseId) {"},{"lineNumber":419,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":420,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.USER_ID, instructorId);"},{"lineNumber":421,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.COURSE_ID, courseId);"},{"lineNumber":422,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR);"},{"lineNumber":423,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.COURSE_STATUS, Const.CourseStatus.ARCHIVED);"},{"lineNumber":424,"author":{"gitId":"-"},"content":""},{"lineNumber":425,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.COURSES, params);"},{"lineNumber":426,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":428,"author":{"gitId":"-"},"content":" }"},{"lineNumber":429,"author":{"gitId":"-"},"content":""},{"lineNumber":430,"author":{"gitId":"-"},"content":" CoursesData coursesData \u003d JsonUtils.fromJson(response.responseBody, CoursesData.class);"},{"lineNumber":431,"author":{"gitId":"-"},"content":" CourseData courseData \u003d coursesData.getCourses()"},{"lineNumber":432,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":433,"author":{"gitId":"-"},"content":" .filter(cd -\u003e cd.getCourseId().equals(courseId))"},{"lineNumber":434,"author":{"gitId":"-"},"content":" .findFirst()"},{"lineNumber":435,"author":{"gitId":"-"},"content":" .orElse(null);"},{"lineNumber":436,"author":{"gitId":"-"},"content":""},{"lineNumber":437,"author":{"gitId":"-"},"content":" if (courseData \u003d\u003d null) {"},{"lineNumber":438,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":439,"author":{"gitId":"-"},"content":" }"},{"lineNumber":440,"author":{"gitId":"-"},"content":""},{"lineNumber":441,"author":{"gitId":"-"},"content":" return courseData;"},{"lineNumber":442,"author":{"gitId":"-"},"content":" }"},{"lineNumber":443,"author":{"gitId":"-"},"content":""},{"lineNumber":444,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":445,"author":{"gitId":"-"},"content":" * Gets a archived course from the database."},{"lineNumber":446,"author":{"gitId":"-"},"content":" */"},{"lineNumber":447,"author":{"gitId":"-"},"content":" public CourseAttributes getArchivedCourse(String instructorId, String courseId) {"},{"lineNumber":448,"author":{"gitId":"-"},"content":" CourseData courseData \u003d getArchivedCourseData(instructorId, courseId);"},{"lineNumber":449,"author":{"gitId":"-"},"content":" if (courseData \u003d\u003d null) {"},{"lineNumber":450,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":451,"author":{"gitId":"-"},"content":" }"},{"lineNumber":452,"author":{"gitId":"-"},"content":" return CourseAttributes.builder(courseData.getCourseId())"},{"lineNumber":453,"author":{"gitId":"-"},"content":" .withName(courseData.getCourseName())"},{"lineNumber":454,"author":{"gitId":"-"},"content":" .withTimezone(courseData.getTimeZone())"},{"lineNumber":455,"author":{"gitId":"-"},"content":" .withInstitute(courseData.getInstitute())"},{"lineNumber":456,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":457,"author":{"gitId":"-"},"content":" }"},{"lineNumber":458,"author":{"gitId":"-"},"content":""},{"lineNumber":459,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":460,"author":{"gitId":"-"},"content":" * Returns true if the course exists and is in recycle bin."},{"lineNumber":461,"author":{"gitId":"-"},"content":" */"},{"lineNumber":462,"author":{"gitId":"-"},"content":" public boolean isCourseInRecycleBin(String courseId) {"},{"lineNumber":463,"author":{"gitId":"-"},"content":" CourseData courseData \u003d getCourseData(courseId);"},{"lineNumber":464,"author":{"gitId":"-"},"content":" if (courseData \u003d\u003d null) {"},{"lineNumber":465,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":466,"author":{"gitId":"-"},"content":" }"},{"lineNumber":467,"author":{"gitId":"-"},"content":" return courseData.getDeletionTimestamp() !\u003d 0;"},{"lineNumber":468,"author":{"gitId":"-"},"content":" }"},{"lineNumber":469,"author":{"gitId":"-"},"content":""},{"lineNumber":470,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":471,"author":{"gitId":"-"},"content":" * Gets instructor data from the database."},{"lineNumber":472,"author":{"gitId":"-"},"content":" */"},{"lineNumber":473,"author":{"gitId":"-"},"content":" public InstructorData getInstructorData(String courseId, String email) {"},{"lineNumber":474,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":475,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.COURSE_ID, courseId);"},{"lineNumber":476,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.INTENT, Intent.FULL_DETAIL.toString());"},{"lineNumber":477,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.INSTRUCTORS, params);"},{"lineNumber":478,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":479,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":480,"author":{"gitId":"-"},"content":" }"},{"lineNumber":481,"author":{"gitId":"-"},"content":""},{"lineNumber":482,"author":{"gitId":"-"},"content":" InstructorsData instructorsData \u003d JsonUtils.fromJson(response.responseBody, InstructorsData.class);"},{"lineNumber":483,"author":{"gitId":"-"},"content":" InstructorData instructorData \u003d instructorsData.getInstructors()"},{"lineNumber":484,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":485,"author":{"gitId":"-"},"content":" .filter(instructor -\u003e instructor.getEmail().equals(email))"},{"lineNumber":486,"author":{"gitId":"-"},"content":" .findFirst()"},{"lineNumber":487,"author":{"gitId":"-"},"content":" .orElse(null);"},{"lineNumber":488,"author":{"gitId":"-"},"content":""},{"lineNumber":489,"author":{"gitId":"-"},"content":" if (instructorData \u003d\u003d null) {"},{"lineNumber":490,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":491,"author":{"gitId":"-"},"content":" }"},{"lineNumber":492,"author":{"gitId":"-"},"content":""},{"lineNumber":493,"author":{"gitId":"-"},"content":" return instructorData;"},{"lineNumber":494,"author":{"gitId":"-"},"content":" }"},{"lineNumber":495,"author":{"gitId":"-"},"content":""},{"lineNumber":496,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":497,"author":{"gitId":"-"},"content":" * Get instructor from database. Does not include certain fields like InstructorPrivileges."},{"lineNumber":498,"author":{"gitId":"-"},"content":" */"},{"lineNumber":499,"author":{"gitId":"-"},"content":" public InstructorAttributes getInstructor(String courseId, String instructorEmail) {"},{"lineNumber":500,"author":{"gitId":"-"},"content":" InstructorData instructorData \u003d getInstructorData(courseId, instructorEmail);"},{"lineNumber":501,"author":{"gitId":"-"},"content":" if (instructorData \u003d\u003d null) {"},{"lineNumber":502,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":503,"author":{"gitId":"-"},"content":" }"},{"lineNumber":504,"author":{"gitId":"-"},"content":" InstructorAttributes.Builder instructor \u003d InstructorAttributes.builder(instructorData.getCourseId(),"},{"lineNumber":505,"author":{"gitId":"-"},"content":" instructorData.getEmail());"},{"lineNumber":506,"author":{"gitId":"-"},"content":" if (instructorData.getGoogleId() !\u003d null) {"},{"lineNumber":507,"author":{"gitId":"-"},"content":" instructor.withGoogleId(instructorData.getGoogleId());"},{"lineNumber":508,"author":{"gitId":"-"},"content":" }"},{"lineNumber":509,"author":{"gitId":"-"},"content":" if (instructorData.getName() !\u003d null) {"},{"lineNumber":510,"author":{"gitId":"-"},"content":" instructor.withName(instructorData.getName());"},{"lineNumber":511,"author":{"gitId":"-"},"content":" }"},{"lineNumber":512,"author":{"gitId":"-"},"content":" if (instructorData.getRole() !\u003d null) {"},{"lineNumber":513,"author":{"gitId":"-"},"content":" instructor.withRole(instructorData.getRole().getRoleName());"},{"lineNumber":514,"author":{"gitId":"-"},"content":" }"},{"lineNumber":515,"author":{"gitId":"-"},"content":" if (instructorData.getIsDisplayedToStudents() !\u003d null) {"},{"lineNumber":516,"author":{"gitId":"-"},"content":" instructor.withIsDisplayedToStudents(instructorData.getIsDisplayedToStudents());"},{"lineNumber":517,"author":{"gitId":"-"},"content":" }"},{"lineNumber":518,"author":{"gitId":"-"},"content":" if (instructorData.getDisplayedToStudentsAs() !\u003d null) {"},{"lineNumber":519,"author":{"gitId":"-"},"content":" instructor.withDisplayedName(instructorData.getDisplayedToStudentsAs());"},{"lineNumber":520,"author":{"gitId":"-"},"content":" }"},{"lineNumber":521,"author":{"gitId":"-"},"content":" InstructorAttributes instructorAttributes \u003d instructor.build();"},{"lineNumber":522,"author":{"gitId":"-"},"content":" if (instructorData.getKey() !\u003d null) {"},{"lineNumber":523,"author":{"gitId":"-"},"content":" instructorAttributes.setKey(instructorData.getKey());"},{"lineNumber":524,"author":{"gitId":"-"},"content":" }"},{"lineNumber":525,"author":{"gitId":"-"},"content":" return instructorAttributes;"},{"lineNumber":526,"author":{"gitId":"-"},"content":" }"},{"lineNumber":527,"author":{"gitId":"-"},"content":""},{"lineNumber":528,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":529,"author":{"gitId":"-"},"content":" * Gets student data from the database."},{"lineNumber":530,"author":{"gitId":"-"},"content":" */"},{"lineNumber":531,"author":{"gitId":"-"},"content":" public StudentData getStudentData(String courseId, String studentEmail) {"},{"lineNumber":532,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":533,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.COURSE_ID, courseId);"},{"lineNumber":534,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.STUDENT_EMAIL, studentEmail);"},{"lineNumber":535,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.STUDENT, params);"},{"lineNumber":536,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":537,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":538,"author":{"gitId":"-"},"content":" }"},{"lineNumber":539,"author":{"gitId":"-"},"content":" return JsonUtils.fromJson(response.responseBody, StudentData.class);"},{"lineNumber":540,"author":{"gitId":"-"},"content":" }"},{"lineNumber":541,"author":{"gitId":"-"},"content":""},{"lineNumber":542,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":543,"author":{"gitId":"-"},"content":" * Get student from database."},{"lineNumber":544,"author":{"gitId":"-"},"content":" */"},{"lineNumber":545,"author":{"gitId":"-"},"content":" public StudentAttributes getStudent(String courseId, String studentEmail) {"},{"lineNumber":546,"author":{"gitId":"-"},"content":" StudentData studentData \u003d getStudentData(courseId, studentEmail);"},{"lineNumber":547,"author":{"gitId":"-"},"content":" if (studentData \u003d\u003d null) {"},{"lineNumber":548,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":549,"author":{"gitId":"-"},"content":" }"},{"lineNumber":550,"author":{"gitId":"-"},"content":" StudentAttributes.Builder builder \u003d StudentAttributes.builder(studentData.getCourseId(),"},{"lineNumber":551,"author":{"gitId":"-"},"content":" studentData.getEmail());"},{"lineNumber":552,"author":{"gitId":"-"},"content":" if (studentData.getGoogleId() !\u003d null) {"},{"lineNumber":553,"author":{"gitId":"-"},"content":" builder.withGoogleId(studentData.getGoogleId());"},{"lineNumber":554,"author":{"gitId":"-"},"content":" }"},{"lineNumber":555,"author":{"gitId":"-"},"content":" if (studentData.getName() !\u003d null) {"},{"lineNumber":556,"author":{"gitId":"-"},"content":" builder.withName(studentData.getName());"},{"lineNumber":557,"author":{"gitId":"-"},"content":" }"},{"lineNumber":558,"author":{"gitId":"-"},"content":" if (studentData.getSectionName() !\u003d null) {"},{"lineNumber":559,"author":{"gitId":"-"},"content":" builder.withSectionName(studentData.getSectionName());"},{"lineNumber":560,"author":{"gitId":"-"},"content":" }"},{"lineNumber":561,"author":{"gitId":"-"},"content":" if (studentData.getTeamName() !\u003d null) {"},{"lineNumber":562,"author":{"gitId":"-"},"content":" builder.withTeamName(studentData.getTeamName());"},{"lineNumber":563,"author":{"gitId":"-"},"content":" }"},{"lineNumber":564,"author":{"gitId":"-"},"content":" if (studentData.getComments() !\u003d null) {"},{"lineNumber":565,"author":{"gitId":"-"},"content":" builder.withComment(studentData.getComments());"},{"lineNumber":566,"author":{"gitId":"-"},"content":" }"},{"lineNumber":567,"author":{"gitId":"-"},"content":" StudentAttributes student \u003d builder.build();"},{"lineNumber":568,"author":{"gitId":"-"},"content":" if (studentData.getKey() !\u003d null) {"},{"lineNumber":569,"author":{"gitId":"-"},"content":" student.setKey(studentData.getKey());"},{"lineNumber":570,"author":{"gitId":"-"},"content":" }"},{"lineNumber":571,"author":{"gitId":"-"},"content":" return student;"},{"lineNumber":572,"author":{"gitId":"-"},"content":" }"},{"lineNumber":573,"author":{"gitId":"-"},"content":""},{"lineNumber":574,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":575,"author":{"gitId":"-"},"content":" * Get feedback session data from database."},{"lineNumber":576,"author":{"gitId":"-"},"content":" */"},{"lineNumber":577,"author":{"gitId":"-"},"content":" public FeedbackSessionData getFeedbackSessionData(String courseId, String feedbackSessionName) {"},{"lineNumber":578,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":579,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.COURSE_ID, courseId);"},{"lineNumber":580,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSessionName);"},{"lineNumber":581,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.INTENT, Intent.FULL_DETAIL.toString());"},{"lineNumber":582,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.SESSION, params);"},{"lineNumber":583,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":584,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":585,"author":{"gitId":"-"},"content":" }"},{"lineNumber":586,"author":{"gitId":"-"},"content":" return JsonUtils.fromJson(response.responseBody, FeedbackSessionData.class);"},{"lineNumber":587,"author":{"gitId":"-"},"content":" }"},{"lineNumber":588,"author":{"gitId":"-"},"content":""},{"lineNumber":589,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":590,"author":{"gitId":"-"},"content":" * Get feedback session from database."},{"lineNumber":591,"author":{"gitId":"-"},"content":" */"},{"lineNumber":592,"author":{"gitId":"-"},"content":" public FeedbackSessionAttributes getFeedbackSession(String courseId, String feedbackSessionName) {"},{"lineNumber":593,"author":{"gitId":"-"},"content":" FeedbackSessionData sessionData \u003d getFeedbackSessionData(courseId, feedbackSessionName);"},{"lineNumber":594,"author":{"gitId":"-"},"content":" if (sessionData \u003d\u003d null) {"},{"lineNumber":595,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":596,"author":{"gitId":"-"},"content":" }"},{"lineNumber":597,"author":{"gitId":"-"},"content":""},{"lineNumber":598,"author":{"gitId":"-"},"content":" Map\u003cString, Instant\u003e studentDeadlines \u003d"},{"lineNumber":599,"author":{"gitId":"-"},"content":" convertDeadlinesToInstant(sessionData.getStudentDeadlines(), sessionData.getTimeZone());"},{"lineNumber":600,"author":{"gitId":"-"},"content":" Map\u003cString, Instant\u003e instructorDeadlines \u003d"},{"lineNumber":601,"author":{"gitId":"-"},"content":" convertDeadlinesToInstant(sessionData.getInstructorDeadlines(), sessionData.getTimeZone());"},{"lineNumber":602,"author":{"gitId":"-"},"content":""},{"lineNumber":603,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes sessionAttributes \u003d FeedbackSessionAttributes"},{"lineNumber":604,"author":{"gitId":"-"},"content":" .builder(sessionData.getFeedbackSessionName(), sessionData.getCourseId())"},{"lineNumber":605,"author":{"gitId":"-"},"content":" .withInstructions(sessionData.getInstructions())"},{"lineNumber":606,"author":{"gitId":"-"},"content":" .withStartTime(Instant.ofEpochMilli(sessionData.getSubmissionStartTimestamp()))"},{"lineNumber":607,"author":{"gitId":"-"},"content":" .withEndTime(Instant.ofEpochMilli(sessionData.getSubmissionEndTimestamp()))"},{"lineNumber":608,"author":{"gitId":"-"},"content":" .withTimeZone(sessionData.getTimeZone())"},{"lineNumber":609,"author":{"gitId":"-"},"content":" .withGracePeriod(Duration.ofMinutes(sessionData.getGracePeriod()))"},{"lineNumber":610,"author":{"gitId":"-"},"content":" .withIsClosingEmailEnabled(sessionData.getIsClosingEmailEnabled())"},{"lineNumber":611,"author":{"gitId":"-"},"content":" .withIsPublishedEmailEnabled(sessionData.getIsPublishedEmailEnabled())"},{"lineNumber":612,"author":{"gitId":"-"},"content":" .withStudentDeadlines(studentDeadlines)"},{"lineNumber":613,"author":{"gitId":"-"},"content":" .withInstructorDeadlines(instructorDeadlines)"},{"lineNumber":614,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":615,"author":{"gitId":"-"},"content":""},{"lineNumber":616,"author":{"gitId":"-"},"content":" sessionAttributes.setCreatedTime(Instant.ofEpochMilli(sessionData.getCreatedAtTimestamp()));"},{"lineNumber":617,"author":{"gitId":"-"},"content":""},{"lineNumber":618,"author":{"gitId":"-"},"content":" if (sessionData.getSessionVisibleSetting().equals(SessionVisibleSetting.AT_OPEN)) {"},{"lineNumber":619,"author":{"gitId":"-"},"content":" sessionAttributes.setSessionVisibleFromTime(Const.TIME_REPRESENTS_FOLLOW_OPENING);"},{"lineNumber":620,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":621,"author":{"gitId":"-"},"content":" sessionAttributes.setSessionVisibleFromTime(Instant.ofEpochMilli("},{"lineNumber":622,"author":{"gitId":"-"},"content":" sessionData.getCustomSessionVisibleTimestamp()));"},{"lineNumber":623,"author":{"gitId":"-"},"content":" }"},{"lineNumber":624,"author":{"gitId":"-"},"content":""},{"lineNumber":625,"author":{"gitId":"-"},"content":" if (sessionData.getResponseVisibleSetting().equals(ResponseVisibleSetting.AT_VISIBLE)) {"},{"lineNumber":626,"author":{"gitId":"-"},"content":" sessionAttributes.setResultsVisibleFromTime(Const.TIME_REPRESENTS_FOLLOW_VISIBLE);"},{"lineNumber":627,"author":{"gitId":"-"},"content":" } else if (sessionData.getResponseVisibleSetting().equals(ResponseVisibleSetting.LATER)) {"},{"lineNumber":628,"author":{"gitId":"-"},"content":" sessionAttributes.setResultsVisibleFromTime(Const.TIME_REPRESENTS_LATER);"},{"lineNumber":629,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":630,"author":{"gitId":"-"},"content":" sessionAttributes.setResultsVisibleFromTime(Instant.ofEpochMilli("},{"lineNumber":631,"author":{"gitId":"-"},"content":" sessionData.getCustomResponseVisibleTimestamp()));"},{"lineNumber":632,"author":{"gitId":"-"},"content":" }"},{"lineNumber":633,"author":{"gitId":"-"},"content":""},{"lineNumber":634,"author":{"gitId":"-"},"content":" return sessionAttributes;"},{"lineNumber":635,"author":{"gitId":"-"},"content":" }"},{"lineNumber":636,"author":{"gitId":"-"},"content":""},{"lineNumber":637,"author":{"gitId":"-"},"content":" private Map\u003cString, Instant\u003e convertDeadlinesToInstant(Map\u003cString, Long\u003e deadlines, String timezone) {"},{"lineNumber":638,"author":{"gitId":"-"},"content":" return deadlines.entrySet()"},{"lineNumber":639,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":640,"author":{"gitId":"-"},"content":" .collect(Collectors.toMap(Map.Entry::getKey, entry -\u003e {"},{"lineNumber":641,"author":{"gitId":"-"},"content":" Instant deadline \u003d Instant.ofEpochMilli(entry.getValue());"},{"lineNumber":642,"author":{"gitId":"-"},"content":" return TimeHelper.getMidnightAdjustedInstantBasedOnZone(deadline, timezone, true);"},{"lineNumber":643,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":644,"author":{"gitId":"-"},"content":" }"},{"lineNumber":645,"author":{"gitId":"-"},"content":""},{"lineNumber":646,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":647,"author":{"gitId":"-"},"content":" * Get soft deleted feedback session from database."},{"lineNumber":648,"author":{"gitId":"-"},"content":" */"},{"lineNumber":649,"author":{"gitId":"-"},"content":" public FeedbackSessionData getSoftDeletedSessionData(String feedbackSessionName, String instructorId) {"},{"lineNumber":650,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":651,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.ENTITY_TYPE, Const.EntityType.INSTRUCTOR);"},{"lineNumber":652,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.IS_IN_RECYCLE_BIN, \"true\");"},{"lineNumber":653,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.USER_ID, instructorId);"},{"lineNumber":654,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.SESSIONS, params);"},{"lineNumber":655,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":656,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":657,"author":{"gitId":"-"},"content":" }"},{"lineNumber":658,"author":{"gitId":"-"},"content":""},{"lineNumber":659,"author":{"gitId":"-"},"content":" FeedbackSessionsData sessionsData \u003d JsonUtils.fromJson(response.responseBody, FeedbackSessionsData.class);"},{"lineNumber":660,"author":{"gitId":"-"},"content":" return sessionsData.getFeedbackSessions()"},{"lineNumber":661,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":662,"author":{"gitId":"-"},"content":" .filter(fs -\u003e fs.getFeedbackSessionName().equals(feedbackSessionName))"},{"lineNumber":663,"author":{"gitId":"-"},"content":" .findFirst()"},{"lineNumber":664,"author":{"gitId":"-"},"content":" .orElse(null);"},{"lineNumber":665,"author":{"gitId":"-"},"content":" }"},{"lineNumber":666,"author":{"gitId":"-"},"content":""},{"lineNumber":667,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":668,"author":{"gitId":"-"},"content":" * Get soft deleted feedback session from database."},{"lineNumber":669,"author":{"gitId":"-"},"content":" */"},{"lineNumber":670,"author":{"gitId":"-"},"content":" public FeedbackSessionAttributes getSoftDeletedSession(String feedbackSessionName, String instructorId) {"},{"lineNumber":671,"author":{"gitId":"-"},"content":" FeedbackSessionData feedbackSession \u003d getSoftDeletedSessionData(feedbackSessionName, instructorId);"},{"lineNumber":672,"author":{"gitId":"-"},"content":" if (feedbackSession \u003d\u003d null) {"},{"lineNumber":673,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":674,"author":{"gitId":"-"},"content":" }"},{"lineNumber":675,"author":{"gitId":"-"},"content":""},{"lineNumber":676,"author":{"gitId":"-"},"content":" return FeedbackSessionAttributes"},{"lineNumber":677,"author":{"gitId":"-"},"content":" .builder(feedbackSession.getCourseId(), feedbackSession.getFeedbackSessionName())"},{"lineNumber":678,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":679,"author":{"gitId":"-"},"content":" }"},{"lineNumber":680,"author":{"gitId":"-"},"content":""},{"lineNumber":681,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":682,"author":{"gitId":"-"},"content":" * Get feedback question data from database."},{"lineNumber":683,"author":{"gitId":"-"},"content":" */"},{"lineNumber":684,"author":{"gitId":"-"},"content":" public FeedbackQuestionData getFeedbackQuestionData(String courseId, String feedbackSessionName,"},{"lineNumber":685,"author":{"gitId":"-"},"content":" int qnNumber) {"},{"lineNumber":686,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":687,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.COURSE_ID, courseId);"},{"lineNumber":688,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSessionName);"},{"lineNumber":689,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.INTENT, Intent.FULL_DETAIL.toString());"},{"lineNumber":690,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.QUESTIONS, params);"},{"lineNumber":691,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":692,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":693,"author":{"gitId":"-"},"content":" }"},{"lineNumber":694,"author":{"gitId":"-"},"content":""},{"lineNumber":695,"author":{"gitId":"-"},"content":" FeedbackQuestionsData questionsData \u003d JsonUtils.fromJson(response.responseBody, FeedbackQuestionsData.class);"},{"lineNumber":696,"author":{"gitId":"-"},"content":" return questionsData.getQuestions()"},{"lineNumber":697,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":698,"author":{"gitId":"-"},"content":" .filter(fq -\u003e fq.getQuestionNumber() \u003d\u003d qnNumber)"},{"lineNumber":699,"author":{"gitId":"-"},"content":" .findFirst()"},{"lineNumber":700,"author":{"gitId":"-"},"content":" .orElse(null);"},{"lineNumber":701,"author":{"gitId":"-"},"content":" }"},{"lineNumber":702,"author":{"gitId":"-"},"content":""},{"lineNumber":703,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":704,"author":{"gitId":"-"},"content":" * Get feedback question from database."},{"lineNumber":705,"author":{"gitId":"-"},"content":" */"},{"lineNumber":706,"author":{"gitId":"-"},"content":" public FeedbackQuestionAttributes getFeedbackQuestion(String courseId, String feedbackSessionName,"},{"lineNumber":707,"author":{"gitId":"-"},"content":" int qnNumber) {"},{"lineNumber":708,"author":{"gitId":"-"},"content":" FeedbackQuestionData question \u003d getFeedbackQuestionData(courseId, feedbackSessionName, qnNumber);"},{"lineNumber":709,"author":{"gitId":"-"},"content":""},{"lineNumber":710,"author":{"gitId":"-"},"content":" if (question \u003d\u003d null) {"},{"lineNumber":711,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":712,"author":{"gitId":"-"},"content":" }"},{"lineNumber":713,"author":{"gitId":"-"},"content":""},{"lineNumber":714,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes questionAttr \u003d FeedbackQuestionAttributes.builder()"},{"lineNumber":715,"author":{"gitId":"-"},"content":" .withCourseId(courseId)"},{"lineNumber":716,"author":{"gitId":"-"},"content":" .withFeedbackSessionName(feedbackSessionName)"},{"lineNumber":717,"author":{"gitId":"-"},"content":" .withQuestionDetails(question.getQuestionDetails())"},{"lineNumber":718,"author":{"gitId":"-"},"content":" .withQuestionDescription(question.getQuestionDescription())"},{"lineNumber":719,"author":{"gitId":"-"},"content":" .withQuestionNumber(question.getQuestionNumber())"},{"lineNumber":720,"author":{"gitId":"-"},"content":" .withGiverType(question.getGiverType())"},{"lineNumber":721,"author":{"gitId":"-"},"content":" .withRecipientType(question.getRecipientType())"},{"lineNumber":722,"author":{"gitId":"-"},"content":" .withNumberOfEntitiesToGiveFeedbackTo(question.getNumberOfEntitiesToGiveFeedbackToSetting()"},{"lineNumber":723,"author":{"gitId":"-"},"content":" .equals(NumberOfEntitiesToGiveFeedbackToSetting.UNLIMITED)"},{"lineNumber":724,"author":{"gitId":"-"},"content":" ? Const.MAX_POSSIBLE_RECIPIENTS"},{"lineNumber":725,"author":{"gitId":"-"},"content":" : question.getCustomNumberOfEntitiesToGiveFeedbackTo())"},{"lineNumber":726,"author":{"gitId":"-"},"content":" .withShowResponsesTo(convertToFeedbackParticipantType(question.getShowResponsesTo()))"},{"lineNumber":727,"author":{"gitId":"-"},"content":" .withShowGiverNameTo(convertToFeedbackParticipantType(question.getShowGiverNameTo()))"},{"lineNumber":728,"author":{"gitId":"-"},"content":" .withShowRecipientNameTo(convertToFeedbackParticipantType(question.getShowRecipientNameTo()))"},{"lineNumber":729,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":730,"author":{"gitId":"-"},"content":" if (question.getFeedbackQuestionId() !\u003d null) {"},{"lineNumber":731,"author":{"gitId":"-"},"content":" questionAttr.setId(question.getFeedbackQuestionId());"},{"lineNumber":732,"author":{"gitId":"-"},"content":" }"},{"lineNumber":733,"author":{"gitId":"-"},"content":" return questionAttr;"},{"lineNumber":734,"author":{"gitId":"-"},"content":" }"},{"lineNumber":735,"author":{"gitId":"-"},"content":""},{"lineNumber":736,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":737,"author":{"gitId":"-"},"content":" * Converts List of FeedbackParticipantType to sorted List of FeedbackVisibilityType."},{"lineNumber":738,"author":{"gitId":"-"},"content":" */"},{"lineNumber":739,"author":{"gitId":"-"},"content":" private static List\u003cFeedbackParticipantType\u003e convertToFeedbackParticipantType("},{"lineNumber":740,"author":{"gitId":"-"},"content":" List\u003cFeedbackVisibilityType\u003e feedbackVisibilityTypeList) {"},{"lineNumber":741,"author":{"gitId":"-"},"content":" List\u003cFeedbackParticipantType\u003e feedbackParticipantTypeList \u003d feedbackVisibilityTypeList.stream()"},{"lineNumber":742,"author":{"gitId":"-"},"content":" .map(feedbackParticipantType -\u003e {"},{"lineNumber":743,"author":{"gitId":"-"},"content":" switch (feedbackParticipantType) {"},{"lineNumber":744,"author":{"gitId":"-"},"content":" case STUDENTS:"},{"lineNumber":745,"author":{"gitId":"-"},"content":" return FeedbackParticipantType.STUDENTS;"},{"lineNumber":746,"author":{"gitId":"-"},"content":" case INSTRUCTORS:"},{"lineNumber":747,"author":{"gitId":"-"},"content":" return FeedbackParticipantType.INSTRUCTORS;"},{"lineNumber":748,"author":{"gitId":"-"},"content":" case RECIPIENT:"},{"lineNumber":749,"author":{"gitId":"-"},"content":" return FeedbackParticipantType.RECEIVER;"},{"lineNumber":750,"author":{"gitId":"-"},"content":" case GIVER_TEAM_MEMBERS:"},{"lineNumber":751,"author":{"gitId":"-"},"content":" return FeedbackParticipantType.OWN_TEAM_MEMBERS;"},{"lineNumber":752,"author":{"gitId":"-"},"content":" case RECIPIENT_TEAM_MEMBERS:"},{"lineNumber":753,"author":{"gitId":"-"},"content":" return FeedbackParticipantType.RECEIVER_TEAM_MEMBERS;"},{"lineNumber":754,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":755,"author":{"gitId":"-"},"content":" throw new RuntimeException(\"Unknown FeedbackVisibilityType \" + feedbackParticipantType);"},{"lineNumber":756,"author":{"gitId":"-"},"content":" }"},{"lineNumber":757,"author":{"gitId":"-"},"content":" }).collect(Collectors.toList());"},{"lineNumber":758,"author":{"gitId":"-"},"content":" Collections.sort(feedbackParticipantTypeList);"},{"lineNumber":759,"author":{"gitId":"-"},"content":" return feedbackParticipantTypeList;"},{"lineNumber":760,"author":{"gitId":"-"},"content":" }"},{"lineNumber":761,"author":{"gitId":"-"},"content":""},{"lineNumber":762,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":763,"author":{"gitId":"-"},"content":" * Get feedback response data from database."},{"lineNumber":764,"author":{"gitId":"-"},"content":" */"},{"lineNumber":765,"author":{"gitId":"-"},"content":" public FeedbackResponseData getFeedbackResponseData(String feedbackQuestionId, String giver,"},{"lineNumber":766,"author":{"gitId":"-"},"content":" String recipient) {"},{"lineNumber":767,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":768,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.FEEDBACK_QUESTION_ID, feedbackQuestionId);"},{"lineNumber":769,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.INTENT, Intent.STUDENT_SUBMISSION.toString());"},{"lineNumber":770,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.FEEDBACK_SESSION_MODERATED_PERSON, giver);"},{"lineNumber":771,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.RESPONSES, params);"},{"lineNumber":772,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":773,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":774,"author":{"gitId":"-"},"content":" }"},{"lineNumber":775,"author":{"gitId":"-"},"content":""},{"lineNumber":776,"author":{"gitId":"-"},"content":" FeedbackResponsesData responsesData \u003d JsonUtils.fromJson(response.responseBody, FeedbackResponsesData.class);"},{"lineNumber":777,"author":{"gitId":"-"},"content":" return responsesData.getResponses()"},{"lineNumber":778,"author":{"gitId":"-"},"content":" .stream()"},{"lineNumber":779,"author":{"gitId":"-"},"content":" .filter(r -\u003e r.getGiverIdentifier().equals(giver) \u0026\u0026 r.getRecipientIdentifier().equals(recipient))"},{"lineNumber":780,"author":{"gitId":"-"},"content":" .findFirst()"},{"lineNumber":781,"author":{"gitId":"-"},"content":" .orElse(null);"},{"lineNumber":782,"author":{"gitId":"-"},"content":" }"},{"lineNumber":783,"author":{"gitId":"-"},"content":""},{"lineNumber":784,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":785,"author":{"gitId":"-"},"content":" * Get feedback response from database."},{"lineNumber":786,"author":{"gitId":"-"},"content":" */"},{"lineNumber":787,"author":{"gitId":"-"},"content":" public FeedbackResponseAttributes getFeedbackResponse(String feedbackQuestionId, String giver,"},{"lineNumber":788,"author":{"gitId":"-"},"content":" String recipient) {"},{"lineNumber":789,"author":{"gitId":"-"},"content":" FeedbackResponseData fr \u003d getFeedbackResponseData(feedbackQuestionId, giver, recipient);"},{"lineNumber":790,"author":{"gitId":"-"},"content":""},{"lineNumber":791,"author":{"gitId":"-"},"content":" if (fr \u003d\u003d null) {"},{"lineNumber":792,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":793,"author":{"gitId":"-"},"content":" }"},{"lineNumber":794,"author":{"gitId":"-"},"content":""},{"lineNumber":795,"author":{"gitId":"-"},"content":" FeedbackResponseAttributes responseAttr \u003d FeedbackResponseAttributes"},{"lineNumber":796,"author":{"gitId":"-"},"content":" .builder(feedbackQuestionId, fr.getGiverIdentifier(), fr.getRecipientIdentifier())"},{"lineNumber":797,"author":{"gitId":"-"},"content":" .withResponseDetails(fr.getResponseDetails())"},{"lineNumber":798,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":799,"author":{"gitId":"-"},"content":" if (fr.getFeedbackResponseId() !\u003d null) {"},{"lineNumber":800,"author":{"gitId":"-"},"content":" responseAttr.setId(fr.getFeedbackResponseId());"},{"lineNumber":801,"author":{"gitId":"-"},"content":" }"},{"lineNumber":802,"author":{"gitId":"-"},"content":" return responseAttr;"},{"lineNumber":803,"author":{"gitId":"-"},"content":" }"},{"lineNumber":804,"author":{"gitId":"-"},"content":""},{"lineNumber":805,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":806,"author":{"gitId":"-"},"content":" * Get feedback response comment from database."},{"lineNumber":807,"author":{"gitId":"-"},"content":" */"},{"lineNumber":808,"author":{"gitId":"-"},"content":" public FeedbackResponseCommentAttributes getFeedbackResponseComment(String feedbackResponseId) {"},{"lineNumber":809,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":810,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.FEEDBACK_RESPONSE_ID, feedbackResponseId);"},{"lineNumber":811,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.INTENT, Intent.STUDENT_SUBMISSION.toString());"},{"lineNumber":812,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.RESPONSE_COMMENT, params);"},{"lineNumber":813,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":814,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":815,"author":{"gitId":"-"},"content":" }"},{"lineNumber":816,"author":{"gitId":"-"},"content":""},{"lineNumber":817,"author":{"gitId":"-"},"content":" FeedbackResponseCommentData frc \u003d JsonUtils.fromJson(response.responseBody, FeedbackResponseCommentData.class);"},{"lineNumber":818,"author":{"gitId":"-"},"content":""},{"lineNumber":819,"author":{"gitId":"-"},"content":" if (frc \u003d\u003d null) {"},{"lineNumber":820,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":821,"author":{"gitId":"-"},"content":" }"},{"lineNumber":822,"author":{"gitId":"-"},"content":""},{"lineNumber":823,"author":{"gitId":"-"},"content":" return FeedbackResponseCommentAttributes.builder()"},{"lineNumber":824,"author":{"gitId":"-"},"content":" .withCommentGiver(frc.getCommentGiver())"},{"lineNumber":825,"author":{"gitId":"-"},"content":" .withCommentText(frc.getCommentText())"},{"lineNumber":826,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":827,"author":{"gitId":"-"},"content":" }"},{"lineNumber":828,"author":{"gitId":"-"},"content":""},{"lineNumber":829,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":830,"author":{"gitId":"-"},"content":" * Deletes a course from the database."},{"lineNumber":831,"author":{"gitId":"-"},"content":" */"},{"lineNumber":832,"author":{"gitId":"-"},"content":" public void deleteCourse(String courseId) {"},{"lineNumber":833,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":834,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.COURSE_ID, courseId);"},{"lineNumber":835,"author":{"gitId":"-"},"content":" executeDeleteRequest(Const.ResourceURIs.COURSE, params);"},{"lineNumber":836,"author":{"gitId":"-"},"content":" }"},{"lineNumber":837,"author":{"gitId":"-"},"content":""},{"lineNumber":838,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":839,"author":{"gitId":"-"},"content":" * Gets an account request from the database."},{"lineNumber":840,"author":{"gitId":"-"},"content":" */"},{"lineNumber":841,"author":{"gitId":"-"},"content":" public AccountRequestAttributes getAccountRequest(UUID id) {"},{"lineNumber":842,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":843,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString());"},{"lineNumber":844,"author":{"gitId":"-"},"content":""},{"lineNumber":845,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.ACCOUNT_REQUEST, params);"},{"lineNumber":846,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":847,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":848,"author":{"gitId":"-"},"content":" }"},{"lineNumber":849,"author":{"gitId":"-"},"content":""},{"lineNumber":850,"author":{"gitId":"-"},"content":" AccountRequestData accountRequestData \u003d JsonUtils.fromJson(response.responseBody, AccountRequestData.class);"},{"lineNumber":851,"author":{"gitId":"-"},"content":""},{"lineNumber":852,"author":{"gitId":"-"},"content":" return AccountRequestAttributes"},{"lineNumber":853,"author":{"gitId":"-"},"content":" .builder(accountRequestData.getEmail(), accountRequestData.getInstitute(), accountRequestData.getName())"},{"lineNumber":854,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":855,"author":{"gitId":"-"},"content":" }"},{"lineNumber":856,"author":{"gitId":"-"},"content":""},{"lineNumber":857,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":858,"author":{"gitId":"-"},"content":" * Gets registration key of an account request from the database."},{"lineNumber":859,"author":{"gitId":"-"},"content":" */"},{"lineNumber":860,"author":{"gitId":"-"},"content":" public String getRegKeyForAccountRequest(UUID id) {"},{"lineNumber":861,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":862,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString());"},{"lineNumber":863,"author":{"gitId":"-"},"content":""},{"lineNumber":864,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.ACCOUNT_REQUEST, params);"},{"lineNumber":865,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":866,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":867,"author":{"gitId":"-"},"content":" }"},{"lineNumber":868,"author":{"gitId":"-"},"content":""},{"lineNumber":869,"author":{"gitId":"-"},"content":" return JsonUtils.fromJson(response.responseBody, AccountRequestData.class).getRegistrationKey();"},{"lineNumber":870,"author":{"gitId":"-"},"content":" }"},{"lineNumber":871,"author":{"gitId":"-"},"content":""},{"lineNumber":872,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":873,"author":{"gitId":"-"},"content":" * Deletes an account request from the database."},{"lineNumber":874,"author":{"gitId":"-"},"content":" */"},{"lineNumber":875,"author":{"gitId":"dishenggg"},"content":" public void deleteAccountRequest(UUID id) {"},{"lineNumber":876,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":877,"author":{"gitId":"dishenggg"},"content":" params.put(Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString());"},{"lineNumber":878,"author":{"gitId":"-"},"content":" executeDeleteRequest(Const.ResourceURIs.ACCOUNT_REQUEST, params);"},{"lineNumber":879,"author":{"gitId":"-"},"content":" }"},{"lineNumber":880,"author":{"gitId":"-"},"content":""},{"lineNumber":881,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":882,"author":{"gitId":"-"},"content":" * Gets notification data from the database."},{"lineNumber":883,"author":{"gitId":"-"},"content":" */"},{"lineNumber":884,"author":{"gitId":"-"},"content":" public NotificationData getNotificationData(String notificationId) {"},{"lineNumber":885,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":886,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.NOTIFICATION_ID, notificationId);"},{"lineNumber":887,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.NOTIFICATION, params);"},{"lineNumber":888,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":889,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":890,"author":{"gitId":"-"},"content":" }"},{"lineNumber":891,"author":{"gitId":"-"},"content":" return JsonUtils.fromJson(response.responseBody, NotificationData.class);"},{"lineNumber":892,"author":{"gitId":"-"},"content":" }"},{"lineNumber":893,"author":{"gitId":"-"},"content":""},{"lineNumber":894,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":895,"author":{"gitId":"-"},"content":" * Gets a notification from the database."},{"lineNumber":896,"author":{"gitId":"-"},"content":" */"},{"lineNumber":897,"author":{"gitId":"-"},"content":" public NotificationAttributes getNotification(String notificationId) {"},{"lineNumber":898,"author":{"gitId":"-"},"content":" NotificationData notificationData \u003d getNotificationData(notificationId);"},{"lineNumber":899,"author":{"gitId":"-"},"content":" if (notificationData \u003d\u003d null) {"},{"lineNumber":900,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":901,"author":{"gitId":"-"},"content":" }"},{"lineNumber":902,"author":{"gitId":"-"},"content":" NotificationAttributes notification \u003d NotificationAttributes.builder(notificationData.getNotificationId())"},{"lineNumber":903,"author":{"gitId":"-"},"content":" .withStartTime(Instant.ofEpochMilli(notificationData.getStartTimestamp()))"},{"lineNumber":904,"author":{"gitId":"-"},"content":" .withEndTime(Instant.ofEpochMilli(notificationData.getEndTimestamp()))"},{"lineNumber":905,"author":{"gitId":"-"},"content":" .withStyle(notificationData.getStyle())"},{"lineNumber":906,"author":{"gitId":"-"},"content":" .withTargetUser(notificationData.getTargetUser())"},{"lineNumber":907,"author":{"gitId":"-"},"content":" .withTitle(notificationData.getTitle())"},{"lineNumber":908,"author":{"gitId":"-"},"content":" .withMessage(notificationData.getMessage())"},{"lineNumber":909,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":910,"author":{"gitId":"-"},"content":" notification.setCreatedAt(Instant.ofEpochMilli(notificationData.getCreatedAt()));"},{"lineNumber":911,"author":{"gitId":"-"},"content":" return notification;"},{"lineNumber":912,"author":{"gitId":"-"},"content":" }"},{"lineNumber":913,"author":{"gitId":"-"},"content":""},{"lineNumber":914,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":915,"author":{"gitId":"-"},"content":" * Deletes a notification from the database."},{"lineNumber":916,"author":{"gitId":"-"},"content":" */"},{"lineNumber":917,"author":{"gitId":"-"},"content":" public void deleteNotification(String notificationId) {"},{"lineNumber":918,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":919,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.NOTIFICATION_ID, notificationId);"},{"lineNumber":920,"author":{"gitId":"-"},"content":" executeDeleteRequest(Const.ResourceURIs.NOTIFICATION, params);"},{"lineNumber":921,"author":{"gitId":"-"},"content":" }"},{"lineNumber":922,"author":{"gitId":"-"},"content":""},{"lineNumber":923,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":924,"author":{"gitId":"-"},"content":" * Deletes a notification from the database."},{"lineNumber":925,"author":{"gitId":"-"},"content":" */"},{"lineNumber":926,"author":{"gitId":"-"},"content":" public void deleteNotification(UUID notificationId) {"},{"lineNumber":927,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":928,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.NOTIFICATION_ID, notificationId.toString());"},{"lineNumber":929,"author":{"gitId":"-"},"content":" executeDeleteRequest(Const.ResourceURIs.NOTIFICATION, params);"},{"lineNumber":930,"author":{"gitId":"-"},"content":" }"},{"lineNumber":931,"author":{"gitId":"-"},"content":""},{"lineNumber":932,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":933,"author":{"gitId":"-"},"content":" * Gets a deadline extension from the database."},{"lineNumber":934,"author":{"gitId":"-"},"content":" */"},{"lineNumber":935,"author":{"gitId":"-"},"content":" public DeadlineExtensionAttributes getDeadlineExtension("},{"lineNumber":936,"author":{"gitId":"-"},"content":" String courseId, String feedbackSessionName, String userEmail, boolean isInstructor) {"},{"lineNumber":937,"author":{"gitId":"-"},"content":" Map\u003cString, String\u003e params \u003d new HashMap\u003c\u003e();"},{"lineNumber":938,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.COURSE_ID, courseId);"},{"lineNumber":939,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSessionName);"},{"lineNumber":940,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.USER_EMAIL, userEmail);"},{"lineNumber":941,"author":{"gitId":"-"},"content":" params.put(Const.ParamsNames.IS_INSTRUCTOR, Boolean.toString(isInstructor));"},{"lineNumber":942,"author":{"gitId":"-"},"content":""},{"lineNumber":943,"author":{"gitId":"-"},"content":" ResponseBodyAndCode response \u003d executeGetRequest(Const.ResourceURIs.DEADLINE_EXTENSION, params);"},{"lineNumber":944,"author":{"gitId":"-"},"content":" if (response.responseCode \u003d\u003d HttpStatus.SC_NOT_FOUND) {"},{"lineNumber":945,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":946,"author":{"gitId":"-"},"content":" }"},{"lineNumber":947,"author":{"gitId":"-"},"content":""},{"lineNumber":948,"author":{"gitId":"-"},"content":" DeadlineExtensionData deadlineExtensionData \u003d JsonUtils.fromJson(response.responseBody, DeadlineExtensionData.class);"},{"lineNumber":949,"author":{"gitId":"-"},"content":""},{"lineNumber":950,"author":{"gitId":"-"},"content":" return DeadlineExtensionAttributes.builder("},{"lineNumber":951,"author":{"gitId":"-"},"content":" deadlineExtensionData.getCourseId(), deadlineExtensionData.getFeedbackSessionName(),"},{"lineNumber":952,"author":{"gitId":"-"},"content":" deadlineExtensionData.getUserEmail(), deadlineExtensionData.getIsInstructor())"},{"lineNumber":953,"author":{"gitId":"-"},"content":" .withEndTime(Instant.ofEpochMilli(deadlineExtensionData.getEndTime()))"},{"lineNumber":954,"author":{"gitId":"-"},"content":" .withSentClosingEmail(deadlineExtensionData.getSentClosingEmail())"},{"lineNumber":955,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":956,"author":{"gitId":"-"},"content":" }"},{"lineNumber":957,"author":{"gitId":"-"},"content":""},{"lineNumber":958,"author":{"gitId":"-"},"content":" private static final class ResponseBodyAndCode {"},{"lineNumber":959,"author":{"gitId":"-"},"content":""},{"lineNumber":960,"author":{"gitId":"-"},"content":" String responseBody;"},{"lineNumber":961,"author":{"gitId":"-"},"content":" int responseCode;"},{"lineNumber":962,"author":{"gitId":"-"},"content":""},{"lineNumber":963,"author":{"gitId":"-"},"content":" ResponseBodyAndCode(String responseBody, int responseCode) {"},{"lineNumber":964,"author":{"gitId":"-"},"content":" this.responseBody \u003d responseBody;"},{"lineNumber":965,"author":{"gitId":"-"},"content":" this.responseCode \u003d responseCode;"},{"lineNumber":966,"author":{"gitId":"-"},"content":" }"},{"lineNumber":967,"author":{"gitId":"-"},"content":""},{"lineNumber":968,"author":{"gitId":"-"},"content":" }"},{"lineNumber":969,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":13,"-":956}},{"path":"src/test/java/teammates/test/BaseTestCase.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.test;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.io.IOException;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.lang.reflect.Method;"},{"lineNumber":5,"author":{"gitId":"dishenggg"},"content":"import java.time.Duration;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import java.util.ArrayList;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import java.util.HashMap;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import java.util.Map;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import java.util.UUID;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import org.junit.jupiter.api.Assertions;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import org.junit.jupiter.api.function.Executable;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.AccountRequestStatus;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.DataBundle;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.FeedbackParticipantType;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPermissionRole;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.InstructorPrivileges;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationStyle;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.NotificationTargetUser;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.questions.FeedbackResponseDetails;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackTextQuestionDetails;"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":"import teammates.common.datatransfer.questions.FeedbackTextResponseDetails;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.common.util.FieldValidator;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.TimeHelperExtension;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.sqllogic.core.DataBundleLogic;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.AccountRequest;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":38,"author":{"gitId":"mingyuanc"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":41,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":42,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Section;"},{"lineNumber":43,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Team;"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":47,"author":{"gitId":"-"},"content":" * Base class for all test cases."},{"lineNumber":48,"author":{"gitId":"-"},"content":" */"},{"lineNumber":49,"author":{"gitId":"-"},"content":"@SuppressWarnings(\"PMD.TestClassWithoutTestCases\")"},{"lineNumber":50,"author":{"gitId":"-"},"content":"public class BaseTestCase {"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":53,"author":{"gitId":"-"},"content":" * Test Segment divider. Used to divide a test case into logical sections."},{"lineNumber":54,"author":{"gitId":"-"},"content":" * The weird name is for easy spotting."},{"lineNumber":55,"author":{"gitId":"-"},"content":" *"},{"lineNumber":56,"author":{"gitId":"-"},"content":" * @param description"},{"lineNumber":57,"author":{"gitId":"-"},"content":" * of the logical section. This will be printed."},{"lineNumber":58,"author":{"gitId":"-"},"content":" */"},{"lineNumber":59,"author":{"gitId":"-"},"content":" // CHECKSTYLE.OFF:AbbreviationAsWordInName|MethodName the weird name is for easy spotting."},{"lineNumber":60,"author":{"gitId":"-"},"content":" public static void ______TS(String description) {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" print(\" * \" + description);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" }"},{"lineNumber":63,"author":{"gitId":"-"},"content":" // CHECKSTYLE.ON:AbbreviationAsWordInName|MethodName"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" @BeforeClass"},{"lineNumber":66,"author":{"gitId":"-"},"content":" public void printTestClassHeader() {"},{"lineNumber":67,"author":{"gitId":"-"},"content":" print(\"[\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\""},{"lineNumber":68,"author":{"gitId":"-"},"content":" + getClass().getCanonicalName()"},{"lineNumber":69,"author":{"gitId":"-"},"content":" + \"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d]\");"},{"lineNumber":70,"author":{"gitId":"-"},"content":" }"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":73,"author":{"gitId":"-"},"content":" public void printTestClassFooter() {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" print(getClass().getCanonicalName() + \" completed\");"},{"lineNumber":75,"author":{"gitId":"-"},"content":" }"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" protected static void print(String message) {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" System.out.println(message);"},{"lineNumber":79,"author":{"gitId":"-"},"content":" }"},{"lineNumber":80,"author":{"gitId":"-"},"content":""},{"lineNumber":81,"author":{"gitId":"-"},"content":" protected String getTestDataFolder() {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" return TestProperties.TEST_DATA_FOLDER;"},{"lineNumber":83,"author":{"gitId":"-"},"content":" }"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":86,"author":{"gitId":"-"},"content":" * Creates a DataBundle as specified in typicalDataBundle.json."},{"lineNumber":87,"author":{"gitId":"-"},"content":" */"},{"lineNumber":88,"author":{"gitId":"-"},"content":" protected DataBundle getTypicalDataBundle() {"},{"lineNumber":89,"author":{"gitId":"-"},"content":" return loadDataBundle(\"/typicalDataBundle.json\");"},{"lineNumber":90,"author":{"gitId":"-"},"content":" }"},{"lineNumber":91,"author":{"gitId":"-"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" protected DataBundle loadDataBundle(String jsonFileName) {"},{"lineNumber":93,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" String pathToJsonFile \u003d getTestDataFolder() + jsonFileName;"},{"lineNumber":95,"author":{"gitId":"-"},"content":" String jsonString \u003d FileHelper.readFile(pathToJsonFile);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" return JsonUtils.fromJson(jsonString, DataBundle.class);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":99,"author":{"gitId":"-"},"content":" }"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" protected SqlDataBundle getTypicalSqlDataBundle() {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" return loadSqlDataBundle(\"/typicalDataBundle.json\");"},{"lineNumber":104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" protected SqlDataBundle loadSqlDataBundle(String jsonFileName) {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":108,"author":{"gitId":"-"},"content":" // TODO: rename to loadDataBundle after migration"},{"lineNumber":109,"author":{"gitId":"-"},"content":" String pathToJsonFile \u003d getTestDataFolder() + jsonFileName;"},{"lineNumber":110,"author":{"gitId":"-"},"content":" String jsonString \u003d FileHelper.readFile(pathToJsonFile);"},{"lineNumber":111,"author":{"gitId":"-"},"content":" return DataBundleLogic.deserializeDataBundle(jsonString);"},{"lineNumber":112,"author":{"gitId":"-"},"content":" } catch (IOException e) {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" throw new RuntimeException(e);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":" }"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":118,"author":{"gitId":"-"},"content":" * These getTypicalX functions are used to generate typical entities for tests."},{"lineNumber":119,"author":{"gitId":"-"},"content":" * The entity fields can be changed using setter methods if needed."},{"lineNumber":120,"author":{"gitId":"-"},"content":" * New entity generator functions for tests should be added here, and follow the"},{"lineNumber":121,"author":{"gitId":"-"},"content":" * same naming convention."},{"lineNumber":122,"author":{"gitId":"-"},"content":" *"},{"lineNumber":123,"author":{"gitId":"-"},"content":" * \u003cp\u003eExample usage:"},{"lineNumber":124,"author":{"gitId":"-"},"content":" * Account account \u003d getTypicalAccount();"},{"lineNumber":125,"author":{"gitId":"-"},"content":" * Student student \u003d getTypicalStudent();"},{"lineNumber":126,"author":{"gitId":"-"},"content":" * account.setEmail(\"newemail@teammates.com\");"},{"lineNumber":127,"author":{"gitId":"-"},"content":" * student.setName(\"New Student Name\");"},{"lineNumber":128,"author":{"gitId":"-"},"content":" */"},{"lineNumber":129,"author":{"gitId":"-"},"content":" protected Account getTypicalAccount() {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" return new Account(\"google-id\", \"name\", \"email@teammates.com\");"},{"lineNumber":131,"author":{"gitId":"-"},"content":" }"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" protected Notification getTypicalNotificationWithId() {"},{"lineNumber":134,"author":{"gitId":"-"},"content":" Notification notification \u003d new Notification(Instant.parse(\"2011-01-01T00:00:00Z\"),"},{"lineNumber":135,"author":{"gitId":"-"},"content":" Instant.parse(\"2099-01-01T00:00:00Z\"), NotificationStyle.DANGER, NotificationTargetUser.GENERAL,"},{"lineNumber":136,"author":{"gitId":"-"},"content":" \"A deprecation note\", \"\u003cp\u003eDeprecation happens in three minutes\u003c/p\u003e\");"},{"lineNumber":137,"author":{"gitId":"-"},"content":" notification.setId(UUID.randomUUID());"},{"lineNumber":138,"author":{"gitId":"-"},"content":" return notification;"},{"lineNumber":139,"author":{"gitId":"-"},"content":" }"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" protected Instructor getTypicalInstructor() {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":143,"author":{"gitId":"-"},"content":" InstructorPrivileges instructorPrivileges \u003d"},{"lineNumber":144,"author":{"gitId":"-"},"content":" new InstructorPrivileges(Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_COOWNER);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" InstructorPermissionRole role \u003d InstructorPermissionRole"},{"lineNumber":146,"author":{"gitId":"-"},"content":" .getEnum(Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_COOWNER);"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" return new Instructor(course, \"instructor-name\", \"valid@teammates.tmt\","},{"lineNumber":149,"author":{"gitId":"-"},"content":" false, Const.DEFAULT_DISPLAY_NAME_FOR_INSTRUCTOR, role, instructorPrivileges);"},{"lineNumber":150,"author":{"gitId":"-"},"content":" }"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" protected Course getTypicalCourse() {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" return new Course(\"course-id\", \"course-name\", Const.DEFAULT_TIME_ZONE, \"teammates\");"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" protected Student getTypicalStudent() {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":158,"author":{"gitId":"-"},"content":" return new Student(course, \"student-name\", \"validstudent@teammates.tmt\", \"comments\");"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" protected Section getTypicalSection() {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" Course course \u003d getTypicalCourse();"},{"lineNumber":163,"author":{"gitId":"-"},"content":" return new Section(course, \"test-section\");"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":""},{"lineNumber":166,"author":{"gitId":"-"},"content":" protected Team getTypicalTeam() {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" Section section \u003d getTypicalSection();"},{"lineNumber":168,"author":{"gitId":"-"},"content":" return new Team(section, \"test-team\");"},{"lineNumber":169,"author":{"gitId":"-"},"content":" }"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" protected FeedbackSession getTypicalFeedbackSessionForCourse(Course course) {"},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":" Instant startTime \u003d TimeHelperExtension.getInstantDaysOffsetFromNow(1);"},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":" Instant endTime \u003d TimeHelperExtension.getInstantDaysOffsetFromNow(7);"},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":" return new FeedbackSession(\"test-feedbacksession\","},{"lineNumber":175,"author":{"gitId":"dishenggg"},"content":" course,"},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":" \"test@teammates.tmt\","},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":" \"test-instructions\","},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":" startTime,"},{"lineNumber":179,"author":{"gitId":"dishenggg"},"content":" endTime,"},{"lineNumber":180,"author":{"gitId":"dishenggg"},"content":" startTime,"},{"lineNumber":181,"author":{"gitId":"dishenggg"},"content":" endTime,"},{"lineNumber":182,"author":{"gitId":"dishenggg"},"content":" Duration.ofMinutes(5),"},{"lineNumber":183,"author":{"gitId":"dishenggg"},"content":" false,"},{"lineNumber":184,"author":{"gitId":"dishenggg"},"content":" false,"},{"lineNumber":185,"author":{"gitId":"dishenggg"},"content":" false);"},{"lineNumber":186,"author":{"gitId":"-"},"content":" }"},{"lineNumber":187,"author":{"gitId":"-"},"content":""},{"lineNumber":188,"author":{"gitId":"-"},"content":" protected FeedbackQuestion getTypicalFeedbackQuestionForSession(FeedbackSession session) {"},{"lineNumber":189,"author":{"gitId":"-"},"content":" return FeedbackQuestion.makeQuestion(session, 1, \"test-description\","},{"lineNumber":190,"author":{"gitId":"-"},"content":" FeedbackParticipantType.SELF, FeedbackParticipantType.SELF, 1, new ArrayList\u003c\u003e(),"},{"lineNumber":191,"author":{"gitId":"-"},"content":" new ArrayList\u003c\u003e(), new ArrayList\u003c\u003e(),"},{"lineNumber":192,"author":{"gitId":"-"},"content":" new FeedbackTextQuestionDetails(\"test question text\"));"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"xenosf"},"content":" protected FeedbackResponse getTypicalFeedbackResponseForQuestion(FeedbackQuestion question) {"},{"lineNumber":196,"author":{"gitId":"xenosf"},"content":" return FeedbackResponse.makeResponse(question, \"test-giver\", getTypicalSection(), \"test-recipient\","},{"lineNumber":197,"author":{"gitId":"xenosf"},"content":" getTypicalSection(), getTypicalFeedbackResponseDetails());"},{"lineNumber":198,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":199,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":200,"author":{"gitId":"xenosf"},"content":" protected FeedbackResponseDetails getTypicalFeedbackResponseDetails() {"},{"lineNumber":201,"author":{"gitId":"xenosf"},"content":" return new FeedbackTextResponseDetails();"},{"lineNumber":202,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":203,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":204,"author":{"gitId":"mingyuanc"},"content":" protected FeedbackResponseComment getTypicalResponseComment(Long id) {"},{"lineNumber":205,"author":{"gitId":"mingyuanc"},"content":" FeedbackResponseComment comment \u003d new FeedbackResponseComment(null, \"\","},{"lineNumber":206,"author":{"gitId":"mingyuanc"},"content":" FeedbackParticipantType.STUDENTS, null, null, \"\","},{"lineNumber":207,"author":{"gitId":"mingyuanc"},"content":" false, false,"},{"lineNumber":208,"author":{"gitId":"mingyuanc"},"content":" null, null, null);"},{"lineNumber":209,"author":{"gitId":"mingyuanc"},"content":" comment.setId(id);"},{"lineNumber":210,"author":{"gitId":"mingyuanc"},"content":" return comment;"},{"lineNumber":211,"author":{"gitId":"mingyuanc"},"content":" }"},{"lineNumber":212,"author":{"gitId":"mingyuanc"},"content":""},{"lineNumber":213,"author":{"gitId":"xenosf"},"content":" protected AccountRequest getTypicalAccountRequest() {"},{"lineNumber":214,"author":{"gitId":"xenosf"},"content":" return new AccountRequest(\"valid@test.com\", \"Test Name\", \"TEAMMATES Test Institute 1, Test Country\","},{"lineNumber":215,"author":{"gitId":"xenosf"},"content":" AccountRequestStatus.PENDING, \"\");"},{"lineNumber":216,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":217,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":218,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":219,"author":{"gitId":"-"},"content":" * Populates the feedback question and response IDs within the data bundle."},{"lineNumber":220,"author":{"gitId":"-"},"content":" *"},{"lineNumber":221,"author":{"gitId":"-"},"content":" * \u003cp\u003eFor tests where simulated database is used, the backend will assign the question and response IDs"},{"lineNumber":222,"author":{"gitId":"-"},"content":" * when the entities are persisted into the database, and modify the relation IDs accordingly."},{"lineNumber":223,"author":{"gitId":"-"},"content":" * However, for tests that do not use simulated database (e.g. pure data structure tests),"},{"lineNumber":224,"author":{"gitId":"-"},"content":" * the assignment of IDs have to be simulated."},{"lineNumber":225,"author":{"gitId":"-"},"content":" */"},{"lineNumber":226,"author":{"gitId":"-"},"content":" protected void populateQuestionAndResponseIds(DataBundle dataBundle) {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" Map\u003cString, Map\u003cInteger, String\u003e\u003e sessionToQuestionNumberToId \u003d new HashMap\u003c\u003e();"},{"lineNumber":228,"author":{"gitId":"-"},"content":""},{"lineNumber":229,"author":{"gitId":"-"},"content":" dataBundle.feedbackQuestions.forEach((key, question) -\u003e {"},{"lineNumber":230,"author":{"gitId":"-"},"content":" // Assign the same ID as the key as a later function requires a match between the key and the question ID"},{"lineNumber":231,"author":{"gitId":"-"},"content":" question.setId(key);"},{"lineNumber":232,"author":{"gitId":"-"},"content":" Map\u003cInteger, String\u003e questionNumberToId \u003d sessionToQuestionNumberToId.computeIfAbsent("},{"lineNumber":233,"author":{"gitId":"-"},"content":" question.getCourseId() + \"%\" + question.getFeedbackSessionName(), k -\u003e new HashMap\u003c\u003e());"},{"lineNumber":234,"author":{"gitId":"-"},"content":" questionNumberToId.put(question.getQuestionNumber(), key);"},{"lineNumber":235,"author":{"gitId":"-"},"content":" });"},{"lineNumber":236,"author":{"gitId":"-"},"content":""},{"lineNumber":237,"author":{"gitId":"-"},"content":" dataBundle.feedbackResponses.forEach((key, response) -\u003e {"},{"lineNumber":238,"author":{"gitId":"-"},"content":" response.setId(key);"},{"lineNumber":239,"author":{"gitId":"-"},"content":" String feedbackQuestionId \u003d sessionToQuestionNumberToId"},{"lineNumber":240,"author":{"gitId":"-"},"content":" .get(response.getCourseId() + \"%\" + response.getFeedbackSessionName())"},{"lineNumber":241,"author":{"gitId":"-"},"content":" .get(Integer.valueOf(response.getFeedbackQuestionId()));"},{"lineNumber":242,"author":{"gitId":"-"},"content":" response.setFeedbackQuestionId(feedbackQuestionId);"},{"lineNumber":243,"author":{"gitId":"-"},"content":" });"},{"lineNumber":244,"author":{"gitId":"-"},"content":" }"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":247,"author":{"gitId":"-"},"content":" * Invokes the method named {@code methodName} as defined in the {@code definingClass}."},{"lineNumber":248,"author":{"gitId":"-"},"content":" * @param definingClass the class which defines the method"},{"lineNumber":249,"author":{"gitId":"-"},"content":" * @param parameterTypes the parameter types of the method,"},{"lineNumber":250,"author":{"gitId":"-"},"content":" * which must be passed in the same order defined in the method"},{"lineNumber":251,"author":{"gitId":"-"},"content":" * @param invokingObject the object which invokes the method, can be {@code null} if the method is static"},{"lineNumber":252,"author":{"gitId":"-"},"content":" * @param args the arguments to be passed to the method invocation"},{"lineNumber":253,"author":{"gitId":"-"},"content":" */"},{"lineNumber":254,"author":{"gitId":"-"},"content":" protected static Object invokeMethod(Class\u003c?\u003e definingClass, String methodName, Class\u003c?\u003e[] parameterTypes,"},{"lineNumber":255,"author":{"gitId":"-"},"content":" Object invokingObject, Object[] args)"},{"lineNumber":256,"author":{"gitId":"-"},"content":" throws ReflectiveOperationException {"},{"lineNumber":257,"author":{"gitId":"-"},"content":" Method method \u003d definingClass.getDeclaredMethod(methodName, parameterTypes);"},{"lineNumber":258,"author":{"gitId":"-"},"content":" method.setAccessible(true);"},{"lineNumber":259,"author":{"gitId":"-"},"content":" return method.invoke(invokingObject, args);"},{"lineNumber":260,"author":{"gitId":"-"},"content":" }"},{"lineNumber":261,"author":{"gitId":"-"},"content":""},{"lineNumber":262,"author":{"gitId":"-"},"content":" protected static String getPopulatedErrorMessage(String messageTemplate, String userInput,"},{"lineNumber":263,"author":{"gitId":"-"},"content":" String fieldName, String errorReason)"},{"lineNumber":264,"author":{"gitId":"-"},"content":" throws ReflectiveOperationException {"},{"lineNumber":265,"author":{"gitId":"-"},"content":" return getPopulatedErrorMessage(messageTemplate, userInput, fieldName, errorReason, 0);"},{"lineNumber":266,"author":{"gitId":"-"},"content":" }"},{"lineNumber":267,"author":{"gitId":"-"},"content":""},{"lineNumber":268,"author":{"gitId":"-"},"content":" protected static String getPopulatedErrorMessage(String messageTemplate, String userInput,"},{"lineNumber":269,"author":{"gitId":"-"},"content":" String fieldName, String errorReason, int maxLength)"},{"lineNumber":270,"author":{"gitId":"-"},"content":" throws ReflectiveOperationException {"},{"lineNumber":271,"author":{"gitId":"-"},"content":" return (String) invokeMethod(FieldValidator.class, \"getPopulatedErrorMessage\","},{"lineNumber":272,"author":{"gitId":"-"},"content":" new Class\u003c?\u003e[] { String.class, String.class, String.class, String.class, int.class },"},{"lineNumber":273,"author":{"gitId":"-"},"content":" null, new Object[] { messageTemplate, userInput, fieldName, errorReason, maxLength });"},{"lineNumber":274,"author":{"gitId":"-"},"content":" }"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" protected static String getPopulatedEmptyStringErrorMessage(String messageTemplate, String fieldName, int maxLength)"},{"lineNumber":277,"author":{"gitId":"-"},"content":" throws ReflectiveOperationException {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" return (String) invokeMethod(FieldValidator.class, \"getPopulatedEmptyStringErrorMessage\","},{"lineNumber":279,"author":{"gitId":"-"},"content":" new Class\u003c?\u003e[] { String.class, String.class, int.class },"},{"lineNumber":280,"author":{"gitId":"-"},"content":" null, new Object[] { messageTemplate, fieldName, maxLength });"},{"lineNumber":281,"author":{"gitId":"-"},"content":" }"},{"lineNumber":282,"author":{"gitId":"-"},"content":""},{"lineNumber":283,"author":{"gitId":"-"},"content":" /*"},{"lineNumber":284,"author":{"gitId":"-"},"content":" * Here are some of the most common assertion methods provided by JUnit."},{"lineNumber":285,"author":{"gitId":"-"},"content":" * They are copied here to prevent repetitive importing in test classes."},{"lineNumber":286,"author":{"gitId":"-"},"content":" */"},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":" protected static void assertTrue(boolean condition) {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" Assertions.assertTrue(condition);"},{"lineNumber":290,"author":{"gitId":"-"},"content":" }"},{"lineNumber":291,"author":{"gitId":"-"},"content":""},{"lineNumber":292,"author":{"gitId":"-"},"content":" protected static void assertTrue(String message, boolean condition) {"},{"lineNumber":293,"author":{"gitId":"-"},"content":" Assertions.assertTrue(condition, message);"},{"lineNumber":294,"author":{"gitId":"-"},"content":" }"},{"lineNumber":295,"author":{"gitId":"-"},"content":""},{"lineNumber":296,"author":{"gitId":"-"},"content":" protected static void assertFalse(boolean condition) {"},{"lineNumber":297,"author":{"gitId":"-"},"content":" Assertions.assertFalse(condition);"},{"lineNumber":298,"author":{"gitId":"-"},"content":" }"},{"lineNumber":299,"author":{"gitId":"-"},"content":""},{"lineNumber":300,"author":{"gitId":"-"},"content":" protected static void assertFalse(String message, boolean condition) {"},{"lineNumber":301,"author":{"gitId":"-"},"content":" Assertions.assertFalse(condition, message);"},{"lineNumber":302,"author":{"gitId":"-"},"content":" }"},{"lineNumber":303,"author":{"gitId":"-"},"content":""},{"lineNumber":304,"author":{"gitId":"-"},"content":" protected static void assertEquals(int expected, int actual) {"},{"lineNumber":305,"author":{"gitId":"-"},"content":" Assertions.assertEquals(expected, actual);"},{"lineNumber":306,"author":{"gitId":"-"},"content":" }"},{"lineNumber":307,"author":{"gitId":"-"},"content":""},{"lineNumber":308,"author":{"gitId":"-"},"content":" protected static void assertEquals(String message, int expected, int actual) {"},{"lineNumber":309,"author":{"gitId":"-"},"content":" Assertions.assertEquals(expected, actual, message);"},{"lineNumber":310,"author":{"gitId":"-"},"content":" }"},{"lineNumber":311,"author":{"gitId":"-"},"content":""},{"lineNumber":312,"author":{"gitId":"-"},"content":" protected static void assertEquals(long expected, long actual) {"},{"lineNumber":313,"author":{"gitId":"-"},"content":" Assertions.assertEquals(expected, actual);"},{"lineNumber":314,"author":{"gitId":"-"},"content":" }"},{"lineNumber":315,"author":{"gitId":"-"},"content":""},{"lineNumber":316,"author":{"gitId":"-"},"content":" protected static void assertEquals(double expected, double actual, double delta) {"},{"lineNumber":317,"author":{"gitId":"-"},"content":" Assertions.assertEquals(expected, actual, delta);"},{"lineNumber":318,"author":{"gitId":"-"},"content":" }"},{"lineNumber":319,"author":{"gitId":"-"},"content":""},{"lineNumber":320,"author":{"gitId":"-"},"content":" protected static void assertEquals(Object expected, Object actual) {"},{"lineNumber":321,"author":{"gitId":"-"},"content":" Assertions.assertEquals(expected, actual);"},{"lineNumber":322,"author":{"gitId":"-"},"content":" }"},{"lineNumber":323,"author":{"gitId":"-"},"content":""},{"lineNumber":324,"author":{"gitId":"-"},"content":" protected static void assertEquals(String message, Object expected, Object actual) {"},{"lineNumber":325,"author":{"gitId":"-"},"content":" Assertions.assertEquals(expected, actual, message);"},{"lineNumber":326,"author":{"gitId":"-"},"content":" }"},{"lineNumber":327,"author":{"gitId":"-"},"content":""},{"lineNumber":328,"author":{"gitId":"-"},"content":" protected static void assertArrayEquals(byte[] expected, byte[] actual) {"},{"lineNumber":329,"author":{"gitId":"-"},"content":" Assertions.assertArrayEquals(expected, actual);"},{"lineNumber":330,"author":{"gitId":"-"},"content":" }"},{"lineNumber":331,"author":{"gitId":"-"},"content":""},{"lineNumber":332,"author":{"gitId":"-"},"content":" protected static void assertNotEquals(Object first, Object second) {"},{"lineNumber":333,"author":{"gitId":"-"},"content":" Assertions.assertNotEquals(first, second);"},{"lineNumber":334,"author":{"gitId":"-"},"content":" }"},{"lineNumber":335,"author":{"gitId":"-"},"content":""},{"lineNumber":336,"author":{"gitId":"-"},"content":" protected static void assertSame(Object expected, Object actual) {"},{"lineNumber":337,"author":{"gitId":"-"},"content":" Assertions.assertSame(expected, actual);"},{"lineNumber":338,"author":{"gitId":"-"},"content":" }"},{"lineNumber":339,"author":{"gitId":"-"},"content":""},{"lineNumber":340,"author":{"gitId":"-"},"content":" protected static void assertNotSame(Object unexpected, Object actual) {"},{"lineNumber":341,"author":{"gitId":"-"},"content":" Assertions.assertNotSame(unexpected, actual);"},{"lineNumber":342,"author":{"gitId":"-"},"content":" }"},{"lineNumber":343,"author":{"gitId":"-"},"content":""},{"lineNumber":344,"author":{"gitId":"-"},"content":" protected static void assertNull(Object object) {"},{"lineNumber":345,"author":{"gitId":"-"},"content":" Assertions.assertNull(object);"},{"lineNumber":346,"author":{"gitId":"-"},"content":" }"},{"lineNumber":347,"author":{"gitId":"-"},"content":""},{"lineNumber":348,"author":{"gitId":"-"},"content":" protected static void assertNull(String message, Object object) {"},{"lineNumber":349,"author":{"gitId":"-"},"content":" Assertions.assertNull(object, message);"},{"lineNumber":350,"author":{"gitId":"-"},"content":" }"},{"lineNumber":351,"author":{"gitId":"-"},"content":""},{"lineNumber":352,"author":{"gitId":"-"},"content":" protected static void assertNotNull(Object object) {"},{"lineNumber":353,"author":{"gitId":"-"},"content":" Assertions.assertNotNull(object);"},{"lineNumber":354,"author":{"gitId":"-"},"content":" }"},{"lineNumber":355,"author":{"gitId":"-"},"content":""},{"lineNumber":356,"author":{"gitId":"-"},"content":" protected static void assertNotNull(String message, Object object) {"},{"lineNumber":357,"author":{"gitId":"-"},"content":" Assertions.assertNotNull(object, message);"},{"lineNumber":358,"author":{"gitId":"-"},"content":" }"},{"lineNumber":359,"author":{"gitId":"-"},"content":""},{"lineNumber":360,"author":{"gitId":"-"},"content":" protected static void fail(String message) {"},{"lineNumber":361,"author":{"gitId":"-"},"content":" Assertions.fail(message);"},{"lineNumber":362,"author":{"gitId":"-"},"content":" }"},{"lineNumber":363,"author":{"gitId":"-"},"content":""},{"lineNumber":364,"author":{"gitId":"-"},"content":" protected static \u003cT extends Throwable\u003e T assertThrows(Class\u003cT\u003e expectedType, Executable executable) {"},{"lineNumber":365,"author":{"gitId":"-"},"content":" return Assertions.assertThrows(expectedType, executable);"},{"lineNumber":366,"author":{"gitId":"-"},"content":" }"},{"lineNumber":367,"author":{"gitId":"-"},"content":""},{"lineNumber":368,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":19,"dishenggg":16,"mingyuanc":10,"-":323}},{"path":"src/test/java/teammates/test/BaseTestCaseWithDatabaseAccess.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.test;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.DataBundle;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountAttributes;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountRequestAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.DeadlineExtensionAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.EntityAttributes;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseAttributes;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseCommentAttributes;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.NotificationAttributes;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.common.util.JsonUtils;"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * Base class for all test cases which are allowed to access the database."},{"lineNumber":21,"author":{"gitId":"-"},"content":" */"},{"lineNumber":22,"author":{"gitId":"-"},"content":"public abstract class BaseTestCaseWithDatabaseAccess extends BaseTestCase {"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" private static final int VERIFICATION_RETRY_COUNT \u003d 5;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" private static final int VERIFICATION_RETRY_DELAY_IN_MS \u003d 1000;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" private static final int OPERATION_RETRY_COUNT \u003d 5;"},{"lineNumber":27,"author":{"gitId":"-"},"content":" private static final int OPERATION_RETRY_DELAY_IN_MS \u003d 1000;"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" protected void verifyPresentInDatabase(DataBundle data) {"},{"lineNumber":30,"author":{"gitId":"-"},"content":" data.accounts.values().forEach(this::verifyPresentInDatabase);"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" data.instructors.values().forEach(this::verifyPresentInDatabase);"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" data.courses.values().stream()"},{"lineNumber":35,"author":{"gitId":"-"},"content":" .filter(course -\u003e !course.isCourseDeleted())"},{"lineNumber":36,"author":{"gitId":"-"},"content":" .forEach(this::verifyPresentInDatabase);"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" data.students.values().forEach(this::verifyPresentInDatabase);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" protected void verifyPresentInDatabase(EntityAttributes\u003c?\u003e expected) {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" int retryLimit \u003d VERIFICATION_RETRY_COUNT;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" EntityAttributes\u003c?\u003e actual \u003d getEntity(expected);"},{"lineNumber":44,"author":{"gitId":"-"},"content":" while (actual \u003d\u003d null \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":46,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(VERIFICATION_RETRY_DELAY_IN_MS);"},{"lineNumber":47,"author":{"gitId":"-"},"content":" actual \u003d getEntity(expected);"},{"lineNumber":48,"author":{"gitId":"-"},"content":" }"},{"lineNumber":49,"author":{"gitId":"-"},"content":" verifyEquals(expected, actual);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" }"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" private EntityAttributes\u003c?\u003e getEntity(EntityAttributes\u003c?\u003e expected) {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" if (expected instanceof AccountAttributes) {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" return getAccount((AccountAttributes) expected);"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" } else if (expected instanceof CourseAttributes) {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" return getCourse((CourseAttributes) expected);"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackQuestionAttributes) {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" return getFeedbackQuestion((FeedbackQuestionAttributes) expected);"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackResponseCommentAttributes) {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" return getFeedbackResponseComment((FeedbackResponseCommentAttributes) expected);"},{"lineNumber":64,"author":{"gitId":"-"},"content":""},{"lineNumber":65,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackResponseAttributes) {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" return getFeedbackResponse((FeedbackResponseAttributes) expected);"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackSessionAttributes) {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" return getFeedbackSession((FeedbackSessionAttributes) expected);"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" } else if (expected instanceof InstructorAttributes) {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" return getInstructor((InstructorAttributes) expected);"},{"lineNumber":73,"author":{"gitId":"-"},"content":""},{"lineNumber":74,"author":{"gitId":"-"},"content":" } else if (expected instanceof StudentAttributes) {"},{"lineNumber":75,"author":{"gitId":"-"},"content":" return getStudent((StudentAttributes) expected);"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" } else if (expected instanceof AccountRequestAttributes) {"},{"lineNumber":78,"author":{"gitId":"-"},"content":" return getAccountRequest((AccountRequestAttributes) expected);"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" } else if (expected instanceof DeadlineExtensionAttributes) {"},{"lineNumber":81,"author":{"gitId":"-"},"content":" return getDeadlineExtension((DeadlineExtensionAttributes) expected);"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"-"},"content":" } else if (expected instanceof NotificationAttributes) {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" return getNotification((NotificationAttributes) expected);"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":87,"author":{"gitId":"-"},"content":" throw new RuntimeException(\"Unknown entity type!\");"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":" }"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" protected void verifyAbsentInDatabase(EntityAttributes\u003c?\u003e entity) {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" int retryLimit \u003d VERIFICATION_RETRY_COUNT;"},{"lineNumber":93,"author":{"gitId":"-"},"content":" EntityAttributes\u003c?\u003e actual \u003d getEntity(entity);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" while (actual !\u003d null \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":96,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(VERIFICATION_RETRY_DELAY_IN_MS);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" actual \u003d getEntity(entity);"},{"lineNumber":98,"author":{"gitId":"-"},"content":" }"},{"lineNumber":99,"author":{"gitId":"-"},"content":" assertNull(actual);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" }"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" private void verifyEquals(EntityAttributes\u003c?\u003e expected, EntityAttributes\u003c?\u003e actual) {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" if (expected instanceof AccountAttributes) {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" AccountAttributes expectedAccount \u003d ((AccountAttributes) expected).getCopy();"},{"lineNumber":105,"author":{"gitId":"-"},"content":" AccountAttributes actualAccount \u003d (AccountAttributes) actual;"},{"lineNumber":106,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedAccount, actualAccount);"},{"lineNumber":107,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedAccount), JsonUtils.toJson(actualAccount));"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" } else if (expected instanceof CourseAttributes) {"},{"lineNumber":110,"author":{"gitId":"-"},"content":" CourseAttributes expectedCourse \u003d (CourseAttributes) expected;"},{"lineNumber":111,"author":{"gitId":"-"},"content":" CourseAttributes actualCourse \u003d (CourseAttributes) actual;"},{"lineNumber":112,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedCourse, actualCourse);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedCourse), JsonUtils.toJson(actualCourse));"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackQuestionAttributes) {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes expectedFq \u003d (FeedbackQuestionAttributes) expected;"},{"lineNumber":117,"author":{"gitId":"-"},"content":" FeedbackQuestionAttributes actualFq \u003d (FeedbackQuestionAttributes) actual;"},{"lineNumber":118,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedFq, actualFq);"},{"lineNumber":119,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedFq), JsonUtils.toJson(actualFq));"},{"lineNumber":120,"author":{"gitId":"-"},"content":""},{"lineNumber":121,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackResponseCommentAttributes) {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" FeedbackResponseCommentAttributes expectedFrc \u003d (FeedbackResponseCommentAttributes) expected;"},{"lineNumber":123,"author":{"gitId":"-"},"content":" FeedbackResponseCommentAttributes actualFrc \u003d (FeedbackResponseCommentAttributes) actual;"},{"lineNumber":124,"author":{"gitId":"-"},"content":" assertEquals(expectedFrc.getCourseId(), actualFrc.getCourseId());"},{"lineNumber":125,"author":{"gitId":"-"},"content":" assertEquals(expectedFrc.getCommentGiver(), actualFrc.getCommentGiver());"},{"lineNumber":126,"author":{"gitId":"-"},"content":" assertEquals(expectedFrc.getFeedbackSessionName(), actualFrc.getFeedbackSessionName());"},{"lineNumber":127,"author":{"gitId":"-"},"content":" assertEquals(expectedFrc.getCommentText(), actualFrc.getCommentText());"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackResponseAttributes) {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" FeedbackResponseAttributes expectedFr \u003d (FeedbackResponseAttributes) expected;"},{"lineNumber":131,"author":{"gitId":"-"},"content":" FeedbackResponseAttributes actualFr \u003d (FeedbackResponseAttributes) actual;"},{"lineNumber":132,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedFr, actualFr);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedFr), JsonUtils.toJson(actualFr));"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackSessionAttributes) {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes expectedFs \u003d ((FeedbackSessionAttributes) expected).getCopy();"},{"lineNumber":137,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes actualFs \u003d (FeedbackSessionAttributes) actual;"},{"lineNumber":138,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedFs, actualFs);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedFs), JsonUtils.toJson(actualFs));"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" } else if (expected instanceof InstructorAttributes) {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" InstructorAttributes expectedInstructor \u003d ((InstructorAttributes) expected).getCopy();"},{"lineNumber":143,"author":{"gitId":"-"},"content":" InstructorAttributes actualInstructor \u003d (InstructorAttributes) actual;"},{"lineNumber":144,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedInstructor, actualInstructor);"},{"lineNumber":145,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedInstructor), JsonUtils.toJson(actualInstructor));"},{"lineNumber":146,"author":{"gitId":"-"},"content":""},{"lineNumber":147,"author":{"gitId":"-"},"content":" } else if (expected instanceof StudentAttributes) {"},{"lineNumber":148,"author":{"gitId":"-"},"content":" StudentAttributes expectedStudent \u003d ((StudentAttributes) expected).getCopy();"},{"lineNumber":149,"author":{"gitId":"-"},"content":" StudentAttributes actualStudent \u003d (StudentAttributes) actual;"},{"lineNumber":150,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedStudent, actualStudent);"},{"lineNumber":151,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedStudent), JsonUtils.toJson(actualStudent));"},{"lineNumber":152,"author":{"gitId":"-"},"content":""},{"lineNumber":153,"author":{"gitId":"-"},"content":" } else if (expected instanceof AccountRequestAttributes) {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" AccountRequestAttributes expectedAccountRequest \u003d (AccountRequestAttributes) expected;"},{"lineNumber":155,"author":{"gitId":"-"},"content":" AccountRequestAttributes actualAccountRequest \u003d (AccountRequestAttributes) actual;"},{"lineNumber":156,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedAccountRequest), JsonUtils.toJson(actualAccountRequest));"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"-"},"content":" } else if (expected instanceof DeadlineExtensionAttributes) {"},{"lineNumber":159,"author":{"gitId":"-"},"content":" DeadlineExtensionAttributes expectedDeadlineExtension \u003d (DeadlineExtensionAttributes) expected;"},{"lineNumber":160,"author":{"gitId":"-"},"content":" DeadlineExtensionAttributes actualDeadlineExtension \u003d (DeadlineExtensionAttributes) actual;"},{"lineNumber":161,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedDeadlineExtension, actualDeadlineExtension);"},{"lineNumber":162,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedDeadlineExtension), JsonUtils.toJson(actualDeadlineExtension));"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" } else if (expected instanceof NotificationAttributes) {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" NotificationAttributes expectedNotification \u003d (NotificationAttributes) expected;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" NotificationAttributes actualNotification \u003d (NotificationAttributes) actual;"},{"lineNumber":167,"author":{"gitId":"-"},"content":" equalizeIrrelevantData(expectedNotification, actualNotification);"},{"lineNumber":168,"author":{"gitId":"-"},"content":" assertEquals(JsonUtils.toJson(expectedNotification), JsonUtils.toJson(actualNotification));"},{"lineNumber":169,"author":{"gitId":"-"},"content":""},{"lineNumber":170,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":171,"author":{"gitId":"-"},"content":" throw new RuntimeException(\"Unknown entity type!\");"},{"lineNumber":172,"author":{"gitId":"-"},"content":" }"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" protected abstract AccountAttributes getAccount(AccountAttributes account);"},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(AccountAttributes expected, AccountAttributes actual) {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":179,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":180,"author":{"gitId":"-"},"content":" }"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(CourseAttributes expected, CourseAttributes actual) {"},{"lineNumber":183,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":184,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(FeedbackQuestionAttributes expected, FeedbackQuestionAttributes actual) {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" expected.setId(actual.getId());"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(FeedbackResponseAttributes expected, FeedbackResponseAttributes actual) {"},{"lineNumber":192,"author":{"gitId":"-"},"content":" expected.setId(actual.getId());"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(FeedbackSessionAttributes expected, FeedbackSessionAttributes actual) {"},{"lineNumber":196,"author":{"gitId":"-"},"content":" expected.setCreatedTime(actual.getCreatedTime());"},{"lineNumber":197,"author":{"gitId":"-"},"content":" // Not available in FeedbackSessionData and thus ignored"},{"lineNumber":198,"author":{"gitId":"-"},"content":" expected.setCreatorEmail(actual.getCreatorEmail());"},{"lineNumber":199,"author":{"gitId":"-"},"content":" }"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(InstructorAttributes expected, InstructorAttributes actual) {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" // pretend keys match because the key is generated only before storing into database"},{"lineNumber":203,"author":{"gitId":"-"},"content":" if (actual.getKey() !\u003d null) {"},{"lineNumber":204,"author":{"gitId":"-"},"content":" expected.setKey(actual.getKey());"},{"lineNumber":205,"author":{"gitId":"-"},"content":" }"},{"lineNumber":206,"author":{"gitId":"-"},"content":" }"},{"lineNumber":207,"author":{"gitId":"-"},"content":""},{"lineNumber":208,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(StudentAttributes expected, StudentAttributes actual) {"},{"lineNumber":209,"author":{"gitId":"-"},"content":" // For these fields, we consider null and \"\" equivalent."},{"lineNumber":210,"author":{"gitId":"-"},"content":" if (expected.getGoogleId() \u003d\u003d null \u0026\u0026 actual.getGoogleId().isEmpty()) {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" expected.setGoogleId(\"\");"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":" if (expected.getTeam() \u003d\u003d null \u0026\u0026 actual.getTeam().isEmpty()) {"},{"lineNumber":214,"author":{"gitId":"-"},"content":" expected.setTeam(\"\");"},{"lineNumber":215,"author":{"gitId":"-"},"content":" }"},{"lineNumber":216,"author":{"gitId":"-"},"content":" if (expected.getComments() \u003d\u003d null \u0026\u0026 actual.getComments().isEmpty()) {"},{"lineNumber":217,"author":{"gitId":"-"},"content":" expected.setComments(\"\");"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" // pretend keys match because the key is generated only before storing into database"},{"lineNumber":221,"author":{"gitId":"-"},"content":" if (actual.getKey() !\u003d null) {"},{"lineNumber":222,"author":{"gitId":"-"},"content":" expected.setKey(actual.getKey());"},{"lineNumber":223,"author":{"gitId":"-"},"content":" }"},{"lineNumber":224,"author":{"gitId":"-"},"content":" }"},{"lineNumber":225,"author":{"gitId":"-"},"content":""},{"lineNumber":226,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(DeadlineExtensionAttributes expected, DeadlineExtensionAttributes actual) {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":228,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":229,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":230,"author":{"gitId":"-"},"content":" }"},{"lineNumber":231,"author":{"gitId":"-"},"content":""},{"lineNumber":232,"author":{"gitId":"-"},"content":" private void equalizeIrrelevantData(NotificationAttributes expected, NotificationAttributes actual) {"},{"lineNumber":233,"author":{"gitId":"-"},"content":" // Ignore time field as it is stamped at the time of creation in testing"},{"lineNumber":234,"author":{"gitId":"-"},"content":" expected.setCreatedAt(actual.getCreatedAt());"},{"lineNumber":235,"author":{"gitId":"-"},"content":" expected.setUpdatedAt(actual.getUpdatedAt());"},{"lineNumber":236,"author":{"gitId":"-"},"content":" }"},{"lineNumber":237,"author":{"gitId":"-"},"content":""},{"lineNumber":238,"author":{"gitId":"-"},"content":" protected abstract CourseAttributes getCourse(CourseAttributes course);"},{"lineNumber":239,"author":{"gitId":"-"},"content":""},{"lineNumber":240,"author":{"gitId":"-"},"content":" protected abstract FeedbackQuestionAttributes getFeedbackQuestion(FeedbackQuestionAttributes fq);"},{"lineNumber":241,"author":{"gitId":"-"},"content":""},{"lineNumber":242,"author":{"gitId":"-"},"content":" protected abstract FeedbackResponseCommentAttributes getFeedbackResponseComment(FeedbackResponseCommentAttributes frc);"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" protected abstract FeedbackResponseAttributes getFeedbackResponse(FeedbackResponseAttributes fr);"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" protected abstract FeedbackSessionAttributes getFeedbackSession(FeedbackSessionAttributes fs);"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" protected abstract InstructorAttributes getInstructor(InstructorAttributes instructor);"},{"lineNumber":249,"author":{"gitId":"-"},"content":""},{"lineNumber":250,"author":{"gitId":"-"},"content":" protected abstract StudentAttributes getStudent(StudentAttributes student);"},{"lineNumber":251,"author":{"gitId":"-"},"content":""},{"lineNumber":252,"author":{"gitId":"-"},"content":" protected abstract AccountRequestAttributes getAccountRequest(AccountRequestAttributes accountRequest);"},{"lineNumber":253,"author":{"gitId":"-"},"content":""},{"lineNumber":254,"author":{"gitId":"-"},"content":" protected abstract DeadlineExtensionAttributes getDeadlineExtension(DeadlineExtensionAttributes accountRequest);"},{"lineNumber":255,"author":{"gitId":"-"},"content":""},{"lineNumber":256,"author":{"gitId":"-"},"content":" protected abstract NotificationAttributes getNotification(NotificationAttributes notification);"},{"lineNumber":257,"author":{"gitId":"-"},"content":""},{"lineNumber":258,"author":{"gitId":"-"},"content":" protected void removeAndRestoreDataBundle(DataBundle testData) {"},{"lineNumber":259,"author":{"gitId":"-"},"content":" int retryLimit \u003d OPERATION_RETRY_COUNT;"},{"lineNumber":260,"author":{"gitId":"-"},"content":" boolean isOperationSuccess \u003d doRemoveAndRestoreDataBundle(testData);"},{"lineNumber":261,"author":{"gitId":"-"},"content":" while (!isOperationSuccess \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":262,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":263,"author":{"gitId":"-"},"content":" print(\"Re-trying removeAndRestoreDataBundle\");"},{"lineNumber":264,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(OPERATION_RETRY_DELAY_IN_MS);"},{"lineNumber":265,"author":{"gitId":"-"},"content":" isOperationSuccess \u003d doRemoveAndRestoreDataBundle(testData);"},{"lineNumber":266,"author":{"gitId":"-"},"content":" }"},{"lineNumber":267,"author":{"gitId":"-"},"content":" assertTrue(isOperationSuccess);"},{"lineNumber":268,"author":{"gitId":"-"},"content":" }"},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":" protected abstract boolean doRemoveAndRestoreDataBundle(DataBundle testData);"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" protected SqlDataBundle removeAndRestoreSqlDataBundle(SqlDataBundle testData) {"},{"lineNumber":273,"author":{"gitId":"-"},"content":" int retryLimit \u003d OPERATION_RETRY_COUNT;"},{"lineNumber":274,"author":{"gitId":"-"},"content":" SqlDataBundle dataBundle \u003d doRemoveAndRestoreSqlDataBundle(testData);"},{"lineNumber":275,"author":{"gitId":"-"},"content":" while (dataBundle \u003d\u003d null \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":276,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":277,"author":{"gitId":"-"},"content":" print(\"Re-trying removeAndRestoreDataBundle\");"},{"lineNumber":278,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(OPERATION_RETRY_DELAY_IN_MS);"},{"lineNumber":279,"author":{"gitId":"-"},"content":" dataBundle \u003d doRemoveAndRestoreSqlDataBundle(testData);"},{"lineNumber":280,"author":{"gitId":"-"},"content":" }"},{"lineNumber":281,"author":{"gitId":"-"},"content":" assertNotNull(dataBundle);"},{"lineNumber":282,"author":{"gitId":"-"},"content":" return dataBundle;"},{"lineNumber":283,"author":{"gitId":"-"},"content":" }"},{"lineNumber":284,"author":{"gitId":"-"},"content":""},{"lineNumber":285,"author":{"gitId":"-"},"content":" protected abstract SqlDataBundle doRemoveAndRestoreSqlDataBundle(SqlDataBundle testData);"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"-"},"content":" protected void putDocuments(DataBundle testData) {"},{"lineNumber":288,"author":{"gitId":"-"},"content":" int retryLimit \u003d OPERATION_RETRY_COUNT;"},{"lineNumber":289,"author":{"gitId":"-"},"content":" boolean isOperationSuccess \u003d doPutDocuments(testData);"},{"lineNumber":290,"author":{"gitId":"-"},"content":" while (!isOperationSuccess \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":291,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":292,"author":{"gitId":"-"},"content":" print(\"Re-trying putDocuments\");"},{"lineNumber":293,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(OPERATION_RETRY_DELAY_IN_MS);"},{"lineNumber":294,"author":{"gitId":"-"},"content":" isOperationSuccess \u003d doPutDocuments(testData);"},{"lineNumber":295,"author":{"gitId":"-"},"content":" }"},{"lineNumber":296,"author":{"gitId":"-"},"content":" assertTrue(isOperationSuccess);"},{"lineNumber":297,"author":{"gitId":"-"},"content":" }"},{"lineNumber":298,"author":{"gitId":"-"},"content":""},{"lineNumber":299,"author":{"gitId":"-"},"content":" protected abstract boolean doPutDocuments(DataBundle testData);"},{"lineNumber":300,"author":{"gitId":"-"},"content":""},{"lineNumber":301,"author":{"gitId":"domoberzin"},"content":" protected void putSqlDocuments(SqlDataBundle testData) {"},{"lineNumber":302,"author":{"gitId":"domoberzin"},"content":" int retryLimit \u003d OPERATION_RETRY_COUNT;"},{"lineNumber":303,"author":{"gitId":"domoberzin"},"content":" boolean isOperationSuccess \u003d doPutDocumentsSql(testData);"},{"lineNumber":304,"author":{"gitId":"domoberzin"},"content":" while (!isOperationSuccess \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":305,"author":{"gitId":"domoberzin"},"content":" retryLimit--;"},{"lineNumber":306,"author":{"gitId":"domoberzin"},"content":" print(\"Re-trying putSqlDocuments\");"},{"lineNumber":307,"author":{"gitId":"domoberzin"},"content":" ThreadHelper.waitFor(OPERATION_RETRY_DELAY_IN_MS);"},{"lineNumber":308,"author":{"gitId":"domoberzin"},"content":" isOperationSuccess \u003d doPutDocumentsSql(testData);"},{"lineNumber":309,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":310,"author":{"gitId":"domoberzin"},"content":" assertTrue(isOperationSuccess);"},{"lineNumber":311,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":312,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":313,"author":{"gitId":"domoberzin"},"content":" protected abstract boolean doPutDocumentsSql(SqlDataBundle testData);"},{"lineNumber":314,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":13,"-":301}},{"path":"src/test/java/teammates/test/BaseTestCaseWithLocalDatabaseAccess.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.test;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import org.testcontainers.containers.PostgreSQLContainer;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterClass;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterMethod;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.AfterSuite;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeClass;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeMethod;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import org.testng.annotations.BeforeSuite;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"import com.google.cloud.datastore.DatastoreOptions;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import com.google.cloud.datastore.testing.LocalDatastoreHelper;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import com.googlecode.objectify.ObjectifyFactory;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import com.googlecode.objectify.ObjectifyService;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import com.googlecode.objectify.util.Closeable;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.DataBundle;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountAttributes;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.AccountRequestAttributes;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.DeadlineExtensionAttributes;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackQuestionAttributes;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseAttributes;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackResponseCommentAttributes;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.NotificationAttributes;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.common.util.HibernateUtil;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import teammates.logic.api.LogicExtension;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import teammates.logic.core.LogicStarter;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import teammates.sqllogic.api.Logic;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import teammates.storage.api.OfyHelper;"},{"lineNumber":36,"author":{"gitId":"-"},"content":"import teammates.storage.search.AccountRequestSearchManager;"},{"lineNumber":37,"author":{"gitId":"-"},"content":"import teammates.storage.search.InstructorSearchManager;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import teammates.storage.search.SearchManagerFactory;"},{"lineNumber":39,"author":{"gitId":"-"},"content":"import teammates.storage.search.StudentSearchManager;"},{"lineNumber":40,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":43,"author":{"gitId":"-"},"content":" * Base class for all tests which require access to a locally run database."},{"lineNumber":44,"author":{"gitId":"-"},"content":" *"},{"lineNumber":45,"author":{"gitId":"-"},"content":" * \u003cp\u003eAs all tests are run against a single DB instance and we use shared test data for most tests,"},{"lineNumber":46,"author":{"gitId":"-"},"content":" * the tests need to be run in a single thread to prevent test data contamination across different tests."},{"lineNumber":47,"author":{"gitId":"-"},"content":" */"},{"lineNumber":48,"author":{"gitId":"-"},"content":"@Test(singleThreaded \u003d true)"},{"lineNumber":49,"author":{"gitId":"-"},"content":"public abstract class BaseTestCaseWithLocalDatabaseAccess extends BaseTestCaseWithDatabaseAccess {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" private static final PostgreSQLContainer\u003c?\u003e PGSQL \u003d new PostgreSQLContainer\u003c\u003e(\"postgres:15.1-alpine\");"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" private static final LocalDatastoreHelper LOCAL_DATASTORE_HELPER \u003d LocalDatastoreHelper.newBuilder()"},{"lineNumber":53,"author":{"gitId":"-"},"content":" .setConsistency(1.0)"},{"lineNumber":54,"author":{"gitId":"-"},"content":" .setPort(TestProperties.TEST_LOCALDATASTORE_PORT)"},{"lineNumber":55,"author":{"gitId":"-"},"content":" .setStoreOnDisk(false)"},{"lineNumber":56,"author":{"gitId":"-"},"content":" .build();"},{"lineNumber":57,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":58,"author":{"gitId":"-"},"content":" * sqlLogic for use in test cases."},{"lineNumber":59,"author":{"gitId":"-"},"content":" */"},{"lineNumber":60,"author":{"gitId":"-"},"content":" protected Logic sqlLogic;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" private final LogicExtension logic \u003d new LogicExtension();"},{"lineNumber":62,"author":{"gitId":"-"},"content":" private Closeable closeable;"},{"lineNumber":63,"author":{"gitId":"-"},"content":""},{"lineNumber":64,"author":{"gitId":"-"},"content":" @BeforeSuite"},{"lineNumber":65,"author":{"gitId":"-"},"content":" public void setupDbLayer() throws Exception {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" PGSQL.start();"},{"lineNumber":67,"author":{"gitId":"-"},"content":" HibernateUtil.buildSessionFactory(PGSQL.getJdbcUrl(), PGSQL.getUsername(), PGSQL.getPassword());"},{"lineNumber":68,"author":{"gitId":"-"},"content":" teammates.sqllogic.core.LogicStarter.initializeDependencies();"},{"lineNumber":69,"author":{"gitId":"-"},"content":" sqlLogic \u003d Logic.inst();"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" LOCAL_DATASTORE_HELPER.start();"},{"lineNumber":72,"author":{"gitId":"-"},"content":" DatastoreOptions options \u003d LOCAL_DATASTORE_HELPER.getOptions();"},{"lineNumber":73,"author":{"gitId":"-"},"content":" ObjectifyService.init(new ObjectifyFactory("},{"lineNumber":74,"author":{"gitId":"-"},"content":" options.getService()"},{"lineNumber":75,"author":{"gitId":"-"},"content":" ));"},{"lineNumber":76,"author":{"gitId":"-"},"content":" OfyHelper.registerEntityClasses();"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" SearchManagerFactory.registerAccountRequestSearchManager("},{"lineNumber":79,"author":{"gitId":"-"},"content":" new AccountRequestSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":80,"author":{"gitId":"-"},"content":" SearchManagerFactory.registerInstructorSearchManager("},{"lineNumber":81,"author":{"gitId":"-"},"content":" new InstructorSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":82,"author":{"gitId":"-"},"content":" SearchManagerFactory.registerStudentSearchManager("},{"lineNumber":83,"author":{"gitId":"-"},"content":" new StudentSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":84,"author":{"gitId":"-"},"content":""},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" teammates.storage.sqlsearch.SearchManagerFactory.registerAccountRequestSearchManager("},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":" new teammates.storage.sqlsearch.AccountRequestSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" teammates.storage.sqlsearch.SearchManagerFactory.registerInstructorSearchManager("},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" new teammates.storage.sqlsearch.InstructorSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" teammates.storage.sqlsearch.SearchManagerFactory.registerStudentSearchManager("},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" new teammates.storage.sqlsearch.StudentSearchManager(TestProperties.SEARCH_SERVICE_HOST, true));"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":92,"author":{"gitId":"-"},"content":" LogicStarter.initializeDependencies();"},{"lineNumber":93,"author":{"gitId":"-"},"content":" }"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" @BeforeClass"},{"lineNumber":96,"author":{"gitId":"-"},"content":" public void setupObjectify() {"},{"lineNumber":97,"author":{"gitId":"-"},"content":" closeable \u003d ObjectifyService.begin();"},{"lineNumber":98,"author":{"gitId":"-"},"content":" }"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":101,"author":{"gitId":"-"},"content":" public void tearDownObjectify() {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" closeable.close();"},{"lineNumber":103,"author":{"gitId":"-"},"content":" }"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" @AfterClass"},{"lineNumber":106,"author":{"gitId":"-"},"content":" public void resetDbLayer() throws Exception {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" SearchManagerFactory.getAccountRequestSearchManager().resetCollections();"},{"lineNumber":108,"author":{"gitId":"-"},"content":" SearchManagerFactory.getInstructorSearchManager().resetCollections();"},{"lineNumber":109,"author":{"gitId":"-"},"content":" SearchManagerFactory.getStudentSearchManager().resetCollections();"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" LOCAL_DATASTORE_HELPER.reset();"},{"lineNumber":112,"author":{"gitId":"-"},"content":" }"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"-"},"content":" @AfterSuite"},{"lineNumber":115,"author":{"gitId":"-"},"content":" public void tearDownLocalDatastoreHelper() throws Exception {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" PGSQL.close();"},{"lineNumber":117,"author":{"gitId":"-"},"content":" LOCAL_DATASTORE_HELPER.stop();"},{"lineNumber":118,"author":{"gitId":"-"},"content":" }"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" @BeforeMethod"},{"lineNumber":121,"author":{"gitId":"-"},"content":" protected void setUp() throws Exception {"},{"lineNumber":122,"author":{"gitId":"-"},"content":" HibernateUtil.beginTransaction();"},{"lineNumber":123,"author":{"gitId":"-"},"content":" }"},{"lineNumber":124,"author":{"gitId":"-"},"content":""},{"lineNumber":125,"author":{"gitId":"-"},"content":" @AfterMethod"},{"lineNumber":126,"author":{"gitId":"-"},"content":" protected void tearDown() {"},{"lineNumber":127,"author":{"gitId":"-"},"content":" HibernateUtil.rollbackTransaction();"},{"lineNumber":128,"author":{"gitId":"-"},"content":" }"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":131,"author":{"gitId":"-"},"content":" protected AccountAttributes getAccount(AccountAttributes account) {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" return logic.getAccount(account.getGoogleId());"},{"lineNumber":133,"author":{"gitId":"-"},"content":" }"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":136,"author":{"gitId":"-"},"content":" protected CourseAttributes getCourse(CourseAttributes course) {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" return logic.getCourse(course.getId());"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":141,"author":{"gitId":"-"},"content":" protected FeedbackQuestionAttributes getFeedbackQuestion(FeedbackQuestionAttributes fq) {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" return logic.getFeedbackQuestion(fq.getFeedbackSessionName(), fq.getCourseId(), fq.getQuestionNumber());"},{"lineNumber":143,"author":{"gitId":"-"},"content":" }"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":146,"author":{"gitId":"-"},"content":" protected FeedbackResponseCommentAttributes getFeedbackResponseComment(FeedbackResponseCommentAttributes frc) {"},{"lineNumber":147,"author":{"gitId":"-"},"content":" return logic.getFeedbackResponseComment(frc.getFeedbackResponseId(), frc.getCommentGiver(), frc.getCreatedAt());"},{"lineNumber":148,"author":{"gitId":"-"},"content":" }"},{"lineNumber":149,"author":{"gitId":"-"},"content":""},{"lineNumber":150,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":151,"author":{"gitId":"-"},"content":" protected FeedbackResponseAttributes getFeedbackResponse(FeedbackResponseAttributes fr) {"},{"lineNumber":152,"author":{"gitId":"-"},"content":" return logic.getFeedbackResponse(fr.getFeedbackQuestionId(), fr.getGiver(), fr.getRecipient());"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":156,"author":{"gitId":"-"},"content":" protected FeedbackSessionAttributes getFeedbackSession(FeedbackSessionAttributes fs) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" return logic.getFeedbackSession(fs.getFeedbackSessionName(), fs.getCourseId());"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":161,"author":{"gitId":"-"},"content":" protected InstructorAttributes getInstructor(InstructorAttributes instructor) {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" return instructor.getGoogleId() \u003d\u003d null"},{"lineNumber":163,"author":{"gitId":"-"},"content":" ? logic.getInstructorForEmail(instructor.getCourseId(), instructor.getEmail())"},{"lineNumber":164,"author":{"gitId":"-"},"content":" : logic.getInstructorForGoogleId(instructor.getCourseId(), instructor.getGoogleId());"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":168,"author":{"gitId":"-"},"content":" protected StudentAttributes getStudent(StudentAttributes student) {"},{"lineNumber":169,"author":{"gitId":"-"},"content":" return logic.getStudentForEmail(student.getCourse(), student.getEmail());"},{"lineNumber":170,"author":{"gitId":"-"},"content":" }"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":173,"author":{"gitId":"-"},"content":" protected AccountRequestAttributes getAccountRequest(AccountRequestAttributes accountRequest) {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" return logic.getAccountRequest(accountRequest.getEmail(), accountRequest.getInstitute());"},{"lineNumber":175,"author":{"gitId":"-"},"content":" }"},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":178,"author":{"gitId":"-"},"content":" protected DeadlineExtensionAttributes getDeadlineExtension(DeadlineExtensionAttributes deadlineExtension) {"},{"lineNumber":179,"author":{"gitId":"-"},"content":" return logic.getDeadlineExtension("},{"lineNumber":180,"author":{"gitId":"-"},"content":" deadlineExtension.getCourseId(), deadlineExtension.getFeedbackSessionName(),"},{"lineNumber":181,"author":{"gitId":"-"},"content":" deadlineExtension.getUserEmail(), deadlineExtension.getIsInstructor());"},{"lineNumber":182,"author":{"gitId":"-"},"content":" }"},{"lineNumber":183,"author":{"gitId":"-"},"content":""},{"lineNumber":184,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":185,"author":{"gitId":"-"},"content":" protected NotificationAttributes getNotification(NotificationAttributes notification) {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" return logic.getNotification(notification.getNotificationId());"},{"lineNumber":187,"author":{"gitId":"-"},"content":" }"},{"lineNumber":188,"author":{"gitId":"-"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":" protected void removeAndRestoreTypicalDataBundle() {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" DataBundle dataBundle \u003d getTypicalDataBundle();"},{"lineNumber":191,"author":{"gitId":"-"},"content":" removeAndRestoreDataBundle(dataBundle);"},{"lineNumber":192,"author":{"gitId":"-"},"content":" }"},{"lineNumber":193,"author":{"gitId":"-"},"content":""},{"lineNumber":194,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":195,"author":{"gitId":"-"},"content":" protected boolean doRemoveAndRestoreDataBundle(DataBundle dataBundle) {"},{"lineNumber":196,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" logic.removeDataBundle(dataBundle);"},{"lineNumber":198,"author":{"gitId":"-"},"content":" logic.persistDataBundle(dataBundle);"},{"lineNumber":199,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":200,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":201,"author":{"gitId":"-"},"content":" e.printStackTrace();"},{"lineNumber":202,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":203,"author":{"gitId":"-"},"content":" }"},{"lineNumber":204,"author":{"gitId":"-"},"content":" }"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":207,"author":{"gitId":"-"},"content":" protected SqlDataBundle doRemoveAndRestoreSqlDataBundle(SqlDataBundle dataBundle) {"},{"lineNumber":208,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":209,"author":{"gitId":"-"},"content":" sqlLogic.removeDataBundle(dataBundle);"},{"lineNumber":210,"author":{"gitId":"-"},"content":" return sqlLogic.persistDataBundle(dataBundle);"},{"lineNumber":211,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" e.printStackTrace();"},{"lineNumber":213,"author":{"gitId":"-"},"content":" return null;"},{"lineNumber":214,"author":{"gitId":"-"},"content":" }"},{"lineNumber":215,"author":{"gitId":"-"},"content":" }"},{"lineNumber":216,"author":{"gitId":"-"},"content":""},{"lineNumber":217,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":218,"author":{"gitId":"-"},"content":" protected boolean doPutDocuments(DataBundle dataBundle) {"},{"lineNumber":219,"author":{"gitId":"-"},"content":" try {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" logic.putDocuments(dataBundle);"},{"lineNumber":221,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":222,"author":{"gitId":"-"},"content":" } catch (Exception e) {"},{"lineNumber":223,"author":{"gitId":"-"},"content":" e.printStackTrace();"},{"lineNumber":224,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":225,"author":{"gitId":"-"},"content":" }"},{"lineNumber":226,"author":{"gitId":"-"},"content":" }"},{"lineNumber":227,"author":{"gitId":"-"},"content":""},{"lineNumber":228,"author":{"gitId":"domoberzin"},"content":" @Override"},{"lineNumber":229,"author":{"gitId":"domoberzin"},"content":" protected boolean doPutDocumentsSql(SqlDataBundle dataBundle) {"},{"lineNumber":230,"author":{"gitId":"domoberzin"},"content":" try {"},{"lineNumber":231,"author":{"gitId":"domoberzin"},"content":" sqlLogic.putDocuments(dataBundle);"},{"lineNumber":232,"author":{"gitId":"domoberzin"},"content":" return true;"},{"lineNumber":233,"author":{"gitId":"domoberzin"},"content":" } catch (Exception e) {"},{"lineNumber":234,"author":{"gitId":"domoberzin"},"content":" e.printStackTrace();"},{"lineNumber":235,"author":{"gitId":"domoberzin"},"content":" return false;"},{"lineNumber":236,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":237,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":238,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":239,"author":{"gitId":"-"},"content":" protected Account getAccountFromDatabase(String googleId) {"},{"lineNumber":240,"author":{"gitId":"-"},"content":" return sqlLogic.getAccountForGoogleId(googleId);"},{"lineNumber":241,"author":{"gitId":"-"},"content":" }"},{"lineNumber":242,"author":{"gitId":"-"},"content":""},{"lineNumber":243,"author":{"gitId":"-"},"content":" protected void clearObjectifyCache() {"},{"lineNumber":244,"author":{"gitId":"-"},"content":" ObjectifyService.ofy().clear();"},{"lineNumber":245,"author":{"gitId":"-"},"content":" }"},{"lineNumber":246,"author":{"gitId":"-"},"content":""},{"lineNumber":247,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":18,"-":229}},{"path":"src/test/java/teammates/test/BaseTestCaseWithSqlDatabaseAccess.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.test;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.SqlDataBundle;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackQuestionDetails;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.questions.FeedbackResponseDetails;"},{"lineNumber":6,"author":{"gitId":"dishenggg"},"content":"import teammates.common.util.Const;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Account;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.BaseEntity;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Course;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.DeadlineExtension;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackQuestion;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponse;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackResponseComment;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.FeedbackSession;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Instructor;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Notification;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.Student;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import teammates.storage.sqlentity.UsageStatistics;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import teammates.ui.output.AccountData;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import teammates.ui.output.ApiOutput;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import teammates.ui.output.CourseData;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import teammates.ui.output.DeadlineExtensionData;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackQuestionData;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackResponseCommentData;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackResponseData;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionData;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import teammates.ui.output.InstructorData;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import teammates.ui.output.NotificationData;"},{"lineNumber":29,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.output.NumberOfEntitiesToGiveFeedbackToSetting;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import teammates.ui.output.StudentData;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import teammates.ui.output.UsageStatisticsData;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":34,"author":{"gitId":"-"},"content":" * Base class for all test cases which are allowed to access the database."},{"lineNumber":35,"author":{"gitId":"-"},"content":" */"},{"lineNumber":36,"author":{"gitId":"-"},"content":"public abstract class BaseTestCaseWithSqlDatabaseAccess extends BaseTestCase {"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" private static final int VERIFICATION_RETRY_COUNT \u003d 5;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" private static final int VERIFICATION_RETRY_DELAY_IN_MS \u003d 1000;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" private static final int OPERATION_RETRY_COUNT \u003d 5;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" private static final int OPERATION_RETRY_DELAY_IN_MS \u003d 1000;"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":44,"author":{"gitId":"-"},"content":" * Removes and restores the databundle, with retries."},{"lineNumber":45,"author":{"gitId":"-"},"content":" */"},{"lineNumber":46,"author":{"gitId":"-"},"content":" protected SqlDataBundle removeAndRestoreDataBundle(SqlDataBundle testData) {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" int retryLimit \u003d OPERATION_RETRY_COUNT;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" SqlDataBundle dataBundle \u003d doRemoveAndRestoreDataBundle(testData);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" while (dataBundle \u003d\u003d null \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":50,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" print(\"Re-trying removeAndRestoreDataBundle\");"},{"lineNumber":52,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(OPERATION_RETRY_DELAY_IN_MS);"},{"lineNumber":53,"author":{"gitId":"-"},"content":" dataBundle \u003d doRemoveAndRestoreDataBundle(testData);"},{"lineNumber":54,"author":{"gitId":"-"},"content":" }"},{"lineNumber":55,"author":{"gitId":"-"},"content":" assertNotNull(dataBundle);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" return dataBundle;"},{"lineNumber":57,"author":{"gitId":"-"},"content":" }"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" protected abstract SqlDataBundle doRemoveAndRestoreDataBundle(SqlDataBundle testData);"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":62,"author":{"gitId":"-"},"content":" * Verifies that two entities are equal."},{"lineNumber":63,"author":{"gitId":"-"},"content":" */"},{"lineNumber":64,"author":{"gitId":"-"},"content":" protected void verifyEquals(BaseEntity expected, ApiOutput actual) {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" if (expected instanceof FeedbackQuestion) {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" FeedbackQuestion expectedQuestion \u003d (FeedbackQuestion) expected;"},{"lineNumber":67,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails expectedQuestionDetails \u003d expectedQuestion.getQuestionDetailsCopy();"},{"lineNumber":68,"author":{"gitId":"-"},"content":" FeedbackQuestionData actualQuestion \u003d (FeedbackQuestionData) actual;"},{"lineNumber":69,"author":{"gitId":"-"},"content":" FeedbackQuestionDetails actualQuestionDetails \u003d actualQuestion.getQuestionDetails();"},{"lineNumber":70,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestion.getQuestionNumber(), (Integer) actualQuestion.getQuestionNumber());"},{"lineNumber":71,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestion.getDescription(), actualQuestion.getQuestionDescription());"},{"lineNumber":72,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestion.getGiverType(), actualQuestion.getGiverType());"},{"lineNumber":73,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestion.getRecipientType(), actualQuestion.getRecipientType());"},{"lineNumber":74,"author":{"gitId":"dishenggg"},"content":" if (expectedQuestion.getNumOfEntitiesToGiveFeedbackTo() \u003d\u003d Const.MAX_POSSIBLE_RECIPIENTS) {"},{"lineNumber":75,"author":{"gitId":"dishenggg"},"content":" assertEquals(actualQuestion.getNumberOfEntitiesToGiveFeedbackToSetting(),"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" NumberOfEntitiesToGiveFeedbackToSetting.UNLIMITED);"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" assertNull(actualQuestion.getCustomNumberOfEntitiesToGiveFeedbackTo());"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":79,"author":{"gitId":"dishenggg"},"content":" assertEquals(actualQuestion.getNumberOfEntitiesToGiveFeedbackToSetting(),"},{"lineNumber":80,"author":{"gitId":"dishenggg"},"content":" NumberOfEntitiesToGiveFeedbackToSetting.CUSTOM);"},{"lineNumber":81,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestion.getNumOfEntitiesToGiveFeedbackTo(),"},{"lineNumber":82,"author":{"gitId":"-"},"content":" actualQuestion.getCustomNumberOfEntitiesToGiveFeedbackTo());"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":84,"author":{"gitId":"-"},"content":" assertEquals(expectedQuestionDetails.getJsonString(), actualQuestionDetails.getJsonString());"},{"lineNumber":85,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackResponse) {"},{"lineNumber":86,"author":{"gitId":"-"},"content":" FeedbackResponse expectedFeedbackResponse \u003d (FeedbackResponse) expected;"},{"lineNumber":87,"author":{"gitId":"-"},"content":" FeedbackResponseDetails expectedResponseDetails \u003d"},{"lineNumber":88,"author":{"gitId":"-"},"content":" expectedFeedbackResponse.getFeedbackResponseDetailsCopy();"},{"lineNumber":89,"author":{"gitId":"-"},"content":" FeedbackResponseData actualResponse \u003d (FeedbackResponseData) actual;"},{"lineNumber":90,"author":{"gitId":"-"},"content":" FeedbackResponseDetails actualResponseDetails \u003d actualResponse.getResponseDetails();"},{"lineNumber":91,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackResponse.getGiver(), actualResponse.getGiverIdentifier());"},{"lineNumber":92,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackResponse.getRecipient(), actualResponse.getRecipientIdentifier());"},{"lineNumber":93,"author":{"gitId":"-"},"content":" assertEquals(expectedResponseDetails.getAnswerString(),"},{"lineNumber":94,"author":{"gitId":"-"},"content":" actualResponse.getResponseDetails().getAnswerString());"},{"lineNumber":95,"author":{"gitId":"-"},"content":" assertEquals(expectedResponseDetails.getQuestionType(),"},{"lineNumber":96,"author":{"gitId":"-"},"content":" actualResponse.getResponseDetails().getQuestionType());"},{"lineNumber":97,"author":{"gitId":"-"},"content":" assertEquals(expectedResponseDetails.getJsonString(), actualResponseDetails.getJsonString());"},{"lineNumber":98,"author":{"gitId":"-"},"content":" } else if (expected instanceof Account) {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" Account expectedAccount \u003d (Account) expected;"},{"lineNumber":100,"author":{"gitId":"-"},"content":" AccountData actualAccount \u003d (AccountData) actual;"},{"lineNumber":101,"author":{"gitId":"-"},"content":" assertEquals(expectedAccount.getGoogleId(), actualAccount.getGoogleId());"},{"lineNumber":102,"author":{"gitId":"-"},"content":" assertEquals(expectedAccount.getName(), actualAccount.getName());"},{"lineNumber":103,"author":{"gitId":"-"},"content":" assertEquals(expectedAccount.getEmail(), actualAccount.getEmail());"},{"lineNumber":104,"author":{"gitId":"-"},"content":" } else if (expected instanceof Course) {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" Course expectedCourse \u003d (Course) expected;"},{"lineNumber":106,"author":{"gitId":"-"},"content":" CourseData actualCourse \u003d (CourseData) actual;"},{"lineNumber":107,"author":{"gitId":"-"},"content":" assertEquals(expectedCourse.getName(), actualCourse.getCourseName());"},{"lineNumber":108,"author":{"gitId":"-"},"content":" assertEquals(expectedCourse.getTimeZone(), actualCourse.getTimeZone());"},{"lineNumber":109,"author":{"gitId":"-"},"content":" assertEquals(expectedCourse.getInstitute(), actualCourse.getInstitute());"},{"lineNumber":110,"author":{"gitId":"-"},"content":" } else if (expected instanceof DeadlineExtension) {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" DeadlineExtension expectedDeadlineExtension \u003d (DeadlineExtension) expected;"},{"lineNumber":112,"author":{"gitId":"-"},"content":" DeadlineExtensionData actualDeadlineExtension \u003d (DeadlineExtensionData) actual;"},{"lineNumber":113,"author":{"gitId":"-"},"content":" assertEquals(expectedDeadlineExtension.getEndTime().toEpochMilli(), actualDeadlineExtension.getEndTime());"},{"lineNumber":114,"author":{"gitId":"-"},"content":" assertEquals(expectedDeadlineExtension.isClosingSoonEmailSent(),"},{"lineNumber":115,"author":{"gitId":"-"},"content":" actualDeadlineExtension.getSentClosingEmail());"},{"lineNumber":116,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackResponseComment) {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" FeedbackResponseComment expectedFeedbackResponseComment \u003d (FeedbackResponseComment) expected;"},{"lineNumber":118,"author":{"gitId":"-"},"content":" FeedbackResponseCommentData actualComment \u003d (FeedbackResponseCommentData) actual;"},{"lineNumber":119,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackResponseComment.getGiver(), actualComment.getCommentGiver());"},{"lineNumber":120,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackResponseComment.getCommentText(), actualComment.getCommentText());"},{"lineNumber":121,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackResponseComment.getIsVisibilityFollowingFeedbackQuestion(),"},{"lineNumber":122,"author":{"gitId":"-"},"content":" actualComment.isVisibilityFollowingFeedbackQuestion());"},{"lineNumber":123,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackResponseComment.getLastEditorEmail(), actualComment.getLastEditorEmail());"},{"lineNumber":124,"author":{"gitId":"-"},"content":" } else if (expected instanceof FeedbackSession) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" FeedbackSession expectedFeedbackSession \u003d (FeedbackSession) expected;"},{"lineNumber":126,"author":{"gitId":"-"},"content":" FeedbackSessionData actualFeedbackSession \u003d (FeedbackSessionData) actual;"},{"lineNumber":127,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackSession.getName(), actualFeedbackSession.getFeedbackSessionName());"},{"lineNumber":128,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackSession.getInstructions(), actualFeedbackSession.getInstructions());"},{"lineNumber":129,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackSession.getStartTime().toEpochMilli(),"},{"lineNumber":130,"author":{"gitId":"-"},"content":" actualFeedbackSession.getSubmissionStartTimestamp());"},{"lineNumber":131,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackSession.getEndTime().toEpochMilli(),"},{"lineNumber":132,"author":{"gitId":"-"},"content":" actualFeedbackSession.getSubmissionEndTimestamp());"},{"lineNumber":133,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackSession.getSessionVisibleFromTime().toEpochMilli(),"},{"lineNumber":134,"author":{"gitId":"-"},"content":" actualFeedbackSession.getSessionVisibleFromTimestamp().longValue());"},{"lineNumber":135,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackSession.getResultsVisibleFromTime().toEpochMilli(),"},{"lineNumber":136,"author":{"gitId":"-"},"content":" actualFeedbackSession.getResultVisibleFromTimestamp().longValue());"},{"lineNumber":137,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackSession.getGracePeriod().toMinutes(),"},{"lineNumber":138,"author":{"gitId":"-"},"content":" actualFeedbackSession.getGracePeriod().longValue());"},{"lineNumber":139,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackSession.isClosingEmailEnabled(),"},{"lineNumber":140,"author":{"gitId":"-"},"content":" actualFeedbackSession.getIsClosingEmailEnabled());"},{"lineNumber":141,"author":{"gitId":"-"},"content":" assertEquals(expectedFeedbackSession.isPublishedEmailEnabled(),"},{"lineNumber":142,"author":{"gitId":"-"},"content":" actualFeedbackSession.getIsPublishedEmailEnabled());"},{"lineNumber":143,"author":{"gitId":"-"},"content":" } else if (expected instanceof Instructor) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" Instructor expectedInstructor \u003d (Instructor) expected;"},{"lineNumber":145,"author":{"gitId":"-"},"content":" InstructorData actualInstructor \u003d (InstructorData) actual;"},{"lineNumber":146,"author":{"gitId":"-"},"content":" assertEquals(expectedInstructor.getCourseId(), actualInstructor.getCourseId());"},{"lineNumber":147,"author":{"gitId":"-"},"content":" assertEquals(expectedInstructor.getName(), actualInstructor.getName());"},{"lineNumber":148,"author":{"gitId":"-"},"content":" assertEquals(expectedInstructor.getEmail(), actualInstructor.getEmail());"},{"lineNumber":149,"author":{"gitId":"-"},"content":" assertEquals(expectedInstructor.getRegKey(), actualInstructor.getKey());"},{"lineNumber":150,"author":{"gitId":"-"},"content":" assertEquals(expectedInstructor.isDisplayedToStudents(), actualInstructor.getIsDisplayedToStudents());"},{"lineNumber":151,"author":{"gitId":"-"},"content":" assertEquals(expectedInstructor.getDisplayName(), actualInstructor.getDisplayedToStudentsAs());"},{"lineNumber":152,"author":{"gitId":"-"},"content":" assertEquals(expectedInstructor.getRole(), actualInstructor.getRole());"},{"lineNumber":153,"author":{"gitId":"-"},"content":" } else if (expected instanceof Notification) {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" Notification expectedNotification \u003d (Notification) expected;"},{"lineNumber":155,"author":{"gitId":"-"},"content":" NotificationData actualNotification \u003d (NotificationData) actual;"},{"lineNumber":156,"author":{"gitId":"-"},"content":" assertEquals(expectedNotification.getStartTime().toEpochMilli(), actualNotification.getStartTimestamp());"},{"lineNumber":157,"author":{"gitId":"-"},"content":" assertEquals(expectedNotification.getEndTime().toEpochMilli(), actualNotification.getEndTimestamp());"},{"lineNumber":158,"author":{"gitId":"-"},"content":" assertEquals(expectedNotification.getStyle(), actualNotification.getStyle());"},{"lineNumber":159,"author":{"gitId":"-"},"content":" assertEquals(expectedNotification.getTargetUser(), actualNotification.getTargetUser());"},{"lineNumber":160,"author":{"gitId":"-"},"content":" assertEquals(expectedNotification.getTitle(), actualNotification.getTitle());"},{"lineNumber":161,"author":{"gitId":"-"},"content":" assertEquals(expectedNotification.getMessage(), actualNotification.getMessage());"},{"lineNumber":162,"author":{"gitId":"-"},"content":" assertEquals(expectedNotification.isShown(), actualNotification.isShown());"},{"lineNumber":163,"author":{"gitId":"-"},"content":" } else if (expected instanceof Student) {"},{"lineNumber":164,"author":{"gitId":"-"},"content":" Student expectedStudent \u003d (Student) expected;"},{"lineNumber":165,"author":{"gitId":"-"},"content":" StudentData actualStudent \u003d (StudentData) actual;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" assertEquals(expectedStudent.getCourseId(), actualStudent.getCourseId());"},{"lineNumber":167,"author":{"gitId":"-"},"content":" assertEquals(expectedStudent.getName(), actualStudent.getName());"},{"lineNumber":168,"author":{"gitId":"-"},"content":" assertEquals(expectedStudent.getEmail(), actualStudent.getEmail());"},{"lineNumber":169,"author":{"gitId":"-"},"content":" assertEquals(expectedStudent.getRegKey(), actualStudent.getKey());"},{"lineNumber":170,"author":{"gitId":"-"},"content":" assertEquals(expectedStudent.getComments(), actualStudent.getComments());"},{"lineNumber":171,"author":{"gitId":"-"},"content":" // TODO: A student might not have a team or section."},{"lineNumber":172,"author":{"gitId":"-"},"content":" // assertEquals(expectedStudent.getTeamName(), actualStudent.getTeamName());"},{"lineNumber":173,"author":{"gitId":"-"},"content":" // assertEquals(expectedStudent.getSectionName(), actualStudent.getSectionName());"},{"lineNumber":174,"author":{"gitId":"-"},"content":" } else if (expected instanceof UsageStatistics) {"},{"lineNumber":175,"author":{"gitId":"-"},"content":" UsageStatistics expectedUsageStatistics \u003d (UsageStatistics) expected;"},{"lineNumber":176,"author":{"gitId":"-"},"content":" UsageStatisticsData actualUsageStatistics \u003d (UsageStatisticsData) actual;"},{"lineNumber":177,"author":{"gitId":"-"},"content":" assertEquals(expectedUsageStatistics.getStartTime().toEpochMilli(), actualUsageStatistics.getStartTime());"},{"lineNumber":178,"author":{"gitId":"-"},"content":" assertEquals(expectedUsageStatistics.getTimePeriod(), actualUsageStatistics.getTimePeriod());"},{"lineNumber":179,"author":{"gitId":"-"},"content":" assertEquals(expectedUsageStatistics.getNumResponses(), actualUsageStatistics.getNumResponses());"},{"lineNumber":180,"author":{"gitId":"-"},"content":" assertEquals(expectedUsageStatistics.getNumCourses(), actualUsageStatistics.getNumCourses());"},{"lineNumber":181,"author":{"gitId":"-"},"content":" assertEquals(expectedUsageStatistics.getNumStudents(), actualUsageStatistics.getNumStudents());"},{"lineNumber":182,"author":{"gitId":"-"},"content":" assertEquals(expectedUsageStatistics.getNumInstructors(), actualUsageStatistics.getNumInstructors());"},{"lineNumber":183,"author":{"gitId":"-"},"content":" assertEquals(expectedUsageStatistics.getNumAccountRequests(),"},{"lineNumber":184,"author":{"gitId":"-"},"content":" actualUsageStatistics.getNumAccountRequests());"},{"lineNumber":185,"author":{"gitId":"-"},"content":" assertEquals(expectedUsageStatistics.getNumEmails(), actualUsageStatistics.getNumEmails());"},{"lineNumber":186,"author":{"gitId":"-"},"content":" assertEquals(expectedUsageStatistics.getNumSubmissions(), actualUsageStatistics.getNumSubmissions());"},{"lineNumber":187,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" fail(\"Unknown entity\");"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":" }"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":193,"author":{"gitId":"-"},"content":" * Verifies that the given entity is present in the database."},{"lineNumber":194,"author":{"gitId":"-"},"content":" */"},{"lineNumber":195,"author":{"gitId":"-"},"content":" protected void verifyPresentInDatabase(BaseEntity expected) {"},{"lineNumber":196,"author":{"gitId":"-"},"content":" int retryLimit \u003d VERIFICATION_RETRY_COUNT;"},{"lineNumber":197,"author":{"gitId":"-"},"content":" ApiOutput actual \u003d getEntity(expected);"},{"lineNumber":198,"author":{"gitId":"-"},"content":" while (actual \u003d\u003d null \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":199,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":200,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(VERIFICATION_RETRY_DELAY_IN_MS);"},{"lineNumber":201,"author":{"gitId":"-"},"content":" actual \u003d getEntity(expected);"},{"lineNumber":202,"author":{"gitId":"-"},"content":" }"},{"lineNumber":203,"author":{"gitId":"-"},"content":" verifyEquals(expected, actual);"},{"lineNumber":204,"author":{"gitId":"-"},"content":" }"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":207,"author":{"gitId":"-"},"content":" * Verifies that the given entity is absent in the database."},{"lineNumber":208,"author":{"gitId":"-"},"content":" */"},{"lineNumber":209,"author":{"gitId":"-"},"content":" protected void verifyAbsentInDatabase(BaseEntity expected) {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" int retryLimit \u003d VERIFICATION_RETRY_COUNT;"},{"lineNumber":211,"author":{"gitId":"-"},"content":" ApiOutput actual \u003d getEntity(expected);"},{"lineNumber":212,"author":{"gitId":"-"},"content":" while (actual !\u003d null \u0026\u0026 retryLimit \u003e 0) {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" retryLimit--;"},{"lineNumber":214,"author":{"gitId":"-"},"content":" ThreadHelper.waitFor(VERIFICATION_RETRY_DELAY_IN_MS);"},{"lineNumber":215,"author":{"gitId":"-"},"content":" actual \u003d getEntity(expected);"},{"lineNumber":216,"author":{"gitId":"-"},"content":" }"},{"lineNumber":217,"author":{"gitId":"-"},"content":" assertNull(actual);"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" private ApiOutput getEntity(BaseEntity entity) {"},{"lineNumber":221,"author":{"gitId":"-"},"content":" if (entity instanceof Student) {"},{"lineNumber":222,"author":{"gitId":"-"},"content":" return getStudent((Student) entity);"},{"lineNumber":223,"author":{"gitId":"-"},"content":" } else if (entity instanceof FeedbackQuestion) {"},{"lineNumber":224,"author":{"gitId":"-"},"content":" return getFeedbackQuestion((FeedbackQuestion) entity);"},{"lineNumber":225,"author":{"gitId":"-"},"content":" } else if (entity instanceof FeedbackSession) {"},{"lineNumber":226,"author":{"gitId":"-"},"content":" return getFeedbackSession((FeedbackSession) entity);"},{"lineNumber":227,"author":{"gitId":"-"},"content":" } else if (entity instanceof FeedbackResponse) {"},{"lineNumber":228,"author":{"gitId":"-"},"content":" return getFeedbackResponse((FeedbackResponse) entity);"},{"lineNumber":229,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":230,"author":{"gitId":"-"},"content":" throw new RuntimeException(\"Unknown entity type\");"},{"lineNumber":231,"author":{"gitId":"-"},"content":" }"},{"lineNumber":232,"author":{"gitId":"-"},"content":" }"},{"lineNumber":233,"author":{"gitId":"-"},"content":""},{"lineNumber":234,"author":{"gitId":"-"},"content":" protected abstract FeedbackQuestionData getFeedbackQuestion(FeedbackQuestion fq);"},{"lineNumber":235,"author":{"gitId":"-"},"content":""},{"lineNumber":236,"author":{"gitId":"-"},"content":" protected abstract FeedbackSessionData getFeedbackSession(FeedbackSession fq);"},{"lineNumber":237,"author":{"gitId":"-"},"content":""},{"lineNumber":238,"author":{"gitId":"-"},"content":" protected abstract FeedbackResponseData getFeedbackResponse(FeedbackResponse fq);"},{"lineNumber":239,"author":{"gitId":"-"},"content":""},{"lineNumber":240,"author":{"gitId":"-"},"content":" protected abstract StudentData getStudent(Student student);"},{"lineNumber":241,"author":{"gitId":"-"},"content":""},{"lineNumber":242,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":10,"-":232}},{"path":"src/test/java/teammates/ui/request/AccountRequestRejectionRequestTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"package teammates.ui.request;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import org.testng.annotations.Test;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import teammates.test.BaseTestCase;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"/**"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":" * SUT: {@link AccountRequestRejectionRequest}."},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"public class AccountRequestRejectionRequestTest extends BaseTestCase {"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" private static final String TYPICAL_TITLE \u003d \"We are Unable to Create an Account for you\";"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" private static final String TYPICAL_BODY \u003d new StringBuilder()"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003eHi, Example\u003c/p\u003e\\n\")"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003eThanks for your interest in using TEAMMATES. \")"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" .append(\"We are unable to create a TEAMMATES instructor account for you.\u003c/p\u003e\\n\\n\")"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003e\\n\")"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":" .append(\" \u003cstrong\u003eReason:\u003c/strong\u003e The email address you provided \")"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":" .append(\"is not an \u0027official\u0027 email address provided by your institution.\u003cbr /\u003e\\n\")"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" .append(\" \u003cstrong\u003eRemedy:\u003c/strong\u003e \")"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" .append(\"Please re-submit an account request with your \u0027official\u0027 institution email address.\\n\")"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" .append(\"\u003c/p\u003e\\n\\n\")"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003eIf you need further clarification or would like to appeal this decision, \")"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" .append(\"please feel free to contact us at teammates@comp.nus.edu.sg.\u003c/p\u003e\\n\")"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" .append(\"\u003cp\u003eRegards,\u003cbr /\u003eTEAMMATES Team.\u003c/p\u003e\\n\")"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" .toString();"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" public void testValidate_withNonNullBodyAndNonNullTitle_shouldPass() throws Exception {"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest request \u003d new AccountRequestRejectionRequest(TYPICAL_TITLE, TYPICAL_BODY);"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" request.validate();"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" public void testValidate_withNullBodyAndNullTitle_shouldPass() throws Exception {"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest request \u003d new AccountRequestRejectionRequest(null, null);"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" request.validate();"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" public void testValidate_withNonNullBodyAndNullTitle_shouldFail() {"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest request \u003d new AccountRequestRejectionRequest(null, TYPICAL_BODY);"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" assertThrows(InvalidHttpRequestBodyException.class, request::validate);"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" @Test"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" public void testValidate_withNullBodyAndNonNullTitle_shouldFail() {"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" AccountRequestRejectionRequest request \u003d new AccountRequestRejectionRequest(TYPICAL_TITLE, null);"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" assertThrows(InvalidHttpRequestBodyException.class, request::validate);"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":51}},{"path":"src/test/java/teammates/ui/webapi/CreateFeedbackSessionLogActionTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":4,"author":{"gitId":"-"},"content":""},{"lineNumber":5,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":10,"author":{"gitId":"dishenggg"},"content":"import teammates.ui.output.MessageOutput;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * SUT: {@link CreateFeedbackSessionLogAction}."},{"lineNumber":14,"author":{"gitId":"-"},"content":" */"},{"lineNumber":15,"author":{"gitId":"-"},"content":"public class CreateFeedbackSessionLogActionTest extends BaseActionTest\u003cCreateFeedbackSessionLogAction\u003e {"},{"lineNumber":16,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":17,"author":{"gitId":"-"},"content":" protected String getActionUri() {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" return Const.ResourceURIs.SESSION_LOGS;"},{"lineNumber":19,"author":{"gitId":"-"},"content":" }"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":22,"author":{"gitId":"-"},"content":" protected String getRequestMethod() {"},{"lineNumber":23,"author":{"gitId":"-"},"content":" return POST;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" }"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"-"},"content":" protected void testExecute() {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" CourseAttributes course1 \u003d typicalBundle.courses.get(\"typicalCourse1\");"},{"lineNumber":30,"author":{"gitId":"-"},"content":" String courseId1 \u003d course1.getId();"},{"lineNumber":31,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes fsa1 \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":32,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes fsa2 \u003d typicalBundle.feedbackSessions.get(\"session2InCourse1\");"},{"lineNumber":33,"author":{"gitId":"-"},"content":" StudentAttributes student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":34,"author":{"gitId":"-"},"content":" StudentAttributes student2 \u003d typicalBundle.students.get(\"student2InCourse1\");"},{"lineNumber":35,"author":{"gitId":"-"},"content":" StudentAttributes student3 \u003d typicalBundle.students.get(\"student1InCourse3\");"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: not enough parameters\");"},{"lineNumber":38,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure(Const.ParamsNames.COURSE_ID, courseId1);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure("},{"lineNumber":40,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":41,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fsa1.getFeedbackSessionName()"},{"lineNumber":42,"author":{"gitId":"-"},"content":" );"},{"lineNumber":43,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure("},{"lineNumber":44,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fsa1.getFeedbackSessionName(),"},{"lineNumber":45,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":46,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail()"},{"lineNumber":47,"author":{"gitId":"-"},"content":" );"},{"lineNumber":48,"author":{"gitId":"-"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: invalid log type\");"},{"lineNumber":50,"author":{"gitId":"-"},"content":" String[] paramsInvalid \u003d {"},{"lineNumber":51,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fsa1.getFeedbackSessionName(),"},{"lineNumber":53,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, \"invalid log type\","},{"lineNumber":54,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":55,"author":{"gitId":"-"},"content":" };"},{"lineNumber":56,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure(paramsInvalid);"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" ______TS(\"Success case: typical access\");"},{"lineNumber":59,"author":{"gitId":"-"},"content":" String[] paramsSuccessfulAccess \u003d {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":61,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fsa1.getFeedbackSessionName(),"},{"lineNumber":62,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.ACCESS.getLabel(),"},{"lineNumber":63,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":64,"author":{"gitId":"-"},"content":" };"},{"lineNumber":65,"author":{"gitId":"dishenggg"},"content":" JsonResult response \u003d getJsonResult(getAction(paramsSuccessfulAccess));"},{"lineNumber":66,"author":{"gitId":"dishenggg"},"content":" MessageOutput output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":67,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" ______TS(\"Success case: typical submission\");"},{"lineNumber":70,"author":{"gitId":"-"},"content":" String[] paramsSuccessfulSubmission \u003d {"},{"lineNumber":71,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fsa2.getFeedbackSessionName(),"},{"lineNumber":73,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":74,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, student2.getEmail(),"},{"lineNumber":75,"author":{"gitId":"-"},"content":" };"},{"lineNumber":76,"author":{"gitId":"dishenggg"},"content":" response \u003d getJsonResult(getAction(paramsSuccessfulSubmission));"},{"lineNumber":77,"author":{"gitId":"dishenggg"},"content":" output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":78,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" ______TS(\"Success case: should create even for invalid parameters\");"},{"lineNumber":81,"author":{"gitId":"-"},"content":" String[] paramsNonExistentFsName \u003d {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":83,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, \"non-existent-feedback-session-name\","},{"lineNumber":84,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":85,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1.getEmail(),"},{"lineNumber":86,"author":{"gitId":"-"},"content":" };"},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" response \u003d getJsonResult(getAction(paramsNonExistentFsName));"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" String[] paramsNonExistentStudentEmail \u003d {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":93,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fsa1.getFeedbackSessionName(),"},{"lineNumber":94,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":95,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, \"non-existent-student@email.com\","},{"lineNumber":96,"author":{"gitId":"-"},"content":" };"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" response \u003d getJsonResult(getAction(paramsNonExistentStudentEmail));"},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":99,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" ______TS(\"Success case: should create even when student cannot access feedback session in course\");"},{"lineNumber":102,"author":{"gitId":"-"},"content":" String[] paramsWithoutAccess \u003d {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId1,"},{"lineNumber":104,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_NAME, fsa1.getFeedbackSessionName(),"},{"lineNumber":105,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_TYPE, FeedbackSessionLogType.SUBMISSION.getLabel(),"},{"lineNumber":106,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, student3.getEmail(),"},{"lineNumber":107,"author":{"gitId":"-"},"content":" };"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":" response \u003d getJsonResult(getAction(paramsWithoutAccess));"},{"lineNumber":109,"author":{"gitId":"dishenggg"},"content":" output \u003d (MessageOutput) response.getOutput();"},{"lineNumber":110,"author":{"gitId":"dishenggg"},"content":" assertEquals(\"Successful\", output.getMessage());"},{"lineNumber":111,"author":{"gitId":"-"},"content":" }"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":114,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":115,"author":{"gitId":"-"},"content":" protected void testAccessControl() {"},{"lineNumber":116,"author":{"gitId":"-"},"content":" verifyAnyUserCanAccess();"},{"lineNumber":117,"author":{"gitId":"-"},"content":" }"},{"lineNumber":118,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":16,"-":102}},{"path":"src/test/java/teammates/ui/webapi/GetActionClassesActionTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.util.Arrays;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.Collections;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import java.util.stream.Collectors;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.ui.output.ActionClasses;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"-"},"content":" * SUT: {@link GetActionClassesAction}."},{"lineNumber":15,"author":{"gitId":"-"},"content":" */"},{"lineNumber":16,"author":{"gitId":"-"},"content":"public class GetActionClassesActionTest extends BaseActionTest\u003cGetActionClassesAction\u003e {"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":19,"author":{"gitId":"-"},"content":" protected String getActionUri() {"},{"lineNumber":20,"author":{"gitId":"-"},"content":" return Const.ResourceURIs.ACTION_CLASS;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" }"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":24,"author":{"gitId":"-"},"content":" protected String getRequestMethod() {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" return GET;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" }"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":29,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":30,"author":{"gitId":"-"},"content":" protected void testExecute() {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" List\u003cClass\u003c? extends Action\u003e\u003e expectedActionClasses \u003d Arrays.asList("},{"lineNumber":32,"author":{"gitId":"-"},"content":" DeleteFeedbackResponseCommentAction.class,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" CreateFeedbackResponseCommentAction.class,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" GetFeedbackResponseCommentAction.class,"},{"lineNumber":35,"author":{"gitId":"-"},"content":" UpdateFeedbackResponseCommentAction.class,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" RestoreFeedbackSessionAction.class,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" BinFeedbackSessionAction.class,"},{"lineNumber":38,"author":{"gitId":"-"},"content":" GetCoursesAction.class,"},{"lineNumber":39,"author":{"gitId":"-"},"content":" GetRegkeyValidityAction.class,"},{"lineNumber":40,"author":{"gitId":"-"},"content":" PutDataBundleAction.class,"},{"lineNumber":41,"author":{"gitId":"-"},"content":" DeleteDataBundleAction.class,"},{"lineNumber":42,"author":{"gitId":"-"},"content":" CreateFeedbackSessionLogAction.class,"},{"lineNumber":43,"author":{"gitId":"-"},"content":" GetFeedbackSessionLogsAction.class,"},{"lineNumber":44,"author":{"gitId":"-"},"content":" GetInstructorPrivilegeAction.class,"},{"lineNumber":45,"author":{"gitId":"-"},"content":" UpdateInstructorPrivilegeAction.class,"},{"lineNumber":46,"author":{"gitId":"-"},"content":" GetFeedbackSessionsAction.class,"},{"lineNumber":47,"author":{"gitId":"-"},"content":" GenerateEmailAction.class,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" GetFeedbackQuestionsAction.class,"},{"lineNumber":49,"author":{"gitId":"-"},"content":" GetOngoingSessionsAction.class,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" AdminExceptionTestAction.class,"},{"lineNumber":51,"author":{"gitId":"-"},"content":" GetUserCookieAction.class,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" RemindFeedbackSessionResultAction.class,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" DeleteInstructorAction.class,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" CreateInstructorAction.class,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" GetInstructorAction.class,"},{"lineNumber":56,"author":{"gitId":"-"},"content":" UpdateInstructorAction.class,"},{"lineNumber":57,"author":{"gitId":"-"},"content":" ArchiveCourseAction.class,"},{"lineNumber":58,"author":{"gitId":"-"},"content":" InstructorCourseJoinEmailWorkerAction.class,"},{"lineNumber":59,"author":{"gitId":"-"},"content":" DeleteStudentAction.class,"},{"lineNumber":60,"author":{"gitId":"-"},"content":" GetStudentAction.class,"},{"lineNumber":61,"author":{"gitId":"-"},"content":" UpdateStudentAction.class,"},{"lineNumber":62,"author":{"gitId":"-"},"content":" SearchStudentsAction.class,"},{"lineNumber":63,"author":{"gitId":"-"},"content":" FeedbackSessionRemindEmailWorkerAction.class,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" DeleteFeedbackSessionAction.class,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" CreateFeedbackSessionAction.class,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" GetFeedbackSessionAction.class,"},{"lineNumber":67,"author":{"gitId":"-"},"content":" UpdateFeedbackSessionAction.class,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" FeedbackSessionClosingRemindersAction.class,"},{"lineNumber":69,"author":{"gitId":"-"},"content":" GetTimeZonesAction.class,"},{"lineNumber":70,"author":{"gitId":"-"},"content":" FeedbackSessionRemindParticularUsersEmailWorkerAction.class,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" GetFeedbackResponsesAction.class,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" SubmitFeedbackResponsesAction.class,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" FeedbackSessionPublishedEmailWorkerAction.class,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" FeedbackSessionClosedRemindersAction.class,"},{"lineNumber":75,"author":{"gitId":"-"},"content":" SendErrorReportAction.class,"},{"lineNumber":76,"author":{"gitId":"-"},"content":" GetActionClassesAction.class,"},{"lineNumber":77,"author":{"gitId":"-"},"content":" UnpublishFeedbackSessionAction.class,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" PublishFeedbackSessionAction.class,"},{"lineNumber":79,"author":{"gitId":"-"},"content":" GetSessionResultsAction.class,"},{"lineNumber":80,"author":{"gitId":"-"},"content":" GetHasResponsesAction.class,"},{"lineNumber":81,"author":{"gitId":"-"},"content":" DatastoreBackupAction.class,"},{"lineNumber":82,"author":{"gitId":"-"},"content":" RestoreCourseAction.class,"},{"lineNumber":83,"author":{"gitId":"-"},"content":" BinCourseAction.class,"},{"lineNumber":84,"author":{"gitId":"-"},"content":" DeleteAccountAction.class,"},{"lineNumber":85,"author":{"gitId":"-"},"content":" CreateAccountAction.class,"},{"lineNumber":86,"author":{"gitId":"-"},"content":" CreateAccountRequestAction.class,"},{"lineNumber":87,"author":{"gitId":"-"},"content":" GetAccountRequestAction.class,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" DeleteAccountRequestAction.class,"},{"lineNumber":89,"author":{"gitId":"-"},"content":" GetAccountRequestsAction.class,"},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" UpdateAccountRequestAction.class,"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":" RejectAccountRequestAction.class,"},{"lineNumber":92,"author":{"gitId":"-"},"content":" GetAccountAction.class,"},{"lineNumber":93,"author":{"gitId":"-"},"content":" GetAccountsAction.class,"},{"lineNumber":94,"author":{"gitId":"-"},"content":" FeedbackSessionPublishedRemindersAction.class,"},{"lineNumber":95,"author":{"gitId":"-"},"content":" QueryLogsAction.class,"},{"lineNumber":96,"author":{"gitId":"-"},"content":" SessionLinksRecoveryAction.class,"},{"lineNumber":97,"author":{"gitId":"-"},"content":" SendJoinReminderEmailAction.class,"},{"lineNumber":98,"author":{"gitId":"-"},"content":" RegenerateInstructorKeyAction.class,"},{"lineNumber":99,"author":{"gitId":"-"},"content":" RegenerateStudentKeyAction.class,"},{"lineNumber":100,"author":{"gitId":"-"},"content":" CompileLogsAction.class,"},{"lineNumber":101,"author":{"gitId":"-"},"content":" GetAuthInfoAction.class,"},{"lineNumber":102,"author":{"gitId":"-"},"content":" GetFeedbackSessionSubmittedGiverSetAction.class,"},{"lineNumber":103,"author":{"gitId":"-"},"content":" GetCourseJoinStatusAction.class,"},{"lineNumber":104,"author":{"gitId":"-"},"content":" JoinCourseAction.class,"},{"lineNumber":105,"author":{"gitId":"-"},"content":" GetSessionResponseStatsAction.class,"},{"lineNumber":106,"author":{"gitId":"-"},"content":" DeleteCourseAction.class,"},{"lineNumber":107,"author":{"gitId":"-"},"content":" CreateCourseAction.class,"},{"lineNumber":108,"author":{"gitId":"-"},"content":" GetCourseAction.class,"},{"lineNumber":109,"author":{"gitId":"-"},"content":" UpdateCourseAction.class,"},{"lineNumber":110,"author":{"gitId":"-"},"content":" GetFeedbackQuestionRecipientsAction.class,"},{"lineNumber":111,"author":{"gitId":"-"},"content":" RemindFeedbackSessionSubmissionAction.class,"},{"lineNumber":112,"author":{"gitId":"-"},"content":" FeedbackSessionUnpublishedEmailWorkerAction.class,"},{"lineNumber":113,"author":{"gitId":"-"},"content":" SendEmailWorkerAction.class,"},{"lineNumber":114,"author":{"gitId":"-"},"content":" GetInstructorsAction.class,"},{"lineNumber":115,"author":{"gitId":"-"},"content":" PutDataBundleDocumentsAction.class,"},{"lineNumber":116,"author":{"gitId":"-"},"content":" FeedbackSessionResendPublishedEmailWorkerAction.class,"},{"lineNumber":117,"author":{"gitId":"-"},"content":" StudentCourseJoinEmailWorkerAction.class,"},{"lineNumber":118,"author":{"gitId":"-"},"content":" SearchInstructorsAction.class,"},{"lineNumber":119,"author":{"gitId":"-"},"content":" GetCourseSectionNamesAction.class,"},{"lineNumber":120,"author":{"gitId":"-"},"content":" ResetAccountAction.class,"},{"lineNumber":121,"author":{"gitId":"-"},"content":" FeedbackSessionOpeningRemindersAction.class,"},{"lineNumber":122,"author":{"gitId":"-"},"content":" FeedbackSessionOpeningSoonRemindersAction.class,"},{"lineNumber":123,"author":{"gitId":"-"},"content":" DeleteStudentsAction.class,"},{"lineNumber":124,"author":{"gitId":"-"},"content":" GetStudentsAction.class,"},{"lineNumber":125,"author":{"gitId":"-"},"content":" EnrollStudentsAction.class,"},{"lineNumber":126,"author":{"gitId":"-"},"content":" DeleteFeedbackQuestionAction.class,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" CreateFeedbackQuestionAction.class,"},{"lineNumber":128,"author":{"gitId":"-"},"content":" UpdateFeedbackQuestionAction.class,"},{"lineNumber":129,"author":{"gitId":"-"},"content":" InstructorSearchIndexingWorkerAction.class,"},{"lineNumber":130,"author":{"gitId":"-"},"content":" StudentSearchIndexingWorkerAction.class,"},{"lineNumber":131,"author":{"gitId":"-"},"content":" AccountRequestSearchIndexingWorkerAction.class,"},{"lineNumber":132,"author":{"gitId":"-"},"content":" SearchAccountRequestsAction.class,"},{"lineNumber":133,"author":{"gitId":"-"},"content":" ResetAccountRequestAction.class,"},{"lineNumber":134,"author":{"gitId":"-"},"content":" CalculateUsageStatisticsAction.class,"},{"lineNumber":135,"author":{"gitId":"-"},"content":" GetUsageStatisticsAction.class,"},{"lineNumber":136,"author":{"gitId":"-"},"content":" GetNotificationAction.class,"},{"lineNumber":137,"author":{"gitId":"-"},"content":" CreateNotificationAction.class,"},{"lineNumber":138,"author":{"gitId":"-"},"content":" UpdateNotificationAction.class,"},{"lineNumber":139,"author":{"gitId":"-"},"content":" DeleteNotificationAction.class,"},{"lineNumber":140,"author":{"gitId":"-"},"content":" GetNotificationsAction.class,"},{"lineNumber":141,"author":{"gitId":"-"},"content":" MarkNotificationAsReadAction.class,"},{"lineNumber":142,"author":{"gitId":"-"},"content":" GetReadNotificationsAction.class,"},{"lineNumber":143,"author":{"gitId":"-"},"content":" GetDeadlineExtensionAction.class,"},{"lineNumber":144,"author":{"gitId":"-"},"content":" SendLoginEmailAction.class,"},{"lineNumber":145,"author":{"gitId":"-"},"content":" PutSqlDataBundleAction.class,"},{"lineNumber":146,"author":{"gitId":"dishenggg"},"content":" DeleteSqlDataBundleAction.class,"},{"lineNumber":147,"author":{"gitId":"dishenggg"},"content":" UpdateFeedbackSessionLogsAction.class"},{"lineNumber":148,"author":{"gitId":"-"},"content":" );"},{"lineNumber":149,"author":{"gitId":"-"},"content":" List\u003cString\u003e expectedActionClassesNames \u003d expectedActionClasses.stream()"},{"lineNumber":150,"author":{"gitId":"-"},"content":" .map(Class::getSimpleName)"},{"lineNumber":151,"author":{"gitId":"-"},"content":" .sorted()"},{"lineNumber":152,"author":{"gitId":"-"},"content":" .collect(Collectors.toList());"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"-"},"content":" GetActionClassesAction action \u003d getAction();"},{"lineNumber":155,"author":{"gitId":"-"},"content":" action.execute();"},{"lineNumber":156,"author":{"gitId":"-"},"content":" JsonResult result \u003d getJsonResult(action);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" ActionClasses data \u003d (ActionClasses) result.getOutput();"},{"lineNumber":158,"author":{"gitId":"-"},"content":" List\u003cString\u003e actualActionClasses \u003d data.getActionClasses();"},{"lineNumber":159,"author":{"gitId":"-"},"content":" Collections.sort(actualActionClasses);"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"-"},"content":" assertEquals(expectedActionClassesNames, actualActionClasses);"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":165,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":166,"author":{"gitId":"-"},"content":" protected void testAccessControl() {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" verifyAccessibleForAdmin();"},{"lineNumber":168,"author":{"gitId":"-"},"content":" verifyAccessibleForMaintainers();"},{"lineNumber":169,"author":{"gitId":"-"},"content":" verifyInaccessibleForStudents();"},{"lineNumber":170,"author":{"gitId":"-"},"content":" verifyInaccessibleForInstructors();"},{"lineNumber":171,"author":{"gitId":"-"},"content":" verifyInaccessibleWithoutLogin();"},{"lineNumber":172,"author":{"gitId":"-"},"content":" verifyInaccessibleForUnregisteredUsers();"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":1,"xenosf":1,"dishenggg":2,"-":171}},{"path":"src/test/java/teammates/ui/webapi/GetFeedbackSessionLogsActionTest.java","fileType":"java","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"package teammates.ui.webapi;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"import java.time.Instant;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import java.util.List;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"import org.testng.annotations.Test;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.CourseAttributes;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.FeedbackSessionAttributes;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.InstructorAttributes;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.attributes.StudentAttributes;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import teammates.common.datatransfer.logs.FeedbackSessionLogType;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import teammates.common.util.Const;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionLogData;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionLogEntryData;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import teammates.ui.output.FeedbackSessionLogsData;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":19,"author":{"gitId":"-"},"content":" * SUT: {@link GetFeedbackSessionLogsAction}."},{"lineNumber":20,"author":{"gitId":"-"},"content":" */"},{"lineNumber":21,"author":{"gitId":"-"},"content":"public class GetFeedbackSessionLogsActionTest extends BaseActionTest\u003cGetFeedbackSessionLogsAction\u003e {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":23,"author":{"gitId":"-"},"content":" protected String getActionUri() {"},{"lineNumber":24,"author":{"gitId":"-"},"content":" return Const.ResourceURIs.SESSION_LOGS;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" }"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":28,"author":{"gitId":"-"},"content":" protected String getRequestMethod() {"},{"lineNumber":29,"author":{"gitId":"-"},"content":" return GET;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" }"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":33,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":34,"author":{"gitId":"-"},"content":" protected void testExecute() {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" JsonResult actionOutput;"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" CourseAttributes course \u003d typicalBundle.courses.get(\"typicalCourse1\");"},{"lineNumber":38,"author":{"gitId":"-"},"content":" String courseId \u003d course.getId();"},{"lineNumber":39,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes fsa1 \u003d typicalBundle.feedbackSessions.get(\"session1InCourse1\");"},{"lineNumber":40,"author":{"gitId":"-"},"content":" FeedbackSessionAttributes fsa2 \u003d typicalBundle.feedbackSessions.get(\"session2InCourse1\");"},{"lineNumber":41,"author":{"gitId":"-"},"content":" String fsa1Name \u003d fsa1.getFeedbackSessionName();"},{"lineNumber":42,"author":{"gitId":"-"},"content":" String fsa2Name \u003d fsa2.getFeedbackSessionName();"},{"lineNumber":43,"author":{"gitId":"-"},"content":" StudentAttributes student1 \u003d typicalBundle.students.get(\"student1InCourse1\");"},{"lineNumber":44,"author":{"gitId":"-"},"content":" StudentAttributes student2 \u003d typicalBundle.students.get(\"student2InCourse1\");"},{"lineNumber":45,"author":{"gitId":"-"},"content":" String student1Email \u003d student1.getEmail();"},{"lineNumber":46,"author":{"gitId":"-"},"content":" String student2Email \u003d student2.getEmail();"},{"lineNumber":47,"author":{"gitId":"-"},"content":" long endTime \u003d Instant.now().toEpochMilli();"},{"lineNumber":48,"author":{"gitId":"-"},"content":" long startTime \u003d endTime - (Const.LOGS_RETENTION_PERIOD.toDays() - 1) * 24 * 60 * 60 * 1000;"},{"lineNumber":49,"author":{"gitId":"-"},"content":" long invalidStartTime \u003d endTime - (Const.LOGS_RETENTION_PERIOD.toDays() + 1) * 24 * 60 * 60 * 1000;"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(courseId, student1Email, fsa1Name,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime);"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(courseId, student1Email, fsa2Name,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime + 1000);"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(courseId, student1Email, fsa2Name,"},{"lineNumber":56,"author":{"gitId":"-"},"content":" FeedbackSessionLogType.SUBMISSION.getLabel(), startTime + 2000);"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(courseId, student2Email, fsa1Name,"},{"lineNumber":58,"author":{"gitId":"-"},"content":" FeedbackSessionLogType.ACCESS.getLabel(), startTime + 3000);"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":" mockLogsProcessor.insertFeedbackSessionLog(courseId, student2Email, fsa1Name,"},{"lineNumber":60,"author":{"gitId":"-"},"content":" FeedbackSessionLogType.SUBMISSION.getLabel(), startTime + 4000);"},{"lineNumber":61,"author":{"gitId":"-"},"content":""},{"lineNumber":62,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: not enough parameters\");"},{"lineNumber":63,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure("},{"lineNumber":64,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId"},{"lineNumber":65,"author":{"gitId":"-"},"content":" );"},{"lineNumber":66,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure("},{"lineNumber":67,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime)"},{"lineNumber":69,"author":{"gitId":"-"},"content":" );"},{"lineNumber":70,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure("},{"lineNumber":71,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":72,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime)"},{"lineNumber":73,"author":{"gitId":"-"},"content":" );"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: invalid course id\");"},{"lineNumber":76,"author":{"gitId":"-"},"content":" String[] paramsInvalid1 \u003d {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, \"fake-course-id\","},{"lineNumber":78,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1Email,"},{"lineNumber":79,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":80,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":81,"author":{"gitId":"-"},"content":" };"},{"lineNumber":82,"author":{"gitId":"-"},"content":" verifyEntityNotFound(paramsInvalid1);"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: invalid student email\");"},{"lineNumber":85,"author":{"gitId":"-"},"content":" String[] paramsInvalid2 \u003d {"},{"lineNumber":86,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":87,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, \"fake-student-email@gmail.com\","},{"lineNumber":88,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":89,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":90,"author":{"gitId":"-"},"content":" };"},{"lineNumber":91,"author":{"gitId":"-"},"content":" verifyEntityNotFound(paramsInvalid2);"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: invalid start or end times\");"},{"lineNumber":94,"author":{"gitId":"-"},"content":" String[] paramsInvalid3 \u003d {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":96,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, \"abc\","},{"lineNumber":97,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":98,"author":{"gitId":"-"},"content":" };"},{"lineNumber":99,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure(paramsInvalid3);"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" String[] paramsInvalid4 \u003d {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":103,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":104,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, \" \","},{"lineNumber":105,"author":{"gitId":"-"},"content":" };"},{"lineNumber":106,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure(paramsInvalid4);"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" ______TS(\"Failure case: start time is before earliest search time\");"},{"lineNumber":109,"author":{"gitId":"-"},"content":" verifyHttpParameterFailure("},{"lineNumber":110,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":111,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(invalidStartTime),"},{"lineNumber":112,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime)"},{"lineNumber":113,"author":{"gitId":"-"},"content":" );"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" ______TS(\"Success case: should group by feedback session\");"},{"lineNumber":116,"author":{"gitId":"-"},"content":" String[] paramsSuccessful1 \u003d {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":118,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":119,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":120,"author":{"gitId":"-"},"content":" };"},{"lineNumber":121,"author":{"gitId":"-"},"content":" actionOutput \u003d getJsonResult(getAction(paramsSuccessful1));"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" // The filtering by the logs processor cannot be tested directly, assume that it filters correctly"},{"lineNumber":124,"author":{"gitId":"-"},"content":" // Here, it simply returns all log entries"},{"lineNumber":125,"author":{"gitId":"-"},"content":" FeedbackSessionLogsData fslData \u003d (FeedbackSessionLogsData) actionOutput.getOutput();"},{"lineNumber":126,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogData\u003e fsLogs \u003d fslData.getFeedbackSessionLogs();"},{"lineNumber":127,"author":{"gitId":"-"},"content":""},{"lineNumber":128,"author":{"gitId":"-"},"content":" // Course has 6 feedback sessions, last 4 of which have no log entries"},{"lineNumber":129,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.size(), 6);"},{"lineNumber":130,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.get(2).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.get(3).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":132,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.get(4).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":133,"author":{"gitId":"-"},"content":" assertEquals(fsLogs.get(5).getFeedbackSessionLogEntries().size(), 0);"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogEntryData\u003e fsLogEntries1 \u003d fsLogs.get(0).getFeedbackSessionLogEntries();"},{"lineNumber":136,"author":{"gitId":"-"},"content":" List\u003cFeedbackSessionLogEntryData\u003e fsLogEntries2 \u003d fsLogs.get(1).getFeedbackSessionLogEntries();"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.size(), 3);"},{"lineNumber":139,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(0).getStudentData().getEmail(), student1Email);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":141,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(1).getStudentData().getEmail(), student2Email);"},{"lineNumber":142,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(2).getStudentData().getEmail(), student2Email);"},{"lineNumber":144,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries1.get(2).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":145,"author":{"gitId":"-"},"content":""},{"lineNumber":146,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.size(), 2);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.get(0).getStudentData().getEmail(), student1Email);"},{"lineNumber":148,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.get(0).getFeedbackSessionLogType(), FeedbackSessionLogType.ACCESS);"},{"lineNumber":149,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.get(1).getStudentData().getEmail(), student1Email);"},{"lineNumber":150,"author":{"gitId":"-"},"content":" assertEquals(fsLogEntries2.get(1).getFeedbackSessionLogType(), FeedbackSessionLogType.SUBMISSION);"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" ______TS(\"Success case: should accept optional email\");"},{"lineNumber":153,"author":{"gitId":"-"},"content":" String[] paramsSuccessful2 \u003d {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":155,"author":{"gitId":"-"},"content":" Const.ParamsNames.STUDENT_EMAIL, student1Email,"},{"lineNumber":156,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_STARTTIME, String.valueOf(startTime),"},{"lineNumber":157,"author":{"gitId":"-"},"content":" Const.ParamsNames.FEEDBACK_SESSION_LOG_ENDTIME, String.valueOf(endTime),"},{"lineNumber":158,"author":{"gitId":"-"},"content":" };"},{"lineNumber":159,"author":{"gitId":"-"},"content":" getJsonResult(getAction(paramsSuccessful2));"},{"lineNumber":160,"author":{"gitId":"-"},"content":" // No need to check output again here, it will be exactly the same as the previous case"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"-"},"content":" // TODO: if we restrict the range from start to end time, it should be tested here as well"},{"lineNumber":163,"author":{"gitId":"-"},"content":" }"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" @Test"},{"lineNumber":166,"author":{"gitId":"-"},"content":" @Override"},{"lineNumber":167,"author":{"gitId":"-"},"content":" protected void testAccessControl() {"},{"lineNumber":168,"author":{"gitId":"-"},"content":" InstructorAttributes instructor \u003d typicalBundle.instructors.get(\"instructor2OfCourse1\");"},{"lineNumber":169,"author":{"gitId":"-"},"content":" InstructorAttributes helper \u003d typicalBundle.instructors.get(\"helperOfCourse1\");"},{"lineNumber":170,"author":{"gitId":"-"},"content":" String courseId \u003d instructor.getCourseId();"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" ______TS(\"Only instructors of the same course can access\");"},{"lineNumber":173,"author":{"gitId":"-"},"content":" String[] submissionParams \u003d new String[] {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":175,"author":{"gitId":"-"},"content":" };"},{"lineNumber":176,"author":{"gitId":"-"},"content":" verifyOnlyInstructorsOfTheSameCourseCanAccess(submissionParams);"},{"lineNumber":177,"author":{"gitId":"-"},"content":""},{"lineNumber":178,"author":{"gitId":"-"},"content":" ______TS(\"Only instructors with modify student, session and instructor privilege can access\");"},{"lineNumber":179,"author":{"gitId":"-"},"content":" submissionParams \u003d new String[] {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" Const.ParamsNames.COURSE_ID, courseId,"},{"lineNumber":181,"author":{"gitId":"-"},"content":" };"},{"lineNumber":182,"author":{"gitId":"-"},"content":""},{"lineNumber":183,"author":{"gitId":"-"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":184,"author":{"gitId":"-"},"content":""},{"lineNumber":185,"author":{"gitId":"-"},"content":" loginAsInstructor(helper.getGoogleId());"},{"lineNumber":186,"author":{"gitId":"-"},"content":" verifyCannotAccess(submissionParams);"},{"lineNumber":187,"author":{"gitId":"-"},"content":""},{"lineNumber":188,"author":{"gitId":"-"},"content":" loginAsInstructor(instructor.getGoogleId());"},{"lineNumber":189,"author":{"gitId":"-"},"content":" verifyCanAccess(submissionParams);"},{"lineNumber":190,"author":{"gitId":"-"},"content":" }"},{"lineNumber":191,"author":{"gitId":"-"},"content":""},{"lineNumber":192,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":5,"-":187}},{"path":"src/test/resources/emails/instructorNewAccountRequestAcknowledgementEmailWithComments.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"\u003cp\u003eHello, Darth Vader\u003c/p\u003e"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":" Thank you for submitting an account request. This is what you have submitted:"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"\u003cdiv\u003e"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":" \u003ctable style\u003d\"max-width:600px;border:1px solid black;\"\u003e"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" Full Name"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" Darth Vader"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" Country \u0026 Institute"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" Sith Order"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" Email Address"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" darth-vader@sith.org"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" Comments"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" I Am Your Father"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" \u003c/table\u003e"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":"\u003c/div\u003e"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" Your request will be reviewed within 24 hours. We will send another email once your request has been accepted."},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" If you have any additional queries, please feel free to contact us at ${support.email}."},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" Regards,\u003cbr\u003e"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" TEAMMATES Team."},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"}],"authorContributionMap":{"xenosf":65}},{"path":"src/test/resources/emails/instructorNewAccountRequestAcknowledgementEmailWithNoComments.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"\u003cp\u003eHello, Maul\u003c/p\u003e"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":" Thank you for submitting an account request. This is what you have submitted:"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"\u003cdiv\u003e"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":" \u003ctable style\u003d\"max-width:600px;border:1px solid black;\"\u003e"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" Full Name"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" Maul"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" Country \u0026 Institute"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" Sith Order"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" Email Address"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" maul@sith.org"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003e"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" Comments"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" \u003c/strong\u003e"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" \u003ctd style\u003d\"padding:5px;\"\u003e"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" "},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" \u003c/table\u003e"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":"\u003c/div\u003e"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" Your request will be reviewed within 24 hours. We will send another email once your request has been accepted."},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" If you have any additional queries, please feel free to contact us at ${support.email}."},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":"\u003cp\u003e"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" Regards,\u003cbr\u003e"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" TEAMMATES Team."},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"}],"authorContributionMap":{"xenosf":65}},{"path":"src/web/app/components/account-requests-table/account-request-table-model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"import { AccountRequestStatus } from \u0027src/web/types/api-output\u0027;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":" * Model for the row entries in the account requests table."},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"export interface AccountRequestTableRowModel {"},{"lineNumber":7,"author":{"gitId":"-"},"content":" id: string;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" name: string;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":" email: string;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" instituteAndCountry: string;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":" createdAtText: string;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":" registeredAtText: string;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":" comments: string;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" registrationLink: string;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" showLinks: boolean;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":16,"-":1}},{"path":"src/web/app/components/account-requests-table/account-request-table.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"\u003cdiv class\u003d\"card bg-light top-padded\" *ngIf\u003d\"accountRequests.length\"\u003e"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"card-header bg-primary text-white\"\u003e"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":" \u003cdiv *ngIf\u003d\"searchString; else pendingRequests\"\u003e"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003eAccount Requests Found\u003c/strong\u003e"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":" \u003cng-template #pendingRequests\u003e"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003ePending Account Requests\u003c/strong\u003e"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" \u003c/ng-template\u003e"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":" \u003cdiv *ngIf\u003d\"searchString\" class\u003d\"card-header-btn-toolbar\"\u003e"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"show-account-request-links\" class\u003d\"btn btn-light btn-sm\" style\u003d\"margin-right: 10px;\" type\u003d\"button\" (click)\u003d\"showAllAccountRequestsLinks()\"\u003eExpand All\u003c/button\u003e"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"hide-account-request-links\" class\u003d\"btn btn-light btn-sm\" type\u003d\"button\" (click)\u003d\"hideAllAccountRequestsLinks()\"\u003eCollapse All\u003c/button\u003e"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"\u003cdiv class\u003d\"table-responsive\"\u003e"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" \u003ctable class\u003d\"table table-striped data-table\" id\u003d\"search-table-account-request\"\u003e"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" \u003cthead\u003e"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" \u003ctr\u003e"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" \u003cth\u003eName\u003c/th\u003e"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" \u003cth\u003eEmail\u003c/th\u003e"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" \u003cth\u003eStatus\u003c/th\u003e"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" \u003cth\u003eInstitute, Country\u003c/th\u003e"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" \u003cth\u003eCreated At\u003c/th\u003e"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" \u003cth *ngIf\u003d\"searchString\"\u003eRegistered At\u003c/th\u003e"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" \u003cth\u003eComments\u003c/th\u003e"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" \u003cth\u003eOptions\u003c/th\u003e"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" \u003c/tr\u003e"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" \u003c/thead\u003e"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" \u003ctbody\u003e"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" \u003cng-container *ngFor\u003d\"let accountRequest of accountRequests; let i \u003d index; trackBy: trackAccountRequest\"\u003e"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" \u003ctr\u003e"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" \u003ctd [innerHtml]\u003d\"accountRequest.name | highlighter:searchString:true\"\u003e"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" \u003cbr\u003e"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"col-sm-1\"\u003e"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" \u003cbutton *ngIf\u003d\"!accountRequest.showLinks\" class\u003d\"btn\" aria-label\u003d\"Expand\"\u003e"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" \u003ci class\u003d\"fas fa-chevron-circle-down\" style\u003d\"color: blue;\"\u003e\u003c/i\u003e"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" \u003c/button\u003e"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" \u003cbutton *ngIf\u003d\"accountRequest.showLinks\" class\u003d\"btn\" aria-label\u003d\"Collapse\"\u003e"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" \u003ci class\u003d\"fas fa-chevron-circle-up\" style\u003d\"color: blue;\"\u003e\u003c/i\u003e"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" \u003c/button\u003e"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" \u003c/td\u003e"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" \u003ctd [innerHtml]\u003d\"accountRequest.email | highlighter:searchString:true\"\u003e{{ accountRequest.email }}\u003c/td\u003e"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" \u003ctd [innerHtml]\u003d\"accountRequest.status | highlighter:searchString:true\"\u003e{{ accountRequest.status }}\u003c/td\u003e"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" \u003ctd [innerHtml]\u003d\"accountRequest.instituteAndCountry | highlighter:searchString:true\"\u003e{{ accountRequest.instituteAndCountry }}\u003c/td\u003e"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" \u003ctd id\u003d\"timestamp-box\"\u003e{{ accountRequest.createdAtText }}\u003c/td\u003e"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" \u003ctd *ngIf\u003d\"searchString\" id\u003d\"timestamp-box\"\u003e{{ accountRequest.registeredAtText || \u0027Not Registered Yet\u0027 }}\u003c/td\u003e"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" \u003ctd\u003e"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" \u003cdiv id\u003d\"comment-box\" [innerHtml]\u003d\"accountRequest.comments | highlighter:searchString:true\"\u003e"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" {{ accountRequest.comments }}"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" \u003c/td\u003e"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" \u003ctd class\u003d\"align-middle\"\u003e"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"d-flex flex-row align-items-center justify-content-center gap-2\"\u003e"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003e"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" \u003ca id\u003d\"edit-account-request-{{i}}\" (click)\u003d\"$event.stopPropagation(); editAccountRequest(accountRequest);\"\u003e"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" \u003ci class\u003d\"fa-solid fa-pen\"\u003e\u003c/i\u003e"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" \u003c/a\u003e"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"ngb-tooltip-class\" [ngbTooltip]\u003d\"accountRequest.registeredAtText \u0026\u0026 \u0027Account requests of registered instructors cannot be deleted\u0027\" placement\u003d\"top\"\u003e"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" \u003ca id\u003d\"delete-account-request-{{i}}\" (click)\u003d\"$event.stopPropagation(); deleteAccountRequest(accountRequest)\"\u003e"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" \u003ci class\u003d\"fa-solid fa-trash\"\u003e\u003c/i\u003e"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" \u003c/a\u003e"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003e"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" \u003ca id\u003d\"view-account-request-{{i}}\" (click)\u003d\"$event.stopPropagation(); viewAccountRequest(accountRequest)\"\u003e"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":" \u003ci class\u003d\"fa-solid fa-eye\"\u003e\u003c/i\u003e"},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" \u003c/a\u003e"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"approve-account-request-{{i}}\" class\u003d\"btn btn-success\" [disabled]\u003d\"!accountRequest.status || accountRequest.status \u003d\u003d\u003d \u0027APPROVED\u0027 || accountRequest.status \u003d\u003d\u003d \u0027REGISTERED\u0027\" (click)\u003d\"$event.stopPropagation(); approveAccountRequest(accountRequest)\"\u003eApprove\u003c/button\u003e"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" \u003cspan ngbDropdown container\u003d\"body\"\u003e"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"reject-account-request-{{i}}\" type\u003d\"button\" class\u003d\"btn btn-warning\" [disabled]\u003d\"!accountRequest.status || accountRequest.status \u003d\u003d\u003d \u0027REGISTERED\u0027 || accountRequest.status \u003d\u003d\u003d \u0027APPROVED\u0027 || accountRequest.status \u003d\u003d\u003d \u0027REJECTED\u0027\" ngbDropdownToggle\u003e Reject \u003c/button\u003e"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" \u003cdiv ngbDropdownMenu (click)\u003d\"$event.stopPropagation()\"\u003e"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"reject-request-{{i}}\" class\u003d\"btn btn-light btn-sm dropdown-item\" (click)\u003d\"$event.stopPropagation(); rejectAccountRequest(accountRequest)\"\u003e Reject \u003c/button\u003e"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"reject-request-with-reason-{{i}}\" class\u003d\"btn btn-light btn-sm dropdown-item\" (click)\u003d\"$event.stopPropagation(); rejectAccountRequestWithReason(accountRequest)\"\u003e Reject With Reason \u003c/button\u003e"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" \u003c/span\u003e"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" \u003cdiv *ngIf\u003d\"searchString\" class\u003d\"ngb-tooltip-class\" [ngbTooltip]\u003d\"accountRequest.registeredAtText \u0026\u0026 \u0027Account requests of registered instructors cannot be deleted\u0027\" placement\u003d\"top\"\u003e"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"reset-account-request-{{i}}\" class\u003d\"btn btn-primary\" [disabled]\u003d\"!accountRequest.registeredAtText\" (click)\u003d\"$event.stopPropagation(); resetAccountRequest(accountRequest);\"\u003eReset\u003c/button\u003e"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" \u003c/td\u003e"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" \u003c/tr\u003e"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" \u003ctr *ngIf\u003d\"accountRequest.showLinks \u0026\u0026 searchString\"\u003e"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" \u003ctd colspan\u003d\"100\"\u003e"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" \u003cul class\u003d\"list-group\" *ngIf\u003d\"accountRequest.showLinks\" @collapseAnim\u003e"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":" \u003cli class\u003d\"list-group-item list-group-item-info\"\u003e"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003eAccount Registration Link\u003c/strong\u003e"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" \u003cinput [value]\u003d\"accountRequest.registrationLink\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" \u003c/li\u003e"},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" \u003c/ul\u003e"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" \u003c/td\u003e"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" \u003c/tr\u003e"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":" \u003c/ng-container\u003e"},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":" \u003c/tbody\u003e"},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" \u003c/table\u003e"},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"}],"authorContributionMap":{"domoberzin":96}},{"path":"src/web/app/components/account-requests-table/account-request-table.component.scss","fileType":"scss","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"::ng-deep .highlighted-text {"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":" background-color: yellow;"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"}"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"/* stylelint-disable declaration-block-no-redundant-longhand-properties */"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":".table-responsive {"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":" overflow-y: visible;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" overflow-x: -moz-scrollbars-horizontal; "},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"}"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":".table-responsive \u003e table \u003e thead \u003e tr \u003e th {"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":" white-space: nowrap;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"}"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"/* stylelint-disable property-no-vendor-prefix */"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"::-webkit-scrollbar {"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" -webkit-appearance: none;"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" width: 1px;"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":"}"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":"::-webkit-scrollbar-thumb {"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" border-radius: 0;"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" background-color: rgb(0 0 0 / 50%);"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" box-shadow: 0 0 1px rgb(255 255 255 / 50%);"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":"}"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":"#search-table-account-request {"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" border-collapse: collapse;"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":"}"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":"#search-table-account-request th:last-child, "},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":"#search-table-account-request td:last-child {"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" min-width: 10vw;"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" position: sticky;"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" right: 0;"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" z-index: 1;"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" background-color: #F8F9FA;"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":"}"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":"#search-table-account-request th:last-child::after,"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":"#search-table-account-request td:last-child::after {"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" content: \"\";"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" position: absolute;"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" left: -1px;"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" top: 0;"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" bottom: 0;"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" width: 1px;"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" background: #c8c7c7;"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" z-index: 1;"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":"}"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":"#comment-box {"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" min-height: 5vh;"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" width: max(800px, 35vw);"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" max-width: max-content;"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" word-break: break-word;"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" word-wrap: break-all;"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":"}"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":".dropdown-item {"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" border: none;"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":65}},{"path":"src/web/app/components/account-requests-table/account-request-table.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"import { HttpClientTestingModule } from \u0027@angular/common/http/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":"import { ComponentFixture, TestBed, waitForAsync } from \u0027@angular/core/testing\u0027;"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import { BrowserAnimationsModule } from \u0027@angular/platform-browser/animations\u0027;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import { NgbModal } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import { of, throwError } from \u0027rxjs\u0027;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import { AccountRequestTableRowModel } from \u0027./account-request-table-model\u0027;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import { AccountRequestTableComponent } from \u0027./account-request-table.component\u0027;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import { AccountRequestTableModule } from \u0027./account-request-table.module\u0027;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import { EditRequestModalComponent } from \u0027./admin-edit-request-modal/admin-edit-request-modal.component\u0027;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import {"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" RejectWithReasonModalComponent,"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"} from \u0027./admin-reject-with-reason-modal/admin-reject-with-reason-modal.component\u0027;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import { AccountService } from \u0027../../../services/account.service\u0027;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import { SimpleModalService } from \u0027../../../services/simple-modal.service\u0027;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"import { StatusMessageService } from \u0027../../../services/status-message.service\u0027;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import { createBuilder } from \u0027../../../test-helpers/generic-builder\u0027;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"import { createMockNgbModalRef } from \u0027../../../test-helpers/mock-ngb-modal-ref\u0027;"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"import { AccountRequest, AccountRequestStatus } from \u0027../../../types/api-output\u0027;"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":"import { SimpleModalType } from \u0027../simple-modal/simple-modal-type\u0027;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":"describe(\u0027AccountRequestTableComponent\u0027, () \u003d\u003e {"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" let component: AccountRequestTableComponent;"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" let fixture: ComponentFixture\u003cAccountRequestTableComponent\u003e;"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" let accountService: AccountService;"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" let statusMessageService: StatusMessageService;"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" let simpleModalService: SimpleModalService;"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" let ngbModal: NgbModal;"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" const accountRequestDetailsBuilder \u003d createBuilder\u003cAccountRequestTableRowModel\u003e({"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" id: \u0027\u0027,"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" email: \u0027\u0027,"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" name: \u0027\u0027,"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" instituteAndCountry: \u0027\u0027,"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" registrationLink: \u0027\u0027,"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus.PENDING,"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" comments: \u0027\u0027,"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" registeredAtText: \u0027\u0027,"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" createdAtText: \u0027\u0027,"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" showLinks: false,"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" const DEFAULT_ACCOUNT_REQUEST \u003d accountRequestDetailsBuilder"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" .email(\u0027email\u0027)"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" .name(\u0027name\u0027)"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" .status(AccountRequestStatus.PENDING)"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" .instituteAndCountry(\u0027institute\u0027)"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" .createdAtText(\u0027Tue, 08 Feb 2022, 08:23 AM +00:00\u0027)"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" .comments(\u0027comment\u0027);"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" const resetModalContent \u003d `Are you sure you want to reset the account request for"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003ename\u003c/strong\u003e with email \u003cstrong\u003eemail\u003c/strong\u003e from"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003einstitute\u003c/strong\u003e?"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" An email with the account registration link will also be sent to the instructor.`;"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" const resetModalTitle \u003d \u0027Reset account request for \u003cstrong\u003ename\u003c/strong\u003e?\u0027;"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" const deleteModalContent \u003d `Are you sure you want to \u003cstrong\u003edelete\u003c/strong\u003e the account request for"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003ename\u003c/strong\u003e with email \u003cstrong\u003eemail\u003c/strong\u003e from"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003einstitute\u003c/strong\u003e?`;"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" const deleteModalTitle \u003d \u0027Delete account request for \u003cstrong\u003ename\u003c/strong\u003e?\u0027;"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" beforeEach(waitForAsync(() \u003d\u003e {"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" TestBed.configureTestingModule({"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" declarations: [AccountRequestTableComponent],"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" imports: ["},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" AccountRequestTableModule,"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" BrowserAnimationsModule,"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":" HttpClientTestingModule,"},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" ],"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":" providers: ["},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" AccountService, SimpleModalService,"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" ],"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" }).compileComponents();"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" }));"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" fixture \u003d TestBed.createComponent(AccountRequestTableComponent);"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" accountService \u003d TestBed.inject(AccountService);"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" statusMessageService \u003d TestBed.inject(StatusMessageService);"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" simpleModalService \u003d TestBed.inject(SimpleModalService);"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" ngbModal \u003d TestBed.inject(NgbModal);"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" expect(component).toBeTruthy();"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" it(\u0027should snap with an expanded account requests table\u0027, () \u003d\u003e {"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" const accountRequestResult: AccountRequestTableRowModel \u003d DEFAULT_ACCOUNT_REQUEST.build();"},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d ["},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" accountRequestResult,"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show account request links when expand all button clicked\u0027, () \u003d\u003e {"},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" const accountRequestResult: AccountRequestTableRowModel \u003d DEFAULT_ACCOUNT_REQUEST.build();"},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":" accountRequestResult.status \u003d AccountRequestStatus.APPROVED;"},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" accountRequestResult.registrationLink \u003d \u0027registrationLink\u0027;"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d ["},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":" accountRequestResult,"},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" component.searchString \u003d \u0027test\u0027;"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" const button: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#show-account-request-links\u0027);"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" button.click();"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" expect(component.accountRequests[0].showLinks).toEqual(true);"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" it(\u0027should display account requests with no reset or expand links button\u0027, () \u003d\u003e {"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" it(\u0027should display account requests with reset button and expandable links buttons\u0027,"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" () \u003d\u003e {"},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" const approvedAccountRequestResult: AccountRequestTableRowModel \u003d DEFAULT_ACCOUNT_REQUEST.build();"},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" approvedAccountRequestResult.status \u003d AccountRequestStatus.APPROVED;"},{"lineNumber":128,"author":{"gitId":"domoberzin"},"content":" approvedAccountRequestResult.registrationLink \u003d \u0027registrationLink\u0027;"},{"lineNumber":129,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":" const registeredAccountRequestResult: AccountRequestTableRowModel \u003d DEFAULT_ACCOUNT_REQUEST.build();"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult.status \u003d AccountRequestStatus.REGISTERED;"},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult.registrationLink \u003d \u0027registrationLink\u0027;"},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":" approvedAccountRequestResult,"},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult,"},{"lineNumber":137,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":140,"author":{"gitId":"domoberzin"},"content":" component.searchString \u003d \u0027test\u0027;"},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":145,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show success message when deleting account request is successful\u0027, () \u003d\u003e {"},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d ["},{"lineNumber":147,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":148,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":149,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":150,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":151,"author":{"gitId":"domoberzin"},"content":" const modalSpy \u003d jest.spyOn(simpleModalService, \u0027openConfirmationModal\u0027).mockImplementation(() \u003d\u003e {"},{"lineNumber":152,"author":{"gitId":"domoberzin"},"content":" return createMockNgbModalRef({});"},{"lineNumber":153,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":154,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":155,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027deleteAccountRequest\u0027).mockReturnValue(of({"},{"lineNumber":156,"author":{"gitId":"domoberzin"},"content":" message: \u0027Account request successfully deleted.\u0027,"},{"lineNumber":157,"author":{"gitId":"domoberzin"},"content":" }));"},{"lineNumber":158,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":159,"author":{"gitId":"domoberzin"},"content":" const spyStatusMessageService: any \u003d jest.spyOn(statusMessageService, \u0027showSuccessToast\u0027)"},{"lineNumber":160,"author":{"gitId":"domoberzin"},"content":" .mockImplementation((args: string) \u003d\u003e {"},{"lineNumber":161,"author":{"gitId":"domoberzin"},"content":" expect(args).toEqual(\u0027Account request successfully deleted.\u0027);"},{"lineNumber":162,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":163,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":164,"author":{"gitId":"domoberzin"},"content":" const deleteButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#delete-account-request-0\u0027);"},{"lineNumber":165,"author":{"gitId":"domoberzin"},"content":" deleteButton.click();"},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" expect(spyStatusMessageService).toHaveBeenCalled();"},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledWith(deleteModalTitle, SimpleModalType.DANGER, deleteModalContent);"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":171,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":172,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show error message when deleting account request is unsuccessful\u0027, () \u003d\u003e {"},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d ["},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" const modalSpy \u003d jest.spyOn(simpleModalService, \u0027openConfirmationModal\u0027).mockImplementation(() \u003d\u003e {"},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" return createMockNgbModalRef({});"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027deleteAccountRequest\u0027).mockReturnValue(throwError(() \u003d\u003e ({"},{"lineNumber":184,"author":{"gitId":"domoberzin"},"content":" error: {"},{"lineNumber":185,"author":{"gitId":"domoberzin"},"content":" message: \u0027This is the error message.\u0027,"},{"lineNumber":186,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":187,"author":{"gitId":"domoberzin"},"content":" })));"},{"lineNumber":188,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":189,"author":{"gitId":"domoberzin"},"content":" const spyStatusMessageService: any \u003d jest.spyOn(statusMessageService, \u0027showErrorToast\u0027)"},{"lineNumber":190,"author":{"gitId":"domoberzin"},"content":" .mockImplementation((args: string) \u003d\u003e {"},{"lineNumber":191,"author":{"gitId":"domoberzin"},"content":" expect(args).toEqual(\u0027This is the error message.\u0027);"},{"lineNumber":192,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" const deleteButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#delete-account-request-0\u0027);"},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":" deleteButton.click();"},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":" expect(spyStatusMessageService).toHaveBeenCalled();"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledWith(deleteModalTitle, SimpleModalType.DANGER, deleteModalContent);"},{"lineNumber":200,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":201,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":202,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show success message when resetting account request is successful\u0027, () \u003d\u003e {"},{"lineNumber":203,"author":{"gitId":"domoberzin"},"content":" const registeredAccountRequestResult: AccountRequestTableRowModel \u003d DEFAULT_ACCOUNT_REQUEST.build();"},{"lineNumber":204,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult.status \u003d AccountRequestStatus.REGISTERED;"},{"lineNumber":205,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult.registrationLink \u003d \u0027registrationLink\u0027;"},{"lineNumber":206,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult.registeredAtText \u003d \u0027registeredTime\u0027;"},{"lineNumber":207,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d ["},{"lineNumber":208,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult,"},{"lineNumber":209,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":210,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":211,"author":{"gitId":"domoberzin"},"content":" component.searchString \u003d \u0027test\u0027;"},{"lineNumber":212,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":213,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":214,"author":{"gitId":"domoberzin"},"content":" const modalSpy \u003d jest.spyOn(simpleModalService, \u0027openConfirmationModal\u0027).mockImplementation(() \u003d\u003e {"},{"lineNumber":215,"author":{"gitId":"domoberzin"},"content":" return createMockNgbModalRef({});"},{"lineNumber":216,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":217,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":218,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027resetAccountRequest\u0027).mockReturnValue(of({"},{"lineNumber":219,"author":{"gitId":"domoberzin"},"content":" joinLink: \u0027joinlink\u0027,"},{"lineNumber":220,"author":{"gitId":"domoberzin"},"content":" }));"},{"lineNumber":221,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":222,"author":{"gitId":"domoberzin"},"content":" const spyStatusMessageService \u003d jest.spyOn(statusMessageService, \u0027showSuccessToast\u0027)"},{"lineNumber":223,"author":{"gitId":"domoberzin"},"content":" .mockImplementation((args: string) \u003d\u003e {"},{"lineNumber":224,"author":{"gitId":"domoberzin"},"content":" expect(args)"},{"lineNumber":225,"author":{"gitId":"domoberzin"},"content":" .toEqual(\u0027Reset successful. An email has been sent to email.\u0027);"},{"lineNumber":226,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":227,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":228,"author":{"gitId":"domoberzin"},"content":" const resetButton \u003d fixture.debugElement.nativeElement.querySelector(\u0027#reset-account-request-0\u0027);"},{"lineNumber":229,"author":{"gitId":"domoberzin"},"content":" resetButton.click();"},{"lineNumber":230,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":231,"author":{"gitId":"domoberzin"},"content":" expect(spyStatusMessageService).toHaveBeenCalled();"},{"lineNumber":232,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":233,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledWith(resetModalTitle, SimpleModalType.WARNING, resetModalContent);"},{"lineNumber":234,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":235,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":236,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show error message when resetting account request is unsuccessful\u0027, () \u003d\u003e {"},{"lineNumber":237,"author":{"gitId":"domoberzin"},"content":" const registeredAccountRequestResult: AccountRequestTableRowModel \u003d DEFAULT_ACCOUNT_REQUEST.build();"},{"lineNumber":238,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult.status \u003d AccountRequestStatus.REGISTERED;"},{"lineNumber":239,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult.registrationLink \u003d \u0027registrationLink\u0027;"},{"lineNumber":240,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult.registeredAtText \u003d \u0027registeredTime\u0027;"},{"lineNumber":241,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d ["},{"lineNumber":242,"author":{"gitId":"domoberzin"},"content":" registeredAccountRequestResult,"},{"lineNumber":243,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":244,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":245,"author":{"gitId":"domoberzin"},"content":" component.searchString \u003d \u0027test\u0027;"},{"lineNumber":246,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":247,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":248,"author":{"gitId":"domoberzin"},"content":" const modalSpy \u003d jest.spyOn(simpleModalService, \u0027openConfirmationModal\u0027).mockImplementation(() \u003d\u003e {"},{"lineNumber":249,"author":{"gitId":"domoberzin"},"content":" return createMockNgbModalRef({});"},{"lineNumber":250,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":251,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":252,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027resetAccountRequest\u0027).mockReturnValue(throwError(() \u003d\u003e ({"},{"lineNumber":253,"author":{"gitId":"domoberzin"},"content":" error: {"},{"lineNumber":254,"author":{"gitId":"domoberzin"},"content":" message: \u0027This is the error message.\u0027,"},{"lineNumber":255,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":256,"author":{"gitId":"domoberzin"},"content":" })));"},{"lineNumber":257,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":258,"author":{"gitId":"domoberzin"},"content":" const spyStatusMessageService \u003d jest.spyOn(statusMessageService, \u0027showErrorToast\u0027)"},{"lineNumber":259,"author":{"gitId":"domoberzin"},"content":" .mockImplementation((args: string) \u003d\u003e {"},{"lineNumber":260,"author":{"gitId":"domoberzin"},"content":" expect(args).toEqual(\u0027This is the error message.\u0027);"},{"lineNumber":261,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":262,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":263,"author":{"gitId":"domoberzin"},"content":" const resetButton \u003d fixture.debugElement.nativeElement.querySelector(\u0027#reset-account-request-0\u0027);"},{"lineNumber":264,"author":{"gitId":"domoberzin"},"content":" resetButton.click();"},{"lineNumber":265,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":266,"author":{"gitId":"domoberzin"},"content":" expect(spyStatusMessageService).toHaveBeenCalled();"},{"lineNumber":267,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":268,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledWith(resetModalTitle, SimpleModalType.WARNING, resetModalContent);"},{"lineNumber":269,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":270,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":271,"author":{"gitId":"domoberzin"},"content":" it(\u0027should display comment modal\u0027, () \u003d\u003e {"},{"lineNumber":272,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":273,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":274,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":275,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":276,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":277,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":278,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":279,"author":{"gitId":"domoberzin"},"content":" const modalSpy \u003d jest.spyOn(simpleModalService, \u0027openInformationModal\u0027)"},{"lineNumber":280,"author":{"gitId":"domoberzin"},"content":" .mockReturnValue(createMockNgbModalRef());"},{"lineNumber":281,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":282,"author":{"gitId":"domoberzin"},"content":" const viewCommentButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#view-account-request-0\u0027);"},{"lineNumber":283,"author":{"gitId":"domoberzin"},"content":" viewCommentButton.click();"},{"lineNumber":284,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":285,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledWith(\u0027Comments for \u003cstrong\u003ename\u003c/strong\u003e Request\u0027,"},{"lineNumber":286,"author":{"gitId":"domoberzin"},"content":" SimpleModalType.INFO, \u0027\u003cstrong\u003eComment:\u003c/strong\u003e comment\u0027);"},{"lineNumber":287,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":288,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":289,"author":{"gitId":"domoberzin"},"content":" it(\u0027should display edit modal when edit button is clicked\u0027, () \u003d\u003e {"},{"lineNumber":290,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":291,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":292,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":293,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":294,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":295,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":296,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":297,"author":{"gitId":"domoberzin"},"content":" const mockModalRef \u003d {"},{"lineNumber":298,"author":{"gitId":"domoberzin"},"content":" componentInstance: {},"},{"lineNumber":299,"author":{"gitId":"domoberzin"},"content":" result: Promise.resolve({}),"},{"lineNumber":300,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":301,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":302,"author":{"gitId":"domoberzin"},"content":" const modalSpy \u003d jest.spyOn(ngbModal, \u0027open\u0027).mockReturnValue(mockModalRef as any);"},{"lineNumber":303,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":304,"author":{"gitId":"domoberzin"},"content":" const editButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#edit-account-request-0\u0027);"},{"lineNumber":305,"author":{"gitId":"domoberzin"},"content":" editButton.click();"},{"lineNumber":306,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":307,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledWith(EditRequestModalComponent);"},{"lineNumber":308,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":309,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":310,"author":{"gitId":"domoberzin"},"content":" it(\u0027should display reject modal when reject button is clicked\u0027, () \u003d\u003e {"},{"lineNumber":311,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":312,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":313,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":314,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":315,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":316,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":317,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":318,"author":{"gitId":"domoberzin"},"content":" const mockModalRef \u003d {"},{"lineNumber":319,"author":{"gitId":"domoberzin"},"content":" componentInstance: {},"},{"lineNumber":320,"author":{"gitId":"domoberzin"},"content":" result: Promise.resolve({}),"},{"lineNumber":321,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":322,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":323,"author":{"gitId":"domoberzin"},"content":" const modalSpy \u003d jest.spyOn(ngbModal, \u0027open\u0027).mockReturnValue(mockModalRef as any);"},{"lineNumber":324,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":325,"author":{"gitId":"domoberzin"},"content":" const rejectButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#reject-request-with-reason-0\u0027);"},{"lineNumber":326,"author":{"gitId":"domoberzin"},"content":" rejectButton.click();"},{"lineNumber":327,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":328,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":329,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledWith(RejectWithReasonModalComponent);"},{"lineNumber":330,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":331,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":332,"author":{"gitId":"domoberzin"},"content":" it(\u0027should display error message when rejection was unsuccessful\u0027, () \u003d\u003e {"},{"lineNumber":333,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":334,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":335,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":336,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":337,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":338,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":339,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":340,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027rejectAccountRequest\u0027).mockReturnValue(throwError(() \u003d\u003e ({"},{"lineNumber":341,"author":{"gitId":"domoberzin"},"content":" error: {"},{"lineNumber":342,"author":{"gitId":"domoberzin"},"content":" message: \u0027This is the error message.\u0027,"},{"lineNumber":343,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":344,"author":{"gitId":"domoberzin"},"content":" })));"},{"lineNumber":345,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":346,"author":{"gitId":"domoberzin"},"content":" const spyStatusMessageService \u003d jest.spyOn(statusMessageService, \u0027showErrorToast\u0027)"},{"lineNumber":347,"author":{"gitId":"domoberzin"},"content":" .mockImplementation((args: string) \u003d\u003e {"},{"lineNumber":348,"author":{"gitId":"domoberzin"},"content":" expect(args).toEqual(\u0027This is the error message.\u0027);"},{"lineNumber":349,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":350,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":351,"author":{"gitId":"domoberzin"},"content":" const rejectButton \u003d fixture.debugElement.nativeElement.querySelector(\u0027#reject-request-0\u0027);"},{"lineNumber":352,"author":{"gitId":"domoberzin"},"content":" rejectButton.click();"},{"lineNumber":353,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":354,"author":{"gitId":"domoberzin"},"content":" expect(spyStatusMessageService).toHaveBeenCalled();"},{"lineNumber":355,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":356,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":357,"author":{"gitId":"domoberzin"},"content":" it(\u0027should display error message when approval was unsuccessful\u0027, () \u003d\u003e {"},{"lineNumber":358,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":359,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":360,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":361,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":362,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":363,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":364,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":365,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027approveAccountRequest\u0027).mockReturnValue(throwError(() \u003d\u003e ({"},{"lineNumber":366,"author":{"gitId":"domoberzin"},"content":" error: {"},{"lineNumber":367,"author":{"gitId":"domoberzin"},"content":" message: \u0027This is the error message.\u0027,"},{"lineNumber":368,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":369,"author":{"gitId":"domoberzin"},"content":" })));"},{"lineNumber":370,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":371,"author":{"gitId":"domoberzin"},"content":" const spyStatusMessageService: any \u003d jest.spyOn(statusMessageService, \u0027showErrorToast\u0027)"},{"lineNumber":372,"author":{"gitId":"domoberzin"},"content":" .mockImplementation((args: string) \u003d\u003e {"},{"lineNumber":373,"author":{"gitId":"domoberzin"},"content":" expect(args).toEqual(\u0027This is the error message.\u0027);"},{"lineNumber":374,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":375,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":376,"author":{"gitId":"domoberzin"},"content":" const approveButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#approve-account-request-0\u0027);"},{"lineNumber":377,"author":{"gitId":"domoberzin"},"content":" approveButton.click();"},{"lineNumber":378,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":379,"author":{"gitId":"domoberzin"},"content":" expect(spyStatusMessageService).toHaveBeenCalled();"},{"lineNumber":380,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":381,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":382,"author":{"gitId":"domoberzin"},"content":" it(\u0027should display error message when edit was unsuccessful\u0027, () \u003d\u003e {"},{"lineNumber":383,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":384,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":385,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":386,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":387,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":388,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":389,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":390,"author":{"gitId":"domoberzin"},"content":" const mockModalRef \u003d {"},{"lineNumber":391,"author":{"gitId":"domoberzin"},"content":" componentInstance: {},"},{"lineNumber":392,"author":{"gitId":"domoberzin"},"content":" result: Promise.resolve({}),"},{"lineNumber":393,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":394,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":395,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(ngbModal, \u0027open\u0027).mockReturnValue(mockModalRef as any);"},{"lineNumber":396,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":397,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027editAccountRequest\u0027).mockReturnValue(throwError(() \u003d\u003e ({"},{"lineNumber":398,"author":{"gitId":"domoberzin"},"content":" error: {"},{"lineNumber":399,"author":{"gitId":"domoberzin"},"content":" message: \u0027This is the error message.\u0027,"},{"lineNumber":400,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":401,"author":{"gitId":"domoberzin"},"content":" })));"},{"lineNumber":402,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":403,"author":{"gitId":"domoberzin"},"content":" const spyStatusMessageService \u003d jest.spyOn(statusMessageService, \u0027showErrorToast\u0027)"},{"lineNumber":404,"author":{"gitId":"domoberzin"},"content":" .mockImplementation((args: string) \u003d\u003e {"},{"lineNumber":405,"author":{"gitId":"domoberzin"},"content":" expect(args).toEqual(\u0027This is the error message.\u0027);"},{"lineNumber":406,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":407,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":408,"author":{"gitId":"domoberzin"},"content":" const editButton \u003d fixture.debugElement.nativeElement.querySelector(\u0027#edit-account-request-0\u0027);"},{"lineNumber":409,"author":{"gitId":"domoberzin"},"content":" editButton.click();"},{"lineNumber":410,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":411,"author":{"gitId":"domoberzin"},"content":" expect(spyStatusMessageService).toHaveBeenCalled();"},{"lineNumber":412,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":413,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":414,"author":{"gitId":"domoberzin"},"content":" it(\u0027should update request when edit is succcessful\u0027, () \u003d\u003e {"},{"lineNumber":415,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":416,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":417,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":418,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":419,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":420,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":421,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":422,"author":{"gitId":"domoberzin"},"content":" const mockModalRef \u003d {"},{"lineNumber":423,"author":{"gitId":"domoberzin"},"content":" componentInstance: {},"},{"lineNumber":424,"author":{"gitId":"domoberzin"},"content":" result: Promise.resolve({}),"},{"lineNumber":425,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":426,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":427,"author":{"gitId":"domoberzin"},"content":" const modalSpy \u003d jest.spyOn(ngbModal, \u0027open\u0027).mockReturnValue(mockModalRef as any);"},{"lineNumber":428,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":429,"author":{"gitId":"domoberzin"},"content":" const editedAccountRequest : AccountRequest \u003d {"},{"lineNumber":430,"author":{"gitId":"domoberzin"},"content":" id: \u0027id\u0027,"},{"lineNumber":431,"author":{"gitId":"domoberzin"},"content":" comments: \u0027new comment\u0027,"},{"lineNumber":432,"author":{"gitId":"domoberzin"},"content":" email: \u0027new email\u0027,"},{"lineNumber":433,"author":{"gitId":"domoberzin"},"content":" institute: \u0027new institute\u0027,"},{"lineNumber":434,"author":{"gitId":"domoberzin"},"content":" registrationKey: \u0027registration key\u0027,"},{"lineNumber":435,"author":{"gitId":"domoberzin"},"content":" name: \u0027new name\u0027,"},{"lineNumber":436,"author":{"gitId":"domoberzin"},"content":" createdAt: 1,"},{"lineNumber":437,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus.PENDING,"},{"lineNumber":438,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":439,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":440,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027editAccountRequest\u0027).mockReturnValue(of(editedAccountRequest));"},{"lineNumber":441,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":442,"author":{"gitId":"domoberzin"},"content":" const editButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#edit-account-request-0\u0027);"},{"lineNumber":443,"author":{"gitId":"domoberzin"},"content":" editButton.click();"},{"lineNumber":444,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":445,"author":{"gitId":"domoberzin"},"content":" expect(modalSpy).toHaveBeenCalledWith(EditRequestModalComponent);"},{"lineNumber":446,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":447,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":448,"author":{"gitId":"domoberzin"},"content":" expect(component.accountRequests[0].comments).toEqual(\u0027new comment\u0027);"},{"lineNumber":449,"author":{"gitId":"domoberzin"},"content":" expect(component.accountRequests[0].email).toEqual(\u0027new email\u0027);"},{"lineNumber":450,"author":{"gitId":"domoberzin"},"content":" expect(component.accountRequests[0].instituteAndCountry).toEqual(\u0027new institute\u0027);"},{"lineNumber":451,"author":{"gitId":"domoberzin"},"content":" expect(component.accountRequests[0].name).toEqual(\u0027new name\u0027);"},{"lineNumber":452,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":453,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":454,"author":{"gitId":"domoberzin"},"content":" it(\u0027should update status when approval is succcessful\u0027, () \u003d\u003e {"},{"lineNumber":455,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":456,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":457,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":458,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":459,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":460,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":461,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":462,"author":{"gitId":"domoberzin"},"content":" const approvedRequest : AccountRequest \u003d {"},{"lineNumber":463,"author":{"gitId":"domoberzin"},"content":" id: component.accountRequests[0].id,"},{"lineNumber":464,"author":{"gitId":"domoberzin"},"content":" comments: component.accountRequests[0].comments,"},{"lineNumber":465,"author":{"gitId":"domoberzin"},"content":" email: component.accountRequests[0].email,"},{"lineNumber":466,"author":{"gitId":"domoberzin"},"content":" institute: component.accountRequests[0].instituteAndCountry,"},{"lineNumber":467,"author":{"gitId":"domoberzin"},"content":" registrationKey: \u0027registration key\u0027,"},{"lineNumber":468,"author":{"gitId":"domoberzin"},"content":" name: component.accountRequests[0].name,"},{"lineNumber":469,"author":{"gitId":"domoberzin"},"content":" createdAt: 1,"},{"lineNumber":470,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus.APPROVED,"},{"lineNumber":471,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":472,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":473,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027approveAccountRequest\u0027).mockReturnValue(of(approvedRequest));"},{"lineNumber":474,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":475,"author":{"gitId":"domoberzin"},"content":" const approveButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#approve-account-request-0\u0027);"},{"lineNumber":476,"author":{"gitId":"domoberzin"},"content":" approveButton.click();"},{"lineNumber":477,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":478,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":479,"author":{"gitId":"domoberzin"},"content":" expect(component.accountRequests[0].status).toEqual(AccountRequestStatus.APPROVED);"},{"lineNumber":480,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":481,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":482,"author":{"gitId":"domoberzin"},"content":" it(\u0027should update status when rejection is succcessful\u0027, () \u003d\u003e {"},{"lineNumber":483,"author":{"gitId":"domoberzin"},"content":" const accountRequestResults: AccountRequestTableRowModel[] \u003d ["},{"lineNumber":484,"author":{"gitId":"domoberzin"},"content":" DEFAULT_ACCOUNT_REQUEST.build(),"},{"lineNumber":485,"author":{"gitId":"domoberzin"},"content":" ];"},{"lineNumber":486,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":487,"author":{"gitId":"domoberzin"},"content":" component.accountRequests \u003d accountRequestResults;"},{"lineNumber":488,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":489,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":490,"author":{"gitId":"domoberzin"},"content":" const rejectedRequest : AccountRequest \u003d {"},{"lineNumber":491,"author":{"gitId":"domoberzin"},"content":" id: component.accountRequests[0].id,"},{"lineNumber":492,"author":{"gitId":"domoberzin"},"content":" comments: component.accountRequests[0].comments,"},{"lineNumber":493,"author":{"gitId":"domoberzin"},"content":" email: component.accountRequests[0].email,"},{"lineNumber":494,"author":{"gitId":"domoberzin"},"content":" institute: component.accountRequests[0].instituteAndCountry,"},{"lineNumber":495,"author":{"gitId":"domoberzin"},"content":" registrationKey: \u0027registration key\u0027,"},{"lineNumber":496,"author":{"gitId":"domoberzin"},"content":" name: component.accountRequests[0].name,"},{"lineNumber":497,"author":{"gitId":"domoberzin"},"content":" createdAt: 1,"},{"lineNumber":498,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus.REJECTED,"},{"lineNumber":499,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":500,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":501,"author":{"gitId":"domoberzin"},"content":" jest.spyOn(accountService, \u0027rejectAccountRequest\u0027).mockReturnValue(of(rejectedRequest));"},{"lineNumber":502,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":503,"author":{"gitId":"domoberzin"},"content":" const rejectButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#reject-request-0\u0027);"},{"lineNumber":504,"author":{"gitId":"domoberzin"},"content":" rejectButton.click();"},{"lineNumber":505,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":506,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":507,"author":{"gitId":"domoberzin"},"content":" expect(component.accountRequests[0].status).toEqual(AccountRequestStatus.REJECTED);"},{"lineNumber":508,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":509,"author":{"gitId":"domoberzin"},"content":"});"}],"authorContributionMap":{"domoberzin":509}},{"path":"src/web/app/components/account-requests-table/account-request-table.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"import { Component, Input } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":"import { NgbModalRef, NgbModal } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import { AccountRequestTableRowModel } from \u0027./account-request-table-model\u0027;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import { EditRequestModalComponentResult } from \u0027./admin-edit-request-modal/admin-edit-request-modal-model\u0027;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import { EditRequestModalComponent } from \u0027./admin-edit-request-modal/admin-edit-request-modal.component\u0027;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import {"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":" RejectWithReasonModalComponentResult,"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"} from \u0027./admin-reject-with-reason-modal/admin-reject-with-reason-modal-model\u0027;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"import {"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" RejectWithReasonModalComponent,"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"} from \u0027./admin-reject-with-reason-modal/admin-reject-with-reason-modal.component\u0027;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"import { AccountService } from \u0027../../../services/account.service\u0027;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import { SimpleModalService } from \u0027../../../services/simple-modal.service\u0027;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import { StatusMessageService } from \u0027../../../services/status-message.service\u0027;"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":"import { AccountRequest, MessageOutput } from \u0027../../../types/api-output\u0027;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import { ErrorMessageOutput } from \u0027../../error-message-output\u0027;"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":"import { SimpleModalType } from \u0027../simple-modal/simple-modal-type\u0027;"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"import { collapseAnim } from \u0027../teammates-common/collapse-anim\u0027;"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" * Account requests table component."},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":"@Component({"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" selector: \u0027tm-account-request-table\u0027,"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" templateUrl: \u0027./account-request-table.component.html\u0027,"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" styleUrls: [\u0027./account-request-table.component.scss\u0027],"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" animations: [collapseAnim],"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":"})"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":"export class AccountRequestTableComponent {"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" @Input()"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" accountRequests: AccountRequestTableRowModel[] \u003d [];"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" @Input()"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" searchString \u003d \u0027\u0027;"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" constructor("},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" private statusMessageService: StatusMessageService,"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" private simpleModalService: SimpleModalService,"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" private accountService: AccountService,"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" private ngbModal: NgbModal,"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" ) {}"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" * Shows all account requests\u0027 links in the page."},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" showAllAccountRequestsLinks(): void {"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" for (const accountRequest of this.accountRequests) {"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" accountRequest.showLinks \u003d true;"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" * Hides all account requests\u0027 links in the page."},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" hideAllAccountRequestsLinks(): void {"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" for (const accountRequest of this.accountRequests) {"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" accountRequest.showLinks \u003d false;"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" editAccountRequest(accountRequest: AccountRequestTableRowModel): void {"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" const modalRef: NgbModalRef \u003d this.ngbModal.open(EditRequestModalComponent);"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" modalRef.componentInstance.accountRequestName \u003d accountRequest.name;"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":" modalRef.componentInstance.accountRequestEmail \u003d accountRequest.email;"},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" modalRef.componentInstance.accountRequestInstitution \u003d accountRequest.instituteAndCountry;"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":" modalRef.componentInstance.accountRequestComments \u003d accountRequest.comments;"},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" modalRef.result.then((res: EditRequestModalComponentResult) \u003d\u003e {"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" this.accountService.editAccountRequest("},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" accountRequest.id,"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" res.accountRequestName,"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" res.accountRequestEmail,"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" res.accountRequestInstitution,"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" accountRequest.status,"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" res.accountRequestComment)"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" .subscribe({"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" next: (resp: AccountRequest) \u003d\u003e {"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":" accountRequest.comments \u003d resp.comments ?? \u0027\u0027;"},{"lineNumber":81,"author":{"gitId":"domoberzin"},"content":" accountRequest.name \u003d resp.name;"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" accountRequest.email \u003d resp.email;"},{"lineNumber":83,"author":{"gitId":"domoberzin"},"content":" accountRequest.instituteAndCountry \u003d resp.institute;"},{"lineNumber":84,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showSuccessToast(\u0027Account request was successfully updated.\u0027);"},{"lineNumber":85,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":88,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":89,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":90,"author":{"gitId":"domoberzin"},"content":" }, () \u003d\u003e {});"},{"lineNumber":91,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":92,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":93,"author":{"gitId":"domoberzin"},"content":" approveAccountRequest(accountRequest: AccountRequestTableRowModel): void {"},{"lineNumber":94,"author":{"gitId":"domoberzin"},"content":" this.accountService.approveAccountRequest(accountRequest.id, accountRequest.name,"},{"lineNumber":95,"author":{"gitId":"domoberzin"},"content":" accountRequest.email, accountRequest.instituteAndCountry)"},{"lineNumber":96,"author":{"gitId":"domoberzin"},"content":" .subscribe({"},{"lineNumber":97,"author":{"gitId":"domoberzin"},"content":" next: (resp : AccountRequest) \u003d\u003e {"},{"lineNumber":98,"author":{"gitId":"domoberzin"},"content":" accountRequest.status \u003d resp.status;"},{"lineNumber":99,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showSuccessToast("},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":" `Account request was successfully approved. Email has been sent to ${accountRequest.email}.`,"},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" );"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" resetAccountRequest(accountRequest: AccountRequestTableRowModel): void {"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" const modalContent \u003d `Are you sure you want to reset the account request for"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003e${accountRequest.name}\u003c/strong\u003e with email \u003cstrong\u003e${accountRequest.email}\u003c/strong\u003e from"},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003e${accountRequest.instituteAndCountry}\u003c/strong\u003e?"},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" An email with the account registration link will also be sent to the instructor.`;"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" const modalRef: NgbModalRef \u003d this.simpleModalService.openConfirmationModal("},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" `Reset account request for \u003cstrong\u003e${accountRequest.name}\u003c/strong\u003e?`, SimpleModalType.WARNING, modalContent);"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":" modalRef.result.then(() \u003d\u003e {"},{"lineNumber":118,"author":{"gitId":"dishenggg"},"content":" this.accountService.resetAccountRequest(accountRequest.id)"},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" .subscribe({"},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" next: () \u003d\u003e {"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService"},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" .showSuccessToast(`Reset successful. An email has been sent to ${accountRequest.email}.`);"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":" accountRequest.registeredAtText \u003d \u0027\u0027;"},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":128,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":129,"author":{"gitId":"domoberzin"},"content":" }, () \u003d\u003e {});"},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":" deleteAccountRequest(accountRequest: AccountRequestTableRowModel): void {"},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" const modalContent: string \u003d `Are you sure you want to \u003cstrong\u003edelete\u003c/strong\u003e the account request for"},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003e${accountRequest.name}\u003c/strong\u003e with email \u003cstrong\u003e${accountRequest.email}\u003c/strong\u003e from"},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":" \u003cstrong\u003e${accountRequest.instituteAndCountry}\u003c/strong\u003e?`;"},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" const modalRef: NgbModalRef \u003d this.simpleModalService.openConfirmationModal("},{"lineNumber":137,"author":{"gitId":"domoberzin"},"content":" `Delete account request for \u003cstrong\u003e${accountRequest.name}\u003c/strong\u003e?`, SimpleModalType.DANGER, modalContent);"},{"lineNumber":138,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":139,"author":{"gitId":"domoberzin"},"content":" modalRef.result.then(() \u003d\u003e {"},{"lineNumber":140,"author":{"gitId":"dishenggg"},"content":" this.accountService.deleteAccountRequest(accountRequest.id)"},{"lineNumber":141,"author":{"gitId":"domoberzin"},"content":" .subscribe({"},{"lineNumber":142,"author":{"gitId":"domoberzin"},"content":" next: (resp: MessageOutput) \u003d\u003e {"},{"lineNumber":143,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showSuccessToast(resp.message);"},{"lineNumber":144,"author":{"gitId":"domoberzin"},"content":" this.accountRequests \u003d this.accountRequests.filter((x: AccountRequestTableRowModel) \u003d\u003e x !\u003d\u003d accountRequest);"},{"lineNumber":145,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":146,"author":{"gitId":"domoberzin"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":147,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":148,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":149,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":150,"author":{"gitId":"domoberzin"},"content":" }, () \u003d\u003e {});"},{"lineNumber":151,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":152,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":153,"author":{"gitId":"domoberzin"},"content":" viewAccountRequest(accountRequest: AccountRequestTableRowModel): void {"},{"lineNumber":154,"author":{"gitId":"domoberzin"},"content":" const modalContent: string \u003d `\u003cstrong\u003eComment:\u003c/strong\u003e ${accountRequest.comments || \u0027No comments\u0027}`;"},{"lineNumber":155,"author":{"gitId":"domoberzin"},"content":" const modalRef: NgbModalRef \u003d this.simpleModalService.openInformationModal("},{"lineNumber":156,"author":{"gitId":"domoberzin"},"content":" `Comments for \u003cstrong\u003e${accountRequest.name}\u003c/strong\u003e Request`, SimpleModalType.INFO, modalContent);"},{"lineNumber":157,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":158,"author":{"gitId":"domoberzin"},"content":" modalRef.result.then(() \u003d\u003e {}, () \u003d\u003e {});"},{"lineNumber":159,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":160,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":161,"author":{"gitId":"domoberzin"},"content":" rejectAccountRequest(accountRequest: AccountRequestTableRowModel): void {"},{"lineNumber":162,"author":{"gitId":"domoberzin"},"content":" this.accountService.rejectAccountRequest(accountRequest.id)"},{"lineNumber":163,"author":{"gitId":"domoberzin"},"content":" .subscribe({"},{"lineNumber":164,"author":{"gitId":"domoberzin"},"content":" next: (resp : AccountRequest) \u003d\u003e {"},{"lineNumber":165,"author":{"gitId":"domoberzin"},"content":" accountRequest.status \u003d resp.status;"},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showSuccessToast(\u0027Account request was successfully rejected.\u0027);"},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":171,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":172,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":" rejectAccountRequestWithReason(accountRequest: AccountRequestTableRowModel): void {"},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" const modalRef: NgbModalRef \u003d this.ngbModal.open(RejectWithReasonModalComponent);"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":" modalRef.componentInstance.accountRequestName \u003d accountRequest.name;"},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" modalRef.componentInstance.accountRequestEmail \u003d accountRequest.email;"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" modalRef.result.then((res: RejectWithReasonModalComponentResult) \u003d\u003e {"},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" this.accountService.rejectAccountRequest(accountRequest.id,"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":" res.rejectionReasonTitle, res.rejectionReasonBody)"},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":" .subscribe({"},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":" next: (resp: AccountRequest) \u003d\u003e {"},{"lineNumber":184,"author":{"gitId":"domoberzin"},"content":" accountRequest.status \u003d resp.status;"},{"lineNumber":185,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showSuccessToast("},{"lineNumber":186,"author":{"gitId":"domoberzin"},"content":" `Account request was successfully rejected. Email has been sent to ${accountRequest.email}.`,"},{"lineNumber":187,"author":{"gitId":"domoberzin"},"content":" );"},{"lineNumber":188,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":189,"author":{"gitId":"domoberzin"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":190,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":191,"author":{"gitId":"domoberzin"},"content":" },"},{"lineNumber":192,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":193,"author":{"gitId":"domoberzin"},"content":" }, () \u003d\u003e {});"},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":195,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":196,"author":{"gitId":"domoberzin"},"content":" trackAccountRequest(accountRequest: AccountRequestTableRowModel): string {"},{"lineNumber":197,"author":{"gitId":"domoberzin"},"content":" return accountRequest.id;"},{"lineNumber":198,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":199,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":197,"dishenggg":2}},{"path":"src/web/app/components/account-requests-table/account-request-table.module.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"import { CommonModule } from \u0027@angular/common\u0027;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":"import { NgModule } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import { FormsModule } from \u0027@angular/forms\u0027;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import { NgbTooltipModule, NgbDropdownModule } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import { AccountRequestTableComponent } from \u0027./account-request-table.component\u0027;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import { EditRequestModalComponent } from \u0027./admin-edit-request-modal/admin-edit-request-modal.component\u0027;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import {"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" RejectWithReasonModalComponent,"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"} from \u0027./admin-reject-with-reason-modal/admin-reject-with-reason-modal.component\u0027;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import { Pipes } from \u0027../../pipes/pipes.module\u0027;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import { RichTextEditorModule } from \u0027../rich-text-editor/rich-text-editor.module\u0027;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":" * Module for account requests table."},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"@NgModule({"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" declarations: ["},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" AccountRequestTableComponent,"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" EditRequestModalComponent,"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" RejectWithReasonModalComponent,"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" ],"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" exports: ["},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" AccountRequestTableComponent,"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" ],"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" imports: ["},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" CommonModule,"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" FormsModule,"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" NgbTooltipModule,"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" NgbDropdownModule,"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" Pipes,"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" RichTextEditorModule,"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" ],"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":"})"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":"export class AccountRequestTableModule { }"}],"authorContributionMap":{"domoberzin":34}},{"path":"src/web/app/components/account-requests-table/admin-edit-request-modal/admin-edit-request-modal-model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":" * Result of {@link EditRequestModalComponent}"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"export interface EditRequestModalComponentResult {"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":" accountRequestName: string;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":" accountRequestEmail: string;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":" accountRequestInstitution: string;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" accountRequestComment: string;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":9}},{"path":"src/web/app/components/account-requests-table/admin-edit-request-modal/admin-edit-request-modal.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"\u003cdiv class\u003d\"modal-header bg-primary\"\u003e"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":" \u003ch5 class\u003d\"modal-title text-white\"\u003e"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003eEdit Account Request for {{ accountRequestName }}\u003c/div\u003e"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":" \u003c/h5\u003e"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn-close\" (click)\u003d\"activeModal.dismiss()\"\u003e\u003c/button\u003e"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":" \u003cdiv id\u003d\"reject-account-request-modal\" class\u003d\"modal-body\"\u003e"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003e"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":" \u003clabel\u003e\u003cb\u003eName:\u003c/b\u003e\u003c/label\u003e"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" \u003cinput id\u003d\"request-name\" type\u003d\"text\" class\u003d\"form-control\" value\u003d\"{{ accountRequestName }}\" (input)\u003d\"accountRequestName \u003d $event.target.value\"\u003e"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003e"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":" \u003clabel\u003e\u003cb\u003eEmail:\u003c/b\u003e\u003c/label\u003e"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":" \u003cinput id\u003d\"request-email\" type\u003d\"text\" class\u003d\"form-control\" value\u003d\"{{ accountRequestEmail }}\" (input)\u003d\"accountRequestEmail \u003d $event.target.value\"\u003e"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003e"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" \u003clabel\u003e\u003cb\u003eInstitution, Country:\u003c/b\u003e\u003c/label\u003e"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" \u003cinput id\u003d\"request-institution\" type\u003d\"text\" class\u003d\"form-control\" value\u003d\"{{ accountRequestInstitution }}\" (input)\u003d\"accountRequestInstitution \u003d $event.target.value\"\u003e"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"row\"\u003e"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003e"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" \u003clabel\u003e\u003cb\u003eComments:\u003c/b\u003e\u003c/label\u003e"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"form-group\"\u003e"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" \u003ctextarea id\u003d\"request-comments\" class\u003d\"form-control\" rows\u003d\"5\" value\u003d\"{{ accountRequestComments }}\" (input)\u003d\"accountRequestComments \u003d $event.target.value\"\u003e\u003c/textarea\u003e"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"modal-footer\"\u003e"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn btn-light\" (click)\u003d\"activeModal.dismiss()\"\u003eCancel\u003c/button\u003e"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"btn-confirm-edit-request\" type\u003d\"button\" class\u003d\"btn btn-primary\" (click)\u003d\"edit()\"\u003e"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" Save"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" \u003c/button\u003e"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"}],"authorContributionMap":{"domoberzin":34}},{"path":"src/web/app/components/account-requests-table/admin-edit-request-modal/admin-edit-request-modal.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"import { HttpClientTestingModule } from \u0027@angular/common/http/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":"import { ComponentFixture, TestBed, waitForAsync } from \u0027@angular/core/testing\u0027;"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import { NgbActiveModal } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import { EditRequestModalComponent } from \u0027./admin-edit-request-modal.component\u0027;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"describe(\u0027RejectWithReasonModal\u0027, () \u003d\u003e {"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":" let fixture: ComponentFixture\u003cEditRequestModalComponent\u003e;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" let component: EditRequestModalComponent;"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" beforeEach(waitForAsync(() \u003d\u003e {"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" TestBed.configureTestingModule({"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":" declarations: [],"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":" imports: ["},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":" HttpClientTestingModule,"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" ],"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" providers: [NgbActiveModal],"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" })"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" .compileComponents();"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" }));"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" fixture \u003d TestBed.createComponent(EditRequestModalComponent);"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" expect(component).toBeTruthy();"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show empty fields\u0027, () \u003d\u003e {"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show populated data\u0027, () \u003d\u003e {"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" component.accountRequestName \u003d \u0027John Doe\u0027;"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" component.accountRequestEmail \u003d \u0027johndoe@email.com\u0027;"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" component.accountRequestInstitution \u003d \u0027NUS\u0027;"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" component.accountRequestComments \u003d \u0027Comments\u0027;"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" it(\u0027should close modal with data\u0027, () \u003d\u003e {"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" const spyActiveModal \u003d jest.spyOn(component.activeModal, \u0027close\u0027);"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" component.accountRequestName \u003d \u0027John Doe\u0027;"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" component.accountRequestEmail \u003d \u0027johndoe@email.com\u0027;"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" component.accountRequestInstitution \u003d \u0027NUS\u0027;"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" component.accountRequestComments \u003d \u0027Comments\u0027;"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" component.edit();"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" expect(spyActiveModal).toHaveBeenCalled();"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":" expect(spyActiveModal).toHaveBeenCalledWith({"},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" accountRequestName: \u0027John Doe\u0027,"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" accountRequestEmail: \u0027johndoe@email.com\u0027,"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" accountRequestInstitution: \u0027NUS\u0027,"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" accountRequestComment: \u0027Comments\u0027,"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":"});"}],"authorContributionMap":{"domoberzin":60}},{"path":"src/web/app/components/account-requests-table/admin-edit-request-modal/admin-edit-request-modal.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"import { Component, Input } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":"import { NgbActiveModal } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import { EditRequestModalComponentResult } from \u0027./admin-edit-request-modal-model\u0027;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":" * Modal to select reject account requests with reason."},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"@Component({"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":" selector: \u0027tm-edit-request-modal\u0027,"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" templateUrl: \u0027./admin-edit-request-modal.component.html\u0027,"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" styleUrls: [\u0027./admin-edit-request-modal.component.scss\u0027],"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":"})"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"export class EditRequestModalComponent {"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" @Input()"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" accountRequestName: string \u003d \u0027\u0027;"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" @Input()"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" accountRequestEmail: string \u003d \u0027\u0027;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" @Input()"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" accountRequestInstitution: string \u003d \u0027\u0027;"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" @Input()"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" accountRequestComments: string \u003d \u0027\u0027;"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" constructor(public activeModal: NgbActiveModal) {}"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" * Fires the edit event."},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" edit(): void {"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" const result: EditRequestModalComponentResult \u003d {"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" accountRequestName: this.accountRequestName,"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" accountRequestEmail: this.accountRequestEmail,"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" accountRequestInstitution: this.accountRequestInstitution,"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" accountRequestComment: this.accountRequestComments,"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" this.activeModal.close(result);"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":40}},{"path":"src/web/app/components/account-requests-table/admin-reject-with-reason-modal/admin-reject-with-reason-modal-model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"export interface RejectWithReasonModalComponentResult {"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":" rejectionReasonTitle: string;"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":" rejectionReasonBody: string;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":4}},{"path":"src/web/app/components/account-requests-table/admin-reject-with-reason-modal/admin-reject-with-reason-modal.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"\u003cdiv class\u003d\"modal-header bg-warning\"\u003e"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":" \u003ch5 class\u003d\"modal-title\"\u003e"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003eReject Account Request for {{ accountRequestName }} With Reason\u003c/div\u003e"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":" \u003c/h5\u003e"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn-close\" (click)\u003d\"activeModal.dismiss()\"\u003e\u003c/button\u003e"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"\u003c/div\u003e"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"\u003cdiv id\u003d\"reject-account-request-modal\" class\u003d\"modal-body\"\u003e"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"row\"\u003e"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003e"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" \u003clabel\u003e\u003cb\u003eRejection Message Title:\u003c/b\u003e\u003c/label\u003e"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":" \u003cdiv class\u003d\"form-group\"\u003e"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":" \u003cinput id\u003d\"rejection-reason-title\" type\u003d\"text\" class\u003d\"form-control\" rows\u003d\"5\" value\u003d\"{{ rejectionReasonTitle }}\" (input)\u003d\"rejectionReasonTitle \u003d $event.target.value\"\u003e"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" \u003cdiv\u003e"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" \u003clabel\u003e\u003cb\u003eRejection Message Body:\u003c/b\u003e\u003c/label\u003e"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" \u003c/div\u003e"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" \u003ctm-rich-text-editor id\u003d\"rejection-reason-body\" [richText]\u003d\"rejectionReasonBody\" (richTextChange)\u003d\"onRejectionReasonBodyChange($event)\"\u003e\u003c/tm-rich-text-editor\u003e"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":"\u003c/div\u003e"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":"\u003cdiv class\u003d\"modal-footer\"\u003e"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"btn-cancel-reject-request\" type\u003d\"button\" class\u003d\"btn btn-light\" (click)\u003d\"activeModal.dismiss()\"\u003eCancel\u003c/button\u003e"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":" \u003cbutton id\u003d\"btn-confirm-reject-request\" type\u003d\"button\" class\u003d\"btn btn-warning\" (click)\u003d\"reject()\"\u003e"},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" Reject"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" \u003c/button\u003e"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"domoberzin":26}},{"path":"src/web/app/components/account-requests-table/admin-reject-with-reason-modal/admin-reject-with-reason-modal.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"import { HttpClientTestingModule } from \u0027@angular/common/http/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":"import { ComponentFixture, TestBed, waitForAsync } from \u0027@angular/core/testing\u0027;"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import { By } from \u0027@angular/platform-browser\u0027;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import { NgbActiveModal } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import { RejectWithReasonModalComponent } from \u0027./admin-reject-with-reason-modal.component\u0027;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":"import { StatusMessageService } from \u0027../../../../services/status-message.service\u0027;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"describe(\u0027RejectWithReasonModal\u0027, () \u003d\u003e {"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":" let statusMessageService: StatusMessageService;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" let fixture: ComponentFixture\u003cRejectWithReasonModalComponent\u003e;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" let component: RejectWithReasonModalComponent;"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":" beforeEach(waitForAsync(() \u003d\u003e {"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":" TestBed.configureTestingModule({"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" declarations: [],"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" imports: ["},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" HttpClientTestingModule,"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" ],"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" providers: [NgbActiveModal, StatusMessageService],"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":" })"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" .compileComponents();"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" }));"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" fixture \u003d TestBed.createComponent(RejectWithReasonModalComponent);"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" statusMessageService \u003d TestBed.inject(StatusMessageService);"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" expect(component).toBeTruthy();"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show empty title and body\u0027, () \u003d\u003e {"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show error message when title is empty upon submitting\u0027, () \u003d\u003e {"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" component.rejectionReasonTitle \u003d \u0027\u0027;"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" const spyStatusMessageService \u003d jest.spyOn(statusMessageService, \u0027showErrorToast\u0027)"},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" .mockImplementation((args: string) \u003d\u003e {"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" expect(args).toEqual(\u0027Please provide a title for the rejection email.\u0027);"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" const rejectButton: any \u003d fixture.debugElement.query(By.css(\u0027#btn-confirm-reject-request\u0027));"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":" rejectButton.nativeElement.click();"},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" expect(spyStatusMessageService).toHaveBeenCalled();"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" it(\u0027should show error message when body is empty upon submitting\u0027, () \u003d\u003e {"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" component.rejectionReasonBody \u003d \u0027\u0027;"},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":" const spyStatusMessageService \u003d jest.spyOn(statusMessageService, \u0027showErrorToast\u0027)"},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" .mockImplementation((args: string) \u003d\u003e {"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" expect(args).toEqual(\u0027Please provide an email body for the rejection email.\u0027);"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":" const rejectButton: any \u003d fixture.debugElement.query(By.css(\u0027#btn-confirm-reject-request\u0027));"},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" rejectButton.nativeElement.click();"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" expect(spyStatusMessageService).toHaveBeenCalled();"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":" it(\u0027should close modal with data\u0027, () \u003d\u003e {"},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" const spyActiveModal \u003d jest.spyOn(component.activeModal, \u0027close\u0027);"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" component.rejectionReasonTitle \u003d \u0027Rejection Title\u0027;"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" component.rejectionReasonBody \u003d \u0027Rejection Body\u0027;"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" fixture.detectChanges();"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":" component.reject();"},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" expect(spyActiveModal).toHaveBeenCalled();"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" expect(spyActiveModal).toHaveBeenCalledWith({"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":" rejectionReasonTitle: \u0027Rejection Title\u0027,"},{"lineNumber":77,"author":{"gitId":"domoberzin"},"content":" rejectionReasonBody: \u0027Rejection Body\u0027,"},{"lineNumber":78,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":79,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":80,"author":{"gitId":"domoberzin"},"content":"});"}],"authorContributionMap":{"domoberzin":80}},{"path":"src/web/app/components/account-requests-table/admin-reject-with-reason-modal/admin-reject-with-reason-modal.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"domoberzin"},"content":"import { Component, Input, OnInit } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"domoberzin"},"content":"import { NgbActiveModal } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":3,"author":{"gitId":"domoberzin"},"content":"import { RejectWithReasonModalComponentResult } from \u0027./admin-reject-with-reason-modal-model\u0027;"},{"lineNumber":4,"author":{"gitId":"domoberzin"},"content":"import { environment } from \u0027../../../../environments/environment\u0027;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import { StatusMessageService } from \u0027../../../../services/status-message.service\u0027;"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"/**"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" * Modal to select reject account requests with reason."},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"@Component({"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" selector: \u0027tm-reject-with-reason-modal\u0027,"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":" templateUrl: \u0027./admin-reject-with-reason-modal.component.html\u0027,"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":" styleUrls: [\u0027./admin-reject-with-reason-modal.component.scss\u0027],"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"})"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"export class RejectWithReasonModalComponent implements OnInit {"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":" @Input()"},{"lineNumber":19,"author":{"gitId":"domoberzin"},"content":" accountRequestName: string \u003d \u0027\u0027;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":" @Input()"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" accountRequestEmail: string \u003d \u0027\u0027;"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":24,"author":{"gitId":"domoberzin"},"content":" rejectionReasonBody: string \u003d \u0027\u003cp\u003eHi, {accountRequestName} \u003c/p\u003e\\n\\n\u0027"},{"lineNumber":25,"author":{"gitId":"domoberzin"},"content":" + \u0027\u003cp\u003eThanks for your interest in using TEAMMATES. \u0027"},{"lineNumber":26,"author":{"gitId":"domoberzin"},"content":" + \u0027We are unable to create a TEAMMATES instructor account for you.\u003c/p\u003e\u0027"},{"lineNumber":27,"author":{"gitId":"domoberzin"},"content":" + \u0027\u003cp\u003e\u003cstrong\u003eReason:\u003c/strong\u003e The email address you provided is not an \u0026#39;official\u0026#39; \u0027"},{"lineNumber":28,"author":{"gitId":"domoberzin"},"content":" + \u0027email address provided by your institution.\u003cbr /\u003e\u0027"},{"lineNumber":29,"author":{"gitId":"domoberzin"},"content":" + \u0027\u003cstrong\u003eRemedy:\u003c/strong\u003e Please re-submit an account request with your \u0026#39;official\u0026#39; \u0027"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" + \u0027institution email address.\u003c/p\u003e\\n\\n\u0027"},{"lineNumber":31,"author":{"gitId":"domoberzin"},"content":" + \u0027\u003cp\u003e\u003cstrong\u003eReason:\u003c/strong\u003e The email address you have provided seems like it belongs to a student \u0027"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" + \u0027(i.e., not a staff member) of your institution.\u003cbr /\u003e\u0027"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" + \u0027\u003cstrong\u003eRemedy:\u003c/strong\u003e If you are a student but you still need an instructor account, \u0027"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" + \u0027please send your justification to {supportEmail}\u003c/p\u003e\\n\\n\u0027"},{"lineNumber":35,"author":{"gitId":"domoberzin"},"content":" + \u0027\u003cp\u003e\u003cstrong\u003eReason:\u003c/strong\u003e You already have an account for this email address and this institution.\u003cbr /\u003e\u0027"},{"lineNumber":36,"author":{"gitId":"domoberzin"},"content":" + \u0027\u003cstrong\u003eRemedy:\u003c/strong\u003e You can login to TEAMMATES using your Google account {existingEmail} \u003c/p\u003e\\n\\n\u0027"},{"lineNumber":37,"author":{"gitId":"domoberzin"},"content":" + \u0027\u003cp\u003eIf you need further clarification or would like to appeal this decision, please \u0027"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" + \u0027feel free to contact us at {supportEmail}\u003c/p\u003e\u0027"},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" + \u0027\u003cp\u003eRegards,\u003cbr /\u003eTEAMMATES Team.\u003c/p\u003e\u0027;"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" rejectionReasonTitle: string \u003d \u0027We are Unable to Create an Account for you\u0027;"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":42,"author":{"gitId":"domoberzin"},"content":" constructor(public activeModal: NgbActiveModal, public statusMessageService: StatusMessageService) {}"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":44,"author":{"gitId":"domoberzin"},"content":" ngOnInit(): void {"},{"lineNumber":45,"author":{"gitId":"domoberzin"},"content":" this.rejectionReasonBody \u003d this.rejectionReasonBody.replace(\u0027{accountRequestName}\u0027, this.accountRequestName);"},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" this.rejectionReasonBody \u003d this.rejectionReasonBody.replace(\u0027{existingEmail}\u0027, this.accountRequestEmail);"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" this.rejectionReasonBody \u003d this.rejectionReasonBody.replaceAll(\u0027{supportEmail}\u0027, environment.supportEmail);"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":50,"author":{"gitId":"domoberzin"},"content":" onRejectionReasonBodyChange(updatedText: string): void {"},{"lineNumber":51,"author":{"gitId":"domoberzin"},"content":" this.rejectionReasonBody \u003d updatedText;"},{"lineNumber":52,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":53,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":54,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":55,"author":{"gitId":"domoberzin"},"content":" * Fires the reject event."},{"lineNumber":56,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":57,"author":{"gitId":"domoberzin"},"content":" reject(): void {"},{"lineNumber":58,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":59,"author":{"gitId":"domoberzin"},"content":" if (!this.rejectionReasonBody || this.rejectionReasonBody.length \u003d\u003d\u003d 0) {"},{"lineNumber":60,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showErrorToast(\u0027Please provide an email body for the rejection email.\u0027);"},{"lineNumber":61,"author":{"gitId":"domoberzin"},"content":" return;"},{"lineNumber":62,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":63,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":64,"author":{"gitId":"domoberzin"},"content":" if (!this.rejectionReasonTitle || this.rejectionReasonTitle.length \u003d\u003d\u003d 0) {"},{"lineNumber":65,"author":{"gitId":"domoberzin"},"content":" this.statusMessageService.showErrorToast(\u0027Please provide a title for the rejection email.\u0027);"},{"lineNumber":66,"author":{"gitId":"domoberzin"},"content":" return;"},{"lineNumber":67,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":68,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":69,"author":{"gitId":"domoberzin"},"content":" const result: RejectWithReasonModalComponentResult \u003d {"},{"lineNumber":70,"author":{"gitId":"domoberzin"},"content":" rejectionReasonTitle: this.rejectionReasonTitle,"},{"lineNumber":71,"author":{"gitId":"domoberzin"},"content":" rejectionReasonBody: this.rejectionReasonBody,"},{"lineNumber":72,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":73,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":74,"author":{"gitId":"domoberzin"},"content":" this.activeModal.close(result);"},{"lineNumber":75,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":76,"author":{"gitId":"domoberzin"},"content":"}"}],"authorContributionMap":{"domoberzin":76}},{"path":"src/web/app/components/comment-box/comment-row/comment-row.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003ctm-comment-edit-form *ngIf\u003d\"model.isEditing || mode \u003d\u003d\u003d CommentRowMode.ADD\""},{"lineNumber":2,"author":{"gitId":"-"},"content":" [mode]\u003d\"mode\""},{"lineNumber":3,"author":{"gitId":"-"},"content":" [model]\u003d\"model.commentEditFormModel\""},{"lineNumber":4,"author":{"gitId":"-"},"content":" (modelChange)\u003d\"triggerModelChange(\u0027commentEditFormModel\u0027, $event)\""},{"lineNumber":5,"author":{"gitId":"-"},"content":" [isVisibilityOptionEnabled]\u003d\"isVisibilityOptionEnabled\""},{"lineNumber":6,"author":{"gitId":"-"},"content":" [isDisabled]\u003d\"isDisabled\""},{"lineNumber":7,"author":{"gitId":"-"},"content":" [shouldHideSavingButton]\u003d\"shouldHideSavingButton\""},{"lineNumber":8,"author":{"gitId":"-"},"content":" [questionShowResponsesTo]\u003d\"questionShowResponsesTo\""},{"lineNumber":9,"author":{"gitId":"-"},"content":" [response]\u003d\"response\""},{"lineNumber":10,"author":{"gitId":"-"},"content":" [isFeedbackParticipantComment]\u003d\"isFeedbackParticipantComment\""},{"lineNumber":11,"author":{"gitId":"-"},"content":" [shouldHideClosingButton]\u003d\"shouldHideClosingButton\""},{"lineNumber":12,"author":{"gitId":"-"},"content":" (closeCommentBoxEvent)\u003d\"triggerCloseEditing()\""},{"lineNumber":13,"author":{"gitId":"-"},"content":" (saveCommentEvent)\u003d\"triggerSaveCommentEvent()\"\u003e\u003c/tm-comment-edit-form\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"card\" *ngIf\u003d\"!model.isEditing \u0026\u0026 mode \u003d\u003d\u003d CommentRowMode.EDIT \u0026\u0026 model.originalComment\"\u003e"},{"lineNumber":16,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row comment-row\"\u003e"},{"lineNumber":18,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":19,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"by-response-giver text-secondary\" *ngIf\u003d\"isFeedbackParticipantComment\"\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" Comment by response giver."},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":22,"author":{"gitId":"yuanxi1"},"content":" \u003cng-container class\u003d\"text-secondary\" *ngIf\u003d\"!isFeedbackParticipantComment\"\u003e"},{"lineNumber":23,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"comment-giver-name\"\u003e{{ model.commentGiverName ? model.commentGiverName : model.originalComment.commentGiver }} commented at \u003c/span\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"ngb-tooltip-class\" style\u003d\"margin-right: .25rem;\" [ngbTooltip]\u003d\"model.originalComment.createdAt | formatDateDetail: model.timezone!\"\u003e"},{"lineNumber":25,"author":{"gitId":"-"},"content":" {{ model.originalComment.createdAt | formatDateBrief: model.timezone! }}\u003c/span\u003e"},{"lineNumber":26,"author":{"gitId":"-"},"content":" \u003cng-container *ngIf\u003d\"model.originalComment.lastEditedAt \u0026\u0026 model.originalComment.lastEditedAt !\u003d\u003d model.originalComment.createdAt\"\u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-circle dot-xs align-middle\" style\u003d\"margin-right: .25rem;\"\u003e\u003c/i\u003e"},{"lineNumber":28,"author":{"gitId":"-"},"content":" \u003cspan id\u003d\"last-editor-name\" style\u003d\"margin-right: .25rem;\" class\u003d\"ngb-tooltip-class\""},{"lineNumber":29,"author":{"gitId":"-"},"content":" [ngbTooltip]\u003d\"model.originalComment.lastEditedAt | formatDateDetail: model.timezone!\"\u003eedited by {{ model.lastEditorName ? model.lastEditorName : model.originalComment.lastEditorEmail }}\u003c/span\u003e"},{"lineNumber":30,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":31,"author":{"gitId":"yuanxi1"},"content":" \u003c/ng-container\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fa fa-eye\" aria-hidden\u003d\"true\" ngbTooltip\u003d\"This response comment is visible to {{ visibilityStateMachine.getVisibilityTypesUnderVisibilityControl(CommentVisibilityControl.SHOW_COMMENT) | commentVisibilityTypesJointName }}\"\u003e\u003c/i\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"float-end\"\u003e"},{"lineNumber":36,"author":{"gitId":"-"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn-edit-comment btn btn-outline-primary btn-sm\" *ngIf\u003d\"!shouldHideEditButton\" ngbTooltip\u003d\u0027Edit this comment\u0027"},{"lineNumber":37,"author":{"gitId":"-"},"content":" (click)\u003d\"triggerModelChange(\u0027isEditing\u0027, true)\" [disabled]\u003d\"isDisabled\"\u003e\u003ci class\u003d\"fas fa-pencil-alt\"\u003e\u003c/i\u003e\u003c/button\u003e"},{"lineNumber":38,"author":{"gitId":"-"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn-delete-comment btn btn-outline-primary btn-sm btn-margin-left\" *ngIf\u003d\"!shouldHideDeleteButton\" ngbTooltip\u003d\u0027Delete this comment\u0027"},{"lineNumber":39,"author":{"gitId":"-"},"content":" (click)\u003d\"triggerDeleteCommentEvent()\" [disabled]\u003d\"isDisabled\"\u003e\u003ci class\u003d\"fas fa-trash\"\u003e\u003c/i\u003e\u003c/button\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"comment-text col-12\" [innerHTML]\u003d\"model.originalComment.commentText | safeHtml\"\u003e\u003c/div\u003e"},{"lineNumber":43,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":45,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"yuanxi1":2,"-":43}},{"path":"src/web/app/components/notification-banner/notification-banner.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"yuanxi1"},"content":"\u003cdiv id\u003d\"notification-banner\" class\u003d\"banner\" [ngClass]\u003d\"notifications[0].style | notificationStyleClass\" *ngIf\u003d\"isShown \u0026\u0026 notifications.length \u003e 0\" [attr.data-testid]\u003d\"notifications[0].notificationId\" @collapseAnim\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-close-notif\" type\u003d\"button\" class\u003d\"btn-close\" aria-label\u003d\"Close\" (click)\u003d\"closeNotification()\"\u003e\u003c/button\u003e"},{"lineNumber":3,"author":{"gitId":"-"},"content":" \u003ch5\u003e{{ notifications[0].title }}\u003c/h5\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"banner-text\" [innerHTML]\u003d\"notifications[0].message\"\u003e\u003c/div\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"d-flex flex-row-reverse mt-3 me-2\"\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-mark-as-read\" type\u003d\"button\" [ngClass]\u003d\"getButtonClass(notifications[0])\" (click)\u003d\"markNotificationAsRead(notifications[0])\"\u003e"},{"lineNumber":7,"author":{"gitId":"-"},"content":" Mark as Read"},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":9,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"yuanxi1":1,"-":9}},{"path":"src/web/app/components/session-edit-form/session-edit-form.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cdiv id\u003d\"session-edit-form\" class\u003d\"card card-plain\"\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"close-header\" *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.ADD\"\u003e"},{"lineNumber":3,"author":{"gitId":"-"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn-close\" aria-label\u003d\"Close\" (click)\u003d\"closeEditFormHandler()\"\u003e\u003c/button\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row\" *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.ADD\"\u003e"},{"lineNumber":7,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-lg-7\"\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row mb-2\"\u003e"},{"lineNumber":9,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 col-sm-3 session-heading-text\"\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003ch5\u003eCreate new\u003c/h5\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 col-sm-9 create-new-dropdown-div\"\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003cselect id\u003d\"session-type\" class\u003d\"form-control form-select\" [ngModel]\u003d\"model.templateSessionName\" (ngModelChange)\u003d\"triggerModelChange(\u0027templateSessionName\u0027, $event)\"\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":" \u003coption *ngFor\u003d\"let templateSession of templateSessions\" [ngValue]\u003d\"templateSession.name\"\u003e{{ templateSession.name }}\u003c/option\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":" \u003c/select\u003e"},{"lineNumber":16,"author":{"gitId":"-"},"content":" \u003ca type\u003d\"button\" class\u003d\"btn btn-link\" tmRouterLink\u003d\"/web/instructor/help\" [queryParams]\u003d\"{ questionId: \u0027sessions\u0027, section: \u0027sessions\u0027 }\" target\u003d\"_blank\" aria-label\u003d\"Help for feedback sessions\"\u003e\u003ci class\u003d\"fas fa-info-circle\"\u003e\u003c/i\u003e\u003c/a\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":18,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":19,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-lg-5\"\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row\"\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 col-sm-3 col-lg-1 session-heading-text\"\u003e"},{"lineNumber":23,"author":{"gitId":"-"},"content":" \u003ch5\u003eOr\u003c/h5\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 col-sm-9 col-lg-11 text-md-start\"\u003e"},{"lineNumber":26,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-copy-session\" type\u003d\"button\" class\u003d\"btn btn-info\" (click)\u003d\"copyOthersHandler()\"\u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003cspan\u003eCopy from previous feedback sessions\u003c/span\u003e"},{"lineNumber":28,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"padding-left-7px\"\u003e"},{"lineNumber":29,"author":{"gitId":"-"},"content":" \u003ctm-ajax-loading *ngIf\u003d\"isCopyOtherSessionLoading\"\u003e\u003c/tm-ajax-loading\u003e"},{"lineNumber":30,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":31,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":36,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row\" *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.EDIT\"\u003e"},{"lineNumber":37,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 text-center text-md-end session-form-buttons\"\u003e"},{"lineNumber":38,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-fs-edit\" type\u003d\"button\" class\u003d\"btn btn-primary\" (click)\u003d\"triggerModelChange(\u0027isEditable\u0027, true)\" *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.EDIT \u0026\u0026 !model.isEditable \u0026\u0026 !model.isSaving\"\u003e\u003ci class\u003d\"fas fa-pencil-alt\"\u003e\u003c/i\u003e Edit\u003c/button\u003e"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-fs-save\" type\u003d\"button\" class\u003d\"btn btn-primary\" (click)\u003d\"submitFormHandler()\" [disabled]\u003d\"model.isSaving\" *ngIf\u003d\"model.isEditable || model.isSaving\"\u003e\u003ctm-ajax-loading *ngIf\u003d\"model.isSaving\"\u003e\u003c/tm-ajax-loading\u003e \u003ci class\u003d\"fas fa-check\"\u003e\u003c/i\u003e Save\u003c/button\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn btn-primary\" ngbTooltip\u003d\"Discard changes to the feedback session\" (click)\u003d\"cancelHandler()\" *ngIf\u003d\"model.isEditable\" [disabled]\u003d\"model.isSaving\"\u003e\u003ci class\u003d\"fas fa-ban\"\u003e\u003c/i\u003e Cancel\u003c/button\u003e"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-fs-delete\" type\u003d\"button\" class\u003d\"btn btn-primary\" ngbTooltip\u003d\"Delete the feedback session\" (click)\u003d\"deleteHandler()\" [disabled]\u003d\"model.isSaving\"\u003e\u003ctm-ajax-loading *ngIf\u003d\"model.isDeleting\"\u003e\u003c/tm-ajax-loading\u003e\u003ci class\u003d\"fas fa-trash\"\u003e\u003c/i\u003e Delete\u003c/button\u003e"},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-fs-copy\" type\u003d\"button\" class\u003d\"btn btn-primary\" ngbTooltip\u003d\"Copy this feedback session to other courses\" (click)\u003d\"copyHandler()\" [disabled]\u003d\"model.isSaving\"\u003e\u003ctm-ajax-loading *ngIf\u003d\"model.isCopying\"\u003e\u003c/tm-ajax-loading\u003e\u003ci class\u003d\"far fa-copy\"\u003e\u003c/i\u003e Copy\u003c/button\u003e"},{"lineNumber":43,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card border-primary margin-top-20px\"\u003e"},{"lineNumber":47,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":48,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\"\u003e"},{"lineNumber":49,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2 text-md-end font-bold\" [ngClass]\u003d\"{\u0027col-form-label\u0027: formMode \u003d\u003d\u003d SessionEditFormMode.ADD}\"\u003e"},{"lineNumber":50,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"ngb-tooltip-class\" ngbTooltip\u003d\"Course for which the feedback session is for.\"\u003eCourse ID\u003c/span\u003e"},{"lineNumber":51,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":52,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-auto text-md-start\"\u003e"},{"lineNumber":53,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.ADD\"\u003e"},{"lineNumber":54,"author":{"gitId":"-"},"content":" \u003cselect id\u003d\"add-course-id\" class\u003d\"form-control form-select\" [ngClass]\u003d\"{\u0027is-invalid\u0027: courseCandidates.length \u003d\u003d\u003d 0}\" [ngModel]\u003d\"model.courseId\" (ngModelChange)\u003d\"courseIdChangeHandler($event)\" [disabled]\u003d\"courseCandidates.length \u003d\u003d\u003d 0\"\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":" \u003coption *ngFor\u003d\"let course of courseCandidates\" [ngValue]\u003d\"course.courseId\"\u003e{{ course.courseId }}\u003c/option\u003e"},{"lineNumber":56,"author":{"gitId":"-"},"content":" \u003c/select\u003e"},{"lineNumber":57,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"invalid-feedback\" *ngIf\u003d\"courseCandidates.length \u003d\u003d\u003d 0\"\u003e"},{"lineNumber":58,"author":{"gitId":"-"},"content":" There is no un-archived course."},{"lineNumber":59,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":60,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":61,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"edit-course-id\" *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.EDIT\"\u003e {{ model.courseId }} \u003c/div\u003e"},{"lineNumber":62,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":63,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":64,"author":{"gitId":"-"},"content":" \u003cbr/\u003e"},{"lineNumber":65,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\"\u003e"},{"lineNumber":66,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2 text-md-end font-bold\" [ngClass]\u003d\"{\u0027col-form-label\u0027: formMode \u003d\u003d\u003d SessionEditFormMode.ADD}\"\u003e"},{"lineNumber":67,"author":{"gitId":"-"},"content":" Time Zone"},{"lineNumber":68,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":69,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"time-zone\" class\u003d\"col-md-3 text-md-start\" [ngClass]\u003d\"{\u0027col-form-label\u0027: formMode \u003d\u003d\u003d SessionEditFormMode.ADD}\"\u003e"},{"lineNumber":70,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"ngb-tooltip-class\" ngbTooltip\u003d\"To change this, edit the course settings. TEAMMATES automatically adjusts to match the current time offset in your area, including clock changes due to daylight saving time.\"\u003e{{ model.timeZone }}\u003c/span\u003e"},{"lineNumber":71,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":72,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":73,"author":{"gitId":"-"},"content":" \u003cbr/\u003e"},{"lineNumber":74,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\"\u003e"},{"lineNumber":75,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2 text-md-end font-bold\"\u003e"},{"lineNumber":76,"author":{"gitId":"-"},"content":" Course Name"},{"lineNumber":77,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":78,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"course-name\" class\u003d\"col-md-10 text-md-start\"\u003e"},{"lineNumber":79,"author":{"gitId":"-"},"content":" {{ model.courseName }}"},{"lineNumber":80,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":81,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":82,"author":{"gitId":"-"},"content":" \u003cbr/\u003e"},{"lineNumber":83,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\"\u003e"},{"lineNumber":84,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2 text-md-end font-bold\"\u003e"},{"lineNumber":85,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.ADD\" class\u003d\"ngb-tooltip-class\" ngbTooltip\u003d\"Enter the name of the feedback session e.g. Feedback Session 1.\"\u003eSession Name*\u003c/span\u003e"},{"lineNumber":86,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"formMode !\u003d\u003d SessionEditFormMode.ADD\"\u003eSession Name\u003c/span\u003e"},{"lineNumber":87,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":88,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-10 text-md-start\"\u003e"},{"lineNumber":89,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.ADD\"\u003e"},{"lineNumber":90,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"add-session-name\" type\u003d\"text\" class\u003d\"form-control\" [ngModel]\u003d\"model.feedbackSessionName\" (ngModelChange)\u003d\"triggerModelChange(\u0027feedbackSessionName\u0027, $event)\" placeholder\u003d\"e.g. Feedback for Project Presentation 1\" maxlength\u003d\"64\" required #sessionName\u003d\"ngModel\" /\u003e"},{"lineNumber":91,"author":{"gitId":"-"},"content":" \u003cdiv [hidden]\u003d\"sessionName.valid || (sessionName.pristine \u0026\u0026 sessionName.untouched)\" class\u003d\"invalid-field\"\u003e"},{"lineNumber":92,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fa fa-exclamation-circle\" aria-hidden\u003d\"true\"\u003e\u003c/i\u003e"},{"lineNumber":93,"author":{"gitId":"-"},"content":" The field Session Name should not be empty."},{"lineNumber":94,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":95,"author":{"gitId":"-"},"content":" \u003cdiv\u003e"},{"lineNumber":96,"author":{"gitId":"-"},"content":" {{FEEDBACK_SESSION_NAME_MAX_LENGTH - model.feedbackSessionName.length}} characters left"},{"lineNumber":97,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":98,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":99,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"edit-session-name\" *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.EDIT\"\u003e {{ model.feedbackSessionName }} \u003c/div\u003e"},{"lineNumber":100,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":101,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":102,"author":{"gitId":"-"},"content":" \u003cbr/\u003e"},{"lineNumber":103,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\"\u003e"},{"lineNumber":104,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2 text-md-end font-bold\"\u003e"},{"lineNumber":105,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"ngb-tooltip-class\" ngbTooltip\u003d\"Will be displayed at the top of the page when users respond to the session.\"\u003eInstructions\u003c/span\u003e"},{"lineNumber":106,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":107,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-10 text-md-start\"\u003e"},{"lineNumber":108,"author":{"gitId":"-"},"content":" \u003ctm-rich-text-editor id\u003d\"instructions\" [richText]\u003d\"model.instructions\" (richTextChange)\u003d\"triggerModelChange(\u0027instructions\u0027, $event)\" [isDisabled]\u003d\"!model.isEditable\" [hasCharacterLimit]\u003d\"true\"\u003e\u003c/tm-rich-text-editor\u003e"},{"lineNumber":109,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":110,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":111,"author":{"gitId":"-"},"content":" \u003cbr/\u003e"},{"lineNumber":112,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\" *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.EDIT\"\u003e"},{"lineNumber":113,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2 text-md-end font-bold\"\u003e"},{"lineNumber":114,"author":{"gitId":"-"},"content":" Submission Status"},{"lineNumber":115,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":116,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"submission-status\" class\u003d\"col-md-4 text-md-start\"\u003e"},{"lineNumber":117,"author":{"gitId":"-"},"content":" {{ model.submissionStatus | submissionStatusName }}"},{"lineNumber":118,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":119,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2 text-md-end font-bold mt-3 mt-md-0\"\u003e"},{"lineNumber":120,"author":{"gitId":"-"},"content":" Published Status"},{"lineNumber":121,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":122,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"published-status\" class\u003d\"col-md-4 text-md-start\"\u003e"},{"lineNumber":123,"author":{"gitId":"-"},"content":" {{ model.publishStatus | publishStatusName }}"},{"lineNumber":124,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":125,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":126,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":127,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card border-primary margin-top-20px\"\u003e"},{"lineNumber":130,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":131,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\"\u003e"},{"lineNumber":132,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-4\"\u003e"},{"lineNumber":133,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 text-md-start\"\u003e"},{"lineNumber":134,"author":{"gitId":"-"},"content":" \u003cdiv\u003e"},{"lineNumber":135,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"ngb-tooltip-class label-control font-bold\" ngbTooltip\u003d\"Users can start submitting responses.\"\u003e"},{"lineNumber":136,"author":{"gitId":"-"},"content":" Submission opening time"},{"lineNumber":137,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":138,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":139,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":140,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center align-items-center\"\u003e"},{"lineNumber":141,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"submission-start-date\" class\u003d\"col-md-7 col-xs-center\"\u003e"},{"lineNumber":142,"author":{"gitId":"-"},"content":" \u003ctm-datepicker [isDisabled]\u003d\"!model.isEditable\" (dateChangeCallback)\u003d\"triggerSubmissionOpeningDateModelChange(\u0027submissionStartDate\u0027, $event)\""},{"lineNumber":143,"author":{"gitId":"-"},"content":" [minDate]\u003d\"minDateForSubmissionStart\" [maxDate]\u003d\"maxDateForSubmissionStart\""},{"lineNumber":144,"author":{"gitId":"-"},"content":" [date]\u003d\"model.submissionStartDate\"\u003e\u003c/tm-datepicker\u003e"},{"lineNumber":145,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":146,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-5\"\u003e"},{"lineNumber":147,"author":{"gitId":"-"},"content":" \u003ctm-timepicker id\u003d\"submission-start-time\" [isDisabled]\u003d\"!model.isEditable\" (timeChange)\u003d\"triggerModelChange(\u0027submissionStartTime\u0027, $event)\""},{"lineNumber":148,"author":{"gitId":"-"},"content":" [minDate]\u003d\"minDateForSubmissionStart\" [maxDate]\u003d\"maxDateForSubmissionStart\""},{"lineNumber":149,"author":{"gitId":"-"},"content":" [date]\u003d\"model.submissionStartDate\""},{"lineNumber":150,"author":{"gitId":"-"},"content":" [minTime]\u003d\"minTimeForSubmissionStart\" [maxTime]\u003d\"maxTimeForSubmissionStart\""},{"lineNumber":151,"author":{"gitId":"-"},"content":" [time]\u003d\"model.submissionStartTime\"\u003e\u003c/tm-timepicker\u003e"},{"lineNumber":152,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":153,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":154,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":155,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-4 border-left-gray\"\u003e"},{"lineNumber":156,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\"\u003e"},{"lineNumber":157,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 text-md-start ms-md-2\"\u003e"},{"lineNumber":158,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"ngb-tooltip-class label-control font-bold\" ngbTooltip\u003d\"No more submissions from users.\"\u003e"},{"lineNumber":159,"author":{"gitId":"-"},"content":" Submission closing time"},{"lineNumber":160,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":161,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":162,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":163,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row align-items-center\"\u003e"},{"lineNumber":164,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"submission-end-date\" class\u003d\"col-md-7 col-xs-center\"\u003e"},{"lineNumber":165,"author":{"gitId":"-"},"content":" \u003ctm-datepicker [isDisabled]\u003d\"!model.isEditable\" (dateChangeCallback)\u003d\"triggerModelChange(\u0027submissionEndDate\u0027, $event)\""},{"lineNumber":166,"author":{"gitId":"-"},"content":" [minDate]\u003d\"minDateForSubmissionEnd\" [maxDate]\u003d\"maxDateForSubmissionEnd\""},{"lineNumber":167,"author":{"gitId":"-"},"content":" [date]\u003d\"model.submissionEndDate\"\u003e\u003c/tm-datepicker\u003e"},{"lineNumber":168,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":169,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-5\"\u003e"},{"lineNumber":170,"author":{"gitId":"-"},"content":" \u003ctm-timepicker id\u003d\"submission-end-time\" [isDisabled]\u003d\"!model.isEditable\" (timeChange)\u003d\"triggerModelChange(\u0027submissionEndTime\u0027, $event)\""},{"lineNumber":171,"author":{"gitId":"-"},"content":" [minDate]\u003d\"minDateForSubmissionEnd\" [maxDate]\u003d\"maxDateForSubmissionEnd\""},{"lineNumber":172,"author":{"gitId":"-"},"content":" [date]\u003d\"model.submissionEndDate\""},{"lineNumber":173,"author":{"gitId":"-"},"content":" [minTime]\u003d\"minTimeForSubmissionEnd\" [maxTime]\u003d\"maxTimeForSubmissionEnd\""},{"lineNumber":174,"author":{"gitId":"-"},"content":" [time]\u003d\"model.submissionEndTime\"\u003e\u003c/tm-timepicker\u003e"},{"lineNumber":175,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":176,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":177,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":178,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-4 border-left-gray\"\u003e"},{"lineNumber":179,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\"\u003e"},{"lineNumber":180,"author":{"gitId":"nknguyenhc"},"content":" \u003cdiv class\u003d\"col-12 text-md-start ms-md-2\"\u003e"},{"lineNumber":181,"author":{"gitId":"nknguyenhc"},"content":" \u003clabel for\u003d\"grace-period\" class\u003d\"ngb-tooltip-class control-label font-bold\" ngbTooltip\u003d\"Amount of time the system will continue accepting submissions after the specified deadline.\"\u003e"},{"lineNumber":182,"author":{"gitId":"-"},"content":" Grace period"},{"lineNumber":183,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":184,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":185,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":186,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row text-center\"\u003e"},{"lineNumber":187,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":188,"author":{"gitId":"-"},"content":" \u003cselect id\u003d\"grace-period\" class\u003d\"form-control form-select\" [ngModel]\u003d\"model.gracePeriod\" (ngModelChange)\u003d\"triggerModelChange(\u0027gracePeriod\u0027, $event)\" [disabled]\u003d\"!model.isEditable\"\u003e"},{"lineNumber":189,"author":{"gitId":"-"},"content":" \u003coption *ngFor\u003d\"let graceMinute of [0, 5, 10, 15, 20, 25, 30]\" [ngValue]\u003d\"graceMinute\"\u003e{{ graceMinute + \u0027 min\u0027}}\u003c/option\u003e"},{"lineNumber":190,"author":{"gitId":"-"},"content":" \u003c/select\u003e"},{"lineNumber":191,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":192,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":193,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row\"\u003e"},{"lineNumber":194,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"ps-3 pt-2\""},{"lineNumber":195,"author":{"gitId":"-"},"content":" *ngIf\u003d\"formMode !\u003d\u003d SessionEditFormMode.ADD\""},{"lineNumber":196,"author":{"gitId":"-"},"content":" tmRouterLink\u003d\"/web/instructor/sessions/individual-extension\""},{"lineNumber":197,"author":{"gitId":"-"},"content":" [queryParams]\u003d\"{ courseid: model.courseId, fsname: model.feedbackSessionName, preselectnonsubmitters: false }\"\u003e"},{"lineNumber":198,"author":{"gitId":"-"},"content":" Individual Deadline Extensions"},{"lineNumber":199,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-edit\"\u003e\u003c/i\u003e"},{"lineNumber":200,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":201,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"ps-3 pt-2 disabled-link ngb-tooltip-class\""},{"lineNumber":202,"author":{"gitId":"-"},"content":" *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.ADD\""},{"lineNumber":203,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"You must save the new session before setting individual deadline extensions\"\u003e"},{"lineNumber":204,"author":{"gitId":"-"},"content":" Individual Deadline Extensions"},{"lineNumber":205,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-edit\"\u003e\u003c/i\u003e"},{"lineNumber":206,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":207,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":208,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":209,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":210,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":211,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":212,"author":{"gitId":"-"},"content":""},{"lineNumber":213,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"!model.hasVisibleSettingsPanelExpanded\" class\u003d\"margin-top-20px\"\u003e"},{"lineNumber":214,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"text-muted\"\u003eSession is visible at submission opening time, responses are only visible when you publish the results.\u003c/span\u003e"},{"lineNumber":215,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-change-visibility\" type\u003d\"button\" class\u003d\"btn btn-link\" (click)\u003d\"triggerModelChange(\u0027hasVisibleSettingsPanelExpanded\u0027, true)\" [disabled]\u003d\"!model.isEditable\"\u003e[Change]\u003c/button\u003e"},{"lineNumber":216,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":217,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card border-primary margin-top-20px\" *ngIf\u003d\"model.hasVisibleSettingsPanelExpanded\" @collapseAnim\u003e"},{"lineNumber":218,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":219,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row align-items-start\"\u003e"},{"lineNumber":220,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-6 text-center text-md-start\"\u003e"},{"lineNumber":221,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row ms-md-1\"\u003e"},{"lineNumber":222,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":223,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"ngb-tooltip-class label-control font-bold\" ngbTooltip\u003d\"Session can be visible before it is open for submissions so that users can preview the questions.\"\u003eMake session visible \u003c/label\u003e"},{"lineNumber":224,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":225,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":226,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row mt-md-2 ms-md-1\"\u003e"},{"lineNumber":227,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2 mt-md-1\"\u003e"},{"lineNumber":228,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"form-check\"\u003e"},{"lineNumber":229,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"form-check-label\"\u003e"},{"lineNumber":230,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"session-visibility-custom\" class\u003d\"form-check-input\" type\u003d\"radio\" name\u003d\"sessionVisibleRadio\" [value]\u003d\"SessionVisibleSetting.CUSTOM\" [ngModel]\u003d\"model.sessionVisibleSetting\" (ngModelChange)\u003d\"triggerModelChange(\u0027sessionVisibleSetting\u0027, $event)\" [disabled]\u003d\"!model.isEditable\"\u003e"},{"lineNumber":231,"author":{"gitId":"-"},"content":" At"},{"lineNumber":232,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":233,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":234,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":235,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"session-visibility-date\" class\u003d\"col-md-6\"\u003e"},{"lineNumber":236,"author":{"gitId":"-"},"content":" \u003ctm-datepicker [isDisabled]\u003d\"model.sessionVisibleSetting !\u003d\u003d SessionVisibleSetting.CUSTOM || !model.isEditable\""},{"lineNumber":237,"author":{"gitId":"-"},"content":" (dateChangeCallback)\u003d\"triggerModelChange(\u0027customSessionVisibleDate\u0027, $event)\""},{"lineNumber":238,"author":{"gitId":"-"},"content":" [minDate]\u003d\"minDateForSessionVisible\" [maxDate]\u003d\"maxDateForSessionVisible\""},{"lineNumber":239,"author":{"gitId":"-"},"content":" [date]\u003d\"model.customSessionVisibleDate\"\u003e\u003c/tm-datepicker\u003e"},{"lineNumber":240,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":241,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-4\"\u003e"},{"lineNumber":242,"author":{"gitId":"-"},"content":" \u003ctm-timepicker id\u003d\"session-visibility-time\" [isDisabled]\u003d\"model.sessionVisibleSetting !\u003d\u003d SessionVisibleSetting.CUSTOM || !model.isEditable\" (timeChange)\u003d\"triggerModelChange(\u0027customSessionVisibleTime\u0027, $event)\""},{"lineNumber":243,"author":{"gitId":"-"},"content":" [minDate]\u003d\"minDateForSessionVisible\" [maxDate]\u003d\"maxDateForSessionVisible\""},{"lineNumber":244,"author":{"gitId":"-"},"content":" [date]\u003d\"model.customSessionVisibleDate\""},{"lineNumber":245,"author":{"gitId":"-"},"content":" [minTime]\u003d\"minTimeForSessionVisible\" [maxTime]\u003d\"maxTimeForSessionVisible\""},{"lineNumber":246,"author":{"gitId":"-"},"content":" [time]\u003d\"model.customSessionVisibleTime\" \u003e\u003c/tm-timepicker\u003e"},{"lineNumber":247,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":248,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":249,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row mt-md-1 ms-md-3\"\u003e"},{"lineNumber":250,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 form-check\"\u003e"},{"lineNumber":251,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"form-check-label\"\u003e"},{"lineNumber":252,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"session-visibility-at-open\" class\u003d\"form-check-input\" type\u003d\"radio\" name\u003d\"sessionVisibleRadio\" [value]\u003d\"SessionVisibleSetting.AT_OPEN\" [ngModel]\u003d\"model.sessionVisibleSetting\" (ngModelChange)\u003d\"triggerModelChange(\u0027sessionVisibleSetting\u0027, $event)\" [disabled]\u003d\"!model.isEditable\"\u003e"},{"lineNumber":253,"author":{"gitId":"-"},"content":" Submission opening time"},{"lineNumber":254,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":255,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":256,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":257,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":258,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-6 sessionVisibleRadio border-left-gray text-center text-md-start\"\u003e"},{"lineNumber":259,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row ms-md-1\"\u003e"},{"lineNumber":260,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":261,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"ngb-tooltip-class label-control font-bold\" ngbTooltip\u003d\"Make responses for the feedback session visible to designated recipients.\"\u003eMake response visible \u003c/label\u003e"},{"lineNumber":262,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":263,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":264,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row mt-md-2 ms-md-1\"\u003e"},{"lineNumber":265,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2 mt-md-1\"\u003e"},{"lineNumber":266,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"form-check\"\u003e"},{"lineNumber":267,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"form-check-label\"\u003e"},{"lineNumber":268,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"response-visibility-custom\" class\u003d\"form-check-input\" type\u003d\"radio\" name\u003d\"responseVisibleRadio\" [value]\u003d\"ResponseVisibleSetting.CUSTOM\" [ngModel]\u003d\"model.responseVisibleSetting\" (ngModelChange)\u003d\"triggerModelChange(\u0027responseVisibleSetting\u0027, $event)\" [disabled]\u003d\"!model.isEditable\"/\u003e"},{"lineNumber":269,"author":{"gitId":"-"},"content":" At"},{"lineNumber":270,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":271,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":272,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":273,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"response-visibility-date\" class\u003d\"col-md-6\"\u003e"},{"lineNumber":274,"author":{"gitId":"-"},"content":" \u003ctm-datepicker [isDisabled]\u003d\"model.responseVisibleSetting !\u003d\u003d ResponseVisibleSetting.CUSTOM || !model.isEditable\""},{"lineNumber":275,"author":{"gitId":"-"},"content":" (dateChangeCallback)\u003d\"triggerModelChange(\u0027customResponseVisibleDate\u0027, $event)\""},{"lineNumber":276,"author":{"gitId":"-"},"content":" [minDate]\u003d\"minDateForResponseVisible\" [date]\u003d\"model.customResponseVisibleDate\"\u003e\u003c/tm-datepicker\u003e"},{"lineNumber":277,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":278,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-4\"\u003e"},{"lineNumber":279,"author":{"gitId":"-"},"content":" \u003ctm-timepicker id\u003d\"response-visibility-time\" [isDisabled]\u003d\"model.responseVisibleSetting !\u003d\u003d ResponseVisibleSetting.CUSTOM || !model.isEditable\" (timeChange)\u003d\"triggerModelChange(\u0027customResponseVisibleTime\u0027, $event)\""},{"lineNumber":280,"author":{"gitId":"-"},"content":" [minDate]\u003d\"minDateForResponseVisible\" [date]\u003d\"model.customResponseVisibleDate\""},{"lineNumber":281,"author":{"gitId":"-"},"content":" [minTime]\u003d\"minTimeForResponseVisible\" [time]\u003d\"model.customResponseVisibleTime\" \u003e\u003c/tm-timepicker\u003e"},{"lineNumber":282,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":283,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":284,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row mt-md-2 ms-md-1\"\u003e"},{"lineNumber":285,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":286,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"form-check\"\u003e"},{"lineNumber":287,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"ngb-tooltip-class form-check-label\" ngbTooltip\u003d\"Same time as when the session becomes visible to users.\"\u003e"},{"lineNumber":288,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"response-visibility-immediately\" class\u003d\"form-check-input\" type\u003d\"radio\" name\u003d\"responseVisibleRadio\" [value]\u003d\"ResponseVisibleSetting.AT_VISIBLE\" [ngModel]\u003d\"model.responseVisibleSetting\" (ngModelChange)\u003d\"triggerModelChange(\u0027responseVisibleSetting\u0027, $event)\" [disabled]\u003d\"!model.isEditable\"\u003e"},{"lineNumber":289,"author":{"gitId":"-"},"content":" Immediately"},{"lineNumber":290,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":291,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":292,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":293,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":294,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row mt-md-2 ms-md-1\"\u003e"},{"lineNumber":295,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":296,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"form-check\"\u003e"},{"lineNumber":297,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"ngb-tooltip-class form-check-label\" ngbTooltip\u003d\"Remember to manually publish the responses for this session later on.\"\u003e"},{"lineNumber":298,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"response-visibility-manually\" class\u003d\"form-check-input\" type\u003d\"radio\" name\u003d\"responseVisibleRadio\" [value]\u003d\"ResponseVisibleSetting.LATER\" [ngModel]\u003d\"model.responseVisibleSetting\" (ngModelChange)\u003d\"triggerModelChange(\u0027responseVisibleSetting\u0027, $event)\" [disabled]\u003d\"!model.isEditable\"\u003e"},{"lineNumber":299,"author":{"gitId":"-"},"content":" Not now (publish manually)"},{"lineNumber":300,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":301,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":302,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":303,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":304,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":305,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":306,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":307,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":308,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"!model.hasEmailSettingsPanelExpanded\"\u003e"},{"lineNumber":309,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"text-muted\"\u003eEmails are sent when session opens (within 15 minutes), 24 hrs before session closes and when results are published.\u003c/span\u003e"},{"lineNumber":310,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-change-email\" type\u003d\"button\" class\u003d\"btn btn-link\" (click)\u003d\"triggerModelChange(\u0027hasEmailSettingsPanelExpanded\u0027, true)\" [disabled]\u003d\"!model.isEditable\"\u003e[Change]\u003c/button\u003e"},{"lineNumber":311,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":312,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card border-primary margin-top-20px\" *ngIf\u003d\"model.hasEmailSettingsPanelExpanded\" @collapseAnim\u003e"},{"lineNumber":313,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":314,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 font-bold\"\u003e"},{"lineNumber":315,"author":{"gitId":"-"},"content":" Send emails for"},{"lineNumber":316,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":317,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row ms-md-1 mt-md-3\"\u003e"},{"lineNumber":318,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-4\"\u003e"},{"lineNumber":319,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"form-check form-check-inline\"\u003e"},{"lineNumber":320,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"ngb-tooltip-class form-check-label\" ngbTooltip\u003d\"Notify students when the session is open for submission.\"\u003e"},{"lineNumber":321,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"email-opening\" class\u003d\"form-check-input\" type\u003d\"checkbox\" checked disabled\u003eSession opening reminder"},{"lineNumber":322,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":323,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":324,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":325,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-4\"\u003e"},{"lineNumber":326,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"form-check form-check-inline\"\u003e"},{"lineNumber":327,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"ngb-tooltip-class form-check-label\" ngbTooltip\u003d\"Remind students to submit 24 hours before the end of the session.\"\u003e"},{"lineNumber":328,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"email-closing\" class\u003d\"form-check-input\" type\u003d\"checkbox\" [ngModel]\u003d\"model.isClosingEmailEnabled\" (ngModelChange)\u003d\"triggerModelChange(\u0027isClosingEmailEnabled\u0027, $event)\" [disabled]\u003d\"!model.isEditable\"\u003e Session closing reminder"},{"lineNumber":329,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":330,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":331,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":332,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-4\"\u003e"},{"lineNumber":333,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"form-check form-check-inline\"\u003e"},{"lineNumber":334,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"ngb-tooltip-class form-check-label\" ngbTooltip\u003d\"Notify students when the session results is published.\"\u003e"},{"lineNumber":335,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"email-published\" class\u003d\"form-check-input\" type\u003d\"checkbox\" [ngModel]\u003d\"model.isPublishedEmailEnabled\" (ngModelChange)\u003d\"triggerModelChange(\u0027isPublishedEmailEnabled\u0027, $event)\" [disabled]\u003d\"!model.isEditable\"\u003e Results published announcement"},{"lineNumber":336,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":337,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":338,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":339,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":340,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":341,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":342,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row margin-top-20px\"\u003e"},{"lineNumber":343,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 text-center\"\u003e"},{"lineNumber":344,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"loader\"\u003e\u003c/span\u003e"},{"lineNumber":345,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.ADD\"\u003e"},{"lineNumber":346,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-create-session\" type\u003d\"button\" class\u003d\"btn btn-primary\" [disabled]\u003d\"courseCandidates.length \u003d\u003d\u003d 0 || model.isSaving || !model.feedbackSessionName\" (click)\u003d\"submitFormHandler()\"\u003e"},{"lineNumber":347,"author":{"gitId":"-"},"content":" \u003ctm-ajax-loading *ngIf\u003d\"model.isSaving\"\u003e\u003c/tm-ajax-loading\u003eCreate Feedback Session"},{"lineNumber":348,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":349,"author":{"gitId":"-"},"content":" \u003cp class\u003d\"text-danger margin-top-20px\" *ngIf\u003d\"courseCandidates.length \u003d\u003d\u003d 0\"\u003e\u003cb\u003eYou need to have an active(unarchived) course to create a session!\u003c/b\u003e\u003c/p\u003e"},{"lineNumber":350,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":351,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.EDIT\"\u003e"},{"lineNumber":352,"author":{"gitId":"-"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn btn-success\" [disabled]\u003d\"model.isSaving || !model.isEditable\" *ngIf\u003d\"formMode \u003d\u003d\u003d SessionEditFormMode.EDIT\" (click)\u003d\"submitFormHandler()\"\u003e"},{"lineNumber":353,"author":{"gitId":"-"},"content":" \u003ctm-ajax-loading *ngIf\u003d\"model.isSaving\"\u003e\u003c/tm-ajax-loading\u003eSave Changes"},{"lineNumber":354,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":355,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":356,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":357,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":358,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":359,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"nknguyenhc":2,"-":357}},{"path":"src/web/app/pages-admin/admin-home-page/admin-home-page.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"card bg-light top-padded\"\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":3,"author":{"gitId":"-"},"content":" \u003cdiv\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003cstrong\u003eAdding Multiple Instructors\u003c/strong\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":" \u003cp class\u003d\"text-muted\"\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-exclamation-circle\"\u003e\u003c/i\u003e Add Instructor Details in the format: Name | Email | Institution"},{"lineNumber":7,"author":{"gitId":"-"},"content":" \u003c/p\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003ctextarea class\u003d\"form-control\" id\u003d\"instructor-details-single-line\" [(ngModel)]\u003d\"instructorDetails\" aria-label\u003d\"Add multiple instructors\"\u003e\u003c/textarea\u003e"},{"lineNumber":9,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":""},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"top-padded\"\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003cbutton class\u003d\"btn btn-primary\" id\u003d\"add-instructor-single-line\" (click)\u003d\"validateAndAddInstructorDetails()\"\u003eAdd Instructors\u003c/button\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"card bg-light top-padded\"\u003e"},{"lineNumber":18,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":19,"author":{"gitId":"-"},"content":" \u003cdiv\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003cstrong\u003eAdding a Single Instructor\u003c/strong\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"top-padded\"\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":" \u003clabel for\u003d\"instructor-name\"\u003e"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u003cstrong\u003eName:\u003c/strong\u003e"},{"lineNumber":26,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003cinput class\u003d\"form-control\" type\u003d\"text\" id\u003d\"instructor-name\" [(ngModel)]\u003d\"instructorName\"\u003e"},{"lineNumber":28,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"top-padded\"\u003e"},{"lineNumber":31,"author":{"gitId":"-"},"content":" \u003clabel for\u003d\"instructor-email\"\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003cstrong\u003eEmail:\u003c/strong\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003cinput class\u003d\"form-control\" type\u003d\"text\" id\u003d\"instructor-email\" [(ngModel)]\u003d\"instructorEmail\"\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"top-padded\"\u003e"},{"lineNumber":38,"author":{"gitId":"-"},"content":" \u003clabel for\u003d\"instructor-institution\"\u003e"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003cstrong\u003eInstitution:\u003c/strong\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003cinput class\u003d\"form-control\" type\u003d\"text\" id\u003d\"instructor-institution\" [(ngModel)]\u003d\"instructorInstitution\"\u003e"},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":43,"author":{"gitId":"-"},"content":""},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"top-padded\"\u003e"},{"lineNumber":45,"author":{"gitId":"-"},"content":" \u003cbutton class\u003d\"btn btn-primary\" id\u003d\"add-instructor\" (click)\u003d\"validateAndAddInstructorDetail()\"\u003eAdd Instructor\u003c/button\u003e"},{"lineNumber":46,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":47,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":48,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"card bg-light top-padded\" *ngIf\u003d\"instructorsConsolidated.length\"\u003e"},{"lineNumber":51,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header bg-primary text-white\"\u003e"},{"lineNumber":52,"author":{"gitId":"-"},"content":" \u003cstrong\u003eResult\u003c/strong\u003e"},{"lineNumber":53,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":54,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"table-responsive\"\u003e"},{"lineNumber":56,"author":{"gitId":"-"},"content":" \u003ctable class\u003d\"table table-striped table-hover\"\u003e"},{"lineNumber":57,"author":{"gitId":"-"},"content":" \u003cthead\u003e"},{"lineNumber":58,"author":{"gitId":"-"},"content":" \u003ctr\u003e"},{"lineNumber":59,"author":{"gitId":"-"},"content":" \u003cth\u003eName\u003c/th\u003e"},{"lineNumber":60,"author":{"gitId":"-"},"content":" \u003cth\u003eEmail\u003c/th\u003e"},{"lineNumber":61,"author":{"gitId":"-"},"content":" \u003cth\u003eInstitution\u003c/th\u003e"},{"lineNumber":62,"author":{"gitId":"-"},"content":" \u003cth\u003eAction\u003c/th\u003e"},{"lineNumber":63,"author":{"gitId":"-"},"content":" \u003cth\u003eStatus\u003c/th\u003e"},{"lineNumber":64,"author":{"gitId":"-"},"content":" \u003cth\u003eMessage\u003c/th\u003e"},{"lineNumber":65,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":66,"author":{"gitId":"-"},"content":" \u003c/thead\u003e"},{"lineNumber":67,"author":{"gitId":"-"},"content":" \u003ctbody\u003e"},{"lineNumber":68,"author":{"gitId":"-"},"content":" \u003ctr tm-new-instructor-data-row"},{"lineNumber":69,"author":{"gitId":"-"},"content":" *ngFor\u003d\"let instructor of instructorsConsolidated; let i \u003d index\""},{"lineNumber":70,"author":{"gitId":"-"},"content":" [instructor]\u003d\"instructor\""},{"lineNumber":71,"author":{"gitId":"-"},"content":" [index]\u003d\"i\""},{"lineNumber":72,"author":{"gitId":"-"},"content":" [isAddDisabled]\u003d\"activeRequests \u003e 0\""},{"lineNumber":73,"author":{"gitId":"-"},"content":" (addInstructorEvent)\u003d\"addInstructor(i)\""},{"lineNumber":74,"author":{"gitId":"-"},"content":" (removeInstructorEvent)\u003d\"removeInstructor(i)\""},{"lineNumber":75,"author":{"gitId":"-"},"content":" (toggleEditModeEvent)\u003d\"setInstructorRowEditModeEnabled(i, $event)\""},{"lineNumber":76,"author":{"gitId":"-"},"content":" \u003e\u003c/tr\u003e"},{"lineNumber":77,"author":{"gitId":"-"},"content":" \u003c/tbody\u003e"},{"lineNumber":78,"author":{"gitId":"-"},"content":" \u003c/table\u003e"},{"lineNumber":79,"author":{"gitId":"-"},"content":" \u003cbutton class\u003d\"btn btn-primary top-padded\" (click)\u003d\"addAllInstructors()\" id\u003d\"add-all-instructors\" [disabled]\u003d\"activeRequests \u003e 0 || isAddingInstructors\"\u003e"},{"lineNumber":80,"author":{"gitId":"-"},"content":" \u003ctm-ajax-loading *ngIf\u003d\"isAddingInstructors\"\u003e\u003c/tm-ajax-loading\u003e"},{"lineNumber":81,"author":{"gitId":"-"},"content":" Add All Instructors"},{"lineNumber":82,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":83,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":84,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":85,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":86,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":87,"author":{"gitId":"domoberzin"},"content":"\u003ctm-account-request-table *ngIf\u003d\"accountReqs.length\" [accountRequests]\u003d\"accountReqs\" [searchString]\u003d\"\"\u003e\u003c/tm-account-request-table\u003e"}],"authorContributionMap":{"domoberzin":2,"-":85}},{"path":"src/web/app/pages-admin/admin-home-page/admin-home-page.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { HttpClientTestingModule } from \u0027@angular/common/http/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { ComponentFixture, TestBed, waitForAsync } from \u0027@angular/core/testing\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { FormsModule } from \u0027@angular/forms\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { RouterTestingModule } from \u0027@angular/router/testing\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { of, throwError } from \u0027rxjs\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { AdminHomePageComponent } from \u0027./admin-home-page.component\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { InstructorData } from \u0027./instructor-data\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { NewInstructorDataRowComponent } from \u0027./new-instructor-data-row/new-instructor-data-row.component\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { AccountService } from \u0027../../../services/account.service\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { LinkService } from \u0027../../../services/link.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { StatusMessageService } from \u0027../../../services/status-message.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { AccountRequestStatus } from \u0027../../../types/api-output\u0027;"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"import { AccountRequestTableModule } from \u0027../../components/account-requests-table/account-request-table.module\u0027;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import { AjaxLoadingModule } from \u0027../../components/ajax-loading/ajax-loading.module\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import { LoadingSpinnerModule } from \u0027../../components/loading-spinner/loading-spinner.module\u0027;"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":"import { FormatDateDetailPipe } from \u0027../../components/teammates-common/format-date-detail.pipe\u0027;"},{"lineNumber":17,"author":{"gitId":"-"},"content":""},{"lineNumber":18,"author":{"gitId":"-"},"content":"describe(\u0027AdminHomePageComponent\u0027, () \u003d\u003e {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" let component: AdminHomePageComponent;"},{"lineNumber":20,"author":{"gitId":"-"},"content":" let fixture: ComponentFixture\u003cAdminHomePageComponent\u003e;"},{"lineNumber":21,"author":{"gitId":"-"},"content":" let accountService: AccountService;"},{"lineNumber":22,"author":{"gitId":"-"},"content":" let linkService: LinkService;"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" beforeEach(waitForAsync(() \u003d\u003e {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" TestBed.configureTestingModule({"},{"lineNumber":26,"author":{"gitId":"-"},"content":" declarations: ["},{"lineNumber":27,"author":{"gitId":"-"},"content":" AdminHomePageComponent,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" NewInstructorDataRowComponent,"},{"lineNumber":29,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":30,"author":{"gitId":"-"},"content":" imports: ["},{"lineNumber":31,"author":{"gitId":"-"},"content":" FormsModule,"},{"lineNumber":32,"author":{"gitId":"-"},"content":" HttpClientTestingModule,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" LoadingSpinnerModule,"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" AccountRequestTableModule,"},{"lineNumber":35,"author":{"gitId":"-"},"content":" AjaxLoadingModule,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" RouterTestingModule,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":38,"author":{"gitId":"-"},"content":" providers: ["},{"lineNumber":39,"author":{"gitId":"-"},"content":" AccountService,"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" FormatDateDetailPipe,"},{"lineNumber":41,"author":{"gitId":"-"},"content":" StatusMessageService,"},{"lineNumber":42,"author":{"gitId":"-"},"content":" LinkService,"},{"lineNumber":43,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":44,"author":{"gitId":"-"},"content":" })"},{"lineNumber":45,"author":{"gitId":"-"},"content":" .compileComponents();"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" fixture \u003d TestBed.createComponent(AdminHomePageComponent);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" accountService \u003d TestBed.inject(AccountService);"},{"lineNumber":51,"author":{"gitId":"-"},"content":" linkService \u003d TestBed.inject(LinkService);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":53,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":54,"author":{"gitId":"-"},"content":" });"},{"lineNumber":55,"author":{"gitId":"-"},"content":""},{"lineNumber":56,"author":{"gitId":"-"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":57,"author":{"gitId":"-"},"content":" expect(component).toBeTruthy();"},{"lineNumber":58,"author":{"gitId":"-"},"content":" });"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" it(\u0027should add one instructor to list if all fields are filled\u0027, () \u003d\u003e {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" component.instructorName \u003d \u0027Instructor Name\u0027;"},{"lineNumber":62,"author":{"gitId":"-"},"content":" component.instructorEmail \u003d \u0027instructor@example.com\u0027;"},{"lineNumber":63,"author":{"gitId":"-"},"content":" component.instructorInstitution \u003d \u0027Instructor Institution\u0027;"},{"lineNumber":64,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":65,"author":{"gitId":"-"},"content":""},{"lineNumber":66,"author":{"gitId":"-"},"content":" const button: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#add-instructor\u0027);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" button.click();"},{"lineNumber":68,"author":{"gitId":"-"},"content":""},{"lineNumber":69,"author":{"gitId":"-"},"content":" expect(component.instructorName).toEqual(\u0027\u0027);"},{"lineNumber":70,"author":{"gitId":"-"},"content":" expect(component.instructorEmail).toEqual(\u0027\u0027);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" expect(component.instructorInstitution).toEqual(\u0027\u0027);"},{"lineNumber":72,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated.length).toEqual(1);"},{"lineNumber":73,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[0]).toEqual({"},{"lineNumber":74,"author":{"gitId":"-"},"content":" email: \u0027instructor@example.com\u0027,"},{"lineNumber":75,"author":{"gitId":"-"},"content":" institution: \u0027Instructor Institution\u0027,"},{"lineNumber":76,"author":{"gitId":"-"},"content":" name: \u0027Instructor Name\u0027,"},{"lineNumber":77,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":79,"author":{"gitId":"-"},"content":" });"},{"lineNumber":80,"author":{"gitId":"-"},"content":" });"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" it(\u0027should not add one instructor to list if some fields are empty\u0027, () \u003d\u003e {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" component.instructorName \u003d \u0027Instructor Name\u0027;"},{"lineNumber":84,"author":{"gitId":"-"},"content":" component.instructorEmail \u003d \u0027\u0027;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" component.instructorInstitution \u003d \u0027Instructor Institution\u0027;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" const button: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#add-instructor\u0027);"},{"lineNumber":89,"author":{"gitId":"-"},"content":" button.click();"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" expect(component.instructorName).toEqual(\u0027Instructor Name\u0027);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" expect(component.instructorEmail).toEqual(\u0027\u0027);"},{"lineNumber":93,"author":{"gitId":"-"},"content":" expect(component.instructorInstitution).toEqual(\u0027Instructor Institution\u0027);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated.length).toEqual(0);"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" component.instructorName \u003d \u0027\u0027;"},{"lineNumber":97,"author":{"gitId":"-"},"content":" component.instructorEmail \u003d \u0027instructor@example.com\u0027;"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" button.click();"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" expect(component.instructorName).toEqual(\u0027\u0027);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" expect(component.instructorEmail).toEqual(\u0027instructor@example.com\u0027);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" expect(component.instructorInstitution).toEqual(\u0027Instructor Institution\u0027);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated.length).toEqual(0);"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":" component.instructorName \u003d \u0027Instructor Name\u0027;"},{"lineNumber":107,"author":{"gitId":"-"},"content":" component.instructorInstitution \u003d \u0027\u0027;"},{"lineNumber":108,"author":{"gitId":"-"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" button.click();"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" expect(component.instructorName).toEqual(\u0027Instructor Name\u0027);"},{"lineNumber":112,"author":{"gitId":"-"},"content":" expect(component.instructorEmail).toEqual(\u0027instructor@example.com\u0027);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" expect(component.instructorInstitution).toEqual(\u0027\u0027);"},{"lineNumber":114,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated.length).toEqual(0);"},{"lineNumber":115,"author":{"gitId":"-"},"content":" });"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" it(\u0027should only add valid instructor details in the single line field\u0027, () \u003d\u003e {"},{"lineNumber":118,"author":{"gitId":"-"},"content":" component.instructorDetails \u003d ["},{"lineNumber":119,"author":{"gitId":"-"},"content":" \u0027Instructor A | instructora@example.com | Institution A\u0027,"},{"lineNumber":120,"author":{"gitId":"-"},"content":" \u0027Instructor B | instructorb@example.com\u0027,"},{"lineNumber":121,"author":{"gitId":"-"},"content":" \u0027Instructor C | | instructorc@example.com\u0027,"},{"lineNumber":122,"author":{"gitId":"-"},"content":" \u0027Instructor D | instructord@example.com | Institution D\u0027,"},{"lineNumber":123,"author":{"gitId":"-"},"content":" \u0027| instructore@example.com | Institution E\u0027,"},{"lineNumber":124,"author":{"gitId":"-"},"content":" ].join(\u0027\\n\u0027);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" const button: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#add-instructor-single-line\u0027);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" button.click();"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" expect(component.instructorDetails).toEqual(["},{"lineNumber":131,"author":{"gitId":"-"},"content":" \u0027Instructor B | instructorb@example.com\u0027,"},{"lineNumber":132,"author":{"gitId":"-"},"content":" \u0027Instructor C | | instructorc@example.com\u0027,"},{"lineNumber":133,"author":{"gitId":"-"},"content":" \u0027| instructore@example.com | Institution E\u0027,"},{"lineNumber":134,"author":{"gitId":"-"},"content":" ].join(\u0027\\r\\n\u0027));"},{"lineNumber":135,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated.length).toEqual(2);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[0]).toEqual({"},{"lineNumber":137,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":138,"author":{"gitId":"-"},"content":" institution: \u0027Institution A\u0027,"},{"lineNumber":139,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":140,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":141,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":142,"author":{"gitId":"-"},"content":" });"},{"lineNumber":143,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[1]).toEqual({"},{"lineNumber":144,"author":{"gitId":"-"},"content":" email: \u0027instructord@example.com\u0027,"},{"lineNumber":145,"author":{"gitId":"-"},"content":" institution: \u0027Institution D\u0027,"},{"lineNumber":146,"author":{"gitId":"-"},"content":" name: \u0027Instructor D\u0027,"},{"lineNumber":147,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":148,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":149,"author":{"gitId":"-"},"content":" });"},{"lineNumber":150,"author":{"gitId":"-"},"content":" });"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" it(\u0027should remove instructor out of queue if REMOVE is requested\u0027, () \u003d\u003e {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" const instructorData: InstructorData \u003d {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":155,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":156,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":157,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":158,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":159,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":160,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":161,"author":{"gitId":"-"},"content":" };"},{"lineNumber":162,"author":{"gitId":"-"},"content":" component.instructorsConsolidated \u003d [instructorData];"},{"lineNumber":163,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" const index: number \u003d 0;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" component.removeInstructor(index);"},{"lineNumber":167,"author":{"gitId":"-"},"content":""},{"lineNumber":168,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated.includes(instructorData)).toBeFalsy();"},{"lineNumber":169,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated.length).toEqual(0);"},{"lineNumber":170,"author":{"gitId":"-"},"content":" });"},{"lineNumber":171,"author":{"gitId":"-"},"content":""},{"lineNumber":172,"author":{"gitId":"-"},"content":" it(\u0027should add instructor and update field when successful\u0027, () \u003d\u003e {"},{"lineNumber":173,"author":{"gitId":"-"},"content":" component.instructorsConsolidated \u003d ["},{"lineNumber":174,"author":{"gitId":"-"},"content":" {"},{"lineNumber":175,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":176,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":177,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":178,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":179,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":180,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":181,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":182,"author":{"gitId":"-"},"content":" },"},{"lineNumber":183,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":184,"author":{"gitId":"-"},"content":" jest.spyOn(accountService, \u0027createAccountRequest\u0027).mockReturnValue(of({"},{"lineNumber":185,"author":{"gitId":"-"},"content":" id: \u0027some.person@example.com%NUS\u0027,"},{"lineNumber":186,"author":{"gitId":"-"},"content":" email: \u0027some.person@example.com\u0027,"},{"lineNumber":187,"author":{"gitId":"-"},"content":" name: \u0027Some Person\u0027,"},{"lineNumber":188,"author":{"gitId":"-"},"content":" institute: \u0027NUS\u0027,"},{"lineNumber":189,"author":{"gitId":"-"},"content":" status: AccountRequestStatus.APPROVED,"},{"lineNumber":190,"author":{"gitId":"-"},"content":" registrationKey: \u0027registrationKey\u0027,"},{"lineNumber":191,"author":{"gitId":"-"},"content":" createdAt: 528,"},{"lineNumber":192,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":193,"author":{"gitId":"-"},"content":" jest.spyOn(linkService, \u0027generateAccountRegistrationLink\u0027)"},{"lineNumber":194,"author":{"gitId":"-"},"content":" .mockReturnValue(\u0027http://localhost:4200/web/join?iscreatingaccount\u003dtrue\u0026key\u003dregistrationKey\u0027);"},{"lineNumber":195,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":196,"author":{"gitId":"-"},"content":""},{"lineNumber":197,"author":{"gitId":"-"},"content":" const index: number \u003d 0;"},{"lineNumber":198,"author":{"gitId":"-"},"content":" component.addInstructor(index);"},{"lineNumber":199,"author":{"gitId":"-"},"content":""},{"lineNumber":200,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[index].status).toEqual(\u0027SUCCESS\u0027);"},{"lineNumber":201,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[index].joinLink)"},{"lineNumber":202,"author":{"gitId":"-"},"content":" .toEqual(\u0027http://localhost:4200/web/join?iscreatingaccount\u003dtrue\u0026key\u003dregistrationKey\u0027);"},{"lineNumber":203,"author":{"gitId":"-"},"content":" expect(component.activeRequests).toEqual(0);"},{"lineNumber":204,"author":{"gitId":"-"},"content":" });"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" it(\u0027should not add instructor and update field during failure\u0027, () \u003d\u003e {"},{"lineNumber":207,"author":{"gitId":"-"},"content":" component.instructorsConsolidated \u003d ["},{"lineNumber":208,"author":{"gitId":"-"},"content":" {"},{"lineNumber":209,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":210,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":211,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":212,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":213,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":214,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":215,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":216,"author":{"gitId":"-"},"content":" },"},{"lineNumber":217,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":218,"author":{"gitId":"-"},"content":" jest.spyOn(accountService, \u0027createAccountRequest\u0027).mockReturnValue(throwError(() \u003d\u003e ({"},{"lineNumber":219,"author":{"gitId":"-"},"content":" error: {"},{"lineNumber":220,"author":{"gitId":"-"},"content":" message: \u0027This is the error message\u0027,"},{"lineNumber":221,"author":{"gitId":"-"},"content":" },"},{"lineNumber":222,"author":{"gitId":"-"},"content":" })));"},{"lineNumber":223,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":224,"author":{"gitId":"-"},"content":""},{"lineNumber":225,"author":{"gitId":"-"},"content":" const index: number \u003d 0;"},{"lineNumber":226,"author":{"gitId":"-"},"content":" component.addInstructor(index);"},{"lineNumber":227,"author":{"gitId":"-"},"content":""},{"lineNumber":228,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[index].status).toEqual(\u0027FAIL\u0027);"},{"lineNumber":229,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[index].message).toEqual(\u0027This is the error message\u0027);"},{"lineNumber":230,"author":{"gitId":"-"},"content":" expect(component.activeRequests).toEqual(0);"},{"lineNumber":231,"author":{"gitId":"-"},"content":" });"},{"lineNumber":232,"author":{"gitId":"-"},"content":""},{"lineNumber":233,"author":{"gitId":"-"},"content":" it(\u0027should enter edit mode for only the specified instructor\u0027, () \u003d\u003e {"},{"lineNumber":234,"author":{"gitId":"-"},"content":" component.instructorsConsolidated \u003d ["},{"lineNumber":235,"author":{"gitId":"-"},"content":" {"},{"lineNumber":236,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":237,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":238,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":239,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":240,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":241,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":242,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":243,"author":{"gitId":"-"},"content":" },"},{"lineNumber":244,"author":{"gitId":"-"},"content":" {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" name: \u0027Instructor B\u0027,"},{"lineNumber":246,"author":{"gitId":"-"},"content":" email: \u0027instructorb@example.com\u0027,"},{"lineNumber":247,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution B\u0027,"},{"lineNumber":248,"author":{"gitId":"-"},"content":" status: \u0027SUCCESS\u0027,"},{"lineNumber":249,"author":{"gitId":"-"},"content":" statusCode: 200,"},{"lineNumber":250,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":251,"author":{"gitId":"-"},"content":" joinLink: \u0027http://localhost:4200/web/join\u0027,"},{"lineNumber":252,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":253,"author":{"gitId":"-"},"content":" },"},{"lineNumber":254,"author":{"gitId":"-"},"content":" {"},{"lineNumber":255,"author":{"gitId":"-"},"content":" name: \u0027Instructor C\u0027,"},{"lineNumber":256,"author":{"gitId":"-"},"content":" email: \u0027instructorc@example.com\u0027,"},{"lineNumber":257,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution C\u0027,"},{"lineNumber":258,"author":{"gitId":"-"},"content":" status: \u0027FAIL\u0027,"},{"lineNumber":259,"author":{"gitId":"-"},"content":" statusCode: 400,"},{"lineNumber":260,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":261,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":262,"author":{"gitId":"-"},"content":" message: \u0027The instructor cannot be added for some reason\u0027,"},{"lineNumber":263,"author":{"gitId":"-"},"content":" },"},{"lineNumber":264,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":265,"author":{"gitId":"-"},"content":""},{"lineNumber":266,"author":{"gitId":"-"},"content":" const index: number \u003d 2;"},{"lineNumber":267,"author":{"gitId":"-"},"content":" component.setInstructorRowEditModeEnabled(index, true);"},{"lineNumber":268,"author":{"gitId":"-"},"content":""},{"lineNumber":269,"author":{"gitId":"-"},"content":" for (let i: number \u003d 0; i \u003c component.instructorsConsolidated.length; i +\u003d 1) {"},{"lineNumber":270,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[i].isCurrentlyBeingEdited).toEqual(i \u003d\u003d\u003d index);"},{"lineNumber":271,"author":{"gitId":"-"},"content":" }"},{"lineNumber":272,"author":{"gitId":"-"},"content":" });"},{"lineNumber":273,"author":{"gitId":"-"},"content":""},{"lineNumber":274,"author":{"gitId":"-"},"content":" it(\u0027should exit edit mode for only the specified instructor\u0027, () \u003d\u003e {"},{"lineNumber":275,"author":{"gitId":"-"},"content":" component.instructorsConsolidated \u003d ["},{"lineNumber":276,"author":{"gitId":"-"},"content":" {"},{"lineNumber":277,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":278,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":279,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":280,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":281,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":282,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":283,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":284,"author":{"gitId":"-"},"content":" },"},{"lineNumber":285,"author":{"gitId":"-"},"content":" {"},{"lineNumber":286,"author":{"gitId":"-"},"content":" name: \u0027Instructor B\u0027,"},{"lineNumber":287,"author":{"gitId":"-"},"content":" email: \u0027instructorb@example.com\u0027,"},{"lineNumber":288,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution B\u0027,"},{"lineNumber":289,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":290,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":291,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":292,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":293,"author":{"gitId":"-"},"content":" },"},{"lineNumber":294,"author":{"gitId":"-"},"content":" {"},{"lineNumber":295,"author":{"gitId":"-"},"content":" name: \u0027Instructor C\u0027,"},{"lineNumber":296,"author":{"gitId":"-"},"content":" email: \u0027instructorc@example.com\u0027,"},{"lineNumber":297,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution C\u0027,"},{"lineNumber":298,"author":{"gitId":"-"},"content":" status: \u0027FAIL\u0027,"},{"lineNumber":299,"author":{"gitId":"-"},"content":" statusCode: 400,"},{"lineNumber":300,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":301,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":302,"author":{"gitId":"-"},"content":" message: \u0027The instructor cannot be added for some reason\u0027,"},{"lineNumber":303,"author":{"gitId":"-"},"content":" },"},{"lineNumber":304,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":305,"author":{"gitId":"-"},"content":" for (let i: number \u003d 0; i \u003c component.instructorsConsolidated.length; i +\u003d 1) {"},{"lineNumber":306,"author":{"gitId":"-"},"content":" component.setInstructorRowEditModeEnabled(i, true);"},{"lineNumber":307,"author":{"gitId":"-"},"content":" }"},{"lineNumber":308,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":309,"author":{"gitId":"-"},"content":""},{"lineNumber":310,"author":{"gitId":"-"},"content":" const index: number \u003d 1;"},{"lineNumber":311,"author":{"gitId":"-"},"content":" component.setInstructorRowEditModeEnabled(index, false);"},{"lineNumber":312,"author":{"gitId":"-"},"content":""},{"lineNumber":313,"author":{"gitId":"-"},"content":" for (let i: number \u003d 0; i \u003c component.instructorsConsolidated.length; i +\u003d 1) {"},{"lineNumber":314,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[i].isCurrentlyBeingEdited).toEqual(i !\u003d\u003d index);"},{"lineNumber":315,"author":{"gitId":"-"},"content":" }"},{"lineNumber":316,"author":{"gitId":"-"},"content":" });"},{"lineNumber":317,"author":{"gitId":"-"},"content":""},{"lineNumber":318,"author":{"gitId":"-"},"content":" it(\u0027should add all instructors when prompted\u0027, () \u003d\u003e {"},{"lineNumber":319,"author":{"gitId":"-"},"content":" component.instructorsConsolidated \u003d ["},{"lineNumber":320,"author":{"gitId":"-"},"content":" {"},{"lineNumber":321,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":322,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":323,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":324,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":325,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":326,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":327,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":328,"author":{"gitId":"-"},"content":" },"},{"lineNumber":329,"author":{"gitId":"-"},"content":" {"},{"lineNumber":330,"author":{"gitId":"-"},"content":" name: \u0027Instructor B\u0027,"},{"lineNumber":331,"author":{"gitId":"-"},"content":" email: \u0027instructorb@example.com\u0027,"},{"lineNumber":332,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution B\u0027,"},{"lineNumber":333,"author":{"gitId":"-"},"content":" status: \u0027SUCCESS\u0027,"},{"lineNumber":334,"author":{"gitId":"-"},"content":" statusCode: 200,"},{"lineNumber":335,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":336,"author":{"gitId":"-"},"content":" joinLink: \u0027http://localhost:4200/web/join\u0027,"},{"lineNumber":337,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":338,"author":{"gitId":"-"},"content":" },"},{"lineNumber":339,"author":{"gitId":"-"},"content":" {"},{"lineNumber":340,"author":{"gitId":"-"},"content":" name: \u0027Instructor C\u0027,"},{"lineNumber":341,"author":{"gitId":"-"},"content":" email: \u0027instructorc@example.com\u0027,"},{"lineNumber":342,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution C\u0027,"},{"lineNumber":343,"author":{"gitId":"-"},"content":" status: \u0027FAIL\u0027,"},{"lineNumber":344,"author":{"gitId":"-"},"content":" statusCode: 400,"},{"lineNumber":345,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":346,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":347,"author":{"gitId":"-"},"content":" message: \u0027The instructor cannot be added for some reason\u0027,"},{"lineNumber":348,"author":{"gitId":"-"},"content":" },"},{"lineNumber":349,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":350,"author":{"gitId":"-"},"content":" // No need to spy here as this test only tests the number of active requests added"},{"lineNumber":351,"author":{"gitId":"-"},"content":" // Testing of adding individual instructors have been done before"},{"lineNumber":352,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":353,"author":{"gitId":"-"},"content":""},{"lineNumber":354,"author":{"gitId":"-"},"content":" const button: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#add-all-instructors\u0027);"},{"lineNumber":355,"author":{"gitId":"-"},"content":" button.click();"},{"lineNumber":356,"author":{"gitId":"-"},"content":""},{"lineNumber":357,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[0].status).toEqual(\u0027ADDING\u0027);"},{"lineNumber":358,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[1].status).toEqual(\u0027SUCCESS\u0027);"},{"lineNumber":359,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[2].status).toEqual(\u0027ADDING\u0027);"},{"lineNumber":360,"author":{"gitId":"-"},"content":" expect(component.activeRequests).toEqual(2);"},{"lineNumber":361,"author":{"gitId":"-"},"content":" });"},{"lineNumber":362,"author":{"gitId":"-"},"content":""},{"lineNumber":363,"author":{"gitId":"-"},"content":" it(\u0027should add only instructors that are not currently in edit mode when trying to add all\u0027, () \u003d\u003e {"},{"lineNumber":364,"author":{"gitId":"-"},"content":" component.instructorsConsolidated \u003d ["},{"lineNumber":365,"author":{"gitId":"-"},"content":" {"},{"lineNumber":366,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":367,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":368,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":369,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":370,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":371,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":372,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":373,"author":{"gitId":"-"},"content":" },"},{"lineNumber":374,"author":{"gitId":"-"},"content":" {"},{"lineNumber":375,"author":{"gitId":"-"},"content":" name: \u0027Instructor B\u0027,"},{"lineNumber":376,"author":{"gitId":"-"},"content":" email: \u0027instructorb@example.com\u0027,"},{"lineNumber":377,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution B\u0027,"},{"lineNumber":378,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":379,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: true,"},{"lineNumber":380,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":381,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":382,"author":{"gitId":"-"},"content":" },"},{"lineNumber":383,"author":{"gitId":"-"},"content":" {"},{"lineNumber":384,"author":{"gitId":"-"},"content":" name: \u0027Instructor C\u0027,"},{"lineNumber":385,"author":{"gitId":"-"},"content":" email: \u0027instructorc@example.com\u0027,"},{"lineNumber":386,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution C\u0027,"},{"lineNumber":387,"author":{"gitId":"-"},"content":" status: \u0027FAIL\u0027,"},{"lineNumber":388,"author":{"gitId":"-"},"content":" statusCode: 400,"},{"lineNumber":389,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":390,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":391,"author":{"gitId":"-"},"content":" message: \u0027The instructor cannot be added for some reason\u0027,"},{"lineNumber":392,"author":{"gitId":"-"},"content":" },"},{"lineNumber":393,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":394,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":395,"author":{"gitId":"-"},"content":""},{"lineNumber":396,"author":{"gitId":"-"},"content":" const addAllButton: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#add-all-instructors\u0027);"},{"lineNumber":397,"author":{"gitId":"-"},"content":" addAllButton.click();"},{"lineNumber":398,"author":{"gitId":"-"},"content":""},{"lineNumber":399,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[0].status).toEqual(\u0027ADDING\u0027);"},{"lineNumber":400,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[1].status).toEqual(\u0027PENDING\u0027);"},{"lineNumber":401,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[2].status).toEqual(\u0027ADDING\u0027);"},{"lineNumber":402,"author":{"gitId":"-"},"content":" expect(component.activeRequests).toEqual(2);"},{"lineNumber":403,"author":{"gitId":"-"},"content":" });"},{"lineNumber":404,"author":{"gitId":"-"},"content":""},{"lineNumber":405,"author":{"gitId":"-"},"content":" it(\u0027should snap with default view\u0027, () \u003d\u003e {"},{"lineNumber":406,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":407,"author":{"gitId":"-"},"content":" });"},{"lineNumber":408,"author":{"gitId":"-"},"content":""},{"lineNumber":409,"author":{"gitId":"-"},"content":" it(\u0027should snap with some instructors details\u0027, () \u003d\u003e {"},{"lineNumber":410,"author":{"gitId":"-"},"content":" component.instructorsConsolidated \u003d ["},{"lineNumber":411,"author":{"gitId":"-"},"content":" {"},{"lineNumber":412,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":413,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":414,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":415,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":416,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":417,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":418,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":419,"author":{"gitId":"-"},"content":" },"},{"lineNumber":420,"author":{"gitId":"-"},"content":" {"},{"lineNumber":421,"author":{"gitId":"-"},"content":" name: \u0027Instructor B\u0027,"},{"lineNumber":422,"author":{"gitId":"-"},"content":" email: \u0027instructorb@example.com\u0027,"},{"lineNumber":423,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution B\u0027,"},{"lineNumber":424,"author":{"gitId":"-"},"content":" status: \u0027SUCCESS\u0027,"},{"lineNumber":425,"author":{"gitId":"-"},"content":" statusCode: 200,"},{"lineNumber":426,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":427,"author":{"gitId":"-"},"content":" joinLink: \u0027http://localhost:4200/web/join\u0027,"},{"lineNumber":428,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":429,"author":{"gitId":"-"},"content":" },"},{"lineNumber":430,"author":{"gitId":"-"},"content":" {"},{"lineNumber":431,"author":{"gitId":"-"},"content":" name: \u0027Instructor C\u0027,"},{"lineNumber":432,"author":{"gitId":"-"},"content":" email: \u0027instructorc@example.com\u0027,"},{"lineNumber":433,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution C\u0027,"},{"lineNumber":434,"author":{"gitId":"-"},"content":" status: \u0027FAIL\u0027,"},{"lineNumber":435,"author":{"gitId":"-"},"content":" statusCode: 400,"},{"lineNumber":436,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":437,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":438,"author":{"gitId":"-"},"content":" message: \u0027The instructor cannot be added for some reason\u0027,"},{"lineNumber":439,"author":{"gitId":"-"},"content":" },"},{"lineNumber":440,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":441,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":442,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":443,"author":{"gitId":"-"},"content":" });"},{"lineNumber":444,"author":{"gitId":"-"},"content":""},{"lineNumber":445,"author":{"gitId":"-"},"content":" it(\u0027should snap with disabled adding instructor button if there are active requests\u0027, () \u003d\u003e {"},{"lineNumber":446,"author":{"gitId":"-"},"content":" component.instructorsConsolidated \u003d ["},{"lineNumber":447,"author":{"gitId":"-"},"content":" {"},{"lineNumber":448,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":449,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":450,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":451,"author":{"gitId":"-"},"content":" status: \u0027ADDING\u0027,"},{"lineNumber":452,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":453,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":454,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":455,"author":{"gitId":"-"},"content":" },"},{"lineNumber":456,"author":{"gitId":"-"},"content":" {"},{"lineNumber":457,"author":{"gitId":"-"},"content":" name: \u0027Instructor B\u0027,"},{"lineNumber":458,"author":{"gitId":"-"},"content":" email: \u0027instructorb@example.com\u0027,"},{"lineNumber":459,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution B\u0027,"},{"lineNumber":460,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":461,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":462,"author":{"gitId":"-"},"content":" joinLink: \u0027This should not be displayed\u0027,"},{"lineNumber":463,"author":{"gitId":"-"},"content":" message: \u0027This should not be displayed\u0027,"},{"lineNumber":464,"author":{"gitId":"-"},"content":" },"},{"lineNumber":465,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":466,"author":{"gitId":"-"},"content":" component.activeRequests \u003d 1;"},{"lineNumber":467,"author":{"gitId":"-"},"content":" component.isAddingInstructors \u003d true;"},{"lineNumber":468,"author":{"gitId":"-"},"content":""},{"lineNumber":469,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":470,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":471,"author":{"gitId":"-"},"content":" });"},{"lineNumber":472,"author":{"gitId":"-"},"content":""},{"lineNumber":473,"author":{"gitId":"-"},"content":" it(\u0027should add multiple instructors split by tabs\u0027, () \u003d\u003e {"},{"lineNumber":474,"author":{"gitId":"-"},"content":" component.instructorDetails \u003d `Instructor A \\t instructora@example.com \\t Sample Institution A\\n"},{"lineNumber":475,"author":{"gitId":"-"},"content":" Instructor B \\t instructorb@example.com \\t Sample Institution B`;"},{"lineNumber":476,"author":{"gitId":"-"},"content":""},{"lineNumber":477,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":478,"author":{"gitId":"-"},"content":""},{"lineNumber":479,"author":{"gitId":"-"},"content":" const button: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#add-instructor-single-line\u0027);"},{"lineNumber":480,"author":{"gitId":"-"},"content":" button.click();"},{"lineNumber":481,"author":{"gitId":"-"},"content":""},{"lineNumber":482,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated.length).toEqual(2);"},{"lineNumber":483,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[0]).toEqual("},{"lineNumber":484,"author":{"gitId":"-"},"content":" {"},{"lineNumber":485,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":486,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":487,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":488,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":489,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":490,"author":{"gitId":"-"},"content":" },"},{"lineNumber":491,"author":{"gitId":"-"},"content":" );"},{"lineNumber":492,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[1]).toEqual("},{"lineNumber":493,"author":{"gitId":"-"},"content":" {"},{"lineNumber":494,"author":{"gitId":"-"},"content":" name: \u0027Instructor B\u0027,"},{"lineNumber":495,"author":{"gitId":"-"},"content":" email: \u0027instructorb@example.com\u0027,"},{"lineNumber":496,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution B\u0027,"},{"lineNumber":497,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":498,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":499,"author":{"gitId":"-"},"content":" },"},{"lineNumber":500,"author":{"gitId":"-"},"content":" );"},{"lineNumber":501,"author":{"gitId":"-"},"content":" });"},{"lineNumber":502,"author":{"gitId":"-"},"content":""},{"lineNumber":503,"author":{"gitId":"-"},"content":" it(\u0027should add multiple instructors split by vertical bars\u0027, () \u003d\u003e {"},{"lineNumber":504,"author":{"gitId":"-"},"content":" component.instructorDetails \u003d `Instructor A | instructora@example.com | Sample Institution A\\n"},{"lineNumber":505,"author":{"gitId":"-"},"content":" Instructor B | instructorb@example.com | Sample Institution B`;"},{"lineNumber":506,"author":{"gitId":"-"},"content":""},{"lineNumber":507,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":508,"author":{"gitId":"-"},"content":""},{"lineNumber":509,"author":{"gitId":"-"},"content":" const button: any \u003d fixture.debugElement.nativeElement.querySelector(\u0027#add-instructor-single-line\u0027);"},{"lineNumber":510,"author":{"gitId":"-"},"content":" button.click();"},{"lineNumber":511,"author":{"gitId":"-"},"content":""},{"lineNumber":512,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated.length).toEqual(2);"},{"lineNumber":513,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[0]).toEqual("},{"lineNumber":514,"author":{"gitId":"-"},"content":" {"},{"lineNumber":515,"author":{"gitId":"-"},"content":" name: \u0027Instructor A\u0027,"},{"lineNumber":516,"author":{"gitId":"-"},"content":" email: \u0027instructora@example.com\u0027,"},{"lineNumber":517,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution A\u0027,"},{"lineNumber":518,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":519,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":520,"author":{"gitId":"-"},"content":" },"},{"lineNumber":521,"author":{"gitId":"-"},"content":" );"},{"lineNumber":522,"author":{"gitId":"-"},"content":" expect(component.instructorsConsolidated[1]).toEqual("},{"lineNumber":523,"author":{"gitId":"-"},"content":" {"},{"lineNumber":524,"author":{"gitId":"-"},"content":" name: \u0027Instructor B\u0027,"},{"lineNumber":525,"author":{"gitId":"-"},"content":" email: \u0027instructorb@example.com\u0027,"},{"lineNumber":526,"author":{"gitId":"-"},"content":" institution: \u0027Sample Institution B\u0027,"},{"lineNumber":527,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":528,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":529,"author":{"gitId":"-"},"content":" },"},{"lineNumber":530,"author":{"gitId":"-"},"content":" );"},{"lineNumber":531,"author":{"gitId":"-"},"content":" });"},{"lineNumber":532,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"domoberzin":4,"-":528}},{"path":"src/web/app/pages-admin/admin-home-page/admin-home-page.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"dishenggg"},"content":"import { Component, OnInit } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"dishenggg"},"content":"import { Observable, of } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"import { finalize } from \u0027rxjs/operators\u0027;"},{"lineNumber":4,"author":{"gitId":"dishenggg"},"content":"import { InstructorData } from \u0027./instructor-data\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { AccountService } from \u0027../../../services/account.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { LinkService } from \u0027../../../services/link.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { StatusMessageService } from \u0027../../../services/status-message.service\u0027;"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":"import { TimezoneService } from \u0027../../../services/timezone.service\u0027;"},{"lineNumber":9,"author":{"gitId":"dishenggg"},"content":"import { AccountRequest, AccountRequests } from \u0027../../../types/api-output\u0027;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import { AccountRequestTableRowModel } from \u0027../../components/account-requests-table/account-request-table-model\u0027;"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":"import { FormatDateDetailPipe } from \u0027../../components/teammates-common/format-date-detail.pipe\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { ErrorMessageOutput } from \u0027../../error-message-output\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":15,"author":{"gitId":"-"},"content":" * Admin home page."},{"lineNumber":16,"author":{"gitId":"-"},"content":" */"},{"lineNumber":17,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":18,"author":{"gitId":"-"},"content":" selector: \u0027tm-admin-home-page\u0027,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" templateUrl: \u0027./admin-home-page.component.html\u0027,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./admin-home-page.component.scss\u0027],"},{"lineNumber":21,"author":{"gitId":"-"},"content":"})"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":"export class AdminHomePageComponent implements OnInit {"},{"lineNumber":23,"author":{"gitId":"-"},"content":""},{"lineNumber":24,"author":{"gitId":"-"},"content":" instructorDetails: string \u003d \u0027\u0027;"},{"lineNumber":25,"author":{"gitId":"-"},"content":" instructorName: string \u003d \u0027\u0027;"},{"lineNumber":26,"author":{"gitId":"-"},"content":" instructorEmail: string \u003d \u0027\u0027;"},{"lineNumber":27,"author":{"gitId":"-"},"content":" instructorInstitution: string \u003d \u0027\u0027;"},{"lineNumber":28,"author":{"gitId":"-"},"content":""},{"lineNumber":29,"author":{"gitId":"-"},"content":" instructorsConsolidated: InstructorData[] \u003d [];"},{"lineNumber":30,"author":{"gitId":"domoberzin"},"content":" accountReqs: AccountRequestTableRowModel[] \u003d [];"},{"lineNumber":31,"author":{"gitId":"-"},"content":" activeRequests: number \u003d 0;"},{"lineNumber":32,"author":{"gitId":"domoberzin"},"content":" currentPage: number \u003d 1;"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" pageSize: number \u003d 20;"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" items$: Observable\u003cany\u003e \u003d of([]);"},{"lineNumber":35,"author":{"gitId":"-"},"content":""},{"lineNumber":36,"author":{"gitId":"-"},"content":" isAddingInstructors: boolean \u003d false;"},{"lineNumber":37,"author":{"gitId":"-"},"content":""},{"lineNumber":38,"author":{"gitId":"-"},"content":" constructor("},{"lineNumber":39,"author":{"gitId":"-"},"content":" private accountService: AccountService,"},{"lineNumber":40,"author":{"gitId":"-"},"content":" private statusMessageService: StatusMessageService,"},{"lineNumber":41,"author":{"gitId":"domoberzin"},"content":" private timezoneService: TimezoneService,"},{"lineNumber":42,"author":{"gitId":"-"},"content":" private linkService: LinkService,"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" private formatDateDetailPipe: FormatDateDetailPipe,"},{"lineNumber":44,"author":{"gitId":"-"},"content":" ) {}"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"domoberzin"},"content":" ngOnInit(): void {"},{"lineNumber":47,"author":{"gitId":"domoberzin"},"content":" this.fetchAccountRequests();"},{"lineNumber":48,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":49,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":51,"author":{"gitId":"-"},"content":" * Validates and adds the instructor details filled with first form."},{"lineNumber":52,"author":{"gitId":"-"},"content":" */"},{"lineNumber":53,"author":{"gitId":"-"},"content":" validateAndAddInstructorDetails(): void {"},{"lineNumber":54,"author":{"gitId":"-"},"content":" const invalidLines: string[] \u003d [];"},{"lineNumber":55,"author":{"gitId":"-"},"content":" for (const instructorDetail of this.instructorDetails.split(/\\r?\\n/)) {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" const instructorDetailSplit: string[] \u003d instructorDetail.split(/[|\\t]/).map((item: string) \u003d\u003e item.trim());"},{"lineNumber":57,"author":{"gitId":"-"},"content":" if (instructorDetailSplit.length \u003c 3) {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" // TODO handle error"},{"lineNumber":59,"author":{"gitId":"-"},"content":" invalidLines.push(instructorDetail);"},{"lineNumber":60,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" }"},{"lineNumber":62,"author":{"gitId":"-"},"content":" if (!instructorDetailSplit[0] || !instructorDetailSplit[1] || !instructorDetailSplit[2]) {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" // TODO handle error"},{"lineNumber":64,"author":{"gitId":"-"},"content":" invalidLines.push(instructorDetail);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" continue;"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":" this.instructorsConsolidated.push({"},{"lineNumber":68,"author":{"gitId":"-"},"content":" name: instructorDetailSplit[0],"},{"lineNumber":69,"author":{"gitId":"-"},"content":" email: instructorDetailSplit[1],"},{"lineNumber":70,"author":{"gitId":"-"},"content":" institution: instructorDetailSplit[2],"},{"lineNumber":71,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" });"},{"lineNumber":74,"author":{"gitId":"-"},"content":" }"},{"lineNumber":75,"author":{"gitId":"-"},"content":" this.instructorDetails \u003d invalidLines.join(\u0027\\r\\n\u0027);"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":79,"author":{"gitId":"-"},"content":" * Validates and adds the instructor detail filled with second form."},{"lineNumber":80,"author":{"gitId":"-"},"content":" */"},{"lineNumber":81,"author":{"gitId":"-"},"content":" validateAndAddInstructorDetail(): void {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" if (!this.instructorName || !this.instructorEmail || !this.instructorInstitution) {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" // TODO handle error"},{"lineNumber":84,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" }"},{"lineNumber":86,"author":{"gitId":"-"},"content":" this.instructorsConsolidated.push({"},{"lineNumber":87,"author":{"gitId":"-"},"content":" name: this.instructorName,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" email: this.instructorEmail,"},{"lineNumber":89,"author":{"gitId":"-"},"content":" institution: this.instructorInstitution,"},{"lineNumber":90,"author":{"gitId":"-"},"content":" status: \u0027PENDING\u0027,"},{"lineNumber":91,"author":{"gitId":"-"},"content":" isCurrentlyBeingEdited: false,"},{"lineNumber":92,"author":{"gitId":"-"},"content":" });"},{"lineNumber":93,"author":{"gitId":"-"},"content":" this.instructorName \u003d \u0027\u0027;"},{"lineNumber":94,"author":{"gitId":"-"},"content":" this.instructorEmail \u003d \u0027\u0027;"},{"lineNumber":95,"author":{"gitId":"-"},"content":" this.instructorInstitution \u003d \u0027\u0027;"},{"lineNumber":96,"author":{"gitId":"-"},"content":" }"},{"lineNumber":97,"author":{"gitId":"-"},"content":""},{"lineNumber":98,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":99,"author":{"gitId":"-"},"content":" * Adds the instructor at the i-th index."},{"lineNumber":100,"author":{"gitId":"-"},"content":" */"},{"lineNumber":101,"author":{"gitId":"-"},"content":" addInstructor(i: number): void {"},{"lineNumber":102,"author":{"gitId":"-"},"content":" const instructor: InstructorData \u003d this.instructorsConsolidated[i];"},{"lineNumber":103,"author":{"gitId":"-"},"content":" if (this.instructorsConsolidated[i].isCurrentlyBeingEdited"},{"lineNumber":104,"author":{"gitId":"-"},"content":" || (instructor.status !\u003d\u003d \u0027PENDING\u0027 \u0026\u0026 instructor.status !\u003d\u003d \u0027FAIL\u0027)) {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":106,"author":{"gitId":"-"},"content":" }"},{"lineNumber":107,"author":{"gitId":"-"},"content":" this.activeRequests +\u003d 1;"},{"lineNumber":108,"author":{"gitId":"-"},"content":" instructor.status \u003d \u0027ADDING\u0027;"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" this.isAddingInstructors \u003d true;"},{"lineNumber":111,"author":{"gitId":"-"},"content":" this.accountService.createAccountRequest({"},{"lineNumber":112,"author":{"gitId":"-"},"content":" instructorEmail: instructor.email,"},{"lineNumber":113,"author":{"gitId":"-"},"content":" instructorName: instructor.name,"},{"lineNumber":114,"author":{"gitId":"-"},"content":" instructorInstitution: instructor.institution,"},{"lineNumber":115,"author":{"gitId":"-"},"content":" })"},{"lineNumber":116,"author":{"gitId":"-"},"content":" .pipe(finalize(() \u003d\u003e {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" this.isAddingInstructors \u003d false;"},{"lineNumber":118,"author":{"gitId":"-"},"content":" }))"},{"lineNumber":119,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":120,"author":{"gitId":"-"},"content":" next: (resp: AccountRequest) \u003d\u003e {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" instructor.status \u003d \u0027SUCCESS\u0027;"},{"lineNumber":122,"author":{"gitId":"-"},"content":" instructor.statusCode \u003d 200;"},{"lineNumber":123,"author":{"gitId":"-"},"content":" instructor.joinLink \u003d this.linkService.generateAccountRegistrationLink(resp.registrationKey);"},{"lineNumber":124,"author":{"gitId":"-"},"content":" this.activeRequests -\u003d 1;"},{"lineNumber":125,"author":{"gitId":"-"},"content":" },"},{"lineNumber":126,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":127,"author":{"gitId":"-"},"content":" instructor.status \u003d \u0027FAIL\u0027;"},{"lineNumber":128,"author":{"gitId":"-"},"content":" instructor.statusCode \u003d resp.status;"},{"lineNumber":129,"author":{"gitId":"-"},"content":" instructor.message \u003d resp.error.message;"},{"lineNumber":130,"author":{"gitId":"-"},"content":" this.activeRequests -\u003d 1;"},{"lineNumber":131,"author":{"gitId":"-"},"content":" },"},{"lineNumber":132,"author":{"gitId":"-"},"content":" });"},{"lineNumber":133,"author":{"gitId":"-"},"content":" }"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":136,"author":{"gitId":"-"},"content":" * Removes the instructor at the i-th index."},{"lineNumber":137,"author":{"gitId":"-"},"content":" */"},{"lineNumber":138,"author":{"gitId":"-"},"content":" removeInstructor(i: number): void {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" this.instructorsConsolidated.splice(i, 1);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":143,"author":{"gitId":"-"},"content":" * Sets the i-th instructor data row\u0027s edit mode status."},{"lineNumber":144,"author":{"gitId":"-"},"content":" *"},{"lineNumber":145,"author":{"gitId":"-"},"content":" * @param i The index."},{"lineNumber":146,"author":{"gitId":"-"},"content":" * @param isEnabled Whether the edit mode status is enabled."},{"lineNumber":147,"author":{"gitId":"-"},"content":" */"},{"lineNumber":148,"author":{"gitId":"-"},"content":" setInstructorRowEditModeEnabled(i: number, isEnabled: boolean): void {"},{"lineNumber":149,"author":{"gitId":"-"},"content":" this.instructorsConsolidated[i].isCurrentlyBeingEdited \u003d isEnabled;"},{"lineNumber":150,"author":{"gitId":"-"},"content":" }"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":153,"author":{"gitId":"-"},"content":" * Adds all the pending and failed-to-add instructors."},{"lineNumber":154,"author":{"gitId":"-"},"content":" */"},{"lineNumber":155,"author":{"gitId":"-"},"content":" addAllInstructors(): void {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" for (let i: number \u003d 0; i \u003c this.instructorsConsolidated.length; i +\u003d 1) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" this.addInstructor(i);"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }"},{"lineNumber":160,"author":{"gitId":"-"},"content":""},{"lineNumber":161,"author":{"gitId":"domoberzin"},"content":" private formatAccountRequests(requests: AccountRequests): AccountRequestTableRowModel[] {"},{"lineNumber":162,"author":{"gitId":"domoberzin"},"content":" const timezone: string \u003d this.timezoneService.guessTimezone() || \u0027UTC\u0027;"},{"lineNumber":163,"author":{"gitId":"domoberzin"},"content":" return requests.accountRequests.map((request) \u003d\u003e {"},{"lineNumber":164,"author":{"gitId":"domoberzin"},"content":" return {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" id: request.id,"},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":" name: request.name,"},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" email: request.email,"},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":" status: request.status,"},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" instituteAndCountry: request.institute,"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" createdAtText: this.formatDateDetailPipe.transform(request.createdAt, timezone),"},{"lineNumber":171,"author":{"gitId":"domoberzin"},"content":" registeredAtText: request.registeredAt"},{"lineNumber":172,"author":{"gitId":"domoberzin"},"content":" ? this.formatDateDetailPipe.transform(request.registeredAt, timezone) : \u0027\u0027,"},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":" comments: request.comments || \u0027\u0027,"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":" registrationLink: \u0027\u0027,"},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" showLinks: false,"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":179,"author":{"gitId":"-"},"content":""},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" fetchAccountRequests(): void {"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":" this.accountService.getPendingAccountRequests().subscribe({"},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":" next: (resp: AccountRequests) \u003d\u003e {"},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":" this.accountReqs \u003d this.formatAccountRequests(resp);"},{"lineNumber":184,"author":{"gitId":"-"},"content":" },"},{"lineNumber":185,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":186,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":187,"author":{"gitId":"-"},"content":" },"},{"lineNumber":188,"author":{"gitId":"-"},"content":" });"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":35,"dishenggg":5,"-":150}},{"path":"src/web/app/pages-admin/admin-home-page/admin-home-page.module.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { CommonModule } from \u0027@angular/common\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { NgModule } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { FormsModule } from \u0027@angular/forms\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { RouterModule, Routes } from \u0027@angular/router\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { AdminHomePageComponent } from \u0027./admin-home-page.component\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { NewInstructorDataRowComponent } from \u0027./new-instructor-data-row/new-instructor-data-row.component\u0027;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import { AccountRequestTableModule } from \u0027../../components/account-requests-table/account-request-table.module\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { AjaxLoadingModule } from \u0027../../components/ajax-loading/ajax-loading.module\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { LoadingSpinnerModule } from \u0027../../components/loading-spinner/loading-spinner.module\u0027;"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":"import { FormatDateDetailPipe } from \u0027../../components/teammates-common/format-date-detail.pipe\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"const routes: Routes \u003d ["},{"lineNumber":13,"author":{"gitId":"-"},"content":" {"},{"lineNumber":14,"author":{"gitId":"-"},"content":" path: \u0027\u0027,"},{"lineNumber":15,"author":{"gitId":"-"},"content":" component: AdminHomePageComponent,"},{"lineNumber":16,"author":{"gitId":"-"},"content":" },"},{"lineNumber":17,"author":{"gitId":"-"},"content":"];"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * Module for admin home page."},{"lineNumber":21,"author":{"gitId":"-"},"content":" */"},{"lineNumber":22,"author":{"gitId":"-"},"content":"@NgModule({"},{"lineNumber":23,"author":{"gitId":"-"},"content":" declarations: ["},{"lineNumber":24,"author":{"gitId":"-"},"content":" AdminHomePageComponent,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" NewInstructorDataRowComponent,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":27,"author":{"gitId":"-"},"content":" exports: ["},{"lineNumber":28,"author":{"gitId":"-"},"content":" AdminHomePageComponent,"},{"lineNumber":29,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":30,"author":{"gitId":"-"},"content":" imports: ["},{"lineNumber":31,"author":{"gitId":"-"},"content":" CommonModule,"},{"lineNumber":32,"author":{"gitId":"-"},"content":" FormsModule,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" RouterModule.forChild(routes),"},{"lineNumber":34,"author":{"gitId":"domoberzin"},"content":" AccountRequestTableModule,"},{"lineNumber":35,"author":{"gitId":"-"},"content":" AjaxLoadingModule,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" LoadingSpinnerModule,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":38,"author":{"gitId":"domoberzin"},"content":" providers: ["},{"lineNumber":39,"author":{"gitId":"domoberzin"},"content":" FormatDateDetailPipe,"},{"lineNumber":40,"author":{"gitId":"domoberzin"},"content":" ],"},{"lineNumber":41,"author":{"gitId":"-"},"content":"})"},{"lineNumber":42,"author":{"gitId":"-"},"content":"export class AdminHomePageModule { }"}],"authorContributionMap":{"domoberzin":6,"-":36}},{"path":"src/web/app/pages-admin/admin-search-page/admin-search-page.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"card bg-light top-padded\"\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":3,"author":{"gitId":"-"},"content":" \u003cp class\u003d\"text-muted\"\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" Tips: Surround key word to search a whole string or string contains punctuation like \"-\" \".\""},{"lineNumber":5,"author":{"gitId":"-"},"content":" \u003c/p\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"input-group\"\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"search-box\" type\u003d\"text\" class\u003d\"form-control\" aria-label\u003d\"Search\" [(ngModel)]\u003d\"searchQuery\""},{"lineNumber":9,"author":{"gitId":"-"},"content":" (keyup.enter)\u003d\"search()\" [maxlength]\u003d\"characterLimit\"\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"search-button\" class\u003d\"btn btn-primary input-group-text\" (click)\u003d\"search()\"\u003eSearch\u003c/button\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003cspan\u003e{{ characterLimit - searchQuery.length }} characters left\u003c/span\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"card bg-light top-padded\" *ngIf\u003d\"instructors.length\"\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header bg-info\"\u003e"},{"lineNumber":18,"author":{"gitId":"-"},"content":" \u003cstrong\u003eInstructors Found\u003c/strong\u003e"},{"lineNumber":19,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header-btn-toolbar\"\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"show-instructor-links\" class\u003d\"btn btn-light btn-sm\" style\u003d\"margin-right: 10px;\" type\u003d\"button\" (click)\u003d\"showAllInstructorsLinks()\"\u003eExpand All\u003c/button\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"hide-instructor-links\" class\u003d\"btn btn-light btn-sm\" type\u003d\"button\" (click)\u003d\"hideAllInstructorsLinks()\"\u003eCollapse All\u003c/button\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":23,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":""},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"table-responsive\"\u003e"},{"lineNumber":26,"author":{"gitId":"-"},"content":" \u003ctable id\u003d\"search-table-instructor\" class\u003d\"table table-striped data-table\"\u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003cthead\u003e"},{"lineNumber":28,"author":{"gitId":"-"},"content":" \u003ctr\u003e"},{"lineNumber":29,"author":{"gitId":"-"},"content":" \u003cth\u003eCourse\u003c/th\u003e"},{"lineNumber":30,"author":{"gitId":"-"},"content":" \u003cth\u003eName\u003c/th\u003e"},{"lineNumber":31,"author":{"gitId":"-"},"content":" \u003cth\u003eGoogle ID\u003c/th\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003cth\u003eInstitute\u003c/th\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003cth\u003eOptions\u003c/th\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":" \u003c/thead\u003e"},{"lineNumber":36,"author":{"gitId":"-"},"content":" \u003ctbody\u003e"},{"lineNumber":37,"author":{"gitId":"-"},"content":" \u003cng-container *ngFor\u003d\"let instructor of instructors; let i \u003d index\"\u003e"},{"lineNumber":38,"author":{"gitId":"-"},"content":" \u003ctr (click)\u003d\"instructor.showLinks \u003d !instructor.showLinks\"\u003e"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003ctd class\u003d\"text-break\"\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"ngb-tooltip-class\" [ngClass]\u003d\"{\u0027text-course-deleted\u0027: instructor.isCourseDeleted}\" [ngbTooltip]\u003d\"instructor.courseName\" [innerHtml]\u003d\"instructor.courseId | highlighter:searchString:true\"\u003e\u003c/span\u003e"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003ci *ngIf\u003d\"instructor.isCourseDeleted\" class\u003d\"fas fa-trash-alt text-course-deleted margin-left-5px bin-icon\" [ngbTooltip]\u003d\"\u0027This course is in the recycle bin.\u0027\"\u003e\u003c/i\u003e"},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u003cbr\u003e"},{"lineNumber":43,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-sm-1\"\u003e"},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u003cbutton *ngIf\u003d\"!instructor.showLinks\" class\u003d\"btn\" aria-label\u003d\"Expand\"\u003e"},{"lineNumber":45,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-chevron-circle-down\" style\u003d\"color: blue;\"\u003e\u003c/i\u003e"},{"lineNumber":46,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":47,"author":{"gitId":"-"},"content":" \u003cbutton *ngIf\u003d\"instructor.showLinks\" class\u003d\"btn\" aria-label\u003d\"Collapse\"\u003e"},{"lineNumber":48,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-chevron-circle-up\" style\u003d\"color: blue;\"\u003e\u003c/i\u003e"},{"lineNumber":49,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":50,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":51,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":52,"author":{"gitId":"-"},"content":" \u003ctd [innerHtml]\u003d\"instructor.name | highlighter:searchString:true\"\u003e\u003c/td\u003e"},{"lineNumber":53,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003ca href\u003d\"{{ instructor.homePageLink }}\" (click)\u003d\"$event.stopPropagation()\" target\u003d\"_blank\" rel\u003d\"noopener noreferrer\" [innerHtml]\u003d\"instructor.googleId | highlighter:searchString:true\"\u003e"},{"lineNumber":54,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":56,"author":{"gitId":"-"},"content":" \u003ctd [innerHtml]\u003d\"instructor.institute | highlighter:searchString:true\"\u003e\u003c/td\u003e"},{"lineNumber":57,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":58,"author":{"gitId":"-"},"content":" \u003ca href\u003d\"{{ instructor.manageAccountLink }}\" *ngIf\u003d\"instructor.manageAccountLink\""},{"lineNumber":59,"author":{"gitId":"-"},"content":" (click)\u003d\"$event.stopPropagation()\" target\u003d\"_blank\" rel\u003d\"noopener noreferrer\"\u003e"},{"lineNumber":60,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-info-circle\"\u003e\u003c/i\u003e Manage this account"},{"lineNumber":61,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":62,"author":{"gitId":"-"},"content":" \u003cbr\u003e"},{"lineNumber":63,"author":{"gitId":"-"},"content":" \u003ca id\u003d\"reset-instructor-id-{{i}}\" href\u003d\"javascript:;\" (click)\u003d\"resetInstructorGoogleId(instructor, $event)\" *ngIf\u003d\"instructor.googleId\"\u003e"},{"lineNumber":64,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sync\"\u003e\u003c/i\u003e Reset Google ID"},{"lineNumber":65,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":66,"author":{"gitId":"-"},"content":" \u003cbr\u003e"},{"lineNumber":67,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"regenerate-instructor-key-{{i}}\" class\u003d\"btn btn-danger\" (click)\u003d\"instructor.showLinks \u003d !instructor.showLinks; regenerateInstructorKey(instructor);\"\u003eRegenerate key\u003c/button\u003e"},{"lineNumber":68,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":69,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":70,"author":{"gitId":"-"},"content":" \u003ctr *ngIf\u003d\"instructor.showLinks\"\u003e"},{"lineNumber":71,"author":{"gitId":"-"},"content":" \u003ctd colspan\u003d\"5\"\u003e"},{"lineNumber":72,"author":{"gitId":"-"},"content":" \u003cul class\u003d\"list-group\"\u003e"},{"lineNumber":73,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-success has-success\"\u003e"},{"lineNumber":74,"author":{"gitId":"-"},"content":" \u003cstrong\u003eEmail\u003c/strong\u003e"},{"lineNumber":75,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"instructor.email\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":76,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":77,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-info\"\u003e"},{"lineNumber":78,"author":{"gitId":"-"},"content":" \u003cstrong\u003eCourse Join Link\u003c/strong\u003e"},{"lineNumber":79,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"instructor.courseJoinLink\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":80,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":81,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-light\" *ngFor\u003d\"let awaitingFs of instructor.awaitingSessions | keyvalue\"\u003e"},{"lineNumber":82,"author":{"gitId":"-"},"content":" \u003cstrong\u003e{{ awaitingFs.key + \u0027 \u0027 + awaitingFs.value.startTime + \u0027 - \u0027 + awaitingFs.value.endTime }}\u003c/strong\u003e"},{"lineNumber":83,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"awaitingFs.value.feedbackSessionUrl\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":84,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":85,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-warning\" *ngFor\u003d\"let openFs of instructor.openSessions | keyvalue\"\u003e"},{"lineNumber":86,"author":{"gitId":"-"},"content":" \u003cstrong\u003e{{ openFs.key + \u0027 \u0027 + openFs.value.startTime + \u0027 - \u0027 + openFs.value.endTime }}\u003c/strong\u003e"},{"lineNumber":87,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"openFs.value.feedbackSessionUrl\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":88,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":89,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-danger\" *ngFor\u003d\"let notOpenFs of instructor.notOpenSessions | keyvalue\"\u003e"},{"lineNumber":90,"author":{"gitId":"-"},"content":" \u003cstrong\u003e{{ notOpenFs.key + \u0027 \u0027 + notOpenFs.value.startTime + \u0027 - \u0027 + notOpenFs.value.endTime }}\u003c/strong\u003e"},{"lineNumber":91,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"notOpenFs.value.feedbackSessionUrl\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":92,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":93,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-success\" *ngFor\u003d\"let publishedFs of instructor.publishedSessions | keyvalue\"\u003e"},{"lineNumber":94,"author":{"gitId":"-"},"content":" \u003cstrong\u003e{{ publishedFs.key + \u0027 \u0027 + publishedFs.value.startTime + \u0027 - \u0027 + publishedFs.value.endTime }}\u003c/strong\u003e"},{"lineNumber":95,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"publishedFs.value.feedbackSessionUrl\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":96,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":97,"author":{"gitId":"-"},"content":" \u003c/ul\u003e"},{"lineNumber":98,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":99,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":100,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":101,"author":{"gitId":"-"},"content":" \u003c/tbody\u003e"},{"lineNumber":102,"author":{"gitId":"-"},"content":" \u003c/table\u003e"},{"lineNumber":103,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":104,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"card bg-light top-padded\" *ngIf\u003d\"students.length\"\u003e"},{"lineNumber":107,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header bg-primary text-white\"\u003e"},{"lineNumber":108,"author":{"gitId":"-"},"content":" \u003cstrong\u003eStudents Found\u003c/strong\u003e"},{"lineNumber":109,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header-btn-toolbar\"\u003e"},{"lineNumber":110,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"show-student-links\" class\u003d\"btn btn-light btn-sm\" style\u003d\"margin-right: 10px;\" type\u003d\"button\" (click)\u003d\"showAllStudentsLinks()\"\u003eExpand All\u003c/button\u003e"},{"lineNumber":111,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"hide-student-links\" class\u003d\"btn btn-light btn-sm\" type\u003d\"button\" (click)\u003d\"hideAllStudentsLinks()\"\u003eCollapse All\u003c/button\u003e"},{"lineNumber":112,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":113,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"table-responsive\"\u003e"},{"lineNumber":116,"author":{"gitId":"-"},"content":" \u003ctable class\u003d\"table table-striped data-table\" id\u003d\"search-table-student\"\u003e"},{"lineNumber":117,"author":{"gitId":"-"},"content":" \u003cthead\u003e"},{"lineNumber":118,"author":{"gitId":"-"},"content":" \u003ctr\u003e"},{"lineNumber":119,"author":{"gitId":"-"},"content":" \u003cth\u003eCourse [Section] (Team)\u003c/th\u003e"},{"lineNumber":120,"author":{"gitId":"-"},"content":" \u003cth\u003eName\u003c/th\u003e"},{"lineNumber":121,"author":{"gitId":"-"},"content":" \u003cth\u003eGoogle ID\u003c/th\u003e"},{"lineNumber":122,"author":{"gitId":"-"},"content":" \u003cth\u003eInstitute\u003c/th\u003e"},{"lineNumber":123,"author":{"gitId":"-"},"content":" \u003cth\u003eComments\u003c/th\u003e"},{"lineNumber":124,"author":{"gitId":"-"},"content":" \u003cth\u003eOptions\u003c/th\u003e"},{"lineNumber":125,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":126,"author":{"gitId":"-"},"content":" \u003c/thead\u003e"},{"lineNumber":127,"author":{"gitId":"-"},"content":" \u003ctbody\u003e"},{"lineNumber":128,"author":{"gitId":"-"},"content":" \u003cng-container *ngFor\u003d\"let student of students; let i \u003d index\"\u003e"},{"lineNumber":129,"author":{"gitId":"-"},"content":" \u003ctr (click)\u003d\"student.showLinks \u003d !student.showLinks\"\u003e"},{"lineNumber":130,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":131,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"text-break ngb-tooltip-class\" [ngClass]\u003d\"{\u0027text-course-deleted\u0027: student.isCourseDeleted}\" [ngbTooltip]\u003d\"student.courseName\""},{"lineNumber":132,"author":{"gitId":"-"},"content":" [innerHtml]\u003d\"student.courseId + \u0027 [\u0027 + student.section + \u0027] (\u0027 + student.team + \u0027)\u0027 | highlighter:searchString:true\"\u003e\u003c/span\u003e"},{"lineNumber":133,"author":{"gitId":"-"},"content":" \u003ci *ngIf\u003d\"student.isCourseDeleted\" class\u003d\"fas fa-trash-alt text-course-deleted margin-left-5px bin-icon\" [ngbTooltip]\u003d\"\u0027This course is in the recycle bin.\u0027\"\u003e\u003c/i\u003e"},{"lineNumber":134,"author":{"gitId":"-"},"content":" \u003cbr\u003e"},{"lineNumber":135,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-sm-1\"\u003e"},{"lineNumber":136,"author":{"gitId":"-"},"content":" \u003cbutton *ngIf\u003d\"!student.showLinks\" class\u003d\"btn\" aria-label\u003d\"Expand\"\u003e"},{"lineNumber":137,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-chevron-circle-down\" style\u003d\"color: blue;\"\u003e\u003c/i\u003e"},{"lineNumber":138,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":139,"author":{"gitId":"-"},"content":" \u003cbutton *ngIf\u003d\"student.showLinks\" class\u003d\"btn\" aria-label\u003d\"Collapse\"\u003e"},{"lineNumber":140,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-chevron-circle-up\" style\u003d\"color: blue;\"\u003e\u003c/i\u003e"},{"lineNumber":141,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":142,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":143,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":144,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003ca href\u003d\"{{ student.profilePageLink }}\""},{"lineNumber":145,"author":{"gitId":"-"},"content":" (click)\u003d\"$event.stopPropagation()\" target\u003d\"_blank\" rel\u003d\"noopener noreferrer\" [innerHtml]\u003d\"student.name | highlighter:searchString:true\"\u003e"},{"lineNumber":146,"author":{"gitId":"-"},"content":" \u003c/a\u003e\u003c/td\u003e"},{"lineNumber":147,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003ca href\u003d\"{{ student.homePageLink }}\" *ngIf\u003d\"student.googleId\""},{"lineNumber":148,"author":{"gitId":"-"},"content":" (click)\u003d\"$event.stopPropagation()\" target\u003d\"_blank\" rel\u003d\"noopener noreferrer\" [innerHtml]\u003d\"student.googleId | highlighter:searchString:true\"\u003e"},{"lineNumber":149,"author":{"gitId":"-"},"content":" \u003c/a\u003e\u003c/td\u003e"},{"lineNumber":150,"author":{"gitId":"-"},"content":" \u003ctd [innerHtml]\u003d\"student.institute | highlighter:searchString:true\"\u003e\u003c/td\u003e"},{"lineNumber":151,"author":{"gitId":"-"},"content":" \u003ctd [innerHtml]\u003d\"student.comments | highlighter:searchString:true\"\u003e\u003c/td\u003e"},{"lineNumber":152,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":153,"author":{"gitId":"-"},"content":" \u003ca href\u003d\"{{ student.manageAccountLink }}\" *ngIf\u003d\"student.googleId \u0026\u0026 student.manageAccountLink\""},{"lineNumber":154,"author":{"gitId":"-"},"content":" (click)\u003d\"$event.stopPropagation()\" target\u003d\"_blank\" rel\u003d\"noopener noreferrer\"\u003e"},{"lineNumber":155,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-info-circle\"\u003e\u003c/i\u003e Manage this account"},{"lineNumber":156,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":157,"author":{"gitId":"-"},"content":" \u003cbr\u003e"},{"lineNumber":158,"author":{"gitId":"-"},"content":" \u003ca id\u003d\"reset-student-id-{{i}}\" href\u003d\"javascript:;\" (click)\u003d\"resetStudentGoogleId(student, $event)\" *ngIf\u003d\"student.googleId\"\u003e"},{"lineNumber":159,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sync\"\u003e\u003c/i\u003e Reset Google ID"},{"lineNumber":160,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":161,"author":{"gitId":"-"},"content":" \u003cbr\u003e"},{"lineNumber":162,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"regenerate-student-key-{{i}}\" class\u003d\"btn btn-danger\" (click)\u003d\"student.showLinks \u003d !student.showLinks; regenerateStudentKey(student);\"\u003eRegenerate key\u003c/button\u003e"},{"lineNumber":163,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":164,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":165,"author":{"gitId":"-"},"content":" \u003ctr\u003e"},{"lineNumber":166,"author":{"gitId":"-"},"content":" \u003ctd colspan\u003d\"6\"\u003e"},{"lineNumber":167,"author":{"gitId":"-"},"content":" \u003cul class\u003d\"list-group\" *ngIf\u003d\"student.showLinks\" @collapseAnim\u003e"},{"lineNumber":168,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-success has-success\"\u003e"},{"lineNumber":169,"author":{"gitId":"-"},"content":" \u003cstrong\u003eEmail\u003c/strong\u003e"},{"lineNumber":170,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"student.email\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":171,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":172,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-info\"\u003e"},{"lineNumber":173,"author":{"gitId":"-"},"content":" \u003cstrong\u003eCourse Join Link\u003c/strong\u003e"},{"lineNumber":174,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"send-course-join-button\" type\u003d\"button\" class\u003d\"btn btn-primary margin-left-5px btn-sm\" (click)\u003d\"openCourseJoinEmail(student.courseId, student.email)\"\u003eSend mail\u003c/button\u003e"},{"lineNumber":175,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"student.courseJoinLink\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":176,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":177,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-light\" *ngFor\u003d\"let awaitingFs of student.awaitingSessions | keyvalue\"\u003e"},{"lineNumber":178,"author":{"gitId":"-"},"content":" \u003cstrong\u003e{{ awaitingFs.key + \u0027 \u0027 + awaitingFs.value.startTime + \u0027 - \u0027 + awaitingFs.value.endTime }}\u003c/strong\u003e"},{"lineNumber":179,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"send-awaiting-session-reminder-button\" type\u003d\"button\" class\u003d\"btn btn-primary margin-left-5px btn-sm\" (click)\u003d\"openFeedbackSessionReminderEmail(student.courseId, student.email, awaitingFs.key)\"\u003eSend mail\u003c/button\u003e"},{"lineNumber":180,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"awaitingFs.value.feedbackSessionUrl\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":181,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":182,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-warning\" *ngFor\u003d\"let openFs of student.openSessions | keyvalue\"\u003e"},{"lineNumber":183,"author":{"gitId":"-"},"content":" \u003cstrong\u003e{{ openFs.key + \u0027 \u0027 + openFs.value.startTime + \u0027 - \u0027 + openFs.value.endTime }}\u003c/strong\u003e"},{"lineNumber":184,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"send-open-session-reminder-button\" type\u003d\"button\" class\u003d\"btn btn-primary margin-left-5px btn-sm\" (click)\u003d\"openFeedbackSessionReminderEmail(student.courseId, student.email, openFs.key)\"\u003eSend mail\u003c/button\u003e"},{"lineNumber":185,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"openFs.value.feedbackSessionUrl\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":186,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":187,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-danger\" *ngFor\u003d\"let notOpenFs of student.notOpenSessions | keyvalue\"\u003e"},{"lineNumber":188,"author":{"gitId":"-"},"content":" \u003cstrong\u003e{{ notOpenFs.key + \u0027 \u0027 + notOpenFs.value.startTime + \u0027 - \u0027 + notOpenFs.value.endTime }}\u003c/strong\u003e"},{"lineNumber":189,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"send-not-open-session-reminder-button\" type\u003d\"button\" class\u003d\"btn btn-primary margin-left-5px btn-sm\" (click)\u003d\"openFeedbackSessionReminderEmail(student.courseId, student.email, notOpenFs.key)\"\u003eSend mail\u003c/button\u003e"},{"lineNumber":190,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"notOpenFs.value.feedbackSessionUrl\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":191,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":192,"author":{"gitId":"-"},"content":" \u003cli class\u003d\"list-group-item list-group-item-success\" *ngFor\u003d\"let publishedFs of student.publishedSessions | keyvalue\"\u003e"},{"lineNumber":193,"author":{"gitId":"-"},"content":" \u003cstrong\u003e{{ publishedFs.key + \u0027 \u0027 + publishedFs.value.startTime + \u0027 - \u0027 + publishedFs.value.endTime }}\u003c/strong\u003e"},{"lineNumber":194,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"send-published-session-reminder-button\" type\u003d\"button\" class\u003d\"btn btn-primary margin-left-5px btn-sm\" (click)\u003d\"openFeedbackSessionReminderEmail(student.courseId, student.email, publishedFs.key)\"\u003eSend mail\u003c/button\u003e"},{"lineNumber":195,"author":{"gitId":"-"},"content":" \u003cinput [value]\u003d\"publishedFs.value.feedbackSessionUrl\" disabled class\u003d\"form-control\"\u003e"},{"lineNumber":196,"author":{"gitId":"-"},"content":" \u003c/li\u003e"},{"lineNumber":197,"author":{"gitId":"-"},"content":" \u003c/ul\u003e"},{"lineNumber":198,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":199,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":200,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":201,"author":{"gitId":"-"},"content":" \u003c/tbody\u003e"},{"lineNumber":202,"author":{"gitId":"-"},"content":" \u003c/table\u003e"},{"lineNumber":203,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":204,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"domoberzin"},"content":"\u003ctm-account-request-table *ngIf\u003d\"accountRequests.length\" [accountRequests]\u003d\"accountRequests\" [searchString]\u003d\"searchString\"\u003e\u003c/tm-account-request-table\u003e"}],"authorContributionMap":{"domoberzin":1,"-":205}},{"path":"src/web/app/pages-admin/admin-search-page/admin-search-page.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { NgbModalRef } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { finalize } from \u0027rxjs/operators\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { AccountService } from \u0027../../../services/account.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { EmailGenerationService } from \u0027../../../services/email-generation.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { InstructorService } from \u0027../../../services/instructor.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { LoadingBarService } from \u0027../../../services/loading-bar.service\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":9,"author":{"gitId":"-"},"content":" AccountRequestSearchResult,"},{"lineNumber":10,"author":{"gitId":"-"},"content":" AdminSearchResult,"},{"lineNumber":11,"author":{"gitId":"-"},"content":" FeedbackSessionsGroup,"},{"lineNumber":12,"author":{"gitId":"-"},"content":" InstructorAccountSearchResult,"},{"lineNumber":13,"author":{"gitId":"-"},"content":" SearchService,"},{"lineNumber":14,"author":{"gitId":"-"},"content":" StudentAccountSearchResult,"},{"lineNumber":15,"author":{"gitId":"-"},"content":"} from \u0027../../../services/search.service\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import { SimpleModalService } from \u0027../../../services/simple-modal.service\u0027;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import { StatusMessageService } from \u0027../../../services/status-message.service\u0027;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import { StudentService } from \u0027../../../services/student.service\u0027;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import { ApiConst } from \u0027../../../types/api-const\u0027;"},{"lineNumber":20,"author":{"gitId":"domoberzin"},"content":"import { Email, RegenerateKey } from \u0027../../../types/api-output\u0027;"},{"lineNumber":21,"author":{"gitId":"domoberzin"},"content":"import {"},{"lineNumber":22,"author":{"gitId":"domoberzin"},"content":" AccountRequestTableRowModel,"},{"lineNumber":23,"author":{"gitId":"domoberzin"},"content":"} from \u0027../../components/account-requests-table/account-request-table-model\u0027;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import { SimpleModalType } from \u0027../../components/simple-modal/simple-modal-type\u0027;"},{"lineNumber":25,"author":{"gitId":"-"},"content":"import { collapseAnim } from \u0027../../components/teammates-common/collapse-anim\u0027;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import { ErrorMessageOutput } from \u0027../../error-message-output\u0027;"},{"lineNumber":27,"author":{"gitId":"-"},"content":""},{"lineNumber":28,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":29,"author":{"gitId":"-"},"content":" * Admin search page."},{"lineNumber":30,"author":{"gitId":"-"},"content":" */"},{"lineNumber":31,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":32,"author":{"gitId":"-"},"content":" selector: \u0027tm-admin-search-page\u0027,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" templateUrl: \u0027./admin-search-page.component.html\u0027,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./admin-search-page.component.scss\u0027],"},{"lineNumber":35,"author":{"gitId":"-"},"content":" animations: [collapseAnim],"},{"lineNumber":36,"author":{"gitId":"-"},"content":"})"},{"lineNumber":37,"author":{"gitId":"-"},"content":"export class AdminSearchPageComponent {"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" searchQuery: string \u003d \u0027\u0027;"},{"lineNumber":40,"author":{"gitId":"-"},"content":" searchString: string \u003d \u0027\u0027;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" instructors: InstructorAccountSearchResult[] \u003d [];"},{"lineNumber":42,"author":{"gitId":"-"},"content":" students: StudentAccountSearchResult[] \u003d [];"},{"lineNumber":43,"author":{"gitId":"domoberzin"},"content":" accountRequests: AccountRequestTableRowModel[] \u003d [];"},{"lineNumber":44,"author":{"gitId":"-"},"content":" characterLimit \u003d 100;"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":" constructor("},{"lineNumber":47,"author":{"gitId":"-"},"content":" private statusMessageService: StatusMessageService,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" private simpleModalService: SimpleModalService,"},{"lineNumber":49,"author":{"gitId":"-"},"content":" private accountService: AccountService,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" private instructorService: InstructorService,"},{"lineNumber":51,"author":{"gitId":"-"},"content":" private studentService: StudentService,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" private searchService: SearchService,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" private emailGenerationService: EmailGenerationService,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" private loadingBarService: LoadingBarService,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" ) {}"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":58,"author":{"gitId":"-"},"content":" * Searches for students and instructors matching the search query."},{"lineNumber":59,"author":{"gitId":"-"},"content":" */"},{"lineNumber":60,"author":{"gitId":"-"},"content":" search(): void {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" this.loadingBarService.showLoadingBar();"},{"lineNumber":62,"author":{"gitId":"-"},"content":" this.searchService.searchAdmin("},{"lineNumber":63,"author":{"gitId":"-"},"content":" this.searchQuery,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" ).pipe(finalize(() \u003d\u003e {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" this.loadingBarService.hideLoadingBar();"},{"lineNumber":66,"author":{"gitId":"-"},"content":" })).subscribe({"},{"lineNumber":67,"author":{"gitId":"-"},"content":" next: (resp: AdminSearchResult) \u003d\u003e {"},{"lineNumber":68,"author":{"gitId":"-"},"content":" const hasStudents: boolean \u003d !!(resp.students \u0026\u0026 resp.students.length);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" const hasInstructors: boolean \u003d !!(resp.instructors \u0026\u0026 resp.instructors.length);"},{"lineNumber":70,"author":{"gitId":"-"},"content":" const hasAccountRequests: boolean \u003d !!(resp.accountRequests \u0026\u0026 resp.accountRequests.length);"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" if (!hasStudents \u0026\u0026 !hasInstructors \u0026\u0026 !hasAccountRequests) {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" this.statusMessageService.showWarningToast(\u0027No results found.\u0027);"},{"lineNumber":74,"author":{"gitId":"-"},"content":" this.instructors \u003d [];"},{"lineNumber":75,"author":{"gitId":"-"},"content":" this.students \u003d [];"},{"lineNumber":76,"author":{"gitId":"-"},"content":" this.accountRequests \u003d [];"},{"lineNumber":77,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }"},{"lineNumber":79,"author":{"gitId":"-"},"content":""},{"lineNumber":80,"author":{"gitId":"-"},"content":" this.instructors \u003d resp.instructors;"},{"lineNumber":81,"author":{"gitId":"-"},"content":" this.students \u003d resp.students;"},{"lineNumber":82,"author":{"gitId":"domoberzin"},"content":" this.accountRequests \u003d this.formatAccountRequests(resp.accountRequests);"},{"lineNumber":83,"author":{"gitId":"-"},"content":" this.hideAllInstructorsLinks();"},{"lineNumber":84,"author":{"gitId":"-"},"content":" this.hideAllStudentsLinks();"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" // prompt user to use more specific terms if search results limit reached"},{"lineNumber":87,"author":{"gitId":"-"},"content":" const limit: number \u003d ApiConst.SEARCH_QUERY_SIZE_LIMIT;"},{"lineNumber":88,"author":{"gitId":"-"},"content":" const limitsReached: string[] \u003d [];"},{"lineNumber":89,"author":{"gitId":"-"},"content":" if (this.students.length \u003e\u003d limit) {"},{"lineNumber":90,"author":{"gitId":"-"},"content":" limitsReached.push(`${limit} student results`);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" }"},{"lineNumber":92,"author":{"gitId":"-"},"content":" if (this.instructors.length \u003e\u003d limit) {"},{"lineNumber":93,"author":{"gitId":"-"},"content":" limitsReached.push(`${limit} instructor results`);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" }"},{"lineNumber":95,"author":{"gitId":"-"},"content":" if (this.accountRequests.length \u003e\u003d limit) {"},{"lineNumber":96,"author":{"gitId":"-"},"content":" limitsReached.push(`${limit} account request results`);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" }"},{"lineNumber":98,"author":{"gitId":"-"},"content":" if (limitsReached.length) {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" this.statusMessageService.showWarningToast(`${limitsReached.join(\u0027 and \u0027)} have been shown on this page"},{"lineNumber":100,"author":{"gitId":"-"},"content":" but there may be more results not shown. Consider searching with more specific terms.`);"},{"lineNumber":101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" this.searchString \u003d this.searchQuery;"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" },"},{"lineNumber":106,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":107,"author":{"gitId":"-"},"content":" this.instructors \u003d [];"},{"lineNumber":108,"author":{"gitId":"-"},"content":" this.students \u003d [];"},{"lineNumber":109,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":110,"author":{"gitId":"-"},"content":" },"},{"lineNumber":111,"author":{"gitId":"-"},"content":" });"},{"lineNumber":112,"author":{"gitId":"-"},"content":" }"},{"lineNumber":113,"author":{"gitId":"-"},"content":""},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":" private formatAccountRequests(accountRequests: AccountRequestSearchResult[]): AccountRequestTableRowModel[] {"},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" return accountRequests.map((accountRequest: AccountRequestSearchResult): AccountRequestTableRowModel \u003d\u003e {"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" return {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" id: accountRequest.id,"},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":" name: accountRequest.name,"},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" email: accountRequest.email,"},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" status: accountRequest.status,"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":" instituteAndCountry: accountRequest.institute,"},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" createdAtText: accountRequest.createdAtText,"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":" registeredAtText: accountRequest.registeredAtText || \u0027\u0027,"},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" comments: accountRequest.comments,"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" registrationLink: accountRequest.registrationLink,"},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" showLinks: accountRequest.showLinks,"},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":128,"author":{"gitId":"domoberzin"},"content":" });"},{"lineNumber":129,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":132,"author":{"gitId":"-"},"content":" * Shows all instructors\u0027 links in the page."},{"lineNumber":133,"author":{"gitId":"-"},"content":" */"},{"lineNumber":134,"author":{"gitId":"-"},"content":" showAllInstructorsLinks(): void {"},{"lineNumber":135,"author":{"gitId":"-"},"content":" for (const instructor of this.instructors) {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" instructor.showLinks \u003d true;"},{"lineNumber":137,"author":{"gitId":"-"},"content":" }"},{"lineNumber":138,"author":{"gitId":"-"},"content":" }"},{"lineNumber":139,"author":{"gitId":"-"},"content":""},{"lineNumber":140,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":141,"author":{"gitId":"-"},"content":" * Hides all instructors\u0027 links in the page."},{"lineNumber":142,"author":{"gitId":"-"},"content":" */"},{"lineNumber":143,"author":{"gitId":"-"},"content":" hideAllInstructorsLinks(): void {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" for (const instructor of this.instructors) {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" instructor.showLinks \u003d false;"},{"lineNumber":146,"author":{"gitId":"-"},"content":" }"},{"lineNumber":147,"author":{"gitId":"-"},"content":" }"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":150,"author":{"gitId":"-"},"content":" * Shows all students\u0027 links in the page."},{"lineNumber":151,"author":{"gitId":"-"},"content":" */"},{"lineNumber":152,"author":{"gitId":"-"},"content":" showAllStudentsLinks(): void {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" for (const student of this.students) {"},{"lineNumber":154,"author":{"gitId":"-"},"content":" student.showLinks \u003d true;"},{"lineNumber":155,"author":{"gitId":"-"},"content":" }"},{"lineNumber":156,"author":{"gitId":"-"},"content":" }"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":159,"author":{"gitId":"-"},"content":" * Hides all students\u0027 links in the page."},{"lineNumber":160,"author":{"gitId":"-"},"content":" */"},{"lineNumber":161,"author":{"gitId":"-"},"content":" hideAllStudentsLinks(): void {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" for (const student of this.students) {"},{"lineNumber":163,"author":{"gitId":"-"},"content":" student.showLinks \u003d false;"},{"lineNumber":164,"author":{"gitId":"-"},"content":" }"},{"lineNumber":165,"author":{"gitId":"-"},"content":" }"},{"lineNumber":166,"author":{"gitId":"-"},"content":""},{"lineNumber":167,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":168,"author":{"gitId":"-"},"content":" * Resets the instructor\u0027s Google ID."},{"lineNumber":169,"author":{"gitId":"-"},"content":" */"},{"lineNumber":170,"author":{"gitId":"-"},"content":" resetInstructorGoogleId(instructor: InstructorAccountSearchResult, event: any): void {"},{"lineNumber":171,"author":{"gitId":"-"},"content":" if (event) {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" event.preventDefault();"},{"lineNumber":173,"author":{"gitId":"-"},"content":" event.stopPropagation();"},{"lineNumber":174,"author":{"gitId":"-"},"content":" }"},{"lineNumber":175,"author":{"gitId":"-"},"content":""},{"lineNumber":176,"author":{"gitId":"-"},"content":" const modalContent: string \u003d `Are you sure you want to reset the Google account ID currently associated for"},{"lineNumber":177,"author":{"gitId":"-"},"content":" \u003cstrong\u003e${instructor.name}\u003c/strong\u003e in the course \u003cstrong\u003e${instructor.courseId}\u003c/strong\u003e?"},{"lineNumber":178,"author":{"gitId":"-"},"content":" The user will need to re-associate their account with a new Google ID.`;"},{"lineNumber":179,"author":{"gitId":"-"},"content":" const modalRef: NgbModalRef \u003d this.simpleModalService.openConfirmationModal("},{"lineNumber":180,"author":{"gitId":"-"},"content":" `Reset \u003cstrong\u003e${instructor.name}\u003c/strong\u003e\u0027s Google ID?`, SimpleModalType.WARNING, modalContent);"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" modalRef.result.then(() \u003d\u003e {"},{"lineNumber":183,"author":{"gitId":"-"},"content":" this.accountService.resetInstructorAccount(instructor.courseId, instructor.email).subscribe({"},{"lineNumber":184,"author":{"gitId":"-"},"content":" next: () \u003d\u003e {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" this.search();"},{"lineNumber":186,"author":{"gitId":"-"},"content":" this.statusMessageService.showSuccessToast(\u0027The instructor\\\u0027s Google ID has been reset.\u0027);"},{"lineNumber":187,"author":{"gitId":"-"},"content":" },"},{"lineNumber":188,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":189,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":190,"author":{"gitId":"-"},"content":" },"},{"lineNumber":191,"author":{"gitId":"-"},"content":" });"},{"lineNumber":192,"author":{"gitId":"-"},"content":" }, () \u003d\u003e {});"},{"lineNumber":193,"author":{"gitId":"-"},"content":" }"},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":196,"author":{"gitId":"-"},"content":" * Resets the student\u0027s Google ID."},{"lineNumber":197,"author":{"gitId":"-"},"content":" */"},{"lineNumber":198,"author":{"gitId":"-"},"content":" resetStudentGoogleId(student: StudentAccountSearchResult, event: any): void {"},{"lineNumber":199,"author":{"gitId":"-"},"content":" if (event) {"},{"lineNumber":200,"author":{"gitId":"-"},"content":" event.preventDefault();"},{"lineNumber":201,"author":{"gitId":"-"},"content":" event.stopPropagation();"},{"lineNumber":202,"author":{"gitId":"-"},"content":" }"},{"lineNumber":203,"author":{"gitId":"-"},"content":" const modalContent: string \u003d `Are you sure you want to reset the Google account ID currently associated for"},{"lineNumber":204,"author":{"gitId":"-"},"content":" \u003cstrong\u003e${student.name}\u003c/strong\u003e in the course \u003cstrong\u003e${student.courseId}\u003c/strong\u003e?"},{"lineNumber":205,"author":{"gitId":"-"},"content":" The user will need to re-associate their account with a new Google ID.`;"},{"lineNumber":206,"author":{"gitId":"-"},"content":" const modalRef: NgbModalRef \u003d this.simpleModalService.openConfirmationModal("},{"lineNumber":207,"author":{"gitId":"-"},"content":" `Reset \u003cstrong\u003e${student.name}\u003c/strong\u003e\u0027s Google ID?`, SimpleModalType.WARNING, modalContent);"},{"lineNumber":208,"author":{"gitId":"-"},"content":""},{"lineNumber":209,"author":{"gitId":"-"},"content":" modalRef.result.then(() \u003d\u003e {"},{"lineNumber":210,"author":{"gitId":"-"},"content":" this.accountService.resetStudentAccount(student.courseId, student.email).subscribe({"},{"lineNumber":211,"author":{"gitId":"-"},"content":" next: () \u003d\u003e {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" student.googleId \u003d \u0027\u0027;"},{"lineNumber":213,"author":{"gitId":"-"},"content":" this.statusMessageService.showSuccessToast(\u0027The student\\\u0027s Google ID has been reset.\u0027);"},{"lineNumber":214,"author":{"gitId":"-"},"content":" },"},{"lineNumber":215,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":216,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":217,"author":{"gitId":"-"},"content":" },"},{"lineNumber":218,"author":{"gitId":"-"},"content":" });"},{"lineNumber":219,"author":{"gitId":"-"},"content":" }, () \u003d\u003e {});"},{"lineNumber":220,"author":{"gitId":"-"},"content":" }"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":223,"author":{"gitId":"-"},"content":" * Regenerates the student\u0027s registration key."},{"lineNumber":224,"author":{"gitId":"-"},"content":" */"},{"lineNumber":225,"author":{"gitId":"-"},"content":" regenerateStudentKey(student: StudentAccountSearchResult): void {"},{"lineNumber":226,"author":{"gitId":"-"},"content":" const modalContent: string \u003d `Are you sure you want to regenerate the registration key for"},{"lineNumber":227,"author":{"gitId":"-"},"content":" \u003cstrong\u003e${student.name}\u003c/strong\u003e for the course \u003cstrong\u003e${student.courseId}\u003c/strong\u003e?"},{"lineNumber":228,"author":{"gitId":"-"},"content":" An email will be sent to the student with all the new course registration and feedback session links.`;"},{"lineNumber":229,"author":{"gitId":"-"},"content":" const modalRef: NgbModalRef \u003d this.simpleModalService.openConfirmationModal("},{"lineNumber":230,"author":{"gitId":"-"},"content":" `Regenerate \u003cstrong\u003e${student.name}\u003c/strong\u003e\u0027s course links?`, SimpleModalType.WARNING, modalContent);"},{"lineNumber":231,"author":{"gitId":"-"},"content":""},{"lineNumber":232,"author":{"gitId":"-"},"content":" modalRef.result.then(() \u003d\u003e {"},{"lineNumber":233,"author":{"gitId":"-"},"content":" this.studentService.regenerateStudentKey(student.courseId, student.email)"},{"lineNumber":234,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":235,"author":{"gitId":"-"},"content":" next: (resp: RegenerateKey) \u003d\u003e {"},{"lineNumber":236,"author":{"gitId":"-"},"content":" this.statusMessageService.showSuccessToast(resp.message);"},{"lineNumber":237,"author":{"gitId":"-"},"content":" this.updateDisplayedStudentCourseLinks(student, resp.newRegistrationKey);"},{"lineNumber":238,"author":{"gitId":"-"},"content":" },"},{"lineNumber":239,"author":{"gitId":"-"},"content":" error: (response: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":240,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(response.error.message);"},{"lineNumber":241,"author":{"gitId":"-"},"content":" },"},{"lineNumber":242,"author":{"gitId":"-"},"content":" });"},{"lineNumber":243,"author":{"gitId":"-"},"content":" }, () \u003d\u003e {});"},{"lineNumber":244,"author":{"gitId":"-"},"content":" }"},{"lineNumber":245,"author":{"gitId":"-"},"content":""},{"lineNumber":246,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":247,"author":{"gitId":"-"},"content":" * Regenerates the instructor\u0027s registration key."},{"lineNumber":248,"author":{"gitId":"-"},"content":" */"},{"lineNumber":249,"author":{"gitId":"-"},"content":" regenerateInstructorKey(instructor: InstructorAccountSearchResult): void {"},{"lineNumber":250,"author":{"gitId":"-"},"content":" const modalContent: string \u003d `Are you sure you want to regenerate the registration key for"},{"lineNumber":251,"author":{"gitId":"-"},"content":" \u003cstrong\u003e${instructor.name}\u003c/strong\u003e for the course \u003cstrong\u003e${instructor.courseId}\u003c/strong\u003e?"},{"lineNumber":252,"author":{"gitId":"-"},"content":" An email will be sent to the instructor with all the new course registration and feedback session links.`;"},{"lineNumber":253,"author":{"gitId":"-"},"content":" const modalRef: NgbModalRef \u003d this.simpleModalService.openConfirmationModal("},{"lineNumber":254,"author":{"gitId":"-"},"content":" `Regenerate \u003cstrong\u003e${instructor.name}\u003c/strong\u003e\u0027s course links?`, SimpleModalType.WARNING, modalContent);"},{"lineNumber":255,"author":{"gitId":"-"},"content":""},{"lineNumber":256,"author":{"gitId":"-"},"content":" modalRef.result.then(() \u003d\u003e {"},{"lineNumber":257,"author":{"gitId":"-"},"content":" this.instructorService.regenerateInstructorKey(instructor.courseId, instructor.email)"},{"lineNumber":258,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":259,"author":{"gitId":"-"},"content":" next: (resp: RegenerateKey) \u003d\u003e {"},{"lineNumber":260,"author":{"gitId":"-"},"content":" this.statusMessageService.showSuccessToast(resp.message);"},{"lineNumber":261,"author":{"gitId":"-"},"content":" this.updateDisplayedInstructorCourseLinks(instructor, resp.newRegistrationKey);"},{"lineNumber":262,"author":{"gitId":"-"},"content":" },"},{"lineNumber":263,"author":{"gitId":"-"},"content":" error: (response: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(response.error.message);"},{"lineNumber":265,"author":{"gitId":"-"},"content":" },"},{"lineNumber":266,"author":{"gitId":"-"},"content":" });"},{"lineNumber":267,"author":{"gitId":"-"},"content":" }, () \u003d\u003e {});"},{"lineNumber":268,"author":{"gitId":"-"},"content":" }"},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":271,"author":{"gitId":"-"},"content":" * Updates the student\u0027s displayed course join and feedback session links with the value of the newKey."},{"lineNumber":272,"author":{"gitId":"-"},"content":" */"},{"lineNumber":273,"author":{"gitId":"-"},"content":" private updateDisplayedStudentCourseLinks(student: StudentAccountSearchResult, newKey: string): void {"},{"lineNumber":274,"author":{"gitId":"-"},"content":" const updateSessions \u003d (sessions: FeedbackSessionsGroup): void \u003d\u003e {"},{"lineNumber":275,"author":{"gitId":"-"},"content":" Object.keys(sessions).forEach((key: string): void \u003d\u003e {"},{"lineNumber":276,"author":{"gitId":"-"},"content":" sessions[key].feedbackSessionUrl \u003d this.getUpdatedUrl(sessions[key].feedbackSessionUrl, newKey);"},{"lineNumber":277,"author":{"gitId":"-"},"content":" });"},{"lineNumber":278,"author":{"gitId":"-"},"content":" };"},{"lineNumber":279,"author":{"gitId":"-"},"content":""},{"lineNumber":280,"author":{"gitId":"-"},"content":" student.courseJoinLink \u003d this.getUpdatedUrl(student.courseJoinLink, newKey);"},{"lineNumber":281,"author":{"gitId":"-"},"content":" updateSessions(student.awaitingSessions);"},{"lineNumber":282,"author":{"gitId":"-"},"content":" updateSessions(student.openSessions);"},{"lineNumber":283,"author":{"gitId":"-"},"content":" updateSessions(student.notOpenSessions);"},{"lineNumber":284,"author":{"gitId":"-"},"content":" updateSessions(student.publishedSessions);"},{"lineNumber":285,"author":{"gitId":"-"},"content":" }"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":288,"author":{"gitId":"-"},"content":" * Updates the instructor\u0027s displayed course join and feedback session links with the value of the newKey."},{"lineNumber":289,"author":{"gitId":"-"},"content":" */"},{"lineNumber":290,"author":{"gitId":"-"},"content":" private updateDisplayedInstructorCourseLinks(instructor: InstructorAccountSearchResult, newKey: string): void {"},{"lineNumber":291,"author":{"gitId":"-"},"content":" const updateSessions \u003d (sessions: FeedbackSessionsGroup): void \u003d\u003e {"},{"lineNumber":292,"author":{"gitId":"-"},"content":" Object.keys(sessions).forEach((key: string): void \u003d\u003e {"},{"lineNumber":293,"author":{"gitId":"-"},"content":" sessions[key].feedbackSessionUrl \u003d this.getUpdatedUrl(sessions[key].feedbackSessionUrl, newKey);"},{"lineNumber":294,"author":{"gitId":"-"},"content":" });"},{"lineNumber":295,"author":{"gitId":"-"},"content":" };"},{"lineNumber":296,"author":{"gitId":"-"},"content":""},{"lineNumber":297,"author":{"gitId":"-"},"content":" instructor.courseJoinLink \u003d this.getUpdatedUrl(instructor.courseJoinLink, newKey);"},{"lineNumber":298,"author":{"gitId":"-"},"content":" updateSessions(instructor.awaitingSessions);"},{"lineNumber":299,"author":{"gitId":"-"},"content":" updateSessions(instructor.openSessions);"},{"lineNumber":300,"author":{"gitId":"-"},"content":" updateSessions(instructor.notOpenSessions);"},{"lineNumber":301,"author":{"gitId":"-"},"content":" updateSessions(instructor.publishedSessions);"},{"lineNumber":302,"author":{"gitId":"-"},"content":" }"},{"lineNumber":303,"author":{"gitId":"-"},"content":""},{"lineNumber":304,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":305,"author":{"gitId":"-"},"content":" * Returns the URL after replacing the value of the `key` parameter with that of the new key."},{"lineNumber":306,"author":{"gitId":"-"},"content":" */"},{"lineNumber":307,"author":{"gitId":"-"},"content":" private getUpdatedUrl(link: string, newVal: string): string {"},{"lineNumber":308,"author":{"gitId":"-"},"content":" const param: string \u003d \u0027key\u0027;"},{"lineNumber":309,"author":{"gitId":"-"},"content":" const regex: RegExp \u003d new RegExp(`(${param}\u003d)[^\u0026]+`);"},{"lineNumber":310,"author":{"gitId":"-"},"content":""},{"lineNumber":311,"author":{"gitId":"-"},"content":" return link.replace(regex, `$1${newVal}`);"},{"lineNumber":312,"author":{"gitId":"-"},"content":" }"},{"lineNumber":313,"author":{"gitId":"-"},"content":""},{"lineNumber":314,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":315,"author":{"gitId":"-"},"content":" * Open up an email populated with content for course join invitation."},{"lineNumber":316,"author":{"gitId":"-"},"content":" */"},{"lineNumber":317,"author":{"gitId":"-"},"content":" openCourseJoinEmail(courseId: string, studentemail: string): void {"},{"lineNumber":318,"author":{"gitId":"-"},"content":" this.emailGenerationService.getCourseJoinEmail(courseId, studentemail)"},{"lineNumber":319,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":320,"author":{"gitId":"-"},"content":" next: (email: Email) \u003d\u003e {"},{"lineNumber":321,"author":{"gitId":"-"},"content":" window.location.href \u003d `mailto:${email.recipient}`"},{"lineNumber":322,"author":{"gitId":"-"},"content":" + `?Subject\u003d${email.subject}`"},{"lineNumber":323,"author":{"gitId":"-"},"content":" + `\u0026body\u003d${email.content}`;"},{"lineNumber":324,"author":{"gitId":"-"},"content":" },"},{"lineNumber":325,"author":{"gitId":"-"},"content":" error: (err: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":326,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(err.error.message);"},{"lineNumber":327,"author":{"gitId":"-"},"content":" },"},{"lineNumber":328,"author":{"gitId":"-"},"content":" });"},{"lineNumber":329,"author":{"gitId":"-"},"content":" }"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":332,"author":{"gitId":"-"},"content":" * Open up an email populated with content for feedback session reminder."},{"lineNumber":333,"author":{"gitId":"-"},"content":" */"},{"lineNumber":334,"author":{"gitId":"-"},"content":" openFeedbackSessionReminderEmail(courseId: string, studentemail: string, fsname: string): void {"},{"lineNumber":335,"author":{"gitId":"-"},"content":" this.emailGenerationService.getFeedbackSessionReminderEmail(courseId, studentemail, fsname)"},{"lineNumber":336,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":337,"author":{"gitId":"-"},"content":" next: (email: Email) \u003d\u003e {"},{"lineNumber":338,"author":{"gitId":"-"},"content":" window.location.href \u003d `mailto:${email.recipient}`"},{"lineNumber":339,"author":{"gitId":"-"},"content":" + `?Subject\u003d${email.subject}`"},{"lineNumber":340,"author":{"gitId":"-"},"content":" + `\u0026body\u003d${email.content}`;"},{"lineNumber":341,"author":{"gitId":"-"},"content":" },"},{"lineNumber":342,"author":{"gitId":"-"},"content":" error: (err: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":343,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(err.error.message);"},{"lineNumber":344,"author":{"gitId":"-"},"content":" },"},{"lineNumber":345,"author":{"gitId":"-"},"content":" });"},{"lineNumber":346,"author":{"gitId":"-"},"content":" }"},{"lineNumber":347,"author":{"gitId":"-"},"content":""},{"lineNumber":348,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":22,"-":326}},{"path":"src/web/app/pages-admin/admin-search-page/admin-search-page.module.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { CommonModule } from \u0027@angular/common\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { NgModule } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { FormsModule } from \u0027@angular/forms\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { RouterModule, Routes } from \u0027@angular/router\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { NgbTooltipModule } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { AdminSearchPageComponent } from \u0027./admin-search-page.component\u0027;"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":"import {"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" AccountRequestTableModule,"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":"} from \u0027../../components/account-requests-table/account-request-table.module\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { Pipes } from \u0027../../pipes/pipes.module\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":"const routes: Routes \u003d ["},{"lineNumber":13,"author":{"gitId":"-"},"content":" {"},{"lineNumber":14,"author":{"gitId":"-"},"content":" path: \u0027\u0027,"},{"lineNumber":15,"author":{"gitId":"-"},"content":" component: AdminSearchPageComponent,"},{"lineNumber":16,"author":{"gitId":"-"},"content":" },"},{"lineNumber":17,"author":{"gitId":"-"},"content":"];"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":20,"author":{"gitId":"-"},"content":" * Module for admin search page."},{"lineNumber":21,"author":{"gitId":"-"},"content":" */"},{"lineNumber":22,"author":{"gitId":"-"},"content":"@NgModule({"},{"lineNumber":23,"author":{"gitId":"-"},"content":" declarations: ["},{"lineNumber":24,"author":{"gitId":"-"},"content":" AdminSearchPageComponent,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":26,"author":{"gitId":"-"},"content":" exports: ["},{"lineNumber":27,"author":{"gitId":"-"},"content":" AdminSearchPageComponent,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":29,"author":{"gitId":"-"},"content":" imports: ["},{"lineNumber":30,"author":{"gitId":"-"},"content":" CommonModule,"},{"lineNumber":31,"author":{"gitId":"-"},"content":" FormsModule,"},{"lineNumber":32,"author":{"gitId":"-"},"content":" NgbTooltipModule,"},{"lineNumber":33,"author":{"gitId":"domoberzin"},"content":" AccountRequestTableModule,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" RouterModule.forChild(routes),"},{"lineNumber":35,"author":{"gitId":"-"},"content":" Pipes,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":37,"author":{"gitId":"-"},"content":"})"},{"lineNumber":38,"author":{"gitId":"-"},"content":"export class AdminSearchPageModule { }"}],"authorContributionMap":{"domoberzin":4,"-":34}},{"path":"src/web/app/pages-instructor/instructor-courses-page/instructor-courses-page.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003cdiv\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-add-course\" class\u003d\"btn btn-success\" (click)\u003d\"isAddNewCourseFormExpanded \u003d true\""},{"lineNumber":3,"author":{"gitId":"-"},"content":" [disabled]\u003d\"isAddNewCourseFormExpanded || isLoadingActiveCourses\"\u003e\u003ci class\u003d\"fas fa-plus\"\u003e\u003c/i\u003e Add New Course"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":""},{"lineNumber":7,"author":{"gitId":"-"},"content":"\u003cdiv id\u003d\"add-course-section\" class\u003d\"course-section\" *ngIf\u003d\"isAddNewCourseFormExpanded \u0026\u0026 !isLoadingActiveCourses\" @collapseAnim\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003ctm-course-edit-form [formMode]\u003d\"CourseEditFormMode.ADD\" [(formModel)]\u003d\"courseFormModel\""},{"lineNumber":9,"author":{"gitId":"-"},"content":" [resetFormEvent]\u003d\"resetCourseForm\" (closeFormEvent)\u003d\"isAddNewCourseFormExpanded \u003d false\""},{"lineNumber":10,"author":{"gitId":"-"},"content":" (createNewCourseEvent)\u003d\"createNewCourse()\" (copyCourseEvent)\u003d\"createCopiedCourse($event)\"\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003c/tm-course-edit-form\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":"\u003cdiv *ngIf\u003d\"isCopyingCourse\" class\u003d\"margin-top-30px\"\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":" \u003cp\u003eCopy Progress\u003c/p\u003e"},{"lineNumber":16,"author":{"gitId":"-"},"content":" \u003ctm-progress-bar\u003e\u003c/tm-progress-bar\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":18,"author":{"gitId":"-"},"content":""},{"lineNumber":19,"author":{"gitId":"-"},"content":"\u003ctm-loading-retry [shouldShowRetry]\u003d\"hasLoadingFailed\" [message]\u003d\"\u0027Failed to load courses\u0027\""},{"lineNumber":20,"author":{"gitId":"-"},"content":" (retryEvent)\u003d\"loadInstructorCourses()\"\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"course-section\"\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u003ch2 class\u003d\"h3\"\u003eActive courses\u003c/h2\u003e"},{"lineNumber":23,"author":{"gitId":"-"},"content":" \u003cdiv *tmIsLoading\u003d\"isLoadingActiveCourses\"\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":" \u003cng-template #addCourseAlert\u003e"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"alert alert-warning margin-top-30px\" role\u003d\"alert\"\u003e"},{"lineNumber":26,"author":{"gitId":"-"},"content":" You do not seem to have any active courses. Use the button above to create a new course."},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":28,"author":{"gitId":"-"},"content":" \u003c/ng-template\u003e"},{"lineNumber":29,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"activeCourses.length; else addCourseAlert;\"\u003e"},{"lineNumber":30,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"table table-responsive\"\u003e"},{"lineNumber":31,"author":{"gitId":"-"},"content":" \u003ctable id\u003d\"active-courses-table\" class\u003d\"table table-striped table-bordered margin-0\"\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003cthead\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003ctr class\u003d\"bg-primary text-white\"\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003cth id\u003d\"sort-course-id\" class\u003d\"sortable-header\" (click)\u003d\"sortCoursesEvent(SortBy.COURSE_ID)\""},{"lineNumber":35,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortActive(SortBy.COURSE_ID)\"\u003e"},{"lineNumber":36,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":37,"author":{"gitId":"-"},"content":" Course ID"},{"lineNumber":38,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":41,"author":{"gitId":"-"},"content":" *ngIf\u003d\"activeTableSortBy \u003d\u003d\u003d SortBy.COURSE_ID \u0026\u0026 activeTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":43,"author":{"gitId":"-"},"content":" *ngIf\u003d\"activeTableSortBy \u003d\u003d\u003d SortBy.COURSE_ID \u0026\u0026 activeTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":45,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":46,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":47,"author":{"gitId":"-"},"content":" \u003cth id\u003d\"sort-course-name\" class\u003d\"sortable-header\" (click)\u003d\"sortCoursesEvent(SortBy.COURSE_NAME)\""},{"lineNumber":48,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortActive(SortBy.COURSE_NAME)\"\u003e"},{"lineNumber":49,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":50,"author":{"gitId":"-"},"content":" Course Name"},{"lineNumber":51,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":52,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":53,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":54,"author":{"gitId":"-"},"content":" *ngIf\u003d\"activeTableSortBy \u003d\u003d\u003d SortBy.COURSE_NAME \u0026\u0026 activeTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":56,"author":{"gitId":"-"},"content":" *ngIf\u003d\"activeTableSortBy \u003d\u003d\u003d SortBy.COURSE_NAME \u0026\u0026 activeTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":57,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":58,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":59,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":60,"author":{"gitId":"-"},"content":" \u003cth id\u003d\"sort-creation-date\" class\u003d\"sortable-header\""},{"lineNumber":61,"author":{"gitId":"-"},"content":" (click)\u003d\"sortCoursesEvent(SortBy.COURSE_CREATION_DATE)\""},{"lineNumber":62,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortActive(SortBy.COURSE_CREATION_DATE)\"\u003e"},{"lineNumber":63,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":64,"author":{"gitId":"-"},"content":" Creation Date"},{"lineNumber":65,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":66,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":67,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":68,"author":{"gitId":"-"},"content":" *ngIf\u003d\"activeTableSortBy \u003d\u003d\u003d SortBy.COURSE_CREATION_DATE \u0026\u0026 activeTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":69,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":70,"author":{"gitId":"-"},"content":" *ngIf\u003d\"activeTableSortBy \u003d\u003d\u003d SortBy.COURSE_CREATION_DATE \u0026\u0026 activeTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":71,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":72,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":73,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":74,"author":{"gitId":"-"},"content":" \u003cth\u003eSections\u003c/th\u003e"},{"lineNumber":75,"author":{"gitId":"-"},"content":" \u003cth\u003eTeams\u003c/th\u003e"},{"lineNumber":76,"author":{"gitId":"-"},"content":" \u003cth\u003eTotal Students\u003c/th\u003e"},{"lineNumber":77,"author":{"gitId":"-"},"content":" \u003cth\u003eTotal Unregistered\u003c/th\u003e"},{"lineNumber":78,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"text-center\"\u003eAction(s)\u003c/th\u003e"},{"lineNumber":79,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":80,"author":{"gitId":"-"},"content":" \u003c/thead\u003e"},{"lineNumber":81,"author":{"gitId":"-"},"content":" \u003ctbody\u003e"},{"lineNumber":82,"author":{"gitId":"-"},"content":" \u003cng-template #loadingSpinner\u003e"},{"lineNumber":83,"author":{"gitId":"-"},"content":" \u003ctm-ajax-loading [useBlueSpinner]\u003d\"true\"\u003e\u003c/tm-ajax-loading\u003e"},{"lineNumber":84,"author":{"gitId":"-"},"content":" \u003c/ng-template\u003e"},{"lineNumber":85,"author":{"gitId":"-"},"content":" \u003ctr *ngFor\u003d\"let course of activeCourses; let i \u003d index\"\u003e"},{"lineNumber":86,"author":{"gitId":"-"},"content":" \u003ctd id\u003d\"course-id-{{ i }}\" class\u003d\"text-break\"\u003e{{course.course.courseId}}\u003c/td\u003e"},{"lineNumber":87,"author":{"gitId":"-"},"content":" \u003ctd class\u003d\"text-break\"\u003e{{course.course.courseName}}\u003c/td\u003e"},{"lineNumber":88,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":89,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"ngb-tooltip-class\" container\u003d\"body\""},{"lineNumber":90,"author":{"gitId":"-"},"content":" [ngbTooltip]\u003d\"course.course.creationTimestamp | date:\u0027EEE, dd MMM yyyy, h:mma\u0027\"\u003e"},{"lineNumber":91,"author":{"gitId":"-"},"content":" {{course.course.creationTimestamp | date:\u0027d MMM yyyy\u0027}}"},{"lineNumber":92,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":93,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":94,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":95,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"!courseStats[course.course.courseId]\"\u003e"},{"lineNumber":96,"author":{"gitId":"-"},"content":" \u003cbutton *ngIf\u003d\"!course.isLoadingCourseStats; else loadingSpinner\""},{"lineNumber":97,"author":{"gitId":"-"},"content":" (click)\u003d\"getCourseStats(i)\" class\u003d\"link-button\" \u003e Show"},{"lineNumber":98,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":99,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":100,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"courseStats[course.course.courseId]\"\u003e"},{"lineNumber":101,"author":{"gitId":"-"},"content":" {{ courseStats[course.course.courseId][\u0027sections\u0027] }}"},{"lineNumber":102,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":103,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":104,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":105,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"!courseStats[course.course.courseId]\"\u003e"},{"lineNumber":106,"author":{"gitId":"-"},"content":" \u003cbutton *ngIf\u003d\"!course.isLoadingCourseStats; else loadingSpinner\" id\u003d\"show-statistics-{{ i }}\""},{"lineNumber":107,"author":{"gitId":"-"},"content":" (click)\u003d\"getCourseStats(i)\" class\u003d\"link-button\" \u003e Show"},{"lineNumber":108,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":109,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":110,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"courseStats[course.course.courseId]\"\u003e"},{"lineNumber":111,"author":{"gitId":"-"},"content":" {{ courseStats[course.course.courseId][\u0027teams\u0027] }}"},{"lineNumber":112,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":113,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":114,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":115,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"!courseStats[course.course.courseId]\"\u003e"},{"lineNumber":116,"author":{"gitId":"-"},"content":" \u003cbutton *ngIf\u003d\"!course.isLoadingCourseStats; else loadingSpinner\""},{"lineNumber":117,"author":{"gitId":"-"},"content":" (click)\u003d\"getCourseStats(i)\" class\u003d\"link-button\" \u003e Show"},{"lineNumber":118,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":119,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":120,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"courseStats[course.course.courseId]\"\u003e"},{"lineNumber":121,"author":{"gitId":"-"},"content":" {{ courseStats[course.course.courseId][\u0027students\u0027] }}"},{"lineNumber":122,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":123,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":124,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":125,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"!courseStats[course.course.courseId]\"\u003e"},{"lineNumber":126,"author":{"gitId":"-"},"content":" \u003cbutton *ngIf\u003d\"!course.isLoadingCourseStats; else loadingSpinner\""},{"lineNumber":127,"author":{"gitId":"-"},"content":" (click)\u003d\"getCourseStats(i)\" class\u003d\"link-button\" \u003e Show"},{"lineNumber":128,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":129,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":130,"author":{"gitId":"-"},"content":" \u003cspan *ngIf\u003d\"courseStats[course.course.courseId]\"\u003e"},{"lineNumber":131,"author":{"gitId":"-"},"content":" {{ courseStats[course.course.courseId][\u0027unregistered\u0027] }}"},{"lineNumber":132,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":133,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":134,"author":{"gitId":"-"},"content":" \u003ctd class\u003d\"text-center actions-cell\"\u003e"},{"lineNumber":135,"author":{"gitId":"-"},"content":" \u003ca id\u003d\"btn-enroll-{{ i }}\" class\u003d\"btn btn-light btn-sm custom-button-active\" *ngIf\u003d\"course.canModifyStudent\""},{"lineNumber":136,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Enroll student into the course\" tmRouterLink\u003d\"/web/instructor/courses/enroll\""},{"lineNumber":137,"author":{"gitId":"-"},"content":" [queryParams]\u003d\"{courseid: course.course.courseId}\"\u003e"},{"lineNumber":138,"author":{"gitId":"-"},"content":" Enroll"},{"lineNumber":139,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":140,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-enroll-disabled-{{ i }}\" class\u003d\"btn btn-light btn-sm disabled\""},{"lineNumber":141,"author":{"gitId":"-"},"content":" *ngIf\u003d\"!course.canModifyStudent\"\u003e"},{"lineNumber":142,"author":{"gitId":"-"},"content":" Enroll"},{"lineNumber":143,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":144,"author":{"gitId":"-"},"content":" \u003cdiv ngbDropdown class\u003d\"d-inline-block\"\u003e"},{"lineNumber":145,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-other-actions-{{ i }}\" class\u003d\"btn btn-light btn-sm custom-button-active\" ngbDropdownToggle\u003eOther"},{"lineNumber":146,"author":{"gitId":"-"},"content":" Actions\u003c/button\u003e"},{"lineNumber":147,"author":{"gitId":"-"},"content":" \u003cdiv ngbDropdownMenu\u003e"},{"lineNumber":148,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn btn-primary btn-sm dropdown-item clickable\""},{"lineNumber":149,"author":{"gitId":"-"},"content":" tmRouterLink\u003d\"/web/instructor/courses/details\" [queryParams]\u003d\"{courseid: course.course.courseId}\"\u003e"},{"lineNumber":150,"author":{"gitId":"-"},"content":" View"},{"lineNumber":151,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":152,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn btn-primary btn-sm dropdown-item clickable\""},{"lineNumber":153,"author":{"gitId":"-"},"content":" tmRouterLink\u003d\"/web/instructor/courses/edit\" [queryParams]\u003d\"{courseid: course.course.courseId}\"\u003e"},{"lineNumber":154,"author":{"gitId":"-"},"content":" Edit"},{"lineNumber":155,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":156,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-copy-{{ i }}\" class\u003d\"btn btn-primary btn-sm dropdown-item clickable\""},{"lineNumber":157,"author":{"gitId":"-"},"content":" *ngIf\u003d\"course.canModifyCourse\""},{"lineNumber":158,"author":{"gitId":"-"},"content":" (click)\u003d\"onCopy(course.course.courseId, course.course.courseName, course.course.timeZone)\""},{"lineNumber":159,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Copy the course and its corresponding sessions\" placement\u003d\"left\" container\u003d\"body\""},{"lineNumber":160,"author":{"gitId":"-"},"content":" [disabled]\u003d\"isCopyingCourse\"\u003e"},{"lineNumber":161,"author":{"gitId":"-"},"content":" Copy"},{"lineNumber":162,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":163,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-archive-{{ i }}\" class\u003d\"btn btn-primary btn-sm dropdown-item clickable\""},{"lineNumber":164,"author":{"gitId":"-"},"content":" (click)\u003d\"changeArchiveStatus(course.course.courseId, true)\""},{"lineNumber":165,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Archive the course so that it will not be shown in the home page any more (you can still access it from the \u0027Courses\u0027 tab)\""},{"lineNumber":166,"author":{"gitId":"-"},"content":" placement\u003d\"left\" container\u003d\"body\"\u003e"},{"lineNumber":167,"author":{"gitId":"-"},"content":" Archive"},{"lineNumber":168,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":169,"author":{"gitId":"dishenggg"},"content":" \u003ca class\u003d\"btn btn-primary btn-sm dropdown-item clickable\" *ngIf\u003d\"course.course.privileges?.canModifyInstructor \u0026\u0026 course.course.isMigrated\""},{"lineNumber":170,"author":{"gitId":"dishenggg"},"content":" tmRouterLink\u003d\u0027/web/instructor/courses/student-activity-logs\u0027 [queryParams]\u003d\"{courseid: course.course.courseId}\"\u003e"},{"lineNumber":171,"author":{"gitId":"dishenggg"},"content":" View Logs"},{"lineNumber":172,"author":{"gitId":"dishenggg"},"content":" \u003c/a\u003e"},{"lineNumber":173,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-soft-delete-{{ i }}\" class\u003d\"btn btn-primary btn-sm dropdown-item clickable\""},{"lineNumber":174,"author":{"gitId":"-"},"content":" *ngIf\u003d\"course.canModifyCourse\" (click)\u003d\"onDelete(course.course.courseId)\""},{"lineNumber":175,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Delete the course and its corresponding students and sessions\" placement\u003d\"left\""},{"lineNumber":176,"author":{"gitId":"-"},"content":" container\u003d\"body\"\u003e"},{"lineNumber":177,"author":{"gitId":"-"},"content":" Delete"},{"lineNumber":178,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":179,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-soft-delete-disabled-{{ i }}\" class\u003d\"btn btn-primary btn-sm dropdown-item disabled\""},{"lineNumber":180,"author":{"gitId":"-"},"content":" *ngIf\u003d\"!course.canModifyCourse\"\u003e"},{"lineNumber":181,"author":{"gitId":"-"},"content":" Delete"},{"lineNumber":182,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":183,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":184,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":185,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":186,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":187,"author":{"gitId":"-"},"content":" \u003c/tbody\u003e"},{"lineNumber":188,"author":{"gitId":"-"},"content":" \u003ctr *ngIf\u003d\"!activeCourses.length\"\u003e"},{"lineNumber":189,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003c/td\u003e"},{"lineNumber":190,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003c/td\u003e"},{"lineNumber":191,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003c/td\u003e"},{"lineNumber":192,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003c/td\u003e"},{"lineNumber":193,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003c/td\u003e"},{"lineNumber":194,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003c/td\u003e"},{"lineNumber":195,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003c/td\u003e"},{"lineNumber":196,"author":{"gitId":"-"},"content":" \u003ctd\u003e\u003c/td\u003e"},{"lineNumber":197,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":198,"author":{"gitId":"-"},"content":" \u003c/table\u003e"},{"lineNumber":199,"author":{"gitId":"-"},"content":" \u003cp *ngIf\u003d\"!activeCourses.length\"\u003eNo records found.\u003c/p\u003e"},{"lineNumber":200,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":201,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":202,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":203,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":204,"author":{"gitId":"-"},"content":"\u003c/tm-loading-retry\u003e"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"course-section\"\u003e"},{"lineNumber":207,"author":{"gitId":"-"},"content":" \u003ch2 class\u003d\"h3 text-muted\"\u003e"},{"lineNumber":208,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa fa-file-archive\" aria-hidden\u003d\"true\"\u003e\u003c/span\u003e Archived courses"},{"lineNumber":209,"author":{"gitId":"-"},"content":" \u003c/h2\u003e"},{"lineNumber":210,"author":{"gitId":"-"},"content":" \u003cdiv *tmIsLoading\u003d\"isLoadingArchivedCourses\"\u003e"},{"lineNumber":211,"author":{"gitId":"-"},"content":" \u003cng-template #noArchiveAlert\u003e"},{"lineNumber":212,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"alert alert-warning margin-top-30px\" role\u003d\"alert\"\u003e"},{"lineNumber":213,"author":{"gitId":"-"},"content":" There are no courses archived currently."},{"lineNumber":214,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":215,"author":{"gitId":"-"},"content":" \u003c/ng-template\u003e"},{"lineNumber":216,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card top-padded\" *ngIf\u003d\"archivedCourses.length else noArchiveAlert\"\u003e"},{"lineNumber":217,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"archived-table-heading\" class\u003d\"card-header bg-info cursor-pointer\""},{"lineNumber":218,"author":{"gitId":"-"},"content":" (click)\u003d\"isArchivedCourseExpanded \u003d !isArchivedCourseExpanded\"\u003e"},{"lineNumber":219,"author":{"gitId":"-"},"content":" \u003cb\u003eArchive\u003c/b\u003e"},{"lineNumber":220,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header-btn-toolbar\"\u003e"},{"lineNumber":221,"author":{"gitId":"-"},"content":" \u003ctm-panel-chevron [isExpanded]\u003d\"isArchivedCourseExpanded\"\u003e\u003c/tm-panel-chevron\u003e"},{"lineNumber":222,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":223,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":224,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body archive-body table-responsive\" *ngIf\u003d\"isArchivedCourseExpanded\" @collapseAnim\u003e"},{"lineNumber":225,"author":{"gitId":"-"},"content":" \u003ctable id\u003d\"archived-courses-table\" class\u003d\"table table-striped table-bordered archive-table\"\u003e"},{"lineNumber":226,"author":{"gitId":"-"},"content":" \u003cthead\u003e"},{"lineNumber":227,"author":{"gitId":"-"},"content":" \u003ctr class\u003d\"background-color-medium-gray text-color-gray\"\u003e"},{"lineNumber":228,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"sortable-header\" (click)\u003d\"sortArchivedCoursesEvent(SortBy.COURSE_ID)\""},{"lineNumber":229,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortArchived(SortBy.COURSE_ID)\"\u003e"},{"lineNumber":230,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":231,"author":{"gitId":"-"},"content":" Course ID"},{"lineNumber":232,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":233,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":234,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":235,"author":{"gitId":"-"},"content":" *ngIf\u003d\"archivedTableSortBy \u003d\u003d\u003d SortBy.COURSE_ID \u0026\u0026 archivedTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":236,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":237,"author":{"gitId":"-"},"content":" *ngIf\u003d\"archivedTableSortBy \u003d\u003d\u003d SortBy.COURSE_ID \u0026\u0026 archivedTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":238,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":239,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":240,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":241,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"sortable-header\" (click)\u003d\"sortArchivedCoursesEvent(SortBy.COURSE_NAME)\""},{"lineNumber":242,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortArchived(SortBy.COURSE_NAME)\"\u003e"},{"lineNumber":243,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":244,"author":{"gitId":"-"},"content":" Course Name"},{"lineNumber":245,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":246,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":247,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":248,"author":{"gitId":"-"},"content":" *ngIf\u003d\"archivedTableSortBy \u003d\u003d\u003d SortBy.COURSE_NAME \u0026\u0026 archivedTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":249,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":250,"author":{"gitId":"-"},"content":" *ngIf\u003d\"archivedTableSortBy \u003d\u003d\u003d SortBy.COURSE_NAME \u0026\u0026 archivedTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":251,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":252,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":253,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":254,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"sortable-header\" (click)\u003d\"sortArchivedCoursesEvent(SortBy.COURSE_CREATION_DATE)\""},{"lineNumber":255,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortArchived(SortBy.COURSE_CREATION_DATE)\"\u003e"},{"lineNumber":256,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":257,"author":{"gitId":"-"},"content":" Creation Date"},{"lineNumber":258,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":259,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":260,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":261,"author":{"gitId":"-"},"content":" *ngIf\u003d\"archivedTableSortBy \u003d\u003d\u003d SortBy.COURSE_CREATION_DATE \u0026\u0026 archivedTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":262,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":263,"author":{"gitId":"-"},"content":" *ngIf\u003d\"archivedTableSortBy \u003d\u003d\u003d SortBy.COURSE_CREATION_DATE \u0026\u0026 archivedTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":264,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":265,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":266,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":267,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"text-center\"\u003eAction(s)\u003c/th\u003e"},{"lineNumber":268,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":269,"author":{"gitId":"-"},"content":" \u003c/thead\u003e"},{"lineNumber":270,"author":{"gitId":"-"},"content":" \u003ctbody\u003e"},{"lineNumber":271,"author":{"gitId":"-"},"content":" \u003ctr *ngFor\u003d\"let course of archivedCourses; let i \u003d index\"\u003e"},{"lineNumber":272,"author":{"gitId":"-"},"content":" \u003ctd id\u003d\"archived-course-id-{{ i }}\" class\u003d\"text-break\"\u003e{{course.course.courseId}}\u003c/td\u003e"},{"lineNumber":273,"author":{"gitId":"-"},"content":" \u003ctd class\u003d\"text-break\"\u003e{{course.course.courseName}}\u003c/td\u003e"},{"lineNumber":274,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":275,"author":{"gitId":"-"},"content":" \u003cspan container\u003d\"body\" class\u003d\"ngb-tooltip-class\""},{"lineNumber":276,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"{{course.course.creationTimestamp | date:\u0027EEE, dd MMM yyyy, h:mma\u0027}}\"\u003e{{course.course.creationTimestamp"},{"lineNumber":277,"author":{"gitId":"-"},"content":" | date:\u0027d MMM yyyy\u0027}}\u003c/span\u003e"},{"lineNumber":278,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":279,"author":{"gitId":"-"},"content":" \u003ctd class\u003d\"text-center actions-cell\"\u003e"},{"lineNumber":280,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-unarchive-{{ i }}\" class\u003d\"btn btn-light btn-sm custom-button-archived\""},{"lineNumber":281,"author":{"gitId":"-"},"content":" (click)\u003d\"changeArchiveStatus(course.course.courseId, false)\"\u003e"},{"lineNumber":282,"author":{"gitId":"-"},"content":" Unarchive"},{"lineNumber":283,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":284,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-soft-delete-archived-{{ i }}\" class\u003d\"btn btn-light btn-sm custom-button-archived\" *ngIf\u003d\"course.canModifyCourse\""},{"lineNumber":285,"author":{"gitId":"-"},"content":" (click)\u003d\"onDelete(course.course.courseId)\""},{"lineNumber":286,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Delete the course and its corresponding students and sessions\"\u003e"},{"lineNumber":287,"author":{"gitId":"-"},"content":" Delete"},{"lineNumber":288,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":289,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-soft-delete-archived-disabled-{{ i }}\" class\u003d\"btn btn-light btn-sm disabled\""},{"lineNumber":290,"author":{"gitId":"-"},"content":" *ngIf\u003d\"!course.canModifyCourse\"\u003e"},{"lineNumber":291,"author":{"gitId":"-"},"content":" Delete"},{"lineNumber":292,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":293,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":294,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":295,"author":{"gitId":"-"},"content":" \u003c/tbody\u003e"},{"lineNumber":296,"author":{"gitId":"-"},"content":" \u003c/table\u003e"},{"lineNumber":297,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":298,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":299,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":300,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":301,"author":{"gitId":"-"},"content":""},{"lineNumber":302,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"row course-section margin-top-30px\"\u003e"},{"lineNumber":303,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":304,"author":{"gitId":"-"},"content":" \u003ch2 class\u003d\"h3 text-muted\"\u003e"},{"lineNumber":305,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa fa-trash-alt\" aria-hidden\u003d\"true\"\u003e\u003c/span\u003e Deleted courses"},{"lineNumber":306,"author":{"gitId":"-"},"content":" \u003c/h2\u003e"},{"lineNumber":307,"author":{"gitId":"-"},"content":" \u003cdiv *tmIsLoading\u003d\"isLoadingSoftDeletedCourses\"\u003e"},{"lineNumber":308,"author":{"gitId":"-"},"content":" \u003cng-template #emptyBinAlert\u003e"},{"lineNumber":309,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"alert alert-warning margin-top-30px\" role\u003d\"alert\"\u003e"},{"lineNumber":310,"author":{"gitId":"-"},"content":" There are no courses in the bin."},{"lineNumber":311,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":312,"author":{"gitId":"-"},"content":" \u003c/ng-template\u003e"},{"lineNumber":313,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card bg-light top-padded\" *ngIf\u003d\"softDeletedCourses.length else emptyBinAlert\"\u003e"},{"lineNumber":314,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"deleted-table-heading\" class\u003d\"card-header bg-secondary text-white cursor-pointer\""},{"lineNumber":315,"author":{"gitId":"-"},"content":" (click)\u003d\"isRecycleBinExpanded \u003d !isRecycleBinExpanded\"\u003e"},{"lineNumber":316,"author":{"gitId":"-"},"content":" \u003cb\u003eRecycle Bin\u003c/b\u003e"},{"lineNumber":317,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header-btn-toolbar\"\u003e"},{"lineNumber":318,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-restore-all\" class\u003d\"btn btn-secondary btn-sm\" *ngIf\u003d\"canRestoreAll\""},{"lineNumber":319,"author":{"gitId":"-"},"content":" (click)\u003d\"$event.stopPropagation(); onRestoreAll()\""},{"lineNumber":320,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Restore all deleted courses and their corresponding students and sessions\"\u003e"},{"lineNumber":321,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-check\" aria-hidden\u003d\"true\"\u003e\u003c/i\u003e Restore All"},{"lineNumber":322,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":323,"author":{"gitId":"-"},"content":" \u003cbutton class\u003d\"btn btn-secondary btn-sm disabled\" *ngIf\u003d\"!canRestoreAll\"\u003e"},{"lineNumber":324,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-check\" aria-hidden\u003d\"true\"\u003e\u003c/i\u003e Restore All"},{"lineNumber":325,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":326,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-delete-all\" class\u003d\"btn btn-secondary btn-sm\" *ngIf\u003d\"canDeleteAll\""},{"lineNumber":327,"author":{"gitId":"-"},"content":" (click)\u003d\"$event.stopPropagation(); onDeleteAll()\""},{"lineNumber":328,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Permanently delete all courses and their corresponding students and sessions\"\u003e"},{"lineNumber":329,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-times\" aria-hidden\u003d\"true\"\u003e\u003c/i\u003e Delete All"},{"lineNumber":330,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":331,"author":{"gitId":"-"},"content":" \u003cbutton class\u003d\"btn btn-secondary btn-sm disabled\" *ngIf\u003d\"!canDeleteAll\"\u003e"},{"lineNumber":332,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-times\" aria-hidden\u003d\"true\"\u003e\u003c/i\u003e Delete All"},{"lineNumber":333,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":334,"author":{"gitId":"-"},"content":" \u003ctm-panel-chevron [isExpanded]\u003d\"isRecycleBinExpanded\"\u003e\u003c/tm-panel-chevron\u003e"},{"lineNumber":335,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":336,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":337,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body recycle-bin-body table-responsive\" *ngIf\u003d\"isRecycleBinExpanded\" @collapseAnim\u003e"},{"lineNumber":338,"author":{"gitId":"-"},"content":" \u003ctable id\u003d\"deleted-courses-table\""},{"lineNumber":339,"author":{"gitId":"-"},"content":" class\u003d\"table table-responsive-lg table-striped table-bordered recycle-bin-table\"\u003e"},{"lineNumber":340,"author":{"gitId":"-"},"content":" \u003cthead\u003e"},{"lineNumber":341,"author":{"gitId":"-"},"content":" \u003ctr class\u003d\"background-color-medium-gray text-color-gray\"\u003e"},{"lineNumber":342,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"sortable-header\" (click)\u003d\"sortDeletedCoursesEvent(SortBy.COURSE_ID)\""},{"lineNumber":343,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortDeleted(SortBy.COURSE_ID)\"\u003e"},{"lineNumber":344,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":345,"author":{"gitId":"-"},"content":" Course ID"},{"lineNumber":346,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":347,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":348,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":349,"author":{"gitId":"-"},"content":" *ngIf\u003d\"deletedTableSortBy \u003d\u003d\u003d SortBy.COURSE_ID \u0026\u0026 deletedTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":350,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":351,"author":{"gitId":"-"},"content":" *ngIf\u003d\"deletedTableSortBy \u003d\u003d\u003d SortBy.COURSE_ID \u0026\u0026 deletedTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":352,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":353,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":354,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":355,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"sortable-header\" (click)\u003d\"sortDeletedCoursesEvent(SortBy.COURSE_NAME)\""},{"lineNumber":356,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortDeleted(SortBy.COURSE_NAME)\"\u003e"},{"lineNumber":357,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":358,"author":{"gitId":"-"},"content":" Course Name"},{"lineNumber":359,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":360,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":361,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":362,"author":{"gitId":"-"},"content":" *ngIf\u003d\"deletedTableSortBy \u003d\u003d\u003d SortBy.COURSE_NAME \u0026\u0026 deletedTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":363,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":364,"author":{"gitId":"-"},"content":" *ngIf\u003d\"deletedTableSortBy \u003d\u003d\u003d SortBy.COURSE_NAME \u0026\u0026 deletedTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":365,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":366,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":367,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":368,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"sortable-header\" (click)\u003d\"sortDeletedCoursesEvent(SortBy.COURSE_CREATION_DATE)\""},{"lineNumber":369,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortDeleted(SortBy.COURSE_CREATION_DATE)\"\u003e"},{"lineNumber":370,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":371,"author":{"gitId":"-"},"content":" Creation Date"},{"lineNumber":372,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":373,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":374,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":375,"author":{"gitId":"-"},"content":" *ngIf\u003d\"deletedTableSortBy \u003d\u003d\u003d SortBy.COURSE_CREATION_DATE \u0026\u0026 deletedTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":376,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":377,"author":{"gitId":"-"},"content":" *ngIf\u003d\"deletedTableSortBy \u003d\u003d\u003d SortBy.COURSE_CREATION_DATE \u0026\u0026 deletedTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":378,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":379,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":380,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":381,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"sortable-header\" (click)\u003d\"sortDeletedCoursesEvent(SortBy.COURSE_DELETION_DATE)\""},{"lineNumber":382,"author":{"gitId":"-"},"content":" [attr.aria-sort]\u003d\"getAriaSortDeleted(SortBy.COURSE_DELETION_DATE)\"\u003e"},{"lineNumber":383,"author":{"gitId":"-"},"content":" \u003cbutton\u003e"},{"lineNumber":384,"author":{"gitId":"-"},"content":" Deletion Date"},{"lineNumber":385,"author":{"gitId":"-"},"content":" \u003cspan class\u003d\"fa-stack\" aria-hidden\u003d\"true\"\u003e"},{"lineNumber":386,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort\"\u003e\u003c/i\u003e"},{"lineNumber":387,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-down\""},{"lineNumber":388,"author":{"gitId":"-"},"content":" *ngIf\u003d\"deletedTableSortBy \u003d\u003d\u003d SortBy.COURSE_DELETION_DATE \u0026\u0026 deletedTableSortOrder \u003d\u003d\u003d SortOrder.DESC\"\u003e\u003c/i\u003e"},{"lineNumber":389,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-sort-up\""},{"lineNumber":390,"author":{"gitId":"-"},"content":" *ngIf\u003d\"deletedTableSortBy \u003d\u003d\u003d SortBy.COURSE_DELETION_DATE \u0026\u0026 deletedTableSortOrder \u003d\u003d\u003d SortOrder.ASC\"\u003e\u003c/i\u003e"},{"lineNumber":391,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":392,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":393,"author":{"gitId":"-"},"content":" \u003c/th\u003e"},{"lineNumber":394,"author":{"gitId":"-"},"content":" \u003cth class\u003d\"text-center\"\u003eAction(s)\u003c/th\u003e"},{"lineNumber":395,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":396,"author":{"gitId":"-"},"content":" \u003c/thead\u003e"},{"lineNumber":397,"author":{"gitId":"-"},"content":" \u003ctbody\u003e"},{"lineNumber":398,"author":{"gitId":"-"},"content":" \u003ctr *ngFor\u003d\"let course of softDeletedCourses; let i \u003d index\"\u003e"},{"lineNumber":399,"author":{"gitId":"-"},"content":" \u003ctd id\u003d\"deleted-course-id-{{ i }}\" class\u003d\"text-break\"\u003e{{course.course.courseId}}\u003c/td\u003e"},{"lineNumber":400,"author":{"gitId":"-"},"content":" \u003ctd class\u003d\"text-break\"\u003e{{course.course.courseName}}\u003c/td\u003e"},{"lineNumber":401,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":402,"author":{"gitId":"-"},"content":" \u003cspan container\u003d\"body\" class\u003d\"ngb-tooltip-class\""},{"lineNumber":403,"author":{"gitId":"-"},"content":" [ngbTooltip]\u003d\"course.course.creationTimestamp | date:\u0027EEE, dd MMM yyyy, h:mma\u0027\"\u003e"},{"lineNumber":404,"author":{"gitId":"-"},"content":" {{course.course.creationTimestamp | date:\u0027d MMM yyyy\u0027}}"},{"lineNumber":405,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":406,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":407,"author":{"gitId":"-"},"content":" \u003ctd\u003e"},{"lineNumber":408,"author":{"gitId":"-"},"content":" \u003cspan container\u003d\"body\" class\u003d\"ngb-tooltip-class\""},{"lineNumber":409,"author":{"gitId":"-"},"content":" [ngbTooltip]\u003d\"course.course.deletionTimestamp | date:\u0027EEE, dd MMM yyyy, h:mma\u0027\"\u003e"},{"lineNumber":410,"author":{"gitId":"-"},"content":" {{course.course.deletionTimestamp | date:\u0027d MMM yyyy\u0027}}"},{"lineNumber":411,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":412,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":413,"author":{"gitId":"-"},"content":" \u003ctd class\u003d\"text-center actions-cell\"\u003e"},{"lineNumber":414,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-restore-{{ i }}\" class\u003d\"btn btn-light btn-sm\" *ngIf\u003d\"course.canModifyCourse\""},{"lineNumber":415,"author":{"gitId":"-"},"content":" (click)\u003d\"onRestore(course.course.courseId)\""},{"lineNumber":416,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Restore the deleted course and its corresponding students and sessions\"\u003e"},{"lineNumber":417,"author":{"gitId":"-"},"content":" Restore"},{"lineNumber":418,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":419,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-restore-disabled-{{ i }}\" class\u003d\"btn btn-light btn-sm disabled\""},{"lineNumber":420,"author":{"gitId":"-"},"content":" *ngIf\u003d\"!course.canModifyCourse\"\u003e"},{"lineNumber":421,"author":{"gitId":"-"},"content":" Restore"},{"lineNumber":422,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":423,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-delete-{{ i }}\" class\u003d\"btn btn-light btn-sm text-danger\" *ngIf\u003d\"course.canModifyCourse\""},{"lineNumber":424,"author":{"gitId":"-"},"content":" (click)\u003d\"onDeletePermanently(course.course.courseId)\""},{"lineNumber":425,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Permanently delete the course and its corresponding students and sessions\"\u003e"},{"lineNumber":426,"author":{"gitId":"-"},"content":" Delete Permanently"},{"lineNumber":427,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":428,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"btn-delete-disabled-{{ i }}\" class\u003d\"btn btn-light btn-sm disabled text-danger\""},{"lineNumber":429,"author":{"gitId":"-"},"content":" *ngIf\u003d\"!course.canModifyCourse\"\u003e"},{"lineNumber":430,"author":{"gitId":"-"},"content":" Delete Permanently"},{"lineNumber":431,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":432,"author":{"gitId":"-"},"content":" \u003c/td\u003e"},{"lineNumber":433,"author":{"gitId":"-"},"content":" \u003c/tr\u003e"},{"lineNumber":434,"author":{"gitId":"-"},"content":" \u003c/tbody\u003e"},{"lineNumber":435,"author":{"gitId":"-"},"content":" \u003c/table\u003e"},{"lineNumber":436,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":437,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":438,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":439,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":440,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":441,"author":{"gitId":"-"},"content":""},{"lineNumber":442,"author":{"gitId":"-"},"content":"\u003cng-template #modifiedTimestampsModal\u003e"},{"lineNumber":443,"author":{"gitId":"-"},"content":" \u003ctm-modified-timestamps-modal [modifiedSessions]\u003d\"this.modifiedSessions\"\u003e"},{"lineNumber":444,"author":{"gitId":"-"},"content":" \u003c/tm-modified-timestamps-modal\u003e"},{"lineNumber":445,"author":{"gitId":"-"},"content":"\u003c/ng-template\u003e"}],"authorContributionMap":{"dishenggg":4,"-":441}},{"path":"src/web/app/pages-instructor/instructor-home-page/instructor-home-page.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003ch1\u003eHome\u003c/h1\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"card bg-light\" style\u003d\"margin-bottom: 20px;\" *ngIf\u003d\"isNewUser\"\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":" New to TEAMMATES? You may wish to have a look at our \u003ca href\u003d\"/web/instructor/getting-started\" target\u003d\"_blank\""},{"lineNumber":6,"author":{"gitId":"-"},"content":" rel\u003d\"noopener noreferrer\"\u003eGetting Started Guide\u003c/a\u003e."},{"lineNumber":7,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"\u003cdiv class\u003d\"row mb-3\" *tmIsLoading\u003d\"!hasCoursesLoaded\"\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-4 mt-auto\"\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003ca tmRouterLink\u003d\"/web/instructor/courses\" class\u003d\"btn btn-success\" [queryParams]\u003d\"{isAddNewCourse: true}\"\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-plus\"\u003e\u003c/i\u003e Add New Course"},{"lineNumber":14,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":16,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-8\" *ngIf\u003d\"courseTabModels.length \u003e 0\"\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"float-end\"\u003e"},{"lineNumber":18,"author":{"gitId":"-"},"content":" \u003cstrong class\u003d\"d-inline\"\u003e Sort By: \u003c/strong\u003e"},{"lineNumber":19,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"btn-group\" data-toggle\u003d\"buttons\"\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"sort-course-id\" class\u003d\"btn btn-light\" [disabled]\u003d\"isSelectedForSorting(SortBy.COURSE_ID)\""},{"lineNumber":21,"author":{"gitId":"-"},"content":" (click)\u003d\"sortCoursesBy(SortBy.COURSE_ID)\"\u003eCourse ID\u003c/button\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"sort-course-name\" class\u003d\"btn btn-light\" [disabled]\u003d\"isSelectedForSorting(SortBy.COURSE_NAME)\""},{"lineNumber":23,"author":{"gitId":"-"},"content":" (click)\u003d\"sortCoursesBy(SortBy.COURSE_NAME)\"\u003eCourse Name\u003c/button\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"sort-course-date\" class\u003d\"btn btn-light\""},{"lineNumber":25,"author":{"gitId":"-"},"content":" [disabled]\u003d\"isSelectedForSorting(SortBy.COURSE_CREATION_DATE)\""},{"lineNumber":26,"author":{"gitId":"-"},"content":" (click)\u003d\"sortCoursesBy(SortBy.COURSE_CREATION_DATE)\"\u003eCreation Date\u003c/button\u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":28,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":29,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":30,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":"\u003cdiv *ngIf\u003d\"isCopyingCourse\" class\u003d\"mb-4\"\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003cp\u003eCopy Progress\u003c/p\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003ctm-progress-bar\u003e\u003c/tm-progress-bar\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":36,"author":{"gitId":"-"},"content":""},{"lineNumber":37,"author":{"gitId":"-"},"content":"\u003ctm-loading-retry [shouldShowRetry]\u003d\"hasCoursesLoadingFailed\" [message]\u003d\"\u0027Something went wrong\u0027\""},{"lineNumber":38,"author":{"gitId":"-"},"content":" (retryEvent)\u003d\"loadCourses()\"\u003e"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003cdiv *tmIsLoading\u003d\"!hasCoursesLoaded || isCopyLoading\"\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"courseTabModels.length \u003e 0\"\u003e"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"course-tab-{{ idx }}\" class\u003d\"card\" *ngFor\u003d\"let courseTabModel of courseTabModels; let idx \u003d index\"\u003e"},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header bg-primary text-white cursor-pointer\""},{"lineNumber":43,"author":{"gitId":"-"},"content":" (click)\u003d\"courseTabModel.isTabExpanded \u003d handleClick($event, courseTabModel); this.loadFeedbackSessions(idx);\"\u003e"},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u003cb class\u003d\"course-details text-break\"\u003e[{{ courseTabModel.course.courseId }}]: {{"},{"lineNumber":45,"author":{"gitId":"-"},"content":" courseTabModel.course.courseName }}\u003c/b\u003e"},{"lineNumber":46,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header-btn-toolbar flex-lg-shrink-0\" *ngIf\u003d\"courseTabModel.isAjaxSuccess\"\u003e"},{"lineNumber":47,"author":{"gitId":"-"},"content":" \u003cspan ngbDropdown container\u003d\"body\"\u003e"},{"lineNumber":48,"author":{"gitId":"-"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn btn-primary btn-sm\" ngbDropdownToggle\u003e Students \u003c/button\u003e"},{"lineNumber":49,"author":{"gitId":"-"},"content":" \u003cdiv ngbDropdownMenu (click)\u003d\"$event.stopPropagation()\"\u003e"},{"lineNumber":50,"author":{"gitId":"-"},"content":" \u003cng-container *ngIf\u003d\"courseTabModel.instructorPrivilege.canModifyStudent\"\u003e"},{"lineNumber":51,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn btn-light btn-sm dropdown-item\" tmRouterLink\u003d\"/web/instructor/courses/enroll\""},{"lineNumber":52,"author":{"gitId":"-"},"content":" [queryParams]\u003d\"{courseid: courseTabModel.course.courseId}\"\u003e Enroll"},{"lineNumber":53,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":54,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn btn-light btn-sm dropdown-item\" tmRouterLink\u003d\"/web/instructor/courses/details\""},{"lineNumber":56,"author":{"gitId":"-"},"content":" [queryParams]\u003d\"{courseid: courseTabModel.course.courseId}\"\u003e View / Edit"},{"lineNumber":57,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":58,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":59,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":60,"author":{"gitId":"-"},"content":" \u003cspan ngbDropdown container\u003d\"body\"\u003e"},{"lineNumber":61,"author":{"gitId":"-"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn btn-primary btn-sm\" ngbDropdownToggle\u003e Instructors \u003c/button\u003e"},{"lineNumber":62,"author":{"gitId":"-"},"content":" \u003cdiv ngbDropdownMenu (click)\u003d\"$event.stopPropagation()\"\u003e"},{"lineNumber":63,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn btn-light btn-sm dropdown-item\" tmRouterLink\u003d\"/web/instructor/courses/edit\""},{"lineNumber":64,"author":{"gitId":"-"},"content":" [queryParams]\u003d\"{courseid: courseTabModel.course.courseId}\"\u003e View / Edit"},{"lineNumber":65,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":66,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":67,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":68,"author":{"gitId":"-"},"content":" \u003cspan ngbDropdown container\u003d\"body\"\u003e"},{"lineNumber":69,"author":{"gitId":"-"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn btn-primary btn-sm\" ngbDropdownToggle\u003e Sessions \u003c/button\u003e"},{"lineNumber":70,"author":{"gitId":"-"},"content":" \u003cdiv ngbDropdownMenu (click)\u003d\"$event.stopPropagation()\"\u003e"},{"lineNumber":71,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn btn-light btn-sm dropdown-item\" tmRouterLink\u003d\"/web/instructor/sessions\""},{"lineNumber":72,"author":{"gitId":"-"},"content":" [queryParams]\u003d\"{courseid: courseTabModel.course.courseId}\"\u003e Add"},{"lineNumber":73,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":74,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":75,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":76,"author":{"gitId":"-"},"content":" \u003cspan ngbDropdown container\u003d\"body\"\u003e"},{"lineNumber":77,"author":{"gitId":"-"},"content":" \u003cbutton type\u003d\"button\" class\u003d\"btn-course btn btn-primary btn-sm\" ngbDropdownToggle\u003e Course \u003c/button\u003e"},{"lineNumber":78,"author":{"gitId":"-"},"content":" \u003cdiv ngbDropdownMenu (click)\u003d\"$event.stopPropagation()\"\u003e"},{"lineNumber":79,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn-archive-course btn btn-light btn-sm dropdown-item\""},{"lineNumber":80,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Archive the course so that it will not be shown in the home page any more (you can still access it from the \u0027Courses\u0027 tab)\""},{"lineNumber":81,"author":{"gitId":"-"},"content":" (click)\u003d\"archiveCourse(courseTabModel.course.courseId)\""},{"lineNumber":82,"author":{"gitId":"-"},"content":" tmRouterLink\u003d\"./\"\u003e Archive"},{"lineNumber":83,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":84,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn btn-light btn-sm dropdown-item\" tmRouterLink\u003d\u0027/web/instructor/courses/edit\u0027"},{"lineNumber":85,"author":{"gitId":"-"},"content":" [queryParams]\u003d\"{courseid: courseTabModel.course.courseId}\"\u003e View / Edit"},{"lineNumber":86,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":87,"author":{"gitId":"-"},"content":" \u003cng-container *ngIf\u003d\"courseTabModel.instructorPrivilege.canModifyCourse\"\u003e"},{"lineNumber":88,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn-copy-course btn btn-light btn-sm dropdown-item\""},{"lineNumber":89,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Copy the course and its corresponding sessions\""},{"lineNumber":90,"author":{"gitId":"-"},"content":" (click)\u003d\"!isCopyingCourse \u0026\u0026 onCopy(courseTabModel.course.courseId, courseTabModel.course.courseName, courseTabModel.course.timeZone)\""},{"lineNumber":91,"author":{"gitId":"-"},"content":" tmRouterLink\u003d\"./\"\u003e Copy"},{"lineNumber":92,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":93,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":94,"author":{"gitId":"dishenggg"},"content":" \u003cng-container *ngIf\u003d\"courseTabModel.instructorPrivilege.canModifyInstructor \u0026\u0026 courseTabModel.course.isMigrated\"\u003e"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" \u003ca class\u003d\"btn-course-logs btn btn-light btn-sm dropdown-item\" tmRouterLink\u003d\"/web/instructor/courses/student-activity-logs\""},{"lineNumber":96,"author":{"gitId":"dishenggg"},"content":" [queryParams]\u003d\"{courseid: courseTabModel.course.courseId}\"\u003e View Logs"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" \u003c/a\u003e"},{"lineNumber":98,"author":{"gitId":"dishenggg"},"content":" \u003c/ng-container\u003e"},{"lineNumber":99,"author":{"gitId":"-"},"content":" \u003cng-container *ngIf\u003d\"courseTabModel.instructorPrivilege.canModifyCourse\"\u003e"},{"lineNumber":100,"author":{"gitId":"-"},"content":" \u003ca class\u003d\"btn-delete-course btn btn-light btn-sm dropdown-item\""},{"lineNumber":101,"author":{"gitId":"-"},"content":" ngbTooltip\u003d\"Delete the course and its corresponding students and sessions\""},{"lineNumber":102,"author":{"gitId":"-"},"content":" (click)\u003d\"deleteCourse(courseTabModel.course.courseId)\""},{"lineNumber":103,"author":{"gitId":"-"},"content":" tmRouterLink\u003d\"./\"\u003e Delete"},{"lineNumber":104,"author":{"gitId":"-"},"content":" \u003c/a\u003e"},{"lineNumber":105,"author":{"gitId":"-"},"content":" \u003c/ng-container\u003e"},{"lineNumber":106,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":107,"author":{"gitId":"-"},"content":" \u003c/span\u003e"},{"lineNumber":108,"author":{"gitId":"-"},"content":" \u003ctm-panel-chevron [isExpanded]\u003d\"courseTabModel.isTabExpanded\"\u003e\u003c/tm-panel-chevron\u003e"},{"lineNumber":109,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":110,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":111,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body padding-0 table-responsive\" *ngIf\u003d\"courseTabModel.isTabExpanded\" @collapseAnim\u003e"},{"lineNumber":112,"author":{"gitId":"-"},"content":" \u003ctm-loading-retry [shouldShowRetry]\u003d\"courseTabModel.hasLoadingFailed\""},{"lineNumber":113,"author":{"gitId":"-"},"content":" [message]\u003d\"\u0027Error loading feedback sessions\u0027\" (retryEvent)\u003d\"loadFeedbackSessions(idx)\"\u003e"},{"lineNumber":114,"author":{"gitId":"-"},"content":" \u003ctm-sessions-table *tmIsLoading\u003d\"!courseTabModel.hasPopulated\""},{"lineNumber":115,"author":{"gitId":"-"},"content":" [sessionsTableRowModels]\u003d\"courseTabModel.sessionsTableRowModels\""},{"lineNumber":116,"author":{"gitId":"-"},"content":" id \u003d \"sessions-table-{{ idx }}\""},{"lineNumber":117,"author":{"gitId":"-"},"content":" [initialSortBy]\u003d\"initialSortBy\""},{"lineNumber":118,"author":{"gitId":"-"},"content":" [sortOrder]\u003d\"sortOrder\""},{"lineNumber":119,"author":{"gitId":"-"},"content":" [courseCandidates]\u003d\"courseCandidates\""},{"lineNumber":120,"author":{"gitId":"-"},"content":" [headerColorScheme]\u003d\"SortableTableHeaderColorScheme.WHITE\""},{"lineNumber":121,"author":{"gitId":"-"},"content":" [columnsToShow]\u003d\"["},{"lineNumber":122,"author":{"gitId":"-"},"content":" SessionsTableColumn.START_DATE,"},{"lineNumber":123,"author":{"gitId":"-"},"content":" SessionsTableColumn.END_DATE"},{"lineNumber":124,"author":{"gitId":"-"},"content":" ]\""},{"lineNumber":125,"author":{"gitId":"-"},"content":" [isSendReminderLoading]\u003d\"isSendReminderLoading\""},{"lineNumber":126,"author":{"gitId":"-"},"content":" (sortSessionsTableRowModelsEvent)\u003d\"sortSessionsTableRowModelsEvent(idx, $event)\""},{"lineNumber":127,"author":{"gitId":"-"},"content":" (loadResponseRateEvent)\u003d\"loadResponseRateEventHandler(idx, $event)\""},{"lineNumber":128,"author":{"gitId":"-"},"content":" (moveSessionToRecycleBinEvent)\u003d\"moveSessionToRecycleBinEventHandler(idx, $event)\""},{"lineNumber":129,"author":{"gitId":"-"},"content":" (copySessionEvent)\u003d\"copySessionEventHandler(idx, $event)\""},{"lineNumber":130,"author":{"gitId":"-"},"content":" (submitSessionAsInstructorEvent)\u003d\"submitSessionAsInstructorEventHandler(idx, $event)\""},{"lineNumber":131,"author":{"gitId":"-"},"content":" (publishSessionEvent)\u003d\"publishSessionEventHandler(idx, $event)\""},{"lineNumber":132,"author":{"gitId":"-"},"content":" (unpublishSessionEvent)\u003d\"unpublishSessionEventHandler(idx, $event)\""},{"lineNumber":133,"author":{"gitId":"-"},"content":" (downloadSessionResultsEvent)\u003d\"downloadSessionResultEventHandler(idx, $event)\""},{"lineNumber":134,"author":{"gitId":"-"},"content":" (resendResultsLinkToStudentsEvent)\u003d\"resendResultsLinkToRespondentsEventHandler(courseTabModel.sessionsTableRowModels[$event])\""},{"lineNumber":135,"author":{"gitId":"-"},"content":" (sendRemindersToAllNonSubmittersEvent)\u003d\"sendRemindersToRespondentsEventHandler(courseTabModel.sessionsTableRowModels[$event], true)\""},{"lineNumber":136,"author":{"gitId":"-"},"content":" (sendRemindersToSelectedNonSubmittersEvent)\u003d\"sendRemindersToRespondentsEventHandler(courseTabModel.sessionsTableRowModels[$event], false)\"\u003e\u003c/tm-sessions-table\u003e"},{"lineNumber":137,"author":{"gitId":"-"},"content":" \u003c/tm-loading-retry\u003e"},{"lineNumber":138,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":139,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":140,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":141,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":142,"author":{"gitId":"-"},"content":"\u003c/tm-loading-retry\u003e"},{"lineNumber":143,"author":{"gitId":"-"},"content":""},{"lineNumber":144,"author":{"gitId":"-"},"content":"\u003cng-template #modifiedTimestampsModal\u003e"},{"lineNumber":145,"author":{"gitId":"-"},"content":" \u003ctm-modified-timestamps-modal [coursesOfModifiedSession]\u003d\"this.coursesOfModifiedSession\""},{"lineNumber":146,"author":{"gitId":"-"},"content":" [modifiedSessions]\u003d\"this.modifiedSession\"\u003e"},{"lineNumber":147,"author":{"gitId":"-"},"content":" \u003c/tm-modified-timestamps-modal\u003e"},{"lineNumber":148,"author":{"gitId":"-"},"content":"\u003c/ng-template\u003e"}],"authorContributionMap":{"dishenggg":5,"-":143}},{"path":"src/web/app/pages-instructor/instructor-student-activity-logs/instructor-student-activity-logs.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003ch1\u003eStudent Activity Logs For {{course.courseName}}\u003c/h1\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":"\u003cp\u003eThis page allows you to find when your students have accessed or submitted a particular feedback session or view a session results. Note that you can only view student logs if you have \u003cb\u003eowner or manager privileges\u003c/b\u003e for the course. The earliest date you can search for is \u003cb\u003e{{this.LOGS_RETENTION_PERIOD}} days\u003c/b\u003e before today.\u003c/p\u003e"},{"lineNumber":3,"author":{"gitId":"dishenggg"},"content":"\u003cp\u003ePlease note that recent activity after \u003cb\u003e{{ this.lastUpdated }}\u003c/b\u003e may \u003cb\u003eNOT\u003c/b\u003e be shown as the information is updated in \u003cb\u003e{{ this.STUDENT_ACTIVITY_LOGS_UPDATE_INTERVAL }} minute\u003c/b\u003e intervals.\u003c/p\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":"\u003chr/\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"\u003cdiv *tmIsLoading\u003d\"isLoading\" class\u003d\"card bg-form no-border\"\u003e"},{"lineNumber":7,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\"\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row form-group\"\u003e"},{"lineNumber":9,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-4\"\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003clabel for\u003d\"activity-type-dropdown\" class\u003d\"fw-bold\"\u003eActivity Type\u003c/label\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":14,"author":{"gitId":"-"},"content":" \u003cselect id\u003d\"activity-type-dropdown\" class\u003d\"form-control form-select col-12\" [(ngModel)]\u003d\"formModel.logType\" (ngModelChange)\u003d\"triggerDefaultLogActivityTypeChange($event)\"\u003e"},{"lineNumber":15,"author":{"gitId":"-"},"content":" \u003coption value\u003d\"\" disabled selected hidden\u003eSelect Activity Type\u003c/option\u003e"},{"lineNumber":16,"author":{"gitId":"-"},"content":" \u003coption *ngFor\u003d\"let logType of LOG_TYPES\" [value]\u003d\"logType.value\"\u003e"},{"lineNumber":17,"author":{"gitId":"-"},"content":" {{logType.label}}"},{"lineNumber":18,"author":{"gitId":"-"},"content":" \u003c/option\u003e"},{"lineNumber":19,"author":{"gitId":"-"},"content":" \u003c/select\u003e"},{"lineNumber":20,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-8\"\u003e"},{"lineNumber":23,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 mb-1\"\u003e"},{"lineNumber":24,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"fw-bold\"\u003eSearch period from\u003c/label\u003e"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":26,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"input-group\"\u003e"},{"lineNumber":27,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"logs-from-datepicker\" class\u003d\"col-md-6 input-group\"\u003e"},{"lineNumber":28,"author":{"gitId":"-"},"content":" \u003cinput type\u003d\"text\" class\u003d\"form-control\" ngbDatepicker readonly [minDate]\u003d\"earliestSearchDate\""},{"lineNumber":29,"author":{"gitId":"-"},"content":" [maxDate]\u003d\"formModel.logsDateTo\" [(ngModel)]\u003d\"formModel.logsDateFrom\" #logsFromDp\u003d\"ngbDatepicker\""},{"lineNumber":30,"author":{"gitId":"-"},"content":" aria-label\u003d\"Date to search from\" /\u003e"},{"lineNumber":31,"author":{"gitId":"-"},"content":" \u003cbutton class\u003d\"btn btn-light\" aria-label\u003d\"Change date\" (click)\u003d\"logsFromDp.toggle()\" type\u003d\"button\"\u003e"},{"lineNumber":32,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-calendar-alt\"\u003e\u003c/i\u003e"},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-3\"\u003e"},{"lineNumber":36,"author":{"gitId":"-"},"content":" \u003ctm-timepicker id\u003d\"logs-from-timepicker\" [(time)]\u003d\"formModel.logsTimeFrom\"\u003e\u003c/tm-timepicker\u003e"},{"lineNumber":37,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":38,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":41,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row form-group\"\u003e"},{"lineNumber":42,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-4\"\u003e"},{"lineNumber":43,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":44,"author":{"gitId":"-"},"content":" \u003clabel for\u003d\"student-name-dropdown\" class\u003d\"fw-bold\"\u003eStudent Name (Optional)\u003c/label\u003e"},{"lineNumber":45,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":46,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" \u003cselect id\u003d\"student-name-dropdown\" class\u003d\"form-control form-select col-12\" [(ngModel)]\u003d\"formModel.selectedStudent\"\u003e"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":" \u003coption *ngFor\u003d\"let student of students\" [ngValue]\u003d\"{studentEmail: student.email || \u0027\u0027, studentId: student.studentId}\"\u003e"},{"lineNumber":49,"author":{"gitId":"-"},"content":" {{student.name}} {{student.email ? \u0027\u003c\u0027 + student.email + \u0027\u003e\u0027 : \u0027\u0027}}"},{"lineNumber":50,"author":{"gitId":"-"},"content":" \u003c/option\u003e"},{"lineNumber":51,"author":{"gitId":"-"},"content":" \u003c/select\u003e"},{"lineNumber":52,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":53,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":54,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-8\"\u003e"},{"lineNumber":55,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 mb-1\"\u003e"},{"lineNumber":56,"author":{"gitId":"-"},"content":" \u003clabel for\u003d\"logs-to-datepicker\" class\u003d\"fw-bold\"\u003eSearch period until\u003c/label\u003e"},{"lineNumber":57,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":58,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"input-group\"\u003e"},{"lineNumber":59,"author":{"gitId":"-"},"content":" \u003cdiv id\u003d\"logs-to-datepicker\" class\u003d\"col-md-6 input-group\"\u003e"},{"lineNumber":60,"author":{"gitId":"-"},"content":" \u003cinput type\u003d\"text\" class\u003d\"form-control\" ngbDatepicker readonly [minDate]\u003d\"formModel.logsDateFrom\""},{"lineNumber":61,"author":{"gitId":"-"},"content":" [maxDate]\u003d\"dateToday\" [(ngModel)]\u003d\"formModel.logsDateTo\" #logsToDp\u003d\"ngbDatepicker\""},{"lineNumber":62,"author":{"gitId":"-"},"content":" aria-label\u003d\"Date to search until\" /\u003e"},{"lineNumber":63,"author":{"gitId":"-"},"content":" \u003cbutton class\u003d\"btn btn-light\" aria-label\u003d\"Change date\" (click)\u003d\"logsToDp.toggle()\" type\u003d\"button\"\u003e"},{"lineNumber":64,"author":{"gitId":"-"},"content":" \u003ci class\u003d\"fas fa-calendar-alt\"\u003e\u003c/i\u003e"},{"lineNumber":65,"author":{"gitId":"-"},"content":" \u003c/button\u003e"},{"lineNumber":66,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":67,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-3\"\u003e"},{"lineNumber":68,"author":{"gitId":"-"},"content":" \u003ctm-timepicker id\u003d\"logs-to-timepicker\" [(time)]\u003d\"formModel.logsTimeTo\" aria-label\u003d\"Search period until time\"\u003e\u003c/tm-timepicker\u003e"},{"lineNumber":69,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":70,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-md-2\"\u003e"},{"lineNumber":71,"author":{"gitId":"-"},"content":" \u003cbutton id\u003d\"search-button\" class\u003d\"float-end btn btn-primary\" (click)\u003d\"search()\" [disabled]\u003d\"course.courseId \u003d\u003d\u003d \u0027\u0027 || isSearching\"\u003eSearch\u003c/button\u003e"},{"lineNumber":72,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":73,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":74,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":75,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":76,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row form-group\"\u003e"},{"lineNumber":77,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-5\"\u003e"},{"lineNumber":78,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":79,"author":{"gitId":"-"},"content":" \u003clabel for\u003d\"session-dropdown\" class\u003d\"fw-bold\"\u003eFeedback Session Name (Optional)\u003c/label\u003e"},{"lineNumber":80,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":81,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12\"\u003e"},{"lineNumber":82,"author":{"gitId":"dishenggg"},"content":" \u003cselect id\u003d\"session-dropdown\" class\u003d\"form-control form-select col-md-12\" [(ngModel)]\u003d\"formModel.selectedSession\"\u003e"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" \u003coption [ngValue]\u003d\"{feedbackSessionName: \u0027\u0027, sessionId: \u0027\u0027}\"\u003e\u003c/option\u003e"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" \u003coption *ngFor\u003d\"let session of feedbackSessions | keyvalue\" [ngValue]\u003d\"{feedbackSessionName: session.key, sessionId: session.value.sessionId}\"\u003e"},{"lineNumber":85,"author":{"gitId":"-"},"content":" {{session.key}}"},{"lineNumber":86,"author":{"gitId":"-"},"content":" \u003c/option\u003e"},{"lineNumber":87,"author":{"gitId":"-"},"content":" \u003c/select\u003e"},{"lineNumber":88,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":89,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":90,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"row mt-md-1 ms-md-3\"\u003e"},{"lineNumber":91,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"col-12 form-check\" style\u003d\"margin-top: 30px;\"\u003e"},{"lineNumber":92,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"form-check-label\"\u003e"},{"lineNumber":93,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"show-actions\" class\u003d\"form-check-input\" type\u003d\"checkbox\" name\u003d\"showActions\" [checked]\u003d\"formModel.showActions\" (click)\u003d\"triggerModelChange(\u0027showActions\u0027, $event.target.checked)\"\u003e"},{"lineNumber":94,"author":{"gitId":"-"},"content":" Show actions"},{"lineNumber":95,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":96,"author":{"gitId":"-"},"content":" \u003clabel class\u003d\"form-check-label\" style\u003d\"margin-left: 40px;\"\u003e"},{"lineNumber":97,"author":{"gitId":"-"},"content":" \u003cinput id\u003d\"show-inactions\" class\u003d\"form-check-input\" type\u003d\"checkbox\" name\u003d\"showInactions\" [checked]\u003d\"formModel.showInactions\" (click)\u003d\"triggerModelChange(\u0027showInactions\u0027, $event.target.checked)\"\u003e"},{"lineNumber":98,"author":{"gitId":"-"},"content":" Show inactions"},{"lineNumber":99,"author":{"gitId":"-"},"content":" \u003c/label\u003e"},{"lineNumber":100,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":101,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":102,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":103,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":104,"author":{"gitId":"-"},"content":"\u003c/div\u003e"},{"lineNumber":105,"author":{"gitId":"-"},"content":"\u003cdiv id\u003d\"logs-output\"\u003e"},{"lineNumber":106,"author":{"gitId":"-"},"content":" \u003cdiv *tmIsLoading\u003d\"isSearching\"\u003e"},{"lineNumber":107,"author":{"gitId":"-"},"content":" \u003cdiv *ngFor\u003d\"let results of searchResults\"\u003e"},{"lineNumber":108,"author":{"gitId":"-"},"content":" \u003cdiv [ngClass]\u003d\"{ \u0027alert-success-border\u0027: results.logRowsData.length, \u0027alert-failure-border\u0027: !results.logRowsData.length }\" class\u003d\"card mb-3\"\u003e"},{"lineNumber":109,"author":{"gitId":"-"},"content":" \u003cdiv [ngClass]\u003d\"{ \u0027alert-success\u0027: results.logRowsData.length, \u0027alert-failure\u0027: !results.logRowsData.length}\" class\u003d\"card-header cursor-pointer text-break\" (click)\u003d\"results.isTabExpanded \u003d !results.isTabExpanded\"\u003e"},{"lineNumber":110,"author":{"gitId":"-"},"content":" {{results.feedbackSessionName}}"},{"lineNumber":111,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header-btn-toolbar\"\u003e"},{"lineNumber":112,"author":{"gitId":"-"},"content":" \u003ctm-panel-chevron [isExpanded]\u003d\"results.isTabExpanded\"\u003e\u003c/tm-panel-chevron\u003e"},{"lineNumber":113,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":114,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":115,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"results.isTabExpanded\"\u003e"},{"lineNumber":116,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"results.logRowsData[0]; else noActivityTemplate\" class\u003d\"card-body mb-4\"\u003e"},{"lineNumber":117,"author":{"gitId":"-"},"content":" \u003ctm-sortable-table [rows]\u003d\"results.logRowsData\" [columns]\u003d\"results.logColumnsData\" [initialSortBy]\u003d\"SortBy.GIVER_NAME\"\u003e\u003c/tm-sortable-table\u003e"},{"lineNumber":118,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":119,"author":{"gitId":"-"},"content":" \u003cng-template #noActivityTemplate\u003e"},{"lineNumber":120,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"no-activity-body\"\u003e"},{"lineNumber":121,"author":{"gitId":"-"},"content":" \u003ci\u003eNo activity for this feedback session in selected search period\u003c/i\u003e"},{"lineNumber":122,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":123,"author":{"gitId":"-"},"content":" \u003c/ng-template\u003e"},{"lineNumber":124,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":125,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":126,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":127,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":128,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"dishenggg":6,"-":122}},{"path":"src/web/app/pages-instructor/instructor-student-activity-logs/instructor-student-activity-logs.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { HttpClientTestingModule } from \u0027@angular/common/http/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { ComponentFixture, TestBed, waitForAsync } from \u0027@angular/core/testing\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { RouterTestingModule } from \u0027@angular/router/testing\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { of } from \u0027rxjs\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import SpyInstance \u003d jest.SpyInstance;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { InstructorStudentActivityLogsComponent } from \u0027./instructor-student-activity-logs.component\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { InstructorStudentActivityLogsModule } from \u0027./instructor-student-activity-logs.module\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { LogService } from \u0027../../../services/log.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { StudentService } from \u0027../../../services/student.service\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { TimezoneService } from \u0027../../../services/timezone.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":12,"author":{"gitId":"-"},"content":" Course,"},{"lineNumber":13,"author":{"gitId":"-"},"content":" FeedbackSession,"},{"lineNumber":14,"author":{"gitId":"-"},"content":" FeedbackSessionLog,"},{"lineNumber":15,"author":{"gitId":"-"},"content":" FeedbackSessionLogType,"},{"lineNumber":16,"author":{"gitId":"-"},"content":" FeedbackSessionPublishStatus,"},{"lineNumber":17,"author":{"gitId":"-"},"content":" FeedbackSessionSubmissionStatus,"},{"lineNumber":18,"author":{"gitId":"-"},"content":" ResponseVisibleSetting,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" SessionVisibleSetting,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" Student,"},{"lineNumber":21,"author":{"gitId":"-"},"content":"} from \u0027../../../types/api-output\u0027;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import { Milliseconds } from \u0027../../../types/datetime-const\u0027;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import { SortBy } from \u0027../../../types/sort-properties\u0027;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import { ColumnData } from \u0027../../components/sortable-table/sortable-table.component\u0027;"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":"describe(\u0027InstructorStudentActivityLogsComponent\u0027, () \u003d\u003e {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" let component: InstructorStudentActivityLogsComponent;"},{"lineNumber":28,"author":{"gitId":"-"},"content":" let fixture: ComponentFixture\u003cInstructorStudentActivityLogsComponent\u003e;"},{"lineNumber":29,"author":{"gitId":"-"},"content":" let studentService: StudentService;"},{"lineNumber":30,"author":{"gitId":"-"},"content":" let logService: LogService;"},{"lineNumber":31,"author":{"gitId":"-"},"content":" let timezoneService: TimezoneService;"},{"lineNumber":32,"author":{"gitId":"-"},"content":""},{"lineNumber":33,"author":{"gitId":"-"},"content":" const LOGS_DATE_TIME_FORMAT: string \u003d \u0027ddd, DD MMM YYYY hh:mm:ss A\u0027;"},{"lineNumber":34,"author":{"gitId":"-"},"content":" const resultColumns: ColumnData[] \u003d ["},{"lineNumber":35,"author":{"gitId":"-"},"content":" { header: \u0027Status\u0027, sortBy: SortBy.RESULT_VIEW_STATUS },"},{"lineNumber":36,"author":{"gitId":"-"},"content":" { header: \u0027Name\u0027, sortBy: SortBy.GIVER_NAME },"},{"lineNumber":37,"author":{"gitId":"-"},"content":" { header: \u0027Email\u0027, sortBy: SortBy.RESPONDENT_EMAIL },"},{"lineNumber":38,"author":{"gitId":"-"},"content":" { header: \u0027Section\u0027, sortBy: SortBy.SECTION_NAME },"},{"lineNumber":39,"author":{"gitId":"-"},"content":" { header: \u0027Team\u0027, sortBy: SortBy.TEAM_NAME },"},{"lineNumber":40,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":41,"author":{"gitId":"-"},"content":" const testCourse1: Course \u003d {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" courseId: \u0027CS9999\u0027,"},{"lineNumber":43,"author":{"gitId":"-"},"content":" courseName: \u0027CS9999\u0027,"},{"lineNumber":44,"author":{"gitId":"-"},"content":" institute: \u0027Test Institute\u0027,"},{"lineNumber":45,"author":{"gitId":"-"},"content":" timeZone: \u0027Asia/Singapore\u0027,"},{"lineNumber":46,"author":{"gitId":"-"},"content":" creationTimestamp: 0,"},{"lineNumber":47,"author":{"gitId":"-"},"content":" deletionTimestamp: 0,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" privileges: {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" canModifyCourse: true,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" canModifySession: true,"},{"lineNumber":51,"author":{"gitId":"-"},"content":" canModifyStudent: true,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" canModifyInstructor: true,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" canViewStudentInSections: true,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" canModifySessionCommentsInSections: true,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" canViewSessionInSections: true,"},{"lineNumber":56,"author":{"gitId":"-"},"content":" canSubmitSessionInSections: true,"},{"lineNumber":57,"author":{"gitId":"-"},"content":" },"},{"lineNumber":58,"author":{"gitId":"-"},"content":" };"},{"lineNumber":59,"author":{"gitId":"-"},"content":" const emptyStudent: Student \u003d {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" courseId: \u0027\u0027, email: \u0027\u0027, name: \u0027\u0027, sectionName: \u0027\u0027, teamName: \u0027\u0027,"},{"lineNumber":61,"author":{"gitId":"-"},"content":" };"},{"lineNumber":62,"author":{"gitId":"-"},"content":" const testStudent: Student \u003d {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" email: \u0027doejohn@email.com\u0027,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" courseId: \u0027CS9999\u0027,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" name: \u0027Doe John\u0027,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" teamName: \u0027team 1\u0027,"},{"lineNumber":67,"author":{"gitId":"-"},"content":" sectionName: \u0027section 1\u0027,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" };"},{"lineNumber":69,"author":{"gitId":"-"},"content":" const testFeedbackSession: FeedbackSession \u003d {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" feedbackSessionName: \u0027Feedback Session 1\u0027,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" courseId: \u0027CS9999\u0027,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" timeZone: \u0027Asia/Singapore\u0027,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" instructions: \u0027\u0027,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" submissionStartTimestamp: 0,"},{"lineNumber":75,"author":{"gitId":"-"},"content":" submissionEndTimestamp: 1549095330000,"},{"lineNumber":76,"author":{"gitId":"-"},"content":" gracePeriod: 0,"},{"lineNumber":77,"author":{"gitId":"-"},"content":" sessionVisibleSetting: SessionVisibleSetting.AT_OPEN,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" responseVisibleSetting: ResponseVisibleSetting.AT_VISIBLE,"},{"lineNumber":79,"author":{"gitId":"-"},"content":" submissionStatus: FeedbackSessionSubmissionStatus.OPEN,"},{"lineNumber":80,"author":{"gitId":"-"},"content":" publishStatus: FeedbackSessionPublishStatus.PUBLISHED,"},{"lineNumber":81,"author":{"gitId":"-"},"content":" isClosingEmailEnabled: true,"},{"lineNumber":82,"author":{"gitId":"-"},"content":" isPublishedEmailEnabled: true,"},{"lineNumber":83,"author":{"gitId":"-"},"content":" createdAtTimestamp: 0,"},{"lineNumber":84,"author":{"gitId":"-"},"content":" studentDeadlines: {},"},{"lineNumber":85,"author":{"gitId":"-"},"content":" instructorDeadlines: {},"},{"lineNumber":86,"author":{"gitId":"-"},"content":" };"},{"lineNumber":87,"author":{"gitId":"-"},"content":" const testLogs1: FeedbackSessionLog \u003d {"},{"lineNumber":88,"author":{"gitId":"-"},"content":" feedbackSessionData: testFeedbackSession,"},{"lineNumber":89,"author":{"gitId":"-"},"content":" feedbackSessionLogEntries: ["},{"lineNumber":90,"author":{"gitId":"-"},"content":" {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" studentData: testStudent,"},{"lineNumber":92,"author":{"gitId":"-"},"content":" feedbackSessionLogType: FeedbackSessionLogType.SUBMISSION,"},{"lineNumber":93,"author":{"gitId":"-"},"content":" timestamp: 0,"},{"lineNumber":94,"author":{"gitId":"-"},"content":" },"},{"lineNumber":95,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":96,"author":{"gitId":"-"},"content":" };"},{"lineNumber":97,"author":{"gitId":"-"},"content":" const testLogs2: FeedbackSessionLog \u003d {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" feedbackSessionData: testFeedbackSession,"},{"lineNumber":99,"author":{"gitId":"-"},"content":" feedbackSessionLogEntries: ["},{"lineNumber":100,"author":{"gitId":"-"},"content":" {"},{"lineNumber":101,"author":{"gitId":"-"},"content":" studentData: testStudent,"},{"lineNumber":102,"author":{"gitId":"-"},"content":" feedbackSessionLogType: FeedbackSessionLogType.SUBMISSION,"},{"lineNumber":103,"author":{"gitId":"-"},"content":" timestamp: 0,"},{"lineNumber":104,"author":{"gitId":"-"},"content":" },"},{"lineNumber":105,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":106,"author":{"gitId":"-"},"content":" };"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" beforeEach(waitForAsync(() \u003d\u003e {"},{"lineNumber":109,"author":{"gitId":"-"},"content":" TestBed.configureTestingModule({"},{"lineNumber":110,"author":{"gitId":"-"},"content":" imports: ["},{"lineNumber":111,"author":{"gitId":"-"},"content":" InstructorStudentActivityLogsModule,"},{"lineNumber":112,"author":{"gitId":"-"},"content":" HttpClientTestingModule,"},{"lineNumber":113,"author":{"gitId":"-"},"content":" RouterTestingModule,"},{"lineNumber":114,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":115,"author":{"gitId":"-"},"content":" }).compileComponents();"},{"lineNumber":116,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":117,"author":{"gitId":"-"},"content":""},{"lineNumber":118,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":119,"author":{"gitId":"-"},"content":" fixture \u003d TestBed.createComponent(InstructorStudentActivityLogsComponent);"},{"lineNumber":120,"author":{"gitId":"-"},"content":" studentService \u003d TestBed.inject(StudentService);"},{"lineNumber":121,"author":{"gitId":"-"},"content":" logService \u003d TestBed.inject(LogService);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" timezoneService \u003d TestBed.inject(TimezoneService);"},{"lineNumber":123,"author":{"gitId":"-"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":124,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":125,"author":{"gitId":"-"},"content":" });"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":128,"author":{"gitId":"-"},"content":" expect(component).toBeTruthy();"},{"lineNumber":129,"author":{"gitId":"-"},"content":" });"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" it(\u0027should snap with default fields\u0027, () \u003d\u003e {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":133,"author":{"gitId":"-"},"content":" });"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" it(\u0027should snap when page is still loading\u0027, () \u003d\u003e {"},{"lineNumber":136,"author":{"gitId":"-"},"content":" component.isLoading \u003d true;"},{"lineNumber":137,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":138,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":139,"author":{"gitId":"-"},"content":" });"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" it(\u0027should snap when searching for details in search form\u0027, () \u003d\u003e {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" component.course \u003d testCourse1;"},{"lineNumber":143,"author":{"gitId":"-"},"content":" component.formModel \u003d {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" logsDateFrom: { year: 1997, month: 9, day: 11 },"},{"lineNumber":145,"author":{"gitId":"-"},"content":" logsTimeFrom: { hour: 23, minute: 59 },"},{"lineNumber":146,"author":{"gitId":"-"},"content":" logsDateTo: { year: 1998, month: 9, day: 11 },"},{"lineNumber":147,"author":{"gitId":"-"},"content":" logsTimeTo: { hour: 15, minute: 0 },"},{"lineNumber":148,"author":{"gitId":"dishenggg"},"content":" selectedStudent: { studentEmail: \u0027doejohn@email.com\u0027, studentId: undefined },"},{"lineNumber":149,"author":{"gitId":"-"},"content":" logType: \u0027session access\u0027,"},{"lineNumber":150,"author":{"gitId":"dishenggg"},"content":" selectedSession: { feedbackSessionName: undefined, sessionId: undefined },"},{"lineNumber":151,"author":{"gitId":"-"},"content":" showActions: false,"},{"lineNumber":152,"author":{"gitId":"-"},"content":" showInactions: false,"},{"lineNumber":153,"author":{"gitId":"-"},"content":" };"},{"lineNumber":154,"author":{"gitId":"-"},"content":" component.students \u003d [testStudent];"},{"lineNumber":155,"author":{"gitId":"-"},"content":" component.isLoading \u003d false;"},{"lineNumber":156,"author":{"gitId":"-"},"content":" component.isSearching \u003d true;"},{"lineNumber":157,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":160,"author":{"gitId":"-"},"content":" });"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"-"},"content":" it(\u0027should snap with results of a search\u0027, () \u003d\u003e {"},{"lineNumber":163,"author":{"gitId":"-"},"content":" component.searchResults \u003d ["},{"lineNumber":164,"author":{"gitId":"-"},"content":" {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" feedbackSessionName: \u0027Feedback session 1\u0027,"},{"lineNumber":166,"author":{"gitId":"-"},"content":" logColumnsData: resultColumns,"},{"lineNumber":167,"author":{"gitId":"-"},"content":" logRowsData: [["},{"lineNumber":168,"author":{"gitId":"-"},"content":" { value: \u002715 January 2021\u0027 },"},{"lineNumber":169,"author":{"gitId":"-"},"content":" { value: \u0027Doe John\u0027 },"},{"lineNumber":170,"author":{"gitId":"-"},"content":" { value: \u0027Viewed the submission page\u0027 },"},{"lineNumber":171,"author":{"gitId":"-"},"content":" { value: \u0027doejohn@email.com\u0027 },"},{"lineNumber":172,"author":{"gitId":"-"},"content":" { value: \u0027section 1\u0027 },"},{"lineNumber":173,"author":{"gitId":"-"},"content":" { value: \u0027team 1\u0027 },"},{"lineNumber":174,"author":{"gitId":"-"},"content":" ]],"},{"lineNumber":175,"author":{"gitId":"-"},"content":" isTabExpanded: true,"},{"lineNumber":176,"author":{"gitId":"-"},"content":" },"},{"lineNumber":177,"author":{"gitId":"-"},"content":" {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" feedbackSessionName: \u0027Feedback session 2\u0027,"},{"lineNumber":179,"author":{"gitId":"-"},"content":" logColumnsData: resultColumns,"},{"lineNumber":180,"author":{"gitId":"-"},"content":" logRowsData: [],"},{"lineNumber":181,"author":{"gitId":"-"},"content":" isTabExpanded: true,"},{"lineNumber":182,"author":{"gitId":"-"},"content":" },"},{"lineNumber":183,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":184,"author":{"gitId":"-"},"content":" component.isLoading \u003d false;"},{"lineNumber":185,"author":{"gitId":"-"},"content":" component.isSearching \u003d false;"},{"lineNumber":186,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":187,"author":{"gitId":"-"},"content":""},{"lineNumber":188,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":189,"author":{"gitId":"-"},"content":" });"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" it(\u0027should load all students of selected course has on select\u0027, () \u003d\u003e {"},{"lineNumber":192,"author":{"gitId":"-"},"content":" const studentSpy: SpyInstance \u003d jest.spyOn(studentService, \u0027getStudentsFromCourse\u0027)"},{"lineNumber":193,"author":{"gitId":"-"},"content":" .mockReturnValue(of({"},{"lineNumber":194,"author":{"gitId":"-"},"content":" students: ["},{"lineNumber":195,"author":{"gitId":"-"},"content":" testStudent,"},{"lineNumber":196,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" component.loadStudents(testCourse1.courseId);"},{"lineNumber":200,"author":{"gitId":"-"},"content":""},{"lineNumber":201,"author":{"gitId":"-"},"content":" expect(component.students[0]).toEqual(emptyStudent);"},{"lineNumber":202,"author":{"gitId":"-"},"content":" expect(component.students[1]).toEqual(testStudent);"},{"lineNumber":203,"author":{"gitId":"-"},"content":" expect(studentSpy).toHaveBeenNthCalledWith(1, { courseId: testCourse1.courseId });"},{"lineNumber":204,"author":{"gitId":"-"},"content":" });"},{"lineNumber":205,"author":{"gitId":"-"},"content":""},{"lineNumber":206,"author":{"gitId":"-"},"content":" it(\u0027should load students from cache if present\u0027, () \u003d\u003e {"},{"lineNumber":207,"author":{"gitId":"-"},"content":" const studentSpy: SpyInstance \u003d jest.spyOn(studentService, \u0027getStudentsFromCourse\u0027)"},{"lineNumber":208,"author":{"gitId":"-"},"content":" .mockReturnValue(of({"},{"lineNumber":209,"author":{"gitId":"-"},"content":" students: ["},{"lineNumber":210,"author":{"gitId":"-"},"content":" testStudent,"},{"lineNumber":211,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":212,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" component.students \u003d [emptyStudent];"},{"lineNumber":215,"author":{"gitId":"-"},"content":" component.loadStudents(testCourse1.courseId);"},{"lineNumber":216,"author":{"gitId":"-"},"content":""},{"lineNumber":217,"author":{"gitId":"-"},"content":" expect(component.students.length).toEqual(1);"},{"lineNumber":218,"author":{"gitId":"-"},"content":" expect(component.students[0]).toEqual(emptyStudent);"},{"lineNumber":219,"author":{"gitId":"-"},"content":" expect(studentSpy).not.toHaveBeenCalled();"},{"lineNumber":220,"author":{"gitId":"-"},"content":" });"},{"lineNumber":221,"author":{"gitId":"-"},"content":""},{"lineNumber":222,"author":{"gitId":"-"},"content":" it(\u0027should search for logs using feedback course timezone when search button is clicked\u0027, () \u003d\u003e {"},{"lineNumber":223,"author":{"gitId":"-"},"content":" const logSpy: SpyInstance \u003d jest.spyOn(logService, \u0027searchFeedbackSessionLog\u0027)"},{"lineNumber":224,"author":{"gitId":"-"},"content":" .mockReturnValue(of({ feedbackSessionLogs: [testLogs1, testLogs2] }));"},{"lineNumber":225,"author":{"gitId":"-"},"content":" const timeSpy: SpyInstance \u003d jest.spyOn(timezoneService, \u0027resolveLocalDateTime\u0027);"},{"lineNumber":226,"author":{"gitId":"-"},"content":" const tzOffset: number \u003d timezoneService.getTzOffsets()[testCourse1.timeZone];"},{"lineNumber":227,"author":{"gitId":"-"},"content":""},{"lineNumber":228,"author":{"gitId":"-"},"content":" component.isLoading \u003d false;"},{"lineNumber":229,"author":{"gitId":"-"},"content":" component.isSearching \u003d false;"},{"lineNumber":230,"author":{"gitId":"-"},"content":" component.formModel \u003d {"},{"lineNumber":231,"author":{"gitId":"-"},"content":" logsDateFrom: { year: 2020, month: 12, day: 30 },"},{"lineNumber":232,"author":{"gitId":"-"},"content":" logsTimeFrom: { hour: 23, minute: 59 },"},{"lineNumber":233,"author":{"gitId":"-"},"content":" logsDateTo: { year: 2020, month: 12, day: 31 },"},{"lineNumber":234,"author":{"gitId":"-"},"content":" logsTimeTo: { hour: 23, minute: 59 },"},{"lineNumber":235,"author":{"gitId":"dishenggg"},"content":" selectedStudent: { studentEmail: testStudent.email, studentId: \u0027\u0027 },"},{"lineNumber":236,"author":{"gitId":"-"},"content":" logType: \u0027submission\u0027,"},{"lineNumber":237,"author":{"gitId":"dishenggg"},"content":" selectedSession: { feedbackSessionName: \u0027\u0027, sessionId: \u0027\u0027 },"},{"lineNumber":238,"author":{"gitId":"-"},"content":" showActions: true,"},{"lineNumber":239,"author":{"gitId":"-"},"content":" showInactions: false,"},{"lineNumber":240,"author":{"gitId":"-"},"content":" };"},{"lineNumber":241,"author":{"gitId":"-"},"content":" component.course \u003d testCourse1;"},{"lineNumber":242,"author":{"gitId":"-"},"content":" component.students \u003d [testStudent];"},{"lineNumber":243,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":" fixture.debugElement.nativeElement.querySelector(\u0027#search-button\u0027).click();"},{"lineNumber":246,"author":{"gitId":"-"},"content":""},{"lineNumber":247,"author":{"gitId":"-"},"content":" expect(timeSpy).toHaveBeenCalledTimes(2);"},{"lineNumber":248,"author":{"gitId":"-"},"content":" expect(timeSpy).toHaveBeenCalledWith("},{"lineNumber":249,"author":{"gitId":"-"},"content":" component.formModel.logsDateFrom,"},{"lineNumber":250,"author":{"gitId":"-"},"content":" component.formModel.logsTimeFrom,"},{"lineNumber":251,"author":{"gitId":"-"},"content":" testCourse1.timeZone,"},{"lineNumber":252,"author":{"gitId":"-"},"content":" true,"},{"lineNumber":253,"author":{"gitId":"-"},"content":" );"},{"lineNumber":254,"author":{"gitId":"-"},"content":" expect(logSpy).toHaveBeenCalled();"},{"lineNumber":255,"author":{"gitId":"-"},"content":" expect(logSpy).toHaveBeenCalledWith({"},{"lineNumber":256,"author":{"gitId":"-"},"content":" courseId: testCourse1.courseId,"},{"lineNumber":257,"author":{"gitId":"-"},"content":" searchFrom: (new Date(\u00272020-12-31T00:00+00:00\u0027).getTime()"},{"lineNumber":258,"author":{"gitId":"-"},"content":" - tzOffset * Milliseconds.IN_ONE_MINUTE).toString(),"},{"lineNumber":259,"author":{"gitId":"-"},"content":" searchUntil: (new Date(\u00272021-01-01T00:00+00:00\u0027).getTime()"},{"lineNumber":260,"author":{"gitId":"-"},"content":" - tzOffset * Milliseconds.IN_ONE_MINUTE).toString(),"},{"lineNumber":261,"author":{"gitId":"-"},"content":" studentEmail: testStudent.email,"},{"lineNumber":262,"author":{"gitId":"-"},"content":" sessionName: \u0027\u0027,"},{"lineNumber":263,"author":{"gitId":"-"},"content":" logType: \u0027submission\u0027,"},{"lineNumber":264,"author":{"gitId":"dishenggg"},"content":" studentId: \u0027\u0027,"},{"lineNumber":265,"author":{"gitId":"dishenggg"},"content":" sessionId: \u0027\u0027,"},{"lineNumber":266,"author":{"gitId":"-"},"content":" });"},{"lineNumber":267,"author":{"gitId":"-"},"content":""},{"lineNumber":268,"author":{"gitId":"-"},"content":" expect(component.searchResults.length).toEqual(2);"},{"lineNumber":269,"author":{"gitId":"-"},"content":""},{"lineNumber":270,"author":{"gitId":"-"},"content":" const timestamp: string \u003d timezoneService.formatToString("},{"lineNumber":271,"author":{"gitId":"-"},"content":" 0, testFeedbackSession.timeZone, LOGS_DATE_TIME_FORMAT);"},{"lineNumber":272,"author":{"gitId":"-"},"content":""},{"lineNumber":273,"author":{"gitId":"-"},"content":" for (let i: number \u003d 0; i \u003c 2; i +\u003d 1) {"},{"lineNumber":274,"author":{"gitId":"-"},"content":" expect(component.searchResults[i].isTabExpanded).toBeTruthy();"},{"lineNumber":275,"author":{"gitId":"-"},"content":" expect(component.searchResults[i].logColumnsData).toEqual(resultColumns);"},{"lineNumber":276,"author":{"gitId":"-"},"content":" // Testing that the LogType is converted correctly."},{"lineNumber":277,"author":{"gitId":"-"},"content":" expect(component.searchResults[i].logRowsData[0][0].value).toEqual(`Submitted responses at ${timestamp}`);"},{"lineNumber":278,"author":{"gitId":"-"},"content":" }"},{"lineNumber":279,"author":{"gitId":"-"},"content":" });"},{"lineNumber":280,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"dishenggg":6,"-":274}},{"path":"src/web/app/pages-instructor/instructor-student-activity-logs/instructor-student-activity-logs.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component, OnInit } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { ActivatedRoute } from \u0027@angular/router\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { NgbDateParserFormatter } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { finalize } from \u0027rxjs/operators\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { CourseService } from \u0027../../../services/course.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { FeedbackSessionsService } from \u0027../../../services/feedback-sessions.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { LogService } from \u0027../../../services/log.service\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { StatusMessageService } from \u0027../../../services/status-message.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { StudentService } from \u0027../../../services/student.service\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { TimezoneService } from \u0027../../../services/timezone.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { ApiConst } from \u0027../../../types/api-const\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":13,"author":{"gitId":"-"},"content":" Course, FeedbackSession,"},{"lineNumber":14,"author":{"gitId":"-"},"content":" FeedbackSessionLog, FeedbackSessionLogEntry,"},{"lineNumber":15,"author":{"gitId":"-"},"content":" FeedbackSessionLogs, FeedbackSessions,"},{"lineNumber":16,"author":{"gitId":"-"},"content":" Student,"},{"lineNumber":17,"author":{"gitId":"-"},"content":"} from \u0027../../../types/api-output\u0027;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":19,"author":{"gitId":"-"},"content":" getDefaultDateFormat,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" getDefaultTimeFormat,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" getLatestTimeFormat,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" DateFormat,"},{"lineNumber":23,"author":{"gitId":"-"},"content":" TimeFormat,"},{"lineNumber":24,"author":{"gitId":"-"},"content":" Milliseconds,"},{"lineNumber":25,"author":{"gitId":"-"},"content":"} from \u0027../../../types/datetime-const\u0027;"},{"lineNumber":26,"author":{"gitId":"-"},"content":"import { SortBy } from \u0027../../../types/sort-properties\u0027;"},{"lineNumber":27,"author":{"gitId":"-"},"content":"import { DatePickerFormatter } from \u0027../../components/datepicker/datepicker-formatter\u0027;"},{"lineNumber":28,"author":{"gitId":"-"},"content":"import { ColumnData, SortableTableCellData } from \u0027../../components/sortable-table/sortable-table.component\u0027;"},{"lineNumber":29,"author":{"gitId":"-"},"content":"import { ErrorMessageOutput } from \u0027../../error-message-output\u0027;"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":32,"author":{"gitId":"-"},"content":" * Model for searching of logs"},{"lineNumber":33,"author":{"gitId":"-"},"content":" */"},{"lineNumber":34,"author":{"gitId":"-"},"content":"interface SearchLogsFormModel {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" logsDateFrom: DateFormat;"},{"lineNumber":36,"author":{"gitId":"-"},"content":" logsDateTo: DateFormat;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" logsTimeFrom: TimeFormat;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" logsTimeTo: TimeFormat;"},{"lineNumber":39,"author":{"gitId":"-"},"content":" logType: string;"},{"lineNumber":40,"author":{"gitId":"dishenggg"},"content":" selectedSession: SelectedSession;"},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" selectedStudent: SelectedStudent;"},{"lineNumber":42,"author":{"gitId":"-"},"content":" showActions: boolean;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" showInactions: boolean;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"}"},{"lineNumber":45,"author":{"gitId":"-"},"content":""},{"lineNumber":46,"author":{"gitId":"-"},"content":"interface LogType {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" label: string;"},{"lineNumber":48,"author":{"gitId":"-"},"content":" value: string;"},{"lineNumber":49,"author":{"gitId":"-"},"content":"}"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"dishenggg"},"content":"interface SelectedStudent {"},{"lineNumber":52,"author":{"gitId":"dishenggg"},"content":" studentEmail?: string;"},{"lineNumber":53,"author":{"gitId":"dishenggg"},"content":" studentId?: string;"},{"lineNumber":54,"author":{"gitId":"dishenggg"},"content":"}"},{"lineNumber":55,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":56,"author":{"gitId":"dishenggg"},"content":"interface SelectedSession {"},{"lineNumber":57,"author":{"gitId":"dishenggg"},"content":" feedbackSessionName?: string;"},{"lineNumber":58,"author":{"gitId":"dishenggg"},"content":" sessionId?: string;"},{"lineNumber":59,"author":{"gitId":"dishenggg"},"content":"}"},{"lineNumber":60,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":62,"author":{"gitId":"-"},"content":" * Model for displaying of feedback session logs"},{"lineNumber":63,"author":{"gitId":"-"},"content":" */"},{"lineNumber":64,"author":{"gitId":"-"},"content":"interface FeedbackSessionLogModel {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" feedbackSessionName: string;"},{"lineNumber":66,"author":{"gitId":"-"},"content":" logColumnsData: ColumnData[];"},{"lineNumber":67,"author":{"gitId":"-"},"content":" logRowsData: SortableTableCellData[][];"},{"lineNumber":68,"author":{"gitId":"-"},"content":" isTabExpanded: boolean;"},{"lineNumber":69,"author":{"gitId":"-"},"content":"}"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":72,"author":{"gitId":"-"},"content":" * Component for student activity and inactivity logs"},{"lineNumber":73,"author":{"gitId":"-"},"content":" */"},{"lineNumber":74,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":75,"author":{"gitId":"-"},"content":" selector: \u0027tm-instructor-student-activity-logs\u0027,"},{"lineNumber":76,"author":{"gitId":"-"},"content":" templateUrl: \u0027./instructor-student-activity-logs.component.html\u0027,"},{"lineNumber":77,"author":{"gitId":"-"},"content":" providers: [{ provide: NgbDateParserFormatter, useClass: DatePickerFormatter }],"},{"lineNumber":78,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./instructor-student-activity-logs.component.scss\u0027],"},{"lineNumber":79,"author":{"gitId":"-"},"content":"})"},{"lineNumber":80,"author":{"gitId":"-"},"content":"export class InstructorStudentActivityLogsComponent implements OnInit {"},{"lineNumber":81,"author":{"gitId":"-"},"content":" LOGS_DATE_TIME_FORMAT: string \u003d \u0027ddd, DD MMM YYYY hh:mm:ss A\u0027;"},{"lineNumber":82,"author":{"gitId":"-"},"content":" LOGS_RETENTION_PERIOD: number \u003d ApiConst.LOGS_RETENTION_PERIOD;"},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" STUDENT_ACTIVITY_LOGS_UPDATE_INTERVAL: number \u003d ApiConst.STUDENT_ACTIVITY_LOGS_UPDATE_INTERVAL;"},{"lineNumber":84,"author":{"gitId":"-"},"content":" LOG_TYPES: LogType[] \u003d ["},{"lineNumber":85,"author":{"gitId":"-"},"content":" { label: \u0027session access\u0027, value: \u0027access\u0027 },"},{"lineNumber":86,"author":{"gitId":"-"},"content":" { label: \u0027session submission\u0027, value: \u0027submission\u0027 },"},{"lineNumber":87,"author":{"gitId":"-"},"content":" { label: \u0027session access and submission\u0027, value: \u0027access,submission\u0027 },"},{"lineNumber":88,"author":{"gitId":"-"},"content":" { label: \u0027view session results\u0027, value: \u0027view result\u0027 },"},{"lineNumber":89,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":90,"author":{"gitId":"-"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" // enum"},{"lineNumber":92,"author":{"gitId":"-"},"content":" SortBy: typeof SortBy \u003d SortBy;"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" formModel: SearchLogsFormModel \u003d {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" logsDateFrom: getDefaultDateFormat(),"},{"lineNumber":96,"author":{"gitId":"-"},"content":" logsTimeFrom: getDefaultTimeFormat(),"},{"lineNumber":97,"author":{"gitId":"-"},"content":" logsDateTo: getDefaultDateFormat(),"},{"lineNumber":98,"author":{"gitId":"-"},"content":" logsTimeTo: getDefaultTimeFormat(),"},{"lineNumber":99,"author":{"gitId":"-"},"content":" logType: \u0027\u0027,"},{"lineNumber":100,"author":{"gitId":"dishenggg"},"content":" selectedStudent: { studentEmail: \u0027\u0027, studentId: \u0027\u0027 },"},{"lineNumber":101,"author":{"gitId":"dishenggg"},"content":" selectedSession: { feedbackSessionName: \u0027\u0027, sessionId: \u0027\u0027 },"},{"lineNumber":102,"author":{"gitId":"-"},"content":" showActions: false,"},{"lineNumber":103,"author":{"gitId":"-"},"content":" showInactions: false,"},{"lineNumber":104,"author":{"gitId":"-"},"content":" };"},{"lineNumber":105,"author":{"gitId":"-"},"content":" course: Course \u003d {"},{"lineNumber":106,"author":{"gitId":"-"},"content":" courseId: \u0027\u0027,"},{"lineNumber":107,"author":{"gitId":"-"},"content":" courseName: \u0027\u0027,"},{"lineNumber":108,"author":{"gitId":"-"},"content":" institute: \u0027\u0027,"},{"lineNumber":109,"author":{"gitId":"-"},"content":" timeZone: \u0027\u0027,"},{"lineNumber":110,"author":{"gitId":"-"},"content":" creationTimestamp: 0,"},{"lineNumber":111,"author":{"gitId":"-"},"content":" deletionTimestamp: 0,"},{"lineNumber":112,"author":{"gitId":"-"},"content":" };"},{"lineNumber":113,"author":{"gitId":"-"},"content":" dateToday: DateFormat \u003d getDefaultDateFormat();"},{"lineNumber":114,"author":{"gitId":"-"},"content":" earliestSearchDate: DateFormat \u003d getDefaultDateFormat();"},{"lineNumber":115,"author":{"gitId":"dishenggg"},"content":" studentLogsMap: Map\u003cstring, FeedbackSessionLogEntry[]\u003e \u003d new Map();"},{"lineNumber":116,"author":{"gitId":"-"},"content":" students: Student[] \u003d [];"},{"lineNumber":117,"author":{"gitId":"-"},"content":" feedbackSessions: Map\u003cstring, FeedbackSession\u003e \u003d new Map();"},{"lineNumber":118,"author":{"gitId":"-"},"content":" searchResults: FeedbackSessionLogModel[] \u003d [];"},{"lineNumber":119,"author":{"gitId":"-"},"content":" isLoading: boolean \u003d true;"},{"lineNumber":120,"author":{"gitId":"-"},"content":" isSearching: boolean \u003d false;"},{"lineNumber":121,"author":{"gitId":"dishenggg"},"content":" lastUpdated: string \u003d \u0027\u0027;"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" constructor(private route: ActivatedRoute,"},{"lineNumber":124,"author":{"gitId":"-"},"content":" private courseService: CourseService,"},{"lineNumber":125,"author":{"gitId":"-"},"content":" private feedbackSessionsService: FeedbackSessionsService,"},{"lineNumber":126,"author":{"gitId":"-"},"content":" private studentService: StudentService,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" private logsService: LogService,"},{"lineNumber":128,"author":{"gitId":"-"},"content":" private timezoneService: TimezoneService,"},{"lineNumber":129,"author":{"gitId":"-"},"content":" private statusMessageService: StatusMessageService) { }"},{"lineNumber":130,"author":{"gitId":"-"},"content":""},{"lineNumber":131,"author":{"gitId":"-"},"content":" ngOnInit(): void {"},{"lineNumber":132,"author":{"gitId":"-"},"content":" this.route.queryParams.subscribe((queryParams: any) \u003d\u003e {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" const courseId \u003d queryParams.courseid;"},{"lineNumber":134,"author":{"gitId":"-"},"content":" this.loadControlPanel();"},{"lineNumber":135,"author":{"gitId":"-"},"content":" this.loadCourse(courseId);"},{"lineNumber":136,"author":{"gitId":"-"},"content":" this.loadFeedbackSessions(courseId);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" this.loadStudents(courseId);"},{"lineNumber":138,"author":{"gitId":"-"},"content":" });"},{"lineNumber":139,"author":{"gitId":"-"},"content":" }"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":142,"author":{"gitId":"-"},"content":" * Loads the control panel based on the given course ID."},{"lineNumber":143,"author":{"gitId":"-"},"content":" */"},{"lineNumber":144,"author":{"gitId":"-"},"content":" loadControlPanel(): void {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" const today: Date \u003d new Date();"},{"lineNumber":146,"author":{"gitId":"-"},"content":" this.dateToday.year \u003d today.getFullYear();"},{"lineNumber":147,"author":{"gitId":"-"},"content":" this.dateToday.month \u003d today.getMonth() + 1;"},{"lineNumber":148,"author":{"gitId":"-"},"content":" this.dateToday.day \u003d today.getDate();"},{"lineNumber":149,"author":{"gitId":"-"},"content":""},{"lineNumber":150,"author":{"gitId":"-"},"content":" const earliestSearchDate: Date \u003d new Date(Date.now()"},{"lineNumber":151,"author":{"gitId":"-"},"content":" - this.LOGS_RETENTION_PERIOD * Milliseconds.IN_ONE_DAY);"},{"lineNumber":152,"author":{"gitId":"-"},"content":" this.earliestSearchDate.year \u003d earliestSearchDate.getFullYear();"},{"lineNumber":153,"author":{"gitId":"-"},"content":" this.earliestSearchDate.month \u003d earliestSearchDate.getMonth() + 1;"},{"lineNumber":154,"author":{"gitId":"-"},"content":" this.earliestSearchDate.day \u003d earliestSearchDate.getDate();"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" const fromDate: Date \u003d new Date();"},{"lineNumber":157,"author":{"gitId":"-"},"content":" fromDate.setDate(today.getDate() - 1);"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" this.formModel.logsDateFrom \u003d {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" year: fromDate.getFullYear(),"},{"lineNumber":161,"author":{"gitId":"-"},"content":" month: fromDate.getMonth() + 1,"},{"lineNumber":162,"author":{"gitId":"-"},"content":" day: fromDate.getDate(),"},{"lineNumber":163,"author":{"gitId":"-"},"content":" };"},{"lineNumber":164,"author":{"gitId":"-"},"content":" this.formModel.logsDateTo \u003d { ...this.dateToday };"},{"lineNumber":165,"author":{"gitId":"-"},"content":" this.formModel.logsTimeFrom \u003d getLatestTimeFormat();"},{"lineNumber":166,"author":{"gitId":"-"},"content":" this.formModel.logsTimeTo \u003d getLatestTimeFormat();"},{"lineNumber":167,"author":{"gitId":"-"},"content":" }"},{"lineNumber":168,"author":{"gitId":"-"},"content":""},{"lineNumber":169,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":170,"author":{"gitId":"-"},"content":" * Search for logs of student activity"},{"lineNumber":171,"author":{"gitId":"-"},"content":" */"},{"lineNumber":172,"author":{"gitId":"-"},"content":" search(): void {"},{"lineNumber":173,"author":{"gitId":"dishenggg"},"content":" if (this.formModel.logType \u003d\u003d\u003d \u0027\u0027) {"},{"lineNumber":174,"author":{"gitId":"dishenggg"},"content":" this.statusMessageService.showErrorToast(\u0027Please select an activity type\u0027);"},{"lineNumber":175,"author":{"gitId":"dishenggg"},"content":" return;"},{"lineNumber":176,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":177,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":178,"author":{"gitId":"dishenggg"},"content":" this.studentLogsMap \u003d new Map();"},{"lineNumber":179,"author":{"gitId":"-"},"content":" this.searchResults \u003d [];"},{"lineNumber":180,"author":{"gitId":"-"},"content":" this.isSearching \u003d true;"},{"lineNumber":181,"author":{"gitId":"-"},"content":""},{"lineNumber":182,"author":{"gitId":"-"},"content":" const timeZone: string \u003d this.course.timeZone;"},{"lineNumber":183,"author":{"gitId":"-"},"content":" const searchFrom: number \u003d this.timezoneService.resolveLocalDateTime("},{"lineNumber":184,"author":{"gitId":"-"},"content":" this.formModel.logsDateFrom, this.formModel.logsTimeFrom, timeZone, true);"},{"lineNumber":185,"author":{"gitId":"-"},"content":" const searchUntil: number \u003d this.timezoneService.resolveLocalDateTime("},{"lineNumber":186,"author":{"gitId":"-"},"content":" this.formModel.logsDateTo, this.formModel.logsTimeTo, timeZone, true);"},{"lineNumber":187,"author":{"gitId":"-"},"content":""},{"lineNumber":188,"author":{"gitId":"-"},"content":" this.logsService.searchFeedbackSessionLog({"},{"lineNumber":189,"author":{"gitId":"-"},"content":" courseId: this.course.courseId,"},{"lineNumber":190,"author":{"gitId":"-"},"content":" searchFrom: searchFrom.toString(),"},{"lineNumber":191,"author":{"gitId":"-"},"content":" searchUntil: searchUntil.toString(),"},{"lineNumber":192,"author":{"gitId":"dishenggg"},"content":" studentEmail: this.formModel.selectedStudent.studentEmail,"},{"lineNumber":193,"author":{"gitId":"-"},"content":" logType: this.formModel.logType,"},{"lineNumber":194,"author":{"gitId":"dishenggg"},"content":" sessionName: this.formModel.selectedSession.feedbackSessionName,"},{"lineNumber":195,"author":{"gitId":"dishenggg"},"content":" studentId: this.formModel.selectedStudent.studentId,"},{"lineNumber":196,"author":{"gitId":"dishenggg"},"content":" sessionId: this.formModel.selectedSession.sessionId,"},{"lineNumber":197,"author":{"gitId":"-"},"content":" }).pipe("},{"lineNumber":198,"author":{"gitId":"-"},"content":" finalize(() \u003d\u003e {"},{"lineNumber":199,"author":{"gitId":"-"},"content":" this.isSearching \u003d false;"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":201,"author":{"gitId":"-"},"content":" ).subscribe({"},{"lineNumber":202,"author":{"gitId":"-"},"content":" next: (logs: FeedbackSessionLogs) \u003d\u003e {"},{"lineNumber":203,"author":{"gitId":"dishenggg"},"content":" if (this.formModel.selectedSession.feedbackSessionName \u003d\u003d\u003d \u0027\u0027) {"},{"lineNumber":204,"author":{"gitId":"-"},"content":" logs.feedbackSessionLogs.forEach((log: FeedbackSessionLog) \u003d\u003e {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" log.feedbackSessionLogEntries.forEach((entry: FeedbackSessionLogEntry) \u003d\u003e {"},{"lineNumber":206,"author":{"gitId":"dishenggg"},"content":" const arr: FeedbackSessionLogEntry[] | undefined \u003d"},{"lineNumber":207,"author":{"gitId":"dishenggg"},"content":" this.studentLogsMap.get(this.getStudentKey(log, entry.studentData.email));"},{"lineNumber":208,"author":{"gitId":"dishenggg"},"content":" if (arr) {"},{"lineNumber":209,"author":{"gitId":"dishenggg"},"content":" arr.push(entry);"},{"lineNumber":210,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":211,"author":{"gitId":"dishenggg"},"content":" this.studentLogsMap.set(this.getStudentKey(log, entry.studentData.email), [entry]);"},{"lineNumber":212,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":213,"author":{"gitId":"-"},"content":" });"},{"lineNumber":214,"author":{"gitId":"-"},"content":" this.searchResults.push(this.toFeedbackSessionLogModel(log));"},{"lineNumber":215,"author":{"gitId":"-"},"content":" });"},{"lineNumber":216,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":217,"author":{"gitId":"-"},"content":" const targetFeedbackSessionLog \u003d logs.feedbackSessionLogs.find((log: FeedbackSessionLog) \u003d\u003e"},{"lineNumber":218,"author":{"gitId":"dishenggg"},"content":" log.feedbackSessionData.feedbackSessionName \u003d\u003d\u003d this.formModel.selectedSession.feedbackSessionName);"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" if (targetFeedbackSessionLog) {"},{"lineNumber":221,"author":{"gitId":"-"},"content":" targetFeedbackSessionLog.feedbackSessionLogEntries.forEach((entry: FeedbackSessionLogEntry) \u003d\u003e {"},{"lineNumber":222,"author":{"gitId":"dishenggg"},"content":" const arr: FeedbackSessionLogEntry[] | undefined \u003d"},{"lineNumber":223,"author":{"gitId":"dishenggg"},"content":" this.studentLogsMap.get(this.getStudentKey(targetFeedbackSessionLog, entry.studentData.email));"},{"lineNumber":224,"author":{"gitId":"dishenggg"},"content":" if (arr) {"},{"lineNumber":225,"author":{"gitId":"dishenggg"},"content":" arr.push(entry);"},{"lineNumber":226,"author":{"gitId":"dishenggg"},"content":" } else {"},{"lineNumber":227,"author":{"gitId":"dishenggg"},"content":" this.studentLogsMap.set("},{"lineNumber":228,"author":{"gitId":"dishenggg"},"content":" this.getStudentKey(targetFeedbackSessionLog, entry.studentData.email), [entry]);"},{"lineNumber":229,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":230,"author":{"gitId":"-"},"content":" });"},{"lineNumber":231,"author":{"gitId":"-"},"content":" this.searchResults.push(this.toFeedbackSessionLogModel(targetFeedbackSessionLog));"},{"lineNumber":232,"author":{"gitId":"-"},"content":" }"},{"lineNumber":233,"author":{"gitId":"-"},"content":" }"},{"lineNumber":234,"author":{"gitId":"-"},"content":" },"},{"lineNumber":235,"author":{"gitId":"-"},"content":" error: (e: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":236,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(e.error.message);"},{"lineNumber":237,"author":{"gitId":"-"},"content":" },"},{"lineNumber":238,"author":{"gitId":"-"},"content":" });"},{"lineNumber":239,"author":{"gitId":"-"},"content":" }"},{"lineNumber":240,"author":{"gitId":"-"},"content":""},{"lineNumber":241,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":242,"author":{"gitId":"-"},"content":" * Load the course based on the course id"},{"lineNumber":243,"author":{"gitId":"-"},"content":" */"},{"lineNumber":244,"author":{"gitId":"-"},"content":" private loadCourse(courseId: string): void {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" this.courseService"},{"lineNumber":246,"author":{"gitId":"-"},"content":" .getCourseAsInstructor(courseId)"},{"lineNumber":247,"author":{"gitId":"-"},"content":" .pipe(finalize(() \u003d\u003e {"},{"lineNumber":248,"author":{"gitId":"-"},"content":" this.isLoading \u003d false;"},{"lineNumber":249,"author":{"gitId":"-"},"content":" }))"},{"lineNumber":250,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":251,"author":{"gitId":"-"},"content":" next: (course: Course) \u003d\u003e {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" this.course \u003d course;"},{"lineNumber":253,"author":{"gitId":"dishenggg"},"content":" this.setLastUpdated();"},{"lineNumber":254,"author":{"gitId":"-"},"content":" },"},{"lineNumber":255,"author":{"gitId":"-"},"content":" error: (e: ErrorMessageOutput) \u003d\u003e this.statusMessageService.showErrorToast(e.error.message),"},{"lineNumber":256,"author":{"gitId":"-"},"content":" });"},{"lineNumber":257,"author":{"gitId":"-"},"content":" }"},{"lineNumber":258,"author":{"gitId":"-"},"content":""},{"lineNumber":259,"author":{"gitId":"-"},"content":" private loadFeedbackSessions(courseId: string): void {"},{"lineNumber":260,"author":{"gitId":"-"},"content":" this.feedbackSessionsService"},{"lineNumber":261,"author":{"gitId":"-"},"content":" .getFeedbackSessionsForInstructor(courseId)"},{"lineNumber":262,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":263,"author":{"gitId":"-"},"content":" next: (feedbackSessions: FeedbackSessions) \u003d\u003e {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" feedbackSessions.feedbackSessions.forEach((fs: FeedbackSession) \u003d\u003e {"},{"lineNumber":265,"author":{"gitId":"-"},"content":" this.feedbackSessions.set(fs.feedbackSessionName, fs);"},{"lineNumber":266,"author":{"gitId":"-"},"content":" });"},{"lineNumber":267,"author":{"gitId":"-"},"content":" },"},{"lineNumber":268,"author":{"gitId":"-"},"content":" error: (e: ErrorMessageOutput) \u003d\u003e this.statusMessageService.showErrorToast(e.error.message),"},{"lineNumber":269,"author":{"gitId":"-"},"content":" });"},{"lineNumber":270,"author":{"gitId":"-"},"content":" }"},{"lineNumber":271,"author":{"gitId":"-"},"content":""},{"lineNumber":272,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":273,"author":{"gitId":"-"},"content":" * Load all students for the selected course"},{"lineNumber":274,"author":{"gitId":"-"},"content":" */"},{"lineNumber":275,"author":{"gitId":"-"},"content":" loadStudents(courseId: string): void {"},{"lineNumber":276,"author":{"gitId":"-"},"content":" if (this.students.length \u003d\u003d\u003d 0) {"},{"lineNumber":277,"author":{"gitId":"-"},"content":" this.isLoading \u003d true;"},{"lineNumber":278,"author":{"gitId":"-"},"content":" this.studentService.getStudentsFromCourse({ courseId })"},{"lineNumber":279,"author":{"gitId":"-"},"content":" .pipe(finalize(() \u003d\u003e { this.isLoading \u003d false; }))"},{"lineNumber":280,"author":{"gitId":"-"},"content":" .subscribe(({ students }: { students: Student[] }) \u003d\u003e {"},{"lineNumber":281,"author":{"gitId":"-"},"content":" const emptyStudent: Student \u003d {"},{"lineNumber":282,"author":{"gitId":"-"},"content":" courseId: \u0027\u0027, email: \u0027\u0027, name: \u0027\u0027, sectionName: \u0027\u0027, teamName: \u0027\u0027,"},{"lineNumber":283,"author":{"gitId":"-"},"content":" };"},{"lineNumber":284,"author":{"gitId":"-"},"content":" students.sort((a: Student, b: Student): number \u003d\u003e a.name.localeCompare(b.name));"},{"lineNumber":285,"author":{"gitId":"-"},"content":""},{"lineNumber":286,"author":{"gitId":"-"},"content":" // Student with no name is selectable to search for all students since the field is optional"},{"lineNumber":287,"author":{"gitId":"-"},"content":" this.students \u003d [emptyStudent, ...students];"},{"lineNumber":288,"author":{"gitId":"-"},"content":" });"},{"lineNumber":289,"author":{"gitId":"-"},"content":" }"},{"lineNumber":290,"author":{"gitId":"-"},"content":" }"},{"lineNumber":291,"author":{"gitId":"-"},"content":""},{"lineNumber":292,"author":{"gitId":"-"},"content":" private toFeedbackSessionLogModel(log: FeedbackSessionLog): FeedbackSessionLogModel {"},{"lineNumber":293,"author":{"gitId":"-"},"content":" const fsName \u003d log.feedbackSessionData.feedbackSessionName;"},{"lineNumber":294,"author":{"gitId":"-"},"content":""},{"lineNumber":295,"author":{"gitId":"-"},"content":" return {"},{"lineNumber":296,"author":{"gitId":"-"},"content":" feedbackSessionName: fsName,"},{"lineNumber":297,"author":{"gitId":"-"},"content":" logColumnsData: ["},{"lineNumber":298,"author":{"gitId":"-"},"content":" { header: \u0027Status\u0027, sortBy: SortBy.RESULT_VIEW_STATUS },"},{"lineNumber":299,"author":{"gitId":"-"},"content":" { header: \u0027Name\u0027, sortBy: SortBy.GIVER_NAME },"},{"lineNumber":300,"author":{"gitId":"-"},"content":" { header: \u0027Email\u0027, sortBy: SortBy.RESPONDENT_EMAIL },"},{"lineNumber":301,"author":{"gitId":"-"},"content":" { header: \u0027Section\u0027, sortBy: SortBy.SECTION_NAME },"},{"lineNumber":302,"author":{"gitId":"-"},"content":" { header: \u0027Team\u0027, sortBy: SortBy.TEAM_NAME },"},{"lineNumber":303,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":304,"author":{"gitId":"-"},"content":" logRowsData: this.students"},{"lineNumber":305,"author":{"gitId":"-"},"content":" .filter((student: Student) \u003d\u003e {"},{"lineNumber":306,"author":{"gitId":"-"},"content":" if (student.email \u003d\u003d\u003d \u0027\u0027) {"},{"lineNumber":307,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":308,"author":{"gitId":"-"},"content":" }"},{"lineNumber":309,"author":{"gitId":"-"},"content":""},{"lineNumber":310,"author":{"gitId":"dishenggg"},"content":" if ("},{"lineNumber":311,"author":{"gitId":"dishenggg"},"content":" this.formModel.selectedStudent.studentEmail !\u003d\u003d \u0027\u0027"},{"lineNumber":312,"author":{"gitId":"dishenggg"},"content":" \u0026\u0026 student.email !\u003d\u003d this.formModel.selectedStudent.studentEmail"},{"lineNumber":313,"author":{"gitId":"dishenggg"},"content":" ) {"},{"lineNumber":314,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":315,"author":{"gitId":"-"},"content":" }"},{"lineNumber":316,"author":{"gitId":"-"},"content":""},{"lineNumber":317,"author":{"gitId":"-"},"content":" if (this.formModel.showInactions \u0026\u0026 this.formModel.showActions) {"},{"lineNumber":318,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":319,"author":{"gitId":"-"},"content":" }"},{"lineNumber":320,"author":{"gitId":"-"},"content":""},{"lineNumber":321,"author":{"gitId":"-"},"content":" const studentKey \u003d this.getStudentKey(log, student.email);"},{"lineNumber":322,"author":{"gitId":"-"},"content":""},{"lineNumber":323,"author":{"gitId":"dishenggg"},"content":" if (this.studentLogsMap.has(studentKey)) {"},{"lineNumber":324,"author":{"gitId":"-"},"content":" if (this.formModel.showInactions) {"},{"lineNumber":325,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":326,"author":{"gitId":"-"},"content":" }"},{"lineNumber":327,"author":{"gitId":"-"},"content":" } else if (this.formModel.showActions) {"},{"lineNumber":328,"author":{"gitId":"-"},"content":" return false;"},{"lineNumber":329,"author":{"gitId":"-"},"content":" }"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" return true;"},{"lineNumber":332,"author":{"gitId":"-"},"content":" })"},{"lineNumber":333,"author":{"gitId":"dishenggg"},"content":" .flatMap((student: Student) \u003d\u003e {"},{"lineNumber":334,"author":{"gitId":"-"},"content":" let status: string;"},{"lineNumber":335,"author":{"gitId":"-"},"content":" let dataStyle: string \u003d \u0027font-family:monospace; white-space:pre;\u0027;"},{"lineNumber":336,"author":{"gitId":"-"},"content":" const studentKey \u003d this.getStudentKey(log, student.email);"},{"lineNumber":337,"author":{"gitId":"-"},"content":""},{"lineNumber":338,"author":{"gitId":"dishenggg"},"content":" const entries: FeedbackSessionLogEntry[] | undefined \u003d this.studentLogsMap.get(studentKey);"},{"lineNumber":339,"author":{"gitId":"dishenggg"},"content":" const rows: any[] \u003d [];"},{"lineNumber":340,"author":{"gitId":"dishenggg"},"content":" if (entries) {"},{"lineNumber":341,"author":{"gitId":"dishenggg"},"content":" entries.forEach((entry: FeedbackSessionLogEntry) \u003d\u003e {"},{"lineNumber":342,"author":{"gitId":"-"},"content":" const timestamp: string \u003d this.timezoneService.formatToString("},{"lineNumber":343,"author":{"gitId":"-"},"content":" entry.timestamp, log.feedbackSessionData.timeZone, this.LOGS_DATE_TIME_FORMAT);"},{"lineNumber":344,"author":{"gitId":"dishenggg"},"content":" status \u003d `${this.logTypeToActivityDisplay(entry.feedbackSessionLogType)} at ${timestamp}`;"},{"lineNumber":345,"author":{"gitId":"dishenggg"},"content":" status \u003d status.charAt(0).toUpperCase() + status.slice(1);"},{"lineNumber":346,"author":{"gitId":"dishenggg"},"content":" rows.push([{"},{"lineNumber":347,"author":{"gitId":"dishenggg"},"content":" value: status,"},{"lineNumber":348,"author":{"gitId":"dishenggg"},"content":" style: dataStyle,"},{"lineNumber":349,"author":{"gitId":"dishenggg"},"content":" },"},{"lineNumber":350,"author":{"gitId":"dishenggg"},"content":" { value: student.name },"},{"lineNumber":351,"author":{"gitId":"dishenggg"},"content":" { value: student.email },"},{"lineNumber":352,"author":{"gitId":"dishenggg"},"content":" { value: student.sectionName },"},{"lineNumber":353,"author":{"gitId":"dishenggg"},"content":" { value: student.teamName }]);"},{"lineNumber":354,"author":{"gitId":"dishenggg"},"content":" });"},{"lineNumber":355,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":356,"author":{"gitId":"dishenggg"},"content":" status \u003d `Not ${this.logTypeToActivityDisplay(this.formModel.logType)} within the query range`;"},{"lineNumber":357,"author":{"gitId":"-"},"content":" dataStyle +\u003d \u0027color:red;\u0027;"},{"lineNumber":358,"author":{"gitId":"dishenggg"},"content":" rows.push(["},{"lineNumber":359,"author":{"gitId":"-"},"content":" {"},{"lineNumber":360,"author":{"gitId":"-"},"content":" value: status,"},{"lineNumber":361,"author":{"gitId":"-"},"content":" style: dataStyle,"},{"lineNumber":362,"author":{"gitId":"-"},"content":" },"},{"lineNumber":363,"author":{"gitId":"-"},"content":" { value: student.name },"},{"lineNumber":364,"author":{"gitId":"-"},"content":" { value: student.email },"},{"lineNumber":365,"author":{"gitId":"-"},"content":" { value: student.sectionName },"},{"lineNumber":366,"author":{"gitId":"-"},"content":" { value: student.teamName },"},{"lineNumber":367,"author":{"gitId":"dishenggg"},"content":" ]);"},{"lineNumber":368,"author":{"gitId":"-"},"content":" }"},{"lineNumber":369,"author":{"gitId":"dishenggg"},"content":" return rows;"},{"lineNumber":370,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":371,"author":{"gitId":"-"},"content":" isTabExpanded: (log.feedbackSessionLogEntries.length !\u003d\u003d 0 \u0026\u0026 this.formModel.showActions)"},{"lineNumber":372,"author":{"gitId":"-"},"content":" || (log.feedbackSessionLogEntries.length \u003d\u003d\u003d 0 \u0026\u0026 this.formModel.showInactions),"},{"lineNumber":373,"author":{"gitId":"-"},"content":" };"},{"lineNumber":374,"author":{"gitId":"-"},"content":" }"},{"lineNumber":375,"author":{"gitId":"-"},"content":""},{"lineNumber":376,"author":{"gitId":"-"},"content":" private logTypeToActivityDisplay(logType: string): string {"},{"lineNumber":377,"author":{"gitId":"-"},"content":" switch (logType.toUpperCase()) {"},{"lineNumber":378,"author":{"gitId":"-"},"content":" case \u0027ACCESS\u0027:"},{"lineNumber":379,"author":{"gitId":"dishenggg"},"content":" return \u0027viewed the submission page\u0027;"},{"lineNumber":380,"author":{"gitId":"-"},"content":" case \u0027SUBMISSION\u0027:"},{"lineNumber":381,"author":{"gitId":"dishenggg"},"content":" return \u0027submitted responses\u0027;"},{"lineNumber":382,"author":{"gitId":"dishenggg"},"content":" case \u0027VIEW_RESULT\u0027:"},{"lineNumber":383,"author":{"gitId":"-"},"content":" case \u0027VIEW RESULT\u0027:"},{"lineNumber":384,"author":{"gitId":"dishenggg"},"content":" return \u0027viewed the session results\u0027;"},{"lineNumber":385,"author":{"gitId":"-"},"content":" case \u0027ACCESS,SUBMISSION\u0027:"},{"lineNumber":386,"author":{"gitId":"dishenggg"},"content":" return \u0027viewed the submission page or submitted responses\u0027;"},{"lineNumber":387,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":388,"author":{"gitId":"dishenggg"},"content":" return \u0027unknown activity\u0027;"},{"lineNumber":389,"author":{"gitId":"-"},"content":" }"},{"lineNumber":390,"author":{"gitId":"-"},"content":" }"},{"lineNumber":391,"author":{"gitId":"-"},"content":""},{"lineNumber":392,"author":{"gitId":"-"},"content":" private getStudentKey(log: FeedbackSessionLog, studentEmail: string): string {"},{"lineNumber":393,"author":{"gitId":"-"},"content":" return `${log.feedbackSessionData.feedbackSessionName}-${studentEmail}`;"},{"lineNumber":394,"author":{"gitId":"-"},"content":" }"},{"lineNumber":395,"author":{"gitId":"-"},"content":""},{"lineNumber":396,"author":{"gitId":"-"},"content":" triggerDefaultLogActivityTypeChange(logType: string): void {"},{"lineNumber":397,"author":{"gitId":"-"},"content":" if (logType \u003d\u003d\u003d \u0027view result\u0027) {"},{"lineNumber":398,"author":{"gitId":"-"},"content":" this.formModel.showInactions \u003d true;"},{"lineNumber":399,"author":{"gitId":"-"},"content":" this.formModel.showActions \u003d false;"},{"lineNumber":400,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":401,"author":{"gitId":"-"},"content":" this.formModel.showInactions \u003d false;"},{"lineNumber":402,"author":{"gitId":"-"},"content":" this.formModel.showActions \u003d true;"},{"lineNumber":403,"author":{"gitId":"-"},"content":" }"},{"lineNumber":404,"author":{"gitId":"-"},"content":" }"},{"lineNumber":405,"author":{"gitId":"-"},"content":""},{"lineNumber":406,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":407,"author":{"gitId":"-"},"content":" * Triggers the change of the model for the form."},{"lineNumber":408,"author":{"gitId":"-"},"content":" */"},{"lineNumber":409,"author":{"gitId":"-"},"content":" triggerModelChange(field: string, data: any): void {"},{"lineNumber":410,"author":{"gitId":"-"},"content":" this.formModel \u003d {"},{"lineNumber":411,"author":{"gitId":"-"},"content":" ...this.formModel,"},{"lineNumber":412,"author":{"gitId":"-"},"content":" [field]: data,"},{"lineNumber":413,"author":{"gitId":"-"},"content":" };"},{"lineNumber":414,"author":{"gitId":"-"},"content":" }"},{"lineNumber":415,"author":{"gitId":"-"},"content":""},{"lineNumber":416,"author":{"gitId":"dishenggg"},"content":" private setLastUpdated(): void {"},{"lineNumber":417,"author":{"gitId":"dishenggg"},"content":" // 15 mins buffer to allow cron job to finish adding all logs to the database"},{"lineNumber":418,"author":{"gitId":"dishenggg"},"content":" const CRON_JOB_BUFFER \u003d 15;"},{"lineNumber":419,"author":{"gitId":"dishenggg"},"content":" const now: Date \u003d new Date();"},{"lineNumber":420,"author":{"gitId":"dishenggg"},"content":" const minsPastQuarter \u003d now.getMinutes() % 15;"},{"lineNumber":421,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":422,"author":{"gitId":"dishenggg"},"content":" const lastUpdated \u003d now.getTime() - ((CRON_JOB_BUFFER + minsPastQuarter) * Milliseconds.IN_ONE_MINUTE);"},{"lineNumber":423,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":424,"author":{"gitId":"dishenggg"},"content":" this.lastUpdated \u003d this.timezoneService.formatToString(lastUpdated, this.course.timeZone, \u0027DD MMM YYYY, hh:mm A\u0027);"},{"lineNumber":425,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":426,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":86,"-":340}},{"path":"src/web/app/pages-instructor/instructor-student-records-page/instructor-student-records-page.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003ch1 id\u003d\"records-header\"\u003e{{studentName}}\u0027s Records\u003csmall class\u003d\"text-muted text-break\"\u003e - {{courseId}}\u003c/small\u003e\u003c/h1\u003e"},{"lineNumber":2,"author":{"gitId":"-"},"content":"\u003ch2\u003eRecords in feedback sessions\u003c/h2\u003e"},{"lineNumber":3,"author":{"gitId":"-"},"content":"\u003ctm-loading-retry [shouldShowRetry]\u003d\"hasStudentResultsLoadingFailed\" [message]\u003d\"\u0027Failed to load student results\u0027\" (retryEvent)\u003d\"loadStudentResults()\"\u003e"},{"lineNumber":4,"author":{"gitId":"-"},"content":" \u003cdiv *tmIsLoading\u003d\"isStudentResultsLoading\"\u003e"},{"lineNumber":5,"author":{"gitId":"-"},"content":" \u003cdiv *ngFor\u003d\"let session of sessionTabs\" class\u003d\"card card-default mb-4\"\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header cursor-pointer\" (click)\u003d\"session.isCollapsed \u003d !session.isCollapsed\"\u003e"},{"lineNumber":7,"author":{"gitId":"-"},"content":" \u003cstrong class\u003d\"text-break\"\u003eFeedback Session: {{ session.feedbackSession.feedbackSessionName }}\u003c/strong\u003e"},{"lineNumber":8,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-header-btn-toolbar\"\u003e"},{"lineNumber":9,"author":{"gitId":"Tim-Siu"},"content":" \u003ctm-panel-chevron [isExpanded]\u003d\"!session.isCollapsed\" chevronColor\u003d\"black\"\u003e\u003c/tm-panel-chevron\u003e"},{"lineNumber":10,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":11,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":12,"author":{"gitId":"-"},"content":" \u003cdiv class\u003d\"card-body\" *ngIf\u003d\"!session.isCollapsed\" @collapseAnim\u003e"},{"lineNumber":13,"author":{"gitId":"-"},"content":" \u003ctm-grq-rgq-view-responses *ngIf\u003d\"session.responsesReceivedByStudent.length \u003e 0\""},{"lineNumber":14,"author":{"gitId":"-"},"content":" [session]\u003d\"session.feedbackSession\""},{"lineNumber":15,"author":{"gitId":"-"},"content":" [responses]\u003d\"session.responsesReceivedByStudent\" [groupByTeam]\u003d\"false\" [section]\u003d\"\" [sectionType]\u003d\"\""},{"lineNumber":16,"author":{"gitId":"-"},"content":" [isGrq]\u003d\"false\" [instructorCommentTableModel]\u003d\"instructorCommentTableModel\""},{"lineNumber":17,"author":{"gitId":"-"},"content":" (saveNewCommentEvent)\u003d\"saveNewComment($event, session.feedbackSession.timeZone)\""},{"lineNumber":18,"author":{"gitId":"-"},"content":" (deleteCommentEvent)\u003d\"deleteComment($event)\""},{"lineNumber":19,"author":{"gitId":"-"},"content":" (updateCommentEvent)\u003d\"updateComment($event, session.feedbackSession.timeZone)\""},{"lineNumber":20,"author":{"gitId":"-"},"content":" [isExpandAll]\u003d\"true\"\u003e"},{"lineNumber":21,"author":{"gitId":"-"},"content":" \u003c/tm-grq-rgq-view-responses\u003e"},{"lineNumber":22,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"session.responsesReceivedByStudent.length \u003d\u003d\u003d 0\" class\u003d\"mb-3\"\u003e"},{"lineNumber":23,"author":{"gitId":"-"},"content":" No feedback responses for {{studentName}} ({{studentTeam}}) found."},{"lineNumber":24,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":25,"author":{"gitId":"-"},"content":" \u003ctm-grq-rgq-view-responses *ngIf\u003d\"session.responsesGivenByStudent.length \u003e 0\""},{"lineNumber":26,"author":{"gitId":"-"},"content":" [session]\u003d\"session.feedbackSession\""},{"lineNumber":27,"author":{"gitId":"-"},"content":" [responses]\u003d\"session.responsesGivenByStudent\" [groupByTeam]\u003d\"false\" [section]\u003d\"\" [sectionType]\u003d\"\""},{"lineNumber":28,"author":{"gitId":"-"},"content":" [isGrq]\u003d\"true\" [instructorCommentTableModel]\u003d\"instructorCommentTableModel\""},{"lineNumber":29,"author":{"gitId":"-"},"content":" (saveNewCommentEvent)\u003d\"saveNewComment($event, session.feedbackSession.timeZone)\""},{"lineNumber":30,"author":{"gitId":"-"},"content":" (deleteCommentEvent)\u003d\"deleteComment($event)\""},{"lineNumber":31,"author":{"gitId":"-"},"content":" (updateCommentEvent)\u003d\"updateComment($event, session.feedbackSession.timeZone)\""},{"lineNumber":32,"author":{"gitId":"-"},"content":" [isExpandAll]\u003d\"true\""},{"lineNumber":33,"author":{"gitId":"-"},"content":" \u003e\u003c/tm-grq-rgq-view-responses\u003e"},{"lineNumber":34,"author":{"gitId":"-"},"content":" \u003cdiv *ngIf\u003d\"session.responsesGivenByStudent.length \u003d\u003d\u003d 0\"\u003e"},{"lineNumber":35,"author":{"gitId":"-"},"content":" No feedback responses from {{studentName}} ({{studentTeam}}) found."},{"lineNumber":36,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":37,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":38,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":39,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":40,"author":{"gitId":"-"},"content":"\u003c/tm-loading-retry\u003e"}],"authorContributionMap":{"-":39,"Tim-Siu":1}},{"path":"src/web/app/pages-session/session-result-page/session-result-page.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { HttpClientTestingModule } from \u0027@angular/common/http/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { ComponentFixture, TestBed, waitForAsync } from \u0027@angular/core/testing\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { ActivatedRoute } from \u0027@angular/router\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { RouterTestingModule } from \u0027@angular/router/testing\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { of, throwError } from \u0027rxjs\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import SpyInstance \u003d jest.SpyInstance;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { FeedbackQuestionModel, SessionResultPageComponent } from \u0027./session-result-page.component\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { environment } from \u0027../../../environments/environment\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { AuthService } from \u0027../../../services/auth.service\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { FeedbackQuestionsService } from \u0027../../../services/feedback-questions.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { FeedbackSessionsService } from \u0027../../../services/feedback-sessions.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { LogService } from \u0027../../../services/log.service\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { NavigationService } from \u0027../../../services/navigation.service\u0027;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import { StudentService } from \u0027../../../services/student.service\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":16,"author":{"gitId":"-"},"content":" AuthInfo,"},{"lineNumber":17,"author":{"gitId":"-"},"content":" FeedbackMcqQuestionDetails,"},{"lineNumber":18,"author":{"gitId":"-"},"content":" FeedbackParticipantType,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" FeedbackQuestion,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" FeedbackQuestions,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" FeedbackQuestionType,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" FeedbackSession,"},{"lineNumber":23,"author":{"gitId":"-"},"content":" FeedbackSessionPublishStatus,"},{"lineNumber":24,"author":{"gitId":"-"},"content":" FeedbackSessionSubmissionStatus,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" NumberOfEntitiesToGiveFeedbackToSetting,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" RegkeyValidity,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" ResponseVisibleSetting,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" SessionVisibleSetting,"},{"lineNumber":29,"author":{"gitId":"-"},"content":"} from \u0027../../../types/api-output\u0027;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import { Intent } from \u0027../../../types/api-request\u0027;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import { LoadingRetryModule } from \u0027../../components/loading-retry/loading-retry.module\u0027;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import { LoadingSpinnerModule } from \u0027../../components/loading-spinner/loading-spinner.module\u0027;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import { QuestionResponsePanelModule } from \u0027../../components/question-response-panel/question-response-panel.module\u0027;"},{"lineNumber":34,"author":{"gitId":"-"},"content":"import { SingleStatisticsModule } from \u0027../../components/question-responses/single-statistics/single-statistics.module\u0027;"},{"lineNumber":35,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" StudentViewResponsesModule,"},{"lineNumber":37,"author":{"gitId":"-"},"content":"} from \u0027../../components/question-responses/student-view-responses/student-view-responses.module\u0027;"},{"lineNumber":38,"author":{"gitId":"-"},"content":"import { QuestionTextWithInfoModule } from \u0027../../components/question-text-with-info/question-text-with-info.module\u0027;"},{"lineNumber":39,"author":{"gitId":"-"},"content":""},{"lineNumber":40,"author":{"gitId":"-"},"content":"describe(\u0027SessionResultPageComponent\u0027, () \u003d\u003e {"},{"lineNumber":41,"author":{"gitId":"-"},"content":" const testFeedbackSession: FeedbackSession \u003d {"},{"lineNumber":42,"author":{"gitId":"-"},"content":" feedbackSessionName: \u0027First Session\u0027,"},{"lineNumber":43,"author":{"gitId":"-"},"content":" courseId: \u0027CS1231\u0027,"},{"lineNumber":44,"author":{"gitId":"-"},"content":" timeZone: \u0027Asia/Singapore\u0027,"},{"lineNumber":45,"author":{"gitId":"-"},"content":" instructions: \u0027\u0027,"},{"lineNumber":46,"author":{"gitId":"-"},"content":" submissionStartTimestamp: 0,"},{"lineNumber":47,"author":{"gitId":"-"},"content":" submissionEndTimestamp: 1549095330000,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" gracePeriod: 0,"},{"lineNumber":49,"author":{"gitId":"-"},"content":" sessionVisibleSetting: SessionVisibleSetting.AT_OPEN,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" responseVisibleSetting: ResponseVisibleSetting.AT_VISIBLE,"},{"lineNumber":51,"author":{"gitId":"-"},"content":" submissionStatus: FeedbackSessionSubmissionStatus.OPEN,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" publishStatus: FeedbackSessionPublishStatus.PUBLISHED,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" isClosingEmailEnabled: true,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" isPublishedEmailEnabled: true,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" createdAtTimestamp: 0,"},{"lineNumber":56,"author":{"gitId":"-"},"content":" studentDeadlines: {},"},{"lineNumber":57,"author":{"gitId":"-"},"content":" instructorDeadlines: {},"},{"lineNumber":58,"author":{"gitId":"-"},"content":" };"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" const testInfo: AuthInfo \u003d {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" masquerade: false,"},{"lineNumber":62,"author":{"gitId":"-"},"content":" user: {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" id: \u0027user-id\u0027,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" isAdmin: false,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" isInstructor: true,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" isStudent: false,"},{"lineNumber":67,"author":{"gitId":"-"},"content":" isMaintainer: false,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" },"},{"lineNumber":69,"author":{"gitId":"-"},"content":" };"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" const testFeedbackQuestion: FeedbackQuestion \u003d {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" feedbackQuestionId: \u0027feedbackQuestion1\u0027,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" questionNumber: 1,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" questionBrief: \u0027How well did team member perform?\u0027,"},{"lineNumber":75,"author":{"gitId":"-"},"content":" questionDescription: \u0027\u0027,"},{"lineNumber":76,"author":{"gitId":"-"},"content":" questionDetails: {"},{"lineNumber":77,"author":{"gitId":"-"},"content":" hasAssignedWeights: false,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" mcqWeights: [],"},{"lineNumber":79,"author":{"gitId":"-"},"content":" mcqOtherWeight: 0,"},{"lineNumber":80,"author":{"gitId":"-"},"content":" mcqChoices: ["},{"lineNumber":81,"author":{"gitId":"-"},"content":" \u0027\u003cp\u003eGood\u003c/p\u003e\u0027,"},{"lineNumber":82,"author":{"gitId":"-"},"content":" \u0027\u003cp\u003eNormal\u003c/p\u003e\u0027,"},{"lineNumber":83,"author":{"gitId":"-"},"content":" \u0027\u003cp\u003eBad\u003c/p\u003e\u0027,"},{"lineNumber":84,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":85,"author":{"gitId":"-"},"content":" otherEnabled: false,"},{"lineNumber":86,"author":{"gitId":"-"},"content":" questionDropdownEnabled: false,"},{"lineNumber":87,"author":{"gitId":"-"},"content":" generateOptionsFor: \u0027NONE\u0027,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" questionType: FeedbackQuestionType.MCQ,"},{"lineNumber":89,"author":{"gitId":"-"},"content":" questionText: \u0027How well did team member perform?\u0027,"},{"lineNumber":90,"author":{"gitId":"-"},"content":" } as FeedbackMcqQuestionDetails,"},{"lineNumber":91,"author":{"gitId":"-"},"content":" questionType: FeedbackQuestionType.MCQ,"},{"lineNumber":92,"author":{"gitId":"-"},"content":" giverType: FeedbackParticipantType.STUDENTS,"},{"lineNumber":93,"author":{"gitId":"-"},"content":" recipientType: FeedbackParticipantType.OWN_TEAM_MEMBERS_INCLUDING_SELF,"},{"lineNumber":94,"author":{"gitId":"-"},"content":" numberOfEntitiesToGiveFeedbackToSetting: NumberOfEntitiesToGiveFeedbackToSetting.UNLIMITED,"},{"lineNumber":95,"author":{"gitId":"-"},"content":" showResponsesTo: [],"},{"lineNumber":96,"author":{"gitId":"-"},"content":" showGiverNameTo: [],"},{"lineNumber":97,"author":{"gitId":"-"},"content":" showRecipientNameTo: [],"},{"lineNumber":98,"author":{"gitId":"-"},"content":" customNumberOfEntitiesToGiveFeedbackTo: 0,"},{"lineNumber":99,"author":{"gitId":"-"},"content":" };"},{"lineNumber":100,"author":{"gitId":"-"},"content":""},{"lineNumber":101,"author":{"gitId":"-"},"content":" let component: SessionResultPageComponent;"},{"lineNumber":102,"author":{"gitId":"-"},"content":" let fixture: ComponentFixture\u003cSessionResultPageComponent\u003e;"},{"lineNumber":103,"author":{"gitId":"-"},"content":" let authService: AuthService;"},{"lineNumber":104,"author":{"gitId":"-"},"content":" let navService: NavigationService;"},{"lineNumber":105,"author":{"gitId":"-"},"content":" let studentService: StudentService;"},{"lineNumber":106,"author":{"gitId":"-"},"content":" let feedbackQuestionsService: FeedbackQuestionsService;"},{"lineNumber":107,"author":{"gitId":"-"},"content":" let feedbackSessionService: FeedbackSessionsService;"},{"lineNumber":108,"author":{"gitId":"-"},"content":" let logService: LogService;"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" const testQueryParams: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" courseid: \u0027CS3281\u0027,"},{"lineNumber":112,"author":{"gitId":"-"},"content":" fsname: \u0027Peer Feedback\u0027,"},{"lineNumber":113,"author":{"gitId":"-"},"content":" key: \u0027reg-key\u0027,"},{"lineNumber":114,"author":{"gitId":"-"},"content":" previewas: \u0027\u0027,"},{"lineNumber":115,"author":{"gitId":"-"},"content":" };"},{"lineNumber":116,"author":{"gitId":"-"},"content":""},{"lineNumber":117,"author":{"gitId":"-"},"content":" beforeEach(waitForAsync(() \u003d\u003e {"},{"lineNumber":118,"author":{"gitId":"-"},"content":" TestBed.configureTestingModule({"},{"lineNumber":119,"author":{"gitId":"-"},"content":" imports: ["},{"lineNumber":120,"author":{"gitId":"-"},"content":" HttpClientTestingModule,"},{"lineNumber":121,"author":{"gitId":"-"},"content":" RouterTestingModule,"},{"lineNumber":122,"author":{"gitId":"-"},"content":" StudentViewResponsesModule,"},{"lineNumber":123,"author":{"gitId":"-"},"content":" QuestionTextWithInfoModule,"},{"lineNumber":124,"author":{"gitId":"-"},"content":" QuestionResponsePanelModule,"},{"lineNumber":125,"author":{"gitId":"-"},"content":" SingleStatisticsModule,"},{"lineNumber":126,"author":{"gitId":"-"},"content":" LoadingSpinnerModule,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" LoadingRetryModule,"},{"lineNumber":128,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":129,"author":{"gitId":"-"},"content":" declarations: [SessionResultPageComponent],"},{"lineNumber":130,"author":{"gitId":"-"},"content":" providers: ["},{"lineNumber":131,"author":{"gitId":"-"},"content":" AuthService,"},{"lineNumber":132,"author":{"gitId":"-"},"content":" NavigationService,"},{"lineNumber":133,"author":{"gitId":"-"},"content":" StudentService,"},{"lineNumber":134,"author":{"gitId":"-"},"content":" FeedbackSessionsService,"},{"lineNumber":135,"author":{"gitId":"-"},"content":" LogService,"},{"lineNumber":136,"author":{"gitId":"-"},"content":" {"},{"lineNumber":137,"author":{"gitId":"-"},"content":" provide: ActivatedRoute,"},{"lineNumber":138,"author":{"gitId":"-"},"content":" useValue: {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" queryParams: of(testQueryParams),"},{"lineNumber":140,"author":{"gitId":"-"},"content":" data: {"},{"lineNumber":141,"author":{"gitId":"-"},"content":" intent: Intent.STUDENT_RESULT,"},{"lineNumber":142,"author":{"gitId":"-"},"content":" pipe: () \u003d\u003e {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" return {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" subscribe: (fn: (value: any) \u003d\u003e void) \u003d\u003e fn(testQueryParams),"},{"lineNumber":145,"author":{"gitId":"-"},"content":" };"},{"lineNumber":146,"author":{"gitId":"-"},"content":" },"},{"lineNumber":147,"author":{"gitId":"-"},"content":" },"},{"lineNumber":148,"author":{"gitId":"-"},"content":" },"},{"lineNumber":149,"author":{"gitId":"-"},"content":" },"},{"lineNumber":150,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":151,"author":{"gitId":"-"},"content":" })"},{"lineNumber":152,"author":{"gitId":"-"},"content":" .compileComponents();"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" fixture \u003d TestBed.createComponent(SessionResultPageComponent);"},{"lineNumber":157,"author":{"gitId":"-"},"content":" authService \u003d TestBed.inject(AuthService);"},{"lineNumber":158,"author":{"gitId":"-"},"content":" navService \u003d TestBed.inject(NavigationService);"},{"lineNumber":159,"author":{"gitId":"-"},"content":" studentService \u003d TestBed.inject(StudentService);"},{"lineNumber":160,"author":{"gitId":"-"},"content":" feedbackQuestionsService \u003d TestBed.inject(FeedbackQuestionsService);"},{"lineNumber":161,"author":{"gitId":"-"},"content":" feedbackSessionService \u003d TestBed.inject(FeedbackSessionsService);"},{"lineNumber":162,"author":{"gitId":"-"},"content":" logService \u003d TestBed.inject(LogService);"},{"lineNumber":163,"author":{"gitId":"-"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":164,"author":{"gitId":"-"},"content":" // Set both loading flags to false initially for testing purposes only"},{"lineNumber":165,"author":{"gitId":"-"},"content":" component.isCourseLoading \u003d false;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" component.isFeedbackSessionDetailsLoading \u003d false;"},{"lineNumber":167,"author":{"gitId":"-"},"content":" component.isFeedbackSessionResultsLoading \u003d false;"},{"lineNumber":168,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":169,"author":{"gitId":"-"},"content":" });"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" expect(component).toBeTruthy();"},{"lineNumber":173,"author":{"gitId":"-"},"content":" });"},{"lineNumber":174,"author":{"gitId":"-"},"content":""},{"lineNumber":175,"author":{"gitId":"-"},"content":" it(\u0027should snap with default fields\u0027, () \u003d\u003e {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":177,"author":{"gitId":"-"},"content":" });"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" it(\u0027should snap with session details and results are loading\u0027, () \u003d\u003e {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" component.isCourseLoading \u003d true;"},{"lineNumber":181,"author":{"gitId":"-"},"content":" component.isFeedbackSessionDetailsLoading \u003d true;"},{"lineNumber":182,"author":{"gitId":"-"},"content":" component.isFeedbackSessionResultsLoading \u003d true;"},{"lineNumber":183,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":184,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":185,"author":{"gitId":"-"},"content":" });"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" it(\u0027should snap with session details loaded and results are loading\u0027, () \u003d\u003e {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" component.isCourseLoading \u003d false;"},{"lineNumber":189,"author":{"gitId":"-"},"content":" component.isFeedbackSessionDetailsLoading \u003d false;"},{"lineNumber":190,"author":{"gitId":"-"},"content":" component.isFeedbackSessionResultsLoading \u003d true;"},{"lineNumber":191,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":192,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":193,"author":{"gitId":"-"},"content":" });"},{"lineNumber":194,"author":{"gitId":"-"},"content":""},{"lineNumber":195,"author":{"gitId":"-"},"content":" it(\u0027should snap when session results failed to load\u0027, () \u003d\u003e {"},{"lineNumber":196,"author":{"gitId":"-"},"content":" component.isCourseLoading \u003d false;"},{"lineNumber":197,"author":{"gitId":"-"},"content":" component.isFeedbackSessionDetailsLoading \u003d false;"},{"lineNumber":198,"author":{"gitId":"-"},"content":" component.isFeedbackSessionResultsLoading \u003d false;"},{"lineNumber":199,"author":{"gitId":"-"},"content":" component.hasFeedbackSessionResultsLoadingFailed \u003d true;"},{"lineNumber":200,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":201,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":202,"author":{"gitId":"-"},"content":" });"},{"lineNumber":203,"author":{"gitId":"-"},"content":""},{"lineNumber":204,"author":{"gitId":"-"},"content":" it(\u0027should snap with user that is logged in and using session link\u0027, () \u003d\u003e {"},{"lineNumber":205,"author":{"gitId":"-"},"content":" component.regKey \u003d \u0027session-link-key\u0027;"},{"lineNumber":206,"author":{"gitId":"-"},"content":" component.loggedInUser \u003d \u0027alice\u0027;"},{"lineNumber":207,"author":{"gitId":"-"},"content":" component.personName \u003d \u0027alice\u0027;"},{"lineNumber":208,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":209,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":210,"author":{"gitId":"-"},"content":" });"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" it(\u0027should snap with user that is not logged in and using session link\u0027, () \u003d\u003e {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" component.regKey \u003d \u0027session-link-key\u0027;"},{"lineNumber":214,"author":{"gitId":"-"},"content":" component.loggedInUser \u003d \u0027\u0027;"},{"lineNumber":215,"author":{"gitId":"-"},"content":" component.personName \u003d \u0027alice\u0027;"},{"lineNumber":216,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":217,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":218,"author":{"gitId":"-"},"content":" });"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" it(\u0027should snap with an open feedback session with no questions\u0027, () \u003d\u003e {"},{"lineNumber":221,"author":{"gitId":"-"},"content":" component.session \u003d {"},{"lineNumber":222,"author":{"gitId":"-"},"content":" courseId: \u0027CS3281\u0027,"},{"lineNumber":223,"author":{"gitId":"-"},"content":" timeZone: \u0027UTC\u0027,"},{"lineNumber":224,"author":{"gitId":"-"},"content":" feedbackSessionName: \u0027Peer Review 1\u0027,"},{"lineNumber":225,"author":{"gitId":"-"},"content":" instructions: \u0027\u0027,"},{"lineNumber":226,"author":{"gitId":"-"},"content":" submissionStartTimestamp: 1555232400,"},{"lineNumber":227,"author":{"gitId":"-"},"content":" submissionEndTimestamp: 1555233400,"},{"lineNumber":228,"author":{"gitId":"-"},"content":" gracePeriod: 0,"},{"lineNumber":229,"author":{"gitId":"-"},"content":" sessionVisibleSetting: SessionVisibleSetting.AT_OPEN,"},{"lineNumber":230,"author":{"gitId":"-"},"content":" responseVisibleSetting: ResponseVisibleSetting.AT_VISIBLE,"},{"lineNumber":231,"author":{"gitId":"-"},"content":" submissionStatus: FeedbackSessionSubmissionStatus.OPEN,"},{"lineNumber":232,"author":{"gitId":"-"},"content":" publishStatus: FeedbackSessionPublishStatus.NOT_PUBLISHED,"},{"lineNumber":233,"author":{"gitId":"-"},"content":" isClosingEmailEnabled: true,"},{"lineNumber":234,"author":{"gitId":"-"},"content":" isPublishedEmailEnabled: true,"},{"lineNumber":235,"author":{"gitId":"-"},"content":" createdAtTimestamp: 1555231400,"},{"lineNumber":236,"author":{"gitId":"-"},"content":" studentDeadlines: {},"},{"lineNumber":237,"author":{"gitId":"-"},"content":" instructorDeadlines: {},"},{"lineNumber":238,"author":{"gitId":"-"},"content":" };"},{"lineNumber":239,"author":{"gitId":"-"},"content":" component.questions \u003d [];"},{"lineNumber":240,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":241,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":242,"author":{"gitId":"-"},"content":" });"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" it(\u0027should snap when previewing results\u0027, () \u003d\u003e {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" component.intent \u003d Intent.STUDENT_RESULT;"},{"lineNumber":246,"author":{"gitId":"-"},"content":" component.regKey \u003d \u0027\u0027;"},{"lineNumber":247,"author":{"gitId":"-"},"content":" component.previewAsPerson \u003d \u0027alice2@tmt.tmt\u0027;"},{"lineNumber":248,"author":{"gitId":"-"},"content":" component.personName \u003d \u0027Alice2\u0027;"},{"lineNumber":249,"author":{"gitId":"-"},"content":" component.personEmail \u003d \u0027alice2@tmt.tmt\u0027;"},{"lineNumber":250,"author":{"gitId":"-"},"content":" component.session \u003d testFeedbackSession;"},{"lineNumber":251,"author":{"gitId":"-"},"content":" component.questions \u003d [];"},{"lineNumber":252,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":253,"author":{"gitId":"-"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":254,"author":{"gitId":"-"},"content":" });"},{"lineNumber":255,"author":{"gitId":"-"},"content":""},{"lineNumber":256,"author":{"gitId":"-"},"content":" it(\u0027should fetch auth info on init\u0027, () \u003d\u003e {"},{"lineNumber":257,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthUser\u0027).mockReturnValue(of(testInfo));"},{"lineNumber":258,"author":{"gitId":"-"},"content":""},{"lineNumber":259,"author":{"gitId":"-"},"content":" component.ngOnInit();"},{"lineNumber":260,"author":{"gitId":"-"},"content":""},{"lineNumber":261,"author":{"gitId":"-"},"content":" expect(component.courseId).toEqual(\u0027CS3281\u0027);"},{"lineNumber":262,"author":{"gitId":"-"},"content":" expect(component.feedbackSessionName).toEqual(\u0027Peer Feedback\u0027);"},{"lineNumber":263,"author":{"gitId":"-"},"content":" expect(component.regKey).toEqual(\u0027reg-key\u0027);"},{"lineNumber":264,"author":{"gitId":"-"},"content":" expect(component.loggedInUser).toEqual(\u0027user-id\u0027);"},{"lineNumber":265,"author":{"gitId":"-"},"content":" });"},{"lineNumber":266,"author":{"gitId":"-"},"content":""},{"lineNumber":267,"author":{"gitId":"-"},"content":" it(\u0027should verify allowed access and used reg key\u0027, () \u003d\u003e {"},{"lineNumber":268,"author":{"gitId":"-"},"content":" const testValidity: RegkeyValidity \u003d {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" isAllowedAccess: true,"},{"lineNumber":270,"author":{"gitId":"-"},"content":" isUsed: true,"},{"lineNumber":271,"author":{"gitId":"-"},"content":" isValid: false,"},{"lineNumber":272,"author":{"gitId":"-"},"content":" };"},{"lineNumber":273,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthUser\u0027).mockReturnValue(of(testInfo));"},{"lineNumber":274,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthRegkeyValidity\u0027).mockReturnValue(of(testValidity));"},{"lineNumber":275,"author":{"gitId":"-"},"content":" const navSpy: SpyInstance \u003d jest.spyOn(navService, \u0027navigateByURLWithParamEncoding\u0027).mockImplementation();"},{"lineNumber":276,"author":{"gitId":"-"},"content":""},{"lineNumber":277,"author":{"gitId":"-"},"content":" component.ngOnInit();"},{"lineNumber":278,"author":{"gitId":"-"},"content":""},{"lineNumber":279,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":280,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenLastCalledWith(\u0027/web/student/sessions/result\u0027,"},{"lineNumber":281,"author":{"gitId":"-"},"content":" { courseid: \u0027CS3281\u0027, fsname: \u0027Peer Feedback\u0027 });"},{"lineNumber":282,"author":{"gitId":"-"},"content":" });"},{"lineNumber":283,"author":{"gitId":"-"},"content":""},{"lineNumber":284,"author":{"gitId":"-"},"content":" it(\u0027should load info and create log for unused reg key that is allowed\u0027, () \u003d\u003e {"},{"lineNumber":285,"author":{"gitId":"-"},"content":" const testValidity: RegkeyValidity \u003d {"},{"lineNumber":286,"author":{"gitId":"-"},"content":" isAllowedAccess: true,"},{"lineNumber":287,"author":{"gitId":"-"},"content":" isUsed: false,"},{"lineNumber":288,"author":{"gitId":"-"},"content":" isValid: false,"},{"lineNumber":289,"author":{"gitId":"-"},"content":" };"},{"lineNumber":290,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthUser\u0027).mockReturnValue(of(testInfo));"},{"lineNumber":291,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthRegkeyValidity\u0027).mockReturnValue(of(testValidity));"},{"lineNumber":292,"author":{"gitId":"-"},"content":" jest.spyOn(studentService, \u0027getStudent\u0027).mockReturnValue(of({"},{"lineNumber":293,"author":{"gitId":"-"},"content":" name: \u0027student-name\u0027,"},{"lineNumber":294,"author":{"gitId":"dishenggg"},"content":" email: \u0027student@tmt.tmt\u0027,"},{"lineNumber":295,"author":{"gitId":"-"},"content":" courseId: \u0027\u0027,"},{"lineNumber":296,"author":{"gitId":"-"},"content":" sectionName: \u0027\u0027,"},{"lineNumber":297,"author":{"gitId":"-"},"content":" teamName: \u0027\u0027,"},{"lineNumber":298,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":299,"author":{"gitId":"-"},"content":" jest.spyOn(feedbackSessionService, \u0027getFeedbackSession\u0027).mockReturnValue(of(testFeedbackSession));"},{"lineNumber":300,"author":{"gitId":"-"},"content":" const logSpy: SpyInstance \u003d jest.spyOn(logService, \u0027createFeedbackSessionLog\u0027).mockReturnValue(of(\u0027log created\u0027));"},{"lineNumber":301,"author":{"gitId":"-"},"content":""},{"lineNumber":302,"author":{"gitId":"-"},"content":" component.ngOnInit();"},{"lineNumber":303,"author":{"gitId":"-"},"content":""},{"lineNumber":304,"author":{"gitId":"-"},"content":" expect(component.personName).toEqual(\u0027student-name\u0027);"},{"lineNumber":305,"author":{"gitId":"-"},"content":" expect(component.session.courseId).toEqual(\u0027CS1231\u0027);"},{"lineNumber":306,"author":{"gitId":"-"},"content":" expect(logSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":307,"author":{"gitId":"-"},"content":" });"},{"lineNumber":308,"author":{"gitId":"-"},"content":""},{"lineNumber":309,"author":{"gitId":"-"},"content":" it(\u0027should deny access for reg key not belonging to logged in user\u0027, () \u003d\u003e {"},{"lineNumber":310,"author":{"gitId":"-"},"content":" const testValidity: RegkeyValidity \u003d {"},{"lineNumber":311,"author":{"gitId":"-"},"content":" isAllowedAccess: false,"},{"lineNumber":312,"author":{"gitId":"-"},"content":" isUsed: false,"},{"lineNumber":313,"author":{"gitId":"-"},"content":" isValid: true,"},{"lineNumber":314,"author":{"gitId":"-"},"content":" };"},{"lineNumber":315,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthUser\u0027).mockReturnValue(of(testInfo));"},{"lineNumber":316,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthRegkeyValidity\u0027).mockReturnValue(of(testValidity));"},{"lineNumber":317,"author":{"gitId":"-"},"content":" const navSpy: SpyInstance \u003d jest.spyOn(navService, \u0027navigateWithErrorMessage\u0027).mockImplementation();"},{"lineNumber":318,"author":{"gitId":"-"},"content":""},{"lineNumber":319,"author":{"gitId":"-"},"content":" component.ngOnInit();"},{"lineNumber":320,"author":{"gitId":"-"},"content":""},{"lineNumber":321,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":322,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenLastCalledWith(\u0027/web/front\u0027,"},{"lineNumber":323,"author":{"gitId":"-"},"content":" `You are trying to access TEAMMATES using the Google account user-id, which"},{"lineNumber":324,"author":{"gitId":"-"},"content":" is not linked to this TEAMMATES account. If you used a different Google account to"},{"lineNumber":325,"author":{"gitId":"-"},"content":" join/access TEAMMATES before, please use that Google account to access TEAMMATES. If you"},{"lineNumber":326,"author":{"gitId":"-"},"content":" cannot remember which Google account you used before, please email us at"},{"lineNumber":327,"author":{"gitId":"-"},"content":" ${environment.supportEmail} for help.`);"},{"lineNumber":328,"author":{"gitId":"-"},"content":" });"},{"lineNumber":329,"author":{"gitId":"-"},"content":""},{"lineNumber":330,"author":{"gitId":"-"},"content":" it(\u0027should deny access for invalid reg key\u0027, () \u003d\u003e {"},{"lineNumber":331,"author":{"gitId":"-"},"content":" const testValidity: RegkeyValidity \u003d {"},{"lineNumber":332,"author":{"gitId":"-"},"content":" isAllowedAccess: false,"},{"lineNumber":333,"author":{"gitId":"-"},"content":" isUsed: false,"},{"lineNumber":334,"author":{"gitId":"-"},"content":" isValid: false,"},{"lineNumber":335,"author":{"gitId":"-"},"content":" };"},{"lineNumber":336,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthUser\u0027).mockReturnValue(of(testInfo));"},{"lineNumber":337,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthRegkeyValidity\u0027).mockReturnValue(of(testValidity));"},{"lineNumber":338,"author":{"gitId":"-"},"content":" const navSpy: SpyInstance \u003d jest.spyOn(navService, \u0027navigateWithErrorMessage\u0027).mockImplementation();"},{"lineNumber":339,"author":{"gitId":"-"},"content":""},{"lineNumber":340,"author":{"gitId":"-"},"content":" component.ngOnInit();"},{"lineNumber":341,"author":{"gitId":"-"},"content":""},{"lineNumber":342,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":343,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenLastCalledWith(\u0027/web/front\u0027,"},{"lineNumber":344,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":345,"author":{"gitId":"-"},"content":" });"},{"lineNumber":346,"author":{"gitId":"-"},"content":""},{"lineNumber":347,"author":{"gitId":"-"},"content":" it(\u0027should navigate away when error occurs\u0027, () \u003d\u003e {"},{"lineNumber":348,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthUser\u0027).mockReturnValue(throwError(() \u003d\u003e ({"},{"lineNumber":349,"author":{"gitId":"-"},"content":" error: { message: \u0027This is error\u0027 },"},{"lineNumber":350,"author":{"gitId":"-"},"content":" })));"},{"lineNumber":351,"author":{"gitId":"-"},"content":" const navSpy: SpyInstance \u003d jest.spyOn(navService, \u0027navigateWithErrorMessage\u0027).mockImplementation();"},{"lineNumber":352,"author":{"gitId":"-"},"content":""},{"lineNumber":353,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":354,"author":{"gitId":"-"},"content":" component.ngOnInit();"},{"lineNumber":355,"author":{"gitId":"-"},"content":""},{"lineNumber":356,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":357,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenLastCalledWith(\u0027/web/front\u0027,"},{"lineNumber":358,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":359,"author":{"gitId":"-"},"content":" });"},{"lineNumber":360,"author":{"gitId":"-"},"content":""},{"lineNumber":361,"author":{"gitId":"-"},"content":" it(\u0027should navigate to join course when user click on join course link\u0027, () \u003d\u003e {"},{"lineNumber":362,"author":{"gitId":"-"},"content":" component.regKey \u003d \u0027reg-key\u0027;"},{"lineNumber":363,"author":{"gitId":"-"},"content":" component.loggedInUser \u003d \u0027user\u0027;"},{"lineNumber":364,"author":{"gitId":"-"},"content":" const navSpy: SpyInstance \u003d jest.spyOn(navService, \u0027navigateByURL\u0027).mockImplementation();"},{"lineNumber":365,"author":{"gitId":"-"},"content":""},{"lineNumber":366,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":367,"author":{"gitId":"-"},"content":""},{"lineNumber":368,"author":{"gitId":"-"},"content":" const btn: any \u003d fixture.debugElement.nativeElement"},{"lineNumber":369,"author":{"gitId":"-"},"content":" .querySelector(\u0027#join-course-btn\u0027);"},{"lineNumber":370,"author":{"gitId":"-"},"content":" btn.click();"},{"lineNumber":371,"author":{"gitId":"-"},"content":""},{"lineNumber":372,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenCalledTimes(1);"},{"lineNumber":373,"author":{"gitId":"-"},"content":" expect(navSpy).toHaveBeenLastCalledWith(\u0027/web/join\u0027, { entitytype: \u0027student\u0027, key: \u0027reg-key\u0027 });"},{"lineNumber":374,"author":{"gitId":"-"},"content":" });"},{"lineNumber":375,"author":{"gitId":"-"},"content":""},{"lineNumber":376,"author":{"gitId":"-"},"content":" it(\u0027should load feedback questions\u0027, () \u003d\u003e {"},{"lineNumber":377,"author":{"gitId":"-"},"content":" const testValidity: RegkeyValidity \u003d {"},{"lineNumber":378,"author":{"gitId":"-"},"content":" isAllowedAccess: true,"},{"lineNumber":379,"author":{"gitId":"-"},"content":" isUsed: false,"},{"lineNumber":380,"author":{"gitId":"-"},"content":" isValid: false,"},{"lineNumber":381,"author":{"gitId":"-"},"content":" };"},{"lineNumber":382,"author":{"gitId":"-"},"content":" const testFeedbackQuestions: FeedbackQuestions \u003d {"},{"lineNumber":383,"author":{"gitId":"-"},"content":" questions: [testFeedbackQuestion],"},{"lineNumber":384,"author":{"gitId":"-"},"content":" };"},{"lineNumber":385,"author":{"gitId":"-"},"content":" const testFeedbackQuestionModel: FeedbackQuestionModel \u003d {"},{"lineNumber":386,"author":{"gitId":"-"},"content":" feedbackQuestion: testFeedbackQuestion,"},{"lineNumber":387,"author":{"gitId":"-"},"content":" questionStatistics: \u0027\u0027,"},{"lineNumber":388,"author":{"gitId":"-"},"content":" allResponses: [],"},{"lineNumber":389,"author":{"gitId":"-"},"content":" responsesToSelf: [],"},{"lineNumber":390,"author":{"gitId":"-"},"content":" responsesFromSelf: [],"},{"lineNumber":391,"author":{"gitId":"-"},"content":" otherResponses: [],"},{"lineNumber":392,"author":{"gitId":"-"},"content":" isLoading: false,"},{"lineNumber":393,"author":{"gitId":"-"},"content":" isLoaded: false,"},{"lineNumber":394,"author":{"gitId":"-"},"content":" hasResponse: false,"},{"lineNumber":395,"author":{"gitId":"-"},"content":" hasResponseButNotVisibleForPreview: false,"},{"lineNumber":396,"author":{"gitId":"-"},"content":" hasCommentNotVisibleForPreview: false,"},{"lineNumber":397,"author":{"gitId":"-"},"content":" };"},{"lineNumber":398,"author":{"gitId":"-"},"content":""},{"lineNumber":399,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthUser\u0027).mockReturnValue(of(testInfo));"},{"lineNumber":400,"author":{"gitId":"-"},"content":" jest.spyOn(authService, \u0027getAuthRegkeyValidity\u0027).mockReturnValue(of(testValidity));"},{"lineNumber":401,"author":{"gitId":"-"},"content":" jest.spyOn(feedbackSessionService, \u0027getFeedbackSession\u0027).mockReturnValue(of(testFeedbackSession));"},{"lineNumber":402,"author":{"gitId":"-"},"content":" const getQuestionsSpy: SpyInstance \u003d jest.spyOn(feedbackQuestionsService, \u0027getFeedbackQuestions\u0027)"},{"lineNumber":403,"author":{"gitId":"-"},"content":" .mockReturnValue(of(testFeedbackQuestions));"},{"lineNumber":404,"author":{"gitId":"-"},"content":""},{"lineNumber":405,"author":{"gitId":"-"},"content":" component.ngOnInit();"},{"lineNumber":406,"author":{"gitId":"-"},"content":" expect(getQuestionsSpy).toHaveBeenLastCalledWith({"},{"lineNumber":407,"author":{"gitId":"-"},"content":" courseId: testQueryParams[\u0027courseid\u0027],"},{"lineNumber":408,"author":{"gitId":"-"},"content":" feedbackSessionName: testQueryParams[\u0027fsname\u0027],"},{"lineNumber":409,"author":{"gitId":"-"},"content":" intent: Intent.STUDENT_RESULT,"},{"lineNumber":410,"author":{"gitId":"-"},"content":" key: testQueryParams[\u0027key\u0027],"},{"lineNumber":411,"author":{"gitId":"-"},"content":" previewAs: testQueryParams[\u0027previewas\u0027],"},{"lineNumber":412,"author":{"gitId":"-"},"content":" });"},{"lineNumber":413,"author":{"gitId":"-"},"content":" expect(component.questions.length).toEqual(1);"},{"lineNumber":414,"author":{"gitId":"-"},"content":" expect(component.questions[0]).toEqual(testFeedbackQuestionModel);"},{"lineNumber":415,"author":{"gitId":"-"},"content":" });"},{"lineNumber":416,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"dishenggg":1,"-":415}},{"path":"src/web/app/pages-session/session-result-page/session-result-page.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component, OnInit } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { ActivatedRoute } from \u0027@angular/router\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { NgbModal, NgbModalRef } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { finalize, switchMap, tap } from \u0027rxjs/operators\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { environment } from \u0027../../../environments/environment\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { AuthService } from \u0027../../../services/auth.service\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { CourseService } from \u0027../../../services/course.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { FeedbackQuestionsService } from \u0027../../../services/feedback-questions.service\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { FeedbackSessionsService } from \u0027../../../services/feedback-sessions.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { InstructorService } from \u0027../../../services/instructor.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { LogService } from \u0027../../../services/log.service\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { NavigationService } from \u0027../../../services/navigation.service\u0027;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import { StatusMessageService } from \u0027../../../services/status-message.service\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import { StudentService } from \u0027../../../services/student.service\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import { TimezoneService } from \u0027../../../services/timezone.service\u0027;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":18,"author":{"gitId":"-"},"content":" AuthInfo,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" Course,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" FeedbackQuestion,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" FeedbackQuestions,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" FeedbackSession, FeedbackSessionLogType,"},{"lineNumber":23,"author":{"gitId":"-"},"content":" FeedbackSessionPublishStatus, FeedbackSessionSubmissionStatus,"},{"lineNumber":24,"author":{"gitId":"-"},"content":" Instructor,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" RegkeyValidity,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" ResponseOutput,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" ResponseVisibleSetting,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" SessionVisibleSetting, Student,"},{"lineNumber":29,"author":{"gitId":"-"},"content":"} from \u0027../../../types/api-output\u0027;"},{"lineNumber":30,"author":{"gitId":"-"},"content":"import { FeedbackVisibilityType, Intent } from \u0027../../../types/api-request\u0027;"},{"lineNumber":31,"author":{"gitId":"-"},"content":"import { DEFAULT_NUMBER_OF_RETRY_ATTEMPTS } from \u0027../../../types/default-retry-attempts\u0027;"},{"lineNumber":32,"author":{"gitId":"-"},"content":"import { ErrorReportComponent } from \u0027../../components/error-report/error-report.component\u0027;"},{"lineNumber":33,"author":{"gitId":"-"},"content":"import { ErrorMessageOutput } from \u0027../../error-message-output\u0027;"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":"export interface FeedbackQuestionModel {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" feedbackQuestion: FeedbackQuestion;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" questionStatistics: string;"},{"lineNumber":38,"author":{"gitId":"-"},"content":" allResponses: ResponseOutput[];"},{"lineNumber":39,"author":{"gitId":"-"},"content":" responsesToSelf: ResponseOutput[];"},{"lineNumber":40,"author":{"gitId":"-"},"content":" responsesFromSelf: ResponseOutput[];"},{"lineNumber":41,"author":{"gitId":"-"},"content":" otherResponses: ResponseOutput[][];"},{"lineNumber":42,"author":{"gitId":"-"},"content":" isLoading: boolean;"},{"lineNumber":43,"author":{"gitId":"-"},"content":" isLoaded: boolean;"},{"lineNumber":44,"author":{"gitId":"-"},"content":" hasResponse: boolean;"},{"lineNumber":45,"author":{"gitId":"-"},"content":" errorMessage?: string;"},{"lineNumber":46,"author":{"gitId":"-"},"content":" hasResponseButNotVisibleForPreview: boolean;"},{"lineNumber":47,"author":{"gitId":"-"},"content":" hasCommentNotVisibleForPreview: boolean;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"}"},{"lineNumber":49,"author":{"gitId":"-"},"content":""},{"lineNumber":50,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":51,"author":{"gitId":"-"},"content":" * Feedback session result page."},{"lineNumber":52,"author":{"gitId":"-"},"content":" */"},{"lineNumber":53,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":54,"author":{"gitId":"-"},"content":" selector: \u0027tm-session-result-page\u0027,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" templateUrl: \u0027./session-result-page.component.html\u0027,"},{"lineNumber":56,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./session-result-page.component.scss\u0027],"},{"lineNumber":57,"author":{"gitId":"-"},"content":"})"},{"lineNumber":58,"author":{"gitId":"-"},"content":"export class SessionResultPageComponent implements OnInit {"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" // enum"},{"lineNumber":61,"author":{"gitId":"-"},"content":" Intent: typeof Intent \u003d Intent;"},{"lineNumber":62,"author":{"gitId":"-"},"content":""},{"lineNumber":63,"author":{"gitId":"-"},"content":" session: FeedbackSession \u003d {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" courseId: \u0027\u0027,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" timeZone: \u0027\u0027,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" feedbackSessionName: \u0027\u0027,"},{"lineNumber":67,"author":{"gitId":"-"},"content":" instructions: \u0027\u0027,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" submissionStartTimestamp: 0,"},{"lineNumber":69,"author":{"gitId":"-"},"content":" submissionEndTimestamp: 0,"},{"lineNumber":70,"author":{"gitId":"-"},"content":" gracePeriod: 0,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" sessionVisibleSetting: SessionVisibleSetting.AT_OPEN,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" responseVisibleSetting: ResponseVisibleSetting.AT_VISIBLE,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" submissionStatus: FeedbackSessionSubmissionStatus.OPEN,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" publishStatus: FeedbackSessionPublishStatus.NOT_PUBLISHED,"},{"lineNumber":75,"author":{"gitId":"-"},"content":" isClosingEmailEnabled: true,"},{"lineNumber":76,"author":{"gitId":"-"},"content":" isPublishedEmailEnabled: true,"},{"lineNumber":77,"author":{"gitId":"-"},"content":" createdAtTimestamp: 0,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" studentDeadlines: {},"},{"lineNumber":79,"author":{"gitId":"-"},"content":" instructorDeadlines: {},"},{"lineNumber":80,"author":{"gitId":"-"},"content":" };"},{"lineNumber":81,"author":{"gitId":"-"},"content":" questions: FeedbackQuestionModel[] \u003d [];"},{"lineNumber":82,"author":{"gitId":"-"},"content":" courseName: string \u003d \u0027\u0027;"},{"lineNumber":83,"author":{"gitId":"-"},"content":" courseInstitute: string \u003d \u0027\u0027;"},{"lineNumber":84,"author":{"gitId":"-"},"content":" formattedSessionOpeningTime: string \u003d \u0027\u0027;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" formattedSessionClosingTime: string \u003d \u0027\u0027;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" personName: string \u003d \u0027\u0027;"},{"lineNumber":87,"author":{"gitId":"-"},"content":" personEmail: string \u003d \u0027\u0027;"},{"lineNumber":88,"author":{"gitId":"-"},"content":" courseId: string \u003d \u0027\u0027;"},{"lineNumber":89,"author":{"gitId":"-"},"content":" feedbackSessionName: string \u003d \u0027\u0027;"},{"lineNumber":90,"author":{"gitId":"-"},"content":" entityType: string \u003d \u0027student\u0027;"},{"lineNumber":91,"author":{"gitId":"-"},"content":" regKey: string \u003d \u0027\u0027;"},{"lineNumber":92,"author":{"gitId":"-"},"content":" loggedInUser: string \u003d \u0027\u0027;"},{"lineNumber":93,"author":{"gitId":"-"},"content":" visibilityRecipient: FeedbackVisibilityType \u003d FeedbackVisibilityType.RECIPIENT;"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" intent: Intent \u003d Intent.STUDENT_RESULT;"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" previewAsPerson: string \u003d \u0027\u0027;"},{"lineNumber":98,"author":{"gitId":"-"},"content":" isPreviewHintExpanded: boolean \u003d false;"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" isCourseLoading: boolean \u003d true;"},{"lineNumber":101,"author":{"gitId":"-"},"content":" isFeedbackSessionDetailsLoading: boolean \u003d true;"},{"lineNumber":102,"author":{"gitId":"-"},"content":" isFeedbackSessionResultsLoading: boolean \u003d true;"},{"lineNumber":103,"author":{"gitId":"-"},"content":" hasFeedbackSessionResultsLoadingFailed: boolean \u003d false;"},{"lineNumber":104,"author":{"gitId":"-"},"content":" retryAttempts: number \u003d DEFAULT_NUMBER_OF_RETRY_ATTEMPTS;"},{"lineNumber":105,"author":{"gitId":"-"},"content":""},{"lineNumber":106,"author":{"gitId":"dishenggg"},"content":" feedbackSessionId: string | undefined \u003d \u0027\u0027;"},{"lineNumber":107,"author":{"gitId":"dishenggg"},"content":" studentId: string | undefined \u003d \u0027\u0027;"},{"lineNumber":108,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":109,"author":{"gitId":"-"},"content":" private backendUrl: string \u003d environment.backendUrl;"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" constructor(private feedbackQuestionsService: FeedbackQuestionsService,"},{"lineNumber":112,"author":{"gitId":"-"},"content":" private feedbackSessionsService: FeedbackSessionsService,"},{"lineNumber":113,"author":{"gitId":"-"},"content":" private route: ActivatedRoute,"},{"lineNumber":114,"author":{"gitId":"-"},"content":" private timezoneService: TimezoneService,"},{"lineNumber":115,"author":{"gitId":"-"},"content":" private navigationService: NavigationService,"},{"lineNumber":116,"author":{"gitId":"-"},"content":" private authService: AuthService,"},{"lineNumber":117,"author":{"gitId":"-"},"content":" private studentService: StudentService,"},{"lineNumber":118,"author":{"gitId":"-"},"content":" private instructorService: InstructorService,"},{"lineNumber":119,"author":{"gitId":"-"},"content":" private courseService: CourseService,"},{"lineNumber":120,"author":{"gitId":"-"},"content":" private statusMessageService: StatusMessageService,"},{"lineNumber":121,"author":{"gitId":"-"},"content":" private logService: LogService,"},{"lineNumber":122,"author":{"gitId":"-"},"content":" private ngbModal: NgbModal) {"},{"lineNumber":123,"author":{"gitId":"-"},"content":" this.timezoneService.getTzVersion(); // import timezone service to load timezone data"},{"lineNumber":124,"author":{"gitId":"-"},"content":" }"},{"lineNumber":125,"author":{"gitId":"-"},"content":""},{"lineNumber":126,"author":{"gitId":"-"},"content":" ngOnInit(): void {"},{"lineNumber":127,"author":{"gitId":"-"},"content":" this.route.data.pipe("},{"lineNumber":128,"author":{"gitId":"-"},"content":" tap((data: any) \u003d\u003e {"},{"lineNumber":129,"author":{"gitId":"-"},"content":" this.intent \u003d data.intent;"},{"lineNumber":130,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":131,"author":{"gitId":"-"},"content":" switchMap(() \u003d\u003e this.route.queryParams),"},{"lineNumber":132,"author":{"gitId":"-"},"content":" ).subscribe((queryParams: any) \u003d\u003e {"},{"lineNumber":133,"author":{"gitId":"-"},"content":" this.courseId \u003d queryParams.courseid;"},{"lineNumber":134,"author":{"gitId":"-"},"content":" this.feedbackSessionName \u003d queryParams.fsname;"},{"lineNumber":135,"author":{"gitId":"-"},"content":" this.regKey \u003d queryParams.key || \u0027\u0027;"},{"lineNumber":136,"author":{"gitId":"-"},"content":" this.previewAsPerson \u003d queryParams.previewas ? queryParams.previewas : \u0027\u0027;"},{"lineNumber":137,"author":{"gitId":"-"},"content":" if (queryParams.entitytype \u003d\u003d\u003d \u0027instructor\u0027) {"},{"lineNumber":138,"author":{"gitId":"-"},"content":" this.entityType \u003d \u0027instructor\u0027;"},{"lineNumber":139,"author":{"gitId":"-"},"content":" this.intent \u003d Intent.INSTRUCTOR_RESULT;"},{"lineNumber":140,"author":{"gitId":"-"},"content":" }"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" const nextUrl: string \u003d `${window.location.pathname}${window.location.search.replace(/\u0026/g, \u0027%26\u0027)}`;"},{"lineNumber":143,"author":{"gitId":"-"},"content":" this.authService.getAuthUser(undefined, nextUrl).subscribe({"},{"lineNumber":144,"author":{"gitId":"-"},"content":" next: (auth: AuthInfo) \u003d\u003e {"},{"lineNumber":145,"author":{"gitId":"-"},"content":" const isPreview: boolean \u003d !!(auth.user \u0026\u0026 this.previewAsPerson);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" if (auth.user) {"},{"lineNumber":147,"author":{"gitId":"-"},"content":" this.loggedInUser \u003d auth.user.id;"},{"lineNumber":148,"author":{"gitId":"-"},"content":" }"},{"lineNumber":149,"author":{"gitId":"-"},"content":" // prevent having both key and previewas parameters in URL"},{"lineNumber":150,"author":{"gitId":"-"},"content":" if (this.regKey \u0026\u0026 isPreview) {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":152,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":153,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":" if (this.regKey) {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" this.authService.getAuthRegkeyValidity(this.regKey, this.intent).subscribe({"},{"lineNumber":157,"author":{"gitId":"-"},"content":" next: (resp: RegkeyValidity) \u003d\u003e {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" if (resp.isAllowedAccess) {"},{"lineNumber":159,"author":{"gitId":"-"},"content":" if (resp.isUsed) {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" // The logged in user matches the registration key; redirect to the logged in URL"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"-"},"content":" this.navigationService.navigateByURLWithParamEncoding("},{"lineNumber":163,"author":{"gitId":"-"},"content":" `/web/${this.entityType}/sessions/result`,"},{"lineNumber":164,"author":{"gitId":"-"},"content":" { courseid: this.courseId, fsname: this.feedbackSessionName });"},{"lineNumber":165,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":166,"author":{"gitId":"-"},"content":" // Valid, unused registration key; load information based on the key"},{"lineNumber":167,"author":{"gitId":"-"},"content":" this.loadCourseInfo();"},{"lineNumber":168,"author":{"gitId":"-"},"content":" this.loadPersonName();"},{"lineNumber":169,"author":{"gitId":"-"},"content":" this.loadFeedbackSession();"},{"lineNumber":170,"author":{"gitId":"-"},"content":" }"},{"lineNumber":171,"author":{"gitId":"-"},"content":" } else if (resp.isValid) {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" // At this point, registration key must already be used, otherwise access would be granted"},{"lineNumber":173,"author":{"gitId":"-"},"content":" if (this.loggedInUser) {"},{"lineNumber":174,"author":{"gitId":"-"},"content":" // Registration key belongs to another user who is not the logged in user"},{"lineNumber":175,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":176,"author":{"gitId":"-"},"content":" `You are trying to access TEAMMATES using the Google account ${this.loggedInUser}, which"},{"lineNumber":177,"author":{"gitId":"-"},"content":" is not linked to this TEAMMATES account. If you used a different Google account to"},{"lineNumber":178,"author":{"gitId":"-"},"content":" join/access TEAMMATES before, please use that Google account to access TEAMMATES. If you"},{"lineNumber":179,"author":{"gitId":"-"},"content":" cannot remember which Google account you used before, please email us at"},{"lineNumber":180,"author":{"gitId":"-"},"content":" ${environment.supportEmail} for help.`);"},{"lineNumber":181,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":182,"author":{"gitId":"-"},"content":" // There is no logged in user for a valid, used registration key, redirect to login page"},{"lineNumber":183,"author":{"gitId":"-"},"content":" // eslint-disable-next-line no-lonely-if"},{"lineNumber":184,"author":{"gitId":"-"},"content":" if (this.entityType \u003d\u003d\u003d \u0027student\u0027) {"},{"lineNumber":185,"author":{"gitId":"-"},"content":" window.location.href \u003d `${this.backendUrl}${auth.studentLoginUrl}`;"},{"lineNumber":186,"author":{"gitId":"-"},"content":" } else if (this.entityType \u003d\u003d\u003d \u0027instructor\u0027) {"},{"lineNumber":187,"author":{"gitId":"-"},"content":" window.location.href \u003d `${this.backendUrl}${auth.instructorLoginUrl}`;"},{"lineNumber":188,"author":{"gitId":"-"},"content":" }"},{"lineNumber":189,"author":{"gitId":"-"},"content":" }"},{"lineNumber":190,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" // The registration key is invalid"},{"lineNumber":192,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":193,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":194,"author":{"gitId":"-"},"content":" }"},{"lineNumber":195,"author":{"gitId":"-"},"content":" },"},{"lineNumber":196,"author":{"gitId":"-"},"content":" error: () \u003d\u003e {"},{"lineNumber":197,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":198,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":199,"author":{"gitId":"-"},"content":" },"},{"lineNumber":200,"author":{"gitId":"-"},"content":" });"},{"lineNumber":201,"author":{"gitId":"-"},"content":" } else if (this.loggedInUser) {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" // Load information based on logged in user"},{"lineNumber":203,"author":{"gitId":"-"},"content":" // This will also cover preview cases"},{"lineNumber":204,"author":{"gitId":"-"},"content":" this.loadCourseInfo();"},{"lineNumber":205,"author":{"gitId":"-"},"content":" this.loadPersonName();"},{"lineNumber":206,"author":{"gitId":"-"},"content":" this.loadFeedbackSession();"},{"lineNumber":207,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":208,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":209,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":210,"author":{"gitId":"-"},"content":" }"},{"lineNumber":211,"author":{"gitId":"-"},"content":" },"},{"lineNumber":212,"author":{"gitId":"-"},"content":" error: () \u003d\u003e {"},{"lineNumber":213,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":214,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":215,"author":{"gitId":"-"},"content":" },"},{"lineNumber":216,"author":{"gitId":"-"},"content":" });"},{"lineNumber":217,"author":{"gitId":"-"},"content":" });"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":""},{"lineNumber":220,"author":{"gitId":"-"},"content":" private loadCourseInfo(): void {"},{"lineNumber":221,"author":{"gitId":"-"},"content":" this.isCourseLoading \u003d true;"},{"lineNumber":222,"author":{"gitId":"-"},"content":" let request: Observable\u003cCourse\u003e;"},{"lineNumber":223,"author":{"gitId":"-"},"content":" switch (this.intent) {"},{"lineNumber":224,"author":{"gitId":"-"},"content":" case Intent.STUDENT_RESULT:"},{"lineNumber":225,"author":{"gitId":"-"},"content":" if (this.previewAsPerson) {"},{"lineNumber":226,"author":{"gitId":"-"},"content":" request \u003d this.courseService.getCourseAsInstructor(this.courseId);"},{"lineNumber":227,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":228,"author":{"gitId":"-"},"content":" request \u003d this.courseService.getCourseAsStudent(this.courseId, this.regKey);"},{"lineNumber":229,"author":{"gitId":"-"},"content":" }"},{"lineNumber":230,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":231,"author":{"gitId":"-"},"content":" case Intent.INSTRUCTOR_RESULT:"},{"lineNumber":232,"author":{"gitId":"-"},"content":" request \u003d this.courseService.getCourseAsInstructor(this.courseId, this.regKey);"},{"lineNumber":233,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":234,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":235,"author":{"gitId":"-"},"content":" this.isCourseLoading \u003d false;"},{"lineNumber":236,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":237,"author":{"gitId":"-"},"content":" }"},{"lineNumber":238,"author":{"gitId":"-"},"content":" request.subscribe({"},{"lineNumber":239,"author":{"gitId":"-"},"content":" next: (resp: Course) \u003d\u003e {"},{"lineNumber":240,"author":{"gitId":"-"},"content":" this.courseName \u003d resp.courseName;"},{"lineNumber":241,"author":{"gitId":"-"},"content":" this.courseInstitute \u003d resp.institute;"},{"lineNumber":242,"author":{"gitId":"-"},"content":" this.isCourseLoading \u003d false;"},{"lineNumber":243,"author":{"gitId":"-"},"content":" },"},{"lineNumber":244,"author":{"gitId":"-"},"content":" error: () \u003d\u003e {"},{"lineNumber":245,"author":{"gitId":"-"},"content":" this.isCourseLoading \u003d false;"},{"lineNumber":246,"author":{"gitId":"-"},"content":" },"},{"lineNumber":247,"author":{"gitId":"-"},"content":" });"},{"lineNumber":248,"author":{"gitId":"-"},"content":" }"},{"lineNumber":249,"author":{"gitId":"-"},"content":""},{"lineNumber":250,"author":{"gitId":"-"},"content":" private loadPersonName(): void {"},{"lineNumber":251,"author":{"gitId":"-"},"content":" switch (this.intent) {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" case Intent.STUDENT_RESULT:"},{"lineNumber":253,"author":{"gitId":"-"},"content":" this.studentService.getStudent("},{"lineNumber":254,"author":{"gitId":"-"},"content":" this.courseId,"},{"lineNumber":255,"author":{"gitId":"-"},"content":" this.previewAsPerson,"},{"lineNumber":256,"author":{"gitId":"-"},"content":" this.regKey,"},{"lineNumber":257,"author":{"gitId":"-"},"content":" ).subscribe((student: Student) \u003d\u003e {"},{"lineNumber":258,"author":{"gitId":"dishenggg"},"content":" this.studentId \u003d student.studentId;"},{"lineNumber":259,"author":{"gitId":"-"},"content":" this.personName \u003d student.name;"},{"lineNumber":260,"author":{"gitId":"-"},"content":" this.personEmail \u003d student.email;"},{"lineNumber":261,"author":{"gitId":"dishenggg"},"content":" this.logStudentView();"},{"lineNumber":262,"author":{"gitId":"-"},"content":" });"},{"lineNumber":263,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":264,"author":{"gitId":"-"},"content":" case Intent.INSTRUCTOR_RESULT:"},{"lineNumber":265,"author":{"gitId":"-"},"content":" this.instructorService.getInstructor({"},{"lineNumber":266,"author":{"gitId":"-"},"content":" courseId: this.courseId,"},{"lineNumber":267,"author":{"gitId":"-"},"content":" feedbackSessionName: this.feedbackSessionName,"},{"lineNumber":268,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":269,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":270,"author":{"gitId":"-"},"content":" previewAs: this.previewAsPerson,"},{"lineNumber":271,"author":{"gitId":"-"},"content":" }).subscribe((instructor: Instructor) \u003d\u003e {"},{"lineNumber":272,"author":{"gitId":"-"},"content":" this.personName \u003d instructor.name;"},{"lineNumber":273,"author":{"gitId":"-"},"content":" this.personEmail \u003d instructor.email;"},{"lineNumber":274,"author":{"gitId":"-"},"content":" });"},{"lineNumber":275,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":276,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":277,"author":{"gitId":"-"},"content":" }"},{"lineNumber":278,"author":{"gitId":"-"},"content":" }"},{"lineNumber":279,"author":{"gitId":"-"},"content":""},{"lineNumber":280,"author":{"gitId":"-"},"content":" private loadFeedbackSession(): void {"},{"lineNumber":281,"author":{"gitId":"-"},"content":" this.isFeedbackSessionDetailsLoading \u003d true;"},{"lineNumber":282,"author":{"gitId":"-"},"content":" this.isFeedbackSessionResultsLoading \u003d true;"},{"lineNumber":283,"author":{"gitId":"-"},"content":" this.feedbackSessionsService.getFeedbackSession({"},{"lineNumber":284,"author":{"gitId":"-"},"content":" courseId: this.courseId,"},{"lineNumber":285,"author":{"gitId":"-"},"content":" feedbackSessionName: this.feedbackSessionName,"},{"lineNumber":286,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":287,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":288,"author":{"gitId":"-"},"content":" previewAs: this.previewAsPerson,"},{"lineNumber":289,"author":{"gitId":"-"},"content":" })"},{"lineNumber":290,"author":{"gitId":"dishenggg"},"content":" .pipe(finalize(() \u003d\u003e {"},{"lineNumber":291,"author":{"gitId":"dishenggg"},"content":" this.isFeedbackSessionDetailsLoading \u003d false;"},{"lineNumber":292,"author":{"gitId":"dishenggg"},"content":" }))"},{"lineNumber":293,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":294,"author":{"gitId":"-"},"content":" next: (feedbackSession: FeedbackSession) \u003d\u003e {"},{"lineNumber":295,"author":{"gitId":"-"},"content":" const TIME_FORMAT: string \u003d \u0027ddd, DD MMM, YYYY, hh:mm A zz\u0027;"},{"lineNumber":296,"author":{"gitId":"-"},"content":" this.session \u003d feedbackSession;"},{"lineNumber":297,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionId \u003d feedbackSession.feedbackSessionId;"},{"lineNumber":298,"author":{"gitId":"-"},"content":" this.formattedSessionOpeningTime \u003d this.timezoneService"},{"lineNumber":299,"author":{"gitId":"-"},"content":" .formatToString(this.session.submissionStartTimestamp, this.session.timeZone, TIME_FORMAT);"},{"lineNumber":300,"author":{"gitId":"-"},"content":" this.formattedSessionClosingTime \u003d this.timezoneService"},{"lineNumber":301,"author":{"gitId":"-"},"content":" .formatToString(this.session.submissionEndTimestamp, this.session.timeZone, TIME_FORMAT);"},{"lineNumber":302,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":303,"author":{"gitId":"dishenggg"},"content":" this.logStudentView();"},{"lineNumber":304,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":305,"author":{"gitId":"-"},"content":" this.feedbackQuestionsService.getFeedbackQuestions({"},{"lineNumber":306,"author":{"gitId":"-"},"content":" courseId: this.courseId,"},{"lineNumber":307,"author":{"gitId":"-"},"content":" feedbackSessionName: this.feedbackSessionName,"},{"lineNumber":308,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":309,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":310,"author":{"gitId":"-"},"content":" previewAs: this.previewAsPerson,"},{"lineNumber":311,"author":{"gitId":"-"},"content":" }).pipe(finalize(() \u003d\u003e {"},{"lineNumber":312,"author":{"gitId":"-"},"content":" this.isFeedbackSessionResultsLoading \u003d false;"},{"lineNumber":313,"author":{"gitId":"-"},"content":" }))"},{"lineNumber":314,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":315,"author":{"gitId":"-"},"content":" next: (feedbackQuestions: FeedbackQuestions) \u003d\u003e {"},{"lineNumber":316,"author":{"gitId":"-"},"content":" feedbackQuestions.questions.sort("},{"lineNumber":317,"author":{"gitId":"-"},"content":" (a: FeedbackQuestion, b: FeedbackQuestion) \u003d\u003e"},{"lineNumber":318,"author":{"gitId":"-"},"content":" a.questionNumber - b.questionNumber);"},{"lineNumber":319,"author":{"gitId":"-"},"content":" for (const question of feedbackQuestions.questions) {"},{"lineNumber":320,"author":{"gitId":"-"},"content":" this.questions.push({"},{"lineNumber":321,"author":{"gitId":"-"},"content":" feedbackQuestion: question,"},{"lineNumber":322,"author":{"gitId":"-"},"content":" questionStatistics: \u0027\u0027,"},{"lineNumber":323,"author":{"gitId":"-"},"content":" allResponses: [],"},{"lineNumber":324,"author":{"gitId":"-"},"content":" responsesToSelf: [],"},{"lineNumber":325,"author":{"gitId":"-"},"content":" responsesFromSelf: [],"},{"lineNumber":326,"author":{"gitId":"-"},"content":" otherResponses: [],"},{"lineNumber":327,"author":{"gitId":"-"},"content":" isLoading: false,"},{"lineNumber":328,"author":{"gitId":"-"},"content":" isLoaded: false,"},{"lineNumber":329,"author":{"gitId":"-"},"content":" hasResponse: false,"},{"lineNumber":330,"author":{"gitId":"-"},"content":" hasResponseButNotVisibleForPreview: false,"},{"lineNumber":331,"author":{"gitId":"-"},"content":" hasCommentNotVisibleForPreview: false,"},{"lineNumber":332,"author":{"gitId":"-"},"content":" });"},{"lineNumber":333,"author":{"gitId":"-"},"content":" }"},{"lineNumber":334,"author":{"gitId":"-"},"content":" },"},{"lineNumber":335,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":336,"author":{"gitId":"-"},"content":" this.handleError(resp);"},{"lineNumber":337,"author":{"gitId":"-"},"content":" },"},{"lineNumber":338,"author":{"gitId":"-"},"content":" });"},{"lineNumber":339,"author":{"gitId":"-"},"content":" },"},{"lineNumber":340,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":341,"author":{"gitId":"-"},"content":" this.isFeedbackSessionResultsLoading \u003d false;"},{"lineNumber":342,"author":{"gitId":"-"},"content":" this.handleError(resp);"},{"lineNumber":343,"author":{"gitId":"-"},"content":" },"},{"lineNumber":344,"author":{"gitId":"-"},"content":" });"},{"lineNumber":345,"author":{"gitId":"-"},"content":" }"},{"lineNumber":346,"author":{"gitId":"-"},"content":""},{"lineNumber":347,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":348,"author":{"gitId":"-"},"content":" * Redirects to join course link for unregistered student/instructor."},{"lineNumber":349,"author":{"gitId":"-"},"content":" */"},{"lineNumber":350,"author":{"gitId":"-"},"content":" joinCourseForUnregisteredEntity(): void {"},{"lineNumber":351,"author":{"gitId":"-"},"content":" this.navigationService.navigateByURL(\u0027/web/join\u0027, { entitytype: this.entityType, key: this.regKey });"},{"lineNumber":352,"author":{"gitId":"-"},"content":" }"},{"lineNumber":353,"author":{"gitId":"-"},"content":""},{"lineNumber":354,"author":{"gitId":"-"},"content":" navigateToSessionReportPage(): void {"},{"lineNumber":355,"author":{"gitId":"-"},"content":" this.navigationService.navigateByURL(\u0027/web/instructor/sessions/report\u0027,"},{"lineNumber":356,"author":{"gitId":"-"},"content":" { courseid: this.courseId, fsname: this.feedbackSessionName });"},{"lineNumber":357,"author":{"gitId":"-"},"content":" }"},{"lineNumber":358,"author":{"gitId":"-"},"content":""},{"lineNumber":359,"author":{"gitId":"-"},"content":" retryLoadingFeedbackSessionResults(): void {"},{"lineNumber":360,"author":{"gitId":"-"},"content":" this.hasFeedbackSessionResultsLoadingFailed \u003d false;"},{"lineNumber":361,"author":{"gitId":"-"},"content":" if (this.retryAttempts \u003e\u003d 0) {"},{"lineNumber":362,"author":{"gitId":"-"},"content":" this.retryAttempts -\u003d 1;"},{"lineNumber":363,"author":{"gitId":"-"},"content":" }"},{"lineNumber":364,"author":{"gitId":"-"},"content":" this.loadFeedbackSession();"},{"lineNumber":365,"author":{"gitId":"-"},"content":" }"},{"lineNumber":366,"author":{"gitId":"-"},"content":""},{"lineNumber":367,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":368,"author":{"gitId":"-"},"content":" * Handles error according to number of attempts at retry"},{"lineNumber":369,"author":{"gitId":"-"},"content":" */"},{"lineNumber":370,"author":{"gitId":"-"},"content":" handleError(resp: ErrorMessageOutput): void {"},{"lineNumber":371,"author":{"gitId":"-"},"content":" this.hasFeedbackSessionResultsLoadingFailed \u003d true;"},{"lineNumber":372,"author":{"gitId":"-"},"content":" if (this.retryAttempts \u003c 0) {"},{"lineNumber":373,"author":{"gitId":"-"},"content":" const report: NgbModalRef \u003d this.ngbModal.open(ErrorReportComponent);"},{"lineNumber":374,"author":{"gitId":"-"},"content":" report.componentInstance.requestId \u003d resp.error.requestId;"},{"lineNumber":375,"author":{"gitId":"-"},"content":" report.componentInstance.errorMessage \u003d resp.error.message;"},{"lineNumber":376,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":377,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":378,"author":{"gitId":"-"},"content":" }"},{"lineNumber":379,"author":{"gitId":"-"},"content":" }"},{"lineNumber":380,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":381,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":382,"author":{"gitId":"dishenggg"},"content":" * Logs student activity after student/session details have been fetched."},{"lineNumber":383,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":384,"author":{"gitId":"dishenggg"},"content":" logStudentView(): void {"},{"lineNumber":385,"author":{"gitId":"dishenggg"},"content":" if (this.intent !\u003d\u003d Intent.STUDENT_RESULT) {"},{"lineNumber":386,"author":{"gitId":"dishenggg"},"content":" return;"},{"lineNumber":387,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":388,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":389,"author":{"gitId":"dishenggg"},"content":" // dummy vars to check that both student and session has been loaded"},{"lineNumber":390,"author":{"gitId":"dishenggg"},"content":" if (!this.personEmail || !this.session.courseId) {"},{"lineNumber":391,"author":{"gitId":"dishenggg"},"content":" return;"},{"lineNumber":392,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":393,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":394,"author":{"gitId":"dishenggg"},"content":" this.logService.createFeedbackSessionLog({"},{"lineNumber":395,"author":{"gitId":"dishenggg"},"content":" courseId: this.courseId,"},{"lineNumber":396,"author":{"gitId":"dishenggg"},"content":" feedbackSessionName: this.feedbackSessionName,"},{"lineNumber":397,"author":{"gitId":"dishenggg"},"content":" studentEmail: this.personEmail,"},{"lineNumber":398,"author":{"gitId":"dishenggg"},"content":" logType: FeedbackSessionLogType.VIEW_RESULT,"},{"lineNumber":399,"author":{"gitId":"dishenggg"},"content":" feedbackSessionId: this.feedbackSessionId,"},{"lineNumber":400,"author":{"gitId":"dishenggg"},"content":" studentId: this.studentId,"},{"lineNumber":401,"author":{"gitId":"dishenggg"},"content":" }).subscribe();"},{"lineNumber":402,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":403,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":35,"-":368}},{"path":"src/web/app/pages-session/session-submission-page/session-submission-page.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { DOCUMENT } from \u0027@angular/common\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { AfterViewInit, Component, Inject, OnInit } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { ActivatedRoute } from \u0027@angular/router\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { NgbModal, NgbModalRef } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { PageScrollService } from \u0027ngx-page-scroll-core\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { forkJoin, Observable, of } from \u0027rxjs\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { catchError, finalize, switchMap, tap } from \u0027rxjs/operators\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { SavingCompleteModalComponent } from \u0027./saving-complete-modal/saving-complete-modal.component\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { environment } from \u0027../../../environments/environment\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { AuthService } from \u0027../../../services/auth.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { CourseService } from \u0027../../../services/course.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import { DeadlineExtensionHelper } from \u0027../../../services/deadline-extension-helper\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { FeedbackQuestionsService } from \u0027../../../services/feedback-questions.service\u0027;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import { FeedbackResponseCommentService } from \u0027../../../services/feedback-response-comment.service\u0027;"},{"lineNumber":15,"author":{"gitId":"-"},"content":"import { FeedbackResponsesResponse, FeedbackResponsesService } from \u0027../../../services/feedback-responses.service\u0027;"},{"lineNumber":16,"author":{"gitId":"-"},"content":"import { FeedbackSessionsService } from \u0027../../../services/feedback-sessions.service\u0027;"},{"lineNumber":17,"author":{"gitId":"-"},"content":"import { InstructorService } from \u0027../../../services/instructor.service\u0027;"},{"lineNumber":18,"author":{"gitId":"-"},"content":"import { LogService } from \u0027../../../services/log.service\u0027;"},{"lineNumber":19,"author":{"gitId":"-"},"content":"import { NavigationService } from \u0027../../../services/navigation.service\u0027;"},{"lineNumber":20,"author":{"gitId":"-"},"content":"import { SimpleModalService } from \u0027../../../services/simple-modal.service\u0027;"},{"lineNumber":21,"author":{"gitId":"-"},"content":"import { StatusMessageService } from \u0027../../../services/status-message.service\u0027;"},{"lineNumber":22,"author":{"gitId":"-"},"content":"import { StudentService } from \u0027../../../services/student.service\u0027;"},{"lineNumber":23,"author":{"gitId":"-"},"content":"import { TimezoneService } from \u0027../../../services/timezone.service\u0027;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":25,"author":{"gitId":"-"},"content":" AuthInfo,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" Course,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" FeedbackParticipantType,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" FeedbackQuestion,"},{"lineNumber":29,"author":{"gitId":"-"},"content":" FeedbackQuestionRecipient,"},{"lineNumber":30,"author":{"gitId":"-"},"content":" FeedbackQuestionRecipients,"},{"lineNumber":31,"author":{"gitId":"-"},"content":" FeedbackQuestionType,"},{"lineNumber":32,"author":{"gitId":"-"},"content":" FeedbackResponse,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" FeedbackResponseComment,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" FeedbackResponses,"},{"lineNumber":35,"author":{"gitId":"-"},"content":" FeedbackSession,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" FeedbackSessionLogType,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" FeedbackSessionSubmissionStatus,"},{"lineNumber":38,"author":{"gitId":"-"},"content":" Instructor,"},{"lineNumber":39,"author":{"gitId":"-"},"content":" NumberOfEntitiesToGiveFeedbackToSetting,"},{"lineNumber":40,"author":{"gitId":"-"},"content":" RegkeyValidity,"},{"lineNumber":41,"author":{"gitId":"-"},"content":" Student,"},{"lineNumber":42,"author":{"gitId":"-"},"content":"} from \u0027../../../types/api-output\u0027;"},{"lineNumber":43,"author":{"gitId":"-"},"content":"import { FeedbackResponseRequest, Intent } from \u0027../../../types/api-request\u0027;"},{"lineNumber":44,"author":{"gitId":"-"},"content":"import { Milliseconds } from \u0027../../../types/datetime-const\u0027;"},{"lineNumber":45,"author":{"gitId":"-"},"content":"import { DEFAULT_NUMBER_OF_RETRY_ATTEMPTS } from \u0027../../../types/default-retry-attempts\u0027;"},{"lineNumber":46,"author":{"gitId":"-"},"content":"import { CommentRowModel } from \u0027../../components/comment-box/comment-row/comment-row.component\u0027;"},{"lineNumber":47,"author":{"gitId":"-"},"content":"import { ErrorReportComponent } from \u0027../../components/error-report/error-report.component\u0027;"},{"lineNumber":48,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" FeedbackResponseRecipient,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" FeedbackResponseRecipientSubmissionFormModel,"},{"lineNumber":51,"author":{"gitId":"-"},"content":" QuestionSubmissionFormMode,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" QuestionSubmissionFormModel,"},{"lineNumber":53,"author":{"gitId":"-"},"content":"} from \u0027../../components/question-submission-form/question-submission-form-model\u0027;"},{"lineNumber":54,"author":{"gitId":"-"},"content":"import { SimpleModalType } from \u0027../../components/simple-modal/simple-modal-type\u0027;"},{"lineNumber":55,"author":{"gitId":"-"},"content":"import { ErrorMessageOutput } from \u0027../../error-message-output\u0027;"},{"lineNumber":56,"author":{"gitId":"-"},"content":""},{"lineNumber":57,"author":{"gitId":"-"},"content":"interface FeedbackQuestionsResponse {"},{"lineNumber":58,"author":{"gitId":"-"},"content":" questions: FeedbackQuestion[];"},{"lineNumber":59,"author":{"gitId":"-"},"content":"}"},{"lineNumber":60,"author":{"gitId":"-"},"content":""},{"lineNumber":61,"author":{"gitId":"-"},"content":"// To export out"},{"lineNumber":62,"author":{"gitId":"-"},"content":"export enum SessionView {"},{"lineNumber":63,"author":{"gitId":"-"},"content":" DEFAULT \u003d \u0027Question\u0027,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" GROUP_RECIPIENTS \u003d \u0027Recipient\u0027,"},{"lineNumber":65,"author":{"gitId":"-"},"content":"}"},{"lineNumber":66,"author":{"gitId":"-"},"content":""},{"lineNumber":67,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":68,"author":{"gitId":"-"},"content":" * Feedback session submission page."},{"lineNumber":69,"author":{"gitId":"-"},"content":" */"},{"lineNumber":70,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":71,"author":{"gitId":"-"},"content":" selector: \u0027tm-session-submission-page\u0027,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" templateUrl: \u0027./session-submission-page.component.html\u0027,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./session-submission-page.component.scss\u0027],"},{"lineNumber":74,"author":{"gitId":"-"},"content":"})"},{"lineNumber":75,"author":{"gitId":"-"},"content":"export class SessionSubmissionPageComponent implements OnInit, AfterViewInit {"},{"lineNumber":76,"author":{"gitId":"-"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" // enum"},{"lineNumber":78,"author":{"gitId":"-"},"content":" FeedbackSessionSubmissionStatus: typeof FeedbackSessionSubmissionStatus \u003d FeedbackSessionSubmissionStatus;"},{"lineNumber":79,"author":{"gitId":"-"},"content":" FeedbackQuestionType: typeof FeedbackQuestionType \u003d FeedbackQuestionType;"},{"lineNumber":80,"author":{"gitId":"-"},"content":" Intent: typeof Intent \u003d Intent;"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" courseId: string \u003d \u0027\u0027;"},{"lineNumber":83,"author":{"gitId":"-"},"content":" feedbackSessionName: string \u003d \u0027\u0027;"},{"lineNumber":84,"author":{"gitId":"-"},"content":" regKey: string \u003d \u0027\u0027;"},{"lineNumber":85,"author":{"gitId":"-"},"content":" entityType: string \u003d \u0027student\u0027;"},{"lineNumber":86,"author":{"gitId":"-"},"content":" loggedInUser: string \u003d \u0027\u0027;"},{"lineNumber":87,"author":{"gitId":"-"},"content":""},{"lineNumber":88,"author":{"gitId":"-"},"content":" moderatedPerson: string \u003d \u0027\u0027;"},{"lineNumber":89,"author":{"gitId":"-"},"content":" previewAsPerson: string \u003d \u0027\u0027;"},{"lineNumber":90,"author":{"gitId":"-"},"content":" // the name of the person involved"},{"lineNumber":91,"author":{"gitId":"-"},"content":" // (e.g. the student name for unregistered student, the name of instructor being moderated)"},{"lineNumber":92,"author":{"gitId":"-"},"content":" personName: string \u003d \u0027\u0027;"},{"lineNumber":93,"author":{"gitId":"-"},"content":" personEmail: string \u003d \u0027\u0027;"},{"lineNumber":94,"author":{"gitId":"-"},"content":""},{"lineNumber":95,"author":{"gitId":"-"},"content":" courseName: string \u003d \u0027\u0027;"},{"lineNumber":96,"author":{"gitId":"-"},"content":" courseInstitute: string \u003d \u0027\u0027;"},{"lineNumber":97,"author":{"gitId":"-"},"content":" formattedSessionOpeningTime: string \u003d \u0027\u0027;"},{"lineNumber":98,"author":{"gitId":"-"},"content":" formattedSessionClosingTime: string \u003d \u0027\u0027;"},{"lineNumber":99,"author":{"gitId":"-"},"content":" feedbackSessionInstructions: string \u003d \u0027\u0027;"},{"lineNumber":100,"author":{"gitId":"-"},"content":" feedbackSessionTimezone: string \u003d \u0027\u0027;"},{"lineNumber":101,"author":{"gitId":"-"},"content":" feedbackSessionSubmissionStatus: FeedbackSessionSubmissionStatus \u003d FeedbackSessionSubmissionStatus.OPEN;"},{"lineNumber":102,"author":{"gitId":"-"},"content":""},{"lineNumber":103,"author":{"gitId":"-"},"content":" intent: Intent \u003d Intent.STUDENT_SUBMISSION;"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" questionSubmissionForms: QuestionSubmissionFormModel[] \u003d [];"},{"lineNumber":106,"author":{"gitId":"-"},"content":""},{"lineNumber":107,"author":{"gitId":"-"},"content":" isSavingResponses: boolean \u003d false;"},{"lineNumber":108,"author":{"gitId":"-"},"content":" isSubmissionFormsDisabled: boolean \u003d false;"},{"lineNumber":109,"author":{"gitId":"-"},"content":""},{"lineNumber":110,"author":{"gitId":"-"},"content":" isModerationHintExpanded: boolean \u003d false;"},{"lineNumber":111,"author":{"gitId":"-"},"content":" moderatedQuestionId: string \u003d \u0027\u0027;"},{"lineNumber":112,"author":{"gitId":"-"},"content":""},{"lineNumber":113,"author":{"gitId":"-"},"content":" isCourseLoading: boolean \u003d true;"},{"lineNumber":114,"author":{"gitId":"-"},"content":" isFeedbackSessionLoading: boolean \u003d true;"},{"lineNumber":115,"author":{"gitId":"-"},"content":" isFeedbackSessionQuestionsLoading: boolean \u003d true;"},{"lineNumber":116,"author":{"gitId":"-"},"content":" hasFeedbackSessionQuestionsLoadingFailed: boolean \u003d false;"},{"lineNumber":117,"author":{"gitId":"-"},"content":" retryAttempts: number \u003d DEFAULT_NUMBER_OF_RETRY_ATTEMPTS;"},{"lineNumber":118,"author":{"gitId":"-"},"content":""},{"lineNumber":119,"author":{"gitId":"-"},"content":" isQuestionCountOne: boolean \u003d false;"},{"lineNumber":120,"author":{"gitId":"-"},"content":" isSubmitAllClicked: boolean \u003d false;"},{"lineNumber":121,"author":{"gitId":"-"},"content":""},{"lineNumber":122,"author":{"gitId":"-"},"content":" allSessionViews \u003d SessionView;"},{"lineNumber":123,"author":{"gitId":"-"},"content":" currentSelectedSessionView: SessionView \u003d SessionView.DEFAULT;"},{"lineNumber":124,"author":{"gitId":"-"},"content":" hasLoadedAllRecipients: boolean \u003d false;"},{"lineNumber":125,"author":{"gitId":"-"},"content":" // Records the recipient to groupable questions mapping used in grouping questions by recipients view"},{"lineNumber":126,"author":{"gitId":"-"},"content":" recipientQuestionMap: Map\u003cstring, Set\u003cnumber\u003e\u003e \u003d new Map\u003cstring, Set\u003cnumber\u003e\u003e();"},{"lineNumber":127,"author":{"gitId":"-"},"content":" ungroupableQuestions: Set\u003cnumber\u003e \u003d new Set();"},{"lineNumber":128,"author":{"gitId":"-"},"content":" ungroupableQuestionsSorted: number[] \u003d [];"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"dishenggg"},"content":" feedbackSessionId: string | undefined \u003d \u0027\u0027;"},{"lineNumber":131,"author":{"gitId":"dishenggg"},"content":" studentId: string | undefined \u003d \u0027\u0027;"},{"lineNumber":132,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" private backendUrl: string \u003d environment.backendUrl;"},{"lineNumber":134,"author":{"gitId":"-"},"content":""},{"lineNumber":135,"author":{"gitId":"-"},"content":" constructor(private route: ActivatedRoute,"},{"lineNumber":136,"author":{"gitId":"-"},"content":" private statusMessageService: StatusMessageService,"},{"lineNumber":137,"author":{"gitId":"-"},"content":" private timezoneService: TimezoneService,"},{"lineNumber":138,"author":{"gitId":"-"},"content":" private feedbackQuestionsService: FeedbackQuestionsService,"},{"lineNumber":139,"author":{"gitId":"-"},"content":" private feedbackResponsesService: FeedbackResponsesService,"},{"lineNumber":140,"author":{"gitId":"-"},"content":" private feedbackSessionsService: FeedbackSessionsService,"},{"lineNumber":141,"author":{"gitId":"-"},"content":" private studentService: StudentService,"},{"lineNumber":142,"author":{"gitId":"-"},"content":" private instructorService: InstructorService,"},{"lineNumber":143,"author":{"gitId":"-"},"content":" private courseService: CourseService,"},{"lineNumber":144,"author":{"gitId":"-"},"content":" private ngbModal: NgbModal,"},{"lineNumber":145,"author":{"gitId":"-"},"content":" private simpleModalService: SimpleModalService,"},{"lineNumber":146,"author":{"gitId":"-"},"content":" private pageScrollService: PageScrollService,"},{"lineNumber":147,"author":{"gitId":"-"},"content":" private authService: AuthService,"},{"lineNumber":148,"author":{"gitId":"-"},"content":" private navigationService: NavigationService,"},{"lineNumber":149,"author":{"gitId":"-"},"content":" private commentService: FeedbackResponseCommentService,"},{"lineNumber":150,"author":{"gitId":"-"},"content":" private logService: LogService,"},{"lineNumber":151,"author":{"gitId":"-"},"content":" @Inject(DOCUMENT) private document: any) {"},{"lineNumber":152,"author":{"gitId":"-"},"content":" this.timezoneService.getTzVersion(); // import timezone service to load timezone data"},{"lineNumber":153,"author":{"gitId":"-"},"content":" }"},{"lineNumber":154,"author":{"gitId":"-"},"content":""},{"lineNumber":155,"author":{"gitId":"-"},"content":" ngOnInit(): void {"},{"lineNumber":156,"author":{"gitId":"-"},"content":" this.route.data.pipe("},{"lineNumber":157,"author":{"gitId":"-"},"content":" tap((data: any) \u003d\u003e {"},{"lineNumber":158,"author":{"gitId":"-"},"content":" this.intent \u003d data.intent;"},{"lineNumber":159,"author":{"gitId":"-"},"content":" this.entityType \u003d data.intent \u003d\u003d\u003d Intent.INSTRUCTOR_SUBMISSION ? \u0027instructor\u0027 : this.entityType;"},{"lineNumber":160,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":161,"author":{"gitId":"-"},"content":" switchMap(() \u003d\u003e this.route.queryParams),"},{"lineNumber":162,"author":{"gitId":"-"},"content":" ).subscribe((queryParams: any) \u003d\u003e {"},{"lineNumber":163,"author":{"gitId":"-"},"content":" this.courseId \u003d queryParams.courseid;"},{"lineNumber":164,"author":{"gitId":"-"},"content":" this.feedbackSessionName \u003d queryParams.fsname;"},{"lineNumber":165,"author":{"gitId":"-"},"content":" this.regKey \u003d queryParams.key ? queryParams.key : \u0027\u0027;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" this.moderatedPerson \u003d queryParams.moderatedperson ? queryParams.moderatedperson : \u0027\u0027;"},{"lineNumber":167,"author":{"gitId":"-"},"content":" this.previewAsPerson \u003d queryParams.previewas ? queryParams.previewas : \u0027\u0027;"},{"lineNumber":168,"author":{"gitId":"-"},"content":" if (queryParams.entitytype \u003d\u003d\u003d \u0027instructor\u0027) {"},{"lineNumber":169,"author":{"gitId":"-"},"content":" this.entityType \u003d \u0027instructor\u0027;"},{"lineNumber":170,"author":{"gitId":"-"},"content":" this.intent \u003d Intent.INSTRUCTOR_SUBMISSION;"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":" this.moderatedQuestionId \u003d queryParams.moderatedquestionId ? queryParams.moderatedquestionId : \u0027\u0027;"},{"lineNumber":173,"author":{"gitId":"-"},"content":""},{"lineNumber":174,"author":{"gitId":"-"},"content":" if (this.previewAsPerson) {"},{"lineNumber":175,"author":{"gitId":"-"},"content":" // disable submission in the preview mode"},{"lineNumber":176,"author":{"gitId":"-"},"content":" this.isSubmissionFormsDisabled \u003d true;"},{"lineNumber":177,"author":{"gitId":"-"},"content":" }"},{"lineNumber":178,"author":{"gitId":"-"},"content":""},{"lineNumber":179,"author":{"gitId":"-"},"content":" const nextUrl: string \u003d `${window.location.pathname}${window.location.search.replace(/\u0026/g, \u0027%26\u0027)}`;"},{"lineNumber":180,"author":{"gitId":"-"},"content":" this.authService.getAuthUser(undefined, nextUrl).subscribe({"},{"lineNumber":181,"author":{"gitId":"-"},"content":" next: (auth: AuthInfo) \u003d\u003e {"},{"lineNumber":182,"author":{"gitId":"-"},"content":" const isPreviewOrModeration: boolean \u003d !!(auth.user \u0026\u0026 (this.moderatedPerson || this.previewAsPerson));"},{"lineNumber":183,"author":{"gitId":"-"},"content":" if (auth.user) {"},{"lineNumber":184,"author":{"gitId":"-"},"content":" this.loggedInUser \u003d auth.user.id;"},{"lineNumber":185,"author":{"gitId":"-"},"content":" }"},{"lineNumber":186,"author":{"gitId":"-"},"content":" if (this.regKey \u0026\u0026 !isPreviewOrModeration) {"},{"lineNumber":187,"author":{"gitId":"-"},"content":" this.authService.getAuthRegkeyValidity(this.regKey, this.intent).subscribe({"},{"lineNumber":188,"author":{"gitId":"-"},"content":" next: (resp: RegkeyValidity) \u003d\u003e {"},{"lineNumber":189,"author":{"gitId":"-"},"content":" if (resp.isAllowedAccess) {"},{"lineNumber":190,"author":{"gitId":"-"},"content":" if (resp.isUsed) {"},{"lineNumber":191,"author":{"gitId":"-"},"content":" // The logged in user matches the registration key; redirect to the logged in URL"},{"lineNumber":192,"author":{"gitId":"-"},"content":" this.navigationService.navigateByURLWithParamEncoding("},{"lineNumber":193,"author":{"gitId":"-"},"content":" `/web/${this.entityType}/sessions/submission`,"},{"lineNumber":194,"author":{"gitId":"-"},"content":" { courseid: this.courseId, fsname: this.feedbackSessionName });"},{"lineNumber":195,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":196,"author":{"gitId":"-"},"content":" // Valid, unused registration key; load information based on the key"},{"lineNumber":197,"author":{"gitId":"-"},"content":" this.loadCourseInfo();"},{"lineNumber":198,"author":{"gitId":"-"},"content":" this.loadPersonName();"},{"lineNumber":199,"author":{"gitId":"-"},"content":" this.loadFeedbackSession(false, auth);"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }"},{"lineNumber":201,"author":{"gitId":"-"},"content":" } else if (resp.isValid) {"},{"lineNumber":202,"author":{"gitId":"-"},"content":" // At this point, registration key must already be used, otherwise access would be granted"},{"lineNumber":203,"author":{"gitId":"-"},"content":" if (this.loggedInUser) {"},{"lineNumber":204,"author":{"gitId":"-"},"content":" // Registration key belongs to another user who is not the logged in user"},{"lineNumber":205,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":206,"author":{"gitId":"-"},"content":" `You are trying to access TEAMMATES using the Google account ${this.loggedInUser}, which"},{"lineNumber":207,"author":{"gitId":"-"},"content":" is not linked to this TEAMMATES account. If you used a different Google account to"},{"lineNumber":208,"author":{"gitId":"-"},"content":" join/access TEAMMATES before, please use that Google account to access TEAMMATES. If you"},{"lineNumber":209,"author":{"gitId":"-"},"content":" cannot remember which Google account you used before, please email us at"},{"lineNumber":210,"author":{"gitId":"-"},"content":" ${environment.supportEmail} for help.`);"},{"lineNumber":211,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":212,"author":{"gitId":"-"},"content":" this.loadFeedbackSession(true, auth);"},{"lineNumber":213,"author":{"gitId":"-"},"content":" }"},{"lineNumber":214,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" // The registration key is invalid"},{"lineNumber":216,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":217,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":218,"author":{"gitId":"-"},"content":" }"},{"lineNumber":219,"author":{"gitId":"-"},"content":" },"},{"lineNumber":220,"author":{"gitId":"-"},"content":" error: () \u003d\u003e {"},{"lineNumber":221,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":222,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":223,"author":{"gitId":"-"},"content":" },"},{"lineNumber":224,"author":{"gitId":"-"},"content":" });"},{"lineNumber":225,"author":{"gitId":"-"},"content":" } else if (this.loggedInUser) {"},{"lineNumber":226,"author":{"gitId":"-"},"content":" // Load information based on logged in user"},{"lineNumber":227,"author":{"gitId":"-"},"content":" // This will also cover moderation/preview cases"},{"lineNumber":228,"author":{"gitId":"-"},"content":" this.loadCourseInfo();"},{"lineNumber":229,"author":{"gitId":"-"},"content":" this.loadPersonName();"},{"lineNumber":230,"author":{"gitId":"-"},"content":" this.loadFeedbackSession(false, auth);"},{"lineNumber":231,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":232,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":233,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":234,"author":{"gitId":"-"},"content":" }"},{"lineNumber":235,"author":{"gitId":"-"},"content":" },"},{"lineNumber":236,"author":{"gitId":"-"},"content":" error: () \u003d\u003e {"},{"lineNumber":237,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage(\u0027/web/front\u0027,"},{"lineNumber":238,"author":{"gitId":"-"},"content":" \u0027You are not authorized to view this page.\u0027);"},{"lineNumber":239,"author":{"gitId":"-"},"content":" },"},{"lineNumber":240,"author":{"gitId":"-"},"content":" });"},{"lineNumber":241,"author":{"gitId":"-"},"content":" });"},{"lineNumber":242,"author":{"gitId":"-"},"content":" }"},{"lineNumber":243,"author":{"gitId":"-"},"content":""},{"lineNumber":244,"author":{"gitId":"-"},"content":" // Solution for checking partial element visibility adapted from"},{"lineNumber":245,"author":{"gitId":"-"},"content":" // https://stackoverflow.com/questions/30943662/check-if-element-is-partially-in-viewport"},{"lineNumber":246,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":247,"author":{"gitId":"-"},"content":" * Checks if a given element is in view."},{"lineNumber":248,"author":{"gitId":"-"},"content":" *"},{"lineNumber":249,"author":{"gitId":"-"},"content":" * @param e element to perform check for"},{"lineNumber":250,"author":{"gitId":"-"},"content":" */"},{"lineNumber":251,"author":{"gitId":"-"},"content":" isInViewport(e: HTMLElement): boolean {"},{"lineNumber":252,"author":{"gitId":"-"},"content":" const rect \u003d e.getBoundingClientRect();"},{"lineNumber":253,"author":{"gitId":"-"},"content":" const windowHeight: number \u003d (window.innerHeight || document.documentElement.clientHeight);"},{"lineNumber":254,"author":{"gitId":"-"},"content":""},{"lineNumber":255,"author":{"gitId":"-"},"content":" return !("},{"lineNumber":256,"author":{"gitId":"-"},"content":" Math.floor(100 - (((rect.top \u003e\u003d 0 ? 0 : rect.top) / +-rect.height) * 100)) \u003c 1"},{"lineNumber":257,"author":{"gitId":"-"},"content":" || Math.floor(100 - ((rect.bottom - windowHeight) / rect.height) * 100) \u003c 1"},{"lineNumber":258,"author":{"gitId":"-"},"content":" );"},{"lineNumber":259,"author":{"gitId":"-"},"content":" }"},{"lineNumber":260,"author":{"gitId":"-"},"content":""},{"lineNumber":261,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":262,"author":{"gitId":"-"},"content":" * Scrolls to the question based on its given question id."},{"lineNumber":263,"author":{"gitId":"-"},"content":" */"},{"lineNumber":264,"author":{"gitId":"-"},"content":" scrollToQuestion(): void {"},{"lineNumber":265,"author":{"gitId":"-"},"content":" const div: HTMLElement | null \u003d document.getElementById(this.moderatedQuestionId);"},{"lineNumber":266,"author":{"gitId":"-"},"content":""},{"lineNumber":267,"author":{"gitId":"-"},"content":" // continue scrolling as long as the element to scroll to is yet to be found or not in view"},{"lineNumber":268,"author":{"gitId":"-"},"content":" if (div \u003d\u003d null || !(this.isInViewport(div))) {"},{"lineNumber":269,"author":{"gitId":"-"},"content":" setTimeout(() \u003d\u003e {"},{"lineNumber":270,"author":{"gitId":"-"},"content":" this.pageScrollService.scroll({"},{"lineNumber":271,"author":{"gitId":"-"},"content":" document: this.document,"},{"lineNumber":272,"author":{"gitId":"-"},"content":" scrollTarget: `#${this.moderatedQuestionId}`,"},{"lineNumber":273,"author":{"gitId":"-"},"content":" scrollOffset: 70,"},{"lineNumber":274,"author":{"gitId":"-"},"content":" });"},{"lineNumber":275,"author":{"gitId":"-"},"content":" this.scrollToQuestion();"},{"lineNumber":276,"author":{"gitId":"-"},"content":" }, 500);"},{"lineNumber":277,"author":{"gitId":"-"},"content":" }"},{"lineNumber":278,"author":{"gitId":"-"},"content":" }"},{"lineNumber":279,"author":{"gitId":"-"},"content":""},{"lineNumber":280,"author":{"gitId":"-"},"content":" ngAfterViewInit(): void {"},{"lineNumber":281,"author":{"gitId":"-"},"content":" if (!this.moderatedQuestionId) {"},{"lineNumber":282,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":283,"author":{"gitId":"-"},"content":" }"},{"lineNumber":284,"author":{"gitId":"-"},"content":" this.scrollToQuestion();"},{"lineNumber":285,"author":{"gitId":"-"},"content":" }"},{"lineNumber":286,"author":{"gitId":"-"},"content":""},{"lineNumber":287,"author":{"gitId":"-"},"content":" private loadCourseInfo(): void {"},{"lineNumber":288,"author":{"gitId":"-"},"content":" this.isCourseLoading \u003d true;"},{"lineNumber":289,"author":{"gitId":"-"},"content":" let request: Observable\u003cCourse\u003e;"},{"lineNumber":290,"author":{"gitId":"-"},"content":" switch (this.intent) {"},{"lineNumber":291,"author":{"gitId":"-"},"content":" case Intent.STUDENT_SUBMISSION:"},{"lineNumber":292,"author":{"gitId":"-"},"content":" if (this.moderatedPerson || this.previewAsPerson) {"},{"lineNumber":293,"author":{"gitId":"-"},"content":" request \u003d this.courseService.getCourseAsInstructor(this.courseId);"},{"lineNumber":294,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":295,"author":{"gitId":"-"},"content":" request \u003d this.courseService.getCourseAsStudent(this.courseId, this.regKey);"},{"lineNumber":296,"author":{"gitId":"-"},"content":" }"},{"lineNumber":297,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":298,"author":{"gitId":"-"},"content":" case Intent.INSTRUCTOR_SUBMISSION:"},{"lineNumber":299,"author":{"gitId":"-"},"content":" request \u003d this.courseService.getCourseAsInstructor(this.courseId, this.regKey);"},{"lineNumber":300,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":301,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":302,"author":{"gitId":"-"},"content":" this.isCourseLoading \u003d false;"},{"lineNumber":303,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":304,"author":{"gitId":"-"},"content":" }"},{"lineNumber":305,"author":{"gitId":"-"},"content":" request.subscribe({"},{"lineNumber":306,"author":{"gitId":"-"},"content":" next: (resp: Course) \u003d\u003e {"},{"lineNumber":307,"author":{"gitId":"-"},"content":" this.courseName \u003d resp.courseName;"},{"lineNumber":308,"author":{"gitId":"-"},"content":" this.courseInstitute \u003d resp.institute;"},{"lineNumber":309,"author":{"gitId":"-"},"content":" this.isCourseLoading \u003d false;"},{"lineNumber":310,"author":{"gitId":"-"},"content":" },"},{"lineNumber":311,"author":{"gitId":"-"},"content":" error: () \u003d\u003e {"},{"lineNumber":312,"author":{"gitId":"-"},"content":" this.isCourseLoading \u003d false;"},{"lineNumber":313,"author":{"gitId":"-"},"content":" },"},{"lineNumber":314,"author":{"gitId":"-"},"content":" });"},{"lineNumber":315,"author":{"gitId":"-"},"content":" }"},{"lineNumber":316,"author":{"gitId":"-"},"content":""},{"lineNumber":317,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":318,"author":{"gitId":"-"},"content":" * Loads the name of the person involved in the submission."},{"lineNumber":319,"author":{"gitId":"-"},"content":" */"},{"lineNumber":320,"author":{"gitId":"-"},"content":" loadPersonName(): void {"},{"lineNumber":321,"author":{"gitId":"-"},"content":" switch (this.intent) {"},{"lineNumber":322,"author":{"gitId":"-"},"content":" case Intent.STUDENT_SUBMISSION:"},{"lineNumber":323,"author":{"gitId":"-"},"content":" this.studentService.getStudent("},{"lineNumber":324,"author":{"gitId":"-"},"content":" this.courseId,"},{"lineNumber":325,"author":{"gitId":"-"},"content":" this.moderatedPerson || this.previewAsPerson,"},{"lineNumber":326,"author":{"gitId":"-"},"content":" this.regKey,"},{"lineNumber":327,"author":{"gitId":"-"},"content":" ).subscribe((student: Student) \u003d\u003e {"},{"lineNumber":328,"author":{"gitId":"dishenggg"},"content":" this.studentId \u003d student.studentId;"},{"lineNumber":329,"author":{"gitId":"-"},"content":" this.personName \u003d student.name;"},{"lineNumber":330,"author":{"gitId":"-"},"content":" this.personEmail \u003d student.email;"},{"lineNumber":331,"author":{"gitId":"dishenggg"},"content":" this.logStudentAccess();"},{"lineNumber":332,"author":{"gitId":"-"},"content":" });"},{"lineNumber":333,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":334,"author":{"gitId":"-"},"content":" case Intent.INSTRUCTOR_SUBMISSION:"},{"lineNumber":335,"author":{"gitId":"-"},"content":" this.instructorService.getInstructor({"},{"lineNumber":336,"author":{"gitId":"-"},"content":" courseId: this.courseId,"},{"lineNumber":337,"author":{"gitId":"-"},"content":" feedbackSessionName: this.feedbackSessionName,"},{"lineNumber":338,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":339,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":340,"author":{"gitId":"-"},"content":" moderatedPerson: this.moderatedPerson,"},{"lineNumber":341,"author":{"gitId":"-"},"content":" previewAs: this.previewAsPerson,"},{"lineNumber":342,"author":{"gitId":"-"},"content":" }).subscribe((instructor: Instructor) \u003d\u003e {"},{"lineNumber":343,"author":{"gitId":"-"},"content":" this.personName \u003d instructor.name;"},{"lineNumber":344,"author":{"gitId":"-"},"content":" this.personEmail \u003d instructor.email;"},{"lineNumber":345,"author":{"gitId":"-"},"content":" });"},{"lineNumber":346,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":347,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":348,"author":{"gitId":"-"},"content":" }"},{"lineNumber":349,"author":{"gitId":"-"},"content":" }"},{"lineNumber":350,"author":{"gitId":"-"},"content":""},{"lineNumber":351,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":352,"author":{"gitId":"-"},"content":" * Redirects to join course link for unregistered student/instructor."},{"lineNumber":353,"author":{"gitId":"-"},"content":" */"},{"lineNumber":354,"author":{"gitId":"-"},"content":" joinCourseForUnregisteredEntity(): void {"},{"lineNumber":355,"author":{"gitId":"-"},"content":" this.navigationService.navigateByURL(\u0027/web/join\u0027, { entitytype: this.entityType, key: this.regKey });"},{"lineNumber":356,"author":{"gitId":"-"},"content":" }"},{"lineNumber":357,"author":{"gitId":"-"},"content":""},{"lineNumber":358,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":359,"author":{"gitId":"-"},"content":" * Loads the feedback session information."},{"lineNumber":360,"author":{"gitId":"-"},"content":" */"},{"lineNumber":361,"author":{"gitId":"-"},"content":" loadFeedbackSession(loginRequired: boolean, auth: AuthInfo): void {"},{"lineNumber":362,"author":{"gitId":"-"},"content":" this.isFeedbackSessionLoading \u003d true;"},{"lineNumber":363,"author":{"gitId":"-"},"content":" const TIME_FORMAT: string \u003d \u0027ddd, DD MMM, YYYY, hh:mm A zz\u0027;"},{"lineNumber":364,"author":{"gitId":"-"},"content":" this.feedbackSessionsService.getFeedbackSession({"},{"lineNumber":365,"author":{"gitId":"-"},"content":" courseId: this.courseId,"},{"lineNumber":366,"author":{"gitId":"-"},"content":" feedbackSessionName: this.feedbackSessionName,"},{"lineNumber":367,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":368,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":369,"author":{"gitId":"-"},"content":" moderatedPerson: this.moderatedPerson,"},{"lineNumber":370,"author":{"gitId":"-"},"content":" previewAs: this.previewAsPerson,"},{"lineNumber":371,"author":{"gitId":"-"},"content":" }).pipe(finalize(() \u003d\u003e {"},{"lineNumber":372,"author":{"gitId":"-"},"content":" this.isFeedbackSessionLoading \u003d false;"},{"lineNumber":373,"author":{"gitId":"-"},"content":" }))"},{"lineNumber":374,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":375,"author":{"gitId":"-"},"content":" next: (feedbackSession: FeedbackSession) \u003d\u003e {"},{"lineNumber":376,"author":{"gitId":"dishenggg"},"content":" this.feedbackSessionId \u003d feedbackSession.feedbackSessionId;"},{"lineNumber":377,"author":{"gitId":"-"},"content":" this.feedbackSessionInstructions \u003d feedbackSession.instructions;"},{"lineNumber":378,"author":{"gitId":"-"},"content":" this.formattedSessionOpeningTime \u003d this.timezoneService"},{"lineNumber":379,"author":{"gitId":"-"},"content":" .formatToString(feedbackSession.submissionStartTimestamp, feedbackSession.timeZone, TIME_FORMAT);"},{"lineNumber":380,"author":{"gitId":"-"},"content":""},{"lineNumber":381,"author":{"gitId":"-"},"content":" this.formattedSessionClosingTime \u003d this.getformattedSessionClosingTime(feedbackSession, TIME_FORMAT);"},{"lineNumber":382,"author":{"gitId":"-"},"content":""},{"lineNumber":383,"author":{"gitId":"-"},"content":" this.feedbackSessionSubmissionStatus \u003d feedbackSession.submissionStatus;"},{"lineNumber":384,"author":{"gitId":"-"},"content":" this.feedbackSessionTimezone \u003d feedbackSession.timeZone;"},{"lineNumber":385,"author":{"gitId":"-"},"content":""},{"lineNumber":386,"author":{"gitId":"dishenggg"},"content":" this.logStudentAccess();"},{"lineNumber":387,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":388,"author":{"gitId":"-"},"content":" // don\u0027t show alert modal in moderation"},{"lineNumber":389,"author":{"gitId":"-"},"content":" if (!this.moderatedPerson) {"},{"lineNumber":390,"author":{"gitId":"-"},"content":" let modalContent: string;"},{"lineNumber":391,"author":{"gitId":"-"},"content":" switch (feedbackSession.submissionStatus) {"},{"lineNumber":392,"author":{"gitId":"-"},"content":" case FeedbackSessionSubmissionStatus.VISIBLE_NOT_OPEN:"},{"lineNumber":393,"author":{"gitId":"-"},"content":" this.isSubmissionFormsDisabled \u003d true;"},{"lineNumber":394,"author":{"gitId":"-"},"content":" modalContent \u003d `\u003cp\u003e\u003cstrong\u003eThe feedback session is currently not open for submissions.\u003c/strong\u003e\u003c/p\u003e"},{"lineNumber":395,"author":{"gitId":"-"},"content":" \u003cp\u003eYou can view the questions and any submitted responses"},{"lineNumber":396,"author":{"gitId":"-"},"content":" for this feedback session but cannot submit new responses.\u003c/p\u003e`;"},{"lineNumber":397,"author":{"gitId":"-"},"content":" this.simpleModalService.openInformationModal("},{"lineNumber":398,"author":{"gitId":"-"},"content":" \u0027Feedback Session Not Open\u0027, SimpleModalType.WARNING, modalContent);"},{"lineNumber":399,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":400,"author":{"gitId":"-"},"content":" case FeedbackSessionSubmissionStatus.OPEN:"},{"lineNumber":401,"author":{"gitId":"-"},"content":" if (this.isFeedbackEndingLessThanFifteenMinutes(feedbackSession)) {"},{"lineNumber":402,"author":{"gitId":"-"},"content":" modalContent \u003d \u0027Warning: you have less than 15 minutes before the submission deadline expires!\u0027;"},{"lineNumber":403,"author":{"gitId":"-"},"content":" this.simpleModalService.openInformationModal("},{"lineNumber":404,"author":{"gitId":"-"},"content":" \u0027Feedback Session Will Be Closing Soon!\u0027, SimpleModalType.WARNING, modalContent);"},{"lineNumber":405,"author":{"gitId":"-"},"content":" }"},{"lineNumber":406,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":407,"author":{"gitId":"-"},"content":" case FeedbackSessionSubmissionStatus.CLOSED:"},{"lineNumber":408,"author":{"gitId":"-"},"content":" this.isSubmissionFormsDisabled \u003d true;"},{"lineNumber":409,"author":{"gitId":"-"},"content":" modalContent \u003d `\u003cp\u003e\u003cstrong\u003eFeedback Session is Closed\u003c/strong\u003e\u003c/p\u003e"},{"lineNumber":410,"author":{"gitId":"-"},"content":" \u003cp\u003eYou can view the questions and any submitted responses"},{"lineNumber":411,"author":{"gitId":"-"},"content":" for this feedback session but cannot submit new responses.\u003c/p\u003e`;"},{"lineNumber":412,"author":{"gitId":"-"},"content":" this.simpleModalService.openInformationModal("},{"lineNumber":413,"author":{"gitId":"-"},"content":" \u0027Feedback Session Closed\u0027, SimpleModalType.WARNING, modalContent);"},{"lineNumber":414,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":415,"author":{"gitId":"-"},"content":" case FeedbackSessionSubmissionStatus.GRACE_PERIOD:"},{"lineNumber":416,"author":{"gitId":"-"},"content":" default:"},{"lineNumber":417,"author":{"gitId":"-"},"content":" }"},{"lineNumber":418,"author":{"gitId":"-"},"content":" }"},{"lineNumber":419,"author":{"gitId":"-"},"content":""},{"lineNumber":420,"author":{"gitId":"-"},"content":" this.loadFeedbackQuestions();"},{"lineNumber":421,"author":{"gitId":"-"},"content":""},{"lineNumber":422,"author":{"gitId":"-"},"content":" // Display note on submission on mobile device"},{"lineNumber":423,"author":{"gitId":"-"},"content":" const mobileDeviceWidth: number \u003d 768;"},{"lineNumber":424,"author":{"gitId":"-"},"content":" if (this.feedbackSessionSubmissionStatus \u003d\u003d\u003d FeedbackSessionSubmissionStatus.OPEN"},{"lineNumber":425,"author":{"gitId":"-"},"content":" \u0026\u0026 window.innerWidth \u003c mobileDeviceWidth) {"},{"lineNumber":426,"author":{"gitId":"-"},"content":" const modalContent: string \u003d `Note that you can use the Submit button to save responses already entered,"},{"lineNumber":427,"author":{"gitId":"-"},"content":" and continue to answer remaining questions after that."},{"lineNumber":428,"author":{"gitId":"-"},"content":" You may also edit your submission any number of times before the closing time of this session.`;"},{"lineNumber":429,"author":{"gitId":"-"},"content":" this.simpleModalService.openInformationModal("},{"lineNumber":430,"author":{"gitId":"-"},"content":" \u0027Note On Submission\u0027, SimpleModalType.INFO, modalContent);"},{"lineNumber":431,"author":{"gitId":"-"},"content":" }"},{"lineNumber":432,"author":{"gitId":"-"},"content":" },"},{"lineNumber":433,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":434,"author":{"gitId":"-"},"content":" if (resp.status \u003d\u003d\u003d 404) {"},{"lineNumber":435,"author":{"gitId":"-"},"content":" const message \u003d \u0027The session does not exist \u0027"},{"lineNumber":436,"author":{"gitId":"-"},"content":" + \u0027(most likely deleted by an instructor after the submission link was sent).\u0027;"},{"lineNumber":437,"author":{"gitId":"-"},"content":" this.simpleModalService.openInformationModal(\u0027Feedback Session Does Not Exist!\u0027, SimpleModalType.DANGER,"},{"lineNumber":438,"author":{"gitId":"-"},"content":" message,"},{"lineNumber":439,"author":{"gitId":"-"},"content":" {"},{"lineNumber":440,"author":{"gitId":"-"},"content":" onClosed: () \u003d\u003e this.navigationService.navigateByURL("},{"lineNumber":441,"author":{"gitId":"-"},"content":" this.loggedInUser ? `/web/${this.entityType}/home` : \u0027/web/front/home\u0027),"},{"lineNumber":442,"author":{"gitId":"-"},"content":" },"},{"lineNumber":443,"author":{"gitId":"-"},"content":" { backdrop: \u0027static\u0027 });"},{"lineNumber":444,"author":{"gitId":"-"},"content":" } else if (resp.status \u003d\u003d\u003d 403) {"},{"lineNumber":445,"author":{"gitId":"-"},"content":" if (loginRequired \u0026\u0026 !auth.user) {"},{"lineNumber":446,"author":{"gitId":"-"},"content":" // There is no logged in user for a valid, used registration key, redirect to login page"},{"lineNumber":447,"author":{"gitId":"-"},"content":" if (this.entityType \u003d\u003d\u003d \u0027student\u0027) {"},{"lineNumber":448,"author":{"gitId":"-"},"content":" window.location.href \u003d `${this.backendUrl}${auth.studentLoginUrl}`;"},{"lineNumber":449,"author":{"gitId":"-"},"content":" } else if (this.entityType \u003d\u003d\u003d \u0027instructor\u0027) {"},{"lineNumber":450,"author":{"gitId":"-"},"content":" window.location.href \u003d `${this.backendUrl}${auth.instructorLoginUrl}`;"},{"lineNumber":451,"author":{"gitId":"-"},"content":" }"},{"lineNumber":452,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":453,"author":{"gitId":"-"},"content":" this.simpleModalService.openInformationModal(\u0027Not Authorised To Access!\u0027, SimpleModalType.DANGER,"},{"lineNumber":454,"author":{"gitId":"-"},"content":" resp.error.message,"},{"lineNumber":455,"author":{"gitId":"-"},"content":" {"},{"lineNumber":456,"author":{"gitId":"-"},"content":" onClosed: () \u003d\u003e this.navigationService.navigateByURL("},{"lineNumber":457,"author":{"gitId":"-"},"content":" this.loggedInUser ? `/web/${this.entityType}/home` : \u0027/web/front/home\u0027),"},{"lineNumber":458,"author":{"gitId":"-"},"content":" },"},{"lineNumber":459,"author":{"gitId":"-"},"content":" { backdrop: \u0027static\u0027 });"},{"lineNumber":460,"author":{"gitId":"-"},"content":" }"},{"lineNumber":461,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":462,"author":{"gitId":"-"},"content":" this.navigationService.navigateWithErrorMessage("},{"lineNumber":463,"author":{"gitId":"-"},"content":" `/web/${this.entityType}/home`, resp.error.message);"},{"lineNumber":464,"author":{"gitId":"-"},"content":" }"},{"lineNumber":465,"author":{"gitId":"-"},"content":" },"},{"lineNumber":466,"author":{"gitId":"-"},"content":" });"},{"lineNumber":467,"author":{"gitId":"-"},"content":" }"},{"lineNumber":468,"author":{"gitId":"-"},"content":""},{"lineNumber":469,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":470,"author":{"gitId":"-"},"content":" * Loads feedback questions to submit."},{"lineNumber":471,"author":{"gitId":"-"},"content":" */"},{"lineNumber":472,"author":{"gitId":"-"},"content":" loadFeedbackQuestions(): void {"},{"lineNumber":473,"author":{"gitId":"-"},"content":" this.isFeedbackSessionQuestionsLoading \u003d true;"},{"lineNumber":474,"author":{"gitId":"-"},"content":" this.questionSubmissionForms \u003d [];"},{"lineNumber":475,"author":{"gitId":"-"},"content":" this.feedbackQuestionsService.getFeedbackQuestions({"},{"lineNumber":476,"author":{"gitId":"-"},"content":" courseId: this.courseId,"},{"lineNumber":477,"author":{"gitId":"-"},"content":" feedbackSessionName: this.feedbackSessionName,"},{"lineNumber":478,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":479,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":480,"author":{"gitId":"-"},"content":" moderatedPerson: this.moderatedPerson,"},{"lineNumber":481,"author":{"gitId":"-"},"content":" previewAs: this.previewAsPerson,"},{"lineNumber":482,"author":{"gitId":"-"},"content":" }).pipe(finalize(() \u003d\u003e {"},{"lineNumber":483,"author":{"gitId":"-"},"content":" this.isFeedbackSessionQuestionsLoading \u003d false;"},{"lineNumber":484,"author":{"gitId":"-"},"content":" }))"},{"lineNumber":485,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":486,"author":{"gitId":"-"},"content":" next: (response: FeedbackQuestionsResponse) \u003d\u003e {"},{"lineNumber":487,"author":{"gitId":"-"},"content":" response.questions.forEach((feedbackQuestion: FeedbackQuestion) \u003d\u003e {"},{"lineNumber":488,"author":{"gitId":"-"},"content":" const model: QuestionSubmissionFormModel \u003d {"},{"lineNumber":489,"author":{"gitId":"-"},"content":" isLoading: false,"},{"lineNumber":490,"author":{"gitId":"-"},"content":" isLoaded: false,"},{"lineNumber":491,"author":{"gitId":"-"},"content":" isTabExpanded: true,"},{"lineNumber":492,"author":{"gitId":"-"},"content":" feedbackQuestionId: feedbackQuestion.feedbackQuestionId,"},{"lineNumber":493,"author":{"gitId":"-"},"content":""},{"lineNumber":494,"author":{"gitId":"-"},"content":" questionNumber: feedbackQuestion.questionNumber,"},{"lineNumber":495,"author":{"gitId":"-"},"content":" questionBrief: feedbackQuestion.questionBrief,"},{"lineNumber":496,"author":{"gitId":"-"},"content":" questionDescription: feedbackQuestion.questionDescription,"},{"lineNumber":497,"author":{"gitId":"-"},"content":""},{"lineNumber":498,"author":{"gitId":"-"},"content":" giverType: feedbackQuestion.giverType,"},{"lineNumber":499,"author":{"gitId":"-"},"content":" recipientType: feedbackQuestion.recipientType,"},{"lineNumber":500,"author":{"gitId":"-"},"content":" recipientList: [],"},{"lineNumber":501,"author":{"gitId":"-"},"content":" recipientSubmissionForms: [],"},{"lineNumber":502,"author":{"gitId":"-"},"content":""},{"lineNumber":503,"author":{"gitId":"-"},"content":" questionType: feedbackQuestion.questionType,"},{"lineNumber":504,"author":{"gitId":"-"},"content":" questionDetails: feedbackQuestion.questionDetails,"},{"lineNumber":505,"author":{"gitId":"-"},"content":""},{"lineNumber":506,"author":{"gitId":"-"},"content":" numberOfEntitiesToGiveFeedbackToSetting: feedbackQuestion.numberOfEntitiesToGiveFeedbackToSetting,"},{"lineNumber":507,"author":{"gitId":"-"},"content":" customNumberOfEntitiesToGiveFeedbackTo: feedbackQuestion.customNumberOfEntitiesToGiveFeedbackTo"},{"lineNumber":508,"author":{"gitId":"-"},"content":" ? feedbackQuestion.customNumberOfEntitiesToGiveFeedbackTo : 0,"},{"lineNumber":509,"author":{"gitId":"-"},"content":""},{"lineNumber":510,"author":{"gitId":"-"},"content":" showGiverNameTo: feedbackQuestion.showGiverNameTo,"},{"lineNumber":511,"author":{"gitId":"-"},"content":" showRecipientNameTo: feedbackQuestion.showRecipientNameTo,"},{"lineNumber":512,"author":{"gitId":"-"},"content":" showResponsesTo: feedbackQuestion.showResponsesTo,"},{"lineNumber":513,"author":{"gitId":"-"},"content":""},{"lineNumber":514,"author":{"gitId":"-"},"content":" hasResponseChangedForRecipients: new Map\u003cstring, boolean\u003e(),"},{"lineNumber":515,"author":{"gitId":"-"},"content":" isTabExpandedForRecipients: new Map\u003cstring, boolean\u003e(),"},{"lineNumber":516,"author":{"gitId":"-"},"content":" };"},{"lineNumber":517,"author":{"gitId":"-"},"content":" this.questionSubmissionForms.push(model);"},{"lineNumber":518,"author":{"gitId":"-"},"content":" });"},{"lineNumber":519,"author":{"gitId":"-"},"content":""},{"lineNumber":520,"author":{"gitId":"-"},"content":" this.isQuestionCountOne \u003d this.questionSubmissionForms.length \u003d\u003d\u003d 1;"},{"lineNumber":521,"author":{"gitId":"-"},"content":" },"},{"lineNumber":522,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":523,"author":{"gitId":"-"},"content":" this.handleError(resp);"},{"lineNumber":524,"author":{"gitId":"-"},"content":" },"},{"lineNumber":525,"author":{"gitId":"-"},"content":" });"},{"lineNumber":526,"author":{"gitId":"-"},"content":" }"},{"lineNumber":527,"author":{"gitId":"-"},"content":""},{"lineNumber":528,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":529,"author":{"gitId":"-"},"content":" * Tracks the question submission form by feedback question id."},{"lineNumber":530,"author":{"gitId":"-"},"content":" *"},{"lineNumber":531,"author":{"gitId":"-"},"content":" * @see https://angular.io/api/common/NgForOf#properties"},{"lineNumber":532,"author":{"gitId":"-"},"content":" */"},{"lineNumber":533,"author":{"gitId":"-"},"content":" trackQuestionSubmissionFormByFn(_: any, item: QuestionSubmissionFormModel): any {"},{"lineNumber":534,"author":{"gitId":"-"},"content":" return item.feedbackQuestionId;"},{"lineNumber":535,"author":{"gitId":"-"},"content":" }"},{"lineNumber":536,"author":{"gitId":"-"},"content":""},{"lineNumber":537,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":538,"author":{"gitId":"-"},"content":" * Loads the feedback question recipients for the question."},{"lineNumber":539,"author":{"gitId":"-"},"content":" */"},{"lineNumber":540,"author":{"gitId":"-"},"content":" loadFeedbackQuestionRecipientsForQuestion(model: QuestionSubmissionFormModel): void {"},{"lineNumber":541,"author":{"gitId":"-"},"content":" this.feedbackQuestionsService.loadFeedbackQuestionRecipients({"},{"lineNumber":542,"author":{"gitId":"-"},"content":" questionId: model.feedbackQuestionId,"},{"lineNumber":543,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":544,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":545,"author":{"gitId":"-"},"content":" moderatedPerson: this.moderatedPerson,"},{"lineNumber":546,"author":{"gitId":"-"},"content":" previewAs: this.previewAsPerson,"},{"lineNumber":547,"author":{"gitId":"-"},"content":" }).subscribe({"},{"lineNumber":548,"author":{"gitId":"-"},"content":" next: (response: FeedbackQuestionRecipients) \u003d\u003e {"},{"lineNumber":549,"author":{"gitId":"-"},"content":" response.recipients.forEach((recipient: FeedbackQuestionRecipient) \u003d\u003e {"},{"lineNumber":550,"author":{"gitId":"-"},"content":" model.recipientList.push({"},{"lineNumber":551,"author":{"gitId":"-"},"content":" recipientIdentifier: recipient.identifier,"},{"lineNumber":552,"author":{"gitId":"-"},"content":" recipientName: recipient.name,"},{"lineNumber":553,"author":{"gitId":"-"},"content":" recipientSection: recipient.section,"},{"lineNumber":554,"author":{"gitId":"-"},"content":" recipientTeam: recipient.team,"},{"lineNumber":555,"author":{"gitId":"-"},"content":" });"},{"lineNumber":556,"author":{"gitId":"-"},"content":" });"},{"lineNumber":557,"author":{"gitId":"-"},"content":""},{"lineNumber":558,"author":{"gitId":"-"},"content":" if (!this.hasLoadedAllRecipients) {"},{"lineNumber":559,"author":{"gitId":"-"},"content":" // Keep track of the recipient to questions mapping and the ungroupable questions even before"},{"lineNumber":560,"author":{"gitId":"-"},"content":" // changing to grouping questions by recipients view"},{"lineNumber":561,"author":{"gitId":"-"},"content":" if (this.getQuestionSubmissionFormModeInDefaultView(model) \u003d\u003d\u003d QuestionSubmissionFormMode.FIXED_RECIPIENT"},{"lineNumber":562,"author":{"gitId":"-"},"content":" \u0026\u0026 model.questionType !\u003d\u003d FeedbackQuestionType.RANK_RECIPIENTS"},{"lineNumber":563,"author":{"gitId":"-"},"content":" \u0026\u0026 model.questionType !\u003d\u003d FeedbackQuestionType.CONSTSUM_RECIPIENTS"},{"lineNumber":564,"author":{"gitId":"-"},"content":" \u0026\u0026 model.questionType !\u003d\u003d FeedbackQuestionType.CONTRIB) {"},{"lineNumber":565,"author":{"gitId":"-"},"content":" model.recipientList.forEach((recipient: FeedbackResponseRecipient) \u003d\u003e {"},{"lineNumber":566,"author":{"gitId":"-"},"content":" this.addQuestionForRecipient(recipient.recipientIdentifier, model.questionNumber);"},{"lineNumber":567,"author":{"gitId":"-"},"content":" });"},{"lineNumber":568,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":569,"author":{"gitId":"-"},"content":" this.ungroupableQuestions.add(model.questionNumber);"},{"lineNumber":570,"author":{"gitId":"-"},"content":" }"},{"lineNumber":571,"author":{"gitId":"-"},"content":" }"},{"lineNumber":572,"author":{"gitId":"-"},"content":""},{"lineNumber":573,"author":{"gitId":"-"},"content":" if (this.previewAsPerson) {"},{"lineNumber":574,"author":{"gitId":"-"},"content":" // don\u0027t load responses in preview mode"},{"lineNumber":575,"author":{"gitId":"-"},"content":" // generate a list of empty response box"},{"lineNumber":576,"author":{"gitId":"-"},"content":" const formMode: QuestionSubmissionFormMode \u003d this.getQuestionSubmissionFormModeInDefaultView(model);"},{"lineNumber":577,"author":{"gitId":"-"},"content":" model.recipientList.forEach((recipient: FeedbackResponseRecipient) \u003d\u003e {"},{"lineNumber":578,"author":{"gitId":"-"},"content":" if (formMode \u003d\u003d\u003d QuestionSubmissionFormMode.FLEXIBLE_RECIPIENT"},{"lineNumber":579,"author":{"gitId":"-"},"content":" \u0026\u0026 model.recipientSubmissionForms.length \u003e\u003d model.customNumberOfEntitiesToGiveFeedbackTo) {"},{"lineNumber":580,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":581,"author":{"gitId":"-"},"content":" }"},{"lineNumber":582,"author":{"gitId":"-"},"content":""},{"lineNumber":583,"author":{"gitId":"-"},"content":" let recipientIdentifier: string \u003d \u0027\u0027;"},{"lineNumber":584,"author":{"gitId":"-"},"content":" if (formMode !\u003d\u003d QuestionSubmissionFormMode.FLEXIBLE_RECIPIENT) {"},{"lineNumber":585,"author":{"gitId":"-"},"content":" recipientIdentifier \u003d recipient.recipientIdentifier;"},{"lineNumber":586,"author":{"gitId":"-"},"content":" }"},{"lineNumber":587,"author":{"gitId":"-"},"content":""},{"lineNumber":588,"author":{"gitId":"-"},"content":" model.recipientSubmissionForms.push({"},{"lineNumber":589,"author":{"gitId":"-"},"content":" recipientIdentifier,"},{"lineNumber":590,"author":{"gitId":"-"},"content":" responseDetails: this.feedbackResponsesService.getDefaultFeedbackResponseDetails(model.questionType),"},{"lineNumber":591,"author":{"gitId":"-"},"content":" responseId: \u0027\u0027,"},{"lineNumber":592,"author":{"gitId":"-"},"content":" isValid: true,"},{"lineNumber":593,"author":{"gitId":"-"},"content":" });"},{"lineNumber":594,"author":{"gitId":"-"},"content":" });"},{"lineNumber":595,"author":{"gitId":"-"},"content":" model.isLoading \u003d false;"},{"lineNumber":596,"author":{"gitId":"-"},"content":" model.isLoaded \u003d true;"},{"lineNumber":597,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":598,"author":{"gitId":"-"},"content":" this.loadFeedbackResponses(model);"},{"lineNumber":599,"author":{"gitId":"-"},"content":" }"},{"lineNumber":600,"author":{"gitId":"-"},"content":" },"},{"lineNumber":601,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e this.statusMessageService.showErrorToast(resp.error.message),"},{"lineNumber":602,"author":{"gitId":"-"},"content":" });"},{"lineNumber":603,"author":{"gitId":"-"},"content":" }"},{"lineNumber":604,"author":{"gitId":"-"},"content":""},{"lineNumber":605,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":606,"author":{"gitId":"-"},"content":" * Gets the form mode of the question submission form."},{"lineNumber":607,"author":{"gitId":"-"},"content":" */"},{"lineNumber":608,"author":{"gitId":"-"},"content":" getQuestionSubmissionFormMode(model: QuestionSubmissionFormModel, recipientListLength: number):"},{"lineNumber":609,"author":{"gitId":"-"},"content":" QuestionSubmissionFormMode {"},{"lineNumber":610,"author":{"gitId":"-"},"content":" const isNumberOfEntitiesToGiveFeedbackToSettingLimited: boolean \u003d"},{"lineNumber":611,"author":{"gitId":"-"},"content":" (model.recipientType \u003d\u003d\u003d FeedbackParticipantType.STUDENTS"},{"lineNumber":612,"author":{"gitId":"-"},"content":" || model.recipientType \u003d\u003d\u003d FeedbackParticipantType.STUDENTS_EXCLUDING_SELF"},{"lineNumber":613,"author":{"gitId":"-"},"content":" || model.recipientType \u003d\u003d\u003d FeedbackParticipantType.STUDENTS_IN_SAME_SECTION"},{"lineNumber":614,"author":{"gitId":"-"},"content":" || model.recipientType \u003d\u003d\u003d FeedbackParticipantType.TEAMS"},{"lineNumber":615,"author":{"gitId":"-"},"content":" || model.recipientType \u003d\u003d\u003d FeedbackParticipantType.TEAMS_EXCLUDING_SELF"},{"lineNumber":616,"author":{"gitId":"-"},"content":" || model.recipientType \u003d\u003d\u003d FeedbackParticipantType.TEAMS_IN_SAME_SECTION"},{"lineNumber":617,"author":{"gitId":"-"},"content":" || model.recipientType \u003d\u003d\u003d FeedbackParticipantType.INSTRUCTORS)"},{"lineNumber":618,"author":{"gitId":"-"},"content":" \u0026\u0026 model.numberOfEntitiesToGiveFeedbackToSetting \u003d\u003d\u003d NumberOfEntitiesToGiveFeedbackToSetting.CUSTOM"},{"lineNumber":619,"author":{"gitId":"-"},"content":" \u0026\u0026 recipientListLength \u003e model.customNumberOfEntitiesToGiveFeedbackTo;"},{"lineNumber":620,"author":{"gitId":"-"},"content":""},{"lineNumber":621,"author":{"gitId":"-"},"content":" return isNumberOfEntitiesToGiveFeedbackToSettingLimited"},{"lineNumber":622,"author":{"gitId":"-"},"content":" ? QuestionSubmissionFormMode.FLEXIBLE_RECIPIENT : QuestionSubmissionFormMode.FIXED_RECIPIENT;"},{"lineNumber":623,"author":{"gitId":"-"},"content":" }"},{"lineNumber":624,"author":{"gitId":"-"},"content":""},{"lineNumber":625,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":626,"author":{"gitId":"-"},"content":" * Gets the form mode of the question submission form in {@code DEFAULT} view."},{"lineNumber":627,"author":{"gitId":"-"},"content":" */"},{"lineNumber":628,"author":{"gitId":"-"},"content":" getQuestionSubmissionFormModeInDefaultView(model: QuestionSubmissionFormModel): QuestionSubmissionFormMode {"},{"lineNumber":629,"author":{"gitId":"-"},"content":" return this.getQuestionSubmissionFormMode(model, model.recipientList.length);"},{"lineNumber":630,"author":{"gitId":"-"},"content":" }"},{"lineNumber":631,"author":{"gitId":"-"},"content":""},{"lineNumber":632,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":633,"author":{"gitId":"-"},"content":" * Loads the responses of the feedback question to {@recipientSubmissionForms} in the model."},{"lineNumber":634,"author":{"gitId":"-"},"content":" */"},{"lineNumber":635,"author":{"gitId":"-"},"content":" loadFeedbackResponses(model: QuestionSubmissionFormModel): void {"},{"lineNumber":636,"author":{"gitId":"-"},"content":" this.feedbackResponsesService.getFeedbackResponse({"},{"lineNumber":637,"author":{"gitId":"-"},"content":" questionId: model.feedbackQuestionId,"},{"lineNumber":638,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":639,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":640,"author":{"gitId":"-"},"content":" moderatedPerson: this.moderatedPerson,"},{"lineNumber":641,"author":{"gitId":"-"},"content":" }).pipe(finalize(() \u003d\u003e {"},{"lineNumber":642,"author":{"gitId":"-"},"content":" model.isLoading \u003d false;"},{"lineNumber":643,"author":{"gitId":"-"},"content":" model.isLoaded \u003d true;"},{"lineNumber":644,"author":{"gitId":"-"},"content":" }))"},{"lineNumber":645,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":646,"author":{"gitId":"-"},"content":" next: (existingResponses: FeedbackResponsesResponse) \u003d\u003e {"},{"lineNumber":647,"author":{"gitId":"-"},"content":" if (this.getQuestionSubmissionFormModeInDefaultView(model) \u003d\u003d\u003d QuestionSubmissionFormMode.FIXED_RECIPIENT) {"},{"lineNumber":648,"author":{"gitId":"-"},"content":" // need to generate a full list of submission forms"},{"lineNumber":649,"author":{"gitId":"-"},"content":" model.recipientList.forEach((recipient: FeedbackResponseRecipient) \u003d\u003e {"},{"lineNumber":650,"author":{"gitId":"-"},"content":" const matchedExistingResponse: FeedbackResponse | undefined \u003d"},{"lineNumber":651,"author":{"gitId":"-"},"content":" existingResponses.responses.find("},{"lineNumber":652,"author":{"gitId":"-"},"content":" (response: FeedbackResponse) \u003d\u003e response.recipientIdentifier \u003d\u003d\u003d recipient.recipientIdentifier);"},{"lineNumber":653,"author":{"gitId":"-"},"content":" const submissionForm: FeedbackResponseRecipientSubmissionFormModel \u003d {"},{"lineNumber":654,"author":{"gitId":"-"},"content":" recipientIdentifier: recipient.recipientIdentifier,"},{"lineNumber":655,"author":{"gitId":"-"},"content":" responseDetails: matchedExistingResponse"},{"lineNumber":656,"author":{"gitId":"-"},"content":" ? matchedExistingResponse.responseDetails"},{"lineNumber":657,"author":{"gitId":"-"},"content":" : this.feedbackResponsesService.getDefaultFeedbackResponseDetails(model.questionType),"},{"lineNumber":658,"author":{"gitId":"-"},"content":" responseId: matchedExistingResponse ? matchedExistingResponse.feedbackResponseId : \u0027\u0027,"},{"lineNumber":659,"author":{"gitId":"-"},"content":" isValid: true,"},{"lineNumber":660,"author":{"gitId":"-"},"content":" };"},{"lineNumber":661,"author":{"gitId":"-"},"content":" if (matchedExistingResponse \u0026\u0026 matchedExistingResponse.giverComment) {"},{"lineNumber":662,"author":{"gitId":"-"},"content":" submissionForm.commentByGiver \u003d this.getCommentModel("},{"lineNumber":663,"author":{"gitId":"-"},"content":" matchedExistingResponse.giverComment, recipient.recipientIdentifier);"},{"lineNumber":664,"author":{"gitId":"-"},"content":" }"},{"lineNumber":665,"author":{"gitId":"-"},"content":" model.recipientSubmissionForms.push(submissionForm);"},{"lineNumber":666,"author":{"gitId":"-"},"content":" });"},{"lineNumber":667,"author":{"gitId":"-"},"content":" }"},{"lineNumber":668,"author":{"gitId":"-"},"content":""},{"lineNumber":669,"author":{"gitId":"-"},"content":" if (this.getQuestionSubmissionFormModeInDefaultView(model)"},{"lineNumber":670,"author":{"gitId":"-"},"content":" \u003d\u003d\u003d QuestionSubmissionFormMode.FLEXIBLE_RECIPIENT) {"},{"lineNumber":671,"author":{"gitId":"-"},"content":" // need to generate limited number of submission forms"},{"lineNumber":672,"author":{"gitId":"-"},"content":" let numberOfRecipientSubmissionFormsNeeded: number \u003d"},{"lineNumber":673,"author":{"gitId":"-"},"content":" model.customNumberOfEntitiesToGiveFeedbackTo - existingResponses.responses.length;"},{"lineNumber":674,"author":{"gitId":"-"},"content":""},{"lineNumber":675,"author":{"gitId":"-"},"content":" existingResponses.responses.forEach((response: FeedbackResponse) \u003d\u003e {"},{"lineNumber":676,"author":{"gitId":"-"},"content":" const submissionForm: FeedbackResponseRecipientSubmissionFormModel \u003d {"},{"lineNumber":677,"author":{"gitId":"-"},"content":" recipientIdentifier: response.recipientIdentifier,"},{"lineNumber":678,"author":{"gitId":"-"},"content":" responseDetails: response.responseDetails,"},{"lineNumber":679,"author":{"gitId":"-"},"content":" responseId: response.feedbackResponseId,"},{"lineNumber":680,"author":{"gitId":"-"},"content":" isValid: true,"},{"lineNumber":681,"author":{"gitId":"-"},"content":" };"},{"lineNumber":682,"author":{"gitId":"-"},"content":" if (response.giverComment) {"},{"lineNumber":683,"author":{"gitId":"-"},"content":" submissionForm.commentByGiver \u003d this.getCommentModel("},{"lineNumber":684,"author":{"gitId":"-"},"content":" response.giverComment, response.recipientIdentifier);"},{"lineNumber":685,"author":{"gitId":"-"},"content":" }"},{"lineNumber":686,"author":{"gitId":"-"},"content":" model.recipientSubmissionForms.push(submissionForm);"},{"lineNumber":687,"author":{"gitId":"-"},"content":" });"},{"lineNumber":688,"author":{"gitId":"-"},"content":""},{"lineNumber":689,"author":{"gitId":"-"},"content":" // generate empty submission forms"},{"lineNumber":690,"author":{"gitId":"-"},"content":" while (numberOfRecipientSubmissionFormsNeeded \u003e 0) {"},{"lineNumber":691,"author":{"gitId":"-"},"content":" model.recipientSubmissionForms.push({"},{"lineNumber":692,"author":{"gitId":"-"},"content":" recipientIdentifier: \u0027\u0027,"},{"lineNumber":693,"author":{"gitId":"-"},"content":" responseDetails: this.feedbackResponsesService.getDefaultFeedbackResponseDetails(model.questionType),"},{"lineNumber":694,"author":{"gitId":"-"},"content":" responseId: \u0027\u0027,"},{"lineNumber":695,"author":{"gitId":"-"},"content":" isValid: true,"},{"lineNumber":696,"author":{"gitId":"-"},"content":" });"},{"lineNumber":697,"author":{"gitId":"-"},"content":" numberOfRecipientSubmissionFormsNeeded -\u003d 1;"},{"lineNumber":698,"author":{"gitId":"-"},"content":" }"},{"lineNumber":699,"author":{"gitId":"-"},"content":" }"},{"lineNumber":700,"author":{"gitId":"-"},"content":" },"},{"lineNumber":701,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e this.statusMessageService.showErrorToast(resp.error.message),"},{"lineNumber":702,"author":{"gitId":"-"},"content":" });"},{"lineNumber":703,"author":{"gitId":"-"},"content":" }"},{"lineNumber":704,"author":{"gitId":"-"},"content":""},{"lineNumber":705,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":706,"author":{"gitId":"-"},"content":" * Gets the comment model for a given comment."},{"lineNumber":707,"author":{"gitId":"-"},"content":" */"},{"lineNumber":708,"author":{"gitId":"-"},"content":" getCommentModel(comment: FeedbackResponseComment, recipientIdentifier: string): CommentRowModel {"},{"lineNumber":709,"author":{"gitId":"-"},"content":" return {"},{"lineNumber":710,"author":{"gitId":"-"},"content":" originalComment: comment,"},{"lineNumber":711,"author":{"gitId":"-"},"content":" originalRecipientIdentifier: recipientIdentifier,"},{"lineNumber":712,"author":{"gitId":"-"},"content":" commentEditFormModel: {"},{"lineNumber":713,"author":{"gitId":"-"},"content":" commentText: comment.commentText,"},{"lineNumber":714,"author":{"gitId":"-"},"content":" // the participant comment shall not use custom visibilities"},{"lineNumber":715,"author":{"gitId":"-"},"content":" isUsingCustomVisibilities: false,"},{"lineNumber":716,"author":{"gitId":"-"},"content":" showCommentTo: [],"},{"lineNumber":717,"author":{"gitId":"-"},"content":" showGiverNameTo: [],"},{"lineNumber":718,"author":{"gitId":"-"},"content":" },"},{"lineNumber":719,"author":{"gitId":"-"},"content":" timezone: this.feedbackSessionTimezone,"},{"lineNumber":720,"author":{"gitId":"-"},"content":" isEditing: false,"},{"lineNumber":721,"author":{"gitId":"-"},"content":" };"},{"lineNumber":722,"author":{"gitId":"-"},"content":" }"},{"lineNumber":723,"author":{"gitId":"-"},"content":""},{"lineNumber":724,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":725,"author":{"gitId":"-"},"content":" * Checks whether there is any submission forms in the current page."},{"lineNumber":726,"author":{"gitId":"-"},"content":" */"},{"lineNumber":727,"author":{"gitId":"-"},"content":" get questionsNeedingSubmission(): QuestionSubmissionFormModel[] {"},{"lineNumber":728,"author":{"gitId":"-"},"content":" return this.questionSubmissionForms"},{"lineNumber":729,"author":{"gitId":"-"},"content":" .filter((model: QuestionSubmissionFormModel) \u003d\u003e model.recipientSubmissionForms.length !\u003d\u003d 0);"},{"lineNumber":730,"author":{"gitId":"-"},"content":" }"},{"lineNumber":731,"author":{"gitId":"-"},"content":""},{"lineNumber":732,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":733,"author":{"gitId":"-"},"content":" * Saves the feedback responses for the specific questions."},{"lineNumber":734,"author":{"gitId":"-"},"content":" *"},{"lineNumber":735,"author":{"gitId":"-"},"content":" * \u003cp\u003eAll empty feedback response will be deleted; For non-empty responses, update/create them if necessary."},{"lineNumber":736,"author":{"gitId":"-"},"content":" *"},{"lineNumber":737,"author":{"gitId":"-"},"content":" * @param questionSubmissionForms An array of question submission forms to be saved"},{"lineNumber":738,"author":{"gitId":"-"},"content":" * @param isSubmitAll Is the \u0027Submit Responses for All Questions\u0027 button clicked when saving responses"},{"lineNumber":739,"author":{"gitId":"-"},"content":" * @param recipientId The recipient identifier of the selected recipient when saving responses for this recipient"},{"lineNumber":740,"author":{"gitId":"-"},"content":" * only. This parameter will be null when saving responses for all questions or saving responses for one question."},{"lineNumber":741,"author":{"gitId":"-"},"content":" */"},{"lineNumber":742,"author":{"gitId":"-"},"content":" saveFeedbackResponses(questionSubmissionForms: QuestionSubmissionFormModel[],"},{"lineNumber":743,"author":{"gitId":"-"},"content":" isSubmitAll: boolean, recipientId: string | null): void {"},{"lineNumber":744,"author":{"gitId":"-"},"content":" if (isSubmitAll) {"},{"lineNumber":745,"author":{"gitId":"-"},"content":" this.isSubmitAllClicked \u003d true;"},{"lineNumber":746,"author":{"gitId":"-"},"content":" }"},{"lineNumber":747,"author":{"gitId":"-"},"content":""},{"lineNumber":748,"author":{"gitId":"-"},"content":" const notYetAnsweredQuestions: Set\u003cnumber\u003e \u003d new Set();"},{"lineNumber":749,"author":{"gitId":"-"},"content":" const requestIds: Record\u003cstring, string\u003e \u003d {};"},{"lineNumber":750,"author":{"gitId":"-"},"content":" const answers: Record\u003cstring, FeedbackResponse[]\u003e \u003d {};"},{"lineNumber":751,"author":{"gitId":"-"},"content":" const failToSaveQuestions: Record\u003cnumber, string\u003e \u003d {}; // Map of question number to error message"},{"lineNumber":752,"author":{"gitId":"-"},"content":" const savingRequests: Observable\u003cany\u003e[] \u003d [];"},{"lineNumber":753,"author":{"gitId":"-"},"content":""},{"lineNumber":754,"author":{"gitId":"-"},"content":" this.logService.createFeedbackSessionLog({"},{"lineNumber":755,"author":{"gitId":"-"},"content":" courseId: this.courseId,"},{"lineNumber":756,"author":{"gitId":"-"},"content":" feedbackSessionName: this.feedbackSessionName,"},{"lineNumber":757,"author":{"gitId":"-"},"content":" studentEmail: this.personEmail,"},{"lineNumber":758,"author":{"gitId":"-"},"content":" logType: FeedbackSessionLogType.SUBMISSION,"},{"lineNumber":759,"author":{"gitId":"dishenggg"},"content":" feedbackSessionId: this.feedbackSessionId,"},{"lineNumber":760,"author":{"gitId":"dishenggg"},"content":" studentId: this.studentId,"},{"lineNumber":761,"author":{"gitId":"dishenggg"},"content":" }).subscribe();"},{"lineNumber":762,"author":{"gitId":"-"},"content":""},{"lineNumber":763,"author":{"gitId":"-"},"content":" questionSubmissionForms.forEach((questionSubmissionFormModel: QuestionSubmissionFormModel) \u003d\u003e {"},{"lineNumber":764,"author":{"gitId":"-"},"content":" let isQuestionFullyAnswered: boolean \u003d true;"},{"lineNumber":765,"author":{"gitId":"-"},"content":""},{"lineNumber":766,"author":{"gitId":"-"},"content":" const responses: FeedbackResponseRequest[] \u003d [];"},{"lineNumber":767,"author":{"gitId":"-"},"content":""},{"lineNumber":768,"author":{"gitId":"-"},"content":" questionSubmissionFormModel.recipientSubmissionForms"},{"lineNumber":769,"author":{"gitId":"-"},"content":" .forEach((recipientSubmissionFormModel: FeedbackResponseRecipientSubmissionFormModel) \u003d\u003e {"},{"lineNumber":770,"author":{"gitId":"-"},"content":" if (!recipientSubmissionFormModel.isValid) {"},{"lineNumber":771,"author":{"gitId":"-"},"content":" failToSaveQuestions[questionSubmissionFormModel.questionNumber] \u003d"},{"lineNumber":772,"author":{"gitId":"-"},"content":" \u0027Invalid responses provided. Please check question constraints.\u0027;"},{"lineNumber":773,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":774,"author":{"gitId":"-"},"content":" }"},{"lineNumber":775,"author":{"gitId":"-"},"content":" const isFeedbackResponseDetailsEmpty: boolean \u003d"},{"lineNumber":776,"author":{"gitId":"-"},"content":" this.feedbackResponsesService.isFeedbackResponseDetailsEmpty("},{"lineNumber":777,"author":{"gitId":"-"},"content":" questionSubmissionFormModel.questionType, recipientSubmissionFormModel.responseDetails);"},{"lineNumber":778,"author":{"gitId":"-"},"content":""},{"lineNumber":779,"author":{"gitId":"-"},"content":" if (!isFeedbackResponseDetailsEmpty) {"},{"lineNumber":780,"author":{"gitId":"-"},"content":" responses.push({"},{"lineNumber":781,"author":{"gitId":"-"},"content":" recipient: recipientSubmissionFormModel.recipientIdentifier,"},{"lineNumber":782,"author":{"gitId":"-"},"content":" responseDetails: recipientSubmissionFormModel.responseDetails,"},{"lineNumber":783,"author":{"gitId":"-"},"content":" });"},{"lineNumber":784,"author":{"gitId":"-"},"content":" }"},{"lineNumber":785,"author":{"gitId":"-"},"content":" });"},{"lineNumber":786,"author":{"gitId":"-"},"content":""},{"lineNumber":787,"author":{"gitId":"-"},"content":" isQuestionFullyAnswered \u003d responses.length \u003e 0;"},{"lineNumber":788,"author":{"gitId":"-"},"content":""},{"lineNumber":789,"author":{"gitId":"-"},"content":" if (!failToSaveQuestions[questionSubmissionFormModel.questionNumber]) {"},{"lineNumber":790,"author":{"gitId":"-"},"content":" savingRequests.push("},{"lineNumber":791,"author":{"gitId":"-"},"content":" this.feedbackResponsesService.submitFeedbackResponses(questionSubmissionFormModel.feedbackQuestionId, {"},{"lineNumber":792,"author":{"gitId":"-"},"content":" responses,"},{"lineNumber":793,"author":{"gitId":"-"},"content":" }, {"},{"lineNumber":794,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":795,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":796,"author":{"gitId":"-"},"content":" moderatedperson: this.moderatedPerson,"},{"lineNumber":797,"author":{"gitId":"-"},"content":" singlerecipientidforsubmission: recipientId?.toString() || \u0027\u0027,"},{"lineNumber":798,"author":{"gitId":"-"},"content":" }).pipe("},{"lineNumber":799,"author":{"gitId":"-"},"content":" tap((resp: FeedbackResponses) \u003d\u003e {"},{"lineNumber":800,"author":{"gitId":"-"},"content":" const responsesMap: Record\u003cstring, FeedbackResponse\u003e \u003d {};"},{"lineNumber":801,"author":{"gitId":"-"},"content":" resp.responses.forEach((response: FeedbackResponse) \u003d\u003e {"},{"lineNumber":802,"author":{"gitId":"-"},"content":" responsesMap[response.recipientIdentifier] \u003d response;"},{"lineNumber":803,"author":{"gitId":"-"},"content":" answers[questionSubmissionFormModel.feedbackQuestionId] \u003d"},{"lineNumber":804,"author":{"gitId":"-"},"content":" answers[questionSubmissionFormModel.feedbackQuestionId] || [];"},{"lineNumber":805,"author":{"gitId":"-"},"content":" answers[questionSubmissionFormModel.feedbackQuestionId].push(response);"},{"lineNumber":806,"author":{"gitId":"-"},"content":" });"},{"lineNumber":807,"author":{"gitId":"-"},"content":" requestIds[questionSubmissionFormModel.feedbackQuestionId] \u003d resp.requestId || \u0027\u0027;"},{"lineNumber":808,"author":{"gitId":"-"},"content":""},{"lineNumber":809,"author":{"gitId":"-"},"content":" questionSubmissionFormModel.recipientSubmissionForms"},{"lineNumber":810,"author":{"gitId":"-"},"content":" .forEach((recipientSubmissionFormModel: FeedbackResponseRecipientSubmissionFormModel) \u003d\u003e {"},{"lineNumber":811,"author":{"gitId":"-"},"content":" if (responsesMap[recipientSubmissionFormModel.recipientIdentifier]) {"},{"lineNumber":812,"author":{"gitId":"-"},"content":" const correspondingResp: FeedbackResponse \u003d"},{"lineNumber":813,"author":{"gitId":"-"},"content":" responsesMap[recipientSubmissionFormModel.recipientIdentifier];"},{"lineNumber":814,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.responseId \u003d correspondingResp.feedbackResponseId;"},{"lineNumber":815,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.responseDetails \u003d correspondingResp.responseDetails;"},{"lineNumber":816,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.recipientIdentifier \u003d correspondingResp.recipientIdentifier;"},{"lineNumber":817,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":818,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.responseId \u003d \u0027\u0027;"},{"lineNumber":819,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.commentByGiver \u003d undefined;"},{"lineNumber":820,"author":{"gitId":"-"},"content":" }"},{"lineNumber":821,"author":{"gitId":"-"},"content":" });"},{"lineNumber":822,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":823,"author":{"gitId":"-"},"content":" switchMap(() \u003d\u003e"},{"lineNumber":824,"author":{"gitId":"-"},"content":" forkJoin(questionSubmissionFormModel.recipientSubmissionForms"},{"lineNumber":825,"author":{"gitId":"-"},"content":" .map((recipientSubmissionFormModel: FeedbackResponseRecipientSubmissionFormModel) \u003d\u003e"},{"lineNumber":826,"author":{"gitId":"-"},"content":" this.createCommentRequest(recipientSubmissionFormModel))),"},{"lineNumber":827,"author":{"gitId":"-"},"content":" ),"},{"lineNumber":828,"author":{"gitId":"-"},"content":" catchError((error: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":829,"author":{"gitId":"-"},"content":" failToSaveQuestions[questionSubmissionFormModel.questionNumber] \u003d error.error.message;"},{"lineNumber":830,"author":{"gitId":"-"},"content":" return of(error);"},{"lineNumber":831,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":832,"author":{"gitId":"-"},"content":" ),"},{"lineNumber":833,"author":{"gitId":"-"},"content":" );"},{"lineNumber":834,"author":{"gitId":"-"},"content":" }"},{"lineNumber":835,"author":{"gitId":"-"},"content":""},{"lineNumber":836,"author":{"gitId":"-"},"content":" if (!isQuestionFullyAnswered) {"},{"lineNumber":837,"author":{"gitId":"-"},"content":" notYetAnsweredQuestions.add(questionSubmissionFormModel.questionNumber);"},{"lineNumber":838,"author":{"gitId":"-"},"content":" }"},{"lineNumber":839,"author":{"gitId":"-"},"content":" });"},{"lineNumber":840,"author":{"gitId":"-"},"content":""},{"lineNumber":841,"author":{"gitId":"-"},"content":" this.isSavingResponses \u003d true;"},{"lineNumber":842,"author":{"gitId":"-"},"content":" forkJoin(savingRequests).pipe("},{"lineNumber":843,"author":{"gitId":"-"},"content":" finalize(() \u003d\u003e {"},{"lineNumber":844,"author":{"gitId":"-"},"content":" this.isSavingResponses \u003d false;"},{"lineNumber":845,"author":{"gitId":"-"},"content":""},{"lineNumber":846,"author":{"gitId":"-"},"content":" const modalRef: NgbModalRef \u003d this.ngbModal.open(SavingCompleteModalComponent);"},{"lineNumber":847,"author":{"gitId":"-"},"content":" modalRef.componentInstance.requestIds \u003d requestIds;"},{"lineNumber":848,"author":{"gitId":"-"},"content":" modalRef.componentInstance.courseId \u003d this.courseId;"},{"lineNumber":849,"author":{"gitId":"-"},"content":" modalRef.componentInstance.feedbackSessionName \u003d this.feedbackSessionName;"},{"lineNumber":850,"author":{"gitId":"-"},"content":" modalRef.componentInstance.feedbackSessionTimezone \u003d this.feedbackSessionTimezone;"},{"lineNumber":851,"author":{"gitId":"-"},"content":" modalRef.componentInstance.personEmail \u003d this.personEmail;"},{"lineNumber":852,"author":{"gitId":"-"},"content":" modalRef.componentInstance.personName \u003d this.personName;"},{"lineNumber":853,"author":{"gitId":"-"},"content":" modalRef.componentInstance.questions \u003d questionSubmissionForms;"},{"lineNumber":854,"author":{"gitId":"-"},"content":" modalRef.componentInstance.answers \u003d answers;"},{"lineNumber":855,"author":{"gitId":"-"},"content":" modalRef.componentInstance.notYetAnsweredQuestions \u003d Array.from(notYetAnsweredQuestions.values());"},{"lineNumber":856,"author":{"gitId":"-"},"content":" modalRef.componentInstance.failToSaveQuestions \u003d failToSaveQuestions;"},{"lineNumber":857,"author":{"gitId":"-"},"content":""},{"lineNumber":858,"author":{"gitId":"-"},"content":" if (recipientId) {"},{"lineNumber":859,"author":{"gitId":"-"},"content":" this.questionSubmissionForms.forEach((model: QuestionSubmissionFormModel) \u003d\u003e {"},{"lineNumber":860,"author":{"gitId":"-"},"content":" if (this.recipientQuestionMap.get(recipientId)!.has(model.questionNumber)) {"},{"lineNumber":861,"author":{"gitId":"-"},"content":" model.hasResponseChangedForRecipients.set(recipientId, false);"},{"lineNumber":862,"author":{"gitId":"-"},"content":" }"},{"lineNumber":863,"author":{"gitId":"-"},"content":" });"},{"lineNumber":864,"author":{"gitId":"-"},"content":" }"},{"lineNumber":865,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":866,"author":{"gitId":"-"},"content":" ).subscribe();"},{"lineNumber":867,"author":{"gitId":"-"},"content":" }"},{"lineNumber":868,"author":{"gitId":"-"},"content":""},{"lineNumber":869,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":870,"author":{"gitId":"-"},"content":" * Creates comment request."},{"lineNumber":871,"author":{"gitId":"-"},"content":" */"},{"lineNumber":872,"author":{"gitId":"-"},"content":" createCommentRequest(recipientSubmissionFormModel: FeedbackResponseRecipientSubmissionFormModel): Observable\u003cany\u003e {"},{"lineNumber":873,"author":{"gitId":"-"},"content":" if (!recipientSubmissionFormModel.responseId) {"},{"lineNumber":874,"author":{"gitId":"-"},"content":" // responseId not set, cannot set comment"},{"lineNumber":875,"author":{"gitId":"-"},"content":" return of({});"},{"lineNumber":876,"author":{"gitId":"-"},"content":" }"},{"lineNumber":877,"author":{"gitId":"-"},"content":" if (!recipientSubmissionFormModel.commentByGiver) {"},{"lineNumber":878,"author":{"gitId":"-"},"content":" // comment not given, do nothing"},{"lineNumber":879,"author":{"gitId":"-"},"content":" return of({});"},{"lineNumber":880,"author":{"gitId":"-"},"content":" }"},{"lineNumber":881,"author":{"gitId":"-"},"content":""},{"lineNumber":882,"author":{"gitId":"-"},"content":" const isSameRecipient \u003d recipientSubmissionFormModel.recipientIdentifier"},{"lineNumber":883,"author":{"gitId":"-"},"content":" \u003d\u003d\u003d recipientSubmissionFormModel.commentByGiver.originalRecipientIdentifier;"},{"lineNumber":884,"author":{"gitId":"-"},"content":""},{"lineNumber":885,"author":{"gitId":"-"},"content":" if (!recipientSubmissionFormModel.commentByGiver.originalComment || !isSameRecipient) {"},{"lineNumber":886,"author":{"gitId":"-"},"content":" // comment is new or original comment deleted because recipient has changed"},{"lineNumber":887,"author":{"gitId":"-"},"content":""},{"lineNumber":888,"author":{"gitId":"-"},"content":" if (recipientSubmissionFormModel.commentByGiver.commentEditFormModel.commentText \u003d\u003d\u003d \u0027\u0027) {"},{"lineNumber":889,"author":{"gitId":"-"},"content":" // new comment is empty"},{"lineNumber":890,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.commentByGiver \u003d undefined;"},{"lineNumber":891,"author":{"gitId":"-"},"content":" return of({});"},{"lineNumber":892,"author":{"gitId":"-"},"content":" }"},{"lineNumber":893,"author":{"gitId":"-"},"content":""},{"lineNumber":894,"author":{"gitId":"-"},"content":" // create new comment"},{"lineNumber":895,"author":{"gitId":"-"},"content":" return this.commentService.createComment({"},{"lineNumber":896,"author":{"gitId":"-"},"content":" commentText: recipientSubmissionFormModel.commentByGiver.commentEditFormModel.commentText,"},{"lineNumber":897,"author":{"gitId":"-"},"content":" // we ignore the fields in comment edit model as participant comment"},{"lineNumber":898,"author":{"gitId":"-"},"content":" // will follow visibilities from question by design"},{"lineNumber":899,"author":{"gitId":"-"},"content":" showCommentTo: [],"},{"lineNumber":900,"author":{"gitId":"-"},"content":" showGiverNameTo: [],"},{"lineNumber":901,"author":{"gitId":"-"},"content":" }, recipientSubmissionFormModel.responseId, this.intent, {"},{"lineNumber":902,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":903,"author":{"gitId":"-"},"content":" moderatedperson: this.moderatedPerson,"},{"lineNumber":904,"author":{"gitId":"-"},"content":" }).pipe("},{"lineNumber":905,"author":{"gitId":"-"},"content":" tap((comment: FeedbackResponseComment) \u003d\u003e {"},{"lineNumber":906,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.commentByGiver \u003d this.getCommentModel("},{"lineNumber":907,"author":{"gitId":"-"},"content":" comment, recipientSubmissionFormModel.recipientIdentifier);"},{"lineNumber":908,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":909,"author":{"gitId":"-"},"content":" );"},{"lineNumber":910,"author":{"gitId":"-"},"content":" }"},{"lineNumber":911,"author":{"gitId":"-"},"content":""},{"lineNumber":912,"author":{"gitId":"-"},"content":" // existing comment"},{"lineNumber":913,"author":{"gitId":"-"},"content":""},{"lineNumber":914,"author":{"gitId":"-"},"content":" if (recipientSubmissionFormModel.commentByGiver.commentEditFormModel.commentText \u003d\u003d\u003d \u0027\u0027) {"},{"lineNumber":915,"author":{"gitId":"-"},"content":" // comment is empty, create delete request"},{"lineNumber":916,"author":{"gitId":"-"},"content":" return this.commentService.deleteComment("},{"lineNumber":917,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.commentByGiver.originalComment.feedbackResponseCommentId, this.intent, {"},{"lineNumber":918,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":919,"author":{"gitId":"-"},"content":" moderatedperson: this.moderatedPerson,"},{"lineNumber":920,"author":{"gitId":"-"},"content":" })"},{"lineNumber":921,"author":{"gitId":"-"},"content":" .pipe("},{"lineNumber":922,"author":{"gitId":"-"},"content":" tap(() \u003d\u003e {"},{"lineNumber":923,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.commentByGiver \u003d undefined;"},{"lineNumber":924,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":925,"author":{"gitId":"-"},"content":" }"},{"lineNumber":926,"author":{"gitId":"-"},"content":""},{"lineNumber":927,"author":{"gitId":"-"},"content":" // update comment"},{"lineNumber":928,"author":{"gitId":"-"},"content":" return this.commentService.updateComment({"},{"lineNumber":929,"author":{"gitId":"-"},"content":" commentText: recipientSubmissionFormModel.commentByGiver.commentEditFormModel.commentText,"},{"lineNumber":930,"author":{"gitId":"-"},"content":" // we ignore the fields in comment edit model as participant comment"},{"lineNumber":931,"author":{"gitId":"-"},"content":" // will follow visibilities from question by design"},{"lineNumber":932,"author":{"gitId":"-"},"content":" showCommentTo: [],"},{"lineNumber":933,"author":{"gitId":"-"},"content":" showGiverNameTo: [],"},{"lineNumber":934,"author":{"gitId":"-"},"content":" }, recipientSubmissionFormModel.commentByGiver.originalComment.feedbackResponseCommentId, this.intent, {"},{"lineNumber":935,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":936,"author":{"gitId":"-"},"content":" moderatedperson: this.moderatedPerson,"},{"lineNumber":937,"author":{"gitId":"-"},"content":" }).pipe("},{"lineNumber":938,"author":{"gitId":"-"},"content":" tap((comment: FeedbackResponseComment) \u003d\u003e {"},{"lineNumber":939,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.commentByGiver \u003d this.getCommentModel("},{"lineNumber":940,"author":{"gitId":"-"},"content":" comment, recipientSubmissionFormModel.recipientIdentifier);"},{"lineNumber":941,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":942,"author":{"gitId":"-"},"content":" );"},{"lineNumber":943,"author":{"gitId":"-"},"content":" }"},{"lineNumber":944,"author":{"gitId":"-"},"content":""},{"lineNumber":945,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":946,"author":{"gitId":"-"},"content":" * Deletes a comment by participants."},{"lineNumber":947,"author":{"gitId":"-"},"content":" */"},{"lineNumber":948,"author":{"gitId":"-"},"content":" deleteParticipantComment(questionIndex: number, responseIdx: number): void {"},{"lineNumber":949,"author":{"gitId":"-"},"content":" const recipientSubmissionFormModel: FeedbackResponseRecipientSubmissionFormModel \u003d"},{"lineNumber":950,"author":{"gitId":"-"},"content":" this.questionSubmissionForms[questionIndex].recipientSubmissionForms[responseIdx];"},{"lineNumber":951,"author":{"gitId":"-"},"content":""},{"lineNumber":952,"author":{"gitId":"-"},"content":" if (!recipientSubmissionFormModel.commentByGiver || !recipientSubmissionFormModel.commentByGiver.originalComment) {"},{"lineNumber":953,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":954,"author":{"gitId":"-"},"content":" }"},{"lineNumber":955,"author":{"gitId":"-"},"content":""},{"lineNumber":956,"author":{"gitId":"-"},"content":" this.commentService.deleteComment("},{"lineNumber":957,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.commentByGiver.originalComment.feedbackResponseCommentId, this.intent, {"},{"lineNumber":958,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":959,"author":{"gitId":"-"},"content":" moderatedperson: this.moderatedPerson,"},{"lineNumber":960,"author":{"gitId":"-"},"content":" })"},{"lineNumber":961,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":962,"author":{"gitId":"-"},"content":" next: () \u003d\u003e {"},{"lineNumber":963,"author":{"gitId":"-"},"content":" recipientSubmissionFormModel.commentByGiver \u003d undefined;"},{"lineNumber":964,"author":{"gitId":"-"},"content":" this.statusMessageService.showSuccessToast(\u0027Your comment has been deleted!\u0027);"},{"lineNumber":965,"author":{"gitId":"-"},"content":" },"},{"lineNumber":966,"author":{"gitId":"-"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":967,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":968,"author":{"gitId":"-"},"content":" },"},{"lineNumber":969,"author":{"gitId":"-"},"content":" });"},{"lineNumber":970,"author":{"gitId":"-"},"content":" }"},{"lineNumber":971,"author":{"gitId":"-"},"content":""},{"lineNumber":972,"author":{"gitId":"-"},"content":" retryLoadingFeedbackSessionQuestions(): void {"},{"lineNumber":973,"author":{"gitId":"-"},"content":" this.hasFeedbackSessionQuestionsLoadingFailed \u003d false;"},{"lineNumber":974,"author":{"gitId":"-"},"content":" if (this.retryAttempts \u003e\u003d 0) {"},{"lineNumber":975,"author":{"gitId":"-"},"content":" this.retryAttempts -\u003d 1;"},{"lineNumber":976,"author":{"gitId":"-"},"content":" }"},{"lineNumber":977,"author":{"gitId":"-"},"content":" this.loadFeedbackQuestions();"},{"lineNumber":978,"author":{"gitId":"-"},"content":" }"},{"lineNumber":979,"author":{"gitId":"-"},"content":""},{"lineNumber":980,"author":{"gitId":"-"},"content":" handleError(resp: ErrorMessageOutput): void {"},{"lineNumber":981,"author":{"gitId":"-"},"content":" this.hasFeedbackSessionQuestionsLoadingFailed \u003d true;"},{"lineNumber":982,"author":{"gitId":"-"},"content":" if (this.retryAttempts \u003c 0) {"},{"lineNumber":983,"author":{"gitId":"-"},"content":" const report: NgbModalRef \u003d this.ngbModal.open(ErrorReportComponent);"},{"lineNumber":984,"author":{"gitId":"-"},"content":" report.componentInstance.requestId \u003d resp.error.requestId;"},{"lineNumber":985,"author":{"gitId":"-"},"content":" report.componentInstance.errorMessage \u003d resp.error.message;"},{"lineNumber":986,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":987,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(resp.error.message);"},{"lineNumber":988,"author":{"gitId":"-"},"content":" }"},{"lineNumber":989,"author":{"gitId":"-"},"content":" }"},{"lineNumber":990,"author":{"gitId":"-"},"content":""},{"lineNumber":991,"author":{"gitId":"-"},"content":" loadRecipientsAndResponses(event: any, questionSubmissionForm: QuestionSubmissionFormModel): void {"},{"lineNumber":992,"author":{"gitId":"-"},"content":" if (event \u0026\u0026 event.visible \u0026\u0026 !questionSubmissionForm.isLoaded \u0026\u0026 !questionSubmissionForm.isLoading) {"},{"lineNumber":993,"author":{"gitId":"-"},"content":" questionSubmissionForm.isLoading \u003d true;"},{"lineNumber":994,"author":{"gitId":"-"},"content":" this.loadFeedbackQuestionRecipientsForQuestion(questionSubmissionForm);"},{"lineNumber":995,"author":{"gitId":"-"},"content":" }"},{"lineNumber":996,"author":{"gitId":"-"},"content":" }"},{"lineNumber":997,"author":{"gitId":"-"},"content":""},{"lineNumber":998,"author":{"gitId":"-"},"content":" private getformattedSessionClosingTime(feedbackSession: FeedbackSession, TIME_FORMAT: string): string {"},{"lineNumber":999,"author":{"gitId":"-"},"content":" const userSessionEndingTime \u003d DeadlineExtensionHelper.getUserFeedbackSessionEndingTimestamp(feedbackSession);"},{"lineNumber":1000,"author":{"gitId":"-"},"content":" let formattedString \u003d this.timezoneService.formatToString("},{"lineNumber":1001,"author":{"gitId":"-"},"content":" userSessionEndingTime, feedbackSession.timeZone, TIME_FORMAT);"},{"lineNumber":1002,"author":{"gitId":"-"},"content":" if (DeadlineExtensionHelper.hasUserExtension(feedbackSession)) {"},{"lineNumber":1003,"author":{"gitId":"-"},"content":" formattedString +\u003d \u0027 (Extension given)\u0027;"},{"lineNumber":1004,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1005,"author":{"gitId":"-"},"content":" return formattedString;"},{"lineNumber":1006,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1007,"author":{"gitId":"-"},"content":""},{"lineNumber":1008,"author":{"gitId":"-"},"content":" private isFeedbackEndingLessThanFifteenMinutes(feedbackSession: FeedbackSession): boolean {"},{"lineNumber":1009,"author":{"gitId":"-"},"content":" const userSessionEndingTime \u003d DeadlineExtensionHelper.getOngoingUserFeedbackSessionEndingTimestamp(feedbackSession);"},{"lineNumber":1010,"author":{"gitId":"-"},"content":" return (userSessionEndingTime - Date.now()) \u003c Milliseconds.IN_FIFTEEN_MINUTES;"},{"lineNumber":1011,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1012,"author":{"gitId":"-"},"content":""},{"lineNumber":1013,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1014,"author":{"gitId":"-"},"content":" * Filter questions that we are submitting for intended recipient"},{"lineNumber":1015,"author":{"gitId":"-"},"content":" * when grouped session view is toggled and save the responses after."},{"lineNumber":1016,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1017,"author":{"gitId":"-"},"content":" saveResponsesForSelectedRecipientQuestions(recipientId: string,"},{"lineNumber":1018,"author":{"gitId":"-"},"content":" questionSubmissionForms: QuestionSubmissionFormModel[]): void {"},{"lineNumber":1019,"author":{"gitId":"-"},"content":" const questionsToRecipient: Set\u003cnumber\u003e | undefined \u003d this.recipientQuestionMap.get(recipientId);"},{"lineNumber":1020,"author":{"gitId":"-"},"content":" if (!questionsToRecipient) {"},{"lineNumber":1021,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(\u0027Failed to save response for this recipient. \u0027"},{"lineNumber":1022,"author":{"gitId":"-"},"content":" + \u0027Please switch back to \"Group by Question\" view to save responses.\u0027);"},{"lineNumber":1023,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1024,"author":{"gitId":"-"},"content":" const recipientQSForms \u003d questionSubmissionForms"},{"lineNumber":1025,"author":{"gitId":"-"},"content":" .filter((questionSubmissionFormModel: QuestionSubmissionFormModel) \u003d\u003e"},{"lineNumber":1026,"author":{"gitId":"-"},"content":" questionsToRecipient!.has(questionSubmissionFormModel.questionNumber));"},{"lineNumber":1027,"author":{"gitId":"-"},"content":""},{"lineNumber":1028,"author":{"gitId":"-"},"content":" this.saveFeedbackResponses(recipientQSForms, false, recipientId);"},{"lineNumber":1029,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1030,"author":{"gitId":"-"},"content":""},{"lineNumber":1031,"author":{"gitId":"-"},"content":" private addQuestionForRecipient(recipientId: string, questionId: any): void {"},{"lineNumber":1032,"author":{"gitId":"-"},"content":" if (this.recipientQuestionMap.has(recipientId)) {"},{"lineNumber":1033,"author":{"gitId":"-"},"content":" this.recipientQuestionMap.get(recipientId)!.add(questionId);"},{"lineNumber":1034,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1035,"author":{"gitId":"-"},"content":" const feedbackQuestionIds: Set\u003cany\u003e \u003d new Set\u003cany\u003e();"},{"lineNumber":1036,"author":{"gitId":"-"},"content":" feedbackQuestionIds.add(questionId);"},{"lineNumber":1037,"author":{"gitId":"-"},"content":" this.recipientQuestionMap.set(recipientId, feedbackQuestionIds);"},{"lineNumber":1038,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1039,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1040,"author":{"gitId":"-"},"content":""},{"lineNumber":1041,"author":{"gitId":"-"},"content":" toggleViewChange(selectedView: SessionView): void {"},{"lineNumber":1042,"author":{"gitId":"-"},"content":" if (selectedView \u003d\u003d\u003d this.currentSelectedSessionView) {"},{"lineNumber":1043,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":1044,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1045,"author":{"gitId":"-"},"content":""},{"lineNumber":1046,"author":{"gitId":"-"},"content":" if (selectedView \u003d\u003d\u003d SessionView.DEFAULT) {"},{"lineNumber":1047,"author":{"gitId":"-"},"content":" this.currentSelectedSessionView \u003d SessionView.DEFAULT;"},{"lineNumber":1048,"author":{"gitId":"-"},"content":" } else if (selectedView \u003d\u003d\u003d SessionView.GROUP_RECIPIENTS) {"},{"lineNumber":1049,"author":{"gitId":"-"},"content":" this.currentSelectedSessionView \u003d SessionView.GROUP_RECIPIENTS;"},{"lineNumber":1050,"author":{"gitId":"-"},"content":" this.groupQuestionsByRecipient();"},{"lineNumber":1051,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1052,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1053,"author":{"gitId":"-"},"content":""},{"lineNumber":1054,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1055,"author":{"gitId":"-"},"content":" * Group questions by recipients in {@code GROUP_RECIPIENTS} view."},{"lineNumber":1056,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1057,"author":{"gitId":"-"},"content":" groupQuestionsByRecipient(): void {"},{"lineNumber":1058,"author":{"gitId":"-"},"content":" if (this.hasLoadedAllRecipients) {"},{"lineNumber":1059,"author":{"gitId":"-"},"content":" return;"},{"lineNumber":1060,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1061,"author":{"gitId":"-"},"content":" // We first need to load the recipient for all the questions. This is because questions with"},{"lineNumber":1062,"author":{"gitId":"-"},"content":" // FIXED_RECIPIENT question submission mode are ungroupable and to know whether the question"},{"lineNumber":1063,"author":{"gitId":"-"},"content":" // submission mode of a question, we need to load the recipient list first."},{"lineNumber":1064,"author":{"gitId":"-"},"content":" const recipientsObservables: Observable\u003cFeedbackQuestionRecipients\u003e[] \u003d [];"},{"lineNumber":1065,"author":{"gitId":"-"},"content":" const questionsToBeLoaded: QuestionSubmissionFormModel[] \u003d [];"},{"lineNumber":1066,"author":{"gitId":"-"},"content":""},{"lineNumber":1067,"author":{"gitId":"-"},"content":" this.questionSubmissionForms.forEach((model: QuestionSubmissionFormModel) \u003d\u003e {"},{"lineNumber":1068,"author":{"gitId":"-"},"content":" if (!model.isLoading \u0026\u0026 !model.isLoaded) {"},{"lineNumber":1069,"author":{"gitId":"-"},"content":" questionsToBeLoaded.push(model);"},{"lineNumber":1070,"author":{"gitId":"-"},"content":" recipientsObservables.push(this.feedbackQuestionsService.loadFeedbackQuestionRecipients({"},{"lineNumber":1071,"author":{"gitId":"-"},"content":" questionId: model.feedbackQuestionId,"},{"lineNumber":1072,"author":{"gitId":"-"},"content":" intent: this.intent,"},{"lineNumber":1073,"author":{"gitId":"-"},"content":" key: this.regKey,"},{"lineNumber":1074,"author":{"gitId":"-"},"content":" moderatedPerson: this.moderatedPerson,"},{"lineNumber":1075,"author":{"gitId":"-"},"content":" previewAs: this.previewAsPerson,"},{"lineNumber":1076,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":1077,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1078,"author":{"gitId":"-"},"content":" });"},{"lineNumber":1079,"author":{"gitId":"-"},"content":""},{"lineNumber":1080,"author":{"gitId":"-"},"content":" // Find the groupable and ungroupable questions and construct the recipient to question mapping."},{"lineNumber":1081,"author":{"gitId":"-"},"content":" forkJoin(recipientsObservables)"},{"lineNumber":1082,"author":{"gitId":"-"},"content":" .pipe(finalize(() \u003d\u003e {"},{"lineNumber":1083,"author":{"gitId":"-"},"content":" this.ungroupableQuestionsSorted \u003d Array.from(this.ungroupableQuestions).sort();"},{"lineNumber":1084,"author":{"gitId":"-"},"content":" this.hasLoadedAllRecipients \u003d true;"},{"lineNumber":1085,"author":{"gitId":"-"},"content":" }))"},{"lineNumber":1086,"author":{"gitId":"-"},"content":" .subscribe({"},{"lineNumber":1087,"author":{"gitId":"-"},"content":" next: (feedbackQuestionRecipients: FeedbackQuestionRecipients[]) \u003d\u003e {"},{"lineNumber":1088,"author":{"gitId":"-"},"content":" for (let i \u003d 0; i \u003c feedbackQuestionRecipients.length; i +\u003d 1) {"},{"lineNumber":1089,"author":{"gitId":"-"},"content":" const question: QuestionSubmissionFormModel \u003d questionsToBeLoaded[i];"},{"lineNumber":1090,"author":{"gitId":"-"},"content":" // Only questions with question submission form mode being FIXED_RECIPIENT and with question type"},{"lineNumber":1091,"author":{"gitId":"-"},"content":" // not being CONSTSUM_RECIPIENTS, RANK_RECIPIENTS, and CONTRIB, are the groupable questions."},{"lineNumber":1092,"author":{"gitId":"-"},"content":" if (this.getQuestionSubmissionFormMode(question, feedbackQuestionRecipients[i].recipients.length)"},{"lineNumber":1093,"author":{"gitId":"-"},"content":" \u003d\u003d\u003d QuestionSubmissionFormMode.FIXED_RECIPIENT"},{"lineNumber":1094,"author":{"gitId":"-"},"content":" \u0026\u0026 question.questionType !\u003d\u003d FeedbackQuestionType.CONSTSUM_RECIPIENTS"},{"lineNumber":1095,"author":{"gitId":"-"},"content":" \u0026\u0026 question.questionType !\u003d\u003d FeedbackQuestionType.RANK_RECIPIENTS"},{"lineNumber":1096,"author":{"gitId":"-"},"content":" \u0026\u0026 question.questionType !\u003d\u003d FeedbackQuestionType.CONTRIB) {"},{"lineNumber":1097,"author":{"gitId":"-"},"content":""},{"lineNumber":1098,"author":{"gitId":"-"},"content":" for (let j \u003d 0; j \u003c feedbackQuestionRecipients[i].recipients.length; j +\u003d 1) {"},{"lineNumber":1099,"author":{"gitId":"-"},"content":" const recipient: FeedbackQuestionRecipient \u003d feedbackQuestionRecipients[i].recipients[j];"},{"lineNumber":1100,"author":{"gitId":"-"},"content":" this.addQuestionForRecipient(recipient.identifier, question.questionNumber);"},{"lineNumber":1101,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1102,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":1103,"author":{"gitId":"-"},"content":" this.ungroupableQuestions.add(question.questionNumber);"},{"lineNumber":1104,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1105,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1106,"author":{"gitId":"-"},"content":" },"},{"lineNumber":1107,"author":{"gitId":"-"},"content":" error: () \u003d\u003e {"},{"lineNumber":1108,"author":{"gitId":"-"},"content":" this.statusMessageService.showWarningToast(\u0027Failed to build groupable questions\u0027);"},{"lineNumber":1109,"author":{"gitId":"-"},"content":" },"},{"lineNumber":1110,"author":{"gitId":"-"},"content":" },"},{"lineNumber":1111,"author":{"gitId":"-"},"content":" );"},{"lineNumber":1112,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1113,"author":{"gitId":"-"},"content":""},{"lineNumber":1114,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":1115,"author":{"gitId":"-"},"content":" * Gets recipient name in {@code FIXED_RECIPIENT} mode and in {@code GROUP_RECIPIENTS} view."},{"lineNumber":1116,"author":{"gitId":"-"},"content":" */"},{"lineNumber":1117,"author":{"gitId":"-"},"content":" getRecipientName(recipientIdentifier: string): string {"},{"lineNumber":1118,"author":{"gitId":"-"},"content":" const question: QuestionSubmissionFormModel | undefined \u003d"},{"lineNumber":1119,"author":{"gitId":"-"},"content":" this.questionSubmissionForms.find((model: QuestionSubmissionFormModel) \u003d\u003e"},{"lineNumber":1120,"author":{"gitId":"-"},"content":" model.questionNumber \u003d\u003d\u003d this.recipientQuestionMap.get(recipientIdentifier)!.values().next().value);"},{"lineNumber":1121,"author":{"gitId":"-"},"content":""},{"lineNumber":1122,"author":{"gitId":"-"},"content":" if (!question) {"},{"lineNumber":1123,"author":{"gitId":"-"},"content":" this.statusMessageService.showErrorToast(\u0027Failed to build groupable questions\u0027);"},{"lineNumber":1124,"author":{"gitId":"-"},"content":" return \u0027Unknown\u0027;"},{"lineNumber":1125,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1126,"author":{"gitId":"-"},"content":""},{"lineNumber":1127,"author":{"gitId":"-"},"content":" const recipient: FeedbackResponseRecipient | undefined \u003d"},{"lineNumber":1128,"author":{"gitId":"-"},"content":" question!.recipientList.find("},{"lineNumber":1129,"author":{"gitId":"-"},"content":" (r: FeedbackResponseRecipient) \u003d\u003e r.recipientIdentifier \u003d\u003d\u003d recipientIdentifier);"},{"lineNumber":1130,"author":{"gitId":"-"},"content":""},{"lineNumber":1131,"author":{"gitId":"-"},"content":" return recipient ? recipient.recipientName : \u0027Unknown\u0027;"},{"lineNumber":1132,"author":{"gitId":"-"},"content":" }"},{"lineNumber":1133,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":1134,"author":{"gitId":"dishenggg"},"content":" /**"},{"lineNumber":1135,"author":{"gitId":"dishenggg"},"content":" * Logs student activity after student/session details have been fetched."},{"lineNumber":1136,"author":{"gitId":"dishenggg"},"content":" */"},{"lineNumber":1137,"author":{"gitId":"dishenggg"},"content":" logStudentAccess(): void {"},{"lineNumber":1138,"author":{"gitId":"dishenggg"},"content":" if (this.intent !\u003d\u003d Intent.STUDENT_SUBMISSION) {"},{"lineNumber":1139,"author":{"gitId":"dishenggg"},"content":" return;"},{"lineNumber":1140,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":1141,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":1142,"author":{"gitId":"dishenggg"},"content":" // dummy vars to check that both student and session has been loaded"},{"lineNumber":1143,"author":{"gitId":"dishenggg"},"content":" if (!this.personEmail || !this.feedbackSessionTimezone) {"},{"lineNumber":1144,"author":{"gitId":"dishenggg"},"content":" return;"},{"lineNumber":1145,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":1146,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":1147,"author":{"gitId":"dishenggg"},"content":" this.logService.createFeedbackSessionLog({"},{"lineNumber":1148,"author":{"gitId":"dishenggg"},"content":" courseId: this.courseId,"},{"lineNumber":1149,"author":{"gitId":"dishenggg"},"content":" feedbackSessionName: this.feedbackSessionName,"},{"lineNumber":1150,"author":{"gitId":"dishenggg"},"content":" studentEmail: this.personEmail,"},{"lineNumber":1151,"author":{"gitId":"dishenggg"},"content":" logType: FeedbackSessionLogType.ACCESS,"},{"lineNumber":1152,"author":{"gitId":"dishenggg"},"content":" feedbackSessionId: this.feedbackSessionId,"},{"lineNumber":1153,"author":{"gitId":"dishenggg"},"content":" studentId: this.studentId,"},{"lineNumber":1154,"author":{"gitId":"dishenggg"},"content":" }).subscribe();"},{"lineNumber":1155,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":1156,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":34,"-":1122}},{"path":"src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form-model.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"export type InstructorRequestFormModel \u003d {"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":" name: string,"},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":" institution: string,"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":" country: string,"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":" email: string,"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":" comments: string,"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"};"}],"authorContributionMap":{"xenosf":7}},{"path":"src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"\u003cp aria-hidden\u003d\"true\"\u003e"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":" \u003c!-- aria-hidden as screen readers use inputs\u0027 required attribute instead (and cannot see the asterisks) --\u003e"},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":" Questions marked with an asterisk \u003cspan class\u003d\"red-font\"\u003e*\u003c/span\u003e are required."},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"\u003c/p\u003e"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"\u003cform (ngSubmit)\u003d\"onSubmit()\" [formGroup]\u003d\"arf\"\u003e"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":" \u003cdiv class\u003d\"form-group {{checkIsFieldRequired(name) ? \u0027required\u0027 : \u0027\u0027}}\"\u003e"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":" \u003clabel for\u003d\"name\" id\u003d\"name-label\" class\u003d\"qn\"\u003e"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":" Full Name"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":" \u003c/label\u003e"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":" \u003cp class\u003d\"help-block\"\u003e"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":" This is the name that will be shown to your students. You may include salutation (Dr. Prof. etc.)"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" \u003c/p\u003e"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" \u003cinput class\u003d\"form-control {{getFieldValidationClasses(name)}}\" type\u003d\"text\" id\u003d\"name\" autocomplete\u003d\"name\""},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":" [formControl]\u003d\"name\" [required]\u003d\"checkIsFieldRequired(name)\" [attr.aria-invalid]\u003d\"name.invalid\"\u003e"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"name.errors?.[\u0027required\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"name-label\" tabindex\u003d\"0\" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" Please enter your name."},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"name.errors?.[\u0027maxlength\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"name-label\" tabindex\u003d\"0\" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":" Name must be shorter than {{STUDENT_NAME_MAX_LENGTH}} characters. (Current: {{name.value?.length}})"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"name.errors?.[\u0027pattern\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"name-label\" tabindex\u003d\"0\""},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" Name must start with an alphanumeric character (a-z, 0-9) and cannot contain any vertical bar (|) or percent sign (%)."},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" \u003cbr\u003e"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" \u003cdiv class\u003d\"form-group {{checkIsFieldRequired(institution) ? \u0027required\u0027 : \u0027\u0027}}\"\u003e"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" \u003clabel for\u003d\"institution\" id\u003d\"institution-label\" class\u003d\"qn\"\u003e"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" University/school/institution"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" \u003c/label\u003e"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" \u003cp class\u003d\"help-block\"\u003e"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" Please give full name of the university/institution."},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" \u003c/p\u003e"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" \u003cinput class\u003d\"form-control {{getFieldValidationClasses(institution)}}\" type\u003d\"text\" id\u003d\"institution\""},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" autocomplete\u003d\"organization\" [formControl]\u003d\"institution\" [required]\u003d\"checkIsFieldRequired(institution)\""},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" [attr.aria-invalid]\u003d\"institution.invalid\"\u003e"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"institution.errors?.[\u0027required\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"institution-label\" tabindex\u003d\"0\""},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" Please enter your institution name."},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"institution.errors?.[\u0027maxlength\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"institution-label\" tabindex\u003d\"0\""},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" Institution name must be shorter than {{INSTITUTION_NAME_MAX_LENGTH}} characters. (Current: {{institution.value?.length}})"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"institution.errors?.[\u0027pattern\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"institution-label\" tabindex\u003d\"0\""},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" Institution name must start with an alphanumeric character (a-z, 0-9) and cannot contain any vertical bar (|) or percent sign (%)."},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" \u003cbr\u003e"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" \u003cdiv class\u003d\"form-group {{checkIsFieldRequired(country) ? \u0027required\u0027 : \u0027\u0027}}\"\u003e"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" \u003clabel for\u003d\"country\" id\u003d\"country-label\" class\u003d\"qn\"\u003e"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" Country"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" \u003c/label\u003e"},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":" \u003cp class\u003d\"help-block\"\u003e"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" Which country is your university/institution based in?"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" \u003c/p\u003e"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" \u003cinput class\u003d\"form-control {{getFieldValidationClasses(country)}}\" type\u003d\"text\" id\u003d\"country\""},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" autocomplete\u003d\"country-name\" [formControl]\u003d\"country\" [required]\u003d\"checkIsFieldRequired(country)\""},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" [attr.aria-invalid]\u003d\"country.invalid\"\u003e"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"country.errors?.[\u0027required\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"country-label\" tabindex\u003d\"0\""},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" Please enter your institution\u0027s country."},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"country.errors?.[\u0027maxlength\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"country-label\" tabindex\u003d\"0\""},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":67,"author":{"gitId":"xenosf"},"content":" Country name must be shorter than {{COUNTRY_NAME_MAX_LENGTH}} characters. (Current: {{country.value?.length}})"},{"lineNumber":68,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"country.errors?.[\u0027pattern\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"country-label\" tabindex\u003d\"0\""},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" Country name must start with an alphanumeric character (a-z, 0-9) and cannot contain any vertical bar (|) or percent sign (%)."},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" \u003cbr\u003e"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" \u003cdiv class\u003d\"form-group {{checkIsFieldRequired(email) ? \u0027required\u0027 : \u0027\u0027}}\"\u003e"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" \u003clabel for\u003d\"email\" id\u003d\"email-label\" class\u003d\"qn\"\u003e"},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":" Official email address"},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" \u003c/label\u003e"},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":" \u003cp class\u003d\"help-block\"\u003e"},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" Please use the email address \u003cb\u003egiven to you by your school/university\u003c/b\u003e"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":" (not your personal Gmail/Hotmail address)."},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":" Note that this email address will be visible to the students you enroll in TEAMMATES."},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" \u003c/p\u003e"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":" \u003cinput class\u003d\"form-control {{getFieldValidationClasses(email)}}\" type\u003d\"email\" id\u003d\"email\" autocomplete\u003d\"email\""},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":" [formControl]\u003d\"email\" [required]\u003d\"checkIsFieldRequired(email)\" [attr.aria-invalid]\u003d\"email.invalid\"\u003e"},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"email.errors?.[\u0027required\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"email-label\" tabindex\u003d\"0\""},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" Please enter your email address."},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"email.errors?.[\u0027maxlength\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"email-label\" tabindex\u003d\"0\""},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":" Email address must be shorter than {{EMAIL_MAX_LENGTH}} characters. (Current: {{email.value?.length}})"},{"lineNumber":93,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":94,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"email.errors?.[\u0027pattern\u0027]\" role\u003d\"alert\" aria-describedby\u003d\"email-label\" tabindex\u003d\"0\""},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":" class\u003d\"invalid-feedback\"\u003e"},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":" Please enter a valid email address."},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" \u003cbr\u003e"},{"lineNumber":100,"author":{"gitId":"xenosf"},"content":" \u003cdiv class\u003d\"form-group {{checkIsFieldRequired(comments) ? \u0027required\u0027 : \u0027\u0027}}\"\u003e"},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":" \u003clabel for\u003d\"comments\" id\u003d\"comments-label\" class\u003d\"qn\"\u003e"},{"lineNumber":102,"author":{"gitId":"xenosf"},"content":" Any other comments/queries"},{"lineNumber":103,"author":{"gitId":"xenosf"},"content":" \u003c/label\u003e"},{"lineNumber":104,"author":{"gitId":"dishenggg"},"content":" \u003ctextarea class\u003d\"form-control {{getFieldValidationClasses(comments)}}\" id\u003d\"comments\" [formControl]\u003d\"comments\""},{"lineNumber":105,"author":{"gitId":"xenosf"},"content":" [attr.aria-invalid]\u003d\"comments.invalid\"\u003e\u003c/textarea\u003e"},{"lineNumber":106,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":107,"author":{"gitId":"xenosf"},"content":" \u003cbr\u003e"},{"lineNumber":108,"author":{"gitId":"xenosf"},"content":" \u003cngb-alert type\u003d\"danger\" [dismissible]\u003d\"false\" *ngIf\u003d\"hasSubmitAttempt \u0026\u0026 arf.invalid\" class\u003d\"error-box\"\u003e"},{"lineNumber":109,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003eThere was a problem with your submission.\u003c/strong\u003e Please check and fix the errors above and submit again."},{"lineNumber":110,"author":{"gitId":"xenosf"},"content":" \u003c/ngb-alert\u003e"},{"lineNumber":111,"author":{"gitId":"xenosf"},"content":" \u003cngb-alert type\u003d\"danger\" [dismissible]\u003d\"false\" *ngIf\u003d\"serverErrorMessage\" class\u003d\"error-box\"\u003e"},{"lineNumber":112,"author":{"gitId":"xenosf"},"content":" \u003cstrong\u003eError submitting request:\u003c/strong\u003e {{serverErrorMessage}}"},{"lineNumber":113,"author":{"gitId":"xenosf"},"content":" \u003c/ngb-alert\u003e"},{"lineNumber":114,"author":{"gitId":"xenosf"},"content":" \u003cbutton type\u003d\"submit\" class\u003d\"btn btn-primary\" id\u003d\"submit-button\" [disabled]\u003d\"!canSubmit\"\u003e"},{"lineNumber":115,"author":{"gitId":"xenosf"},"content":" {{isLoading ? \"Submitting...\" : \"Submit\"}}"},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" \u003c/button\u003e"},{"lineNumber":117,"author":{"gitId":"xenosf"},"content":"\u003c/form\u003e"}],"authorContributionMap":{"xenosf":116,"dishenggg":1}},{"path":"src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.scss","fileType":"scss","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"label.qn {"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":" font-weight: bold;"},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":" font-size: 1rem;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":" margin-bottom: 0.3rem;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"}"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":".form-group {"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":" margin-bottom: 0.5rem;"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":"}"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":".form-group.required \u003e label::after {"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" content:\"*\";"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" color: red;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":"}"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":".help-block {"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" margin-bottom: 0.8rem;"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":"}"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":".red-font {"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" color: red;"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":"}"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":".error-box {"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" margin: 1rem 0;"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":26}},{"path":"src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"import { ComponentFixture, TestBed, waitForAsync } from \u0027@angular/core/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":"import { ReactiveFormsModule } from \u0027@angular/forms\u0027;"},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import { By } from \u0027@angular/platform-browser\u0027;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import { Observable, first } from \u0027rxjs\u0027;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import { InstructorRequestFormModel } from \u0027./instructor-request-form-model\u0027;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import { InstructorRequestFormComponent } from \u0027./instructor-request-form.component\u0027;"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import { AccountService } from \u0027../../../../services/account.service\u0027;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":"import { AccountCreateRequest } from \u0027../../../../types/api-request\u0027;"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"describe(\u0027InstructorRequestFormComponent\u0027, () \u003d\u003e {"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":" let component: InstructorRequestFormComponent;"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" let fixture: ComponentFixture\u003cInstructorRequestFormComponent\u003e;"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" let accountService: AccountService;"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":" const typicalModel: InstructorRequestFormModel \u003d {"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":" name: \u0027John Doe\u0027,"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" institution: \u0027Example Institution\u0027,"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" country: \u0027Example Country\u0027,"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":" email: \u0027jd@example.edu\u0027,"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":" comments: \u0027\u0027,"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" const typicalCreateRequest: AccountCreateRequest \u003d {"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" instructorEmail: typicalModel.email,"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" instructorName: typicalModel.name,"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" instructorInstitution: `${typicalModel.institution}, ${typicalModel.country}`,"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" const accountServiceStub: Partial\u003cAccountService\u003e \u003d {"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" createAccountRequest: () \u003d\u003e new Observable((subscriber) \u003d\u003e {"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" subscriber.next();"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" }),"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" * Fills in form fields with the given data."},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" * @param data Data to fill form with."},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" function fillFormWith(data: InstructorRequestFormModel): void {"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" component.name.setValue(data.name);"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" component.institution.setValue(data.institution);"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" component.country.setValue(data.country);"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" component.email.setValue(data.email);"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" component.comments.setValue(data.comments);"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" beforeEach(waitForAsync(() \u003d\u003e {"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" TestBed.configureTestingModule({"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" declarations: [InstructorRequestFormComponent],"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" imports: [ReactiveFormsModule],"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" providers: [{ provide: AccountService, useValue: accountServiceStub }],"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" })"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" .compileComponents();"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" }));"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" fixture \u003d TestBed.createComponent(InstructorRequestFormComponent);"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" accountService \u003d TestBed.inject(AccountService);"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" fixture.detectChanges();"},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" jest.clearAllMocks();"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" expect(component).toBeTruthy();"},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":67,"author":{"gitId":"xenosf"},"content":" it(\u0027should render correctly\u0027, () \u003d\u003e {"},{"lineNumber":68,"author":{"gitId":"xenosf"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" it(\u0027should run onSubmit() when submit button is clicked\u0027, () \u003d\u003e {"},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" jest.spyOn(component, \u0027onSubmit\u0027);"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" fillFormWith(typicalModel);"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" const submitButton \u003d fixture.debugElement.query(By.css(\u0027#submit-button\u0027));"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" submitButton.nativeElement.click();"},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" expect(component.onSubmit).toHaveBeenCalledTimes(1);"},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":" it(\u0027should emit requestSubmissionEvent with the correct data when form is submitted\u0027, () \u003d\u003e {"},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":" jest.spyOn(accountService, \u0027createAccountRequest\u0027).mockReturnValue("},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" new Observable((subscriber) \u003d\u003e { subscriber.next(); }));"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":" // Listen for emitted value"},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":" let actualModel: InstructorRequestFormModel | null \u003d null;"},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":" component.requestSubmissionEvent.pipe(first())"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" .subscribe((data: InstructorRequestFormModel) \u003d\u003e { actualModel \u003d data; });"},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" fillFormWith(typicalModel);"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":" component.onSubmit();"},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":93,"author":{"gitId":"xenosf"},"content":" expect(actualModel).toBeTruthy();"},{"lineNumber":94,"author":{"gitId":"xenosf"},"content":" expect(actualModel!.name).toBe(typicalModel.name);"},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":" expect(actualModel!.institution).toBe(typicalModel.institution);"},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":" expect(actualModel!.country).toBe(typicalModel.country);"},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" expect(actualModel!.email).toBe(typicalModel.email);"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" expect(actualModel!.comments).toBe(typicalModel.comments);"},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":100,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":" it(\u0027should send the correct request data when form is submitted\u0027, () \u003d\u003e {"},{"lineNumber":102,"author":{"gitId":"xenosf"},"content":" jest.spyOn(accountService, \u0027createAccountRequest\u0027).mockReturnValue("},{"lineNumber":103,"author":{"gitId":"xenosf"},"content":" new Observable((subscriber) \u003d\u003e { subscriber.next(); }));"},{"lineNumber":104,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":105,"author":{"gitId":"xenosf"},"content":" fillFormWith(typicalModel);"},{"lineNumber":106,"author":{"gitId":"xenosf"},"content":" component.onSubmit();"},{"lineNumber":107,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":108,"author":{"gitId":"xenosf"},"content":" expect(accountService.createAccountRequest).toHaveBeenCalledTimes(1);"},{"lineNumber":109,"author":{"gitId":"xenosf"},"content":" expect(accountService.createAccountRequest).toHaveBeenCalledWith(expect.objectContaining(typicalCreateRequest));"},{"lineNumber":110,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":111,"author":{"gitId":"xenosf"},"content":"});"}],"authorContributionMap":{"xenosf":111}},{"path":"src/web/app/pages-static/request-page/instructor-request-form/instructor-request-form.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"import { Component, EventEmitter, Output } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":"import { FormControl, FormGroup, Validators } from \u0027@angular/forms\u0027;"},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import { finalize } from \u0027rxjs\u0027;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"import { InstructorRequestFormModel } from \u0027./instructor-request-form-model\u0027;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import { AccountService } from \u0027../../../../services/account.service\u0027;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import { AccountCreateRequest } from \u0027../../../../types/api-request\u0027;"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":"import { FormValidator } from \u0027../../../../types/form-validator\u0027;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":"import { ErrorMessageOutput } from \u0027../../../error-message-output\u0027;"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":"@Component({"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":" selector: \u0027tm-instructor-request-form\u0027,"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" templateUrl: \u0027./instructor-request-form.component.html\u0027,"},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" styleUrls: [\u0027./instructor-request-form.component.scss\u0027],"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":"})"},{"lineNumber":15,"author":{"gitId":"xenosf"},"content":"export class InstructorRequestFormComponent {"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" constructor(private accountService: AccountService) {}"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":" // Create members to be accessed in template"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" readonly STUDENT_NAME_MAX_LENGTH \u003d FormValidator.STUDENT_NAME_MAX_LENGTH;"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" readonly INSTITUTION_NAME_MAX_LENGTH \u003d FormValidator.INSTITUTION_NAME_MAX_LENGTH;"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" readonly COUNTRY_NAME_MAX_LENGTH \u003d FormValidator.COUNTRY_NAME_MAX_LENGTH;"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" readonly EMAIL_MAX_LENGTH \u003d FormValidator.EMAIL_MAX_LENGTH;"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" arf \u003d new FormGroup({"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" name: new FormControl(\u0027\u0027, ["},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" Validators.required,"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" Validators.maxLength(FormValidator.STUDENT_NAME_MAX_LENGTH),"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" Validators.pattern(FormValidator.NAME_REGEX),"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" ]),"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" institution: new FormControl(\u0027\u0027, ["},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" Validators.required,"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" Validators.maxLength(FormValidator.INSTITUTION_NAME_MAX_LENGTH),"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" Validators.pattern(FormValidator.NAME_REGEX),"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" ]),"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" country: new FormControl(\u0027\u0027, ["},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" Validators.required,"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" Validators.maxLength(FormValidator.COUNTRY_NAME_MAX_LENGTH),"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" Validators.pattern(FormValidator.NAME_REGEX),"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" ]),"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" email: new FormControl(\u0027\u0027, ["},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" Validators.required,"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" Validators.pattern(FormValidator.EMAIL_REGEX),"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" Validators.maxLength(FormValidator.EMAIL_MAX_LENGTH),"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" ]),"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" comments: new FormControl(\u0027\u0027),"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" }, { updateOn: \u0027submit\u0027 });"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" // Create members for easier access of arf controls"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" name \u003d this.arf.controls.name;"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" institution \u003d this.arf.controls.institution;"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" country \u003d this.arf.controls.country;"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" email \u003d this.arf.controls.email;"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" comments \u003d this.arf.controls.comments;"},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" hasSubmitAttempt \u003d false;"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":" isLoading \u003d false;"},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" @Output() requestSubmissionEvent \u003d new EventEmitter\u003cInstructorRequestFormModel\u003e();"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" serverErrorMessage \u003d \u0027\u0027;"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":" checkIsFieldRequired(field: FormControl): boolean {"},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" return field.hasValidator(Validators.required);"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":" get canSubmit(): boolean {"},{"lineNumber":67,"author":{"gitId":"xenosf"},"content":" return !this.isLoading;"},{"lineNumber":68,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":69,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":70,"author":{"gitId":"xenosf"},"content":" getFieldValidationClasses(field: FormControl): string {"},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" let str \u003d \u0027\u0027;"},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" if (this.hasSubmitAttempt) {"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":" if (field.invalid) {"},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" str \u003d \u0027is-invalid\u0027;"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" } else if (field.value !\u003d\u003d \u0027\u0027) {"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":" str \u003d \u0027is-valid\u0027;"},{"lineNumber":77,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":78,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":79,"author":{"gitId":"xenosf"},"content":" return str;"},{"lineNumber":80,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":81,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":82,"author":{"gitId":"xenosf"},"content":" onSubmit(): void {"},{"lineNumber":83,"author":{"gitId":"xenosf"},"content":" this.hasSubmitAttempt \u003d true;"},{"lineNumber":84,"author":{"gitId":"xenosf"},"content":" this.isLoading \u003d true;"},{"lineNumber":85,"author":{"gitId":"xenosf"},"content":" this.serverErrorMessage \u003d \u0027\u0027;"},{"lineNumber":86,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":87,"author":{"gitId":"xenosf"},"content":" if (this.arf.invalid) {"},{"lineNumber":88,"author":{"gitId":"xenosf"},"content":" this.isLoading \u003d false;"},{"lineNumber":89,"author":{"gitId":"xenosf"},"content":" // Do not submit form"},{"lineNumber":90,"author":{"gitId":"xenosf"},"content":" return;"},{"lineNumber":91,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":92,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":93,"author":{"gitId":"xenosf"},"content":" const name \u003d this.name.value!.trim();"},{"lineNumber":94,"author":{"gitId":"xenosf"},"content":" const email \u003d this.email.value!.trim();"},{"lineNumber":95,"author":{"gitId":"xenosf"},"content":" const comments \u003d this.comments.value!.trim();"},{"lineNumber":96,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":97,"author":{"gitId":"xenosf"},"content":" // Combine country and institution"},{"lineNumber":98,"author":{"gitId":"xenosf"},"content":" const country \u003d this.country.value!.trim();"},{"lineNumber":99,"author":{"gitId":"xenosf"},"content":" const institution \u003d this.institution.value!.trim();"},{"lineNumber":100,"author":{"gitId":"xenosf"},"content":" const combinedInstitution \u003d `${institution}, ${country}`;"},{"lineNumber":101,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":102,"author":{"gitId":"xenosf"},"content":" const requestData: AccountCreateRequest \u003d {"},{"lineNumber":103,"author":{"gitId":"xenosf"},"content":" instructorEmail: email,"},{"lineNumber":104,"author":{"gitId":"xenosf"},"content":" instructorName: name,"},{"lineNumber":105,"author":{"gitId":"xenosf"},"content":" instructorInstitution: combinedInstitution,"},{"lineNumber":106,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":107,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":108,"author":{"gitId":"xenosf"},"content":" if (comments) {"},{"lineNumber":109,"author":{"gitId":"xenosf"},"content":" requestData.instructorComments \u003d comments;"},{"lineNumber":110,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":111,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":112,"author":{"gitId":"xenosf"},"content":" this.accountService.createAccountRequest(requestData)"},{"lineNumber":113,"author":{"gitId":"xenosf"},"content":" .pipe(finalize(() \u003d\u003e { this.isLoading \u003d false; }))"},{"lineNumber":114,"author":{"gitId":"xenosf"},"content":" .subscribe({"},{"lineNumber":115,"author":{"gitId":"xenosf"},"content":" next: () \u003d\u003e {"},{"lineNumber":116,"author":{"gitId":"xenosf"},"content":" // Pass form input to parent to display confirmation"},{"lineNumber":117,"author":{"gitId":"xenosf"},"content":" this.requestSubmissionEvent.emit({"},{"lineNumber":118,"author":{"gitId":"xenosf"},"content":" name,"},{"lineNumber":119,"author":{"gitId":"xenosf"},"content":" institution,"},{"lineNumber":120,"author":{"gitId":"xenosf"},"content":" country,"},{"lineNumber":121,"author":{"gitId":"xenosf"},"content":" email,"},{"lineNumber":122,"author":{"gitId":"xenosf"},"content":" comments,"},{"lineNumber":123,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":124,"author":{"gitId":"xenosf"},"content":" },"},{"lineNumber":125,"author":{"gitId":"xenosf"},"content":" error: (resp: ErrorMessageOutput) \u003d\u003e {"},{"lineNumber":126,"author":{"gitId":"xenosf"},"content":" this.serverErrorMessage \u003d resp.error.message;"},{"lineNumber":127,"author":{"gitId":"xenosf"},"content":" },"},{"lineNumber":128,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":129,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":130,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":130}},{"path":"src/web/app/pages-static/request-page/request-page.component.html","fileType":"html","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"\u003ch1 class\u003d\"color-orange\"\u003e"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":" Request for an Instructor Account"},{"lineNumber":3,"author":{"gitId":"-"},"content":"\u003c/h1\u003e"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":"\u003cdiv class\u003d\"col-xs-12 col-md-10 col-lg-8 col-xl-7 col-xxl-6\"\u003e"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"!submittedFormData\"\u003e"},{"lineNumber":6,"author":{"gitId":"-"},"content":" \u003cp\u003e"},{"lineNumber":7,"author":{"gitId":"xenosf"},"content":" Request for an instructor account using this form if you are an instructor and want to use TEAMMATES to manage peer evaluations and/or other feedback paths of your students."},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":" \u003c/p\u003e"},{"lineNumber":9,"author":{"gitId":"xenosf"},"content":" \u003chr\u003e"},{"lineNumber":10,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"!isDeclarationDone\"\u003e"},{"lineNumber":11,"author":{"gitId":"xenosf"},"content":" \u003cp\u003e"},{"lineNumber":12,"author":{"gitId":"xenosf"},"content":" Note: \u003cb\u003eStudents should not use this form to request for TEAMMATES accounts\u003c/b\u003e, as students do not need accounts to use TEAMMATES. Instead, TEAMMATES will email students (who have been added to TEAMMATES by a course instructor) an access link when there is a TEAMMATES session available for them to access."},{"lineNumber":13,"author":{"gitId":"xenosf"},"content":" \u003c/p\u003e"},{"lineNumber":14,"author":{"gitId":"xenosf"},"content":" \u003ca type\u003d\"button\" class\u003d\"btn btn-secondary\" tmRouterLink\u003d\"/web/front/home\"\u003eBack to home page\u003c/a\u003e"},{"lineNumber":15,"author":{"gitId":"dishenggg"},"content":" \u003cbutton id\u003d\"btn-am-instructor\" type\u003d\"button\" class\u003d\"btn btn-primary ms-3\" (click)\u003d\"onDeclarationButtonClicked()\"\u003eI am an instructor\u003c/button\u003e"},{"lineNumber":16,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"isDeclarationDone\"\u003e"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":" \u003ctm-instructor-request-form *ngIf\u003d\"!submittedFormData\" (requestSubmissionEvent)\u003d\"onRequestSubmitted($event)\"\u003e\u003c/tm-instructor-request-form\u003e"},{"lineNumber":19,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":20,"author":{"gitId":"xenosf"},"content":" \u003chr\u003e"},{"lineNumber":21,"author":{"gitId":"xenosf"},"content":" \u003c/div\u003e"},{"lineNumber":22,"author":{"gitId":"xenosf"},"content":" \u003cdiv *ngIf\u003d\"submittedFormData\"\u003e"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" \u003cp\u003e"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":" Your request has been submitted successfully:"},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" \u003c/p\u003e"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" \u003ctable class\u003d\"table table-bordered my-3\"\u003e"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" \u003ctbody\u003e"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" \u003cth scope\u003d\"row\" class\u003d\"col-3\"\u003eFull Name\u003c/th\u003e"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" \u003ctd\u003e{{submittedFormData.name}}\u003c/td\u003e"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" \u003cth scope\u003d\"row\"\u003eInstitution\u003c/th\u003e"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" \u003ctd\u003e{{submittedFormData.institution}}\u003c/td\u003e"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" \u003cth scope\u003d\"row\"\u003eCountry\u003c/th\u003e"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" \u003ctd\u003e{{submittedFormData.country}}\u003c/td\u003e"},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" \u003cth scope\u003d\"row\"\u003eEmail\u003c/th\u003e"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" \u003ctd\u003e{{submittedFormData.email}}\u003c/td\u003e"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" \u003ctr\u003e"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" \u003cth scope\u003d\"row\"\u003eComments\u003c/th\u003e"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" \u003ctd\u003e"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" {{submittedFormData.comments}}"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" \u003cspan class\u003d\"empty-field-placeholder\" *ngIf\u003d\"!submittedFormData.comments\"\u003e\u003c/span\u003e"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" \u003c/td\u003e"},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" \u003c/tr\u003e"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" \u003c/tbody\u003e"},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" \u003c/table\u003e"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" \u003cp\u003e"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" We have sent an acknowledgement email to your email address \u003cb\u003e{{submittedFormData.email}}\u003c/b\u003e."},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":" Please check your email inbox or spam folder."},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" If you do not receive the acknowledgement email within 1 hour, please \u003ca tmRouterLink\u003d\"/web/front/contact\"\u003econtact\u003c/a\u003e us."},{"lineNumber":57,"author":{"gitId":"-"},"content":" \u003c/p\u003e"},{"lineNumber":58,"author":{"gitId":"-"},"content":" \u003c/div\u003e"},{"lineNumber":59,"author":{"gitId":"-"},"content":"\u003c/div\u003e"}],"authorContributionMap":{"xenosf":52,"dishenggg":1,"-":6}},{"path":"src/web/app/pages-static/request-page/request-page.component.scss","fileType":"scss","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":".empty-field-placeholder::after {"},{"lineNumber":2,"author":{"gitId":"xenosf"},"content":" content: \"(empty)\";"},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":" opacity: 0.5;"},{"lineNumber":4,"author":{"gitId":"xenosf"},"content":" font-style: italic;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"}"}],"authorContributionMap":{"xenosf":5}},{"path":"src/web/app/pages-static/request-page/request-page.component.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { ComponentFixture, TestBed, waitForAsync } from \u0027@angular/core/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { RequestPageComponent } from \u0027./request-page.component\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":""},{"lineNumber":4,"author":{"gitId":"-"},"content":"describe(\u0027RequestPageComponent\u0027, () \u003d\u003e {"},{"lineNumber":5,"author":{"gitId":"-"},"content":" let component: RequestPageComponent;"},{"lineNumber":6,"author":{"gitId":"-"},"content":" let fixture: ComponentFixture\u003cRequestPageComponent\u003e;"},{"lineNumber":7,"author":{"gitId":"-"},"content":""},{"lineNumber":8,"author":{"gitId":"-"},"content":" beforeEach(waitForAsync(() \u003d\u003e {"},{"lineNumber":9,"author":{"gitId":"-"},"content":" TestBed.configureTestingModule({"},{"lineNumber":10,"author":{"gitId":"-"},"content":" declarations: [RequestPageComponent],"},{"lineNumber":11,"author":{"gitId":"-"},"content":" })"},{"lineNumber":12,"author":{"gitId":"-"},"content":" .compileComponents();"},{"lineNumber":13,"author":{"gitId":"-"},"content":" }));"},{"lineNumber":14,"author":{"gitId":"-"},"content":""},{"lineNumber":15,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":16,"author":{"gitId":"-"},"content":" fixture \u003d TestBed.createComponent(RequestPageComponent);"},{"lineNumber":17,"author":{"gitId":"-"},"content":" component \u003d fixture.componentInstance;"},{"lineNumber":18,"author":{"gitId":"-"},"content":" fixture.detectChanges();"},{"lineNumber":19,"author":{"gitId":"-"},"content":" });"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" it(\u0027should create\u0027, () \u003d\u003e {"},{"lineNumber":22,"author":{"gitId":"-"},"content":" expect(component).toBeTruthy();"},{"lineNumber":23,"author":{"gitId":"-"},"content":" });"},{"lineNumber":24,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":25,"author":{"gitId":"xenosf"},"content":" it(\u0027should render correctly before instructor declaration is done\u0027, () \u003d\u003e {"},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" component.isDeclarationDone \u003d false;"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" component.submittedFormData \u003d null;"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" fixture.detectChanges();"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" it(\u0027should render correctly after instructor declaration is done\u0027, () \u003d\u003e {"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" component.isDeclarationDone \u003d true;"},{"lineNumber":34,"author":{"gitId":"xenosf"},"content":" component.submittedFormData \u003d null;"},{"lineNumber":35,"author":{"gitId":"xenosf"},"content":" fixture.detectChanges();"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" it(\u0027should render correctly after form is submitted\u0027, () \u003d\u003e {"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" component.submittedFormData \u003d {"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":" name: \u0027Jane Smith\u0027,"},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" institution: \u0027University of Example\u0027,"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" country: \u0027Example Republic\u0027,"},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" email: \u0027js@exampleu.edu\u0027,"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" comments: \u0027\u0027,"},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" };"},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" fixture.detectChanges();"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" expect(fixture).toMatchSnapshot();"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":50,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"xenosf":26,"-":24}},{"path":"src/web/app/pages-static/request-page/request-page.component.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Component } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { DomSanitizer, SafeResourceUrl } from \u0027@angular/platform-browser\u0027;"},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import { InstructorRequestFormModel } from \u0027./instructor-request-form/instructor-request-form-model\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { environment } from \u0027../../../environments/environment\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":""},{"lineNumber":6,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":7,"author":{"gitId":"-"},"content":" * Account request page."},{"lineNumber":8,"author":{"gitId":"-"},"content":" */"},{"lineNumber":9,"author":{"gitId":"-"},"content":"@Component({"},{"lineNumber":10,"author":{"gitId":"-"},"content":" selector: \u0027tm-request-page\u0027,"},{"lineNumber":11,"author":{"gitId":"-"},"content":" templateUrl: \u0027./request-page.component.html\u0027,"},{"lineNumber":12,"author":{"gitId":"-"},"content":" styleUrls: [\u0027./request-page.component.scss\u0027],"},{"lineNumber":13,"author":{"gitId":"-"},"content":"})"},{"lineNumber":14,"author":{"gitId":"-"},"content":"export class RequestPageComponent {"},{"lineNumber":15,"author":{"gitId":"-"},"content":""},{"lineNumber":16,"author":{"gitId":"-"},"content":" accountRequestFormUrl: SafeResourceUrl | null;"},{"lineNumber":17,"author":{"gitId":"xenosf"},"content":" isDeclarationDone: boolean \u003d false;"},{"lineNumber":18,"author":{"gitId":"xenosf"},"content":" submittedFormData: InstructorRequestFormModel | null \u003d null;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":" constructor(private sanitizer: DomSanitizer) {"},{"lineNumber":21,"author":{"gitId":"-"},"content":" this.accountRequestFormUrl \u003d environment.accountRequestFormUrl"},{"lineNumber":22,"author":{"gitId":"-"},"content":" ? this.sanitizer.bypassSecurityTrustResourceUrl(environment.accountRequestFormUrl)"},{"lineNumber":23,"author":{"gitId":"-"},"content":" : null;"},{"lineNumber":24,"author":{"gitId":"-"},"content":" }"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"xenosf"},"content":" onDeclarationButtonClicked(): void {"},{"lineNumber":27,"author":{"gitId":"xenosf"},"content":" this.isDeclarationDone \u003d true;"},{"lineNumber":28,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":29,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":30,"author":{"gitId":"xenosf"},"content":" onRequestSubmitted(data: InstructorRequestFormModel): void {"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" this.submittedFormData \u003d data;"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" }"},{"lineNumber":33,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":10,"-":23}},{"path":"src/web/app/pages-static/request-page/request-page.module.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { CommonModule } from \u0027@angular/common\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { NgModule } from \u0027@angular/core\u0027;"},{"lineNumber":3,"author":{"gitId":"xenosf"},"content":"import { ReactiveFormsModule } from \u0027@angular/forms\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { RouterModule, Routes } from \u0027@angular/router\u0027;"},{"lineNumber":5,"author":{"gitId":"xenosf"},"content":"import { NgbAlertModule } from \u0027@ng-bootstrap/ng-bootstrap\u0027;"},{"lineNumber":6,"author":{"gitId":"xenosf"},"content":"import { InstructorRequestFormComponent } from \u0027./instructor-request-form/instructor-request-form.component\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { RequestPageComponent } from \u0027./request-page.component\u0027;"},{"lineNumber":8,"author":{"gitId":"xenosf"},"content":"import { TeammatesRouterModule } from \u0027../../components/teammates-router/teammates-router.module\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":""},{"lineNumber":10,"author":{"gitId":"-"},"content":"const routes: Routes \u003d ["},{"lineNumber":11,"author":{"gitId":"-"},"content":" {"},{"lineNumber":12,"author":{"gitId":"-"},"content":" path: \u0027\u0027,"},{"lineNumber":13,"author":{"gitId":"-"},"content":" component: RequestPageComponent,"},{"lineNumber":14,"author":{"gitId":"-"},"content":" },"},{"lineNumber":15,"author":{"gitId":"-"},"content":"];"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * Module for request page."},{"lineNumber":19,"author":{"gitId":"-"},"content":" */"},{"lineNumber":20,"author":{"gitId":"-"},"content":"@NgModule({"},{"lineNumber":21,"author":{"gitId":"-"},"content":" declarations: ["},{"lineNumber":22,"author":{"gitId":"-"},"content":" RequestPageComponent,"},{"lineNumber":23,"author":{"gitId":"xenosf"},"content":" InstructorRequestFormComponent,"},{"lineNumber":24,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":25,"author":{"gitId":"-"},"content":" exports: ["},{"lineNumber":26,"author":{"gitId":"-"},"content":" RequestPageComponent,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":28,"author":{"gitId":"-"},"content":" imports: ["},{"lineNumber":29,"author":{"gitId":"-"},"content":" CommonModule,"},{"lineNumber":30,"author":{"gitId":"-"},"content":" RouterModule.forChild(routes),"},{"lineNumber":31,"author":{"gitId":"xenosf"},"content":" TeammatesRouterModule,"},{"lineNumber":32,"author":{"gitId":"xenosf"},"content":" ReactiveFormsModule,"},{"lineNumber":33,"author":{"gitId":"xenosf"},"content":" NgbAlertModule,"},{"lineNumber":34,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":35,"author":{"gitId":"-"},"content":"})"},{"lineNumber":36,"author":{"gitId":"-"},"content":"export class RequestPageModule { }"}],"authorContributionMap":{"xenosf":8,"-":28}},{"path":"src/web/services/account.service.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { HttpClientTestingModule } from \u0027@angular/common/http/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { TestBed } from \u0027@angular/core/testing\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { AccountService } from \u0027./account.service\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { HttpRequestService } from \u0027./http-request.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import createSpyFromClass from \u0027../test-helpers/create-spy-from-class\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { ResourceEndpoints } from \u0027../types/api-const\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { AccountCreateRequest } from \u0027../types/api-request\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":""},{"lineNumber":9,"author":{"gitId":"-"},"content":"describe(\u0027AccountService\u0027, () \u003d\u003e {"},{"lineNumber":10,"author":{"gitId":"-"},"content":" let spyHttpRequestService: any;"},{"lineNumber":11,"author":{"gitId":"-"},"content":" let service: AccountService;"},{"lineNumber":12,"author":{"gitId":"-"},"content":" const id: string \u003d \u0027TestID\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":""},{"lineNumber":14,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":15,"author":{"gitId":"-"},"content":" spyHttpRequestService \u003d createSpyFromClass(HttpRequestService);"},{"lineNumber":16,"author":{"gitId":"-"},"content":" TestBed.configureTestingModule({"},{"lineNumber":17,"author":{"gitId":"-"},"content":" imports: ["},{"lineNumber":18,"author":{"gitId":"-"},"content":" HttpClientTestingModule,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":20,"author":{"gitId":"-"},"content":" providers: ["},{"lineNumber":21,"author":{"gitId":"-"},"content":" { provide: HttpRequestService, useValue: spyHttpRequestService },"},{"lineNumber":22,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":23,"author":{"gitId":"-"},"content":" });"},{"lineNumber":24,"author":{"gitId":"-"},"content":" service \u003d TestBed.inject(AccountService);"},{"lineNumber":25,"author":{"gitId":"-"},"content":" });"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" it(\u0027should be created\u0027, () \u003d\u003e {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" expect(service).toBeTruthy();"},{"lineNumber":29,"author":{"gitId":"-"},"content":" });"},{"lineNumber":30,"author":{"gitId":"-"},"content":""},{"lineNumber":31,"author":{"gitId":"-"},"content":" it(\u0027should execute GET on account endpoint\u0027, () \u003d\u003e {"},{"lineNumber":32,"author":{"gitId":"-"},"content":" service.getAccount(id);"},{"lineNumber":33,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" instructorid: id,"},{"lineNumber":35,"author":{"gitId":"-"},"content":" };"},{"lineNumber":36,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.get).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNT, paramMap);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" });"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" it(\u0027should execute GET on accounts endpoint\u0027, () \u003d\u003e {"},{"lineNumber":40,"author":{"gitId":"-"},"content":" const email \u003d \u0027email@gmail.tmt\u0027;"},{"lineNumber":41,"author":{"gitId":"-"},"content":" service.getAccounts(email);"},{"lineNumber":42,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":43,"author":{"gitId":"-"},"content":" useremail: email,"},{"lineNumber":44,"author":{"gitId":"-"},"content":" };"},{"lineNumber":45,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.get).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNTS, paramMap);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" });"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" it(\u0027should execute POST on account endpoint with timezone string\u0027, () \u003d\u003e {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" const testKey: string \u003d \u0027testKey\u0027;"},{"lineNumber":50,"author":{"gitId":"-"},"content":" const testTimezone: string \u003d \u0027UTC\u0027;"},{"lineNumber":51,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" key: testKey,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" timezone: testTimezone,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" };"},{"lineNumber":55,"author":{"gitId":"-"},"content":" service.createAccount(testKey, testTimezone);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.post).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNT, paramMap);"},{"lineNumber":57,"author":{"gitId":"-"},"content":" });"},{"lineNumber":58,"author":{"gitId":"-"},"content":""},{"lineNumber":59,"author":{"gitId":"-"},"content":" it(\u0027should execute POST on account endpoint with empty timezone string\u0027, () \u003d\u003e {"},{"lineNumber":60,"author":{"gitId":"-"},"content":" const testKey: string \u003d \u0027testKey\u0027;"},{"lineNumber":61,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" key: testKey,"},{"lineNumber":63,"author":{"gitId":"-"},"content":" };"},{"lineNumber":64,"author":{"gitId":"-"},"content":" service.createAccount(testKey, \u0027\u0027);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.post).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNT, paramMap);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" });"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" it(\u0027should execute POST on account request endpoint\u0027, () \u003d\u003e {"},{"lineNumber":69,"author":{"gitId":"-"},"content":" const testRequest: AccountCreateRequest \u003d {"},{"lineNumber":70,"author":{"gitId":"-"},"content":" instructorEmail: \u0027testEmail\u0027,"},{"lineNumber":71,"author":{"gitId":"-"},"content":" instructorInstitution: \u0027testInstitution\u0027,"},{"lineNumber":72,"author":{"gitId":"-"},"content":" instructorName: \u0027testName\u0027,"},{"lineNumber":73,"author":{"gitId":"-"},"content":" };"},{"lineNumber":74,"author":{"gitId":"-"},"content":" service.createAccountRequest(testRequest);"},{"lineNumber":75,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.post).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNT_REQUEST, {}, testRequest);"},{"lineNumber":76,"author":{"gitId":"-"},"content":" });"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" it(\u0027should execute DELETE on account endpoint\u0027, () \u003d\u003e {"},{"lineNumber":79,"author":{"gitId":"-"},"content":" service.deleteAccount(id);"},{"lineNumber":80,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":81,"author":{"gitId":"-"},"content":" instructorid: id,"},{"lineNumber":82,"author":{"gitId":"-"},"content":" };"},{"lineNumber":83,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.delete).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNT, paramMap);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" });"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" it(\u0027should execute DELETE on account request endpoint\u0027, () \u003d\u003e {"},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" service.deleteAccountRequest(\u0027testId\u0027);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":" id: \u0027testId\u0027,"},{"lineNumber":90,"author":{"gitId":"-"},"content":" };"},{"lineNumber":91,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.delete).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNT_REQUEST, paramMap);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" });"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" it(\u0027should execute PUT on account request reset endpoint\u0027, () \u003d\u003e {"},{"lineNumber":95,"author":{"gitId":"dishenggg"},"content":" service.resetAccountRequest(\u0027testId\u0027);"},{"lineNumber":96,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":97,"author":{"gitId":"dishenggg"},"content":" id: \u0027testId\u0027,"},{"lineNumber":98,"author":{"gitId":"-"},"content":" };"},{"lineNumber":99,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.put).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNT_REQUEST_RESET, paramMap);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" });"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" it(\u0027should execute PUT on account/reset endpoint for student\u0027, () \u003d\u003e {"},{"lineNumber":103,"author":{"gitId":"-"},"content":" service.resetStudentAccount(id, \u0027testStudentEmail\u0027);"},{"lineNumber":104,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" courseid: id,"},{"lineNumber":106,"author":{"gitId":"-"},"content":" studentemail: \u0027testStudentEmail\u0027,"},{"lineNumber":107,"author":{"gitId":"-"},"content":" };"},{"lineNumber":108,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.put).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNT_RESET, paramMap);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" });"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" it(\u0027should execute PUT on account/reset endpoint for instructor\u0027, () \u003d\u003e {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" service.resetInstructorAccount(id, \u0027testInstructorEmail\u0027);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":114,"author":{"gitId":"-"},"content":" courseid: id,"},{"lineNumber":115,"author":{"gitId":"-"},"content":" instructoremail: \u0027testInstructorEmail\u0027,"},{"lineNumber":116,"author":{"gitId":"-"},"content":" };"},{"lineNumber":117,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.put).toHaveBeenCalledWith(ResourceEndpoints.ACCOUNT_RESET, paramMap);"},{"lineNumber":118,"author":{"gitId":"-"},"content":" });"},{"lineNumber":119,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"dishenggg":4,"-":115}},{"path":"src/web/services/account.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { HttpRequestService } from \u0027./http-request.service\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { ResourceEndpoints } from \u0027../types/api-const\u0027;"},{"lineNumber":5,"author":{"gitId":"domoberzin"},"content":"import {"},{"lineNumber":6,"author":{"gitId":"domoberzin"},"content":" Account,"},{"lineNumber":7,"author":{"gitId":"domoberzin"},"content":" AccountRequest,"},{"lineNumber":8,"author":{"gitId":"domoberzin"},"content":" Accounts,"},{"lineNumber":9,"author":{"gitId":"domoberzin"},"content":" AccountRequests,"},{"lineNumber":10,"author":{"gitId":"domoberzin"},"content":" JoinLink,"},{"lineNumber":11,"author":{"gitId":"domoberzin"},"content":" MessageOutput,"},{"lineNumber":12,"author":{"gitId":"domoberzin"},"content":" AccountRequestStatus,"},{"lineNumber":13,"author":{"gitId":"domoberzin"},"content":"} from \u0027../types/api-output\u0027;"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":"import {"},{"lineNumber":15,"author":{"gitId":"domoberzin"},"content":" AccountCreateRequest,"},{"lineNumber":16,"author":{"gitId":"domoberzin"},"content":" AccountRequestUpdateRequest,"},{"lineNumber":17,"author":{"gitId":"domoberzin"},"content":" AccountRequestRejectionRequest,"},{"lineNumber":18,"author":{"gitId":"domoberzin"},"content":"} from \u0027../types/api-request\u0027;"},{"lineNumber":19,"author":{"gitId":"-"},"content":""},{"lineNumber":20,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":21,"author":{"gitId":"-"},"content":" * Handles account related logic provision"},{"lineNumber":22,"author":{"gitId":"-"},"content":" */"},{"lineNumber":23,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":24,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027,"},{"lineNumber":25,"author":{"gitId":"-"},"content":"})"},{"lineNumber":26,"author":{"gitId":"-"},"content":"export class AccountService {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" constructor(private httpRequestService: HttpRequestService) {"},{"lineNumber":28,"author":{"gitId":"-"},"content":" }"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":31,"author":{"gitId":"-"},"content":" * Creates an account by calling API."},{"lineNumber":32,"author":{"gitId":"-"},"content":" */"},{"lineNumber":33,"author":{"gitId":"-"},"content":" createAccount(key: string, timezone: string): Observable\u003cMessageOutput\u003e {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d { key };"},{"lineNumber":35,"author":{"gitId":"-"},"content":" if (timezone) {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" paramMap[\u0027timezone\u0027] \u003d timezone;"},{"lineNumber":37,"author":{"gitId":"-"},"content":" }"},{"lineNumber":38,"author":{"gitId":"-"},"content":" return this.httpRequestService.post(ResourceEndpoints.ACCOUNT, paramMap);"},{"lineNumber":39,"author":{"gitId":"-"},"content":" }"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":42,"author":{"gitId":"-"},"content":" * Creates an account request by calling API."},{"lineNumber":43,"author":{"gitId":"-"},"content":" */"},{"lineNumber":44,"author":{"gitId":"-"},"content":" createAccountRequest(request: AccountCreateRequest): Observable\u003cAccountRequest\u003e {"},{"lineNumber":45,"author":{"gitId":"-"},"content":" return this.httpRequestService.post(ResourceEndpoints.ACCOUNT_REQUEST, {}, request);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" }"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":49,"author":{"gitId":"-"},"content":" * Deletes an account by calling API."},{"lineNumber":50,"author":{"gitId":"-"},"content":" */"},{"lineNumber":51,"author":{"gitId":"-"},"content":" deleteAccount(id: string): Observable\u003cMessageOutput\u003e {"},{"lineNumber":52,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":53,"author":{"gitId":"-"},"content":" instructorid: id,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" };"},{"lineNumber":55,"author":{"gitId":"-"},"content":" return this.httpRequestService.delete(ResourceEndpoints.ACCOUNT, paramMap);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" }"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":59,"author":{"gitId":"-"},"content":" * Deletes an account request by calling API."},{"lineNumber":60,"author":{"gitId":"-"},"content":" */"},{"lineNumber":61,"author":{"gitId":"dishenggg"},"content":" deleteAccountRequest(id: string): Observable\u003cMessageOutput\u003e {"},{"lineNumber":62,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" id,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" };"},{"lineNumber":65,"author":{"gitId":"-"},"content":" return this.httpRequestService.delete(ResourceEndpoints.ACCOUNT_REQUEST, paramMap);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" }"},{"lineNumber":67,"author":{"gitId":"-"},"content":""},{"lineNumber":68,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":69,"author":{"gitId":"-"},"content":" * Resets an account request by calling API."},{"lineNumber":70,"author":{"gitId":"-"},"content":" */"},{"lineNumber":71,"author":{"gitId":"dishenggg"},"content":" resetAccountRequest(id: string): Observable\u003cJoinLink\u003e {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":73,"author":{"gitId":"dishenggg"},"content":" id,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" };"},{"lineNumber":75,"author":{"gitId":"-"},"content":" return this.httpRequestService.put(ResourceEndpoints.ACCOUNT_REQUEST_RESET, paramMap);"},{"lineNumber":76,"author":{"gitId":"-"},"content":" }"},{"lineNumber":77,"author":{"gitId":"-"},"content":""},{"lineNumber":78,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":79,"author":{"gitId":"-"},"content":" * Resets a student account by calling API."},{"lineNumber":80,"author":{"gitId":"-"},"content":" */"},{"lineNumber":81,"author":{"gitId":"-"},"content":" resetStudentAccount(courseId: string, studentEmail: string): Observable\u003cMessageOutput\u003e {"},{"lineNumber":82,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" courseid: courseId,"},{"lineNumber":84,"author":{"gitId":"-"},"content":" studentemail: studentEmail,"},{"lineNumber":85,"author":{"gitId":"-"},"content":" };"},{"lineNumber":86,"author":{"gitId":"-"},"content":" return this.httpRequestService.put(ResourceEndpoints.ACCOUNT_RESET, paramMap);"},{"lineNumber":87,"author":{"gitId":"-"},"content":" }"},{"lineNumber":88,"author":{"gitId":"-"},"content":""},{"lineNumber":89,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":90,"author":{"gitId":"-"},"content":" * Resets an instructor account by calling API."},{"lineNumber":91,"author":{"gitId":"-"},"content":" */"},{"lineNumber":92,"author":{"gitId":"-"},"content":" resetInstructorAccount(courseId: string, instructorEmail: string): Observable\u003cMessageOutput\u003e {"},{"lineNumber":93,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":94,"author":{"gitId":"-"},"content":" courseid: courseId,"},{"lineNumber":95,"author":{"gitId":"-"},"content":" instructoremail: instructorEmail,"},{"lineNumber":96,"author":{"gitId":"-"},"content":" };"},{"lineNumber":97,"author":{"gitId":"-"},"content":" return this.httpRequestService.put(ResourceEndpoints.ACCOUNT_RESET, paramMap);"},{"lineNumber":98,"author":{"gitId":"-"},"content":" }"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":101,"author":{"gitId":"domoberzin"},"content":" * Approves account request by calling API"},{"lineNumber":102,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":103,"author":{"gitId":"domoberzin"},"content":" approveAccountRequest(id: string, name: string, email: string, institute: string)"},{"lineNumber":104,"author":{"gitId":"domoberzin"},"content":" : Observable\u003cAccountRequest\u003e {"},{"lineNumber":105,"author":{"gitId":"domoberzin"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":106,"author":{"gitId":"domoberzin"},"content":" id,"},{"lineNumber":107,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":108,"author":{"gitId":"domoberzin"},"content":" const accountReqUpdateRequest : AccountRequestUpdateRequest \u003d {"},{"lineNumber":109,"author":{"gitId":"domoberzin"},"content":" name,"},{"lineNumber":110,"author":{"gitId":"domoberzin"},"content":" email,"},{"lineNumber":111,"author":{"gitId":"domoberzin"},"content":" institute,"},{"lineNumber":112,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus.APPROVED,"},{"lineNumber":113,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":114,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":115,"author":{"gitId":"domoberzin"},"content":" return this.httpRequestService.put(ResourceEndpoints.ACCOUNT_REQUEST, paramMap, accountReqUpdateRequest);"},{"lineNumber":116,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":117,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":118,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":119,"author":{"gitId":"domoberzin"},"content":" * Edits an account request by calling API."},{"lineNumber":120,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":121,"author":{"gitId":"domoberzin"},"content":" editAccountRequest(id: string, name: string, email: string, institute: string,"},{"lineNumber":122,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus, comments: string)"},{"lineNumber":123,"author":{"gitId":"domoberzin"},"content":" : Observable\u003cAccountRequest\u003e {"},{"lineNumber":124,"author":{"gitId":"domoberzin"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":125,"author":{"gitId":"domoberzin"},"content":" id,"},{"lineNumber":126,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":127,"author":{"gitId":"domoberzin"},"content":" const accountReqUpdateRequest : AccountRequestUpdateRequest \u003d {"},{"lineNumber":128,"author":{"gitId":"domoberzin"},"content":" name,"},{"lineNumber":129,"author":{"gitId":"domoberzin"},"content":" email,"},{"lineNumber":130,"author":{"gitId":"domoberzin"},"content":" institute,"},{"lineNumber":131,"author":{"gitId":"domoberzin"},"content":" status,"},{"lineNumber":132,"author":{"gitId":"domoberzin"},"content":" comments,"},{"lineNumber":133,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":134,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":135,"author":{"gitId":"domoberzin"},"content":" return this.httpRequestService.put(ResourceEndpoints.ACCOUNT_REQUEST, paramMap, accountReqUpdateRequest);"},{"lineNumber":136,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":137,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":139,"author":{"gitId":"-"},"content":" * Gets an account by calling API."},{"lineNumber":140,"author":{"gitId":"-"},"content":" */"},{"lineNumber":141,"author":{"gitId":"-"},"content":" getAccount(googleId: string): Observable\u003cAccount\u003e {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" instructorid: googleId,"},{"lineNumber":144,"author":{"gitId":"-"},"content":" };"},{"lineNumber":145,"author":{"gitId":"-"},"content":" return this.httpRequestService.get(ResourceEndpoints.ACCOUNT, paramMap);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" }"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":149,"author":{"gitId":"-"},"content":" * Gets accounts by calling API."},{"lineNumber":150,"author":{"gitId":"-"},"content":" */"},{"lineNumber":151,"author":{"gitId":"-"},"content":" getAccounts(email: string): Observable\u003cAccounts\u003e {"},{"lineNumber":152,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" useremail: email,"},{"lineNumber":154,"author":{"gitId":"-"},"content":" };"},{"lineNumber":155,"author":{"gitId":"-"},"content":" return this.httpRequestService.get(ResourceEndpoints.ACCOUNTS, paramMap);"},{"lineNumber":156,"author":{"gitId":"-"},"content":" }"},{"lineNumber":157,"author":{"gitId":"-"},"content":""},{"lineNumber":158,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":159,"author":{"gitId":"domoberzin"},"content":" * Gets account requests by calling API."},{"lineNumber":160,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":161,"author":{"gitId":"domoberzin"},"content":" getPendingAccountRequests(): Observable\u003cAccountRequests\u003e {"},{"lineNumber":162,"author":{"gitId":"domoberzin"},"content":" const paramMap \u003d {"},{"lineNumber":163,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus.PENDING,"},{"lineNumber":164,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":165,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":166,"author":{"gitId":"domoberzin"},"content":" return this.httpRequestService.get(ResourceEndpoints.ACCOUNT_REQUESTS, paramMap);"},{"lineNumber":167,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":168,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":169,"author":{"gitId":"domoberzin"},"content":" /**"},{"lineNumber":170,"author":{"gitId":"domoberzin"},"content":" * Rejects an account request by calling API."},{"lineNumber":171,"author":{"gitId":"domoberzin"},"content":" */"},{"lineNumber":172,"author":{"gitId":"domoberzin"},"content":" rejectAccountRequest(id: string, title?: string, body?: string): Observable\u003cAccountRequest\u003e {"},{"lineNumber":173,"author":{"gitId":"domoberzin"},"content":" let accountReqRejectRequest: AccountRequestRejectionRequest \u003d {};"},{"lineNumber":174,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":175,"author":{"gitId":"domoberzin"},"content":" if (title !\u003d\u003d undefined \u0026\u0026 body !\u003d\u003d undefined) {"},{"lineNumber":176,"author":{"gitId":"domoberzin"},"content":" accountReqRejectRequest \u003d {"},{"lineNumber":177,"author":{"gitId":"domoberzin"},"content":" reasonTitle: title,"},{"lineNumber":178,"author":{"gitId":"domoberzin"},"content":" reasonBody: body,"},{"lineNumber":179,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":180,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":181,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":182,"author":{"gitId":"domoberzin"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":183,"author":{"gitId":"domoberzin"},"content":" id,"},{"lineNumber":184,"author":{"gitId":"domoberzin"},"content":" };"},{"lineNumber":185,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":186,"author":{"gitId":"domoberzin"},"content":" return this.httpRequestService.post(ResourceEndpoints.ACCOUNT_REQUEST_REJECT, paramMap, accountReqRejectRequest);"},{"lineNumber":187,"author":{"gitId":"domoberzin"},"content":" }"},{"lineNumber":188,"author":{"gitId":"domoberzin"},"content":""},{"lineNumber":189,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"domoberzin":83,"dishenggg":4,"-":102}},{"path":"src/web/services/log.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { Observable } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { HttpRequestService } from \u0027./http-request.service\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { ResourceEndpoints } from \u0027../types/api-const\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":6,"author":{"gitId":"-"},"content":" ActionClasses,"},{"lineNumber":7,"author":{"gitId":"-"},"content":" FeedbackSessionLogs,"},{"lineNumber":8,"author":{"gitId":"-"},"content":" FeedbackSessionLogType,"},{"lineNumber":9,"author":{"gitId":"-"},"content":" GeneralLogs,"},{"lineNumber":10,"author":{"gitId":"-"},"content":" QueryLogsParams,"},{"lineNumber":11,"author":{"gitId":"-"},"content":"} from \u0027../types/api-output\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":""},{"lineNumber":13,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":14,"author":{"gitId":"-"},"content":" * Handles logging related logic provision."},{"lineNumber":15,"author":{"gitId":"-"},"content":" */"},{"lineNumber":16,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":17,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027,"},{"lineNumber":18,"author":{"gitId":"-"},"content":"})"},{"lineNumber":19,"author":{"gitId":"-"},"content":"export class LogService {"},{"lineNumber":20,"author":{"gitId":"-"},"content":""},{"lineNumber":21,"author":{"gitId":"-"},"content":" constructor(private httpRequestService: HttpRequestService) { }"},{"lineNumber":22,"author":{"gitId":"-"},"content":""},{"lineNumber":23,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":24,"author":{"gitId":"-"},"content":" * Creates a log for feedback session by calling API."},{"lineNumber":25,"author":{"gitId":"-"},"content":" */"},{"lineNumber":26,"author":{"gitId":"-"},"content":" createFeedbackSessionLog(queryParams: {"},{"lineNumber":27,"author":{"gitId":"-"},"content":" courseId: string,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" feedbackSessionName: string,"},{"lineNumber":29,"author":{"gitId":"-"},"content":" studentEmail: string,"},{"lineNumber":30,"author":{"gitId":"-"},"content":" logType: FeedbackSessionLogType,"},{"lineNumber":31,"author":{"gitId":"dishenggg"},"content":" feedbackSessionId?: string,"},{"lineNumber":32,"author":{"gitId":"dishenggg"},"content":" studentId?: string,"},{"lineNumber":33,"author":{"gitId":"-"},"content":" }): Observable\u003cstring\u003e {"},{"lineNumber":34,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":35,"author":{"gitId":"-"},"content":" courseid: queryParams.courseId,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" fsname: queryParams.feedbackSessionName,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" studentemail: queryParams.studentEmail,"},{"lineNumber":38,"author":{"gitId":"-"},"content":" fsltype: queryParams.logType.toString(),"},{"lineNumber":39,"author":{"gitId":"-"},"content":" };"},{"lineNumber":40,"author":{"gitId":"-"},"content":""},{"lineNumber":41,"author":{"gitId":"dishenggg"},"content":" if (queryParams.feedbackSessionId) {"},{"lineNumber":42,"author":{"gitId":"dishenggg"},"content":" paramMap[\u0027fsid\u0027] \u003d queryParams.feedbackSessionId;"},{"lineNumber":43,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":44,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":45,"author":{"gitId":"dishenggg"},"content":" if (queryParams.studentId) {"},{"lineNumber":46,"author":{"gitId":"dishenggg"},"content":" paramMap[\u0027studentid\u0027] \u003d queryParams.studentId;"},{"lineNumber":47,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":48,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":49,"author":{"gitId":"-"},"content":" return this.httpRequestService.post(ResourceEndpoints.SESSION_LOGS, paramMap);"},{"lineNumber":50,"author":{"gitId":"-"},"content":" }"},{"lineNumber":51,"author":{"gitId":"-"},"content":""},{"lineNumber":52,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":53,"author":{"gitId":"-"},"content":" * Searches for feedback session logs."},{"lineNumber":54,"author":{"gitId":"-"},"content":" */"},{"lineNumber":55,"author":{"gitId":"-"},"content":" searchFeedbackSessionLog(queryParams: {"},{"lineNumber":56,"author":{"gitId":"-"},"content":" courseId: string,"},{"lineNumber":57,"author":{"gitId":"-"},"content":" searchFrom: string,"},{"lineNumber":58,"author":{"gitId":"-"},"content":" searchUntil: string,"},{"lineNumber":59,"author":{"gitId":"-"},"content":" studentEmail?: string,"},{"lineNumber":60,"author":{"gitId":"-"},"content":" sessionName?: string,"},{"lineNumber":61,"author":{"gitId":"-"},"content":" logType?: string,"},{"lineNumber":62,"author":{"gitId":"dishenggg"},"content":" studentId?: string,"},{"lineNumber":63,"author":{"gitId":"dishenggg"},"content":" sessionId?: string,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" }): Observable\u003cFeedbackSessionLogs\u003e {"},{"lineNumber":65,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":66,"author":{"gitId":"-"},"content":" courseid: queryParams.courseId,"},{"lineNumber":67,"author":{"gitId":"-"},"content":" fslstarttime: queryParams.searchFrom,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" fslendtime: queryParams.searchUntil,"},{"lineNumber":69,"author":{"gitId":"-"},"content":" };"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"-"},"content":" if (queryParams.studentEmail) {"},{"lineNumber":72,"author":{"gitId":"-"},"content":" paramMap[\u0027studentemail\u0027] \u003d queryParams.studentEmail;"},{"lineNumber":73,"author":{"gitId":"-"},"content":" }"},{"lineNumber":74,"author":{"gitId":"-"},"content":""},{"lineNumber":75,"author":{"gitId":"-"},"content":" if (queryParams.sessionName) {"},{"lineNumber":76,"author":{"gitId":"-"},"content":" paramMap[\u0027fsname\u0027] \u003d queryParams.sessionName;"},{"lineNumber":77,"author":{"gitId":"-"},"content":" }"},{"lineNumber":78,"author":{"gitId":"-"},"content":""},{"lineNumber":79,"author":{"gitId":"-"},"content":" if (queryParams.logType) {"},{"lineNumber":80,"author":{"gitId":"-"},"content":" paramMap[\u0027fsltype\u0027] \u003d queryParams.logType;"},{"lineNumber":81,"author":{"gitId":"-"},"content":" }"},{"lineNumber":82,"author":{"gitId":"-"},"content":""},{"lineNumber":83,"author":{"gitId":"dishenggg"},"content":" if (queryParams.studentId) {"},{"lineNumber":84,"author":{"gitId":"dishenggg"},"content":" paramMap[\u0027studentid\u0027] \u003d queryParams.studentId;"},{"lineNumber":85,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":86,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":87,"author":{"gitId":"dishenggg"},"content":" if (queryParams.sessionId) {"},{"lineNumber":88,"author":{"gitId":"dishenggg"},"content":" paramMap[\u0027fsid\u0027] \u003d queryParams.sessionId;"},{"lineNumber":89,"author":{"gitId":"dishenggg"},"content":" }"},{"lineNumber":90,"author":{"gitId":"dishenggg"},"content":""},{"lineNumber":91,"author":{"gitId":"-"},"content":" return this.httpRequestService.get(ResourceEndpoints.SESSION_LOGS, paramMap);"},{"lineNumber":92,"author":{"gitId":"-"},"content":" }"},{"lineNumber":93,"author":{"gitId":"-"},"content":""},{"lineNumber":94,"author":{"gitId":"-"},"content":" searchLogs(queryParams: Partial\u003cQueryLogsParams\u003e): Observable\u003cGeneralLogs\u003e {"},{"lineNumber":95,"author":{"gitId":"-"},"content":" const paramMap: Record\u003cstring, string\u003e \u003d {"},{"lineNumber":96,"author":{"gitId":"-"},"content":" starttime: `${queryParams.startTime || -1}`,"},{"lineNumber":97,"author":{"gitId":"-"},"content":" endtime: `${queryParams.endTime || -1}`,"},{"lineNumber":98,"author":{"gitId":"-"},"content":" };"},{"lineNumber":99,"author":{"gitId":"-"},"content":""},{"lineNumber":100,"author":{"gitId":"-"},"content":" if (queryParams.order) {"},{"lineNumber":101,"author":{"gitId":"-"},"content":" paramMap[\u0027order\u0027] \u003d queryParams.order;"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" if (queryParams.severity) {"},{"lineNumber":105,"author":{"gitId":"-"},"content":" paramMap[\u0027severity\u0027] \u003d queryParams.severity;"},{"lineNumber":106,"author":{"gitId":"-"},"content":" }"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" if (queryParams.minSeverity) {"},{"lineNumber":109,"author":{"gitId":"-"},"content":" paramMap[\u0027minseverity\u0027] \u003d queryParams.minSeverity;"},{"lineNumber":110,"author":{"gitId":"-"},"content":" }"},{"lineNumber":111,"author":{"gitId":"-"},"content":""},{"lineNumber":112,"author":{"gitId":"-"},"content":" if (queryParams.logEvent) {"},{"lineNumber":113,"author":{"gitId":"-"},"content":" paramMap[\u0027logevent\u0027] \u003d queryParams.logEvent;"},{"lineNumber":114,"author":{"gitId":"-"},"content":" }"},{"lineNumber":115,"author":{"gitId":"-"},"content":""},{"lineNumber":116,"author":{"gitId":"-"},"content":" if (queryParams.actionClass) {"},{"lineNumber":117,"author":{"gitId":"-"},"content":" paramMap[\u0027actionclass\u0027] \u003d queryParams.actionClass;"},{"lineNumber":118,"author":{"gitId":"-"},"content":" }"},{"lineNumber":119,"author":{"gitId":"-"},"content":""},{"lineNumber":120,"author":{"gitId":"-"},"content":" if (queryParams.traceId) {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" paramMap[\u0027traceid\u0027] \u003d queryParams.traceId;"},{"lineNumber":122,"author":{"gitId":"-"},"content":" }"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" if (queryParams.userInfoParams) {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" if (queryParams.userInfoParams.googleId) {"},{"lineNumber":126,"author":{"gitId":"-"},"content":" paramMap[\u0027googleid\u0027] \u003d queryParams.userInfoParams.googleId;"},{"lineNumber":127,"author":{"gitId":"-"},"content":" }"},{"lineNumber":128,"author":{"gitId":"-"},"content":""},{"lineNumber":129,"author":{"gitId":"-"},"content":" if (queryParams.userInfoParams.regkey) {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" paramMap[\u0027key\u0027] \u003d queryParams.userInfoParams.regkey;"},{"lineNumber":131,"author":{"gitId":"-"},"content":" }"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" if (queryParams.userInfoParams.email) {"},{"lineNumber":134,"author":{"gitId":"-"},"content":" paramMap[\u0027email\u0027] \u003d queryParams.userInfoParams.email;"},{"lineNumber":135,"author":{"gitId":"-"},"content":" }"},{"lineNumber":136,"author":{"gitId":"-"},"content":" }"},{"lineNumber":137,"author":{"gitId":"-"},"content":""},{"lineNumber":138,"author":{"gitId":"-"},"content":" if (queryParams.sourceLocation) {"},{"lineNumber":139,"author":{"gitId":"-"},"content":" if (queryParams.sourceLocation.file) {"},{"lineNumber":140,"author":{"gitId":"-"},"content":" paramMap[\u0027sourcelocationfile\u0027] \u003d queryParams.sourceLocation.file;"},{"lineNumber":141,"author":{"gitId":"-"},"content":" }"},{"lineNumber":142,"author":{"gitId":"-"},"content":""},{"lineNumber":143,"author":{"gitId":"-"},"content":" if (queryParams.sourceLocation.function) {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" paramMap[\u0027sourcelocationfunction\u0027] \u003d queryParams.sourceLocation.function;"},{"lineNumber":145,"author":{"gitId":"-"},"content":" }"},{"lineNumber":146,"author":{"gitId":"-"},"content":" }"},{"lineNumber":147,"author":{"gitId":"-"},"content":""},{"lineNumber":148,"author":{"gitId":"-"},"content":" if (queryParams.exceptionClass) {"},{"lineNumber":149,"author":{"gitId":"-"},"content":" paramMap[\u0027exceptionclass\u0027] \u003d queryParams.exceptionClass;"},{"lineNumber":150,"author":{"gitId":"-"},"content":" }"},{"lineNumber":151,"author":{"gitId":"-"},"content":""},{"lineNumber":152,"author":{"gitId":"-"},"content":" if (queryParams.latency) {"},{"lineNumber":153,"author":{"gitId":"-"},"content":" paramMap[\u0027latency\u0027] \u003d queryParams.latency;"},{"lineNumber":154,"author":{"gitId":"-"},"content":" }"},{"lineNumber":155,"author":{"gitId":"-"},"content":""},{"lineNumber":156,"author":{"gitId":"-"},"content":" if (queryParams.status) {"},{"lineNumber":157,"author":{"gitId":"-"},"content":" paramMap[\u0027status\u0027] \u003d queryParams.status;"},{"lineNumber":158,"author":{"gitId":"-"},"content":" }"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" if (queryParams.version) {"},{"lineNumber":161,"author":{"gitId":"-"},"content":" paramMap[\u0027version\u0027] \u003d queryParams.version;"},{"lineNumber":162,"author":{"gitId":"-"},"content":" }"},{"lineNumber":163,"author":{"gitId":"-"},"content":""},{"lineNumber":164,"author":{"gitId":"-"},"content":" if (queryParams.extraFilters) {"},{"lineNumber":165,"author":{"gitId":"-"},"content":" paramMap[\u0027extrafilters\u0027] \u003d queryParams.extraFilters;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" }"},{"lineNumber":167,"author":{"gitId":"-"},"content":""},{"lineNumber":168,"author":{"gitId":"-"},"content":" return this.httpRequestService.get(ResourceEndpoints.LOGS, paramMap);"},{"lineNumber":169,"author":{"gitId":"-"},"content":" }"},{"lineNumber":170,"author":{"gitId":"-"},"content":""},{"lineNumber":171,"author":{"gitId":"-"},"content":" getActionClassList(): Observable\u003cActionClasses\u003e {"},{"lineNumber":172,"author":{"gitId":"-"},"content":" return this.httpRequestService.get(ResourceEndpoints.ACTION_CLASS);"},{"lineNumber":173,"author":{"gitId":"-"},"content":" }"},{"lineNumber":174,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"dishenggg":20,"-":154}},{"path":"src/web/services/search.service.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { HttpClientTestingModule } from \u0027@angular/common/http/testing\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { TestBed } from \u0027@angular/core/testing\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { RouterTestingModule } from \u0027@angular/router/testing\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { HttpRequestService } from \u0027./http-request.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":6,"author":{"gitId":"-"},"content":" AccountRequestSearchResult,"},{"lineNumber":7,"author":{"gitId":"-"},"content":" InstructorAccountSearchResult,"},{"lineNumber":8,"author":{"gitId":"-"},"content":" SearchService,"},{"lineNumber":9,"author":{"gitId":"-"},"content":" StudentAccountSearchResult,"},{"lineNumber":10,"author":{"gitId":"-"},"content":"} from \u0027./search.service\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import { TimezoneService } from \u0027./timezone.service\u0027;"},{"lineNumber":12,"author":{"gitId":"-"},"content":"import createSpyFromClass from \u0027../test-helpers/create-spy-from-class\u0027;"},{"lineNumber":13,"author":{"gitId":"-"},"content":"import { ResourceEndpoints } from \u0027../types/api-const\u0027;"},{"lineNumber":14,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":15,"author":{"gitId":"-"},"content":" AccountRequest,"},{"lineNumber":16,"author":{"gitId":"-"},"content":" AccountRequestStatus,"},{"lineNumber":17,"author":{"gitId":"-"},"content":" Course,"},{"lineNumber":18,"author":{"gitId":"-"},"content":" FeedbackSession,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" FeedbackSessionPublishStatus,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" FeedbackSessionSubmissionStatus,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" Instructor,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" InstructorPermissionRole,"},{"lineNumber":23,"author":{"gitId":"-"},"content":" InstructorPrivilege,"},{"lineNumber":24,"author":{"gitId":"-"},"content":" JoinState,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" ResponseVisibleSetting,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" SessionVisibleSetting,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" Student,"},{"lineNumber":28,"author":{"gitId":"-"},"content":"} from \u0027../types/api-output\u0027;"},{"lineNumber":29,"author":{"gitId":"-"},"content":""},{"lineNumber":30,"author":{"gitId":"-"},"content":"describe(\u0027SearchService\u0027, () \u003d\u003e {"},{"lineNumber":31,"author":{"gitId":"-"},"content":" let spyHttpRequestService: any;"},{"lineNumber":32,"author":{"gitId":"-"},"content":" let service: SearchService;"},{"lineNumber":33,"author":{"gitId":"-"},"content":" let timezoneService: TimezoneService;"},{"lineNumber":34,"author":{"gitId":"-"},"content":""},{"lineNumber":35,"author":{"gitId":"-"},"content":" const mockStudent: Student \u003d {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" email: \u0027alice.b.tmms@gmail.tmt\u0027,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" courseId: \u0027dog.gma-demo\u0027,"},{"lineNumber":38,"author":{"gitId":"-"},"content":" name: \u0027Alice Betsy\u0027,"},{"lineNumber":39,"author":{"gitId":"-"},"content":" googleId: \u0027alice.b.tmms.sampleData\u0027,"},{"lineNumber":40,"author":{"gitId":"-"},"content":" comments: \"This student\u0027s name is Alice Betsy\","},{"lineNumber":41,"author":{"gitId":"-"},"content":" key: \u0027keyheehee\u0027,"},{"lineNumber":42,"author":{"gitId":"-"},"content":" institute: \u0027NUS\u0027,"},{"lineNumber":43,"author":{"gitId":"-"},"content":" joinState: JoinState.JOINED,"},{"lineNumber":44,"author":{"gitId":"-"},"content":" teamName: \u0027Team 1\u0027,"},{"lineNumber":45,"author":{"gitId":"-"},"content":" sectionName: \u0027Tutorial Group 1\u0027,"},{"lineNumber":46,"author":{"gitId":"-"},"content":" };"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" const mockInstructorA: Instructor \u003d {"},{"lineNumber":49,"author":{"gitId":"-"},"content":" googleId: \u0027test@example.com\u0027,"},{"lineNumber":50,"author":{"gitId":"-"},"content":" courseId: \u0027dog.gma-demo\u0027,"},{"lineNumber":51,"author":{"gitId":"-"},"content":" email: \u0027dog@gmail.com\u0027,"},{"lineNumber":52,"author":{"gitId":"-"},"content":" isDisplayedToStudents: true,"},{"lineNumber":53,"author":{"gitId":"-"},"content":" displayedToStudentsAs: \u0027Instructor\u0027,"},{"lineNumber":54,"author":{"gitId":"-"},"content":" name: \u0027Hi\u0027,"},{"lineNumber":55,"author":{"gitId":"-"},"content":" key: \u0027impicklerick\u0027,"},{"lineNumber":56,"author":{"gitId":"-"},"content":" role: InstructorPermissionRole.INSTRUCTOR_PERMISSION_ROLE_COOWNER,"},{"lineNumber":57,"author":{"gitId":"-"},"content":" joinState: JoinState.JOINED,"},{"lineNumber":58,"author":{"gitId":"-"},"content":" };"},{"lineNumber":59,"author":{"gitId":"-"},"content":""},{"lineNumber":60,"author":{"gitId":"-"},"content":" const mockInstructorB: Instructor \u003d {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" googleId: \u0027insB\u0027,"},{"lineNumber":62,"author":{"gitId":"-"},"content":" courseId: \u0027dog.gma-demo\u0027,"},{"lineNumber":63,"author":{"gitId":"-"},"content":" email: \u0027cat@gmail.com\u0027,"},{"lineNumber":64,"author":{"gitId":"-"},"content":" isDisplayedToStudents: true,"},{"lineNumber":65,"author":{"gitId":"-"},"content":" displayedToStudentsAs: \u0027Instructor\u0027,"},{"lineNumber":66,"author":{"gitId":"-"},"content":" name: \u0027Cat\u0027,"},{"lineNumber":67,"author":{"gitId":"-"},"content":" key: \u0027qwertyuiop\u0027,"},{"lineNumber":68,"author":{"gitId":"-"},"content":" role: InstructorPermissionRole.INSTRUCTOR_PERMISSION_ROLE_CUSTOM,"},{"lineNumber":69,"author":{"gitId":"-"},"content":" joinState: JoinState.JOINED,"},{"lineNumber":70,"author":{"gitId":"-"},"content":" };"},{"lineNumber":71,"author":{"gitId":"-"},"content":""},{"lineNumber":72,"author":{"gitId":"-"},"content":" const mockInstructorC: Instructor \u003d {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" googleId: \u0027insC\u0027,"},{"lineNumber":74,"author":{"gitId":"-"},"content":" courseId: \u0027dog.gma-demo\u0027,"},{"lineNumber":75,"author":{"gitId":"-"},"content":" email: \u0027animal@gmail.com\u0027,"},{"lineNumber":76,"author":{"gitId":"-"},"content":" isDisplayedToStudents: true,"},{"lineNumber":77,"author":{"gitId":"-"},"content":" displayedToStudentsAs: \u0027Instructor\u0027,"},{"lineNumber":78,"author":{"gitId":"-"},"content":" name: \u0027QWQ\u0027,"},{"lineNumber":79,"author":{"gitId":"-"},"content":" key: \u0027vjvkjsnffwicvvcsc\u0027,"},{"lineNumber":80,"author":{"gitId":"-"},"content":" role: InstructorPermissionRole.INSTRUCTOR_PERMISSION_ROLE_CUSTOM,"},{"lineNumber":81,"author":{"gitId":"-"},"content":" joinState: JoinState.JOINED,"},{"lineNumber":82,"author":{"gitId":"-"},"content":" };"},{"lineNumber":83,"author":{"gitId":"-"},"content":""},{"lineNumber":84,"author":{"gitId":"-"},"content":" const mockSessions: FeedbackSession[] \u003d ["},{"lineNumber":85,"author":{"gitId":"-"},"content":" {"},{"lineNumber":86,"author":{"gitId":"-"},"content":" courseId: \u0027dog.gma-demo\u0027,"},{"lineNumber":87,"author":{"gitId":"-"},"content":" timeZone: \u0027Asia/Singapore\u0027,"},{"lineNumber":88,"author":{"gitId":"-"},"content":" feedbackSessionName: \u0027First team feedback session\u0027,"},{"lineNumber":89,"author":{"gitId":"-"},"content":" instructions: \u0027Please give your feedback based on the following questions.\u0027,"},{"lineNumber":90,"author":{"gitId":"-"},"content":" submissionStartTimestamp: 1333295940000,"},{"lineNumber":91,"author":{"gitId":"-"},"content":" submissionEndTimestamp: 1333382340000,"},{"lineNumber":92,"author":{"gitId":"-"},"content":" submissionStatus: FeedbackSessionSubmissionStatus.CLOSED,"},{"lineNumber":93,"author":{"gitId":"-"},"content":" publishStatus: FeedbackSessionPublishStatus.PUBLISHED,"},{"lineNumber":94,"author":{"gitId":"-"},"content":" createdAtTimestamp: 1333324740000,"},{"lineNumber":95,"author":{"gitId":"-"},"content":" gracePeriod: 1,"},{"lineNumber":96,"author":{"gitId":"-"},"content":" sessionVisibleSetting: SessionVisibleSetting.CUSTOM,"},{"lineNumber":97,"author":{"gitId":"-"},"content":" responseVisibleSetting: ResponseVisibleSetting.CUSTOM,"},{"lineNumber":98,"author":{"gitId":"-"},"content":" isClosingEmailEnabled: false,"},{"lineNumber":99,"author":{"gitId":"-"},"content":" isPublishedEmailEnabled: false,"},{"lineNumber":100,"author":{"gitId":"-"},"content":" studentDeadlines: {},"},{"lineNumber":101,"author":{"gitId":"-"},"content":" instructorDeadlines: {},"},{"lineNumber":102,"author":{"gitId":"-"},"content":" },"},{"lineNumber":103,"author":{"gitId":"-"},"content":" {"},{"lineNumber":104,"author":{"gitId":"-"},"content":" courseId: \u0027dog.gma-demo\u0027,"},{"lineNumber":105,"author":{"gitId":"-"},"content":" timeZone: \u0027Asia/Singapore\u0027,"},{"lineNumber":106,"author":{"gitId":"-"},"content":" feedbackSessionName: \u0027Second team feedback session\u0027,"},{"lineNumber":107,"author":{"gitId":"-"},"content":" instructions: \u0027Please give your feedback based on the following questions.\u0027,"},{"lineNumber":108,"author":{"gitId":"-"},"content":" submissionStartTimestamp: 1333295940000,"},{"lineNumber":109,"author":{"gitId":"-"},"content":" submissionEndTimestamp: 2122300740000,"},{"lineNumber":110,"author":{"gitId":"-"},"content":" submissionStatus: FeedbackSessionSubmissionStatus.OPEN,"},{"lineNumber":111,"author":{"gitId":"-"},"content":" publishStatus: FeedbackSessionPublishStatus.NOT_PUBLISHED,"},{"lineNumber":112,"author":{"gitId":"-"},"content":" createdAtTimestamp: 1333324740000,"},{"lineNumber":113,"author":{"gitId":"-"},"content":" gracePeriod: 1,"},{"lineNumber":114,"author":{"gitId":"-"},"content":" sessionVisibleSetting: SessionVisibleSetting.CUSTOM,"},{"lineNumber":115,"author":{"gitId":"-"},"content":" responseVisibleSetting: ResponseVisibleSetting.CUSTOM,"},{"lineNumber":116,"author":{"gitId":"-"},"content":" isClosingEmailEnabled: false,"},{"lineNumber":117,"author":{"gitId":"-"},"content":" isPublishedEmailEnabled: false,"},{"lineNumber":118,"author":{"gitId":"-"},"content":" studentDeadlines: {},"},{"lineNumber":119,"author":{"gitId":"-"},"content":" instructorDeadlines: {},"},{"lineNumber":120,"author":{"gitId":"-"},"content":" },"},{"lineNumber":121,"author":{"gitId":"-"},"content":" ];"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" const mockPrivilegeA: InstructorPrivilege \u003d {"},{"lineNumber":124,"author":{"gitId":"-"},"content":" privileges: {"},{"lineNumber":125,"author":{"gitId":"-"},"content":" courseLevel: {"},{"lineNumber":126,"author":{"gitId":"-"},"content":" canModifyCourse: true,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" canModifySession: true,"},{"lineNumber":128,"author":{"gitId":"-"},"content":" canModifyStudent: true,"},{"lineNumber":129,"author":{"gitId":"-"},"content":" canModifyInstructor: true,"},{"lineNumber":130,"author":{"gitId":"-"},"content":" canViewStudentInSections: true,"},{"lineNumber":131,"author":{"gitId":"-"},"content":" canModifySessionCommentsInSections: true,"},{"lineNumber":132,"author":{"gitId":"-"},"content":" canViewSessionInSections: true,"},{"lineNumber":133,"author":{"gitId":"-"},"content":" canSubmitSessionInSections: true,"},{"lineNumber":134,"author":{"gitId":"-"},"content":" },"},{"lineNumber":135,"author":{"gitId":"-"},"content":" sectionLevel: {},"},{"lineNumber":136,"author":{"gitId":"-"},"content":" sessionLevel: {},"},{"lineNumber":137,"author":{"gitId":"-"},"content":" },"},{"lineNumber":138,"author":{"gitId":"-"},"content":" requestId: \u0027checkyourprivilege\u0027,"},{"lineNumber":139,"author":{"gitId":"-"},"content":" };"},{"lineNumber":140,"author":{"gitId":"-"},"content":""},{"lineNumber":141,"author":{"gitId":"-"},"content":" const mockPrivilegeB: InstructorPrivilege \u003d {"},{"lineNumber":142,"author":{"gitId":"-"},"content":" privileges: {"},{"lineNumber":143,"author":{"gitId":"-"},"content":" courseLevel: {"},{"lineNumber":144,"author":{"gitId":"-"},"content":" canModifyCourse: true,"},{"lineNumber":145,"author":{"gitId":"-"},"content":" canModifySession: true,"},{"lineNumber":146,"author":{"gitId":"-"},"content":" canModifyStudent: true,"},{"lineNumber":147,"author":{"gitId":"-"},"content":" canModifyInstructor: false,"},{"lineNumber":148,"author":{"gitId":"-"},"content":" canViewStudentInSections: true,"},{"lineNumber":149,"author":{"gitId":"-"},"content":" canModifySessionCommentsInSections: true,"},{"lineNumber":150,"author":{"gitId":"-"},"content":" canViewSessionInSections: true,"},{"lineNumber":151,"author":{"gitId":"-"},"content":" canSubmitSessionInSections: true,"},{"lineNumber":152,"author":{"gitId":"-"},"content":" },"},{"lineNumber":153,"author":{"gitId":"-"},"content":" sectionLevel: {},"},{"lineNumber":154,"author":{"gitId":"-"},"content":" sessionLevel: {},"},{"lineNumber":155,"author":{"gitId":"-"},"content":" },"},{"lineNumber":156,"author":{"gitId":"-"},"content":" requestId: \u0027123gyijuyol56w8refw123ce8f5\u0027,"},{"lineNumber":157,"author":{"gitId":"-"},"content":" };"},{"lineNumber":158,"author":{"gitId":"-"},"content":""},{"lineNumber":159,"author":{"gitId":"-"},"content":" const mockPrivilegeC: InstructorPrivilege \u003d {"},{"lineNumber":160,"author":{"gitId":"-"},"content":" privileges: {"},{"lineNumber":161,"author":{"gitId":"-"},"content":" courseLevel: {"},{"lineNumber":162,"author":{"gitId":"-"},"content":" canModifyCourse: false,"},{"lineNumber":163,"author":{"gitId":"-"},"content":" canModifySession: false,"},{"lineNumber":164,"author":{"gitId":"-"},"content":" canModifyStudent: false,"},{"lineNumber":165,"author":{"gitId":"-"},"content":" canModifyInstructor: true,"},{"lineNumber":166,"author":{"gitId":"-"},"content":" canViewStudentInSections: false,"},{"lineNumber":167,"author":{"gitId":"-"},"content":" canModifySessionCommentsInSections: false,"},{"lineNumber":168,"author":{"gitId":"-"},"content":" canViewSessionInSections: false,"},{"lineNumber":169,"author":{"gitId":"-"},"content":" canSubmitSessionInSections: false,"},{"lineNumber":170,"author":{"gitId":"-"},"content":" },"},{"lineNumber":171,"author":{"gitId":"-"},"content":" sectionLevel: {},"},{"lineNumber":172,"author":{"gitId":"-"},"content":" sessionLevel: {},"},{"lineNumber":173,"author":{"gitId":"-"},"content":" },"},{"lineNumber":174,"author":{"gitId":"-"},"content":" requestId: \u002798pa78342kjnk22s1213rsdff4\u0027,"},{"lineNumber":175,"author":{"gitId":"-"},"content":" };"},{"lineNumber":176,"author":{"gitId":"-"},"content":""},{"lineNumber":177,"author":{"gitId":"-"},"content":" const mockCourse: Course \u003d {"},{"lineNumber":178,"author":{"gitId":"-"},"content":" courseId: \u0027dog.gma-demo\u0027,"},{"lineNumber":179,"author":{"gitId":"-"},"content":" courseName: \u0027Sample Course 101\u0027,"},{"lineNumber":180,"author":{"gitId":"-"},"content":" institute: \u0027Test Institute\u0027,"},{"lineNumber":181,"author":{"gitId":"-"},"content":" timeZone: \u0027UTC\u0027,"},{"lineNumber":182,"author":{"gitId":"-"},"content":" creationTimestamp: 1585487897502,"},{"lineNumber":183,"author":{"gitId":"-"},"content":" deletionTimestamp: 0,"},{"lineNumber":184,"author":{"gitId":"-"},"content":" requestId: \u00275e80aa3c00007918934385f5\u0027,"},{"lineNumber":185,"author":{"gitId":"-"},"content":" };"},{"lineNumber":186,"author":{"gitId":"-"},"content":""},{"lineNumber":187,"author":{"gitId":"-"},"content":" const mockAccountRequest: AccountRequest \u003d {"},{"lineNumber":188,"author":{"gitId":"-"},"content":" id: \u0027132efa02-b208-4195-a262-a8eae25ceb95\u0027,"},{"lineNumber":189,"author":{"gitId":"-"},"content":" registrationKey: \u0027regkey\u0027,"},{"lineNumber":190,"author":{"gitId":"-"},"content":" createdAt: 1585487897502,"},{"lineNumber":191,"author":{"gitId":"-"},"content":" name: \u0027Test Instructor\u0027,"},{"lineNumber":192,"author":{"gitId":"-"},"content":" institute: \u0027Test Institute\u0027,"},{"lineNumber":193,"author":{"gitId":"-"},"content":" email: \u0027test@example.com\u0027,"},{"lineNumber":194,"author":{"gitId":"domoberzin"},"content":" comments: \u0027This is a test account request\u0027,"},{"lineNumber":195,"author":{"gitId":"-"},"content":" status: AccountRequestStatus.APPROVED,"},{"lineNumber":196,"author":{"gitId":"-"},"content":" };"},{"lineNumber":197,"author":{"gitId":"-"},"content":""},{"lineNumber":198,"author":{"gitId":"-"},"content":" beforeEach(() \u003d\u003e {"},{"lineNumber":199,"author":{"gitId":"-"},"content":" spyHttpRequestService \u003d createSpyFromClass(HttpRequestService);"},{"lineNumber":200,"author":{"gitId":"-"},"content":" TestBed.configureTestingModule({"},{"lineNumber":201,"author":{"gitId":"-"},"content":" imports: [HttpClientTestingModule, RouterTestingModule],"},{"lineNumber":202,"author":{"gitId":"-"},"content":" providers: ["},{"lineNumber":203,"author":{"gitId":"-"},"content":" { provide: HttpRequestService, useValue: spyHttpRequestService },"},{"lineNumber":204,"author":{"gitId":"-"},"content":" ],"},{"lineNumber":205,"author":{"gitId":"-"},"content":" });"},{"lineNumber":206,"author":{"gitId":"-"},"content":" service \u003d TestBed.inject(SearchService);"},{"lineNumber":207,"author":{"gitId":"-"},"content":" timezoneService \u003d TestBed.inject(TimezoneService);"},{"lineNumber":208,"author":{"gitId":"-"},"content":" });"},{"lineNumber":209,"author":{"gitId":"-"},"content":""},{"lineNumber":210,"author":{"gitId":"-"},"content":" it(\u0027should be created\u0027, () \u003d\u003e {"},{"lineNumber":211,"author":{"gitId":"-"},"content":" expect(service).toBeTruthy();"},{"lineNumber":212,"author":{"gitId":"-"},"content":" });"},{"lineNumber":213,"author":{"gitId":"-"},"content":""},{"lineNumber":214,"author":{"gitId":"-"},"content":" it(\u0027should execute GET when searching for students\u0027, () \u003d\u003e {"},{"lineNumber":215,"author":{"gitId":"-"},"content":" service.searchStudents(\u0027Alice\u0027, \u0027instructor\u0027);"},{"lineNumber":216,"author":{"gitId":"-"},"content":" const paramMap: { [key: string]: string } \u003d {"},{"lineNumber":217,"author":{"gitId":"-"},"content":" searchkey: \u0027Alice\u0027,"},{"lineNumber":218,"author":{"gitId":"-"},"content":" entitytype: \u0027instructor\u0027,"},{"lineNumber":219,"author":{"gitId":"-"},"content":" };"},{"lineNumber":220,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.get).toHaveBeenCalledWith("},{"lineNumber":221,"author":{"gitId":"-"},"content":" ResourceEndpoints.SEARCH_STUDENTS,"},{"lineNumber":222,"author":{"gitId":"-"},"content":" paramMap,"},{"lineNumber":223,"author":{"gitId":"-"},"content":" );"},{"lineNumber":224,"author":{"gitId":"-"},"content":" });"},{"lineNumber":225,"author":{"gitId":"-"},"content":""},{"lineNumber":226,"author":{"gitId":"-"},"content":" it(\u0027should execute GET when searching for instructors\u0027, () \u003d\u003e {"},{"lineNumber":227,"author":{"gitId":"-"},"content":" service.searchInstructors(\u0027YoyoImCoronavirus\u0027);"},{"lineNumber":228,"author":{"gitId":"-"},"content":" const paramMap: { [key: string]: string } \u003d {"},{"lineNumber":229,"author":{"gitId":"-"},"content":" searchkey: \u0027YoyoImCoronavirus\u0027,"},{"lineNumber":230,"author":{"gitId":"-"},"content":" };"},{"lineNumber":231,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.get).toHaveBeenCalledWith("},{"lineNumber":232,"author":{"gitId":"-"},"content":" ResourceEndpoints.SEARCH_INSTRUCTORS,"},{"lineNumber":233,"author":{"gitId":"-"},"content":" paramMap,"},{"lineNumber":234,"author":{"gitId":"-"},"content":" );"},{"lineNumber":235,"author":{"gitId":"-"},"content":" });"},{"lineNumber":236,"author":{"gitId":"-"},"content":""},{"lineNumber":237,"author":{"gitId":"-"},"content":" it(\u0027should execute GET when searching for account requests\u0027, () \u003d\u003e {"},{"lineNumber":238,"author":{"gitId":"-"},"content":" service.searchAccountRequests(\u0027Account Request\u0027);"},{"lineNumber":239,"author":{"gitId":"-"},"content":" const paramMap: { [key: string]: string } \u003d {"},{"lineNumber":240,"author":{"gitId":"-"},"content":" searchkey: \u0027Account Request\u0027,"},{"lineNumber":241,"author":{"gitId":"-"},"content":" };"},{"lineNumber":242,"author":{"gitId":"-"},"content":" expect(spyHttpRequestService.get).toHaveBeenCalledWith("},{"lineNumber":243,"author":{"gitId":"-"},"content":" ResourceEndpoints.SEARCH_ACCOUNT_REQUESTS,"},{"lineNumber":244,"author":{"gitId":"-"},"content":" paramMap,"},{"lineNumber":245,"author":{"gitId":"-"},"content":" );"},{"lineNumber":246,"author":{"gitId":"-"},"content":" });"},{"lineNumber":247,"author":{"gitId":"-"},"content":""},{"lineNumber":248,"author":{"gitId":"-"},"content":" it(\u0027should join students accurately when calling as admin\u0027, () \u003d\u003e {"},{"lineNumber":249,"author":{"gitId":"-"},"content":" const result: StudentAccountSearchResult \u003d service.joinAdminStudent("},{"lineNumber":250,"author":{"gitId":"-"},"content":" mockStudent,"},{"lineNumber":251,"author":{"gitId":"-"},"content":" { instructors: [mockInstructorA] },"},{"lineNumber":252,"author":{"gitId":"-"},"content":" mockCourse,"},{"lineNumber":253,"author":{"gitId":"-"},"content":" { feedbackSessions: mockSessions },"},{"lineNumber":254,"author":{"gitId":"-"},"content":" [mockPrivilegeA],"},{"lineNumber":255,"author":{"gitId":"-"},"content":" );"},{"lineNumber":256,"author":{"gitId":"-"},"content":" expect(result.comments).toBe(\"This student\u0027s name is Alice Betsy\");"},{"lineNumber":257,"author":{"gitId":"-"},"content":" expect(result.courseId).toBe(\u0027dog.gma-demo\u0027);"},{"lineNumber":258,"author":{"gitId":"-"},"content":" expect(result.courseJoinLink).toBe(`${window.location.origin}/web/join?key\u003dkeyheehee\u0026entitytype\u003dstudent`);"},{"lineNumber":259,"author":{"gitId":"-"},"content":" expect(result.courseName).toBe(\u0027Sample Course 101\u0027);"},{"lineNumber":260,"author":{"gitId":"-"},"content":" expect(result.email).toBe(\u0027alice.b.tmms@gmail.tmt\u0027);"},{"lineNumber":261,"author":{"gitId":"-"},"content":" expect(result.manageAccountLink).toBe(\u0027/web/admin/accounts?instructorid\u003dalice.b.tmms.sampleData\u0027);"},{"lineNumber":262,"author":{"gitId":"-"},"content":" });"},{"lineNumber":263,"author":{"gitId":"-"},"content":""},{"lineNumber":264,"author":{"gitId":"-"},"content":" it(\u0027should join students with correct profile page link when course has co-owner\u0027, () \u003d\u003e {"},{"lineNumber":265,"author":{"gitId":"-"},"content":" const result: StudentAccountSearchResult \u003d service.joinAdminStudent("},{"lineNumber":266,"author":{"gitId":"-"},"content":" mockStudent,"},{"lineNumber":267,"author":{"gitId":"-"},"content":" { instructors: [mockInstructorC, mockInstructorB, mockInstructorA] },"},{"lineNumber":268,"author":{"gitId":"-"},"content":" mockCourse,"},{"lineNumber":269,"author":{"gitId":"-"},"content":" { feedbackSessions: mockSessions },"},{"lineNumber":270,"author":{"gitId":"-"},"content":" [mockPrivilegeC, mockPrivilegeB, mockPrivilegeA],"},{"lineNumber":271,"author":{"gitId":"-"},"content":" );"},{"lineNumber":272,"author":{"gitId":"-"},"content":" expect(result.profilePageLink).toBe(\u0027/web/instructor/courses/student/details?\u0027"},{"lineNumber":273,"author":{"gitId":"-"},"content":" + \u0027courseid\u003ddog.gma-demo\u0026studentemail\u003dalice.b.tmms%40gmail.tmt\u0026user\u003dtest%40example.com\u0027);"},{"lineNumber":274,"author":{"gitId":"-"},"content":" });"},{"lineNumber":275,"author":{"gitId":"-"},"content":""},{"lineNumber":276,"author":{"gitId":"-"},"content":" it(\u0027should join students with correct profile page link when course has no co-owner\u0027, () \u003d\u003e {"},{"lineNumber":277,"author":{"gitId":"-"},"content":" const result: StudentAccountSearchResult \u003d service.joinAdminStudent("},{"lineNumber":278,"author":{"gitId":"-"},"content":" mockStudent,"},{"lineNumber":279,"author":{"gitId":"-"},"content":" { instructors: [mockInstructorB, mockInstructorC] },"},{"lineNumber":280,"author":{"gitId":"-"},"content":" mockCourse,"},{"lineNumber":281,"author":{"gitId":"-"},"content":" { feedbackSessions: mockSessions },"},{"lineNumber":282,"author":{"gitId":"-"},"content":" [mockPrivilegeB, mockPrivilegeC],"},{"lineNumber":283,"author":{"gitId":"-"},"content":" );"},{"lineNumber":284,"author":{"gitId":"-"},"content":" expect(result.profilePageLink).toBe(\u0027/web/instructor/courses/student/details?\u0027"},{"lineNumber":285,"author":{"gitId":"-"},"content":" + \u0027courseid\u003ddog.gma-demo\u0026studentemail\u003dalice.b.tmms%40gmail.tmt\u0026user\u003dinsC\u0027);"},{"lineNumber":286,"author":{"gitId":"-"},"content":" });"},{"lineNumber":287,"author":{"gitId":"-"},"content":""},{"lineNumber":288,"author":{"gitId":"-"},"content":" it(\u0027should join instructors accurately when calling as admin\u0027, () \u003d\u003e {"},{"lineNumber":289,"author":{"gitId":"-"},"content":" const result: InstructorAccountSearchResult \u003d service"},{"lineNumber":290,"author":{"gitId":"-"},"content":" .joinAdminInstructor(mockInstructorA, mockCourse, { feedbackSessions: mockSessions });"},{"lineNumber":291,"author":{"gitId":"-"},"content":" expect(result.courseId).toBe(\u0027dog.gma-demo\u0027);"},{"lineNumber":292,"author":{"gitId":"-"},"content":" expect(result.courseJoinLink).toBe(`${window.location.origin}/web/join?key\u003dimpicklerick\u0026entitytype\u003dinstructor`);"},{"lineNumber":293,"author":{"gitId":"-"},"content":" expect(result.courseName).toBe(\u0027Sample Course 101\u0027);"},{"lineNumber":294,"author":{"gitId":"-"},"content":" expect(result.email).toBe(\u0027dog@gmail.com\u0027);"},{"lineNumber":295,"author":{"gitId":"-"},"content":" expect(result.manageAccountLink).toBe(\u0027/web/admin/accounts?instructorid\u003dtest%40example.com\u0027);"},{"lineNumber":296,"author":{"gitId":"-"},"content":" expect(result.homePageLink).toBe(\u0027/web/instructor/home?user\u003dtest%40example.com\u0027);"},{"lineNumber":297,"author":{"gitId":"-"},"content":" });"},{"lineNumber":298,"author":{"gitId":"-"},"content":""},{"lineNumber":299,"author":{"gitId":"-"},"content":" it(\u0027should join account requests accurately when timezone can be guessed and instructor is registered\u0027, () \u003d\u003e {"},{"lineNumber":300,"author":{"gitId":"-"},"content":" jest.spyOn(timezoneService, \u0027guessTimezone\u0027).mockReturnValue(\u0027Asia/Singapore\u0027);"},{"lineNumber":301,"author":{"gitId":"-"},"content":" const accountRequest: AccountRequest \u003d {"},{"lineNumber":302,"author":{"gitId":"-"},"content":" ...mockAccountRequest,"},{"lineNumber":303,"author":{"gitId":"-"},"content":" registeredAt: 1685487897502,"},{"lineNumber":304,"author":{"gitId":"-"},"content":" status: AccountRequestStatus.REGISTERED,"},{"lineNumber":305,"author":{"gitId":"-"},"content":" };"},{"lineNumber":306,"author":{"gitId":"-"},"content":" const result: AccountRequestSearchResult \u003d service.joinAdminAccountRequest(accountRequest);"},{"lineNumber":307,"author":{"gitId":"-"},"content":""},{"lineNumber":308,"author":{"gitId":"-"},"content":" expect(result.id).toBe(\u0027132efa02-b208-4195-a262-a8eae25ceb95\u0027);"},{"lineNumber":309,"author":{"gitId":"-"},"content":" expect(result.email).toBe(\u0027test@example.com\u0027);"},{"lineNumber":310,"author":{"gitId":"-"},"content":" expect(result.institute).toBe(\u0027Test Institute\u0027);"},{"lineNumber":311,"author":{"gitId":"-"},"content":" expect(result.name).toBe(\u0027Test Instructor\u0027);"},{"lineNumber":312,"author":{"gitId":"-"},"content":" expect(result.createdAtText).toBe(\u0027Sun, 29 Mar 2020, 09:18 PM +08:00\u0027);"},{"lineNumber":313,"author":{"gitId":"-"},"content":" expect(result.registeredAtText).toBe(\u0027Wed, 31 May 2023, 07:04 AM +08:00\u0027);"},{"lineNumber":314,"author":{"gitId":"-"},"content":" expect(result.registrationLink).toBe(`${window.location.origin}/web/join?iscreatingaccount\u003dtrue\u0026key\u003dregkey`);"},{"lineNumber":315,"author":{"gitId":"-"},"content":" });"},{"lineNumber":316,"author":{"gitId":"-"},"content":""},{"lineNumber":317,"author":{"gitId":"-"},"content":" it(\u0027should join account requests accurately when timezone cannot be guessed and instructor is not registered\u0027, () \u003d\u003e {"},{"lineNumber":318,"author":{"gitId":"-"},"content":" jest.spyOn(timezoneService, \u0027guessTimezone\u0027).mockReturnValue(\u0027\u0027);"},{"lineNumber":319,"author":{"gitId":"-"},"content":" const result: AccountRequestSearchResult \u003d service.joinAdminAccountRequest(mockAccountRequest);"},{"lineNumber":320,"author":{"gitId":"-"},"content":""},{"lineNumber":321,"author":{"gitId":"-"},"content":" expect(result.email).toBe(\u0027test@example.com\u0027);"},{"lineNumber":322,"author":{"gitId":"-"},"content":" expect(result.institute).toBe(\u0027Test Institute\u0027);"},{"lineNumber":323,"author":{"gitId":"-"},"content":" expect(result.name).toBe(\u0027Test Instructor\u0027);"},{"lineNumber":324,"author":{"gitId":"-"},"content":" expect(result.createdAtText).toBe(\u0027Sun, 29 Mar 2020, 01:18 PM +00:00\u0027);"},{"lineNumber":325,"author":{"gitId":"-"},"content":" expect(result.registeredAtText).toBe(null);"},{"lineNumber":326,"author":{"gitId":"-"},"content":" expect(result.registrationLink).toBe(`${window.location.origin}/web/join?iscreatingaccount\u003dtrue\u0026key\u003dregkey`);"},{"lineNumber":327,"author":{"gitId":"-"},"content":" });"},{"lineNumber":328,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"domoberzin":1,"-":327}},{"path":"src/web/services/search.service.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"-"},"content":"import { Injectable } from \u0027@angular/core\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { forkJoin, Observable, of } from \u0027rxjs\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import { map, mergeMap } from \u0027rxjs/operators\u0027;"},{"lineNumber":4,"author":{"gitId":"-"},"content":"import { CourseService } from \u0027./course.service\u0027;"},{"lineNumber":5,"author":{"gitId":"-"},"content":"import { FeedbackSessionsService } from \u0027./feedback-sessions.service\u0027;"},{"lineNumber":6,"author":{"gitId":"-"},"content":"import { HttpRequestService } from \u0027./http-request.service\u0027;"},{"lineNumber":7,"author":{"gitId":"-"},"content":"import { InstructorService } from \u0027./instructor.service\u0027;"},{"lineNumber":8,"author":{"gitId":"-"},"content":"import { LinkService } from \u0027./link.service\u0027;"},{"lineNumber":9,"author":{"gitId":"-"},"content":"import { TimezoneService } from \u0027./timezone.service\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import { ResourceEndpoints } from \u0027../types/api-const\u0027;"},{"lineNumber":11,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":12,"author":{"gitId":"-"},"content":" AccountRequest,"},{"lineNumber":13,"author":{"gitId":"-"},"content":" AccountRequests,"},{"lineNumber":14,"author":{"gitId":"domoberzin"},"content":" AccountRequestStatus,"},{"lineNumber":15,"author":{"gitId":"-"},"content":" Course, FeedbackSession,"},{"lineNumber":16,"author":{"gitId":"-"},"content":" FeedbackSessions,"},{"lineNumber":17,"author":{"gitId":"-"},"content":" Instructor,"},{"lineNumber":18,"author":{"gitId":"-"},"content":" InstructorPermissionRole,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" InstructorPrivilege,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" Instructors,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" Student,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" Students,"},{"lineNumber":23,"author":{"gitId":"-"},"content":"} from \u0027../types/api-output\u0027;"},{"lineNumber":24,"author":{"gitId":"-"},"content":"import { Intent } from \u0027../types/api-request\u0027;"},{"lineNumber":25,"author":{"gitId":"-"},"content":""},{"lineNumber":26,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":27,"author":{"gitId":"-"},"content":" * Handles the logic for search."},{"lineNumber":28,"author":{"gitId":"-"},"content":" */"},{"lineNumber":29,"author":{"gitId":"-"},"content":"@Injectable({"},{"lineNumber":30,"author":{"gitId":"-"},"content":" providedIn: \u0027root\u0027,"},{"lineNumber":31,"author":{"gitId":"-"},"content":"})"},{"lineNumber":32,"author":{"gitId":"-"},"content":"export class SearchService {"},{"lineNumber":33,"author":{"gitId":"-"},"content":""},{"lineNumber":34,"author":{"gitId":"-"},"content":" constructor("},{"lineNumber":35,"author":{"gitId":"-"},"content":" private instructorService: InstructorService,"},{"lineNumber":36,"author":{"gitId":"-"},"content":" private httpRequestService: HttpRequestService,"},{"lineNumber":37,"author":{"gitId":"-"},"content":" private feedbackSessionService: FeedbackSessionsService,"},{"lineNumber":38,"author":{"gitId":"-"},"content":" private courseService: CourseService,"},{"lineNumber":39,"author":{"gitId":"-"},"content":" private linkService: LinkService,"},{"lineNumber":40,"author":{"gitId":"-"},"content":" private timezoneService: TimezoneService,"},{"lineNumber":41,"author":{"gitId":"-"},"content":" ) {}"},{"lineNumber":42,"author":{"gitId":"-"},"content":""},{"lineNumber":43,"author":{"gitId":"-"},"content":" searchInstructor(searchKey: string): Observable\u003cInstructorSearchResult\u003e {"},{"lineNumber":44,"author":{"gitId":"-"},"content":" return this.searchStudents(searchKey, \u0027instructor\u0027).pipe("},{"lineNumber":45,"author":{"gitId":"-"},"content":" map((studentsRes: Students) \u003d\u003e {"},{"lineNumber":46,"author":{"gitId":"-"},"content":" return {"},{"lineNumber":47,"author":{"gitId":"-"},"content":" students: studentsRes.students,"},{"lineNumber":48,"author":{"gitId":"-"},"content":" comments: [],"},{"lineNumber":49,"author":{"gitId":"-"},"content":" };"},{"lineNumber":50,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":51,"author":{"gitId":"-"},"content":" );"},{"lineNumber":52,"author":{"gitId":"-"},"content":" }"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" searchAdmin(searchKey: string): Observable\u003cAdminSearchResult\u003e {"},{"lineNumber":55,"author":{"gitId":"-"},"content":" return forkJoin(["},{"lineNumber":56,"author":{"gitId":"-"},"content":" this.searchStudents(searchKey, \u0027admin\u0027),"},{"lineNumber":57,"author":{"gitId":"-"},"content":" this.searchInstructors(searchKey),"},{"lineNumber":58,"author":{"gitId":"-"},"content":" this.searchAccountRequests(searchKey),"},{"lineNumber":59,"author":{"gitId":"-"},"content":" ]).pipe("},{"lineNumber":60,"author":{"gitId":"-"},"content":" map((value: [Students, Instructors, AccountRequests]): [Student[], Instructor[], AccountRequest[]] \u003d\u003e"},{"lineNumber":61,"author":{"gitId":"-"},"content":" [value[0].students, value[1].instructors, value[2].accountRequests],"},{"lineNumber":62,"author":{"gitId":"-"},"content":" ),"},{"lineNumber":63,"author":{"gitId":"-"},"content":" mergeMap((value: [Student[], Instructor[], AccountRequest[]]) \u003d\u003e {"},{"lineNumber":64,"author":{"gitId":"-"},"content":" const [students, instructors, accountRequests]: [Student[], Instructor[], AccountRequest[]] \u003d value;"},{"lineNumber":65,"author":{"gitId":"-"},"content":" return forkJoin(["},{"lineNumber":66,"author":{"gitId":"-"},"content":" of(students),"},{"lineNumber":67,"author":{"gitId":"-"},"content":" of(instructors),"},{"lineNumber":68,"author":{"gitId":"-"},"content":" of(accountRequests),"},{"lineNumber":69,"author":{"gitId":"-"},"content":" this.getDistinctFields(students, instructors),"},{"lineNumber":70,"author":{"gitId":"-"},"content":" ]);"},{"lineNumber":71,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":72,"author":{"gitId":"-"},"content":" map((value: [Student[], Instructor[], AccountRequest[], DistinctFields]) \u003d\u003e {"},{"lineNumber":73,"author":{"gitId":"-"},"content":" return {"},{"lineNumber":74,"author":{"gitId":"-"},"content":" students: this.createStudentAccountSearchResults(value[0], ...value[3]),"},{"lineNumber":75,"author":{"gitId":"-"},"content":" instructors: this.createInstructorAccountSearchResults(value[1], value[3][1], value[3][2]),"},{"lineNumber":76,"author":{"gitId":"-"},"content":" accountRequests: this.createAccountRequestSearchResults(value[2]),"},{"lineNumber":77,"author":{"gitId":"-"},"content":" };"},{"lineNumber":78,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":79,"author":{"gitId":"-"},"content":" );"},{"lineNumber":80,"author":{"gitId":"-"},"content":" }"},{"lineNumber":81,"author":{"gitId":"-"},"content":""},{"lineNumber":82,"author":{"gitId":"-"},"content":" searchStudents(searchKey: string, entityType: string): Observable\u003cStudents\u003e {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" const paramMap: { [key: string]: string } \u003d {"},{"lineNumber":84,"author":{"gitId":"-"},"content":" searchkey: searchKey,"},{"lineNumber":85,"author":{"gitId":"-"},"content":" entitytype: entityType,"},{"lineNumber":86,"author":{"gitId":"-"},"content":" };"},{"lineNumber":87,"author":{"gitId":"-"},"content":" return this.httpRequestService.get(ResourceEndpoints.SEARCH_STUDENTS, paramMap);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" }"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" searchInstructors(searchKey: string): Observable\u003cInstructors\u003e {"},{"lineNumber":91,"author":{"gitId":"-"},"content":" const paramMap: { [key: string]: string } \u003d {"},{"lineNumber":92,"author":{"gitId":"-"},"content":" searchkey: searchKey,"},{"lineNumber":93,"author":{"gitId":"-"},"content":" };"},{"lineNumber":94,"author":{"gitId":"-"},"content":" return this.httpRequestService.get(ResourceEndpoints.SEARCH_INSTRUCTORS, paramMap);"},{"lineNumber":95,"author":{"gitId":"-"},"content":" }"},{"lineNumber":96,"author":{"gitId":"-"},"content":""},{"lineNumber":97,"author":{"gitId":"-"},"content":" searchAccountRequests(searchKey: string): Observable\u003cAccountRequests\u003e {"},{"lineNumber":98,"author":{"gitId":"-"},"content":" const paramMap: { [key: string]: string } \u003d {"},{"lineNumber":99,"author":{"gitId":"-"},"content":" searchkey: searchKey,"},{"lineNumber":100,"author":{"gitId":"-"},"content":" };"},{"lineNumber":101,"author":{"gitId":"-"},"content":" return this.httpRequestService.get(ResourceEndpoints.SEARCH_ACCOUNT_REQUESTS, paramMap);"},{"lineNumber":102,"author":{"gitId":"-"},"content":" }"},{"lineNumber":103,"author":{"gitId":"-"},"content":""},{"lineNumber":104,"author":{"gitId":"-"},"content":" createStudentAccountSearchResults("},{"lineNumber":105,"author":{"gitId":"-"},"content":" students: Student[],"},{"lineNumber":106,"author":{"gitId":"-"},"content":" distinctInstructorsMap: DistinctInstructorsMap,"},{"lineNumber":107,"author":{"gitId":"-"},"content":" distinctCoursesMap: DistinctCoursesMap,"},{"lineNumber":108,"author":{"gitId":"-"},"content":" distinctFeedbackSessionsMap: DistinctFeedbackSessionsMap,"},{"lineNumber":109,"author":{"gitId":"-"},"content":" distinctInstructorPrivilegesMap: DistinctInstructorPrivilegesMap,"},{"lineNumber":110,"author":{"gitId":"-"},"content":" ): StudentAccountSearchResult[] {"},{"lineNumber":111,"author":{"gitId":"-"},"content":" return students.map((student: Student) \u003d\u003e {"},{"lineNumber":112,"author":{"gitId":"-"},"content":" const { courseId }: Student \u003d student;"},{"lineNumber":113,"author":{"gitId":"-"},"content":" return this.joinAdminStudent("},{"lineNumber":114,"author":{"gitId":"-"},"content":" student,"},{"lineNumber":115,"author":{"gitId":"-"},"content":" distinctInstructorsMap[courseId],"},{"lineNumber":116,"author":{"gitId":"-"},"content":" distinctCoursesMap[courseId],"},{"lineNumber":117,"author":{"gitId":"-"},"content":" distinctFeedbackSessionsMap[courseId],"},{"lineNumber":118,"author":{"gitId":"-"},"content":" distinctInstructorPrivilegesMap[courseId],"},{"lineNumber":119,"author":{"gitId":"-"},"content":" );"},{"lineNumber":120,"author":{"gitId":"-"},"content":" });"},{"lineNumber":121,"author":{"gitId":"-"},"content":" }"},{"lineNumber":122,"author":{"gitId":"-"},"content":""},{"lineNumber":123,"author":{"gitId":"-"},"content":" joinAdminStudent("},{"lineNumber":124,"author":{"gitId":"-"},"content":" student: Student,"},{"lineNumber":125,"author":{"gitId":"-"},"content":" instructors: Instructors,"},{"lineNumber":126,"author":{"gitId":"-"},"content":" course: Course,"},{"lineNumber":127,"author":{"gitId":"-"},"content":" feedbackSessions: FeedbackSessions,"},{"lineNumber":128,"author":{"gitId":"-"},"content":" instructorPrivileges: InstructorPrivilege[],"},{"lineNumber":129,"author":{"gitId":"-"},"content":" ): StudentAccountSearchResult {"},{"lineNumber":130,"author":{"gitId":"-"},"content":" let studentResult: StudentAccountSearchResult \u003d {"},{"lineNumber":131,"author":{"gitId":"-"},"content":" email: \u0027\u0027,"},{"lineNumber":132,"author":{"gitId":"-"},"content":" name: \u0027\u0027,"},{"lineNumber":133,"author":{"gitId":"-"},"content":" comments: \u0027\u0027,"},{"lineNumber":134,"author":{"gitId":"-"},"content":" team: \u0027\u0027,"},{"lineNumber":135,"author":{"gitId":"-"},"content":" section: \u0027\u0027,"},{"lineNumber":136,"author":{"gitId":"-"},"content":" awaitingSessions: {},"},{"lineNumber":137,"author":{"gitId":"-"},"content":" openSessions: {},"},{"lineNumber":138,"author":{"gitId":"-"},"content":" notOpenSessions: {},"},{"lineNumber":139,"author":{"gitId":"-"},"content":" publishedSessions: {},"},{"lineNumber":140,"author":{"gitId":"-"},"content":" courseId: \u0027\u0027,"},{"lineNumber":141,"author":{"gitId":"-"},"content":" courseName: \u0027\u0027,"},{"lineNumber":142,"author":{"gitId":"-"},"content":" isCourseDeleted: false,"},{"lineNumber":143,"author":{"gitId":"-"},"content":" institute: \u0027\u0027,"},{"lineNumber":144,"author":{"gitId":"-"},"content":" manageAccountLink: \u0027\u0027,"},{"lineNumber":145,"author":{"gitId":"-"},"content":" homePageLink: \u0027\u0027,"},{"lineNumber":146,"author":{"gitId":"-"},"content":" profilePageLink: \u0027\u0027,"},{"lineNumber":147,"author":{"gitId":"-"},"content":" courseJoinLink: \u0027\u0027,"},{"lineNumber":148,"author":{"gitId":"-"},"content":" googleId: \u0027\u0027,"},{"lineNumber":149,"author":{"gitId":"-"},"content":" showLinks: false,"},{"lineNumber":150,"author":{"gitId":"-"},"content":" };"},{"lineNumber":151,"author":{"gitId":"-"},"content":" const {"},{"lineNumber":152,"author":{"gitId":"-"},"content":" email,"},{"lineNumber":153,"author":{"gitId":"-"},"content":" name,"},{"lineNumber":154,"author":{"gitId":"-"},"content":" comments \u003d \u0027\u0027,"},{"lineNumber":155,"author":{"gitId":"-"},"content":" teamName: team,"},{"lineNumber":156,"author":{"gitId":"-"},"content":" sectionName: section,"},{"lineNumber":157,"author":{"gitId":"-"},"content":" googleId \u003d \u0027\u0027,"},{"lineNumber":158,"author":{"gitId":"-"},"content":" institute \u003d \u0027\u0027,"},{"lineNumber":159,"author":{"gitId":"-"},"content":" }: Student \u003d student;"},{"lineNumber":160,"author":{"gitId":"-"},"content":" studentResult \u003d { ...studentResult, email, name, comments, team, section, googleId, institute };"},{"lineNumber":161,"author":{"gitId":"-"},"content":""},{"lineNumber":162,"author":{"gitId":"-"},"content":" const { courseId, courseName, deletionTimestamp }: Course \u003d course;"},{"lineNumber":163,"author":{"gitId":"-"},"content":" studentResult \u003d { ...studentResult, courseId, courseName, isCourseDeleted: Boolean(deletionTimestamp) };"},{"lineNumber":164,"author":{"gitId":"-"},"content":""},{"lineNumber":165,"author":{"gitId":"-"},"content":" let masqueradeGoogleId: string \u003d \u0027\u0027;"},{"lineNumber":166,"author":{"gitId":"-"},"content":" for (const instructor of instructors.instructors) {"},{"lineNumber":167,"author":{"gitId":"-"},"content":" if (instructor.googleId"},{"lineNumber":168,"author":{"gitId":"-"},"content":" \u0026\u0026 instructor.role \u003d\u003d\u003d InstructorPermissionRole.INSTRUCTOR_PERMISSION_ROLE_COOWNER) {"},{"lineNumber":169,"author":{"gitId":"-"},"content":" masqueradeGoogleId \u003d instructor.googleId;"},{"lineNumber":170,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":171,"author":{"gitId":"-"},"content":" }"},{"lineNumber":172,"author":{"gitId":"-"},"content":" }"},{"lineNumber":173,"author":{"gitId":"-"},"content":" // no instructor with co-owner privileges"},{"lineNumber":174,"author":{"gitId":"-"},"content":" // there is usually at least one instructor with \"modify instructor\" permission"},{"lineNumber":175,"author":{"gitId":"-"},"content":" if (masqueradeGoogleId \u003d\u003d\u003d \u0027\u0027) {"},{"lineNumber":176,"author":{"gitId":"-"},"content":" for (const instructor of instructors.instructors) {"},{"lineNumber":177,"author":{"gitId":"-"},"content":" const instructorPrivilege: InstructorPrivilege | undefined \u003d instructorPrivileges.shift();"},{"lineNumber":178,"author":{"gitId":"-"},"content":" if (instructor.googleId"},{"lineNumber":179,"author":{"gitId":"-"},"content":" \u0026\u0026 (instructorPrivilege \u0026\u0026 instructorPrivilege.privileges.courseLevel.canModifyInstructor)) {"},{"lineNumber":180,"author":{"gitId":"-"},"content":" masqueradeGoogleId \u003d instructor.googleId;"},{"lineNumber":181,"author":{"gitId":"-"},"content":" break;"},{"lineNumber":182,"author":{"gitId":"-"},"content":" }"},{"lineNumber":183,"author":{"gitId":"-"},"content":" }"},{"lineNumber":184,"author":{"gitId":"-"},"content":" }"},{"lineNumber":185,"author":{"gitId":"-"},"content":""},{"lineNumber":186,"author":{"gitId":"-"},"content":" // Generate feedback session urls"},{"lineNumber":187,"author":{"gitId":"-"},"content":" const { awaitingSessions, openSessions, notOpenSessions, publishedSessions }: StudentFeedbackSessions \u003d"},{"lineNumber":188,"author":{"gitId":"-"},"content":" this.classifyFeedbackSessions(feedbackSessions, student, false);"},{"lineNumber":189,"author":{"gitId":"-"},"content":" studentResult \u003d { ...studentResult, awaitingSessions, openSessions, notOpenSessions, publishedSessions };"},{"lineNumber":190,"author":{"gitId":"-"},"content":""},{"lineNumber":191,"author":{"gitId":"-"},"content":" // Generate links for students"},{"lineNumber":192,"author":{"gitId":"-"},"content":" studentResult.courseJoinLink \u003d this.linkService.generateCourseJoinLink(student, \u0027student\u0027);"},{"lineNumber":193,"author":{"gitId":"-"},"content":" studentResult.homePageLink \u003d this.linkService"},{"lineNumber":194,"author":{"gitId":"-"},"content":" .generateHomePageLink(googleId, this.linkService.STUDENT_HOME_PAGE);"},{"lineNumber":195,"author":{"gitId":"-"},"content":" studentResult.profilePageLink \u003d this.linkService.generateProfilePageLink(student, masqueradeGoogleId);"},{"lineNumber":196,"author":{"gitId":"-"},"content":" studentResult.manageAccountLink \u003d this.linkService"},{"lineNumber":197,"author":{"gitId":"-"},"content":" .generateManageAccountLink(googleId, this.linkService.ADMIN_ACCOUNTS_PAGE);"},{"lineNumber":198,"author":{"gitId":"-"},"content":""},{"lineNumber":199,"author":{"gitId":"-"},"content":" return studentResult;"},{"lineNumber":200,"author":{"gitId":"-"},"content":" }"},{"lineNumber":201,"author":{"gitId":"-"},"content":""},{"lineNumber":202,"author":{"gitId":"-"},"content":" createInstructorAccountSearchResults("},{"lineNumber":203,"author":{"gitId":"-"},"content":" instructors: Instructor[],"},{"lineNumber":204,"author":{"gitId":"-"},"content":" distinctCoursesMap: DistinctCoursesMap,"},{"lineNumber":205,"author":{"gitId":"-"},"content":" distinctFeedbackSessionsMap: DistinctFeedbackSessionsMap,"},{"lineNumber":206,"author":{"gitId":"-"},"content":" ): InstructorAccountSearchResult[] {"},{"lineNumber":207,"author":{"gitId":"-"},"content":" return instructors.map((instructor: Instructor) \u003d\u003e"},{"lineNumber":208,"author":{"gitId":"-"},"content":" this.joinAdminInstructor(instructor, distinctCoursesMap[instructor.courseId],"},{"lineNumber":209,"author":{"gitId":"-"},"content":" distinctFeedbackSessionsMap[instructor.courseId]));"},{"lineNumber":210,"author":{"gitId":"-"},"content":" }"},{"lineNumber":211,"author":{"gitId":"-"},"content":""},{"lineNumber":212,"author":{"gitId":"-"},"content":" joinAdminInstructor("},{"lineNumber":213,"author":{"gitId":"-"},"content":" instructor: Instructor,"},{"lineNumber":214,"author":{"gitId":"-"},"content":" course: Course,"},{"lineNumber":215,"author":{"gitId":"-"},"content":" feedbackSessions: FeedbackSessions,"},{"lineNumber":216,"author":{"gitId":"-"},"content":" ): InstructorAccountSearchResult {"},{"lineNumber":217,"author":{"gitId":"-"},"content":" let instructorResult: InstructorAccountSearchResult \u003d {"},{"lineNumber":218,"author":{"gitId":"-"},"content":" email: \u0027\u0027,"},{"lineNumber":219,"author":{"gitId":"-"},"content":" name: \u0027\u0027,"},{"lineNumber":220,"author":{"gitId":"-"},"content":" courseId: \u0027\u0027,"},{"lineNumber":221,"author":{"gitId":"-"},"content":" courseName: \u0027\u0027,"},{"lineNumber":222,"author":{"gitId":"-"},"content":" isCourseDeleted: false,"},{"lineNumber":223,"author":{"gitId":"-"},"content":" institute: \u0027\u0027,"},{"lineNumber":224,"author":{"gitId":"-"},"content":" manageAccountLink: \u0027\u0027,"},{"lineNumber":225,"author":{"gitId":"-"},"content":" homePageLink: \u0027\u0027,"},{"lineNumber":226,"author":{"gitId":"-"},"content":" courseJoinLink: \u0027\u0027,"},{"lineNumber":227,"author":{"gitId":"-"},"content":" googleId: \u0027\u0027,"},{"lineNumber":228,"author":{"gitId":"-"},"content":" showLinks: false,"},{"lineNumber":229,"author":{"gitId":"-"},"content":" awaitingSessions: {},"},{"lineNumber":230,"author":{"gitId":"-"},"content":" openSessions: {},"},{"lineNumber":231,"author":{"gitId":"-"},"content":" notOpenSessions: {},"},{"lineNumber":232,"author":{"gitId":"-"},"content":" publishedSessions: {},"},{"lineNumber":233,"author":{"gitId":"-"},"content":" };"},{"lineNumber":234,"author":{"gitId":"-"},"content":" const { email, name, googleId \u003d \u0027\u0027, institute \u003d \u0027\u0027 }: Instructor \u003d instructor;"},{"lineNumber":235,"author":{"gitId":"-"},"content":" instructorResult \u003d { ...instructorResult, email, name, googleId, institute };"},{"lineNumber":236,"author":{"gitId":"-"},"content":""},{"lineNumber":237,"author":{"gitId":"-"},"content":" const { courseId, courseName, deletionTimestamp }: Course \u003d course;"},{"lineNumber":238,"author":{"gitId":"-"},"content":" instructorResult \u003d { ...instructorResult, courseId, courseName, isCourseDeleted: Boolean(deletionTimestamp) };"},{"lineNumber":239,"author":{"gitId":"-"},"content":""},{"lineNumber":240,"author":{"gitId":"-"},"content":" // Generate feedback session urls"},{"lineNumber":241,"author":{"gitId":"-"},"content":" const { awaitingSessions, openSessions, notOpenSessions, publishedSessions }: StudentFeedbackSessions \u003d"},{"lineNumber":242,"author":{"gitId":"-"},"content":" this.classifyFeedbackSessions(feedbackSessions, instructor, true);"},{"lineNumber":243,"author":{"gitId":"-"},"content":" instructorResult \u003d { ...instructorResult, awaitingSessions, openSessions, notOpenSessions, publishedSessions };"},{"lineNumber":244,"author":{"gitId":"-"},"content":""},{"lineNumber":245,"author":{"gitId":"-"},"content":" // Generate links for instructors"},{"lineNumber":246,"author":{"gitId":"-"},"content":" instructorResult.courseJoinLink \u003d this.linkService.generateCourseJoinLink(instructor, \u0027instructor\u0027);"},{"lineNumber":247,"author":{"gitId":"-"},"content":" instructorResult.homePageLink \u003d this.linkService"},{"lineNumber":248,"author":{"gitId":"-"},"content":" .generateHomePageLink(googleId, this.linkService.INSTRUCTOR_HOME_PAGE);"},{"lineNumber":249,"author":{"gitId":"-"},"content":" instructorResult.manageAccountLink \u003d this.linkService"},{"lineNumber":250,"author":{"gitId":"-"},"content":" .generateManageAccountLink(googleId, this.linkService.ADMIN_ACCOUNTS_PAGE);"},{"lineNumber":251,"author":{"gitId":"-"},"content":""},{"lineNumber":252,"author":{"gitId":"-"},"content":" return instructorResult;"},{"lineNumber":253,"author":{"gitId":"-"},"content":" }"},{"lineNumber":254,"author":{"gitId":"-"},"content":""},{"lineNumber":255,"author":{"gitId":"-"},"content":" classifyFeedbackSessions(feedbackSessions: FeedbackSessions, entity: Student | Instructor, isInstructor: boolean):"},{"lineNumber":256,"author":{"gitId":"-"},"content":" StudentFeedbackSessions {"},{"lineNumber":257,"author":{"gitId":"-"},"content":" const feedbackSessionLinks: StudentFeedbackSessions \u003d {"},{"lineNumber":258,"author":{"gitId":"-"},"content":" awaitingSessions: {},"},{"lineNumber":259,"author":{"gitId":"-"},"content":" openSessions: {},"},{"lineNumber":260,"author":{"gitId":"-"},"content":" notOpenSessions: {},"},{"lineNumber":261,"author":{"gitId":"-"},"content":" publishedSessions: {},"},{"lineNumber":262,"author":{"gitId":"-"},"content":" };"},{"lineNumber":263,"author":{"gitId":"-"},"content":" for (const feedbackSession of feedbackSessions.feedbackSessions) {"},{"lineNumber":264,"author":{"gitId":"-"},"content":" if (this.feedbackSessionService.isFeedbackSessionOpen(feedbackSession)) {"},{"lineNumber":265,"author":{"gitId":"-"},"content":" feedbackSessionLinks.openSessions[feedbackSession.feedbackSessionName] \u003d {"},{"lineNumber":266,"author":{"gitId":"-"},"content":" ...this.formatProperties(feedbackSession),"},{"lineNumber":267,"author":{"gitId":"-"},"content":" feedbackSessionUrl: this.linkService.generateSubmitUrl("},{"lineNumber":268,"author":{"gitId":"-"},"content":" entity, feedbackSession.feedbackSessionName, isInstructor),"},{"lineNumber":269,"author":{"gitId":"-"},"content":" };"},{"lineNumber":270,"author":{"gitId":"-"},"content":" } else if (this.feedbackSessionService.isFeedbackSessionAwaiting(feedbackSession)) {"},{"lineNumber":271,"author":{"gitId":"-"},"content":" feedbackSessionLinks.awaitingSessions[feedbackSession.feedbackSessionName] \u003d {"},{"lineNumber":272,"author":{"gitId":"-"},"content":" ...this.formatProperties(feedbackSession),"},{"lineNumber":273,"author":{"gitId":"-"},"content":" feedbackSessionUrl: this.linkService.generateSubmitUrl("},{"lineNumber":274,"author":{"gitId":"-"},"content":" entity, feedbackSession.feedbackSessionName, isInstructor),"},{"lineNumber":275,"author":{"gitId":"-"},"content":" };"},{"lineNumber":276,"author":{"gitId":"-"},"content":" } else {"},{"lineNumber":277,"author":{"gitId":"-"},"content":" feedbackSessionLinks.notOpenSessions[feedbackSession.feedbackSessionName] \u003d {"},{"lineNumber":278,"author":{"gitId":"-"},"content":" ...this.formatProperties(feedbackSession),"},{"lineNumber":279,"author":{"gitId":"-"},"content":" feedbackSessionUrl: this.linkService.generateSubmitUrl("},{"lineNumber":280,"author":{"gitId":"-"},"content":" entity, feedbackSession.feedbackSessionName, isInstructor),"},{"lineNumber":281,"author":{"gitId":"-"},"content":" };"},{"lineNumber":282,"author":{"gitId":"-"},"content":" }"},{"lineNumber":283,"author":{"gitId":"-"},"content":""},{"lineNumber":284,"author":{"gitId":"-"},"content":" if (this.feedbackSessionService.isFeedbackSessionPublished(feedbackSession)) {"},{"lineNumber":285,"author":{"gitId":"-"},"content":" feedbackSessionLinks.publishedSessions[feedbackSession.feedbackSessionName] \u003d {"},{"lineNumber":286,"author":{"gitId":"-"},"content":" ...this.formatProperties(feedbackSession),"},{"lineNumber":287,"author":{"gitId":"-"},"content":" feedbackSessionUrl: this.linkService.generateResultUrl("},{"lineNumber":288,"author":{"gitId":"-"},"content":" entity, feedbackSession.feedbackSessionName, isInstructor),"},{"lineNumber":289,"author":{"gitId":"-"},"content":" };"},{"lineNumber":290,"author":{"gitId":"-"},"content":" }"},{"lineNumber":291,"author":{"gitId":"-"},"content":" }"},{"lineNumber":292,"author":{"gitId":"-"},"content":" return feedbackSessionLinks;"},{"lineNumber":293,"author":{"gitId":"-"},"content":" }"},{"lineNumber":294,"author":{"gitId":"-"},"content":""},{"lineNumber":295,"author":{"gitId":"-"},"content":" createAccountRequestSearchResults("},{"lineNumber":296,"author":{"gitId":"-"},"content":" accountRequests: AccountRequest[],"},{"lineNumber":297,"author":{"gitId":"-"},"content":" ): AccountRequestSearchResult[] {"},{"lineNumber":298,"author":{"gitId":"-"},"content":" return accountRequests.map((accountRequest: AccountRequest) \u003d\u003e this.joinAdminAccountRequest(accountRequest));"},{"lineNumber":299,"author":{"gitId":"-"},"content":" }"},{"lineNumber":300,"author":{"gitId":"-"},"content":""},{"lineNumber":301,"author":{"gitId":"-"},"content":" joinAdminAccountRequest(accountRequest: AccountRequest): AccountRequestSearchResult {"},{"lineNumber":302,"author":{"gitId":"-"},"content":" let accountRequestResult: AccountRequestSearchResult \u003d {"},{"lineNumber":303,"author":{"gitId":"-"},"content":" id: \u0027\u0027,"},{"lineNumber":304,"author":{"gitId":"-"},"content":" name: \u0027\u0027,"},{"lineNumber":305,"author":{"gitId":"-"},"content":" email: \u0027\u0027,"},{"lineNumber":306,"author":{"gitId":"-"},"content":" institute: \u0027\u0027,"},{"lineNumber":307,"author":{"gitId":"-"},"content":" createdAtText: \u0027\u0027,"},{"lineNumber":308,"author":{"gitId":"-"},"content":" registeredAtText: \u0027\u0027,"},{"lineNumber":309,"author":{"gitId":"-"},"content":" registrationLink: \u0027\u0027,"},{"lineNumber":310,"author":{"gitId":"-"},"content":" showLinks: false,"},{"lineNumber":311,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus.PENDING,"},{"lineNumber":312,"author":{"gitId":"domoberzin"},"content":" comments: \u0027\u0027,"},{"lineNumber":313,"author":{"gitId":"-"},"content":" };"},{"lineNumber":314,"author":{"gitId":"-"},"content":""},{"lineNumber":315,"author":{"gitId":"domoberzin"},"content":" const {"},{"lineNumber":316,"author":{"gitId":"-"},"content":" id, registrationKey, createdAt, registeredAt,"},{"lineNumber":317,"author":{"gitId":"domoberzin"},"content":" name, institute, email, status, comments,"},{"lineNumber":318,"author":{"gitId":"domoberzin"},"content":" }: AccountRequest \u003d accountRequest;"},{"lineNumber":319,"author":{"gitId":"-"},"content":""},{"lineNumber":320,"author":{"gitId":"-"},"content":" const timezone: string \u003d this.timezoneService.guessTimezone() || \u0027UTC\u0027;"},{"lineNumber":321,"author":{"gitId":"-"},"content":" accountRequestResult.createdAtText \u003d this.formatTimestampAsString(createdAt, timezone);"},{"lineNumber":322,"author":{"gitId":"-"},"content":" accountRequestResult.registeredAtText \u003d registeredAt ? this.formatTimestampAsString(registeredAt, timezone) : null;"},{"lineNumber":323,"author":{"gitId":"domoberzin"},"content":" accountRequestResult.comments \u003d comments || \u0027\u0027;"},{"lineNumber":324,"author":{"gitId":"-"},"content":""},{"lineNumber":325,"author":{"gitId":"-"},"content":" const registrationLink: string \u003d this.linkService.generateAccountRegistrationLink(registrationKey);"},{"lineNumber":326,"author":{"gitId":"-"},"content":" accountRequestResult \u003d { ...accountRequestResult, id, name, email, institute, registrationLink, status };"},{"lineNumber":327,"author":{"gitId":"-"},"content":""},{"lineNumber":328,"author":{"gitId":"-"},"content":" return accountRequestResult;"},{"lineNumber":329,"author":{"gitId":"-"},"content":" }"},{"lineNumber":330,"author":{"gitId":"-"},"content":""},{"lineNumber":331,"author":{"gitId":"-"},"content":" private getDistinctFields(students: Student[], instructors: Instructor[]): Observable\u003cDistinctFields\u003e {"},{"lineNumber":332,"author":{"gitId":"-"},"content":" const distinctCourseIds: string[] \u003d Array.from(new Set(["},{"lineNumber":333,"author":{"gitId":"-"},"content":" ...students.map((student: Student) \u003d\u003e student.courseId),"},{"lineNumber":334,"author":{"gitId":"-"},"content":" ...instructors.map((instructor: Instructor) \u003d\u003e instructor.courseId),"},{"lineNumber":335,"author":{"gitId":"-"},"content":" ]));"},{"lineNumber":336,"author":{"gitId":"-"},"content":" if (distinctCourseIds.length \u003d\u003d\u003d 0) {"},{"lineNumber":337,"author":{"gitId":"-"},"content":" return forkJoin([of({}), of({}), of({}), of({})]);"},{"lineNumber":338,"author":{"gitId":"-"},"content":" }"},{"lineNumber":339,"author":{"gitId":"-"},"content":" return forkJoin(["},{"lineNumber":340,"author":{"gitId":"-"},"content":" this.getDistinctInstructors(distinctCourseIds),"},{"lineNumber":341,"author":{"gitId":"-"},"content":" this.getDistinctCourses(distinctCourseIds),"},{"lineNumber":342,"author":{"gitId":"-"},"content":" this.getDistinctFeedbackSessions(distinctCourseIds),"},{"lineNumber":343,"author":{"gitId":"-"},"content":" ]).pipe("},{"lineNumber":344,"author":{"gitId":"-"},"content":" mergeMap((value: ["},{"lineNumber":345,"author":{"gitId":"-"},"content":" DistinctInstructorsMap,"},{"lineNumber":346,"author":{"gitId":"-"},"content":" DistinctCoursesMap,"},{"lineNumber":347,"author":{"gitId":"-"},"content":" DistinctFeedbackSessionsMap],"},{"lineNumber":348,"author":{"gitId":"-"},"content":" ) \u003d\u003e {"},{"lineNumber":349,"author":{"gitId":"-"},"content":" return forkJoin(["},{"lineNumber":350,"author":{"gitId":"-"},"content":" of(value[0]),"},{"lineNumber":351,"author":{"gitId":"-"},"content":" of(value[1]),"},{"lineNumber":352,"author":{"gitId":"-"},"content":" of(value[2]),"},{"lineNumber":353,"author":{"gitId":"-"},"content":" this.getDistinctInstructorPrivileges(value[0]),"},{"lineNumber":354,"author":{"gitId":"-"},"content":" ]);"},{"lineNumber":355,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":356,"author":{"gitId":"-"},"content":" );"},{"lineNumber":357,"author":{"gitId":"-"},"content":" }"},{"lineNumber":358,"author":{"gitId":"-"},"content":""},{"lineNumber":359,"author":{"gitId":"-"},"content":" private getDistinctInstructors(distinctCourseIds: string[]): Observable\u003cDistinctInstructorsMap\u003e {"},{"lineNumber":360,"author":{"gitId":"-"},"content":" return forkJoin("},{"lineNumber":361,"author":{"gitId":"-"},"content":" distinctCourseIds.map((courseId: string) \u003d\u003e"},{"lineNumber":362,"author":{"gitId":"-"},"content":" this.instructorService.loadInstructors({ courseId, intent: Intent.FULL_DETAIL })),"},{"lineNumber":363,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":364,"author":{"gitId":"-"},"content":" map((instructorsArray: Instructors[]) \u003d\u003e {"},{"lineNumber":365,"author":{"gitId":"-"},"content":" const distinctInstructorsMap: DistinctInstructorsMap \u003d {};"},{"lineNumber":366,"author":{"gitId":"-"},"content":" instructorsArray.forEach((instructors: Instructors, index: number) \u003d\u003e {"},{"lineNumber":367,"author":{"gitId":"-"},"content":" distinctInstructorsMap[distinctCourseIds[index]] \u003d instructors;"},{"lineNumber":368,"author":{"gitId":"-"},"content":" });"},{"lineNumber":369,"author":{"gitId":"-"},"content":" return distinctInstructorsMap;"},{"lineNumber":370,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":371,"author":{"gitId":"-"},"content":" );"},{"lineNumber":372,"author":{"gitId":"-"},"content":" }"},{"lineNumber":373,"author":{"gitId":"-"},"content":""},{"lineNumber":374,"author":{"gitId":"-"},"content":" private getDistinctInstructorPrivileges("},{"lineNumber":375,"author":{"gitId":"-"},"content":" distinctInstructorsMap: DistinctInstructorsMap,"},{"lineNumber":376,"author":{"gitId":"-"},"content":" ): Observable\u003cDistinctInstructorPrivilegesMap\u003e {"},{"lineNumber":377,"author":{"gitId":"-"},"content":" const distinctCourseIds: string[] \u003d Object.keys(distinctInstructorsMap);"},{"lineNumber":378,"author":{"gitId":"-"},"content":" const instructorsArray: Instructors[] \u003d Object.values(distinctInstructorsMap);"},{"lineNumber":379,"author":{"gitId":"-"},"content":" return forkJoin(["},{"lineNumber":380,"author":{"gitId":"-"},"content":" of(distinctCourseIds),"},{"lineNumber":381,"author":{"gitId":"-"},"content":" forkJoin(instructorsArray.map((instructors: Instructors) \u003d\u003e {"},{"lineNumber":382,"author":{"gitId":"-"},"content":" return forkJoin("},{"lineNumber":383,"author":{"gitId":"-"},"content":" instructors.instructors.map("},{"lineNumber":384,"author":{"gitId":"-"},"content":" (instructor: Instructor) \u003d\u003e this.instructorService.loadInstructorPrivilege("},{"lineNumber":385,"author":{"gitId":"-"},"content":" {"},{"lineNumber":386,"author":{"gitId":"-"},"content":" courseId: instructor.courseId,"},{"lineNumber":387,"author":{"gitId":"-"},"content":" instructorEmail: instructor.email,"},{"lineNumber":388,"author":{"gitId":"-"},"content":" },"},{"lineNumber":389,"author":{"gitId":"-"},"content":" ),"},{"lineNumber":390,"author":{"gitId":"-"},"content":" ),"},{"lineNumber":391,"author":{"gitId":"-"},"content":" );"},{"lineNumber":392,"author":{"gitId":"-"},"content":" })),"},{"lineNumber":393,"author":{"gitId":"-"},"content":" ]).pipe("},{"lineNumber":394,"author":{"gitId":"-"},"content":" map("},{"lineNumber":395,"author":{"gitId":"-"},"content":" (value: [string[], InstructorPrivilege[][]]) \u003d\u003e {"},{"lineNumber":396,"author":{"gitId":"-"},"content":" const distinctInstructorPrivilegesMap: DistinctInstructorPrivilegesMap \u003d {};"},{"lineNumber":397,"author":{"gitId":"-"},"content":" value[1].forEach((instructorPrivilegesArray: InstructorPrivilege[], index: number) \u003d\u003e {"},{"lineNumber":398,"author":{"gitId":"-"},"content":" distinctInstructorPrivilegesMap[value[0][index]] \u003d instructorPrivilegesArray;"},{"lineNumber":399,"author":{"gitId":"-"},"content":" });"},{"lineNumber":400,"author":{"gitId":"-"},"content":" return distinctInstructorPrivilegesMap;"},{"lineNumber":401,"author":{"gitId":"-"},"content":" },"},{"lineNumber":402,"author":{"gitId":"-"},"content":" ),"},{"lineNumber":403,"author":{"gitId":"-"},"content":" );"},{"lineNumber":404,"author":{"gitId":"-"},"content":" }"},{"lineNumber":405,"author":{"gitId":"-"},"content":""},{"lineNumber":406,"author":{"gitId":"-"},"content":" private getDistinctCourses(distinctCourseIds: string[]): Observable\u003cDistinctCoursesMap\u003e {"},{"lineNumber":407,"author":{"gitId":"-"},"content":" return forkJoin("},{"lineNumber":408,"author":{"gitId":"-"},"content":" distinctCourseIds.map((id: string) \u003d\u003e this.courseService.getCourseAsInstructor(id)),"},{"lineNumber":409,"author":{"gitId":"-"},"content":" ).pipe("},{"lineNumber":410,"author":{"gitId":"-"},"content":" map((courses: Course[]) \u003d\u003e {"},{"lineNumber":411,"author":{"gitId":"-"},"content":" const distinctCoursesMap: DistinctCoursesMap \u003d {};"},{"lineNumber":412,"author":{"gitId":"-"},"content":" courses.forEach((course: Course, index: number) \u003d\u003e {"},{"lineNumber":413,"author":{"gitId":"-"},"content":" distinctCoursesMap[distinctCourseIds[index]] \u003d course;"},{"lineNumber":414,"author":{"gitId":"-"},"content":" });"},{"lineNumber":415,"author":{"gitId":"-"},"content":" return distinctCoursesMap;"},{"lineNumber":416,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":417,"author":{"gitId":"-"},"content":" );"},{"lineNumber":418,"author":{"gitId":"-"},"content":" }"},{"lineNumber":419,"author":{"gitId":"-"},"content":""},{"lineNumber":420,"author":{"gitId":"-"},"content":" private getDistinctFeedbackSessions(distinctCourseIds: string[]): Observable\u003cDistinctFeedbackSessionsMap\u003e {"},{"lineNumber":421,"author":{"gitId":"-"},"content":" return forkJoin("},{"lineNumber":422,"author":{"gitId":"-"},"content":" distinctCourseIds.map((id: string) \u003d\u003e"},{"lineNumber":423,"author":{"gitId":"-"},"content":" this.feedbackSessionService.getFeedbackSessionsForStudent(\u0027admin\u0027, id)),"},{"lineNumber":424,"author":{"gitId":"-"},"content":" )"},{"lineNumber":425,"author":{"gitId":"-"},"content":" .pipe("},{"lineNumber":426,"author":{"gitId":"-"},"content":" map((feedbackSessionsArray: FeedbackSessions[]) \u003d\u003e {"},{"lineNumber":427,"author":{"gitId":"-"},"content":" const distinctFeedbackSessionsMap: DistinctFeedbackSessionsMap \u003d {};"},{"lineNumber":428,"author":{"gitId":"-"},"content":" feedbackSessionsArray.forEach("},{"lineNumber":429,"author":{"gitId":"-"},"content":" (feedbackSessions: FeedbackSessions, index: number) \u003d\u003e {"},{"lineNumber":430,"author":{"gitId":"-"},"content":" distinctFeedbackSessionsMap[distinctCourseIds[index]] \u003d feedbackSessions;"},{"lineNumber":431,"author":{"gitId":"-"},"content":" },"},{"lineNumber":432,"author":{"gitId":"-"},"content":" );"},{"lineNumber":433,"author":{"gitId":"-"},"content":" return distinctFeedbackSessionsMap;"},{"lineNumber":434,"author":{"gitId":"-"},"content":" }),"},{"lineNumber":435,"author":{"gitId":"-"},"content":" );"},{"lineNumber":436,"author":{"gitId":"-"},"content":" }"},{"lineNumber":437,"author":{"gitId":"-"},"content":""},{"lineNumber":438,"author":{"gitId":"-"},"content":" private formatProperties(feedbackSession: FeedbackSession): { startTime: string, endTime: string } {"},{"lineNumber":439,"author":{"gitId":"-"},"content":" const startTime: string \u003d"},{"lineNumber":440,"author":{"gitId":"-"},"content":" this.formatTimestampAsString(feedbackSession.submissionStartTimestamp, feedbackSession.timeZone);"},{"lineNumber":441,"author":{"gitId":"-"},"content":" const endTime: string \u003d"},{"lineNumber":442,"author":{"gitId":"-"},"content":" this.formatTimestampAsString(feedbackSession.submissionEndTimestamp, feedbackSession.timeZone);"},{"lineNumber":443,"author":{"gitId":"-"},"content":""},{"lineNumber":444,"author":{"gitId":"-"},"content":" return { startTime, endTime };"},{"lineNumber":445,"author":{"gitId":"-"},"content":" }"},{"lineNumber":446,"author":{"gitId":"-"},"content":""},{"lineNumber":447,"author":{"gitId":"-"},"content":" private formatTimestampAsString(timestamp: number, timezone: string): string {"},{"lineNumber":448,"author":{"gitId":"-"},"content":" const dateFormatWithZoneInfo: string \u003d \u0027ddd, DD MMM YYYY, hh:mm A Z\u0027;"},{"lineNumber":449,"author":{"gitId":"-"},"content":""},{"lineNumber":450,"author":{"gitId":"-"},"content":" return this.timezoneService"},{"lineNumber":451,"author":{"gitId":"-"},"content":" .formatToString(timestamp, timezone, dateFormatWithZoneInfo);"},{"lineNumber":452,"author":{"gitId":"-"},"content":" }"},{"lineNumber":453,"author":{"gitId":"-"},"content":"}"},{"lineNumber":454,"author":{"gitId":"-"},"content":""},{"lineNumber":455,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":456,"author":{"gitId":"-"},"content":" * The typings for the response object returned by the instructor search service."},{"lineNumber":457,"author":{"gitId":"-"},"content":" */"},{"lineNumber":458,"author":{"gitId":"-"},"content":"export interface InstructorSearchResult {"},{"lineNumber":459,"author":{"gitId":"-"},"content":" students: Student[];"},{"lineNumber":460,"author":{"gitId":"-"},"content":"}"},{"lineNumber":461,"author":{"gitId":"-"},"content":""},{"lineNumber":462,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":463,"author":{"gitId":"-"},"content":" * The typings for the response object returned by admin search service."},{"lineNumber":464,"author":{"gitId":"-"},"content":" */"},{"lineNumber":465,"author":{"gitId":"-"},"content":"export interface AdminSearchResult {"},{"lineNumber":466,"author":{"gitId":"-"},"content":" students: StudentAccountSearchResult[];"},{"lineNumber":467,"author":{"gitId":"-"},"content":" instructors: InstructorAccountSearchResult[];"},{"lineNumber":468,"author":{"gitId":"-"},"content":" accountRequests: AccountRequestSearchResult[];"},{"lineNumber":469,"author":{"gitId":"-"},"content":"}"},{"lineNumber":470,"author":{"gitId":"-"},"content":""},{"lineNumber":471,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":472,"author":{"gitId":"-"},"content":" * Search results for account requests from the admin endpoint."},{"lineNumber":473,"author":{"gitId":"-"},"content":" */"},{"lineNumber":474,"author":{"gitId":"-"},"content":"export interface AccountRequestSearchResult {"},{"lineNumber":475,"author":{"gitId":"-"},"content":" id: string;"},{"lineNumber":476,"author":{"gitId":"-"},"content":" name: string;"},{"lineNumber":477,"author":{"gitId":"-"},"content":" email: string;"},{"lineNumber":478,"author":{"gitId":"domoberzin"},"content":" status: AccountRequestStatus;"},{"lineNumber":479,"author":{"gitId":"-"},"content":" institute: string;"},{"lineNumber":480,"author":{"gitId":"-"},"content":" createdAtText: string;"},{"lineNumber":481,"author":{"gitId":"-"},"content":" registeredAtText: string | null;"},{"lineNumber":482,"author":{"gitId":"-"},"content":" registrationLink: string;"},{"lineNumber":483,"author":{"gitId":"-"},"content":" showLinks: boolean;"},{"lineNumber":484,"author":{"gitId":"domoberzin"},"content":" comments: string;"},{"lineNumber":485,"author":{"gitId":"-"},"content":"}"},{"lineNumber":486,"author":{"gitId":"-"},"content":""},{"lineNumber":487,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":488,"author":{"gitId":"-"},"content":" * Search results for instructors for the admin endpoint"},{"lineNumber":489,"author":{"gitId":"-"},"content":" */"},{"lineNumber":490,"author":{"gitId":"-"},"content":"export interface InstructorAccountSearchResult {"},{"lineNumber":491,"author":{"gitId":"-"},"content":" name: string;"},{"lineNumber":492,"author":{"gitId":"-"},"content":" email: string;"},{"lineNumber":493,"author":{"gitId":"-"},"content":" googleId: string;"},{"lineNumber":494,"author":{"gitId":"-"},"content":" courseId: string;"},{"lineNumber":495,"author":{"gitId":"-"},"content":" courseName: string;"},{"lineNumber":496,"author":{"gitId":"-"},"content":" isCourseDeleted: boolean;"},{"lineNumber":497,"author":{"gitId":"-"},"content":" institute: string;"},{"lineNumber":498,"author":{"gitId":"-"},"content":" courseJoinLink: string;"},{"lineNumber":499,"author":{"gitId":"-"},"content":" homePageLink: string;"},{"lineNumber":500,"author":{"gitId":"-"},"content":" manageAccountLink: string;"},{"lineNumber":501,"author":{"gitId":"-"},"content":" showLinks: boolean;"},{"lineNumber":502,"author":{"gitId":"-"},"content":" awaitingSessions: FeedbackSessionsGroup;"},{"lineNumber":503,"author":{"gitId":"-"},"content":" openSessions: FeedbackSessionsGroup;"},{"lineNumber":504,"author":{"gitId":"-"},"content":" notOpenSessions: FeedbackSessionsGroup;"},{"lineNumber":505,"author":{"gitId":"-"},"content":" publishedSessions: FeedbackSessionsGroup;"},{"lineNumber":506,"author":{"gitId":"-"},"content":"}"},{"lineNumber":507,"author":{"gitId":"-"},"content":""},{"lineNumber":508,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":509,"author":{"gitId":"-"},"content":" * Search results for students from the Admin endpoint."},{"lineNumber":510,"author":{"gitId":"-"},"content":" */"},{"lineNumber":511,"author":{"gitId":"-"},"content":"export interface StudentAccountSearchResult extends InstructorAccountSearchResult {"},{"lineNumber":512,"author":{"gitId":"-"},"content":" section: string;"},{"lineNumber":513,"author":{"gitId":"-"},"content":" team: string;"},{"lineNumber":514,"author":{"gitId":"-"},"content":" comments: string;"},{"lineNumber":515,"author":{"gitId":"-"},"content":" profilePageLink: string;"},{"lineNumber":516,"author":{"gitId":"-"},"content":"}"},{"lineNumber":517,"author":{"gitId":"-"},"content":""},{"lineNumber":518,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":519,"author":{"gitId":"-"},"content":" * Feedback session information for search result."},{"lineNumber":520,"author":{"gitId":"-"},"content":" */"},{"lineNumber":521,"author":{"gitId":"-"},"content":"export interface FeedbackSessionsGroup {"},{"lineNumber":522,"author":{"gitId":"-"},"content":" [name: string]: {"},{"lineNumber":523,"author":{"gitId":"-"},"content":" startTime: string,"},{"lineNumber":524,"author":{"gitId":"-"},"content":" endTime: string,"},{"lineNumber":525,"author":{"gitId":"-"},"content":" feedbackSessionUrl: string,"},{"lineNumber":526,"author":{"gitId":"-"},"content":" };"},{"lineNumber":527,"author":{"gitId":"-"},"content":"}"},{"lineNumber":528,"author":{"gitId":"-"},"content":""},{"lineNumber":529,"author":{"gitId":"-"},"content":"interface StudentFeedbackSessions {"},{"lineNumber":530,"author":{"gitId":"-"},"content":" awaitingSessions: FeedbackSessionsGroup;"},{"lineNumber":531,"author":{"gitId":"-"},"content":" openSessions: FeedbackSessionsGroup;"},{"lineNumber":532,"author":{"gitId":"-"},"content":" notOpenSessions: FeedbackSessionsGroup;"},{"lineNumber":533,"author":{"gitId":"-"},"content":" publishedSessions: FeedbackSessionsGroup;"},{"lineNumber":534,"author":{"gitId":"-"},"content":"}"},{"lineNumber":535,"author":{"gitId":"-"},"content":""},{"lineNumber":536,"author":{"gitId":"-"},"content":"interface DistinctInstructorsMap {"},{"lineNumber":537,"author":{"gitId":"-"},"content":" [courseId: string]: Instructors;"},{"lineNumber":538,"author":{"gitId":"-"},"content":"}"},{"lineNumber":539,"author":{"gitId":"-"},"content":""},{"lineNumber":540,"author":{"gitId":"-"},"content":"interface DistinctFeedbackSessionsMap {"},{"lineNumber":541,"author":{"gitId":"-"},"content":" [courseId: string]: FeedbackSessions;"},{"lineNumber":542,"author":{"gitId":"-"},"content":"}"},{"lineNumber":543,"author":{"gitId":"-"},"content":""},{"lineNumber":544,"author":{"gitId":"-"},"content":"interface DistinctCoursesMap {"},{"lineNumber":545,"author":{"gitId":"-"},"content":" [courseId: string]: Course;"},{"lineNumber":546,"author":{"gitId":"-"},"content":"}"},{"lineNumber":547,"author":{"gitId":"-"},"content":""},{"lineNumber":548,"author":{"gitId":"-"},"content":"interface DistinctInstructorPrivilegesMap {"},{"lineNumber":549,"author":{"gitId":"-"},"content":" [courseId: string]: InstructorPrivilege[];"},{"lineNumber":550,"author":{"gitId":"-"},"content":"}"},{"lineNumber":551,"author":{"gitId":"-"},"content":""},{"lineNumber":552,"author":{"gitId":"-"},"content":"type DistinctFields \u003d ["},{"lineNumber":553,"author":{"gitId":"-"},"content":" DistinctInstructorsMap,"},{"lineNumber":554,"author":{"gitId":"-"},"content":" DistinctCoursesMap,"},{"lineNumber":555,"author":{"gitId":"-"},"content":" DistinctFeedbackSessionsMap,"},{"lineNumber":556,"author":{"gitId":"-"},"content":" DistinctInstructorPrivilegesMap,"},{"lineNumber":557,"author":{"gitId":"-"},"content":"];"}],"authorContributionMap":{"domoberzin":9,"-":548}},{"path":"src/web/types/const.spec.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"import { ApiConst, ApiStringConst } from \u0027./api-const\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":"import { FeedbackQuestionType } from \u0027./api-output\u0027;"},{"lineNumber":3,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":4,"author":{"gitId":"-"},"content":" DEFAULT_INSTRUCTOR_PRIVILEGE,"},{"lineNumber":5,"author":{"gitId":"-"},"content":" DEFAULT_PRIVILEGE_COOWNER,"},{"lineNumber":6,"author":{"gitId":"-"},"content":" DEFAULT_PRIVILEGE_MANAGER,"},{"lineNumber":7,"author":{"gitId":"-"},"content":" DEFAULT_PRIVILEGE_OBSERVER,"},{"lineNumber":8,"author":{"gitId":"-"},"content":" DEFAULT_PRIVILEGE_TUTOR,"},{"lineNumber":9,"author":{"gitId":"-"},"content":"} from \u0027./default-instructor-privilege\u0027;"},{"lineNumber":10,"author":{"gitId":"-"},"content":"import {"},{"lineNumber":11,"author":{"gitId":"-"},"content":" DEFAULT_CONSTSUM_OPTIONS_QUESTION_DETAILS,"},{"lineNumber":12,"author":{"gitId":"-"},"content":" DEFAULT_CONSTSUM_RECIPIENTS_QUESTION_DETAILS,"},{"lineNumber":13,"author":{"gitId":"-"},"content":" DEFAULT_CONSTSUM_RESPONSE_DETAILS,"},{"lineNumber":14,"author":{"gitId":"-"},"content":" DEFAULT_CONTRIBUTION_QUESTION_DETAILS,"},{"lineNumber":15,"author":{"gitId":"-"},"content":" DEFAULT_CONTRIBUTION_RESPONSE_DETAILS,"},{"lineNumber":16,"author":{"gitId":"-"},"content":" DEFAULT_MCQ_QUESTION_DETAILS,"},{"lineNumber":17,"author":{"gitId":"-"},"content":" DEFAULT_MCQ_RESPONSE_DETAILS,"},{"lineNumber":18,"author":{"gitId":"-"},"content":" DEFAULT_MSQ_QUESTION_DETAILS,"},{"lineNumber":19,"author":{"gitId":"-"},"content":" DEFAULT_MSQ_RESPONSE_DETAILS,"},{"lineNumber":20,"author":{"gitId":"-"},"content":" DEFAULT_NUMSCALE_QUESTION_DETAILS,"},{"lineNumber":21,"author":{"gitId":"-"},"content":" DEFAULT_NUMSCALE_RESPONSE_DETAILS,"},{"lineNumber":22,"author":{"gitId":"-"},"content":" DEFAULT_RANK_OPTIONS_QUESTION_DETAILS,"},{"lineNumber":23,"author":{"gitId":"-"},"content":" DEFAULT_RANK_OPTIONS_RESPONSE_DETAILS,"},{"lineNumber":24,"author":{"gitId":"-"},"content":" DEFAULT_RANK_RECIPIENTS_QUESTION_DETAILS,"},{"lineNumber":25,"author":{"gitId":"-"},"content":" DEFAULT_RANK_RECIPIENTS_RESPONSE_DETAILS,"},{"lineNumber":26,"author":{"gitId":"-"},"content":" DEFAULT_RUBRIC_QUESTION_DETAILS,"},{"lineNumber":27,"author":{"gitId":"-"},"content":" DEFAULT_RUBRIC_RESPONSE_DETAILS,"},{"lineNumber":28,"author":{"gitId":"-"},"content":" DEFAULT_TEXT_QUESTION_DETAILS,"},{"lineNumber":29,"author":{"gitId":"-"},"content":" DEFAULT_TEXT_RESPONSE_DETAILS,"},{"lineNumber":30,"author":{"gitId":"-"},"content":"} from \u0027./default-question-structs\u0027;"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":"describe(\u0027Constants\u0027, () \u003d\u003e {"},{"lineNumber":33,"author":{"gitId":"-"},"content":" // Here we test that the constants are positive numbers"},{"lineNumber":34,"author":{"gitId":"-"},"content":" // The exact values are implementation details that do not matter"},{"lineNumber":35,"author":{"gitId":"-"},"content":" it(\u0027should generate length limits correctly\u0027, () \u003d\u003e {"},{"lineNumber":36,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.COURSE_ID_MAX_LENGTH).toEqual(\u0027number\u0027);"},{"lineNumber":37,"author":{"gitId":"-"},"content":" expect(ApiConst.COURSE_ID_MAX_LENGTH).toBeGreaterThan(0);"},{"lineNumber":38,"author":{"gitId":"-"},"content":""},{"lineNumber":39,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.COURSE_NAME_MAX_LENGTH).toEqual(\u0027number\u0027);"},{"lineNumber":40,"author":{"gitId":"-"},"content":" expect(ApiConst.COURSE_NAME_MAX_LENGTH).toBeGreaterThan(0);"},{"lineNumber":41,"author":{"gitId":"-"},"content":""},{"lineNumber":42,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.STUDENT_NAME_MAX_LENGTH).toEqual(\u0027number\u0027);"},{"lineNumber":43,"author":{"gitId":"-"},"content":" expect(ApiConst.STUDENT_NAME_MAX_LENGTH).toBeGreaterThan(0);"},{"lineNumber":44,"author":{"gitId":"-"},"content":""},{"lineNumber":45,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.SECTION_NAME_MAX_LENGTH).toEqual(\u0027number\u0027);"},{"lineNumber":46,"author":{"gitId":"-"},"content":" expect(ApiConst.SECTION_NAME_MAX_LENGTH).toBeGreaterThan(0);"},{"lineNumber":47,"author":{"gitId":"-"},"content":""},{"lineNumber":48,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.TEAM_NAME_MAX_LENGTH).toEqual(\u0027number\u0027);"},{"lineNumber":49,"author":{"gitId":"-"},"content":" expect(ApiConst.TEAM_NAME_MAX_LENGTH).toBeGreaterThan(0);"},{"lineNumber":50,"author":{"gitId":"-"},"content":""},{"lineNumber":51,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.EMAIL_MAX_LENGTH).toEqual(\u0027number\u0027);"},{"lineNumber":52,"author":{"gitId":"-"},"content":" expect(ApiConst.EMAIL_MAX_LENGTH).toBeGreaterThan(0);"},{"lineNumber":53,"author":{"gitId":"-"},"content":""},{"lineNumber":54,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.FEEDBACK_SESSION_NAME_MAX_LENGTH).toEqual(\u0027number\u0027);"},{"lineNumber":55,"author":{"gitId":"-"},"content":" expect(ApiConst.FEEDBACK_SESSION_NAME_MAX_LENGTH).toBeGreaterThan(0);"},{"lineNumber":56,"author":{"gitId":"-"},"content":" });"},{"lineNumber":57,"author":{"gitId":"-"},"content":""},{"lineNumber":58,"author":{"gitId":"-"},"content":" // Here we test that the constants are numbers"},{"lineNumber":59,"author":{"gitId":"-"},"content":" // The exact values are implementation details that do not matter"},{"lineNumber":60,"author":{"gitId":"-"},"content":" it(\u0027should generate numerical constants correctly\u0027, () \u003d\u003e {"},{"lineNumber":61,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.CONTRIBUTION_POINT_NOT_SUBMITTED).toEqual(\u0027number\u0027);"},{"lineNumber":62,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.CONTRIBUTION_POINT_NOT_INITIALIZED).toEqual(\u0027number\u0027);"},{"lineNumber":63,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.CONTRIBUTION_POINT_NOT_SURE).toEqual(\u0027number\u0027);"},{"lineNumber":64,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.CONTRIBUTION_POINT_EQUAL_SHARE).toEqual(\u0027number\u0027);"},{"lineNumber":65,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.NUMERICAL_SCALE_ANSWER_NOT_SUBMITTED).toEqual(\u0027number\u0027);"},{"lineNumber":66,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.RANK_OPTIONS_ANSWER_NOT_SUBMITTED).toEqual(\u0027number\u0027);"},{"lineNumber":67,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.RANK_RECIPIENTS_ANSWER_NOT_SUBMITTED).toEqual(\u0027number\u0027);"},{"lineNumber":68,"author":{"gitId":"-"},"content":" expect(typeof ApiConst.NO_VALUE).toEqual(\u0027number\u0027);"},{"lineNumber":69,"author":{"gitId":"-"},"content":" });"},{"lineNumber":70,"author":{"gitId":"-"},"content":""},{"lineNumber":71,"author":{"gitId":"xenosf"},"content":" // Here we test that the constants are strings"},{"lineNumber":72,"author":{"gitId":"xenosf"},"content":" it(\u0027should generate string constants correctly\u0027, () \u003d\u003e {"},{"lineNumber":73,"author":{"gitId":"xenosf"},"content":" expect(typeof ApiStringConst.EMAIL_REGEX).toEqual(\u0027string\u0027);"},{"lineNumber":74,"author":{"gitId":"xenosf"},"content":" expect(() \u003d\u003e new RegExp(ApiStringConst.EMAIL_REGEX)).not.toThrow();"},{"lineNumber":75,"author":{"gitId":"xenosf"},"content":" });"},{"lineNumber":76,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":77,"author":{"gitId":"-"},"content":" // Here we test that:"},{"lineNumber":78,"author":{"gitId":"-"},"content":" // 1. The string is parseable to JSON"},{"lineNumber":79,"author":{"gitId":"-"},"content":" // 2. The question type is correct"},{"lineNumber":80,"author":{"gitId":"-"},"content":" // 3. There is questionText field"},{"lineNumber":81,"author":{"gitId":"-"},"content":" // They are sufficient to ascertain that the correct structure is generated"},{"lineNumber":82,"author":{"gitId":"-"},"content":" it(\u0027should generate question details correctly\u0027, () \u003d\u003e {"},{"lineNumber":83,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONSTSUM_OPTIONS_QUESTION_DETAILS().questionType).toEqual(FeedbackQuestionType.CONSTSUM_OPTIONS);"},{"lineNumber":84,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONSTSUM_OPTIONS_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":85,"author":{"gitId":"-"},"content":""},{"lineNumber":86,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONSTSUM_RECIPIENTS_QUESTION_DETAILS().questionType)"},{"lineNumber":87,"author":{"gitId":"-"},"content":" .toEqual(FeedbackQuestionType.CONSTSUM_RECIPIENTS);"},{"lineNumber":88,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONSTSUM_RECIPIENTS_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":89,"author":{"gitId":"-"},"content":""},{"lineNumber":90,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONTRIBUTION_QUESTION_DETAILS().questionType).toEqual(FeedbackQuestionType.CONTRIB);"},{"lineNumber":91,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONTRIBUTION_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":92,"author":{"gitId":"-"},"content":""},{"lineNumber":93,"author":{"gitId":"-"},"content":" expect(DEFAULT_MCQ_QUESTION_DETAILS().questionType).toEqual(FeedbackQuestionType.MCQ);"},{"lineNumber":94,"author":{"gitId":"-"},"content":" expect(DEFAULT_MCQ_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":95,"author":{"gitId":"-"},"content":""},{"lineNumber":96,"author":{"gitId":"-"},"content":" expect(DEFAULT_MSQ_QUESTION_DETAILS().questionType).toEqual(FeedbackQuestionType.MSQ);"},{"lineNumber":97,"author":{"gitId":"-"},"content":" expect(DEFAULT_MSQ_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":98,"author":{"gitId":"-"},"content":""},{"lineNumber":99,"author":{"gitId":"-"},"content":" expect(DEFAULT_NUMSCALE_QUESTION_DETAILS().questionType).toEqual(FeedbackQuestionType.NUMSCALE);"},{"lineNumber":100,"author":{"gitId":"-"},"content":" expect(DEFAULT_NUMSCALE_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":101,"author":{"gitId":"-"},"content":""},{"lineNumber":102,"author":{"gitId":"-"},"content":" expect(DEFAULT_RANK_OPTIONS_QUESTION_DETAILS().questionType).toEqual(FeedbackQuestionType.RANK_OPTIONS);"},{"lineNumber":103,"author":{"gitId":"-"},"content":" expect(DEFAULT_RANK_OPTIONS_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":104,"author":{"gitId":"-"},"content":""},{"lineNumber":105,"author":{"gitId":"-"},"content":" expect(DEFAULT_RANK_RECIPIENTS_QUESTION_DETAILS().questionType).toEqual(FeedbackQuestionType.RANK_RECIPIENTS);"},{"lineNumber":106,"author":{"gitId":"-"},"content":" expect(DEFAULT_RANK_RECIPIENTS_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":107,"author":{"gitId":"-"},"content":""},{"lineNumber":108,"author":{"gitId":"-"},"content":" expect(DEFAULT_RUBRIC_QUESTION_DETAILS().questionType).toEqual(FeedbackQuestionType.RUBRIC);"},{"lineNumber":109,"author":{"gitId":"-"},"content":" expect(DEFAULT_RUBRIC_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":110,"author":{"gitId":"-"},"content":""},{"lineNumber":111,"author":{"gitId":"-"},"content":" expect(DEFAULT_TEXT_QUESTION_DETAILS().questionType).toEqual(FeedbackQuestionType.TEXT);"},{"lineNumber":112,"author":{"gitId":"-"},"content":" expect(DEFAULT_TEXT_QUESTION_DETAILS().questionText).toEqual(\u0027\u0027);"},{"lineNumber":113,"author":{"gitId":"-"},"content":" });"},{"lineNumber":114,"author":{"gitId":"-"},"content":""},{"lineNumber":115,"author":{"gitId":"-"},"content":" // Here we test that:"},{"lineNumber":116,"author":{"gitId":"-"},"content":" // 1. The string is parseable to JSON"},{"lineNumber":117,"author":{"gitId":"-"},"content":" // 2. The question type is correct"},{"lineNumber":118,"author":{"gitId":"-"},"content":" // 3. There is either answer or answers field (depending on question type)"},{"lineNumber":119,"author":{"gitId":"-"},"content":" // They are sufficient to ascertain that the correct structure is generated"},{"lineNumber":120,"author":{"gitId":"-"},"content":" it(\u0027should generate response details correctly\u0027, () \u003d\u003e {"},{"lineNumber":121,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONSTSUM_RESPONSE_DETAILS().questionType).toEqual(FeedbackQuestionType.CONSTSUM);"},{"lineNumber":122,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONSTSUM_RESPONSE_DETAILS().answers).toBeTruthy();"},{"lineNumber":123,"author":{"gitId":"-"},"content":""},{"lineNumber":124,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONTRIBUTION_RESPONSE_DETAILS().questionType).toEqual(FeedbackQuestionType.CONTRIB);"},{"lineNumber":125,"author":{"gitId":"-"},"content":" expect(DEFAULT_CONTRIBUTION_RESPONSE_DETAILS().answer).toBeTruthy();"},{"lineNumber":126,"author":{"gitId":"-"},"content":""},{"lineNumber":127,"author":{"gitId":"-"},"content":" expect(DEFAULT_MCQ_RESPONSE_DETAILS().questionType).toEqual(FeedbackQuestionType.MCQ);"},{"lineNumber":128,"author":{"gitId":"-"},"content":" expect(DEFAULT_MCQ_RESPONSE_DETAILS().answer).toEqual(\u0027\u0027);"},{"lineNumber":129,"author":{"gitId":"-"},"content":""},{"lineNumber":130,"author":{"gitId":"-"},"content":" expect(DEFAULT_MSQ_RESPONSE_DETAILS().questionType).toEqual(FeedbackQuestionType.MSQ);"},{"lineNumber":131,"author":{"gitId":"-"},"content":" expect(DEFAULT_MSQ_RESPONSE_DETAILS().answers).toBeTruthy();"},{"lineNumber":132,"author":{"gitId":"-"},"content":""},{"lineNumber":133,"author":{"gitId":"-"},"content":" expect(DEFAULT_NUMSCALE_RESPONSE_DETAILS().questionType).toEqual(FeedbackQuestionType.NUMSCALE);"},{"lineNumber":134,"author":{"gitId":"-"},"content":" expect(DEFAULT_NUMSCALE_RESPONSE_DETAILS().answer).toBeTruthy();"},{"lineNumber":135,"author":{"gitId":"-"},"content":""},{"lineNumber":136,"author":{"gitId":"-"},"content":" expect(DEFAULT_RANK_OPTIONS_RESPONSE_DETAILS().questionType).toEqual(FeedbackQuestionType.RANK_OPTIONS);"},{"lineNumber":137,"author":{"gitId":"-"},"content":" expect(DEFAULT_RANK_OPTIONS_RESPONSE_DETAILS().answers).toBeTruthy();"},{"lineNumber":138,"author":{"gitId":"-"},"content":""},{"lineNumber":139,"author":{"gitId":"-"},"content":" expect(DEFAULT_RANK_RECIPIENTS_RESPONSE_DETAILS().questionType).toEqual(FeedbackQuestionType.RANK_RECIPIENTS);"},{"lineNumber":140,"author":{"gitId":"-"},"content":" expect(DEFAULT_RANK_RECIPIENTS_RESPONSE_DETAILS().answer).toBeTruthy();"},{"lineNumber":141,"author":{"gitId":"-"},"content":""},{"lineNumber":142,"author":{"gitId":"-"},"content":" expect(DEFAULT_RUBRIC_RESPONSE_DETAILS().questionType).toEqual(FeedbackQuestionType.RUBRIC);"},{"lineNumber":143,"author":{"gitId":"-"},"content":" expect(DEFAULT_RUBRIC_RESPONSE_DETAILS().answer).toBeTruthy();"},{"lineNumber":144,"author":{"gitId":"-"},"content":""},{"lineNumber":145,"author":{"gitId":"-"},"content":" expect(DEFAULT_TEXT_RESPONSE_DETAILS().questionType).toEqual(FeedbackQuestionType.TEXT);"},{"lineNumber":146,"author":{"gitId":"-"},"content":" expect(DEFAULT_TEXT_RESPONSE_DETAILS().answer).toEqual(\u0027\u0027);"},{"lineNumber":147,"author":{"gitId":"-"},"content":" });"},{"lineNumber":148,"author":{"gitId":"-"},"content":""},{"lineNumber":149,"author":{"gitId":"-"},"content":" // Here we just test that the string is parseable to JSON and one representative privilege is correct"},{"lineNumber":150,"author":{"gitId":"-"},"content":" it(\u0027should generate instructor privileges correctly\u0027, () \u003d\u003e {"},{"lineNumber":151,"author":{"gitId":"-"},"content":" expect(DEFAULT_INSTRUCTOR_PRIVILEGE()).toBeTruthy();"},{"lineNumber":152,"author":{"gitId":"-"},"content":" expect(DEFAULT_INSTRUCTOR_PRIVILEGE().canModifyCourse).toBeFalsy();"},{"lineNumber":153,"author":{"gitId":"-"},"content":""},{"lineNumber":154,"author":{"gitId":"-"},"content":" expect(DEFAULT_PRIVILEGE_COOWNER()).toBeTruthy();"},{"lineNumber":155,"author":{"gitId":"-"},"content":" expect(DEFAULT_PRIVILEGE_COOWNER().canModifyCourse).toBeTruthy();"},{"lineNumber":156,"author":{"gitId":"-"},"content":""},{"lineNumber":157,"author":{"gitId":"-"},"content":" expect(DEFAULT_PRIVILEGE_MANAGER()).toBeTruthy();"},{"lineNumber":158,"author":{"gitId":"-"},"content":" expect(DEFAULT_PRIVILEGE_MANAGER().canModifyStudent).toBeTruthy();"},{"lineNumber":159,"author":{"gitId":"-"},"content":""},{"lineNumber":160,"author":{"gitId":"-"},"content":" expect(DEFAULT_PRIVILEGE_OBSERVER()).toBeTruthy();"},{"lineNumber":161,"author":{"gitId":"-"},"content":" expect(DEFAULT_PRIVILEGE_OBSERVER().canViewStudentInSections).toBeTruthy();"},{"lineNumber":162,"author":{"gitId":"-"},"content":""},{"lineNumber":163,"author":{"gitId":"-"},"content":" expect(DEFAULT_PRIVILEGE_TUTOR()).toBeTruthy();"},{"lineNumber":164,"author":{"gitId":"-"},"content":" expect(DEFAULT_PRIVILEGE_TUTOR().canSubmitSessionInSections).toBeTruthy();"},{"lineNumber":165,"author":{"gitId":"-"},"content":" });"},{"lineNumber":166,"author":{"gitId":"-"},"content":"});"}],"authorContributionMap":{"xenosf":7,"-":159}},{"path":"src/web/types/form-validator.ts","fileType":"ts","lines":[{"lineNumber":1,"author":{"gitId":"xenosf"},"content":"import { ApiConst, ApiStringConst } from \u0027./api-const\u0027;"},{"lineNumber":2,"author":{"gitId":"-"},"content":""},{"lineNumber":3,"author":{"gitId":"-"},"content":"/**"},{"lineNumber":4,"author":{"gitId":"-"},"content":" * Represents the root FormValidator object of all form fields."},{"lineNumber":5,"author":{"gitId":"-"},"content":" */"},{"lineNumber":6,"author":{"gitId":"-"},"content":"export enum FormValidator {"},{"lineNumber":7,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":8,"author":{"gitId":"-"},"content":" * Max length for the \u0027Course ID\u0027 field."},{"lineNumber":9,"author":{"gitId":"-"},"content":" */"},{"lineNumber":10,"author":{"gitId":"-"},"content":" COURSE_ID_MAX_LENGTH \u003d ApiConst.COURSE_ID_MAX_LENGTH,"},{"lineNumber":11,"author":{"gitId":"-"},"content":""},{"lineNumber":12,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":13,"author":{"gitId":"-"},"content":" * Max length for the \u0027Course Name\u0027 field."},{"lineNumber":14,"author":{"gitId":"-"},"content":" */"},{"lineNumber":15,"author":{"gitId":"-"},"content":" COURSE_NAME_MAX_LENGTH \u003d ApiConst.COURSE_NAME_MAX_LENGTH,"},{"lineNumber":16,"author":{"gitId":"-"},"content":""},{"lineNumber":17,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":18,"author":{"gitId":"-"},"content":" * Max length for the \u0027Student Name` field."},{"lineNumber":19,"author":{"gitId":"-"},"content":" */"},{"lineNumber":20,"author":{"gitId":"-"},"content":" STUDENT_NAME_MAX_LENGTH \u003d ApiConst.STUDENT_NAME_MAX_LENGTH,"},{"lineNumber":21,"author":{"gitId":"-"},"content":""},{"lineNumber":22,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":23,"author":{"gitId":"-"},"content":" * Max length for the \u0027Section Name` field."},{"lineNumber":24,"author":{"gitId":"-"},"content":" */"},{"lineNumber":25,"author":{"gitId":"-"},"content":" SECTION_NAME_MAX_LENGTH \u003d ApiConst.SECTION_NAME_MAX_LENGTH,"},{"lineNumber":26,"author":{"gitId":"-"},"content":""},{"lineNumber":27,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":28,"author":{"gitId":"-"},"content":" * Max length for the \u0027Team Name` field."},{"lineNumber":29,"author":{"gitId":"-"},"content":" */"},{"lineNumber":30,"author":{"gitId":"-"},"content":" TEAM_NAME_MAX_LENGTH \u003d ApiConst.TEAM_NAME_MAX_LENGTH,"},{"lineNumber":31,"author":{"gitId":"-"},"content":""},{"lineNumber":32,"author":{"gitId":"-"},"content":" /**"},{"lineNumber":33,"author":{"gitId":"-"},"content":" * Max length for the \u0027E-mail Address` field."},{"lineNumber":34,"author":{"gitId":"-"},"content":" */"},{"lineNumber":35,"author":{"gitId":"-"},"content":" EMAIL_MAX_LENGTH \u003d ApiConst.EMAIL_MAX_LENGTH,"},{"lineNumber":36,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":37,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":38,"author":{"gitId":"xenosf"},"content":" * Regex used to verify emails in the back-end."},{"lineNumber":39,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":40,"author":{"gitId":"xenosf"},"content":" EMAIL_REGEX \u003d ApiStringConst.EMAIL_REGEX,"},{"lineNumber":41,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":42,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":43,"author":{"gitId":"xenosf"},"content":" * Regex used to verify names."},{"lineNumber":44,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":45,"author":{"gitId":"xenosf"},"content":" * Based on back-end\u0027s `FieldValidator.REGEX_NAME`."},{"lineNumber":46,"author":{"gitId":"xenosf"},"content":" * The back-end regex is not converted to use here as the pattern syntax is not accepted in JS."},{"lineNumber":47,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":48,"author":{"gitId":"xenosf"},"content":" NAME_REGEX \u003d \u0027^[a-zA-Z0-9][^|%]*$\u0027,"},{"lineNumber":49,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":50,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":51,"author":{"gitId":"xenosf"},"content":" * Regex used to verify country names."},{"lineNumber":52,"author":{"gitId":"xenosf"},"content":" *"},{"lineNumber":53,"author":{"gitId":"xenosf"},"content":" * Based on back-end\u0027s `FieldValidator.REGEX_NAME`, but without needing to start with alphanumeric"},{"lineNumber":54,"author":{"gitId":"xenosf"},"content":" * as the country is added to the end of the combined institute string."},{"lineNumber":55,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":56,"author":{"gitId":"xenosf"},"content":" COUNTRY_REGEX \u003d \u0027^[^|%]*$\u0027,"},{"lineNumber":57,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":58,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":59,"author":{"gitId":"xenosf"},"content":" * Max length for institution name in account request. (to be combined with country)"},{"lineNumber":60,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":61,"author":{"gitId":"xenosf"},"content":" INSTITUTION_NAME_MAX_LENGTH \u003d 86,"},{"lineNumber":62,"author":{"gitId":"xenosf"},"content":""},{"lineNumber":63,"author":{"gitId":"xenosf"},"content":" /**"},{"lineNumber":64,"author":{"gitId":"xenosf"},"content":" * Max length for country in account request. (to be combined with institution name)"},{"lineNumber":65,"author":{"gitId":"xenosf"},"content":" */"},{"lineNumber":66,"author":{"gitId":"xenosf"},"content":" COUNTRY_NAME_MAX_LENGTH \u003d 40,"},{"lineNumber":67,"author":{"gitId":"-"},"content":"}"}],"authorContributionMap":{"xenosf":32,"-":35}}] diff --git a/TEAMMATES_teammates_master/commits.json b/TEAMMATES_teammates_master/commits.json index 1f967aa..4d304ca 100644 --- a/TEAMMATES_teammates_master/commits.json +++ b/TEAMMATES_teammates_master/commits.json @@ -1 +1 @@ -{"authorDailyContributionsMap":{"xenosf":[{"date":"2024-02-15","commitResults":[{"hash":"3c0126ef4feeda7cedcd8f098ee953f916856d70","isMergeCommit":false,"messageTitle":"[#12048] Migrate StudentSearchIndexingWorkerAction (#12733)","messageBody":"* Migrate StudentSearchIndexingWorkerAction\r\n\r\n* Add IT for StudentSearchIndexingWorkerAction\r\n\r\n* Fix javadoc for putStudentDocument\r\n\r\n* Refactor SQL logic and Datastore execute logic to separate methods\r\n\r\n* Fix checkstyle errors\r\n\r\n* Reset student search collections before test\r\n\r\n* Rename test methods to use \"should\"","fileTypesAndContributionMap":{"java":{"insertions":116,"deletions":0}}}]},{"date":"2024-02-27","commitResults":[{"hash":"2dad48b8d3bf32fb337f3021bcf7a9021f15a656","isMergeCommit":false,"messageTitle":"[#12048] Migrate GetSessionResultsAction (#12719)","messageBody":"* Migrate SessionResultsData\r\n\r\n* Add default entities\r\n\r\n* Add helper methods to assist migrated logic\r\n\r\n* Migrate buildCompleteGiverRecipientMap\r\n\r\n* Migrate checkSpecificAccessControl\r\n\r\n* Add default team instance for instructor\r\n\r\n* Migrate session results data logic\r\n\r\n* Use default team entity for instructor instead of const\r\n\r\n* Migrate non-db logic\r\n\r\n* Refactor Datastore and SQL action logic out to separate methods\r\n\r\n* Fix checkstyle errors\r\n\r\n* Migrate DB logic\r\n\r\n* Fix checkstyle errors\r\n\r\n* Move default instructor team entity to const\r\n\r\n* Add test for SqlSessionResultsBundle\r\n\r\n* Fix SQL results bundle test\r\n\r\n* Add IT for GetSessionResultsAction\r\n\r\n* Fix action logic\r\n\r\n* Fix checkstyle errors\r\n\r\n* Remove unused method parameters\r\n\r\n* Fix persistence issues in test cases\r\n\r\n* Remove question getter for comment\r\n\r\n* Rename boolean methods to start with verb\r\n\r\n* Reword comment to clarify question ID\r\n\r\n* Refactor getting question UUID from param value\r\n\r\n* Remove unneeded getters\r\n\r\n* Remove entities from Const\r\n\r\n* Revert changes to SqlCourseRoster\r\n\r\n* Create and use missing response class\r\n\r\n* Refactor no response text to const\r\n\r\n* Migrate preview-related functionality\r\n\r\n* Migrate preview functionality for question output\r\n\r\n* Fix recipient section filter\r\n\r\n* Update test cases to handle question preview\r\n\r\n* Merge duplicate methods\r\n\r\n* Fix checkstyle errors\r\n\r\n* Add missing questions with non-visible preview responses\r\n\r\n* Remove outdated test\r\n\r\n* Edit for style and readability\r\n\r\n* Fix missing join\r\n\r\n* Fix section filtering logic\r\n\r\n* Fix checkstyle errors","fileTypesAndContributionMap":{"java":{"insertions":2563,"deletions":23}}}]},{"date":"2024-03-13","commitResults":[{"hash":"b8023350e370623921776a3cdc18776f65d1c3f6","isMergeCommit":false,"messageTitle":"[#12048] Add integration tests for FeedbackResponseCommentsDb (#12849)","messageBody":"* Migrate SessionResultsData\r\n\r\n* Add default entities\r\n\r\n* Add helper methods to assist migrated logic\r\n\r\n* Migrate buildCompleteGiverRecipientMap\r\n\r\n* Migrate checkSpecificAccessControl\r\n\r\n* Add default team instance for instructor\r\n\r\n* Migrate session results data logic\r\n\r\n* Use default team entity for instructor instead of const\r\n\r\n* Migrate non-db logic\r\n\r\n* Refactor Datastore and SQL action logic out to separate methods\r\n\r\n* Fix checkstyle errors\r\n\r\n* Migrate DB logic\r\n\r\n* Fix checkstyle errors\r\n\r\n* Move default instructor team entity to const\r\n\r\n* Add test for SqlSessionResultsBundle\r\n\r\n* Fix SQL results bundle test\r\n\r\n* Add IT for GetSessionResultsAction\r\n\r\n* Fix action logic\r\n\r\n* Fix checkstyle errors\r\n\r\n* Remove unused method parameters\r\n\r\n* Fix persistence issues in test cases\r\n\r\n* Remove question getter for comment\r\n\r\n* Rename boolean methods to start with verb\r\n\r\n* Reword comment to clarify question ID\r\n\r\n* Refactor getting question UUID from param value\r\n\r\n* Remove unneeded getters\r\n\r\n* Remove entities from Const\r\n\r\n* Revert changes to SqlCourseRoster\r\n\r\n* Create and use missing response class\r\n\r\n* Refactor no response text to const\r\n\r\n* Migrate preview-related functionality\r\n\r\n* Migrate preview functionality for question output\r\n\r\n* Fix recipient section filter\r\n\r\n* Update test cases to handle question preview\r\n\r\n* Merge duplicate methods\r\n\r\n* Fix checkstyle errors\r\n\r\n* Add missing questions with non-visible preview responses\r\n\r\n* Remove outdated test\r\n\r\n* Edit for style and readability\r\n\r\n* Fix missing join\r\n\r\n* Fix section filtering logic\r\n\r\n* Fix checkstyle errors\r\n\r\n* Add integration tests\r\n\r\n* Refactor tests for readability\r\n\r\n* Fix broken test cases\r\n\r\n* Rename test section key\r\n\r\n* Use separate json bundle for test data\r\n\r\n* Clear session when set up\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":202,"deletions":8}}}]},{"date":"2024-03-14","commitResults":[{"hash":"931dea4d8747bfec25bd10309e2b722a743a6b7e","isMergeCommit":false,"messageTitle":"[#12048] Add integration tests for FeedbackResponsesDb (#12856)","messageBody":"* Migrate SessionResultsData\r\n\r\n* Add default entities\r\n\r\n* Add helper methods to assist migrated logic\r\n\r\n* Migrate buildCompleteGiverRecipientMap\r\n\r\n* Migrate checkSpecificAccessControl\r\n\r\n* Add default team instance for instructor\r\n\r\n* Migrate session results data logic\r\n\r\n* Use default team entity for instructor instead of const\r\n\r\n* Migrate non-db logic\r\n\r\n* Refactor Datastore and SQL action logic out to separate methods\r\n\r\n* Fix checkstyle errors\r\n\r\n* Migrate DB logic\r\n\r\n* Fix checkstyle errors\r\n\r\n* Move default instructor team entity to const\r\n\r\n* Add test for SqlSessionResultsBundle\r\n\r\n* Fix SQL results bundle test\r\n\r\n* Add IT for GetSessionResultsAction\r\n\r\n* Fix action logic\r\n\r\n* Fix checkstyle errors\r\n\r\n* Remove unused method parameters\r\n\r\n* Fix persistence issues in test cases\r\n\r\n* Remove question getter for comment\r\n\r\n* Rename boolean methods to start with verb\r\n\r\n* Reword comment to clarify question ID\r\n\r\n* Refactor getting question UUID from param value\r\n\r\n* Remove unneeded getters\r\n\r\n* Remove entities from Const\r\n\r\n* Revert changes to SqlCourseRoster\r\n\r\n* Create and use missing response class\r\n\r\n* Refactor no response text to const\r\n\r\n* Migrate preview-related functionality\r\n\r\n* Migrate preview functionality for question output\r\n\r\n* Fix recipient section filter\r\n\r\n* Update test cases to handle question preview\r\n\r\n* Merge duplicate methods\r\n\r\n* Fix checkstyle errors\r\n\r\n* Add missing questions with non-visible preview responses\r\n\r\n* Remove outdated test\r\n\r\n* Edit for style and readability\r\n\r\n* Fix missing join\r\n\r\n* Fix section filtering logic\r\n\r\n* Fix checkstyle errors\r\n\r\n* Add integration tests\r\n\r\n* Update and use typical bundle\r\n\r\n* Update test cases for updated bundle\r\n\r\n* Revert typical data bundle\r\n\r\n* Use separate data bundle for feedback responses test\r\n\r\n* Revert unrelated tests\r\n\r\n* Fix json formatting\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":215,"deletions":19}}}]},{"date":"2024-03-27","commitResults":[{"hash":"f7eaa617f1e129a828bc4eb5b3f2776629ef9a3f","isMergeCommit":false,"messageTitle":"[#11878] Upgrade instructor request form UI (#12929)","messageBody":"* Add confirmation prompt\r\n\r\n* Remove old form iframe\r\n\r\n* Improve declaration view spacing\r\n\r\n* Edit page heading phrasing for clarity\r\n\r\n* Create request form\r\n\r\n* Add validation messages\r\n\r\n* Fix form validation\r\n\r\n* Set up form submission confirmation\r\n\r\n* Create submission acknowledgement view\r\n\r\n* Fix URL checking regex\r\n\r\n* Fix initial state\r\n\r\n* Display placeholder when optional field is empty\r\n\r\n* Fix code style\r\n\r\n* Edit comment for clarity\r\n\r\n* Fix institution and country combination\r\n\r\nCo-authored-by: Jay Aljelo Ting \u003c65202977+jayasting98@users.noreply.github.com\u003e\r\n\r\n* Fix naming\r\n\r\n* Remove hard line break\r\n\r\n* Add explanatory comment for regex\r\n\r\n* Remove newline\r\n\r\n* Add newlines at end of file\r\n\r\n* Clear styles file\r\n\r\n* Re-add styles file\r\n\r\n* Include test\r\n\r\n* Add test cases for requestSubmissionEvent\r\n\r\n* Improve test case readability\r\n\r\n* Edit test case name for clarity\r\n\r\n* Add snapshot tests\r\n\r\n* Revert \"Add snapshot tests\"\r\n\r\nThis reverts commit ec7395d4e8bd0d956f3c355b9906ec0ab3ae0f58.\r\n\r\n* Fix lint errors\r\n\r\n* Rename methods to be clearer\r\n\r\n* Disable submit button when not ready to submit\r\n\r\n---------\r\n\r\nCo-authored-by: Jay Aljelo Ting \u003c65202977+jayasting98@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"scss":{"insertions":27,"deletions":0},"html":{"insertions":155,"deletions":11},"ts":{"insertions":198,"deletions":0}}}]},{"date":"2024-03-29","commitResults":[{"hash":"f6329eb10233e07143153782451605524216c901","isMergeCommit":false,"messageTitle":"[#11878] Add snapshot tests for instructor request form UI (#12942)","messageBody":"* Add snapshot tests\r\n\r\n* Change double quotes to single quotes","fileTypesAndContributionMap":{"ts":{"insertions":31,"deletions":0}}}]},{"date":"2024-03-30","commitResults":[{"hash":"00b85cec55172709a112a6519ff11316b448f79e","isMergeCommit":false,"messageTitle":"[#11878] Create instructor request acknowledgement email (#12944)","messageBody":"* Create instructor request acknowledgement email\r\n\r\n* Add tests for acknowledgement email\r\n\r\n* Fix test cases\r\n\r\n* Fix comments in expected email\r\n\r\n* Use config support email value in email template\r\n\r\n* Fix email recipient\r\n\r\n* Fix test expected emails\r\n\r\n* Remove trailing space\r\n\r\n* Use placeholder for support email\r\n\r\n* Sanitize acknowledgement email\r\n\r\n* Set acknowledgement email to bcc support","fileTypesAndContributionMap":{"java":{"insertions":80,"deletions":3},"html":{"insertions":195,"deletions":0}}}]},{"date":"2024-04-02","commitResults":[{"hash":"7ec74c76f1feb2c2528ac061e88332e166994316","isMergeCommit":false,"messageTitle":"[#11878] Change institute length limit (#12974)","messageBody":"* Change institute name max length to 128\r\n\r\n* Edit test case for new length limit","fileTypesAndContributionMap":{"java":{"insertions":6,"deletions":5}}}]},{"date":"2024-04-04","commitResults":[{"hash":"de3181a347f241d23d34dad524a2542231a03e1f","isMergeCommit":false,"messageTitle":"[#11878] Integrate instructor request form with API (#12943)","messageBody":"* Integrate instructor request form FE with API\r\n\r\n* Remove redundant statement\r\n\r\n* Move URL regex const to backend const file\r\n\r\n* Fix import path\r\n\r\n* Move URL regex to FieldValidator\r\n\r\n* Add validators to match backend fields\r\n\r\n* Add error message box\r\n\r\n* Change submit button display when loading\r\n\r\n* Combine final action into subscribe\r\n\r\n* Add max length validators for institution and country\r\n\r\n* Fix lint errors\r\n\r\n* Add test cases to test submission\r\n\r\n* Add specific error messages for form validation\r\n\r\n* Remove home page URL field\r\n\r\n* Fix lint errors\r\n\r\n* Remove url regex from test\r\n\r\n* Update snap\r\n\r\n* Clean up test code\r\n\r\n* Remove comment about home page URL\r\n\r\n* Change canSubmit check to getter\r\n\r\n* Fix form submit button not re-enabling on error\r\n\r\n* Add name pattern validator to front-end\r\n\r\n* Fix snapshot","fileTypesAndContributionMap":{"java":{"insertions":40,"deletions":0},"scss":{"insertions":4,"deletions":0},"html":{"insertions":48,"deletions":30},"ts":{"insertions":153,"deletions":53}}}]},{"date":"2024-04-09","commitResults":[{"hash":"1e9ccb091fac81793a93c460e017c076b797c66b","isMergeCommit":false,"messageTitle":"[#12048] Migrate AccountRequestsLogicTest (#12780)","messageBody":"* Migrate test cases for AccountRequestsLogic\r\n\r\n* Remove test case\r\n\r\n* Split test cases","fileTypesAndContributionMap":{"java":{"insertions":182,"deletions":0}}},{"hash":"fb0ba194ba1759bc5ce1da0f23ec467bdfed36fe","isMergeCommit":false,"messageTitle":"[#11878] Create reject account request endpoint (#12985)","messageBody":"* Create account request rejection endpoint\r\n\r\n* Add validation\r\n\r\n* Add check for already rejected request when sending email\r\n\r\n* Add integration test cases\r\n\r\n* Set request method to post\r\n\r\n* Fix lint errors\r\n\r\n* Update tests list\r\n\r\n* Update validation check\r\n\r\n* Add test for validation\r\n\r\n* Fix lint errors\r\n\r\n* Fix validation comparison\r\n\r\n* Fix error message test\r\n\r\n* Add email sending\r\n\r\n* Update test cases\r\n\r\n* Refactor reason check code for clarity","fileTypesAndContributionMap":{"java":{"insertions":371,"deletions":3}}}]},{"date":"2024-04-15","commitResults":[{"hash":"bb261f4fdaff9efad9048da9dae71578a11cf09a","isMergeCommit":false,"messageTitle":"[#11878] Remove mention of home page URL from confirmation email (#13030)","messageBody":"","fileTypesAndContributionMap":{"html":{"insertions":3,"deletions":3}}}]},{"date":"2024-04-16","commitResults":[{"hash":"665752c8ff7379ebef441b427093fcbefd8bb561","isMergeCommit":false,"messageTitle":"[#11878] Check if account request is not created by admin before sending email (#13032)","messageBody":"* Add check if admin when creating account request\r\n\r\n* Trim down test case","fileTypesAndContributionMap":{"java":{"insertions":25,"deletions":5}}}]},{"date":"2024-04-17","commitResults":[{"hash":"ab22022dc4511f3f522931c2ab1324de5dbebea9","isMergeCommit":false,"messageTitle":"[#11878] Migrate AccountRequestsLogic unit tests (#13043)","messageBody":"* Add get typical account request method\r\n\r\n* Migrate AccountRequestsLogicTest\r\n\r\n* Remove test for get by email address and institute\r\n\r\n---------\r\n\r\nCo-authored-by: Jay Aljelo Ting \u003c65202977+jayasting98@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":139,"deletions":1}}}]},{"date":"2024-04-18","commitResults":[{"hash":"2cc6ef82fc92e2bc742c39b6c5b337330faf5e62","isMergeCommit":false,"messageTitle":"[#11878] Add SQLI tests (#13047)","messageBody":"","fileTypesAndContributionMap":{"java":{"insertions":31,"deletions":0}}}]}],"sopa301":[],"mingyuanc":[{"date":"2024-02-07","commitResults":[{"hash":"cc0bf4f77bc293c689f5e721d16aae14f150e152","isMergeCommit":false,"messageTitle":"[#12048] Migrate CreateInstructorAction (#12706)","messageBody":"","fileTypesAndContributionMap":{"java":{"insertions":257,"deletions":37}}}]},{"date":"2024-02-18","commitResults":[{"hash":"8e757e2125448b07dbc7e46d94e8967c9925da4c","isMergeCommit":false,"messageTitle":"[#12048] Migrate instructor search indexing worker action (#12731)","messageBody":"* Fix lint\r\n\r\n* Migrate instructor search indexing worker action\r\n\r\n* Fix Checkstyle\r\n\r\n* Fix Checkstyle\r\n\r\n* Fix Checkstyle\r\n\r\n* Add testcases\r\n\r\n* Update comparator to Id\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e\r\nCo-authored-by: Nicolas \u003c25302138+NicolasCwy@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":107,"deletions":0}}}]},{"date":"2024-02-19","commitResults":[{"hash":"d6c67fc9dd31c36f196be454a22cce955e1c8229","isMergeCommit":false,"messageTitle":"Add testcases for FeedbackResponseCommentsDbTest (#12755)","messageBody":"* Add CRUD testcases\r\n\r\n* Fix linting\r\n\r\n* Refactor getTypicalComment\r\n\r\n* Amend testDeleteComment testcase\r\n\r\n* Amend testDeleteComment testcase\r\n\r\n* Fix compile error\r\n\r\n* Revert linting changes\r\n\r\n---------\r\n\r\nCo-authored-by: Nicolas \u003c25302138+NicolasCwy@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":156,"deletions":1}}}]},{"date":"2024-03-09","commitResults":[{"hash":"ef31826b7ec1e1308c0e6016ba513e9c6afa3c58","isMergeCommit":false,"messageTitle":"Add testcases for FeedbackResponseCommentsLogicTest (#12769)","messageBody":"* Added testcase\r\n\r\n* Add new testcases\r\n\r\n* Remove dead store\r\n\r\n---------\r\n\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":185,"deletions":0}}}]},{"date":"2024-03-27","commitResults":[{"hash":"0cfadeffbb74c112f2705ade1be7c6b0cf61d51f","isMergeCommit":false,"messageTitle":"[#12048] Migrate Feedback Rank Option E2E test (#12902)","messageBody":"* Initial commit\r\n\r\n* Fix lint\r\n\r\n* Follow convention and add test\r\n\r\n* Change file path\r\n\r\n* Fix requested changes\r\n\r\n* Fixed testcases\r\n\r\n* Fix lint\r\n\r\n* Add deepcopy\r\n\r\n* Fixed e2e test\r\n\r\n---------\r\n\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":154,"deletions":4}}}]},{"date":"2024-04-15","commitResults":[{"hash":"98d9044d7e95ecdaf31f2191f76fa0254ace4f40","isMergeCommit":false,"messageTitle":"Initial commit (#13024)","messageBody":"","fileTypesAndContributionMap":{"java":{"insertions":2,"deletions":2}}}]},{"date":"2024-04-17","commitResults":[{"hash":"f8522866c39bc7d7208f1e3443061b408ef4af9e","isMergeCommit":false,"messageTitle":"[#12048] Fix getSessionResultAction bugs (#13023)","messageBody":"* [#12048] Config prod settings and convenience scripts for non course migration (#12959)\r\n\r\n* Add fields\r\n\r\n* Change based on feedback\r\n\r\n* Add changes\r\n\r\n* Add reverse data migration script for account (#12962)\r\n\r\n* Add changes (#12965)\r\n\r\n* V9 non course migration fix to check extra SQL accounts (#12966)\r\n\r\n* Add changes\r\n\r\n* Add isMarked script\r\n\r\n* Add patch data migration script for usage stats (#12970)\r\n\r\n* Add patch data migration script for usage stats\r\n\r\n* Fix hibernate batch query\r\n\r\n* Revert log\r\n\r\n* Initial commit\r\n\r\n* Revert \"[#12048] Config prod settings and convenience scripts for non course migration (#12959)\"\r\n\r\nThis reverts commit 6df39c19108de833624992c56e09f75960ff65c1.\r\n\r\n* Revert \"Add reverse data migration script for account (#12962)\"\r\n\r\nThis reverts commit 05099825679c31ace2872860a358288ec0bdacc3.\r\n\r\n* Revert \"V9 non course migration fix to check extra SQL accounts (#12966)\"\r\n\r\nThis reverts commit 611b2cc3682b11e75c3631a8843aa030e8a34b9d.\r\n\r\n* Revert \"Add patch data migration script for usage stats (#12970)\"\r\n\r\nThis reverts commit 239ae85a5bd2d40ea4464b6e47a626f76913a6e1.\r\n\r\n* Revert \"Add changes (#12965)\"\r\n\r\nThis reverts commit 1292dbe995e50b9c3fe1bf5ec377e92f6f751ec2.\r\n\r\n* Fix lint\r\n\r\n* Retry lint\r\n\r\n---------\r\n\r\nCo-authored-by: FergusMok \u003cFergusMok1@gmail.com\u003e\r\nCo-authored-by: Zhang Ziqing \u003c69516975+ziqing26@users.noreply.github.com\u003e\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":33,"deletions":5}}}]}],"jingting1412":[{"date":"2024-03-16","commitResults":[{"hash":"2d1080682a62f32981cb4b0edd497f0928bcd83b","isMergeCommit":false,"messageTitle":"[#12271] Docs: Upgrade to latest MarkBind version (#12893)","messageBody":"* Upgrade layouts\r\n\r\n* Add breadcrumb for pages\r\n\r\n* Fix puml diagrams\r\n\r\n* Make navbar sticky\r\n\r\n* Upgrade markbind version\r\n\r\n* Upgrade markbind\r\n\r\n* Upgrade markbind version\r\n\r\n* Update pages\r\n\r\n* Revert \"Upgrade markbind version\"\r\n\r\nThis reverts commit 76b2d44f3bc57d5bfdf03fdb2c01cb92a186105f.\r\n\r\n---------\r\n\r\nCo-authored-by: Zhang Ziqing \u003c69516975+ziqing26@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"md":{"insertions":43,"deletions":44}}}]}],"KevinEyo1":[],"LamJiuFong":[],"yiwen101":[],"jonasongg":[],"domoberzin":[{"date":"2024-02-04","commitResults":[{"hash":"333f582460d9b1ba7174321de3ea3113cc71c9db","isMergeCommit":false,"messageTitle":"[#12048] Migrate enroll students action (#12715)","messageBody":"* Modify student entity\r\n\r\n* Add update comment logic\r\n\r\n* Modify logic files for cascading update and creation for student\r\n\r\n* Add database queries for updating student\r\n\r\n* Update EnrollStudentsAction\r\n\r\n* Fix checkstyle\r\n\r\n* Remove extra query for editor update\r\n\r\n* Remove email update logic\r\n\r\n* Update javadocs\r\n\r\n* Copy over logic for Team and Section validation\r\n\r\n* Edit javadocs\r\n\r\n* Change StudentAttributes to Student instead\r\n\r\n* Fix lint issues\r\n\r\n* Fix lint issues\r\n\r\n* Fix component tests and lint\r\n\r\n* Remove ununsed method\r\n\r\n* Fix lint\r\n\r\n* Update validation logic to use Student\r\n\r\n* Update test case\r\n\r\n* Add tests for duplicate team across sections\r\n\r\n* Remove unused methods and add getSection to UsersLogic\r\n\r\n* Fix sorting logic\r\n\r\n* Change getName method calls for section and team\r\n\r\n* Remove unused methods\r\n\r\n* Add more detail to JavaDocs\r\n\r\n* Remove unusued methods\r\n\r\n* Use getCourseId instead of toString\r\n\r\n* Modify test case\r\n\r\n* Revert changes\r\n\r\n* Change toString to getCourseId\r\n\r\n* Update tests to include unregistered student\r\n\r\n* Fix trailing whitespaces","fileTypesAndContributionMap":{"java":{"insertions":875,"deletions":66}}}]},{"date":"2024-02-10","commitResults":[{"hash":"21ae95eab736f4c37933d3fa0fd9bd592c6b92d6","isMergeCommit":false,"messageTitle":"[#12048] Migrate search account requests action (#12726)","messageBody":"* feat: add search account request methods to SQL storage and logic layers\r\n\r\n* feat: migrate SearchAccountRequestsAction to use SQL logic\r\n\r\n* fix: failing tests\r\n\r\n* fix: remove commented line\r\n\r\n* fix: migrate AccountRequestSearch tests\r\n\r\n---------\r\n\r\nCo-authored-by: Dominic Lim \u003c46486515+domlimm@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":347,"deletions":5}}}]},{"date":"2024-02-18","commitResults":[{"hash":"c314aa9f3462f76ac3a3e8d15e58289181b31573","isMergeCommit":false,"messageTitle":"[#12048] Add tests for CoursesLogic (#12746)","messageBody":"* feat: add tests for CoursesLogic\r\n\r\n* fix: verify parameters of mocked logic classes\r\n\r\n* fix: lint issues\r\n\r\n* fix: add additional verification of parameters\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":319,"deletions":2}}}]},{"date":"2024-02-20","commitResults":[{"hash":"daba8ebd1ead324ae4e4b2daba64d2586538a9f5","isMergeCommit":false,"messageTitle":"[#12048] Migrate AccountRequestSearchIndexingWorkerAction (#12757)","messageBody":"* feat: migrate account request search indexing worker action\r\n\r\n* fix: remove datastore logic and old test\r\n\r\n* fix: remove NPE suppress","fileTypesAndContributionMap":{"java":{"insertions":38,"deletions":13}}}]},{"date":"2024-02-24","commitResults":[{"hash":"7a22ab856fb641e0d7897a00e45ed3c5024ab766","isMergeCommit":false,"messageTitle":"[#12048] Fix GetSessionResponseStatsActionIT (#12777)","messageBody":"* Migrate GetSessionResponseStatsAction\r\n\r\n* fix: fix NPE issues\r\n\r\n* fix: remove extra comments\r\n\r\n* fix: remove extra line\r\n\r\n---------\r\n\r\nCo-authored-by: Zhang Ziqing \u003czhangziqing9926@gmail.com\u003e\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e\r\nCo-authored-by: Zhang Ziqing \u003c69516975+ziqing26@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":218,"deletions":15}}},{"hash":"7da77bb9ba38925e675b94d64dc6bff2d7d5bcc1","isMergeCommit":false,"messageTitle":"[#12048] Create IT for GetFeedbackSessionSubmittedGiverSetAction (#12778)","messageBody":"* Migrate GetSessionResponseStatsAction\r\n\r\n* fix: fix NPE issues\r\n\r\n* feat: add IT for GetFeedbackSessionSubmittedGiverSetAction\r\n\r\n* fix: remove extra comment\r\n\r\n* fix: remove duplicate method\r\n\r\n---------\r\n\r\nCo-authored-by: Zhang Ziqing \u003czhangziqing9926@gmail.com\u003e\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e\r\nCo-authored-by: Zhang Ziqing \u003c69516975+ziqing26@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":81,"deletions":3}}}]},{"date":"2024-02-26","commitResults":[{"hash":"500e7421dc31bd884ba6d2ff7a01b6abcabf646b","isMergeCommit":false,"messageTitle":"[#12048] Migrate Admin Notifications E2E Test (#12793)","messageBody":"* feat: add resources for admin notifications e2e test\r\n\r\n* fix: set created at on notification creation\r\n\r\n* feat: migrate admin notifications e2e test\r\n\r\n* fix: remove created at check for notifications\r\n\r\n* fix: remove extra comments\r\n\r\n* fix: remove explicit created at\r\n\r\n* fix: null check for created at\r\n\r\n* fix lint\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e\r\nCo-authored-by: Cedric Ong \u003ccedricongjh@gmail.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":47,"deletions":34}}},{"hash":"203ec245f53c97be136208df3f583bfd6db97f8c","isMergeCommit":false,"messageTitle":"[#12048] Migrate AdminSearchPageE2ETest (#12838)","messageBody":"* migate admin search e2e\r\n\r\n* fix e2e test\r\n\r\n* fix failing tests\r\n\r\n* fix: add put sql document methods\r\n\r\n* fix: add migrated check back in\r\n\r\n* fix: add cleanup method\r\n\r\n* fix: add search document removal for account request\r\n\r\n* fix lint and tests\r\n\r\n* fix: json file formatting\r\n\r\n* fix: init both searchManagers\r\n\r\n* fix: add comments\r\n\r\n* fix: remove notifications field in data file\r\n\r\n---------\r\n\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":201,"deletions":45}}}]},{"date":"2024-03-03","commitResults":[{"hash":"0f9d99069cca05ac16878b0f5e0fa78bf629d96d","isMergeCommit":false,"messageTitle":"[#12048] Add tests for CourseDbIT (#12786)","messageBody":"* feat: add more coverage for methods in CoursesDb\r\n\r\n* fix: add further test cases\r\n\r\n---------\r\n\r\nCo-authored-by: Dominic Lim \u003c46486515+domlimm@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":165,"deletions":4}}}]},{"date":"2024-03-13","commitResults":[{"hash":"ccdb6ccf64330e83bff24d7b93e15f2081c30398","isMergeCommit":false,"messageTitle":"[#12048] Migrate InstructorSearchPageE2ETest (#12891)","messageBody":"* feat: migrate instructor search page e2e test\r\n\r\n* fix: add new line\r\n\r\n* fix axe test\r\n\r\n* remove extra whitespace","fileTypesAndContributionMap":{"java":{"insertions":5,"deletions":3}}}]},{"date":"2024-03-27","commitResults":[{"hash":"40613dff7486e2224c1375a218f55f442279a4e9","isMergeCommit":false,"messageTitle":"[#11878] Update Admin Home Page UI for ARF (#12933)","messageBody":"* create component for account request table\r\n\r\n* cherry pick admin home page changes\r\n\r\n* remove testing code\r\n\r\n* fix lint and css issues\r\n\r\n* fix admin home page snaps\r\n\r\n* update admin home snaps\r\n\r\n* remove edit approve and reject components\r\n\r\n* modify css\r\n\r\n* delete edit and reject modal components\r\n\r\n* revert spec file changes\r\n\r\n* integrate new types\r\n\r\n* fix lint\r\n\r\n* use enum for status\r\n\r\n* fix lint\r\n\r\n* fix css lint\r\n\r\n* fix lint\r\n\r\n* fix lint\r\n\r\n* use enum and remove infinite scroll\r\n\r\n* remove approve account request code\r\n\r\n* remove extra div\r\n\r\n* fix url\r\n\r\n* modify comments\r\n\r\n* revert extra formatting\r\n\r\n* remove plural form and use date pipe\r\n\r\n* fix naming\r\n\r\n* fix spec file and update institute formatting\r\n\r\n* fix lint\r\n\r\n* combine institute and country columns","fileTypesAndContributionMap":{"scss":{"insertions":63,"deletions":0},"html":{"insertions":84,"deletions":0},"ts":{"insertions":243,"deletions":9}}}]},{"date":"2024-03-28","commitResults":[{"hash":"561837052d6810ac904eb5cd34454e0cb98fa530","isMergeCommit":false,"messageTitle":"[#11878] Admin Search UI Update for ARF (#12945)","messageBody":"* update admin search page to use acc req component\r\n\r\n* fix selector for e2e test\r\n\r\n* fix spec files and imports\r\n\r\n* update e2e selector\r\n\r\n* fix column numbers","fileTypesAndContributionMap":{"java":{"insertions":5,"deletions":5},"html":{"insertions":2,"deletions":64},"ts":{"insertions":43,"deletions":78}}}]},{"date":"2024-04-05","commitResults":[{"hash":"5779d2f365abad11ed259714c8422bc66f82db1e","isMergeCommit":false,"messageTitle":"[#11878] Create Update Account Request Action (#12982)","messageBody":"* create update action and IT\r\n\r\n* update javadocs\r\n\r\n* update tests\r\n\r\n* add more tests\r\n\r\n* simplify logic\r\n\r\n* remove unused string\r\n\r\n* fix test\r\n\r\n* allow null comments\r\n\r\n* add more tests\r\n\r\n* use EntityNotFoundException\r\n\r\n* cleanup after create account requests test\r\n\r\n* remove unncessary check","fileTypesAndContributionMap":{"java":{"insertions":378,"deletions":0}}}]},{"date":"2024-04-06","commitResults":[{"hash":"4a54001bac3824cc8ac2fb66324d7061151f4504","isMergeCommit":false,"messageTitle":"[#11878] Fix Account Request Update Search Indexing (#12984)","messageBody":"* update account request indexing\r\n\r\n* add methods to test access control\r\n\r\n* refactoring for transactions","fileTypesAndContributionMap":{"java":{"insertions":259,"deletions":28}}}]},{"date":"2024-04-07","commitResults":[{"hash":"62750b08b4ea5169b7098e5071f1d58153152970","isMergeCommit":false,"messageTitle":"[#11878] Add Edit and Approve Account Requests functionality (#12975)","messageBody":"* add edit and approve functionality\r\n\r\n* remove rejection code\r\n\r\n* fix snap\r\n\r\n* integrate endpoint\r\n\r\n* disable approve button for approved requests\r\n\r\n* use comments instead of comment\r\n\r\n* use searchString instead of searchQuery\r\n\r\n* fix snap","fileTypesAndContributionMap":{"scss":{"insertions":0,"deletions":0},"html":{"insertions":42,"deletions":2},"ts":{"insertions":147,"deletions":9}}}]},{"date":"2024-04-09","commitResults":[{"hash":"84ed244ade96870b71346808916568ae41b64b92","isMergeCommit":false,"messageTitle":"[#12048] Migrate AdminSearchPageE2ETest SQL (#12811)","messageBody":"* test e2e changes\r\n\r\n* fix: reduce e2e test json file size\r\n\r\n* fix student key\r\n\r\n* fix course key\r\n\r\n* fix instructor keys\r\n\r\n* fix filepath\r\n\r\n* fix e2e test\r\n\r\n* remove extra data from bundle\r\n\r\n* Add correct removal logic to avoid constraint violation\r\n\r\n* Fix e2e tests and lint\r\n\r\nfix reset google id test\r\n\r\nfix e2e tests\r\n\r\nfix e2e tests\r\n\r\nfix tests\r\n\r\nremove double click\r\n\r\nfix unknown symbol\r\n\r\nadd toast check\r\n\r\nchange toast verification message\r\n\r\nremove toast check\r\n\r\n* fix: add null check\r\n\r\n* move admin search page e2e test to sql cases\r\n\r\n* Rename AdminSearchPageE2ETest_SQLEntities.json to AdminSearchPageE2ETest_SqlEntities.json\r\n\r\n* fix failing test\r\n\r\n* fix: remove extra null check\r\n\r\n* fix: add test to e2e sql xml file\r\n\r\n* fix function call\r\n\r\n* remove unnecessary changes\r\n\r\n* create new file for sql entities\r\n\r\n* revert unnecessary changes\r\n\r\n* remove trailing whitespace\r\n\r\n* add teardown for account requests\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":446,"deletions":11}}},{"hash":"50c87bc8390e6a7c3592e00ef5db575cc66f8fcc","isMergeCommit":false,"messageTitle":"use transactions for reject account request action (#13001)","messageBody":"","fileTypesAndContributionMap":{"java":{"insertions":53,"deletions":38}}}]},{"date":"2024-04-10","commitResults":[{"hash":"a36ecf7d6996d7e4b468d19eb8c9de42eceb65d3","isMergeCommit":false,"messageTitle":"[#11878] Create Rejection Modal for Account Requests (#12989)","messageBody":"* Create rejection modal\r\n\r\n* fix lint and tests\r\n\r\n* fix placeholders and lint\r\n\r\n* remove title\r\n\r\n* integrate api\r\n\r\n* check undefined title and body\r\n\r\n* fix trailing white spaces\r\n\r\n* fix whitespace\r\n\r\n* change error message\r\n\r\n* re-add account request table on home page\r\n\r\n* replace support email","fileTypesAndContributionMap":{"scss":{"insertions":0,"deletions":0},"html":{"insertions":37,"deletions":2},"ts":{"insertions":147,"deletions":1}}}]},{"date":"2024-04-11","commitResults":[{"hash":"ce75a0a56f69d64a0c4ebcf15cffa78c9ca7b182","isMergeCommit":false,"messageTitle":"[#11878] Add Error Message for Approving Existing Account (#13004)","messageBody":"* add error message for duplicate account request\r\n\r\n* add tests","fileTypesAndContributionMap":{"java":{"insertions":75,"deletions":0}}}]},{"date":"2024-04-12","commitResults":[{"hash":"451a25a53c859e2d5382842450158ea641ec92f7","isMergeCommit":false,"messageTitle":"[#11878] Handle Duplicate Approved Account Requests (#13009)","messageBody":"","fileTypesAndContributionMap":{"java":{"insertions":52,"deletions":0}}}]},{"date":"2024-04-14","commitResults":[{"hash":"4682dffb71e4566ed72a9e8a7b2b814e8d16f869","isMergeCommit":false,"messageTitle":"[#11878] Add tests for Account Request Table (#12977)","messageBody":"* add component tests for account request table\r\n\r\n* modify tests\r\n\r\n* remove old tests\r\n\r\n* remove comment\r\n\r\n* remove unnecessary code\r\n\r\n* add tests\r\n\r\n* update disabled criteria\r\n\r\n* remove extra builders and update snaps","fileTypesAndContributionMap":{"html":{"insertions":5,"deletions":5},"ts":{"insertions":641,"deletions":197}}}]},{"date":"2024-04-15","commitResults":[{"hash":"f0e2af37f90ed48f0e48c6e3222ae96b6c4eb7f7","isMergeCommit":false,"messageTitle":"[#11878] Fix Approval Email Bug (#13027)","messageBody":"","fileTypesAndContributionMap":{"java":{"insertions":1,"deletions":1}}},{"hash":"0f0fd05a3a1a36169972f73abd67da32cfb2ab73","isMergeCommit":false,"messageTitle":"[#11878] Add Toasts (#13028)","messageBody":"* add toasts\r\n\r\n* lint","fileTypesAndContributionMap":{"ts":{"insertions":9,"deletions":1}}},{"hash":"20c29e589224601c5ceace8a656f0c14a33ec36f","isMergeCommit":false,"messageTitle":"fix highlighting and null statuses (#13031)","messageBody":"","fileTypesAndContributionMap":{"html":{"insertions":4,"deletions":4},"ts":{"insertions":1,"deletions":1}}},{"hash":"3dab1dc547f30044b2d6938a5973b9ab34e70159","isMergeCommit":false,"messageTitle":"[#11878] Fix Overlapping Tooltip (#13026)","messageBody":"* fix tooltip\r\n\r\n* re-add removed lines\r\n\r\n* update snap\r\n\r\n* update snaps\r\n\r\n* lint\r\n\r\n* suppress warning\r\n\r\n* lint","fileTypesAndContributionMap":{"scss":{"insertions":3,"deletions":1},"html":{"insertions":2,"deletions":2}}}]},{"date":"2024-04-17","commitResults":[{"hash":"68a4fbfe4052918b322acdbf89144477f677eb22","isMergeCommit":false,"messageTitle":"[#11878] Add Admin E2E Tests (#13020)","messageBody":"* add admin e2e tests\r\n\r\n* remove exception catching and update snaps\r\n\r\n* fix snaps\r\n\r\n* add comment verification\r\n\r\n* fix test","fileTypesAndContributionMap":{"java":{"insertions":293,"deletions":0},"html":{"insertions":1,"deletions":1},"ts":{"insertions":2,"deletions":2}}}]},{"date":"2024-04-18","commitResults":[{"hash":"ce839ab4351aba3036c19afa92edc60cadcbd85f","isMergeCommit":false,"messageTitle":"fix edit (#13056)","messageBody":"Co-authored-by: Zhang Ziqing \u003c69516975+ziqing26@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"ts":{"insertions":24,"deletions":14}}}]}],"asdfghjkxd":[],"yuanxi1":[{"date":"2023-12-28","commitResults":[{"hash":"5de8300549d6b06bd21d38f1d258bdcaebc6c443","isMergeCommit":false,"messageTitle":"[#12663] Instructor\u0027s Student Records Page: Tooltips for comments (#12676)","messageBody":"* Fix comment tooltip causing the text to go into next line\r\n\r\n* Update snapshot test\r\n\r\n---------\r\n\r\nCo-authored-by: YX Z \u003cyxz@YXs-MacBook-Air-2.local\u003e\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e\r\nCo-authored-by: Dominic Lim \u003c46486515+domlimm@users.noreply.github.com\u003e\r\nCo-authored-by: Jason Qiu \u003cjason_qiu@hotmail.com\u003e","fileTypesAndContributionMap":{"html":{"insertions":2,"deletions":2}}}]},{"date":"2024-02-06","commitResults":[{"hash":"f0279fa802b98f5dbf9d92c200168f21aa41ef62","isMergeCommit":false,"messageTitle":"[#12048] Migrate join course action (#12722)","messageBody":"* Add join course for student and instructor to AccountsLogic\r\n\r\n* Update AccountsLogic tests\r\n\r\n* Migrate JoinCourseAction\r\n\r\n* Add JoinCourseActionIT\r\n\r\n* Update to use usersLogic for student update\r\n\r\n* Fix failing IT caused by updates to typicalDataBundle\r\n\r\n* Fix failing IT\r\n\r\n* Remove print statements\r\n\r\n---------\r\n\r\nCo-authored-by: YX Z \u003cyxz@YXs-MacBook-Air-2.local\u003e\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":605,"deletions":12}}}]},{"date":"2024-02-14","commitResults":[{"hash":"33953dc064e3230bf0c27f2b591f5b06e212d8cf","isMergeCommit":false,"messageTitle":"[#12048] Migrate search students action (#12735)","messageBody":"* Migrate search students action and associated logic\r\n\r\n* Add tests for student search\r\n\r\n* Remove old test\r\n\r\n* Restore datastore test\r\n\r\n* Add support for dual db search\r\n\r\n* Suppress NPE warning\r\n\r\n---------\r\n\r\nCo-authored-by: YX Z \u003cyxz@YXs-MacBook-Air-2.local\u003e\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":528,"deletions":5}}}]},{"date":"2024-02-25","commitResults":[{"hash":"a913315da176e03961d0a0a4fae955571a5bf8aa","isMergeCommit":false,"messageTitle":"Add locale for java datetime formatter (#12826)","messageBody":"Co-authored-by: YX Z \u003cyxz@r-154-105-25-172.comp.nus.edu.sg\u003e","fileTypesAndContributionMap":{"java":{"insertions":2,"deletions":1}}}]},{"date":"2024-02-26","commitResults":[{"hash":"7b2a69c88dad53002650c37e12a16ba6e5564281","isMergeCommit":false,"messageTitle":"[#12048] Migrate Notification Banner E2E (#12840)","messageBody":"* Add locale for java datetime formatter\r\n\r\n* Migrate non-course content for NotificationBannerE2ETest\r\n\r\n* Fix linting\r\n\r\n* Fix snapshot test\r\n\r\n---------\r\n\r\nCo-authored-by: YX Z \u003cyxz@r-154-105-25-172.comp.nus.edu.sg\u003e\r\nCo-authored-by: YX Z \u003cyxz@YXs-MacBook-Air-2.local\u003e\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":14,"deletions":14},"html":{"insertions":1,"deletions":1}}}]},{"date":"2024-03-19","commitResults":[{"hash":"a34c3c57b22456de526d5af9a0317d502f44907a","isMergeCommit":false,"messageTitle":"[#12048] Migrate InstructorNotificationsPageE2E (#12906)","messageBody":"* Migrate InstructorNotificationsPageE2E\r\n\r\n* Fix unsaved transient entity error\r\n\r\n* Fix lint\r\n\r\n* Fix lint\r\n\r\n* Update testng xml\r\n\r\n---------\r\n\r\nCo-authored-by: YX Z \u003cyxz@YXs-MacBook-Air-2.local\u003e\r\nCo-authored-by: YX Z \u003cyxz@r-121-109-25-172.comp.nus.edu.sg\u003e\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":202,"deletions":0}}}]}],"supermii2":[],"marquestye":[{"date":"2024-02-25","commitResults":[{"hash":"3191fd1c0a471a34b3dbbfae8e305946280b0d42","isMergeCommit":false,"messageTitle":"[#12048] Migrate UpdateStudentAction (#12727)","messageBody":"* Modify student entity\r\n\r\n* Add update comment logic\r\n\r\n* Modify logic files for cascading update and creation for student\r\n\r\n* Add database queries for updating student\r\n\r\n* Update EnrollStudentsAction\r\n\r\n* Fix checkstyle\r\n\r\n* Remove extra query for editor update\r\n\r\n* Remove email update logic\r\n\r\n* Update javadocs\r\n\r\n* Copy over logic for Team and Section validation\r\n\r\n* Edit javadocs\r\n\r\n* Change StudentAttributes to Student instead\r\n\r\n* Fix lint issues\r\n\r\n* Fix lint issues\r\n\r\n* Fix component tests and lint\r\n\r\n* Remove ununsed method\r\n\r\n* Fix lint\r\n\r\n* Update validation logic to use Student\r\n\r\n* Update test case\r\n\r\n* Add tests for duplicate team across sections\r\n\r\n* Migrate UpdateStudentAction and add tests\r\n\r\n* Remove resetStudentGoogleId\r\n\r\n* Refactor updateStudentCascade\r\n\r\n* Fix integration tests\r\n\r\n* Fix checkstyle\r\n\r\n* Fix integration tests\r\n\r\n* Fix lint\r\n\r\n* Add persist verification in test\r\n\r\n* Fix test\r\n\r\n* Fix tests\r\n\r\n* Remove unused method\r\n\r\n* Fix test\r\n\r\n* Fix test\r\n\r\n* Fix test\r\n\r\n* Split UpdateStudentActionIT into multiple testcases\r\n\r\n* Add test separators\r\n\r\n---------\r\n\r\nCo-authored-by: Dominic Berzin \u003cberzindominic@gmail.com\u003e\r\nCo-authored-by: domoberzin \u003c74132255+domoberzin@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":522,"deletions":36}}}]},{"date":"2024-03-10","commitResults":[{"hash":"bf5a2ac8506bc49ecd1c479b634991a6380452e3","isMergeCommit":false,"messageTitle":"[#12048] Add tests for FeedbackQuestionsDb (#12759)","messageBody":"* Add verification during feedback question creation\r\n\r\n* Add tests for FeedbackQuestionsDb\r\n\r\n* Fix missing javadocs\r\n\r\n* Fix feedback question creation logic\r\n\r\n* Add test\r\n\r\n* Reuse error message\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e\r\nCo-authored-by: Zhang Ziqing \u003c69516975+ziqing26@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":169,"deletions":17}}}]},{"date":"2024-04-09","commitResults":[{"hash":"b9ccd4fb42a005822ba785a396699cf2a5005cec","isMergeCommit":false,"messageTitle":"[#12048] Migrate FeedbackNumScaleQuestionE2ETest (#12940)","messageBody":"* Migrate num scale e2e\r\n\r\n* Fix team id\r\n\r\n* Fix bugs","fileTypesAndContributionMap":{"java":{"insertions":147,"deletions":0}}}]}],"nknguyenhc":[{"date":"2023-12-25","commitResults":[{"hash":"a64f6605aec32e664527d017f7e2d9946010d4b2","isMergeCommit":false,"messageTitle":"[#12654] Instructor Edit Session Page: Bug in Grace Period Tooltip (#12675)","messageBody":"* Fix grace period tooltip\r\n\r\n* Update test cases\r\n\r\n---------\r\n\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e\r\nCo-authored-by: Dominic Lim \u003c46486515+domlimm@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"html":{"insertions":2,"deletions":2}}}]}],"Arif-Khalid":[],"NereusWB922":[],"dishenggg":[{"date":"2024-02-04","commitResults":[{"hash":"c8723d594557a0afdc117d679b9b4dfa41b32b61","isMergeCommit":false,"messageTitle":"[#12048] Migrate GetCourseJoinStatusAction (#12713)","messageBody":"* Migrate get course join status\r\n\r\n* Add IT for getCourseJoinStatusAction\r\n\r\n* Fix checkstyle\r\n\r\n* Update testcases\r\n\r\n* Update testcases\r\n\r\n* Refactor code\r\n\r\n---------\r\n\r\nCo-authored-by: dishenggg \u003cdisheng05@gmail.com\u003e\r\nCo-authored-by: FergusMok \u003cFergusMok1@gmail.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":262,"deletions":25}}}]},{"date":"2024-02-11","commitResults":[{"hash":"13c58fd88627b5fd90ca5aa5d605a6d2420cf128","isMergeCommit":false,"messageTitle":"[#12048] Migrate PutDataBundleDocumentsAction (#12734)","messageBody":"","fileTypesAndContributionMap":{"java":{"insertions":50,"deletions":4}}}]},{"date":"2024-02-18","commitResults":[{"hash":"5bfb84739674612f2d8d4f7c9d0202f5f2dbab83","isMergeCommit":false,"messageTitle":"Merge restore deleted to db (#12751)","messageBody":"Co-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":1,"deletions":0}}}]},{"date":"2024-02-22","commitResults":[{"hash":"5b3a96fdde95d6ab3fef6b861c2867efe92d15f4","isMergeCommit":false,"messageTitle":"[#12048] Add test cases for FeedbackSessionsDb (#12752)","messageBody":"* Add test for FeedbackSessionsDb\r\n\r\n* update test cases\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":253,"deletions":2}}}]},{"date":"2024-02-24","commitResults":[{"hash":"8125d5353307b0d225e90fc671c3f7420e8602a4","isMergeCommit":false,"messageTitle":"migrate instructor notif e2e (#12792)","messageBody":"Co-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":28,"deletions":21}}}]},{"date":"2024-03-13","commitResults":[{"hash":"2ad2242e44748557db65217b87dda052cbf55f7c","isMergeCommit":false,"messageTitle":"[#12048] Add tests for FeedbackQuestionsDbIT (#12781)","messageBody":"* Add verification during feedback question creation\r\n\r\n* Add tests for FeedbackQuestionsDb\r\n\r\n* Fix missing javadocs\r\n\r\n* Fix feedback question creation logic\r\n\r\n* Add test\r\n\r\n* Reuse error message\r\n\r\n* Add tests for FeedbackQuestionsDbIT\r\n\r\n---------\r\n\r\nCo-authored-by: marquestye \u003ce0360581@u.nus.edu\u003e\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":72,"deletions":0}}}]},{"date":"2024-03-18","commitResults":[{"hash":"17866eb4b93c3d773296ea2022cbf3ad96585a16","isMergeCommit":false,"messageTitle":"[#11843] Create FeedbackSessionLog entity and cron job action (#12895)","messageBody":"* Create FeedbackSessionLog entity\r\n\r\n* fix lint\r\n\r\n* Create UpdateFeedbackSessionLogsAction\r\n\r\n* Sort query results from logging service\r\n\r\n* Update type of feedbackSessionLogType\r\n\r\n* Fix naming\r\n\r\n* Fix enum in entity\r\n\r\n* Update filter to differentiate by session\r\n\r\n* Add Uri Info\r\n\r\n* Add tests\r\n\r\n* Update test case\r\n\r\n* Update to getOrderedFeedbackSessionLogs","fileTypesAndContributionMap":{"java":{"insertions":426,"deletions":11}}}]},{"date":"2024-03-19","commitResults":[{"hash":"4dc0c6deff8108eba7be7d85ccdd2f770d2b1a8e","isMergeCommit":false,"messageTitle":"[#12048] Migrate FeedbackMsqQuestionE2ETest (#12904)","messageBody":"* Migrate test\r\n\r\n* Update test\r\n\r\n* Update sql json\r\n\r\n* fix lint\r\n\r\n* Fix lint\r\n\r\n* Update json and add test to xml\r\n\r\n* Revert \"Fix lint\"\r\n\r\nThis reverts commit f767b5233dc280290b31bc6e669b173d0befd26d.\r\n\r\n* Revert \"Update sql json\"\r\n\r\nThis reverts commit 45744750bb262c3537d5628e9beef1289e163fb6.\r\n\r\n* Fix xml\r\n\r\n* Change to use makeDeepCopy\r\n\r\n* sort questions\r\n\r\n* fix verifyEquals method\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e\r\nCo-authored-by: Cedric Ong \u003ccedricong99@gmail.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":217,"deletions":4}}}]},{"date":"2024-03-27","commitResults":[{"hash":"e51132e3c4f2c694c60ac53e3f4a2dd973f9c1c9","isMergeCommit":false,"messageTitle":"[#12048] Migrate FeedbackMcqQuestionE2ETest (#12820)","messageBody":"* Migrate MCQ E2E\r\n\r\n* Fix lint\r\n\r\n* Fix lint\r\n\r\n* Update xml\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":166,"deletions":1}}}]},{"date":"2024-03-28","commitResults":[{"hash":"ccad41b26b4c62529fda29bc2d4b556e7098c356","isMergeCommit":false,"messageTitle":"[#11843] Create Logic and Db layer for FeedbackSessionLogs (#12914)","messageBody":"* Create FeedbackSessionLog entity\r\n\r\n* fix lint\r\n\r\n* Create UpdateFeedbackSessionLogsAction\r\n\r\n* Sort query results from logging service\r\n\r\n* Update type of feedbackSessionLogType\r\n\r\n* Fix naming\r\n\r\n* Fix enum in entity\r\n\r\n* Update filter to differentiate by session\r\n\r\n* Add Uri Info\r\n\r\n* Add tests\r\n\r\n* Update test case\r\n\r\n* Update to getOrderedFeedbackSessionLogs\r\n\r\n* Create skeleton\r\n\r\n* Implement logic and db layer\r\n\r\n* fix lint\r\n\r\n* Update entity\r\n\r\n* Fix tests\r\n\r\n* Fix bugs and optimize action\r\n\r\n* Prevent courseId from being null\r\n\r\n* Update GCP logs to store ids\r\n\r\n* Fix tests\r\n\r\n* Update action to use reference\r\n\r\n* Add some error handling\r\n\r\n* Fix tests\r\n\r\n* Add ids to api output","fileTypesAndContributionMap":{"java":{"insertions":1055,"deletions":124}}}]},{"date":"2024-04-05","commitResults":[{"hash":"a98630d6fe89136c4953bba2fd7b887e2e57b011","isMergeCommit":false,"messageTitle":"[#11843] Update GetFeedbackSessionLogsAction to use SQL db (#12938)","messageBody":"* Create FeedbackSessionLog entity\r\n\r\n* fix lint\r\n\r\n* Create UpdateFeedbackSessionLogsAction\r\n\r\n* Sort query results from logging service\r\n\r\n* Update type of feedbackSessionLogType\r\n\r\n* Fix naming\r\n\r\n* Fix enum in entity\r\n\r\n* Update filter to differentiate by session\r\n\r\n* Add Uri Info\r\n\r\n* Add tests\r\n\r\n* Update test case\r\n\r\n* Update to getOrderedFeedbackSessionLogs\r\n\r\n* Create skeleton\r\n\r\n* Implement logic and db layer\r\n\r\n* fix lint\r\n\r\n* Update entity\r\n\r\n* Fix tests\r\n\r\n* Update action to use fslDb\r\n\r\n* Fix tests\r\n\r\n* Update DbIT to use databundle\r\n\r\n* Fix bugs and optimize action\r\n\r\n* Prevent courseId from being null\r\n\r\n* Update GCP logs to store ids\r\n\r\n* Fix tests\r\n\r\n* Update action to use reference\r\n\r\n* Add some error handling\r\n\r\n* Fix tests\r\n\r\n* Add ids to api output\r\n\r\n* Fix lint\r\n\r\n* Update cron.yaml\r\n\r\n* Tidy up code\r\n\r\n* Update comments","fileTypesAndContributionMap":{"java":{"insertions":657,"deletions":169}}}]},{"date":"2024-04-09","commitResults":[{"hash":"cfff21db4a28c169de343df4f24198923e250b8e","isMergeCommit":false,"messageTitle":"Remove unused modal (#12998)","messageBody":"","fileTypesAndContributionMap":{"html":{"insertions":0,"deletions":68},"ts":{"insertions":5,"deletions":364}}}]},{"date":"2024-04-11","commitResults":[{"hash":"6de9607e48ecd10b38c87d1b1f42aaa2379d9440","isMergeCommit":false,"messageTitle":"[#11878] Update DeleteAccountRequest to reference by ID (#12997)","messageBody":"* Update to delete by id\r\n\r\n* fix lint\r\n\r\n* fix lint\r\n\r\n* fix frontend lint","fileTypesAndContributionMap":{"java":{"insertions":22,"deletions":21},"ts":{"insertions":5,"deletions":7}}},{"hash":"e0beb08e5c1ef5e726e6f21ba87a2a7213290d26","isMergeCommit":false,"messageTitle":"[#11878] Update ResetAccountRequest to reference by ID (#13002)","messageBody":"* Update reset to reference by id\r\n\r\n* fix comments","fileTypesAndContributionMap":{"java":{"insertions":17,"deletions":16},"ts":{"insertions":5,"deletions":7}}}]},{"date":"2024-04-13","commitResults":[{"hash":"8d506a13d6a11feb0d7129b1c2563e82b7b5527d","isMergeCommit":false,"messageTitle":"[#11843] Update front end for session activity logs (#12973)","messageBody":"* Create FeedbackSessionLog entity\r\n\r\n* fix lint\r\n\r\n* Create UpdateFeedbackSessionLogsAction\r\n\r\n* Sort query results from logging service\r\n\r\n* Update type of feedbackSessionLogType\r\n\r\n* Fix naming\r\n\r\n* Fix enum in entity\r\n\r\n* Update filter to differentiate by session\r\n\r\n* Add Uri Info\r\n\r\n* Add tests\r\n\r\n* Update test case\r\n\r\n* Update to getOrderedFeedbackSessionLogs\r\n\r\n* Create skeleton\r\n\r\n* Implement logic and db layer\r\n\r\n* fix lint\r\n\r\n* Update entity\r\n\r\n* Fix tests\r\n\r\n* Update action to use fslDb\r\n\r\n* Fix tests\r\n\r\n* Update DbIT to use databundle\r\n\r\n* Fix bugs and optimize action\r\n\r\n* Prevent courseId from being null\r\n\r\n* Update GCP logs to store ids\r\n\r\n* Fix tests\r\n\r\n* Update action to use reference\r\n\r\n* Add some error handling\r\n\r\n* Fix tests\r\n\r\n* Add ids to api output\r\n\r\n* Fix lint\r\n\r\n* Update front end\r\n\r\n* Update cron.yaml\r\n\r\n* Update front end\r\n\r\n* Fix result display\r\n\r\n* Tidy up code\r\n\r\n* Update actions to use getUuid\r\n\r\n* Fix formatting\r\n\r\n* Fix bug\r\n\r\n* Add buttons to access page\r\n\r\n* Shift logging\r\n\r\n* fiox bug\r\n\r\n* fix fe tests\r\n\r\n* Fix bug\r\n\r\n* Fix tests\r\n\r\n* Add IT\r\n\r\n* remove email and fsname\r\n\r\n* fix ts lint\r\n\r\n* Fix status message\r\n\r\n* Remove front end error messages\r\n\r\n* Add assertion fortests\r\n\r\n* Fix migrated check\r\n\r\n* Change to use id\r\n\r\n* Update javadoc\r\n\r\n* Change cron job to 15 mins intervals\r\n\r\n* fix tests\r\n\r\n* fix fe bug\r\n\r\n* Add delay note\r\n\r\n* Update to use const\r\n\r\n* Add const\r\n\r\n* fix fe tests","fileTypesAndContributionMap":{"java":{"insertions":440,"deletions":225},"html":{"insertions":15,"deletions":9},"ts":{"insertions":179,"deletions":74}}}]},{"date":"2024-04-16","commitResults":[{"hash":"16f776768a3b4a6e24c2b0673993e4fce1afb8a3","isMergeCommit":false,"messageTitle":"[#11878] Request Page E2E (#13015)","messageBody":"* Add E2E skeleton\r\n\r\n* Fix test and lint\r\n\r\n* Add verifyEmailSent\r\n\r\n* fix fe tests","fileTypesAndContributionMap":{"java":{"insertions":125,"deletions":0},"html":{"insertions":2,"deletions":2}}}]},{"date":"2024-04-17","commitResults":[{"hash":"3915b8c5684bfb77087c9b334468b0960965d6e5","isMergeCommit":false,"messageTitle":"Remove method from logic and db (#13044)","messageBody":"","fileTypesAndContributionMap":{"java":{"insertions":0,"deletions":31}}}]},{"date":"2024-04-18","commitResults":[{"hash":"9a51e2ae1348baac90d5e704a49ecb58d7ca9064","isMergeCommit":false,"messageTitle":"[#11843] Fix front end bugs (#13037)","messageBody":"* Fix notViewedSince\r\n\r\n* Update disclaimer\r\n\r\n* Change disclaimer message\r\n\r\n* Fix view result message\r\n\r\n* Fix not viewed since message","fileTypesAndContributionMap":{"html":{"insertions":2,"deletions":1},"ts":{"insertions":14,"deletions":12}}}]}],"MadLamprey":[],"Tim-Siu":[{"date":"2023-12-22","commitResults":[{"hash":"fdfdded21b473d79468a263a61b32985cce72ed3","isMergeCommit":false,"messageTitle":"[#3942] Instructor\u0027s Student Records Page: Feedback session panel chevron barely visible #12668 (#12673)","messageBody":"* Fix chevron color issue\r\n\r\n* Replace property binding with static value assignation","fileTypesAndContributionMap":{"html":{"insertions":1,"deletions":1}}}]}]},"authorFileTypeContributionMap":{"xenosf":{"java":3735,"js":0,"scss":31,"md":0,"py":0,"tag":0,"html":363,"ts":331},"sopa301":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"mingyuanc":{"java":851,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"jingting1412":{"java":0,"js":0,"scss":0,"md":42,"py":0,"tag":0,"html":0,"ts":0},"KevinEyo1":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"LamJiuFong":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"yiwen101":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"jonasongg":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"domoberzin":{"java":3240,"js":0,"scss":65,"md":0,"py":0,"tag":0,"html":159,"ts":1183},"asdfghjkxd":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"yuanxi1":{"java":1309,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":3,"ts":0},"supermii2":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"marquestye":{"java":819,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"nknguyenhc":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":2,"ts":0},"Arif-Khalid":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"NereusWB922":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"dishenggg":{"java":3323,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":17,"ts":197},"MadLamprey":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"Tim-Siu":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":1,"ts":0}},"authorContributionVariance":{"xenosf":52102.08,"sopa301":0.0,"mingyuanc":1263.081,"jingting1412":53.678123,"KevinEyo1":0.0,"LamJiuFong":0.0,"yiwen101":0.0,"jonasongg":0.0,"domoberzin":19354.154,"asdfghjkxd":0.0,"yuanxi1":4948.0444,"supermii2":0.0,"marquestye":2584.9875,"nknguyenhc":0.11346941,"Arif-Khalid":0.0,"NereusWB922":0.0,"dishenggg":24359.678,"MadLamprey":0.0,"Tim-Siu":0.028367352},"authorDisplayNameMap":{"xenosf":"XENO..NONG","sopa301":"POON..RYAN","mingyuanc":"CHIN..YUAN","jingting1412":"WANG..TING","KevinEyo1":"EYO ..EVIN","LamJiuFong":"LAM ..FONG","yiwen101":"WANG..IWEN","jonasongg":"JONA.. WEI","domoberzin":"DOMI.. GIN","asdfghjkxd":"GEOR.. YAO","yuanxi1":"ZHU ..ANXI","supermii2":"ALVI..S NG","marquestye":"TYE ..QUES","nknguyenhc":"NGUY..UYEN","Arif-Khalid":"ARIF..ALID","NereusWB922":"NERE.. BIN","dishenggg":"YEO ..HENG","MadLamprey":"MISR..ITYA","Tim-Siu":"XU S..UYAO"}} +{"authorDailyContributionsMap":{"xenosf":[{"date":"2024-02-15","commitResults":[{"hash":"3c0126ef4feeda7cedcd8f098ee953f916856d70","isMergeCommit":false,"messageTitle":"[#12048] Migrate StudentSearchIndexingWorkerAction (#12733)","messageBody":"* Migrate StudentSearchIndexingWorkerAction\r\n\r\n* Add IT for StudentSearchIndexingWorkerAction\r\n\r\n* Fix javadoc for putStudentDocument\r\n\r\n* Refactor SQL logic and Datastore execute logic to separate methods\r\n\r\n* Fix checkstyle errors\r\n\r\n* Reset student search collections before test\r\n\r\n* Rename test methods to use \"should\"","fileTypesAndContributionMap":{"java":{"insertions":116,"deletions":0}}}]},{"date":"2024-02-27","commitResults":[{"hash":"2dad48b8d3bf32fb337f3021bcf7a9021f15a656","isMergeCommit":false,"messageTitle":"[#12048] Migrate GetSessionResultsAction (#12719)","messageBody":"* Migrate SessionResultsData\r\n\r\n* Add default entities\r\n\r\n* Add helper methods to assist migrated logic\r\n\r\n* Migrate buildCompleteGiverRecipientMap\r\n\r\n* Migrate checkSpecificAccessControl\r\n\r\n* Add default team instance for instructor\r\n\r\n* Migrate session results data logic\r\n\r\n* Use default team entity for instructor instead of const\r\n\r\n* Migrate non-db logic\r\n\r\n* Refactor Datastore and SQL action logic out to separate methods\r\n\r\n* Fix checkstyle errors\r\n\r\n* Migrate DB logic\r\n\r\n* Fix checkstyle errors\r\n\r\n* Move default instructor team entity to const\r\n\r\n* Add test for SqlSessionResultsBundle\r\n\r\n* Fix SQL results bundle test\r\n\r\n* Add IT for GetSessionResultsAction\r\n\r\n* Fix action logic\r\n\r\n* Fix checkstyle errors\r\n\r\n* Remove unused method parameters\r\n\r\n* Fix persistence issues in test cases\r\n\r\n* Remove question getter for comment\r\n\r\n* Rename boolean methods to start with verb\r\n\r\n* Reword comment to clarify question ID\r\n\r\n* Refactor getting question UUID from param value\r\n\r\n* Remove unneeded getters\r\n\r\n* Remove entities from Const\r\n\r\n* Revert changes to SqlCourseRoster\r\n\r\n* Create and use missing response class\r\n\r\n* Refactor no response text to const\r\n\r\n* Migrate preview-related functionality\r\n\r\n* Migrate preview functionality for question output\r\n\r\n* Fix recipient section filter\r\n\r\n* Update test cases to handle question preview\r\n\r\n* Merge duplicate methods\r\n\r\n* Fix checkstyle errors\r\n\r\n* Add missing questions with non-visible preview responses\r\n\r\n* Remove outdated test\r\n\r\n* Edit for style and readability\r\n\r\n* Fix missing join\r\n\r\n* Fix section filtering logic\r\n\r\n* Fix checkstyle errors","fileTypesAndContributionMap":{"java":{"insertions":2563,"deletions":23}}}]},{"date":"2024-03-13","commitResults":[{"hash":"b8023350e370623921776a3cdc18776f65d1c3f6","isMergeCommit":false,"messageTitle":"[#12048] Add integration tests for FeedbackResponseCommentsDb (#12849)","messageBody":"* Migrate SessionResultsData\r\n\r\n* Add default entities\r\n\r\n* Add helper methods to assist migrated logic\r\n\r\n* Migrate buildCompleteGiverRecipientMap\r\n\r\n* Migrate checkSpecificAccessControl\r\n\r\n* Add default team instance for instructor\r\n\r\n* Migrate session results data logic\r\n\r\n* Use default team entity for instructor instead of const\r\n\r\n* Migrate non-db logic\r\n\r\n* Refactor Datastore and SQL action logic out to separate methods\r\n\r\n* Fix checkstyle errors\r\n\r\n* Migrate DB logic\r\n\r\n* Fix checkstyle errors\r\n\r\n* Move default instructor team entity to const\r\n\r\n* Add test for SqlSessionResultsBundle\r\n\r\n* Fix SQL results bundle test\r\n\r\n* Add IT for GetSessionResultsAction\r\n\r\n* Fix action logic\r\n\r\n* Fix checkstyle errors\r\n\r\n* Remove unused method parameters\r\n\r\n* Fix persistence issues in test cases\r\n\r\n* Remove question getter for comment\r\n\r\n* Rename boolean methods to start with verb\r\n\r\n* Reword comment to clarify question ID\r\n\r\n* Refactor getting question UUID from param value\r\n\r\n* Remove unneeded getters\r\n\r\n* Remove entities from Const\r\n\r\n* Revert changes to SqlCourseRoster\r\n\r\n* Create and use missing response class\r\n\r\n* Refactor no response text to const\r\n\r\n* Migrate preview-related functionality\r\n\r\n* Migrate preview functionality for question output\r\n\r\n* Fix recipient section filter\r\n\r\n* Update test cases to handle question preview\r\n\r\n* Merge duplicate methods\r\n\r\n* Fix checkstyle errors\r\n\r\n* Add missing questions with non-visible preview responses\r\n\r\n* Remove outdated test\r\n\r\n* Edit for style and readability\r\n\r\n* Fix missing join\r\n\r\n* Fix section filtering logic\r\n\r\n* Fix checkstyle errors\r\n\r\n* Add integration tests\r\n\r\n* Refactor tests for readability\r\n\r\n* Fix broken test cases\r\n\r\n* Rename test section key\r\n\r\n* Use separate json bundle for test data\r\n\r\n* Clear session when set up\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":202,"deletions":8}}}]},{"date":"2024-03-14","commitResults":[{"hash":"931dea4d8747bfec25bd10309e2b722a743a6b7e","isMergeCommit":false,"messageTitle":"[#12048] Add integration tests for FeedbackResponsesDb (#12856)","messageBody":"* Migrate SessionResultsData\r\n\r\n* Add default entities\r\n\r\n* Add helper methods to assist migrated logic\r\n\r\n* Migrate buildCompleteGiverRecipientMap\r\n\r\n* Migrate checkSpecificAccessControl\r\n\r\n* Add default team instance for instructor\r\n\r\n* Migrate session results data logic\r\n\r\n* Use default team entity for instructor instead of const\r\n\r\n* Migrate non-db logic\r\n\r\n* Refactor Datastore and SQL action logic out to separate methods\r\n\r\n* Fix checkstyle errors\r\n\r\n* Migrate DB logic\r\n\r\n* Fix checkstyle errors\r\n\r\n* Move default instructor team entity to const\r\n\r\n* Add test for SqlSessionResultsBundle\r\n\r\n* Fix SQL results bundle test\r\n\r\n* Add IT for GetSessionResultsAction\r\n\r\n* Fix action logic\r\n\r\n* Fix checkstyle errors\r\n\r\n* Remove unused method parameters\r\n\r\n* Fix persistence issues in test cases\r\n\r\n* Remove question getter for comment\r\n\r\n* Rename boolean methods to start with verb\r\n\r\n* Reword comment to clarify question ID\r\n\r\n* Refactor getting question UUID from param value\r\n\r\n* Remove unneeded getters\r\n\r\n* Remove entities from Const\r\n\r\n* Revert changes to SqlCourseRoster\r\n\r\n* Create and use missing response class\r\n\r\n* Refactor no response text to const\r\n\r\n* Migrate preview-related functionality\r\n\r\n* Migrate preview functionality for question output\r\n\r\n* Fix recipient section filter\r\n\r\n* Update test cases to handle question preview\r\n\r\n* Merge duplicate methods\r\n\r\n* Fix checkstyle errors\r\n\r\n* Add missing questions with non-visible preview responses\r\n\r\n* Remove outdated test\r\n\r\n* Edit for style and readability\r\n\r\n* Fix missing join\r\n\r\n* Fix section filtering logic\r\n\r\n* Fix checkstyle errors\r\n\r\n* Add integration tests\r\n\r\n* Update and use typical bundle\r\n\r\n* Update test cases for updated bundle\r\n\r\n* Revert typical data bundle\r\n\r\n* Use separate data bundle for feedback responses test\r\n\r\n* Revert unrelated tests\r\n\r\n* Fix json formatting\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":215,"deletions":19}}}]},{"date":"2024-03-27","commitResults":[{"hash":"f7eaa617f1e129a828bc4eb5b3f2776629ef9a3f","isMergeCommit":false,"messageTitle":"[#11878] Upgrade instructor request form UI (#12929)","messageBody":"* Add confirmation prompt\r\n\r\n* Remove old form iframe\r\n\r\n* Improve declaration view spacing\r\n\r\n* Edit page heading phrasing for clarity\r\n\r\n* Create request form\r\n\r\n* Add validation messages\r\n\r\n* Fix form validation\r\n\r\n* Set up form submission confirmation\r\n\r\n* Create submission acknowledgement view\r\n\r\n* Fix URL checking regex\r\n\r\n* Fix initial state\r\n\r\n* Display placeholder when optional field is empty\r\n\r\n* Fix code style\r\n\r\n* Edit comment for clarity\r\n\r\n* Fix institution and country combination\r\n\r\nCo-authored-by: Jay Aljelo Ting \u003c65202977+jayasting98@users.noreply.github.com\u003e\r\n\r\n* Fix naming\r\n\r\n* Remove hard line break\r\n\r\n* Add explanatory comment for regex\r\n\r\n* Remove newline\r\n\r\n* Add newlines at end of file\r\n\r\n* Clear styles file\r\n\r\n* Re-add styles file\r\n\r\n* Include test\r\n\r\n* Add test cases for requestSubmissionEvent\r\n\r\n* Improve test case readability\r\n\r\n* Edit test case name for clarity\r\n\r\n* Add snapshot tests\r\n\r\n* Revert \"Add snapshot tests\"\r\n\r\nThis reverts commit ec7395d4e8bd0d956f3c355b9906ec0ab3ae0f58.\r\n\r\n* Fix lint errors\r\n\r\n* Rename methods to be clearer\r\n\r\n* Disable submit button when not ready to submit\r\n\r\n---------\r\n\r\nCo-authored-by: Jay Aljelo Ting \u003c65202977+jayasting98@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"scss":{"insertions":27,"deletions":0},"html":{"insertions":155,"deletions":11},"ts":{"insertions":198,"deletions":0}}}]},{"date":"2024-03-29","commitResults":[{"hash":"f6329eb10233e07143153782451605524216c901","isMergeCommit":false,"messageTitle":"[#11878] Add snapshot tests for instructor request form UI (#12942)","messageBody":"* Add snapshot tests\r\n\r\n* Change double quotes to single quotes","fileTypesAndContributionMap":{"ts":{"insertions":31,"deletions":0}}}]},{"date":"2024-03-30","commitResults":[{"hash":"00b85cec55172709a112a6519ff11316b448f79e","isMergeCommit":false,"messageTitle":"[#11878] Create instructor request acknowledgement email (#12944)","messageBody":"* Create instructor request acknowledgement email\r\n\r\n* Add tests for acknowledgement email\r\n\r\n* Fix test cases\r\n\r\n* Fix comments in expected email\r\n\r\n* Use config support email value in email template\r\n\r\n* Fix email recipient\r\n\r\n* Fix test expected emails\r\n\r\n* Remove trailing space\r\n\r\n* Use placeholder for support email\r\n\r\n* Sanitize acknowledgement email\r\n\r\n* Set acknowledgement email to bcc support","fileTypesAndContributionMap":{"java":{"insertions":80,"deletions":3},"html":{"insertions":195,"deletions":0}}}]},{"date":"2024-04-02","commitResults":[{"hash":"7ec74c76f1feb2c2528ac061e88332e166994316","isMergeCommit":false,"messageTitle":"[#11878] Change institute length limit (#12974)","messageBody":"* Change institute name max length to 128\r\n\r\n* Edit test case for new length limit","fileTypesAndContributionMap":{"java":{"insertions":6,"deletions":5}}}]},{"date":"2024-04-04","commitResults":[{"hash":"de3181a347f241d23d34dad524a2542231a03e1f","isMergeCommit":false,"messageTitle":"[#11878] Integrate instructor request form with API (#12943)","messageBody":"* Integrate instructor request form FE with API\r\n\r\n* Remove redundant statement\r\n\r\n* Move URL regex const to backend const file\r\n\r\n* Fix import path\r\n\r\n* Move URL regex to FieldValidator\r\n\r\n* Add validators to match backend fields\r\n\r\n* Add error message box\r\n\r\n* Change submit button display when loading\r\n\r\n* Combine final action into subscribe\r\n\r\n* Add max length validators for institution and country\r\n\r\n* Fix lint errors\r\n\r\n* Add test cases to test submission\r\n\r\n* Add specific error messages for form validation\r\n\r\n* Remove home page URL field\r\n\r\n* Fix lint errors\r\n\r\n* Remove url regex from test\r\n\r\n* Update snap\r\n\r\n* Clean up test code\r\n\r\n* Remove comment about home page URL\r\n\r\n* Change canSubmit check to getter\r\n\r\n* Fix form submit button not re-enabling on error\r\n\r\n* Add name pattern validator to front-end\r\n\r\n* Fix snapshot","fileTypesAndContributionMap":{"java":{"insertions":40,"deletions":0},"scss":{"insertions":4,"deletions":0},"html":{"insertions":48,"deletions":30},"ts":{"insertions":153,"deletions":53}}}]},{"date":"2024-04-09","commitResults":[{"hash":"1e9ccb091fac81793a93c460e017c076b797c66b","isMergeCommit":false,"messageTitle":"[#12048] Migrate AccountRequestsLogicTest (#12780)","messageBody":"* Migrate test cases for AccountRequestsLogic\r\n\r\n* Remove test case\r\n\r\n* Split test cases","fileTypesAndContributionMap":{"java":{"insertions":182,"deletions":0}}},{"hash":"fb0ba194ba1759bc5ce1da0f23ec467bdfed36fe","isMergeCommit":false,"messageTitle":"[#11878] Create reject account request endpoint (#12985)","messageBody":"* Create account request rejection endpoint\r\n\r\n* Add validation\r\n\r\n* Add check for already rejected request when sending email\r\n\r\n* Add integration test cases\r\n\r\n* Set request method to post\r\n\r\n* Fix lint errors\r\n\r\n* Update tests list\r\n\r\n* Update validation check\r\n\r\n* Add test for validation\r\n\r\n* Fix lint errors\r\n\r\n* Fix validation comparison\r\n\r\n* Fix error message test\r\n\r\n* Add email sending\r\n\r\n* Update test cases\r\n\r\n* Refactor reason check code for clarity","fileTypesAndContributionMap":{"java":{"insertions":371,"deletions":3}}}]},{"date":"2024-04-15","commitResults":[{"hash":"bb261f4fdaff9efad9048da9dae71578a11cf09a","isMergeCommit":false,"messageTitle":"[#11878] Remove mention of home page URL from confirmation email (#13030)","messageBody":"","fileTypesAndContributionMap":{"html":{"insertions":3,"deletions":3}}}]},{"date":"2024-04-16","commitResults":[{"hash":"665752c8ff7379ebef441b427093fcbefd8bb561","isMergeCommit":false,"messageTitle":"[#11878] Check if account request is not created by admin before sending email (#13032)","messageBody":"* Add check if admin when creating account request\r\n\r\n* Trim down test case","fileTypesAndContributionMap":{"java":{"insertions":25,"deletions":5}}}]},{"date":"2024-04-17","commitResults":[{"hash":"ab22022dc4511f3f522931c2ab1324de5dbebea9","isMergeCommit":false,"messageTitle":"[#11878] Migrate AccountRequestsLogic unit tests (#13043)","messageBody":"* Add get typical account request method\r\n\r\n* Migrate AccountRequestsLogicTest\r\n\r\n* Remove test for get by email address and institute\r\n\r\n---------\r\n\r\nCo-authored-by: Jay Aljelo Ting \u003c65202977+jayasting98@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":139,"deletions":1}}}]},{"date":"2024-04-18","commitResults":[{"hash":"2cc6ef82fc92e2bc742c39b6c5b337330faf5e62","isMergeCommit":false,"messageTitle":"[#11878] Add SQLI tests (#13047)","messageBody":"","fileTypesAndContributionMap":{"java":{"insertions":31,"deletions":0}}}]}],"sopa301":[],"mingyuanc":[{"date":"2024-02-07","commitResults":[{"hash":"cc0bf4f77bc293c689f5e721d16aae14f150e152","isMergeCommit":false,"messageTitle":"[#12048] Migrate CreateInstructorAction (#12706)","messageBody":"","fileTypesAndContributionMap":{"java":{"insertions":257,"deletions":37}}}]},{"date":"2024-02-18","commitResults":[{"hash":"8e757e2125448b07dbc7e46d94e8967c9925da4c","isMergeCommit":false,"messageTitle":"[#12048] Migrate instructor search indexing worker action (#12731)","messageBody":"* Fix lint\r\n\r\n* Migrate instructor search indexing worker action\r\n\r\n* Fix Checkstyle\r\n\r\n* Fix Checkstyle\r\n\r\n* Fix Checkstyle\r\n\r\n* Add testcases\r\n\r\n* Update comparator to Id\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e\r\nCo-authored-by: Nicolas \u003c25302138+NicolasCwy@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":107,"deletions":0}}}]},{"date":"2024-02-19","commitResults":[{"hash":"d6c67fc9dd31c36f196be454a22cce955e1c8229","isMergeCommit":false,"messageTitle":"Add testcases for FeedbackResponseCommentsDbTest (#12755)","messageBody":"* Add CRUD testcases\r\n\r\n* Fix linting\r\n\r\n* Refactor getTypicalComment\r\n\r\n* Amend testDeleteComment testcase\r\n\r\n* Amend testDeleteComment testcase\r\n\r\n* Fix compile error\r\n\r\n* Revert linting changes\r\n\r\n---------\r\n\r\nCo-authored-by: Nicolas \u003c25302138+NicolasCwy@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":156,"deletions":1}}}]},{"date":"2024-03-09","commitResults":[{"hash":"ef31826b7ec1e1308c0e6016ba513e9c6afa3c58","isMergeCommit":false,"messageTitle":"Add testcases for FeedbackResponseCommentsLogicTest (#12769)","messageBody":"* Added testcase\r\n\r\n* Add new testcases\r\n\r\n* Remove dead store\r\n\r\n---------\r\n\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":185,"deletions":0}}}]},{"date":"2024-03-27","commitResults":[{"hash":"0cfadeffbb74c112f2705ade1be7c6b0cf61d51f","isMergeCommit":false,"messageTitle":"[#12048] Migrate Feedback Rank Option E2E test (#12902)","messageBody":"* Initial commit\r\n\r\n* Fix lint\r\n\r\n* Follow convention and add test\r\n\r\n* Change file path\r\n\r\n* Fix requested changes\r\n\r\n* Fixed testcases\r\n\r\n* Fix lint\r\n\r\n* Add deepcopy\r\n\r\n* Fixed e2e test\r\n\r\n---------\r\n\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":154,"deletions":4}}}]},{"date":"2024-04-15","commitResults":[{"hash":"98d9044d7e95ecdaf31f2191f76fa0254ace4f40","isMergeCommit":false,"messageTitle":"Initial commit (#13024)","messageBody":"","fileTypesAndContributionMap":{"java":{"insertions":2,"deletions":2}}}]},{"date":"2024-04-17","commitResults":[{"hash":"f8522866c39bc7d7208f1e3443061b408ef4af9e","isMergeCommit":false,"messageTitle":"[#12048] Fix getSessionResultAction bugs (#13023)","messageBody":"* [#12048] Config prod settings and convenience scripts for non course migration (#12959)\r\n\r\n* Add fields\r\n\r\n* Change based on feedback\r\n\r\n* Add changes\r\n\r\n* Add reverse data migration script for account (#12962)\r\n\r\n* Add changes (#12965)\r\n\r\n* V9 non course migration fix to check extra SQL accounts (#12966)\r\n\r\n* Add changes\r\n\r\n* Add isMarked script\r\n\r\n* Add patch data migration script for usage stats (#12970)\r\n\r\n* Add patch data migration script for usage stats\r\n\r\n* Fix hibernate batch query\r\n\r\n* Revert log\r\n\r\n* Initial commit\r\n\r\n* Revert \"[#12048] Config prod settings and convenience scripts for non course migration (#12959)\"\r\n\r\nThis reverts commit 6df39c19108de833624992c56e09f75960ff65c1.\r\n\r\n* Revert \"Add reverse data migration script for account (#12962)\"\r\n\r\nThis reverts commit 05099825679c31ace2872860a358288ec0bdacc3.\r\n\r\n* Revert \"V9 non course migration fix to check extra SQL accounts (#12966)\"\r\n\r\nThis reverts commit 611b2cc3682b11e75c3631a8843aa030e8a34b9d.\r\n\r\n* Revert \"Add patch data migration script for usage stats (#12970)\"\r\n\r\nThis reverts commit 239ae85a5bd2d40ea4464b6e47a626f76913a6e1.\r\n\r\n* Revert \"Add changes (#12965)\"\r\n\r\nThis reverts commit 1292dbe995e50b9c3fe1bf5ec377e92f6f751ec2.\r\n\r\n* Fix lint\r\n\r\n* Retry lint\r\n\r\n---------\r\n\r\nCo-authored-by: FergusMok \u003cFergusMok1@gmail.com\u003e\r\nCo-authored-by: Zhang Ziqing \u003c69516975+ziqing26@users.noreply.github.com\u003e\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":33,"deletions":5}}}]}],"jingting1412":[{"date":"2024-03-16","commitResults":[{"hash":"2d1080682a62f32981cb4b0edd497f0928bcd83b","isMergeCommit":false,"messageTitle":"[#12271] Docs: Upgrade to latest MarkBind version (#12893)","messageBody":"* Upgrade layouts\r\n\r\n* Add breadcrumb for pages\r\n\r\n* Fix puml diagrams\r\n\r\n* Make navbar sticky\r\n\r\n* Upgrade markbind version\r\n\r\n* Upgrade markbind\r\n\r\n* Upgrade markbind version\r\n\r\n* Update pages\r\n\r\n* Revert \"Upgrade markbind version\"\r\n\r\nThis reverts commit 76b2d44f3bc57d5bfdf03fdb2c01cb92a186105f.\r\n\r\n---------\r\n\r\nCo-authored-by: Zhang Ziqing \u003c69516975+ziqing26@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"md":{"insertions":43,"deletions":44}}}]}],"KevinEyo1":[],"LamJiuFong":[],"yiwen101":[],"jonasongg":[],"domoberzin":[{"date":"2024-02-04","commitResults":[{"hash":"333f582460d9b1ba7174321de3ea3113cc71c9db","isMergeCommit":false,"messageTitle":"[#12048] Migrate enroll students action (#12715)","messageBody":"* Modify student entity\r\n\r\n* Add update comment logic\r\n\r\n* Modify logic files for cascading update and creation for student\r\n\r\n* Add database queries for updating student\r\n\r\n* Update EnrollStudentsAction\r\n\r\n* Fix checkstyle\r\n\r\n* Remove extra query for editor update\r\n\r\n* Remove email update logic\r\n\r\n* Update javadocs\r\n\r\n* Copy over logic for Team and Section validation\r\n\r\n* Edit javadocs\r\n\r\n* Change StudentAttributes to Student instead\r\n\r\n* Fix lint issues\r\n\r\n* Fix lint issues\r\n\r\n* Fix component tests and lint\r\n\r\n* Remove ununsed method\r\n\r\n* Fix lint\r\n\r\n* Update validation logic to use Student\r\n\r\n* Update test case\r\n\r\n* Add tests for duplicate team across sections\r\n\r\n* Remove unused methods and add getSection to UsersLogic\r\n\r\n* Fix sorting logic\r\n\r\n* Change getName method calls for section and team\r\n\r\n* Remove unused methods\r\n\r\n* Add more detail to JavaDocs\r\n\r\n* Remove unusued methods\r\n\r\n* Use getCourseId instead of toString\r\n\r\n* Modify test case\r\n\r\n* Revert changes\r\n\r\n* Change toString to getCourseId\r\n\r\n* Update tests to include unregistered student\r\n\r\n* Fix trailing whitespaces","fileTypesAndContributionMap":{"java":{"insertions":875,"deletions":66}}}]},{"date":"2024-02-10","commitResults":[{"hash":"21ae95eab736f4c37933d3fa0fd9bd592c6b92d6","isMergeCommit":false,"messageTitle":"[#12048] Migrate search account requests action (#12726)","messageBody":"* feat: add search account request methods to SQL storage and logic layers\r\n\r\n* feat: migrate SearchAccountRequestsAction to use SQL logic\r\n\r\n* fix: failing tests\r\n\r\n* fix: remove commented line\r\n\r\n* fix: migrate AccountRequestSearch tests\r\n\r\n---------\r\n\r\nCo-authored-by: Dominic Lim \u003c46486515+domlimm@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":347,"deletions":5}}}]},{"date":"2024-02-18","commitResults":[{"hash":"c314aa9f3462f76ac3a3e8d15e58289181b31573","isMergeCommit":false,"messageTitle":"[#12048] Add tests for CoursesLogic (#12746)","messageBody":"* feat: add tests for CoursesLogic\r\n\r\n* fix: verify parameters of mocked logic classes\r\n\r\n* fix: lint issues\r\n\r\n* fix: add additional verification of parameters\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":319,"deletions":2}}}]},{"date":"2024-02-20","commitResults":[{"hash":"daba8ebd1ead324ae4e4b2daba64d2586538a9f5","isMergeCommit":false,"messageTitle":"[#12048] Migrate AccountRequestSearchIndexingWorkerAction (#12757)","messageBody":"* feat: migrate account request search indexing worker action\r\n\r\n* fix: remove datastore logic and old test\r\n\r\n* fix: remove NPE suppress","fileTypesAndContributionMap":{"java":{"insertions":38,"deletions":13}}}]},{"date":"2024-02-24","commitResults":[{"hash":"7a22ab856fb641e0d7897a00e45ed3c5024ab766","isMergeCommit":false,"messageTitle":"[#12048] Fix GetSessionResponseStatsActionIT (#12777)","messageBody":"* Migrate GetSessionResponseStatsAction\r\n\r\n* fix: fix NPE issues\r\n\r\n* fix: remove extra comments\r\n\r\n* fix: remove extra line\r\n\r\n---------\r\n\r\nCo-authored-by: Zhang Ziqing \u003czhangziqing9926@gmail.com\u003e\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e\r\nCo-authored-by: Zhang Ziqing \u003c69516975+ziqing26@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":218,"deletions":15}}},{"hash":"7da77bb9ba38925e675b94d64dc6bff2d7d5bcc1","isMergeCommit":false,"messageTitle":"[#12048] Create IT for GetFeedbackSessionSubmittedGiverSetAction (#12778)","messageBody":"* Migrate GetSessionResponseStatsAction\r\n\r\n* fix: fix NPE issues\r\n\r\n* feat: add IT for GetFeedbackSessionSubmittedGiverSetAction\r\n\r\n* fix: remove extra comment\r\n\r\n* fix: remove duplicate method\r\n\r\n---------\r\n\r\nCo-authored-by: Zhang Ziqing \u003czhangziqing9926@gmail.com\u003e\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e\r\nCo-authored-by: Zhang Ziqing \u003c69516975+ziqing26@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":81,"deletions":3}}}]},{"date":"2024-02-26","commitResults":[{"hash":"500e7421dc31bd884ba6d2ff7a01b6abcabf646b","isMergeCommit":false,"messageTitle":"[#12048] Migrate Admin Notifications E2E Test (#12793)","messageBody":"* feat: add resources for admin notifications e2e test\r\n\r\n* fix: set created at on notification creation\r\n\r\n* feat: migrate admin notifications e2e test\r\n\r\n* fix: remove created at check for notifications\r\n\r\n* fix: remove extra comments\r\n\r\n* fix: remove explicit created at\r\n\r\n* fix: null check for created at\r\n\r\n* fix lint\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e\r\nCo-authored-by: Cedric Ong \u003ccedricongjh@gmail.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":47,"deletions":34}}},{"hash":"203ec245f53c97be136208df3f583bfd6db97f8c","isMergeCommit":false,"messageTitle":"[#12048] Migrate AdminSearchPageE2ETest (#12838)","messageBody":"* migate admin search e2e\r\n\r\n* fix e2e test\r\n\r\n* fix failing tests\r\n\r\n* fix: add put sql document methods\r\n\r\n* fix: add migrated check back in\r\n\r\n* fix: add cleanup method\r\n\r\n* fix: add search document removal for account request\r\n\r\n* fix lint and tests\r\n\r\n* fix: json file formatting\r\n\r\n* fix: init both searchManagers\r\n\r\n* fix: add comments\r\n\r\n* fix: remove notifications field in data file\r\n\r\n---------\r\n\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":201,"deletions":45}}}]},{"date":"2024-03-03","commitResults":[{"hash":"0f9d99069cca05ac16878b0f5e0fa78bf629d96d","isMergeCommit":false,"messageTitle":"[#12048] Add tests for CourseDbIT (#12786)","messageBody":"* feat: add more coverage for methods in CoursesDb\r\n\r\n* fix: add further test cases\r\n\r\n---------\r\n\r\nCo-authored-by: Dominic Lim \u003c46486515+domlimm@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":165,"deletions":4}}}]},{"date":"2024-03-13","commitResults":[{"hash":"ccdb6ccf64330e83bff24d7b93e15f2081c30398","isMergeCommit":false,"messageTitle":"[#12048] Migrate InstructorSearchPageE2ETest (#12891)","messageBody":"* feat: migrate instructor search page e2e test\r\n\r\n* fix: add new line\r\n\r\n* fix axe test\r\n\r\n* remove extra whitespace","fileTypesAndContributionMap":{"java":{"insertions":5,"deletions":3}}}]},{"date":"2024-03-27","commitResults":[{"hash":"40613dff7486e2224c1375a218f55f442279a4e9","isMergeCommit":false,"messageTitle":"[#11878] Update Admin Home Page UI for ARF (#12933)","messageBody":"* create component for account request table\r\n\r\n* cherry pick admin home page changes\r\n\r\n* remove testing code\r\n\r\n* fix lint and css issues\r\n\r\n* fix admin home page snaps\r\n\r\n* update admin home snaps\r\n\r\n* remove edit approve and reject components\r\n\r\n* modify css\r\n\r\n* delete edit and reject modal components\r\n\r\n* revert spec file changes\r\n\r\n* integrate new types\r\n\r\n* fix lint\r\n\r\n* use enum for status\r\n\r\n* fix lint\r\n\r\n* fix css lint\r\n\r\n* fix lint\r\n\r\n* fix lint\r\n\r\n* use enum and remove infinite scroll\r\n\r\n* remove approve account request code\r\n\r\n* remove extra div\r\n\r\n* fix url\r\n\r\n* modify comments\r\n\r\n* revert extra formatting\r\n\r\n* remove plural form and use date pipe\r\n\r\n* fix naming\r\n\r\n* fix spec file and update institute formatting\r\n\r\n* fix lint\r\n\r\n* combine institute and country columns","fileTypesAndContributionMap":{"scss":{"insertions":63,"deletions":0},"html":{"insertions":84,"deletions":0},"ts":{"insertions":243,"deletions":9}}}]},{"date":"2024-03-28","commitResults":[{"hash":"561837052d6810ac904eb5cd34454e0cb98fa530","isMergeCommit":false,"messageTitle":"[#11878] Admin Search UI Update for ARF (#12945)","messageBody":"* update admin search page to use acc req component\r\n\r\n* fix selector for e2e test\r\n\r\n* fix spec files and imports\r\n\r\n* update e2e selector\r\n\r\n* fix column numbers","fileTypesAndContributionMap":{"java":{"insertions":5,"deletions":5},"html":{"insertions":2,"deletions":64},"ts":{"insertions":43,"deletions":78}}}]},{"date":"2024-04-05","commitResults":[{"hash":"5779d2f365abad11ed259714c8422bc66f82db1e","isMergeCommit":false,"messageTitle":"[#11878] Create Update Account Request Action (#12982)","messageBody":"* create update action and IT\r\n\r\n* update javadocs\r\n\r\n* update tests\r\n\r\n* add more tests\r\n\r\n* simplify logic\r\n\r\n* remove unused string\r\n\r\n* fix test\r\n\r\n* allow null comments\r\n\r\n* add more tests\r\n\r\n* use EntityNotFoundException\r\n\r\n* cleanup after create account requests test\r\n\r\n* remove unncessary check","fileTypesAndContributionMap":{"java":{"insertions":378,"deletions":0}}}]},{"date":"2024-04-06","commitResults":[{"hash":"4a54001bac3824cc8ac2fb66324d7061151f4504","isMergeCommit":false,"messageTitle":"[#11878] Fix Account Request Update Search Indexing (#12984)","messageBody":"* update account request indexing\r\n\r\n* add methods to test access control\r\n\r\n* refactoring for transactions","fileTypesAndContributionMap":{"java":{"insertions":259,"deletions":28}}}]},{"date":"2024-04-07","commitResults":[{"hash":"62750b08b4ea5169b7098e5071f1d58153152970","isMergeCommit":false,"messageTitle":"[#11878] Add Edit and Approve Account Requests functionality (#12975)","messageBody":"* add edit and approve functionality\r\n\r\n* remove rejection code\r\n\r\n* fix snap\r\n\r\n* integrate endpoint\r\n\r\n* disable approve button for approved requests\r\n\r\n* use comments instead of comment\r\n\r\n* use searchString instead of searchQuery\r\n\r\n* fix snap","fileTypesAndContributionMap":{"scss":{"insertions":0,"deletions":0},"html":{"insertions":42,"deletions":2},"ts":{"insertions":147,"deletions":9}}}]},{"date":"2024-04-09","commitResults":[{"hash":"84ed244ade96870b71346808916568ae41b64b92","isMergeCommit":false,"messageTitle":"[#12048] Migrate AdminSearchPageE2ETest SQL (#12811)","messageBody":"* test e2e changes\r\n\r\n* fix: reduce e2e test json file size\r\n\r\n* fix student key\r\n\r\n* fix course key\r\n\r\n* fix instructor keys\r\n\r\n* fix filepath\r\n\r\n* fix e2e test\r\n\r\n* remove extra data from bundle\r\n\r\n* Add correct removal logic to avoid constraint violation\r\n\r\n* Fix e2e tests and lint\r\n\r\nfix reset google id test\r\n\r\nfix e2e tests\r\n\r\nfix e2e tests\r\n\r\nfix tests\r\n\r\nremove double click\r\n\r\nfix unknown symbol\r\n\r\nadd toast check\r\n\r\nchange toast verification message\r\n\r\nremove toast check\r\n\r\n* fix: add null check\r\n\r\n* move admin search page e2e test to sql cases\r\n\r\n* Rename AdminSearchPageE2ETest_SQLEntities.json to AdminSearchPageE2ETest_SqlEntities.json\r\n\r\n* fix failing test\r\n\r\n* fix: remove extra null check\r\n\r\n* fix: add test to e2e sql xml file\r\n\r\n* fix function call\r\n\r\n* remove unnecessary changes\r\n\r\n* create new file for sql entities\r\n\r\n* revert unnecessary changes\r\n\r\n* remove trailing whitespace\r\n\r\n* add teardown for account requests\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":446,"deletions":11}}},{"hash":"50c87bc8390e6a7c3592e00ef5db575cc66f8fcc","isMergeCommit":false,"messageTitle":"use transactions for reject account request action (#13001)","messageBody":"","fileTypesAndContributionMap":{"java":{"insertions":53,"deletions":38}}}]},{"date":"2024-04-10","commitResults":[{"hash":"a36ecf7d6996d7e4b468d19eb8c9de42eceb65d3","isMergeCommit":false,"messageTitle":"[#11878] Create Rejection Modal for Account Requests (#12989)","messageBody":"* Create rejection modal\r\n\r\n* fix lint and tests\r\n\r\n* fix placeholders and lint\r\n\r\n* remove title\r\n\r\n* integrate api\r\n\r\n* check undefined title and body\r\n\r\n* fix trailing white spaces\r\n\r\n* fix whitespace\r\n\r\n* change error message\r\n\r\n* re-add account request table on home page\r\n\r\n* replace support email","fileTypesAndContributionMap":{"scss":{"insertions":0,"deletions":0},"html":{"insertions":37,"deletions":2},"ts":{"insertions":147,"deletions":1}}}]},{"date":"2024-04-11","commitResults":[{"hash":"ce75a0a56f69d64a0c4ebcf15cffa78c9ca7b182","isMergeCommit":false,"messageTitle":"[#11878] Add Error Message for Approving Existing Account (#13004)","messageBody":"* add error message for duplicate account request\r\n\r\n* add tests","fileTypesAndContributionMap":{"java":{"insertions":75,"deletions":0}}}]},{"date":"2024-04-12","commitResults":[{"hash":"451a25a53c859e2d5382842450158ea641ec92f7","isMergeCommit":false,"messageTitle":"[#11878] Handle Duplicate Approved Account Requests (#13009)","messageBody":"","fileTypesAndContributionMap":{"java":{"insertions":52,"deletions":0}}}]},{"date":"2024-04-14","commitResults":[{"hash":"4682dffb71e4566ed72a9e8a7b2b814e8d16f869","isMergeCommit":false,"messageTitle":"[#11878] Add tests for Account Request Table (#12977)","messageBody":"* add component tests for account request table\r\n\r\n* modify tests\r\n\r\n* remove old tests\r\n\r\n* remove comment\r\n\r\n* remove unnecessary code\r\n\r\n* add tests\r\n\r\n* update disabled criteria\r\n\r\n* remove extra builders and update snaps","fileTypesAndContributionMap":{"html":{"insertions":5,"deletions":5},"ts":{"insertions":641,"deletions":197}}}]},{"date":"2024-04-15","commitResults":[{"hash":"f0e2af37f90ed48f0e48c6e3222ae96b6c4eb7f7","isMergeCommit":false,"messageTitle":"[#11878] Fix Approval Email Bug (#13027)","messageBody":"","fileTypesAndContributionMap":{"java":{"insertions":1,"deletions":1}}},{"hash":"0f0fd05a3a1a36169972f73abd67da32cfb2ab73","isMergeCommit":false,"messageTitle":"[#11878] Add Toasts (#13028)","messageBody":"* add toasts\r\n\r\n* lint","fileTypesAndContributionMap":{"ts":{"insertions":9,"deletions":1}}},{"hash":"20c29e589224601c5ceace8a656f0c14a33ec36f","isMergeCommit":false,"messageTitle":"fix highlighting and null statuses (#13031)","messageBody":"","fileTypesAndContributionMap":{"html":{"insertions":4,"deletions":4},"ts":{"insertions":1,"deletions":1}}},{"hash":"3dab1dc547f30044b2d6938a5973b9ab34e70159","isMergeCommit":false,"messageTitle":"[#11878] Fix Overlapping Tooltip (#13026)","messageBody":"* fix tooltip\r\n\r\n* re-add removed lines\r\n\r\n* update snap\r\n\r\n* update snaps\r\n\r\n* lint\r\n\r\n* suppress warning\r\n\r\n* lint","fileTypesAndContributionMap":{"scss":{"insertions":3,"deletions":1},"html":{"insertions":2,"deletions":2}}}]},{"date":"2024-04-17","commitResults":[{"hash":"68a4fbfe4052918b322acdbf89144477f677eb22","isMergeCommit":false,"messageTitle":"[#11878] Add Admin E2E Tests (#13020)","messageBody":"* add admin e2e tests\r\n\r\n* remove exception catching and update snaps\r\n\r\n* fix snaps\r\n\r\n* add comment verification\r\n\r\n* fix test","fileTypesAndContributionMap":{"java":{"insertions":293,"deletions":0},"html":{"insertions":1,"deletions":1},"ts":{"insertions":2,"deletions":2}}}]},{"date":"2024-04-18","commitResults":[{"hash":"ce839ab4351aba3036c19afa92edc60cadcbd85f","isMergeCommit":false,"messageTitle":"fix edit (#13056)","messageBody":"Co-authored-by: Zhang Ziqing \u003c69516975+ziqing26@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"ts":{"insertions":24,"deletions":14}}}]},{"date":"2024-04-19","commitResults":[{"hash":"f8bae93711d421abca2d55c08b8fd25e77a4f2ca","isMergeCommit":false,"messageTitle":"[#11878] Fix console errors (#13058)","messageBody":"","fileTypesAndContributionMap":{"html":{"insertions":3,"deletions":3},"ts":{"insertions":1,"deletions":1}}},{"hash":"ba6979e784af277f72d96563cb16ac4518618559","isMergeCommit":false,"messageTitle":"[#11878] Fix Rejection Modal (#13059)","messageBody":"","fileTypesAndContributionMap":{"ts":{"insertions":11,"deletions":5}}}]}],"asdfghjkxd":[],"yuanxi1":[{"date":"2023-12-28","commitResults":[{"hash":"5de8300549d6b06bd21d38f1d258bdcaebc6c443","isMergeCommit":false,"messageTitle":"[#12663] Instructor\u0027s Student Records Page: Tooltips for comments (#12676)","messageBody":"* Fix comment tooltip causing the text to go into next line\r\n\r\n* Update snapshot test\r\n\r\n---------\r\n\r\nCo-authored-by: YX Z \u003cyxz@YXs-MacBook-Air-2.local\u003e\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e\r\nCo-authored-by: Dominic Lim \u003c46486515+domlimm@users.noreply.github.com\u003e\r\nCo-authored-by: Jason Qiu \u003cjason_qiu@hotmail.com\u003e","fileTypesAndContributionMap":{"html":{"insertions":2,"deletions":2}}}]},{"date":"2024-02-06","commitResults":[{"hash":"f0279fa802b98f5dbf9d92c200168f21aa41ef62","isMergeCommit":false,"messageTitle":"[#12048] Migrate join course action (#12722)","messageBody":"* Add join course for student and instructor to AccountsLogic\r\n\r\n* Update AccountsLogic tests\r\n\r\n* Migrate JoinCourseAction\r\n\r\n* Add JoinCourseActionIT\r\n\r\n* Update to use usersLogic for student update\r\n\r\n* Fix failing IT caused by updates to typicalDataBundle\r\n\r\n* Fix failing IT\r\n\r\n* Remove print statements\r\n\r\n---------\r\n\r\nCo-authored-by: YX Z \u003cyxz@YXs-MacBook-Air-2.local\u003e\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":605,"deletions":12}}}]},{"date":"2024-02-14","commitResults":[{"hash":"33953dc064e3230bf0c27f2b591f5b06e212d8cf","isMergeCommit":false,"messageTitle":"[#12048] Migrate search students action (#12735)","messageBody":"* Migrate search students action and associated logic\r\n\r\n* Add tests for student search\r\n\r\n* Remove old test\r\n\r\n* Restore datastore test\r\n\r\n* Add support for dual db search\r\n\r\n* Suppress NPE warning\r\n\r\n---------\r\n\r\nCo-authored-by: YX Z \u003cyxz@YXs-MacBook-Air-2.local\u003e\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":528,"deletions":5}}}]},{"date":"2024-02-25","commitResults":[{"hash":"a913315da176e03961d0a0a4fae955571a5bf8aa","isMergeCommit":false,"messageTitle":"Add locale for java datetime formatter (#12826)","messageBody":"Co-authored-by: YX Z \u003cyxz@r-154-105-25-172.comp.nus.edu.sg\u003e","fileTypesAndContributionMap":{"java":{"insertions":2,"deletions":1}}}]},{"date":"2024-02-26","commitResults":[{"hash":"7b2a69c88dad53002650c37e12a16ba6e5564281","isMergeCommit":false,"messageTitle":"[#12048] Migrate Notification Banner E2E (#12840)","messageBody":"* Add locale for java datetime formatter\r\n\r\n* Migrate non-course content for NotificationBannerE2ETest\r\n\r\n* Fix linting\r\n\r\n* Fix snapshot test\r\n\r\n---------\r\n\r\nCo-authored-by: YX Z \u003cyxz@r-154-105-25-172.comp.nus.edu.sg\u003e\r\nCo-authored-by: YX Z \u003cyxz@YXs-MacBook-Air-2.local\u003e\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":14,"deletions":14},"html":{"insertions":1,"deletions":1}}}]},{"date":"2024-03-19","commitResults":[{"hash":"a34c3c57b22456de526d5af9a0317d502f44907a","isMergeCommit":false,"messageTitle":"[#12048] Migrate InstructorNotificationsPageE2E (#12906)","messageBody":"* Migrate InstructorNotificationsPageE2E\r\n\r\n* Fix unsaved transient entity error\r\n\r\n* Fix lint\r\n\r\n* Fix lint\r\n\r\n* Update testng xml\r\n\r\n---------\r\n\r\nCo-authored-by: YX Z \u003cyxz@YXs-MacBook-Air-2.local\u003e\r\nCo-authored-by: YX Z \u003cyxz@r-121-109-25-172.comp.nus.edu.sg\u003e\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":202,"deletions":0}}}]}],"supermii2":[],"marquestye":[{"date":"2024-02-25","commitResults":[{"hash":"3191fd1c0a471a34b3dbbfae8e305946280b0d42","isMergeCommit":false,"messageTitle":"[#12048] Migrate UpdateStudentAction (#12727)","messageBody":"* Modify student entity\r\n\r\n* Add update comment logic\r\n\r\n* Modify logic files for cascading update and creation for student\r\n\r\n* Add database queries for updating student\r\n\r\n* Update EnrollStudentsAction\r\n\r\n* Fix checkstyle\r\n\r\n* Remove extra query for editor update\r\n\r\n* Remove email update logic\r\n\r\n* Update javadocs\r\n\r\n* Copy over logic for Team and Section validation\r\n\r\n* Edit javadocs\r\n\r\n* Change StudentAttributes to Student instead\r\n\r\n* Fix lint issues\r\n\r\n* Fix lint issues\r\n\r\n* Fix component tests and lint\r\n\r\n* Remove ununsed method\r\n\r\n* Fix lint\r\n\r\n* Update validation logic to use Student\r\n\r\n* Update test case\r\n\r\n* Add tests for duplicate team across sections\r\n\r\n* Migrate UpdateStudentAction and add tests\r\n\r\n* Remove resetStudentGoogleId\r\n\r\n* Refactor updateStudentCascade\r\n\r\n* Fix integration tests\r\n\r\n* Fix checkstyle\r\n\r\n* Fix integration tests\r\n\r\n* Fix lint\r\n\r\n* Add persist verification in test\r\n\r\n* Fix test\r\n\r\n* Fix tests\r\n\r\n* Remove unused method\r\n\r\n* Fix test\r\n\r\n* Fix test\r\n\r\n* Fix test\r\n\r\n* Split UpdateStudentActionIT into multiple testcases\r\n\r\n* Add test separators\r\n\r\n---------\r\n\r\nCo-authored-by: Dominic Berzin \u003cberzindominic@gmail.com\u003e\r\nCo-authored-by: domoberzin \u003c74132255+domoberzin@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":522,"deletions":36}}}]},{"date":"2024-03-10","commitResults":[{"hash":"bf5a2ac8506bc49ecd1c479b634991a6380452e3","isMergeCommit":false,"messageTitle":"[#12048] Add tests for FeedbackQuestionsDb (#12759)","messageBody":"* Add verification during feedback question creation\r\n\r\n* Add tests for FeedbackQuestionsDb\r\n\r\n* Fix missing javadocs\r\n\r\n* Fix feedback question creation logic\r\n\r\n* Add test\r\n\r\n* Reuse error message\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e\r\nCo-authored-by: Zhang Ziqing \u003c69516975+ziqing26@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":169,"deletions":17}}}]},{"date":"2024-04-09","commitResults":[{"hash":"b9ccd4fb42a005822ba785a396699cf2a5005cec","isMergeCommit":false,"messageTitle":"[#12048] Migrate FeedbackNumScaleQuestionE2ETest (#12940)","messageBody":"* Migrate num scale e2e\r\n\r\n* Fix team id\r\n\r\n* Fix bugs","fileTypesAndContributionMap":{"java":{"insertions":147,"deletions":0}}}]},{"date":"2024-04-19","commitResults":[{"hash":"498efdc87b2e1f1b201446fe05c1dbce3a54d210","isMergeCommit":false,"messageTitle":"Add composite index for data migration (#13057)","messageBody":"Co-authored-by: FergusMok \u003cFergusMok1@gmail.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":37,"deletions":0}}}]}],"nknguyenhc":[{"date":"2023-12-25","commitResults":[{"hash":"a64f6605aec32e664527d017f7e2d9946010d4b2","isMergeCommit":false,"messageTitle":"[#12654] Instructor Edit Session Page: Bug in Grace Period Tooltip (#12675)","messageBody":"* Fix grace period tooltip\r\n\r\n* Update test cases\r\n\r\n---------\r\n\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e\r\nCo-authored-by: Dominic Lim \u003c46486515+domlimm@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"html":{"insertions":2,"deletions":2}}}]}],"Arif-Khalid":[],"NereusWB922":[],"dishenggg":[{"date":"2024-02-04","commitResults":[{"hash":"c8723d594557a0afdc117d679b9b4dfa41b32b61","isMergeCommit":false,"messageTitle":"[#12048] Migrate GetCourseJoinStatusAction (#12713)","messageBody":"* Migrate get course join status\r\n\r\n* Add IT for getCourseJoinStatusAction\r\n\r\n* Fix checkstyle\r\n\r\n* Update testcases\r\n\r\n* Update testcases\r\n\r\n* Refactor code\r\n\r\n---------\r\n\r\nCo-authored-by: dishenggg \u003cdisheng05@gmail.com\u003e\r\nCo-authored-by: FergusMok \u003cFergusMok1@gmail.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":262,"deletions":25}}}]},{"date":"2024-02-11","commitResults":[{"hash":"13c58fd88627b5fd90ca5aa5d605a6d2420cf128","isMergeCommit":false,"messageTitle":"[#12048] Migrate PutDataBundleDocumentsAction (#12734)","messageBody":"","fileTypesAndContributionMap":{"java":{"insertions":50,"deletions":4}}}]},{"date":"2024-02-18","commitResults":[{"hash":"5bfb84739674612f2d8d4f7c9d0202f5f2dbab83","isMergeCommit":false,"messageTitle":"Merge restore deleted to db (#12751)","messageBody":"Co-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":1,"deletions":0}}}]},{"date":"2024-02-22","commitResults":[{"hash":"5b3a96fdde95d6ab3fef6b861c2867efe92d15f4","isMergeCommit":false,"messageTitle":"[#12048] Add test cases for FeedbackSessionsDb (#12752)","messageBody":"* Add test for FeedbackSessionsDb\r\n\r\n* update test cases\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":253,"deletions":2}}}]},{"date":"2024-02-24","commitResults":[{"hash":"8125d5353307b0d225e90fc671c3f7420e8602a4","isMergeCommit":false,"messageTitle":"migrate instructor notif e2e (#12792)","messageBody":"Co-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":28,"deletions":21}}}]},{"date":"2024-03-13","commitResults":[{"hash":"2ad2242e44748557db65217b87dda052cbf55f7c","isMergeCommit":false,"messageTitle":"[#12048] Add tests for FeedbackQuestionsDbIT (#12781)","messageBody":"* Add verification during feedback question creation\r\n\r\n* Add tests for FeedbackQuestionsDb\r\n\r\n* Fix missing javadocs\r\n\r\n* Fix feedback question creation logic\r\n\r\n* Add test\r\n\r\n* Reuse error message\r\n\r\n* Add tests for FeedbackQuestionsDbIT\r\n\r\n---------\r\n\r\nCo-authored-by: marquestye \u003ce0360581@u.nus.edu\u003e\r\nCo-authored-by: Wei Qing \u003c48304907+weiquu@users.noreply.github.com\u003e\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":72,"deletions":0}}}]},{"date":"2024-03-18","commitResults":[{"hash":"17866eb4b93c3d773296ea2022cbf3ad96585a16","isMergeCommit":false,"messageTitle":"[#11843] Create FeedbackSessionLog entity and cron job action (#12895)","messageBody":"* Create FeedbackSessionLog entity\r\n\r\n* fix lint\r\n\r\n* Create UpdateFeedbackSessionLogsAction\r\n\r\n* Sort query results from logging service\r\n\r\n* Update type of feedbackSessionLogType\r\n\r\n* Fix naming\r\n\r\n* Fix enum in entity\r\n\r\n* Update filter to differentiate by session\r\n\r\n* Add Uri Info\r\n\r\n* Add tests\r\n\r\n* Update test case\r\n\r\n* Update to getOrderedFeedbackSessionLogs","fileTypesAndContributionMap":{"java":{"insertions":426,"deletions":11}}}]},{"date":"2024-03-19","commitResults":[{"hash":"4dc0c6deff8108eba7be7d85ccdd2f770d2b1a8e","isMergeCommit":false,"messageTitle":"[#12048] Migrate FeedbackMsqQuestionE2ETest (#12904)","messageBody":"* Migrate test\r\n\r\n* Update test\r\n\r\n* Update sql json\r\n\r\n* fix lint\r\n\r\n* Fix lint\r\n\r\n* Update json and add test to xml\r\n\r\n* Revert \"Fix lint\"\r\n\r\nThis reverts commit f767b5233dc280290b31bc6e669b173d0befd26d.\r\n\r\n* Revert \"Update sql json\"\r\n\r\nThis reverts commit 45744750bb262c3537d5628e9beef1289e163fb6.\r\n\r\n* Fix xml\r\n\r\n* Change to use makeDeepCopy\r\n\r\n* sort questions\r\n\r\n* fix verifyEquals method\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e\r\nCo-authored-by: Cedric Ong \u003ccedricong99@gmail.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":217,"deletions":4}}}]},{"date":"2024-03-27","commitResults":[{"hash":"e51132e3c4f2c694c60ac53e3f4a2dd973f9c1c9","isMergeCommit":false,"messageTitle":"[#12048] Migrate FeedbackMcqQuestionE2ETest (#12820)","messageBody":"* Migrate MCQ E2E\r\n\r\n* Fix lint\r\n\r\n* Fix lint\r\n\r\n* Update xml\r\n\r\n---------\r\n\r\nCo-authored-by: Cedric Ong \u003c67156011+cedricongjh@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"java":{"insertions":166,"deletions":1}}}]},{"date":"2024-03-28","commitResults":[{"hash":"ccad41b26b4c62529fda29bc2d4b556e7098c356","isMergeCommit":false,"messageTitle":"[#11843] Create Logic and Db layer for FeedbackSessionLogs (#12914)","messageBody":"* Create FeedbackSessionLog entity\r\n\r\n* fix lint\r\n\r\n* Create UpdateFeedbackSessionLogsAction\r\n\r\n* Sort query results from logging service\r\n\r\n* Update type of feedbackSessionLogType\r\n\r\n* Fix naming\r\n\r\n* Fix enum in entity\r\n\r\n* Update filter to differentiate by session\r\n\r\n* Add Uri Info\r\n\r\n* Add tests\r\n\r\n* Update test case\r\n\r\n* Update to getOrderedFeedbackSessionLogs\r\n\r\n* Create skeleton\r\n\r\n* Implement logic and db layer\r\n\r\n* fix lint\r\n\r\n* Update entity\r\n\r\n* Fix tests\r\n\r\n* Fix bugs and optimize action\r\n\r\n* Prevent courseId from being null\r\n\r\n* Update GCP logs to store ids\r\n\r\n* Fix tests\r\n\r\n* Update action to use reference\r\n\r\n* Add some error handling\r\n\r\n* Fix tests\r\n\r\n* Add ids to api output","fileTypesAndContributionMap":{"java":{"insertions":1055,"deletions":124}}}]},{"date":"2024-04-05","commitResults":[{"hash":"a98630d6fe89136c4953bba2fd7b887e2e57b011","isMergeCommit":false,"messageTitle":"[#11843] Update GetFeedbackSessionLogsAction to use SQL db (#12938)","messageBody":"* Create FeedbackSessionLog entity\r\n\r\n* fix lint\r\n\r\n* Create UpdateFeedbackSessionLogsAction\r\n\r\n* Sort query results from logging service\r\n\r\n* Update type of feedbackSessionLogType\r\n\r\n* Fix naming\r\n\r\n* Fix enum in entity\r\n\r\n* Update filter to differentiate by session\r\n\r\n* Add Uri Info\r\n\r\n* Add tests\r\n\r\n* Update test case\r\n\r\n* Update to getOrderedFeedbackSessionLogs\r\n\r\n* Create skeleton\r\n\r\n* Implement logic and db layer\r\n\r\n* fix lint\r\n\r\n* Update entity\r\n\r\n* Fix tests\r\n\r\n* Update action to use fslDb\r\n\r\n* Fix tests\r\n\r\n* Update DbIT to use databundle\r\n\r\n* Fix bugs and optimize action\r\n\r\n* Prevent courseId from being null\r\n\r\n* Update GCP logs to store ids\r\n\r\n* Fix tests\r\n\r\n* Update action to use reference\r\n\r\n* Add some error handling\r\n\r\n* Fix tests\r\n\r\n* Add ids to api output\r\n\r\n* Fix lint\r\n\r\n* Update cron.yaml\r\n\r\n* Tidy up code\r\n\r\n* Update comments","fileTypesAndContributionMap":{"java":{"insertions":657,"deletions":169}}}]},{"date":"2024-04-09","commitResults":[{"hash":"cfff21db4a28c169de343df4f24198923e250b8e","isMergeCommit":false,"messageTitle":"Remove unused modal (#12998)","messageBody":"","fileTypesAndContributionMap":{"html":{"insertions":0,"deletions":68},"ts":{"insertions":5,"deletions":364}}}]},{"date":"2024-04-11","commitResults":[{"hash":"6de9607e48ecd10b38c87d1b1f42aaa2379d9440","isMergeCommit":false,"messageTitle":"[#11878] Update DeleteAccountRequest to reference by ID (#12997)","messageBody":"* Update to delete by id\r\n\r\n* fix lint\r\n\r\n* fix lint\r\n\r\n* fix frontend lint","fileTypesAndContributionMap":{"java":{"insertions":22,"deletions":21},"ts":{"insertions":5,"deletions":7}}},{"hash":"e0beb08e5c1ef5e726e6f21ba87a2a7213290d26","isMergeCommit":false,"messageTitle":"[#11878] Update ResetAccountRequest to reference by ID (#13002)","messageBody":"* Update reset to reference by id\r\n\r\n* fix comments","fileTypesAndContributionMap":{"java":{"insertions":17,"deletions":16},"ts":{"insertions":5,"deletions":7}}}]},{"date":"2024-04-13","commitResults":[{"hash":"8d506a13d6a11feb0d7129b1c2563e82b7b5527d","isMergeCommit":false,"messageTitle":"[#11843] Update front end for session activity logs (#12973)","messageBody":"* Create FeedbackSessionLog entity\r\n\r\n* fix lint\r\n\r\n* Create UpdateFeedbackSessionLogsAction\r\n\r\n* Sort query results from logging service\r\n\r\n* Update type of feedbackSessionLogType\r\n\r\n* Fix naming\r\n\r\n* Fix enum in entity\r\n\r\n* Update filter to differentiate by session\r\n\r\n* Add Uri Info\r\n\r\n* Add tests\r\n\r\n* Update test case\r\n\r\n* Update to getOrderedFeedbackSessionLogs\r\n\r\n* Create skeleton\r\n\r\n* Implement logic and db layer\r\n\r\n* fix lint\r\n\r\n* Update entity\r\n\r\n* Fix tests\r\n\r\n* Update action to use fslDb\r\n\r\n* Fix tests\r\n\r\n* Update DbIT to use databundle\r\n\r\n* Fix bugs and optimize action\r\n\r\n* Prevent courseId from being null\r\n\r\n* Update GCP logs to store ids\r\n\r\n* Fix tests\r\n\r\n* Update action to use reference\r\n\r\n* Add some error handling\r\n\r\n* Fix tests\r\n\r\n* Add ids to api output\r\n\r\n* Fix lint\r\n\r\n* Update front end\r\n\r\n* Update cron.yaml\r\n\r\n* Update front end\r\n\r\n* Fix result display\r\n\r\n* Tidy up code\r\n\r\n* Update actions to use getUuid\r\n\r\n* Fix formatting\r\n\r\n* Fix bug\r\n\r\n* Add buttons to access page\r\n\r\n* Shift logging\r\n\r\n* fiox bug\r\n\r\n* fix fe tests\r\n\r\n* Fix bug\r\n\r\n* Fix tests\r\n\r\n* Add IT\r\n\r\n* remove email and fsname\r\n\r\n* fix ts lint\r\n\r\n* Fix status message\r\n\r\n* Remove front end error messages\r\n\r\n* Add assertion fortests\r\n\r\n* Fix migrated check\r\n\r\n* Change to use id\r\n\r\n* Update javadoc\r\n\r\n* Change cron job to 15 mins intervals\r\n\r\n* fix tests\r\n\r\n* fix fe bug\r\n\r\n* Add delay note\r\n\r\n* Update to use const\r\n\r\n* Add const\r\n\r\n* fix fe tests","fileTypesAndContributionMap":{"java":{"insertions":440,"deletions":225},"html":{"insertions":15,"deletions":9},"ts":{"insertions":179,"deletions":74}}}]},{"date":"2024-04-16","commitResults":[{"hash":"16f776768a3b4a6e24c2b0673993e4fce1afb8a3","isMergeCommit":false,"messageTitle":"[#11878] Request Page E2E (#13015)","messageBody":"* Add E2E skeleton\r\n\r\n* Fix test and lint\r\n\r\n* Add verifyEmailSent\r\n\r\n* fix fe tests","fileTypesAndContributionMap":{"java":{"insertions":125,"deletions":0},"html":{"insertions":2,"deletions":2}}}]},{"date":"2024-04-17","commitResults":[{"hash":"3915b8c5684bfb77087c9b334468b0960965d6e5","isMergeCommit":false,"messageTitle":"Remove method from logic and db (#13044)","messageBody":"","fileTypesAndContributionMap":{"java":{"insertions":0,"deletions":31}}}]},{"date":"2024-04-18","commitResults":[{"hash":"9a51e2ae1348baac90d5e704a49ecb58d7ca9064","isMergeCommit":false,"messageTitle":"[#11843] Fix front end bugs (#13037)","messageBody":"* Fix notViewedSince\r\n\r\n* Update disclaimer\r\n\r\n* Change disclaimer message\r\n\r\n* Fix view result message\r\n\r\n* Fix not viewed since message","fileTypesAndContributionMap":{"html":{"insertions":2,"deletions":1},"ts":{"insertions":14,"deletions":12}}}]}],"MadLamprey":[],"Tim-Siu":[{"date":"2023-12-22","commitResults":[{"hash":"fdfdded21b473d79468a263a61b32985cce72ed3","isMergeCommit":false,"messageTitle":"[#3942] Instructor\u0027s Student Records Page: Feedback session panel chevron barely visible #12668 (#12673)","messageBody":"* Fix chevron color issue\r\n\r\n* Replace property binding with static value assignation","fileTypesAndContributionMap":{"html":{"insertions":1,"deletions":1}}}]}]},"authorFileTypeContributionMap":{"xenosf":{"java":3735,"js":0,"scss":31,"md":0,"py":0,"tag":0,"html":363,"ts":331},"sopa301":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"mingyuanc":{"java":851,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"jingting1412":{"java":0,"js":0,"scss":0,"md":42,"py":0,"tag":0,"html":0,"ts":0},"KevinEyo1":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"LamJiuFong":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"yiwen101":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"jonasongg":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"domoberzin":{"java":3240,"js":0,"scss":65,"md":0,"py":0,"tag":0,"html":159,"ts":1189},"asdfghjkxd":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"yuanxi1":{"java":1309,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":3,"ts":0},"supermii2":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"marquestye":{"java":856,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"nknguyenhc":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":2,"ts":0},"Arif-Khalid":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"NereusWB922":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"dishenggg":{"java":3323,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":17,"ts":197},"MadLamprey":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":0,"ts":0},"Tim-Siu":{"java":0,"js":0,"scss":0,"md":0,"py":0,"tag":0,"html":1,"ts":0}},"authorContributionVariance":{"xenosf":51741.395,"sopa301":0.0,"mingyuanc":1254.4426,"jingting1412":53.30017,"KevinEyo1":0.0,"LamJiuFong":0.0,"yiwen101":0.0,"jonasongg":0.0,"domoberzin":19219.434,"asdfghjkxd":0.0,"yuanxi1":4913.652,"supermii2":0.0,"marquestye":2573.2632,"nknguyenhc":0.11267049,"Arif-Khalid":0.0,"NereusWB922":0.0,"dishenggg":24196.69,"MadLamprey":0.0,"Tim-Siu":0.028167622},"authorDisplayNameMap":{"xenosf":"XENO..NONG","sopa301":"POON..RYAN","mingyuanc":"CHIN..YUAN","jingting1412":"WANG..TING","KevinEyo1":"EYO ..EVIN","LamJiuFong":"LAM ..FONG","yiwen101":"WANG..IWEN","jonasongg":"JONA.. WEI","domoberzin":"DOMI.. GIN","asdfghjkxd":"GEOR.. YAO","yuanxi1":"ZHU ..ANXI","supermii2":"ALVI..S NG","marquestye":"TYE ..QUES","nknguyenhc":"NGUY..UYEN","Arif-Khalid":"ARIF..ALID","NereusWB922":"NERE.. BIN","dishenggg":"YEO ..HENG","MadLamprey":"MISR..ITYA","Tim-Siu":"XU S..UYAO"}} diff --git a/archive.zip b/archive.zip index a7db2c469669fc21449f91364f0ddc7ca145d438..9d13844d915e8ab5fbda853333ab14c2740c1004 100644 GIT binary patch delta 704496 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�co`j!6EU128I~Wk_p(&EW^|O| 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 z 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%0Aup)}TkqH=4o|M;h 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

lg{N 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 z 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 diff --git a/markbind_markbind_master/commits.json b/markbind_markbind_master/commits.json index 07478e8..4dfdd4e 100644 --- a/markbind_markbind_master/commits.json +++ b/markbind_markbind_master/commits.json @@ -1 +1 @@ -{"authorDailyContributionsMap":{"xenosf":[],"sopa301":[],"mingyuanc":[],"jingting1412":[{"date":"2024-01-25","commitResults":[{"hash":"613461c0ed23970046e1b17a2099ac5b2df71200","isMergeCommit":false,"messageTitle":"Replacing default icon for conversion (#2389)","messageBody":"Change default favicon for conversions","fileTypesAndContributionMap":{"js":{"insertions":24,"deletions":24},"njk":{"insertions":1,"deletions":1}}}]},{"date":"2024-03-04","commitResults":[{"hash":"a44bdaa163ab457753e8e737711b2843dbcc9512","isMergeCommit":false,"messageTitle":"Combining syntax cheat sheet and full syntax reference pages (#2426)","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":91,"deletions":142},"json":{"insertions":2,"deletions":4},"njk":{"insertions":71,"deletions":0}}}]},{"date":"2024-03-08","commitResults":[{"hash":"7d10b69845d4c3bdcaa862fd4bb1d053128d0c21","isMergeCommit":false,"messageTitle":"Add pageNav and info box to readerFacingFeatures page","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":7,"deletions":3}}}]},{"date":"2024-04-08","commitResults":[{"hash":"147899a56e5731aa08b10277cf9d9047cecb2d90","isMergeCommit":false,"messageTitle":"Add portfolio template for init command","messageBody":"","fileTypesAndContributionMap":{"css":{"insertions":593,"deletions":0},"md":{"insertions":517,"deletions":0},"js":{"insertions":91,"deletions":0},"json":{"insertions":83,"deletions":0}}}]},{"date":"2024-04-16","commitResults":[{"hash":"fc776ba075678182d7257b835aaa5bdd9ce4f1d6","isMergeCommit":false,"messageTitle":"Add note on absolute links (#2507)","messageBody":"* Add note on absolute links\r\n\r\n* Fix typos\r\n\r\n* Add tip to more pages\r\n\r\n* Update docs/userGuide/syntax/includes.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Update docs/userGuide/syntax/includes.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Add negative example\r\n\r\n* Update docs/userGuide/troubleshooting.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Update docs/userGuide/syntax/includes.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Update docs/userGuide/syntax/includes.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Update docs/userGuide/syntax/includes.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Add more details\r\n\r\n* Improve explanation\r\n\r\n* Improve look of tip\r\n\r\n* Update docs/userGuide/syntax/includes.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Update docs/userGuide/syntax/includes.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Update docs/userGuide/syntax/includes.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Implement review changes\r\n\r\n---------\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\nCo-authored-by: Shuyao \"Tim\" Xu \u003c61866948+Tim-Siu@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"md":{"insertions":39,"deletions":2}}}]},{"date":"2024-04-17","commitResults":[{"hash":"8253f827ea122ee8bf7ba8b12e64974be07c1f10","isMergeCommit":false,"messageTitle":"Enable seamless panels to inherit any parent\u0027s colours (#2501)","messageBody":"* Change seamless panels\r\n\r\n* Improve look of seamless panels\r\n\r\n* Add tests\r\n\r\n* Update userguide example\r\n---------\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\nCo-authored-by: Hannah \u003c59471320+kaixin-hc@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"md":{"insertions":8,"deletions":0},"vue":{"insertions":55,"deletions":9},"js":{"insertions":44,"deletions":0}}}]}],"KevinEyo1":[{"date":"2024-02-24","commitResults":[{"hash":"8bac97a3f0143e39c601e34a4761a4a0669eba97","isMergeCommit":false,"messageTitle":"GitHub Actions: add check for empty commit message","messageBody":"There is no checking of proposed commit message presence.\r\n\r\nPR authors may forget to include proposed commit message.\r\n\r\nAdding a check using GitHub Actions will help remind and ensure\r\nthat authors don\u0027t miss out on filling in the commit message.\r\n\r\nLet\u0027s add a job to the a new workflow, pr-message-reminder.yml\r\nfile to help automate checking and reminding of filling in the\r\nproposed commit message for each PR.\r\n\r\nThis approach automates the process, without having to have\r\nother users check and remind PR authors themselves. Adding the\r\nnew job to a new workflow will allow greater control of job triggers\r\nwhile maintaining clean code.","fileTypesAndContributionMap":{"yml":{"insertions":39,"deletions":0},"py":{"insertions":15,"deletions":0}}}]},{"date":"2024-03-04","commitResults":[{"hash":"e6e639d23136709d0b1784d22fdc4148485252ec","isMergeCommit":false,"messageTitle":"Upgrade simple-git version (#2439)","messageBody":"simple-git version: update to latest version\r\n\r\nsimple-git was not updated. Currently used version should no\r\nlonger be used due to security advisory.\r\n\r\nUpdating it avoids newly found vulnerabilities.\r\n\r\nLet\u0027s update it to the current latest version.","fileTypesAndContributionMap":{"json":{"insertions":1,"deletions":1}}}]},{"date":"2024-03-10","commitResults":[{"hash":"1c01cfb9351a6696b2dafafab545a868a897211e","isMergeCommit":false,"messageTitle":"UG: update wording of UG (#2440)","messageBody":"Wording might mislead readers into thinking that PageNavs\r\ncannot be used in normal pages.\r\n\r\nUpdating the wording will allow readers to know that\r\nindividual pages can also use PageNavs.\r\n\r\nLet\u0027s update the wording to be clearer and more explicit.\r\n\r\nCo-authored-by: david \u003c71922282+itsyme@users.noreply.github.com\u003e\r\n\r\n---------\r\n\r\nCo-authored-by: david \u003c71922282+itsyme@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"md":{"insertions":1,"deletions":1}}}]},{"date":"2024-03-30","commitResults":[{"hash":"e95e5885ef9306e92adc1bc7f6228c27ed76c86c","isMergeCommit":false,"messageTitle":"Utilize GitHub Actions to check for SEMVER impact label (#2470)","messageBody":"It is easy to forget to label PRs with their SEMVER impact when\r\nmerging.\r\n\r\nAdding a workflow to automate labelling will help prevent\r\nusers from missing labels when merging.\r\n\r\nLet\u0027s check the PR body description for user selected impact,\r\nand automatically add the label to the PR when merging.\r\n\r\nThis approach allows the user to not even have to add the label\r\nthemselves.","fileTypesAndContributionMap":{"yml":{"insertions":69,"deletions":0}}},{"hash":"011808d72db7321d00db0ea2765c35999ac7525e","isMergeCommit":false,"messageTitle":"MarkBind templates: add a project-specific template (#2400)","messageBody":"MarkBind has default and minimal templates.\r\n\r\nMarkBind lacks a specific template for project documentation,\r\nlimiting its appeal to users seeking specialized starting points.\r\n\r\nCreating a new template for such users enhances MarkBind\u0027s\r\nusability by providing a tailored starting point for creating\r\nproject documentation, encouraging more users to choose\r\nMarkBind for their documentation needs.\r\n\r\nLet\u0027s add a project template option during MarkBind\r\ninitialization that generates a template specifically to project\r\ndocumentation needs, with a User Guide and Developer Guide.\r\n\r\nThis approach directly addresses the gap for specialized\r\ndocumentation templates, making MarkBind a more attractive\r\noption for project maintainers.","fileTypesAndContributionMap":{"css":{"insertions":594,"deletions":0},"md":{"insertions":838,"deletions":1},"js":{"insertions":534,"deletions":0},"json":{"insertions":205,"deletions":0}}}]},{"date":"2024-04-07","commitResults":[{"hash":"fa483439e7057b002287d4b96d017cecf99481a3","isMergeCommit":false,"messageTitle":"Add `once` attribute to custom lists so attributes only apply to current item","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":169,"deletions":1},"js":{"insertions":91,"deletions":1}}}]},{"date":"2024-04-11","commitResults":[{"hash":"362f7611f4560f69bece75cf550394dd3906a7b0","isMergeCommit":false,"messageTitle":"Add references between image and pic in UG","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":12,"deletions":0}}},{"hash":"889836c6f0e29063a3ae6dcf417bbeef0d80c17c","isMergeCommit":false,"messageTitle":"Add a reminder when contributor is new to ping all contributor bot","messageBody":"","fileTypesAndContributionMap":{"yml":{"insertions":45,"deletions":0}}}]},{"date":"2024-04-16","commitResults":[{"hash":"f1c365c7e76f326c5d3e70ca4ed0dd9bc3a5d7c1","isMergeCommit":false,"messageTitle":"GitHub Actions: improve security","messageBody":"Security best practices need to be enforced to ensure no avenues\r\nof attack and security breaches.\r\n\r\nLet\u0027s update the workflows following security best practices,\r\nparticularly restricting permissions to read permissions","fileTypesAndContributionMap":{"yml":{"insertions":45,"deletions":26}}},{"hash":"fc71dd63e3da2703b79cb97fcdffe378beb951d2","isMergeCommit":false,"messageTitle":"Add back GITHUB_TOKEN to deploy-docs job (#2521)","messageBody":"","fileTypesAndContributionMap":{"yml":{"insertions":2,"deletions":0}}}]},{"date":"2024-04-18","commitResults":[{"hash":"206036977c4fb41d2676a3237f6db675c8587614","isMergeCommit":true,"messageTitle":"Merge branch \u0027master\u0027 into include-log","messageBody":"","fileTypesAndContributionMap":{}},{"hash":"104b46c8530437d046dc8b40e981b1d19045f3d1","isMergeCommit":true,"messageTitle":"Add warning for including empty segments or files in optional mode (#2506)","messageBody":"","fileTypesAndContributionMap":{}}]}],"LamJiuFong":[{"date":"2024-02-17","commitResults":[{"hash":"2647090c14283e8f108f478495c5cba4514023c4","isMergeCommit":false,"messageTitle":"Allow `markbind serve` to specify custom host #2382 (#2395)","messageBody":"Allow markbind serve to specify custom host\r\n\r\nCo-authored-by: Jiu Fong Lam \u003c\u003e","fileTypesAndContributionMap":{"md":{"insertions":5,"deletions":3},"js":{"insertions":48,"deletions":8}}}]},{"date":"2024-02-29","commitResults":[{"hash":"933655950dc65c079f911f6867b0a4d02e49f54d","isMergeCommit":false,"messageTitle":"Migrate stylelint to latest version #2292 (#2425)","messageBody":"Migrate stylelint to latest version ^16.0.0\r\nAdd devdependency \"stylelint-config-recommended-vue\"\r\nAdd plugin @stylistic/stylelint-plugin\r\nAdd dependency postcss@^8.4.35\r\nFix syntax to obey new rules\r\n\r\n---------\r\n\r\nCo-authored-by: Jiu Fong Lam \u003c\u003e","fileTypesAndContributionMap":{"css":{"insertions":72,"deletions":82},"vue":{"insertions":29,"deletions":47},"js":{"insertions":4,"deletions":3},"json":{"insertions":8,"deletions":3}}}]},{"date":"2024-03-17","commitResults":[{"hash":"371228d0a255d8b34fe24045a32692b79932fd7f","isMergeCommit":false,"messageTitle":"Add lazy property to pic and annotate","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":6,"deletions":4},"vue":{"insertions":47,"deletions":15}}}]},{"date":"2024-04-07","commitResults":[{"hash":"8ad1b0c7e1b5bc42635a83398701f256ada274f2","isMergeCommit":false,"messageTitle":"Add defer attribute to scripts in page template (#2492)","messageBody":"","fileTypesAndContributionMap":{"njk":{"insertions":4,"deletions":4}}}]}],"yiwen101":[{"date":"2024-02-12","commitResults":[{"hash":"7d9cf5a1aff00079400f020a71ad03332dc6d8f8","isMergeCommit":false,"messageTitle":"Add documentation on troubleshooting rendering markdown","messageBody":"* Update trouble shooting\r\n\r\n* Update code examples in affected presentation components\r\n\r\n* Update message for presentation component\r\n\r\n* Revert unrelated changes\r\n\r\n* Fix links\r\n\r\n* Update docs/userGuide/components/presentation.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Revert distracting changes made by formatter\r\n\r\n* Revert distracting changes by formatter2\r\n\r\n* Migrate to codeAndOutput\r\n\r\n* Updade doc\r\n\r\n* Update presentation.md\r\n\r\n* Update ug\r\n\r\n* Clean formatting error\r\n\r\n* Proof read\r\n\r\n* Improve formatting\r\n\r\n* Improve format\r\n\r\n* Improve format\r\n\r\n* Update troubleshooting.md\r\n\r\n* Update troubleshooting.md\r\n\r\n---------\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"md":{"insertions":81,"deletions":10}}}]},{"date":"2024-02-25","commitResults":[{"hash":"ef502dbf57d5b798ec535c4d4a62f62b5dd2588f","isMergeCommit":false,"messageTitle":" Fix external styles and script not hoisted by externals (#2414)","messageBody":"Also add warning in documentation that styles in hoisted\r\nexternal will also affect the rest of the page","fileTypesAndContributionMap":{"md":{"insertions":27,"deletions":0},"json":{"insertions":13,"deletions":0},"js":{"insertions":16,"deletions":0}}}]},{"date":"2024-03-18","commitResults":[{"hash":"dd4bfd3288e02174d39005654a4891fa5d88698f","isMergeCommit":false,"messageTitle":"Fix issue of cannot import footnote from hash","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":9,"deletions":0},"js":{"insertions":10,"deletions":1}}}]},{"date":"2024-03-29","commitResults":[{"hash":"66591c50686edbeb4d1ea33d7365ea4fc363dab5","isMergeCommit":false,"messageTitle":"Implement efficient validation for hash intra-link (#2465)","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":12,"deletions":12}}}]},{"date":"2024-04-04","commitResults":[{"hash":"c268733678094626ac4df26c0091d99df58c16ef","isMergeCommit":false,"messageTitle":"Fix stray space before popover and tooltip (#2486)","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":5,"deletions":0},"vue":{"insertions":6,"deletions":9},"js":{"insertions":1,"deletions":1}}}]},{"date":"2024-04-09","commitResults":[{"hash":"e0e923985f3185c800ea5755bb4f6fb4fc6ff9a8","isMergeCommit":false,"messageTitle":"Support Bootstrap icons","messageBody":"","fileTypesAndContributionMap":{"css":{"insertions":16664,"deletions":0},"md":{"insertions":18,"deletions":2},"json":{"insertions":16427,"deletions":0},"js":{"insertions":22,"deletions":0},"njk":{"insertions":1,"deletions":0}}}]},{"date":"2024-04-12","commitResults":[{"hash":"ff8e9b135c35dd1949ea25778da1146876a4f62d","isMergeCommit":false,"messageTitle":"Fix off-positioned close button in imported modal (#2487)","messageBody":"---------\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"md":{"insertions":16,"deletions":0},"vue":{"insertions":4,"deletions":4},"js":{"insertions":4,"deletions":1}}}]},{"date":"2024-04-18","commitResults":[{"hash":"f616fd2acfebba90d91b01251e91393b937a82aa","isMergeCommit":false,"messageTitle":"Rule based html validation against hydration (#2493)","messageBody":"* Add rule based html validation against Vue hydration issue\r\n\r\n* Improve docs\r\n\r\n* Update test\r\n\r\n* Add rule to check against table tag without tboby\r\n\r\n* Update docs/devGuide/design/serverSideRendering.md\r\n\r\n* Update packages/core/test/unit/utils/HtmlValidationUtil.test.ts\r\n\r\n* Update packages/core/src/utils/htmlValidationUtil.ts\r\n\r\n* Update packages/core/test/unit/utils/HtmlValidationUtil.test.ts\r\n---------\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"md":{"insertions":6,"deletions":0}}},{"hash":"bb8d02fe1a2fb75300b6819b703e21ac88acf3b9","isMergeCommit":false,"messageTitle":"Support text-icons of lists (#2520)","messageBody":"* Add text-icons of lists\r\n\r\n* Update test\r\n\r\n* Trim texts\r\n\r\n* Update user doc\r\n\r\n* Update input format\r\n\r\n* Update test\r\n\r\n* Update user guide\r\n\r\n* Improve code quality\r\n\r\n* Fix cannot override\r\n\r\n* Format the code\r\n\r\n* Update docs/userGuide/syntax/lists.md\r\n\r\n* Update docs/userGuide/syntax/lists.md\r\n\r\n* Improve code\r\n\r\n* Update user docs\r\n\r\n* Update docs/userGuide/syntax/lists.md\r\n\r\n* Update docs/userGuide/syntax/lists.md\r\n\r\n* Update docs/userGuide/syntax/lists.md\r\n\r\n---------\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"md":{"insertions":82,"deletions":0},"js":{"insertions":43,"deletions":1}}}]}],"jonasongg":[],"domoberzin":[],"asdfghjkxd":[],"yuanxi1":[],"supermii2":[],"marquestye":[],"nknguyenhc":[],"Arif-Khalid":[],"NereusWB922":[],"dishenggg":[],"MadLamprey":[],"Tim-Siu":[{"date":"2024-01-28","commitResults":[{"hash":"25326afde09843a79c4c6efb8bf0d8733844d415","isMergeCommit":false,"messageTitle":"Correct broken UG external link (#2392)","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":2,"deletions":2}}}]},{"date":"2024-02-01","commitResults":[{"hash":"67ae4b134ce35eacad680850b7233e39a516b71e","isMergeCommit":false,"messageTitle":"Use a more noticeable color for highlight words in fenced code under dark theme","messageBody":"","fileTypesAndContributionMap":{"css":{"insertions":8,"deletions":8}}}]},{"date":"2024-02-28","commitResults":[{"hash":"990d6136d1103ceae3005f1fe72be920cc7a6448","isMergeCommit":false,"messageTitle":"Automatically enforce soft-wrapping and add line-numbers when code is cut off for printing","messageBody":"","fileTypesAndContributionMap":{"css":{"insertions":29,"deletions":4},"md":{"insertions":10,"deletions":0},"js":{"insertions":18,"deletions":0}}}]},{"date":"2024-04-08","commitResults":[{"hash":"353300c5f0e2bc095213e852aba03455e485c57f","isMergeCommit":true,"messageTitle":"Merge branch \u0027master\u0027 into include-log","messageBody":"","fileTypesAndContributionMap":{}}]},{"date":"2024-04-13","commitResults":[{"hash":"69567576c8e75623e349eaa66008f3d67c3ec8e8","isMergeCommit":true,"messageTitle":"Merge branch \u0027master\u0027 into include-log","messageBody":"","fileTypesAndContributionMap":{}}]},{"date":"2024-04-14","commitResults":[{"hash":"ed5e8b14024fa5813f29f1c345a8e8496735d4cc","isMergeCommit":false,"messageTitle":"Add examples in siteNavigationMenus.md","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":5,"deletions":0}}},{"hash":"fef8cedd123a74d28e0b9a868c898814ceab90f0","isMergeCommit":false,"messageTitle":"Fix redundant example","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":4,"deletions":6}}}]},{"date":"2024-04-15","commitResults":[{"hash":"799e2ccaa00875dc67b8a71ea74ed18e243cdbe1","isMergeCommit":true,"messageTitle":"Merge branch \u0027master\u0027 into include-log","messageBody":"","fileTypesAndContributionMap":{}},{"hash":"9cd7de939d904e5d92295a144c9f2c3dd01177f0","isMergeCommit":false,"messageTitle":"Fix wrong information","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":1,"deletions":1}}}]}]},"authorFileTypeContributionMap":{"xenosf":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"sopa301":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"mingyuanc":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"jingting1412":{"java":0,"js":148,"css":676,"json":85,"md":661,"mbd":0,"mbdf":0,"njk":72,"py":0,"vue":55,"yml":0},"KevinEyo1":{"java":0,"js":619,"css":675,"json":206,"md":1017,"mbd":0,"mbdf":0,"njk":0,"py":15,"vue":0,"yml":175},"LamJiuFong":{"java":0,"js":52,"css":71,"json":7,"md":11,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":69,"yml":0},"yiwen101":{"java":0,"js":94,"css":33384,"json":16440,"md":253,"mbd":0,"mbdf":0,"njk":1,"py":0,"vue":10,"yml":0},"jonasongg":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"domoberzin":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"asdfghjkxd":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"yuanxi1":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"supermii2":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"marquestye":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"nknguyenhc":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"Arif-Khalid":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"NereusWB922":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"dishenggg":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"MadLamprey":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"Tim-Siu":{"java":0,"js":18,"css":31,"json":0,"md":14,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0}},"authorContributionVariance":{"xenosf":0.0,"sopa301":0.0,"mingyuanc":0.0,"jingting1412":12421.907,"KevinEyo1":36075.02,"LamJiuFong":498.21793,"yiwen101":7784811.0,"jonasongg":0.0,"domoberzin":0.0,"asdfghjkxd":0.0,"yuanxi1":0.0,"supermii2":0.0,"marquestye":0.0,"nknguyenhc":0.0,"Arif-Khalid":0.0,"NereusWB922":0.0,"dishenggg":0.0,"MadLamprey":0.0,"Tim-Siu":29.667143},"authorDisplayNameMap":{"xenosf":"XENO..NONG","sopa301":"POON..RYAN","mingyuanc":"CHIN..YUAN","jingting1412":"WANG..TING","KevinEyo1":"EYO ..EVIN","LamJiuFong":"LAM ..FONG","yiwen101":"WANG..IWEN","jonasongg":"JONA.. WEI","domoberzin":"DOMI.. GIN","asdfghjkxd":"GEOR.. YAO","yuanxi1":"ZHU ..ANXI","supermii2":"ALVI..S NG","marquestye":"TYE ..QUES","nknguyenhc":"NGUY..UYEN","Arif-Khalid":"ARIF..ALID","NereusWB922":"NERE.. BIN","dishenggg":"YEO ..HENG","MadLamprey":"MISR..ITYA","Tim-Siu":"XU S..UYAO"}} +{"authorDailyContributionsMap":{"xenosf":[],"sopa301":[],"mingyuanc":[],"jingting1412":[{"date":"2024-01-25","commitResults":[{"hash":"613461c0ed23970046e1b17a2099ac5b2df71200","isMergeCommit":false,"messageTitle":"Replacing default icon for conversion (#2389)","messageBody":"Change default favicon for conversions","fileTypesAndContributionMap":{"js":{"insertions":24,"deletions":24},"njk":{"insertions":1,"deletions":1}}}]},{"date":"2024-03-04","commitResults":[{"hash":"a44bdaa163ab457753e8e737711b2843dbcc9512","isMergeCommit":false,"messageTitle":"Combining syntax cheat sheet and full syntax reference pages (#2426)","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":91,"deletions":142},"json":{"insertions":2,"deletions":4},"njk":{"insertions":71,"deletions":0}}}]},{"date":"2024-03-08","commitResults":[{"hash":"7d10b69845d4c3bdcaa862fd4bb1d053128d0c21","isMergeCommit":false,"messageTitle":"Add pageNav and info box to readerFacingFeatures page","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":7,"deletions":3}}}]},{"date":"2024-04-08","commitResults":[{"hash":"147899a56e5731aa08b10277cf9d9047cecb2d90","isMergeCommit":false,"messageTitle":"Add portfolio template for init command","messageBody":"","fileTypesAndContributionMap":{"css":{"insertions":593,"deletions":0},"md":{"insertions":517,"deletions":0},"js":{"insertions":91,"deletions":0},"json":{"insertions":83,"deletions":0}}}]},{"date":"2024-04-16","commitResults":[{"hash":"fc776ba075678182d7257b835aaa5bdd9ce4f1d6","isMergeCommit":false,"messageTitle":"Add note on absolute links (#2507)","messageBody":"* Add note on absolute links\r\n\r\n* Fix typos\r\n\r\n* Add tip to more pages\r\n\r\n* Update docs/userGuide/syntax/includes.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Update docs/userGuide/syntax/includes.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Add negative example\r\n\r\n* Update docs/userGuide/troubleshooting.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Update docs/userGuide/syntax/includes.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Update docs/userGuide/syntax/includes.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Update docs/userGuide/syntax/includes.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Add more details\r\n\r\n* Improve explanation\r\n\r\n* Improve look of tip\r\n\r\n* Update docs/userGuide/syntax/includes.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Update docs/userGuide/syntax/includes.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Update docs/userGuide/syntax/includes.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Implement review changes\r\n\r\n---------\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\nCo-authored-by: Shuyao \"Tim\" Xu \u003c61866948+Tim-Siu@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"md":{"insertions":39,"deletions":2}}}]},{"date":"2024-04-19","commitResults":[{"hash":"8063cdb6951c723ac68bb71c5910c96eee2b4c14","isMergeCommit":false,"messageTitle":"Enable seamless panels to inherit any parent\u0027s colours (#2501)","messageBody":"* Change seamless panels\r\n\r\n* Improve look of seamless panels\r\n\r\n* Add tests\r\n\r\n* Update userguide example\r\n---------\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\nCo-authored-by: Hannah \u003c59471320+kaixin-hc@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"md":{"insertions":8,"deletions":0},"vue":{"insertions":55,"deletions":9},"js":{"insertions":44,"deletions":0}}}]}],"KevinEyo1":[{"date":"2024-02-24","commitResults":[{"hash":"8bac97a3f0143e39c601e34a4761a4a0669eba97","isMergeCommit":false,"messageTitle":"GitHub Actions: add check for empty commit message","messageBody":"There is no checking of proposed commit message presence.\r\n\r\nPR authors may forget to include proposed commit message.\r\n\r\nAdding a check using GitHub Actions will help remind and ensure\r\nthat authors don\u0027t miss out on filling in the commit message.\r\n\r\nLet\u0027s add a job to the a new workflow, pr-message-reminder.yml\r\nfile to help automate checking and reminding of filling in the\r\nproposed commit message for each PR.\r\n\r\nThis approach automates the process, without having to have\r\nother users check and remind PR authors themselves. Adding the\r\nnew job to a new workflow will allow greater control of job triggers\r\nwhile maintaining clean code.","fileTypesAndContributionMap":{"yml":{"insertions":39,"deletions":0},"py":{"insertions":15,"deletions":0}}}]},{"date":"2024-03-04","commitResults":[{"hash":"e6e639d23136709d0b1784d22fdc4148485252ec","isMergeCommit":false,"messageTitle":"Upgrade simple-git version (#2439)","messageBody":"simple-git version: update to latest version\r\n\r\nsimple-git was not updated. Currently used version should no\r\nlonger be used due to security advisory.\r\n\r\nUpdating it avoids newly found vulnerabilities.\r\n\r\nLet\u0027s update it to the current latest version.","fileTypesAndContributionMap":{"json":{"insertions":1,"deletions":1}}}]},{"date":"2024-03-10","commitResults":[{"hash":"1c01cfb9351a6696b2dafafab545a868a897211e","isMergeCommit":false,"messageTitle":"UG: update wording of UG (#2440)","messageBody":"Wording might mislead readers into thinking that PageNavs\r\ncannot be used in normal pages.\r\n\r\nUpdating the wording will allow readers to know that\r\nindividual pages can also use PageNavs.\r\n\r\nLet\u0027s update the wording to be clearer and more explicit.\r\n\r\nCo-authored-by: david \u003c71922282+itsyme@users.noreply.github.com\u003e\r\n\r\n---------\r\n\r\nCo-authored-by: david \u003c71922282+itsyme@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"md":{"insertions":1,"deletions":1}}}]},{"date":"2024-03-30","commitResults":[{"hash":"e95e5885ef9306e92adc1bc7f6228c27ed76c86c","isMergeCommit":false,"messageTitle":"Utilize GitHub Actions to check for SEMVER impact label (#2470)","messageBody":"It is easy to forget to label PRs with their SEMVER impact when\r\nmerging.\r\n\r\nAdding a workflow to automate labelling will help prevent\r\nusers from missing labels when merging.\r\n\r\nLet\u0027s check the PR body description for user selected impact,\r\nand automatically add the label to the PR when merging.\r\n\r\nThis approach allows the user to not even have to add the label\r\nthemselves.","fileTypesAndContributionMap":{"yml":{"insertions":69,"deletions":0}}},{"hash":"011808d72db7321d00db0ea2765c35999ac7525e","isMergeCommit":false,"messageTitle":"MarkBind templates: add a project-specific template (#2400)","messageBody":"MarkBind has default and minimal templates.\r\n\r\nMarkBind lacks a specific template for project documentation,\r\nlimiting its appeal to users seeking specialized starting points.\r\n\r\nCreating a new template for such users enhances MarkBind\u0027s\r\nusability by providing a tailored starting point for creating\r\nproject documentation, encouraging more users to choose\r\nMarkBind for their documentation needs.\r\n\r\nLet\u0027s add a project template option during MarkBind\r\ninitialization that generates a template specifically to project\r\ndocumentation needs, with a User Guide and Developer Guide.\r\n\r\nThis approach directly addresses the gap for specialized\r\ndocumentation templates, making MarkBind a more attractive\r\noption for project maintainers.","fileTypesAndContributionMap":{"css":{"insertions":594,"deletions":0},"md":{"insertions":838,"deletions":1},"js":{"insertions":534,"deletions":0},"json":{"insertions":205,"deletions":0}}}]},{"date":"2024-04-07","commitResults":[{"hash":"fa483439e7057b002287d4b96d017cecf99481a3","isMergeCommit":false,"messageTitle":"Add `once` attribute to custom lists so attributes only apply to current item","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":169,"deletions":1},"js":{"insertions":91,"deletions":1}}}]},{"date":"2024-04-11","commitResults":[{"hash":"362f7611f4560f69bece75cf550394dd3906a7b0","isMergeCommit":false,"messageTitle":"Add references between image and pic in UG","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":12,"deletions":0}}},{"hash":"889836c6f0e29063a3ae6dcf417bbeef0d80c17c","isMergeCommit":false,"messageTitle":"Add a reminder when contributor is new to ping all contributor bot","messageBody":"","fileTypesAndContributionMap":{"yml":{"insertions":45,"deletions":0}}}]},{"date":"2024-04-16","commitResults":[{"hash":"f1c365c7e76f326c5d3e70ca4ed0dd9bc3a5d7c1","isMergeCommit":false,"messageTitle":"GitHub Actions: improve security","messageBody":"Security best practices need to be enforced to ensure no avenues\r\nof attack and security breaches.\r\n\r\nLet\u0027s update the workflows following security best practices,\r\nparticularly restricting permissions to read permissions","fileTypesAndContributionMap":{"yml":{"insertions":45,"deletions":26}}},{"hash":"fc71dd63e3da2703b79cb97fcdffe378beb951d2","isMergeCommit":false,"messageTitle":"Add back GITHUB_TOKEN to deploy-docs job (#2521)","messageBody":"","fileTypesAndContributionMap":{"yml":{"insertions":2,"deletions":0}}}]}],"LamJiuFong":[{"date":"2024-02-17","commitResults":[{"hash":"2647090c14283e8f108f478495c5cba4514023c4","isMergeCommit":false,"messageTitle":"Allow `markbind serve` to specify custom host #2382 (#2395)","messageBody":"Allow markbind serve to specify custom host\r\n\r\nCo-authored-by: Jiu Fong Lam \u003c\u003e","fileTypesAndContributionMap":{"md":{"insertions":5,"deletions":3},"js":{"insertions":48,"deletions":8}}}]},{"date":"2024-02-29","commitResults":[{"hash":"933655950dc65c079f911f6867b0a4d02e49f54d","isMergeCommit":false,"messageTitle":"Migrate stylelint to latest version #2292 (#2425)","messageBody":"Migrate stylelint to latest version ^16.0.0\r\nAdd devdependency \"stylelint-config-recommended-vue\"\r\nAdd plugin @stylistic/stylelint-plugin\r\nAdd dependency postcss@^8.4.35\r\nFix syntax to obey new rules\r\n\r\n---------\r\n\r\nCo-authored-by: Jiu Fong Lam \u003c\u003e","fileTypesAndContributionMap":{"css":{"insertions":72,"deletions":82},"vue":{"insertions":29,"deletions":47},"js":{"insertions":4,"deletions":3},"json":{"insertions":8,"deletions":3}}}]},{"date":"2024-03-17","commitResults":[{"hash":"371228d0a255d8b34fe24045a32692b79932fd7f","isMergeCommit":false,"messageTitle":"Add lazy property to pic and annotate","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":6,"deletions":4},"vue":{"insertions":47,"deletions":15}}}]},{"date":"2024-04-07","commitResults":[{"hash":"8ad1b0c7e1b5bc42635a83398701f256ada274f2","isMergeCommit":false,"messageTitle":"Add defer attribute to scripts in page template (#2492)","messageBody":"","fileTypesAndContributionMap":{"njk":{"insertions":4,"deletions":4}}}]}],"yiwen101":[{"date":"2024-02-12","commitResults":[{"hash":"7d9cf5a1aff00079400f020a71ad03332dc6d8f8","isMergeCommit":false,"messageTitle":"Add documentation on troubleshooting rendering markdown","messageBody":"* Update trouble shooting\r\n\r\n* Update code examples in affected presentation components\r\n\r\n* Update message for presentation component\r\n\r\n* Revert unrelated changes\r\n\r\n* Fix links\r\n\r\n* Update docs/userGuide/components/presentation.md\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e\r\n\r\n* Revert distracting changes made by formatter\r\n\r\n* Revert distracting changes by formatter2\r\n\r\n* Migrate to codeAndOutput\r\n\r\n* Updade doc\r\n\r\n* Update presentation.md\r\n\r\n* Update ug\r\n\r\n* Clean formatting error\r\n\r\n* Proof read\r\n\r\n* Improve formatting\r\n\r\n* Improve format\r\n\r\n* Improve format\r\n\r\n* Update troubleshooting.md\r\n\r\n* Update troubleshooting.md\r\n\r\n---------\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"md":{"insertions":81,"deletions":10}}}]},{"date":"2024-02-25","commitResults":[{"hash":"ef502dbf57d5b798ec535c4d4a62f62b5dd2588f","isMergeCommit":false,"messageTitle":" Fix external styles and script not hoisted by externals (#2414)","messageBody":"Also add warning in documentation that styles in hoisted\r\nexternal will also affect the rest of the page","fileTypesAndContributionMap":{"md":{"insertions":27,"deletions":0},"json":{"insertions":13,"deletions":0},"js":{"insertions":16,"deletions":0}}}]},{"date":"2024-03-18","commitResults":[{"hash":"dd4bfd3288e02174d39005654a4891fa5d88698f","isMergeCommit":false,"messageTitle":"Fix issue of cannot import footnote from hash","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":9,"deletions":0},"js":{"insertions":10,"deletions":1}}}]},{"date":"2024-03-29","commitResults":[{"hash":"66591c50686edbeb4d1ea33d7365ea4fc363dab5","isMergeCommit":false,"messageTitle":"Implement efficient validation for hash intra-link (#2465)","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":12,"deletions":12}}}]},{"date":"2024-04-04","commitResults":[{"hash":"c268733678094626ac4df26c0091d99df58c16ef","isMergeCommit":false,"messageTitle":"Fix stray space before popover and tooltip (#2486)","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":5,"deletions":0},"vue":{"insertions":6,"deletions":9},"js":{"insertions":1,"deletions":1}}}]},{"date":"2024-04-09","commitResults":[{"hash":"e0e923985f3185c800ea5755bb4f6fb4fc6ff9a8","isMergeCommit":false,"messageTitle":"Support Bootstrap icons","messageBody":"","fileTypesAndContributionMap":{"css":{"insertions":16664,"deletions":0},"md":{"insertions":18,"deletions":2},"json":{"insertions":16427,"deletions":0},"js":{"insertions":22,"deletions":0},"njk":{"insertions":1,"deletions":0}}}]},{"date":"2024-04-12","commitResults":[{"hash":"ff8e9b135c35dd1949ea25778da1146876a4f62d","isMergeCommit":false,"messageTitle":"Fix off-positioned close button in imported modal (#2487)","messageBody":"---------\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"md":{"insertions":16,"deletions":0},"vue":{"insertions":4,"deletions":4},"js":{"insertions":4,"deletions":1}}}]},{"date":"2024-04-19","commitResults":[{"hash":"eb4f44425ec52326c8c9c9e311325d18bdefcb1f","isMergeCommit":false,"messageTitle":"Rule based html validation against hydration (#2493)","messageBody":"* Add rule based html validation against Vue hydration issue\r\n\r\n* Improve docs\r\n\r\n* Update test\r\n\r\n* Add rule to check against table tag without tboby\r\n\r\n* Update docs/devGuide/design/serverSideRendering.md\r\n\r\n* Update packages/core/test/unit/utils/HtmlValidationUtil.test.ts\r\n\r\n* Update packages/core/src/utils/htmlValidationUtil.ts\r\n\r\n* Update packages/core/test/unit/utils/HtmlValidationUtil.test.ts\r\n---------\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"md":{"insertions":6,"deletions":0}}},{"hash":"cb59668ba7582660227fb3939283e778807038eb","isMergeCommit":false,"messageTitle":"Support text-icons of lists (#2520)","messageBody":"* Add text-icons of lists\r\n\r\n* Update test\r\n\r\n* Trim texts\r\n\r\n* Update user doc\r\n\r\n* Update input format\r\n\r\n* Update test\r\n\r\n* Update user guide\r\n\r\n* Improve code quality\r\n\r\n* Fix cannot override\r\n\r\n* Format the code\r\n\r\n* Update docs/userGuide/syntax/lists.md\r\n\r\n* Update docs/userGuide/syntax/lists.md\r\n\r\n* Improve code\r\n\r\n* Update user docs\r\n\r\n* Update docs/userGuide/syntax/lists.md\r\n\r\n* Update docs/userGuide/syntax/lists.md\r\n\r\n* Update docs/userGuide/syntax/lists.md\r\n\r\n---------\r\n\r\nCo-authored-by: Chan Yu Cheng \u003c77204346+yucheng11122017@users.noreply.github.com\u003e","fileTypesAndContributionMap":{"md":{"insertions":82,"deletions":0},"js":{"insertions":43,"deletions":1}}}]}],"jonasongg":[],"domoberzin":[],"asdfghjkxd":[],"yuanxi1":[],"supermii2":[],"marquestye":[],"nknguyenhc":[],"Arif-Khalid":[],"NereusWB922":[],"dishenggg":[],"MadLamprey":[],"Tim-Siu":[{"date":"2024-01-28","commitResults":[{"hash":"25326afde09843a79c4c6efb8bf0d8733844d415","isMergeCommit":false,"messageTitle":"Correct broken UG external link (#2392)","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":2,"deletions":2}}}]},{"date":"2024-02-01","commitResults":[{"hash":"67ae4b134ce35eacad680850b7233e39a516b71e","isMergeCommit":false,"messageTitle":"Use a more noticeable color for highlight words in fenced code under dark theme","messageBody":"","fileTypesAndContributionMap":{"css":{"insertions":8,"deletions":8}}}]},{"date":"2024-02-28","commitResults":[{"hash":"990d6136d1103ceae3005f1fe72be920cc7a6448","isMergeCommit":false,"messageTitle":"Automatically enforce soft-wrapping and add line-numbers when code is cut off for printing","messageBody":"","fileTypesAndContributionMap":{"css":{"insertions":29,"deletions":4},"md":{"insertions":10,"deletions":0},"js":{"insertions":18,"deletions":0}}}]},{"date":"2024-04-19","commitResults":[{"hash":"ac3e4f579afd2e67be0af2e5ad0158824f2fe368","isMergeCommit":false,"messageTitle":"Add warning for including empty segments or files in optional mode (#2506)","messageBody":"","fileTypesAndContributionMap":{"md":{"insertions":4,"deletions":1}}}]}]},"authorFileTypeContributionMap":{"xenosf":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"sopa301":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"mingyuanc":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"jingting1412":{"java":0,"js":148,"css":676,"json":85,"md":661,"mbd":0,"mbdf":0,"njk":72,"py":0,"vue":55,"yml":0},"KevinEyo1":{"java":0,"js":619,"css":675,"json":206,"md":1017,"mbd":0,"mbdf":0,"njk":0,"py":15,"vue":0,"yml":175},"LamJiuFong":{"java":0,"js":52,"css":71,"json":7,"md":11,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":69,"yml":0},"yiwen101":{"java":0,"js":94,"css":33384,"json":16440,"md":253,"mbd":0,"mbdf":0,"njk":1,"py":0,"vue":10,"yml":0},"jonasongg":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"domoberzin":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"asdfghjkxd":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"yuanxi1":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"supermii2":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"marquestye":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"nknguyenhc":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"Arif-Khalid":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"NereusWB922":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"dishenggg":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"MadLamprey":{"java":0,"js":0,"css":0,"json":0,"md":0,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0},"Tim-Siu":{"java":0,"js":18,"css":31,"json":0,"md":14,"mbd":0,"mbdf":0,"njk":0,"py":0,"vue":0,"yml":0}},"authorContributionVariance":{"xenosf":0.0,"sopa301":0.0,"mingyuanc":0.0,"jingting1412":12334.984,"KevinEyo1":35821.734,"LamJiuFong":494.73846,"yiwen101":7729999.0,"jonasongg":0.0,"domoberzin":0.0,"asdfghjkxd":0.0,"yuanxi1":0.0,"supermii2":0.0,"marquestye":0.0,"nknguyenhc":0.0,"Arif-Khalid":0.0,"NereusWB922":0.0,"dishenggg":0.0,"MadLamprey":0.0,"Tim-Siu":28.12446},"authorDisplayNameMap":{"xenosf":"XENO..NONG","sopa301":"POON..RYAN","mingyuanc":"CHIN..YUAN","jingting1412":"WANG..TING","KevinEyo1":"EYO ..EVIN","LamJiuFong":"LAM ..FONG","yiwen101":"WANG..IWEN","jonasongg":"JONA.. WEI","domoberzin":"DOMI.. GIN","asdfghjkxd":"GEOR.. YAO","yuanxi1":"ZHU ..ANXI","supermii2":"ALVI..S NG","marquestye":"TYE ..QUES","nknguyenhc":"NGUY..UYEN","Arif-Khalid":"ARIF..ALID","NereusWB922":"NERE.. BIN","dishenggg":"YEO ..HENG","MadLamprey":"MISR..ITYA","Tim-Siu":"XU S..UYAO"}} diff --git a/reposense-logs/reposense.log.0 b/reposense-logs/reposense.log.0 index 6e63fdb..7e6a89a 100644 --- a/reposense-logs/reposense.log.0 +++ b/reposense-logs/reposense.log.0 @@ -1,1546 +1,1546 @@ -Apr 19, 2024 12:02:09 AM reposense.system.LogsManager addFileHandler +Apr 20, 2024 12:02:15 AM reposense.system.LogsManager addFileHandler INFO: Log temp folder has been successfully created -Apr 19, 2024 12:02:09 AM reposense.parser.CsvParser validateHeader +Apr 20, 2024 12:02:15 AM reposense.parser.CsvParser validateHeader INFO: Parsed header of CSV file, repo-config.csv, and recognized columns: Ignore Standalone Config, Repository's Location, Branch, Shallow Cloning, File formats, Ignore Glob List, Ignore Authors List, Find Previous Authors, Ignore Commits List -Apr 19, 2024 12:02:09 AM reposense.parser.CsvParser validateHeader +Apr 20, 2024 12:02:15 AM reposense.parser.CsvParser validateHeader INFO: Parsed header of CSV file, author-config.csv, and recognized columns: Author's Emails, Repository's Location, Author's GitHub ID, Branch, Author's Display Name, Ignore Glob List, Author's Git Author Name -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias marquestye found. The alias will belong to the last author - marquestye -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias marquestye found. The alias will belong to the last author - marquestye -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias marquestye found. The alias will belong to the last author - marquestye -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias marquestye found. The alias will belong to the last author - marquestye -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias marquestye found. The alias will belong to the last author - marquestye -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias marquestye found. The alias will belong to the last author - marquestye -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias arif-khalid found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias arif-khalid found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias arif-khalid found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias arif-khalid found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias arif-khalid found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias arif-khalid found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias kevineyo1 found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias kevineyo1 found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias kevineyo1 found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias kevineyo1 found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias kevineyo1 found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias kevineyo1 found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias domoberzin found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias domoberzin found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias domoberzin found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias domoberzin found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias domoberzin found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias domoberzin found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yuanxi1 found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yuanxi1 found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yuanxi1 found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yuanxi1 found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yuanxi1 found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yuanxi1 found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias dishenggg found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias dishenggg found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias dishenggg found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias dishenggg found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias dishenggg found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias dishenggg found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias supermii2 found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias supermii2 found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias supermii2 found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias supermii2 found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias supermii2 found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias supermii2 found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jonasongg found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jonasongg found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jonasongg found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jonasongg found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jonasongg found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jonasongg found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nereuswb922 found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nereuswb922 found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nereuswb922 found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nereuswb922 found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nereuswb922 found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nereuswb922 found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lamjiufong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lamjiufong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lamjiufong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lamjiufong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lamjiufong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lamjiufong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yiwen101 found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yiwen101 found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yiwen101 found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yiwen101 found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yiwen101 found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yiwen101 found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sopa301 found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sopa301 found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sopa301 found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sopa301 found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sopa301 found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sopa301 found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias mingyuanc found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias mingyuanc found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias mingyuanc found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias mingyuanc found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias mingyuanc found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias mingyuanc found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nknguyenhc found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nknguyenhc found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nknguyenhc found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nknguyenhc found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nknguyenhc found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nknguyenhc found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jingting1412 found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jingting1412 found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jingting1412 found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jingting1412 found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jingting1412 found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jingting1412 found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias tim-siu found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias tim-siu found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias tim-siu found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias tim-siu found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias tim-siu found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias tim-siu found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias marquestye found. The alias will belong to the last author - marquestye -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias arif-khalid found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias kevineyo1 found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias domoberzin found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yuanxi1 found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias dishenggg found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias supermii2 found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jonasongg found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nereuswb922 found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lamjiufong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yiwen101 found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sopa301 found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias mingyuanc found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nknguyenhc found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jingting1412 found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias tim-siu found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias marquestye found. The alias will belong to the last author - marquestye -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias arif-khalid found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias kevineyo1 found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias domoberzin found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yuanxi1 found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias dishenggg found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias supermii2 found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jonasongg found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nereuswb922 found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lamjiufong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yiwen101 found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sopa301 found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias mingyuanc found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nknguyenhc found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jingting1412 found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias tim-siu found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias marquestye found. The alias will belong to the last author - marquestye -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias arif-khalid found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias kevineyo1 found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias domoberzin found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yuanxi1 found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias dishenggg found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias supermii2 found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jonasongg found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nereuswb922 found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lamjiufong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yiwen101 found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sopa301 found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias mingyuanc found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nknguyenhc found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jingting1412 found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias tim-siu found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias marquestye found. The alias will belong to the last author - marquestye -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias arif-khalid found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias kevineyo1 found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias domoberzin found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yuanxi1 found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias dishenggg found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias supermii2 found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jonasongg found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nereuswb922 found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lamjiufong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yiwen101 found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sopa301 found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias mingyuanc found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nknguyenhc found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jingting1412 found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias tim-siu found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias marquestye found. The alias will belong to the last author - marquestye -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias arif-khalid found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias kevineyo1 found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias domoberzin found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yuanxi1 found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias dishenggg found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias supermii2 found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jonasongg found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nereuswb922 found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lamjiufong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yiwen101 found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sopa301 found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias mingyuanc found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nknguyenhc found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jingting1412 found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias tim-siu found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias marquestye found. The alias will belong to the last author - marquestye -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias arif-khalid found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Arif-Khalid -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias kevineyo1 found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - KevinEyo1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias domoberzin found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - domoberzin -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yuanxi1 found. The alias will belong to the last author - yuanxi1 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias dishenggg found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - dishenggg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - asdfghjkxd -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias supermii2 found. The alias will belong to the last author - supermii2 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jonasongg found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jonasongg -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nereuswb922 found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - NereusWB922 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lamjiufong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - LamJiuFong -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - xenosf -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias yiwen101 found. The alias will belong to the last author - yiwen101 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sopa301 found. The alias will belong to the last author - sopa301 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias mingyuanc found. The alias will belong to the last author - mingyuanc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias nknguyenhc found. The alias will belong to the last author - nknguyenhc -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jingting1412 found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - jingting1412 -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias tim-siu found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - Tim-Siu -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias sean leong found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias jiachen found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.model.AuthorConfiguration checkDuplicateAliases +Apr 20, 2024 12:02:15 AM reposense.model.AuthorConfiguration checkDuplicateAliases WARNING: Duplicate alias lzq found. The alias will belong to the last author - MadLamprey -Apr 19, 2024 12:02:09 AM reposense.git.GitConfig getGlobalGitLfsConfig +Apr 20, 2024 12:02:15 AM reposense.git.GitConfig getGlobalGitLfsConfig WARNING: Could not get global git lfs config java.lang.RuntimeException: reposense.system.CommandRunnerProcessException: Error returned from command git config --global --list on path . : fatal: unable to read config file '/home/runner/.gitconfig': No such file or directory @@ -1556,115 +1556,115 @@ fatal: unable to read config file '/home/runner/.gitconfig': No such file or dir at reposense.system.CommandRunner.runCommand(CommandRunner.java:21) ... 3 more -Apr 19, 2024 12:02:09 AM reposense.report.RepoCloner spawnCloneProcess -INFO: Cloning in parallel from https://github.com/markbind/markbind.git... -Apr 19, 2024 12:02:09 AM reposense.report.RepoCloner spawnCloneProcess -INFO: Cloning in parallel from https://github.com/reposense/reposense.git... -Apr 19, 2024 12:02:09 AM reposense.report.RepoCloner spawnCloneProcess +Apr 20, 2024 12:02:15 AM reposense.report.RepoCloner spawnCloneProcess INFO: Cloning in parallel from https://github.com/TEAMMATES/teammates.git... -Apr 19, 2024 12:02:09 AM reposense.report.RepoCloner spawnCloneProcess +Apr 20, 2024 12:02:15 AM reposense.report.RepoCloner spawnCloneProcess INFO: Cloning in parallel from https://github.com/CATcher-org/WATcher.git... -Apr 19, 2024 12:02:09 AM reposense.report.RepoCloner waitForCloneProcess -INFO: Waiting for cloning of https://github.com/TEAMMATES/teammates.git to complete... -Apr 19, 2024 12:02:09 AM reposense.report.RepoCloner waitForCloneProcess +Apr 20, 2024 12:02:15 AM reposense.report.RepoCloner spawnCloneProcess +INFO: Cloning in parallel from https://github.com/markbind/markbind.git... +Apr 20, 2024 12:02:15 AM reposense.report.RepoCloner spawnCloneProcess +INFO: Cloning in parallel from https://github.com/reposense/reposense.git... +Apr 20, 2024 12:02:15 AM reposense.report.RepoCloner waitForCloneProcess +INFO: Waiting for cloning of https://github.com/reposense/reposense.git to complete... +Apr 20, 2024 12:02:15 AM reposense.report.RepoCloner waitForCloneProcess INFO: Waiting for cloning of https://github.com/CATcher-org/WATcher.git to complete... -Apr 19, 2024 12:02:09 AM reposense.report.RepoCloner waitForCloneProcess +Apr 20, 2024 12:02:15 AM reposense.report.RepoCloner waitForCloneProcess +INFO: Waiting for cloning of https://github.com/TEAMMATES/teammates.git to complete... +Apr 20, 2024 12:02:15 AM reposense.report.RepoCloner waitForCloneProcess INFO: Waiting for cloning of https://github.com/markbind/markbind.git to complete... -Apr 19, 2024 12:02:09 AM reposense.report.RepoCloner waitForCloneProcess -INFO: Waiting for cloning of https://github.com/reposense/reposense.git to complete... -Apr 19, 2024 12:02:10 AM reposense.report.RepoCloner waitForCloneProcess +Apr 20, 2024 12:02:16 AM reposense.report.RepoCloner waitForCloneProcess INFO: Cloning of https://github.com/CATcher-org/WATcher.git completed! -Apr 19, 2024 12:02:10 AM reposense.report.RepoCloner spawnCloneProcess +Apr 20, 2024 12:02:16 AM reposense.report.RepoCloner spawnCloneProcess INFO: Cloning in parallel from https://github.com/CATcher-org/CATcher.git... -Apr 19, 2024 12:02:10 AM reposense.report.ReportGenerator analyzeRepos +Apr 20, 2024 12:02:16 AM reposense.report.ReportGenerator analyzeRepos INFO: [1/6] Analyzing https://github.com/CATcher-org/WATcher.git (main)... -Apr 19, 2024 12:02:10 AM reposense.report.RepoCloner waitForCloneProcess +Apr 20, 2024 12:02:16 AM reposense.report.RepoCloner waitForCloneProcess INFO: Waiting for cloning of https://github.com/CATcher-org/CATcher.git to complete... -Apr 19, 2024 12:02:10 AM reposense.report.ReportGenerator updateRepoConfig +Apr 20, 2024 12:02:17 AM reposense.report.ReportGenerator updateRepoConfig INFO: https://github.com/CATcher-org/WATcher.git (main) does not contain a standalone config file. -Apr 19, 2024 12:02:10 AM reposense.authorship.FileInfoExtractor extractTextFileInfos +Apr 20, 2024 12:02:17 AM reposense.authorship.FileInfoExtractor extractTextFileInfos INFO: Extracting relevant file info from https://github.com/CATcher-org/WATcher.git (main)... -Apr 19, 2024 12:02:12 AM reposense.report.RepoCloner waitForCloneProcess +Apr 20, 2024 12:02:18 AM reposense.report.RepoCloner waitForCloneProcess INFO: Cloning of https://github.com/CATcher-org/CATcher.git completed! -Apr 19, 2024 12:02:12 AM reposense.report.RepoCloner spawnCloneProcess +Apr 20, 2024 12:02:18 AM reposense.report.RepoCloner spawnCloneProcess INFO: Cloning in parallel from https://github.com/se-edu/addressbook-level3.git... -Apr 19, 2024 12:02:12 AM reposense.report.ReportGenerator analyzeRepos +Apr 20, 2024 12:02:18 AM reposense.report.ReportGenerator analyzeRepos INFO: [2/6] Analyzing https://github.com/CATcher-org/CATcher.git (master)... -Apr 19, 2024 12:02:12 AM reposense.report.RepoCloner waitForCloneProcess +Apr 20, 2024 12:02:18 AM reposense.report.RepoCloner waitForCloneProcess INFO: Waiting for cloning of https://github.com/se-edu/addressbook-level3.git to complete... -Apr 19, 2024 12:02:12 AM reposense.report.ReportGenerator updateRepoConfig +Apr 20, 2024 12:02:18 AM reposense.report.ReportGenerator updateRepoConfig INFO: https://github.com/CATcher-org/CATcher.git (master) does not contain a standalone config file. -Apr 19, 2024 12:02:12 AM reposense.authorship.FileInfoExtractor extractTextFileInfos +Apr 20, 2024 12:02:18 AM reposense.authorship.FileInfoExtractor extractTextFileInfos INFO: Extracting relevant file info from https://github.com/CATcher-org/CATcher.git (master)... -Apr 19, 2024 12:02:13 AM reposense.report.RepoCloner waitForCloneProcess +Apr 20, 2024 12:02:20 AM reposense.report.RepoCloner waitForCloneProcess INFO: Cloning of https://github.com/markbind/markbind.git completed! -Apr 19, 2024 12:02:13 AM reposense.report.ReportGenerator analyzeRepos +Apr 20, 2024 12:02:20 AM reposense.report.ReportGenerator analyzeRepos INFO: [3/6] Analyzing https://github.com/markbind/markbind.git (master)... -Apr 19, 2024 12:02:14 AM reposense.report.RepoCloner waitForCloneProcess +Apr 20, 2024 12:02:20 AM reposense.report.RepoCloner waitForCloneProcess INFO: Cloning of https://github.com/se-edu/addressbook-level3.git completed! -Apr 19, 2024 12:02:14 AM reposense.report.ReportGenerator analyzeRepos +Apr 20, 2024 12:02:20 AM reposense.report.ReportGenerator analyzeRepos INFO: [4/6] Analyzing https://github.com/se-edu/addressbook-level3.git (master)... -Apr 19, 2024 12:02:14 AM reposense.report.ReportGenerator updateRepoConfig +Apr 20, 2024 12:02:20 AM reposense.report.ReportGenerator updateRepoConfig INFO: https://github.com/se-edu/addressbook-level3.git (master) does not contain a standalone config file. -Apr 19, 2024 12:02:14 AM reposense.authorship.FileInfoExtractor extractTextFileInfos +Apr 20, 2024 12:02:20 AM reposense.authorship.FileInfoExtractor extractTextFileInfos INFO: Extracting relevant file info from https://github.com/se-edu/addressbook-level3.git (master)... -Apr 19, 2024 12:02:14 AM reposense.report.ReportGenerator updateRepoConfig +Apr 20, 2024 12:02:21 AM reposense.commits.CommitInfoExtractor extractCommitInfos +INFO: Extracting commits info for https://github.com/se-edu/addressbook-level3.git (master)... +Apr 20, 2024 12:02:21 AM reposense.report.ReportGenerator updateRepoConfig INFO: https://github.com/markbind/markbind.git (master) does not contain a standalone config file. -Apr 19, 2024 12:02:14 AM reposense.authorship.FileInfoExtractor extractTextFileInfos +Apr 20, 2024 12:02:21 AM reposense.authorship.FileInfoExtractor extractTextFileInfos INFO: Extracting relevant file info from https://github.com/markbind/markbind.git (master)... -Apr 19, 2024 12:02:14 AM reposense.commits.CommitInfoExtractor extractCommitInfos -INFO: Extracting commits info for https://github.com/CATcher-org/WATcher.git (main)... -Apr 19, 2024 12:02:14 AM reposense.commits.CommitInfoExtractor extractCommitInfos -INFO: Extracting commits info for https://github.com/se-edu/addressbook-level3.git (master)... -Apr 19, 2024 12:02:15 AM reposense.commits.CommitInfoExtractor extractCommitInfos +Apr 20, 2024 12:02:21 AM reposense.commits.CommitInfoExtractor extractCommitInfos INFO: Extracting commits info for https://github.com/CATcher-org/CATcher.git (master)... -Apr 19, 2024 12:02:15 AM reposense.commits.CommitInfoAnalyzer analyzeCommits +Apr 20, 2024 12:02:21 AM reposense.commits.CommitInfoAnalyzer analyzeCommits +INFO: Analyzing commits info for https://github.com/CATcher-org/CATcher.git (master)... +Apr 20, 2024 12:02:21 AM reposense.commits.CommitInfoExtractor extractCommitInfos +INFO: Extracting commits info for https://github.com/CATcher-org/WATcher.git (main)... +Apr 20, 2024 12:02:21 AM reposense.commits.CommitInfoAnalyzer analyzeCommits INFO: Analyzing commits info for https://github.com/se-edu/addressbook-level3.git (master)... -Apr 19, 2024 12:02:15 AM reposense.commits.CommitInfoAnalyzer analyzeCommits -INFO: Analyzing commits info for https://github.com/CATcher-org/WATcher.git (main)... -Apr 19, 2024 12:02:15 AM reposense.report.ReportGenerator analyzeRepo +Apr 20, 2024 12:02:22 AM reposense.report.ReportGenerator analyzeRepo INFO: Analysis of https://github.com/se-edu/addressbook-level3.git (master) completed! -Apr 19, 2024 12:02:15 AM reposense.commits.CommitInfoAnalyzer analyzeCommits -INFO: Analyzing commits info for https://github.com/CATcher-org/CATcher.git (master)... -Apr 19, 2024 12:02:15 AM reposense.report.ReportGenerator analyzeRepo +Apr 20, 2024 12:02:22 AM reposense.report.ReportGenerator analyzeRepo INFO: Analysis of https://github.com/CATcher-org/CATcher.git (master) completed! -Apr 19, 2024 12:02:15 AM reposense.report.ReportGenerator analyzeRepo +Apr 20, 2024 12:02:22 AM reposense.commits.CommitInfoAnalyzer analyzeCommits +INFO: Analyzing commits info for https://github.com/CATcher-org/WATcher.git (main)... +Apr 20, 2024 12:02:22 AM reposense.report.ReportGenerator analyzeRepo INFO: Analysis of https://github.com/CATcher-org/WATcher.git (main) completed! -Apr 19, 2024 12:02:19 AM reposense.report.RepoCloner waitForCloneProcess +Apr 20, 2024 12:02:25 AM reposense.report.RepoCloner waitForCloneProcess INFO: Cloning of https://github.com/reposense/reposense.git completed! -Apr 19, 2024 12:02:19 AM reposense.report.ReportGenerator analyzeRepos +Apr 20, 2024 12:02:25 AM reposense.report.ReportGenerator analyzeRepos INFO: [5/6] Analyzing https://github.com/reposense/reposense.git (master)... -Apr 19, 2024 12:02:19 AM reposense.report.ReportGenerator updateRepoConfig +Apr 20, 2024 12:02:26 AM reposense.report.ReportGenerator updateRepoConfig INFO: Ignoring standalone config file in https://github.com/reposense/reposense.git (master). -Apr 19, 2024 12:02:19 AM reposense.authorship.FileInfoExtractor extractTextFileInfos +Apr 20, 2024 12:02:26 AM reposense.authorship.FileInfoExtractor extractTextFileInfos INFO: Extracting relevant file info from https://github.com/reposense/reposense.git (master)... -Apr 19, 2024 12:02:24 AM reposense.commits.CommitInfoExtractor extractCommitInfos +Apr 20, 2024 12:02:31 AM reposense.commits.CommitInfoExtractor extractCommitInfos INFO: Extracting commits info for https://github.com/reposense/reposense.git (master)... -Apr 19, 2024 12:02:25 AM reposense.commits.CommitInfoAnalyzer analyzeCommits +Apr 20, 2024 12:02:31 AM reposense.commits.CommitInfoAnalyzer analyzeCommits INFO: Analyzing commits info for https://github.com/reposense/reposense.git (master)... -Apr 19, 2024 12:02:25 AM reposense.report.ReportGenerator analyzeRepo +Apr 20, 2024 12:02:31 AM reposense.report.ReportGenerator analyzeRepo INFO: Analysis of https://github.com/reposense/reposense.git (master) completed! -Apr 19, 2024 12:02:27 AM reposense.commits.CommitInfoExtractor extractCommitInfos +Apr 20, 2024 12:02:34 AM reposense.commits.CommitInfoExtractor extractCommitInfos INFO: Extracting commits info for https://github.com/markbind/markbind.git (master)... -Apr 19, 2024 12:02:27 AM reposense.commits.CommitInfoAnalyzer analyzeCommits +Apr 20, 2024 12:02:34 AM reposense.commits.CommitInfoAnalyzer analyzeCommits INFO: Analyzing commits info for https://github.com/markbind/markbind.git (master)... -Apr 19, 2024 12:02:27 AM reposense.report.ReportGenerator analyzeRepo +Apr 20, 2024 12:02:35 AM reposense.report.ReportGenerator analyzeRepo INFO: Analysis of https://github.com/markbind/markbind.git (master) completed! -Apr 19, 2024 12:02:31 AM reposense.report.RepoCloner waitForCloneProcess +Apr 20, 2024 12:02:38 AM reposense.report.RepoCloner waitForCloneProcess INFO: Cloning of https://github.com/TEAMMATES/teammates.git completed! -Apr 19, 2024 12:02:31 AM reposense.report.ReportGenerator analyzeRepos +Apr 20, 2024 12:02:38 AM reposense.report.ReportGenerator analyzeRepos INFO: [6/6] Analyzing https://github.com/TEAMMATES/teammates.git (master)... -Apr 19, 2024 12:02:31 AM reposense.report.ReportGenerator updateRepoConfig +Apr 20, 2024 12:02:38 AM reposense.report.ReportGenerator updateRepoConfig INFO: https://github.com/TEAMMATES/teammates.git (master) does not contain a standalone config file. -Apr 19, 2024 12:02:31 AM reposense.authorship.FileInfoExtractor extractTextFileInfos +Apr 20, 2024 12:02:38 AM reposense.authorship.FileInfoExtractor extractTextFileInfos INFO: Extracting relevant file info from https://github.com/TEAMMATES/teammates.git (master)... -Apr 19, 2024 12:03:14 AM reposense.commits.CommitInfoExtractor extractCommitInfos +Apr 20, 2024 12:03:24 AM reposense.commits.CommitInfoExtractor extractCommitInfos INFO: Extracting commits info for https://github.com/TEAMMATES/teammates.git (master)... -Apr 19, 2024 12:03:14 AM reposense.commits.CommitInfoAnalyzer analyzeCommits +Apr 20, 2024 12:03:24 AM reposense.commits.CommitInfoAnalyzer analyzeCommits INFO: Analyzing commits info for https://github.com/TEAMMATES/teammates.git (master)... -Apr 19, 2024 12:03:14 AM reposense.report.ReportGenerator analyzeRepo +Apr 20, 2024 12:03:24 AM reposense.report.ReportGenerator analyzeRepo INFO: Analysis of https://github.com/TEAMMATES/teammates.git (master) completed! -Apr 19, 2024 12:03:14 AM reposense.report.ReportGenerator generateReposReport +Apr 20, 2024 12:03:24 AM reposense.report.ReportGenerator generateReposReport INFO: The report is generated at /home/runner/work/2024-dashboard/2024-dashboard/reposense-report -Apr 19, 2024 12:03:15 AM reposense.RepoSense main -INFO: Elapsed processing time: 1 minute(s) 6.21 second(s) +Apr 20, 2024 12:03:25 AM reposense.RepoSense main +INFO: Elapsed processing time: 1 minute(s) 10.12 second(s) diff --git a/summary.json b/summary.json index fc4f60a..a5c095a 100644 --- a/summary.json +++ b/summary.json @@ -1 +1 @@ -{"repoSenseVersion":"5cd529fb46","reportGeneratedTime":"Fri Apr 19 08:02:09 2024 UTC+08:00","reportGenerationTime":" 1 minute(s) 5.86 second(s)","zoneId":"UTC+08:00","reportTitle":"RepoSense Report","repos":[{"location":{"location":"https://github.com/markbind/markbind.git","repoName":"markbind","organization":"markbind","domainName":"github"},"branch":"master","displayName":"markbind/markbind[master]","outputFolderName":"markbind_markbind_master"},{"location":{"location":"https://github.com/reposense/reposense.git","repoName":"reposense","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/reposense[master]","outputFolderName":"reposense_reposense_master"},{"location":{"location":"https://github.com/se-edu/addressbook-level3.git","repoName":"addressbook-level3","organization":"se-edu","domainName":"github"},"branch":"master","displayName":"se-edu/addressbook-level3[master]","outputFolderName":"se-edu_addressbook-level3_master"},{"location":{"location":"https://github.com/TEAMMATES/teammates.git","repoName":"teammates","organization":"TEAMMATES","domainName":"github"},"branch":"master","displayName":"TEAMMATES/teammates[master]","outputFolderName":"TEAMMATES_teammates_master"},{"location":{"location":"https://github.com/CATcher-org/CATcher.git","repoName":"CATcher","organization":"CATcher-org","domainName":"github"},"branch":"master","displayName":"CATcher-org/CATcher[master]","outputFolderName":"CATcher-org_CATcher_master"},{"location":{"location":"https://github.com/CATcher-org/WATcher.git","repoName":"WATcher","organization":"CATcher-org","domainName":"github"},"branch":"main","displayName":"CATcher-org/WATcher[main]","outputFolderName":"CATcher-org_WATcher_main"}],"errorSet":[],"sinceDate":"2023-12-01","untilDate":"2024-04-19","isSinceDateProvided":true,"isUntilDateProvided":false,"supportedDomainUrlMap":{"NOT_RECOGNIZED":{"BRANCH":"","REPO_URL":"UNSUPPORTED","BASE_URL":"UNSUPPORTED","HISTORY_PATH":"","COMMIT_PATH":"","BLAME_PATH":""},"github":{"BRANCH":"tree/$BRANCH","REPO_URL":"https://github.com/$ORGANIZATION/$REPO_NAME/","BASE_URL":"https://github.com/","HISTORY_PATH":"commits/$BRANCH/$FILE_PATH","COMMIT_PATH":"commit/$COMMIT_HASH","BLAME_PATH":"blame/$BRANCH/$FILE_PATH"}}} +{"repoSenseVersion":"5cd529fb46","reportGeneratedTime":"Sat Apr 20 08:02:15 2024 UTC+08:00","reportGenerationTime":" 1 minute(s) 9.77 second(s)","zoneId":"UTC+08:00","reportTitle":"RepoSense Report","repos":[{"location":{"location":"https://github.com/markbind/markbind.git","repoName":"markbind","organization":"markbind","domainName":"github"},"branch":"master","displayName":"markbind/markbind[master]","outputFolderName":"markbind_markbind_master"},{"location":{"location":"https://github.com/reposense/reposense.git","repoName":"reposense","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/reposense[master]","outputFolderName":"reposense_reposense_master"},{"location":{"location":"https://github.com/se-edu/addressbook-level3.git","repoName":"addressbook-level3","organization":"se-edu","domainName":"github"},"branch":"master","displayName":"se-edu/addressbook-level3[master]","outputFolderName":"se-edu_addressbook-level3_master"},{"location":{"location":"https://github.com/TEAMMATES/teammates.git","repoName":"teammates","organization":"TEAMMATES","domainName":"github"},"branch":"master","displayName":"TEAMMATES/teammates[master]","outputFolderName":"TEAMMATES_teammates_master"},{"location":{"location":"https://github.com/CATcher-org/CATcher.git","repoName":"CATcher","organization":"CATcher-org","domainName":"github"},"branch":"master","displayName":"CATcher-org/CATcher[master]","outputFolderName":"CATcher-org_CATcher_master"},{"location":{"location":"https://github.com/CATcher-org/WATcher.git","repoName":"WATcher","organization":"CATcher-org","domainName":"github"},"branch":"main","displayName":"CATcher-org/WATcher[main]","outputFolderName":"CATcher-org_WATcher_main"}],"errorSet":[],"sinceDate":"2023-12-01","untilDate":"2024-04-20","isSinceDateProvided":true,"isUntilDateProvided":false,"supportedDomainUrlMap":{"NOT_RECOGNIZED":{"BRANCH":"","REPO_URL":"UNSUPPORTED","BASE_URL":"UNSUPPORTED","HISTORY_PATH":"","COMMIT_PATH":"","BLAME_PATH":""},"github":{"BRANCH":"tree/$BRANCH","REPO_URL":"https://github.com/$ORGANIZATION/$REPO_NAME/","BASE_URL":"https://github.com/","HISTORY_PATH":"commits/$BRANCH/$FILE_PATH","COMMIT_PATH":"commit/$COMMIT_HASH","BLAME_PATH":"blame/$BRANCH/$FILE_PATH"}}}

    }d!*W4A&$VcG7V%!X~DU^erLQ3H@-dPOJdXvmy; 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